summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernhard Rosenkraenzer <Bernhard.Rosenkranzer@linaro.org>2012-10-28 00:30:36 +0200
committerBernhard Rosenkraenzer <Bernhard.Rosenkranzer@linaro.org>2012-10-28 00:30:36 +0200
commit66af4fcda965dc9bc66a63ee69b9e4d812d82870 (patch)
tree616dd9e631feff9d99bdc61137b9793911eb762f
downloadhackerskeyboard-66af4fcda965dc9bc66a63ee69b9e4d812d82870.tar.gz
Import source from hg https://code.google.com/p/hackerskeyboardHEADmaster
Change-Id: I454d241efe6b13f2bb03d9891022550867479ef3 Signed-off-by: Bernhard Rosenkraenzer <Bernhard.Rosenkranzer@linaro.org>
-rw-r--r--Android.mk17
-rw-r--r--CleanSpec.mk53
-rw-r--r--README-hackerskeyboard.txt12
-rw-r--r--dictionaries/sample.xml16
-rw-r--r--java/Android.mk22
-rwxr-xr-xjava/AndroidManifest.xml86
-rwxr-xr-xjava/AutoVersion.sh18
-rwxr-xr-xjava/CheckMap.pl178
-rwxr-xr-xjava/CheckMaps.sh24
-rwxr-xr-xjava/GetLanguages.sh42
-rw-r--r--java/MODULE_LICENSE_APACHE20
-rw-r--r--java/NOTICE190
-rw-r--r--java/build.xml89
-rw-r--r--java/jni/Android.mk20
-rw-r--r--java/jni/Application.mk1
-rw-r--r--java/jni/jni/org_pocketworkstation_pckeyboard_BinaryDictionary.cpp191
-rw-r--r--java/jni/src/basechars.h172
-rw-r--r--java/jni/src/char_utils.cpp899
-rw-r--r--java/jni/src/char_utils.h26
-rw-r--r--java/jni/src/dictionary.cpp604
-rw-r--r--java/jni/src/dictionary.h107
-rw-r--r--java/proguard.flags8
-rw-r--r--java/project.properties11
-rw-r--r--java/res/anim/key_preview_fadein.xml29
-rw-r--r--java/res/anim/key_preview_fadeout.xml29
-rw-r--r--java/res/anim/mini_keyboard_fadein.xml29
-rw-r--r--java/res/anim/mini_keyboard_fadeout.xml29
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_active_holo.9.pngbin0 -> 462 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_normal.9.pngbin0 -> 511 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_normal_holo.9.pngbin0 -> 435 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_normal_lock.9.pngbin0 -> 1127 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_normal_lock_holo.9.pngbin0 -> 588 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_normal_off.9.pngbin0 -> 760 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_normal_off_holo.9.pngbin0 -> 547 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on.9.pngbin0 -> 1088 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on_holo.9.pngbin0 -> 587 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_pressed.9.pngbin0 -> 730 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_holo.9.pngbin0 -> 553 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off.9.pngbin0 -> 940 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off_holo.9.pngbin0 -> 668 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on.9.pngbin0 -> 1260 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on_holo.9.pngbin0 -> 707 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_light_normal.9.pngbin0 -> 461 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_light_normal_holo.9.pngbin0 -> 468 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_light_popup_normal.9.pngbin0 -> 332 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_light_popup_selected.9.pngbin0 -> 498 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_light_pressed.9.pngbin0 -> 811 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_light_pressed_holo.9.pngbin0 -> 547 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_normal_lock_stone.9.pngbin0 -> 1593 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_normal_off_stone.9.pngbin0 -> 2389 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_normal_on_stone.9.pngbin0 -> 2408 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_normal_stone.9.pngbin0 -> 2213 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_popup_selected_holo.9.pngbin0 -> 282 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_pressed_stone.9.pngbin0 -> 1696 bytes
-rw-r--r--java/res/drawable-hdpi/cancel.pngbin0 -> 3992 bytes
-rw-r--r--java/res/drawable-hdpi/candidate_feedback_background.9.pngbin0 -> 833 bytes
-rw-r--r--java/res/drawable-hdpi/caution.pngbin0 -> 1641 bytes
-rw-r--r--java/res/drawable-hdpi/dialog_bubble_step02.9.pngbin0 -> 1475 bytes
-rw-r--r--java/res/drawable-hdpi/dialog_bubble_step07.9.pngbin0 -> 6012 bytes
-rw-r--r--java/res/drawable-hdpi/highlight_pressed.pngbin0 -> 4110 bytes
-rw-r--r--java/res/drawable-hdpi/hint_popup.9.pngbin0 -> 226 bytes
-rw-r--r--java/res/drawable-hdpi/ic_dialog_keyboard.pngbin0 -> 807 bytes
-rw-r--r--java/res/drawable-hdpi/ic_mic_dialog.pngbin0 -> 3634 bytes
-rw-r--r--java/res/drawable-hdpi/ic_subtype_keyboard.pngbin0 -> 1068 bytes
-rw-r--r--java/res/drawable-hdpi/ic_subtype_mic.pngbin0 -> 681 bytes
-rw-r--r--java/res/drawable-hdpi/ic_suggest_strip_microphone.pngbin0 -> 548 bytes
-rw-r--r--java/res/drawable-hdpi/ic_suggest_strip_microphone_swipe.pngbin0 -> 438 bytes
-rw-r--r--java/res/drawable-hdpi/icon.pngbin0 -> 4464 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_background.9.pngbin0 -> 200 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_dark_background.9.pngbin0 -> 1041 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_key_feedback_background.9.pngbin0 -> 1099 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_key_feedback_more_background.9.pngbin0 -> 1310 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_popup_panel_background.9.pngbin0 -> 1494 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_suggest_strip.9.pngbin0 -> 215 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_suggest_strip_divider.pngbin0 -> 1012 bytes
-rw-r--r--java/res/drawable-hdpi/list_selector_background_pressed.9.pngbin0 -> 4203 bytes
-rw-r--r--java/res/drawable-hdpi/mic_slash.pngbin0 -> 6995 bytes
-rw-r--r--java/res/drawable-hdpi/ok_cancel.pngbin0 -> 774 bytes
-rw-r--r--java/res/drawable-hdpi/speak_now_level0.pngbin0 -> 6017 bytes
-rw-r--r--java/res/drawable-hdpi/speak_now_level1.pngbin0 -> 6267 bytes
-rw-r--r--java/res/drawable-hdpi/speak_now_level2.pngbin0 -> 6359 bytes
-rw-r--r--java/res/drawable-hdpi/speak_now_level3.pngbin0 -> 6506 bytes
-rw-r--r--java/res/drawable-hdpi/speak_now_level4.pngbin0 -> 6542 bytes
-rw-r--r--java/res/drawable-hdpi/speak_now_level5.pngbin0 -> 6463 bytes
-rw-r--r--java/res/drawable-hdpi/speak_now_level6.pngbin0 -> 6782 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_123_mic.pngbin0 -> 2575 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_delete.pngbin0 -> 599 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_done.pngbin0 -> 1593 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_feedback_123_mic.pngbin0 -> 3541 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_feedback_delete.pngbin0 -> 681 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_feedback_done.pngbin0 -> 1068 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_feedback_language_arrows_left.pngbin0 -> 1275 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_feedback_language_arrows_right.pngbin0 -> 1329 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_feedback_mic.pngbin0 -> 2494 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_feedback_numalt.pngbin0 -> 3797 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_feedback_return.pngbin0 -> 2018 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_feedback_search.pngbin0 -> 2335 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_feedback_settings.pngbin0 -> 1558 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_feedback_shift.pngbin0 -> 677 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_feedback_shift_locked.pngbin0 -> 652 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_feedback_space.pngbin0 -> 1336 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_feedback_tab.pngbin0 -> 1707 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_language_arrows_left.pngbin0 -> 1253 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_language_arrows_right.pngbin0 -> 1372 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_mic.pngbin0 -> 886 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_num0.pngbin0 -> 1931 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_num1.pngbin0 -> 809 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_num2.pngbin0 -> 3214 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_num3.pngbin0 -> 2805 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_num4.pngbin0 -> 2647 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_num5.pngbin0 -> 2536 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_num6.pngbin0 -> 3573 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_num7.pngbin0 -> 3684 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_num8.pngbin0 -> 2904 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_num9.pngbin0 -> 3860 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_numalt.pngbin0 -> 2919 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_numpound.pngbin0 -> 1600 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_numstar.pngbin0 -> 1749 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_return.pngbin0 -> 1719 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_search.pngbin0 -> 1260 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_settings.pngbin0 -> 1094 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_shift.pngbin0 -> 640 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_shift_locked.pngbin0 -> 593 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_space.pngbin0 -> 326 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_space_led.9.pngbin0 -> 3249 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_tab.pngbin0 -> 1434 bytes
-rw-r--r--java/res/drawable-hdpi/voice_ime_background.9.pngbin0 -> 1271 bytes
-rw-r--r--java/res/drawable-hdpi/voice_swipe_hint.pngbin0 -> 5965 bytes
-rwxr-xr-xjava/res/drawable-hdpi/working.pngbin0 -> 1180 bytes
-rw-r--r--java/res/drawable-ldpi/icon.pngbin0 -> 1934 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_active_holo.9.pngbin0 -> 345 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_normal.9.pngbin0 -> 377 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_normal_holo.9.pngbin0 -> 334 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_normal_lock.9.pngbin0 -> 848 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_normal_lock_holo.9.pngbin0 -> 414 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_normal_off.9.pngbin0 -> 545 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_normal_off_holo.9.pngbin0 -> 407 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on.9.pngbin0 -> 806 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on_holo.9.pngbin0 -> 411 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_pressed.9.pngbin0 -> 514 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_holo.9.pngbin0 -> 394 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off.9.pngbin0 -> 687 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off_holo.9.pngbin0 -> 505 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on.9.pngbin0 -> 940 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on_holo.9.pngbin0 -> 489 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_light_normal.9.pngbin0 -> 355 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_light_normal_holo.9.pngbin0 -> 332 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_light_popup_normal.9.pngbin0 -> 252 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_light_popup_selected.9.pngbin0 -> 389 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_light_pressed.9.pngbin0 -> 526 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_light_pressed_holo.9.pngbin0 -> 381 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_normal_lock_stone.9.pngbin0 -> 1593 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_normal_off_stone.9.pngbin0 -> 2389 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_normal_on_stone.9.pngbin0 -> 2408 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_normal_stone.9.pngbin0 -> 2213 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_popup_selected_holo.9.pngbin0 -> 236 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_pressed_stone.9.pngbin0 -> 1021 bytes
-rw-r--r--java/res/drawable-mdpi/cancel.pngbin0 -> 5792 bytes
-rw-r--r--java/res/drawable-mdpi/candidate_feedback_background.9.pngbin0 -> 1182 bytes
-rw-r--r--java/res/drawable-mdpi/caution.pngbin0 -> 1100 bytes
-rw-r--r--java/res/drawable-mdpi/dialog_bubble_step02.9.pngbin0 -> 1036 bytes
-rw-r--r--java/res/drawable-mdpi/dialog_bubble_step07.9.pngbin0 -> 4646 bytes
-rw-r--r--java/res/drawable-mdpi/highlight_pressed.pngbin0 -> 593 bytes
-rw-r--r--java/res/drawable-mdpi/hint_popup.9.pngbin0 -> 202 bytes
-rw-r--r--java/res/drawable-mdpi/ic_dialog_keyboard.pngbin0 -> 528 bytes
-rw-r--r--java/res/drawable-mdpi/ic_mic_dialog.pngbin0 -> 3312 bytes
-rw-r--r--java/res/drawable-mdpi/ic_subtype_keyboard.pngbin0 -> 498 bytes
-rw-r--r--java/res/drawable-mdpi/ic_subtype_mic.pngbin0 -> 483 bytes
-rw-r--r--java/res/drawable-mdpi/ic_suggest_strip_microphone.pngbin0 -> 398 bytes
-rw-r--r--java/res/drawable-mdpi/ic_suggest_strip_microphone_swipe.pngbin0 -> 309 bytes
-rw-r--r--java/res/drawable-mdpi/icon.pngbin0 -> 2711 bytes
-rw-r--r--java/res/drawable-mdpi/keyboard_background.9.pngbin0 -> 214 bytes
-rw-r--r--java/res/drawable-mdpi/keyboard_dark_background.9.pngbin0 -> 196 bytes
-rw-r--r--java/res/drawable-mdpi/keyboard_key_feedback_background.9.pngbin0 -> 764 bytes
-rw-r--r--java/res/drawable-mdpi/keyboard_key_feedback_more_background.9.pngbin0 -> 850 bytes
-rw-r--r--java/res/drawable-mdpi/keyboard_popup_panel_background.9.pngbin0 -> 1726 bytes
-rw-r--r--java/res/drawable-mdpi/keyboard_suggest_strip.9.pngbin0 -> 205 bytes
-rw-r--r--java/res/drawable-mdpi/keyboard_suggest_strip_divider.pngbin0 -> 2812 bytes
-rw-r--r--java/res/drawable-mdpi/list_selector_background_pressed.9.pngbin0 -> 11006 bytes
-rw-r--r--java/res/drawable-mdpi/mic_slash.pngbin0 -> 7595 bytes
-rw-r--r--java/res/drawable-mdpi/ok_cancel.pngbin0 -> 3330 bytes
-rw-r--r--java/res/drawable-mdpi/speak_now_level0.pngbin0 -> 6738 bytes
-rw-r--r--java/res/drawable-mdpi/speak_now_level1.pngbin0 -> 6804 bytes
-rw-r--r--java/res/drawable-mdpi/speak_now_level2.pngbin0 -> 6897 bytes
-rw-r--r--java/res/drawable-mdpi/speak_now_level3.pngbin0 -> 7077 bytes
-rw-r--r--java/res/drawable-mdpi/speak_now_level4.pngbin0 -> 7109 bytes
-rw-r--r--java/res/drawable-mdpi/speak_now_level5.pngbin0 -> 6933 bytes
-rw-r--r--java/res/drawable-mdpi/speak_now_level6.pngbin0 -> 7050 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_123_mic.pngbin0 -> 1540 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_delete.pngbin0 -> 3432 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_done.pngbin0 -> 771 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_feedback_123_mic.pngbin0 -> 4640 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_feedback_delete.pngbin0 -> 3414 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_feedback_done.pngbin0 -> 498 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_feedback_language_arrows_left.pngbin0 -> 3126 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_feedback_language_arrows_right.pngbin0 -> 3121 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_feedback_mic.pngbin0 -> 3803 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_feedback_numalt.pngbin0 -> 4679 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_feedback_return.pngbin0 -> 3613 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_feedback_search.pngbin0 -> 3793 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_feedback_settings.pngbin0 -> 3839 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_feedback_shift.pngbin0 -> 3320 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_feedback_shift_locked.pngbin0 -> 3268 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_feedback_space.pngbin0 -> 3222 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_feedback_tab.pngbin0 -> 3529 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_language_arrows_left.pngbin0 -> 3001 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_language_arrows_right.pngbin0 -> 3032 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_mic.pngbin0 -> 3439 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_num0.pngbin0 -> 1160 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_num1.pngbin0 -> 506 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_num2.pngbin0 -> 1778 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_num3.pngbin0 -> 1676 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_num4.pngbin0 -> 1540 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_num5.pngbin0 -> 1417 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_num6.pngbin0 -> 1952 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_num7.pngbin0 -> 2051 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_num8.pngbin0 -> 1605 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_num9.pngbin0 -> 2173 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_numalt.pngbin0 -> 1673 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_numpound.pngbin0 -> 963 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_numstar.pngbin0 -> 954 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_return.pngbin0 -> 3380 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_search.pngbin0 -> 3535 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_settings.pngbin0 -> 3448 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_shift.pngbin0 -> 3217 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_shift_lock.pngbin0 -> 3188 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_shift_locked.pngbin0 -> 3188 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_space.pngbin0 -> 3063 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_space_led.9.pngbin0 -> 365 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_tab.pngbin0 -> 3269 bytes
-rw-r--r--java/res/drawable-mdpi/voice_ime_background.9.pngbin0 -> 828 bytes
-rw-r--r--java/res/drawable-mdpi/voice_swipe_hint.pngbin0 -> 3111 bytes
-rw-r--r--java/res/drawable-mdpi/working.pngbin0 -> 3367 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_dark_active_holo.9.pngbin0 -> 601 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_holo.9.pngbin0 -> 568 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_lock_holo.9.pngbin0 -> 722 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_off_holo.9.pngbin0 -> 722 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_on_holo.9.pngbin0 -> 745 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_holo.9.pngbin0 -> 737 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_off_holo.9.pngbin0 -> 953 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_on_holo.9.pngbin0 -> 945 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_light_normal_holo.9.pngbin0 -> 591 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_light_pressed_holo.9.pngbin0 -> 668 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_popup_selected_holo.9.pngbin0 -> 351 bytes
-rw-r--r--java/res/drawable/btn_keyboard_key_gingerbread.xml45
-rw-r--r--java/res/drawable/btn_keyboard_key_gingerbread_popup.xml21
-rw-r--r--java/res/drawable/btn_keyboard_key_ics.xml52
-rw-r--r--java/res/drawable/btn_keyboard_key_stone.xml40
-rw-r--r--java/res/drawable/ic_suggest_scroll_background.xml25
-rw-r--r--java/res/layout/bubble_text.xml30
-rw-r--r--java/res/layout/candidate_preview.xml29
-rw-r--r--java/res/layout/candidates.xml38
-rw-r--r--java/res/layout/input_gingerbread.xml34
-rw-r--r--java/res/layout/input_ics.xml35
-rw-r--r--java/res/layout/input_stone_bold.xml40
-rw-r--r--java/res/layout/input_stone_normal.xml38
-rw-r--r--java/res/layout/input_stone_popup.xml45
-rwxr-xr-xjava/res/layout/input_trans.xml34
-rwxr-xr-xjava/res/layout/input_trans_neon.xml40
-rw-r--r--java/res/layout/key_preview.xml29
-rw-r--r--java/res/layout/keyboard_popup.xml43
-rw-r--r--java/res/layout/main.xml30
-rw-r--r--java/res/layout/null_layout.xml8
-rw-r--r--java/res/layout/recognition_status.xml98
-rw-r--r--java/res/layout/seek_bar_dialog.xml43
-rw-r--r--java/res/layout/voice_punctuation_hint.xml49
-rw-r--r--java/res/layout/voice_swipe_hint.xml56
-rwxr-xr-xjava/res/raw/main.dictbin0 -> 34 bytes
-rwxr-xr-xjava/res/raw/type3.oggbin0 -> 4126 bytes
-rw-r--r--java/res/values-ar/bools.xml22
-rw-r--r--java/res/values-ar/donottranslate-altchars.xml47
-rw-r--r--java/res/values-ar/donottranslate-keymap.xml221
-rw-r--r--java/res/values-ar/donottranslate.xml27
-rw-r--r--java/res/values-ar/strings.xml140
-rw-r--r--java/res/values-bg/donottranslate-keymap.xml223
-rw-r--r--java/res/values-bg/strings.xml140
-rw-r--r--java/res/values-ca/strings.xml140
-rw-r--r--java/res/values-cs-rQY/donottranslate-altchars.xml43
-rw-r--r--java/res/values-cs-rQY/donottranslate-keymap.xml222
-rw-r--r--java/res/values-cs/donottranslate-altchars.xml43
-rw-r--r--java/res/values-cs/donottranslate-keymap.xml222
-rw-r--r--java/res/values-cs/strings.xml140
-rw-r--r--java/res/values-da/donottranslate-altchars.xml41
-rw-r--r--java/res/values-da/donottranslate-keymap.xml222
-rw-r--r--java/res/values-da/strings.xml142
-rw-r--r--java/res/values-de/donottranslate-altchars.xml29
-rw-r--r--java/res/values-de/donottranslate-keymap.xml126
-rw-r--r--java/res/values-de/strings.xml140
-rw-r--r--java/res/values-el/donottranslate-altchars.xml30
-rw-r--r--java/res/values-el/donottranslate-keymap.xml223
-rw-r--r--java/res/values-el/strings.xml140
-rw-r--r--java/res/values-en-rDV/donottranslate-altchars.xml47
-rw-r--r--java/res/values-en-rDV/donottranslate-keymap.xml225
-rw-r--r--java/res/values-en-rGB/donottranslate-altchars.xml23
-rw-r--r--java/res/values-en-rGB/donottranslate-keymap.xml215
-rw-r--r--java/res/values-en-rGB/strings.xml143
-rw-r--r--java/res/values-en/donottranslate-altchars.xml54
-rw-r--r--java/res/values-en/donottranslate-keymap.xml221
-rw-r--r--java/res/values-es-rUS/donottranslate-altchars.xml30
-rw-r--r--java/res/values-es-rUS/strings.xml140
-rw-r--r--java/res/values-es/donottranslate-altchars.xml30
-rw-r--r--java/res/values-es/donottranslate-keymap.xml221
-rw-r--r--java/res/values-es/strings.xml140
-rw-r--r--java/res/values-fa/donottranslate-keymap.xml223
-rw-r--r--java/res/values-fa/donottranslate.xml27
-rw-r--r--java/res/values-fa/strings.xml140
-rw-r--r--java/res/values-fi/donottranslate-altchars.xml47
-rw-r--r--java/res/values-fi/donottranslate-keymap.xml223
-rw-r--r--java/res/values-fi/strings.xml140
-rw-r--r--java/res/values-fr-rCA/donottranslate-altchars.xml33
-rw-r--r--java/res/values-fr-rCA/donottranslate-keymap.xml221
-rw-r--r--java/res/values-fr-rCA/strings.xml19
-rw-r--r--java/res/values-fr/donottranslate-altchars.xml33
-rw-r--r--java/res/values-fr/donottranslate-keymap.xml221
-rw-r--r--java/res/values-fr/donottranslate.xml25
-rw-r--r--java/res/values-fr/strings.xml140
-rw-r--r--java/res/values-he/bools.xml22
-rw-r--r--java/res/values-he/donottranslate-altchars.xml47
-rw-r--r--java/res/values-he/donottranslate-keymap.xml217
-rw-r--r--java/res/values-he/strings.xml140
-rw-r--r--java/res/values-hr/donottranslate-altchars.xml38
-rw-r--r--java/res/values-hr/donottranslate-keymap.xml126
-rw-r--r--java/res/values-hr/strings.xml140
-rw-r--r--java/res/values-hu/donottranslate-altchars.xml47
-rw-r--r--java/res/values-hu/strings.xml140
-rw-r--r--java/res/values-hy/donottranslate-keymap.xml221
-rw-r--r--java/res/values-in/strings.xml140
-rw-r--r--java/res/values-it/donottranslate-altchars.xml30
-rw-r--r--java/res/values-it/donottranslate-keymap.xml221
-rw-r--r--java/res/values-it/donottranslate.xml23
-rw-r--r--java/res/values-it/strings.xml140
-rw-r--r--java/res/values-iw/bools.xml22
-rw-r--r--java/res/values-iw/donottranslate-altchars.xml47
-rw-r--r--java/res/values-iw/donottranslate-keymap.xml217
-rw-r--r--java/res/values-iw/strings.xml140
-rw-r--r--java/res/values-ja/donottranslate-altchars.xml30
-rw-r--r--java/res/values-ja/strings.xml140
-rw-r--r--java/res/values-ko/donottranslate-altchars.xml30
-rw-r--r--java/res/values-ko/strings.xml140
-rw-r--r--java/res/values-land/dimens.xml39
-rw-r--r--java/res/values-lo/donottranslate-keymap.xml221
-rw-r--r--java/res/values-lt/strings.xml140
-rw-r--r--java/res/values-lv/donottranslate-altchars.xml47
-rw-r--r--java/res/values-lv/strings.xml140
-rw-r--r--java/res/values-nb/donottranslate-altchars.xml37
-rw-r--r--java/res/values-nb/donottranslate-keymap.xml223
-rw-r--r--java/res/values-nb/strings.xml140
-rw-r--r--java/res/values-nl/donottranslate-altchars.xml30
-rw-r--r--java/res/values-nl/strings.xml140
-rw-r--r--java/res/values-pl/donottranslate-altchars.xml33
-rw-r--r--java/res/values-pl/strings.xml140
-rw-r--r--java/res/values-pt-rPT/donottranslate-altchars.xml30
-rw-r--r--java/res/values-pt-rPT/donottranslate-keymap.xml221
-rw-r--r--java/res/values-pt-rPT/strings.xml140
-rw-r--r--java/res/values-pt/donottranslate-altchars.xml30
-rw-r--r--java/res/values-pt/strings.xml140
-rw-r--r--java/res/values-rm/donottranslate-altchars.xml30
-rw-r--r--java/res/values-rm/strings.xml148
-rw-r--r--java/res/values-ro/donottranslate-altchars.xml25
-rw-r--r--java/res/values-ro/donottranslate-keymap.xml221
-rw-r--r--java/res/values-ro/strings.xml140
-rw-r--r--java/res/values-ru-rPH/donottranslate-keymap.xml221
-rw-r--r--java/res/values-ru/donottranslate-altchars.xml23
-rw-r--r--java/res/values-ru/donottranslate-keymap.xml221
-rw-r--r--java/res/values-ru/strings.xml140
-rw-r--r--java/res/values-si/donottranslate-keymap.xml222
-rw-r--r--java/res/values-sk-rQY/donottranslate-altchars.xml43
-rw-r--r--java/res/values-sk-rQY/donottranslate-keymap.xml222
-rw-r--r--java/res/values-sk/donottranslate-altchars.xml43
-rw-r--r--java/res/values-sk/donottranslate-keymap.xml222
-rw-r--r--java/res/values-sk/strings.xml140
-rw-r--r--java/res/values-sl/donottranslate-altchars.xml39
-rw-r--r--java/res/values-sl/donottranslate-keymap.xml126
-rw-r--r--java/res/values-sl/strings.xml140
-rw-r--r--java/res/values-sr/donottranslate-keymap.xml197
-rw-r--r--java/res/values-sr/strings.xml140
-rw-r--r--java/res/values-sv/donottranslate-altchars.xml38
-rw-r--r--java/res/values-sv/donottranslate-keymap.xml219
-rw-r--r--java/res/values-sv/strings.xml140
-rw-r--r--java/res/values-th/donottranslate-keymap.xml211
-rw-r--r--java/res/values-th/strings.xml140
-rw-r--r--java/res/values-tl/strings.xml140
-rw-r--r--java/res/values-tr/donottranslate-altchars.xml35
-rw-r--r--java/res/values-tr/donottranslate-keymap.xml221
-rw-r--r--java/res/values-tr/strings.xml140
-rw-r--r--java/res/values-uk/donottranslate-keymap.xml224
-rw-r--r--java/res/values-uk/strings.xml140
-rw-r--r--java/res/values-vi/strings.xml140
-rw-r--r--java/res/values-xlarge-land/dimens.xml29
-rw-r--r--java/res/values-xlarge/bools.xml23
-rw-r--r--java/res/values-xlarge/dimens.xml31
-rw-r--r--java/res/values-xlarge/size-defaults.xml25
-rw-r--r--java/res/values-zh-rCN/donottranslate-altchars.xml30
-rw-r--r--java/res/values-zh-rCN/strings.xml140
-rw-r--r--java/res/values-zh-rTW/donottranslate-altchars.xml30
-rw-r--r--java/res/values-zh-rTW/strings.xml140
-rw-r--r--java/res/values/attrs-keyboard.xml90
-rw-r--r--java/res/values/attrs-seekbarpref.xml26
-rw-r--r--java/res/values/attrs.xml84
-rw-r--r--java/res/values/bools.xml45
-rw-r--r--java/res/values/colors.xml36
-rw-r--r--java/res/values/config.xml34
-rw-r--r--java/res/values/dimens.xml54
-rw-r--r--java/res/values/donottranslate-altchars.xml54
-rw-r--r--java/res/values/donottranslate-keymap.xml223
-rw-r--r--java/res/values/donottranslate.xml36
-rw-r--r--java/res/values/durations.xml25
-rw-r--r--java/res/values/keycodes.xml65
-rw-r--r--java/res/values/size-defaults.xml26
-rw-r--r--java/res/values/strings.xml654
-rw-r--r--java/res/values/styles.xml48
-rw-r--r--java/res/xml-ar/kbd_qwerty.xml525
-rw-r--r--java/res/xml-bg/kbd_qwerty.xml516
-rw-r--r--java/res/xml-cs-rQY/kbd_qwerty.xml527
-rw-r--r--java/res/xml-cs/kbd_qwerty.xml527
-rw-r--r--java/res/xml-da/kbd_qwerty.xml532
-rw-r--r--java/res/xml-de/kbd_qwerty.xml513
-rw-r--r--java/res/xml-el/kbd_qwerty.xml136
-rw-r--r--java/res/xml-en-rDV/kbd_qwerty.xml538
-rw-r--r--java/res/xml-en/kbd_extension.xml61
-rw-r--r--java/res/xml-en/kbd_qwerty.xml527
-rw-r--r--java/res/xml-en/kbd_symbols.xml213
-rw-r--r--java/res/xml-fa/kbd_qwerty.xml525
-rw-r--r--java/res/xml-fr-rCA/kbd_qwerty.xml503
-rw-r--r--java/res/xml-fr/kbd_qwerty.xml516
-rw-r--r--java/res/xml-he/kbd_qwerty.xml472
-rw-r--r--java/res/xml-hr/kbd_qwerty.xml527
-rw-r--r--java/res/xml-iw/kbd_qwerty.xml472
-rw-r--r--java/res/xml-nb/kbd_qwerty.xml532
-rw-r--r--java/res/xml-ru-rPH/kbd_qwerty.xml515
-rw-r--r--java/res/xml-ru/kbd_qwerty.xml512
-rw-r--r--java/res/xml-sk-rQY/kbd_qwerty.xml527
-rw-r--r--java/res/xml-sk/kbd_qwerty.xml527
-rw-r--r--java/res/xml-sl/kbd_qwerty.xml527
-rw-r--r--java/res/xml-sr/kbd_qwerty.xml503
-rw-r--r--java/res/xml-sv/kbd_qwerty.xml535
-rw-r--r--java/res/xml-tr/kbd_qwerty.xml530
-rw-r--r--java/res/xml-uk/kbd_qwerty.xml516
-rw-r--r--java/res/xml/dictionary.xml23
-rw-r--r--java/res/xml/kbd_compact.xml330
-rw-r--r--java/res/xml/kbd_compact_fn.xml282
-rw-r--r--java/res/xml/kbd_extension.xml61
-rw-r--r--java/res/xml/kbd_extension_full.xml56
-rw-r--r--java/res/xml/kbd_full.xml407
-rw-r--r--java/res/xml/kbd_full_fn.xml320
-rw-r--r--java/res/xml/kbd_phone.xml105
-rw-r--r--java/res/xml/kbd_phone_symbols.xml101
-rw-r--r--java/res/xml/kbd_popup_narrow_template.xml27
-rw-r--r--java/res/xml/kbd_popup_template.xml27
-rw-r--r--java/res/xml/kbd_qwerty.xml527
-rw-r--r--java/res/xml/kbd_symbols.xml213
-rw-r--r--java/res/xml/kbd_symbols_shift.xml188
-rw-r--r--java/res/xml/language_prefs.xml19
-rw-r--r--java/res/xml/method.xml26
-rw-r--r--java/res/xml/popup_at.xml39
-rw-r--r--java/res/xml/popup_comma.xml39
-rw-r--r--java/res/xml/popup_domains.xml46
-rw-r--r--java/res/xml/popup_mic.xml40
-rw-r--r--java/res/xml/popup_punctuation.xml68
-rw-r--r--java/res/xml/popup_slash.xml39
-rw-r--r--java/res/xml/popup_smileys.xml89
-rw-r--r--java/res/xml/prefs.xml325
-rw-r--r--java/res/xml/prefs_actions.xml77
-rw-r--r--java/res/xml/prefs_feedback.xml71
-rw-r--r--java/res/xml/prefs_for_debug.xml45
-rw-r--r--java/res/xml/prefs_view.xml89
-rw-r--r--java/src/com/android/inputmethod/voice/FieldContext.java102
-rw-r--r--java/src/com/android/inputmethod/voice/RecognitionView.java323
-rw-r--r--java/src/com/android/inputmethod/voice/SettingsUtil.java113
-rw-r--r--java/src/com/android/inputmethod/voice/VoiceInput.java649
-rw-r--r--java/src/com/android/inputmethod/voice/VoiceInputLogger.java127
-rw-r--r--java/src/com/android/inputmethod/voice/WaveformImage.java90
-rw-r--r--java/src/com/android/inputmethod/voice/Whitelist.java67
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/AutoDictionary.java259
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/AutoSummaryEditTextPreference.java27
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/AutoSummaryListPreference.java53
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/BinaryDictionary.java287
-rwxr-xr-xjava/src/org/pocketworkstation/pckeyboard/CandidateView.java487
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/ComposeBase.java134
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/ComposeSequence.java910
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/ContactsDictionary.java152
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/DeadAccentSequence.java1063
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/Dictionary.java120
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/EditingUtil.java337
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/ExpandableDictionary.java691
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/GlobalKeyboardSettings.java266
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/Hints.java187
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/InputLanguageSelection.java367
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/KeyDetector.java112
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/Keyboard.java1314
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/KeyboardSwitcher.java685
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/LanguageSwitcher.java228
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/LatinIME.java3976
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/LatinIMEBackupAgent.java32
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/LatinIMEDebugSettings.java75
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/LatinIMESettings.java323
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/LatinIMEUtil.java166
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/LatinImeLogger.java70
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/LatinKeyboard.java967
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/LatinKeyboardBaseView.java1779
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/LatinKeyboardView.java650
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/Main.java92
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/MiniKeyboardKeyDetector.java59
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/ModifierKeyState.java46
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/NotificationReceiver.java29
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/PluginManager.java259
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/PointerTracker.java645
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/PrefScreenActions.java45
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/PrefScreenFeedback.java51
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/PrefScreenView.java59
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/ProximityKeyDetector.java86
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/SeekBarPreference.java166
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/SeekBarPreferenceString.java59
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/SharedPreferencesCompat.java53
-rwxr-xr-xjava/src/org/pocketworkstation/pckeyboard/Suggest.java544
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/SwipeTracker.java157
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/TextEntryState.java284
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/Tutorial.java244
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/UserBigramDictionary.java401
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/UserDictionary.java145
-rw-r--r--java/src/org/pocketworkstation/pckeyboard/WordComposer.java209
-rw-r--r--tests/Android.mk17
-rw-r--r--tests/AndroidManifest.xml33
-rw-r--r--tests/data/bigramlist.xml36
-rw-r--r--tests/data/wordlist.xml244
-rw-r--r--tests/res/raw/test.dictbin0 -> 2829 bytes
-rw-r--r--tests/res/raw/testtext.txt24
-rw-r--r--tests/src/com/android/inputmethod/latin/EventRingBufferTests.java154
-rw-r--r--tests/src/com/android/inputmethod/latin/SuggestHelper.java268
-rw-r--r--tests/src/com/android/inputmethod/latin/SuggestPerformanceTests.java126
-rw-r--r--tests/src/com/android/inputmethod/latin/SuggestTests.java172
-rw-r--r--tests/src/com/android/inputmethod/latin/UserBigramTests.java100
532 files changed, 58824 insertions, 0 deletions
diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..8f1acc5
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,17 @@
+# 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.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/CleanSpec.mk b/CleanSpec.mk
new file mode 100644
index 0000000..44ff0a2
--- /dev/null
+++ b/CleanSpec.mk
@@ -0,0 +1,53 @@
+# Copyright (C) 2007 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# If you don't need to do a full clean build but would like to touch
+# a file or delete some intermediate files, add a clean step to the end
+# of the list. These steps will only be run once, if they haven't been
+# run before.
+#
+# E.g.:
+# $(call add-clean-step, touch -c external/sqlite/sqlite3.h)
+# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)
+#
+# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with
+# files that are missing or have been moved.
+#
+# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory.
+# Use $(OUT_DIR) to refer to the "out" directory.
+#
+# If you need to re-do something that's already mentioned, just copy
+# the command and add it to the bottom of the list. E.g., if a change
+# that you made last week required touching a file and a change you
+# made today requires touching the same file, just copy the old
+# touch step and add it to the end of the list.
+#
+# ************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
+# ************************************************
+
+# For example:
+#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates)
+#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)
+#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
+#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
+
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/LatinIME*)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/app/LatinIME.apk)
+
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libjni_latinime_intermediates)
+# ************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
+# ************************************************
diff --git a/README-hackerskeyboard.txt b/README-hackerskeyboard.txt
new file mode 100644
index 0000000..ef8bb78
--- /dev/null
+++ b/README-hackerskeyboard.txt
@@ -0,0 +1,12 @@
+See http://code.google.com/p/hackerskeyboard/ for more details about
+this project.
+
+Build instructions:
+ http://code.google.com/p/hackerskeyboard/wiki/BuildingFromSource
+
+If you're planning to make changes that you intend to contribute to the
+project, please get in touch first, the code is currently in flux and
+there may be active refactorings that could break whatever you are
+working on.
+
+Project contact: pocketworkstation@gmail.com
diff --git a/dictionaries/sample.xml b/dictionaries/sample.xml
new file mode 100644
index 0000000..85233b6
--- /dev/null
+++ b/dictionaries/sample.xml
@@ -0,0 +1,16 @@
+<!-- This is a sample wordlist that can be converted to a binary dictionary
+ for use by the Latin IME.
+ The format of the word list is a flat list of word entries.
+ Each entry has a frequency between 255 and 0.
+ Highest frequency words get more weight in the prediction algorithm.
+ You can capitalize words that must always be capitalized, such as "January".
+ You can have a capitalized and a non-capitalized word as separate entries,
+ such as "robin" and "Robin".
+-->
+<wordlist>
+ <w f="255">this</w>
+ <w f="255">is</w>
+ <w f="128">sample</w>
+ <w f="1">wordlist</w>
+</wordlist>
+
diff --git a/java/Android.mk b/java/Android.mk
new file mode 100644
index 0000000..b9da275
--- /dev/null
+++ b/java/Android.mk
@@ -0,0 +1,22 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := PCKeyboard
+
+LOCAL_CERTIFICATE := shared
+
+LOCAL_JNI_SHARED_LIBRARIES := libjni_pckeyboard
+
+LOCAL_STATIC_JAVA_LIBRARIES := android-common
+
+#LOCAL_AAPT_FLAGS := -0 .dict
+
+LOCAL_SDK_VERSION := current
+
+LOCAL_PROGUARD_FLAG_FILES := proguard.flags
+
+include $(BUILD_PACKAGE)
diff --git a/java/AndroidManifest.xml b/java/AndroidManifest.xml
new file mode 100755
index 0000000..1b836f6
--- /dev/null
+++ b/java/AndroidManifest.xml
@@ -0,0 +1,86 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="org.pocketworkstation.pckeyboard" android:versionName="v1.34" android:versionCode="1034">
+
+ <uses-permission android:name="android.permission.VIBRATE"/>
+ <uses-permission android:name="android.permission.READ_USER_DICTIONARY" />
+ <uses-permission android:name="android.permission.WRITE_USER_DICTIONARY" />
+ <uses-permission android:name="android.permission.RECORD_AUDIO" />
+ <uses-permission android:name="android.permission.READ_CONTACTS" />
+ <uses-feature android:name="android.hardware.microphone" android:required="false" />
+ <uses-feature android:name="android.hardware.faketouch" android:required="false" />
+ <uses-feature android:name="android.hardware.touchscreen" android:required="false" />
+
+ <uses-sdk android:targetSdkVersion="11" android:minSdkVersion="8"></uses-sdk>
+
+ <application android:label="@string/english_ime_name"
+ android:backupAgent="LatinIMEBackupAgent"
+ android:restoreAnyVersion="true"
+ android:hardwareAccelerated="false"
+ android:killAfterRestore="false"
+ android:icon="@drawable/icon">
+
+ <service android:name="LatinIME"
+ android:label="@string/english_ime_name"
+ android:permission="android.permission.BIND_INPUT_METHOD">
+ <intent-filter>
+ <action android:name="android.view.InputMethod" />
+ </intent-filter>
+ <meta-data android:name="android.view.im" android:resource="@xml/method" />
+ </service>
+
+ <activity android:name="Main" android:label="Hacker's Keyboard">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
+ </intent-filter>
+ </activity>
+
+ <activity android:name="LatinIMESettings" android:label="@string/english_ime_settings">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ </intent-filter>
+ </activity>
+
+ <activity android:name="LatinIMEDebugSettings" android:label="@string/english_ime_debug_settings">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ </intent-filter>
+ </activity>
+
+ <activity android:name="InputLanguageSelection"
+ android:label="@string/language_selection_title">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <action android:name="org.pocketworkstation.pckeyboard.INPUT_LANGUAGE_SELECTION"/>
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name="PrefScreenActions"
+ android:label="@string/pref_screen_actions_title">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <action android:name="org.pocketworkstation.pckeyboard.PREFS_ACTIONS"/>
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name="PrefScreenView"
+ android:label="@string/pref_screen_actions_title">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <action android:name="org.pocketworkstation.pckeyboard.PREFS_VIEW"/>
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name="PrefScreenFeedback"
+ android:label="@string/pref_screen_feedback_title">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <action android:name="org.pocketworkstation.pckeyboard.PREFS_FEEDBACK"/>
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
+</application>
+</manifest>
diff --git a/java/AutoVersion.sh b/java/AutoVersion.sh
new file mode 100755
index 0000000..51112d5
--- /dev/null
+++ b/java/AutoVersion.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+# Use the fancy id generator if present, fall back to plain "hg id" if not.
+Id="$(Hg-ident)" 2>/dev/null
+[ -z "$Id" ] && Id="$(hg id)"
+
+Ver="$Id $(date +%Y-%m-%d)"
+
+# Create the auto-version file with this version string
+exec > res/values/auto-version.xml
+
+cat <<'EOF'
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Auto-generated file, do not edit -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+EOF
+echo ' <string name="auto_version">'"$Ver"'</string>'
+echo '</resources>'
diff --git a/java/CheckMap.pl b/java/CheckMap.pl
new file mode 100755
index 0000000..d190489
--- /dev/null
+++ b/java/CheckMap.pl
@@ -0,0 +1,178 @@
+#!/usr/bin/perl
+
+binmode(STDOUT, ":utf8");
+
+use Getopt::Std;
+getopts('c') || die;
+
+# Character used to display combining diacritics
+my $placeholder = "\x{25cc}"; # dotted circle
+#my $placeholder = "\x{25ab}"; # very small square
+#my $placeholder = " "; # space
+
+my %entities = (
+ 'amp' => '&',
+ 'lt' => '<',
+ 'gt' => '>',
+);
+
+sub expand_entity {
+ my $in = shift;
+ if ($entities{$in}) {
+ return $entities{$in};
+ }
+ if ($in =~ /^#x(\w+)$/) {
+ return chr(hex($1));
+ } elsif ($in =~ /^#(\d+)$/) {
+ return chr(0+$1);
+ } else {
+ return '[???]';
+ }
+}
+
+sub prefix_diacritic {
+ my $in = shift;
+ return $in if $in =~ /^[\040-\176]/;
+ #$in =~ s/^(\p{Diacritic})/$placeholder$1/;
+ $in =~ s/^(\p{BidiClass:NSM})/$placeholder$1/;
+ return $in;
+}
+
+my @std_map = (
+ ['key_tlde', 'key_ae01', 'key_ae02', 'key_ae03', 'key_ae04', 'key_ae05',
+ 'key_ae06', 'key_ae07', 'key_ae08', 'key_ae09', 'key_ae10', 'key_ae11',
+ 'key_ae12'],
+
+ ['key_ad01', 'key_ad02', 'key_ad03', 'key_ad04', 'key_ad05', 'key_ad06',
+ 'key_ad07', 'key_ad08', 'key_ad09', 'key_ad10', 'key_ad11', 'key_ad12',
+ 'key_bksl'],
+
+ ['key_ac01', 'key_ac02', 'key_ac03', 'key_ac04', 'key_ac05', 'key_ac06',
+ 'key_ac07', 'key_ac08', 'key_ac09', 'key_ac10', 'key_ac11'],
+
+ ['key_lsgt', 'key_ab01', 'key_ab02', 'key_ab03', 'key_ab04', 'key_ab05',
+ 'key_ab06', 'key_ab07', 'key_ab08', 'key_ab09', 'key_ab10'],
+);
+my %edge = (
+ 'key_ae12' => 1,
+ 'key_bksl' => 1,
+ 'key_ac11' => 1,
+);
+my %std_col = ();
+my %std_row = ();
+for (my $i = 0; $i < @std_map; ++$i) {
+ my @row = @{$std_map[$i]};
+ for (my $j = 0; $j < @row; ++$j) {
+ my $key = $row[$j];
+ $std_row{$key} = $i;
+ $std_col{$key} = $j;
+ }
+}
+
+sub read_strings {
+ my ($href, $file) = @_;
+
+ open(my $in, '<:utf8', $file) or die;
+ while (<$in>) {
+ #print;
+ if (/string\s+name="(.*)"\s*>(.*)</) {
+ my $name = $1;
+ my $chars = $2;
+ if ($chars =~ /\@string\/(\w+)/) {
+ $chars = $$href{$1};
+ } else {
+ print STDERR "ERROR: trailing backslash for $name; " if $chars =~ /[^\\]\\$/;
+ $chars =~ s/&(\#?\w+);/expand_entity($1)/eg;
+ $chars =~ s/\\(.)/$1/g; # Backslashes
+ }
+ $$href{$name} = $chars;
+ }
+ }
+ close $in;
+}
+
+sub main {
+ my %res = ();
+
+ foreach my $arg (@ARGV) {
+ read_strings(\%res, $arg);
+ }
+
+ my %found = ();
+ for (my $c = 33; $c < 127; ++$c) {
+ $found{chr($c)} = 0;
+ }
+
+ my $missing_digits = '';
+ my %keys = ();
+ foreach my $key (sort keys %res) {
+ next unless $key =~ /^key_/;
+ $keys{substr($key, 0, length('key_ae01'))} = 1;
+
+ my $chars = $res{$key};
+
+ ## Replace entities
+ #$chars =~ s/\&(\w+)\;/entities{$1}/eg;
+ ## Unescape backslashes
+ #$chars =~ s/\\(.)/$1/g;
+
+ for (my $i = 0; $i < length($chars); ++$i) {
+ my $char = substr($chars, $i, 1);
+ #print "$key $chars: char at $i = $char\n";
+ ++ $found{$char};
+ }
+ if ($key =~ /key_ad(\d(\d))_alt/) {
+ my $keynum = $1;
+ next if $keynum > 10;
+ my $digit = $2;
+ #print "Digit check: key=$key chars=$chars\n";
+ $missing_digits .= $digit unless $chars =~ /$digit/;
+ }
+ }
+
+ if ($opt_c) {
+ my $prev_row = 0;
+ for my $key (sort {
+ $std_row{$a} <=> $std_row{$b}
+ ||
+ $std_col{$a} <=> $std_col{$b}
+ ||
+ $a cmp $b
+ } keys %keys) {
+ my $row = $std_row{$key};
+ if ($row != $prev_row) {
+ print "\n";
+ $prev_row = $row;
+ }
+ my $main = $res{$key . '_main'};
+ my $shift = $res{$key . '_shift'};
+ my $alt = $res{$key . '_alt'};
+
+ $main = prefix_diacritic($main);
+ $shift = prefix_diacritic($shift);
+ my @alt_list = split('', $alt);
+ @alt_list = map { prefix_diacritic($_) } @alt_list;
+ my $alt_join = join(' ', @alt_list);
+
+ print "$key\t$main\t$shift\t$alt_join\n";
+ }
+ }
+
+ my $missing = '';
+ if ($missing_digits ne '') {
+ $missing .= "Digits '$missing_digits', ";
+ }
+
+ foreach my $c (sort keys %found) {
+ if ($found{$c} == 0) {
+ $missing .= $c;
+ }
+ }
+ if (length($missing) > 0) {
+ print STDERR "Missing: $missing\n";
+ } else {
+ print STDERR "All present.\n" unless $opt_c;
+ }
+}
+
+&main();
diff --git a/java/CheckMaps.sh b/java/CheckMaps.sh
new file mode 100755
index 0000000..93a75d1
--- /dev/null
+++ b/java/CheckMaps.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+Res=res/
+Alt=donottranslate-altchars.xml
+Map=donottranslate-keymap.xml
+
+Out=assets/kbd/
+mkdir -p "$Out"
+
+for Dir in res/values res/values-*
+do
+ [ -f $Dir/$Map ] || continue # -o -f $Dir/$Alt ] || continue
+ Args="$Res/values/$Alt"
+ [ -f $Dir/$Alt ] && Args="$Args $Dir/$Alt"
+ Args="$Args $Res/values/$Map"
+ [ -f $Dir/$Map ] && Args="$Args $Dir/$Map"
+ if [ -n "$CONVERT_MAPS" ]; then
+ Loc=$(echo "$Dir" | sed 's/res.values-*//; s/\/$//; s/^$/en/')
+ perl CheckMap.pl -c $Args > "$Out/map-full-$Loc.txt"
+ else
+ echo >&2 -n "$Dir: "
+ perl CheckMap.pl $Args
+ fi
+done
diff --git a/java/GetLanguages.sh b/java/GetLanguages.sh
new file mode 100755
index 0000000..d1efc03
--- /dev/null
+++ b/java/GetLanguages.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+
+getLangsForFiles () {
+ echo "en" # default language
+ for F in "$@"
+ do
+ find res/ -name "$F"
+ done \
+ | sed -n '
+ s/.*res.[a-z]*-\(..\)-r\(..\).*/\1_\2/p; # yy-rXX => yy_XX
+ s/.*res.[a-z]*-\(..\)\/.*/\1/p; # yy => yy
+ '
+}
+
+getLangsForDicts () {
+ ls ../Dicts \
+ | sed 's/.*-//; s/.dict//'
+}
+
+makeStrings () {
+ Name="$1"
+ shift
+ echo " private static final String[] $Name = {"
+ echo $(
+ for F in "$@"; do echo "$F"; done \
+ | sort -u
+ ) \
+ | sed 's/ /", "/g; s/^/"/; s/$/"/' \
+ | fmt -w 70 \
+ | sed 's/^/ /'
+ echo " };"
+ echo
+}
+
+LOCS=$(getLangsForFiles donottranslate-altchars.xml donottranslate-keymap.xml kbd_qwerty.xml strings.xml)
+DICTS=$(getLangsForDicts)
+
+makeStrings KBD_LOCALIZATIONS $LOCS $DICTS
+
+makeStrings KBD_5_ROW $(getLangsForFiles donottranslate-keymap.xml)
+
+makeStrings KBD_4_ROW $(getLangsForFiles kbd_qwerty.xml)
diff --git a/java/MODULE_LICENSE_APACHE2 b/java/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/java/MODULE_LICENSE_APACHE2
diff --git a/java/NOTICE b/java/NOTICE
new file mode 100644
index 0000000..7340b9e
--- /dev/null
+++ b/java/NOTICE
@@ -0,0 +1,190 @@
+
+ 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.
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
diff --git a/java/build.xml b/java/build.xml
new file mode 100644
index 0000000..2771d30
--- /dev/null
+++ b/java/build.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="hackerskeyboard" default="help">
+
+ <!-- The local.properties file is created and updated by the 'android' tool.
+ It contains the path to the SDK. It should *NOT* be checked into
+ Version Control Systems. -->
+ <loadproperties srcFile="local.properties" />
+
+ <!-- The ant.properties file can be created by you. It is only edited by the
+ 'android' tool to add properties to it.
+ This is the place to change some Ant specific build properties.
+ Here are some properties you may want to change/update:
+
+ source.dir
+ The name of the source directory. Default is 'src'.
+ out.dir
+ The name of the output directory. Default is 'bin'.
+
+ For other overridable properties, look at the beginning of the rules
+ files in the SDK, at tools/ant/build.xml
+
+ Properties related to the SDK location or the project target should
+ be updated using the 'android' tool with the 'update' action.
+
+ This file is an integral part of the build system for your
+ application and should be checked into Version Control Systems.
+
+ -->
+ <property file="ant.properties" />
+
+ <!-- The project.properties file is created and updated by the 'android'
+ tool, as well as ADT.
+
+ This contains project specific properties such as project target, and library
+ dependencies. Lower level build properties are stored in ant.properties
+ (or in .classpath for Eclipse projects).
+
+ This file is an integral part of the build system for your
+ application and should be checked into Version Control Systems. -->
+ <loadproperties srcFile="project.properties" />
+
+ <property file="private.properties" />
+
+ <!-- quick check on sdk.dir -->
+ <fail
+ message="sdk.dir is missing. Make sure to generate local.properties using 'android update project'"
+ unless="sdk.dir"
+ />
+
+
+<!-- extension targets. Uncomment the ones where you want to do custom work
+ in between standard targets -->
+ <target name="-pre-build">
+ <exec dir="." executable="./AutoVersion.sh">
+ </exec>
+ </target>
+<!--
+ <target name="-pre-compile">
+ </target>
+
+ /* This is typically used for code obfuscation.
+ Compiled code location: ${out.classes.absolute.dir}
+ If this is not done in place, override ${out.dex.input.absolute.dir} */
+ <target name="-post-compile">
+ </target>
+-->
+
+ <!-- Import the actual build file.
+
+ To customize existing targets, there are two options:
+ - Customize only one target:
+ - copy/paste the target into this file, *before* the
+ <import> task.
+ - customize it to your needs.
+ - Customize the whole content of build.xml
+ - copy/paste the content of the rules files (minus the top node)
+ into this file, replacing the <import> task.
+ - customize to your needs.
+
+ ***********************
+ ****** IMPORTANT ******
+ ***********************
+ In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
+ in order to avoid having your file be overridden by tools such as "android update project"
+ -->
+ <!-- version-tag: custom -->
+ <import file="${sdk.dir}/tools/ant/build.xml" />
+
+</project>
diff --git a/java/jni/Android.mk b/java/jni/Android.mk
new file mode 100644
index 0000000..9713638
--- /dev/null
+++ b/java/jni/Android.mk
@@ -0,0 +1,20 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/src
+
+LOCAL_SRC_FILES := \
+ jni/org_pocketworkstation_pckeyboard_BinaryDictionary.cpp \
+ src/dictionary.cpp \
+ src/char_utils.cpp
+
+#ifneq ($(TARGET_ARCH),x86)
+#LOCAL_NDK_VERSION := 4
+#LOCAL_SDK_VERSION := 8
+#endif
+
+LOCAL_MODULE := libjni_pckeyboard
+
+LOCAL_MODULE_TAGS := user
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/java/jni/Application.mk b/java/jni/Application.mk
new file mode 100644
index 0000000..a252a72
--- /dev/null
+++ b/java/jni/Application.mk
@@ -0,0 +1 @@
+APP_ABI := all
diff --git a/java/jni/jni/org_pocketworkstation_pckeyboard_BinaryDictionary.cpp b/java/jni/jni/org_pocketworkstation_pckeyboard_BinaryDictionary.cpp
new file mode 100644
index 0000000..fc81ed2
--- /dev/null
+++ b/java/jni/jni/org_pocketworkstation_pckeyboard_BinaryDictionary.cpp
@@ -0,0 +1,191 @@
+/*
+**
+** 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.
+*/
+
+#include <stdio.h>
+#include <assert.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <jni.h>
+#include "dictionary.h"
+
+// ----------------------------------------------------------------------------
+
+using namespace latinime;
+
+//
+// helper function to throw an exception
+//
+static void throwException(JNIEnv *env, const char* ex, const char* fmt, int data)
+{
+ if (jclass cls = env->FindClass(ex)) {
+ char msg[1000];
+ sprintf(msg, fmt, data);
+ env->ThrowNew(cls, msg);
+ env->DeleteLocalRef(cls);
+ }
+}
+
+static jint latinime_BinaryDictionary_open
+ (JNIEnv *env, jobject object, jobject dictDirectBuffer,
+ jint typedLetterMultiplier, jint fullWordMultiplier, jint size)
+{
+ void *dict = env->GetDirectBufferAddress(dictDirectBuffer);
+ if (dict == NULL) {
+ fprintf(stderr, "DICT: Dictionary buffer is null\n");
+ return 0;
+ }
+ Dictionary *dictionary = new Dictionary(dict, typedLetterMultiplier, fullWordMultiplier, size);
+ return (jint) dictionary;
+}
+
+static int latinime_BinaryDictionary_getSuggestions(
+ JNIEnv *env, jobject object, jint dict, jintArray inputArray, jint arraySize,
+ jcharArray outputArray, jintArray frequencyArray, jint maxWordLength, jint maxWords,
+ jint maxAlternatives, jint skipPos, jintArray nextLettersArray, jint nextLettersSize)
+{
+ Dictionary *dictionary = (Dictionary*) dict;
+ if (dictionary == NULL) return 0;
+
+ int *frequencies = env->GetIntArrayElements(frequencyArray, NULL);
+ int *inputCodes = env->GetIntArrayElements(inputArray, NULL);
+ jchar *outputChars = env->GetCharArrayElements(outputArray, NULL);
+ int *nextLetters = nextLettersArray != NULL ? env->GetIntArrayElements(nextLettersArray, NULL)
+ : NULL;
+
+ int count = dictionary->getSuggestions(inputCodes, arraySize, (unsigned short*) outputChars,
+ frequencies, maxWordLength, maxWords, maxAlternatives, skipPos, nextLetters,
+ nextLettersSize);
+
+ env->ReleaseIntArrayElements(frequencyArray, frequencies, 0);
+ env->ReleaseIntArrayElements(inputArray, inputCodes, JNI_ABORT);
+ env->ReleaseCharArrayElements(outputArray, outputChars, 0);
+ if (nextLetters) {
+ env->ReleaseIntArrayElements(nextLettersArray, nextLetters, 0);
+ }
+
+ return count;
+}
+
+static int latinime_BinaryDictionary_getBigrams
+ (JNIEnv *env, jobject object, jint dict, jcharArray prevWordArray, jint prevWordLength,
+ jintArray inputArray, jint inputArraySize, jcharArray outputArray,
+ jintArray frequencyArray, jint maxWordLength, jint maxBigrams, jint maxAlternatives)
+{
+ Dictionary *dictionary = (Dictionary*) dict;
+ if (dictionary == NULL) return 0;
+
+ jchar *prevWord = env->GetCharArrayElements(prevWordArray, NULL);
+ int *inputCodes = env->GetIntArrayElements(inputArray, NULL);
+ jchar *outputChars = env->GetCharArrayElements(outputArray, NULL);
+ int *frequencies = env->GetIntArrayElements(frequencyArray, NULL);
+
+ int count = dictionary->getBigrams((unsigned short*) prevWord, prevWordLength, inputCodes,
+ inputArraySize, (unsigned short*) outputChars, frequencies, maxWordLength, maxBigrams,
+ maxAlternatives);
+
+ env->ReleaseCharArrayElements(prevWordArray, prevWord, JNI_ABORT);
+ env->ReleaseIntArrayElements(inputArray, inputCodes, JNI_ABORT);
+ env->ReleaseCharArrayElements(outputArray, outputChars, 0);
+ env->ReleaseIntArrayElements(frequencyArray, frequencies, 0);
+
+ return count;
+}
+
+
+static jboolean latinime_BinaryDictionary_isValidWord
+ (JNIEnv *env, jobject object, jint dict, jcharArray wordArray, jint wordLength)
+{
+ Dictionary *dictionary = (Dictionary*) dict;
+ if (dictionary == NULL) return (jboolean) false;
+
+ jchar *word = env->GetCharArrayElements(wordArray, NULL);
+ jboolean result = dictionary->isValidWord((unsigned short*) word, wordLength);
+ env->ReleaseCharArrayElements(wordArray, word, JNI_ABORT);
+
+ return result;
+}
+
+static void latinime_BinaryDictionary_close
+ (JNIEnv *env, jobject object, jint dict)
+{
+ Dictionary *dictionary = (Dictionary*) dict;
+ delete (Dictionary*) dict;
+}
+
+// ----------------------------------------------------------------------------
+
+static JNINativeMethod gMethods[] = {
+ {"openNative", "(Ljava/nio/ByteBuffer;III)I",
+ (void*)latinime_BinaryDictionary_open},
+ {"closeNative", "(I)V", (void*)latinime_BinaryDictionary_close},
+ {"getSuggestionsNative", "(I[II[C[IIIII[II)I", (void*)latinime_BinaryDictionary_getSuggestions},
+ {"isValidWordNative", "(I[CI)Z", (void*)latinime_BinaryDictionary_isValidWord},
+ {"getBigramsNative", "(I[CI[II[C[IIII)I", (void*)latinime_BinaryDictionary_getBigrams}
+};
+
+static int registerNativeMethods(JNIEnv* env, const char* className,
+ JNINativeMethod* gMethods, int numMethods)
+{
+ jclass clazz;
+
+ clazz = env->FindClass(className);
+ if (clazz == NULL) {
+ fprintf(stderr,
+ "Native registration unable to find class '%s'\n", className);
+ return JNI_FALSE;
+ }
+ if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) {
+ fprintf(stderr, "RegisterNatives failed for '%s'\n", className);
+ return JNI_FALSE;
+ }
+
+ return JNI_TRUE;
+}
+
+static int registerNatives(JNIEnv *env)
+{
+ const char* const kClassPathName = "org/pocketworkstation/pckeyboard/BinaryDictionary";
+ return registerNativeMethods(env,
+ kClassPathName, gMethods, sizeof(gMethods) / sizeof(gMethods[0]));
+}
+
+/*
+ * Returns the JNI version on success, -1 on failure.
+ */
+jint JNI_OnLoad(JavaVM* vm, void* reserved)
+{
+ JNIEnv* env = NULL;
+ jint result = -1;
+
+ if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
+ fprintf(stderr, "ERROR: GetEnv failed\n");
+ goto bail;
+ }
+ assert(env != NULL);
+
+ if (!registerNatives(env)) {
+ fprintf(stderr, "ERROR: BinaryDictionary native registration failed\n");
+ goto bail;
+ }
+
+ /* success -- return valid version number */
+ result = JNI_VERSION_1_4;
+
+bail:
+ return result;
+}
diff --git a/java/jni/src/basechars.h b/java/jni/src/basechars.h
new file mode 100644
index 0000000..5a44066
--- /dev/null
+++ b/java/jni/src/basechars.h
@@ -0,0 +1,172 @@
+/**
+ * Table mapping most combined Latin, Greek, and Cyrillic characters
+ * to their base characters. If c is in range, BASE_CHARS[c] == c
+ * if c is not a combined character, or the base character if it
+ * is combined.
+ */
+static unsigned short BASE_CHARS[] = {
+ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
+ 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
+ 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
+ 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
+ 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
+ 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
+ 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
+ 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
+ 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
+ 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
+ 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
+ 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
+ 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
+ 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
+ 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
+ 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f,
+ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
+ 0x0020, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7,
+ 0x0020, 0x00a9, 0x0061, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x0020,
+ 0x00b0, 0x00b1, 0x0032, 0x0033, 0x0020, 0x03bc, 0x00b6, 0x00b7,
+ 0x0020, 0x0031, 0x006f, 0x00bb, 0x0031, 0x0031, 0x0033, 0x00bf,
+ 0x0041, 0x0041, 0x0041, 0x0041, 0x0041, 0x0041, 0x00c6, 0x0043,
+ 0x0045, 0x0045, 0x0045, 0x0045, 0x0049, 0x0049, 0x0049, 0x0049,
+ 0x00d0, 0x004e, 0x004f, 0x004f, 0x004f, 0x004f, 0x004f, 0x00d7,
+ 0x004f, 0x0055, 0x0055, 0x0055, 0x0055, 0x0059, 0x00de, 0x0073, // Manually changed d8 to 4f
+ // Manually changed df to 73
+ 0x0061, 0x0061, 0x0061, 0x0061, 0x0061, 0x0061, 0x00e6, 0x0063,
+ 0x0065, 0x0065, 0x0065, 0x0065, 0x0069, 0x0069, 0x0069, 0x0069,
+ 0x00f0, 0x006e, 0x006f, 0x006f, 0x006f, 0x006f, 0x006f, 0x00f7,
+ 0x006f, 0x0075, 0x0075, 0x0075, 0x0075, 0x0079, 0x00fe, 0x0079, // Manually changed f8 to 6f
+ 0x0041, 0x0061, 0x0041, 0x0061, 0x0041, 0x0061, 0x0043, 0x0063,
+ 0x0043, 0x0063, 0x0043, 0x0063, 0x0043, 0x0063, 0x0044, 0x0064,
+ 0x0110, 0x0111, 0x0045, 0x0065, 0x0045, 0x0065, 0x0045, 0x0065,
+ 0x0045, 0x0065, 0x0045, 0x0065, 0x0047, 0x0067, 0x0047, 0x0067,
+ 0x0047, 0x0067, 0x0047, 0x0067, 0x0048, 0x0068, 0x0126, 0x0127,
+ 0x0049, 0x0069, 0x0049, 0x0069, 0x0049, 0x0069, 0x0049, 0x0069,
+ 0x0049, 0x0131, 0x0049, 0x0069, 0x004a, 0x006a, 0x004b, 0x006b,
+ 0x0138, 0x004c, 0x006c, 0x004c, 0x006c, 0x004c, 0x006c, 0x004c,
+ 0x006c, 0x0141, 0x0142, 0x004e, 0x006e, 0x004e, 0x006e, 0x004e,
+ 0x006e, 0x02bc, 0x014a, 0x014b, 0x004f, 0x006f, 0x004f, 0x006f,
+ 0x004f, 0x006f, 0x0152, 0x0153, 0x0052, 0x0072, 0x0052, 0x0072,
+ 0x0052, 0x0072, 0x0053, 0x0073, 0x0053, 0x0073, 0x0053, 0x0073,
+ 0x0053, 0x0073, 0x0054, 0x0074, 0x0054, 0x0074, 0x0166, 0x0167,
+ 0x0055, 0x0075, 0x0055, 0x0075, 0x0055, 0x0075, 0x0055, 0x0075,
+ 0x0055, 0x0075, 0x0055, 0x0075, 0x0057, 0x0077, 0x0059, 0x0079,
+ 0x0059, 0x005a, 0x007a, 0x005a, 0x007a, 0x005a, 0x007a, 0x0073,
+ 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185, 0x0186, 0x0187,
+ 0x0188, 0x0189, 0x018a, 0x018b, 0x018c, 0x018d, 0x018e, 0x018f,
+ 0x0190, 0x0191, 0x0192, 0x0193, 0x0194, 0x0195, 0x0196, 0x0197,
+ 0x0198, 0x0199, 0x019a, 0x019b, 0x019c, 0x019d, 0x019e, 0x019f,
+ 0x004f, 0x006f, 0x01a2, 0x01a3, 0x01a4, 0x01a5, 0x01a6, 0x01a7,
+ 0x01a8, 0x01a9, 0x01aa, 0x01ab, 0x01ac, 0x01ad, 0x01ae, 0x0055,
+ 0x0075, 0x01b1, 0x01b2, 0x01b3, 0x01b4, 0x01b5, 0x01b6, 0x01b7,
+ 0x01b8, 0x01b9, 0x01ba, 0x01bb, 0x01bc, 0x01bd, 0x01be, 0x01bf,
+ 0x01c0, 0x01c1, 0x01c2, 0x01c3, 0x0044, 0x0044, 0x0064, 0x004c,
+ 0x004c, 0x006c, 0x004e, 0x004e, 0x006e, 0x0041, 0x0061, 0x0049,
+ 0x0069, 0x004f, 0x006f, 0x0055, 0x0075, 0x00dc, 0x00fc, 0x00dc,
+ 0x00fc, 0x00dc, 0x00fc, 0x00dc, 0x00fc, 0x01dd, 0x00c4, 0x00e4,
+ 0x0226, 0x0227, 0x00c6, 0x00e6, 0x01e4, 0x01e5, 0x0047, 0x0067,
+ 0x004b, 0x006b, 0x004f, 0x006f, 0x01ea, 0x01eb, 0x01b7, 0x0292,
+ 0x006a, 0x0044, 0x0044, 0x0064, 0x0047, 0x0067, 0x01f6, 0x01f7,
+ 0x004e, 0x006e, 0x00c5, 0x00e5, 0x00c6, 0x00e6, 0x00d8, 0x00f8,
+ 0x0041, 0x0061, 0x0041, 0x0061, 0x0045, 0x0065, 0x0045, 0x0065,
+ 0x0049, 0x0069, 0x0049, 0x0069, 0x004f, 0x006f, 0x004f, 0x006f,
+ 0x0052, 0x0072, 0x0052, 0x0072, 0x0055, 0x0075, 0x0055, 0x0075,
+ 0x0053, 0x0073, 0x0054, 0x0074, 0x021c, 0x021d, 0x0048, 0x0068,
+ 0x0220, 0x0221, 0x0222, 0x0223, 0x0224, 0x0225, 0x0041, 0x0061,
+ 0x0045, 0x0065, 0x00d6, 0x00f6, 0x00d5, 0x00f5, 0x004f, 0x006f,
+ 0x022e, 0x022f, 0x0059, 0x0079, 0x0234, 0x0235, 0x0236, 0x0237,
+ 0x0238, 0x0239, 0x023a, 0x023b, 0x023c, 0x023d, 0x023e, 0x023f,
+ 0x0240, 0x0241, 0x0242, 0x0243, 0x0244, 0x0245, 0x0246, 0x0247,
+ 0x0248, 0x0249, 0x024a, 0x024b, 0x024c, 0x024d, 0x024e, 0x024f,
+ 0x0250, 0x0251, 0x0252, 0x0253, 0x0254, 0x0255, 0x0256, 0x0257,
+ 0x0258, 0x0259, 0x025a, 0x025b, 0x025c, 0x025d, 0x025e, 0x025f,
+ 0x0260, 0x0261, 0x0262, 0x0263, 0x0264, 0x0265, 0x0266, 0x0267,
+ 0x0268, 0x0269, 0x026a, 0x026b, 0x026c, 0x026d, 0x026e, 0x026f,
+ 0x0270, 0x0271, 0x0272, 0x0273, 0x0274, 0x0275, 0x0276, 0x0277,
+ 0x0278, 0x0279, 0x027a, 0x027b, 0x027c, 0x027d, 0x027e, 0x027f,
+ 0x0280, 0x0281, 0x0282, 0x0283, 0x0284, 0x0285, 0x0286, 0x0287,
+ 0x0288, 0x0289, 0x028a, 0x028b, 0x028c, 0x028d, 0x028e, 0x028f,
+ 0x0290, 0x0291, 0x0292, 0x0293, 0x0294, 0x0295, 0x0296, 0x0297,
+ 0x0298, 0x0299, 0x029a, 0x029b, 0x029c, 0x029d, 0x029e, 0x029f,
+ 0x02a0, 0x02a1, 0x02a2, 0x02a3, 0x02a4, 0x02a5, 0x02a6, 0x02a7,
+ 0x02a8, 0x02a9, 0x02aa, 0x02ab, 0x02ac, 0x02ad, 0x02ae, 0x02af,
+ 0x0068, 0x0266, 0x006a, 0x0072, 0x0279, 0x027b, 0x0281, 0x0077,
+ 0x0079, 0x02b9, 0x02ba, 0x02bb, 0x02bc, 0x02bd, 0x02be, 0x02bf,
+ 0x02c0, 0x02c1, 0x02c2, 0x02c3, 0x02c4, 0x02c5, 0x02c6, 0x02c7,
+ 0x02c8, 0x02c9, 0x02ca, 0x02cb, 0x02cc, 0x02cd, 0x02ce, 0x02cf,
+ 0x02d0, 0x02d1, 0x02d2, 0x02d3, 0x02d4, 0x02d5, 0x02d6, 0x02d7,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x02de, 0x02df,
+ 0x0263, 0x006c, 0x0073, 0x0078, 0x0295, 0x02e5, 0x02e6, 0x02e7,
+ 0x02e8, 0x02e9, 0x02ea, 0x02eb, 0x02ec, 0x02ed, 0x02ee, 0x02ef,
+ 0x02f0, 0x02f1, 0x02f2, 0x02f3, 0x02f4, 0x02f5, 0x02f6, 0x02f7,
+ 0x02f8, 0x02f9, 0x02fa, 0x02fb, 0x02fc, 0x02fd, 0x02fe, 0x02ff,
+ 0x0300, 0x0301, 0x0302, 0x0303, 0x0304, 0x0305, 0x0306, 0x0307,
+ 0x0308, 0x0309, 0x030a, 0x030b, 0x030c, 0x030d, 0x030e, 0x030f,
+ 0x0310, 0x0311, 0x0312, 0x0313, 0x0314, 0x0315, 0x0316, 0x0317,
+ 0x0318, 0x0319, 0x031a, 0x031b, 0x031c, 0x031d, 0x031e, 0x031f,
+ 0x0320, 0x0321, 0x0322, 0x0323, 0x0324, 0x0325, 0x0326, 0x0327,
+ 0x0328, 0x0329, 0x032a, 0x032b, 0x032c, 0x032d, 0x032e, 0x032f,
+ 0x0330, 0x0331, 0x0332, 0x0333, 0x0334, 0x0335, 0x0336, 0x0337,
+ 0x0338, 0x0339, 0x033a, 0x033b, 0x033c, 0x033d, 0x033e, 0x033f,
+ 0x0300, 0x0301, 0x0342, 0x0313, 0x0308, 0x0345, 0x0346, 0x0347,
+ 0x0348, 0x0349, 0x034a, 0x034b, 0x034c, 0x034d, 0x034e, 0x034f,
+ 0x0350, 0x0351, 0x0352, 0x0353, 0x0354, 0x0355, 0x0356, 0x0357,
+ 0x0358, 0x0359, 0x035a, 0x035b, 0x035c, 0x035d, 0x035e, 0x035f,
+ 0x0360, 0x0361, 0x0362, 0x0363, 0x0364, 0x0365, 0x0366, 0x0367,
+ 0x0368, 0x0369, 0x036a, 0x036b, 0x036c, 0x036d, 0x036e, 0x036f,
+ 0x0370, 0x0371, 0x0372, 0x0373, 0x02b9, 0x0375, 0x0376, 0x0377,
+ 0x0378, 0x0379, 0x0020, 0x037b, 0x037c, 0x037d, 0x003b, 0x037f,
+ 0x0380, 0x0381, 0x0382, 0x0383, 0x0020, 0x00a8, 0x0391, 0x00b7,
+ 0x0395, 0x0397, 0x0399, 0x038b, 0x039f, 0x038d, 0x03a5, 0x03a9,
+ 0x03ca, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
+ 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f,
+ 0x03a0, 0x03a1, 0x03a2, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7,
+ 0x03a8, 0x03a9, 0x0399, 0x03a5, 0x03b1, 0x03b5, 0x03b7, 0x03b9,
+ 0x03cb, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7,
+ 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf,
+ 0x03c0, 0x03c1, 0x03c2, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7,
+ 0x03c8, 0x03c9, 0x03b9, 0x03c5, 0x03bf, 0x03c5, 0x03c9, 0x03cf,
+ 0x03b2, 0x03b8, 0x03a5, 0x03d2, 0x03d2, 0x03c6, 0x03c0, 0x03d7,
+ 0x03d8, 0x03d9, 0x03da, 0x03db, 0x03dc, 0x03dd, 0x03de, 0x03df,
+ 0x03e0, 0x03e1, 0x03e2, 0x03e3, 0x03e4, 0x03e5, 0x03e6, 0x03e7,
+ 0x03e8, 0x03e9, 0x03ea, 0x03eb, 0x03ec, 0x03ed, 0x03ee, 0x03ef,
+ 0x03ba, 0x03c1, 0x03c2, 0x03f3, 0x0398, 0x03b5, 0x03f6, 0x03f7,
+ 0x03f8, 0x03a3, 0x03fa, 0x03fb, 0x03fc, 0x03fd, 0x03fe, 0x03ff,
+ 0x0415, 0x0415, 0x0402, 0x0413, 0x0404, 0x0405, 0x0406, 0x0406,
+ 0x0408, 0x0409, 0x040a, 0x040b, 0x041a, 0x0418, 0x0423, 0x040f,
+ 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
+ 0x0418, 0x0418, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f,
+ 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
+ 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f,
+ 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
+ 0x0438, 0x0438, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f,
+ 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
+ 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f,
+ 0x0435, 0x0435, 0x0452, 0x0433, 0x0454, 0x0455, 0x0456, 0x0456,
+ 0x0458, 0x0459, 0x045a, 0x045b, 0x043a, 0x0438, 0x0443, 0x045f,
+ 0x0460, 0x0461, 0x0462, 0x0463, 0x0464, 0x0465, 0x0466, 0x0467,
+ 0x0468, 0x0469, 0x046a, 0x046b, 0x046c, 0x046d, 0x046e, 0x046f,
+ 0x0470, 0x0471, 0x0472, 0x0473, 0x0474, 0x0475, 0x0474, 0x0475,
+ 0x0478, 0x0479, 0x047a, 0x047b, 0x047c, 0x047d, 0x047e, 0x047f,
+ 0x0480, 0x0481, 0x0482, 0x0483, 0x0484, 0x0485, 0x0486, 0x0487,
+ 0x0488, 0x0489, 0x048a, 0x048b, 0x048c, 0x048d, 0x048e, 0x048f,
+ 0x0490, 0x0491, 0x0492, 0x0493, 0x0494, 0x0495, 0x0496, 0x0497,
+ 0x0498, 0x0499, 0x049a, 0x049b, 0x049c, 0x049d, 0x049e, 0x049f,
+ 0x04a0, 0x04a1, 0x04a2, 0x04a3, 0x04a4, 0x04a5, 0x04a6, 0x04a7,
+ 0x04a8, 0x04a9, 0x04aa, 0x04ab, 0x04ac, 0x04ad, 0x04ae, 0x04af,
+ 0x04b0, 0x04b1, 0x04b2, 0x04b3, 0x04b4, 0x04b5, 0x04b6, 0x04b7,
+ 0x04b8, 0x04b9, 0x04ba, 0x04bb, 0x04bc, 0x04bd, 0x04be, 0x04bf,
+ 0x04c0, 0x0416, 0x0436, 0x04c3, 0x04c4, 0x04c5, 0x04c6, 0x04c7,
+ 0x04c8, 0x04c9, 0x04ca, 0x04cb, 0x04cc, 0x04cd, 0x04ce, 0x04cf,
+ 0x0410, 0x0430, 0x0410, 0x0430, 0x04d4, 0x04d5, 0x0415, 0x0435,
+ 0x04d8, 0x04d9, 0x04d8, 0x04d9, 0x0416, 0x0436, 0x0417, 0x0437,
+ 0x04e0, 0x04e1, 0x0418, 0x0438, 0x0418, 0x0438, 0x041e, 0x043e,
+ 0x04e8, 0x04e9, 0x04e8, 0x04e9, 0x042d, 0x044d, 0x0423, 0x0443,
+ 0x0423, 0x0443, 0x0423, 0x0443, 0x0427, 0x0447, 0x04f6, 0x04f7,
+ 0x042b, 0x044b, 0x04fa, 0x04fb, 0x04fc, 0x04fd, 0x04fe, 0x04ff,
+};
+
+// generated with:
+// cat UnicodeData.txt | perl -e 'while (<>) { @foo = split(/;/); $foo[5] =~ s/<.*> //; $base[hex($foo[0])] = hex($foo[5]);} for ($i = 0; $i < 0x500; $i += 8) { for ($j = $i; $j < $i + 8; $j++) { printf("0x%04x, ", $base[$j] ? $base[$j] : $j)}; print "\n"; }'
diff --git a/java/jni/src/char_utils.cpp b/java/jni/src/char_utils.cpp
new file mode 100644
index 0000000..a31a063
--- /dev/null
+++ b/java/jni/src/char_utils.cpp
@@ -0,0 +1,899 @@
+/*
+ * 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.
+ */
+
+#include <stdlib.h>
+
+namespace latinime {
+
+struct LatinCapitalSmallPair {
+ unsigned short capital;
+ unsigned short small;
+};
+
+// Generated from http://unicode.org/Public/UNIDATA/UnicodeData.txt
+//
+// 1. Run the following code. Bascially taken from
+// Dictionary::toLowerCase(unsigned short c) in dictionary.cpp.
+// Then, get the list of chars where cc != ccc.
+//
+// unsigned short c, cc, ccc, ccc2;
+// for (c = 0; c < 0xFFFF ; c++) {
+// if (c < sizeof(BASE_CHARS) / sizeof(BASE_CHARS[0])) {
+// cc = BASE_CHARS[c];
+// } else {
+// cc = c;
+// }
+//
+// // tolower
+// int isBase = 0;
+// if (cc >='A' && cc <= 'Z') {
+// ccc = (cc | 0x20);
+// ccc2 = ccc;
+// isBase = 1;
+// } else if (cc > 0x7F) {
+// ccc = u_tolower(cc);
+// ccc2 = latin_tolower(cc);
+// } else {
+// ccc = cc;
+// ccc2 = ccc;
+// }
+// if (!isBase && cc != ccc) {
+// wprintf(L" 0x%04X => 0x%04X => 0x%04X %lc => %lc => %lc \n",
+// c, cc, ccc, c, cc, ccc);
+// //assert(ccc == ccc2);
+// }
+// }
+//
+// Initially, started with an empty latin_tolower() as below.
+//
+// unsigned short latin_tolower(unsigned short c) {
+// return c;
+// }
+//
+//
+// 2. Process the list obtained by 1 by the following perl script and apply
+// 'sort -u' as well. Get the SORTED_CHAR_MAP[].
+// Note that '$1' in the perl script is 'cc' in the above C code.
+//
+// while(<>) {
+// / 0x\w* => 0x(\w*) =/;
+// open(HDL, "grep -iw ^" . $1 . " UnicodeData.txt | ");
+// $line = <HDL>;
+// chomp $line;
+// @cols = split(/;/, $line);
+// print " { 0x$1, 0x$cols[13] }, // $cols[1]\n";
+// }
+//
+//
+// 3. Update the latin_tolower() function above with SORTED_CHAR_MAP. Enable
+// the assert(ccc == ccc2) above and confirm the function exits successfully.
+//
+static const struct LatinCapitalSmallPair SORTED_CHAR_MAP[] = {
+ { 0x00C4, 0x00E4 }, // LATIN CAPITAL LETTER A WITH DIAERESIS
+ { 0x00C5, 0x00E5 }, // LATIN CAPITAL LETTER A WITH RING ABOVE
+ { 0x00C6, 0x00E6 }, // LATIN CAPITAL LETTER AE
+ { 0x00D0, 0x00F0 }, // LATIN CAPITAL LETTER ETH
+ { 0x00D5, 0x00F5 }, // LATIN CAPITAL LETTER O WITH TILDE
+ { 0x00D6, 0x00F6 }, // LATIN CAPITAL LETTER O WITH DIAERESIS
+ { 0x00D8, 0x00F8 }, // LATIN CAPITAL LETTER O WITH STROKE
+ { 0x00DC, 0x00FC }, // LATIN CAPITAL LETTER U WITH DIAERESIS
+ { 0x00DE, 0x00FE }, // LATIN CAPITAL LETTER THORN
+ { 0x0110, 0x0111 }, // LATIN CAPITAL LETTER D WITH STROKE
+ { 0x0126, 0x0127 }, // LATIN CAPITAL LETTER H WITH STROKE
+ { 0x0141, 0x0142 }, // LATIN CAPITAL LETTER L WITH STROKE
+ { 0x014A, 0x014B }, // LATIN CAPITAL LETTER ENG
+ { 0x0152, 0x0153 }, // LATIN CAPITAL LIGATURE OE
+ { 0x0166, 0x0167 }, // LATIN CAPITAL LETTER T WITH STROKE
+ { 0x0181, 0x0253 }, // LATIN CAPITAL LETTER B WITH HOOK
+ { 0x0182, 0x0183 }, // LATIN CAPITAL LETTER B WITH TOPBAR
+ { 0x0184, 0x0185 }, // LATIN CAPITAL LETTER TONE SIX
+ { 0x0186, 0x0254 }, // LATIN CAPITAL LETTER OPEN O
+ { 0x0187, 0x0188 }, // LATIN CAPITAL LETTER C WITH HOOK
+ { 0x0189, 0x0256 }, // LATIN CAPITAL LETTER AFRICAN D
+ { 0x018A, 0x0257 }, // LATIN CAPITAL LETTER D WITH HOOK
+ { 0x018B, 0x018C }, // LATIN CAPITAL LETTER D WITH TOPBAR
+ { 0x018E, 0x01DD }, // LATIN CAPITAL LETTER REVERSED E
+ { 0x018F, 0x0259 }, // LATIN CAPITAL LETTER SCHWA
+ { 0x0190, 0x025B }, // LATIN CAPITAL LETTER OPEN E
+ { 0x0191, 0x0192 }, // LATIN CAPITAL LETTER F WITH HOOK
+ { 0x0193, 0x0260 }, // LATIN CAPITAL LETTER G WITH HOOK
+ { 0x0194, 0x0263 }, // LATIN CAPITAL LETTER GAMMA
+ { 0x0196, 0x0269 }, // LATIN CAPITAL LETTER IOTA
+ { 0x0197, 0x0268 }, // LATIN CAPITAL LETTER I WITH STROKE
+ { 0x0198, 0x0199 }, // LATIN CAPITAL LETTER K WITH HOOK
+ { 0x019C, 0x026F }, // LATIN CAPITAL LETTER TURNED M
+ { 0x019D, 0x0272 }, // LATIN CAPITAL LETTER N WITH LEFT HOOK
+ { 0x019F, 0x0275 }, // LATIN CAPITAL LETTER O WITH MIDDLE TILDE
+ { 0x01A2, 0x01A3 }, // LATIN CAPITAL LETTER OI
+ { 0x01A4, 0x01A5 }, // LATIN CAPITAL LETTER P WITH HOOK
+ { 0x01A6, 0x0280 }, // LATIN LETTER YR
+ { 0x01A7, 0x01A8 }, // LATIN CAPITAL LETTER TONE TWO
+ { 0x01A9, 0x0283 }, // LATIN CAPITAL LETTER ESH
+ { 0x01AC, 0x01AD }, // LATIN CAPITAL LETTER T WITH HOOK
+ { 0x01AE, 0x0288 }, // LATIN CAPITAL LETTER T WITH RETROFLEX HOOK
+ { 0x01B1, 0x028A }, // LATIN CAPITAL LETTER UPSILON
+ { 0x01B2, 0x028B }, // LATIN CAPITAL LETTER V WITH HOOK
+ { 0x01B3, 0x01B4 }, // LATIN CAPITAL LETTER Y WITH HOOK
+ { 0x01B5, 0x01B6 }, // LATIN CAPITAL LETTER Z WITH STROKE
+ { 0x01B7, 0x0292 }, // LATIN CAPITAL LETTER EZH
+ { 0x01B8, 0x01B9 }, // LATIN CAPITAL LETTER EZH REVERSED
+ { 0x01BC, 0x01BD }, // LATIN CAPITAL LETTER TONE FIVE
+ { 0x01E4, 0x01E5 }, // LATIN CAPITAL LETTER G WITH STROKE
+ { 0x01EA, 0x01EB }, // LATIN CAPITAL LETTER O WITH OGONEK
+ { 0x01F6, 0x0195 }, // LATIN CAPITAL LETTER HWAIR
+ { 0x01F7, 0x01BF }, // LATIN CAPITAL LETTER WYNN
+ { 0x021C, 0x021D }, // LATIN CAPITAL LETTER YOGH
+ { 0x0220, 0x019E }, // LATIN CAPITAL LETTER N WITH LONG RIGHT LEG
+ { 0x0222, 0x0223 }, // LATIN CAPITAL LETTER OU
+ { 0x0224, 0x0225 }, // LATIN CAPITAL LETTER Z WITH HOOK
+ { 0x0226, 0x0227 }, // LATIN CAPITAL LETTER A WITH DOT ABOVE
+ { 0x022E, 0x022F }, // LATIN CAPITAL LETTER O WITH DOT ABOVE
+ { 0x023A, 0x2C65 }, // LATIN CAPITAL LETTER A WITH STROKE
+ { 0x023B, 0x023C }, // LATIN CAPITAL LETTER C WITH STROKE
+ { 0x023D, 0x019A }, // LATIN CAPITAL LETTER L WITH BAR
+ { 0x023E, 0x2C66 }, // LATIN CAPITAL LETTER T WITH DIAGONAL STROKE
+ { 0x0241, 0x0242 }, // LATIN CAPITAL LETTER GLOTTAL STOP
+ { 0x0243, 0x0180 }, // LATIN CAPITAL LETTER B WITH STROKE
+ { 0x0244, 0x0289 }, // LATIN CAPITAL LETTER U BAR
+ { 0x0245, 0x028C }, // LATIN CAPITAL LETTER TURNED V
+ { 0x0246, 0x0247 }, // LATIN CAPITAL LETTER E WITH STROKE
+ { 0x0248, 0x0249 }, // LATIN CAPITAL LETTER J WITH STROKE
+ { 0x024A, 0x024B }, // LATIN CAPITAL LETTER SMALL Q WITH HOOK TAIL
+ { 0x024C, 0x024D }, // LATIN CAPITAL LETTER R WITH STROKE
+ { 0x024E, 0x024F }, // LATIN CAPITAL LETTER Y WITH STROKE
+ { 0x0370, 0x0371 }, // GREEK CAPITAL LETTER HETA
+ { 0x0372, 0x0373 }, // GREEK CAPITAL LETTER ARCHAIC SAMPI
+ { 0x0376, 0x0377 }, // GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA
+ { 0x0391, 0x03B1 }, // GREEK CAPITAL LETTER ALPHA
+ { 0x0392, 0x03B2 }, // GREEK CAPITAL LETTER BETA
+ { 0x0393, 0x03B3 }, // GREEK CAPITAL LETTER GAMMA
+ { 0x0394, 0x03B4 }, // GREEK CAPITAL LETTER DELTA
+ { 0x0395, 0x03B5 }, // GREEK CAPITAL LETTER EPSILON
+ { 0x0396, 0x03B6 }, // GREEK CAPITAL LETTER ZETA
+ { 0x0397, 0x03B7 }, // GREEK CAPITAL LETTER ETA
+ { 0x0398, 0x03B8 }, // GREEK CAPITAL LETTER THETA
+ { 0x0399, 0x03B9 }, // GREEK CAPITAL LETTER IOTA
+ { 0x039A, 0x03BA }, // GREEK CAPITAL LETTER KAPPA
+ { 0x039B, 0x03BB }, // GREEK CAPITAL LETTER LAMDA
+ { 0x039C, 0x03BC }, // GREEK CAPITAL LETTER MU
+ { 0x039D, 0x03BD }, // GREEK CAPITAL LETTER NU
+ { 0x039E, 0x03BE }, // GREEK CAPITAL LETTER XI
+ { 0x039F, 0x03BF }, // GREEK CAPITAL LETTER OMICRON
+ { 0x03A0, 0x03C0 }, // GREEK CAPITAL LETTER PI
+ { 0x03A1, 0x03C1 }, // GREEK CAPITAL LETTER RHO
+ { 0x03A3, 0x03C3 }, // GREEK CAPITAL LETTER SIGMA
+ { 0x03A4, 0x03C4 }, // GREEK CAPITAL LETTER TAU
+ { 0x03A5, 0x03C5 }, // GREEK CAPITAL LETTER UPSILON
+ { 0x03A6, 0x03C6 }, // GREEK CAPITAL LETTER PHI
+ { 0x03A7, 0x03C7 }, // GREEK CAPITAL LETTER CHI
+ { 0x03A8, 0x03C8 }, // GREEK CAPITAL LETTER PSI
+ { 0x03A9, 0x03C9 }, // GREEK CAPITAL LETTER OMEGA
+ { 0x03CF, 0x03D7 }, // GREEK CAPITAL KAI SYMBOL
+ { 0x03D8, 0x03D9 }, // GREEK LETTER ARCHAIC KOPPA
+ { 0x03DA, 0x03DB }, // GREEK LETTER STIGMA
+ { 0x03DC, 0x03DD }, // GREEK LETTER DIGAMMA
+ { 0x03DE, 0x03DF }, // GREEK LETTER KOPPA
+ { 0x03E0, 0x03E1 }, // GREEK LETTER SAMPI
+ { 0x03E2, 0x03E3 }, // COPTIC CAPITAL LETTER SHEI
+ { 0x03E4, 0x03E5 }, // COPTIC CAPITAL LETTER FEI
+ { 0x03E6, 0x03E7 }, // COPTIC CAPITAL LETTER KHEI
+ { 0x03E8, 0x03E9 }, // COPTIC CAPITAL LETTER HORI
+ { 0x03EA, 0x03EB }, // COPTIC CAPITAL LETTER GANGIA
+ { 0x03EC, 0x03ED }, // COPTIC CAPITAL LETTER SHIMA
+ { 0x03EE, 0x03EF }, // COPTIC CAPITAL LETTER DEI
+ { 0x03F7, 0x03F8 }, // GREEK CAPITAL LETTER SHO
+ { 0x03FA, 0x03FB }, // GREEK CAPITAL LETTER SAN
+ { 0x03FD, 0x037B }, // GREEK CAPITAL REVERSED LUNATE SIGMA SYMBOL
+ { 0x03FE, 0x037C }, // GREEK CAPITAL DOTTED LUNATE SIGMA SYMBOL
+ { 0x03FF, 0x037D }, // GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL
+ { 0x0402, 0x0452 }, // CYRILLIC CAPITAL LETTER DJE
+ { 0x0404, 0x0454 }, // CYRILLIC CAPITAL LETTER UKRAINIAN IE
+ { 0x0405, 0x0455 }, // CYRILLIC CAPITAL LETTER DZE
+ { 0x0406, 0x0456 }, // CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
+ { 0x0408, 0x0458 }, // CYRILLIC CAPITAL LETTER JE
+ { 0x0409, 0x0459 }, // CYRILLIC CAPITAL LETTER LJE
+ { 0x040A, 0x045A }, // CYRILLIC CAPITAL LETTER NJE
+ { 0x040B, 0x045B }, // CYRILLIC CAPITAL LETTER TSHE
+ { 0x040F, 0x045F }, // CYRILLIC CAPITAL LETTER DZHE
+ { 0x0410, 0x0430 }, // CYRILLIC CAPITAL LETTER A
+ { 0x0411, 0x0431 }, // CYRILLIC CAPITAL LETTER BE
+ { 0x0412, 0x0432 }, // CYRILLIC CAPITAL LETTER VE
+ { 0x0413, 0x0433 }, // CYRILLIC CAPITAL LETTER GHE
+ { 0x0414, 0x0434 }, // CYRILLIC CAPITAL LETTER DE
+ { 0x0415, 0x0435 }, // CYRILLIC CAPITAL LETTER IE
+ { 0x0416, 0x0436 }, // CYRILLIC CAPITAL LETTER ZHE
+ { 0x0417, 0x0437 }, // CYRILLIC CAPITAL LETTER ZE
+ { 0x0418, 0x0438 }, // CYRILLIC CAPITAL LETTER I
+ { 0x041A, 0x043A }, // CYRILLIC CAPITAL LETTER KA
+ { 0x041B, 0x043B }, // CYRILLIC CAPITAL LETTER EL
+ { 0x041C, 0x043C }, // CYRILLIC CAPITAL LETTER EM
+ { 0x041D, 0x043D }, // CYRILLIC CAPITAL LETTER EN
+ { 0x041E, 0x043E }, // CYRILLIC CAPITAL LETTER O
+ { 0x041F, 0x043F }, // CYRILLIC CAPITAL LETTER PE
+ { 0x0420, 0x0440 }, // CYRILLIC CAPITAL LETTER ER
+ { 0x0421, 0x0441 }, // CYRILLIC CAPITAL LETTER ES
+ { 0x0422, 0x0442 }, // CYRILLIC CAPITAL LETTER TE
+ { 0x0423, 0x0443 }, // CYRILLIC CAPITAL LETTER U
+ { 0x0424, 0x0444 }, // CYRILLIC CAPITAL LETTER EF
+ { 0x0425, 0x0445 }, // CYRILLIC CAPITAL LETTER HA
+ { 0x0426, 0x0446 }, // CYRILLIC CAPITAL LETTER TSE
+ { 0x0427, 0x0447 }, // CYRILLIC CAPITAL LETTER CHE
+ { 0x0428, 0x0448 }, // CYRILLIC CAPITAL LETTER SHA
+ { 0x0429, 0x0449 }, // CYRILLIC CAPITAL LETTER SHCHA
+ { 0x042A, 0x044A }, // CYRILLIC CAPITAL LETTER HARD SIGN
+ { 0x042B, 0x044B }, // CYRILLIC CAPITAL LETTER YERU
+ { 0x042C, 0x044C }, // CYRILLIC CAPITAL LETTER SOFT SIGN
+ { 0x042D, 0x044D }, // CYRILLIC CAPITAL LETTER E
+ { 0x042E, 0x044E }, // CYRILLIC CAPITAL LETTER YU
+ { 0x042F, 0x044F }, // CYRILLIC CAPITAL LETTER YA
+ { 0x0460, 0x0461 }, // CYRILLIC CAPITAL LETTER OMEGA
+ { 0x0462, 0x0463 }, // CYRILLIC CAPITAL LETTER YAT
+ { 0x0464, 0x0465 }, // CYRILLIC CAPITAL LETTER IOTIFIED E
+ { 0x0466, 0x0467 }, // CYRILLIC CAPITAL LETTER LITTLE YUS
+ { 0x0468, 0x0469 }, // CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS
+ { 0x046A, 0x046B }, // CYRILLIC CAPITAL LETTER BIG YUS
+ { 0x046C, 0x046D }, // CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS
+ { 0x046E, 0x046F }, // CYRILLIC CAPITAL LETTER KSI
+ { 0x0470, 0x0471 }, // CYRILLIC CAPITAL LETTER PSI
+ { 0x0472, 0x0473 }, // CYRILLIC CAPITAL LETTER FITA
+ { 0x0474, 0x0475 }, // CYRILLIC CAPITAL LETTER IZHITSA
+ { 0x0478, 0x0479 }, // CYRILLIC CAPITAL LETTER UK
+ { 0x047A, 0x047B }, // CYRILLIC CAPITAL LETTER ROUND OMEGA
+ { 0x047C, 0x047D }, // CYRILLIC CAPITAL LETTER OMEGA WITH TITLO
+ { 0x047E, 0x047F }, // CYRILLIC CAPITAL LETTER OT
+ { 0x0480, 0x0481 }, // CYRILLIC CAPITAL LETTER KOPPA
+ { 0x048A, 0x048B }, // CYRILLIC CAPITAL LETTER SHORT I WITH TAIL
+ { 0x048C, 0x048D }, // CYRILLIC CAPITAL LETTER SEMISOFT SIGN
+ { 0x048E, 0x048F }, // CYRILLIC CAPITAL LETTER ER WITH TICK
+ { 0x0490, 0x0491 }, // CYRILLIC CAPITAL LETTER GHE WITH UPTURN
+ { 0x0492, 0x0493 }, // CYRILLIC CAPITAL LETTER GHE WITH STROKE
+ { 0x0494, 0x0495 }, // CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK
+ { 0x0496, 0x0497 }, // CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER
+ { 0x0498, 0x0499 }, // CYRILLIC CAPITAL LETTER ZE WITH DESCENDER
+ { 0x049A, 0x049B }, // CYRILLIC CAPITAL LETTER KA WITH DESCENDER
+ { 0x049C, 0x049D }, // CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE
+ { 0x049E, 0x049F }, // CYRILLIC CAPITAL LETTER KA WITH STROKE
+ { 0x04A0, 0x04A1 }, // CYRILLIC CAPITAL LETTER BASHKIR KA
+ { 0x04A2, 0x04A3 }, // CYRILLIC CAPITAL LETTER EN WITH DESCENDER
+ { 0x04A4, 0x04A5 }, // CYRILLIC CAPITAL LIGATURE EN GHE
+ { 0x04A6, 0x04A7 }, // CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK
+ { 0x04A8, 0x04A9 }, // CYRILLIC CAPITAL LETTER ABKHASIAN HA
+ { 0x04AA, 0x04AB }, // CYRILLIC CAPITAL LETTER ES WITH DESCENDER
+ { 0x04AC, 0x04AD }, // CYRILLIC CAPITAL LETTER TE WITH DESCENDER
+ { 0x04AE, 0x04AF }, // CYRILLIC CAPITAL LETTER STRAIGHT U
+ { 0x04B0, 0x04B1 }, // CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE
+ { 0x04B2, 0x04B3 }, // CYRILLIC CAPITAL LETTER HA WITH DESCENDER
+ { 0x04B4, 0x04B5 }, // CYRILLIC CAPITAL LIGATURE TE TSE
+ { 0x04B6, 0x04B7 }, // CYRILLIC CAPITAL LETTER CHE WITH DESCENDER
+ { 0x04B8, 0x04B9 }, // CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE
+ { 0x04BA, 0x04BB }, // CYRILLIC CAPITAL LETTER SHHA
+ { 0x04BC, 0x04BD }, // CYRILLIC CAPITAL LETTER ABKHASIAN CHE
+ { 0x04BE, 0x04BF }, // CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER
+ { 0x04C0, 0x04CF }, // CYRILLIC LETTER PALOCHKA
+ { 0x04C3, 0x04C4 }, // CYRILLIC CAPITAL LETTER KA WITH HOOK
+ { 0x04C5, 0x04C6 }, // CYRILLIC CAPITAL LETTER EL WITH TAIL
+ { 0x04C7, 0x04C8 }, // CYRILLIC CAPITAL LETTER EN WITH HOOK
+ { 0x04C9, 0x04CA }, // CYRILLIC CAPITAL LETTER EN WITH TAIL
+ { 0x04CB, 0x04CC }, // CYRILLIC CAPITAL LETTER KHAKASSIAN CHE
+ { 0x04CD, 0x04CE }, // CYRILLIC CAPITAL LETTER EM WITH TAIL
+ { 0x04D4, 0x04D5 }, // CYRILLIC CAPITAL LIGATURE A IE
+ { 0x04D8, 0x04D9 }, // CYRILLIC CAPITAL LETTER SCHWA
+ { 0x04E0, 0x04E1 }, // CYRILLIC CAPITAL LETTER ABKHASIAN DZE
+ { 0x04E8, 0x04E9 }, // CYRILLIC CAPITAL LETTER BARRED O
+ { 0x04F6, 0x04F7 }, // CYRILLIC CAPITAL LETTER GHE WITH DESCENDER
+ { 0x04FA, 0x04FB }, // CYRILLIC CAPITAL LETTER GHE WITH STROKE AND HOOK
+ { 0x04FC, 0x04FD }, // CYRILLIC CAPITAL LETTER HA WITH HOOK
+ { 0x04FE, 0x04FF }, // CYRILLIC CAPITAL LETTER HA WITH STROKE
+ { 0x0500, 0x0501 }, // CYRILLIC CAPITAL LETTER KOMI DE
+ { 0x0502, 0x0503 }, // CYRILLIC CAPITAL LETTER KOMI DJE
+ { 0x0504, 0x0505 }, // CYRILLIC CAPITAL LETTER KOMI ZJE
+ { 0x0506, 0x0507 }, // CYRILLIC CAPITAL LETTER KOMI DZJE
+ { 0x0508, 0x0509 }, // CYRILLIC CAPITAL LETTER KOMI LJE
+ { 0x050A, 0x050B }, // CYRILLIC CAPITAL LETTER KOMI NJE
+ { 0x050C, 0x050D }, // CYRILLIC CAPITAL LETTER KOMI SJE
+ { 0x050E, 0x050F }, // CYRILLIC CAPITAL LETTER KOMI TJE
+ { 0x0510, 0x0511 }, // CYRILLIC CAPITAL LETTER REVERSED ZE
+ { 0x0512, 0x0513 }, // CYRILLIC CAPITAL LETTER EL WITH HOOK
+ { 0x0514, 0x0515 }, // CYRILLIC CAPITAL LETTER LHA
+ { 0x0516, 0x0517 }, // CYRILLIC CAPITAL LETTER RHA
+ { 0x0518, 0x0519 }, // CYRILLIC CAPITAL LETTER YAE
+ { 0x051A, 0x051B }, // CYRILLIC CAPITAL LETTER QA
+ { 0x051C, 0x051D }, // CYRILLIC CAPITAL LETTER WE
+ { 0x051E, 0x051F }, // CYRILLIC CAPITAL LETTER ALEUT KA
+ { 0x0520, 0x0521 }, // CYRILLIC CAPITAL LETTER EL WITH MIDDLE HOOK
+ { 0x0522, 0x0523 }, // CYRILLIC CAPITAL LETTER EN WITH MIDDLE HOOK
+ { 0x0524, 0x0525 }, // CYRILLIC CAPITAL LETTER PE WITH DESCENDER
+ { 0x0531, 0x0561 }, // ARMENIAN CAPITAL LETTER AYB
+ { 0x0532, 0x0562 }, // ARMENIAN CAPITAL LETTER BEN
+ { 0x0533, 0x0563 }, // ARMENIAN CAPITAL LETTER GIM
+ { 0x0534, 0x0564 }, // ARMENIAN CAPITAL LETTER DA
+ { 0x0535, 0x0565 }, // ARMENIAN CAPITAL LETTER ECH
+ { 0x0536, 0x0566 }, // ARMENIAN CAPITAL LETTER ZA
+ { 0x0537, 0x0567 }, // ARMENIAN CAPITAL LETTER EH
+ { 0x0538, 0x0568 }, // ARMENIAN CAPITAL LETTER ET
+ { 0x0539, 0x0569 }, // ARMENIAN CAPITAL LETTER TO
+ { 0x053A, 0x056A }, // ARMENIAN CAPITAL LETTER ZHE
+ { 0x053B, 0x056B }, // ARMENIAN CAPITAL LETTER INI
+ { 0x053C, 0x056C }, // ARMENIAN CAPITAL LETTER LIWN
+ { 0x053D, 0x056D }, // ARMENIAN CAPITAL LETTER XEH
+ { 0x053E, 0x056E }, // ARMENIAN CAPITAL LETTER CA
+ { 0x053F, 0x056F }, // ARMENIAN CAPITAL LETTER KEN
+ { 0x0540, 0x0570 }, // ARMENIAN CAPITAL LETTER HO
+ { 0x0541, 0x0571 }, // ARMENIAN CAPITAL LETTER JA
+ { 0x0542, 0x0572 }, // ARMENIAN CAPITAL LETTER GHAD
+ { 0x0543, 0x0573 }, // ARMENIAN CAPITAL LETTER CHEH
+ { 0x0544, 0x0574 }, // ARMENIAN CAPITAL LETTER MEN
+ { 0x0545, 0x0575 }, // ARMENIAN CAPITAL LETTER YI
+ { 0x0546, 0x0576 }, // ARMENIAN CAPITAL LETTER NOW
+ { 0x0547, 0x0577 }, // ARMENIAN CAPITAL LETTER SHA
+ { 0x0548, 0x0578 }, // ARMENIAN CAPITAL LETTER VO
+ { 0x0549, 0x0579 }, // ARMENIAN CAPITAL LETTER CHA
+ { 0x054A, 0x057A }, // ARMENIAN CAPITAL LETTER PEH
+ { 0x054B, 0x057B }, // ARMENIAN CAPITAL LETTER JHEH
+ { 0x054C, 0x057C }, // ARMENIAN CAPITAL LETTER RA
+ { 0x054D, 0x057D }, // ARMENIAN CAPITAL LETTER SEH
+ { 0x054E, 0x057E }, // ARMENIAN CAPITAL LETTER VEW
+ { 0x054F, 0x057F }, // ARMENIAN CAPITAL LETTER TIWN
+ { 0x0550, 0x0580 }, // ARMENIAN CAPITAL LETTER REH
+ { 0x0551, 0x0581 }, // ARMENIAN CAPITAL LETTER CO
+ { 0x0552, 0x0582 }, // ARMENIAN CAPITAL LETTER YIWN
+ { 0x0553, 0x0583 }, // ARMENIAN CAPITAL LETTER PIWR
+ { 0x0554, 0x0584 }, // ARMENIAN CAPITAL LETTER KEH
+ { 0x0555, 0x0585 }, // ARMENIAN CAPITAL LETTER OH
+ { 0x0556, 0x0586 }, // ARMENIAN CAPITAL LETTER FEH
+ { 0x10A0, 0x2D00 }, // GEORGIAN CAPITAL LETTER AN
+ { 0x10A1, 0x2D01 }, // GEORGIAN CAPITAL LETTER BAN
+ { 0x10A2, 0x2D02 }, // GEORGIAN CAPITAL LETTER GAN
+ { 0x10A3, 0x2D03 }, // GEORGIAN CAPITAL LETTER DON
+ { 0x10A4, 0x2D04 }, // GEORGIAN CAPITAL LETTER EN
+ { 0x10A5, 0x2D05 }, // GEORGIAN CAPITAL LETTER VIN
+ { 0x10A6, 0x2D06 }, // GEORGIAN CAPITAL LETTER ZEN
+ { 0x10A7, 0x2D07 }, // GEORGIAN CAPITAL LETTER TAN
+ { 0x10A8, 0x2D08 }, // GEORGIAN CAPITAL LETTER IN
+ { 0x10A9, 0x2D09 }, // GEORGIAN CAPITAL LETTER KAN
+ { 0x10AA, 0x2D0A }, // GEORGIAN CAPITAL LETTER LAS
+ { 0x10AB, 0x2D0B }, // GEORGIAN CAPITAL LETTER MAN
+ { 0x10AC, 0x2D0C }, // GEORGIAN CAPITAL LETTER NAR
+ { 0x10AD, 0x2D0D }, // GEORGIAN CAPITAL LETTER ON
+ { 0x10AE, 0x2D0E }, // GEORGIAN CAPITAL LETTER PAR
+ { 0x10AF, 0x2D0F }, // GEORGIAN CAPITAL LETTER ZHAR
+ { 0x10B0, 0x2D10 }, // GEORGIAN CAPITAL LETTER RAE
+ { 0x10B1, 0x2D11 }, // GEORGIAN CAPITAL LETTER SAN
+ { 0x10B2, 0x2D12 }, // GEORGIAN CAPITAL LETTER TAR
+ { 0x10B3, 0x2D13 }, // GEORGIAN CAPITAL LETTER UN
+ { 0x10B4, 0x2D14 }, // GEORGIAN CAPITAL LETTER PHAR
+ { 0x10B5, 0x2D15 }, // GEORGIAN CAPITAL LETTER KHAR
+ { 0x10B6, 0x2D16 }, // GEORGIAN CAPITAL LETTER GHAN
+ { 0x10B7, 0x2D17 }, // GEORGIAN CAPITAL LETTER QAR
+ { 0x10B8, 0x2D18 }, // GEORGIAN CAPITAL LETTER SHIN
+ { 0x10B9, 0x2D19 }, // GEORGIAN CAPITAL LETTER CHIN
+ { 0x10BA, 0x2D1A }, // GEORGIAN CAPITAL LETTER CAN
+ { 0x10BB, 0x2D1B }, // GEORGIAN CAPITAL LETTER JIL
+ { 0x10BC, 0x2D1C }, // GEORGIAN CAPITAL LETTER CIL
+ { 0x10BD, 0x2D1D }, // GEORGIAN CAPITAL LETTER CHAR
+ { 0x10BE, 0x2D1E }, // GEORGIAN CAPITAL LETTER XAN
+ { 0x10BF, 0x2D1F }, // GEORGIAN CAPITAL LETTER JHAN
+ { 0x10C0, 0x2D20 }, // GEORGIAN CAPITAL LETTER HAE
+ { 0x10C1, 0x2D21 }, // GEORGIAN CAPITAL LETTER HE
+ { 0x10C2, 0x2D22 }, // GEORGIAN CAPITAL LETTER HIE
+ { 0x10C3, 0x2D23 }, // GEORGIAN CAPITAL LETTER WE
+ { 0x10C4, 0x2D24 }, // GEORGIAN CAPITAL LETTER HAR
+ { 0x10C5, 0x2D25 }, // GEORGIAN CAPITAL LETTER HOE
+ { 0x1E00, 0x1E01 }, // LATIN CAPITAL LETTER A WITH RING BELOW
+ { 0x1E02, 0x1E03 }, // LATIN CAPITAL LETTER B WITH DOT ABOVE
+ { 0x1E04, 0x1E05 }, // LATIN CAPITAL LETTER B WITH DOT BELOW
+ { 0x1E06, 0x1E07 }, // LATIN CAPITAL LETTER B WITH LINE BELOW
+ { 0x1E08, 0x1E09 }, // LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE
+ { 0x1E0A, 0x1E0B }, // LATIN CAPITAL LETTER D WITH DOT ABOVE
+ { 0x1E0C, 0x1E0D }, // LATIN CAPITAL LETTER D WITH DOT BELOW
+ { 0x1E0E, 0x1E0F }, // LATIN CAPITAL LETTER D WITH LINE BELOW
+ { 0x1E10, 0x1E11 }, // LATIN CAPITAL LETTER D WITH CEDILLA
+ { 0x1E12, 0x1E13 }, // LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW
+ { 0x1E14, 0x1E15 }, // LATIN CAPITAL LETTER E WITH MACRON AND GRAVE
+ { 0x1E16, 0x1E17 }, // LATIN CAPITAL LETTER E WITH MACRON AND ACUTE
+ { 0x1E18, 0x1E19 }, // LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW
+ { 0x1E1A, 0x1E1B }, // LATIN CAPITAL LETTER E WITH TILDE BELOW
+ { 0x1E1C, 0x1E1D }, // LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE
+ { 0x1E1E, 0x1E1F }, // LATIN CAPITAL LETTER F WITH DOT ABOVE
+ { 0x1E20, 0x1E21 }, // LATIN CAPITAL LETTER G WITH MACRON
+ { 0x1E22, 0x1E23 }, // LATIN CAPITAL LETTER H WITH DOT ABOVE
+ { 0x1E24, 0x1E25 }, // LATIN CAPITAL LETTER H WITH DOT BELOW
+ { 0x1E26, 0x1E27 }, // LATIN CAPITAL LETTER H WITH DIAERESIS
+ { 0x1E28, 0x1E29 }, // LATIN CAPITAL LETTER H WITH CEDILLA
+ { 0x1E2A, 0x1E2B }, // LATIN CAPITAL LETTER H WITH BREVE BELOW
+ { 0x1E2C, 0x1E2D }, // LATIN CAPITAL LETTER I WITH TILDE BELOW
+ { 0x1E2E, 0x1E2F }, // LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE
+ { 0x1E30, 0x1E31 }, // LATIN CAPITAL LETTER K WITH ACUTE
+ { 0x1E32, 0x1E33 }, // LATIN CAPITAL LETTER K WITH DOT BELOW
+ { 0x1E34, 0x1E35 }, // LATIN CAPITAL LETTER K WITH LINE BELOW
+ { 0x1E36, 0x1E37 }, // LATIN CAPITAL LETTER L WITH DOT BELOW
+ { 0x1E38, 0x1E39 }, // LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON
+ { 0x1E3A, 0x1E3B }, // LATIN CAPITAL LETTER L WITH LINE BELOW
+ { 0x1E3C, 0x1E3D }, // LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW
+ { 0x1E3E, 0x1E3F }, // LATIN CAPITAL LETTER M WITH ACUTE
+ { 0x1E40, 0x1E41 }, // LATIN CAPITAL LETTER M WITH DOT ABOVE
+ { 0x1E42, 0x1E43 }, // LATIN CAPITAL LETTER M WITH DOT BELOW
+ { 0x1E44, 0x1E45 }, // LATIN CAPITAL LETTER N WITH DOT ABOVE
+ { 0x1E46, 0x1E47 }, // LATIN CAPITAL LETTER N WITH DOT BELOW
+ { 0x1E48, 0x1E49 }, // LATIN CAPITAL LETTER N WITH LINE BELOW
+ { 0x1E4A, 0x1E4B }, // LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW
+ { 0x1E4C, 0x1E4D }, // LATIN CAPITAL LETTER O WITH TILDE AND ACUTE
+ { 0x1E4E, 0x1E4F }, // LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS
+ { 0x1E50, 0x1E51 }, // LATIN CAPITAL LETTER O WITH MACRON AND GRAVE
+ { 0x1E52, 0x1E53 }, // LATIN CAPITAL LETTER O WITH MACRON AND ACUTE
+ { 0x1E54, 0x1E55 }, // LATIN CAPITAL LETTER P WITH ACUTE
+ { 0x1E56, 0x1E57 }, // LATIN CAPITAL LETTER P WITH DOT ABOVE
+ { 0x1E58, 0x1E59 }, // LATIN CAPITAL LETTER R WITH DOT ABOVE
+ { 0x1E5A, 0x1E5B }, // LATIN CAPITAL LETTER R WITH DOT BELOW
+ { 0x1E5C, 0x1E5D }, // LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON
+ { 0x1E5E, 0x1E5F }, // LATIN CAPITAL LETTER R WITH LINE BELOW
+ { 0x1E60, 0x1E61 }, // LATIN CAPITAL LETTER S WITH DOT ABOVE
+ { 0x1E62, 0x1E63 }, // LATIN CAPITAL LETTER S WITH DOT BELOW
+ { 0x1E64, 0x1E65 }, // LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE
+ { 0x1E66, 0x1E67 }, // LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE
+ { 0x1E68, 0x1E69 }, // LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE
+ { 0x1E6A, 0x1E6B }, // LATIN CAPITAL LETTER T WITH DOT ABOVE
+ { 0x1E6C, 0x1E6D }, // LATIN CAPITAL LETTER T WITH DOT BELOW
+ { 0x1E6E, 0x1E6F }, // LATIN CAPITAL LETTER T WITH LINE BELOW
+ { 0x1E70, 0x1E71 }, // LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW
+ { 0x1E72, 0x1E73 }, // LATIN CAPITAL LETTER U WITH DIAERESIS BELOW
+ { 0x1E74, 0x1E75 }, // LATIN CAPITAL LETTER U WITH TILDE BELOW
+ { 0x1E76, 0x1E77 }, // LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW
+ { 0x1E78, 0x1E79 }, // LATIN CAPITAL LETTER U WITH TILDE AND ACUTE
+ { 0x1E7A, 0x1E7B }, // LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS
+ { 0x1E7C, 0x1E7D }, // LATIN CAPITAL LETTER V WITH TILDE
+ { 0x1E7E, 0x1E7F }, // LATIN CAPITAL LETTER V WITH DOT BELOW
+ { 0x1E80, 0x1E81 }, // LATIN CAPITAL LETTER W WITH GRAVE
+ { 0x1E82, 0x1E83 }, // LATIN CAPITAL LETTER W WITH ACUTE
+ { 0x1E84, 0x1E85 }, // LATIN CAPITAL LETTER W WITH DIAERESIS
+ { 0x1E86, 0x1E87 }, // LATIN CAPITAL LETTER W WITH DOT ABOVE
+ { 0x1E88, 0x1E89 }, // LATIN CAPITAL LETTER W WITH DOT BELOW
+ { 0x1E8A, 0x1E8B }, // LATIN CAPITAL LETTER X WITH DOT ABOVE
+ { 0x1E8C, 0x1E8D }, // LATIN CAPITAL LETTER X WITH DIAERESIS
+ { 0x1E8E, 0x1E8F }, // LATIN CAPITAL LETTER Y WITH DOT ABOVE
+ { 0x1E90, 0x1E91 }, // LATIN CAPITAL LETTER Z WITH CIRCUMFLEX
+ { 0x1E92, 0x1E93 }, // LATIN CAPITAL LETTER Z WITH DOT BELOW
+ { 0x1E94, 0x1E95 }, // LATIN CAPITAL LETTER Z WITH LINE BELOW
+ { 0x1E9E, 0x00DF }, // LATIN CAPITAL LETTER SHARP S
+ { 0x1EA0, 0x1EA1 }, // LATIN CAPITAL LETTER A WITH DOT BELOW
+ { 0x1EA2, 0x1EA3 }, // LATIN CAPITAL LETTER A WITH HOOK ABOVE
+ { 0x1EA4, 0x1EA5 }, // LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE
+ { 0x1EA6, 0x1EA7 }, // LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE
+ { 0x1EA8, 0x1EA9 }, // LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE
+ { 0x1EAA, 0x1EAB }, // LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE
+ { 0x1EAC, 0x1EAD }, // LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW
+ { 0x1EAE, 0x1EAF }, // LATIN CAPITAL LETTER A WITH BREVE AND ACUTE
+ { 0x1EB0, 0x1EB1 }, // LATIN CAPITAL LETTER A WITH BREVE AND GRAVE
+ { 0x1EB2, 0x1EB3 }, // LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE
+ { 0x1EB4, 0x1EB5 }, // LATIN CAPITAL LETTER A WITH BREVE AND TILDE
+ { 0x1EB6, 0x1EB7 }, // LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW
+ { 0x1EB8, 0x1EB9 }, // LATIN CAPITAL LETTER E WITH DOT BELOW
+ { 0x1EBA, 0x1EBB }, // LATIN CAPITAL LETTER E WITH HOOK ABOVE
+ { 0x1EBC, 0x1EBD }, // LATIN CAPITAL LETTER E WITH TILDE
+ { 0x1EBE, 0x1EBF }, // LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE
+ { 0x1EC0, 0x1EC1 }, // LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE
+ { 0x1EC2, 0x1EC3 }, // LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE
+ { 0x1EC4, 0x1EC5 }, // LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE
+ { 0x1EC6, 0x1EC7 }, // LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW
+ { 0x1EC8, 0x1EC9 }, // LATIN CAPITAL LETTER I WITH HOOK ABOVE
+ { 0x1ECA, 0x1ECB }, // LATIN CAPITAL LETTER I WITH DOT BELOW
+ { 0x1ECC, 0x1ECD }, // LATIN CAPITAL LETTER O WITH DOT BELOW
+ { 0x1ECE, 0x1ECF }, // LATIN CAPITAL LETTER O WITH HOOK ABOVE
+ { 0x1ED0, 0x1ED1 }, // LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE
+ { 0x1ED2, 0x1ED3 }, // LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE
+ { 0x1ED4, 0x1ED5 }, // LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE
+ { 0x1ED6, 0x1ED7 }, // LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE
+ { 0x1ED8, 0x1ED9 }, // LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW
+ { 0x1EDA, 0x1EDB }, // LATIN CAPITAL LETTER O WITH HORN AND ACUTE
+ { 0x1EDC, 0x1EDD }, // LATIN CAPITAL LETTER O WITH HORN AND GRAVE
+ { 0x1EDE, 0x1EDF }, // LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE
+ { 0x1EE0, 0x1EE1 }, // LATIN CAPITAL LETTER O WITH HORN AND TILDE
+ { 0x1EE2, 0x1EE3 }, // LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW
+ { 0x1EE4, 0x1EE5 }, // LATIN CAPITAL LETTER U WITH DOT BELOW
+ { 0x1EE6, 0x1EE7 }, // LATIN CAPITAL LETTER U WITH HOOK ABOVE
+ { 0x1EE8, 0x1EE9 }, // LATIN CAPITAL LETTER U WITH HORN AND ACUTE
+ { 0x1EEA, 0x1EEB }, // LATIN CAPITAL LETTER U WITH HORN AND GRAVE
+ { 0x1EEC, 0x1EED }, // LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE
+ { 0x1EEE, 0x1EEF }, // LATIN CAPITAL LETTER U WITH HORN AND TILDE
+ { 0x1EF0, 0x1EF1 }, // LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW
+ { 0x1EF2, 0x1EF3 }, // LATIN CAPITAL LETTER Y WITH GRAVE
+ { 0x1EF4, 0x1EF5 }, // LATIN CAPITAL LETTER Y WITH DOT BELOW
+ { 0x1EF6, 0x1EF7 }, // LATIN CAPITAL LETTER Y WITH HOOK ABOVE
+ { 0x1EF8, 0x1EF9 }, // LATIN CAPITAL LETTER Y WITH TILDE
+ { 0x1EFA, 0x1EFB }, // LATIN CAPITAL LETTER MIDDLE-WELSH LL
+ { 0x1EFC, 0x1EFD }, // LATIN CAPITAL LETTER MIDDLE-WELSH V
+ { 0x1EFE, 0x1EFF }, // LATIN CAPITAL LETTER Y WITH LOOP
+ { 0x1F08, 0x1F00 }, // GREEK CAPITAL LETTER ALPHA WITH PSILI
+ { 0x1F09, 0x1F01 }, // GREEK CAPITAL LETTER ALPHA WITH DASIA
+ { 0x1F0A, 0x1F02 }, // GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA
+ { 0x1F0B, 0x1F03 }, // GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA
+ { 0x1F0C, 0x1F04 }, // GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA
+ { 0x1F0D, 0x1F05 }, // GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA
+ { 0x1F0E, 0x1F06 }, // GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI
+ { 0x1F0F, 0x1F07 }, // GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI
+ { 0x1F18, 0x1F10 }, // GREEK CAPITAL LETTER EPSILON WITH PSILI
+ { 0x1F19, 0x1F11 }, // GREEK CAPITAL LETTER EPSILON WITH DASIA
+ { 0x1F1A, 0x1F12 }, // GREEK CAPITAL LETTER EPSILON WITH PSILI AND VARIA
+ { 0x1F1B, 0x1F13 }, // GREEK CAPITAL LETTER EPSILON WITH DASIA AND VARIA
+ { 0x1F1C, 0x1F14 }, // GREEK CAPITAL LETTER EPSILON WITH PSILI AND OXIA
+ { 0x1F1D, 0x1F15 }, // GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA
+ { 0x1F28, 0x1F20 }, // GREEK CAPITAL LETTER ETA WITH PSILI
+ { 0x1F29, 0x1F21 }, // GREEK CAPITAL LETTER ETA WITH DASIA
+ { 0x1F2A, 0x1F22 }, // GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA
+ { 0x1F2B, 0x1F23 }, // GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA
+ { 0x1F2C, 0x1F24 }, // GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA
+ { 0x1F2D, 0x1F25 }, // GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA
+ { 0x1F2E, 0x1F26 }, // GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI
+ { 0x1F2F, 0x1F27 }, // GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI
+ { 0x1F38, 0x1F30 }, // GREEK CAPITAL LETTER IOTA WITH PSILI
+ { 0x1F39, 0x1F31 }, // GREEK CAPITAL LETTER IOTA WITH DASIA
+ { 0x1F3A, 0x1F32 }, // GREEK CAPITAL LETTER IOTA WITH PSILI AND VARIA
+ { 0x1F3B, 0x1F33 }, // GREEK CAPITAL LETTER IOTA WITH DASIA AND VARIA
+ { 0x1F3C, 0x1F34 }, // GREEK CAPITAL LETTER IOTA WITH PSILI AND OXIA
+ { 0x1F3D, 0x1F35 }, // GREEK CAPITAL LETTER IOTA WITH DASIA AND OXIA
+ { 0x1F3E, 0x1F36 }, // GREEK CAPITAL LETTER IOTA WITH PSILI AND PERISPOMENI
+ { 0x1F3F, 0x1F37 }, // GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI
+ { 0x1F48, 0x1F40 }, // GREEK CAPITAL LETTER OMICRON WITH PSILI
+ { 0x1F49, 0x1F41 }, // GREEK CAPITAL LETTER OMICRON WITH DASIA
+ { 0x1F4A, 0x1F42 }, // GREEK CAPITAL LETTER OMICRON WITH PSILI AND VARIA
+ { 0x1F4B, 0x1F43 }, // GREEK CAPITAL LETTER OMICRON WITH DASIA AND VARIA
+ { 0x1F4C, 0x1F44 }, // GREEK CAPITAL LETTER OMICRON WITH PSILI AND OXIA
+ { 0x1F4D, 0x1F45 }, // GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA
+ { 0x1F59, 0x1F51 }, // GREEK CAPITAL LETTER UPSILON WITH DASIA
+ { 0x1F5B, 0x1F53 }, // GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA
+ { 0x1F5D, 0x1F55 }, // GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA
+ { 0x1F5F, 0x1F57 }, // GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI
+ { 0x1F68, 0x1F60 }, // GREEK CAPITAL LETTER OMEGA WITH PSILI
+ { 0x1F69, 0x1F61 }, // GREEK CAPITAL LETTER OMEGA WITH DASIA
+ { 0x1F6A, 0x1F62 }, // GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA
+ { 0x1F6B, 0x1F63 }, // GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA
+ { 0x1F6C, 0x1F64 }, // GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA
+ { 0x1F6D, 0x1F65 }, // GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA
+ { 0x1F6E, 0x1F66 }, // GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI
+ { 0x1F6F, 0x1F67 }, // GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI
+ { 0x1F88, 0x1F80 }, // GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI
+ { 0x1F89, 0x1F81 }, // GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI
+ { 0x1F8A, 0x1F82 }, // GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI
+ { 0x1F8B, 0x1F83 }, // GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI
+ { 0x1F8C, 0x1F84 }, // GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI
+ { 0x1F8D, 0x1F85 }, // GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI
+ { 0x1F8E, 0x1F86 }, // GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
+ { 0x1F8F, 0x1F87 }, // GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
+ { 0x1F98, 0x1F90 }, // GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI
+ { 0x1F99, 0x1F91 }, // GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI
+ { 0x1F9A, 0x1F92 }, // GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI
+ { 0x1F9B, 0x1F93 }, // GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI
+ { 0x1F9C, 0x1F94 }, // GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI
+ { 0x1F9D, 0x1F95 }, // GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI
+ { 0x1F9E, 0x1F96 }, // GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
+ { 0x1F9F, 0x1F97 }, // GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
+ { 0x1FA8, 0x1FA0 }, // GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI
+ { 0x1FA9, 0x1FA1 }, // GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI
+ { 0x1FAA, 0x1FA2 }, // GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI
+ { 0x1FAB, 0x1FA3 }, // GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI
+ { 0x1FAC, 0x1FA4 }, // GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI
+ { 0x1FAD, 0x1FA5 }, // GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI
+ { 0x1FAE, 0x1FA6 }, // GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
+ { 0x1FAF, 0x1FA7 }, // GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
+ { 0x1FB8, 0x1FB0 }, // GREEK CAPITAL LETTER ALPHA WITH VRACHY
+ { 0x1FB9, 0x1FB1 }, // GREEK CAPITAL LETTER ALPHA WITH MACRON
+ { 0x1FBA, 0x1F70 }, // GREEK CAPITAL LETTER ALPHA WITH VARIA
+ { 0x1FBB, 0x1F71 }, // GREEK CAPITAL LETTER ALPHA WITH OXIA
+ { 0x1FBC, 0x1FB3 }, // GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI
+ { 0x1FC8, 0x1F72 }, // GREEK CAPITAL LETTER EPSILON WITH VARIA
+ { 0x1FC9, 0x1F73 }, // GREEK CAPITAL LETTER EPSILON WITH OXIA
+ { 0x1FCA, 0x1F74 }, // GREEK CAPITAL LETTER ETA WITH VARIA
+ { 0x1FCB, 0x1F75 }, // GREEK CAPITAL LETTER ETA WITH OXIA
+ { 0x1FCC, 0x1FC3 }, // GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI
+ { 0x1FD8, 0x1FD0 }, // GREEK CAPITAL LETTER IOTA WITH VRACHY
+ { 0x1FD9, 0x1FD1 }, // GREEK CAPITAL LETTER IOTA WITH MACRON
+ { 0x1FDA, 0x1F76 }, // GREEK CAPITAL LETTER IOTA WITH VARIA
+ { 0x1FDB, 0x1F77 }, // GREEK CAPITAL LETTER IOTA WITH OXIA
+ { 0x1FE8, 0x1FE0 }, // GREEK CAPITAL LETTER UPSILON WITH VRACHY
+ { 0x1FE9, 0x1FE1 }, // GREEK CAPITAL LETTER UPSILON WITH MACRON
+ { 0x1FEA, 0x1F7A }, // GREEK CAPITAL LETTER UPSILON WITH VARIA
+ { 0x1FEB, 0x1F7B }, // GREEK CAPITAL LETTER UPSILON WITH OXIA
+ { 0x1FEC, 0x1FE5 }, // GREEK CAPITAL LETTER RHO WITH DASIA
+ { 0x1FF8, 0x1F78 }, // GREEK CAPITAL LETTER OMICRON WITH VARIA
+ { 0x1FF9, 0x1F79 }, // GREEK CAPITAL LETTER OMICRON WITH OXIA
+ { 0x1FFA, 0x1F7C }, // GREEK CAPITAL LETTER OMEGA WITH VARIA
+ { 0x1FFB, 0x1F7D }, // GREEK CAPITAL LETTER OMEGA WITH OXIA
+ { 0x1FFC, 0x1FF3 }, // GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI
+ { 0x2126, 0x03C9 }, // OHM SIGN
+ { 0x212A, 0x006B }, // KELVIN SIGN
+ { 0x212B, 0x00E5 }, // ANGSTROM SIGN
+ { 0x2132, 0x214E }, // TURNED CAPITAL F
+ { 0x2160, 0x2170 }, // ROMAN NUMERAL ONE
+ { 0x2161, 0x2171 }, // ROMAN NUMERAL TWO
+ { 0x2162, 0x2172 }, // ROMAN NUMERAL THREE
+ { 0x2163, 0x2173 }, // ROMAN NUMERAL FOUR
+ { 0x2164, 0x2174 }, // ROMAN NUMERAL FIVE
+ { 0x2165, 0x2175 }, // ROMAN NUMERAL SIX
+ { 0x2166, 0x2176 }, // ROMAN NUMERAL SEVEN
+ { 0x2167, 0x2177 }, // ROMAN NUMERAL EIGHT
+ { 0x2168, 0x2178 }, // ROMAN NUMERAL NINE
+ { 0x2169, 0x2179 }, // ROMAN NUMERAL TEN
+ { 0x216A, 0x217A }, // ROMAN NUMERAL ELEVEN
+ { 0x216B, 0x217B }, // ROMAN NUMERAL TWELVE
+ { 0x216C, 0x217C }, // ROMAN NUMERAL FIFTY
+ { 0x216D, 0x217D }, // ROMAN NUMERAL ONE HUNDRED
+ { 0x216E, 0x217E }, // ROMAN NUMERAL FIVE HUNDRED
+ { 0x216F, 0x217F }, // ROMAN NUMERAL ONE THOUSAND
+ { 0x2183, 0x2184 }, // ROMAN NUMERAL REVERSED ONE HUNDRED
+ { 0x24B6, 0x24D0 }, // CIRCLED LATIN CAPITAL LETTER A
+ { 0x24B7, 0x24D1 }, // CIRCLED LATIN CAPITAL LETTER B
+ { 0x24B8, 0x24D2 }, // CIRCLED LATIN CAPITAL LETTER C
+ { 0x24B9, 0x24D3 }, // CIRCLED LATIN CAPITAL LETTER D
+ { 0x24BA, 0x24D4 }, // CIRCLED LATIN CAPITAL LETTER E
+ { 0x24BB, 0x24D5 }, // CIRCLED LATIN CAPITAL LETTER F
+ { 0x24BC, 0x24D6 }, // CIRCLED LATIN CAPITAL LETTER G
+ { 0x24BD, 0x24D7 }, // CIRCLED LATIN CAPITAL LETTER H
+ { 0x24BE, 0x24D8 }, // CIRCLED LATIN CAPITAL LETTER I
+ { 0x24BF, 0x24D9 }, // CIRCLED LATIN CAPITAL LETTER J
+ { 0x24C0, 0x24DA }, // CIRCLED LATIN CAPITAL LETTER K
+ { 0x24C1, 0x24DB }, // CIRCLED LATIN CAPITAL LETTER L
+ { 0x24C2, 0x24DC }, // CIRCLED LATIN CAPITAL LETTER M
+ { 0x24C3, 0x24DD }, // CIRCLED LATIN CAPITAL LETTER N
+ { 0x24C4, 0x24DE }, // CIRCLED LATIN CAPITAL LETTER O
+ { 0x24C5, 0x24DF }, // CIRCLED LATIN CAPITAL LETTER P
+ { 0x24C6, 0x24E0 }, // CIRCLED LATIN CAPITAL LETTER Q
+ { 0x24C7, 0x24E1 }, // CIRCLED LATIN CAPITAL LETTER R
+ { 0x24C8, 0x24E2 }, // CIRCLED LATIN CAPITAL LETTER S
+ { 0x24C9, 0x24E3 }, // CIRCLED LATIN CAPITAL LETTER T
+ { 0x24CA, 0x24E4 }, // CIRCLED LATIN CAPITAL LETTER U
+ { 0x24CB, 0x24E5 }, // CIRCLED LATIN CAPITAL LETTER V
+ { 0x24CC, 0x24E6 }, // CIRCLED LATIN CAPITAL LETTER W
+ { 0x24CD, 0x24E7 }, // CIRCLED LATIN CAPITAL LETTER X
+ { 0x24CE, 0x24E8 }, // CIRCLED LATIN CAPITAL LETTER Y
+ { 0x24CF, 0x24E9 }, // CIRCLED LATIN CAPITAL LETTER Z
+ { 0x2C00, 0x2C30 }, // GLAGOLITIC CAPITAL LETTER AZU
+ { 0x2C01, 0x2C31 }, // GLAGOLITIC CAPITAL LETTER BUKY
+ { 0x2C02, 0x2C32 }, // GLAGOLITIC CAPITAL LETTER VEDE
+ { 0x2C03, 0x2C33 }, // GLAGOLITIC CAPITAL LETTER GLAGOLI
+ { 0x2C04, 0x2C34 }, // GLAGOLITIC CAPITAL LETTER DOBRO
+ { 0x2C05, 0x2C35 }, // GLAGOLITIC CAPITAL LETTER YESTU
+ { 0x2C06, 0x2C36 }, // GLAGOLITIC CAPITAL LETTER ZHIVETE
+ { 0x2C07, 0x2C37 }, // GLAGOLITIC CAPITAL LETTER DZELO
+ { 0x2C08, 0x2C38 }, // GLAGOLITIC CAPITAL LETTER ZEMLJA
+ { 0x2C09, 0x2C39 }, // GLAGOLITIC CAPITAL LETTER IZHE
+ { 0x2C0A, 0x2C3A }, // GLAGOLITIC CAPITAL LETTER INITIAL IZHE
+ { 0x2C0B, 0x2C3B }, // GLAGOLITIC CAPITAL LETTER I
+ { 0x2C0C, 0x2C3C }, // GLAGOLITIC CAPITAL LETTER DJERVI
+ { 0x2C0D, 0x2C3D }, // GLAGOLITIC CAPITAL LETTER KAKO
+ { 0x2C0E, 0x2C3E }, // GLAGOLITIC CAPITAL LETTER LJUDIJE
+ { 0x2C0F, 0x2C3F }, // GLAGOLITIC CAPITAL LETTER MYSLITE
+ { 0x2C10, 0x2C40 }, // GLAGOLITIC CAPITAL LETTER NASHI
+ { 0x2C11, 0x2C41 }, // GLAGOLITIC CAPITAL LETTER ONU
+ { 0x2C12, 0x2C42 }, // GLAGOLITIC CAPITAL LETTER POKOJI
+ { 0x2C13, 0x2C43 }, // GLAGOLITIC CAPITAL LETTER RITSI
+ { 0x2C14, 0x2C44 }, // GLAGOLITIC CAPITAL LETTER SLOVO
+ { 0x2C15, 0x2C45 }, // GLAGOLITIC CAPITAL LETTER TVRIDO
+ { 0x2C16, 0x2C46 }, // GLAGOLITIC CAPITAL LETTER UKU
+ { 0x2C17, 0x2C47 }, // GLAGOLITIC CAPITAL LETTER FRITU
+ { 0x2C18, 0x2C48 }, // GLAGOLITIC CAPITAL LETTER HERU
+ { 0x2C19, 0x2C49 }, // GLAGOLITIC CAPITAL LETTER OTU
+ { 0x2C1A, 0x2C4A }, // GLAGOLITIC CAPITAL LETTER PE
+ { 0x2C1B, 0x2C4B }, // GLAGOLITIC CAPITAL LETTER SHTA
+ { 0x2C1C, 0x2C4C }, // GLAGOLITIC CAPITAL LETTER TSI
+ { 0x2C1D, 0x2C4D }, // GLAGOLITIC CAPITAL LETTER CHRIVI
+ { 0x2C1E, 0x2C4E }, // GLAGOLITIC CAPITAL LETTER SHA
+ { 0x2C1F, 0x2C4F }, // GLAGOLITIC CAPITAL LETTER YERU
+ { 0x2C20, 0x2C50 }, // GLAGOLITIC CAPITAL LETTER YERI
+ { 0x2C21, 0x2C51 }, // GLAGOLITIC CAPITAL LETTER YATI
+ { 0x2C22, 0x2C52 }, // GLAGOLITIC CAPITAL LETTER SPIDERY HA
+ { 0x2C23, 0x2C53 }, // GLAGOLITIC CAPITAL LETTER YU
+ { 0x2C24, 0x2C54 }, // GLAGOLITIC CAPITAL LETTER SMALL YUS
+ { 0x2C25, 0x2C55 }, // GLAGOLITIC CAPITAL LETTER SMALL YUS WITH TAIL
+ { 0x2C26, 0x2C56 }, // GLAGOLITIC CAPITAL LETTER YO
+ { 0x2C27, 0x2C57 }, // GLAGOLITIC CAPITAL LETTER IOTATED SMALL YUS
+ { 0x2C28, 0x2C58 }, // GLAGOLITIC CAPITAL LETTER BIG YUS
+ { 0x2C29, 0x2C59 }, // GLAGOLITIC CAPITAL LETTER IOTATED BIG YUS
+ { 0x2C2A, 0x2C5A }, // GLAGOLITIC CAPITAL LETTER FITA
+ { 0x2C2B, 0x2C5B }, // GLAGOLITIC CAPITAL LETTER IZHITSA
+ { 0x2C2C, 0x2C5C }, // GLAGOLITIC CAPITAL LETTER SHTAPIC
+ { 0x2C2D, 0x2C5D }, // GLAGOLITIC CAPITAL LETTER TROKUTASTI A
+ { 0x2C2E, 0x2C5E }, // GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE
+ { 0x2C60, 0x2C61 }, // LATIN CAPITAL LETTER L WITH DOUBLE BAR
+ { 0x2C62, 0x026B }, // LATIN CAPITAL LETTER L WITH MIDDLE TILDE
+ { 0x2C63, 0x1D7D }, // LATIN CAPITAL LETTER P WITH STROKE
+ { 0x2C64, 0x027D }, // LATIN CAPITAL LETTER R WITH TAIL
+ { 0x2C67, 0x2C68 }, // LATIN CAPITAL LETTER H WITH DESCENDER
+ { 0x2C69, 0x2C6A }, // LATIN CAPITAL LETTER K WITH DESCENDER
+ { 0x2C6B, 0x2C6C }, // LATIN CAPITAL LETTER Z WITH DESCENDER
+ { 0x2C6D, 0x0251 }, // LATIN CAPITAL LETTER ALPHA
+ { 0x2C6E, 0x0271 }, // LATIN CAPITAL LETTER M WITH HOOK
+ { 0x2C6F, 0x0250 }, // LATIN CAPITAL LETTER TURNED A
+ { 0x2C70, 0x0252 }, // LATIN CAPITAL LETTER TURNED ALPHA
+ { 0x2C72, 0x2C73 }, // LATIN CAPITAL LETTER W WITH HOOK
+ { 0x2C75, 0x2C76 }, // LATIN CAPITAL LETTER HALF H
+ { 0x2C7E, 0x023F }, // LATIN CAPITAL LETTER S WITH SWASH TAIL
+ { 0x2C7F, 0x0240 }, // LATIN CAPITAL LETTER Z WITH SWASH TAIL
+ { 0x2C80, 0x2C81 }, // COPTIC CAPITAL LETTER ALFA
+ { 0x2C82, 0x2C83 }, // COPTIC CAPITAL LETTER VIDA
+ { 0x2C84, 0x2C85 }, // COPTIC CAPITAL LETTER GAMMA
+ { 0x2C86, 0x2C87 }, // COPTIC CAPITAL LETTER DALDA
+ { 0x2C88, 0x2C89 }, // COPTIC CAPITAL LETTER EIE
+ { 0x2C8A, 0x2C8B }, // COPTIC CAPITAL LETTER SOU
+ { 0x2C8C, 0x2C8D }, // COPTIC CAPITAL LETTER ZATA
+ { 0x2C8E, 0x2C8F }, // COPTIC CAPITAL LETTER HATE
+ { 0x2C90, 0x2C91 }, // COPTIC CAPITAL LETTER THETHE
+ { 0x2C92, 0x2C93 }, // COPTIC CAPITAL LETTER IAUDA
+ { 0x2C94, 0x2C95 }, // COPTIC CAPITAL LETTER KAPA
+ { 0x2C96, 0x2C97 }, // COPTIC CAPITAL LETTER LAULA
+ { 0x2C98, 0x2C99 }, // COPTIC CAPITAL LETTER MI
+ { 0x2C9A, 0x2C9B }, // COPTIC CAPITAL LETTER NI
+ { 0x2C9C, 0x2C9D }, // COPTIC CAPITAL LETTER KSI
+ { 0x2C9E, 0x2C9F }, // COPTIC CAPITAL LETTER O
+ { 0x2CA0, 0x2CA1 }, // COPTIC CAPITAL LETTER PI
+ { 0x2CA2, 0x2CA3 }, // COPTIC CAPITAL LETTER RO
+ { 0x2CA4, 0x2CA5 }, // COPTIC CAPITAL LETTER SIMA
+ { 0x2CA6, 0x2CA7 }, // COPTIC CAPITAL LETTER TAU
+ { 0x2CA8, 0x2CA9 }, // COPTIC CAPITAL LETTER UA
+ { 0x2CAA, 0x2CAB }, // COPTIC CAPITAL LETTER FI
+ { 0x2CAC, 0x2CAD }, // COPTIC CAPITAL LETTER KHI
+ { 0x2CAE, 0x2CAF }, // COPTIC CAPITAL LETTER PSI
+ { 0x2CB0, 0x2CB1 }, // COPTIC CAPITAL LETTER OOU
+ { 0x2CB2, 0x2CB3 }, // COPTIC CAPITAL LETTER DIALECT-P ALEF
+ { 0x2CB4, 0x2CB5 }, // COPTIC CAPITAL LETTER OLD COPTIC AIN
+ { 0x2CB6, 0x2CB7 }, // COPTIC CAPITAL LETTER CRYPTOGRAMMIC EIE
+ { 0x2CB8, 0x2CB9 }, // COPTIC CAPITAL LETTER DIALECT-P KAPA
+ { 0x2CBA, 0x2CBB }, // COPTIC CAPITAL LETTER DIALECT-P NI
+ { 0x2CBC, 0x2CBD }, // COPTIC CAPITAL LETTER CRYPTOGRAMMIC NI
+ { 0x2CBE, 0x2CBF }, // COPTIC CAPITAL LETTER OLD COPTIC OOU
+ { 0x2CC0, 0x2CC1 }, // COPTIC CAPITAL LETTER SAMPI
+ { 0x2CC2, 0x2CC3 }, // COPTIC CAPITAL LETTER CROSSED SHEI
+ { 0x2CC4, 0x2CC5 }, // COPTIC CAPITAL LETTER OLD COPTIC SHEI
+ { 0x2CC6, 0x2CC7 }, // COPTIC CAPITAL LETTER OLD COPTIC ESH
+ { 0x2CC8, 0x2CC9 }, // COPTIC CAPITAL LETTER AKHMIMIC KHEI
+ { 0x2CCA, 0x2CCB }, // COPTIC CAPITAL LETTER DIALECT-P HORI
+ { 0x2CCC, 0x2CCD }, // COPTIC CAPITAL LETTER OLD COPTIC HORI
+ { 0x2CCE, 0x2CCF }, // COPTIC CAPITAL LETTER OLD COPTIC HA
+ { 0x2CD0, 0x2CD1 }, // COPTIC CAPITAL LETTER L-SHAPED HA
+ { 0x2CD2, 0x2CD3 }, // COPTIC CAPITAL LETTER OLD COPTIC HEI
+ { 0x2CD4, 0x2CD5 }, // COPTIC CAPITAL LETTER OLD COPTIC HAT
+ { 0x2CD6, 0x2CD7 }, // COPTIC CAPITAL LETTER OLD COPTIC GANGIA
+ { 0x2CD8, 0x2CD9 }, // COPTIC CAPITAL LETTER OLD COPTIC DJA
+ { 0x2CDA, 0x2CDB }, // COPTIC CAPITAL LETTER OLD COPTIC SHIMA
+ { 0x2CDC, 0x2CDD }, // COPTIC CAPITAL LETTER OLD NUBIAN SHIMA
+ { 0x2CDE, 0x2CDF }, // COPTIC CAPITAL LETTER OLD NUBIAN NGI
+ { 0x2CE0, 0x2CE1 }, // COPTIC CAPITAL LETTER OLD NUBIAN NYI
+ { 0x2CE2, 0x2CE3 }, // COPTIC CAPITAL LETTER OLD NUBIAN WAU
+ { 0x2CEB, 0x2CEC }, // COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI
+ { 0x2CED, 0x2CEE }, // COPTIC CAPITAL LETTER CRYPTOGRAMMIC GANGIA
+ { 0xA640, 0xA641 }, // CYRILLIC CAPITAL LETTER ZEMLYA
+ { 0xA642, 0xA643 }, // CYRILLIC CAPITAL LETTER DZELO
+ { 0xA644, 0xA645 }, // CYRILLIC CAPITAL LETTER REVERSED DZE
+ { 0xA646, 0xA647 }, // CYRILLIC CAPITAL LETTER IOTA
+ { 0xA648, 0xA649 }, // CYRILLIC CAPITAL LETTER DJERV
+ { 0xA64A, 0xA64B }, // CYRILLIC CAPITAL LETTER MONOGRAPH UK
+ { 0xA64C, 0xA64D }, // CYRILLIC CAPITAL LETTER BROAD OMEGA
+ { 0xA64E, 0xA64F }, // CYRILLIC CAPITAL LETTER NEUTRAL YER
+ { 0xA650, 0xA651 }, // CYRILLIC CAPITAL LETTER YERU WITH BACK YER
+ { 0xA652, 0xA653 }, // CYRILLIC CAPITAL LETTER IOTIFIED YAT
+ { 0xA654, 0xA655 }, // CYRILLIC CAPITAL LETTER REVERSED YU
+ { 0xA656, 0xA657 }, // CYRILLIC CAPITAL LETTER IOTIFIED A
+ { 0xA658, 0xA659 }, // CYRILLIC CAPITAL LETTER CLOSED LITTLE YUS
+ { 0xA65A, 0xA65B }, // CYRILLIC CAPITAL LETTER BLENDED YUS
+ { 0xA65C, 0xA65D }, // CYRILLIC CAPITAL LETTER IOTIFIED CLOSED LITTLE YUS
+ { 0xA65E, 0xA65F }, // CYRILLIC CAPITAL LETTER YN
+ { 0xA662, 0xA663 }, // CYRILLIC CAPITAL LETTER SOFT DE
+ { 0xA664, 0xA665 }, // CYRILLIC CAPITAL LETTER SOFT EL
+ { 0xA666, 0xA667 }, // CYRILLIC CAPITAL LETTER SOFT EM
+ { 0xA668, 0xA669 }, // CYRILLIC CAPITAL LETTER MONOCULAR O
+ { 0xA66A, 0xA66B }, // CYRILLIC CAPITAL LETTER BINOCULAR O
+ { 0xA66C, 0xA66D }, // CYRILLIC CAPITAL LETTER DOUBLE MONOCULAR O
+ { 0xA680, 0xA681 }, // CYRILLIC CAPITAL LETTER DWE
+ { 0xA682, 0xA683 }, // CYRILLIC CAPITAL LETTER DZWE
+ { 0xA684, 0xA685 }, // CYRILLIC CAPITAL LETTER ZHWE
+ { 0xA686, 0xA687 }, // CYRILLIC CAPITAL LETTER CCHE
+ { 0xA688, 0xA689 }, // CYRILLIC CAPITAL LETTER DZZE
+ { 0xA68A, 0xA68B }, // CYRILLIC CAPITAL LETTER TE WITH MIDDLE HOOK
+ { 0xA68C, 0xA68D }, // CYRILLIC CAPITAL LETTER TWE
+ { 0xA68E, 0xA68F }, // CYRILLIC CAPITAL LETTER TSWE
+ { 0xA690, 0xA691 }, // CYRILLIC CAPITAL LETTER TSSE
+ { 0xA692, 0xA693 }, // CYRILLIC CAPITAL LETTER TCHE
+ { 0xA694, 0xA695 }, // CYRILLIC CAPITAL LETTER HWE
+ { 0xA696, 0xA697 }, // CYRILLIC CAPITAL LETTER SHWE
+ { 0xA722, 0xA723 }, // LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF
+ { 0xA724, 0xA725 }, // LATIN CAPITAL LETTER EGYPTOLOGICAL AIN
+ { 0xA726, 0xA727 }, // LATIN CAPITAL LETTER HENG
+ { 0xA728, 0xA729 }, // LATIN CAPITAL LETTER TZ
+ { 0xA72A, 0xA72B }, // LATIN CAPITAL LETTER TRESILLO
+ { 0xA72C, 0xA72D }, // LATIN CAPITAL LETTER CUATRILLO
+ { 0xA72E, 0xA72F }, // LATIN CAPITAL LETTER CUATRILLO WITH COMMA
+ { 0xA732, 0xA733 }, // LATIN CAPITAL LETTER AA
+ { 0xA734, 0xA735 }, // LATIN CAPITAL LETTER AO
+ { 0xA736, 0xA737 }, // LATIN CAPITAL LETTER AU
+ { 0xA738, 0xA739 }, // LATIN CAPITAL LETTER AV
+ { 0xA73A, 0xA73B }, // LATIN CAPITAL LETTER AV WITH HORIZONTAL BAR
+ { 0xA73C, 0xA73D }, // LATIN CAPITAL LETTER AY
+ { 0xA73E, 0xA73F }, // LATIN CAPITAL LETTER REVERSED C WITH DOT
+ { 0xA740, 0xA741 }, // LATIN CAPITAL LETTER K WITH STROKE
+ { 0xA742, 0xA743 }, // LATIN CAPITAL LETTER K WITH DIAGONAL STROKE
+ { 0xA744, 0xA745 }, // LATIN CAPITAL LETTER K WITH STROKE AND DIAGONAL STROKE
+ { 0xA746, 0xA747 }, // LATIN CAPITAL LETTER BROKEN L
+ { 0xA748, 0xA749 }, // LATIN CAPITAL LETTER L WITH HIGH STROKE
+ { 0xA74A, 0xA74B }, // LATIN CAPITAL LETTER O WITH LONG STROKE OVERLAY
+ { 0xA74C, 0xA74D }, // LATIN CAPITAL LETTER O WITH LOOP
+ { 0xA74E, 0xA74F }, // LATIN CAPITAL LETTER OO
+ { 0xA750, 0xA751 }, // LATIN CAPITAL LETTER P WITH STROKE THROUGH DESCENDER
+ { 0xA752, 0xA753 }, // LATIN CAPITAL LETTER P WITH FLOURISH
+ { 0xA754, 0xA755 }, // LATIN CAPITAL LETTER P WITH SQUIRREL TAIL
+ { 0xA756, 0xA757 }, // LATIN CAPITAL LETTER Q WITH STROKE THROUGH DESCENDER
+ { 0xA758, 0xA759 }, // LATIN CAPITAL LETTER Q WITH DIAGONAL STROKE
+ { 0xA75A, 0xA75B }, // LATIN CAPITAL LETTER R ROTUNDA
+ { 0xA75C, 0xA75D }, // LATIN CAPITAL LETTER RUM ROTUNDA
+ { 0xA75E, 0xA75F }, // LATIN CAPITAL LETTER V WITH DIAGONAL STROKE
+ { 0xA760, 0xA761 }, // LATIN CAPITAL LETTER VY
+ { 0xA762, 0xA763 }, // LATIN CAPITAL LETTER VISIGOTHIC Z
+ { 0xA764, 0xA765 }, // LATIN CAPITAL LETTER THORN WITH STROKE
+ { 0xA766, 0xA767 }, // LATIN CAPITAL LETTER THORN WITH STROKE THROUGH DESCENDER
+ { 0xA768, 0xA769 }, // LATIN CAPITAL LETTER VEND
+ { 0xA76A, 0xA76B }, // LATIN CAPITAL LETTER ET
+ { 0xA76C, 0xA76D }, // LATIN CAPITAL LETTER IS
+ { 0xA76E, 0xA76F }, // LATIN CAPITAL LETTER CON
+ { 0xA779, 0xA77A }, // LATIN CAPITAL LETTER INSULAR D
+ { 0xA77B, 0xA77C }, // LATIN CAPITAL LETTER INSULAR F
+ { 0xA77D, 0x1D79 }, // LATIN CAPITAL LETTER INSULAR G
+ { 0xA77E, 0xA77F }, // LATIN CAPITAL LETTER TURNED INSULAR G
+ { 0xA780, 0xA781 }, // LATIN CAPITAL LETTER TURNED L
+ { 0xA782, 0xA783 }, // LATIN CAPITAL LETTER INSULAR R
+ { 0xA784, 0xA785 }, // LATIN CAPITAL LETTER INSULAR S
+ { 0xA786, 0xA787 }, // LATIN CAPITAL LETTER INSULAR T
+ { 0xA78B, 0xA78C }, // LATIN CAPITAL LETTER SALTILLO
+ { 0xFF21, 0xFF41 }, // FULLWIDTH LATIN CAPITAL LETTER A
+ { 0xFF22, 0xFF42 }, // FULLWIDTH LATIN CAPITAL LETTER B
+ { 0xFF23, 0xFF43 }, // FULLWIDTH LATIN CAPITAL LETTER C
+ { 0xFF24, 0xFF44 }, // FULLWIDTH LATIN CAPITAL LETTER D
+ { 0xFF25, 0xFF45 }, // FULLWIDTH LATIN CAPITAL LETTER E
+ { 0xFF26, 0xFF46 }, // FULLWIDTH LATIN CAPITAL LETTER F
+ { 0xFF27, 0xFF47 }, // FULLWIDTH LATIN CAPITAL LETTER G
+ { 0xFF28, 0xFF48 }, // FULLWIDTH LATIN CAPITAL LETTER H
+ { 0xFF29, 0xFF49 }, // FULLWIDTH LATIN CAPITAL LETTER I
+ { 0xFF2A, 0xFF4A }, // FULLWIDTH LATIN CAPITAL LETTER J
+ { 0xFF2B, 0xFF4B }, // FULLWIDTH LATIN CAPITAL LETTER K
+ { 0xFF2C, 0xFF4C }, // FULLWIDTH LATIN CAPITAL LETTER L
+ { 0xFF2D, 0xFF4D }, // FULLWIDTH LATIN CAPITAL LETTER M
+ { 0xFF2E, 0xFF4E }, // FULLWIDTH LATIN CAPITAL LETTER N
+ { 0xFF2F, 0xFF4F }, // FULLWIDTH LATIN CAPITAL LETTER O
+ { 0xFF30, 0xFF50 }, // FULLWIDTH LATIN CAPITAL LETTER P
+ { 0xFF31, 0xFF51 }, // FULLWIDTH LATIN CAPITAL LETTER Q
+ { 0xFF32, 0xFF52 }, // FULLWIDTH LATIN CAPITAL LETTER R
+ { 0xFF33, 0xFF53 }, // FULLWIDTH LATIN CAPITAL LETTER S
+ { 0xFF34, 0xFF54 }, // FULLWIDTH LATIN CAPITAL LETTER T
+ { 0xFF35, 0xFF55 }, // FULLWIDTH LATIN CAPITAL LETTER U
+ { 0xFF36, 0xFF56 }, // FULLWIDTH LATIN CAPITAL LETTER V
+ { 0xFF37, 0xFF57 }, // FULLWIDTH LATIN CAPITAL LETTER W
+ { 0xFF38, 0xFF58 }, // FULLWIDTH LATIN CAPITAL LETTER X
+ { 0xFF39, 0xFF59 }, // FULLWIDTH LATIN CAPITAL LETTER Y
+ { 0xFF3A, 0xFF5A } // FULLWIDTH LATIN CAPITAL LETTER Z
+};
+
+static int compare_pair_capital(const void *a, const void *b) {
+ return (int)(*(unsigned short *)a)
+ - (int)((struct LatinCapitalSmallPair*)b)->capital;
+}
+
+unsigned short latin_tolower(unsigned short c) {
+ struct LatinCapitalSmallPair *p =
+ (struct LatinCapitalSmallPair *)bsearch(&c, SORTED_CHAR_MAP,
+ sizeof(SORTED_CHAR_MAP) / sizeof(SORTED_CHAR_MAP[0]),
+ sizeof(SORTED_CHAR_MAP[0]),
+ compare_pair_capital);
+ return p ? p->small : c;
+}
+
+} // namespace latinime
diff --git a/java/jni/src/char_utils.h b/java/jni/src/char_utils.h
new file mode 100644
index 0000000..921ecb4
--- /dev/null
+++ b/java/jni/src/char_utils.h
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+#ifndef LATINIME_CHAR_UTILS_H
+#define LATINIME_CHAR_UTILS_H
+
+namespace latinime {
+
+unsigned short latin_tolower(unsigned short c);
+
+}; // namespace latinime
+
+#endif // LATINIME_CHAR_UTILS_H
diff --git a/java/jni/src/dictionary.cpp b/java/jni/src/dictionary.cpp
new file mode 100644
index 0000000..9b8512e
--- /dev/null
+++ b/java/jni/src/dictionary.cpp
@@ -0,0 +1,604 @@
+/*
+**
+** 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.
+*/
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <string.h>
+//#define LOG_TAG "dictionary.cpp"
+//#include <cutils/log.h>
+#define LOGI
+
+#include "dictionary.h"
+#include "basechars.h"
+#include "char_utils.h"
+
+#define DEBUG_DICT 0
+#define DICTIONARY_VERSION_MIN 200
+#define DICTIONARY_HEADER_SIZE 2
+#define NOT_VALID_WORD -99
+
+namespace latinime {
+
+Dictionary::Dictionary(void *dict, int typedLetterMultiplier, int fullWordMultiplier, int size)
+{
+ mDict = (unsigned char*) dict;
+ mTypedLetterMultiplier = typedLetterMultiplier;
+ mFullWordMultiplier = fullWordMultiplier;
+ mDictSize = size;
+ getVersionNumber();
+}
+
+Dictionary::~Dictionary()
+{
+}
+
+int Dictionary::getSuggestions(int *codes, int codesSize, unsigned short *outWords, int *frequencies,
+ int maxWordLength, int maxWords, int maxAlternatives, int skipPos,
+ int *nextLetters, int nextLettersSize)
+{
+ int suggWords;
+ mFrequencies = frequencies;
+ mOutputChars = outWords;
+ mInputCodes = codes;
+ mInputLength = codesSize;
+ mMaxAlternatives = maxAlternatives;
+ mMaxWordLength = maxWordLength;
+ mMaxWords = maxWords;
+ mSkipPos = skipPos;
+ mMaxEditDistance = mInputLength < 5 ? 2 : mInputLength / 2;
+ mNextLettersFrequencies = nextLetters;
+ mNextLettersSize = nextLettersSize;
+
+ if (checkIfDictVersionIsLatest()) {
+ getWordsRec(DICTIONARY_HEADER_SIZE, 0, mInputLength * 3, false, 1, 0, 0);
+ } else {
+ getWordsRec(0, 0, mInputLength * 3, false, 1, 0, 0);
+ }
+
+ // Get the word count
+ suggWords = 0;
+ while (suggWords < mMaxWords && mFrequencies[suggWords] > 0) suggWords++;
+ if (DEBUG_DICT) LOGI("Returning %d words", suggWords);
+
+ if (DEBUG_DICT) {
+ LOGI("Next letters: ");
+ for (int k = 0; k < nextLettersSize; k++) {
+ if (mNextLettersFrequencies[k] > 0) {
+ LOGI("%c = %d,", k, mNextLettersFrequencies[k]);
+ }
+ }
+ LOGI("\n");
+ }
+ return suggWords;
+}
+
+void
+Dictionary::registerNextLetter(unsigned short c)
+{
+ if (c < mNextLettersSize) {
+ mNextLettersFrequencies[c]++;
+ }
+}
+
+void
+Dictionary::getVersionNumber()
+{
+ mVersion = (mDict[0] & 0xFF);
+ mBigram = (mDict[1] & 0xFF);
+ LOGI("IN NATIVE SUGGEST Version: %d Bigram : %d \n", mVersion, mBigram);
+}
+
+// Checks whether it has the latest dictionary or the old dictionary
+bool
+Dictionary::checkIfDictVersionIsLatest()
+{
+ return (mVersion >= DICTIONARY_VERSION_MIN) && (mBigram == 1 || mBigram == 0);
+}
+
+unsigned short
+Dictionary::getChar(int *pos)
+{
+ if (*pos < 0 || *pos >= mDictSize) return 0;
+ unsigned short ch = (unsigned short) (mDict[(*pos)++] & 0xFF);
+ // If the code is 255, then actual 16 bit code follows (in big endian)
+ if (ch == 0xFF) {
+ ch = ((mDict[*pos] & 0xFF) << 8) | (mDict[*pos + 1] & 0xFF);
+ (*pos) += 2;
+ }
+ return ch;
+}
+
+int
+Dictionary::getAddress(int *pos)
+{
+ if (*pos < 0 || *pos >= mDictSize) return 0;
+ int address = 0;
+ if ((mDict[*pos] & FLAG_ADDRESS_MASK) == 0) {
+ *pos += 1;
+ } else {
+ address += (mDict[*pos] & (ADDRESS_MASK >> 16)) << 16;
+ address += (mDict[*pos + 1] & 0xFF) << 8;
+ address += (mDict[*pos + 2] & 0xFF);
+ *pos += 3;
+ }
+ if (address < 0 || address >= mDictSize) return 0;
+ return address;
+}
+
+int
+Dictionary::getFreq(int *pos)
+{
+ if (*pos < 0 || *pos >= mDictSize) return 0;
+ int freq = mDict[(*pos)++] & 0xFF;
+
+ if (checkIfDictVersionIsLatest()) {
+ // skipping bigram
+ int bigramExist = (mDict[*pos] & FLAG_BIGRAM_READ);
+ if (bigramExist > 0) {
+ int nextBigramExist = 1;
+ while (nextBigramExist > 0) {
+ (*pos) += 3;
+ nextBigramExist = (mDict[(*pos)++] & FLAG_BIGRAM_CONTINUED);
+ }
+ } else {
+ (*pos)++;
+ }
+ }
+
+ return freq;
+}
+
+int
+Dictionary::wideStrLen(unsigned short *str)
+{
+ if (!str) return 0;
+ unsigned short *end = str;
+ while (*end)
+ end++;
+ return end - str;
+}
+
+bool
+Dictionary::addWord(unsigned short *word, int length, int frequency)
+{
+ word[length] = 0;
+ if (DEBUG_DICT) {
+ char s[length + 1];
+ for (int i = 0; i <= length; i++) s[i] = word[i];
+ LOGI("Found word = %s, freq = %d : \n", s, frequency);
+ }
+
+ // Find the right insertion point
+ int insertAt = 0;
+ while (insertAt < mMaxWords) {
+ if (frequency > mFrequencies[insertAt]
+ || (mFrequencies[insertAt] == frequency
+ && length < wideStrLen(mOutputChars + insertAt * mMaxWordLength))) {
+ break;
+ }
+ insertAt++;
+ }
+ if (insertAt < mMaxWords) {
+ memmove((char*) mFrequencies + (insertAt + 1) * sizeof(mFrequencies[0]),
+ (char*) mFrequencies + insertAt * sizeof(mFrequencies[0]),
+ (mMaxWords - insertAt - 1) * sizeof(mFrequencies[0]));
+ mFrequencies[insertAt] = frequency;
+ memmove((char*) mOutputChars + (insertAt + 1) * mMaxWordLength * sizeof(short),
+ (char*) mOutputChars + (insertAt ) * mMaxWordLength * sizeof(short),
+ (mMaxWords - insertAt - 1) * sizeof(short) * mMaxWordLength);
+ unsigned short *dest = mOutputChars + (insertAt ) * mMaxWordLength;
+ while (length--) {
+ *dest++ = *word++;
+ }
+ *dest = 0; // NULL terminate
+ if (DEBUG_DICT) LOGI("Added word at %d\n", insertAt);
+ return true;
+ }
+ return false;
+}
+
+bool
+Dictionary::addWordBigram(unsigned short *word, int length, int frequency)
+{
+ word[length] = 0;
+ if (DEBUG_DICT) {
+ char s[length + 1];
+ for (int i = 0; i <= length; i++) s[i] = word[i];
+ LOGI("Bigram: Found word = %s, freq = %d : \n", s, frequency);
+ }
+
+ // Find the right insertion point
+ int insertAt = 0;
+ while (insertAt < mMaxBigrams) {
+ if (frequency > mBigramFreq[insertAt]
+ || (mBigramFreq[insertAt] == frequency
+ && length < wideStrLen(mBigramChars + insertAt * mMaxWordLength))) {
+ break;
+ }
+ insertAt++;
+ }
+ LOGI("Bigram: InsertAt -> %d maxBigrams: %d\n", insertAt, mMaxBigrams);
+ if (insertAt < mMaxBigrams) {
+ memmove((char*) mBigramFreq + (insertAt + 1) * sizeof(mBigramFreq[0]),
+ (char*) mBigramFreq + insertAt * sizeof(mBigramFreq[0]),
+ (mMaxBigrams - insertAt - 1) * sizeof(mBigramFreq[0]));
+ mBigramFreq[insertAt] = frequency;
+ memmove((char*) mBigramChars + (insertAt + 1) * mMaxWordLength * sizeof(short),
+ (char*) mBigramChars + (insertAt ) * mMaxWordLength * sizeof(short),
+ (mMaxBigrams - insertAt - 1) * sizeof(short) * mMaxWordLength);
+ unsigned short *dest = mBigramChars + (insertAt ) * mMaxWordLength;
+ while (length--) {
+ *dest++ = *word++;
+ }
+ *dest = 0; // NULL terminate
+ if (DEBUG_DICT) LOGI("Bigram: Added word at %d\n", insertAt);
+ return true;
+ }
+ return false;
+}
+
+unsigned short
+Dictionary::toLowerCase(unsigned short c) {
+ if (c < sizeof(BASE_CHARS) / sizeof(BASE_CHARS[0])) {
+ c = BASE_CHARS[c];
+ }
+ if (c >='A' && c <= 'Z') {
+ c |= 32;
+ } else if (c > 127) {
+ c = latin_tolower(c);
+ }
+ return c;
+}
+
+bool
+Dictionary::sameAsTyped(unsigned short *word, int length)
+{
+ if (length != mInputLength) {
+ return false;
+ }
+ int *inputCodes = mInputCodes;
+ while (length--) {
+ if ((unsigned int) *inputCodes != (unsigned int) *word) {
+ return false;
+ }
+ inputCodes += mMaxAlternatives;
+ word++;
+ }
+ return true;
+}
+
+static char QUOTE = '\'';
+
+void
+Dictionary::getWordsRec(int pos, int depth, int maxDepth, bool completion, int snr, int inputIndex,
+ int diffs)
+{
+ // Optimization: Prune out words that are too long compared to how much was typed.
+ if (depth > maxDepth) {
+ return;
+ }
+ if (diffs > mMaxEditDistance) {
+ return;
+ }
+ int count = getCount(&pos);
+ int *currentChars = NULL;
+ if (mInputLength <= inputIndex) {
+ completion = true;
+ } else {
+ currentChars = mInputCodes + (inputIndex * mMaxAlternatives);
+ }
+
+ for (int i = 0; i < count; i++) {
+ // -- at char
+ unsigned short c = getChar(&pos);
+ // -- at flag/add
+ unsigned short lowerC = toLowerCase(c);
+ bool terminal = getTerminal(&pos);
+ int childrenAddress = getAddress(&pos);
+ // -- after address or flag
+ int freq = 1;
+ if (terminal) freq = getFreq(&pos);
+ // -- after add or freq
+
+ // If we are only doing completions, no need to look at the typed characters.
+ if (completion) {
+ mWord[depth] = c;
+ if (terminal) {
+ addWord(mWord, depth + 1, freq * snr);
+ if (depth >= mInputLength && mSkipPos < 0) {
+ registerNextLetter(mWord[mInputLength]);
+ }
+ }
+ if (childrenAddress != 0) {
+ getWordsRec(childrenAddress, depth + 1, maxDepth,
+ completion, snr, inputIndex, diffs);
+ }
+ } else if ((c == QUOTE && currentChars[0] != QUOTE) || mSkipPos == depth) {
+ // Skip the ' or other letter and continue deeper
+ mWord[depth] = c;
+ if (childrenAddress != 0) {
+ getWordsRec(childrenAddress, depth + 1, maxDepth, false, snr, inputIndex, diffs);
+ }
+ } else {
+ int j = 0;
+ while (currentChars[j] > 0) {
+ if (currentChars[j] == lowerC || currentChars[j] == c) {
+ int addedWeight = j == 0 ? mTypedLetterMultiplier : 1;
+ mWord[depth] = c;
+ if (mInputLength == inputIndex + 1) {
+ if (terminal) {
+ if (//INCLUDE_TYPED_WORD_IF_VALID ||
+ !sameAsTyped(mWord, depth + 1)) {
+ int finalFreq = freq * snr * addedWeight;
+ if (mSkipPos < 0) finalFreq *= mFullWordMultiplier;
+ addWord(mWord, depth + 1, finalFreq);
+ }
+ }
+ if (childrenAddress != 0) {
+ getWordsRec(childrenAddress, depth + 1,
+ maxDepth, true, snr * addedWeight, inputIndex + 1,
+ diffs + (j > 0));
+ }
+ } else if (childrenAddress != 0) {
+ getWordsRec(childrenAddress, depth + 1, maxDepth,
+ false, snr * addedWeight, inputIndex + 1, diffs + (j > 0));
+ }
+ }
+ j++;
+ if (mSkipPos >= 0) break;
+ }
+ }
+ }
+}
+
+int
+Dictionary::getBigramAddress(int *pos, bool advance)
+{
+ if (*pos < 0 || *pos >= mDictSize) return 0;
+ int address = 0;
+
+ address += (mDict[*pos] & 0x3F) << 16;
+ address += (mDict[*pos + 1] & 0xFF) << 8;
+ address += (mDict[*pos + 2] & 0xFF);
+
+ if (advance) {
+ *pos += 3;
+ }
+
+ if (address < 0 || address >= mDictSize) return 0;
+ return address;
+}
+
+int
+Dictionary::getBigramFreq(int *pos)
+{
+ if (*pos < 0 || *pos >= mDictSize) return 0;
+ int freq = mDict[(*pos)++] & FLAG_BIGRAM_FREQ;
+
+ return freq;
+}
+
+
+int
+Dictionary::getBigrams(unsigned short *prevWord, int prevWordLength, int *codes, int codesSize,
+ unsigned short *bigramChars, int *bigramFreq, int maxWordLength, int maxBigrams,
+ int maxAlternatives)
+{
+ mBigramFreq = bigramFreq;
+ mBigramChars = bigramChars;
+ mInputCodes = codes;
+ mInputLength = codesSize;
+ mMaxWordLength = maxWordLength;
+ mMaxBigrams = maxBigrams;
+ mMaxAlternatives = maxAlternatives;
+
+ if (mBigram == 1 && checkIfDictVersionIsLatest()) {
+ int pos = isValidWordRec(DICTIONARY_HEADER_SIZE, prevWord, 0, prevWordLength);
+ LOGI("Pos -> %d\n", pos);
+ if (pos < 0) {
+ return 0;
+ }
+
+ int bigramCount = 0;
+ int bigramExist = (mDict[pos] & FLAG_BIGRAM_READ);
+ if (bigramExist > 0) {
+ int nextBigramExist = 1;
+ while (nextBigramExist > 0 && bigramCount < maxBigrams) {
+ int bigramAddress = getBigramAddress(&pos, true);
+ int frequency = (FLAG_BIGRAM_FREQ & mDict[pos]);
+ // search for all bigrams and store them
+ searchForTerminalNode(bigramAddress, frequency);
+ nextBigramExist = (mDict[pos++] & FLAG_BIGRAM_CONTINUED);
+ bigramCount++;
+ }
+ }
+
+ return bigramCount;
+ }
+ return 0;
+}
+
+void
+Dictionary::searchForTerminalNode(int addressLookingFor, int frequency)
+{
+ // track word with such address and store it in an array
+ unsigned short word[mMaxWordLength];
+
+ int pos;
+ int followDownBranchAddress = DICTIONARY_HEADER_SIZE;
+ bool found = false;
+ char followingChar = ' ';
+ int depth = -1;
+
+ while(!found) {
+ bool followDownAddressSearchStop = false;
+ bool firstAddress = true;
+ bool haveToSearchAll = true;
+
+ if (depth >= 0) {
+ word[depth] = (unsigned short) followingChar;
+ }
+ pos = followDownBranchAddress; // pos start at count
+ int count = mDict[pos] & 0xFF;
+ LOGI("count - %d\n",count);
+ pos++;
+ for (int i = 0; i < count; i++) {
+ // pos at data
+ pos++;
+ // pos now at flag
+ if (!getFirstBitOfByte(&pos)) { // non-terminal
+ if (!followDownAddressSearchStop) {
+ int addr = getBigramAddress(&pos, false);
+ if (addr > addressLookingFor) {
+ followDownAddressSearchStop = true;
+ if (firstAddress) {
+ firstAddress = false;
+ haveToSearchAll = true;
+ } else if (!haveToSearchAll) {
+ break;
+ }
+ } else {
+ followDownBranchAddress = addr;
+ followingChar = (char)(0xFF & mDict[pos-1]);
+ if (firstAddress) {
+ firstAddress = false;
+ haveToSearchAll = false;
+ }
+ }
+ }
+ pos += 3;
+ } else if (getFirstBitOfByte(&pos)) { // terminal
+ if (addressLookingFor == (pos-1)) { // found !!
+ depth++;
+ word[depth] = (0xFF & mDict[pos-1]);
+ found = true;
+ break;
+ }
+ if (getSecondBitOfByte(&pos)) { // address + freq (4 byte)
+ if (!followDownAddressSearchStop) {
+ int addr = getBigramAddress(&pos, false);
+ if (addr > addressLookingFor) {
+ followDownAddressSearchStop = true;
+ if (firstAddress) {
+ firstAddress = false;
+ haveToSearchAll = true;
+ } else if (!haveToSearchAll) {
+ break;
+ }
+ } else {
+ followDownBranchAddress = addr;
+ followingChar = (char)(0xFF & mDict[pos-1]);
+ if (firstAddress) {
+ firstAddress = false;
+ haveToSearchAll = true;
+ }
+ }
+ }
+ pos += 4;
+ } else { // freq only (2 byte)
+ pos += 2;
+ }
+
+ // skipping bigram
+ int bigramExist = (mDict[pos] & FLAG_BIGRAM_READ);
+ if (bigramExist > 0) {
+ int nextBigramExist = 1;
+ while (nextBigramExist > 0) {
+ pos += 3;
+ nextBigramExist = (mDict[pos++] & FLAG_BIGRAM_CONTINUED);
+ }
+ } else {
+ pos++;
+ }
+ }
+ }
+ depth++;
+ if (followDownBranchAddress == 0) {
+ LOGI("ERROR!!! Cannot find bigram!!");
+ break;
+ }
+ }
+ if (checkFirstCharacter(word)) {
+ addWordBigram(word, depth, frequency);
+ }
+}
+
+bool
+Dictionary::checkFirstCharacter(unsigned short *word)
+{
+ // Checks whether this word starts with same character or neighboring characters of
+ // what user typed.
+
+ int *inputCodes = mInputCodes;
+ int maxAlt = mMaxAlternatives;
+ while (maxAlt > 0) {
+ if ((unsigned int) *inputCodes == (unsigned int) *word) {
+ return true;
+ }
+ inputCodes++;
+ maxAlt--;
+ }
+ return false;
+}
+
+bool
+Dictionary::isValidWord(unsigned short *word, int length)
+{
+ if (checkIfDictVersionIsLatest()) {
+ return (isValidWordRec(DICTIONARY_HEADER_SIZE, word, 0, length) != NOT_VALID_WORD);
+ } else {
+ return (isValidWordRec(0, word, 0, length) != NOT_VALID_WORD);
+ }
+}
+
+int
+Dictionary::isValidWordRec(int pos, unsigned short *word, int offset, int length) {
+ // returns address of bigram data of that word
+ // return -99 if not found
+
+ int count = getCount(&pos);
+ unsigned short currentChar = (unsigned short) word[offset];
+ for (int j = 0; j < count; j++) {
+ unsigned short c = getChar(&pos);
+ int terminal = getTerminal(&pos);
+ int childPos = getAddress(&pos);
+ if (c == currentChar) {
+ if (offset == length - 1) {
+ if (terminal) {
+ return (pos+1);
+ }
+ } else {
+ if (childPos != 0) {
+ int t = isValidWordRec(childPos, word, offset + 1, length);
+ if (t > 0) {
+ return t;
+ }
+ }
+ }
+ }
+ if (terminal) {
+ getFreq(&pos);
+ }
+ // There could be two instances of each alphabet - upper and lower case. So continue
+ // looking ...
+ }
+ return NOT_VALID_WORD;
+}
+
+
+} // namespace latinime
diff --git a/java/jni/src/dictionary.h b/java/jni/src/dictionary.h
new file mode 100644
index 0000000..69af565
--- /dev/null
+++ b/java/jni/src/dictionary.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 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.
+ */
+
+#ifndef LATINIME_DICTIONARY_H
+#define LATINIME_DICTIONARY_H
+
+namespace latinime {
+
+// 22-bit address = ~4MB dictionary size limit, which on average would be about 200k-300k words
+#define ADDRESS_MASK 0x3FFFFF
+
+// The bit that decides if an address follows in the next 22 bits
+#define FLAG_ADDRESS_MASK 0x40
+// The bit that decides if this is a terminal node for a word. The node could still have children,
+// if the word has other endings.
+#define FLAG_TERMINAL_MASK 0x80
+
+#define FLAG_BIGRAM_READ 0x80
+#define FLAG_BIGRAM_CHILDEXIST 0x40
+#define FLAG_BIGRAM_CONTINUED 0x80
+#define FLAG_BIGRAM_FREQ 0x7F
+
+class Dictionary {
+public:
+ Dictionary(void *dict, int typedLetterMultipler, int fullWordMultiplier, int dictSize);
+ int getSuggestions(int *codes, int codesSize, unsigned short *outWords, int *frequencies,
+ int maxWordLength, int maxWords, int maxAlternatives, int skipPos,
+ int *nextLetters, int nextLettersSize);
+ int getBigrams(unsigned short *word, int length, int *codes, int codesSize,
+ unsigned short *outWords, int *frequencies, int maxWordLength, int maxBigrams,
+ int maxAlternatives);
+ bool isValidWord(unsigned short *word, int length);
+ void setAsset(void *asset) { mAsset = asset; }
+ void *getAsset() { return mAsset; }
+ ~Dictionary();
+
+private:
+
+ void getVersionNumber();
+ bool checkIfDictVersionIsLatest();
+ int getAddress(int *pos);
+ int getBigramAddress(int *pos, bool advance);
+ int getFreq(int *pos);
+ int getBigramFreq(int *pos);
+ void searchForTerminalNode(int address, int frequency);
+
+ bool getFirstBitOfByte(int *pos) { return (mDict[*pos] & 0x80) > 0; }
+ bool getSecondBitOfByte(int *pos) { return (mDict[*pos] & 0x40) > 0; }
+ bool getTerminal(int *pos) { return (mDict[*pos] & FLAG_TERMINAL_MASK) > 0; }
+ int getCount(int *pos) { return mDict[(*pos)++] & 0xFF; }
+ unsigned short getChar(int *pos);
+ int wideStrLen(unsigned short *str);
+
+ bool sameAsTyped(unsigned short *word, int length);
+ bool checkFirstCharacter(unsigned short *word);
+ bool addWord(unsigned short *word, int length, int frequency);
+ bool addWordBigram(unsigned short *word, int length, int frequency);
+ unsigned short toLowerCase(unsigned short c);
+ void getWordsRec(int pos, int depth, int maxDepth, bool completion, int frequency,
+ int inputIndex, int diffs);
+ int isValidWordRec(int pos, unsigned short *word, int offset, int length);
+ void registerNextLetter(unsigned short c);
+
+ unsigned char *mDict;
+ void *mAsset;
+
+ int *mFrequencies;
+ int *mBigramFreq;
+ int mMaxWords;
+ int mMaxBigrams;
+ int mMaxWordLength;
+ unsigned short *mOutputChars;
+ unsigned short *mBigramChars;
+ int *mInputCodes;
+ int mInputLength;
+ int mMaxAlternatives;
+ unsigned short mWord[128];
+ int mSkipPos;
+ int mMaxEditDistance;
+
+ int mFullWordMultiplier;
+ int mTypedLetterMultiplier;
+ int mDictSize;
+ int *mNextLettersFrequencies;
+ int mNextLettersSize;
+ int mVersion;
+ int mBigram;
+};
+
+// ----------------------------------------------------------------------------
+
+}; // namespace latinime
+
+#endif // LATINIME_DICTIONARY_H
diff --git a/java/proguard.flags b/java/proguard.flags
new file mode 100644
index 0000000..814c8c7
--- /dev/null
+++ b/java/proguard.flags
@@ -0,0 +1,8 @@
+-keep class org.pocketworkstation.pckeyboard.BinaryDictionary {
+ int mDictLength;
+ <init>(...);
+}
+
+-keep class org.pocketworkstation.pckeyboard.Suggest {
+ <init>(...);
+}
diff --git a/java/project.properties b/java/project.properties
new file mode 100644
index 0000000..2cc58fa
--- /dev/null
+++ b/java/project.properties
@@ -0,0 +1,11 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system use,
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+
+# Project target.
+target=android-12
diff --git a/java/res/anim/key_preview_fadein.xml b/java/res/anim/key_preview_fadein.xml
new file mode 100644
index 0000000..9fad7b9
--- /dev/null
+++ b/java/res/anim/key_preview_fadein.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2010, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:interpolator="@android:anim/decelerate_interpolator"
+>
+ <alpha
+ android:fromAlpha="0.5"
+ android:toAlpha="1.0"
+ android:duration="@integer/config_preview_fadein_anim_time" />
+</set>
diff --git a/java/res/anim/key_preview_fadeout.xml b/java/res/anim/key_preview_fadeout.xml
new file mode 100644
index 0000000..7de5123
--- /dev/null
+++ b/java/res/anim/key_preview_fadeout.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2010, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:interpolator="@android:anim/accelerate_interpolator"
+>
+ <alpha
+ android:fromAlpha="1.0"
+ android:toAlpha="0.0"
+ android:duration="@integer/config_preview_fadeout_anim_time" />
+</set>
diff --git a/java/res/anim/mini_keyboard_fadein.xml b/java/res/anim/mini_keyboard_fadein.xml
new file mode 100644
index 0000000..9fad7b9
--- /dev/null
+++ b/java/res/anim/mini_keyboard_fadein.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2010, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:interpolator="@android:anim/decelerate_interpolator"
+>
+ <alpha
+ android:fromAlpha="0.5"
+ android:toAlpha="1.0"
+ android:duration="@integer/config_preview_fadein_anim_time" />
+</set>
diff --git a/java/res/anim/mini_keyboard_fadeout.xml b/java/res/anim/mini_keyboard_fadeout.xml
new file mode 100644
index 0000000..7de5123
--- /dev/null
+++ b/java/res/anim/mini_keyboard_fadeout.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2010, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:interpolator="@android:anim/accelerate_interpolator"
+>
+ <alpha
+ android:fromAlpha="1.0"
+ android:toAlpha="0.0"
+ android:duration="@integer/config_preview_fadeout_anim_time" />
+</set>
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_active_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_active_holo.9.png
new file mode 100644
index 0000000..9aa8db6
--- /dev/null
+++ b/java/res/drawable-hdpi/btn_keyboard_key_dark_active_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal.9.png
new file mode 100644
index 0000000..01fc8ca
--- /dev/null
+++ b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_holo.9.png
new file mode 100644
index 0000000..5e6a9d6
--- /dev/null
+++ b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_lock.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_lock.9.png
new file mode 100644
index 0000000..6596c0f
--- /dev/null
+++ b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_lock.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_lock_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_lock_holo.9.png
new file mode 100644
index 0000000..e5e3f09
--- /dev/null
+++ b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_lock_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_off.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_off.9.png
new file mode 100644
index 0000000..af4017e
--- /dev/null
+++ b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_off.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_off_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_off_holo.9.png
new file mode 100644
index 0000000..a3ba223
--- /dev/null
+++ b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_off_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on.9.png
new file mode 100644
index 0000000..4c35aca
--- /dev/null
+++ b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on_holo.9.png
new file mode 100644
index 0000000..9f4587b
--- /dev/null
+++ b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed.9.png
new file mode 100644
index 0000000..174f345
--- /dev/null
+++ b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_holo.9.png
new file mode 100644
index 0000000..7ec33dd
--- /dev/null
+++ b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off.9.png
new file mode 100644
index 0000000..1fcbd9a
--- /dev/null
+++ b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
new file mode 100644
index 0000000..655bc01
--- /dev/null
+++ b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on.9.png
new file mode 100644
index 0000000..072753f
--- /dev/null
+++ b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
new file mode 100644
index 0000000..138e915
--- /dev/null
+++ b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_light_normal.9.png b/java/res/drawable-hdpi/btn_keyboard_key_light_normal.9.png
new file mode 100644
index 0000000..1ad7460
--- /dev/null
+++ b/java/res/drawable-hdpi/btn_keyboard_key_light_normal.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_light_normal_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_light_normal_holo.9.png
new file mode 100644
index 0000000..baff858
--- /dev/null
+++ b/java/res/drawable-hdpi/btn_keyboard_key_light_normal_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_light_popup_normal.9.png b/java/res/drawable-hdpi/btn_keyboard_key_light_popup_normal.9.png
new file mode 100644
index 0000000..e3a77d6
--- /dev/null
+++ b/java/res/drawable-hdpi/btn_keyboard_key_light_popup_normal.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_light_popup_selected.9.png b/java/res/drawable-hdpi/btn_keyboard_key_light_popup_selected.9.png
new file mode 100644
index 0000000..431c449
--- /dev/null
+++ b/java/res/drawable-hdpi/btn_keyboard_key_light_popup_selected.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_light_pressed.9.png b/java/res/drawable-hdpi/btn_keyboard_key_light_pressed.9.png
new file mode 100644
index 0000000..ccd59d5
--- /dev/null
+++ b/java/res/drawable-hdpi/btn_keyboard_key_light_pressed.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_light_pressed_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_light_pressed_holo.9.png
new file mode 100644
index 0000000..5612c51
--- /dev/null
+++ b/java/res/drawable-hdpi/btn_keyboard_key_light_pressed_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_normal_lock_stone.9.png b/java/res/drawable-hdpi/btn_keyboard_key_normal_lock_stone.9.png
new file mode 100644
index 0000000..85ccaf0
--- /dev/null
+++ b/java/res/drawable-hdpi/btn_keyboard_key_normal_lock_stone.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_normal_off_stone.9.png b/java/res/drawable-hdpi/btn_keyboard_key_normal_off_stone.9.png
new file mode 100644
index 0000000..fad0ec4
--- /dev/null
+++ b/java/res/drawable-hdpi/btn_keyboard_key_normal_off_stone.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_normal_on_stone.9.png b/java/res/drawable-hdpi/btn_keyboard_key_normal_on_stone.9.png
new file mode 100644
index 0000000..215f815
--- /dev/null
+++ b/java/res/drawable-hdpi/btn_keyboard_key_normal_on_stone.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_normal_stone.9.png b/java/res/drawable-hdpi/btn_keyboard_key_normal_stone.9.png
new file mode 100644
index 0000000..88acdd7
--- /dev/null
+++ b/java/res/drawable-hdpi/btn_keyboard_key_normal_stone.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_popup_selected_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_popup_selected_holo.9.png
new file mode 100644
index 0000000..c2e8b37
--- /dev/null
+++ b/java/res/drawable-hdpi/btn_keyboard_key_popup_selected_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_pressed_stone.9.png b/java/res/drawable-hdpi/btn_keyboard_key_pressed_stone.9.png
new file mode 100644
index 0000000..73a8cd1
--- /dev/null
+++ b/java/res/drawable-hdpi/btn_keyboard_key_pressed_stone.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/cancel.png b/java/res/drawable-hdpi/cancel.png
new file mode 100644
index 0000000..506cf99
--- /dev/null
+++ b/java/res/drawable-hdpi/cancel.png
Binary files differ
diff --git a/java/res/drawable-hdpi/candidate_feedback_background.9.png b/java/res/drawable-hdpi/candidate_feedback_background.9.png
new file mode 100644
index 0000000..203c4e6
--- /dev/null
+++ b/java/res/drawable-hdpi/candidate_feedback_background.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/caution.png b/java/res/drawable-hdpi/caution.png
new file mode 100644
index 0000000..5cb6c54
--- /dev/null
+++ b/java/res/drawable-hdpi/caution.png
Binary files differ
diff --git a/java/res/drawable-hdpi/dialog_bubble_step02.9.png b/java/res/drawable-hdpi/dialog_bubble_step02.9.png
new file mode 100644
index 0000000..b338364
--- /dev/null
+++ b/java/res/drawable-hdpi/dialog_bubble_step02.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/dialog_bubble_step07.9.png b/java/res/drawable-hdpi/dialog_bubble_step07.9.png
new file mode 100644
index 0000000..94b9154
--- /dev/null
+++ b/java/res/drawable-hdpi/dialog_bubble_step07.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/highlight_pressed.png b/java/res/drawable-hdpi/highlight_pressed.png
new file mode 100644
index 0000000..ae04901
--- /dev/null
+++ b/java/res/drawable-hdpi/highlight_pressed.png
Binary files differ
diff --git a/java/res/drawable-hdpi/hint_popup.9.png b/java/res/drawable-hdpi/hint_popup.9.png
new file mode 100644
index 0000000..b5ec003
--- /dev/null
+++ b/java/res/drawable-hdpi/hint_popup.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_dialog_keyboard.png b/java/res/drawable-hdpi/ic_dialog_keyboard.png
new file mode 100644
index 0000000..c772956
--- /dev/null
+++ b/java/res/drawable-hdpi/ic_dialog_keyboard.png
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_mic_dialog.png b/java/res/drawable-hdpi/ic_mic_dialog.png
new file mode 100644
index 0000000..349dc4b
--- /dev/null
+++ b/java/res/drawable-hdpi/ic_mic_dialog.png
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_subtype_keyboard.png b/java/res/drawable-hdpi/ic_subtype_keyboard.png
new file mode 100644
index 0000000..7015e26
--- /dev/null
+++ b/java/res/drawable-hdpi/ic_subtype_keyboard.png
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_subtype_mic.png b/java/res/drawable-hdpi/ic_subtype_mic.png
new file mode 100644
index 0000000..cb86a55
--- /dev/null
+++ b/java/res/drawable-hdpi/ic_subtype_mic.png
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_suggest_strip_microphone.png b/java/res/drawable-hdpi/ic_suggest_strip_microphone.png
new file mode 100644
index 0000000..c00b4aa
--- /dev/null
+++ b/java/res/drawable-hdpi/ic_suggest_strip_microphone.png
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_suggest_strip_microphone_swipe.png b/java/res/drawable-hdpi/ic_suggest_strip_microphone_swipe.png
new file mode 100644
index 0000000..256dc3d
--- /dev/null
+++ b/java/res/drawable-hdpi/ic_suggest_strip_microphone_swipe.png
Binary files differ
diff --git a/java/res/drawable-hdpi/icon.png b/java/res/drawable-hdpi/icon.png
new file mode 100644
index 0000000..dad3a84
--- /dev/null
+++ b/java/res/drawable-hdpi/icon.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_background.9.png b/java/res/drawable-hdpi/keyboard_background.9.png
new file mode 100644
index 0000000..edffac5
--- /dev/null
+++ b/java/res/drawable-hdpi/keyboard_background.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_dark_background.9.png b/java/res/drawable-hdpi/keyboard_dark_background.9.png
new file mode 100644
index 0000000..f315cbd
--- /dev/null
+++ b/java/res/drawable-hdpi/keyboard_dark_background.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_key_feedback_background.9.png b/java/res/drawable-hdpi/keyboard_key_feedback_background.9.png
new file mode 100644
index 0000000..762a257
--- /dev/null
+++ b/java/res/drawable-hdpi/keyboard_key_feedback_background.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_key_feedback_more_background.9.png b/java/res/drawable-hdpi/keyboard_key_feedback_more_background.9.png
new file mode 100644
index 0000000..141d2d6
--- /dev/null
+++ b/java/res/drawable-hdpi/keyboard_key_feedback_more_background.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_popup_panel_background.9.png b/java/res/drawable-hdpi/keyboard_popup_panel_background.9.png
new file mode 100644
index 0000000..d6b2c79
--- /dev/null
+++ b/java/res/drawable-hdpi/keyboard_popup_panel_background.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_suggest_strip.9.png b/java/res/drawable-hdpi/keyboard_suggest_strip.9.png
new file mode 100644
index 0000000..0ccdb6a
--- /dev/null
+++ b/java/res/drawable-hdpi/keyboard_suggest_strip.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_suggest_strip_divider.png b/java/res/drawable-hdpi/keyboard_suggest_strip_divider.png
new file mode 100644
index 0000000..7ca3e61
--- /dev/null
+++ b/java/res/drawable-hdpi/keyboard_suggest_strip_divider.png
Binary files differ
diff --git a/java/res/drawable-hdpi/list_selector_background_pressed.9.png b/java/res/drawable-hdpi/list_selector_background_pressed.9.png
new file mode 100644
index 0000000..ba79cf7
--- /dev/null
+++ b/java/res/drawable-hdpi/list_selector_background_pressed.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/mic_slash.png b/java/res/drawable-hdpi/mic_slash.png
new file mode 100644
index 0000000..dc8da62
--- /dev/null
+++ b/java/res/drawable-hdpi/mic_slash.png
Binary files differ
diff --git a/java/res/drawable-hdpi/ok_cancel.png b/java/res/drawable-hdpi/ok_cancel.png
new file mode 100644
index 0000000..f11e57a
--- /dev/null
+++ b/java/res/drawable-hdpi/ok_cancel.png
Binary files differ
diff --git a/java/res/drawable-hdpi/speak_now_level0.png b/java/res/drawable-hdpi/speak_now_level0.png
new file mode 100644
index 0000000..342849c
--- /dev/null
+++ b/java/res/drawable-hdpi/speak_now_level0.png
Binary files differ
diff --git a/java/res/drawable-hdpi/speak_now_level1.png b/java/res/drawable-hdpi/speak_now_level1.png
new file mode 100644
index 0000000..8947a43
--- /dev/null
+++ b/java/res/drawable-hdpi/speak_now_level1.png
Binary files differ
diff --git a/java/res/drawable-hdpi/speak_now_level2.png b/java/res/drawable-hdpi/speak_now_level2.png
new file mode 100644
index 0000000..44fc58c
--- /dev/null
+++ b/java/res/drawable-hdpi/speak_now_level2.png
Binary files differ
diff --git a/java/res/drawable-hdpi/speak_now_level3.png b/java/res/drawable-hdpi/speak_now_level3.png
new file mode 100644
index 0000000..cfa5c1b
--- /dev/null
+++ b/java/res/drawable-hdpi/speak_now_level3.png
Binary files differ
diff --git a/java/res/drawable-hdpi/speak_now_level4.png b/java/res/drawable-hdpi/speak_now_level4.png
new file mode 100644
index 0000000..a050d88
--- /dev/null
+++ b/java/res/drawable-hdpi/speak_now_level4.png
Binary files differ
diff --git a/java/res/drawable-hdpi/speak_now_level5.png b/java/res/drawable-hdpi/speak_now_level5.png
new file mode 100644
index 0000000..8cd5ae7
--- /dev/null
+++ b/java/res/drawable-hdpi/speak_now_level5.png
Binary files differ
diff --git a/java/res/drawable-hdpi/speak_now_level6.png b/java/res/drawable-hdpi/speak_now_level6.png
new file mode 100644
index 0000000..9f4481e
--- /dev/null
+++ b/java/res/drawable-hdpi/speak_now_level6.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_123_mic.png b/java/res/drawable-hdpi/sym_keyboard_123_mic.png
new file mode 100644
index 0000000..6266980
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_123_mic.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_delete.png b/java/res/drawable-hdpi/sym_keyboard_delete.png
new file mode 100644
index 0000000..459ebcf
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_delete.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_done.png b/java/res/drawable-hdpi/sym_keyboard_done.png
new file mode 100644
index 0000000..471c502
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_done.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_feedback_123_mic.png b/java/res/drawable-hdpi/sym_keyboard_feedback_123_mic.png
new file mode 100644
index 0000000..eef7896
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_feedback_123_mic.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_feedback_delete.png b/java/res/drawable-hdpi/sym_keyboard_feedback_delete.png
new file mode 100644
index 0000000..8322e8e
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_feedback_delete.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_feedback_done.png b/java/res/drawable-hdpi/sym_keyboard_feedback_done.png
new file mode 100644
index 0000000..7015e26
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_feedback_done.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_feedback_language_arrows_left.png b/java/res/drawable-hdpi/sym_keyboard_feedback_language_arrows_left.png
new file mode 100644
index 0000000..889477c
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_feedback_language_arrows_left.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_feedback_language_arrows_right.png b/java/res/drawable-hdpi/sym_keyboard_feedback_language_arrows_right.png
new file mode 100644
index 0000000..b0f6d7f
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_feedback_language_arrows_right.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_feedback_mic.png b/java/res/drawable-hdpi/sym_keyboard_feedback_mic.png
new file mode 100644
index 0000000..f82c33a
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_feedback_mic.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_feedback_numalt.png b/java/res/drawable-hdpi/sym_keyboard_feedback_numalt.png
new file mode 100644
index 0000000..819236c
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_feedback_numalt.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_feedback_return.png b/java/res/drawable-hdpi/sym_keyboard_feedback_return.png
new file mode 100644
index 0000000..f038d3a
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_feedback_return.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_feedback_search.png b/java/res/drawable-hdpi/sym_keyboard_feedback_search.png
new file mode 100644
index 0000000..337f9e4
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_feedback_search.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_feedback_settings.png b/java/res/drawable-hdpi/sym_keyboard_feedback_settings.png
new file mode 100644
index 0000000..8a02be0
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_feedback_settings.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_feedback_shift.png b/java/res/drawable-hdpi/sym_keyboard_feedback_shift.png
new file mode 100644
index 0000000..abf15f8
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_feedback_shift.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_feedback_shift_locked.png b/java/res/drawable-hdpi/sym_keyboard_feedback_shift_locked.png
new file mode 100644
index 0000000..1fd822e
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_feedback_shift_locked.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_feedback_space.png b/java/res/drawable-hdpi/sym_keyboard_feedback_space.png
new file mode 100644
index 0000000..70debca
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_feedback_space.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_feedback_tab.png b/java/res/drawable-hdpi/sym_keyboard_feedback_tab.png
new file mode 100644
index 0000000..d2efb16
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_feedback_tab.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_language_arrows_left.png b/java/res/drawable-hdpi/sym_keyboard_language_arrows_left.png
new file mode 100644
index 0000000..dcc4bd5
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_language_arrows_left.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_language_arrows_right.png b/java/res/drawable-hdpi/sym_keyboard_language_arrows_right.png
new file mode 100644
index 0000000..ecf61a9
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_language_arrows_right.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_mic.png b/java/res/drawable-hdpi/sym_keyboard_mic.png
new file mode 100644
index 0000000..c8dca62
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_mic.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_num0.png b/java/res/drawable-hdpi/sym_keyboard_num0.png
new file mode 100644
index 0000000..10ac70b
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_num0.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_num1.png b/java/res/drawable-hdpi/sym_keyboard_num1.png
new file mode 100644
index 0000000..0fc03ef
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_num1.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_num2.png b/java/res/drawable-hdpi/sym_keyboard_num2.png
new file mode 100644
index 0000000..283560b
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_num2.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_num3.png b/java/res/drawable-hdpi/sym_keyboard_num3.png
new file mode 100644
index 0000000..9a3b329
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_num3.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_num4.png b/java/res/drawable-hdpi/sym_keyboard_num4.png
new file mode 100644
index 0000000..f13ff1a
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_num4.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_num5.png b/java/res/drawable-hdpi/sym_keyboard_num5.png
new file mode 100644
index 0000000..c251329
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_num5.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_num6.png b/java/res/drawable-hdpi/sym_keyboard_num6.png
new file mode 100644
index 0000000..4acba4c
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_num6.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_num7.png b/java/res/drawable-hdpi/sym_keyboard_num7.png
new file mode 100644
index 0000000..14931c1
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_num7.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_num8.png b/java/res/drawable-hdpi/sym_keyboard_num8.png
new file mode 100644
index 0000000..d4973fd
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_num8.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_num9.png b/java/res/drawable-hdpi/sym_keyboard_num9.png
new file mode 100644
index 0000000..49cec66
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_num9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_numalt.png b/java/res/drawable-hdpi/sym_keyboard_numalt.png
new file mode 100644
index 0000000..3cc5311
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_numalt.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_numpound.png b/java/res/drawable-hdpi/sym_keyboard_numpound.png
new file mode 100644
index 0000000..d091339
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_numpound.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_numstar.png b/java/res/drawable-hdpi/sym_keyboard_numstar.png
new file mode 100644
index 0000000..e838e16
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_numstar.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_return.png b/java/res/drawable-hdpi/sym_keyboard_return.png
new file mode 100644
index 0000000..9d97e1e
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_return.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_search.png b/java/res/drawable-hdpi/sym_keyboard_search.png
new file mode 100644
index 0000000..1aa22d7
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_search.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_settings.png b/java/res/drawable-hdpi/sym_keyboard_settings.png
new file mode 100644
index 0000000..35d1ed6
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_settings.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_shift.png b/java/res/drawable-hdpi/sym_keyboard_shift.png
new file mode 100644
index 0000000..bf217d1
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_shift.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_shift_locked.png b/java/res/drawable-hdpi/sym_keyboard_shift_locked.png
new file mode 100644
index 0000000..d11b397
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_shift_locked.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_space.png b/java/res/drawable-hdpi/sym_keyboard_space.png
new file mode 100644
index 0000000..fcd20de
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_space.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_space_led.9.png b/java/res/drawable-hdpi/sym_keyboard_space_led.9.png
new file mode 100644
index 0000000..2c6f4a9
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_space_led.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_tab.png b/java/res/drawable-hdpi/sym_keyboard_tab.png
new file mode 100644
index 0000000..51d17d9
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_tab.png
Binary files differ
diff --git a/java/res/drawable-hdpi/voice_ime_background.9.png b/java/res/drawable-hdpi/voice_ime_background.9.png
new file mode 100644
index 0000000..4286852
--- /dev/null
+++ b/java/res/drawable-hdpi/voice_ime_background.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/voice_swipe_hint.png b/java/res/drawable-hdpi/voice_swipe_hint.png
new file mode 100644
index 0000000..130f83a
--- /dev/null
+++ b/java/res/drawable-hdpi/voice_swipe_hint.png
Binary files differ
diff --git a/java/res/drawable-hdpi/working.png b/java/res/drawable-hdpi/working.png
new file mode 100755
index 0000000..5ea7023
--- /dev/null
+++ b/java/res/drawable-hdpi/working.png
Binary files differ
diff --git a/java/res/drawable-ldpi/icon.png b/java/res/drawable-ldpi/icon.png
new file mode 100644
index 0000000..154e656
--- /dev/null
+++ b/java/res/drawable-ldpi/icon.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_active_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_active_holo.9.png
new file mode 100644
index 0000000..e810c77
--- /dev/null
+++ b/java/res/drawable-mdpi/btn_keyboard_key_dark_active_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal.9.png
new file mode 100644
index 0000000..4e337fa
--- /dev/null
+++ b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_holo.9.png
new file mode 100644
index 0000000..d449d76
--- /dev/null
+++ b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_lock.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_lock.9.png
new file mode 100644
index 0000000..c203bdf
--- /dev/null
+++ b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_lock.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_lock_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_lock_holo.9.png
new file mode 100644
index 0000000..678ce10
--- /dev/null
+++ b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_lock_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_off.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_off.9.png
new file mode 100644
index 0000000..fe18497
--- /dev/null
+++ b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_off.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_off_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_off_holo.9.png
new file mode 100644
index 0000000..fa24d59
--- /dev/null
+++ b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_off_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on.9.png
new file mode 100644
index 0000000..00aab3d
--- /dev/null
+++ b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on_holo.9.png
new file mode 100644
index 0000000..f3fc641
--- /dev/null
+++ b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed.9.png
new file mode 100644
index 0000000..ac0bfd3
--- /dev/null
+++ b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_holo.9.png
new file mode 100644
index 0000000..8f340d3
--- /dev/null
+++ b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off.9.png
new file mode 100644
index 0000000..ea2f357
--- /dev/null
+++ b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
new file mode 100644
index 0000000..53ea5f8
--- /dev/null
+++ b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on.9.png
new file mode 100644
index 0000000..6195ac0
--- /dev/null
+++ b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
new file mode 100644
index 0000000..69c84e7
--- /dev/null
+++ b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_light_normal.9.png b/java/res/drawable-mdpi/btn_keyboard_key_light_normal.9.png
new file mode 100644
index 0000000..50cd06a
--- /dev/null
+++ b/java/res/drawable-mdpi/btn_keyboard_key_light_normal.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_light_normal_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_light_normal_holo.9.png
new file mode 100644
index 0000000..976083f
--- /dev/null
+++ b/java/res/drawable-mdpi/btn_keyboard_key_light_normal_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_light_popup_normal.9.png b/java/res/drawable-mdpi/btn_keyboard_key_light_popup_normal.9.png
new file mode 100644
index 0000000..02d0fcf
--- /dev/null
+++ b/java/res/drawable-mdpi/btn_keyboard_key_light_popup_normal.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_light_popup_selected.9.png b/java/res/drawable-mdpi/btn_keyboard_key_light_popup_selected.9.png
new file mode 100644
index 0000000..125ff13
--- /dev/null
+++ b/java/res/drawable-mdpi/btn_keyboard_key_light_popup_selected.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_light_pressed.9.png b/java/res/drawable-mdpi/btn_keyboard_key_light_pressed.9.png
new file mode 100644
index 0000000..7ce52f0
--- /dev/null
+++ b/java/res/drawable-mdpi/btn_keyboard_key_light_pressed.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_light_pressed_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_light_pressed_holo.9.png
new file mode 100644
index 0000000..c39dd4a
--- /dev/null
+++ b/java/res/drawable-mdpi/btn_keyboard_key_light_pressed_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_normal_lock_stone.9.png b/java/res/drawable-mdpi/btn_keyboard_key_normal_lock_stone.9.png
new file mode 100644
index 0000000..2ced914
--- /dev/null
+++ b/java/res/drawable-mdpi/btn_keyboard_key_normal_lock_stone.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_normal_off_stone.9.png b/java/res/drawable-mdpi/btn_keyboard_key_normal_off_stone.9.png
new file mode 100644
index 0000000..fad0ec4
--- /dev/null
+++ b/java/res/drawable-mdpi/btn_keyboard_key_normal_off_stone.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_normal_on_stone.9.png b/java/res/drawable-mdpi/btn_keyboard_key_normal_on_stone.9.png
new file mode 100644
index 0000000..215f815
--- /dev/null
+++ b/java/res/drawable-mdpi/btn_keyboard_key_normal_on_stone.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_normal_stone.9.png b/java/res/drawable-mdpi/btn_keyboard_key_normal_stone.9.png
new file mode 100644
index 0000000..88acdd7
--- /dev/null
+++ b/java/res/drawable-mdpi/btn_keyboard_key_normal_stone.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_popup_selected_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_popup_selected_holo.9.png
new file mode 100644
index 0000000..93a6e79
--- /dev/null
+++ b/java/res/drawable-mdpi/btn_keyboard_key_popup_selected_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_pressed_stone.9.png b/java/res/drawable-mdpi/btn_keyboard_key_pressed_stone.9.png
new file mode 100644
index 0000000..1ed3065
--- /dev/null
+++ b/java/res/drawable-mdpi/btn_keyboard_key_pressed_stone.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/cancel.png b/java/res/drawable-mdpi/cancel.png
new file mode 100644
index 0000000..713a378
--- /dev/null
+++ b/java/res/drawable-mdpi/cancel.png
Binary files differ
diff --git a/java/res/drawable-mdpi/candidate_feedback_background.9.png b/java/res/drawable-mdpi/candidate_feedback_background.9.png
new file mode 100644
index 0000000..2a80f09
--- /dev/null
+++ b/java/res/drawable-mdpi/candidate_feedback_background.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/caution.png b/java/res/drawable-mdpi/caution.png
new file mode 100644
index 0000000..eaef534
--- /dev/null
+++ b/java/res/drawable-mdpi/caution.png
Binary files differ
diff --git a/java/res/drawable-mdpi/dialog_bubble_step02.9.png b/java/res/drawable-mdpi/dialog_bubble_step02.9.png
new file mode 100644
index 0000000..d77f85f
--- /dev/null
+++ b/java/res/drawable-mdpi/dialog_bubble_step02.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/dialog_bubble_step07.9.png b/java/res/drawable-mdpi/dialog_bubble_step07.9.png
new file mode 100644
index 0000000..80f4a0e
--- /dev/null
+++ b/java/res/drawable-mdpi/dialog_bubble_step07.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/highlight_pressed.png b/java/res/drawable-mdpi/highlight_pressed.png
new file mode 100644
index 0000000..d27f106
--- /dev/null
+++ b/java/res/drawable-mdpi/highlight_pressed.png
Binary files differ
diff --git a/java/res/drawable-mdpi/hint_popup.9.png b/java/res/drawable-mdpi/hint_popup.9.png
new file mode 100644
index 0000000..444cc26
--- /dev/null
+++ b/java/res/drawable-mdpi/hint_popup.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/ic_dialog_keyboard.png b/java/res/drawable-mdpi/ic_dialog_keyboard.png
new file mode 100644
index 0000000..9a5aada
--- /dev/null
+++ b/java/res/drawable-mdpi/ic_dialog_keyboard.png
Binary files differ
diff --git a/java/res/drawable-mdpi/ic_mic_dialog.png b/java/res/drawable-mdpi/ic_mic_dialog.png
new file mode 100644
index 0000000..77613ca
--- /dev/null
+++ b/java/res/drawable-mdpi/ic_mic_dialog.png
Binary files differ
diff --git a/java/res/drawable-mdpi/ic_subtype_keyboard.png b/java/res/drawable-mdpi/ic_subtype_keyboard.png
new file mode 100644
index 0000000..0d7ebd4
--- /dev/null
+++ b/java/res/drawable-mdpi/ic_subtype_keyboard.png
Binary files differ
diff --git a/java/res/drawable-mdpi/ic_subtype_mic.png b/java/res/drawable-mdpi/ic_subtype_mic.png
new file mode 100644
index 0000000..247d5b3
--- /dev/null
+++ b/java/res/drawable-mdpi/ic_subtype_mic.png
Binary files differ
diff --git a/java/res/drawable-mdpi/ic_suggest_strip_microphone.png b/java/res/drawable-mdpi/ic_suggest_strip_microphone.png
new file mode 100644
index 0000000..18f314a
--- /dev/null
+++ b/java/res/drawable-mdpi/ic_suggest_strip_microphone.png
Binary files differ
diff --git a/java/res/drawable-mdpi/ic_suggest_strip_microphone_swipe.png b/java/res/drawable-mdpi/ic_suggest_strip_microphone_swipe.png
new file mode 100644
index 0000000..ff629b6
--- /dev/null
+++ b/java/res/drawable-mdpi/ic_suggest_strip_microphone_swipe.png
Binary files differ
diff --git a/java/res/drawable-mdpi/icon.png b/java/res/drawable-mdpi/icon.png
new file mode 100644
index 0000000..0f2d145
--- /dev/null
+++ b/java/res/drawable-mdpi/icon.png
Binary files differ
diff --git a/java/res/drawable-mdpi/keyboard_background.9.png b/java/res/drawable-mdpi/keyboard_background.9.png
new file mode 100644
index 0000000..2bd4b62
--- /dev/null
+++ b/java/res/drawable-mdpi/keyboard_background.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/keyboard_dark_background.9.png b/java/res/drawable-mdpi/keyboard_dark_background.9.png
new file mode 100644
index 0000000..4f81704
--- /dev/null
+++ b/java/res/drawable-mdpi/keyboard_dark_background.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/keyboard_key_feedback_background.9.png b/java/res/drawable-mdpi/keyboard_key_feedback_background.9.png
new file mode 100644
index 0000000..a84c19c
--- /dev/null
+++ b/java/res/drawable-mdpi/keyboard_key_feedback_background.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/keyboard_key_feedback_more_background.9.png b/java/res/drawable-mdpi/keyboard_key_feedback_more_background.9.png
new file mode 100644
index 0000000..82513aa
--- /dev/null
+++ b/java/res/drawable-mdpi/keyboard_key_feedback_more_background.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/keyboard_popup_panel_background.9.png b/java/res/drawable-mdpi/keyboard_popup_panel_background.9.png
new file mode 100644
index 0000000..0d9ab97
--- /dev/null
+++ b/java/res/drawable-mdpi/keyboard_popup_panel_background.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/keyboard_suggest_strip.9.png b/java/res/drawable-mdpi/keyboard_suggest_strip.9.png
new file mode 100644
index 0000000..fa6c0fe
--- /dev/null
+++ b/java/res/drawable-mdpi/keyboard_suggest_strip.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/keyboard_suggest_strip_divider.png b/java/res/drawable-mdpi/keyboard_suggest_strip_divider.png
new file mode 100644
index 0000000..3639363
--- /dev/null
+++ b/java/res/drawable-mdpi/keyboard_suggest_strip_divider.png
Binary files differ
diff --git a/java/res/drawable-mdpi/list_selector_background_pressed.9.png b/java/res/drawable-mdpi/list_selector_background_pressed.9.png
new file mode 100644
index 0000000..02b4e9a
--- /dev/null
+++ b/java/res/drawable-mdpi/list_selector_background_pressed.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/mic_slash.png b/java/res/drawable-mdpi/mic_slash.png
new file mode 100644
index 0000000..d04b563
--- /dev/null
+++ b/java/res/drawable-mdpi/mic_slash.png
Binary files differ
diff --git a/java/res/drawable-mdpi/ok_cancel.png b/java/res/drawable-mdpi/ok_cancel.png
new file mode 100644
index 0000000..20d10f9
--- /dev/null
+++ b/java/res/drawable-mdpi/ok_cancel.png
Binary files differ
diff --git a/java/res/drawable-mdpi/speak_now_level0.png b/java/res/drawable-mdpi/speak_now_level0.png
new file mode 100644
index 0000000..5bd1360
--- /dev/null
+++ b/java/res/drawable-mdpi/speak_now_level0.png
Binary files differ
diff --git a/java/res/drawable-mdpi/speak_now_level1.png b/java/res/drawable-mdpi/speak_now_level1.png
new file mode 100644
index 0000000..ccb76b8
--- /dev/null
+++ b/java/res/drawable-mdpi/speak_now_level1.png
Binary files differ
diff --git a/java/res/drawable-mdpi/speak_now_level2.png b/java/res/drawable-mdpi/speak_now_level2.png
new file mode 100644
index 0000000..715f900
--- /dev/null
+++ b/java/res/drawable-mdpi/speak_now_level2.png
Binary files differ
diff --git a/java/res/drawable-mdpi/speak_now_level3.png b/java/res/drawable-mdpi/speak_now_level3.png
new file mode 100644
index 0000000..725248a
--- /dev/null
+++ b/java/res/drawable-mdpi/speak_now_level3.png
Binary files differ
diff --git a/java/res/drawable-mdpi/speak_now_level4.png b/java/res/drawable-mdpi/speak_now_level4.png
new file mode 100644
index 0000000..ff6c50b
--- /dev/null
+++ b/java/res/drawable-mdpi/speak_now_level4.png
Binary files differ
diff --git a/java/res/drawable-mdpi/speak_now_level5.png b/java/res/drawable-mdpi/speak_now_level5.png
new file mode 100644
index 0000000..a5d6b89
--- /dev/null
+++ b/java/res/drawable-mdpi/speak_now_level5.png
Binary files differ
diff --git a/java/res/drawable-mdpi/speak_now_level6.png b/java/res/drawable-mdpi/speak_now_level6.png
new file mode 100644
index 0000000..dcdb48d
--- /dev/null
+++ b/java/res/drawable-mdpi/speak_now_level6.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_123_mic.png b/java/res/drawable-mdpi/sym_keyboard_123_mic.png
new file mode 100644
index 0000000..35afe08
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_123_mic.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_delete.png b/java/res/drawable-mdpi/sym_keyboard_delete.png
new file mode 100644
index 0000000..1b0f3f8
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_delete.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_done.png b/java/res/drawable-mdpi/sym_keyboard_done.png
new file mode 100644
index 0000000..c0d6d13
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_done.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_feedback_123_mic.png b/java/res/drawable-mdpi/sym_keyboard_feedback_123_mic.png
new file mode 100644
index 0000000..c556c35
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_feedback_123_mic.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_feedback_delete.png b/java/res/drawable-mdpi/sym_keyboard_feedback_delete.png
new file mode 100644
index 0000000..a79f158
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_feedback_delete.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_feedback_done.png b/java/res/drawable-mdpi/sym_keyboard_feedback_done.png
new file mode 100644
index 0000000..0d7ebd4
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_feedback_done.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_feedback_language_arrows_left.png b/java/res/drawable-mdpi/sym_keyboard_feedback_language_arrows_left.png
new file mode 100644
index 0000000..eecb026
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_feedback_language_arrows_left.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_feedback_language_arrows_right.png b/java/res/drawable-mdpi/sym_keyboard_feedback_language_arrows_right.png
new file mode 100644
index 0000000..7e10ae3
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_feedback_language_arrows_right.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_feedback_mic.png b/java/res/drawable-mdpi/sym_keyboard_feedback_mic.png
new file mode 100644
index 0000000..3ed0782
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_feedback_mic.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_feedback_numalt.png b/java/res/drawable-mdpi/sym_keyboard_feedback_numalt.png
new file mode 100644
index 0000000..bc8f1cf
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_feedback_numalt.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_feedback_return.png b/java/res/drawable-mdpi/sym_keyboard_feedback_return.png
new file mode 100644
index 0000000..dd99ff3
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_feedback_return.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_feedback_search.png b/java/res/drawable-mdpi/sym_keyboard_feedback_search.png
new file mode 100644
index 0000000..6b8e01d
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_feedback_search.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_feedback_settings.png b/java/res/drawable-mdpi/sym_keyboard_feedback_settings.png
new file mode 100644
index 0000000..03bad18
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_feedback_settings.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_feedback_shift.png b/java/res/drawable-mdpi/sym_keyboard_feedback_shift.png
new file mode 100644
index 0000000..d563575
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_feedback_shift.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_feedback_shift_locked.png b/java/res/drawable-mdpi/sym_keyboard_feedback_shift_locked.png
new file mode 100644
index 0000000..494524a
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_feedback_shift_locked.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_feedback_space.png b/java/res/drawable-mdpi/sym_keyboard_feedback_space.png
new file mode 100644
index 0000000..36eb60c
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_feedback_space.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_feedback_tab.png b/java/res/drawable-mdpi/sym_keyboard_feedback_tab.png
new file mode 100644
index 0000000..a10dc8f
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_feedback_tab.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_language_arrows_left.png b/java/res/drawable-mdpi/sym_keyboard_language_arrows_left.png
new file mode 100644
index 0000000..7067a8b
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_language_arrows_left.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_language_arrows_right.png b/java/res/drawable-mdpi/sym_keyboard_language_arrows_right.png
new file mode 100644
index 0000000..f7a133d
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_language_arrows_right.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_mic.png b/java/res/drawable-mdpi/sym_keyboard_mic.png
new file mode 100644
index 0000000..e926b3f
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_mic.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_num0.png b/java/res/drawable-mdpi/sym_keyboard_num0.png
new file mode 100644
index 0000000..e7007c8
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_num0.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_num1.png b/java/res/drawable-mdpi/sym_keyboard_num1.png
new file mode 100644
index 0000000..aaac11b
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_num1.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_num2.png b/java/res/drawable-mdpi/sym_keyboard_num2.png
new file mode 100644
index 0000000..4372eb8
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_num2.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_num3.png b/java/res/drawable-mdpi/sym_keyboard_num3.png
new file mode 100644
index 0000000..6f54c85
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_num3.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_num4.png b/java/res/drawable-mdpi/sym_keyboard_num4.png
new file mode 100644
index 0000000..3e50bb9
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_num4.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_num5.png b/java/res/drawable-mdpi/sym_keyboard_num5.png
new file mode 100644
index 0000000..c39ef44
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_num5.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_num6.png b/java/res/drawable-mdpi/sym_keyboard_num6.png
new file mode 100644
index 0000000..ea88ceb
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_num6.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_num7.png b/java/res/drawable-mdpi/sym_keyboard_num7.png
new file mode 100644
index 0000000..ce800ba
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_num7.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_num8.png b/java/res/drawable-mdpi/sym_keyboard_num8.png
new file mode 100644
index 0000000..1a8ff94
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_num8.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_num9.png b/java/res/drawable-mdpi/sym_keyboard_num9.png
new file mode 100644
index 0000000..8b344c0
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_num9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_numalt.png b/java/res/drawable-mdpi/sym_keyboard_numalt.png
new file mode 100644
index 0000000..32a2cf3
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_numalt.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_numpound.png b/java/res/drawable-mdpi/sym_keyboard_numpound.png
new file mode 100644
index 0000000..b2419d9
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_numpound.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_numstar.png b/java/res/drawable-mdpi/sym_keyboard_numstar.png
new file mode 100644
index 0000000..cb66f96
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_numstar.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_return.png b/java/res/drawable-mdpi/sym_keyboard_return.png
new file mode 100644
index 0000000..0c10f00
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_return.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_search.png b/java/res/drawable-mdpi/sym_keyboard_search.png
new file mode 100644
index 0000000..614f85f
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_search.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_settings.png b/java/res/drawable-mdpi/sym_keyboard_settings.png
new file mode 100644
index 0000000..ad7618f
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_settings.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_shift.png b/java/res/drawable-mdpi/sym_keyboard_shift.png
new file mode 100644
index 0000000..5109b04
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_shift.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_shift_lock.png b/java/res/drawable-mdpi/sym_keyboard_shift_lock.png
new file mode 100644
index 0000000..244179c
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_shift_lock.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_shift_locked.png b/java/res/drawable-mdpi/sym_keyboard_shift_locked.png
new file mode 100644
index 0000000..244179c
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_shift_locked.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_space.png b/java/res/drawable-mdpi/sym_keyboard_space.png
new file mode 100644
index 0000000..cbe4a88
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_space.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_space_led.9.png b/java/res/drawable-mdpi/sym_keyboard_space_led.9.png
new file mode 100644
index 0000000..1c1ca2c
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_space_led.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_tab.png b/java/res/drawable-mdpi/sym_keyboard_tab.png
new file mode 100644
index 0000000..eddb9a5
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_tab.png
Binary files differ
diff --git a/java/res/drawable-mdpi/voice_ime_background.9.png b/java/res/drawable-mdpi/voice_ime_background.9.png
new file mode 100644
index 0000000..9b15bc2
--- /dev/null
+++ b/java/res/drawable-mdpi/voice_ime_background.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/voice_swipe_hint.png b/java/res/drawable-mdpi/voice_swipe_hint.png
new file mode 100644
index 0000000..bb88732
--- /dev/null
+++ b/java/res/drawable-mdpi/voice_swipe_hint.png
Binary files differ
diff --git a/java/res/drawable-mdpi/working.png b/java/res/drawable-mdpi/working.png
new file mode 100644
index 0000000..4a930c5
--- /dev/null
+++ b/java/res/drawable-mdpi/working.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_active_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_active_holo.9.png
new file mode 100644
index 0000000..d990c02
--- /dev/null
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_dark_active_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_holo.9.png
new file mode 100644
index 0000000..d2cd029
--- /dev/null
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_lock_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_lock_holo.9.png
new file mode 100644
index 0000000..6b4ec0b
--- /dev/null
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_lock_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_off_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_off_holo.9.png
new file mode 100644
index 0000000..bca39cf
--- /dev/null
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_off_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_on_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_on_holo.9.png
new file mode 100644
index 0000000..ab8fb2e
--- /dev/null
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_on_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_holo.9.png
new file mode 100644
index 0000000..3871689
--- /dev/null
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_off_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
new file mode 100644
index 0000000..9125063
--- /dev/null
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_on_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
new file mode 100644
index 0000000..35ce67f
--- /dev/null
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_light_normal_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_light_normal_holo.9.png
new file mode 100644
index 0000000..b26f1d2
--- /dev/null
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_light_normal_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_light_pressed_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_light_pressed_holo.9.png
new file mode 100644
index 0000000..c23a4b2
--- /dev/null
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_light_pressed_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_popup_selected_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_popup_selected_holo.9.png
new file mode 100644
index 0000000..0c7bfda
--- /dev/null
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_popup_selected_holo.9.png
Binary files differ
diff --git a/java/res/drawable/btn_keyboard_key_gingerbread.xml b/java/res/drawable/btn_keyboard_key_gingerbread.xml
new file mode 100644
index 0000000..112fb61
--- /dev/null
+++ b/java/res/drawable/btn_keyboard_key_gingerbread.xml
@@ -0,0 +1,45 @@
+<?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_dark_pressed" />
+ <item android:state_single="true"
+ android:drawable="@drawable/btn_keyboard_key_dark_normal" />
+
+ <!-- Toggle keys. Use checkable/checked state. -->
+ <!-- The lock icon is a copy of the 'on' icon, hue shifted by -75 using Gimp's Colors/Hue&Saturation -->
+
+ <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"
+ android:drawable="@drawable/btn_keyboard_key_dark_pressed_off" />
+ <item android:state_checkable="true" android:state_checked="true" android:state_active="true"
+ android:drawable="@drawable/btn_keyboard_key_dark_normal_lock" />
+ <item android:state_checkable="true" android:state_checked="true"
+ android:drawable="@drawable/btn_keyboard_key_dark_normal_on" />
+ <item android:state_checkable="true"
+ android:drawable="@drawable/btn_keyboard_key_dark_normal_off" />
+
+ <!-- Normal keys -->
+
+ <item android:state_pressed="true"
+ android:drawable="@drawable/btn_keyboard_key_light_pressed" />
+ <item android:drawable="@drawable/btn_keyboard_key_light_normal" />
+</selector>
diff --git a/java/res/drawable/btn_keyboard_key_gingerbread_popup.xml b/java/res/drawable/btn_keyboard_key_gingerbread_popup.xml
new file mode 100644
index 0000000..9b6d23b
--- /dev/null
+++ b/java/res/drawable/btn_keyboard_key_gingerbread_popup.xml
@@ -0,0 +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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true"
+ android:drawable="@drawable/btn_keyboard_key_light_popup_selected" />
+ <item android:drawable="@drawable/btn_keyboard_key_light_popup_normal" />
+</selector>
diff --git a/java/res/drawable/btn_keyboard_key_ics.xml b/java/res/drawable/btn_keyboard_key_ics.xml
new file mode 100644
index 0000000..a77dde1
--- /dev/null
+++ b/java/res/drawable/btn_keyboard_key_ics.xml
@@ -0,0 +1,52 @@
+<?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.
+
+
+ Unused 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" />
+-->
+
+<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" />
+
+ <!-- Toggle keys. Use checkable/checked state. -->
+ <!-- The lock icon is a copy of the 'on' icon, hue shifted by +164 using Gimp's Colors/Hue&Saturation -->
+
+ <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"
+ android:drawable="@drawable/btn_keyboard_key_dark_pressed_off_holo" />
+ <item android:state_checkable="true" android:state_checked="true" android:state_active="true"
+ android:drawable="@drawable/btn_keyboard_key_dark_normal_lock_holo" />
+ <item android:state_checkable="true" android:state_checked="true"
+ android:drawable="@drawable/btn_keyboard_key_dark_normal_on_holo" />
+ <item android:state_checkable="true"
+ android:drawable="@drawable/btn_keyboard_key_dark_normal_off_holo" />
+
+ <!-- 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" />
+</selector>
diff --git a/java/res/drawable/btn_keyboard_key_stone.xml b/java/res/drawable/btn_keyboard_key_stone.xml
new file mode 100644
index 0000000..7cb12b3
--- /dev/null
+++ b/java/res/drawable/btn_keyboard_key_stone.xml
@@ -0,0 +1,40 @@
+<?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. -->
+ <!-- The lock icon is a copy of the 'on' icon, hue shifted by -75 using Gimp's Colors/Hue&Saturation -->
+
+ <item android:state_checkable="true" android:state_checked="true" android:state_active="true" android:state_pressed="true"
+ android:drawable="@drawable/btn_keyboard_key_normal_lock_stone" />
+ <item android:state_checkable="true" android:state_checked="true" android:state_active="true"
+ android:drawable="@drawable/btn_keyboard_key_normal_lock_stone" />
+ <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_pressed_stone" />
+ <item android:drawable="@drawable/btn_keyboard_key_normal_stone" />
+</selector>
diff --git a/java/res/drawable/ic_suggest_scroll_background.xml b/java/res/drawable/ic_suggest_scroll_background.xml
new file mode 100644
index 0000000..9d246e4
--- /dev/null
+++ b/java/res/drawable/ic_suggest_scroll_background.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <item android:state_pressed="false"
+ android:drawable="@android:color/transparent" />
+
+ <item android:state_pressed="true"
+ android:drawable="@drawable/highlight_pressed" />
+
+</selector> \ No newline at end of file
diff --git a/java/res/layout/bubble_text.xml b/java/res/layout/bubble_text.xml
new file mode 100644
index 0000000..c3957b6
--- /dev/null
+++ b/java/res/layout/bubble_text.xml
@@ -0,0 +1,30 @@
+<?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.
+*/
+-->
+
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="14sp"
+ android:textColor="?android:attr/textColorPrimary"
+ android:minWidth="32dip"
+ android:gravity="center"
+ android:shadowRadius="2.75"
+ android:shadowColor="#BB000000"
+ />
diff --git a/java/res/layout/candidate_preview.xml b/java/res/layout/candidate_preview.xml
new file mode 100644
index 0000000..fe2002d
--- /dev/null
+++ b/java/res/layout/candidate_preview.xml
@@ -0,0 +1,29 @@
+<?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.
+*/
+-->
+
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="18sp"
+ android:textColor="?android:attr/textColorPrimaryInverse"
+ android:minWidth="32dip"
+ android:gravity="center"
+ android:background="@drawable/candidate_feedback_background"
+ />
diff --git a/java/res/layout/candidates.xml b/java/res/layout/candidates.xml
new file mode 100644
index 0000000..9ef2438
--- /dev/null
+++ b/java/res/layout/candidates.xml
@@ -0,0 +1,38 @@
+<?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.
+*/
+-->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/candidate_strip_height"
+ android:background="@drawable/keyboard_suggest_strip"
+ >
+
+ <org.pocketworkstation.pckeyboard.CandidateView
+ android:id="@+id/candidates"
+ android:layout_width="wrap_content"
+ android:layout_height="@dimen/candidate_strip_height"
+ android:layout_weight="1"
+ android:fadingEdge="horizontal"
+ android:fadingEdgeLength="@dimen/candidate_strip_fading_edge_length"
+ />
+
+</LinearLayout>
diff --git a/java/res/layout/input_gingerbread.xml b/java/res/layout/input_gingerbread.xml
new file mode 100644
index 0000000..665fa4b
--- /dev/null
+++ b/java/res/layout/input_gingerbread.xml
@@ -0,0 +1,34 @@
+<?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.
+*/
+-->
+
+<org.pocketworkstation.pckeyboard.LatinKeyboardView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:latin="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:id="@+id/LatinkeyboardBaseView"
+ android:layout_alignParentBottom="true"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingBottom="@dimen/keyboard_bottom_padding"
+ android:background="@drawable/keyboard_dark_background"
+ android:textStyle="bold"
+
+ latin:keyBackground="@drawable/btn_keyboard_key_gingerbread"
+ latin:keyTextStyle="bold"
+ />
diff --git a/java/res/layout/input_ics.xml b/java/res/layout/input_ics.xml
new file mode 100644
index 0000000..4ed3f30
--- /dev/null
+++ b/java/res/layout/input_ics.xml
@@ -0,0 +1,35 @@
+<?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.
+*/
+-->
+
+<org.pocketworkstation.pckeyboard.LatinKeyboardView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:latin="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:id="@+id/LatinkeyboardBaseView"
+ android:layout_alignParentBottom="true"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingBottom="@dimen/keyboard_bottom_padding"
+ android:background="@drawable/keyboard_dark_background"
+ android:textStyle="bold"
+
+ latin:keyBackground="@drawable/btn_keyboard_key_ics"
+ latin:keyTextStyle="bold"
+ latin:keyHintColor="#FF000000"
+ />
diff --git a/java/res/layout/input_stone_bold.xml b/java/res/layout/input_stone_bold.xml
new file mode 100644
index 0000000..9f71b88
--- /dev/null
+++ b/java/res/layout/input_stone_bold.xml
@@ -0,0 +1,40 @@
+<?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.
+*/
+-->
+
+<org.pocketworkstation.pckeyboard.LatinKeyboardView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:latin="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:id="@+id/LatinkeyboardBaseView"
+ android:layout_alignParentBottom="true"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@drawable/keyboard_background"
+ android:textStyle="bold"
+
+ latin:keyBackground="@drawable/btn_keyboard_key_stone"
+ latin:keyTextColor="@color/latinkeyboard_key_color_black"
+ latin:keyHintColor="#FF777777"
+ latin:keyCursorColor="@color/latinkeyboard_dim_color_black"
+ latin:shadowColor="@color/latinkeyboard_key_color_white"
+ latin:keyTextStyle="bold"
+ latin:symbolColorScheme="black"
+ latin:recolorSymbols="true"
+ latin:popupLayout="@layout/input_stone_popup"
+ />
diff --git a/java/res/layout/input_stone_normal.xml b/java/res/layout/input_stone_normal.xml
new file mode 100644
index 0000000..dd33388
--- /dev/null
+++ b/java/res/layout/input_stone_normal.xml
@@ -0,0 +1,38 @@
+<?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.
+*/
+-->
+
+<org.pocketworkstation.pckeyboard.LatinKeyboardView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:latin="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:id="@+id/LatinkeyboardBaseView"
+ android:layout_alignParentBottom="true"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@drawable/keyboard_background"
+
+ latin:keyBackground="@drawable/btn_keyboard_key_stone"
+ latin:keyTextColor="@color/latinkeyboard_key_color_black"
+ latin:keyHintColor="#FF777777"
+ latin:keyCursorColor="@color/latinkeyboard_dim_color_black"
+ latin:shadowColor="@color/latinkeyboard_key_color_white"
+ latin:symbolColorScheme="black"
+ latin:recolorSymbols="true"
+ latin:popupLayout="@layout/input_stone_popup"
+ />
diff --git a/java/res/layout/input_stone_popup.xml b/java/res/layout/input_stone_popup.xml
new file mode 100644
index 0000000..18539e5
--- /dev/null
+++ b/java/res/layout/input_stone_popup.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2010, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:background="@drawable/keyboard_popup_panel_background"
+ >
+ <org.pocketworkstation.pckeyboard.LatinKeyboardBaseView
+ xmlns:latin="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:id="@+id/LatinKeyboardBaseView"
+ android:layout_alignParentBottom="true"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@drawable/keyboard_background"
+
+ latin:keyBackground="@drawable/btn_keyboard_key_stone"
+ latin:keyTextColor="@color/latinkeyboard_key_color_black"
+ latin:keyHintColor="#FF777777"
+ latin:keyCursorColor="@color/latinkeyboard_dim_color_black"
+ latin:shadowColor="@color/latinkeyboard_key_color_white"
+ latin:recolorSymbols="true"
+ latin:keyPreviewLayout="@layout/null_layout"
+ latin:popupLayout="@layout/null_layout"
+ />
+</LinearLayout>
diff --git a/java/res/layout/input_trans.xml b/java/res/layout/input_trans.xml
new file mode 100755
index 0000000..ae7b366
--- /dev/null
+++ b/java/res/layout/input_trans.xml
@@ -0,0 +1,34 @@
+<?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.
+*/
+-->
+
+<org.pocketworkstation.pckeyboard.LatinKeyboardView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:latin="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:id="@android:id/keyboardView"
+ android:layout_alignParentBottom="true"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@color/latinkeyboard_extension_background"
+ android:verticalCorrection="0dip"
+
+ latin:keyBackground="@drawable/btn_keyboard_key_ics"
+ latin:recolorSymbols="true"
+ latin:backgroundAlpha="128"
+ />
diff --git a/java/res/layout/input_trans_neon.xml b/java/res/layout/input_trans_neon.xml
new file mode 100755
index 0000000..2da4f45
--- /dev/null
+++ b/java/res/layout/input_trans_neon.xml
@@ -0,0 +1,40 @@
+<?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.
+*/
+-->
+
+<org.pocketworkstation.pckeyboard.LatinKeyboardView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:latin="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:id="@android:id/keyboardView"
+ android:layout_alignParentBottom="true"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="#c0000000"
+ android:verticalCorrection="0dip"
+
+ latin:keyBackground="@drawable/btn_keyboard_key_ics"
+ latin:keyTextColor="#FFFFFFFF"
+ latin:keyHintColor="#FFAAAAAA"
+ latin:keyCursorColor="#FFFFFFFF"
+ latin:shadowColor="#FF33B5E5"
+ latin:shadowRadius="9"
+ latin:keyTextStyle="bold"
+ latin:recolorSymbols="true"
+ latin:backgroundAlpha="32"
+ />
diff --git a/java/res/layout/key_preview.xml b/java/res/layout/key_preview.xml
new file mode 100644
index 0000000..19f9312
--- /dev/null
+++ b/java/res/layout/key_preview.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2010, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="80sp"
+ android:textSize="40sp"
+ android:textColor="@color/latinkeyboard_key_color_white"
+ android:minWidth="32dip"
+ android:gravity="center"
+ android:background="@drawable/keyboard_key_feedback_background"
+ />
diff --git a/java/res/layout/keyboard_popup.xml b/java/res/layout/keyboard_popup.xml
new file mode 100644
index 0000000..641a1cb
--- /dev/null
+++ b/java/res/layout/keyboard_popup.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2010, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:background="@drawable/keyboard_popup_panel_background"
+ android:paddingLeft="16dip"
+ android:paddingRight="16dip"
+ >
+ <org.pocketworkstation.pckeyboard.LatinKeyboardBaseView
+ xmlns:latin="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:id="@+id/LatinKeyboardBaseView"
+ android:layout_alignParentBottom="true"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@color/latinkeyboard_transparent"
+
+ latin:keyBackground="@drawable/btn_keyboard_key_gingerbread_popup"
+ latin:keyHysteresisDistance="0dip"
+ latin:verticalCorrection="@dimen/mini_keyboard_vertical_correction"
+ latin:keyPreviewLayout="@layout/null_layout"
+ latin:popupLayout="@layout/null_layout"
+ />
+</LinearLayout>
diff --git a/java/res/layout/main.xml b/java/res/layout/main.xml
new file mode 100644
index 0000000..921ffa5
--- /dev/null
+++ b/java/res/layout/main.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent" android:layout_height="match_parent"
+ android:orientation="vertical">
+ <!--
+ <TextView android:layout_height="wrap_content" android:id="@+id/main_intro"
+ android:text="@string/english_ime_name" android:layout_width="wrap_content"
+ android:textStyle="bold" android:textSize="25sp"></TextView>
+ -->
+ <TableLayout android:layout_width="match_parent"
+ android:id="@+id/main_linear1" android:layout_height="wrap_content">
+ <TableRow>
+ <Button android:text="@string/main_setup_configure_imes"
+ android:id="@+id/main_setup_btn_configure_imes"
+ android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
+ <Button android:text="@string/main_setup_input_lang"
+ android:id="@+id/main_setup_btn_input_lang" android:layout_width="wrap_content"
+ android:layout_height="wrap_content"></Button>
+ </TableRow>
+ <TableRow>
+ <Button android:text="@string/main_setup_set_ime" android:id="@+id/main_setup_btn_set_ime"
+ android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
+ <Button android:text="@string/main_setup_get_dicts"
+ android:id="@+id/main_setup_btn_get_dicts" android:layout_width="wrap_content"
+ android:layout_height="wrap_content"></Button>
+ </TableRow>
+ </TableLayout>
+ <TextView android:layout_height="wrap_content" android:id="@+id/main_description"
+ android:layout_width="wrap_content"></TextView>
+</LinearLayout>
diff --git a/java/res/layout/null_layout.xml b/java/res/layout/null_layout.xml
new file mode 100644
index 0000000..9ccf311
--- /dev/null
+++ b/java/res/layout/null_layout.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Used as a "don't use this layout" placeholder for LatinKeyboardBaseView -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+</LinearLayout>
diff --git a/java/res/layout/recognition_status.xml b/java/res/layout/recognition_status.xml
new file mode 100644
index 0000000..49af773
--- /dev/null
+++ b/java/res/layout/recognition_status.xml
@@ -0,0 +1,98 @@
+<?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.
+*/
+-->
+
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:background="@android:color/black"
+ android:paddingBottom="0dip"
+ android:paddingLeft="0dip"
+ android:paddingRight="0dip"
+>
+
+ <LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/main_image"
+ android:orientation="vertical"
+ android:background="@drawable/voice_ime_background"
+ android:scaleType="fitXY"
+ android:layout_width="match_parent"
+ android:layout_height="180dip"
+ android:paddingBottom="2dip"
+ android:paddingTop="2dip"
+ >
+
+ <TextView android:id="@+id/text"
+ android:text="@string/voice_initializing"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_marginTop="15dip"
+ android:textSize="28sp"
+ android:textColor="#ffffff"
+ android:layout_gravity="center_horizontal"
+ />
+
+ <ImageView android:id="@+id/image"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_marginTop="20dip"
+ android:layout_gravity="center_horizontal"
+ android:src="@drawable/mic_slash"
+ />
+
+ <ProgressBar android:id="@+id/progress"
+ android:layout_height="60dip"
+ android:layout_width="60dip"
+ android:layout_gravity="center"
+ android:visibility="gone"
+ android:indeterminate="true"
+ android:indeterminateOnly="false"
+ />
+
+
+
+ </LinearLayout>
+
+ <LinearLayout android:id="@+id/button"
+ android:orientation="vertical"
+ android:background="@drawable/ok_cancel"
+ android:scaleType="fitXY"
+ android:layout_width="match_parent"
+ android:layout_height="42dip"
+ android:paddingLeft="1dip"
+ android:paddingRight="1dip"
+ >
+
+ <TextView android:id="@+id/button_text"
+ android:text="@string/cancel"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_marginTop="7dip"
+ android:textSize="19sp"
+ android:textColor="#ffffff"
+ android:layout_gravity="center_horizontal"
+ />
+ </LinearLayout>
+
+</LinearLayout>
+
diff --git a/java/res/layout/seek_bar_dialog.xml b/java/res/layout/seek_bar_dialog.xml
new file mode 100644
index 0000000..6441dfa
--- /dev/null
+++ b/java/res/layout/seek_bar_dialog.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:padding="10dp"
+ android:orientation="vertical" >
+
+ <TextView
+ android:id="@+id/seekVal"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:text="@string/seek_pref_val"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ <SeekBar
+ android:id="@+id/seekBarPref"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+ <LinearLayout
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content" >
+
+ <TextView
+ android:id="@+id/seekMin"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:text="@string/seek_pref_0"
+ android:textAppearance="?android:attr/textAppearanceSmall" />
+
+ <TextView
+ android:id="@+id/seekMax"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:gravity="right"
+ android:text="@string/seek_pref_max"
+ android:textAppearance="?android:attr/textAppearanceSmall" />
+
+ </LinearLayout>
+</LinearLayout> \ No newline at end of file
diff --git a/java/res/layout/voice_punctuation_hint.xml b/java/res/layout/voice_punctuation_hint.xml
new file mode 100644
index 0000000..629a7f2
--- /dev/null
+++ b/java/res/layout/voice_punctuation_hint.xml
@@ -0,0 +1,49 @@
+<?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.
+*/
+-->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@drawable/keyboard_suggest_strip">
+
+ <!-- TODO: Use dark mic icon. -->
+ <ImageView android:id="@+id/image"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:paddingLeft="8dip"
+ android:paddingRight="8dip"
+ android:layout_gravity="center_horizontal"
+ android:src="@drawable/ic_suggest_strip_microphone"
+ />
+
+ <TextView android:id="@+id/text"
+ android:text="@string/voice_punctuation_hint"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:paddingTop="2dip"
+ android:paddingRight="3dip"
+ android:textSize="13sp"
+ android:textColor="#888888"
+ android:layout_gravity="center_horizontal"
+ />
+
+</LinearLayout>
diff --git a/java/res/layout/voice_swipe_hint.xml b/java/res/layout/voice_swipe_hint.xml
new file mode 100644
index 0000000..4e8859a
--- /dev/null
+++ b/java/res/layout/voice_swipe_hint.xml
@@ -0,0 +1,56 @@
+<?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.
+*/
+-->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@drawable/keyboard_suggest_strip"
+ android:gravity="center_horizontal"
+ android:paddingTop="2dip">
+
+ <TextView android:id="@+id/text"
+ android:text="@string/voice_swipe_hint"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:paddingTop="10dip"
+ android:paddingRight="6dip"
+ android:textSize="13sp"
+ android:textColor="#888888"
+ android:layout_gravity="center_horizontal"
+ />
+
+ <ImageView
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:src="@drawable/ic_suggest_strip_microphone"
+ />
+
+ <ImageView
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:src="@drawable/ic_suggest_strip_microphone_swipe"
+ />
+
+
+</LinearLayout>
diff --git a/java/res/raw/main.dict b/java/res/raw/main.dict
new file mode 100755
index 0000000..a456cf3
--- /dev/null
+++ b/java/res/raw/main.dict
Binary files differ
diff --git a/java/res/raw/type3.ogg b/java/res/raw/type3.ogg
new file mode 100755
index 0000000..20e6708
--- /dev/null
+++ b/java/res/raw/type3.ogg
Binary files differ
diff --git a/java/res/values-ar/bools.xml b/java/res/values-ar/bools.xml
new file mode 100644
index 0000000..126c437
--- /dev/null
+++ b/java/res/values-ar/bools.xml
@@ -0,0 +1,22 @@
+<?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>
+ <bool name="default_auto_cap">false</bool>
+</resources>
diff --git a/java/res/values-ar/donottranslate-altchars.xml b/java/res/values-ar/donottranslate-altchars.xml
new file mode 100644
index 0000000..6e2245a
--- /dev/null
+++ b/java/res/values-ar/donottranslate-altchars.xml
@@ -0,0 +1,47 @@
+<?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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="alternates_for_a"></string>
+ <string name="alternates_for_b"></string>
+ <string name="alternates_for_c"></string>
+ <string name="alternates_for_d"></string>
+ <string name="alternates_for_e">3</string>
+ <string name="alternates_for_f"></string>
+ <string name="alternates_for_g"></string>
+ <string name="alternates_for_h"></string>
+ <string name="alternates_for_i">8</string>
+ <string name="alternates_for_j"></string>
+ <string name="alternates_for_k"></string>
+ <string name="alternates_for_l"></string>
+ <string name="alternates_for_m"></string>
+ <string name="alternates_for_n"></string>
+ <string name="alternates_for_o">9</string>
+ <string name="alternates_for_p">0</string>
+ <string name="alternates_for_q">1</string>
+ <string name="alternates_for_r">4</string>
+ <string name="alternates_for_s"></string>
+ <string name="alternates_for_t">5</string>
+ <string name="alternates_for_u">7</string>
+ <string name="alternates_for_v"></string>
+ <string name="alternates_for_w">2</string>
+ <string name="alternates_for_x"></string>
+ <string name="alternates_for_y">6</string>
+ <string name="alternates_for_z"></string>
+</resources>
diff --git a/java/res/values-ar/donottranslate-keymap.xml b/java/res/values-ar/donottranslate-keymap.xml
new file mode 100644
index 0000000..e04dd09
--- /dev/null
+++ b/java/res/values-ar/donottranslate-keymap.xml
@@ -0,0 +1,221 @@
+<?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.
+**
+**
+** 5-row layout for Arabic.
+**
+** See http://code.google.com/p/hackerskeyboard/wiki/AddingNewLayouts for
+** more information.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="key_tlde_main">ذ</string>
+ <string name="key_tlde_shift">&#x0651;</string>
+ <string name="key_tlde_alt">ذ&#x0651;</string>
+
+ <string name="key_ae01_main">1</string>
+ <string name="key_ae01_shift">!</string>
+ <string name="key_ae01_alt">1!¡¹½⅓¼⅛</string>
+
+ <string name="key_ae02_main">2</string>
+ <string name="key_ae02_shift">\@</string>
+ <string name="key_ae02_alt">2\@²⅔</string>
+
+ <string name="key_ae03_main">3</string>
+ <string name="key_ae03_shift">#</string>
+ <string name="key_ae03_alt">3#³¾⅜♥♠♦♣</string>
+
+ <string name="key_ae04_main">4</string>
+ <string name="key_ae04_shift">$</string>
+ <string name="key_ae04_alt">4$⁴¢£€¥</string>
+
+ <string name="key_ae05_main">5</string>
+ <string name="key_ae05_shift">%</string>
+ <string name="key_ae05_alt">5%⅝‰</string>
+
+ <string name="key_ae06_main">6</string>
+ <string name="key_ae06_shift">^</string>
+ <string name="key_ae06_alt">6^↑↓←→</string>
+
+ <string name="key_ae07_main">7</string>
+ <string name="key_ae07_shift">&amp;</string>
+ <string name="key_ae07_alt">7&amp;⅞♪</string>
+
+ <string name="key_ae08_main">8</string>
+ <string name="key_ae08_shift">*</string>
+ <string name="key_ae08_alt">8*•★∞†‡</string>
+
+ <string name="key_ae09_main">9</string>
+ <string name="key_ae09_shift">)</string>
+ <string name="key_ae09_alt">9)√</string>
+
+ <string name="key_ae10_main">0</string>
+ <string name="key_ae10_shift">(</string>
+ <string name="key_ae10_alt">0(ⁿ°</string>
+
+ <string name="key_ae11_main">-</string>
+ <string name="key_ae11_shift">_</string>
+ <string name="key_ae11_alt">-_—–</string>
+
+ <string name="key_ae12_main">=</string>
+ <string name="key_ae12_shift">+</string>
+ <string name="key_ae12_alt">=+≈≠±×÷</string>
+
+
+ <string name="key_ad01_main">ض</string>
+ <string name="key_ad01_shift">َ</string>
+ <string name="key_ad01_alt"></string>
+
+ <string name="key_ad02_main">ص</string>
+ <string name="key_ad02_shift">ً</string>
+ <string name="key_ad02_alt"></string>
+
+ <string name="key_ad03_main">ث</string>
+ <string name="key_ad03_shift">ُ</string>
+ <string name="key_ad03_alt"></string>
+
+ <string name="key_ad04_main">ق</string>
+ <string name="key_ad04_shift">ٌ</string>
+ <string name="key_ad04_alt"></string>
+
+ <string name="key_ad05_main">ف</string>
+ <string name="key_ad05_shift">ﻹ</string>
+ <string name="key_ad05_alt"></string>
+
+ <string name="key_ad06_main">غ</string>
+ <string name="key_ad06_shift">إ</string>
+ <string name="key_ad06_alt"></string>
+
+ <string name="key_ad07_main">ع</string>
+ <string name="key_ad07_shift">`</string>
+ <string name="key_ad07_alt"></string>
+
+ <string name="key_ad08_main">ه</string>
+ <string name="key_ad08_shift">÷</string>
+ <string name="key_ad08_alt"></string>
+
+ <string name="key_ad09_main">خ</string>
+ <string name="key_ad09_shift">×</string>
+ <string name="key_ad09_alt"></string>
+
+ <string name="key_ad10_main">ح</string>
+ <string name="key_ad10_shift">؛</string>
+ <string name="key_ad10_alt">;</string>
+
+ <string name="key_ad11_main">ج</string>
+ <string name="key_ad11_shift">&lt;</string>
+ <string name="key_ad11_alt">ج&lt;≤«‹</string>
+
+ <string name="key_ad12_main">د</string>
+ <string name="key_ad12_shift">&gt;</string>
+ <string name="key_ad12_alt">د&gt;≥»›</string>
+
+ <string name="key_bksl_main">\\</string>
+ <string name="key_bksl_shift">|</string>
+ <string name="key_bksl_alt">\\|</string>
+
+
+ <string name="key_ac01_main">ش</string>
+ <string name="key_ac01_shift">ِ</string>
+ <string name="key_ac01_alt"></string>
+
+ <string name="key_ac02_main">س</string>
+ <string name="key_ac02_shift">ٍ</string>
+ <string name="key_ac02_alt"></string>
+
+ <string name="key_ac03_main">ي</string>
+ <string name="key_ac03_shift">]</string>
+ <string name="key_ac03_alt"></string>
+
+ <string name="key_ac04_main">ب</string>
+ <string name="key_ac04_shift">[</string>
+ <string name="key_ac04_alt"></string>
+
+ <string name="key_ac05_main">ل</string>
+ <string name="key_ac05_shift">ﻷ</string>
+ <string name="key_ac05_alt"></string>
+
+ <string name="key_ac06_main">ا</string>
+ <string name="key_ac06_shift">أ</string>
+ <string name="key_ac06_alt"></string>
+
+ <string name="key_ac07_main">ت</string>
+ <string name="key_ac07_shift">ـ</string>
+ <string name="key_ac07_alt"></string>
+
+ <string name="key_ac08_main">ن</string>
+ <string name="key_ac08_shift">،</string>
+ <string name="key_ac08_alt"></string>
+
+ <string name="key_ac09_main">م</string>
+ <string name="key_ac09_shift">/</string>
+ <string name="key_ac09_alt"></string>
+
+ <string name="key_ac10_main">ك</string>
+ <string name="key_ac10_shift">:</string>
+ <string name="key_ac10_alt">ك:</string>
+
+ <string name="key_ac11_main">ط</string>
+ <string name="key_ac11_shift">\"</string>
+ <string name="key_ac11_alt">ط\"\'‘’“”</string>
+
+
+ <string name="key_lsgt_main"></string>
+ <string name="key_lsgt_shift"></string>
+ <string name="key_lsgt_alt"></string>
+
+ <string name="key_ab01_main">ئ</string>
+ <string name="key_ab01_shift">~</string>
+ <string name="key_ab01_alt"></string>
+
+ <string name="key_ab02_main">ء</string>
+ <string name="key_ab02_shift">ْ</string>
+ <string name="key_ab02_alt"></string>
+
+ <string name="key_ab03_main">ؤ</string>
+ <string name="key_ab03_shift">}</string>
+ <string name="key_ab03_alt"></string>
+
+ <string name="key_ab04_main">ر</string>
+ <string name="key_ab04_shift">{</string>
+ <string name="key_ab04_alt"></string>
+
+ <string name="key_ab05_main">ﻻ</string>
+ <string name="key_ab05_shift">ﻵ</string>
+ <string name="key_ab05_alt"></string>
+
+ <string name="key_ab06_main">ى</string>
+ <string name="key_ab06_shift">آ</string>
+ <string name="key_ab06_alt"></string>
+
+ <string name="key_ab07_main">ة</string>
+ <string name="key_ab07_shift">\'</string>
+ <string name="key_ab07_alt"></string>
+
+ <string name="key_ab08_main">و</string>
+ <string name="key_ab08_shift">,</string>
+ <string name="key_ab08_alt">و,</string>
+
+ <string name="key_ab09_main">ز</string>
+ <string name="key_ab09_shift">.</string>
+ <string name="key_ab09_alt">ز.</string>
+
+ <string name="key_ab10_main">ظ</string>
+ <string name="key_ab10_shift">؟</string>
+ <string name="key_ab10_alt">ظ؟\?¿</string>
+</resources>
diff --git a/java/res/values-ar/donottranslate.xml b/java/res/values-ar/donottranslate.xml
new file mode 100644
index 0000000..07ae7b0
--- /dev/null
+++ b/java/res/values-ar/donottranslate.xml
@@ -0,0 +1,27 @@
+<?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 commonly considered word separators in this language -->
+ <string name="word_separators">.\u0009\u0020،؛:!؟\n()[]*&amp;@{}/&lt;&gt;_+=|\u0022«»</string>
+ <!-- Symbols that are sentence separators, for purposes of making it hug the last sentence. -->
+ <string name="sentence_separators">.،!؟)؛:</string>
+ <!-- Symbols that are suggested between words -->
+ <string name="suggested_punctuations">!؟،«»:؛()-\u0022/@_</string>
+</resources>
diff --git a/java/res/values-ar/strings.xml b/java/res/values-ar/strings.xml
new file mode 100644
index 0000000..ad24b32
--- /dev/null
+++ b/java/res/values-ar/strings.xml
@@ -0,0 +1,140 @@
+<?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/org.pocketworkstation.pckeyboard"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- <string name="english_ime_name" msgid="7252517407088836577">"لوحة مفاتيح Android"</string> -->
+ <!-- <string name="english_ime_settings" msgid="6661589557206947774">"إعدادات لوحة مفاتيح Android"</string> -->
+ <string name="english_ime_input_options" msgid="3909945612939668554">"خيارات الإرسال"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"اهتزاز عند الضغط على مفتاح"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"صوت عند الضغط على مفتاح"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"انبثاق عند الضغط على المفاتيح"</string>
+ <string name="hit_correction" msgid="4855351009261318389">"تصحيح أخطاء الكتابة"</string>
+ <string name="hit_correction_summary" msgid="8761701873008070796">"تمكين تصحيح خطأ الإدخال"</string>
+ <string name="hit_correction_land" msgid="2567691684825205448">"أخطاء في الإدخال الأفقي"</string>
+ <string name="hit_correction_land_summary" msgid="4076803842198368328">"تمكين تصحيح خطأ الإدخال"</string>
+ <string name="auto_correction" msgid="7911639788808958255">"اقتراحات الكلمات"</string>
+ <string name="auto_correction_summary" msgid="6881047311475758267">"تصحيح الكلمة السابقة تلقائيًا"</string>
+ <string name="prediction" msgid="466220283138359837">"اقتراحات الكلمات"</string>
+ <string name="prediction_category" msgid="7027100625580696660">"إعدادات اقتراحات الكلمات"</string>
+ <string name="prediction_summary" msgid="459788228830873110">"تمكين الإكمال التلقائي أثناء الكتابة"</string>
+ <string name="auto_complete_dialog_title" msgid="2172048590607201920">"إكمال تلقائي"</string>
+ <string name="prediction_landscape" msgid="4874601565593216183">"زيادة حجم الحقل النصي"</string>
+ <string name="prediction_landscape_summary" msgid="6736551095997839472">"إخفاء اقتراحات الكلمات في طريقة العرض الأفقية"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"استخدام الأحرف الكبيرة تلقائيًا"</string>
+ <string name="auto_cap_summary" msgid="3260681697600786825">"استخدام الأحرف الكبيرة في بداية الجملة"</string>
+ <string name="auto_punctuate" msgid="7276672334264521751">"ترقيم تلقائي"</string>
+ <string name="auto_punctuate_summary" msgid="6589441565817502132"></string>
+ <string name="quick_fixes" msgid="5353213327680897927">"إصلاحات سريعة"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"تصحيح الأخطاء المكتوبة الشائعة"</string>
+ <string name="show_suggestions" msgid="507074425254289133">"عرض الاقتراحات"</string>
+ <string name="show_suggestions_summary" msgid="1989672863935759654">"عرض الكلمات المقترحة أثناء الكتابة"</string>
+ <string name="auto_complete" msgid="1103196318775486023">"إكمال تلقائي"</string>
+ <string name="auto_complete_summary" msgid="6113149638718274624">"مفتاح المسافة والترقيم لإدخال كلمة محددة تلقائيًا"</string>
+ <string name="prefs_settings_key" msgid="4623341240804046498">"عرض مفتاح الإعدادات"</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"تلقائي"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"إظهار بشكل دائم"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"إخفاء دومًا"</string>
+ <!-- no translation found for settings_key_modes:0 (8549888726962891527) -->
+ <!-- no translation found for settings_key_modes:1 (881280041213210923) -->
+ <!-- no translation found for settings_key_modes:2 (7317310620171067848) -->
+ <string name="bigram_suggestion" msgid="1323347224043514969">"اقتراحات ثنائية"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"استخدام الكلمة السابقة لتحسين الاقتراح"</string>
+ <string-array name="prediction_modes">
+ <item msgid="4870266572388153286">"لا شيء"</item>
+ <item msgid="1669461741568287396">"أساسي"</item>
+ <item msgid="4894328801530136615">"متقدم"</item>
+ </string-array>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : تم الحفظ"</string>
+ <string name="tip_long_press" msgid="6101270866284343344">"اضغط باستمرار على أحد المفاتيح لأسفل لمشاهدة علامات التشكيل"</string>
+ <string name="tip_dismiss" msgid="7585579046862204381">"اضغط على مفتاح الرجوع ↶ لإغلاق لوحة المفاتيح في أي نقطة"</string>
+ <string name="tip_access_symbols" msgid="6344098517525531652">"الدخول إلى الأرقام والرموز"</string>
+ <string name="tip_add_to_dictionary" msgid="1487293888469227817">"اضغط مع الاستمرار على أقصى يمين الكلمة لإضافتها إلى القاموس"</string>
+ <string name="touch_to_continue" msgid="7869803257948414531">"المس هذا التلميح للمتابعة »"</string>
+ <string name="touch_to_finish" msgid="7990196086480585789">"المس هنا لإغلاق هذا التلميح وبدء الكتابة!"</string>
+ <string name="tip_to_open_keyboard" msgid="6821200275486950452"><b>"تفتح لوحة المفاتيح في أي وقت تلمس فيه حقلًا نصيًا"</b></string>
+ <string name="tip_to_view_accents" msgid="5433158573693308501"><b>"المس مع الاستمرار أحد المفاتيح لعرض علامات التشكيل"\n"(ø, ö, ô, ó, وهكذا)"</b></string>
+ <string name="tip_to_open_symbols" msgid="7345139325622444880"><b>"التبديل إلى الأرقام والرموز من خلال لمس هذا الزر"</b></string>
+ <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"يمكنك الرجوع إلى الأحرف من خلال لمس هذا المفتاح مرة أخرى"</b></string>
+ <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"المس هذا المفتاح مع الاستمرار لتغيير إعدادات لوحة المفاتيح، مثل الإكمال التلقائي"</b></string>
+ <string name="tip_to_start_typing" msgid="7213843601369174313"><b>"جربه!"</b></string>
+ <string name="label_go_key" msgid="1635148082137219148">"تنفيذ"</string>
+ <string name="label_next_key" msgid="362972844525672568">"التالي"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"تم"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"إرسال"</string>
+ <string name="label_symbol_key" msgid="6175820506864489453">"?123"</string>
+ <string name="label_phone_key" msgid="4275497665515080551">"123"</string>
+ <string name="label_alpha_key" msgid="8864943487292437456">"ب ت ث"</string>
+ <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string>
+ <string name="voice_warning_title" msgid="4419354150908395008">"الإدخال الصوتي"</string>
+ <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"الإدخال الصوتي غير معتمد حاليًا للغتك، ولكنه يعمل باللغة الإنجليزية."</string>
+ <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"الإدخال الصوتي هو ميزة تجريبية تستخدم التعرف على الكلام المتصل في Google."</string>
+ <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"لتشغيل الإدخال الصوتي، انتقل إلى إعدادات لوحة المفاتيح."</string>
+ <string name="voice_hint_dialog_message" msgid="6892342981545727994">"لاستخدام الإدخال الصوتي، اضغط على زر الميكروفون أو مرر إصبعك عبر لوحة المفاتيح على الشاشة."</string>
+ <string name="voice_listening" msgid="467518160751321844">"تحدث الآن"</string>
+ <string name="voice_working" msgid="6666937792815731889">"العمل"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"خطأ. الرجاء المحاولة مرة أخرى."</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"تعذر الاتصال"</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"خطأ، كلام أكثر مما ينبغي."</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"مشكلة بالإعدادات الصوتية"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"خطأ في الخادم"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"لم يتم سماع كلام"</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"لم يتمّ العثور على أية تطابقات"</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"لم يتم تثبيت البحث الصوتي"</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"تلميح:"</b>" مرر عبر لوحة المفاتيح للتحدث"</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"تلميح:"</b>" جرب في المرة التالية نطق الترقيم مثل \"نقطة\" أو \"فاصلة\" أو \"علامة استفهام\"."</string>
+ <string name="cancel" msgid="6830980399865683324">"إلغاء"</string>
+ <string name="ok" msgid="7898366843681727667">"موافق"</string>
+ <string name="voice_input" msgid="2466640768843347841">"الإدخال الصوتي"</string>
+ <string-array name="voice_input_modes">
+ <item msgid="1349082139076086774">"في لوحة المفاتيح الرئيسية"</item>
+ <item msgid="8529385602829095903">"على لوحة مفاتيح الرموز"</item>
+ <item msgid="7283103513488381103">"إيقاف"</item>
+ </string-array>
+ <string-array name="voice_input_modes_summary">
+ <item msgid="554248625705084903">"الميكروفون في لوحة المفاتيح الرئيسية"</item>
+ <item msgid="6907837061058876770">"الميكروفون على لوحة مفاتيح الرموز"</item>
+ <item msgid="3664304608587798036">"تم تعطيل الإدخال الصوتي"</item>
+ </string-array>
+ <string name="auto_submit" msgid="9151008027068358518">"إرسال تلقائي بعد الصوت"</string>
+ <string name="auto_submit_summary" msgid="4961875269610384226">"الضغط تلقائيًا على المفتاح enter عند البحث أو الانتقال إلى الحقل التالي."</string>
+ <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"افتح لوحة المفاتيح"\n</b></font><font size="3">\n</font>"المس أي حقل نصي."</string>
+ <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"إغلاق لوحة المفاتيح"\n</b></font><font size="3">\n</font>"اضغط على المفتاح \"رجوع\"."</string>
+ <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"المس أحد مفاتيح الخيارات مع الاستمرار"\n</b></font><font size="3">\n</font>"الدخول إلى الترقيم والحركات."</string>
+ <string name="keyboard_settings" msgid="4585753477617374032"><font size="17"><b>"إعدادات لوحة المفاتيح"\n</b></font><font size="3">\n</font>"المس مع الاستمرار المفتاح "<b>"?123"</b>"."</string>
+ <string name="popular_domain_0" msgid="3745279225122472969">"com."</string>
+ <string name="popular_domain_1" msgid="1370572248164278467">"net."</string>
+ <string name="popular_domain_2" msgid="3036812463748402878">"org."</string>
+ <string name="popular_domain_3" msgid="8718639560809452028">"gov."</string>
+ <string name="popular_domain_4" msgid="35359437471311470">"edu."</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"تحديد طريقة الإرسال"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"لغات الإدخال"</string>
+ <string name="language_selection_summary" msgid="187110938289512256">"مرر إصبعك على مفتاح المسافة لتغيير اللغة"</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← المس مرة أخرى للحفظ"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"القاموس متاح"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"تمكين ملاحظات المستخدم"</string>
+ <string name="prefs_description_log" msgid="5827825607258246003">"المساعدة في تحسين محرر طريقة الإرسال هذا من خلال إرسال إحصاءات الاستخدام وتقارير الأعطال تلقائيًا إلى Google."</string>
+ <string name="prefs_enable_recorrection" msgid="4588408906649533582">"المس لتصحيح الكلمات"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="1056068922330206170">"المس الكلمات المدخلة لتصحيحها"</string>
+ <string name="keyboard_layout" msgid="437433231038683666">"مظهر لوحة المفاتيح"</string>
+ <string name="subtype_mode_keyboard" msgid="2242090416595003881">"لوحة مفاتيح"</string>
+ <string name="subtype_mode_voice" msgid="4394113125441627771">"صوت"</string>
+</resources>
diff --git a/java/res/values-bg/donottranslate-keymap.xml b/java/res/values-bg/donottranslate-keymap.xml
new file mode 100644
index 0000000..ac306cb
--- /dev/null
+++ b/java/res/values-bg/donottranslate-keymap.xml
@@ -0,0 +1,223 @@
+<?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.
+**
+**
+** 5-row layout for Bulgarian, contributed by Nuclear
+** Adapted from the 5-row layout for Russian, contributed by Igor Tonky.
+**
+** See http://code.google.com/p/hackerskeyboard/wiki/AddingNewLayouts
+for
+** more information.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="key_tlde_main">`</string>
+ <string name="key_tlde_shift">\"</string>
+ <string name="key_tlde_alt">`\"~\'</string>
+
+ <string name="key_ae01_main">1</string>
+ <string name="key_ae01_shift">!</string>
+ <string name="key_ae01_alt">1!¡¹½⅓¼⅛</string>
+
+ <string name="key_ae02_main">2</string>
+ <string name="key_ae02_shift">\@</string>
+ <string name="key_ae02_alt">2\@²⅔</string>
+
+ <string name="key_ae03_main">3</string>
+ <string name="key_ae03_shift">№</string>
+ <string name="key_ae03_alt">3№#³¾⅜</string>
+
+ <string name="key_ae04_main">4</string>
+ <string name="key_ae04_shift">$</string>
+ <string name="key_ae04_alt">4$⁴¢£€¥</string>
+
+ <string name="key_ae05_main">5</string>
+ <string name="key_ae05_shift">%</string>
+ <string name="key_ae05_alt">5%⅝‰</string>
+
+ <string name="key_ae06_main">6</string>
+ <string name="key_ae06_shift">:</string>
+ <string name="key_ae06_alt">6:^↑↓←→</string>
+
+ <string name="key_ae07_main">7</string>
+ <string name="key_ae07_shift">&amp;</string>
+ <string name="key_ae07_alt">7&amp;⅞♪</string>
+
+ <string name="key_ae08_main">8</string>
+ <string name="key_ae08_shift">*</string>
+ <string name="key_ae08_alt">8*•★∞†‡</string>
+
+ <string name="key_ae09_main">9</string>
+ <string name="key_ae09_shift">(</string>
+ <string name="key_ae09_alt">9([{√</string>
+
+ <string name="key_ae10_main">0</string>
+ <string name="key_ae10_shift">)</string>
+ <string name="key_ae10_alt">0)]}ⁿ°</string>
+
+ <string name="key_ae11_main">-</string>
+ <string name="key_ae11_shift">_</string>
+ <string name="key_ae11_alt">-_—–</string>
+
+ <string name="key_ae12_main">=</string>
+ <string name="key_ae12_shift">+</string>
+ <string name="key_ae12_alt">=+≈≠±×÷</string>
+
+
+ <string name="key_ad01_main">я</string>
+ <string name="key_ad01_shift">Я</string>
+ <string name="key_ad01_alt"></string>
+
+ <string name="key_ad02_main">в</string>
+ <string name="key_ad02_shift">В</string>
+ <string name="key_ad02_alt"></string>
+
+ <string name="key_ad03_main">е</string>
+ <string name="key_ad03_shift">Е</string>
+ <string name="key_ad03_alt"></string>
+
+ <string name="key_ad04_main">р</string>
+ <string name="key_ad04_shift">Р</string>
+ <string name="key_ad04_alt"></string>
+
+ <string name="key_ad05_main">т</string>
+ <string name="key_ad05_shift">Т</string>
+ <string name="key_ad05_alt"></string>
+
+ <string name="key_ad06_main">ъ</string>
+ <string name="key_ad06_shift">ъ</string>
+ <string name="key_ad06_alt"></string>
+
+ <string name="key_ad07_main">у</string>
+ <string name="key_ad07_shift">У</string>
+ <string name="key_ad07_alt"></string>
+
+ <string name="key_ad08_main">и</string>
+ <string name="key_ad08_shift">И</string>
+ <string name="key_ad08_alt"></string>
+
+ <string name="key_ad09_main">о</string>
+ <string name="key_ad09_shift">О</string>
+ <string name="key_ad09_alt"></string>
+
+ <string name="key_ad10_main">п</string>
+ <string name="key_ad10_shift">П</string>
+ <string name="key_ad10_alt"></string>
+
+ <string name="key_ad11_main">ш</string>
+ <string name="key_ad11_shift">Ш</string>
+ <string name="key_ad11_alt"></string>
+
+ <string name="key_ad12_main">щ</string>
+ <string name="key_ad12_shift">Щ</string>
+ <string name="key_ad12_alt"></string>
+
+ <string name="key_bksl_main">;</string>
+ <string name="key_bksl_shift">:</string>
+ <string name="key_bksl_alt">;:</string>
+
+
+ <string name="key_ac01_main">а</string>
+ <string name="key_ac01_shift">А</string>
+ <string name="key_ac01_alt"></string>
+
+ <string name="key_ac02_main">с</string>
+ <string name="key_ac02_shift">С</string>
+ <string name="key_ac02_alt"></string>
+
+ <string name="key_ac03_main">д</string>
+ <string name="key_ac03_shift">Д</string>
+ <string name="key_ac03_alt"></string>
+
+ <string name="key_ac04_main">ф</string>
+ <string name="key_ac04_shift">Ф</string>
+ <string name="key_ac04_alt"></string>
+
+ <string name="key_ac05_main">г</string>
+ <string name="key_ac05_shift">Г</string>
+ <string name="key_ac05_alt"></string>
+
+ <string name="key_ac06_main">х</string>
+ <string name="key_ac06_shift">Х</string>
+ <string name="key_ac06_alt"></string>
+
+ <string name="key_ac07_main">й</string>
+ <string name="key_ac07_shift">Й</string>
+ <string name="key_ac07_alt"></string>
+
+ <string name="key_ac08_main">к</string>
+ <string name="key_ac08_shift">К</string>
+ <string name="key_ac08_alt"></string>
+
+ <string name="key_ac09_main">л</string>
+ <string name="key_ac09_shift">Л</string>
+ <string name="key_ac09_alt"></string>
+
+ <string name="key_ac10_main">ю</string>
+ <string name="key_ac10_shift">Ю</string>
+ <string name="key_ac10_alt"></string>
+
+ <string name="key_ac11_main">ч</string>
+ <string name="key_ac11_shift">Ч</string>
+ <string name="key_ac11_alt"></string>
+
+
+
+
+ <string name="key_ab01_main">з</string>
+ <string name="key_ab01_shift">З</string>
+ <string name="key_ab01_alt"></string>
+
+ <string name="key_ab02_main">ь</string>
+ <string name="key_ab02_shift">ѝ</string>
+ <string name="key_ab02_alt"></string>
+
+ <string name="key_ab03_main">ц</string>
+ <string name="key_ab03_shift">Ц</string>
+ <string name="key_ab03_alt"></string>
+
+ <string name="key_ab04_main">ж</string>
+ <string name="key_ab04_shift">Ж</string>
+ <string name="key_ab04_alt"></string>
+
+ <string name="key_ab05_main">б</string>
+ <string name="key_ab05_shift">Б</string>
+ <string name="key_ab05_alt"></string>
+
+ <string name="key_ab06_main">н</string>
+ <string name="key_ab06_shift">Н</string>
+ <string name="key_ab06_alt"></string>
+
+ <string name="key_ab07_main">м</string>
+ <string name="key_ab07_shift">М</string>
+ <string name="key_ab07_alt"></string>
+
+ <string name="key_ab08_main">,</string>
+ <string name="key_ab08_shift">&lt;</string>
+ <string name="key_ab08_alt">,&lt;≤«‹</string>
+
+ <string name="key_ab09_main">.</string>
+ <string name="key_ab09_shift">&gt;</string>
+ <string name="key_ab09_alt">&gt;≥»›…</string>
+
+
+ <string name="key_ab10_main">/</string>
+ <string name="key_ab10_shift">\?</string>
+ <string name="key_ab10_alt">/\?¿</string>
+</resources>
diff --git a/java/res/values-bg/strings.xml b/java/res/values-bg/strings.xml
new file mode 100644
index 0000000..d8e2603
--- /dev/null
+++ b/java/res/values-bg/strings.xml
@@ -0,0 +1,140 @@
+<?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/org.pocketworkstation.pckeyboard"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- <string name="english_ime_name" msgid="7252517407088836577">"Клавиатура на Android"</string> -->
+ <!-- <string name="english_ime_settings" msgid="6661589557206947774">"Настройки на клавиатурата на Android"</string> -->
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Опции за въвеждане"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"Да вибрира при натискане на клавиш"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"Звук при натискане на клавиш"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"Изскачащ прозорец при натискане на клавиш"</string>
+ <string name="hit_correction" msgid="4855351009261318389">"Коригиране на грешките при въвеждане"</string>
+ <string name="hit_correction_summary" msgid="8761701873008070796">"Активиране на корекция на грешки при въвеждане"</string>
+ <string name="hit_correction_land" msgid="2567691684825205448">"Грешки при въвеждане в хоризонтален изглед"</string>
+ <string name="hit_correction_land_summary" msgid="4076803842198368328">"Активиране на корекция на грешки при въвеждане"</string>
+ <string name="auto_correction" msgid="7911639788808958255">"Предложения на думи"</string>
+ <string name="auto_correction_summary" msgid="6881047311475758267">"Автоматично коригиране на предишната дума"</string>
+ <string name="prediction" msgid="466220283138359837">"Предложения на думи"</string>
+ <string name="prediction_category" msgid="7027100625580696660">"Настройки за предложения на думи"</string>
+ <string name="prediction_summary" msgid="459788228830873110">"Активиране на автодовършване, докато пишете"</string>
+ <string name="auto_complete_dialog_title" msgid="2172048590607201920">"Автодовършване"</string>
+ <string name="prediction_landscape" msgid="4874601565593216183">"Размерът на текстовото поле да се увеличи"</string>
+ <string name="prediction_landscape_summary" msgid="6736551095997839472">"Скриване на предложенията на думи в хоризонтален изглед"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"Автоматично поставяне на главни букви"</string>
+ <string name="auto_cap_summary" msgid="3260681697600786825">"Поставя главна буква в началото на изреченията"</string>
+ <string name="auto_punctuate" msgid="7276672334264521751">"Автоматично поставяне на пунктуация"</string>
+ <string name="auto_punctuate_summary" msgid="6589441565817502132"></string>
+ <string name="quick_fixes" msgid="5353213327680897927">"Бързи корекции"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"Коригира най-честите грешки при въвеждане"</string>
+ <string name="show_suggestions" msgid="507074425254289133">"Показване на предложения"</string>
+ <string name="show_suggestions_summary" msgid="1989672863935759654">"Показване на предложения, докато пишете"</string>
+ <string name="auto_complete" msgid="1103196318775486023">"Автоматично завършване"</string>
+ <string name="auto_complete_summary" msgid="6113149638718274624">"Клавишът за интервал и пунктуация поставя автоматично откроена дума"</string>
+ <string name="prefs_settings_key" msgid="4623341240804046498">"Показване на клавиша за настройки"</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Автоматично"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Да се показва винаги"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"Да се скрива винаги"</string>
+ <!-- no translation found for settings_key_modes:0 (8549888726962891527) -->
+ <!-- no translation found for settings_key_modes:1 (881280041213210923) -->
+ <!-- no translation found for settings_key_modes:2 (7317310620171067848) -->
+ <string name="bigram_suggestion" msgid="1323347224043514969">"Предложения за биграми"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Използване на предишната дума за подобряване на предложението"</string>
+ <string-array name="prediction_modes">
+ <item msgid="4870266572388153286">"Няма"</item>
+ <item msgid="1669461741568287396">"Основен"</item>
+ <item msgid="4894328801530136615">"Разширени"</item>
+ </string-array>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Запазено"</string>
+ <string name="tip_long_press" msgid="6101270866284343344">"Задръжте клавиша, за да видите ударенията (ø, ö и т.н.)"</string>
+ <string name="tip_dismiss" msgid="7585579046862204381">"Натиснете клавиша „Назад“ ↶, за да затворите клавиатурата във всяка една точка"</string>
+ <string name="tip_access_symbols" msgid="6344098517525531652">"Достъп до номера и символи"</string>
+ <string name="tip_add_to_dictionary" msgid="1487293888469227817">"Натиснете и задръжте върху най-лявата дума, за да я добавите към речника"</string>
+ <string name="touch_to_continue" msgid="7869803257948414531">"Докоснете съвета, за да продължите »"</string>
+ <string name="touch_to_finish" msgid="7990196086480585789">"Докоснете тук, за да затворите този съвет и да започнете да пишете!"</string>
+ <string name="tip_to_open_keyboard" msgid="6821200275486950452"><b>"Клавиатурата се отваря при всяко докосване на текстово поле"</b></string>
+ <string name="tip_to_view_accents" msgid="5433158573693308501"><b>"Докоснете и задръжте клавиша, за да видите ударенията"\n"(ø, ö, ô, ó и т.н.)"</b></string>
+ <string name="tip_to_open_symbols" msgid="7345139325622444880"><b>"Докосването на този клавиш води до преминаване към цифри и символи"</b></string>
+ <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"Върнете се към използване на букви чрез повторно докосване на този клавиш"</b></string>
+ <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"Докоснете и задръжте клавиша за промяна на настройките на клавиатурата, напр. автодовършване"</b></string>
+ <string name="tip_to_start_typing" msgid="7213843601369174313"><b>"Пробвайте!"</b></string>
+ <string name="label_go_key" msgid="1635148082137219148">"Старт"</string>
+ <string name="label_next_key" msgid="362972844525672568">"Напред"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"Готово"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"Изпращане"</string>
+ <string name="label_symbol_key" msgid="6175820506864489453">"?123"</string>
+ <string name="label_phone_key" msgid="4275497665515080551">"123"</string>
+ <string name="label_alpha_key" msgid="8864943487292437456">"АБВГ"</string>
+ <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string>
+ <string name="voice_warning_title" msgid="4419354150908395008">"Гласово въвеждане"</string>
+ <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"За вашия език понастоящем не се поддържа гласово въвеждане, но можете да го използвате на английски."</string>
+ <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"Гласовото въвеждане е експериментална функция, използваща разпознаването на реч в мрежата на Google."</string>
+ <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"За да изключите гласовото въвеждане, отворете настройките на клавиатурата."</string>
+ <string name="voice_hint_dialog_message" msgid="6892342981545727994">"За да използвате гласово въвеждане, натиснете бутона на микрофона или плъзнете пръст през екранната клавиатура."</string>
+ <string name="voice_listening" msgid="467518160751321844">"Говорете сега"</string>
+ <string name="voice_working" msgid="6666937792815731889">"Обработва се"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"Грешка. Моля, опитайте отново."</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"Не можа да се свърже"</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"Грешка, твърде много речева информация."</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"Аудиопроблем"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"Грешка в сървъра"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"Не се чува реч"</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"Нямаше съответствия"</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"Не е инсталирано гласово търсене"</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Съвет:"</b>" Прокарайте палец през клавиатурата, за да говорите"</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Съвет:"</b>" Следващия път опитайте да произнесете знаците за пунктуация, напр. „точка“, „запетая“ или „въпросителен знак“."</string>
+ <string name="cancel" msgid="6830980399865683324">"Отказ"</string>
+ <string name="ok" msgid="7898366843681727667">"OK"</string>
+ <string name="voice_input" msgid="2466640768843347841">"Гласово въвеждане"</string>
+ <string-array name="voice_input_modes">
+ <item msgid="1349082139076086774">"На основната клавиатура"</item>
+ <item msgid="8529385602829095903">"На клавиатурата на символите"</item>
+ <item msgid="7283103513488381103">"Изкл."</item>
+ </string-array>
+ <string-array name="voice_input_modes_summary">
+ <item msgid="554248625705084903">"Микрофон на основната клавиатура"</item>
+ <item msgid="6907837061058876770">"Микрофон на клавиатурата на символите"</item>
+ <item msgid="3664304608587798036">"Гласовото въвеждане е деактивирано"</item>
+ </string-array>
+ <string name="auto_submit" msgid="9151008027068358518">"Автоматично изпращане след глас"</string>
+ <string name="auto_submit_summary" msgid="4961875269610384226">"Да се натиска автоматично „Enter“ при търсене или преминаване към следващото поле."</string>
+ <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Отворете клавиатурата"\n</b></font><font size="3">\n</font>"Докоснете текстово поле."</string>
+ <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Затваряне на клавиатурата"\n</b></font><font size="3">\n</font>"Натиснете клавиша „Назад“."</string>
+ <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Докоснете и задръжте клавиш за опции"\n</b></font><font size="3">\n</font>"Използвайте пунктуация и акценти."</string>
+ <string name="keyboard_settings" msgid="4585753477617374032"><font size="17"><b>"Настройки на клавиатурата"\n</b></font><font size="3">\n</font>"Докоснете и задръжте клавиша "<b>"?123"</b>"."</string>
+ <string name="popular_domain_0" msgid="3745279225122472969">".com"</string>
+ <string name="popular_domain_1" msgid="1370572248164278467">".net"</string>
+ <string name="popular_domain_2" msgid="3036812463748402878">".org"</string>
+ <string name="popular_domain_3" msgid="8718639560809452028">".gov"</string>
+ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"Избор на метод на въвеждане"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Входни езици"</string>
+ <string name="language_selection_summary" msgid="187110938289512256">"Плъзнете пръст по клавиша за интервал за промяна на езика"</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Докоснете отново, за да запазите"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"Има достъп до речник"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"Активиране на отзивите от потребителите"</string>
+ <string name="prefs_description_log" msgid="5827825607258246003">"Помогнете за подобряването на този редактор за въвеждане чрез автоматично изпращане до Google на статистически данни за употребата и сигнали за сривове."</string>
+ <string name="prefs_enable_recorrection" msgid="4588408906649533582">"Докоснете, за да поправите думите"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="1056068922330206170">"Докоснете въведените думи, за да ги поправите"</string>
+ <string name="keyboard_layout" msgid="437433231038683666">"Тема на клавиатурата"</string>
+ <string name="subtype_mode_keyboard" msgid="2242090416595003881">"клавиатура"</string>
+ <string name="subtype_mode_voice" msgid="4394113125441627771">"гласово"</string>
+</resources>
diff --git a/java/res/values-ca/strings.xml b/java/res/values-ca/strings.xml
new file mode 100644
index 0000000..f3277df
--- /dev/null
+++ b/java/res/values-ca/strings.xml
@@ -0,0 +1,140 @@
+<?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/org.pocketworkstation.pckeyboard"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- <string name="english_ime_name" msgid="7252517407088836577">"Teclat Android"</string> -->
+ <!-- <string name="english_ime_settings" msgid="6661589557206947774">"Configuració del teclat d\'Android"</string> -->
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Opcions d\'entrada"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibra en prémer tecles"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"So en prémer una tecla"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"Finestra emergent en prémer un botó"</string>
+ <string name="hit_correction" msgid="4855351009261318389">"Corregeix els errors ortogràfics"</string>
+ <string name="hit_correction_summary" msgid="8761701873008070796">"Activa la correcció d\'errors d\'entrada"</string>
+ <string name="hit_correction_land" msgid="2567691684825205448">"Errors d\'entrada en horitzontal"</string>
+ <string name="hit_correction_land_summary" msgid="4076803842198368328">"Activa la correcció d\'errors d\'entrada"</string>
+ <string name="auto_correction" msgid="7911639788808958255">"Suggeriments de paraules"</string>
+ <string name="auto_correction_summary" msgid="6881047311475758267">"Corregeix automàticament la paraula anterior"</string>
+ <string name="prediction" msgid="466220283138359837">"Suggeriments de paraules"</string>
+ <string name="prediction_category" msgid="7027100625580696660">"Configuració de suggeriment de paraules"</string>
+ <string name="prediction_summary" msgid="459788228830873110">"Activa l\'emplenament automàtic mentre s\'escriu"</string>
+ <string name="auto_complete_dialog_title" msgid="2172048590607201920">"Emplenament automàtic"</string>
+ <string name="prediction_landscape" msgid="4874601565593216183">"Augmenta la mida del camp de text"</string>
+ <string name="prediction_landscape_summary" msgid="6736551095997839472">"Oculta els suggeriments de paraules en visualització horitzontal"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"Majúscules automàtiques"</string>
+ <string name="auto_cap_summary" msgid="3260681697600786825">"Posa l\'inici d\'una frase en majúscula"</string>
+ <string name="auto_punctuate" msgid="7276672334264521751">"Puntuació automàtica"</string>
+ <string name="auto_punctuate_summary" msgid="6589441565817502132"></string>
+ <string name="quick_fixes" msgid="5353213327680897927">"Correccions ràpides"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"Corregeix els errors d\'ortografia habituals"</string>
+ <string name="show_suggestions" msgid="507074425254289133">"Mostra els suggeriments"</string>
+ <string name="show_suggestions_summary" msgid="1989672863935759654">"Visualitza paraules suggerides mentre s\'escriu"</string>
+ <string name="auto_complete" msgid="1103196318775486023">"Emplenament automàtic"</string>
+ <string name="auto_complete_summary" msgid="6113149638718274624">"La barra espaiadora i la puntuació insereixen automàticament la paraula ressaltada"</string>
+ <string name="prefs_settings_key" msgid="4623341240804046498">"Mostra la tecla de configuració"</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automàtic"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Mostra sempre"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"Amaga sempre"</string>
+ <!-- no translation found for settings_key_modes:0 (8549888726962891527) -->
+ <!-- no translation found for settings_key_modes:1 (881280041213210923) -->
+ <!-- no translation found for settings_key_modes:2 (7317310620171067848) -->
+ <string name="bigram_suggestion" msgid="1323347224043514969">"Suggeriments Bigram"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Utilitza la paraula anterior per millorar el suggeriment"</string>
+ <string-array name="prediction_modes">
+ <item msgid="4870266572388153286">"Cap"</item>
+ <item msgid="1669461741568287396">"Bàsic"</item>
+ <item msgid="4894328801530136615">"Avançat"</item>
+ </string-array>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: desada"</string>
+ <string name="tip_long_press" msgid="6101270866284343344">"Manteniu una tecla premuda per veure\'n les variants (ø, ö, etc.)"</string>
+ <string name="tip_dismiss" msgid="7585579046862204381">"Premeu la tecla Enrere ↶ per tancar el teclat en qualsevol moment"</string>
+ <string name="tip_access_symbols" msgid="6344098517525531652">"Accedeix a números i símbols"</string>
+ <string name="tip_add_to_dictionary" msgid="1487293888469227817">"Manteniu premuda la paraula de l\'extrem esquerre per afegir-la al diccionari"</string>
+ <string name="touch_to_continue" msgid="7869803257948414531">"Toqueu aquest suggeriment per continuar »"</string>
+ <string name="touch_to_finish" msgid="7990196086480585789">"Toqueu aquí per tancar aquest suggeriment i començar a escriure."</string>
+ <string name="tip_to_open_keyboard" msgid="6821200275486950452"><b>"S\'obre el teclat cada vegada que toqueu un camp de text"</b></string>
+ <string name="tip_to_view_accents" msgid="5433158573693308501"><b>"Manteniu premuda una tecla per veure\'n les variants"\n"(ø, ö, ô, ó, etc.)"</b></string>
+ <string name="tip_to_open_symbols" msgid="7345139325622444880"><b>"Toqueu aquesta tecla per canviar als números i als símbols"</b></string>
+ <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"Torneu a tocar aquesta tecla per tornar a les lletres"</b></string>
+ <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"Manteniu premuda aquesta tecla per canviar la configuració del teclat, com ara l\'emplenament automàtic"</b></string>
+ <string name="tip_to_start_typing" msgid="7213843601369174313"><b>"Proveu-ho!"</b></string>
+ <string name="label_go_key" msgid="1635148082137219148">"Vés"</string>
+ <string name="label_next_key" msgid="362972844525672568">"Següent"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"Fet"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"Envia"</string>
+ <string name="label_symbol_key" msgid="6175820506864489453">"?123"</string>
+ <string name="label_phone_key" msgid="4275497665515080551">"123"</string>
+ <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string>
+ <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string>
+ <string name="voice_warning_title" msgid="4419354150908395008">"Entrada de veu"</string>
+ <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Actualment, l\'entrada de veu no és compatible amb el vostre idioma, però funciona en anglès."</string>
+ <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"L\'entrada de veu és una funció experimental que utilitza el reconeixement de la parla en xarxa de Google."</string>
+ <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"Per desactivar l\'entada de veu, aneu a la configuració del teclat."</string>
+ <string name="voice_hint_dialog_message" msgid="6892342981545727994">"Per utilitzar l\'entrada de veu, premeu el botó del micròfon o feu lliscar el dit pel teclat en pantalla."</string>
+ <string name="voice_listening" msgid="467518160751321844">"Parleu ara"</string>
+ <string name="voice_working" msgid="6666937792815731889">"S\'està treballant"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"Error. Torneu-ho a provar."</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"No s\'ha pogut connectar"</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"Error; s\'ha parlat massa."</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"Problema d\'àudio"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"Error del servidor"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"No s\'escolten paraules"</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"No hi ha resultats"</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"Cerca per veu no instal·lada"</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Consell:"</b>" Feu lliscar el dit pel teclat per parlar"</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Suggeriment:"</b>" La propera vegada, proveu de dir la puntuació, com ara \"punt\", \"coma\" o \"interrogant\"."</string>
+ <string name="cancel" msgid="6830980399865683324">"Cancel·la"</string>
+ <string name="ok" msgid="7898366843681727667">"D\'acord"</string>
+ <string name="voice_input" msgid="2466640768843347841">"Entrada de veu"</string>
+ <string-array name="voice_input_modes">
+ <item msgid="1349082139076086774">"Al teclat principal"</item>
+ <item msgid="8529385602829095903">"Al teclat de símbols"</item>
+ <item msgid="7283103513488381103">"Desactivat"</item>
+ </string-array>
+ <string-array name="voice_input_modes_summary">
+ <item msgid="554248625705084903">"Micròfon al teclat principal"</item>
+ <item msgid="6907837061058876770">"Micròfon al teclat de símbols"</item>
+ <item msgid="3664304608587798036">"L\'entrada de veu està desactivada"</item>
+ </string-array>
+ <string name="auto_submit" msgid="9151008027068358518">"Enviament automàtic després de la veu"</string>
+ <string name="auto_submit_summary" msgid="4961875269610384226">"Prem automàticament Retorn en cercar o en anar al camp següent."</string>
+ <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Obrir el teclat"\n</b></font><font size="3">\n</font>"Toqueu qualsevol camp de text."</string>
+ <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Tancar el teclat"\n</b></font><font size="3">\n</font>"Premeu la tecla Enrere."</string>
+ <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Manteniu premuda una tecla per veure les opcions"\n</b></font><font size="3">\n</font>"Accediu a la puntuació i als accents."</string>
+ <string name="keyboard_settings" msgid="4585753477617374032"><font size="17"><b>"Configuració del teclat"\n</b></font><font size="3">\n</font>"Manteniu premuda la tecla "<b>"?123"</b>"."</string>
+ <string name="popular_domain_0" msgid="3745279225122472969">".com"</string>
+ <string name="popular_domain_1" msgid="1370572248164278467">".net"</string>
+ <string name="popular_domain_2" msgid="3036812463748402878">".org"</string>
+ <string name="popular_domain_3" msgid="8718639560809452028">".gov"</string>
+ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"Selecciona el mètode d\'entrada"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Idiomes d\'entrada"</string>
+ <string name="language_selection_summary" msgid="187110938289512256">"Feu lliscar el dit a la barra espaiadora per canviar l\'idioma"</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Torna a tocar per desar"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"Diccionari disponible"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"Activa els comentaris de l\'usuari"</string>
+ <string name="prefs_description_log" msgid="5827825607258246003">"Ajuda a millorar aquest editor de mètodes d\'entrada enviant automàticament estadístiques d\'ús i informes de bloqueigs a Google."</string>
+ <string name="prefs_enable_recorrection" msgid="4588408906649533582">"Toca per corregir paraules"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="1056068922330206170">"Toca les paraules introduïdes per corregir-les"</string>
+ <string name="keyboard_layout" msgid="437433231038683666">"Tema del teclat"</string>
+ <string name="subtype_mode_keyboard" msgid="2242090416595003881">"teclat"</string>
+ <string name="subtype_mode_voice" msgid="4394113125441627771">"veu"</string>
+</resources>
diff --git a/java/res/values-cs-rQY/donottranslate-altchars.xml b/java/res/values-cs-rQY/donottranslate-altchars.xml
new file mode 100644
index 0000000..7c4e9be
--- /dev/null
+++ b/java/res/values-cs-rQY/donottranslate-altchars.xml
@@ -0,0 +1,43 @@
+<?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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="alternates_for_a">áäàâãåæ</string>
+ <string name="alternates_for_b">{</string>
+ <string name="alternates_for_c">&amp;čç</string>
+ <string name="alternates_for_d">ďĐ</string>
+ <string name="alternates_for_e">3éě€èêë</string>
+ <string name="alternates_for_f">[</string>
+ <string name="alternates_for_g">]</string>
+ <string name="alternates_for_i">8íïîìí</string>
+ <string name="alternates_for_k">ł</string>
+ <string name="alternates_for_l">Ł</string>
+ <string name="alternates_for_n">}ňñ</string>
+ <string name="alternates_for_o">9óøœöõôò</string>
+ <string name="alternates_for_q">1\\</string>
+ <string name="alternates_for_r">4ř</string>
+ <string name="alternates_for_s">š§ßđ</string>
+ <string name="alternates_for_t">5ť</string>
+ <string name="alternates_for_u">7úůüûù</string>
+ <string name="alternates_for_v">\@</string>
+ <string name="alternates_for_w">2|</string>
+ <string name="alternates_for_x">#</string>
+ <string name="alternates_for_y">6ýÿ</string>
+ <string name="alternates_for_z">ž</string>
+</resources>
diff --git a/java/res/values-cs-rQY/donottranslate-keymap.xml b/java/res/values-cs-rQY/donottranslate-keymap.xml
new file mode 100644
index 0000000..0454f0f
--- /dev/null
+++ b/java/res/values-cs-rQY/donottranslate-keymap.xml
@@ -0,0 +1,222 @@
+<?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.
+**
+**
+** 5-row layout for Czech QWERTY.
+**
+** See http://code.google.com/p/hackerskeyboard/wiki/AddingNewLayouts for
+** more information.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="key_tlde_main">;</string>
+ <string name="key_tlde_shift">°</string>
+ <string name="key_tlde_alt">;°`~</string>
+
+ <string name="key_ae01_main">+</string>
+ <string name="key_ae01_shift">1</string>
+ <string name="key_ae01_alt">+1~!¹¡½⅓¼⅛</string>
+
+ <string name="key_ae02_main">ě</string>
+ <string name="key_ae02_shift">2</string>
+ <string name="key_ae02_alt">ě2\@²⅛⅔</string>
+
+ <string name="key_ae03_main">š</string>
+ <string name="key_ae03_shift">3</string>
+ <string name="key_ae03_alt">š3#³£¾⅜</string>
+
+ <string name="key_ae04_main">č</string>
+ <string name="key_ae04_shift">4</string>
+ <string name="key_ae04_alt">č4$¼¤⁴¢¥</string>
+
+ <string name="key_ae05_main">ř</string>
+ <string name="key_ae05_shift">5</string>
+ <string name="key_ae05_alt">ř5%½⅜‰</string>
+
+ <string name="key_ae06_main">ž</string>
+ <string name="key_ae06_shift">6</string>
+ <string name="key_ae06_alt">ž6^¬⅝</string>
+
+ <string name="key_ae07_main">ý</string>
+ <string name="key_ae07_shift">7</string>
+ <string name="key_ae07_alt">ý7&amp;{⅞♪√</string>
+
+ <string name="key_ae08_main">á</string>
+ <string name="key_ae08_shift">8</string>
+ <string name="key_ae08_alt">á8*[™∞</string>
+
+ <string name="key_ae09_main">í</string>
+ <string name="key_ae09_shift">9</string>
+ <string name="key_ae09_alt">í9(]±</string>
+
+ <string name="key_ae10_main">é</string>
+ <string name="key_ae10_shift">0</string>
+ <string name="key_ae10_alt">é0)}°ⁿ≈≠</string>
+
+ <string name="key_ae11_main">=</string>
+ <string name="key_ae11_shift">%</string>
+ <string name="key_ae11_alt">=%-_\?\¿</string>
+
+ <string name="key_ae12_main">&#x0301;</string>
+ <string name="key_ae12_shift">&#x030c;</string>
+ <string name="key_ae12_alt">&#x0301;&#x030c;&lt;&gt;|</string>
+
+
+ <string name="key_ad01_main">q</string>
+ <string name="key_ad01_shift">Q</string>
+ <string name="key_ad01_alt">@string/alternates_for_q</string>
+
+ <string name="key_ad02_main">w</string>
+ <string name="key_ad02_shift">W</string>
+ <string name="key_ad02_alt">@string/alternates_for_w</string>
+
+ <string name="key_ad03_main">e</string>
+ <string name="key_ad03_shift">E</string>
+ <string name="key_ad03_alt">@string/alternates_for_e</string>
+
+ <string name="key_ad04_main">r</string>
+ <string name="key_ad04_shift">R</string>
+ <string name="key_ad04_alt">@string/alternates_for_r</string>
+
+ <string name="key_ad05_main">t</string>
+ <string name="key_ad05_shift">T</string>
+ <string name="key_ad05_alt">@string/alternates_for_t</string>
+
+ <string name="key_ad06_main">y</string>
+ <string name="key_ad06_shift">Y</string>
+ <string name="key_ad06_alt">@string/alternates_for_y</string>
+
+ <string name="key_ad07_main">u</string>
+ <string name="key_ad07_shift">U</string>
+ <string name="key_ad07_alt">@string/alternates_for_u</string>
+
+ <string name="key_ad08_main">i</string>
+ <string name="key_ad08_shift">I</string>
+ <string name="key_ad08_alt">@string/alternates_for_i</string>
+
+ <string name="key_ad09_main">o</string>
+ <string name="key_ad09_shift">O</string>
+ <string name="key_ad09_alt">@string/alternates_for_o</string>
+
+ <string name="key_ad10_main">p</string>
+ <string name="key_ad10_shift">P</string>
+ <string name="key_ad10_alt">@string/alternates_for_p</string>
+
+ <string name="key_ad11_main">ú</string>
+ <string name="key_ad11_shift">/</string>
+ <string name="key_ad11_alt">ú/÷[{</string>
+
+ <string name="key_ad12_main">)</string>
+ <string name="key_ad12_shift">(</string>
+ <string name="key_ad12_alt">)(×]}</string>
+
+ <string name="key_bksl_main">\'</string>
+ <string name="key_bksl_shift">\\</string>
+ <string name="key_bksl_alt">\'\\|¤</string>
+
+
+ <string name="key_ac01_main">a</string>
+ <string name="key_ac01_shift">A</string>
+ <string name="key_ac01_alt">@string/alternates_for_a</string>
+
+ <string name="key_ac02_main">s</string>
+ <string name="key_ac02_shift">S</string>
+ <string name="key_ac02_alt">@string/alternates_for_s</string>
+
+ <string name="key_ac03_main">d</string>
+ <string name="key_ac03_shift">D</string>
+ <string name="key_ac03_alt">@string/alternates_for_d</string>
+
+ <string name="key_ac04_main">f</string>
+ <string name="key_ac04_shift">F</string>
+ <string name="key_ac04_alt">@string/alternates_for_f</string>
+
+ <string name="key_ac05_main">g</string>
+ <string name="key_ac05_shift">G</string>
+ <string name="key_ac05_alt">@string/alternates_for_g</string>
+
+ <string name="key_ac06_main">h</string>
+ <string name="key_ac06_shift">H</string>
+ <string name="key_ac06_alt">@string/alternates_for_h</string>
+
+ <string name="key_ac07_main">j</string>
+ <string name="key_ac07_shift">J</string>
+ <string name="key_ac07_alt">@string/alternates_for_j</string>
+
+ <string name="key_ac08_main">k</string>
+ <string name="key_ac08_shift">K</string>
+ <string name="key_ac08_alt">@string/alternates_for_k</string>
+
+ <string name="key_ac09_main">l</string>
+ <string name="key_ac09_shift">L</string>
+ <string name="key_ac09_alt">@string/alternates_for_l</string>
+
+ <string name="key_ac10_main">ů</string>
+ <string name="key_ac10_shift">\"</string>
+ <string name="key_ac10_alt">ů\"$;:</string>
+
+ <string name="key_ac11_main">§</string>
+ <string name="key_ac11_shift">!</string>
+ <string name="key_ac11_alt">§!ß\'\"‘’“”</string>
+
+
+ <string name="key_lsgt_main"></string>
+ <string name="key_lsgt_shift"></string>
+ <string name="key_lsgt_alt"></string>
+
+ <string name="key_ab01_main">z</string>
+ <string name="key_ab01_shift">Z</string>
+ <string name="key_ab01_alt">@string/alternates_for_z</string>
+
+ <string name="key_ab02_main">x</string>
+ <string name="key_ab02_shift">X</string>
+ <string name="key_ab02_alt">@string/alternates_for_x</string>
+
+ <string name="key_ab03_main">c</string>
+ <string name="key_ab03_shift">C</string>
+ <string name="key_ab03_alt">@string/alternates_for_c</string>
+
+ <string name="key_ab04_main">v</string>
+ <string name="key_ab04_shift">V</string>
+ <string name="key_ab04_alt">@string/alternates_for_v</string>
+
+ <string name="key_ab05_main">b</string>
+ <string name="key_ab05_shift">B</string>
+ <string name="key_ab05_alt">@string/alternates_for_b</string>
+
+ <string name="key_ab06_main">n</string>
+ <string name="key_ab06_shift">N</string>
+ <string name="key_ab06_alt">@string/alternates_for_n</string>
+
+ <string name="key_ab07_main">m</string>
+ <string name="key_ab07_shift">M</string>
+ <string name="key_ab07_alt">@string/alternates_for_m</string>
+
+ <string name="key_ab08_main">,</string>
+ <string name="key_ab08_shift">\?</string>
+ <string name="key_ab08_alt">,\?&lt;≤«‹</string>
+
+ <string name="key_ab09_main">.</string>
+ <string name="key_ab09_shift">:</string>
+ <string name="key_ab09_alt">.:&gt;≥»›…</string>
+
+ <string name="key_ab10_main">-</string>
+ <string name="key_ab10_shift">_</string>
+ <string name="key_ab10_alt">-_\?¿*</string>
+</resources>
+ \ No newline at end of file
diff --git a/java/res/values-cs/donottranslate-altchars.xml b/java/res/values-cs/donottranslate-altchars.xml
new file mode 100644
index 0000000..f6e5b4b
--- /dev/null
+++ b/java/res/values-cs/donottranslate-altchars.xml
@@ -0,0 +1,43 @@
+<?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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="alternates_for_a">áäàâãåæ</string>
+ <string name="alternates_for_b">{</string>
+ <string name="alternates_for_c">&amp;čç</string>
+ <string name="alternates_for_d">ďĐ</string>
+ <string name="alternates_for_e">3éě€èêë</string>
+ <string name="alternates_for_f">[</string>
+ <string name="alternates_for_g">]</string>
+ <string name="alternates_for_i">8íïîìí</string>
+ <string name="alternates_for_k">ł</string>
+ <string name="alternates_for_l">Ł</string>
+ <string name="alternates_for_n">}ňñ</string>
+ <string name="alternates_for_o">9óøœöõôò</string>
+ <string name="alternates_for_q">1\\</string>
+ <string name="alternates_for_r">4ř</string>
+ <string name="alternates_for_s">š§ßđ</string>
+ <string name="alternates_for_t">5ť</string>
+ <string name="alternates_for_u">7úůüûù</string>
+ <string name="alternates_for_v">\@</string>
+ <string name="alternates_for_w">2|</string>
+ <string name="alternates_for_x">#</string>
+ <string name="alternates_for_y">ýÿ</string>
+ <string name="alternates_for_z">6ž</string>
+</resources>
diff --git a/java/res/values-cs/donottranslate-keymap.xml b/java/res/values-cs/donottranslate-keymap.xml
new file mode 100644
index 0000000..30e45f5
--- /dev/null
+++ b/java/res/values-cs/donottranslate-keymap.xml
@@ -0,0 +1,222 @@
+<?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.
+**
+**
+** 5-row layout for Czech QWERTZ.
+**
+** See http://code.google.com/p/hackerskeyboard/wiki/AddingNewLayouts for
+** more information.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="key_tlde_main">;</string>
+ <string name="key_tlde_shift">°</string>
+ <string name="key_tlde_alt">;°`~</string>
+
+ <string name="key_ae01_main">+</string>
+ <string name="key_ae01_shift">1</string>
+ <string name="key_ae01_alt">+1~!¹¡½⅓¼⅛</string>
+
+ <string name="key_ae02_main">ě</string>
+ <string name="key_ae02_shift">2</string>
+ <string name="key_ae02_alt">ě2\@²⅛⅔</string>
+
+ <string name="key_ae03_main">š</string>
+ <string name="key_ae03_shift">3</string>
+ <string name="key_ae03_alt">š3#³£¾⅜</string>
+
+ <string name="key_ae04_main">č</string>
+ <string name="key_ae04_shift">4</string>
+ <string name="key_ae04_alt">č4$¼¤⁴¢¥</string>
+
+ <string name="key_ae05_main">ř</string>
+ <string name="key_ae05_shift">5</string>
+ <string name="key_ae05_alt">ř5%½⅜‰</string>
+
+ <string name="key_ae06_main">ž</string>
+ <string name="key_ae06_shift">6</string>
+ <string name="key_ae06_alt">ž6^¬⅝</string>
+
+ <string name="key_ae07_main">ý</string>
+ <string name="key_ae07_shift">7</string>
+ <string name="key_ae07_alt">ý7&amp;{⅞♪√</string>
+
+ <string name="key_ae08_main">á</string>
+ <string name="key_ae08_shift">8</string>
+ <string name="key_ae08_alt">á8*[™∞</string>
+
+ <string name="key_ae09_main">í</string>
+ <string name="key_ae09_shift">9</string>
+ <string name="key_ae09_alt">í9(]±</string>
+
+ <string name="key_ae10_main">é</string>
+ <string name="key_ae10_shift">0</string>
+ <string name="key_ae10_alt">é0)}°ⁿ≈≠</string>
+
+ <string name="key_ae11_main">=</string>
+ <string name="key_ae11_shift">%</string>
+ <string name="key_ae11_alt">=%-_\?\¿</string>
+
+ <string name="key_ae12_main">&#x0301;</string>
+ <string name="key_ae12_shift">&#x030c;</string>
+ <string name="key_ae12_alt">&#x0301;&#x030c;&lt;&gt;|</string>
+
+
+ <string name="key_ad01_main">q</string>
+ <string name="key_ad01_shift">Q</string>
+ <string name="key_ad01_alt">@string/alternates_for_q</string>
+
+ <string name="key_ad02_main">w</string>
+ <string name="key_ad02_shift">W</string>
+ <string name="key_ad02_alt">@string/alternates_for_w</string>
+
+ <string name="key_ad03_main">e</string>
+ <string name="key_ad03_shift">E</string>
+ <string name="key_ad03_alt">@string/alternates_for_e</string>
+
+ <string name="key_ad04_main">r</string>
+ <string name="key_ad04_shift">R</string>
+ <string name="key_ad04_alt">@string/alternates_for_r</string>
+
+ <string name="key_ad05_main">t</string>
+ <string name="key_ad05_shift">T</string>
+ <string name="key_ad05_alt">@string/alternates_for_t</string>
+
+ <string name="key_ad06_main">z</string>
+ <string name="key_ad06_shift">Z</string>
+ <string name="key_ad06_alt">@string/alternates_for_z</string>
+
+ <string name="key_ad07_main">u</string>
+ <string name="key_ad07_shift">U</string>
+ <string name="key_ad07_alt">@string/alternates_for_u</string>
+
+ <string name="key_ad08_main">i</string>
+ <string name="key_ad08_shift">I</string>
+ <string name="key_ad08_alt">@string/alternates_for_i</string>
+
+ <string name="key_ad09_main">o</string>
+ <string name="key_ad09_shift">O</string>
+ <string name="key_ad09_alt">@string/alternates_for_o</string>
+
+ <string name="key_ad10_main">p</string>
+ <string name="key_ad10_shift">P</string>
+ <string name="key_ad10_alt">@string/alternates_for_p</string>
+
+ <string name="key_ad11_main">ú</string>
+ <string name="key_ad11_shift">/</string>
+ <string name="key_ad11_alt">ú/÷[{</string>
+
+ <string name="key_ad12_main">)</string>
+ <string name="key_ad12_shift">(</string>
+ <string name="key_ad12_alt">)(×]}</string>
+
+ <string name="key_bksl_main">\'</string>
+ <string name="key_bksl_shift">\\</string>
+ <string name="key_bksl_alt">\'\\|¤</string>
+
+
+ <string name="key_ac01_main">a</string>
+ <string name="key_ac01_shift">A</string>
+ <string name="key_ac01_alt">@string/alternates_for_a</string>
+
+ <string name="key_ac02_main">s</string>
+ <string name="key_ac02_shift">S</string>
+ <string name="key_ac02_alt">@string/alternates_for_s</string>
+
+ <string name="key_ac03_main">d</string>
+ <string name="key_ac03_shift">D</string>
+ <string name="key_ac03_alt">@string/alternates_for_d</string>
+
+ <string name="key_ac04_main">f</string>
+ <string name="key_ac04_shift">F</string>
+ <string name="key_ac04_alt">@string/alternates_for_f</string>
+
+ <string name="key_ac05_main">g</string>
+ <string name="key_ac05_shift">G</string>
+ <string name="key_ac05_alt">@string/alternates_for_g</string>
+
+ <string name="key_ac06_main">h</string>
+ <string name="key_ac06_shift">H</string>
+ <string name="key_ac06_alt">@string/alternates_for_h</string>
+
+ <string name="key_ac07_main">j</string>
+ <string name="key_ac07_shift">J</string>
+ <string name="key_ac07_alt">@string/alternates_for_j</string>
+
+ <string name="key_ac08_main">k</string>
+ <string name="key_ac08_shift">K</string>
+ <string name="key_ac08_alt">@string/alternates_for_k</string>
+
+ <string name="key_ac09_main">l</string>
+ <string name="key_ac09_shift">L</string>
+ <string name="key_ac09_alt">@string/alternates_for_l</string>
+
+ <string name="key_ac10_main">ů</string>
+ <string name="key_ac10_shift">\"</string>
+ <string name="key_ac10_alt">ů\"$;:</string>
+
+ <string name="key_ac11_main">§</string>
+ <string name="key_ac11_shift">!</string>
+ <string name="key_ac11_alt">§!ß\'\"‘’“”</string>
+
+
+ <string name="key_lsgt_main"></string>
+ <string name="key_lsgt_shift"></string>
+ <string name="key_lsgt_alt"></string>
+
+ <string name="key_ab01_main">y</string>
+ <string name="key_ab01_shift">Y</string>
+ <string name="key_ab01_alt">@string/alternates_for_y</string>
+
+ <string name="key_ab02_main">x</string>
+ <string name="key_ab02_shift">X</string>
+ <string name="key_ab02_alt">@string/alternates_for_x</string>
+
+ <string name="key_ab03_main">c</string>
+ <string name="key_ab03_shift">C</string>
+ <string name="key_ab03_alt">@string/alternates_for_c</string>
+
+ <string name="key_ab04_main">v</string>
+ <string name="key_ab04_shift">V</string>
+ <string name="key_ab04_alt">@string/alternates_for_v</string>
+
+ <string name="key_ab05_main">b</string>
+ <string name="key_ab05_shift">B</string>
+ <string name="key_ab05_alt">@string/alternates_for_b</string>
+
+ <string name="key_ab06_main">n</string>
+ <string name="key_ab06_shift">N</string>
+ <string name="key_ab06_alt">@string/alternates_for_n</string>
+
+ <string name="key_ab07_main">m</string>
+ <string name="key_ab07_shift">M</string>
+ <string name="key_ab07_alt">@string/alternates_for_m</string>
+
+ <string name="key_ab08_main">,</string>
+ <string name="key_ab08_shift">\?</string>
+ <string name="key_ab08_alt">,\?&lt;≤«‹</string>
+
+ <string name="key_ab09_main">.</string>
+ <string name="key_ab09_shift">:</string>
+ <string name="key_ab09_alt">.:&gt;≥»›…</string>
+
+ <string name="key_ab10_main">-</string>
+ <string name="key_ab10_shift">_</string>
+ <string name="key_ab10_alt">-_\?¿*</string>
+</resources>
+ \ No newline at end of file
diff --git a/java/res/values-cs/strings.xml b/java/res/values-cs/strings.xml
new file mode 100644
index 0000000..6573584
--- /dev/null
+++ b/java/res/values-cs/strings.xml
@@ -0,0 +1,140 @@
+<?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/org.pocketworkstation.pckeyboard"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- <string name="english_ime_name" msgid="7252517407088836577">"Klávesnice Android"</string> -->
+ <!-- <string name="english_ime_settings" msgid="6661589557206947774">"Nastavení klávesnice Android"</string> -->
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Možnosti zadávání textu a dat"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"Při stisku klávesy vibrovat"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"Zvuk při stisku klávesy"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"Zobrazit znaky při stisku klávesy"</string>
+ <string name="hit_correction" msgid="4855351009261318389">"Opravovat překlepy"</string>
+ <string name="hit_correction_summary" msgid="8761701873008070796">"Povolit opravu chyb vstupu"</string>
+ <string name="hit_correction_land" msgid="2567691684825205448">"Chyby vstupu v zobrazení na šířku"</string>
+ <string name="hit_correction_land_summary" msgid="4076803842198368328">"Povolit opravu chyb vstupu"</string>
+ <string name="auto_correction" msgid="7911639788808958255">"Návrhy slov"</string>
+ <string name="auto_correction_summary" msgid="6881047311475758267">"Automaticky opravit předchozí slovo"</string>
+ <string name="prediction" msgid="466220283138359837">"Návrhy slov"</string>
+ <string name="prediction_category" msgid="7027100625580696660">"Nastavení návrhů slov"</string>
+ <string name="prediction_summary" msgid="459788228830873110">"Povolit automatické dokončování při psaní"</string>
+ <string name="auto_complete_dialog_title" msgid="2172048590607201920">"Automatické dokončování"</string>
+ <string name="prediction_landscape" msgid="4874601565593216183">"Zvětšit textové pole"</string>
+ <string name="prediction_landscape_summary" msgid="6736551095997839472">"Skrýt návrhy slov v zobrazení na šířku"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"Velká písmena automaticky"</string>
+ <string name="auto_cap_summary" msgid="3260681697600786825">"Zahájit větu velkým písmenem"</string>
+ <string name="auto_punctuate" msgid="7276672334264521751">"Automatická interpunkce"</string>
+ <string name="auto_punctuate_summary" msgid="6589441565817502132"></string>
+ <string name="quick_fixes" msgid="5353213327680897927">"Rychlé opravy"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"Opravuje nejčastější chyby při psaní"</string>
+ <string name="show_suggestions" msgid="507074425254289133">"Zobrazit návrhy"</string>
+ <string name="show_suggestions_summary" msgid="1989672863935759654">"Zobrazovat navržená slova během psaní"</string>
+ <string name="auto_complete" msgid="1103196318775486023">"Automatické dokončování"</string>
+ <string name="auto_complete_summary" msgid="6113149638718274624">"Stisknutím mezerníku nebo interpunkčního znaménka automaticky vložíte zvýrazněné slovo."</string>
+ <string name="prefs_settings_key" msgid="4623341240804046498">"Zobrazit klávesu Nastavení"</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automaticky"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Vždy zobrazovat"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"Vždy skrývat"</string>
+ <!-- no translation found for settings_key_modes:0 (8549888726962891527) -->
+ <!-- no translation found for settings_key_modes:1 (881280041213210923) -->
+ <!-- no translation found for settings_key_modes:2 (7317310620171067848) -->
+ <string name="bigram_suggestion" msgid="1323347224043514969">"Návrh Bigram"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Použít předchozí slovo ke zlepšení návrhu"</string>
+ <string-array name="prediction_modes">
+ <item msgid="4870266572388153286">"Žádný"</item>
+ <item msgid="1669461741568287396">"Základní"</item>
+ <item msgid="4894328801530136615">"Pokročilé"</item>
+ </string-array>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: Uloženo"</string>
+ <string name="tip_long_press" msgid="6101270866284343344">"Podržením klávesy zobrazíte diakritiku (á, ž apod.)"</string>
+ <string name="tip_dismiss" msgid="7585579046862204381">"Stisknutím klávesy Zpět ↶ můžete klávesnici kdykoli zavřít."</string>
+ <string name="tip_access_symbols" msgid="6344098517525531652">"Přístup k číslům a symbolům"</string>
+ <string name="tip_add_to_dictionary" msgid="1487293888469227817">"Stisknutím a podržením slova zcela vlevo toto slovo přidáte do slovníku."</string>
+ <string name="touch_to_continue" msgid="7869803257948414531">"Chcete-li pokračovat, dotkněte se tohoto tipu »"</string>
+ <string name="touch_to_finish" msgid="7990196086480585789">"Chcete-li tento tip zavřít a začít psát, dotkněte se zde."</string>
+ <string name="tip_to_open_keyboard" msgid="6821200275486950452"><b>"Klávesnice se otevře vždy, když se dotknete textového pole."</b></string>
+ <string name="tip_to_view_accents" msgid="5433158573693308501"><b>"Přidržením klávesy zobrazíte diakritiku"\n"(ó, ø, ö, ô apod.)"</b></string>
+ <string name="tip_to_open_symbols" msgid="7345139325622444880"><b>"Chcete-li přepnout na režim zadávání číslic a symbolů, dotkněte se této klávesy."</b></string>
+ <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"Chcete-li přejít zpět k zadávání písmen, dotkněte se této klávesy znovu."</b></string>
+ <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"Přidržením této klávesy změníte nastavení klávesnice (např. automatické dokončování)."</b></string>
+ <string name="tip_to_start_typing" msgid="7213843601369174313"><b>"Vyzkoušejte si to."</b></string>
+ <string name="label_go_key" msgid="1635148082137219148">"Přejít"</string>
+ <string name="label_next_key" msgid="362972844525672568">"Další"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"Hotovo"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"Odeslat"</string>
+ <string name="label_symbol_key" msgid="6175820506864489453">"?123"</string>
+ <string name="label_phone_key" msgid="4275497665515080551">"123"</string>
+ <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string>
+ <string name="label_alt_key" msgid="2846315350346694811">"Alt"</string>
+ <string name="voice_warning_title" msgid="4419354150908395008">"Hlasový vstup"</string>
+ <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Pro váš jazyk aktuálně není hlasový vstup podporován, ale funguje v angličtině."</string>
+ <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"Hlasový vstup je experimentální funkce, která využívá síťové rozpoznávání řeči společnosti Google."</string>
+ <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"Chcete-li vypnout hlasový vstup, přejděte do nastavení klávesnice."</string>
+ <string name="voice_hint_dialog_message" msgid="6892342981545727994">"Chcete-li použít hlasový vstup, stiskněte tlačítko mikrofonu nebo přejeďte prstem přes klávesnici na obrazovce."</string>
+ <string name="voice_listening" msgid="467518160751321844">"Mluvte"</string>
+ <string name="voice_working" msgid="6666937792815731889">"Probíhá zpracování"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"Chyba. Zkuste to prosím znovu."</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"Připojení se nezdařilo."</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"Chyba, řeč je příliš dlouhá."</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"Problém se zvukem"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"Chyba serveru"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"Nebyla detekována žádná řeč."</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"Nebyly nalezeny žádné shody"</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"Hlasové vyhledávání není nainstalováno"</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Nápověda:"</b>" Chcete-li aktivovat hlasový vstup, přejeďte prstem přes klávesnici."</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Nápověda:"</b>" Příště zkuste vyslovit interpunkci, například „tečka“, „čárka“ nebo „otazník“."</string>
+ <string name="cancel" msgid="6830980399865683324">"Zrušit"</string>
+ <string name="ok" msgid="7898366843681727667">"OK"</string>
+ <string name="voice_input" msgid="2466640768843347841">"Hlasový vstup"</string>
+ <string-array name="voice_input_modes">
+ <item msgid="1349082139076086774">"Na hlavní klávesnici"</item>
+ <item msgid="8529385602829095903">"Na klávesnici se symboly"</item>
+ <item msgid="7283103513488381103">"Vypnout"</item>
+ </string-array>
+ <string-array name="voice_input_modes_summary">
+ <item msgid="554248625705084903">"Mikrofon na hlavní klávesnici"</item>
+ <item msgid="6907837061058876770">"Mikrofon na klávesnici se symboly"</item>
+ <item msgid="3664304608587798036">"Hlasový vstup je deaktivován"</item>
+ </string-array>
+ <string name="auto_submit" msgid="9151008027068358518">"Po hlasovém vstupu automaticky odeslat"</string>
+ <string name="auto_submit_summary" msgid="4961875269610384226">"Při vyhledávání nebo přechodu na další pole automaticky stisknout Enter."</string>
+ <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Otevřete klávesnici"\n</b></font><font size="3">\n</font>"Dotkněte se libovolného textového pole."</string>
+ <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Zavřete klávesnici"\n</b></font><font size="3">\n</font>"Stiskněte tlačítko Zpět."</string>
+ <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Přidržením klávesy zobrazte možnosti"\n</b></font><font size="3">\n</font>"Přístup k interpunkčním znaménkům a diakritice."</string>
+ <string name="keyboard_settings" msgid="4585753477617374032"><font size="17"><b>"Nastavení klávesnice"\n</b></font><font size="3">\n</font>"Dotkněte se klávesy "<b>"?123"</b>" a přidržte ji."</string>
+ <string name="popular_domain_0" msgid="3745279225122472969">".com"</string>
+ <string name="popular_domain_1" msgid="1370572248164278467">".cz"</string>
+ <string name="popular_domain_2" msgid="3036812463748402878">".org"</string>
+ <string name="popular_domain_3" msgid="8718639560809452028">".net"</string>
+ <string name="popular_domain_4" msgid="35359437471311470">".eu"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"Výběr metody zadávání dat"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Vstupní jazyky"</string>
+ <string name="language_selection_summary" msgid="187110938289512256">"Jazyk můžete změnit posunutím prstu po mezerníku."</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Dalším dotykem slovo uložíte"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"K dispozici je slovník"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"Aktivovat zasílání statistik užívání a zpráv o selhání"</string>
+ <string name="prefs_description_log" msgid="5827825607258246003">"Automatickým zasíláním statistik o užívání editoru zadávání dat a zpráv o jeho selhání do Googlu můžete přispět k vylepšení tohoto nástroje."</string>
+ <string name="prefs_enable_recorrection" msgid="4588408906649533582">"Aktivovat opravy dotykem"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="1056068922330206170">"Opravy napsaných slov dotykem"</string>
+ <string name="keyboard_layout" msgid="437433231038683666">"Motiv klávesnice"</string>
+ <string name="subtype_mode_keyboard" msgid="2242090416595003881">"klávesnice"</string>
+ <string name="subtype_mode_voice" msgid="4394113125441627771">"hlas"</string>
+</resources>
diff --git a/java/res/values-da/donottranslate-altchars.xml b/java/res/values-da/donottranslate-altchars.xml
new file mode 100644
index 0000000..81b386a
--- /dev/null
+++ b/java/res/values-da/donottranslate-altchars.xml
@@ -0,0 +1,41 @@
+<?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.
+**
+** Danish alternate glyphs for 4 row keyboard
+** Christian Holm Christensen <cholmcc@gmail.com>
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="alternates_for_a">áàâąãåæ</string>
+ <string name="alternates_for_e">3éèêëę€</string>
+ <string name="alternates_for_i">8ïîìí</string>
+ <string name="alternates_for_o">9õôòóø</string>
+ <string name="alternates_for_u">7ūûùú</string>
+ <string name="alternates_for_s">śšşß</string>
+ <string name="alternates_for_n">ńñň</string>
+ <string name="alternates_for_c">çćč</string>
+ <string name="alternates_for_y">6üÿý</string>
+ <string name="alternates_for_d">ðď</string>
+ <string name="alternates_for_r">4ř</string>
+ <string name="alternates_for_t">5þť</string>
+ <string name="alternates_for_z">źžż</string>
+ <string name="alternates_for_l">ł</string>
+ <string name="alternates_for_v">w</string>
+ <string name="alternates_for_a_umlaut">æ</string>
+ <string name="alternates_for_o_umlaut">øœ</string>
+</resources>
diff --git a/java/res/values-da/donottranslate-keymap.xml b/java/res/values-da/donottranslate-keymap.xml
new file mode 100644
index 0000000..d4430cf
--- /dev/null
+++ b/java/res/values-da/donottranslate-keymap.xml
@@ -0,0 +1,222 @@
+<?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.
+**
+**
+** 5-row layout for Danish QWERTY.
+** By Christian Holm Christensen <cholmcc@gmail.com>.
+** Based on 5-row layout for Swedish QWERTY.
+**
+** See http://code.google.com/p/hackerskeyboard/wiki/AddingNewLayouts for
+** more information.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="key_tlde_main">§</string>
+ <string name="key_tlde_shift">½</string>
+ <string name="key_tlde_alt">§½¼¾¶</string>
+
+ <string name="key_ae01_main">1</string>
+ <string name="key_ae01_shift">!</string>
+ <string name="key_ae01_alt">1!¡¹</string>
+
+ <string name="key_ae02_main">2</string>
+ <string name="key_ae02_shift">\"</string>
+ <string name="key_ae02_alt">2\"\@²</string>
+
+ <string name="key_ae03_main">3</string>
+ <string name="key_ae03_shift">#</string>
+ <string name="key_ae03_alt">3#£³</string>
+
+ <string name="key_ae04_main">4</string>
+ <string name="key_ae04_shift">¤</string>
+ <string name="key_ae04_alt">4¤$¼</string>
+
+ <string name="key_ae05_main">5</string>
+ <string name="key_ae05_shift">%</string>
+ <string name="key_ae05_alt">5%½¢</string>
+
+ <string name="key_ae06_main">6</string>
+ <string name="key_ae06_shift">&amp;</string>
+ <string name="key_ae06_alt">6&amp;¥⅝</string>
+
+ <string name="key_ae07_main">7</string>
+ <string name="key_ae07_shift">/</string>
+ <string name="key_ae07_alt">7/{÷</string>
+
+ <string name="key_ae08_main">8</string>
+ <string name="key_ae08_shift">(</string>
+ <string name="key_ae08_alt">8([«</string>
+
+ <string name="key_ae09_main">9</string>
+ <string name="key_ae09_shift">)</string>
+ <string name="key_ae09_alt">9)]»</string>
+
+ <string name="key_ae10_main">0</string>
+ <string name="key_ae10_shift">=</string>
+ <string name="key_ae10_alt">0=}°</string>
+
+ <string name="key_ae11_main">+</string>
+ <string name="key_ae11_shift">\?</string>
+ <string name="key_ae11_alt">+\?\\¿±</string>
+
+ <string name="key_ae12_main">&#x301;</string>
+ <string name="key_ae12_shift">&#x300;</string>
+ <string name="key_ae12_alt">&#x301;&#x300;`|¦</string>
+
+
+ <string name="key_ad01_main">q</string>
+ <string name="key_ad01_shift">Q</string>
+ <string name="key_ad01_alt">\@Ω</string>
+
+ <string name="key_ad02_main">w</string>
+ <string name="key_ad02_shift">W</string>
+ <string name="key_ad02_alt">ł</string>
+
+ <string name="key_ad03_main">e</string>
+ <string name="key_ad03_shift">E</string>
+ <string name="key_ad03_alt">€¢éèêë</string>
+
+ <string name="key_ad04_main">r</string>
+ <string name="key_ad04_shift">R</string>
+ <string name="key_ad04_alt">r®</string>
+
+ <string name="key_ad05_main">t</string>
+ <string name="key_ad05_shift">T</string>
+ <string name="key_ad05_alt">þ</string>
+
+ <string name="key_ad06_main">y</string>
+ <string name="key_ad06_shift">Y</string>
+ <string name="key_ad06_alt">ÿ←¥</string>
+
+ <string name="key_ad07_main">u</string>
+ <string name="key_ad07_shift">U</string>
+ <string name="key_ad07_alt">üû↓↑</string>
+
+ <string name="key_ad08_main">i</string>
+ <string name="key_ad08_shift">I</string>
+ <string name="key_ad08_alt">íï→ı</string>
+
+ <string name="key_ad09_main">o</string>
+ <string name="key_ad09_shift">O</string>
+ <string name="key_ad09_alt">ôõœ</string>
+
+ <string name="key_ad10_main">p</string>
+ <string name="key_ad10_shift">P</string>
+ <string name="key_ad10_alt">þ</string>
+
+ <string name="key_ad11_main">å</string>
+ <string name="key_ad11_shift">Å</string>
+ <string name="key_ad11_alt">&#x308;&#x30a;</string>
+
+ <string name="key_ad12_main">&#x308;</string>
+ <string name="key_ad12_shift">&#x302;</string>
+ <string name="key_ad12_alt">&#x308;&#x302;~&#x303;&#x30c;</string>
+
+
+ <string name="key_bksl_main">\'</string>
+ <string name="key_bksl_shift">*</string>
+ <string name="key_bksl_alt">\'*×˝</string>
+
+ <string name="key_ac01_main">a</string>
+ <string name="key_ac01_shift">A</string>
+ <string name="key_ac01_alt">âãáà@ªº</string>
+
+ <string name="key_ac02_main">s</string>
+ <string name="key_ac02_shift">S</string>
+ <string name="key_ac02_alt">ߧ</string>
+
+ <string name="key_ac03_main">d</string>
+ <string name="key_ac03_shift">D</string>
+ <string name="key_ac03_alt">ð</string>
+
+ <string name="key_ac04_main">f</string>
+ <string name="key_ac04_shift">F</string>
+ <string name="key_ac04_alt">đª</string>
+
+ <string name="key_ac05_main">g</string>
+ <string name="key_ac05_shift">G</string>
+ <string name="key_ac05_alt">ŋ</string>
+
+ <string name="key_ac06_main">h</string>
+ <string name="key_ac06_shift">H</string>
+ <string name="key_ac06_alt">ħ</string>
+
+ <string name="key_ac07_main">j</string>
+ <string name="key_ac07_shift">J</string>
+ <string name="key_ac07_alt"></string>
+
+ <string name="key_ac08_main">k</string>
+ <string name="key_ac08_shift">K</string>
+ <string name="key_ac08_alt">ĸ&amp;</string>
+
+ <string name="key_ac09_main">l</string>
+ <string name="key_ac09_shift">L</string>
+ <string name="key_ac09_alt">ł</string>
+
+ <string name="key_ac10_main">æ</string>
+ <string name="key_ac10_shift">Æ</string>
+ <string name="key_ac10_alt">ä\'˝</string>
+
+ <string name="key_ac11_main">ø</string>
+ <string name="key_ac11_shift">Ø</string>
+ <string name="key_ac11_alt">ö^ˇ</string>
+
+ <string name="key_lsgt_main">&gt;</string>
+ <string name="key_lsgt_shift">&lt;</string>
+ <string name="key_lsgt_alt">&gt;&lt;|«»</string>
+
+ <string name="key_ab01_main">z</string>
+ <string name="key_ab01_shift">Z</string>
+ <string name="key_ab01_alt">«&lt;</string>
+
+ <string name="key_ab02_main">x</string>
+ <string name="key_ab02_shift">X</string>
+ <string name="key_ab02_alt">»&gt;</string>
+
+ <string name="key_ab03_main">c</string>
+ <string name="key_ab03_shift">C</string>
+ <string name="key_ab03_alt">©</string>
+
+ <string name="key_ab04_main">v</string>
+ <string name="key_ab04_shift">V</string>
+ <string name="key_ab04_alt">“‘</string>
+
+ <string name="key_ab05_main">b</string>
+ <string name="key_ab05_shift">B</string>
+ <string name="key_ab05_alt">”’</string>
+
+ <string name="key_ab06_main">n</string>
+ <string name="key_ab06_shift">N</string>
+ <string name="key_ab06_alt">ñ</string>
+
+ <string name="key_ab07_main">m</string>
+ <string name="key_ab07_shift">M</string>
+ <string name="key_ab07_alt">µº</string>
+
+ <string name="key_ab08_main">,</string>
+ <string name="key_ab08_shift">;</string>
+ <string name="key_ab08_alt">,;</string>
+
+ <string name="key_ab09_main">.</string>
+ <string name="key_ab09_shift">:</string>
+ <string name="key_ab09_alt">.:·˙</string>
+
+ <string name="key_ab10_main">-</string>
+ <string name="key_ab10_shift">_</string>
+ <string name="key_ab10_alt">-¯̣ ˙</string>
+</resources>
diff --git a/java/res/values-da/strings.xml b/java/res/values-da/strings.xml
new file mode 100644
index 0000000..f8efcb3
--- /dev/null
+++ b/java/res/values-da/strings.xml
@@ -0,0 +1,142 @@
+<?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.
+**
+** Modified by Christian Holm Christensen <cholmcc@gmail.com>
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- <string name="english_ime_name" msgid="7252517407088836577">"Android-tastatur"</string> -->
+ <!-- <string name="english_ime_settings" msgid="6661589557206947774">"Indstillinger for Android-tastatur"</string> -->
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Indstillinger for indtastning"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibration ved tastetryk"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"Lyd ved tastetryk"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"Popup ved tastetryk"</string>
+ <string name="hit_correction" msgid="4855351009261318389">"Ret stavefejl"</string>
+ <string name="hit_correction_summary" msgid="8761701873008070796">"Aktivér fejlretning af indtastning"</string>
+ <string name="hit_correction_land" msgid="2567691684825205448">"Indtastingsfejl i landskab"</string>
+ <string name="hit_correction_land_summary" msgid="4076803842198368328">"Aktivér fejlretning af indtastning"</string>
+ <string name="auto_correction" msgid="7911639788808958255">"Ordforslag"</string>
+ <string name="auto_correction_summary" msgid="6881047311475758267">"Ret automatisk det forrige ord"</string>
+ <string name="prediction" msgid="466220283138359837">"Ordforslag"</string>
+ <string name="prediction_category" msgid="7027100625580696660">"Indstillinger for ordforslag"</string>
+ <string name="prediction_summary" msgid="459788228830873110">"Aktivér automatisk udfyldelse, når du indtaster"</string>
+ <string name="auto_complete_dialog_title" msgid="2172048590607201920">"Automatisk udfyldelse"</string>
+ <string name="prediction_landscape" msgid="4874601565593216183">"Forøg tekstfeltets størrelse"</string>
+ <string name="prediction_landscape_summary" msgid="6736551095997839472">"Skjul ordforslag i landskabsvisning"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"Skriv aut. med stort"</string>
+ <string name="auto_cap_summary" msgid="3260681697600786825">"Første bogstav i en sætning skrives med stort"</string>
+ <string name="auto_punctuate" msgid="7276672334264521751">"Foretag automatisk tegnsætning"</string>
+ <string name="auto_punctuate_summary" msgid="6589441565817502132"></string>
+ <string name="quick_fixes" msgid="5353213327680897927">"Hurtige løsninger"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"Retter almindelige stavefejl"</string>
+ <string name="show_suggestions" msgid="507074425254289133">"Vis forslag"</string>
+ <string name="show_suggestions_summary" msgid="1989672863935759654">"Vis ordforslag under indtastning"</string>
+ <string name="auto_complete" msgid="1103196318775486023">"Udfyld automatisk"</string>
+ <string name="auto_complete_summary" msgid="6113149638718274624">"Mellemrumstast og tegnsætning indsætter automatisk fremhævet ord"</string>
+ <string name="prefs_settings_key" msgid="4623341240804046498">"Vis indstillingsnøgle"</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automatisk"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Vis altid"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"Skjul altid"</string>
+ <!-- no translation found for settings_key_modes:0 (8549888726962891527) -->
+ <!-- no translation found for settings_key_modes:1 (881280041213210923) -->
+ <!-- no translation found for settings_key_modes:2 (7317310620171067848) -->
+ <string name="bigram_suggestion" msgid="1323347224043514969">"Bigram-forslag"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Brug forrige ord for at forbedre forslag"</string>
+ <string-array name="prediction_modes">
+ <item msgid="4870266572388153286">"Ingen"</item>
+ <item msgid="1669461741568287396">"Grundlæggende"</item>
+ <item msgid="4894328801530136615">"Avanceret"</item>
+ </string-array>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: Gemt"</string>
+ <string name="tip_long_press" msgid="6101270866284343344">"Hold en tast nede for at se accenter (ø, ö osv.)"</string>
+ <string name="tip_dismiss" msgid="7585579046862204381">"Tryk på knappen Tilbage ↶ for når som helst at lukke for tastaturet"</string>
+ <string name="tip_access_symbols" msgid="6344098517525531652">"Få adgang til tal og symboler"</string>
+ <string name="tip_add_to_dictionary" msgid="1487293888469227817">"Tryk og hold på ordet længst til venstre for at føje det til ordbogen"</string>
+ <string name="touch_to_continue" msgid="7869803257948414531">"Rør dette tip for at fortsætte »"</string>
+ <string name="touch_to_finish" msgid="7990196086480585789">"Rør her for at lukke dette tip og begynde at indtaste!"</string>
+ <string name="tip_to_open_keyboard" msgid="6821200275486950452"><b>"Tastaturet åbner når som helst, du rører et tekstfelt"</b></string>
+ <string name="tip_to_view_accents" msgid="5433158573693308501"><b>"Tryk på en tast, og hold den nede for a vise accenter"\n"(ø, ö, ô, ó osv.)"</b></string>
+ <string name="tip_to_open_symbols" msgid="7345139325622444880"><b>"Skift til tal og symboler ved at røre denne tast"</b></string>
+ <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"Gå tilbage til bogstaver ved at røre denne tast igen"</b></string>
+ <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"Tryk på denne tast, og hold den nede for at ændre tastaturindstillingerne, som f.eks. automatisk udfyldelse"</b></string>
+ <string name="tip_to_start_typing" msgid="7213843601369174313"><b>"Prøv det!"</b></string>
+ <string name="label_go_key" msgid="1635148082137219148">"Gå"</string>
+ <string name="label_next_key" msgid="362972844525672568">"Næste"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"Udfør"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"Send"</string>
+ <string name="label_symbol_key" msgid="6175820506864489453">"?123"</string>
+ <string name="label_phone_key" msgid="4275497665515080551">"123"</string>
+ <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string>
+ <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string>
+ <string name="voice_warning_title" msgid="4419354150908395008">"Stemmeinput"</string>
+ <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Stemmeinput understøttes i øjeblikket ikke for dit sprog, men fungerer på engelsk."</string>
+ <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"Stemme-input er en funktion på forsøgsbasis, som bruger Googles netværksstemmegenkendelse."</string>
+ <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"Slå stemmeinput fra i indstillingerne for tastaturet."</string>
+ <string name="voice_hint_dialog_message" msgid="6892342981545727994">"For at bruge stemme-input skal du trykke på knappen mikrofon eller lade glide fingeren hen over skærmtastaturet."</string>
+ <string name="voice_listening" msgid="467518160751321844">"Tal nu"</string>
+ <string name="voice_working" msgid="6666937792815731889">"Arbejder"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"Fejl. Prøv igen."</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"Kunne ikke oprette forbindelse"</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"Fejl. For meget tale."</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"Lydproblem"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"Serverfejl"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"Der høres ingen tale"</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"Der blev ikke fundet nogen sammenfald"</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"Stemmesøgning er ikke installeret"</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Tip:"</b>" Glid hen over tastaturet for at tale"</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Tip:"</b>" Næste gang kan du forsøge at sige tegnsætning, f.eks. \"punktum\", \"komma\" eller \"spørgsmålstegn\"."</string>
+ <string name="cancel" msgid="6830980399865683324">"Annuller"</string>
+ <string name="ok" msgid="7898366843681727667">"OK"</string>
+ <string name="voice_input" msgid="2466640768843347841">"Stemmeinput"</string>
+ <string-array name="voice_input_modes">
+ <item msgid="1349082139076086774">"På hovedtastatur"</item>
+ <item msgid="8529385602829095903">"På symboltastatur"</item>
+ <item msgid="7283103513488381103">"Fra"</item>
+ </string-array>
+ <string-array name="voice_input_modes_summary">
+ <item msgid="554248625705084903">"Mikrofon på hovedtastatur"</item>
+ <item msgid="6907837061058876770">"Mikrofon på symboltastatur"</item>
+ <item msgid="3664304608587798036">"Stemmeinput er deaktiveret"</item>
+ </string-array>
+ <string name="auto_submit" msgid="9151008027068358518">"Send automatisk efter stemme"</string>
+ <string name="auto_submit_summary" msgid="4961875269610384226">"Tryk automatisk på enter, når du søger eller går til det næste felt."</string>
+ <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Åbn tastaturet"\n</b></font><font size="3">\n</font>"Tryk på et hvilket som helst tekstfelt."</string>
+ <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Luk tastaturet"\n</b></font><font size="3">\n</font>"Tryk på knappen Tilbage."</string>
+ <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Tryk på en tast, og hold den nede for valgmuligheder"\n</b></font><font size="3">\n</font>"Få adgang til tegnsætning og accenter."</string>
+ <string name="keyboard_settings" msgid="4585753477617374032"><font size="17"><b>"Tastaturindstillinger"\n</b></font><font size="3">\n</font>"Tryk på tasten "<b>"?123"</b>", og hold den nede."</string>
+ <string name="popular_domain_0" msgid="3745279225122472969">".com"</string>
+ <string name="popular_domain_1" msgid="1370572248164278467">".net"</string>
+ <string name="popular_domain_2" msgid="3036812463748402878">".org"</string>
+ <string name="popular_domain_3" msgid="8718639560809452028">".gov"</string>
+ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"Vælg indtastningsmetode"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Indtastingssprog"</string>
+ <string name="language_selection_summary" msgid="187110938289512256">"Træk fingeren på mellemrumstasten for at skifte sprog"</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Tryk igen for at gemme"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"Ordbog er tilgængelig"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"Aktiver brugerfeedback"</string>
+ <string name="prefs_description_log" msgid="5827825607258246003">"Vær med til at forbedre denne inputmetode ved at sende anvendelsesstatistikker og rapporter om nedbrud til Google."</string>
+ <string name="prefs_enable_recorrection" msgid="4588408906649533582">"Tryk for at rette ord"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="1056068922330206170">"Tryk på de indtastede ord for at rette dem"</string>
+ <string name="keyboard_layout" msgid="437433231038683666">"Tastaturtema"</string>
+ <string name="subtype_mode_keyboard" msgid="2242090416595003881">"tastatur"</string>
+ <string name="subtype_mode_voice" msgid="4394113125441627771">"stemme"</string>
+</resources>
diff --git a/java/res/values-de/donottranslate-altchars.xml b/java/res/values-de/donottranslate-altchars.xml
new file mode 100644
index 0000000..5413453
--- /dev/null
+++ b/java/res/values-de/donottranslate-altchars.xml
@@ -0,0 +1,29 @@
+<?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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="alternates_for_a">äáàâãåāæ</string>
+ <string name="alternates_for_e">3€éèêë</string>
+ <string name="alternates_for_o">9öóòôõōø</string>
+ <string name="alternates_for_u">7üúùûū</string>
+ <string name="alternates_for_s">§ßš</string>
+ <string name="alternates_for_q">1@</string>
+ <string name="alternates_for_y">ýÿ¥</string>
+ <string name="alternates_for_z">6ž</string>
+</resources>
diff --git a/java/res/values-de/donottranslate-keymap.xml b/java/res/values-de/donottranslate-keymap.xml
new file mode 100644
index 0000000..4ee97c2
--- /dev/null
+++ b/java/res/values-de/donottranslate-keymap.xml
@@ -0,0 +1,126 @@
+<?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.
+**
+**
+** 5-row layout for German QWERTZ.
+**
+** See http://code.google.com/p/hackerskeyboard/wiki/AddingNewLayouts for
+** more information.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="key_tlde_main">^</string>
+ <string name="key_tlde_shift">°</string>
+ <string name="key_tlde_alt">^°</string>
+
+ <string name="key_ae01_main">1</string>
+ <string name="key_ae01_shift">!</string>
+ <string name="key_ae01_alt">1!¹¡½⅓¼⅛</string>
+
+ <string name="key_ae02_main">2</string>
+ <string name="key_ae02_shift">\"</string>
+ <string name="key_ae02_alt">2\"²⅛⅔</string>
+
+ <string name="key_ae03_main">3</string>
+ <string name="key_ae03_shift">§</string>
+ <string name="key_ae03_alt">3§³£¾⅜</string>
+
+ <string name="key_ae04_main">4</string>
+ <string name="key_ae04_shift">$</string>
+ <string name="key_ae04_alt">4$¼¤⁴¢¥</string>
+
+ <string name="key_ae05_main">5</string>
+ <string name="key_ae05_shift">%</string>
+ <string name="key_ae05_alt">5%½⅜‰</string>
+
+ <string name="key_ae06_main">6</string>
+ <string name="key_ae06_shift">&amp;</string>
+ <string name="key_ae06_alt">6&amp;¬⅝</string>
+
+ <string name="key_ae07_main">7</string>
+ <string name="key_ae07_shift">/</string>
+ <string name="key_ae07_alt">7/{⅞♪√</string>
+
+ <string name="key_ae08_main">8</string>
+ <string name="key_ae08_shift">(</string>
+ <string name="key_ae08_alt">8([™∞</string>
+
+ <string name="key_ae09_main">9</string>
+ <string name="key_ae09_shift">)</string>
+ <string name="key_ae09_alt">9)]±</string>
+
+ <string name="key_ae10_main">0</string>
+ <string name="key_ae10_shift">=</string>
+ <string name="key_ae10_alt">0=}°ⁿ≈≠</string>
+
+ <string name="key_ae11_main">ß</string>
+ <string name="key_ae11_shift">\?</string>
+ <string name="key_ae11_alt">ß\?\\¿</string>
+
+ <string name="key_ae12_main">\'</string>
+ <string name="key_ae12_shift">`</string>
+ <string name="key_ae12_alt">\'`’‘”“</string>
+
+
+ <string name="key_ad06_main">z</string>
+ <string name="key_ad06_shift">Z</string>
+ <string name="key_ad06_alt">@string/alternates_for_z</string>
+
+
+ <string name="key_ad11_main">ü</string>
+ <string name="key_ad11_shift">Ü</string>
+ <string name="key_ad11_alt"></string>
+
+ <string name="key_ad12_main">+</string>
+ <string name="key_ad12_shift">*</string>
+ <string name="key_ad12_alt">+*~•★±</string>
+
+ <string name="key_bksl_main">#</string>
+ <string name="key_bksl_shift">\'</string>
+ <string name="key_bksl_alt">#\'†‡</string>
+
+
+ <string name="key_ac10_main">ö</string>
+ <string name="key_ac10_shift">Ö</string>
+ <string name="key_ac10_alt">♦♥♠♣</string>
+
+ <string name="key_ac11_main">ä</string>
+ <string name="key_ac11_shift">Ä</string>
+ <string name="key_ac11_alt">↑↓←→</string>
+
+
+ <string name="key_lsgt_main">&lt;</string>
+ <string name="key_lsgt_shift">&gt;</string>
+ <string name="key_lsgt_alt">&lt;&gt;|≤«‹≥»›</string>
+
+ <string name="key_ab01_main">y</string>
+ <string name="key_ab01_shift">Y</string>
+ <string name="key_ab01_alt">@string/alternates_for_y</string>
+
+ <string name="key_ab08_main">,</string>
+ <string name="key_ab08_shift">;</string>
+ <string name="key_ab08_alt">,;·×</string>
+
+ <string name="key_ab09_main">.</string>
+ <string name="key_ab09_shift">:</string>
+ <string name="key_ab09_alt">.:…÷</string>
+
+ <string name="key_ab10_main">-</string>
+ <string name="key_ab10_shift">_</string>
+ <string name="key_ab10_alt">-_–—</string>
+</resources>
diff --git a/java/res/values-de/strings.xml b/java/res/values-de/strings.xml
new file mode 100644
index 0000000..9bc717b
--- /dev/null
+++ b/java/res/values-de/strings.xml
@@ -0,0 +1,140 @@
+<?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/org.pocketworkstation.pckeyboard"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- <string name="english_ime_name" msgid="7252517407088836577">"Android-Tastatur"</string> -->
+ <!-- <string name="english_ime_settings" msgid="6661589557206947774">"Android-Tastatureinstellungen"</string> -->
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Eingabeoptionen"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrieren b. Tastendruck"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"Ton bei Tastendruck"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"Pop-up bei Tastendruck"</string>
+ <string name="hit_correction" msgid="4855351009261318389">"Eingabefehler korrigieren"</string>
+ <string name="hit_correction_summary" msgid="8761701873008070796">"Korrektur von Eingabefehlern aktivieren"</string>
+ <string name="hit_correction_land" msgid="2567691684825205448">"Eingabefehler im Querformat"</string>
+ <string name="hit_correction_land_summary" msgid="4076803842198368328">"Korrektur von Eingabefehlern aktivieren"</string>
+ <string name="auto_correction" msgid="7911639788808958255">"Wortvorschläge"</string>
+ <string name="auto_correction_summary" msgid="6881047311475758267">"Vorheriges Wort automatisch korrigieren"</string>
+ <string name="prediction" msgid="466220283138359837">"Wortvorschläge"</string>
+ <string name="prediction_category" msgid="7027100625580696660">"Einstellungen für Wortvorschläge"</string>
+ <string name="prediction_summary" msgid="459788228830873110">"Automatische Vervollständigung während der Eingabe aktivieren"</string>
+ <string name="auto_complete_dialog_title" msgid="2172048590607201920">"Autom. vervollständigen"</string>
+ <string name="prediction_landscape" msgid="4874601565593216183">"Textfeld vergrößern"</string>
+ <string name="prediction_landscape_summary" msgid="6736551095997839472">"Wortvorschläge in Querformat ausblenden"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"Autom. Groß-/Kleinschr."</string>
+ <string name="auto_cap_summary" msgid="3260681697600786825">"Sätze mit Großbuchstaben beginnen"</string>
+ <string name="auto_punctuate" msgid="7276672334264521751">"Autom. Zeichensetzung"</string>
+ <string name="auto_punctuate_summary" msgid="6589441565817502132"></string>
+ <string name="quick_fixes" msgid="5353213327680897927">"Quick Fixes"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"Korrigiert gängige Tippfehler"</string>
+ <string name="show_suggestions" msgid="507074425254289133">"Vorschläge anzeigen"</string>
+ <string name="show_suggestions_summary" msgid="1989672863935759654">"Vorgeschlagene Wörter während des Tippens anzeigen"</string>
+ <string name="auto_complete" msgid="1103196318775486023">"Autom. vervollständigen"</string>
+ <string name="auto_complete_summary" msgid="6113149638718274624">"Leertaste und Interpunktion fügen autom. ein markiertes Wort ein"</string>
+ <string name="prefs_settings_key" msgid="4623341240804046498">"Einstellungstaste anz."</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automatisch"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Immer anzeigen"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"Immer ausblenden"</string>
+ <!-- no translation found for settings_key_modes:0 (8549888726962891527) -->
+ <!-- no translation found for settings_key_modes:1 (881280041213210923) -->
+ <!-- no translation found for settings_key_modes:2 (7317310620171067848) -->
+ <string name="bigram_suggestion" msgid="1323347224043514969">"Bigramm-Vorschläge"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Zur Verbesserung des Vorschlags vorheriges Wort verwenden"</string>
+ <string-array name="prediction_modes">
+ <item msgid="4870266572388153286">"Kein"</item>
+ <item msgid="1669461741568287396">"Standard"</item>
+ <item msgid="4894328801530136615">"Erweitert"</item>
+ </string-array>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: gespeichert"</string>
+ <string name="tip_long_press" msgid="6101270866284343344">"Zur Anzeige von Umlauten (ä, ö usw.) Taste gedrückt halten"</string>
+ <string name="tip_dismiss" msgid="7585579046862204381">"Zum Schließen der Tastatur ↶ drücken"</string>
+ <string name="tip_access_symbols" msgid="6344098517525531652">"Auf Zahlen und Symbole zugreifen"</string>
+ <string name="tip_add_to_dictionary" msgid="1487293888469227817">"Lange auf das Wort ganz links außen drücken, um es zum Wörterbuch hinzuzufügen"</string>
+ <string name="touch_to_continue" msgid="7869803257948414531">"Diesen Hinweis berühren, um fortzufahren »"</string>
+ <string name="touch_to_finish" msgid="7990196086480585789">"Hier berühren, um diesen Hinweis zu schließen und mit dem Tippen zu beginnen!"</string>
+ <string name="tip_to_open_keyboard" msgid="6821200275486950452"><b>"Die Tastatur wird immer dann geöffnet, wenn Sie ein Textfeld berühren."</b></string>
+ <string name="tip_to_view_accents" msgid="5433158573693308501"><b>"Halten Sie eine Taste gedrückt, um Akzente anzuzeigen"\n"(ø, ö, ô, ó usw.)."</b></string>
+ <string name="tip_to_open_symbols" msgid="7345139325622444880"><b>"Wechseln Sie zu Ziffern und Symbolen, indem Sie diese Taste berühren."</b></string>
+ <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"Durch erneutes Drücken dieser Taste gelangen Sie zurück zu den Buchstaben."</b></string>
+ <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"Halten Sie diese Taste gedrückt, um die Tastatureinstellungen, wie beispielsweise die automatische Vervollständigung, zu ändern."</b></string>
+ <string name="tip_to_start_typing" msgid="7213843601369174313"><b>"Probieren Sie es aus!"</b></string>
+ <string name="label_go_key" msgid="1635148082137219148">"Los"</string>
+ <string name="label_next_key" msgid="362972844525672568">"Weiter"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"Fertig"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"Senden"</string>
+ <string name="label_symbol_key" msgid="6175820506864489453">"?123"</string>
+ <string name="label_phone_key" msgid="4275497665515080551">"123"</string>
+ <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string>
+ <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string>
+ <string name="voice_warning_title" msgid="4419354150908395008">"Spracheingabe"</string>
+ <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Spracheingaben werden derzeit nicht für Ihre Sprache unterstützt, funktionieren jedoch in Englisch."</string>
+ <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"Die Spracheingabe ist eine Funktion im Versuchsstadium, die die vernetzte Spracherkennung von Google verwendet."</string>
+ <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"Wenn Sie die Spracheingabe deaktivieren möchten, rufen Sie die Tastatureinstellungen auf."</string>
+ <string name="voice_hint_dialog_message" msgid="6892342981545727994">"Um die Spracheingabe zu verwenden, drücken Sie die Mikrofontaste oder ziehen Sie Ihren Finger über die Bildschirmtastatur."</string>
+ <string name="voice_listening" msgid="467518160751321844">"Jetzt sprechen"</string>
+ <string name="voice_working" msgid="6666937792815731889">"Vorgang läuft"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"Fehler. Versuchen Sie es erneut.."</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"Keine Verbindung"</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"Fehler – Text zu lang"</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"Audio-Problem"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"Serverfehler"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"Keine Sprache zu hören"</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"Keine Treffer gefunden"</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"Sprachsuche nicht installiert"</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Hinweis:"</b>" Ziehen Sie zum Sprechen den Finger über die Tastatur."</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Hinweis:"</b>" Versuchen Sie beim nächsten Mal, Satzzeichen wie \"Punkt\", \"Komma\" oder \"Fragezeichen\" per Sprachbefehl einzugeben."</string>
+ <string name="cancel" msgid="6830980399865683324">"Abbrechen"</string>
+ <string name="ok" msgid="7898366843681727667">"OK"</string>
+ <string name="voice_input" msgid="2466640768843347841">"Spracheingabe"</string>
+ <string-array name="voice_input_modes">
+ <item msgid="1349082139076086774">"Auf Haupttastatur"</item>
+ <item msgid="8529385602829095903">"Auf Symboltastatur"</item>
+ <item msgid="7283103513488381103">"Aus"</item>
+ </string-array>
+ <string-array name="voice_input_modes_summary">
+ <item msgid="554248625705084903">"Mikrofon auf Haupttastatur"</item>
+ <item msgid="6907837061058876770">"Mikrofon auf Symboltastatur"</item>
+ <item msgid="3664304608587798036">"Spracheingabe ist deaktiviert"</item>
+ </string-array>
+ <string name="auto_submit" msgid="9151008027068358518">"Nach Sprachaufnahme automatisch senden"</string>
+ <string name="auto_submit_summary" msgid="4961875269610384226">"Drücken Sie auf die Eingabetaste, wenn Sie einen Suchvorgang durchführen oder zum nächsten Feld wechseln."</string>
+ <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Tastatur öffnen"\n</b></font><font size="3">\n</font>"Berühren Sie ein beliebiges Textfeld."</string>
+ <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Tastatur schließen"\n</b></font><font size="3">\n</font>"Drücken Sie die Zurücktaste."</string>
+ <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Für Optionen eine Taste berühren und gedrückt halten"\n</b></font><font size="3">\n</font>"Greifen Sie auf Satzzeichen und Akzente zu."</string>
+ <string name="keyboard_settings" msgid="4585753477617374032"><font size="17"><b>"Tastatureinstellungen"\n</b></font><font size="3">\n</font>"Berühren und halten Sie die Taste "<b>"?123"</b>" gedrückt."</string>
+ <string name="popular_domain_0" msgid="3745279225122472969">".com"</string>
+ <string name="popular_domain_1" msgid="1370572248164278467">".net"</string>
+ <string name="popular_domain_2" msgid="3036812463748402878">".org"</string>
+ <string name="popular_domain_3" msgid="8718639560809452028">".gov"</string>
+ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"Eingabemethode auswählen"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Eingabesprachen"</string>
+ <string name="language_selection_summary" msgid="187110938289512256">"Finger über die Leertaste bewegen, um die Eingabesprache zu wechseln"</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Zum Speichern erneut berühren"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"Wörterbuch verfügbar"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"Nutzer-Feedback aktivieren"</string>
+ <string name="prefs_description_log" msgid="5827825607258246003">"Tragen Sie zur Verbesserung dieses Eingabemethodeneditors bei, indem Sie automatisch Nutzungsstatistiken und Absturzberichte an Google senden."</string>
+ <string name="prefs_enable_recorrection" msgid="4588408906649533582">"Wortkorrektur"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="1056068922330206170">"Zum Korrigieren auf eingegebene Wörter tippen"</string>
+ <string name="keyboard_layout" msgid="437433231038683666">"Tastaturdesign"</string>
+ <string name="subtype_mode_keyboard" msgid="2242090416595003881">"Tastatur"</string>
+ <string name="subtype_mode_voice" msgid="4394113125441627771">"Sprache"</string>
+</resources>
diff --git a/java/res/values-el/donottranslate-altchars.xml b/java/res/values-el/donottranslate-altchars.xml
new file mode 100644
index 0000000..4074cdb
--- /dev/null
+++ b/java/res/values-el/donottranslate-altchars.xml
@@ -0,0 +1,30 @@
+<?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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="alternates_for_a">àáâãäåæ</string>
+ <string name="alternates_for_e">3èéêë</string>
+ <string name="alternates_for_i">8ïîíì</string>
+ <string name="alternates_for_o">9øœöõôóò</string>
+ <string name="alternates_for_u">7üûúù</string>
+ <string name="alternates_for_s">§ß</string>
+ <string name="alternates_for_n">ñ</string>
+ <string name="alternates_for_c">ç</string>
+ <string name="alternates_for_y">6ÿý</string>
+</resources>
diff --git a/java/res/values-el/donottranslate-keymap.xml b/java/res/values-el/donottranslate-keymap.xml
new file mode 100644
index 0000000..4700aba
--- /dev/null
+++ b/java/res/values-el/donottranslate-keymap.xml
@@ -0,0 +1,223 @@
+<?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.
+**
+**
+** 5-row layout for Greek Keyboard. Note: The translation for the W and the
+** ; keys are not exact, but their functionality has been restored through
+** the alt keys (The are used for accents)
+**
+** See http://code.google.com/p/hackerskeyboard/wiki/AddingNewLayouts for
+** more information.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="key_tlde_main">`</string>
+ <string name="key_tlde_shift">~</string>
+ <string name="key_tlde_alt">`~</string>
+
+ <string name="key_ae01_main">1</string>
+ <string name="key_ae01_shift">!</string>
+ <string name="key_ae01_alt">1!¡¹½⅓¼⅛</string>
+
+ <string name="key_ae02_main">2</string>
+ <string name="key_ae02_shift">\@</string>
+ <string name="key_ae02_alt">2\@²⅔</string>
+
+ <string name="key_ae03_main">3</string>
+ <string name="key_ae03_shift">#</string>
+ <string name="key_ae03_alt">3#³¾⅜♥♠♦♣</string>
+
+ <string name="key_ae04_main">4</string>
+ <string name="key_ae04_shift">$</string>
+ <string name="key_ae04_alt">4$⁴¢£€¥</string>
+
+ <string name="key_ae05_main">5</string>
+ <string name="key_ae05_shift">%</string>
+ <string name="key_ae05_alt">5%⅝‰</string>
+
+ <string name="key_ae06_main">6</string>
+ <string name="key_ae06_shift">^</string>
+ <string name="key_ae06_alt">6^↑↓←→</string>
+
+ <string name="key_ae07_main">7</string>
+ <string name="key_ae07_shift">&amp;</string>
+ <string name="key_ae07_alt">7&amp;⅞♪</string>
+
+ <string name="key_ae08_main">8</string>
+ <string name="key_ae08_shift">*</string>
+ <string name="key_ae08_alt">8*•★∞†‡</string>
+
+ <string name="key_ae09_main">9</string>
+ <string name="key_ae09_shift">(</string>
+ <string name="key_ae09_alt">9(√</string>
+
+ <string name="key_ae10_main">0</string>
+ <string name="key_ae10_shift">)</string>
+ <string name="key_ae10_alt">0)ⁿ°</string>
+
+ <string name="key_ae11_main">-</string>
+ <string name="key_ae11_shift">_</string>
+ <string name="key_ae11_alt">-_—–</string>
+
+ <string name="key_ae12_main">=</string>
+ <string name="key_ae12_shift">+</string>
+ <string name="key_ae12_alt">=+≈≠±×÷</string>
+
+
+ <string name="key_ad01_main">;</string>
+ <string name="key_ad01_shift">:</string>
+ <string name="key_ad01_alt">;:</string>
+
+ <string name="key_ad02_main">ς</string>
+ <string name="key_ad02_shift">Σ</string>
+ <string name="key_ad02_alt">ςσΣ</string>
+
+ <string name="key_ad03_main">ε</string>
+ <string name="key_ad03_shift">Ε</string>
+ <string name="key_ad03_alt">εΕέΈ</string>
+
+ <string name="key_ad04_main">ρ</string>
+ <string name="key_ad04_shift">Ρ</string>
+ <string name="key_ad04_alt">ρΡ</string>
+
+ <string name="key_ad05_main">τ</string>
+ <string name="key_ad05_shift">Τ</string>
+ <string name="key_ad05_alt">τΤ</string>
+
+ <string name="key_ad06_main">υ</string>
+ <string name="key_ad06_shift">Υ</string>
+ <string name="key_ad06_alt">υΥύΎϋΫΰ</string>
+
+ <string name="key_ad07_main">θ</string>
+ <string name="key_ad07_shift">Θ</string>
+ <string name="key_ad07_alt">θΘ</string>
+
+ <string name="key_ad08_main">ι</string>
+ <string name="key_ad08_shift">Ι</string>
+ <string name="key_ad08_alt">ιΙίΊϊΪΐ</string>
+
+ <string name="key_ad09_main">ο</string>
+ <string name="key_ad09_shift">Ο</string>
+ <string name="key_ad09_alt">οΟόΌ</string>
+
+ <string name="key_ad10_main">π</string>
+ <string name="key_ad10_shift">Π</string>
+ <string name="key_ad10_alt">πΠ</string>
+
+ <string name="key_ad11_main">[</string>
+ <string name="key_ad11_shift">{</string>
+ <string name="key_ad11_alt">[{&#x303;&#x304;&#x308;</string>
+
+ <string name="key_ad12_main">]</string>
+ <string name="key_ad12_shift">}</string>
+ <string name="key_ad12_alt">]}&#x345;&#x306;</string>
+
+ <string name="key_bksl_main">\\</string>
+ <string name="key_bksl_shift">|</string>
+ <string name="key_bksl_alt">\\|</string>
+
+
+ <string name="key_ac01_main">α</string>
+ <string name="key_ac01_shift">Α</string>
+ <string name="key_ac01_alt">αΑάΆ</string>
+
+ <string name="key_ac02_main">σ</string>
+ <string name="key_ac02_shift">Σ</string>
+ <string name="key_ac02_alt">σΣς</string>
+
+ <string name="key_ac03_main">δ</string>
+ <string name="key_ac03_shift">Δ</string>
+ <string name="key_ac03_alt">δΔ</string>
+
+ <string name="key_ac04_main">φ</string>
+ <string name="key_ac04_shift">Φ</string>
+ <string name="key_ac04_alt">φΦ</string>
+
+ <string name="key_ac05_main">γ</string>
+ <string name="key_ac05_shift">Γ</string>
+ <string name="key_ac05_alt">γΓ</string>
+
+ <string name="key_ac06_main">η</string>
+ <string name="key_ac06_shift">Η</string>
+ <string name="key_ac06_alt">ηΗήΉ</string>
+
+ <string name="key_ac07_main">ξ</string>
+ <string name="key_ac07_shift">Ξ</string>
+ <string name="key_ac07_alt">ξΞ</string>
+
+ <string name="key_ac08_main">κ</string>
+ <string name="key_ac08_shift">Κ</string>
+ <string name="key_ac08_alt">κΚ</string>
+
+ <string name="key_ac09_main">λ</string>
+ <string name="key_ac09_shift">Λ</string>
+ <string name="key_ac09_alt">λΛ</string>
+
+ <string name="key_ac10_main">&#x301;</string>
+ <string name="key_ac10_shift">&#x308;</string>
+ <string name="key_ac10_alt">&#x301;&#x308;&#x313;</string>
+
+ <string name="key_ac11_main">\'</string>
+ <string name="key_ac11_shift">\"</string>
+ <string name="key_ac11_alt">\'\"&#x300;&#x314;</string>
+
+
+ <string name="key_lsgt_main"/>
+ <string name="key_lsgt_shift"/>
+ <string name="key_lsgt_alt"/>
+
+ <string name="key_ab01_main">ζ</string>
+ <string name="key_ab01_shift">Ζ</string>
+ <string name="key_ab01_alt">ζΖ</string>
+
+ <string name="key_ab02_main">χ</string>
+ <string name="key_ab02_shift">Χ</string>
+ <string name="key_ab02_alt">χΧ</string>
+
+ <string name="key_ab03_main">ψ</string>
+ <string name="key_ab03_shift">Ψ</string>
+ <string name="key_ab03_alt">ψΨ</string>
+
+ <string name="key_ab04_main">ω</string>
+ <string name="key_ab04_shift">Ω</string>
+ <string name="key_ab04_alt">ωΩώΏ</string>
+
+ <string name="key_ab05_main">β</string>
+ <string name="key_ab05_shift">Β</string>
+ <string name="key_ab05_alt">βΒ</string>
+
+ <string name="key_ab06_main">ν</string>
+ <string name="key_ab06_shift">Ν</string>
+ <string name="key_ab06_alt">νΝ</string>
+
+ <string name="key_ab07_main">μ</string>
+ <string name="key_ab07_shift">Μ</string>
+ <string name="key_ab07_alt">μΜ</string>
+
+ <string name="key_ab08_main">,</string>
+ <string name="key_ab08_shift">&lt;</string>
+ <string name="key_ab08_alt">,&lt;≤«‹</string>
+
+ <string name="key_ab09_main">.</string>
+ <string name="key_ab09_shift">&gt;</string>
+ <string name="key_ab09_alt">&gt;≥»›…</string>
+
+ <string name="key_ab10_main">/</string>
+ <string name="key_ab10_shift">\?</string>
+ <string name="key_ab10_alt">/\?¿</string>
+</resources>
diff --git a/java/res/values-el/strings.xml b/java/res/values-el/strings.xml
new file mode 100644
index 0000000..174fe70
--- /dev/null
+++ b/java/res/values-el/strings.xml
@@ -0,0 +1,140 @@
+<?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/org.pocketworkstation.pckeyboard"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- <string name="english_ime_name" msgid="7252517407088836577">"Πληκτρολόγιο Android"</string> -->
+ <!-- <string name="english_ime_settings" msgid="6661589557206947774">"Ρυθμίσεις πληκτρολογίου Android"</string> -->
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Επιλογές εισόδου"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"Δόνηση κατά το πάτημα πλήκτρων"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"Ήχος κατά το πάτημα πλήκτρων"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"Εμφάνιση με το πάτημα πλήκτρου"</string>
+ <string name="hit_correction" msgid="4855351009261318389">"Διόρθωση σφαλμάτων πληκτρολόγησης"</string>
+ <string name="hit_correction_summary" msgid="8761701873008070796">"Ενεργοποίηση διόρθωσης σφαλμάτων εισόδου"</string>
+ <string name="hit_correction_land" msgid="2567691684825205448">"Σφάλματα οριζόντιας εισαγωγής"</string>
+ <string name="hit_correction_land_summary" msgid="4076803842198368328">"Ενεργοποίηση διόρθωσης σφαλμάτων εισόδου"</string>
+ <string name="auto_correction" msgid="7911639788808958255">"Υποδείξεις λέξεων"</string>
+ <string name="auto_correction_summary" msgid="6881047311475758267">"Αυτόματη διόρθωση της προηγούμενης λέξης"</string>
+ <string name="prediction" msgid="466220283138359837">"Υποδείξεις λέξεων"</string>
+ <string name="prediction_category" msgid="7027100625580696660">"Ρυθμίσεις υποδείξεων λέξεων"</string>
+ <string name="prediction_summary" msgid="459788228830873110">"Ενεργοποίηση αυτόματης συμπλήρωσης κατά την πληκτρολόγηση"</string>
+ <string name="auto_complete_dialog_title" msgid="2172048590607201920">"Αυτόματη συμπλήρωση"</string>
+ <string name="prediction_landscape" msgid="4874601565593216183">"Αυξήστε το μέγεθος του πεδίου κειμένου"</string>
+ <string name="prediction_landscape_summary" msgid="6736551095997839472">"Απόκρυψη υποδείξεων λέξεων στην οριζόντια προβολή"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"Αυτόματη χρήση κεφαλαίων"</string>
+ <string name="auto_cap_summary" msgid="3260681697600786825">"Κεφαλαίο το πρώτο γράμμα της πρότασης"</string>
+ <string name="auto_punctuate" msgid="7276672334264521751">"Αυτόματος τονισμός"</string>
+ <string name="auto_punctuate_summary" msgid="6589441565817502132"></string>
+ <string name="quick_fixes" msgid="5353213327680897927">"Γρήγορες διορθώσεις"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"Διορθώνει συνηθισμένα λάθη πληκτρολόγησης"</string>
+ <string name="show_suggestions" msgid="507074425254289133">"Εμφάνιση υποδείξεων"</string>
+ <string name="show_suggestions_summary" msgid="1989672863935759654">"Προβολή προτεινόμενων λέξεων κατά την πληκτρολόγηση"</string>
+ <string name="auto_complete" msgid="1103196318775486023">"Αυτόματη συμπλήρωση"</string>
+ <string name="auto_complete_summary" msgid="6113149638718274624">"Τα πλήκ.διαστήμ.και τονισμού εισάγ.αυτόμ.την επιλ.λέξη"</string>
+ <string name="prefs_settings_key" msgid="4623341240804046498">"Εμφάνιση πλήκτρου ρυθμίσεων"</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Αυτόματο"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Να εμφανίζεται πάντα"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"Πάντα απόκρυψη"</string>
+ <!-- no translation found for settings_key_modes:0 (8549888726962891527) -->
+ <!-- no translation found for settings_key_modes:1 (881280041213210923) -->
+ <!-- no translation found for settings_key_modes:2 (7317310620171067848) -->
+ <string name="bigram_suggestion" msgid="1323347224043514969">"Προτάσεις bigram"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Χρήση προηγούμενης λέξης για τη βελτίωση πρότασης"</string>
+ <string-array name="prediction_modes">
+ <item msgid="4870266572388153286">"Καμία"</item>
+ <item msgid="1669461741568287396">"Βασική"</item>
+ <item msgid="4894328801530136615">"Σύνθετη"</item>
+ </string-array>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Αποθηκεύτηκε"</string>
+ <string name="tip_long_press" msgid="6101270866284343344">"Κρατήστε πατημένο ένα πλήκτρο για να δείτε τους τονισμένους χαρακτήρες (ø, ö, κ.τ.λ.)"</string>
+ <string name="tip_dismiss" msgid="7585579046862204381">"Πατήστε το πλήκτρο Πίσω ↶ για να κλείσετε το πληκτρολόγιο ανά πάσα στιγμή"</string>
+ <string name="tip_access_symbols" msgid="6344098517525531652">"Πρόσβαση σε αριθμούς και σύμβολα"</string>
+ <string name="tip_add_to_dictionary" msgid="1487293888469227817">"Κρατήστε πατημένη τη λέξη στην άκρη αριστερά, για να την προσθέσετε στο λεξικό"</string>
+ <string name="touch_to_continue" msgid="7869803257948414531">"Αγγίξτε αυτή τη συμβουλή για να συνεχίσετε »"</string>
+ <string name="touch_to_finish" msgid="7990196086480585789">"Αγγίξτε εδώ για να κλείσετε τη συμβουλή και να ξεκινήσετε την πληκτρολόγηση!"</string>
+ <string name="tip_to_open_keyboard" msgid="6821200275486950452"><b>"Το πληκτρολόγιο ανοίγει κάθε φορά που αγγίζετε ένα πεδίο κειμένου"</b></string>
+ <string name="tip_to_view_accents" msgid="5433158573693308501"><b>"Αγγίξτε και κρατήστε κάποιο πλήκτρο για να προβάλετε τους τονισμένους χαρακτήρες"\n"(ø, ö, ô, ó κ.τ.λ.)"</b></string>
+ <string name="tip_to_open_symbols" msgid="7345139325622444880"><b>"Αλλαγή σε αριθμούς και σύμβολα με το πάτημα αυτού του πλήκτρου"</b></string>
+ <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"Επιστρέψτε στα γράμματα αγγίζοντας ξανά αυτό το πλήκτρο"</b></string>
+ <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"Αγγίξτε και κρατήστε πατημένο αυτό το πληκτρολόγιο για να αλλάξετε τις ρυθμίσεις πληκτρολογίου, όπως η αυτόματη συμπλήρωση"</b></string>
+ <string name="tip_to_start_typing" msgid="7213843601369174313"><b>"Δοκιμάστε το!"</b></string>
+ <string name="label_go_key" msgid="1635148082137219148">"Μετάβαση"</string>
+ <string name="label_next_key" msgid="362972844525672568">"Επόμενο"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"Τέλος"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"Αποστολή"</string>
+ <string name="label_symbol_key" msgid="6175820506864489453">"?123"</string>
+ <string name="label_phone_key" msgid="4275497665515080551">"123"</string>
+ <string name="label_alpha_key" msgid="8864943487292437456">"ΑΒΓ"</string>
+ <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string>
+ <string name="voice_warning_title" msgid="4419354150908395008">"Φωνητική είσοδος"</string>
+ <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Η φωνητική είσοδος δεν υποστηρίζεται αυτή τη στιγμή για τη γλώσσα σας, ωστόσο λειτουργεί στα Αγγλικά."</string>
+ <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"Οι φωνητικές εντολές είναι μια πειραματική λειτουργία, η οποία χρησιμοποιεί τη δικτυακή αναγνώριση ομιλίας της Google."</string>
+ <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"Για να απενεργοποιήσετε τη φωνητική είσοδο, μεταβείτε στις ρυθμίσεις πληκτρολογίου."</string>
+ <string name="voice_hint_dialog_message" msgid="6892342981545727994">"Για να χρησιμοποιήσετε τις φωνητικές εντολές, πιέστε το κουμπί μικροφώνου ή σύρετε το δάχτυλό σας κατά μήκος του πληκτρολογίου της οθόνης."</string>
+ <string name="voice_listening" msgid="467518160751321844">"Μιλήστε τώρα"</string>
+ <string name="voice_working" msgid="6666937792815731889">"Σε λειτουργία"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"Σφάλμα. Δοκιμάστε ξανά."</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"Δεν ήταν δυνατή η σύνδεση"</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"Σφάλμα, πολλές λέξεις."</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"Πρόβλημα ήχου"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"Σφάλμα διακομιστή"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"Δεν ακούγεται ομιλία"</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"Δεν βρέθηκε καμία αντιστοίχιση"</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"Η Φωνητική αναζήτηση δεν εγκαταστάθηκε"</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Υπόδειξη:"</b>" Σύρετε κατά μήκος του πληκτρολογίου για να μιλήσετε"</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Υπόδειξη:"</b>" Την επόμενη φορά, προσπαθήστε να προφέρετε σημεία στίξης, όπως \"τελεία\", \"κόμμα\" ή \"ερωτηματικό\"."</string>
+ <string name="cancel" msgid="6830980399865683324">"Ακύρωση"</string>
+ <string name="ok" msgid="7898366843681727667">"ΟΚ"</string>
+ <string name="voice_input" msgid="2466640768843347841">"Φωνητική είσοδος"</string>
+ <string-array name="voice_input_modes">
+ <item msgid="1349082139076086774">"Στο κύριο πληκτρολόγιο"</item>
+ <item msgid="8529385602829095903">"Πληκτρολόγιο συμβόλων ενεργοποίησης"</item>
+ <item msgid="7283103513488381103">"Απενεργοποίηση"</item>
+ </string-array>
+ <string-array name="voice_input_modes_summary">
+ <item msgid="554248625705084903">"Μικρόφωνο στο κύριο πληκτρολόγιο"</item>
+ <item msgid="6907837061058876770">"Μικρόφωνο στο πληκτρολόγιο συμβόλων"</item>
+ <item msgid="3664304608587798036">"Η φωνητική είσοδος είναι απενεργοποιημένη"</item>
+ </string-array>
+ <string name="auto_submit" msgid="9151008027068358518">"Αυτόματη υποβολή μετά από ήχο"</string>
+ <string name="auto_submit_summary" msgid="4961875269610384226">"Πατήστε enter αυτόματα κατά την αναζήτηση ή τη μετάβαση στο επόμενο πεδίο."</string>
+ <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Ανοίξτε το πληκτρολόγιο"\n</b></font><font size="3">\n</font>"Αγγίξτε οποιοδήποτε πεδίο κειμένου."</string>
+ <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Κλείστε το πληκτρολόγιο"\n</b></font><font size="3">\n</font>"Πατήστε το πλήκτρο Πίσω."</string>
+ <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Αγγίξτε και κρατήστε ένα πλήκτρο για ορισμό επιλογών"\n</b></font><font size="3">\n</font>"Πρόσβαση στα σημεία στίξης και τονισμού."</string>
+ <string name="keyboard_settings" msgid="4585753477617374032"><font size="17"><b>"Ρυθμίσεις πληκτρολογίου"\n</b></font><font size="3">\n</font>"Αγγίξτε και κρατήστε το πλήκτρο "<b>"?123"</b>"."</string>
+ <string name="popular_domain_0" msgid="3745279225122472969">".com"</string>
+ <string name="popular_domain_1" msgid="1370572248164278467">".net"</string>
+ <string name="popular_domain_2" msgid="3036812463748402878">".org"</string>
+ <string name="popular_domain_3" msgid="8718639560809452028">".gov"</string>
+ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"Επιλογή μεθόδου εισόδου"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Γλώσσες εισόδου"</string>
+ <string name="language_selection_summary" msgid="187110938289512256">"Σύρετε το δάχτυλο στο πλήκτρο διαστήματος για να αλλάξετε γλώσσα"</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Αγγίξτε ξανά για αποθήκευση"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"Λεξικό διαθέσιμο"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"Ενεργοποίηση σχολίων χρηστών"</string>
+ <string name="prefs_description_log" msgid="5827825607258246003">"Βοηθήστε μας να βελτιώσουμε αυτό το πρόγραμμα επεξεργασίας μεθόδου εισόδου στέλνοντας αυτόματα στατιστικά στοιχεία και αναφορές σφαλμάτων στην Google."</string>
+ <string name="prefs_enable_recorrection" msgid="4588408906649533582">"Αγγίξτε για διόρθωση λέξεων"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="1056068922330206170">"Αγγίξτε τις λέξεις που εισάγετε για να τις διορθώσετε"</string>
+ <string name="keyboard_layout" msgid="437433231038683666">"Θέμα πληκτρολογίου"</string>
+ <string name="subtype_mode_keyboard" msgid="2242090416595003881">"πληκτρολόγιο"</string>
+ <string name="subtype_mode_voice" msgid="4394113125441627771">"φωνητική"</string>
+</resources>
diff --git a/java/res/values-en-rDV/donottranslate-altchars.xml b/java/res/values-en-rDV/donottranslate-altchars.xml
new file mode 100644
index 0000000..f6baa5c
--- /dev/null
+++ b/java/res/values-en-rDV/donottranslate-altchars.xml
@@ -0,0 +1,47 @@
+<?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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="alternates_for_a">áàâãäåāæ</string>
+ <string name="alternates_for_b"></string>
+ <string name="alternates_for_c">8çčć¢</string>
+ <string name="alternates_for_d">đ</string>
+ <string name="alternates_for_e">éèêëē€</string>
+ <string name="alternates_for_f">6₣</string>
+ <string name="alternates_for_g">7</string>
+ <string name="alternates_for_h"></string>
+ <string name="alternates_for_i">íìîïī</string>
+ <string name="alternates_for_j"></string>
+ <string name="alternates_for_k"></string>
+ <string name="alternates_for_l">0£₤λ</string>
+ <string name="alternates_for_m">μ</string>
+ <string name="alternates_for_n">ñ</string>
+ <string name="alternates_for_o">óòôõöōø</string>
+ <string name="alternates_for_p">4π₱</string>
+ <string name="alternates_for_q"></string>
+ <string name="alternates_for_r">9</string>
+ <string name="alternates_for_s">§ßš</string>
+ <string name="alternates_for_t"></string>
+ <string name="alternates_for_u">úùûüū</string>
+ <string name="alternates_for_v"></string>
+ <string name="alternates_for_w"></string>
+ <string name="alternates_for_x"></string>
+ <string name="alternates_for_y">5ýÿ¥</string>
+ <string name="alternates_for_z">ž</string>
+</resources>
diff --git a/java/res/values-en-rDV/donottranslate-keymap.xml b/java/res/values-en-rDV/donottranslate-keymap.xml
new file mode 100644
index 0000000..a0a0c7f
--- /dev/null
+++ b/java/res/values-en-rDV/donottranslate-keymap.xml
@@ -0,0 +1,225 @@
+<?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.
+**
+**
+** 5-row layout for English Dvorak.
+** Trevor Bergeron, mallegonian@gmail.com
+** Uses the same altkeys as QWERTY
+**
+** See http://code.google.com/p/hackerskeyboard/wiki/AddingNewLayouts for
+** more information.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="key_tlde_main">`</string>
+ <string name="key_tlde_shift">~</string>
+ <string name="key_tlde_alt">`~</string>
+
+ <string name="key_ae01_main">1</string>
+ <string name="key_ae01_shift">!</string>
+ <string name="key_ae01_alt">1!¡¹½⅓¼⅛</string>
+
+ <string name="key_ae02_main">2</string>
+ <string name="key_ae02_shift">\@</string>
+ <string name="key_ae02_alt">2\@²⅔</string>
+
+ <string name="key_ae03_main">3</string>
+ <string name="key_ae03_shift">#</string>
+ <string name="key_ae03_alt">3#³¾⅜♥♠♦♣</string>
+
+ <string name="key_ae04_main">4</string>
+ <string name="key_ae04_shift">$</string>
+ <string name="key_ae04_alt">4$⁴¢£€¥</string>
+
+ <string name="key_ae05_main">5</string>
+ <string name="key_ae05_shift">%</string>
+ <string name="key_ae05_alt">5%⅝‰</string>
+
+ <string name="key_ae06_main">6</string>
+ <string name="key_ae06_shift">^</string>
+ <string name="key_ae06_alt">6^↑↓←→</string>
+
+ <string name="key_ae07_main">7</string>
+ <string name="key_ae07_shift">&amp;</string>
+ <string name="key_ae07_alt">7&amp;⅞♪</string>
+
+ <string name="key_ae08_main">8</string>
+ <string name="key_ae08_shift">*</string>
+ <string name="key_ae08_alt">8*•★∞†‡</string>
+
+ <string name="key_ae09_main">9</string>
+ <string name="key_ae09_shift">(</string>
+ <string name="key_ae09_alt">9(√</string>
+
+ <string name="key_ae10_main">0</string>
+ <string name="key_ae10_shift">)</string>
+ <string name="key_ae10_alt">0)ⁿ°</string>
+
+ <string name="key_ae11_main">[</string>
+ <string name="key_ae11_shift">{</string>
+ <string name="key_ae11_alt">[{</string>
+
+ <string name="key_ae12_main">]</string>
+ <string name="key_ae12_shift">}</string>
+ <string name="key_ae12_alt">]}</string>
+
+
+
+ <string name="key_ad01_main">\'</string>
+ <string name="key_ad01_shift">\"</string>
+ <string name="key_ad01_alt">\'\"‘’“”</string>
+
+ <string name="key_ad02_main">,</string>
+ <string name="key_ad02_shift">&lt;</string>
+ <string name="key_ad02_alt">,&lt;≤«‹</string>
+
+ <string name="key_ad03_main">.</string>
+ <string name="key_ad03_shift">&gt;</string>
+ <string name="key_ad03_alt">&gt;≥»›…</string>
+
+ <string name="key_ad04_main">p</string>
+ <string name="key_ad04_shift">P</string>
+ <string name="key_ad04_alt">@string/alternates_for_p</string>
+
+ <string name="key_ad05_main">y</string>
+ <string name="key_ad05_shift">Y</string>
+ <string name="key_ad05_alt">@string/alternates_for_y</string>
+
+ <string name="key_ad06_main">f</string>
+ <string name="key_ad06_shift">F</string>
+ <string name="key_ad06_alt">@string/alternates_for_f</string>
+
+ <string name="key_ad07_main">g</string>
+ <string name="key_ad07_shift">G</string>
+ <string name="key_ad07_alt">@string/alternates_for_g</string>
+
+ <string name="key_ad08_main">c</string>
+ <string name="key_ad08_shift">C</string>
+ <string name="key_ad08_alt">@string/alternates_for_c</string>
+
+ <string name="key_ad09_main">r</string>
+ <string name="key_ad09_shift">R</string>
+ <string name="key_ad09_alt">@string/alternates_for_r</string>
+
+ <string name="key_ad10_main">l</string>
+ <string name="key_ad10_shift">L</string>
+ <string name="key_ad10_alt">@string/alternates_for_l</string>
+
+ <string name="key_ad11_main">/</string>
+ <string name="key_ad11_shift">\?</string>
+ <string name="key_ad11_alt">/\?¿</string>
+
+ <string name="key_ad12_main">=</string>
+ <string name="key_ad12_shift">+</string>
+ <string name="key_ad12_alt">=+≈≠±×÷</string>
+
+ <string name="key_bksl_main">\\</string>
+ <string name="key_bksl_shift">|</string>
+ <string name="key_bksl_alt">\\|</string>
+
+
+ <string name="key_ac01_main">a</string>
+ <string name="key_ac01_shift">A</string>
+ <string name="key_ac01_alt">@string/alternates_for_a</string>
+
+ <string name="key_ac02_main">o</string>
+ <string name="key_ac02_shift">O</string>
+ <string name="key_ac02_alt">@string/alternates_for_o</string>
+
+ <string name="key_ac03_main">e</string>
+ <string name="key_ac03_shift">E</string>
+ <string name="key_ac03_alt">@string/alternates_for_e</string>
+
+ <string name="key_ac04_main">u</string>
+ <string name="key_ac04_shift">U</string>
+ <string name="key_ac04_alt">@string/alternates_for_u</string>
+
+ <string name="key_ac05_main">i</string>
+ <string name="key_ac05_shift">I</string>
+ <string name="key_ac05_alt">@string/alternates_for_i</string>
+
+ <string name="key_ac06_main">d</string>
+ <string name="key_ac06_shift">D</string>
+ <string name="key_ac06_alt">@string/alternates_for_d</string>
+
+ <string name="key_ac07_main">h</string>
+ <string name="key_ac07_shift">H</string>
+ <string name="key_ac07_alt">@string/alternates_for_h</string>
+
+ <string name="key_ac08_main">t</string>
+ <string name="key_ac08_shift">T</string>
+ <string name="key_ac08_alt">@string/alternates_for_t</string>
+
+ <string name="key_ac09_main">n</string>
+ <string name="key_ac09_shift">N</string>
+ <string name="key_ac09_alt">@string/alternates_for_n</string>
+
+ <string name="key_ac10_main">s</string>
+ <string name="key_ac10_shift">S</string>
+ <string name="key_ac10_alt">@string/alternates_for_s</string>
+
+ <string name="key_ac11_main">-</string>
+ <string name="key_ac11_shift">_</string>
+ <string name="key_ac11_alt">-_—–</string>
+
+
+ <string name="key_lsgt_main"></string>
+ <string name="key_lsgt_shift"></string>
+ <string name="key_lsgt_alt"></string>
+
+ <string name="key_ab01_main">;</string>
+ <string name="key_ab01_shift">:</string>
+ <string name="key_ab01_alt">;:</string>
+
+ <string name="key_ab02_main">q</string>
+ <string name="key_ab02_shift">Q</string>
+ <string name="key_ab02_alt">@string/alternates_for_q</string>
+
+ <string name="key_ab03_main">j</string>
+ <string name="key_ab03_shift">J</string>
+ <string name="key_ab03_alt">@string/alternates_for_j</string>
+
+ <string name="key_ab04_main">k</string>
+ <string name="key_ab04_shift">K</string>
+ <string name="key_ab04_alt">@string/alternates_for_k</string>
+
+ <string name="key_ab05_main">x</string>
+ <string name="key_ab05_shift">X</string>
+ <string name="key_ab05_alt">@string/alternates_for_x</string>
+
+ <string name="key_ab06_main">b</string>
+ <string name="key_ab06_shift">B</string>
+ <string name="key_ab06_alt">@string/alternates_for_b</string>
+
+ <string name="key_ab07_main">m</string>
+ <string name="key_ab07_shift">M</string>
+ <string name="key_ab07_alt">@string/alternates_for_m</string>
+
+ <string name="key_ab08_main">w</string>
+ <string name="key_ab08_shift">W</string>
+ <string name="key_ab08_alt">@string/alternates_for_w</string>
+
+ <string name="key_ab09_main">v</string>
+ <string name="key_ab09_shift">V</string>
+ <string name="key_ab09_alt">@string/alternates_for_v</string>
+
+ <string name="key_ab10_main">z</string>
+ <string name="key_ab10_shift">Z</string>
+ <string name="key_ab10_alt">@string/alternates_for_z</string>
+</resources>
+
diff --git a/java/res/values-en-rGB/donottranslate-altchars.xml b/java/res/values-en-rGB/donottranslate-altchars.xml
new file mode 100644
index 0000000..7d25dbd
--- /dev/null
+++ b/java/res/values-en-rGB/donottranslate-altchars.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2010, The Android Open Source Project
+** Copyright 2011, Darren Salt
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="alternates_for_w">2ŵ</string>
+ <string name="alternates_for_y">6ýÿŷ¥</string>
+</resources>
diff --git a/java/res/values-en-rGB/donottranslate-keymap.xml b/java/res/values-en-rGB/donottranslate-keymap.xml
new file mode 100644
index 0000000..a53f782
--- /dev/null
+++ b/java/res/values-en-rGB/donottranslate-keymap.xml
@@ -0,0 +1,215 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2010, The Android Open Source Project
+** Copyright 2011, Darren Salt
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="key_tlde_main">`</string>
+ <string name="key_tlde_shift">¬</string>
+ <string name="key_tlde_alt">`¬¦</string>
+
+ <string name="key_ae01_main">1</string>
+ <string name="key_ae01_shift">!</string>
+ <string name="key_ae01_alt">1!¡¹½⅓¼⅛</string>
+
+ <string name="key_ae02_main">2</string>
+ <string name="key_ae02_shift">\"</string>
+ <string name="key_ae02_alt">2\"²⅔“”</string>
+
+ <string name="key_ae03_main">3</string>
+ <string name="key_ae03_shift">£</string>
+ <string name="key_ae03_alt">3£³¾⅜♥♠♦♣</string>
+
+ <string name="key_ae04_main">4</string>
+ <string name="key_ae04_shift">$</string>
+ <string name="key_ae04_alt">4$⁴¢£€¥</string>
+
+ <string name="key_ae05_main">5</string>
+ <string name="key_ae05_shift">%</string>
+ <string name="key_ae05_alt">5%⅝‰</string>
+
+ <string name="key_ae06_main">6</string>
+ <string name="key_ae06_shift">^</string>
+ <string name="key_ae06_alt">6^↑↓←→</string>
+
+ <string name="key_ae07_main">7</string>
+ <string name="key_ae07_shift">&amp;</string>
+ <string name="key_ae07_alt">7&amp;⅞♪</string>
+
+ <string name="key_ae08_main">8</string>
+ <string name="key_ae08_shift">*</string>
+ <string name="key_ae08_alt">8*•★∞†‡</string>
+
+ <string name="key_ae09_main">9</string>
+ <string name="key_ae09_shift">(</string>
+ <string name="key_ae09_alt">9(√</string>
+
+ <string name="key_ae10_main">0</string>
+ <string name="key_ae10_shift">)</string>
+ <string name="key_ae10_alt">0)ⁿ°</string>
+
+ <string name="key_ae11_main">-</string>
+ <string name="key_ae11_shift">_</string>
+ <string name="key_ae11_alt">-_—–</string>
+
+ <string name="key_ae12_main">=</string>
+ <string name="key_ae12_shift">+</string>
+ <string name="key_ae12_alt">=+≈≠±×÷</string>
+
+
+ <string name="key_ad01_main">q</string>
+ <string name="key_ad01_shift">Q</string>
+ <string name="key_ad01_alt">@string/alternates_for_q</string>
+
+ <string name="key_ad02_main">w</string>
+ <string name="key_ad02_shift">W</string>
+ <string name="key_ad02_alt">@string/alternates_for_w</string>
+
+ <string name="key_ad03_main">e</string>
+ <string name="key_ad03_shift">E</string>
+ <string name="key_ad03_alt">@string/alternates_for_e</string>
+
+ <string name="key_ad04_main">r</string>
+ <string name="key_ad04_shift">R</string>
+ <string name="key_ad04_alt">@string/alternates_for_r</string>
+
+ <string name="key_ad05_main">t</string>
+ <string name="key_ad05_shift">T</string>
+ <string name="key_ad05_alt">@string/alternates_for_t</string>
+
+ <string name="key_ad06_main">y</string>
+ <string name="key_ad06_shift">Y</string>
+ <string name="key_ad06_alt">@string/alternates_for_y</string>
+
+ <string name="key_ad07_main">u</string>
+ <string name="key_ad07_shift">U</string>
+ <string name="key_ad07_alt">@string/alternates_for_u</string>
+
+ <string name="key_ad08_main">i</string>
+ <string name="key_ad08_shift">I</string>
+ <string name="key_ad08_alt">@string/alternates_for_i</string>
+
+ <string name="key_ad09_main">o</string>
+ <string name="key_ad09_shift">O</string>
+ <string name="key_ad09_alt">@string/alternates_for_o</string>
+
+ <string name="key_ad10_main">p</string>
+ <string name="key_ad10_shift">P</string>
+ <string name="key_ad10_alt">@string/alternates_for_p</string>
+
+ <string name="key_ad11_main">[</string>
+ <string name="key_ad11_shift">{</string>
+ <string name="key_ad11_alt">[{</string>
+
+ <string name="key_ad12_main">]</string>
+ <string name="key_ad12_shift">}</string>
+ <string name="key_ad12_alt">]}</string>
+
+ <string name="key_bksl_main">#</string>
+ <string name="key_bksl_shift">~</string>
+ <string name="key_bksl_alt">#~|</string>
+
+
+ <string name="key_ac01_main">a</string>
+ <string name="key_ac01_shift">A</string>
+ <string name="key_ac01_alt">@string/alternates_for_a</string>
+
+ <string name="key_ac02_main">s</string>
+ <string name="key_ac02_shift">S</string>
+ <string name="key_ac02_alt">@string/alternates_for_s</string>
+
+ <string name="key_ac03_main">d</string>
+ <string name="key_ac03_shift">D</string>
+ <string name="key_ac03_alt">@string/alternates_for_d</string>
+
+ <string name="key_ac04_main">f</string>
+ <string name="key_ac04_shift">F</string>
+ <string name="key_ac04_alt">@string/alternates_for_f</string>
+
+ <string name="key_ac05_main">g</string>
+ <string name="key_ac05_shift">G</string>
+ <string name="key_ac05_alt">@string/alternates_for_g</string>
+
+ <string name="key_ac06_main">h</string>
+ <string name="key_ac06_shift">H</string>
+ <string name="key_ac06_alt">@string/alternates_for_h</string>
+
+ <string name="key_ac07_main">j</string>
+ <string name="key_ac07_shift">J</string>
+ <string name="key_ac07_alt">@string/alternates_for_j</string>
+
+ <string name="key_ac08_main">k</string>
+ <string name="key_ac08_shift">K</string>
+ <string name="key_ac08_alt">@string/alternates_for_k</string>
+
+ <string name="key_ac09_main">l</string>
+ <string name="key_ac09_shift">L</string>
+ <string name="key_ac09_alt">@string/alternates_for_l</string>
+
+ <string name="key_ac10_main">;</string>
+ <string name="key_ac10_shift">:</string>
+ <string name="key_ac10_alt">;:</string>
+
+ <string name="key_ac11_main">\'</string>
+ <string name="key_ac11_shift">\@</string>
+ <string name="key_ac11_alt">\'\@‘’</string>
+
+
+ <string name="key_lsgt_main">\\</string>
+ <string name="key_lsgt_shift">|</string>
+ <string name="key_lsgt_alt">\\|</string>
+
+ <string name="key_ab01_main">z</string>
+ <string name="key_ab01_shift">Z</string>
+ <string name="key_ab01_alt">@string/alternates_for_z</string>
+
+ <string name="key_ab02_main">x</string>
+ <string name="key_ab02_shift">X</string>
+ <string name="key_ab02_alt">@string/alternates_for_x</string>
+
+ <string name="key_ab03_main">c</string>
+ <string name="key_ab03_shift">C</string>
+ <string name="key_ab03_alt">@string/alternates_for_c</string>
+
+ <string name="key_ab04_main">v</string>
+ <string name="key_ab04_shift">V</string>
+ <string name="key_ab04_alt">@string/alternates_for_v</string>
+
+ <string name="key_ab05_main">b</string>
+ <string name="key_ab05_shift">B</string>
+ <string name="key_ab05_alt">@string/alternates_for_b</string>
+
+ <string name="key_ab06_main">n</string>
+ <string name="key_ab06_shift">N</string>
+ <string name="key_ab06_alt">@string/alternates_for_n</string>
+
+ <string name="key_ab07_main">m</string>
+ <string name="key_ab07_shift">M</string>
+ <string name="key_ab07_alt">@string/alternates_for_m</string>
+
+ <string name="key_ab08_main">,</string>
+ <string name="key_ab08_shift">&lt;</string>
+ <string name="key_ab08_alt">,&lt;≤«‹</string>
+
+ <string name="key_ab09_main">.</string>
+ <string name="key_ab09_shift">&gt;</string>
+ <string name="key_ab09_alt">.&gt;≥»›…</string>
+
+ <string name="key_ab10_main">/</string>
+ <string name="key_ab10_shift">\?</string>
+ <string name="key_ab10_alt">/\?¿</string>
+</resources>
diff --git a/java/res/values-en-rGB/strings.xml b/java/res/values-en-rGB/strings.xml
new file mode 100644
index 0000000..1062fad
--- /dev/null
+++ b/java/res/values-en-rGB/strings.xml
@@ -0,0 +1,143 @@
+<?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/org.pocketworkstation.pckeyboard"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- <string name="english_ime_name" msgid="7252517407088836577">"Android keyboard"</string> -->
+ <!-- <string name="english_ime_settings" msgid="6661589557206947774">"Android keyboard settings"</string> -->
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Input options"</string>
+ <string name="title_key_behavior_settings">Key behaviour settings</string>
+ <string name="title_long_press_alternate_keys">Long-press alternative keys</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrate on key press"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"Sound on key press"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"Pop-up on key press"</string>
+ <string name="hit_correction" msgid="4855351009261318389">"Correct typing errors"</string>
+ <string name="hit_correction_summary" msgid="8761701873008070796">"Enable input error correction"</string>
+ <string name="hit_correction_land" msgid="2567691684825205448">"Landscape input errors"</string>
+ <string name="hit_correction_land_summary" msgid="4076803842198368328">"Enable input error correction"</string>
+ <string name="auto_correction" msgid="7911639788808958255">"Word suggestions"</string>
+ <string name="auto_correction_summary" msgid="6881047311475758267">"Automatically correct the previous word"</string>
+ <string name="prediction" msgid="466220283138359837">"Word suggestions"</string>
+ <string name="prediction_category" msgid="7027100625580696660">"Word suggestion settings"</string>
+ <string name="prediction_summary" msgid="459788228830873110">"Enable auto-completion while typing"</string>
+ <string name="auto_complete_dialog_title" msgid="2172048590607201920">"Auto-completion"</string>
+ <string name="prediction_landscape" msgid="4874601565593216183">"Increase text field size"</string>
+ <string name="prediction_landscape_summary" msgid="6736551095997839472">"Hide word suggestions in landscape view"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"Auto-capitalisation"</string>
+ <string name="auto_cap_summary" msgid="3260681697600786825">"Capitalise the start of a sentence"</string>
+ <string name="auto_punctuate" msgid="7276672334264521751">"Auto-punctuate"</string>
+ <string name="auto_punctuate_summary" msgid="6589441565817502132"></string>
+ <string name="quick_fixes" msgid="5353213327680897927">"Quick fixes"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"Corrects commonly typed mistakes"</string>
+ <string name="show_suggestions" msgid="507074425254289133">"Show suggestions"</string>
+ <string name="show_suggestions_summary" msgid="1989672863935759654">"Display suggested words while typing"</string>
+ <string name="auto_complete" msgid="1103196318775486023">"Auto-complete"</string>
+ <string name="auto_complete_summary" msgid="6113149638718274624">"Spacebar and punctuation automatically insert highlighted word"</string>
+ <string name="prefs_settings_key" msgid="4623341240804046498">"Show settings key"</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automatic"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Always show"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"Always hide"</string>
+ <!-- no translation found for settings_key_modes:0 (8549888726962891527) -->
+ <!-- no translation found for settings_key_modes:1 (881280041213210923) -->
+ <!-- no translation found for settings_key_modes:2 (7317310620171067848) -->
+ <string name="bigram_suggestion" msgid="1323347224043514969">"Bigram Suggestions"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Use previous word to improve suggestion"</string>
+ <string-array name="prediction_modes">
+ <item msgid="4870266572388153286">"None"</item>
+ <item msgid="1669461741568287396">"Basic"</item>
+ <item msgid="4894328801530136615">"Advanced"</item>
+ </string-array>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Saved"</string>
+ <string name="tip_long_press" msgid="6101270866284343344">"Hold a key down to see accents (ø, ö, etc.)"</string>
+ <string name="tip_dismiss" msgid="7585579046862204381">"Press the back key ↶ to close the keyboard at any point"</string>
+ <string name="tip_access_symbols" msgid="6344098517525531652">"Access numbers and symbols"</string>
+ <string name="tip_add_to_dictionary" msgid="1487293888469227817">"Press and hold the leftmost word to add it to the dictionary"</string>
+ <string name="touch_to_continue" msgid="7869803257948414531">"Touch this hint to continue »"</string>
+ <string name="touch_to_finish" msgid="7990196086480585789">"Touch here to close this hint and start typing!"</string>
+ <string name="tip_to_open_keyboard" msgid="6821200275486950452"><b>"The keyboard opens any time you touch a text field"</b></string>
+ <string name="tip_to_view_accents" msgid="5433158573693308501"><b>"Touch &amp; hold a key to view accents"\n"(ø, ö, ô, ó and so on)"</b></string>
+ <string name="tip_to_open_symbols" msgid="7345139325622444880"><b>"Switch to numbers and symbols by touching this key"</b></string>
+ <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"Go back to letters by touching this key again"</b></string>
+ <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"Touch &amp; hold this key to change keyboard settings, like auto-complete"</b></string>
+ <string name="tip_to_start_typing" msgid="7213843601369174313"><b>"Try it!"</b></string>
+ <string name="label_go_key" msgid="1635148082137219148">"Go"</string>
+ <string name="label_next_key" msgid="362972844525672568">"Next"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"Done"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"Send"</string>
+ <string name="label_symbol_key" msgid="6175820506864489453">"?123"</string>
+ <string name="label_phone_key" msgid="4275497665515080551">"123"</string>
+ <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string>
+ <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string>
+ <string name="voice_warning_title" msgid="4419354150908395008">"Voice input"</string>
+ <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Voice input is not currently supported for your language, but does work in English."</string>
+ <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"Voice input is an experimental feature using Google\'s networked speech recognition."</string>
+ <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"To turn off voice input, go to keyboard settings."</string>
+ <string name="voice_hint_dialog_message" msgid="6892342981545727994">"To use voice input, press the microphone button or slide your finger across the on-screen keyboard."</string>
+ <string name="voice_listening" msgid="467518160751321844">"Speak now"</string>
+ <string name="voice_working" msgid="6666937792815731889">"Working"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"Error: Please try again."</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"Couldn\'t connect"</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"Error, too much speech."</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"Audio problem"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"Server error"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"No speech heard"</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"No matches found"</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"Voice search not installed"</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Hint:"</b>" Swipe across keyboard to speak"</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Hint:"</b>" Next time, try speaking punctuation marks, like \"full stop\", \"comma\" or \"question mark\"."</string>
+ <string name="cancel" msgid="6830980399865683324">"Cancel"</string>
+ <string name="ok" msgid="7898366843681727667">"OK"</string>
+ <string name="voice_input" msgid="2466640768843347841">"Voice input"</string>
+ <string-array name="voice_input_modes">
+ <item msgid="1349082139076086774">"On main keyboard"</item>
+ <item msgid="8529385602829095903">"On symbols keyboard"</item>
+ <item msgid="7283103513488381103">"Off"</item>
+ </string-array>
+ <string-array name="voice_input_modes_summary">
+ <item msgid="554248625705084903">"Mic on main keyboard"</item>
+ <item msgid="6907837061058876770">"Mic on symbols keyboard"</item>
+ <item msgid="3664304608587798036">"Voice input is disabled"</item>
+ </string-array>
+ <string name="auto_submit" msgid="9151008027068358518">"Auto-submit after voice"</string>
+ <string name="auto_submit_summary" msgid="4961875269610384226">"Automatically press enter when searching or going to the next field."</string>
+ <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Open the keyboard"\n</b></font><font size="3">\n</font>"Touch any text field."</string>
+ <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Close the keyboard"\n</b></font><font size="3">\n</font>"Press the Back key."</string>
+ <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Touch &amp; hold a key for options"\n</b></font><font size="3">\n</font>"Access punctuation and accents."</string>
+ <string name="keyboard_settings" msgid="4585753477617374032"><font size="17"><b>"Keyboard settings"\n</b></font><font size="3">\n</font>"Touch &amp; hold the "<b>"?123"</b>" key."</string>
+ <string name="popular_domain_0" msgid="3745279225122472969">".com"</string>
+ <string name="popular_domain_1" msgid="1370572248164278467">".net"</string>
+ <string name="popular_domain_2" msgid="3036812463748402878">".org"</string>
+ <string name="popular_domain_3" msgid="8718639560809452028">".co.uk"</string>
+ <string name="popular_domain_4" msgid="35359437471311470">".ac.uk"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"Select input method"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Input languages"</string>
+ <string name="language_selection_summary" msgid="187110938289512256">"Slide finger on spacebar to change language"</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Touch again to save"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"Dictionary available"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"Enable user feedback"</string>
+ <string name="prefs_description_log" msgid="5827825607258246003">"Help improve this input method editor by sending usage statistics and crash reports automatically to Google."</string>
+ <string name="prefs_enable_recorrection" msgid="4588408906649533582">"Touch to correct words"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="1056068922330206170">"Touch words entered to correct them"</string>
+ <string name="keyboard_layout" msgid="437433231038683666">"Keyboard Theme"</string>
+ <string name="subtype_mode_keyboard" msgid="2242090416595003881">"keyboard"</string>
+ <string name="subtype_mode_voice" msgid="4394113125441627771">"voice"</string>
+ <string name="title_hint_mode">Labelled alternative keys</string>
+</resources>
diff --git a/java/res/values-en/donottranslate-altchars.xml b/java/res/values-en/donottranslate-altchars.xml
new file mode 100644
index 0000000..51c7faf
--- /dev/null
+++ b/java/res/values-en/donottranslate-altchars.xml
@@ -0,0 +1,54 @@
+<?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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="alternates_for_a">áàâãäåāæ</string>
+ <string name="alternates_for_b"></string>
+ <string name="alternates_for_c">çčć¢</string>
+ <string name="alternates_for_d">đ</string>
+ <string name="alternates_for_e">3éèêëē€</string>
+ <string name="alternates_for_f">₣</string>
+ <string name="alternates_for_g"></string>
+ <string name="alternates_for_h"></string>
+ <string name="alternates_for_i">8íìîïī</string>
+ <string name="alternates_for_j"></string>
+ <string name="alternates_for_k"></string>
+ <string name="alternates_for_l">£₤λ</string>
+ <string name="alternates_for_m">μ</string>
+ <string name="alternates_for_n">ñ</string>
+ <string name="alternates_for_o">9óòôõöōø</string>
+ <string name="alternates_for_p">0π₱</string>
+ <string name="alternates_for_q">1</string>
+ <string name="alternates_for_r">4</string>
+ <string name="alternates_for_s">§ßš</string>
+ <string name="alternates_for_t">5</string>
+ <string name="alternates_for_u">7úùûüū</string>
+ <string name="alternates_for_v"></string>
+ <string name="alternates_for_w">2</string>
+ <string name="alternates_for_x"></string>
+ <string name="alternates_for_y">6ýÿ¥</string>
+ <string name="alternates_for_z">ž</string>
+
+ <string name="alternates_for_a_umlaut"></string>
+ <string name="alternates_for_ae"></string>
+ <string name="alternates_for_cyrillic_e"></string>
+ <string name="alternates_for_cyrillic_soft_sign"></string>
+ <string name="alternates_for_o_umlaut"></string>
+ <string name="alternates_for_oe"></string>
+</resources>
diff --git a/java/res/values-en/donottranslate-keymap.xml b/java/res/values-en/donottranslate-keymap.xml
new file mode 100644
index 0000000..184dc56
--- /dev/null
+++ b/java/res/values-en/donottranslate-keymap.xml
@@ -0,0 +1,221 @@
+<?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.
+**
+**
+** 5-row layout for English QWERTY.
+**
+** See http://code.google.com/p/hackerskeyboard/wiki/AddingNewLayouts for
+** more information.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="key_tlde_main">`</string>
+ <string name="key_tlde_shift">~</string>
+ <string name="key_tlde_alt">`~</string>
+
+ <string name="key_ae01_main">1</string>
+ <string name="key_ae01_shift">!</string>
+ <string name="key_ae01_alt">1!¡¹½⅓¼⅛</string>
+
+ <string name="key_ae02_main">2</string>
+ <string name="key_ae02_shift">\@</string>
+ <string name="key_ae02_alt">2\@²⅔</string>
+
+ <string name="key_ae03_main">3</string>
+ <string name="key_ae03_shift">#</string>
+ <string name="key_ae03_alt">3#³¾⅜♥♠♦♣</string>
+
+ <string name="key_ae04_main">4</string>
+ <string name="key_ae04_shift">$</string>
+ <string name="key_ae04_alt">4$⁴¢£€¥</string>
+
+ <string name="key_ae05_main">5</string>
+ <string name="key_ae05_shift">%</string>
+ <string name="key_ae05_alt">5%⅝‰</string>
+
+ <string name="key_ae06_main">6</string>
+ <string name="key_ae06_shift">^</string>
+ <string name="key_ae06_alt">6^↑↓←→</string>
+
+ <string name="key_ae07_main">7</string>
+ <string name="key_ae07_shift">&amp;</string>
+ <string name="key_ae07_alt">7&amp;⅞♪</string>
+
+ <string name="key_ae08_main">8</string>
+ <string name="key_ae08_shift">*</string>
+ <string name="key_ae08_alt">8*•★∞†‡</string>
+
+ <string name="key_ae09_main">9</string>
+ <string name="key_ae09_shift">(</string>
+ <string name="key_ae09_alt">9(√</string>
+
+ <string name="key_ae10_main">0</string>
+ <string name="key_ae10_shift">)</string>
+ <string name="key_ae10_alt">0)ⁿ°</string>
+
+ <string name="key_ae11_main">-</string>
+ <string name="key_ae11_shift">_</string>
+ <string name="key_ae11_alt">-_—–</string>
+
+ <string name="key_ae12_main">=</string>
+ <string name="key_ae12_shift">+</string>
+ <string name="key_ae12_alt">=+≈≠±×÷</string>
+
+
+ <string name="key_ad01_main">q</string>
+ <string name="key_ad01_shift">Q</string>
+ <string name="key_ad01_alt">@string/alternates_for_q</string>
+
+ <string name="key_ad02_main">w</string>
+ <string name="key_ad02_shift">W</string>
+ <string name="key_ad02_alt">@string/alternates_for_w</string>
+
+ <string name="key_ad03_main">e</string>
+ <string name="key_ad03_shift">E</string>
+ <string name="key_ad03_alt">@string/alternates_for_e</string>
+
+ <string name="key_ad04_main">r</string>
+ <string name="key_ad04_shift">R</string>
+ <string name="key_ad04_alt">@string/alternates_for_r</string>
+
+ <string name="key_ad05_main">t</string>
+ <string name="key_ad05_shift">T</string>
+ <string name="key_ad05_alt">@string/alternates_for_t</string>
+
+ <string name="key_ad06_main">y</string>
+ <string name="key_ad06_shift">Y</string>
+ <string name="key_ad06_alt">@string/alternates_for_y</string>
+
+ <string name="key_ad07_main">u</string>
+ <string name="key_ad07_shift">U</string>
+ <string name="key_ad07_alt">@string/alternates_for_u</string>
+
+ <string name="key_ad08_main">i</string>
+ <string name="key_ad08_shift">I</string>
+ <string name="key_ad08_alt">@string/alternates_for_i</string>
+
+ <string name="key_ad09_main">o</string>
+ <string name="key_ad09_shift">O</string>
+ <string name="key_ad09_alt">@string/alternates_for_o</string>
+
+ <string name="key_ad10_main">p</string>
+ <string name="key_ad10_shift">P</string>
+ <string name="key_ad10_alt">@string/alternates_for_p</string>
+
+ <string name="key_ad11_main">[</string>
+ <string name="key_ad11_shift">{</string>
+ <string name="key_ad11_alt">[{</string>
+
+ <string name="key_ad12_main">]</string>
+ <string name="key_ad12_shift">}</string>
+ <string name="key_ad12_alt">]}</string>
+
+ <string name="key_bksl_main">\\</string>
+ <string name="key_bksl_shift">|</string>
+ <string name="key_bksl_alt">\\|</string>
+
+
+ <string name="key_ac01_main">a</string>
+ <string name="key_ac01_shift">A</string>
+ <string name="key_ac01_alt">@string/alternates_for_a</string>
+
+ <string name="key_ac02_main">s</string>
+ <string name="key_ac02_shift">S</string>
+ <string name="key_ac02_alt">@string/alternates_for_s</string>
+
+ <string name="key_ac03_main">d</string>
+ <string name="key_ac03_shift">D</string>
+ <string name="key_ac03_alt">@string/alternates_for_d</string>
+
+ <string name="key_ac04_main">f</string>
+ <string name="key_ac04_shift">F</string>
+ <string name="key_ac04_alt">@string/alternates_for_f</string>
+
+ <string name="key_ac05_main">g</string>
+ <string name="key_ac05_shift">G</string>
+ <string name="key_ac05_alt">@string/alternates_for_g</string>
+
+ <string name="key_ac06_main">h</string>
+ <string name="key_ac06_shift">H</string>
+ <string name="key_ac06_alt">@string/alternates_for_h</string>
+
+ <string name="key_ac07_main">j</string>
+ <string name="key_ac07_shift">J</string>
+ <string name="key_ac07_alt">@string/alternates_for_j</string>
+
+ <string name="key_ac08_main">k</string>
+ <string name="key_ac08_shift">K</string>
+ <string name="key_ac08_alt">@string/alternates_for_k</string>
+
+ <string name="key_ac09_main">l</string>
+ <string name="key_ac09_shift">L</string>
+ <string name="key_ac09_alt">@string/alternates_for_l</string>
+
+ <string name="key_ac10_main">;</string>
+ <string name="key_ac10_shift">:</string>
+ <string name="key_ac10_alt">;:</string>
+
+ <string name="key_ac11_main">\'</string>
+ <string name="key_ac11_shift">\"</string>
+ <string name="key_ac11_alt">\'\"‘’“”</string>
+
+
+ <string name="key_lsgt_main"></string>
+ <string name="key_lsgt_shift"></string>
+ <string name="key_lsgt_alt"></string>
+
+ <string name="key_ab01_main">z</string>
+ <string name="key_ab01_shift">Z</string>
+ <string name="key_ab01_alt">@string/alternates_for_z</string>
+
+ <string name="key_ab02_main">x</string>
+ <string name="key_ab02_shift">X</string>
+ <string name="key_ab02_alt">@string/alternates_for_x</string>
+
+ <string name="key_ab03_main">c</string>
+ <string name="key_ab03_shift">C</string>
+ <string name="key_ab03_alt">@string/alternates_for_c</string>
+
+ <string name="key_ab04_main">v</string>
+ <string name="key_ab04_shift">V</string>
+ <string name="key_ab04_alt">@string/alternates_for_v</string>
+
+ <string name="key_ab05_main">b</string>
+ <string name="key_ab05_shift">B</string>
+ <string name="key_ab05_alt">@string/alternates_for_b</string>
+
+ <string name="key_ab06_main">n</string>
+ <string name="key_ab06_shift">N</string>
+ <string name="key_ab06_alt">@string/alternates_for_n</string>
+
+ <string name="key_ab07_main">m</string>
+ <string name="key_ab07_shift">M</string>
+ <string name="key_ab07_alt">@string/alternates_for_m</string>
+
+ <string name="key_ab08_main">,</string>
+ <string name="key_ab08_shift">&lt;</string>
+ <string name="key_ab08_alt">,&lt;≤«‹</string>
+
+ <string name="key_ab09_main">.</string>
+ <string name="key_ab09_shift">&gt;</string>
+ <string name="key_ab09_alt">.&gt;≥»›…</string>
+
+ <string name="key_ab10_main">/</string>
+ <string name="key_ab10_shift">\?</string>
+ <string name="key_ab10_alt">/\?¿</string>
+</resources>
diff --git a/java/res/values-es-rUS/donottranslate-altchars.xml b/java/res/values-es-rUS/donottranslate-altchars.xml
new file mode 100644
index 0000000..431a41a
--- /dev/null
+++ b/java/res/values-es-rUS/donottranslate-altchars.xml
@@ -0,0 +1,30 @@
+<?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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="alternates_for_a">áàâãäåæ</string>
+ <string name="alternates_for_e">3éèêë</string>
+ <string name="alternates_for_i">8íìïî</string>
+ <string name="alternates_for_o">9óòõôöœø</string>
+ <string name="alternates_for_u">7úùüû</string>
+ <string name="alternates_for_s">§ß</string>
+ <string name="alternates_for_n">ñ</string>
+ <string name="alternates_for_c">ç</string>
+ <string name="alternates_for_y">6ýÿ</string>
+</resources>
diff --git a/java/res/values-es-rUS/strings.xml b/java/res/values-es-rUS/strings.xml
new file mode 100644
index 0000000..802bedb
--- /dev/null
+++ b/java/res/values-es-rUS/strings.xml
@@ -0,0 +1,140 @@
+<?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/org.pocketworkstation.pckeyboard"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- <string name="english_ime_name" msgid="7252517407088836577">"Teclado de Android"</string> -->
+ <!-- <string name="english_ime_settings" msgid="6661589557206947774">"Configuración de teclado de Android"</string> -->
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Opciones de entrada"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrar al pulsar teclas"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"Sonar al pulsar las teclas"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"Aviso emergente sobre keypress"</string>
+ <string name="hit_correction" msgid="4855351009261318389">"Corregir errores de escritura"</string>
+ <string name="hit_correction_summary" msgid="8761701873008070796">"Habilitar corrección de error de entrada"</string>
+ <string name="hit_correction_land" msgid="2567691684825205448">"Errores de entrada apaisada"</string>
+ <string name="hit_correction_land_summary" msgid="4076803842198368328">"Habilitar corrección de error de entrada"</string>
+ <string name="auto_correction" msgid="7911639788808958255">"Sugerencias de palabras"</string>
+ <string name="auto_correction_summary" msgid="6881047311475758267">"Corregir automáticamente la palabra anterior"</string>
+ <string name="prediction" msgid="466220283138359837">"Sugerencias de palabras"</string>
+ <string name="prediction_category" msgid="7027100625580696660">"Configuración de sugerencia de palabra"</string>
+ <string name="prediction_summary" msgid="459788228830873110">"Habilitar finalización automática al escribir"</string>
+ <string name="auto_complete_dialog_title" msgid="2172048590607201920">"Finalización automática"</string>
+ <string name="prediction_landscape" msgid="4874601565593216183">"Aumentar el tamaño del campo de texto"</string>
+ <string name="prediction_landscape_summary" msgid="6736551095997839472">"Ocultar sugerencias de palabras en vista apaisada"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"Mayúsculas automáticas"</string>
+ <string name="auto_cap_summary" msgid="3260681697600786825">"Poner en mayúscula el inicio de una oración"</string>
+ <string name="auto_punctuate" msgid="7276672334264521751">"Puntuación automática"</string>
+ <string name="auto_punctuate_summary" msgid="6589441565817502132"></string>
+ <string name="quick_fixes" msgid="5353213327680897927">"Arreglos rápidos"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"Corrige errores de escritura comunes"</string>
+ <string name="show_suggestions" msgid="507074425254289133">"Mostrar sugerencias"</string>
+ <string name="show_suggestions_summary" msgid="1989672863935759654">"Mostrar palabras sugeridas mientras escribe"</string>
+ <string name="auto_complete" msgid="1103196318775486023">"Completar automát."</string>
+ <string name="auto_complete_summary" msgid="6113149638718274624">"La barra espaciadora o la puntuación insertan automáticamente la palabra resaltada."</string>
+ <string name="prefs_settings_key" msgid="4623341240804046498">"Mostrar tecla de configuración"</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automático"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Mostrar siempre"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"Ocultar siempre"</string>
+ <!-- no translation found for settings_key_modes:0 (8549888726962891527) -->
+ <!-- no translation found for settings_key_modes:1 (881280041213210923) -->
+ <!-- no translation found for settings_key_modes:2 (7317310620171067848) -->
+ <string name="bigram_suggestion" msgid="1323347224043514969">"Sugerencias de Vigoran"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Utiliza la palabra anterior para mejorar la sugerencia"</string>
+ <string-array name="prediction_modes">
+ <item msgid="4870266572388153286">"Ninguno"</item>
+ <item msgid="1669461741568287396">"Básico"</item>
+ <item msgid="4894328801530136615">"Avanzado"</item>
+ </string-array>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: guardada"</string>
+ <string name="tip_long_press" msgid="6101270866284343344">"Mantén una tecla presionada para ver los acentos (ø, ö, etc.)"</string>
+ <string name="tip_dismiss" msgid="7585579046862204381">"Pulsa la tecla hacia atrás ↶ para cerrar el teclado en cualquier momento"</string>
+ <string name="tip_access_symbols" msgid="6344098517525531652">"Acceder a números y símbolos"</string>
+ <string name="tip_add_to_dictionary" msgid="1487293888469227817">"Presiona y mantén presionada la palabra de la izquierda para agregarla al diccionario"</string>
+ <string name="touch_to_continue" msgid="7869803257948414531">"Toca esta sugerencia para continuar »"</string>
+ <string name="touch_to_finish" msgid="7990196086480585789">"Toca aquí para cerrar esta sugerencia y comenzar a escribir."</string>
+ <string name="tip_to_open_keyboard" msgid="6821200275486950452"><b>"El teclado se abre cada vez que tocas un campo de texto."</b></string>
+ <string name="tip_to_view_accents" msgid="5433158573693308501"><b>"Toca y mantén presionada una tecla para ver los acentos"\n"(ø, ö, ô, ó, y así sucesivamente)."</b></string>
+ <string name="tip_to_open_symbols" msgid="7345139325622444880"><b>"Cambia de números a símbolos tocando esta tecla."</b></string>
+ <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"Vuelve a letras tocando esta tecla nuevamente."</b></string>
+ <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"Toca y mantén presionada esta tecla para cambiar la configuración del teclado, como completar automáticamente."</b></string>
+ <string name="tip_to_start_typing" msgid="7213843601369174313"><b>"¡Pruébalo!"</b></string>
+ <string name="label_go_key" msgid="1635148082137219148">"Ir"</string>
+ <string name="label_next_key" msgid="362972844525672568">"Siguiente"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"Hecho"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"Enviar"</string>
+ <string name="label_symbol_key" msgid="6175820506864489453">"?123"</string>
+ <string name="label_phone_key" msgid="4275497665515080551">"123"</string>
+ <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string>
+ <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string>
+ <string name="voice_warning_title" msgid="4419354150908395008">"Entrada por voz"</string>
+ <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"La entrada por voz no está admitida en tu idioma, pero sí funciona en inglés."</string>
+ <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"La entrada por voz es una característica experimental que utiliza la red de reconocimiento de voz de Google."</string>
+ <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"Para desactivar la entrada por voz, ve a configuración del teclado."</string>
+ <string name="voice_hint_dialog_message" msgid="6892342981545727994">"Para realizar entrada por voz, presiona el botón del micrófono o desliza tus dedos por el teclado en pantalla."</string>
+ <string name="voice_listening" msgid="467518160751321844">"Habla ahora"</string>
+ <string name="voice_working" msgid="6666937792815731889">"Procesando"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"Error. Vuelve a intentarlo."</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"No se pudo establecer la conexión."</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"Error, demasiado discurso."</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"Problema de audio"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"Error del servidor"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"No se oyó la voz"</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"No se encontraron coincidencias"</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"Búsqueda por voz no instalada"</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Sugerencia:"</b>" Deslizar en el teclado para hablar"</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Sugerencia:"</b>" La próxima vez intenta decir la puntuación como \"punto\", \"coma\" o \"signo de pregunta\"."</string>
+ <string name="cancel" msgid="6830980399865683324">"Cancelar"</string>
+ <string name="ok" msgid="7898366843681727667">"Aceptar"</string>
+ <string name="voice_input" msgid="2466640768843347841">"Entrada por voz"</string>
+ <string-array name="voice_input_modes">
+ <item msgid="1349082139076086774">"En el teclado principal"</item>
+ <item msgid="8529385602829095903">"En el teclado de símbolos"</item>
+ <item msgid="7283103513488381103">"Apagado"</item>
+ </string-array>
+ <string-array name="voice_input_modes_summary">
+ <item msgid="554248625705084903">"Micrófono en el teclado principal"</item>
+ <item msgid="6907837061058876770">"Micrófono en el teclado de símbolos"</item>
+ <item msgid="3664304608587798036">"La entrada por voz está inhabilitada."</item>
+ </string-array>
+ <string name="auto_submit" msgid="9151008027068358518">"Enviar automáticamente después del audio"</string>
+ <string name="auto_submit_summary" msgid="4961875269610384226">"Presionar automáticamente Ingresar al buscar o ir al campo siguiente."</string>
+ <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Abrir el teclado"\n</b></font><font size="3">\n</font>"Tocar cualquier campo de texto."</string>
+ <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Cerrar el teclado"\n</b></font><font size="3">\n</font>"Presionar la tecla Atrás."</string>
+ <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Tocar &amp; y mantener presionada una tecla para las opciones"\n</b></font><font size="3">\n</font>"Acceder a puntuación y acentos."</string>
+ <string name="keyboard_settings" msgid="4585753477617374032"><font size="17"><b>"Configuración del teclado"\n</b></font><font size="3">\n</font>"Tocar &amp; y mantener presionada la tecla "<b>"?123"</b>"."</string>
+ <string name="popular_domain_0" msgid="3745279225122472969">".com"</string>
+ <string name="popular_domain_1" msgid="1370572248164278467">".net"</string>
+ <string name="popular_domain_2" msgid="3036812463748402878">".org"</string>
+ <string name="popular_domain_3" msgid="8718639560809452028">".gov"</string>
+ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"Seleccionar método de entrada"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Idiomas de entrada"</string>
+ <string name="language_selection_summary" msgid="187110938289512256">"Deslizarse manualmente por la barra espaciadora para cambiar el idioma"</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Tocar de nuevo para guardar"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"Diccionario disponible"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"Habilitar los comentarios del usuario"</string>
+ <string name="prefs_description_log" msgid="5827825607258246003">"Ayuda a mejorar este editor de método de introducción de texto al enviar las estadísticas de uso y los informes de error a Google."</string>
+ <string name="prefs_enable_recorrection" msgid="4588408906649533582">"Tocar para corregir palabras"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="1056068922330206170">"Toca las palabras ingresadas que desees corregir"</string>
+ <string name="keyboard_layout" msgid="437433231038683666">"Tema del teclado"</string>
+ <string name="subtype_mode_keyboard" msgid="2242090416595003881">"Teclado"</string>
+ <string name="subtype_mode_voice" msgid="4394113125441627771">"Voz"</string>
+</resources>
diff --git a/java/res/values-es/donottranslate-altchars.xml b/java/res/values-es/donottranslate-altchars.xml
new file mode 100644
index 0000000..2cfb992
--- /dev/null
+++ b/java/res/values-es/donottranslate-altchars.xml
@@ -0,0 +1,30 @@
+<?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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="alternates_for_a">á</string>
+ <string name="alternates_for_e">3é</string>
+ <string name="alternates_for_i">8íìïî</string>
+ <string name="alternates_for_o">9ó</string>
+ <string name="alternates_for_u">7úùüû</string>
+ <string name="alternates_for_s">§ß</string>
+ <string name="alternates_for_n">ñ</string>
+ <string name="alternates_for_c">ç</string>
+ <string name="alternates_for_y">6ýÿ</string>
+</resources>
diff --git a/java/res/values-es/donottranslate-keymap.xml b/java/res/values-es/donottranslate-keymap.xml
new file mode 100644
index 0000000..0969b43
--- /dev/null
+++ b/java/res/values-es/donottranslate-keymap.xml
@@ -0,0 +1,221 @@
+<?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.
+**
+**
+** 5-row layout for Spanish.
+**
+** See http://code.google.com/p/hackerskeyboard/wiki/AddingNewLayouts for
+** more information.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="key_tlde_main">º</string>
+ <string name="key_tlde_shift">ª</string>
+ <string name="key_tlde_alt">ºª</string>
+
+ <string name="key_ae01_main">1</string>
+ <string name="key_ae01_shift">!</string>
+ <string name="key_ae01_alt">1!|¡¹</string>
+
+ <string name="key_ae02_main">2</string>
+ <string name="key_ae02_shift">\"</string>
+ <string name="key_ae02_alt">2\"\@²⅛“”‘’</string>
+
+ <string name="key_ae03_main">3</string>
+ <string name="key_ae03_shift">·</string>
+ <string name="key_ae03_alt">3·#£³</string>
+
+ <string name="key_ae04_main">4</string>
+ <string name="key_ae04_shift">$</string>
+ <string name="key_ae04_alt">4$&#x0303;~⁴¢¥</string>
+
+ <string name="key_ae05_main">5</string>
+ <string name="key_ae05_shift">%</string>
+ <string name="key_ae05_alt">5%½⅜</string>
+
+ <string name="key_ae06_main">6</string>
+ <string name="key_ae06_shift">&amp;</string>
+ <string name="key_ae06_alt">6&amp;¬⅝</string>
+
+ <string name="key_ae07_main">7</string>
+ <string name="key_ae07_shift">/</string>
+ <string name="key_ae07_alt">7/{⅞♪</string>
+
+ <string name="key_ae08_main">8</string>
+ <string name="key_ae08_shift">(</string>
+ <string name="key_ae08_alt">8([™</string>
+
+ <string name="key_ae09_main">9</string>
+ <string name="key_ae09_shift">)</string>
+ <string name="key_ae09_alt">9)]±</string>
+
+ <string name="key_ae10_main">0</string>
+ <string name="key_ae10_shift">=</string>
+ <string name="key_ae10_alt">0=}°</string>
+
+ <string name="key_ae11_main">\'</string>
+ <string name="key_ae11_shift">\?</string>
+ <string name="key_ae11_alt">\'\?\\¿</string>
+
+ <string name="key_ae12_main">¡</string>
+ <string name="key_ae12_shift">¿</string>
+ <string name="key_ae12_alt">¡¿~</string>
+
+
+ <string name="key_ad01_main">q</string>
+ <string name="key_ad01_shift">Q</string>
+ <string name="key_ad01_alt">@string/alternates_for_q</string>
+
+ <string name="key_ad02_main">w</string>
+ <string name="key_ad02_shift">W</string>
+ <string name="key_ad02_alt">@string/alternates_for_w</string>
+
+ <string name="key_ad03_main">e</string>
+ <string name="key_ad03_shift">E</string>
+ <string name="key_ad03_alt">@string/alternates_for_e</string>
+
+ <string name="key_ad04_main">r</string>
+ <string name="key_ad04_shift">R</string>
+ <string name="key_ad04_alt">@string/alternates_for_r</string>
+
+ <string name="key_ad05_main">t</string>
+ <string name="key_ad05_shift">T</string>
+ <string name="key_ad05_alt">@string/alternates_for_t</string>
+
+ <string name="key_ad06_main">y</string>
+ <string name="key_ad06_shift">Y</string>
+ <string name="key_ad06_alt">@string/alternates_for_y</string>
+
+ <string name="key_ad07_main">u</string>
+ <string name="key_ad07_shift">U</string>
+ <string name="key_ad07_alt">@string/alternates_for_u</string>
+
+ <string name="key_ad08_main">i</string>
+ <string name="key_ad08_shift">I</string>
+ <string name="key_ad08_alt">@string/alternates_for_i</string>
+
+ <string name="key_ad09_main">o</string>
+ <string name="key_ad09_shift">O</string>
+ <string name="key_ad09_alt">@string/alternates_for_o</string>
+
+ <string name="key_ad10_main">p</string>
+ <string name="key_ad10_shift">P</string>
+ <string name="key_ad10_alt">@string/alternates_for_p</string>
+
+ <string name="key_ad11_main">&#x0300;</string>
+ <string name="key_ad11_shift">&#x0302;</string>
+ <string name="key_ad11_alt">&#x0300;&#x0302;`^[°</string>
+
+ <string name="key_ad12_main">+</string>
+ <string name="key_ad12_shift">*</string>
+ <string name="key_ad12_alt">]</string>
+
+ <string name="key_bksl_main">ç</string>
+ <string name="key_bksl_shift">Ç</string>
+ <string name="key_bksl_alt">}</string>
+
+
+ <string name="key_ac01_main">a</string>
+ <string name="key_ac01_shift">A</string>
+ <string name="key_ac01_alt">@string/alternates_for_a</string>
+
+ <string name="key_ac02_main">s</string>
+ <string name="key_ac02_shift">S</string>
+ <string name="key_ac02_alt">@string/alternates_for_s</string>
+
+ <string name="key_ac03_main">d</string>
+ <string name="key_ac03_shift">D</string>
+ <string name="key_ac03_alt">@string/alternates_for_d</string>
+
+ <string name="key_ac04_main">f</string>
+ <string name="key_ac04_shift">F</string>
+ <string name="key_ac04_alt">@string/alternates_for_f</string>
+
+ <string name="key_ac05_main">g</string>
+ <string name="key_ac05_shift">G</string>
+ <string name="key_ac05_alt">@string/alternates_for_g</string>
+
+ <string name="key_ac06_main">h</string>
+ <string name="key_ac06_shift">H</string>
+ <string name="key_ac06_alt">@string/alternates_for_h</string>
+
+ <string name="key_ac07_main">j</string>
+ <string name="key_ac07_shift">J</string>
+ <string name="key_ac07_alt">@string/alternates_for_j</string>
+
+ <string name="key_ac08_main">k</string>
+ <string name="key_ac08_shift">K</string>
+ <string name="key_ac08_alt">@string/alternates_for_k</string>
+
+ <string name="key_ac09_main">l</string>
+ <string name="key_ac09_shift">L</string>
+ <string name="key_ac09_alt">@string/alternates_for_l</string>
+
+ <string name="key_ac10_main">ñ</string>
+ <string name="key_ac10_shift">Ñ</string>
+ <string name="key_ac10_alt">~</string>
+
+ <string name="key_ac11_main">&#x0301;</string>
+ <string name="key_ac11_shift">&#x0308;</string>
+ <string name="key_ac11_alt">&#x0301;&#x0308;</string>
+
+
+ <string name="key_lsgt_main">&lt;</string>
+ <string name="key_lsgt_shift">&gt;</string>
+ <string name="key_lsgt_alt">&lt;&gt;|</string>
+
+ <string name="key_ab01_main">z</string>
+ <string name="key_ab01_shift">Z</string>
+ <string name="key_ab01_alt">@string/alternates_for_z</string>
+
+ <string name="key_ab02_main">x</string>
+ <string name="key_ab02_shift">X</string>
+ <string name="key_ab02_alt">@string/alternates_for_x</string>
+
+ <string name="key_ab03_main">c</string>
+ <string name="key_ab03_shift">C</string>
+ <string name="key_ab03_alt">@string/alternates_for_c</string>
+
+ <string name="key_ab04_main">v</string>
+ <string name="key_ab04_shift">V</string>
+ <string name="key_ab04_alt">@string/alternates_for_v</string>
+
+ <string name="key_ab05_main">b</string>
+ <string name="key_ab05_shift">B</string>
+ <string name="key_ab05_alt">@string/alternates_for_b</string>
+
+ <string name="key_ab06_main">n</string>
+ <string name="key_ab06_shift">N</string>
+ <string name="key_ab06_alt">@string/alternates_for_n</string>
+
+ <string name="key_ab07_main">m</string>
+ <string name="key_ab07_shift">M</string>
+ <string name="key_ab07_alt">@string/alternates_for_m</string>
+
+ <string name="key_ab08_main">,</string>
+ <string name="key_ab08_shift">;</string>
+ <string name="key_ab08_alt">,;×</string>
+
+ <string name="key_ab09_main">.</string>
+ <string name="key_ab09_shift">:</string>
+ <string name="key_ab09_alt">.:…</string>
+
+ <string name="key_ab10_main">-</string>
+ <string name="key_ab10_shift">_</string>
+ <string name="key_ab10_alt">-_</string>
+</resources>
diff --git a/java/res/values-es/strings.xml b/java/res/values-es/strings.xml
new file mode 100644
index 0000000..a93a269
--- /dev/null
+++ b/java/res/values-es/strings.xml
@@ -0,0 +1,140 @@
+<?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/org.pocketworkstation.pckeyboard"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- <string name="english_ime_name" msgid="7252517407088836577">"Teclado de Android"</string> -->
+ <!-- <string name="english_ime_settings" msgid="6661589557206947774">"Ajustes del teclado de Android"</string> -->
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Opciones introducción texto"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrar al pulsar tecla"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"Sonido al pulsar tecla"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"Popup al pulsar tecla"</string>
+ <string name="hit_correction" msgid="4855351009261318389">"Corregir errores de escritura"</string>
+ <string name="hit_correction_summary" msgid="8761701873008070796">"Habilitar la introducción de corrección de errores"</string>
+ <string name="hit_correction_land" msgid="2567691684825205448">"Errores de introducción de datos en vista horizontal"</string>
+ <string name="hit_correction_land_summary" msgid="4076803842198368328">"Habilitar la introducción de corrección de errores"</string>
+ <string name="auto_correction" msgid="7911639788808958255">"Sugerencias de palabras"</string>
+ <string name="auto_correction_summary" msgid="6881047311475758267">"Corregir automáticamente la palabra anterior"</string>
+ <string name="prediction" msgid="466220283138359837">"Sugerencias de palabras"</string>
+ <string name="prediction_category" msgid="7027100625580696660">"Ajustes de sugerencia de palabras"</string>
+ <string name="prediction_summary" msgid="459788228830873110">"Habilitar Autocompletar al escribir"</string>
+ <string name="auto_complete_dialog_title" msgid="2172048590607201920">"Autocompletar"</string>
+ <string name="prediction_landscape" msgid="4874601565593216183">"Aumentar el tamaño del campo de texto"</string>
+ <string name="prediction_landscape_summary" msgid="6736551095997839472">"Ocultar sugerencias de palabras en la vista horizontal"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"Mayúsculas automáticas"</string>
+ <string name="auto_cap_summary" msgid="3260681697600786825">"Escribir en mayúscula el principio de la frase"</string>
+ <string name="auto_punctuate" msgid="7276672334264521751">"Puntuación automática"</string>
+ <string name="auto_punctuate_summary" msgid="6589441565817502132"></string>
+ <string name="quick_fixes" msgid="5353213327680897927">"Correcciones rápidas"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"Corrige los errores tipográficos que se cometen con más frecuencia."</string>
+ <string name="show_suggestions" msgid="507074425254289133">"Mostrar sugerencias"</string>
+ <string name="show_suggestions_summary" msgid="1989672863935759654">"Muestra las palabras sugeridas mientras se escribe."</string>
+ <string name="auto_complete" msgid="1103196318775486023">"Autocompletar"</string>
+ <string name="auto_complete_summary" msgid="6113149638718274624">"La barra espaciadora y los signos de puntuación insertan automáticamente la palabra resaltada."</string>
+ <string name="prefs_settings_key" msgid="4623341240804046498">"Mostrar tecla de ajustes"</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automáticamente"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Mostrar siempre"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"Ocultar siempre"</string>
+ <!-- no translation found for settings_key_modes:0 (8549888726962891527) -->
+ <!-- no translation found for settings_key_modes:1 (881280041213210923) -->
+ <!-- no translation found for settings_key_modes:2 (7317310620171067848) -->
+ <string name="bigram_suggestion" msgid="1323347224043514969">"Sugerencias de bigramas"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Usar palabra anterior para mejorar sugerencias"</string>
+ <string-array name="prediction_modes">
+ <item msgid="4870266572388153286">"Ninguno"</item>
+ <item msgid="1669461741568287396">"Básico"</item>
+ <item msgid="4894328801530136615">"Avanzado"</item>
+ </string-array>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: guardada"</string>
+ <string name="tip_long_press" msgid="6101270866284343344">"Mantén pulsada una tecla para ver los caracteres acentuados (ø, ö, etc.)."</string>
+ <string name="tip_dismiss" msgid="7585579046862204381">"Pulsa la tecla \"Atrás\" ↶ para cerrar el teclado en cualquier momento."</string>
+ <string name="tip_access_symbols" msgid="6344098517525531652">"Acceso a números y símbolos"</string>
+ <string name="tip_add_to_dictionary" msgid="1487293888469227817">"Mantén pulsada la palabra situada más a la izquierda para añadirla al diccionario."</string>
+ <string name="touch_to_continue" msgid="7869803257948414531">"Toca esta sugerencia para continuar »"</string>
+ <string name="touch_to_finish" msgid="7990196086480585789">"Toca aquí para cerrar la sugerencia y comenzar a escribir."</string>
+ <string name="tip_to_open_keyboard" msgid="6821200275486950452"><b>"El teclado se abre cada vez que tocas un campo de texto"</b>"."</string>
+ <string name="tip_to_view_accents" msgid="5433158573693308501"><b>"Mantén pulsada una tecla para ver los caracteres acentuados"\n"(ø, ö, ô, ó, etc.)."</b></string>
+ <string name="tip_to_open_symbols" msgid="7345139325622444880"><b>"Cambiar a números y a símbolos tocando esta tecla"</b></string>
+ <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"Volver a las letras tocando esta tecla de nuevo"</b></string>
+ <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"Mantén pulsada esta tecla para cambiar la configuración de teclado a, por ejemplo, autocompletar"</b>"."</string>
+ <string name="tip_to_start_typing" msgid="7213843601369174313"><b>"¡Pruébalo!"</b></string>
+ <string name="label_go_key" msgid="1635148082137219148">"Ir"</string>
+ <string name="label_next_key" msgid="362972844525672568">"Sig."</string>
+ <string name="label_done_key" msgid="2441578748772529288">"Listo"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"Enviar"</string>
+ <string name="label_symbol_key" msgid="6175820506864489453">"?123"</string>
+ <string name="label_phone_key" msgid="4275497665515080551">"123"</string>
+ <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string>
+ <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string>
+ <string name="voice_warning_title" msgid="4419354150908395008">"Introducción de voz"</string>
+ <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Actualmente la introducción de voz no está disponible en tu idioma, pero se puede utilizar en inglés."</string>
+ <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"La introducción de voz es una función en fase experimental que utiliza la tecnología de reconocimiento de voz en red de Google."</string>
+ <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"Para desactivar la función de introducción de voz, accede a la configuración del teclado."</string>
+ <string name="voice_hint_dialog_message" msgid="6892342981545727994">"Para utilizar la función de introducción de voz, pulsa el botón de micrófono o desliza el dedo por el teclado en pantalla."</string>
+ <string name="voice_listening" msgid="467518160751321844">"Habla ahora"</string>
+ <string name="voice_working" msgid="6666937792815731889">"En curso"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"Se ha producido un error. Inténtalo de nuevo."</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"No se ha podido establecer conexión."</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"Se ha producido un error debido a un exceso de introducción de datos de voz."</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"Problema de audio"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"Error del servidor"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"Ninguna conversación escuchada"</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"No se ha encontrado ninguna coincidencia."</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"La búsqueda por voz no está instalada."</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Sugerencia:"</b>" muévete por el teclado para hablar."</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Sugerencia:"</b>" la próxima vez, prueba a indicar signos de puntuación como, por ejemplo, \"punto\", \"coma\" o \"signo de interrogación\"."</string>
+ <string name="cancel" msgid="6830980399865683324">"Cancelar"</string>
+ <string name="ok" msgid="7898366843681727667">"Aceptar"</string>
+ <string name="voice_input" msgid="2466640768843347841">"Introducción de voz"</string>
+ <string-array name="voice_input_modes">
+ <item msgid="1349082139076086774">"En teclado principal"</item>
+ <item msgid="8529385602829095903">"En teclado de símbolos"</item>
+ <item msgid="7283103513488381103">"Desactivado"</item>
+ </string-array>
+ <string-array name="voice_input_modes_summary">
+ <item msgid="554248625705084903">"Micrófono en teclado principal"</item>
+ <item msgid="6907837061058876770">"Micrófono en teclado de símbolos"</item>
+ <item msgid="3664304608587798036">"La función de introducción de voz no está habilitada."</item>
+ </string-array>
+ <string name="auto_submit" msgid="9151008027068358518">"Enviar automáticamente después de la introducción de voz"</string>
+ <string name="auto_submit_summary" msgid="4961875269610384226">"Pulsar Intro automáticamente al buscar o al pasar al siguiente campo"</string>
+ <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Abrir el teclado"\n</b></font><font size="3">\n</font>"Toca cualquier campo de texto."</string>
+ <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Cerrar el teclado"\n</b></font><font size="3">\n</font>"Pulsa la tecla \"Atrás\"."</string>
+ <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Mantén pulsada una tecla para acceder a las opciones."\n</b></font><font size="3">\n</font>"Accede a los signos de puntuación y a los acentos."</string>
+ <string name="keyboard_settings" msgid="4585753477617374032"><font size="17"><b>"Ajustes del teclado"\n</b></font><font size="3">\n</font>"Mantén pulsada la tecla "<b>"?123"</b>"."</string>
+ <string name="popular_domain_0" msgid="3745279225122472969">".com"</string>
+ <string name="popular_domain_1" msgid="1370572248164278467">".net"</string>
+ <string name="popular_domain_2" msgid="3036812463748402878">".org"</string>
+ <string name="popular_domain_3" msgid="8718639560809452028">".gov"</string>
+ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"Seleccionar método de introducción de texto"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Idiomas"</string>
+ <string name="language_selection_summary" msgid="187110938289512256">"Deslizar el dedo por la barra espaciadora para cambiar el idioma"</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Volver a tocar para guardar"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"Hay un diccionario disponible."</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"Habilitar comentarios de usuarios"</string>
+ <string name="prefs_description_log" msgid="5827825607258246003">"Ayuda a mejorar este editor de método de introducción de texto enviando estadísticas de uso e informes de error a Google."</string>
+ <string name="prefs_enable_recorrection" msgid="4588408906649533582">"Tocar para corregir palabras"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="1056068922330206170">"Tocar palabras introducidas para corregirlas"</string>
+ <string name="keyboard_layout" msgid="437433231038683666">"Tema de teclado"</string>
+ <string name="subtype_mode_keyboard" msgid="2242090416595003881">"teclado"</string>
+ <string name="subtype_mode_voice" msgid="4394113125441627771">"voz"</string>
+</resources>
diff --git a/java/res/values-fa/donottranslate-keymap.xml b/java/res/values-fa/donottranslate-keymap.xml
new file mode 100644
index 0000000..ac52ac0
--- /dev/null
+++ b/java/res/values-fa/donottranslate-keymap.xml
@@ -0,0 +1,223 @@
+<?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.
+**
+**
+** 5-row layout for Arabic.
+**
+** See http://code.google.com/p/hackerskeyboard/wiki/AddingNewLayouts for
+** more information.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="key_tlde_main">‍</string>
+ <string name="key_tlde_shift">÷</string>
+ <string name="key_tlde_alt">‍÷~</string>
+
+ <string name="key_ae01_main">۱</string>
+ <string name="key_ae01_shift">!</string>
+ <string name="key_ae01_alt">۱!`1</string>
+
+ <string name="key_ae02_main">۲</string>
+ <string name="key_ae02_shift">٬</string>
+ <string name="key_ae02_alt">۲٬\@2</string>
+
+ <string name="key_ae03_main">۳</string>
+ <string name="key_ae03_shift">٫</string>
+ <string name="key_ae03_alt">۳٫#♥♠♦♣3</string>
+
+ <string name="key_ae04_main">۴</string>
+ <string name="key_ae04_shift">﷼</string>
+ <string name="key_ae04_alt">۴﷼$€¥¢£4</string>
+
+ <string name="key_ae05_main">۵</string>
+ <string name="key_ae05_shift">٪</string>
+ <string name="key_ae05_alt">۵٪%5</string>
+
+ <string name="key_ae06_main">۶</string>
+ <string name="key_ae06_shift">×</string>
+ <string name="key_ae06_alt">۶×^↑↓←→6</string>
+
+ <string name="key_ae07_main">۷</string>
+ <string name="key_ae07_shift">،</string>
+ <string name="key_ae07_alt">۷،&amp;♪7</string>
+
+ <string name="key_ae08_main">۸</string>
+ <string name="key_ae08_shift">*</string>
+ <string name="key_ae08_alt">۸*•★∞†‡8</string>
+
+ <string name="key_ae09_main">۹</string>
+ <string name="key_ae09_shift">)</string>
+ <string name="key_ae09_alt">۹)√9</string>
+
+ <string name="key_ae10_main">۰</string>
+ <string name="key_ae10_shift">(</string>
+ <string name="key_ae10_alt">۰(ⁿ°0</string>
+
+ <string name="key_ae11_main">-</string>
+ <string name="key_ae11_shift">ـ</string>
+ <string name="key_ae11_alt">-ـ—–</string>
+
+ <string name="key_ae12_main">=</string>
+ <string name="key_ae12_shift">+</string>
+ <string name="key_ae12_alt">=+≈≠±×÷</string>
+
+
+ <string name="key_ad01_main">ض</string>
+ <string name="key_ad01_shift">ْ</string>
+ <string name="key_ad01_alt">ضْ</string>
+
+ <string name="key_ad02_main">ص</string>
+ <string name="key_ad02_shift">ٌ</string>
+ <string name="key_ad02_alt">صٌ</string>
+
+ <string name="key_ad03_main">ث</string>
+ <string name="key_ad03_shift">ٍ</string>
+ <string name="key_ad03_alt">ثٍ€</string>
+
+ <string name="key_ad04_main">ق</string>
+ <string name="key_ad04_shift">ً</string>
+ <string name="key_ad04_alt">قً</string>
+
+ <string name="key_ad05_main">ف</string>
+ <string name="key_ad05_shift">ُ</string>
+ <string name="key_ad05_alt">فُ</string>
+
+ <string name="key_ad06_main">غ</string>
+ <string name="key_ad06_shift">ِ</string>
+ <string name="key_ad06_alt">غِ</string>
+
+ <string name="key_ad07_main">ع</string>
+ <string name="key_ad07_shift">َ</string>
+ <string name="key_ad07_alt">عَ</string>
+
+ <string name="key_ad08_main">ه</string>
+ <string name="key_ad08_shift">ّ</string>
+ <string name="key_ad08_alt">هّ</string>
+
+ <string name="key_ad09_main">خ</string>
+ <string name="key_ad09_shift">]</string>
+ <string name="key_ad09_alt">خ]</string>
+
+ <string name="key_ad10_main">ح</string>
+ <string name="key_ad10_shift">[</string>
+ <string name="key_ad10_alt">ح[</string>
+
+ <string name="key_ad11_main">ج</string>
+ <string name="key_ad11_shift">}</string>
+ <string name="key_ad11_alt">ج}</string>
+
+ <string name="key_ad12_main">چ</string>
+ <string name="key_ad12_shift">{</string>
+ <string name="key_ad12_alt">چ{</string>
+
+ <string name="key_bksl_main">\\</string>
+ <string name="key_bksl_shift">|</string>
+ <string name="key_bksl_alt">\\|</string>
+
+
+ <string name="key_ac01_main">ش</string>
+ <string name="key_ac01_shift">ؤ</string>
+ <string name="key_ac01_alt">شؤ</string>
+
+ <string name="key_ac02_main">س</string>
+ <string name="key_ac02_shift">ئ</string>
+ <string name="key_ac02_alt">سئ</string>
+
+ <string name="key_ac03_main">ی</string>
+ <string name="key_ac03_shift">ي</string>
+ <string name="key_ac03_alt">یي</string>
+
+ <string name="key_ac04_main">ب</string>
+ <string name="key_ac04_shift">إ</string>
+ <string name="key_ac04_alt">بإ</string>
+
+ <string name="key_ac05_main">ل</string>
+ <string name="key_ac05_shift">أ</string>
+ <string name="key_ac05_alt">لأ</string>
+
+ <string name="key_ac06_main">ا</string>
+ <string name="key_ac06_shift">آ</string>
+ <string name="key_ac06_alt">اآﭐ</string>
+
+ <string name="key_ac07_main">ت</string>
+ <string name="key_ac07_shift">ة</string>
+ <string name="key_ac07_alt">تة</string>
+
+ <string name="key_ac08_main">ن</string>
+ <string name="key_ac08_shift">»</string>
+ <string name="key_ac08_alt">ن»</string>
+
+ <string name="key_ac09_main">م</string>
+ <string name="key_ac09_shift">«</string>
+ <string name="key_ac09_alt">م«</string>
+
+ <string name="key_ac10_main">ک</string>
+ <string name="key_ac10_shift">:</string>
+ <string name="key_ac10_alt">ک:;</string>
+
+ <string name="key_ac11_main">گ</string>
+ <string name="key_ac11_shift">؛</string>
+ <string name="key_ac11_alt">گ؛\"</string>
+
+
+ <string name="key_lsgt_main"></string>
+ <string name="key_lsgt_shift"></string>
+ <string name="key_lsgt_alt"></string>
+
+ <string name="key_ab01_main">ظ</string>
+ <string name="key_ab01_shift">ك</string>
+ <string name="key_ab01_alt">ظك</string>
+
+ <string name="key_ab02_main">ط</string>
+ <string name="key_ab02_shift">ٓ</string>
+ <string name="key_ab02_alt">طٓ</string>
+
+ <string name="key_ab03_main">ز</string>
+ <string name="key_ab03_shift">ژ</string>
+ <string name="key_ab03_alt">زژ</string>
+
+ <string name="key_ab04_main">ر</string>
+ <string name="key_ab04_shift">ٰ</string>
+ <string name="key_ab04_alt">رٰ</string>
+
+ <string name="key_ab05_main">ذ</string>
+ <string name="key_ab05_shift">‌</string>
+ <string name="key_ab05_alt"></string>
+
+ <string name="key_ab06_main">د</string>
+ <string name="key_ab06_shift">ٔ</string>
+ <string name="key_ab06_alt">دٔ</string>
+
+ <string name="key_ab07_main">پ</string>
+ <string name="key_ab07_shift">ء</string>
+ <string name="key_ab07_alt">…پء</string>
+
+ <string name="key_ab08_main">و</string>
+ <string name="key_ab08_shift">&gt;</string>
+ <string name="key_ab08_alt">و&gt;,></string>
+
+ <string name="key_ab09_main">.</string>
+ <string name="key_ab09_shift">&lt;</string>
+ <string name="key_ab09_alt">.&lt;</string>
+
+ <string name="key_ab10_main">/</string>
+ <string name="key_ab10_shift">؟</string>
+ <string name="key_ab10_alt">/؟?</string>
+
+ <string name="key_space_shift">&#x200c;</string>
+</resources>
diff --git a/java/res/values-fa/donottranslate.xml b/java/res/values-fa/donottranslate.xml
new file mode 100644
index 0000000..07ae7b0
--- /dev/null
+++ b/java/res/values-fa/donottranslate.xml
@@ -0,0 +1,27 @@
+<?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 commonly considered word separators in this language -->
+ <string name="word_separators">.\u0009\u0020،؛:!؟\n()[]*&amp;@{}/&lt;&gt;_+=|\u0022«»</string>
+ <!-- Symbols that are sentence separators, for purposes of making it hug the last sentence. -->
+ <string name="sentence_separators">.،!؟)؛:</string>
+ <!-- Symbols that are suggested between words -->
+ <string name="suggested_punctuations">!؟،«»:؛()-\u0022/@_</string>
+</resources>
diff --git a/java/res/values-fa/strings.xml b/java/res/values-fa/strings.xml
new file mode 100644
index 0000000..0bfb38b
--- /dev/null
+++ b/java/res/values-fa/strings.xml
@@ -0,0 +1,140 @@
+<?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/org.pocketworkstation.pckeyboard"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- <string name="english_ime_name" msgid="7252517407088836577">"صفحه کلید Android"</string> -->
+ <!-- <string name="english_ime_settings" msgid="6661589557206947774">"تنظیمات صفحه کلید Android"</string> -->
+ <string name="english_ime_input_options" msgid="3909945612939668554">"گزینه های ورودی"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"لرزش با فشار کلید"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"صدا با فشار کلید"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"بازشو با فشار کلید"</string>
+ <string name="hit_correction" msgid="4855351009261318389">"تصحیح خطاهای تایپی"</string>
+ <string name="hit_correction_summary" msgid="8761701873008070796">"فعال کردن تصحیح خطای ورودی"</string>
+ <string name="hit_correction_land" msgid="2567691684825205448">"خطاهای ورود افقی"</string>
+ <string name="hit_correction_land_summary" msgid="4076803842198368328">"فعال کردن تصحیح خطای ورودی"</string>
+ <string name="auto_correction" msgid="7911639788808958255">"پیشنهادات کلمه"</string>
+ <string name="auto_correction_summary" msgid="6881047311475758267">"تصحیح خودکار کلمه قبلی"</string>
+ <string name="prediction" msgid="466220283138359837">"پیشنهادات کلمه"</string>
+ <string name="prediction_category" msgid="7027100625580696660">"تنظیمات پیشنهاد کلمه"</string>
+ <string name="prediction_summary" msgid="459788228830873110">"فعال کردن تکمیل خودکار در حین تایپ"</string>
+ <string name="auto_complete_dialog_title" msgid="2172048590607201920">"تکمیل خودکار"</string>
+ <string name="prediction_landscape" msgid="4874601565593216183">"افزایش اندازه قسمت متنی"</string>
+ <string name="prediction_landscape_summary" msgid="6736551095997839472">"پنهان کردن پیشنهادات کلمه در نمای افقی"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"نوشتن با حروف بزرگ خودکار"</string>
+ <string name="auto_cap_summary" msgid="3260681697600786825">"بزرگ کردن اول هر جمله"</string>
+ <string name="auto_punctuate" msgid="7276672334264521751">"نشان گذاری خودکار"</string>
+ <string name="auto_punctuate_summary" msgid="6589441565817502132"></string>
+ <string name="quick_fixes" msgid="5353213327680897927">"راه حل های سریع"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"تصحیح خطاهای تایپی رایج"</string>
+ <string name="show_suggestions" msgid="507074425254289133">"نمایش پیشنهادات"</string>
+ <string name="show_suggestions_summary" msgid="1989672863935759654">"نمایش واژه های پیشنهادی در حین تایپ"</string>
+ <string name="auto_complete" msgid="1103196318775486023">"تکمیل خودکار"</string>
+ <string name="auto_complete_summary" msgid="6113149638718274624">"کلید خط فاصله و علائم نگارشی به صورت خودکار کلمه برجسته شده را وارد می کنند."</string>
+ <string name="prefs_settings_key" msgid="4623341240804046498">"نمایش کلید تنظیمات"</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"خودکار"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"همیشه نمایش"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"همیشه پنهان"</string>
+ <!-- no translation found for settings_key_modes:0 (8549888726962891527) -->
+ <!-- no translation found for settings_key_modes:1 (881280041213210923) -->
+ <!-- no translation found for settings_key_modes:2 (7317310620171067848) -->
+ <string name="bigram_suggestion" msgid="1323347224043514969">"توضیحات بیگرام"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"برای بهبود پیشنهاد از کلمه قبلی استفاده شود"</string>
+ <string-array name="prediction_modes">
+ <item msgid="4870266572388153286">"هیچکدام"</item>
+ <item msgid="1669461741568287396">"پایه"</item>
+ <item msgid="4894328801530136615">"پیشرفته"</item>
+ </string-array>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : ذخیره شد"</string>
+ <string name="tip_long_press" msgid="6101270866284343344">"برای مشاهده علائم تکیه (ø، ö و موارد دیگر) کلیدی را پایین نگه دارید"</string>
+ <string name="tip_dismiss" msgid="7585579046862204381">"برای بستن صفحه کلید در هر نقطه که بخواهید، کلید برگشت ↶ را فشار دهید"</string>
+ <string name="tip_access_symbols" msgid="6344098517525531652">"دسترسی به اعداد و نمادها"</string>
+ <string name="tip_add_to_dictionary" msgid="1487293888469227817">"انتهای سمت چپ واژه را برای افزودن آن به فرهنگ لغت فشار داده و نگه دارید"</string>
+ <string name="touch_to_continue" msgid="7869803257948414531">"این نکته را برای ادامه لمس کنید »"</string>
+ <string name="touch_to_finish" msgid="7990196086480585789">"برای بستن این نکته و شروع تایپ، اینجا را لمس کنید!"</string>
+ <string name="tip_to_open_keyboard" msgid="6821200275486950452"><b>"هر زمان که قسمت متنی را لمس می کنید، صفحه کلید باز می شود"</b></string>
+ <string name="tip_to_view_accents" msgid="5433158573693308501"><b>"یک کلید را برای مشاهده تکیه های صدا لمس کرده و نگه دارید (ø، ö، ô، ó و موارد دیگر)"\n</b></string>
+ <string name="tip_to_open_symbols" msgid="7345139325622444880"><b>"تغییر شماره ها و نمادها با لمس این کلید"</b></string>
+ <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"با لمس مجدد این کلید، به حروف برگردید"</b></string>
+ <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"این کلید را برای تغییر تنظیمات صفحه کلید مانند تکمیل خودکار لمس کرده و فشار دهید"</b></string>
+ <string name="tip_to_start_typing" msgid="7213843601369174313"><b>"امتحان کنید!"</b></string>
+ <string name="label_go_key" msgid="1635148082137219148">"برو"</string>
+ <string name="label_next_key" msgid="362972844525672568">"بعدی"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"انجام شد"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"ارسال"</string>
+ <string name="label_symbol_key" msgid="6175820506864489453">"?123"</string>
+ <string name="label_phone_key" msgid="4275497665515080551">"123"</string>
+ <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string>
+ <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string>
+ <string name="voice_warning_title" msgid="4419354150908395008">"ورودی صوتی"</string>
+ <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"ورودی صوتی در حال حاضر برای زبان شما پشتیبانی نمی شود اما برای زبان انگلیسی فعال است."</string>
+ <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"ورودی صوتی یک ویژگی آزمایشی با استفاده از تشخیص گفتار شبکه Google است."</string>
+ <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"برای خاموش کردن ورودی صدا، به تنظیمات صفحه کلید بروید."</string>
+ <string name="voice_hint_dialog_message" msgid="6892342981545727994">"برای استفاده از ورودی صوتی، دکمه میکروفن را فشار دهید یا انگشت خود را روی صفحه کلید روی صفحه حرکت دهید."</string>
+ <string name="voice_listening" msgid="467518160751321844">"اکنون صحبت کنید"</string>
+ <string name="voice_working" msgid="6666937792815731889">"در حال کار"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"خطا: لطفاً دوباره امتحان کنید."</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"متصل نشد"</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"خطا، گفتار بسیار زیاد است."</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"مشکل صوتی"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"خطای سرور"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"گفتاری شنیده نشد"</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"مورد منطبقی یافت نشد"</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"جستجوی صوتی نصب نشده است"</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"نکته: "</b>" برای صحبت روی صفحه کلید ضربه بزنید"</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"نکته: دفعه دیگر، از نشانه گذاری های گفتاری مانند \"نقطه\"، \"کاما\" یا \"علامت سؤال\" استفاده کنید."</b></string>
+ <string name="cancel" msgid="6830980399865683324">"لغو"</string>
+ <string name="ok" msgid="7898366843681727667">"تأیید"</string>
+ <string name="voice_input" msgid="2466640768843347841">"ورودی صوتی"</string>
+ <string-array name="voice_input_modes">
+ <item msgid="1349082139076086774">"در صفحه کلید اصلی"</item>
+ <item msgid="8529385602829095903">"در صفحه کلید نمادها"</item>
+ <item msgid="7283103513488381103">"خاموش"</item>
+ </string-array>
+ <string-array name="voice_input_modes_summary">
+ <item msgid="554248625705084903">"میکروفن در صفحه کلید اصلی"</item>
+ <item msgid="6907837061058876770">"میکروفن در صفحه کلید نمادها"</item>
+ <item msgid="3664304608587798036">"ورودی صوتی غیر فعال شده است"</item>
+ </string-array>
+ <string name="auto_submit" msgid="9151008027068358518">"ارائه خودکار بعد از صدا"</string>
+ <string name="auto_submit_summary" msgid="4961875269610384226">"هنگام جستجو یا رفتن به قسمت بعدی، Enter را به صورت خودکار فشار دهید."</string>
+ <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"صفحه کلید را باز کنید"\n</b></font><font size="3">\n</font>"هر قسمت متنی را لمس کنید."</string>
+ <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"بستن صفحه کلید"\n</b></font><font size="3">\n</font>"کلید برگشت را فشار دهید."</string>
+ <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"یک کلید را برای گزینه های"\n</b></font><font size="3">\n</font>" دسترسی به علائم نگارشی و تکیه های صدا لمس کرده و نگه دارید."</string>
+ <string name="keyboard_settings" msgid="4585753477617374032"><font size="17"><b>"تنظیمات صفحه کلید"\n</b></font><font size="3">\n</font>"کلید "<b>"?123"</b>" را لمس کرده و نگهدارید."</string>
+ <string name="popular_domain_0" msgid="3745279225122472969">".com"</string>
+ <string name="popular_domain_1" msgid="1370572248164278467">".net"</string>
+ <string name="popular_domain_2" msgid="3036812463748402878">".org"</string>
+ <string name="popular_domain_3" msgid="8718639560809452028">".gov"</string>
+ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"انتخاب روش ورودی"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"زبان های ورودی"</string>
+ <string name="language_selection_summary" msgid="187110938289512256">"برای تغییر زبان انگشت را روی کلید فاصله بلغزانید"</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← جهت ذخیره دوباره لمس کنید"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"دیکشنری موجود است"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"فعال کردن بازخورد کاربر"</string>
+ <string name="prefs_description_log" msgid="5827825607258246003">"با ارسال خودکار آمارهای کاربرد و گزارش های خرابی به Google، به بهبود این ویرایشگر روش ورودی کمک کنید."</string>
+ <string name="prefs_enable_recorrection" msgid="4588408906649533582">"برای تصحیح کلمات لمس کنید"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="1056068922330206170">"برای تصحیح کلمات وارد شده آنها را لمس کنید"</string>
+ <string name="keyboard_layout" msgid="437433231038683666">"طرح زمینه صفحه کلید"</string>
+ <string name="subtype_mode_keyboard" msgid="2242090416595003881">"صفحه کلید"</string>
+ <string name="subtype_mode_voice" msgid="4394113125441627771">"صوتی"</string>
+</resources>
diff --git a/java/res/values-fi/donottranslate-altchars.xml b/java/res/values-fi/donottranslate-altchars.xml
new file mode 100644
index 0000000..b7da61e
--- /dev/null
+++ b/java/res/values-fi/donottranslate-altchars.xml
@@ -0,0 +1,47 @@
+<?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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="alternates_for_a">æåáàâãäā</string>
+ <string name="alternates_for_b"></string>
+ <string name="alternates_for_c">çčć¢</string>
+ <string name="alternates_for_d">ð</string>
+ <string name="alternates_for_e">3€əéèêëē</string>
+ <string name="alternates_for_f">₣</string>
+ <string name="alternates_for_g"></string>
+ <string name="alternates_for_h"></string>
+ <string name="alternates_for_i">8ıíìîïī</string>
+ <string name="alternates_for_j"></string>
+ <string name="alternates_for_k">ĸ</string>
+ <string name="alternates_for_l">¬£₤λ</string>
+ <string name="alternates_for_m">μ</string>
+ <string name="alternates_for_n">ŋñ</string>
+ <string name="alternates_for_o">9œóòôõöō</string>
+ <string name="alternates_for_p">0π₱</string>
+ <string name="alternates_for_q">1</string>
+ <string name="alternates_for_r">4</string>
+ <string name="alternates_for_s">§ßš</string>
+ <string name="alternates_for_t">5þ</string>
+ <string name="alternates_for_u">7úùûüū</string>
+ <string name="alternates_for_v"></string>
+ <string name="alternates_for_w">2</string>
+ <string name="alternates_for_x"></string>
+ <string name="alternates_for_y">6ýÿ¥</string>
+ <string name="alternates_for_z">ʒž</string>
+</resources>
diff --git a/java/res/values-fi/donottranslate-keymap.xml b/java/res/values-fi/donottranslate-keymap.xml
new file mode 100644
index 0000000..7d8ba35
--- /dev/null
+++ b/java/res/values-fi/donottranslate-keymap.xml
@@ -0,0 +1,223 @@
+<?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.
+**
+**
+** 5-row layout for English QWERTY.
+**
+** See http://code.google.com/p/hackerskeyboard/wiki/AddingNewLayouts
+for
+** more information.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="key_tlde_main">§</string>
+ <string name="key_tlde_shift">½</string>
+ <string name="key_tlde_alt">§½¼¾</string>
+
+ <string name="key_ae01_main">1</string>
+ <string name="key_ae01_shift">!</string>
+ <string name="key_ae01_alt">1!¡¹½⅓¼⅛</string>
+
+ <string name="key_ae02_main">2</string>
+ <string name="key_ae02_shift">\"</string>
+ <string name="key_ae02_alt">2\"\@²⅔</string>
+
+ <string name="key_ae03_main">3</string>
+ <string name="key_ae03_shift">#</string>
+ <string name="key_ae03_alt">3#£»³¾⅜†‡</string>
+
+ <string name="key_ae04_main">4</string>
+ <string name="key_ae04_shift">$</string>
+ <string name="key_ae04_alt">4$«⁴¢¥</string>
+
+ <string name="key_ae05_main">5</string>
+ <string name="key_ae05_shift">%</string>
+ <string name="key_ae05_alt">5%€‰⅝</string>
+
+ <string name="key_ae06_main">6</string>
+ <string name="key_ae06_shift">&amp;</string>
+ <string name="key_ae06_alt">6&amp;</string>
+
+ <string name="key_ae07_main">7</string>
+ <string name="key_ae07_shift">/</string>
+ <string name="key_ae07_alt">7/{⅞√♪</string>
+
+ <string name="key_ae08_main">8</string>
+ <string name="key_ae08_shift">(</string>
+ <string name="key_ae08_alt">8([∞</string>
+
+ <string name="key_ae09_main">9</string>
+ <string name="key_ae09_shift">)</string>
+ <string name="key_ae09_alt">9)]♥♠♦♣</string>
+
+ <string name="key_ae10_main">0</string>
+ <string name="key_ae10_shift">=</string>
+ <string name="key_ae10_alt">0=}°≠≈ⁿ</string>
+
+ <string name="key_ae11_main">\?</string>
+ <string name="key_ae11_shift">+</string>
+ <string name="key_ae11_alt">\?+\\¿+±×÷</string>
+
+ <string name="key_ae12_main">\'</string>
+ <string name="key_ae12_shift">`</string>
+ <string name="key_ae12_alt">\'`</string>
+
+
+ <string name="key_ad01_main">q</string>
+ <string name="key_ad01_shift">Q</string>
+ <string name="key_ad01_alt">@string/alternates_for_q</string>
+
+ <string name="key_ad02_main">w</string>
+ <string name="key_ad02_shift">W</string>
+ <string name="key_ad02_alt">@string/alternates_for_w</string>
+
+ <string name="key_ad03_main">e</string>
+ <string name="key_ad03_shift">E</string>
+ <string name="key_ad03_alt">@string/alternates_for_e</string>
+
+ <string name="key_ad04_main">r</string>
+ <string name="key_ad04_shift">R</string>
+ <string name="key_ad04_alt">@string/alternates_for_r</string>
+
+ <string name="key_ad05_main">t</string>
+ <string name="key_ad05_shift">T</string>
+ <string name="key_ad05_alt">@string/alternates_for_t</string>
+
+ <string name="key_ad06_main">y</string>
+ <string name="key_ad06_shift">Y</string>
+ <string name="key_ad06_alt">@string/alternates_for_y</string>
+
+ <string name="key_ad07_main">u</string>
+ <string name="key_ad07_shift">U</string>
+ <string name="key_ad07_alt">@string/alternates_for_u</string>
+
+ <string name="key_ad08_main">i</string>
+ <string name="key_ad08_shift">I</string>
+ <string name="key_ad08_alt">@string/alternates_for_i</string>
+
+ <string name="key_ad09_main">o</string>
+ <string name="key_ad09_shift">O</string>
+ <string name="key_ad09_alt">@string/alternates_for_o</string>
+
+ <string name="key_ad10_main">p</string>
+ <string name="key_ad10_shift">P</string>
+ <string name="key_ad10_alt">@string/alternates_for_p</string>
+
+ <string name="key_ad11_main">å</string>
+ <string name="key_ad11_shift">Å</string>
+ <string name="key_ad11_alt">@string/alternates_for_a</string>
+
+ <string name="key_ad12_main">~</string>
+ <string name="key_ad12_shift">^</string>
+ <string name="key_ad12_alt">~^ˇ↑↓←→</string>
+
+ <string name="key_bksl_main">\'</string>
+ <string name="key_bksl_shift">*</string>
+ <string name="key_bksl_alt">\'*•★</string>
+
+
+ <string name="key_ac01_main">a</string>
+ <string name="key_ac01_shift">A</string>
+ <string name="key_ac01_alt">@string/alternates_for_a</string>
+
+ <string name="key_ac02_main">s</string>
+ <string name="key_ac02_shift">S</string>
+ <string name="key_ac02_alt">@string/alternates_for_s</string>
+
+ <string name="key_ac03_main">d</string>
+ <string name="key_ac03_shift">D</string>
+ <string name="key_ac03_alt">@string/alternates_for_d</string>
+
+ <string name="key_ac04_main">f</string>
+ <string name="key_ac04_shift">F</string>
+ <string name="key_ac04_alt">@string/alternates_for_f</string>
+
+ <string name="key_ac05_main">g</string>
+ <string name="key_ac05_shift">G</string>
+ <string name="key_ac05_alt">@string/alternates_for_g</string>
+
+ <string name="key_ac06_main">h</string>
+ <string name="key_ac06_shift">H</string>
+ <string name="key_ac06_alt">@string/alternates_for_h</string>
+
+ <string name="key_ac07_main">j</string>
+ <string name="key_ac07_shift">J</string>
+ <string name="key_ac07_alt">@string/alternates_for_j</string>
+
+ <string name="key_ac08_main">k</string>
+ <string name="key_ac08_shift">K</string>
+ <string name="key_ac08_alt">@string/alternates_for_k</string>
+
+ <string name="key_ac09_main">l</string>
+ <string name="key_ac09_shift">L</string>
+ <string name="key_ac09_alt">@string/alternates_for_l</string>
+
+ <string name="key_ac10_main">ö</string>
+ <string name="key_ac10_shift">Ö</string>
+ <string name="key_ac10_alt">@string/alternates_for_o</string>
+
+ <string name="key_ac11_main">ä</string>
+ <string name="key_ac11_shift">Ä</string>
+ <string name="key_ac11_alt">@string/alternates_for_a</string>
+
+
+ <string name="key_lsgt_main">&lt;</string>
+ <string name="key_lsgt_shift">&gt;</string>
+ <string name="key_lsgt_alt">&lt;&gt;|≤≥‹›</string>
+
+ <string name="key_ab01_main">z</string>
+ <string name="key_ab01_shift">Z</string>
+ <string name="key_ab01_alt">@string/alternates_for_z</string>
+
+ <string name="key_ab02_main">x</string>
+ <string name="key_ab02_shift">X</string>
+ <string name="key_ab02_alt">@string/alternates_for_x</string>
+
+ <string name="key_ab03_main">c</string>
+ <string name="key_ab03_shift">C</string>
+ <string name="key_ab03_alt">@string/alternates_for_c</string>
+
+ <string name="key_ab04_main">v</string>
+ <string name="key_ab04_shift">V</string>
+ <string name="key_ab04_alt">@string/alternates_for_v</string>
+
+ <string name="key_ab05_main">b</string>
+ <string name="key_ab05_shift">B</string>
+ <string name="key_ab05_alt">@string/alternates_for_b</string>
+
+ <string name="key_ab06_main">n</string>
+ <string name="key_ab06_shift">N</string>
+ <string name="key_ab06_alt">@string/alternates_for_n</string>
+
+ <string name="key_ab07_main">m</string>
+ <string name="key_ab07_shift">M</string>
+ <string name="key_ab07_alt">@string/alternates_for_m</string>
+
+ <string name="key_ab08_main">,</string>
+ <string name="key_ab08_shift">;</string>
+ <string name="key_ab08_alt">;,</string>
+
+ <string name="key_ab09_main">.</string>
+ <string name="key_ab09_shift">:</string>
+ <string name="key_ab09_alt">:.…</string>
+
+ <string name="key_ab10_main">-</string>
+ <string name="key_ab10_shift">_</string>
+ <string name="key_ab10_alt">-_—–</string>
+</resources>
diff --git a/java/res/values-fi/strings.xml b/java/res/values-fi/strings.xml
new file mode 100644
index 0000000..e424e16
--- /dev/null
+++ b/java/res/values-fi/strings.xml
@@ -0,0 +1,140 @@
+<?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/org.pocketworkstation.pckeyboard"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- <string name="english_ime_name" msgid="7252517407088836577">"Android-näppäimistö"</string> -->
+ <!-- <string name="english_ime_settings" msgid="6661589557206947774">"Android-näppäimistön asetukset"</string> -->
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Syöttövalinnat"</string>
+ <string name="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="hit_correction" msgid="4855351009261318389">"Korjaa kirjoitusvirheet"</string>
+ <string name="hit_correction_summary" msgid="8761701873008070796">"Ota syöttövirheen korjaus käyttöön"</string>
+ <string name="hit_correction_land" msgid="2567691684825205448">"Vaakasuunnan syöttövirheet"</string>
+ <string name="hit_correction_land_summary" msgid="4076803842198368328">"Ota syöttövirheen korjaus käyttöön"</string>
+ <string name="auto_correction" msgid="7911639788808958255">"Sanaehdotukset"</string>
+ <string name="auto_correction_summary" msgid="6881047311475758267">"Korjaa edellinen sana automaattisesti"</string>
+ <string name="prediction" msgid="466220283138359837">"Sanaehdotukset"</string>
+ <string name="prediction_category" msgid="7027100625580696660">"Sanaehdotusasetukset"</string>
+ <string name="prediction_summary" msgid="459788228830873110">"Ota automaattinen täydennys käyttöön kirjoitettaessa"</string>
+ <string name="auto_complete_dialog_title" msgid="2172048590607201920">"Automaattinen täydennys"</string>
+ <string name="prediction_landscape" msgid="4874601565593216183">"Suurenna tekstikenttää"</string>
+ <string name="prediction_landscape_summary" msgid="6736551095997839472">"Piilota sanaehdotukset vaakasuuntaisessa näkymässä"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"Automaattiset isot kirjaimet"</string>
+ <string name="auto_cap_summary" msgid="3260681697600786825">"Aloittaa lauseet isolla kirjaimella"</string>
+ <string name="auto_punctuate" msgid="7276672334264521751">"Automaattiset välimerkit"</string>
+ <string name="auto_punctuate_summary" msgid="6589441565817502132"></string>
+ <string name="quick_fixes" msgid="5353213327680897927">"Pikakorjaukset"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"Korjaa yleiset kirjoitusvirheet"</string>
+ <string name="show_suggestions" msgid="507074425254289133">"Näytä ehdotukset"</string>
+ <string name="show_suggestions_summary" msgid="1989672863935759654">"Näytä sanaehdotukset kirjoitettaessa"</string>
+ <string name="auto_complete" msgid="1103196318775486023">"Automaattinen täydennys"</string>
+ <string name="auto_complete_summary" msgid="6113149638718274624">"Välilyönti ja välimerkki lisäävät automaattisesti korostetun sanan"</string>
+ <string name="prefs_settings_key" msgid="4623341240804046498">"Näytä asetukset-näppäin"</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automaattinen"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Näytä aina"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"Piilota aina"</string>
+ <!-- no translation found for settings_key_modes:0 (8549888726962891527) -->
+ <!-- no translation found for settings_key_modes:1 (881280041213210923) -->
+ <!-- no translation found for settings_key_modes:2 (7317310620171067848) -->
+ <string name="bigram_suggestion" msgid="1323347224043514969">"Bigram-ehdotukset"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Paranna ehdotusta aiemman sanan avulla"</string>
+ <string-array name="prediction_modes">
+ <item msgid="4870266572388153286">"Ei mitään"</item>
+ <item msgid="1669461741568287396">"Tavallinen"</item>
+ <item msgid="4894328801530136615">"Edistynyt"</item>
+ </string-array>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Tallennettu"</string>
+ <string name="tip_long_press" msgid="6101270866284343344">"Näet aksenttimerkit (ø, ö jne.) pitämällä näppäintä painettuna."</string>
+ <string name="tip_dismiss" msgid="7585579046862204381">"Voit sulkea näppäimistön milloin tahansa painamalla Takaisin-painiketta ↶"</string>
+ <string name="tip_access_symbols" msgid="6344098517525531652">"Käytä numeroita ja symboleita"</string>
+ <string name="tip_add_to_dictionary" msgid="1487293888469227817">"Lisää vasemmanpuoleinen sana sanakirjaan pitämällä sitä painettuna"</string>
+ <string name="touch_to_continue" msgid="7869803257948414531">"Jatka koskettamalla tätä vihjettä »"</string>
+ <string name="touch_to_finish" msgid="7990196086480585789">"Sulje tämä vihje ja aloita kirjoittaa koskettamalla tätä!"</string>
+ <string name="tip_to_open_keyboard" msgid="6821200275486950452"><b>"Näppäimistö avautuu, kun kosketat tekstikenttää"</b></string>
+ <string name="tip_to_view_accents" msgid="5433158573693308501"><b>"Näytä aksenttimerkit pitämällä näppäintä painettuna"\n"(ø, ö, ô, ó ja niin edelleen"</b></string>
+ <string name="tip_to_open_symbols" msgid="7345139325622444880"><b>"Vaihda numeroihin ja symboleihin koskettamalla tätä näppäintä"</b></string>
+ <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"Siirry takaisin kirjaimiin koskettamalla tätä näppäintä uudelleen"</b></string>
+ <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"Muuta näppäimistön asetuksia, kuten automaattista täydentämistä, pitämällä tätä näppäintä painettuna"</b></string>
+ <string name="tip_to_start_typing" msgid="7213843601369174313"><b>"Kokeile!"</b></string>
+ <string name="label_go_key" msgid="1635148082137219148">"Siirry"</string>
+ <string name="label_next_key" msgid="362972844525672568">"Seuraava"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"Valmis"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"Lähetä"</string>
+ <string name="label_symbol_key" msgid="6175820506864489453">"?123"</string>
+ <string name="label_phone_key" msgid="4275497665515080551">"123"</string>
+ <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string>
+ <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string>
+ <string name="voice_warning_title" msgid="4419354150908395008">"Äänisyöte"</string>
+ <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Äänisyötettä ei vielä tueta kielelläsi, mutta voit käyttää sitä englanniksi."</string>
+ <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"Äänisyöte on kokeellinen Googlen puheentunnistusta käyttävä ominaisuus."</string>
+ <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"Siirry näppäimistön asetuksiin poistaaksesi äänisyötteen käytöstä."</string>
+ <string name="voice_hint_dialog_message" msgid="6892342981545727994">"Käytä äänisyötettä painamalla mikrofonipainiketta tai liu\'uttamalla sormeasi näytön näppäimistön poikki."</string>
+ <string name="voice_listening" msgid="467518160751321844">"Puhu nyt"</string>
+ <string name="voice_working" msgid="6666937792815731889">"Työstetään"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"Virhe. Yritä uudelleen."</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"Ei yhteyttä"</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"Virhe, liikaa puhetta."</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"Ääniongelma"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"Palvelinvirhe"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"Puhetta ei kuulu"</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"Ei vastineita"</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"Äänihakua ei asennettu"</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Vihje:"</b>" liu\'uta sormea näppäimistöllä ja puhu"</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Vihje:"</b>" kokeile seuraavalla kerralla puhua välimerkit, kuten \"period\" (piste), \"comma\" (pilkku) tai \"question mark\" (kysymysmerkki)."</string>
+ <string name="cancel" msgid="6830980399865683324">"Peruuta"</string>
+ <string name="ok" msgid="7898366843681727667">"OK"</string>
+ <string name="voice_input" msgid="2466640768843347841">"Äänisyöte"</string>
+ <string-array name="voice_input_modes">
+ <item msgid="1349082139076086774">"Päänäppäimistössä"</item>
+ <item msgid="8529385602829095903">"Symbolinäppäimistössä"</item>
+ <item msgid="7283103513488381103">"Pois käytöstä"</item>
+ </string-array>
+ <string-array name="voice_input_modes_summary">
+ <item msgid="554248625705084903">"Päänäppäimistön mikrofoni"</item>
+ <item msgid="6907837061058876770">"Symbolinäppäimistön mikrofoni"</item>
+ <item msgid="3664304608587798036">"Äänisyöte ei ole käytössä"</item>
+ </string-array>
+ <string name="auto_submit" msgid="9151008027068358518">"Lähetä automaattisesti puheen jälkeen"</string>
+ <string name="auto_submit_summary" msgid="4961875269610384226">"Paina automaattisesti enter-näppäintä tehdessäsi hakuja tai siirtyessäsi seuraavaan kenttään."</string>
+ <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Avaa näppäimistö"\n</b></font><font size="3">\n</font>"Kosketa tekstikenttää."</string>
+ <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Sulje näppäimistö"\n</b></font><font size="3">\n</font>"Paina Takaisin-näppäintä."</string>
+ <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Näet asetukset pitämällä näppäintä painettuna"\n</b></font><font size="3">\n</font>"Käytä välimerkkejä ja aksenttimerkkejä."</string>
+ <string name="keyboard_settings" msgid="4585753477617374032"><font size="17"><b>"Näppäimistön asetukset"\n</b></font><font size="3">\n</font>"Pidä painettuna"<b>"?123"</b>"-näppäintä."</string>
+ <string name="popular_domain_0" msgid="3745279225122472969">".com"</string>
+ <string name="popular_domain_1" msgid="1370572248164278467">".net"</string>
+ <string name="popular_domain_2" msgid="3036812463748402878">".org"</string>
+ <string name="popular_domain_3" msgid="8718639560809452028">".gov"</string>
+ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"Valitse syöttötapa"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Syöttökielet"</string>
+ <string name="language_selection_summary" msgid="187110938289512256">"Vaihda kieltä liu\'uttamalla sormea välilyöntinäppäimellä"</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Tallenna koskettamalla uudelleen"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"Sanakirja saatavilla"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"Ota käyttäjäpalaute käyttöön"</string>
+ <string name="prefs_description_log" msgid="5827825607258246003">"Auta parantamaan tätä syöttötavan muokkausohjelmaa lähettämällä automaattisesti käyttötietoja ja kaatumisraportteja Googlelle."</string>
+ <string name="prefs_enable_recorrection" msgid="4588408906649533582">"Korjaa sanoja koskettamalla"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="1056068922330206170">"Korjaa sanoja koskettamalla niitä"</string>
+ <string name="keyboard_layout" msgid="437433231038683666">"Näppäimistön teema"</string>
+ <string name="subtype_mode_keyboard" msgid="2242090416595003881">"näppäimistö"</string>
+ <string name="subtype_mode_voice" msgid="4394113125441627771">"ääni"</string>
+</resources>
diff --git a/java/res/values-fr-rCA/donottranslate-altchars.xml b/java/res/values-fr-rCA/donottranslate-altchars.xml
new file mode 100644
index 0000000..b1a7f4e
--- /dev/null
+++ b/java/res/values-fr-rCA/donottranslate-altchars.xml
@@ -0,0 +1,33 @@
+<?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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="alternates_for_a">àáâãäåæ</string>
+ <string name="alternates_for_e">3èéêë</string>
+ <string name="alternates_for_i">8ïîíì</string>
+ <string name="alternates_for_o">9øœöõôóò</string>
+ <string name="alternates_for_u">7üûúù</string>
+ <string name="alternates_for_s">§ß</string>
+ <string name="alternates_for_n">ñ</string>
+ <string name="alternates_for_c">ç</string>
+ <string name="alternates_for_y">6ÿý</string>
+ <string name="alternates_for_q">1</string>
+ <string name="alternates_for_w">2</string>
+ <string name="alternates_for_z"></string>
+</resources>
diff --git a/java/res/values-fr-rCA/donottranslate-keymap.xml b/java/res/values-fr-rCA/donottranslate-keymap.xml
new file mode 100644
index 0000000..71cac3b
--- /dev/null
+++ b/java/res/values-fr-rCA/donottranslate-keymap.xml
@@ -0,0 +1,221 @@
+<?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.
+**
+**
+** 5-row layout for English QWERTY.
+**
+** See http://code.google.com/p/hackerskeyboard/wiki/AddingNewLayouts for
+** more information.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="key_tlde_main">`</string>
+ <string name="key_tlde_shift">~</string>
+ <string name="key_tlde_alt">`~</string>
+
+ <string name="key_ae01_main">1</string>
+ <string name="key_ae01_shift">!</string>
+ <string name="key_ae01_alt">1!¡¹½⅓¼⅛</string>
+
+ <string name="key_ae02_main">2</string>
+ <string name="key_ae02_shift">\@</string>
+ <string name="key_ae02_alt">2\@²⅔</string>
+
+ <string name="key_ae03_main">3</string>
+ <string name="key_ae03_shift">#</string>
+ <string name="key_ae03_alt">3#³¾⅜♥♠♦♣</string>
+
+ <string name="key_ae04_main">4</string>
+ <string name="key_ae04_shift">$</string>
+ <string name="key_ae04_alt">4$⁴¢£€¥</string>
+
+ <string name="key_ae05_main">5</string>
+ <string name="key_ae05_shift">%</string>
+ <string name="key_ae05_alt">5%⅝‰</string>
+
+ <string name="key_ae06_main">6</string>
+ <string name="key_ae06_shift">^</string>
+ <string name="key_ae06_alt">6^↑↓←→</string>
+
+ <string name="key_ae07_main">7</string>
+ <string name="key_ae07_shift">&amp;</string>
+ <string name="key_ae07_alt">7&amp;⅞♪</string>
+
+ <string name="key_ae08_main">8</string>
+ <string name="key_ae08_shift">*</string>
+ <string name="key_ae08_alt">8*•★∞†‡</string>
+
+ <string name="key_ae09_main">9</string>
+ <string name="key_ae09_shift">(</string>
+ <string name="key_ae09_alt">9(√</string>
+
+ <string name="key_ae10_main">0</string>
+ <string name="key_ae10_shift">)</string>
+ <string name="key_ae10_alt">0)ⁿ°</string>
+
+ <string name="key_ae11_main">-</string>
+ <string name="key_ae11_shift">_</string>
+ <string name="key_ae11_alt">-_—–</string>
+
+ <string name="key_ae12_main">=</string>
+ <string name="key_ae12_shift">+</string>
+ <string name="key_ae12_alt">=+≈≠±×÷</string>
+
+
+ <string name="key_ad01_main">q</string>
+ <string name="key_ad01_shift">Q</string>
+ <string name="key_ad01_alt">@string/alternates_for_q</string>
+
+ <string name="key_ad02_main">w</string>
+ <string name="key_ad02_shift">W</string>
+ <string name="key_ad02_alt">@string/alternates_for_w</string>
+
+ <string name="key_ad03_main">e</string>
+ <string name="key_ad03_shift">E</string>
+ <string name="key_ad03_alt">@string/alternates_for_e</string>
+
+ <string name="key_ad04_main">r</string>
+ <string name="key_ad04_shift">R</string>
+ <string name="key_ad04_alt">@string/alternates_for_r</string>
+
+ <string name="key_ad05_main">t</string>
+ <string name="key_ad05_shift">T</string>
+ <string name="key_ad05_alt">@string/alternates_for_t</string>
+
+ <string name="key_ad06_main">y</string>
+ <string name="key_ad06_shift">Y</string>
+ <string name="key_ad06_alt">@string/alternates_for_y</string>
+
+ <string name="key_ad07_main">u</string>
+ <string name="key_ad07_shift">U</string>
+ <string name="key_ad07_alt">@string/alternates_for_u</string>
+
+ <string name="key_ad08_main">i</string>
+ <string name="key_ad08_shift">I</string>
+ <string name="key_ad08_alt">@string/alternates_for_i</string>
+
+ <string name="key_ad09_main">o</string>
+ <string name="key_ad09_shift">O</string>
+ <string name="key_ad09_alt">@string/alternates_for_o</string>
+
+ <string name="key_ad10_main">p</string>
+ <string name="key_ad10_shift">P</string>
+ <string name="key_ad10_alt">@string/alternates_for_p</string>
+
+ <string name="key_ad11_main">[</string>
+ <string name="key_ad11_shift">{</string>
+ <string name="key_ad11_alt">[{</string>
+
+ <string name="key_ad12_main">]</string>
+ <string name="key_ad12_shift">}</string>
+ <string name="key_ad12_alt">]}</string>
+
+ <string name="key_bksl_main">\\</string>
+ <string name="key_bksl_shift">|</string>
+ <string name="key_bksl_alt">\\|</string>
+
+
+ <string name="key_ac01_main">a</string>
+ <string name="key_ac01_shift">A</string>
+ <string name="key_ac01_alt">@string/alternates_for_a</string>
+
+ <string name="key_ac02_main">s</string>
+ <string name="key_ac02_shift">S</string>
+ <string name="key_ac02_alt">@string/alternates_for_s</string>
+
+ <string name="key_ac03_main">d</string>
+ <string name="key_ac03_shift">D</string>
+ <string name="key_ac03_alt">@string/alternates_for_d</string>
+
+ <string name="key_ac04_main">f</string>
+ <string name="key_ac04_shift">F</string>
+ <string name="key_ac04_alt">@string/alternates_for_f</string>
+
+ <string name="key_ac05_main">g</string>
+ <string name="key_ac05_shift">G</string>
+ <string name="key_ac05_alt">@string/alternates_for_g</string>
+
+ <string name="key_ac06_main">h</string>
+ <string name="key_ac06_shift">H</string>
+ <string name="key_ac06_alt">@string/alternates_for_h</string>
+
+ <string name="key_ac07_main">j</string>
+ <string name="key_ac07_shift">J</string>
+ <string name="key_ac07_alt">@string/alternates_for_j</string>
+
+ <string name="key_ac08_main">k</string>
+ <string name="key_ac08_shift">K</string>
+ <string name="key_ac08_alt">@string/alternates_for_k</string>
+
+ <string name="key_ac09_main">l</string>
+ <string name="key_ac09_shift">L</string>
+ <string name="key_ac09_alt">@string/alternates_for_l</string>
+
+ <string name="key_ac10_main">;</string>
+ <string name="key_ac10_shift">:</string>
+ <string name="key_ac10_alt">;:</string>
+
+ <string name="key_ac11_main">\'</string>
+ <string name="key_ac11_shift">\"</string>
+ <string name="key_ac11_alt">\'\"‘’“”</string>
+
+
+ <string name="key_lsgt_main"></string>
+ <string name="key_lsgt_shift"></string>
+ <string name="key_lsgt_alt"></string>
+
+ <string name="key_ab01_main">z</string>
+ <string name="key_ab01_shift">Z</string>
+ <string name="key_ab01_alt">@string/alternates_for_z</string>
+
+ <string name="key_ab02_main">x</string>
+ <string name="key_ab02_shift">X</string>
+ <string name="key_ab02_alt">@string/alternates_for_x</string>
+
+ <string name="key_ab03_main">c</string>
+ <string name="key_ab03_shift">C</string>
+ <string name="key_ab03_alt">@string/alternates_for_c</string>
+
+ <string name="key_ab04_main">v</string>
+ <string name="key_ab04_shift">V</string>
+ <string name="key_ab04_alt">@string/alternates_for_v</string>
+
+ <string name="key_ab05_main">b</string>
+ <string name="key_ab05_shift">B</string>
+ <string name="key_ab05_alt">@string/alternates_for_b</string>
+
+ <string name="key_ab06_main">n</string>
+ <string name="key_ab06_shift">N</string>
+ <string name="key_ab06_alt">@string/alternates_for_n</string>
+
+ <string name="key_ab07_main">m</string>
+ <string name="key_ab07_shift">M</string>
+ <string name="key_ab07_alt">@string/alternates_for_m</string>
+
+ <string name="key_ab08_main">,</string>
+ <string name="key_ab08_shift">&lt;</string>
+ <string name="key_ab08_alt">,&lt;≤«‹</string>
+
+ <string name="key_ab09_main">.</string>
+ <string name="key_ab09_shift">&gt;</string>
+ <string name="key_ab09_alt">&gt;≥»›…</string>
+
+ <string name="key_ab10_main">/</string>
+ <string name="key_ab10_shift">\?</string>
+ <string name="key_ab10_alt">/\?¿</string>
+</resources>
diff --git a/java/res/values-fr-rCA/strings.xml b/java/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..02d3205
--- /dev/null
+++ b/java/res/values-fr-rCA/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- <string name="english_ime_name" msgid="7252517407088836577">"Clavier Android"</string> -->
+</resources>
diff --git a/java/res/values-fr/donottranslate-altchars.xml b/java/res/values-fr/donottranslate-altchars.xml
new file mode 100644
index 0000000..b3c21c6
--- /dev/null
+++ b/java/res/values-fr/donottranslate-altchars.xml
@@ -0,0 +1,33 @@
+<?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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="alternates_for_a">1àáâãäåæ</string>
+ <string name="alternates_for_e">3èéêë€</string>
+ <string name="alternates_for_i">8ïîíì</string>
+ <string name="alternates_for_o">9øœöõôóò</string>
+ <string name="alternates_for_u">7üûúù</string>
+ <string name="alternates_for_s">§ß</string>
+ <string name="alternates_for_n">ñ</string>
+ <string name="alternates_for_c">ç</string>
+ <string name="alternates_for_y">6ÿý</string>
+ <string name="alternates_for_q"></string>
+ <string name="alternates_for_w"></string>
+ <string name="alternates_for_z">2</string>
+</resources>
diff --git a/java/res/values-fr/donottranslate-keymap.xml b/java/res/values-fr/donottranslate-keymap.xml
new file mode 100644
index 0000000..c17ba77
--- /dev/null
+++ b/java/res/values-fr/donottranslate-keymap.xml
@@ -0,0 +1,221 @@
+<?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.
+**
+**
+** 5-row layout for French AZERTY.
+**
+** See http://code.google.com/p/hackerskeyboard/wiki/AddingNewLayouts for
+** more information.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="key_tlde_main">²</string>
+ <string name="key_tlde_shift">²</string>
+ <string name="key_tlde_alt">²³¹</string>
+
+ <string name="key_ae01_main">&amp;</string>
+ <string name="key_ae01_shift">1</string>
+ <string name="key_ae01_alt">1&amp;½⅓¼⅛</string>
+
+ <string name="key_ae02_main">é</string>
+ <string name="key_ae02_shift">2</string>
+ <string name="key_ae02_alt">é2É&#x301;&#x303;~\@⅔</string>
+
+ <string name="key_ae03_main">\"</string>
+ <string name="key_ae03_shift">3</string>
+ <string name="key_ae03_alt">\"3#¾⅜</string>
+
+ <string name="key_ae04_main">\'</string>
+ <string name="key_ae04_shift">4</string>
+ <string name="key_ae04_alt">\'4{—⁴</string>
+
+ <string name="key_ae05_main">(</string>
+ <string name="key_ae05_shift">5</string>
+ <string name="key_ae05_alt">(5[–⅝</string>
+
+ <string name="key_ae06_main">-</string>
+ <string name="key_ae06_shift">6</string>
+ <string name="key_ae06_alt">-6|↑↓←→</string>
+
+ <string name="key_ae07_main">è</string>
+ <string name="key_ae07_shift">7</string>
+ <string name="key_ae07_alt">è7&#x300;`È⅞♪</string>
+
+ <string name="key_ae08_main">_</string>
+ <string name="key_ae08_shift">8</string>
+ <string name="key_ae08_alt">_8\\™∞†‡</string>
+
+ <string name="key_ae09_main">ç</string>
+ <string name="key_ae09_shift">9</string>
+ <string name="key_ae09_alt">ç9^Ç√</string>
+
+ <string name="key_ae10_main">à</string>
+ <string name="key_ae10_shift">0</string>
+ <string name="key_ae10_alt">à0\@À°</string>
+
+ <string name="key_ae11_main">)</string>
+ <string name="key_ae11_shift">°</string>
+ <string name="key_ae11_alt">)°]≠≈</string>
+
+ <string name="key_ae12_main">=</string>
+ <string name="key_ae12_shift">+</string>
+ <string name="key_ae12_alt">=+}±</string>
+
+
+ <string name="key_ad01_main">a</string>
+ <string name="key_ad01_shift">A</string>
+ <string name="key_ad01_alt">@string/alternates_for_a</string>
+
+ <string name="key_ad02_main">z</string>
+ <string name="key_ad02_shift">Z</string>
+ <string name="key_ad02_alt">@string/alternates_for_z</string>
+
+ <string name="key_ad03_main">e</string>
+ <string name="key_ad03_shift">E</string>
+ <string name="key_ad03_alt">@string/alternates_for_e</string>
+
+ <string name="key_ad04_main">r</string>
+ <string name="key_ad04_shift">R</string>
+ <string name="key_ad04_alt">@string/alternates_for_r</string>
+
+ <string name="key_ad05_main">t</string>
+ <string name="key_ad05_shift">T</string>
+ <string name="key_ad05_alt">@string/alternates_for_t</string>
+
+ <string name="key_ad06_main">y</string>
+ <string name="key_ad06_shift">Y</string>
+ <string name="key_ad06_alt">@string/alternates_for_y</string>
+
+ <string name="key_ad07_main">u</string>
+ <string name="key_ad07_shift">U</string>
+ <string name="key_ad07_alt">@string/alternates_for_u</string>
+
+ <string name="key_ad08_main">i</string>
+ <string name="key_ad08_shift">I</string>
+ <string name="key_ad08_alt">@string/alternates_for_i</string>
+
+ <string name="key_ad09_main">o</string>
+ <string name="key_ad09_shift">O</string>
+ <string name="key_ad09_alt">@string/alternates_for_o</string>
+
+ <string name="key_ad10_main">p</string>
+ <string name="key_ad10_shift">P</string>
+ <string name="key_ad10_alt">@string/alternates_for_p</string>
+
+ <string name="key_ad11_main">&#x302;</string>
+ <string name="key_ad11_shift">&#x308;</string>
+ <string name="key_ad11_alt">&#x302;&#x308;^Å</string>
+
+ <string name="key_ad12_main">$</string>
+ <string name="key_ad12_shift">£</string>
+ <string name="key_ad12_alt">$£øØ€¥¢</string>
+
+ <string name="key_bksl_main">*</string>
+ <string name="key_bksl_shift">µ</string>
+ <string name="key_bksl_alt">*µ`</string>
+
+
+ <string name="key_ac01_main">q</string>
+ <string name="key_ac01_shift">Q</string>
+ <string name="key_ac01_alt">@string/alternates_for_q</string>
+
+ <string name="key_ac02_main">s</string>
+ <string name="key_ac02_shift">S</string>
+ <string name="key_ac02_alt">@string/alternates_for_s</string>
+
+ <string name="key_ac03_main">d</string>
+ <string name="key_ac03_shift">D</string>
+ <string name="key_ac03_alt">@string/alternates_for_d</string>
+
+ <string name="key_ac04_main">f</string>
+ <string name="key_ac04_shift">F</string>
+ <string name="key_ac04_alt">@string/alternates_for_f</string>
+
+ <string name="key_ac05_main">g</string>
+ <string name="key_ac05_shift">G</string>
+ <string name="key_ac05_alt">@string/alternates_for_g</string>
+
+ <string name="key_ac06_main">h</string>
+ <string name="key_ac06_shift">H</string>
+ <string name="key_ac06_alt">@string/alternates_for_h</string>
+
+ <string name="key_ac07_main">j</string>
+ <string name="key_ac07_shift">J</string>
+ <string name="key_ac07_alt">@string/alternates_for_j</string>
+
+ <string name="key_ac08_main">k</string>
+ <string name="key_ac08_shift">K</string>
+ <string name="key_ac08_alt">@string/alternates_for_k</string>
+
+ <string name="key_ac09_main">l</string>
+ <string name="key_ac09_shift">L</string>
+ <string name="key_ac09_alt">@string/alternates_for_l</string>
+
+ <string name="key_ac10_main">m</string>
+ <string name="key_ac10_shift">M</string>
+ <string name="key_ac10_alt">@string/alternates_for_m</string>
+
+ <string name="key_ac11_main">ù</string>
+ <string name="key_ac11_shift">%</string>
+ <string name="key_ac11_alt">ù%Ù‰</string>
+
+
+ <string name="key_lsgt_main">&lt;</string>
+ <string name="key_lsgt_shift">&gt;</string>
+ <string name="key_lsgt_alt">&lt;&gt;≤≥</string>
+
+ <string name="key_ab01_main">w</string>
+ <string name="key_ab01_shift">W</string>
+ <string name="key_ab01_alt">@string/alternates_for_w</string>
+
+ <string name="key_ab02_main">x</string>
+ <string name="key_ab02_shift">X</string>
+ <string name="key_ab02_alt">@string/alternates_for_x</string>
+
+ <string name="key_ab03_main">c</string>
+ <string name="key_ab03_shift">C</string>
+ <string name="key_ab03_alt">@string/alternates_for_c</string>
+
+ <string name="key_ab04_main">v</string>
+ <string name="key_ab04_shift">V</string>
+ <string name="key_ab04_alt">@string/alternates_for_v</string>
+
+ <string name="key_ab05_main">b</string>
+ <string name="key_ab05_shift">B</string>
+ <string name="key_ab05_alt">@string/alternates_for_b</string>
+
+ <string name="key_ab06_main">n</string>
+ <string name="key_ab06_shift">N</string>
+ <string name="key_ab06_alt">@string/alternates_for_n</string>
+
+ <string name="key_ab07_main">,</string>
+ <string name="key_ab07_shift">\?</string>
+ <string name="key_ab07_alt">,\?¿…</string>
+
+ <string name="key_ab08_main">;</string>
+ <string name="key_ab08_shift">.</string>
+ <string name="key_ab08_alt">;.×⋅</string>
+
+ <string name="key_ab09_main">:</string>
+ <string name="key_ab09_shift">/</string>
+ <string name="key_ab09_alt">:/÷</string>
+
+ <string name="key_ab10_main">!</string>
+ <string name="key_ab10_shift">§</string>
+ <string name="key_ab10_alt">!§¡−</string>
+</resources>
diff --git a/java/res/values-fr/donottranslate.xml b/java/res/values-fr/donottranslate.xml
new file mode 100644
index 0000000..b79df7b
--- /dev/null
+++ b/java/res/values-fr/donottranslate.xml
@@ -0,0 +1,25 @@
+<?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 commonly considered word separators in this language -->
+ <string name="word_separators">.\u0009\u0020,;:!?\'\n()[]*&amp;@{}/&lt;&gt;_+=|\u0022</string>
+ <!-- Symbols that are sentence separators, for purposes of making it hug the last sentence. -->
+ <string name="sentence_separators">.,</string>
+</resources>
diff --git a/java/res/values-fr/strings.xml b/java/res/values-fr/strings.xml
new file mode 100644
index 0000000..ccf4d2f
--- /dev/null
+++ b/java/res/values-fr/strings.xml
@@ -0,0 +1,140 @@
+<?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/org.pocketworkstation.pckeyboard"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- <string name="english_ime_name" msgid="7252517407088836577">"Clavier Android"</string> -->
+ <!-- <string name="english_ime_settings" msgid="6661589557206947774">"Paramètres du clavier Android"</string> -->
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Options de saisie"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrer à chaque touche"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"Son à chaque touche"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"Agrandir les caractères"</string>
+ <string name="hit_correction" msgid="4855351009261318389">"Corriger les fautes de frappe"</string>
+ <string name="hit_correction_summary" msgid="8761701873008070796">"Activer la correction des erreurs de saisie"</string>
+ <string name="hit_correction_land" msgid="2567691684825205448">"Erreurs de saisie en mode paysage"</string>
+ <string name="hit_correction_land_summary" msgid="4076803842198368328">"Activer la correction des erreurs de saisie"</string>
+ <string name="auto_correction" msgid="7911639788808958255">"Saisie prédictive"</string>
+ <string name="auto_correction_summary" msgid="6881047311475758267">"Corriger automatiquement le mot précédent"</string>
+ <string name="prediction" msgid="466220283138359837">"Saisie prédictive"</string>
+ <string name="prediction_category" msgid="7027100625580696660">"Paramètres de la saisie prédictive"</string>
+ <string name="prediction_summary" msgid="459788228830873110">"Activer la saisie semi-automatique"</string>
+ <string name="auto_complete_dialog_title" msgid="2172048590607201920">"Saisie semi-automatique"</string>
+ <string name="prediction_landscape" msgid="4874601565593216183">"Agrandir le champ de texte"</string>
+ <string name="prediction_landscape_summary" msgid="6736551095997839472">"Masquer la saisie prédictive en mode paysage"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"Majuscules auto"</string>
+ <string name="auto_cap_summary" msgid="3260681697600786825">"Mettre en majuscule la première lettre de chaque phrase"</string>
+ <string name="auto_punctuate" msgid="7276672334264521751">"Ponctuation automatique"</string>
+ <string name="auto_punctuate_summary" msgid="6589441565817502132"></string>
+ <string name="quick_fixes" msgid="5353213327680897927">"Corrections rapides"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"Corrige les fautes de frappe courantes"</string>
+ <string name="show_suggestions" msgid="507074425254289133">"Afficher les suggestions"</string>
+ <string name="show_suggestions_summary" msgid="1989672863935759654">"Afficher les suggestions de terme lors de la saisie"</string>
+ <string name="auto_complete" msgid="1103196318775486023">"Saisie semi-automatique"</string>
+ <string name="auto_complete_summary" msgid="6113149638718274624">"Insérer auto. le terme surligné avec barre espace/ponctuation"</string>
+ <string name="prefs_settings_key" msgid="4623341240804046498">"Afficher touche paramètr."</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automatique"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Toujours afficher"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"Toujours masquer"</string>
+ <!-- no translation found for settings_key_modes:0 (8549888726962891527) -->
+ <!-- no translation found for settings_key_modes:1 (881280041213210923) -->
+ <!-- no translation found for settings_key_modes:2 (7317310620171067848) -->
+ <string name="bigram_suggestion" msgid="1323347224043514969">"Suggestions de type bigramme"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Améliorer la suggestion en fonction du mot précédent"</string>
+ <string-array name="prediction_modes">
+ <item msgid="4870266572388153286">"Aucun"</item>
+ <item msgid="1669461741568287396">"Simple"</item>
+ <item msgid="4894328801530136615">"Avancé"</item>
+ </string-array>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : enregistré"</string>
+ <string name="tip_long_press" msgid="6101270866284343344">"Maintenir une touche enfoncée pour afficher les accents (à, é, etc.)"</string>
+ <string name="tip_dismiss" msgid="7585579046862204381">"Appuyez sur la touche Retour ↶ pour fermer le clavier à tout moment."</string>
+ <string name="tip_access_symbols" msgid="6344098517525531652">"Accéder aux chiffres et symboles"</string>
+ <string name="tip_add_to_dictionary" msgid="1487293888469227817">"Appuyer et maintenir le doigt sur le mot le plus à gauche pour l\'ajouter au dictionnaire"</string>
+ <string name="touch_to_continue" msgid="7869803257948414531">"Touchez ce conseil pour continuer »"</string>
+ <string name="touch_to_finish" msgid="7990196086480585789">"Touchez ici pour fermer ce conseil et commencer à saisir votre texte."</string>
+ <string name="tip_to_open_keyboard" msgid="6821200275486950452"><b>"Le clavier s\'affiche à chaque fois que vous touchez une zone de texte."</b></string>
+ <string name="tip_to_view_accents" msgid="5433158573693308501"><b>"Maintenez une touche enfoncée pour afficher les accents"\n"(ø, ö, ô, ó, etc.)"</b>"."</string>
+ <string name="tip_to_open_symbols" msgid="7345139325622444880"><b>"Appuyez sur cette touche pour basculer vers les chiffres et les symboles."</b></string>
+ <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"Appuyez de nouveau sur cette touche pour retourner aux lettres."</b></string>
+ <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"Maintenez cette touche enfoncée afin de modifier les paramètres du clavier, tels que la saisie semi-automatique."</b></string>
+ <string name="tip_to_start_typing" msgid="7213843601369174313"><b>"Essayez !"</b></string>
+ <string name="label_go_key" msgid="1635148082137219148">"OK"</string>
+ <string name="label_next_key" msgid="362972844525672568">"Suivant"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"OK"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"Envoyer"</string>
+ <string name="label_symbol_key" msgid="6175820506864489453">"?123"</string>
+ <string name="label_phone_key" msgid="4275497665515080551">"123"</string>
+ <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string>
+ <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string>
+ <string name="voice_warning_title" msgid="4419354150908395008">"Saisie vocale"</string>
+ <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"La saisie vocale n\'est pas encore prise en charge pour votre langue, mais elle fonctionne en anglais."</string>
+ <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"La saisie vocale est une fonctionnalité expérimentale qui fait appel à la reconnaissance vocale en réseau de Google."</string>
+ <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"Pour désactiver la saisie vocale, accédez aux paramètres du clavier."</string>
+ <string name="voice_hint_dialog_message" msgid="6892342981545727994">"Pour utiliser la saisie vocale, appuyez sur la touche du microphone ou faites glisser votre doigt sur le clavier à l\'écran."</string>
+ <string name="voice_listening" msgid="467518160751321844">"Parlez maintenant"</string>
+ <string name="voice_working" msgid="6666937792815731889">"Traitement en cours"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"Erreur. Veuillez réessayer."</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"Connexion impossible"</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"Erreur, discours trop long."</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"Problème audio"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"Erreur serveur"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"Aucune requête vocale détectée"</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"Aucune correspondance n\'a été trouvée."</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"Recherche vocale non installée"</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Astuce :"</b>" Faites glisser votre doigt sur le clavier pour parler."</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Astuce :"</b>" La prochaine fois, essayez de prononcer la ponctuation, en énonçant des termes tels que \"point\", \"virgule\" ou \"point d\'interrogation\"."</string>
+ <string name="cancel" msgid="6830980399865683324">"Annuler"</string>
+ <string name="ok" msgid="7898366843681727667">"OK"</string>
+ <string name="voice_input" msgid="2466640768843347841">"Saisie vocale"</string>
+ <string-array name="voice_input_modes">
+ <item msgid="1349082139076086774">"Sur le clavier principal"</item>
+ <item msgid="8529385602829095903">"Sur le clavier des symboles"</item>
+ <item msgid="7283103513488381103">"Désactivée"</item>
+ </string-array>
+ <string-array name="voice_input_modes_summary">
+ <item msgid="554248625705084903">"Micro sur le clavier principal"</item>
+ <item msgid="6907837061058876770">"Micro sur le clavier des symboles"</item>
+ <item msgid="3664304608587798036">"Saisie vocale désactivée"</item>
+ </string-array>
+ <string name="auto_submit" msgid="9151008027068358518">"Envoi automatique après la saisie vocale"</string>
+ <string name="auto_submit_summary" msgid="4961875269610384226">"Appuyez automatiquement sur Entrée pour effectuer une recherche ou accéder au champ suivant."</string>
+ <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Ouvrir le clavier"\n</b></font><font size="3">\n</font>"Appuyez sur un champ de texte."</string>
+ <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Fermer le clavier"\n</b></font><font size="3">\n</font>"Appuyez sur la touche Retour."</string>
+ <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Appuyez sur une touche de manière prolongée pour accéder aux options"\n</b></font><font size="3">\n</font>"Accédez aux signes de ponctuation et aux accents."</string>
+ <string name="keyboard_settings" msgid="4585753477617374032"><font size="17"><b>"Paramètres du clavier"\n</b></font><font size="3">\n</font>"Appuyez sur la touche "<b>"?123"</b>" de manière prolongée."</string>
+ <string name="popular_domain_0" msgid="3745279225122472969">".com"</string>
+ <string name="popular_domain_1" msgid="1370572248164278467">".net"</string>
+ <string name="popular_domain_2" msgid="3036812463748402878">".org"</string>
+ <string name="popular_domain_3" msgid="8718639560809452028">".gouv"</string>
+ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"Sélectionner un mode de saisie."</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Langues de saisie"</string>
+ <string name="language_selection_summary" msgid="187110938289512256">"Faites glisser votre doigt sur la barre d\'espacement pour changer la langue."</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Appuyer de nouveau pour enregistrer"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"Dictionnaire disponible"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"Autoriser les commentaires des utilisateurs"</string>
+ <string name="prefs_description_log" msgid="5827825607258246003">"Contribuer à l\'amélioration de cet éditeur du mode de saisie grâce à l\'envoi automatique de statistiques d\'utilisation et de rapports d\'incident à Google."</string>
+ <string name="prefs_enable_recorrection" msgid="4588408906649533582">"Appuyer pour corriger les suggestions"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="1056068922330206170">"Appuyer sur les mots saisis pour les corriger"</string>
+ <string name="keyboard_layout" msgid="437433231038683666">"Thème du clavier"</string>
+ <string name="subtype_mode_keyboard" msgid="2242090416595003881">"clavier"</string>
+ <string name="subtype_mode_voice" msgid="4394113125441627771">"voix"</string>
+</resources>
diff --git a/java/res/values-he/bools.xml b/java/res/values-he/bools.xml
new file mode 100644
index 0000000..126c437
--- /dev/null
+++ b/java/res/values-he/bools.xml
@@ -0,0 +1,22 @@
+<?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>
+ <bool name="default_auto_cap">false</bool>
+</resources>
diff --git a/java/res/values-he/donottranslate-altchars.xml b/java/res/values-he/donottranslate-altchars.xml
new file mode 100644
index 0000000..d2ae8c6
--- /dev/null
+++ b/java/res/values-he/donottranslate-altchars.xml
@@ -0,0 +1,47 @@
+<?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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="alternates_for_a">aáàâãäå</string>
+ <string name="alternates_for_b">b</string>
+ <string name="alternates_for_c">cçčć¢</string>
+ <string name="alternates_for_d">dđ</string>
+ <string name="alternates_for_e">3eéèêëē€</string>
+ <string name="alternates_for_f">f₣</string>
+ <string name="alternates_for_g">g</string>
+ <string name="alternates_for_h">h</string>
+ <string name="alternates_for_i">8iíìîïī</string>
+ <string name="alternates_for_j">j</string>
+ <string name="alternates_for_k">k</string>
+ <string name="alternates_for_l">l£₤λ</string>
+ <string name="alternates_for_m">mμ</string>
+ <string name="alternates_for_n">nñ</string>
+ <string name="alternates_for_o">9oóòôõö</string>
+ <string name="alternates_for_p">0pπ₱</string>
+ <string name="alternates_for_q">1q</string>
+ <string name="alternates_for_r">4r</string>
+ <string name="alternates_for_s">s§ßš</string>
+ <string name="alternates_for_t">5t</string>
+ <string name="alternates_for_u">7uúùûü</string>
+ <string name="alternates_for_v">v</string>
+ <string name="alternates_for_w">2w`</string>
+ <string name="alternates_for_x">x</string>
+ <string name="alternates_for_y">6yýÿ¥</string>
+ <string name="alternates_for_z">zž</string>
+</resources>
diff --git a/java/res/values-he/donottranslate-keymap.xml b/java/res/values-he/donottranslate-keymap.xml
new file mode 100644
index 0000000..5bff5d2
--- /dev/null
+++ b/java/res/values-he/donottranslate-keymap.xml
@@ -0,0 +1,217 @@
+<?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.
+**
+**
+** 5-row layout for Hebrew.
+**
+** See http://code.google.com/p/hackerskeyboard/wiki/AddingNewLayouts for
+** more information.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="key_tlde_main">;</string>
+ <string name="key_tlde_shift">~</string>
+ <string name="key_tlde_alt">;~</string>
+
+ <string name="key_ae01_main">1</string>
+ <string name="key_ae01_shift">!</string>
+ <string name="key_ae01_alt">1!¡¹½⅓¼⅛</string>
+
+ <string name="key_ae02_main">2</string>
+ <string name="key_ae02_shift">\@</string>
+ <string name="key_ae02_alt">2\@²⅔</string>
+
+ <string name="key_ae03_main">3</string>
+ <string name="key_ae03_shift">#</string>
+ <string name="key_ae03_alt">3#³¾⅜♥♠♦♣</string>
+
+ <string name="key_ae04_main">4</string>
+ <string name="key_ae04_shift">$</string>
+ <string name="key_ae04_alt">4$⁴¢£€¥</string>
+
+ <string name="key_ae05_main">5</string>
+ <string name="key_ae05_shift">%</string>
+ <string name="key_ae05_alt">5%⅝‰</string>
+
+ <string name="key_ae06_main">6</string>
+ <string name="key_ae06_shift">^</string>
+ <string name="key_ae06_alt">6^↑↓←→</string>
+
+ <string name="key_ae07_main">7</string>
+ <string name="key_ae07_shift">&amp;</string>
+ <string name="key_ae07_alt">7&amp;⅞♪</string>
+
+ <string name="key_ae08_main">8</string>
+ <string name="key_ae08_shift">*</string>
+ <string name="key_ae08_alt">8*•★∞†‡</string>
+
+ <string name="key_ae09_main">9</string>
+ <string name="key_ae09_shift">)</string>
+ <string name="key_ae09_alt">9)√</string>
+
+ <string name="key_ae10_main">0</string>
+ <string name="key_ae10_shift">(</string>
+ <string name="key_ae10_alt">0(ⁿ°</string>
+
+ <string name="key_ae11_main">-</string>
+ <string name="key_ae11_shift">_</string>
+ <string name="key_ae11_alt">-_—–</string>
+
+ <string name="key_ae12_main">=</string>
+ <string name="key_ae12_shift">+</string>
+ <string name="key_ae12_alt">=+≈≠±×÷</string>
+
+
+ <string name="key_ad01_main">/</string>
+ <string name="key_ad01_shift">Q</string>
+ <string name="key_ad01_alt">@string/alternates_for_q</string>
+
+ <string name="key_ad02_main">\'</string>
+ <string name="key_ad02_shift">W</string>
+ <string name="key_ad02_alt">@string/alternates_for_w</string>
+
+ <string name="key_ad03_main">ק</string>
+ <string name="key_ad03_shift">E</string>
+ <string name="key_ad03_alt">@string/alternates_for_e</string>
+
+ <string name="key_ad04_main">ר</string>
+ <string name="key_ad04_shift">R</string>
+ <string name="key_ad04_alt">@string/alternates_for_r</string>
+
+ <string name="key_ad05_main">א</string>
+ <string name="key_ad05_shift">T</string>
+ <string name="key_ad05_alt">@string/alternates_for_t</string>
+
+ <string name="key_ad06_main">ט</string>
+ <string name="key_ad06_shift">Y</string>
+ <string name="key_ad06_alt">@string/alternates_for_y</string>
+
+ <string name="key_ad07_main">ו</string>
+ <string name="key_ad07_shift">U</string>
+ <string name="key_ad07_alt">@string/alternates_for_u</string>
+
+ <string name="key_ad08_main">ן</string>
+ <string name="key_ad08_shift">I</string>
+ <string name="key_ad08_alt">@string/alternates_for_i</string>
+
+ <string name="key_ad09_main">ם</string>
+ <string name="key_ad09_shift">O</string>
+ <string name="key_ad09_alt">@string/alternates_for_o</string>
+
+ <string name="key_ad10_main">פ</string>
+ <string name="key_ad10_shift">P</string>
+ <string name="key_ad10_alt">@string/alternates_for_p</string>
+
+ <string name="key_ad11_main">]</string>
+ <string name="key_ad11_shift">}</string>
+ <string name="key_ad11_alt">]}</string>
+
+ <string name="key_ad12_main">[</string>
+ <string name="key_ad12_shift">{</string>
+ <string name="key_ad12_alt">[{</string>
+
+ <string name="key_bksl_main">\\</string>
+ <string name="key_bksl_shift">|</string>
+ <string name="key_bksl_alt">\\|</string>
+
+
+ <string name="key_ac01_main">ש</string>
+ <string name="key_ac01_shift">A</string>
+ <string name="key_ac01_alt">@string/alternates_for_a</string>
+
+ <string name="key_ac02_main">ד</string>
+ <string name="key_ac02_shift">S</string>
+ <string name="key_ac02_alt">@string/alternates_for_s</string>
+
+ <string name="key_ac03_main">ג</string>
+ <string name="key_ac03_shift">D</string>
+ <string name="key_ac03_alt">@string/alternates_for_d</string>
+
+ <string name="key_ac04_main">כ</string>
+ <string name="key_ac04_shift">F</string>
+ <string name="key_ac04_alt">@string/alternates_for_f</string>
+
+ <string name="key_ac05_main">ע</string>
+ <string name="key_ac05_shift">G</string>
+ <string name="key_ac05_alt">@string/alternates_for_g</string>
+
+ <string name="key_ac06_main">י</string>
+ <string name="key_ac06_shift">H</string>
+ <string name="key_ac06_alt">@string/alternates_for_h</string>
+
+ <string name="key_ac07_main">ח</string>
+ <string name="key_ac07_shift">J</string>
+ <string name="key_ac07_alt">@string/alternates_for_j</string>
+
+ <string name="key_ac08_main">ל</string>
+ <string name="key_ac08_shift">K</string>
+ <string name="key_ac08_alt">@string/alternates_for_k</string>
+
+ <string name="key_ac09_main">ך</string>
+ <string name="key_ac09_shift">L</string>
+ <string name="key_ac09_alt">@string/alternates_for_l</string>
+
+ <string name="key_ac10_main">ף</string>
+ <string name="key_ac10_shift">:</string>
+ <string name="key_ac10_alt">ף:</string>
+
+ <string name="key_ac11_main">,</string>
+ <string name="key_ac11_shift">\"</string>
+ <string name="key_ac11_alt">,\"‘’“”</string>
+
+
+ <string name="key_ab01_main">ז</string>
+ <string name="key_ab01_shift">Z</string>
+ <string name="key_ab01_alt">@string/alternates_for_z</string>
+
+ <string name="key_ab02_main">ס</string>
+ <string name="key_ab02_shift">X</string>
+ <string name="key_ab02_alt">@string/alternates_for_x</string>
+
+ <string name="key_ab03_main">ב</string>
+ <string name="key_ab03_shift">C</string>
+ <string name="key_ab03_alt">@string/alternates_for_c</string>
+
+ <string name="key_ab04_main">ה</string>
+ <string name="key_ab04_shift">V</string>
+ <string name="key_ab04_alt">@string/alternates_for_v</string>
+
+ <string name="key_ab05_main">נ</string>
+ <string name="key_ab05_shift">B</string>
+ <string name="key_ab05_alt">@string/alternates_for_b</string>
+
+ <string name="key_ab06_main">מ</string>
+ <string name="key_ab06_shift">N</string>
+ <string name="key_ab06_alt">@string/alternates_for_n</string>
+
+ <string name="key_ab07_main">צ</string>
+ <string name="key_ab07_shift">M</string>
+ <string name="key_ab07_alt">@string/alternates_for_m</string>
+
+ <string name="key_ab08_main">ת</string>
+ <string name="key_ab08_shift">&gt;</string>
+ <string name="key_ab08_alt">&gt;≥»›</string>
+
+ <string name="key_ab09_main">ץ</string>
+ <string name="key_ab09_shift">&lt;</string>
+ <string name="key_ab09_alt">&lt;≤«‹</string>
+
+ <string name="key_ab10_main">.</string>
+ <string name="key_ab10_shift">\?</string>
+ <string name="key_ab10_alt">.?\?¿</string>
+</resources>
diff --git a/java/res/values-he/strings.xml b/java/res/values-he/strings.xml
new file mode 100644
index 0000000..54bedd3
--- /dev/null
+++ b/java/res/values-he/strings.xml
@@ -0,0 +1,140 @@
+<?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/org.pocketworkstation.pckeyboard"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- <string name="english_ime_name" msgid="7252517407088836577">"מקלדת Android"</string> -->
+ <!-- <string name="english_ime_settings" msgid="6661589557206947774">"הגדרות מקלדת של Android"</string> -->
+ <string name="english_ime_input_options" msgid="3909945612939668554">"אפשרויות קלט"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"רטט עם לחיצה על מקשים"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"צלילים עם לחיצה על מקשים"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"חלון קופץ עם לחיצה על מקשים"</string>
+ <string name="hit_correction" msgid="4855351009261318389">"תקן שגיאות הקלדה"</string>
+ <string name="hit_correction_summary" msgid="8761701873008070796">"הפוך תיקון שגיאות קלט לפעיל"</string>
+ <string name="hit_correction_land" msgid="2567691684825205448">"שגיאות קלט בפריסה לרוחב"</string>
+ <string name="hit_correction_land_summary" msgid="4076803842198368328">"הפוך תיקון שגיאות קלט לפעיל"</string>
+ <string name="auto_correction" msgid="7911639788808958255">"הצעות למילים"</string>
+ <string name="auto_correction_summary" msgid="6881047311475758267">"תקן באופן אוטומטי את המילה הקודמת"</string>
+ <string name="prediction" msgid="466220283138359837">"הצעות למילים"</string>
+ <string name="prediction_category" msgid="7027100625580696660">"הגדרות של הצעות מילים"</string>
+ <string name="prediction_summary" msgid="459788228830873110">"הפוך השלמה אוטומטית לפעילה בעת הקלדה"</string>
+ <string name="auto_complete_dialog_title" msgid="2172048590607201920">"השלמה אוטומטית"</string>
+ <string name="prediction_landscape" msgid="4874601565593216183">"הגדל את הגודל של שדה הטקסט"</string>
+ <string name="prediction_landscape_summary" msgid="6736551095997839472">"הסתר הצעות למילים בתצוגה לרוחב"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"הפיכה אוטומטית של אותיות לרישיות"</string>
+ <string name="auto_cap_summary" msgid="3260681697600786825">"הוסף אות רישית בתחילת משפט"</string>
+ <string name="auto_punctuate" msgid="7276672334264521751">"פיסוק אוטומטי"</string>
+ <string name="auto_punctuate_summary" msgid="6589441565817502132"></string>
+ <string name="quick_fixes" msgid="5353213327680897927">"תיקונים מהירים"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"מתקן שגיאות הקלדה נפוצות"</string>
+ <string name="show_suggestions" msgid="507074425254289133">"הצג הצעות"</string>
+ <string name="show_suggestions_summary" msgid="1989672863935759654">"הצג הצעות למילים בעת הקלדה"</string>
+ <string name="auto_complete" msgid="1103196318775486023">"השלמה אוטומטית"</string>
+ <string name="auto_complete_summary" msgid="6113149638718274624">"הקשה על מקש הרווח וסימני הפיסוק תוסיף באופן אוטומטי את המילה המסומנת"</string>
+ <string name="prefs_settings_key" msgid="4623341240804046498">"הצג מקש הגדרות"</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"אוטומטי"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"הצג תמיד"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"הסתר תמיד"</string>
+ <!-- no translation found for settings_key_modes:0 (8549888726962891527) -->
+ <!-- no translation found for settings_key_modes:1 (881280041213210923) -->
+ <!-- no translation found for settings_key_modes:2 (7317310620171067848) -->
+ <string name="bigram_suggestion" msgid="1323347224043514969">"הצעות של צמדי אותיות (Bigram)"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"השתמש במילה הקודמת כדי לשפר את ההצעה"</string>
+ <string-array name="prediction_modes">
+ <item msgid="4870266572388153286">"ללא"</item>
+ <item msgid="1669461741568287396">"בסיסי"</item>
+ <item msgid="4894328801530136615">"מתקדם"</item>
+ </string-array>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : נשמרה"</string>
+ <string name="tip_long_press" msgid="6101270866284343344">"החזק מקש לחוץ כדי לראות אקצנטים (ø, ö וכדומה)"</string>
+ <string name="tip_dismiss" msgid="7585579046862204381">"לחץ על המקש \'הקודם\' ↶ כדי לסגור את המקלדת בכל עת"</string>
+ <string name="tip_access_symbols" msgid="6344098517525531652">"גישה למספרים וסמלים"</string>
+ <string name="tip_add_to_dictionary" msgid="1487293888469227817">"לחץ על המילה השמאלית הקיצונית והחזק אותה לחוצה כדי להוסיף למילון"</string>
+ <string name="touch_to_continue" msgid="7869803257948414531">"גע ברמז זה כדי להמשיך »"</string>
+ <string name="touch_to_finish" msgid="7990196086480585789">"גע כאן כדי לסגור רמז זה ולהתחיל בהקלדה!"</string>
+ <string name="tip_to_open_keyboard" msgid="6821200275486950452"><b>"המקלדת נפתחת בכל פעם שאתה נוגע בשדה טקסט"</b></string>
+ <string name="tip_to_view_accents" msgid="5433158573693308501"><b>"גע במקש והחזק אותו לחוץ כדי להציג אקצנטים"\n"(ø, ö, ô, ó וכדומה)"</b></string>
+ <string name="tip_to_open_symbols" msgid="7345139325622444880"><b>"עבור למספרים וסמלים על ידי נגיעה במקש זה"</b></string>
+ <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"חזור לאותיות על ידי מגע במקש זה שוב"</b></string>
+ <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"גע במקש זה והחזק אותו לחוץ כדי לשנות את הגדרות המקלדת, כגון השלמה אוטומטית"</b></string>
+ <string name="tip_to_start_typing" msgid="7213843601369174313"><b>"נסה אותו!"</b></string>
+ <string name="label_go_key" msgid="1635148082137219148">"בצע"</string>
+ <string name="label_next_key" msgid="362972844525672568">"הבא"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"בוצע"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"שלח"</string>
+ <string name="label_symbol_key" msgid="6175820506864489453">"?123"</string>
+ <string name="label_phone_key" msgid="4275497665515080551">"123"</string>
+ <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string>
+ <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string>
+ <string name="voice_warning_title" msgid="4419354150908395008">"קלט קולי"</string>
+ <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"קלט קולי אינו נתמך בשלב זה בשפתך, אך הוא פועל באנגלית."</string>
+ <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"קלט קולי הוא תכונה ניסיונית של זיהוי הדיבור ברשת של Google."</string>
+ <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"כדי לכבות את הקלט הקולי, עבור להגדרות מקלדת."</string>
+ <string name="voice_hint_dialog_message" msgid="6892342981545727994">"כדי להשתמש בקלט הקולי, לחץ על לחצן המיקרופון או החלק את האצבע על המקלדת שבמסך."</string>
+ <string name="voice_listening" msgid="467518160751321844">"דבר כעת"</string>
+ <string name="voice_working" msgid="6666937792815731889">"פועל"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"שגיאה. נסה שוב."</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"אין אפשרות להתחבר"</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"שגיאה, דיבור רב מדי."</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"בעיה באודיו"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"שגיאת שרת"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"לא נשמע דיבור"</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"לא נמצאו התאמות"</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"חיפוש קולי לא מותקן"</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"רמז:"</b>" העבר על המקלדת כדי לדבר"</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"רמז:"</b>" בפעם הבאה, נסה לומר את סימני הפיסוק כגון \"נקודה\", \"פסיק\" או \"סימן שאלה\"."</string>
+ <string name="cancel" msgid="6830980399865683324">"ביטול"</string>
+ <string name="ok" msgid="7898366843681727667">"אישור"</string>
+ <string name="voice_input" msgid="2466640768843347841">"קלט קולי"</string>
+ <string-array name="voice_input_modes">
+ <item msgid="1349082139076086774">"במקלדת הראשית"</item>
+ <item msgid="8529385602829095903">"מקלדת סמלים מופעלת"</item>
+ <item msgid="7283103513488381103">"כבוי"</item>
+ </string-array>
+ <string-array name="voice_input_modes_summary">
+ <item msgid="554248625705084903">"מיקרופון במקלדת הראשית"</item>
+ <item msgid="6907837061058876770">"מיקרופון במקלדת סמלים"</item>
+ <item msgid="3664304608587798036">"הקלט הקולי מושבת"</item>
+ </string-array>
+ <string name="auto_submit" msgid="9151008027068358518">"שליחה אוטומטית לאחר הקלטת קול"</string>
+ <string name="auto_submit_summary" msgid="4961875269610384226">"הקש על Enter באופן אוטומטי בעת חיפוש או מעבר לשדה הבא."</string>
+ <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"פתח את המקלדת"\n</b></font><font size="3">\n</font>"גע בשדה טקסט כלשהו."</string>
+ <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"סגור את המקלדת"\n</b></font><font size="3">\n</font>"לחץ על הלחצן \'הקודם\'."</string>
+ <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"גע במקש והחזק אותו לחוץ לקבלת אפשרויות"\n</b></font><font size="3">\n</font>"קבל גישה לסימני פיסוק ואקצנטים."</string>
+ <string name="keyboard_settings" msgid="4585753477617374032"><font size="17"><b>"הגדרות מקלדת"\n</b></font><font size="3">\n</font>"גע במקש "<b>"?123"</b>" והחזק אותו לחוץ."</string>
+ <string name="popular_domain_0" msgid="3745279225122472969">"‎.com"</string>
+ <string name="popular_domain_1" msgid="1370572248164278467">"‎.net"</string>
+ <string name="popular_domain_2" msgid="3036812463748402878">"‎.org"</string>
+ <string name="popular_domain_3" msgid="8718639560809452028">"‎.gov"</string>
+ <string name="popular_domain_4" msgid="35359437471311470">"‎.edu"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"בחר שיטת קלט"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"שפות קלט"</string>
+ <string name="language_selection_summary" msgid="187110938289512256">"החלק את האצבע על מקש הרווח כדי לשנות שפה"</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← גע שוב כדי לשמור"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"מילון זמין"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"הפוך משוב ממשתמשים לפעיל"</string>
+ <string name="prefs_description_log" msgid="5827825607258246003">"עזור לשפר שיטת קלט זו על ידי שליחה אוטומטית של סטטיסטיקת שימוש ודוחות קריסת מחשב ל-Google."</string>
+ <string name="prefs_enable_recorrection" msgid="4588408906649533582">"גע כדי לתקן מילים"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="1056068922330206170">"גע במילים שהוזנו כדי לתקן אותן"</string>
+ <string name="keyboard_layout" msgid="437433231038683666">"עיצוב מקלדת"</string>
+ <string name="subtype_mode_keyboard" msgid="2242090416595003881">"מקלדת"</string>
+ <string name="subtype_mode_voice" msgid="4394113125441627771">"קולי"</string>
+</resources>
diff --git a/java/res/values-hr/donottranslate-altchars.xml b/java/res/values-hr/donottranslate-altchars.xml
new file mode 100644
index 0000000..cc60456
--- /dev/null
+++ b/java/res/values-hr/donottranslate-altchars.xml
@@ -0,0 +1,38 @@
+<?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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="alternates_for_a">äáàâãåāæ</string>
+ <string name="alternates_for_b">{</string>
+ <string name="alternates_for_c">čć¢</string>
+ <string name="alternates_for_e">3€éèêë</string>
+ <string name="alternates_for_f">[</string>
+ <string name="alternates_for_g">]</string>
+ <string name="alternates_for_k">ł</string>
+ <string name="alternates_for_m">§</string>
+ <string name="alternates_for_n">}</string>
+ <string name="alternates_for_o">9öóòôõōø</string>
+ <string name="alternates_for_u">7üúùûū</string>
+ <string name="alternates_for_q">1\\</string>
+ <string name="alternates_for_s">š§ß</string>
+ <string name="alternates_for_v">\@</string>
+ <string name="alternates_for_w">2|</string>
+ <string name="alternates_for_y">ýÿ¥</string>
+ <string name="alternates_for_z">6ž</string>
+</resources>
diff --git a/java/res/values-hr/donottranslate-keymap.xml b/java/res/values-hr/donottranslate-keymap.xml
new file mode 100644
index 0000000..5d31d0c
--- /dev/null
+++ b/java/res/values-hr/donottranslate-keymap.xml
@@ -0,0 +1,126 @@
+<?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.
+**
+**
+** 5-row layout for Slovenian, Bosnian, Croatian, and Latin Serbian,
+** contributed by Uroš Vampl.
+**
+** See http://code.google.com/p/hackerskeyboard/wiki/AddingNewLayouts for
+** more information.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="key_tlde_main">`</string>
+ <string name="key_tlde_shift">~</string>
+ <string name="key_tlde_alt">`~^°</string>
+
+ <string name="key_ae01_main">1</string>
+ <string name="key_ae01_shift">!</string>
+ <string name="key_ae01_alt">1!¹¡½⅓¼⅛</string>
+
+ <string name="key_ae02_main">2</string>
+ <string name="key_ae02_shift">\"</string>
+ <string name="key_ae02_alt">2\"²⅔</string>
+
+ <string name="key_ae03_main">3</string>
+ <string name="key_ae03_shift">#</string>
+ <string name="key_ae03_alt">3#³¾⅜♥♠♦♣</string>
+
+ <string name="key_ae04_main">4</string>
+ <string name="key_ae04_shift">$</string>
+ <string name="key_ae04_alt">4$⁴¼¥</string>
+
+ <string name="key_ae05_main">5</string>
+ <string name="key_ae05_shift">%</string>
+ <string name="key_ae05_alt">5%⅝‰</string>
+
+ <string name="key_ae06_main">6</string>
+ <string name="key_ae06_shift">&amp;</string>
+ <string name="key_ae06_alt">6&amp;↑↓←→</string>
+
+ <string name="key_ae07_main">7</string>
+ <string name="key_ae07_shift">/</string>
+ <string name="key_ae07_alt">7/⅞♪</string>
+
+ <string name="key_ae08_main">8</string>
+ <string name="key_ae08_shift">(</string>
+ <string name="key_ae08_alt">8(™∞†‡</string>
+
+ <string name="key_ae09_main">9</string>
+ <string name="key_ae09_shift">)</string>
+ <string name="key_ae09_alt">9)√</string>
+
+ <string name="key_ae10_main">0</string>
+ <string name="key_ae10_shift">=</string>
+ <string name="key_ae10_alt">0=ⁿ°≈≠</string>
+
+ <string name="key_ae11_main">\'</string>
+ <string name="key_ae11_shift">\?</string>
+ <string name="key_ae11_alt">\'\?</string>
+
+ <string name="key_ae12_main">+</string>
+ <string name="key_ae12_shift">*</string>
+ <string name="key_ae12_alt">+*•★±</string>
+
+
+ <string name="key_ad06_main">z</string>
+ <string name="key_ad06_shift">Z</string>
+ <string name="key_ad06_alt">@string/alternates_for_z</string>
+
+ <string name="key_ad11_main">š</string>
+ <string name="key_ad11_shift">Š</string>
+ <string name="key_ad11_alt">š÷</string>
+
+ <string name="key_ad12_main">đ</string>
+ <string name="key_ad12_shift">Đ</string>
+ <string name="key_ad12_alt">đ×</string>
+
+ <string name="key_bksl_main">ž</string>
+ <string name="key_bksl_shift">Ž</string>
+ <string name="key_bksl_alt">ž¤</string>
+
+
+ <string name="key_ac10_main">č</string>
+ <string name="key_ac10_shift">Č</string>
+ <string name="key_ac10_alt">č</string>
+
+ <string name="key_ac11_main">ć</string>
+ <string name="key_ac11_shift">Ć</string>
+ <string name="key_ac11_alt">ćß</string>
+
+
+ <string name="key_lsgt_main">&lt;</string>
+ <string name="key_lsgt_shift">&gt;</string>
+ <string name="key_lsgt_alt">&lt;&gt;|</string>
+
+ <string name="key_ab01_main">y</string>
+ <string name="key_ab01_shift">Y</string>
+ <string name="key_ab01_alt">@string/alternates_for_y</string>
+
+ <string name="key_ab08_main">,</string>
+ <string name="key_ab08_shift">;</string>
+ <string name="key_ab08_alt">;&lt;≤«‹</string>
+
+ <string name="key_ab09_main">.</string>
+ <string name="key_ab09_shift">:</string>
+ <string name="key_ab09_alt">:&gt;≥»›…</string>
+
+ <string name="key_ab10_main">-</string>
+ <string name="key_ab10_shift">_</string>
+ <string name="key_ab10_alt">-_–—</string>
+</resources>
diff --git a/java/res/values-hr/strings.xml b/java/res/values-hr/strings.xml
new file mode 100644
index 0000000..02d454c
--- /dev/null
+++ b/java/res/values-hr/strings.xml
@@ -0,0 +1,140 @@
+<?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/org.pocketworkstation.pckeyboard"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- <string name="english_ime_name" msgid="7252517407088836577">"Android tipkovnica"</string> -->
+ <!-- <string name="english_ime_settings" msgid="6661589557206947774">"Postavke tipkovnice za Android"</string> -->
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Opcije ulaza"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibracija pri pritisku na tipku"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"Zvuk pri pritisku tipke"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"Povećanja na pritisak tipke"</string>
+ <string name="hit_correction" msgid="4855351009261318389">"Ispravi pogreške u pisanju"</string>
+ <string name="hit_correction_summary" msgid="8761701873008070796">"Omogućavanje ispravka pogreške pri unosu"</string>
+ <string name="hit_correction_land" msgid="2567691684825205448">"Pogreške pri pejzažnom unosu"</string>
+ <string name="hit_correction_land_summary" msgid="4076803842198368328">"Omogućavanje ispravka pogreške pri unosu"</string>
+ <string name="auto_correction" msgid="7911639788808958255">"Prijedlozi riječi"</string>
+ <string name="auto_correction_summary" msgid="6881047311475758267">"Automatsko ispravljanje prethodne riječi"</string>
+ <string name="prediction" msgid="466220283138359837">"Prijedlozi riječi"</string>
+ <string name="prediction_category" msgid="7027100625580696660">"Postavke prijedloga riječi"</string>
+ <string name="prediction_summary" msgid="459788228830873110">"Omogućavanje automatskog dovršavanja pri upisivanju"</string>
+ <string name="auto_complete_dialog_title" msgid="2172048590607201920">"Automatsko dovršavanje"</string>
+ <string name="prediction_landscape" msgid="4874601565593216183">"Povećaj tekstualno polje"</string>
+ <string name="prediction_landscape_summary" msgid="6736551095997839472">"Sakrij prijedloge riječi u pejzažnom prikazu"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"Automatsko pisanje velikih slova"</string>
+ <string name="auto_cap_summary" msgid="3260681697600786825">"Stavi veliko slovo na početku rečenice"</string>
+ <string name="auto_punctuate" msgid="7276672334264521751">"Automatsko stavljanje interpunkcije"</string>
+ <string name="auto_punctuate_summary" msgid="6589441565817502132"></string>
+ <string name="quick_fixes" msgid="5353213327680897927">"Brzi popravci"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"Ispravlja uobičajene pogreške u pisanju"</string>
+ <string name="show_suggestions" msgid="507074425254289133">"Pokaži prijedloge"</string>
+ <string name="show_suggestions_summary" msgid="1989672863935759654">"Prikazivanje predloženih riječi prilikom upisivanja"</string>
+ <string name="auto_complete" msgid="1103196318775486023">"Automatsko dovršavanje"</string>
+ <string name="auto_complete_summary" msgid="6113149638718274624">"Razmaknica i interpunkcija automatski umeću istaknutu riječ"</string>
+ <string name="prefs_settings_key" msgid="4623341240804046498">"Prikaži tipku postavki"</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automatski"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Uvijek prikaži"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"Uvijek sakrij"</string>
+ <!-- no translation found for settings_key_modes:0 (8549888726962891527) -->
+ <!-- no translation found for settings_key_modes:1 (881280041213210923) -->
+ <!-- no translation found for settings_key_modes:2 (7317310620171067848) -->
+ <string name="bigram_suggestion" msgid="1323347224043514969">"Bigram prijedlozi"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Upotrijebi prethodnu riječ radi poboljšanja prijedloga"</string>
+ <string-array name="prediction_modes">
+ <item msgid="4870266572388153286">"Nijedan"</item>
+ <item msgid="1669461741568287396">"Osnovni"</item>
+ <item msgid="4894328801530136615">"Napredno"</item>
+ </string-array>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Spremljeno"</string>
+ <string name="tip_long_press" msgid="6101270866284343344">"Pritisnite i držite tipku da biste vidjeli naglaske (ø, ö itd.)"</string>
+ <string name="tip_dismiss" msgid="7585579046862204381">"Pritisnite tipku \"Natrag\" ↶ za zatvaranje tipkovnice"</string>
+ <string name="tip_access_symbols" msgid="6344098517525531652">"Pristup brojevima i simbolima"</string>
+ <string name="tip_add_to_dictionary" msgid="1487293888469227817">"Pritisnite i držite krajnju lijevu riječ da biste je dodali u rječnik."</string>
+ <string name="touch_to_continue" msgid="7869803257948414531">"Dodirnite ovaj savjet za nastavak »"</string>
+ <string name="touch_to_finish" msgid="7990196086480585789">"Dodirnite ovdje da biste zatvorili savjet i počeli upisivati!"</string>
+ <string name="tip_to_open_keyboard" msgid="6821200275486950452"><b>"Tipkovnica se otvara svaki put kada dodirnete tekstualno polje"</b></string>
+ <string name="tip_to_view_accents" msgid="5433158573693308501"><b>"Dodirnite i držite tipku da biste vidjeli naglaske"\n"(ø, ö, ô, ó i tako dalje)"</b></string>
+ <string name="tip_to_open_symbols" msgid="7345139325622444880"><b>"Prijeđite na brojeve i simbole dodirom na ovu tipku"</b></string>
+ <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"Dodirnite ponovo ovu tipku za povratak na slova"</b></string>
+ <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"Dodirnite i držite ovu tipku da biste promijenili postavke tipkovnice, poput automatskog dovršavanja"</b></string>
+ <string name="tip_to_start_typing" msgid="7213843601369174313"><b>"Isprobajte!"</b></string>
+ <string name="label_go_key" msgid="1635148082137219148">"Idi"</string>
+ <string name="label_next_key" msgid="362972844525672568">"Dalje"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"Gotovo"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"Pošalji"</string>
+ <string name="label_symbol_key" msgid="6175820506864489453">"?123"</string>
+ <string name="label_phone_key" msgid="4275497665515080551">"123"</string>
+ <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string>
+ <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string>
+ <string name="voice_warning_title" msgid="4419354150908395008">"Glasovni unos"</string>
+ <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Vaš jezik trenutno nije podržan za glasovni unos, ali radi za engleski."</string>
+ <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"Glasovni unos je pokusna značajka koja koristi Googleovo umreženo prepoznavanje govora."</string>
+ <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"Za isključivanje glasovnog unosa idite na postavke tipkovnice."</string>
+ <string name="voice_hint_dialog_message" msgid="6892342981545727994">"Da biste koristili glasovni unos pritisnite gumb mikrofona ili kliznite prstom preko tipkovnice na zaslonu."</string>
+ <string name="voice_listening" msgid="467518160751321844">"Govorite sad"</string>
+ <string name="voice_working" msgid="6666937792815731889">"Obrada"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"Pogreška. Pokušajte ponovo."</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"Spajanje nije bilo moguće"</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"Pogreška, predugi govor."</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"Problem sa zvukom"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"Pogreška na poslužitelju"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"Nije se čuo govor"</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"Nisu pronađeni rezultati"</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"Glasovno pretraživanje nije instalirano"</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Savjet:"</b>" Prijeđite preko tipkovnice pa govorite"</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Savjet:"</b>" Sljedeći put pokušajte izgovoriti znakove interpunkcije poput \"točka, \"zarez\" ili \"upitnik\"."</string>
+ <string name="cancel" msgid="6830980399865683324">"Odustani"</string>
+ <string name="ok" msgid="7898366843681727667">"U redu"</string>
+ <string name="voice_input" msgid="2466640768843347841">"Glasovni unos"</string>
+ <string-array name="voice_input_modes">
+ <item msgid="1349082139076086774">"Na glavnoj tipkovnici"</item>
+ <item msgid="8529385602829095903">"Na tipkovnici sa simbolima"</item>
+ <item msgid="7283103513488381103">"Isključeno"</item>
+ </string-array>
+ <string-array name="voice_input_modes_summary">
+ <item msgid="554248625705084903">"Mikrofon na glavnoj tipkovnici"</item>
+ <item msgid="6907837061058876770">"Mikrofon na tipkovnici sa simbolima"</item>
+ <item msgid="3664304608587798036">"Glasovni unos je onemogućen"</item>
+ </string-array>
+ <string name="auto_submit" msgid="9151008027068358518">"Automatski pošalji nakon glasovnog unosa"</string>
+ <string name="auto_submit_summary" msgid="4961875269610384226">"Automatski se pritišće \"Enter\" kad pretražujete ili idete na sljedeće polje."</string>
+ <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Otvaranje tipkovnice"\n</b></font><font size="3">\n</font>"Dodirnite bilo koje tekstualno polje"</string>
+ <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Zatvaranje tipkovnice"\n</b></font><font size="3">\n</font>"Pritisnite tipku \"Natrag\"."</string>
+ <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Dodirnite i držite tipku da biste vidjeli opcije"\n</b></font><font size="3">\n</font>"Pristup interpunkciji i naglascima."</string>
+ <string name="keyboard_settings" msgid="4585753477617374032"><font size="17"><b>"Postavke tipkovnice"\n</b></font><font size="3">\n</font>"Dodirnite i držite tipku "<b>"?123"</b>"."</string>
+ <string name="popular_domain_0" msgid="3745279225122472969">".com"</string>
+ <string name="popular_domain_1" msgid="1370572248164278467">".net"</string>
+ <string name="popular_domain_2" msgid="3036812463748402878">".org"</string>
+ <string name="popular_domain_3" msgid="8718639560809452028">".gov"</string>
+ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"Odabir ulazne metode"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Jezici unosa"</string>
+ <string name="language_selection_summary" msgid="187110938289512256">"Kliznite prstom po razmaknici za promjenu jezika"</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Dodirnite opet za spremanje"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"Rječnik je dostupan"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"Omogući korisničke povratne informacije"</string>
+ <string name="prefs_description_log" msgid="5827825607258246003">"Pomozite u poboljšanju ovog urednika ulazne metode automatskim slanjem statistike upotrebe i padova Googleu."</string>
+ <string name="prefs_enable_recorrection" msgid="4588408906649533582">"Dodirnite za ispravak riječi"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="1056068922330206170">"Dodirnite unesene riječi radi ispravka"</string>
+ <string name="keyboard_layout" msgid="437433231038683666">"Tema tipkovnice"</string>
+ <string name="subtype_mode_keyboard" msgid="2242090416595003881">"tipkovnica"</string>
+ <string name="subtype_mode_voice" msgid="4394113125441627771">"glas"</string>
+</resources>
diff --git a/java/res/values-hu/donottranslate-altchars.xml b/java/res/values-hu/donottranslate-altchars.xml
new file mode 100644
index 0000000..d1d38bb
--- /dev/null
+++ b/java/res/values-hu/donottranslate-altchars.xml
@@ -0,0 +1,47 @@
+<?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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="alternates_for_a">á</string>
+ <string name="alternates_for_b"></string>
+ <string name="alternates_for_c"></string>
+ <string name="alternates_for_d"></string>
+ <string name="alternates_for_e">3é</string>
+ <string name="alternates_for_f"></string>
+ <string name="alternates_for_g"></string>
+ <string name="alternates_for_h"></string>
+ <string name="alternates_for_i">8í</string>
+ <string name="alternates_for_j"></string>
+ <string name="alternates_for_k"></string>
+ <string name="alternates_for_l"></string>
+ <string name="alternates_for_m"></string>
+ <string name="alternates_for_n"></string>
+ <string name="alternates_for_o">9óöő</string>
+ <string name="alternates_for_p">0</string>
+ <string name="alternates_for_q">1</string>
+ <string name="alternates_for_r">4</string>
+ <string name="alternates_for_s"></string>
+ <string name="alternates_for_t">5</string>
+ <string name="alternates_for_u">7úüű</string>
+ <string name="alternates_for_v"></string>
+ <string name="alternates_for_w">2</string>
+ <string name="alternates_for_x"></string>
+ <string name="alternates_for_y">6</string>
+ <string name="alternates_for_z"></string>
+</resources>
diff --git a/java/res/values-hu/strings.xml b/java/res/values-hu/strings.xml
new file mode 100644
index 0000000..3d0e34b
--- /dev/null
+++ b/java/res/values-hu/strings.xml
@@ -0,0 +1,140 @@
+<?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/org.pocketworkstation.pckeyboard"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- <string name="english_ime_name" msgid="7252517407088836577">"Android-billentyűzet"</string> -->
+ <!-- <string name="english_ime_settings" msgid="6661589557206947774">"Android billentyűzetbeállítások"</string> -->
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Beviteli beállítások"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"Rezgés billentyű megnyomása esetén"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"Hangjelzés billentyű megnyomása esetén"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"Legyen nagyobb billentyű lenyomásakor"</string>
+ <string name="hit_correction" msgid="4855351009261318389">"Gépelési hibák kijavítása"</string>
+ <string name="hit_correction_summary" msgid="8761701873008070796">"Beviteli hibák javításának engedélyezése"</string>
+ <string name="hit_correction_land" msgid="2567691684825205448">"Fekvő beviteli hibák"</string>
+ <string name="hit_correction_land_summary" msgid="4076803842198368328">"Beviteli hibák javításának engedélyezése"</string>
+ <string name="auto_correction" msgid="7911639788808958255">"Szójavaslatok"</string>
+ <string name="auto_correction_summary" msgid="6881047311475758267">"Az előző szó automatikus kijavítása"</string>
+ <string name="prediction" msgid="466220283138359837">"Szójavaslatok"</string>
+ <string name="prediction_category" msgid="7027100625580696660">"Szójavaslati beállítások"</string>
+ <string name="prediction_summary" msgid="459788228830873110">"Automatikus kiegészítés engedélyezése gépelés közben"</string>
+ <string name="auto_complete_dialog_title" msgid="2172048590607201920">"Automatikus kiegészítés"</string>
+ <string name="prediction_landscape" msgid="4874601565593216183">"A szövegmező méretének növelése"</string>
+ <string name="prediction_landscape_summary" msgid="6736551095997839472">"Szójavaslatok elrejtése fekvő nézetben"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"Automatikusan nagy kezdőbetű"</string>
+ <string name="auto_cap_summary" msgid="3260681697600786825">"Nagybetűvel kezdi a mondatot"</string>
+ <string name="auto_punctuate" msgid="7276672334264521751">"Automatikus központozás"</string>
+ <string name="auto_punctuate_summary" msgid="6589441565817502132"></string>
+ <string name="quick_fixes" msgid="5353213327680897927">"Gyorsjavítások"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"Kijavítja a gyakori gépelési hibákat"</string>
+ <string name="show_suggestions" msgid="507074425254289133">"Javaslatok megjelenítése"</string>
+ <string name="show_suggestions_summary" msgid="1989672863935759654">"A javasolt szavak megjelenítése gépelés közben"</string>
+ <string name="auto_complete" msgid="1103196318775486023">"Automatikus kiegészítés"</string>
+ <string name="auto_complete_summary" msgid="6113149638718274624">"A szóköz és az írásjelek használata automatikusan beszúrja a kiemelt szót"</string>
+ <string name="prefs_settings_key" msgid="4623341240804046498">"Beállítások billentyű megjelenítése"</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automatikus"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Mindig látszik"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"Mindig rejtve"</string>
+ <!-- no translation found for settings_key_modes:0 (8549888726962891527) -->
+ <!-- no translation found for settings_key_modes:1 (881280041213210923) -->
+ <!-- no translation found for settings_key_modes:2 (7317310620171067848) -->
+ <string name="bigram_suggestion" msgid="1323347224043514969">"Bigram javaslatok"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Előző szó használata a javaslatok javításához"</string>
+ <string-array name="prediction_modes">
+ <item msgid="4870266572388153286">"Nincs"</item>
+ <item msgid="1669461741568287396">"Alap"</item>
+ <item msgid="4894328801530136615">"Speciális"</item>
+ </string-array>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : mentve"</string>
+ <string name="tip_long_press" msgid="6101270866284343344">"Az ékezetes betűk megtekintéséhez tartsa lenyomva valamelyik billentyűt (ø, ö stb.)"</string>
+ <string name="tip_dismiss" msgid="7585579046862204381">"A vissza gomb ↶ megnyomásával bármikor elrejtheti a billentyűzetet"</string>
+ <string name="tip_access_symbols" msgid="6344098517525531652">"Számok és szimbólumok elérése"</string>
+ <string name="tip_add_to_dictionary" msgid="1487293888469227817">"A szótárhoz történő hozzáadásához nyomja meg hosszan a bal oldali legszélső szót"</string>
+ <string name="touch_to_continue" msgid="7869803257948414531">"A folytatáshoz érintse meg ezt a tippet »"</string>
+ <string name="touch_to_finish" msgid="7990196086480585789">"Érintse meg itt a tipp bezárásához és a gépelés megkezdéséhez."</string>
+ <string name="tip_to_open_keyboard" msgid="6821200275486950452"><b>"Szövegmező megérintésekor a billentyűzet mindig megjelenik"</b></string>
+ <string name="tip_to_view_accents" msgid="5433158573693308501"><b>"Érintse meg és tartsa lenyomva valamelyik billentyűt az ékezetes betűk megtekintéséhez"\n"(ø, ö, ô, ó stb.)"</b></string>
+ <string name="tip_to_open_symbols" msgid="7345139325622444880"><b>"Számokra és szimbólumokra ennek a billentyűnek a megérintésével válthat"</b></string>
+ <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"A billentyű újbóli megérintésével visszatérhet a betűkhöz"</b></string>
+ <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"Érintse meg és tartsa lenyomva ezt a billentyűt a billentyűzet-beállítások (pl. az automatikus kiegészítés) módosításához"</b></string>
+ <string name="tip_to_start_typing" msgid="7213843601369174313"><b>"Próbálja ki!"</b></string>
+ <string name="label_go_key" msgid="1635148082137219148">"Ugrás"</string>
+ <string name="label_next_key" msgid="362972844525672568">"Tovább"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"Kész"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"Küldés"</string>
+ <string name="label_symbol_key" msgid="6175820506864489453">"?123"</string>
+ <string name="label_phone_key" msgid="4275497665515080551">"123"</string>
+ <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string>
+ <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string>
+ <string name="voice_warning_title" msgid="4419354150908395008">"Hangbevitel"</string>
+ <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"A hangbevitel szolgáltatás jelenleg nem támogatja az Ön nyelvét, ám angolul működik."</string>
+ <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"A hangbevitel a Google hálózati beszédfelismerését alkalmazó kísérleti funkció."</string>
+ <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"A hangbevitelt a billentyűzet beállításai között lehet kikapcsolni."</string>
+ <string name="voice_hint_dialog_message" msgid="6892342981545727994">"A hangbevitel használatához nyomja meg a mikrofon gombját vagy húzza végig az ujját a képernyő-billentyűzeten."</string>
+ <string name="voice_listening" msgid="467518160751321844">"Most beszéljen"</string>
+ <string name="voice_working" msgid="6666937792815731889">"Feldolgozás"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"Hiba történt. Kérjük, próbálja újra."</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"Nem sikerült kapcsolódni"</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"Hiba történt; túl sokat beszélt."</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"Hangprobléma"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"Szerverhiba"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"Nem hallatszott beszéd"</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"Nem található egyezés"</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"A hangalapú keresés nincs telepítve"</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Tipp:"</b>" húzza végig az ujját a billentyűzeten a beszédhez"</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Tipp:"</b>" következő alkalommal próbálja ki az írásjelek kimondását is, pl. \"period\", \"comma\" vagy \"question mark\"."</string>
+ <string name="cancel" msgid="6830980399865683324">"Mégse"</string>
+ <string name="ok" msgid="7898366843681727667">"OK"</string>
+ <string name="voice_input" msgid="2466640768843347841">"Hangbevitel"</string>
+ <string-array name="voice_input_modes">
+ <item msgid="1349082139076086774">"Főbillentyűzeten"</item>
+ <item msgid="8529385602829095903">"Szimbólumbillentyűzeten"</item>
+ <item msgid="7283103513488381103">"Ki"</item>
+ </string-array>
+ <string-array name="voice_input_modes_summary">
+ <item msgid="554248625705084903">"Mikrofon a főbillentyűzeten"</item>
+ <item msgid="6907837061058876770">"Mikrofon a szimbólumbillentyűzeten"</item>
+ <item msgid="3664304608587798036">"A hangbevitel ki van kapcsolva"</item>
+ </string-array>
+ <string name="auto_submit" msgid="9151008027068358518">"Automatikus küldés a beszéd után"</string>
+ <string name="auto_submit_summary" msgid="4961875269610384226">"Az Enter automatikus megnyomása keresés vagy a következő mezőre ugrás során."</string>
+ <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"A billentyűzet megjelenítése"\n</b></font><font size="3">\n</font>"Érintse meg valamelyik szövegmezőt."</string>
+ <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"A billentyűzet bezárása"\n</b></font><font size="3">\n</font>"Nyomja meg a Vissza billentyűt."</string>
+ <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"A lehetőségek megjelenítéséhez érintse meg és tartsa lenyomva valamelyik billentyűt"\n</b></font><font size="3">\n</font>"Az írásjelek és az ékezetes betűk elérése."</string>
+ <string name="keyboard_settings" msgid="4585753477617374032"><font size="17"><b>"Billentyűzetbeállítások"\n</b></font><font size="3">\n</font>"Érintse meg és tartsa lenyomva a "<b>"?123"</b>" billentyűt."</string>
+ <string name="popular_domain_0" msgid="3745279225122472969">".com"</string>
+ <string name="popular_domain_1" msgid="1370572248164278467">".net"</string>
+ <string name="popular_domain_2" msgid="3036812463748402878">".org"</string>
+ <string name="popular_domain_3" msgid="8718639560809452028">".gov"</string>
+ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"Beviteli mód kiválasztása"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Beviteli nyelvek"</string>
+ <string name="language_selection_summary" msgid="187110938289512256">"A nyelv módosításához húzza végig az ujját a szóköz billentyűn"</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Érintse meg újra a mentéshez"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"Van elérhető szótár"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"Felhasználói visszajelzés engedélyezése"</string>
+ <string name="prefs_description_log" msgid="5827825607258246003">"Segíthet ennek a beviteli módszernek a javításában, ha engedélyezi a használati statisztikák és a hibajelentések elküldését a Google-nak."</string>
+ <string name="prefs_enable_recorrection" msgid="4588408906649533582">"Javítás a szavak megérintésével"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="1056068922330206170">"A beírt szavakat megérintve kijavíthatja őket"</string>
+ <string name="keyboard_layout" msgid="437433231038683666">"Billentyűzettéma"</string>
+ <string name="subtype_mode_keyboard" msgid="2242090416595003881">"billentyűzet"</string>
+ <string name="subtype_mode_voice" msgid="4394113125441627771">"hang"</string>
+</resources>
diff --git a/java/res/values-hy/donottranslate-keymap.xml b/java/res/values-hy/donottranslate-keymap.xml
new file mode 100644
index 0000000..c9725d7
--- /dev/null
+++ b/java/res/values-hy/donottranslate-keymap.xml
@@ -0,0 +1,221 @@
+<?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.
+**
+**
+** 5-row layout for English QWERTY.
+**
+** See http://code.google.com/p/hackerskeyboard/wiki/AddingNewLayouts for
+** more information.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="key_tlde_main">`</string>
+ <string name="key_tlde_shift">~</string>
+ <string name="key_tlde_alt">`~</string>
+
+ <string name="key_ae01_main">(</string>
+ <string name="key_ae01_shift">«</string>
+ <string name="key_ae01_alt">1!¡¹½⅓¼⅛</string>
+
+ <string name="key_ae02_main">)</string>
+ <string name="key_ae02_shift">»</string>
+ <string name="key_ae02_alt">2\@²⅔</string>
+
+ <string name="key_ae03_main">՚</string>
+ <string name="key_ae03_shift"> ՛</string>
+ <string name="key_ae03_alt">3#³¾⅜♥♠♦♣</string>
+
+ <string name="key_ae04_main"> ՝</string>
+ <string name="key_ae04_shift">՞</string>
+ <string name="key_ae04_alt">4$⁴¢£€¥</string>
+
+ <string name="key_ae05_main">։</string>
+ <string name="key_ae05_shift"> ՜</string>
+ <string name="key_ae05_alt">5%⅝‰</string>
+
+ <string name="key_ae06_main">.</string>
+ <string name="key_ae06_shift">[</string>
+ <string name="key_ae06_alt">6^↑↓←→</string>
+
+ <string name="key_ae07_main">,</string>
+ <string name="key_ae07_shift">]</string>
+ <string name="key_ae07_alt">7&amp;⅞♪</string>
+
+ <string name="key_ae08_main">-</string>
+ <string name="key_ae08_shift">_</string>
+ <string name="key_ae08_alt">8*•★∞†‡</string>
+
+ <string name="key_ae09_main">ֆ</string>
+ <string name="key_ae09_shift">Ֆ</string>
+ <string name="key_ae09_alt">9(√</string>
+
+ <string name="key_ae10_main">օ</string>
+ <string name="key_ae10_shift">Օ</string>
+ <string name="key_ae10_alt">0)ⁿ°</string>
+
+ <string name="key_ae11_main">ռ</string>
+ <string name="key_ae11_shift">Ռ</string>
+ <string name="key_ae11_alt">-_—–</string>
+
+ <string name="key_ae12_main">ջ</string>
+ <string name="key_ae12_shift">Ջ</string>
+ <string name="key_ae12_alt">=+≈≠±×÷</string>
+
+
+ <string name="key_ad01_main">ք</string>
+ <string name="key_ad01_shift">Ք</string>
+ <string name="key_ad01_alt">@string/alternates_for_q</string>
+
+ <string name="key_ad02_main">վ</string>
+ <string name="key_ad02_shift">Վ</string>
+ <string name="key_ad02_alt">@string/alternates_for_w</string>
+
+ <string name="key_ad03_main">ը</string>
+ <string name="key_ad03_shift">Ը</string>
+ <string name="key_ad03_alt">@string/alternates_for_e</string>
+
+ <string name="key_ad04_main">ր</string>
+ <string name="key_ad04_shift">Ր</string>
+ <string name="key_ad04_alt">@string/alternates_for_r</string>
+
+ <string name="key_ad05_main">տ</string>
+ <string name="key_ad05_shift">Տ</string>
+ <string name="key_ad05_alt">@string/alternates_for_t</string>
+
+ <string name="key_ad06_main">ճ</string>
+ <string name="key_ad06_shift">Ճ</string>
+ <string name="key_ad06_alt">@string/alternates_for_y</string>
+
+ <string name="key_ad07_main">ւ</string>
+ <string name="key_ad07_shift">Ւ</string>
+ <string name="key_ad07_alt">@string/alternates_for_u</string>
+
+ <string name="key_ad08_main">ի</string>
+ <string name="key_ad08_shift">Ի</string>
+ <string name="key_ad08_alt">@string/alternates_for_i</string>
+
+ <string name="key_ad09_main">ո</string>
+ <string name="key_ad09_shift">Ո</string>
+ <string name="key_ad09_alt">@string/alternates_for_o</string>
+
+ <string name="key_ad10_main">պ</string>
+ <string name="key_ad10_shift">Պ</string>
+ <string name="key_ad10_alt">@string/alternates_for_p</string>
+
+ <string name="key_ad11_main">ղ</string>
+ <string name="key_ad11_shift">Ղ</string>
+ <string name="key_ad11_alt">[{</string>
+
+ <string name="key_ad12_main">յ</string>
+ <string name="key_ad12_shift">Յ</string>
+ <string name="key_ad12_alt">]}</string>
+
+ <string name="key_bksl_main">ձ</string>
+ <string name="key_bksl_shift">Ձ</string>
+ <string name="key_bksl_alt">\\|</string>
+
+
+ <string name="key_ac01_main">ա</string>
+ <string name="key_ac01_shift">Ա</string>
+ <string name="key_ac01_alt">@string/alternates_for_a</string>
+
+ <string name="key_ac02_main">ս</string>
+ <string name="key_ac02_shift">Ս</string>
+ <string name="key_ac02_alt">@string/alternates_for_s</string>
+
+ <string name="key_ac03_main">դ</string>
+ <string name="key_ac03_shift">Դ</string>
+ <string name="key_ac03_alt">@string/alternates_for_d</string>
+
+ <string name="key_ac04_main">հ</string>
+ <string name="key_ac04_shift">Հ</string>
+ <string name="key_ac04_alt">@string/alternates_for_f</string>
+
+ <string name="key_ac05_main">գ</string>
+ <string name="key_ac05_shift">Գ</string>
+ <string name="key_ac05_alt">@string/alternates_for_g</string>
+
+ <string name="key_ac06_main">է</string>
+ <string name="key_ac06_shift">Է</string>
+ <string name="key_ac06_alt">@string/alternates_for_h</string>
+
+ <string name="key_ac07_main">թ</string>
+ <string name="key_ac07_shift">Թ</string>
+ <string name="key_ac07_alt">@string/alternates_for_j</string>
+
+ <string name="key_ac08_main">կ</string>
+ <string name="key_ac08_shift">Կ</string>
+ <string name="key_ac08_alt">@string/alternates_for_k</string>
+
+ <string name="key_ac09_main">լ</string>
+ <string name="key_ac09_shift">Լ</string>
+ <string name="key_ac09_alt">@string/alternates_for_l</string>
+
+ <string name="key_ac10_main">ե</string>
+ <string name="key_ac10_shift">Ե</string>
+ <string name="key_ac10_alt">;:</string>
+
+ <string name="key_ac11_main">փ</string>
+ <string name="key_ac11_shift">Փ</string>
+ <string name="key_ac11_alt">\'\"‘’“”</string>
+
+
+ <string name="key_lsgt_main"></string>
+ <string name="key_lsgt_shift"></string>
+ <string name="key_lsgt_alt"></string>
+
+ <string name="key_ab01_main">ց</string>
+ <string name="key_ab01_shift">Ց</string>
+ <string name="key_ab01_alt">@string/alternates_for_z</string>
+
+ <string name="key_ab02_main">զ</string>
+ <string name="key_ab02_shift">Զ</string>
+ <string name="key_ab02_alt">@string/alternates_for_x</string>
+
+ <string name="key_ab03_main">չ</string>
+ <string name="key_ab03_shift">Չ</string>
+ <string name="key_ab03_alt">@string/alternates_for_c</string>
+
+ <string name="key_ab04_main">ժ</string>
+ <string name="key_ab04_shift">Ժ</string>
+ <string name="key_ab04_alt">@string/alternates_for_v</string>
+
+ <string name="key_ab05_main">բ</string>
+ <string name="key_ab05_shift">Բ</string>
+ <string name="key_ab05_alt">@string/alternates_for_b</string>
+
+ <string name="key_ab06_main">ն</string>
+ <string name="key_ab06_shift">Ն</string>
+ <string name="key_ab06_alt">@string/alternates_for_n</string>
+
+ <string name="key_ab07_main">մ</string>
+ <string name="key_ab07_shift">Մ</string>
+ <string name="key_ab07_alt">@string/alternates_for_m</string>
+
+ <string name="key_ab08_main">շ</string>
+ <string name="key_ab08_shift">Շ</string>
+ <string name="key_ab08_alt">,&lt;≤«‹</string>
+
+ <string name="key_ab09_main">խ</string>
+ <string name="key_ab09_shift">Խ</string>
+ <string name="key_ab09_alt">.&gt;≥»›…</string>
+
+ <string name="key_ab10_main">ծ</string>
+ <string name="key_ab10_shift">Ծ</string>
+ <string name="key_ab10_alt">/\?¿</string>
+</resources>
diff --git a/java/res/values-in/strings.xml b/java/res/values-in/strings.xml
new file mode 100644
index 0000000..27d3b6c
--- /dev/null
+++ b/java/res/values-in/strings.xml
@@ -0,0 +1,140 @@
+<?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/org.pocketworkstation.pckeyboard"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- <string name="english_ime_name" msgid="7252517407088836577">"Keyboard Android"</string> -->
+ <!-- <string name="english_ime_settings" msgid="6661589557206947774">"Setelan keyboard Android"</string> -->
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Opsi masukan"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"Getar jika tombol ditekan"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"Berbunyi jika tombol ditekan"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"Muncul saat tombol ditekan"</string>
+ <string name="hit_correction" msgid="4855351009261318389">"Perbaiki kesalahan ketik"</string>
+ <string name="hit_correction_summary" msgid="8761701873008070796">"Aktifkan perbaikan galat masukan"</string>
+ <string name="hit_correction_land" msgid="2567691684825205448">"Galat masukan lanskap"</string>
+ <string name="hit_correction_land_summary" msgid="4076803842198368328">"Aktifkan perbaikan galat masukan"</string>
+ <string name="auto_correction" msgid="7911639788808958255">"Saran kata"</string>
+ <string name="auto_correction_summary" msgid="6881047311475758267">"Perbaiki kata sebelumnya secara otomatis"</string>
+ <string name="prediction" msgid="466220283138359837">"Saran kata"</string>
+ <string name="prediction_category" msgid="7027100625580696660">"Setelan saran kata"</string>
+ <string name="prediction_summary" msgid="459788228830873110">"Aktifkan pengisian otomatis saat mengetik"</string>
+ <string name="auto_complete_dialog_title" msgid="2172048590607201920">"Pengisian otomatis"</string>
+ <string name="prediction_landscape" msgid="4874601565593216183">"Tambah ukuran bidang teks"</string>
+ <string name="prediction_landscape_summary" msgid="6736551095997839472">"Sembunyikan saran kata dalam tampilan melintang"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"Kapitalisasi otomatis"</string>
+ <string name="auto_cap_summary" msgid="3260681697600786825">"Kapitalisasi awal kalimat"</string>
+ <string name="auto_punctuate" msgid="7276672334264521751">"Beri tanda baca otomatis"</string>
+ <string name="auto_punctuate_summary" msgid="6589441565817502132"></string>
+ <string name="quick_fixes" msgid="5353213327680897927">"Perbaikan cepat"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"Memperbaiki kesalahan ketik umum"</string>
+ <string name="show_suggestions" msgid="507074425254289133">"Perlihatkan saran"</string>
+ <string name="show_suggestions_summary" msgid="1989672863935759654">"Tampilkan kata yang disarankan ketika mengetik"</string>
+ <string name="auto_complete" msgid="1103196318775486023">"Pengisian otomatis"</string>
+ <string name="auto_complete_summary" msgid="6113149638718274624">"Bilah spasi dan tanda baca secara otomatis memasukkan kata yang disorot"</string>
+ <string name="prefs_settings_key" msgid="4623341240804046498">"Lihat tombol setelan"</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Otomatis"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Selalu tampilkan"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"Selalu sembunyikan"</string>
+ <!-- no translation found for settings_key_modes:0 (8549888726962891527) -->
+ <!-- no translation found for settings_key_modes:1 (881280041213210923) -->
+ <!-- no translation found for settings_key_modes:2 (7317310620171067848) -->
+ <string name="bigram_suggestion" msgid="1323347224043514969">"Saran Bigram"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Gunakan kata sebelumnya untuk meningkatkan sara"</string>
+ <string-array name="prediction_modes">
+ <item msgid="4870266572388153286">"Tak Satu Pun"</item>
+ <item msgid="1669461741568287396">"Dasar"</item>
+ <item msgid="4894328801530136615">"Lanjutan"</item>
+ </string-array>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Telah disimpan"</string>
+ <string name="tip_long_press" msgid="6101270866284343344">"Tahan tombol untuk melihat aksen (ø, ö, dll.)"</string>
+ <string name="tip_dismiss" msgid="7585579046862204381">"Tekan tombol kembali ↶ untuk menutup keyboard kapan saja"</string>
+ <string name="tip_access_symbols" msgid="6344098517525531652">"Akses angka dan simbol"</string>
+ <string name="tip_add_to_dictionary" msgid="1487293888469227817">"Tekan terus kata yang paling kiri untuk menambahkannya ke kamus"</string>
+ <string name="touch_to_continue" msgid="7869803257948414531">"Sentuh petunjuk ini untuk melanjutkan »"</string>
+ <string name="touch_to_finish" msgid="7990196086480585789">"Sentuh di sini untuk menutup petunjuk dan mulailah mengetik!"</string>
+ <string name="tip_to_open_keyboard" msgid="6821200275486950452"><b>"Keyboard terbuka setiap kali Anda menyentuh bidang teks"</b></string>
+ <string name="tip_to_view_accents" msgid="5433158573693308501"><b>"Sentuh &amp; tahan tombol untuk melihat aksen"\n"(ø, ö, ô, ó, dan seterusnya)"</b></string>
+ <string name="tip_to_open_symbols" msgid="7345139325622444880"><b>"Beralih ke angka dan simbol dengan menekan tombol ini"</b></string>
+ <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"Kembali ke huruf dengan menekan tombol ini lagi"</b></string>
+ <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"Sentuh &amp; tahan tombol ini untuk mengubah setelan keyboard, seperti lengkapi otomatis"</b></string>
+ <string name="tip_to_start_typing" msgid="7213843601369174313"><b>"Cobalah!"</b></string>
+ <string name="label_go_key" msgid="1635148082137219148">"Buka"</string>
+ <string name="label_next_key" msgid="362972844525672568">"Berikutnya"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"Selesai"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"Kirimkan"</string>
+ <string name="label_symbol_key" msgid="6175820506864489453">"?123"</string>
+ <string name="label_phone_key" msgid="4275497665515080551">"123"</string>
+ <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string>
+ <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string>
+ <string name="voice_warning_title" msgid="4419354150908395008">"Masukan suara"</string>
+ <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Masukan suara saat ini tidak didukung untuk bahasa Anda, tetapi bekerja dalam Bahasa Inggris."</string>
+ <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"Masukan suara adalah fitur eksperimental yang menggunakan pengenal suara berjaringan Google."</string>
+ <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"Untuk mematikan masukan suara, buka setelan keyboard."</string>
+ <string name="voice_hint_dialog_message" msgid="6892342981545727994">"Untuk menggunakan masukan suara, tekan tombol mikrofon atau geser jari Anda di sepanjang keyboard pada layar."</string>
+ <string name="voice_listening" msgid="467518160751321844">"Ucapkan sekarang"</string>
+ <string name="voice_working" msgid="6666937792815731889">"Bekerja"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"Galat: Coba lagi."</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"Tidak dapat menyambung"</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"Galat, terlalu banyak ucapan."</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"Masalah audio"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"Galat server"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"Tidak terdengar ucapan"</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"Tak ditemukan yang cocok"</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"Penelusuran suara tidak terpasang"</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Petunjuk:"</b>" Gesek keyboard untuk berbicara"</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Petunjuk:"</b>" Selanjutnya, coba ucapkan tanda baca seperti \"titik\", \"koma\", atau \"tanda tanya\"."</string>
+ <string name="cancel" msgid="6830980399865683324">"Batal"</string>
+ <string name="ok" msgid="7898366843681727667">"OK"</string>
+ <string name="voice_input" msgid="2466640768843347841">"Masukan suara"</string>
+ <string-array name="voice_input_modes">
+ <item msgid="1349082139076086774">"Di keyboard utama"</item>
+ <item msgid="8529385602829095903">"Di keyboard simbol"</item>
+ <item msgid="7283103513488381103">"Mati"</item>
+ </string-array>
+ <string-array name="voice_input_modes_summary">
+ <item msgid="554248625705084903">"Mik di keyboard utama"</item>
+ <item msgid="6907837061058876770">"Mik di keyboard simbol"</item>
+ <item msgid="3664304608587798036">"Masukan suara dinonaktifkan"</item>
+ </string-array>
+ <string name="auto_submit" msgid="9151008027068358518">"Kirim otomatis setelah suara"</string>
+ <string name="auto_submit_summary" msgid="4961875269610384226">"Tekan enter secara otomatis saat menelusuri atau menuju ke bidang berikutnya."</string>
+ <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Buka keyboard"\n</b></font><font size="3">\n</font>"Sentuh bidang teks mana pun."</string>
+ <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Tutup keyboard"\n</b></font><font size="3">\n</font>"Tekan tombol Kembali."</string>
+ <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Sentuh &amp; tahan tombol tertentu untuk opsi"\n</b></font><font size="3">\n</font>"Akses tanda baca dan aksen."</string>
+ <string name="keyboard_settings" msgid="4585753477617374032"><font size="17"><b>"Setelan keyboard"\n</b></font><font size="3">\n</font>"Sentuh &amp; tahan tombol "<b>"?123"</b>"."</string>
+ <string name="popular_domain_0" msgid="3745279225122472969">".com"</string>
+ <string name="popular_domain_1" msgid="1370572248164278467">".net"</string>
+ <string name="popular_domain_2" msgid="3036812463748402878">".org"</string>
+ <string name="popular_domain_3" msgid="8718639560809452028">".gov"</string>
+ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"Pilih metode masukan"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Bahasa masukan"</string>
+ <string name="language_selection_summary" msgid="187110938289512256">"Geser jari pada bilah spasi untuk mengubah bahasa"</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Sentuh sekali lagi untuk menyimpan"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"Kamus yang tersedia"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"Aktifkan umpan balik pengguna"</string>
+ <string name="prefs_description_log" msgid="5827825607258246003">"Bantu tingkatkan metode editor masukan dengan mengirim statistik penggunaan dan laporan kerusakan ke Google secara otomatis."</string>
+ <string name="prefs_enable_recorrection" msgid="4588408906649533582">"Sentuh untuk memperbaiki kata"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="1056068922330206170">"Sentuh kata yang dimasukkan untuk memperbaikinya"</string>
+ <string name="keyboard_layout" msgid="437433231038683666">"Tema Keyboard"</string>
+ <string name="subtype_mode_keyboard" msgid="2242090416595003881">"keyboard"</string>
+ <string name="subtype_mode_voice" msgid="4394113125441627771">"suara"</string>
+</resources>
diff --git a/java/res/values-it/donottranslate-altchars.xml b/java/res/values-it/donottranslate-altchars.xml
new file mode 100644
index 0000000..55116ad
--- /dev/null
+++ b/java/res/values-it/donottranslate-altchars.xml
@@ -0,0 +1,30 @@
+<?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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="alternates_for_a">àá</string>
+ <string name="alternates_for_e">3èé</string>
+ <string name="alternates_for_i">8ïîíì</string>
+ <string name="alternates_for_o">9óò</string>
+ <string name="alternates_for_u">7üûúù</string>
+ <string name="alternates_for_s">§</string>
+ <string name="alternates_for_n">ñ</string>
+ <string name="alternates_for_c">ç</string>
+ <string name="alternates_for_y">6ÿý</string>
+</resources>
diff --git a/java/res/values-it/donottranslate-keymap.xml b/java/res/values-it/donottranslate-keymap.xml
new file mode 100644
index 0000000..dbb4e7e
--- /dev/null
+++ b/java/res/values-it/donottranslate-keymap.xml
@@ -0,0 +1,221 @@
+<?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.
+**
+**
+** 5-row layout for Spanish.
+**
+** See http://code.google.com/p/hackerskeyboard/wiki/AddingNewLayouts for
+** more information.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="key_tlde_main">\\</string>
+ <string name="key_tlde_shift">|</string>
+ <string name="key_tlde_alt">¬¦</string>
+
+ <string name="key_ae01_main">1</string>
+ <string name="key_ae01_shift">!</string>
+ <string name="key_ae01_alt">¹¡</string>
+
+ <string name="key_ae02_main">2</string>
+ <string name="key_ae02_shift">\"</string>
+ <string name="key_ae02_alt">²&#x030B;</string>
+
+ <string name="key_ae03_main">3</string>
+ <string name="key_ae03_shift">£</string>
+ <string name="key_ae03_alt">#³&#x0303;</string>
+
+ <string name="key_ae04_main">4</string>
+ <string name="key_ae04_shift">$</string>
+ <string name="key_ae04_alt">¼⅛</string>
+
+ <string name="key_ae05_main">5</string>
+ <string name="key_ae05_shift">%</string>
+ <string name="key_ae05_alt">½⅜</string>
+
+ <string name="key_ae06_main">6</string>
+ <string name="key_ae06_shift">&amp;</string>
+ <string name="key_ae06_alt">¬⅝</string>
+
+ <string name="key_ae07_main">7</string>
+ <string name="key_ae07_shift">/</string>
+ <string name="key_ae07_alt">{⅞</string>
+
+ <string name="key_ae08_main">8</string>
+ <string name="key_ae08_shift">(</string>
+ <string name="key_ae08_alt">[™</string>
+
+ <string name="key_ae09_main">9</string>
+ <string name="key_ae09_shift">)</string>
+ <string name="key_ae09_alt">]±</string>
+
+ <string name="key_ae10_main">0</string>
+ <string name="key_ae10_shift">=</string>
+ <string name="key_ae10_alt">}&#x0328;</string>
+
+ <string name="key_ae11_main">\'</string>
+ <string name="key_ae11_shift">\?</string>
+ <string name="key_ae11_alt">`¿</string>
+
+ <string name="key_ae12_main">ì</string>
+ <string name="key_ae12_shift">^</string>
+ <string name="key_ae12_alt">~&#x0302;</string>
+
+
+ <string name="key_ad01_main">q</string>
+ <string name="key_ad01_shift">Q</string>
+ <string name="key_ad01_alt">\@Ω</string>
+
+ <string name="key_ad02_main">w</string>
+ <string name="key_ad02_shift">W</string>
+ <string name="key_ad02_alt">łŁ</string>
+
+ <string name="key_ad03_main">e</string>
+ <string name="key_ad03_shift">E</string>
+ <string name="key_ad03_alt">€¢</string>
+
+ <string name="key_ad04_main">r</string>
+ <string name="key_ad04_shift">R</string>
+ <string name="key_ad04_alt">¶®</string>
+
+ <string name="key_ad05_main">t</string>
+ <string name="key_ad05_shift">T</string>
+ <string name="key_ad05_alt">ŧŦ</string>
+
+ <string name="key_ad06_main">y</string>
+ <string name="key_ad06_shift">Y</string>
+ <string name="key_ad06_alt">←¥</string>
+
+ <string name="key_ad07_main">u</string>
+ <string name="key_ad07_shift">U</string>
+ <string name="key_ad07_alt">↓↑</string>
+
+ <string name="key_ad08_main">i</string>
+ <string name="key_ad08_shift">I</string>
+ <string name="key_ad08_alt">→ı</string>
+
+ <string name="key_ad09_main">o</string>
+ <string name="key_ad09_shift">O</string>
+ <string name="key_ad09_alt">øØ</string>
+
+ <string name="key_ad10_main">p</string>
+ <string name="key_ad10_shift">P</string>
+ <string name="key_ad10_alt">þÞ</string>
+
+ <string name="key_ad11_main">è</string>
+ <string name="key_ad11_shift">é</string>
+ <string name="key_ad11_alt">[{</string>
+
+ <string name="key_ad12_main">+</string>
+ <string name="key_ad12_shift">*</string>
+ <string name="key_ad12_alt">]}</string>
+
+ <string name="key_bksl_main">ù</string>
+ <string name="key_bksl_shift">§</string>
+ <string name="key_bksl_alt">&#x0300;&#x0306;</string>
+
+
+ <string name="key_ac01_main">a</string>
+ <string name="key_ac01_shift">A</string>
+ <string name="key_ac01_alt">æÆ</string>
+
+ <string name="key_ac02_main">s</string>
+ <string name="key_ac02_shift">S</string>
+ <string name="key_ac02_alt">ߧ</string>
+
+ <string name="key_ac03_main">d</string>
+ <string name="key_ac03_shift">D</string>
+ <string name="key_ac03_alt">ðÐ</string>
+
+ <string name="key_ac04_main">f</string>
+ <string name="key_ac04_shift">F</string>
+ <string name="key_ac04_alt">đª</string>
+
+ <string name="key_ac05_main">g</string>
+ <string name="key_ac05_shift">G</string>
+ <string name="key_ac05_alt">ŋŊ</string>
+
+ <string name="key_ac06_main">h</string>
+ <string name="key_ac06_shift">H</string>
+ <string name="key_ac06_alt">ħĦ</string>
+
+ <string name="key_ac07_main">j</string>
+ <string name="key_ac07_shift">J</string>
+ <string name="key_ac07_alt">jJ</string>
+
+ <string name="key_ac08_main">k</string>
+ <string name="key_ac08_shift">K</string>
+ <string name="key_ac08_alt">ĸ&amp;</string>
+
+ <string name="key_ac09_main">l</string>
+ <string name="key_ac09_shift">L</string>
+ <string name="key_ac09_alt">łŁ</string>
+
+ <string name="key_ac10_main">ò</string>
+ <string name="key_ac10_shift">ç</string>
+ <string name="key_ac10_alt">\@&#x0327;</string>
+
+ <string name="key_ac11_main">à</string>
+ <string name="key_ac11_shift">°</string>
+ <string name="key_ac11_alt">#&#x030A;</string>
+
+
+ <string name="key_lsgt_main">&lt;</string>
+ <string name="key_lsgt_shift">&gt;</string>
+ <string name="key_lsgt_alt">«»</string>
+
+ <string name="key_ab01_main">z</string>
+ <string name="key_ab01_shift">Z</string>
+ <string name="key_ab01_alt">«</string>
+
+ <string name="key_ab02_main">x</string>
+ <string name="key_ab02_shift">X</string>
+ <string name="key_ab02_alt">»</string>
+
+ <string name="key_ab03_main">c</string>
+ <string name="key_ab03_shift">C</string>
+ <string name="key_ab03_alt">¢©</string>
+
+ <string name="key_ab04_main">v</string>
+ <string name="key_ab04_shift">V</string>
+ <string name="key_ab04_alt">“‘</string>
+
+ <string name="key_ab05_main">b</string>
+ <string name="key_ab05_shift">B</string>
+ <string name="key_ab05_alt">”’</string>
+
+ <string name="key_ab06_main">n</string>
+ <string name="key_ab06_shift">N</string>
+ <string name="key_ab06_alt">ñÑ</string>
+
+ <string name="key_ab07_main">m</string>
+ <string name="key_ab07_shift">M</string>
+ <string name="key_ab07_alt">µº</string>
+
+ <string name="key_ab08_main">,</string>
+ <string name="key_ab08_shift">;</string>
+ <string name="key_ab08_alt">&#x0301;×</string>
+
+ <string name="key_ab09_main">.</string>
+ <string name="key_ab09_shift">:</string>
+ <string name="key_ab09_alt">·&#x0308;</string>
+
+ <string name="key_ab10_main">-</string>
+ <string name="key_ab10_shift">_</string>
+ <string name="key_ab10_alt">&#x0304;÷</string>
+</resources>
diff --git a/java/res/values-it/donottranslate.xml b/java/res/values-it/donottranslate.xml
new file mode 100644
index 0000000..3e3f3ef
--- /dev/null
+++ b/java/res/values-it/donottranslate.xml
@@ -0,0 +1,23 @@
+<?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 commonly considered word separators in this language -->
+ <string name="word_separators">.\u0009\u0020,;:!?\'\n()[]*&amp;@{}/&lt;&gt;_+=|\u0022</string>
+</resources>
diff --git a/java/res/values-it/strings.xml b/java/res/values-it/strings.xml
new file mode 100644
index 0000000..7b79f0f
--- /dev/null
+++ b/java/res/values-it/strings.xml
@@ -0,0 +1,140 @@
+<?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/org.pocketworkstation.pckeyboard"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- <string name="english_ime_name" msgid="7252517407088836577">"Tastiera Android"</string> -->
+ <!-- <string name="english_ime_settings" msgid="6661589557206947774">"Impostazioni tastiera Android"</string> -->
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Opzioni inserimento"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrazione tasti"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"Suono tasti"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"Popup alla pressione di un tasto"</string>
+ <string name="hit_correction" msgid="4855351009261318389">"Correggi errori di digitazione"</string>
+ <string name="hit_correction_summary" msgid="8761701873008070796">"Attiva la correzione degli errori di inserimento"</string>
+ <string name="hit_correction_land" msgid="2567691684825205448">"Errori di inserimento in visualizzazione orizzontale"</string>
+ <string name="hit_correction_land_summary" msgid="4076803842198368328">"Attiva la correzione degli errori di inserimento"</string>
+ <string name="auto_correction" msgid="7911639788808958255">"Suggerimenti parola"</string>
+ <string name="auto_correction_summary" msgid="6881047311475758267">"Correggi automaticamente la parola precedente"</string>
+ <string name="prediction" msgid="466220283138359837">"Suggerimenti parola"</string>
+ <string name="prediction_category" msgid="7027100625580696660">"Impostazioni suggerimento parole"</string>
+ <string name="prediction_summary" msgid="459788228830873110">"Attiva il completamento automatico durante la digitazione"</string>
+ <string name="auto_complete_dialog_title" msgid="2172048590607201920">"Completamento automatico"</string>
+ <string name="prediction_landscape" msgid="4874601565593216183">"Aumenta dimensioni campo di testo"</string>
+ <string name="prediction_landscape_summary" msgid="6736551095997839472">"Nascondi i suggerimenti delle parole in visualizzazione orizzontale"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"Maiuscole automatiche"</string>
+ <string name="auto_cap_summary" msgid="3260681697600786825">"Rendi maiuscole le iniziali delle frasi"</string>
+ <string name="auto_punctuate" msgid="7276672334264521751">"Punteggiatura automat."</string>
+ <string name="auto_punctuate_summary" msgid="6589441565817502132"></string>
+ <string name="quick_fixes" msgid="5353213327680897927">"Correzioni veloci"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"Corregge gli errori di digitazione più comuni"</string>
+ <string name="show_suggestions" msgid="507074425254289133">"Mostra suggerimenti"</string>
+ <string name="show_suggestions_summary" msgid="1989672863935759654">"Visualizza le parole suggerite durante la digitazione"</string>
+ <string name="auto_complete" msgid="1103196318775486023">"Completamento autom."</string>
+ <string name="auto_complete_summary" msgid="6113149638718274624">"Barra spaziatrice e punteggiatura inseriscono la parola evidenziata"</string>
+ <string name="prefs_settings_key" msgid="4623341240804046498">"Mostra tasto impostazioni"</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automatico"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Mostra sempre"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"Nascondi sempre"</string>
+ <!-- no translation found for settings_key_modes:0 (8549888726962891527) -->
+ <!-- no translation found for settings_key_modes:1 (881280041213210923) -->
+ <!-- no translation found for settings_key_modes:2 (7317310620171067848) -->
+ <string name="bigram_suggestion" msgid="1323347224043514969">"Suggerimenti sui bigrammi"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Utilizza parola precedente per migliorare il suggerimento"</string>
+ <string-array name="prediction_modes">
+ <item msgid="4870266572388153286">"Nessuna"</item>
+ <item msgid="1669461741568287396">"Base"</item>
+ <item msgid="4894328801530136615">"Avanzate"</item>
+ </string-array>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : parola salvata"</string>
+ <string name="tip_long_press" msgid="6101270866284343344">"Tieni premuto un tasto per vedere le lettere con segni diacritici (ø, ö etc.)"</string>
+ <string name="tip_dismiss" msgid="7585579046862204381">"Premi il tasto Indietro ↶ per chiudere la tastiera"</string>
+ <string name="tip_access_symbols" msgid="6344098517525531652">"Accedi a numeri e simboli"</string>
+ <string name="tip_add_to_dictionary" msgid="1487293888469227817">"Tieni premuto sulla parola all\'estrema sinistra per aggiungerla al dizionario"</string>
+ <string name="touch_to_continue" msgid="7869803257948414531">"Tocca questo suggerimento per continuare »"</string>
+ <string name="touch_to_finish" msgid="7990196086480585789">"Tocca qui per chiudere questo suggerimento e iniziare a digitare."</string>
+ <string name="tip_to_open_keyboard" msgid="6821200275486950452"><b>"La tastiera si apre ogni volta che tocchi un campo di testo"</b></string>
+ <string name="tip_to_view_accents" msgid="5433158573693308501"><b>"Tocca e tieni premuto un pulsante per visualizzare le lettere con segni diacritici"\n"(ø, ö, ô, ó e così via)"</b></string>
+ <string name="tip_to_open_symbols" msgid="7345139325622444880"><b>"Passa a numeri e simboli toccando questo pulsante"</b></string>
+ <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"Torna alle lettere toccando di nuovo questo pulsante"</b></string>
+ <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"Tocca e tieni premuto questo pulsante per modificare le impostazioni della tastiera, come il completamento automatico"</b></string>
+ <string name="tip_to_start_typing" msgid="7213843601369174313"><b>"Prova!"</b></string>
+ <string name="label_go_key" msgid="1635148082137219148">"Vai"</string>
+ <string name="label_next_key" msgid="362972844525672568">"Avanti"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"Fine"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"Invia"</string>
+ <string name="label_symbol_key" msgid="6175820506864489453">"?123"</string>
+ <string name="label_phone_key" msgid="4275497665515080551">"123"</string>
+ <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string>
+ <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string>
+ <string name="voice_warning_title" msgid="4419354150908395008">"Comandi vocali"</string>
+ <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"I comandi vocali non sono attualmente supportati per la tua lingua ma funzionano in inglese."</string>
+ <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"I comandi vocali sono una funzione sperimentale che utilizza il riconoscimento vocale in rete di Google."</string>
+ <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"Per disattivare i comandi vocali, vai alle impostazioni della tastiera."</string>
+ <string name="voice_hint_dialog_message" msgid="6892342981545727994">"Per utilizzare i comandi vocali, premi il pulsante del microfono o fai scorrere il dito sulla tastiera sullo schermo."</string>
+ <string name="voice_listening" msgid="467518160751321844">"Parla ora"</string>
+ <string name="voice_working" msgid="6666937792815731889">"Elaborazione in corso"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"Errore. Riprova più tardi."</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"Impossibile connettersi."</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"Errore: conversazione troppo lunga."</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"Problema audio"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"Errore del server"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"Nessuna frase vocale rilevata"</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"Nessuna corrispondenza trovata"</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"Ricerca vocale non installata"</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Suggerimento."</b>" Fai scorrere il dito sulla tastiera per parlare"</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Suggerimento."</b>" La prossima volta, prova a pronunciare termini relativi alla punteggiatura come \"punto\", \"virgola\" o \"punto di domanda\"."</string>
+ <string name="cancel" msgid="6830980399865683324">"Annulla"</string>
+ <string name="ok" msgid="7898366843681727667">"OK"</string>
+ <string name="voice_input" msgid="2466640768843347841">"Comandi vocali"</string>
+ <string-array name="voice_input_modes">
+ <item msgid="1349082139076086774">"Su tastiera principale"</item>
+ <item msgid="8529385602829095903">"Su tastiera simboli"</item>
+ <item msgid="7283103513488381103">"Non attivi"</item>
+ </string-array>
+ <string-array name="voice_input_modes_summary">
+ <item msgid="554248625705084903">"Microfono su tastiera principale"</item>
+ <item msgid="6907837061058876770">"Microfono su tastiera simboli"</item>
+ <item msgid="3664304608587798036">"Comandi vocali disabilitati"</item>
+ </string-array>
+ <string name="auto_submit" msgid="9151008027068358518">"Invia automaticamente dopo comando vocale"</string>
+ <string name="auto_submit_summary" msgid="4961875269610384226">"Premi automaticamente \"Invio\" durante una ricerca o un passaggio al campo successivo."</string>
+ <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Apertura tastiera"\n</b></font><font size="3">\n</font>"Tocca qualsiasi campo di testo."</string>
+ <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Chiusura tastiera"\n</b></font><font size="3">\n</font>"Premi il tasto Indietro."</string>
+ <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Tocca e tieni premuto un pulsante per le opzioni"\n</b></font><font size="3">\n</font>"Accesso a punteggiatura e accenti."</string>
+ <string name="keyboard_settings" msgid="4585753477617374032"><font size="17"><b>"Impostazioni tastiera"\n</b></font><font size="3">\n</font>"Tocca e tieni premuto il pulsante "<b>"?123"</b>"."</string>
+ <string name="popular_domain_0" msgid="3745279225122472969">".com"</string>
+ <string name="popular_domain_1" msgid="1370572248164278467">".net"</string>
+ <string name="popular_domain_2" msgid="3036812463748402878">".org"</string>
+ <string name="popular_domain_3" msgid="8718639560809452028">".gov"</string>
+ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"Seleziona metodo di inserimento"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Lingue comandi"</string>
+ <string name="language_selection_summary" msgid="187110938289512256">"Scorri il dito sulla barra spaziatrice per cambiare la lingua"</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Tocca di nuovo per salvare"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"Dizionario disponibile"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"Attiva commenti degli utenti"</string>
+ <string name="prefs_description_log" msgid="5827825607258246003">"Aiuta a migliorare l\'editor del metodo di inserimento inviando automaticamente a Google statistiche sull\'utilizzo e segnalazioni sugli arresti anomali."</string>
+ <string name="prefs_enable_recorrection" msgid="4588408906649533582">"Tocca per correggere le parole"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="1056068922330206170">"Tocca le parole inserite per correggerle"</string>
+ <string name="keyboard_layout" msgid="437433231038683666">"Tema della tastiera"</string>
+ <string name="subtype_mode_keyboard" msgid="2242090416595003881">"tastiera"</string>
+ <string name="subtype_mode_voice" msgid="4394113125441627771">"vocale"</string>
+</resources>
diff --git a/java/res/values-iw/bools.xml b/java/res/values-iw/bools.xml
new file mode 100644
index 0000000..126c437
--- /dev/null
+++ b/java/res/values-iw/bools.xml
@@ -0,0 +1,22 @@
+<?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>
+ <bool name="default_auto_cap">false</bool>
+</resources>
diff --git a/java/res/values-iw/donottranslate-altchars.xml b/java/res/values-iw/donottranslate-altchars.xml
new file mode 100644
index 0000000..d2ae8c6
--- /dev/null
+++ b/java/res/values-iw/donottranslate-altchars.xml
@@ -0,0 +1,47 @@
+<?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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="alternates_for_a">aáàâãäå</string>
+ <string name="alternates_for_b">b</string>
+ <string name="alternates_for_c">cçčć¢</string>
+ <string name="alternates_for_d">dđ</string>
+ <string name="alternates_for_e">3eéèêëē€</string>
+ <string name="alternates_for_f">f₣</string>
+ <string name="alternates_for_g">g</string>
+ <string name="alternates_for_h">h</string>
+ <string name="alternates_for_i">8iíìîïī</string>
+ <string name="alternates_for_j">j</string>
+ <string name="alternates_for_k">k</string>
+ <string name="alternates_for_l">l£₤λ</string>
+ <string name="alternates_for_m">mμ</string>
+ <string name="alternates_for_n">nñ</string>
+ <string name="alternates_for_o">9oóòôõö</string>
+ <string name="alternates_for_p">0pπ₱</string>
+ <string name="alternates_for_q">1q</string>
+ <string name="alternates_for_r">4r</string>
+ <string name="alternates_for_s">s§ßš</string>
+ <string name="alternates_for_t">5t</string>
+ <string name="alternates_for_u">7uúùûü</string>
+ <string name="alternates_for_v">v</string>
+ <string name="alternates_for_w">2w`</string>
+ <string name="alternates_for_x">x</string>
+ <string name="alternates_for_y">6yýÿ¥</string>
+ <string name="alternates_for_z">zž</string>
+</resources>
diff --git a/java/res/values-iw/donottranslate-keymap.xml b/java/res/values-iw/donottranslate-keymap.xml
new file mode 100644
index 0000000..5bff5d2
--- /dev/null
+++ b/java/res/values-iw/donottranslate-keymap.xml
@@ -0,0 +1,217 @@
+<?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.
+**
+**
+** 5-row layout for Hebrew.
+**
+** See http://code.google.com/p/hackerskeyboard/wiki/AddingNewLayouts for
+** more information.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="key_tlde_main">;</string>
+ <string name="key_tlde_shift">~</string>
+ <string name="key_tlde_alt">;~</string>
+
+ <string name="key_ae01_main">1</string>
+ <string name="key_ae01_shift">!</string>
+ <string name="key_ae01_alt">1!¡¹½⅓¼⅛</string>
+
+ <string name="key_ae02_main">2</string>
+ <string name="key_ae02_shift">\@</string>
+ <string name="key_ae02_alt">2\@²⅔</string>
+
+ <string name="key_ae03_main">3</string>
+ <string name="key_ae03_shift">#</string>
+ <string name="key_ae03_alt">3#³¾⅜♥♠♦♣</string>
+
+ <string name="key_ae04_main">4</string>
+ <string name="key_ae04_shift">$</string>
+ <string name="key_ae04_alt">4$⁴¢£€¥</string>
+
+ <string name="key_ae05_main">5</string>
+ <string name="key_ae05_shift">%</string>
+ <string name="key_ae05_alt">5%⅝‰</string>
+
+ <string name="key_ae06_main">6</string>
+ <string name="key_ae06_shift">^</string>
+ <string name="key_ae06_alt">6^↑↓←→</string>
+
+ <string name="key_ae07_main">7</string>
+ <string name="key_ae07_shift">&amp;</string>
+ <string name="key_ae07_alt">7&amp;⅞♪</string>
+
+ <string name="key_ae08_main">8</string>
+ <string name="key_ae08_shift">*</string>
+ <string name="key_ae08_alt">8*•★∞†‡</string>
+
+ <string name="key_ae09_main">9</string>
+ <string name="key_ae09_shift">)</string>
+ <string name="key_ae09_alt">9)√</string>
+
+ <string name="key_ae10_main">0</string>
+ <string name="key_ae10_shift">(</string>
+ <string name="key_ae10_alt">0(ⁿ°</string>
+
+ <string name="key_ae11_main">-</string>
+ <string name="key_ae11_shift">_</string>
+ <string name="key_ae11_alt">-_—–</string>
+
+ <string name="key_ae12_main">=</string>
+ <string name="key_ae12_shift">+</string>
+ <string name="key_ae12_alt">=+≈≠±×÷</string>
+
+
+ <string name="key_ad01_main">/</string>
+ <string name="key_ad01_shift">Q</string>
+ <string name="key_ad01_alt">@string/alternates_for_q</string>
+
+ <string name="key_ad02_main">\'</string>
+ <string name="key_ad02_shift">W</string>
+ <string name="key_ad02_alt">@string/alternates_for_w</string>
+
+ <string name="key_ad03_main">ק</string>
+ <string name="key_ad03_shift">E</string>
+ <string name="key_ad03_alt">@string/alternates_for_e</string>
+
+ <string name="key_ad04_main">ר</string>
+ <string name="key_ad04_shift">R</string>
+ <string name="key_ad04_alt">@string/alternates_for_r</string>
+
+ <string name="key_ad05_main">א</string>
+ <string name="key_ad05_shift">T</string>
+ <string name="key_ad05_alt">@string/alternates_for_t</string>
+
+ <string name="key_ad06_main">ט</string>
+ <string name="key_ad06_shift">Y</string>
+ <string name="key_ad06_alt">@string/alternates_for_y</string>
+
+ <string name="key_ad07_main">ו</string>
+ <string name="key_ad07_shift">U</string>
+ <string name="key_ad07_alt">@string/alternates_for_u</string>
+
+ <string name="key_ad08_main">ן</string>
+ <string name="key_ad08_shift">I</string>
+ <string name="key_ad08_alt">@string/alternates_for_i</string>
+
+ <string name="key_ad09_main">ם</string>
+ <string name="key_ad09_shift">O</string>
+ <string name="key_ad09_alt">@string/alternates_for_o</string>
+
+ <string name="key_ad10_main">פ</string>
+ <string name="key_ad10_shift">P</string>
+ <string name="key_ad10_alt">@string/alternates_for_p</string>
+
+ <string name="key_ad11_main">]</string>
+ <string name="key_ad11_shift">}</string>
+ <string name="key_ad11_alt">]}</string>
+
+ <string name="key_ad12_main">[</string>
+ <string name="key_ad12_shift">{</string>
+ <string name="key_ad12_alt">[{</string>
+
+ <string name="key_bksl_main">\\</string>
+ <string name="key_bksl_shift">|</string>
+ <string name="key_bksl_alt">\\|</string>
+
+
+ <string name="key_ac01_main">ש</string>
+ <string name="key_ac01_shift">A</string>
+ <string name="key_ac01_alt">@string/alternates_for_a</string>
+
+ <string name="key_ac02_main">ד</string>
+ <string name="key_ac02_shift">S</string>
+ <string name="key_ac02_alt">@string/alternates_for_s</string>
+
+ <string name="key_ac03_main">ג</string>
+ <string name="key_ac03_shift">D</string>
+ <string name="key_ac03_alt">@string/alternates_for_d</string>
+
+ <string name="key_ac04_main">כ</string>
+ <string name="key_ac04_shift">F</string>
+ <string name="key_ac04_alt">@string/alternates_for_f</string>
+
+ <string name="key_ac05_main">ע</string>
+ <string name="key_ac05_shift">G</string>
+ <string name="key_ac05_alt">@string/alternates_for_g</string>
+
+ <string name="key_ac06_main">י</string>
+ <string name="key_ac06_shift">H</string>
+ <string name="key_ac06_alt">@string/alternates_for_h</string>
+
+ <string name="key_ac07_main">ח</string>
+ <string name="key_ac07_shift">J</string>
+ <string name="key_ac07_alt">@string/alternates_for_j</string>
+
+ <string name="key_ac08_main">ל</string>
+ <string name="key_ac08_shift">K</string>
+ <string name="key_ac08_alt">@string/alternates_for_k</string>
+
+ <string name="key_ac09_main">ך</string>
+ <string name="key_ac09_shift">L</string>
+ <string name="key_ac09_alt">@string/alternates_for_l</string>
+
+ <string name="key_ac10_main">ף</string>
+ <string name="key_ac10_shift">:</string>
+ <string name="key_ac10_alt">ף:</string>
+
+ <string name="key_ac11_main">,</string>
+ <string name="key_ac11_shift">\"</string>
+ <string name="key_ac11_alt">,\"‘’“”</string>
+
+
+ <string name="key_ab01_main">ז</string>
+ <string name="key_ab01_shift">Z</string>
+ <string name="key_ab01_alt">@string/alternates_for_z</string>
+
+ <string name="key_ab02_main">ס</string>
+ <string name="key_ab02_shift">X</string>
+ <string name="key_ab02_alt">@string/alternates_for_x</string>
+
+ <string name="key_ab03_main">ב</string>
+ <string name="key_ab03_shift">C</string>
+ <string name="key_ab03_alt">@string/alternates_for_c</string>
+
+ <string name="key_ab04_main">ה</string>
+ <string name="key_ab04_shift">V</string>
+ <string name="key_ab04_alt">@string/alternates_for_v</string>
+
+ <string name="key_ab05_main">נ</string>
+ <string name="key_ab05_shift">B</string>
+ <string name="key_ab05_alt">@string/alternates_for_b</string>
+
+ <string name="key_ab06_main">מ</string>
+ <string name="key_ab06_shift">N</string>
+ <string name="key_ab06_alt">@string/alternates_for_n</string>
+
+ <string name="key_ab07_main">צ</string>
+ <string name="key_ab07_shift">M</string>
+ <string name="key_ab07_alt">@string/alternates_for_m</string>
+
+ <string name="key_ab08_main">ת</string>
+ <string name="key_ab08_shift">&gt;</string>
+ <string name="key_ab08_alt">&gt;≥»›</string>
+
+ <string name="key_ab09_main">ץ</string>
+ <string name="key_ab09_shift">&lt;</string>
+ <string name="key_ab09_alt">&lt;≤«‹</string>
+
+ <string name="key_ab10_main">.</string>
+ <string name="key_ab10_shift">\?</string>
+ <string name="key_ab10_alt">.?\?¿</string>
+</resources>
diff --git a/java/res/values-iw/strings.xml b/java/res/values-iw/strings.xml
new file mode 100644
index 0000000..54bedd3
--- /dev/null
+++ b/java/res/values-iw/strings.xml
@@ -0,0 +1,140 @@
+<?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/org.pocketworkstation.pckeyboard"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- <string name="english_ime_name" msgid="7252517407088836577">"מקלדת Android"</string> -->
+ <!-- <string name="english_ime_settings" msgid="6661589557206947774">"הגדרות מקלדת של Android"</string> -->
+ <string name="english_ime_input_options" msgid="3909945612939668554">"אפשרויות קלט"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"רטט עם לחיצה על מקשים"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"צלילים עם לחיצה על מקשים"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"חלון קופץ עם לחיצה על מקשים"</string>
+ <string name="hit_correction" msgid="4855351009261318389">"תקן שגיאות הקלדה"</string>
+ <string name="hit_correction_summary" msgid="8761701873008070796">"הפוך תיקון שגיאות קלט לפעיל"</string>
+ <string name="hit_correction_land" msgid="2567691684825205448">"שגיאות קלט בפריסה לרוחב"</string>
+ <string name="hit_correction_land_summary" msgid="4076803842198368328">"הפוך תיקון שגיאות קלט לפעיל"</string>
+ <string name="auto_correction" msgid="7911639788808958255">"הצעות למילים"</string>
+ <string name="auto_correction_summary" msgid="6881047311475758267">"תקן באופן אוטומטי את המילה הקודמת"</string>
+ <string name="prediction" msgid="466220283138359837">"הצעות למילים"</string>
+ <string name="prediction_category" msgid="7027100625580696660">"הגדרות של הצעות מילים"</string>
+ <string name="prediction_summary" msgid="459788228830873110">"הפוך השלמה אוטומטית לפעילה בעת הקלדה"</string>
+ <string name="auto_complete_dialog_title" msgid="2172048590607201920">"השלמה אוטומטית"</string>
+ <string name="prediction_landscape" msgid="4874601565593216183">"הגדל את הגודל של שדה הטקסט"</string>
+ <string name="prediction_landscape_summary" msgid="6736551095997839472">"הסתר הצעות למילים בתצוגה לרוחב"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"הפיכה אוטומטית של אותיות לרישיות"</string>
+ <string name="auto_cap_summary" msgid="3260681697600786825">"הוסף אות רישית בתחילת משפט"</string>
+ <string name="auto_punctuate" msgid="7276672334264521751">"פיסוק אוטומטי"</string>
+ <string name="auto_punctuate_summary" msgid="6589441565817502132"></string>
+ <string name="quick_fixes" msgid="5353213327680897927">"תיקונים מהירים"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"מתקן שגיאות הקלדה נפוצות"</string>
+ <string name="show_suggestions" msgid="507074425254289133">"הצג הצעות"</string>
+ <string name="show_suggestions_summary" msgid="1989672863935759654">"הצג הצעות למילים בעת הקלדה"</string>
+ <string name="auto_complete" msgid="1103196318775486023">"השלמה אוטומטית"</string>
+ <string name="auto_complete_summary" msgid="6113149638718274624">"הקשה על מקש הרווח וסימני הפיסוק תוסיף באופן אוטומטי את המילה המסומנת"</string>
+ <string name="prefs_settings_key" msgid="4623341240804046498">"הצג מקש הגדרות"</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"אוטומטי"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"הצג תמיד"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"הסתר תמיד"</string>
+ <!-- no translation found for settings_key_modes:0 (8549888726962891527) -->
+ <!-- no translation found for settings_key_modes:1 (881280041213210923) -->
+ <!-- no translation found for settings_key_modes:2 (7317310620171067848) -->
+ <string name="bigram_suggestion" msgid="1323347224043514969">"הצעות של צמדי אותיות (Bigram)"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"השתמש במילה הקודמת כדי לשפר את ההצעה"</string>
+ <string-array name="prediction_modes">
+ <item msgid="4870266572388153286">"ללא"</item>
+ <item msgid="1669461741568287396">"בסיסי"</item>
+ <item msgid="4894328801530136615">"מתקדם"</item>
+ </string-array>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : נשמרה"</string>
+ <string name="tip_long_press" msgid="6101270866284343344">"החזק מקש לחוץ כדי לראות אקצנטים (ø, ö וכדומה)"</string>
+ <string name="tip_dismiss" msgid="7585579046862204381">"לחץ על המקש \'הקודם\' ↶ כדי לסגור את המקלדת בכל עת"</string>
+ <string name="tip_access_symbols" msgid="6344098517525531652">"גישה למספרים וסמלים"</string>
+ <string name="tip_add_to_dictionary" msgid="1487293888469227817">"לחץ על המילה השמאלית הקיצונית והחזק אותה לחוצה כדי להוסיף למילון"</string>
+ <string name="touch_to_continue" msgid="7869803257948414531">"גע ברמז זה כדי להמשיך »"</string>
+ <string name="touch_to_finish" msgid="7990196086480585789">"גע כאן כדי לסגור רמז זה ולהתחיל בהקלדה!"</string>
+ <string name="tip_to_open_keyboard" msgid="6821200275486950452"><b>"המקלדת נפתחת בכל פעם שאתה נוגע בשדה טקסט"</b></string>
+ <string name="tip_to_view_accents" msgid="5433158573693308501"><b>"גע במקש והחזק אותו לחוץ כדי להציג אקצנטים"\n"(ø, ö, ô, ó וכדומה)"</b></string>
+ <string name="tip_to_open_symbols" msgid="7345139325622444880"><b>"עבור למספרים וסמלים על ידי נגיעה במקש זה"</b></string>
+ <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"חזור לאותיות על ידי מגע במקש זה שוב"</b></string>
+ <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"גע במקש זה והחזק אותו לחוץ כדי לשנות את הגדרות המקלדת, כגון השלמה אוטומטית"</b></string>
+ <string name="tip_to_start_typing" msgid="7213843601369174313"><b>"נסה אותו!"</b></string>
+ <string name="label_go_key" msgid="1635148082137219148">"בצע"</string>
+ <string name="label_next_key" msgid="362972844525672568">"הבא"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"בוצע"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"שלח"</string>
+ <string name="label_symbol_key" msgid="6175820506864489453">"?123"</string>
+ <string name="label_phone_key" msgid="4275497665515080551">"123"</string>
+ <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string>
+ <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string>
+ <string name="voice_warning_title" msgid="4419354150908395008">"קלט קולי"</string>
+ <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"קלט קולי אינו נתמך בשלב זה בשפתך, אך הוא פועל באנגלית."</string>
+ <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"קלט קולי הוא תכונה ניסיונית של זיהוי הדיבור ברשת של Google."</string>
+ <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"כדי לכבות את הקלט הקולי, עבור להגדרות מקלדת."</string>
+ <string name="voice_hint_dialog_message" msgid="6892342981545727994">"כדי להשתמש בקלט הקולי, לחץ על לחצן המיקרופון או החלק את האצבע על המקלדת שבמסך."</string>
+ <string name="voice_listening" msgid="467518160751321844">"דבר כעת"</string>
+ <string name="voice_working" msgid="6666937792815731889">"פועל"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"שגיאה. נסה שוב."</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"אין אפשרות להתחבר"</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"שגיאה, דיבור רב מדי."</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"בעיה באודיו"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"שגיאת שרת"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"לא נשמע דיבור"</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"לא נמצאו התאמות"</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"חיפוש קולי לא מותקן"</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"רמז:"</b>" העבר על המקלדת כדי לדבר"</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"רמז:"</b>" בפעם הבאה, נסה לומר את סימני הפיסוק כגון \"נקודה\", \"פסיק\" או \"סימן שאלה\"."</string>
+ <string name="cancel" msgid="6830980399865683324">"ביטול"</string>
+ <string name="ok" msgid="7898366843681727667">"אישור"</string>
+ <string name="voice_input" msgid="2466640768843347841">"קלט קולי"</string>
+ <string-array name="voice_input_modes">
+ <item msgid="1349082139076086774">"במקלדת הראשית"</item>
+ <item msgid="8529385602829095903">"מקלדת סמלים מופעלת"</item>
+ <item msgid="7283103513488381103">"כבוי"</item>
+ </string-array>
+ <string-array name="voice_input_modes_summary">
+ <item msgid="554248625705084903">"מיקרופון במקלדת הראשית"</item>
+ <item msgid="6907837061058876770">"מיקרופון במקלדת סמלים"</item>
+ <item msgid="3664304608587798036">"הקלט הקולי מושבת"</item>
+ </string-array>
+ <string name="auto_submit" msgid="9151008027068358518">"שליחה אוטומטית לאחר הקלטת קול"</string>
+ <string name="auto_submit_summary" msgid="4961875269610384226">"הקש על Enter באופן אוטומטי בעת חיפוש או מעבר לשדה הבא."</string>
+ <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"פתח את המקלדת"\n</b></font><font size="3">\n</font>"גע בשדה טקסט כלשהו."</string>
+ <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"סגור את המקלדת"\n</b></font><font size="3">\n</font>"לחץ על הלחצן \'הקודם\'."</string>
+ <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"גע במקש והחזק אותו לחוץ לקבלת אפשרויות"\n</b></font><font size="3">\n</font>"קבל גישה לסימני פיסוק ואקצנטים."</string>
+ <string name="keyboard_settings" msgid="4585753477617374032"><font size="17"><b>"הגדרות מקלדת"\n</b></font><font size="3">\n</font>"גע במקש "<b>"?123"</b>" והחזק אותו לחוץ."</string>
+ <string name="popular_domain_0" msgid="3745279225122472969">"‎.com"</string>
+ <string name="popular_domain_1" msgid="1370572248164278467">"‎.net"</string>
+ <string name="popular_domain_2" msgid="3036812463748402878">"‎.org"</string>
+ <string name="popular_domain_3" msgid="8718639560809452028">"‎.gov"</string>
+ <string name="popular_domain_4" msgid="35359437471311470">"‎.edu"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"בחר שיטת קלט"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"שפות קלט"</string>
+ <string name="language_selection_summary" msgid="187110938289512256">"החלק את האצבע על מקש הרווח כדי לשנות שפה"</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← גע שוב כדי לשמור"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"מילון זמין"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"הפוך משוב ממשתמשים לפעיל"</string>
+ <string name="prefs_description_log" msgid="5827825607258246003">"עזור לשפר שיטת קלט זו על ידי שליחה אוטומטית של סטטיסטיקת שימוש ודוחות קריסת מחשב ל-Google."</string>
+ <string name="prefs_enable_recorrection" msgid="4588408906649533582">"גע כדי לתקן מילים"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="1056068922330206170">"גע במילים שהוזנו כדי לתקן אותן"</string>
+ <string name="keyboard_layout" msgid="437433231038683666">"עיצוב מקלדת"</string>
+ <string name="subtype_mode_keyboard" msgid="2242090416595003881">"מקלדת"</string>
+ <string name="subtype_mode_voice" msgid="4394113125441627771">"קולי"</string>
+</resources>
diff --git a/java/res/values-ja/donottranslate-altchars.xml b/java/res/values-ja/donottranslate-altchars.xml
new file mode 100644
index 0000000..4074cdb
--- /dev/null
+++ b/java/res/values-ja/donottranslate-altchars.xml
@@ -0,0 +1,30 @@
+<?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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="alternates_for_a">àáâãäåæ</string>
+ <string name="alternates_for_e">3èéêë</string>
+ <string name="alternates_for_i">8ïîíì</string>
+ <string name="alternates_for_o">9øœöõôóò</string>
+ <string name="alternates_for_u">7üûúù</string>
+ <string name="alternates_for_s">§ß</string>
+ <string name="alternates_for_n">ñ</string>
+ <string name="alternates_for_c">ç</string>
+ <string name="alternates_for_y">6ÿý</string>
+</resources>
diff --git a/java/res/values-ja/strings.xml b/java/res/values-ja/strings.xml
new file mode 100644
index 0000000..d7c7d7d
--- /dev/null
+++ b/java/res/values-ja/strings.xml
@@ -0,0 +1,140 @@
+<?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/org.pocketworkstation.pckeyboard"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- <string name="english_ime_name" msgid="7252517407088836577">"Androidキーボード"</string> -->
+ <!-- <string name="english_ime_settings" msgid="6661589557206947774">"Androidキーボードの設定"</string> -->
+ <string name="english_ime_input_options" msgid="3909945612939668554">"入力オプション"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"キー操作バイブ"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"キー操作音"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"キー押下時ポップアップ"</string>
+ <string name="hit_correction" msgid="4855351009261318389">"入力ミス補正"</string>
+ <string name="hit_correction_summary" msgid="8761701873008070796">"入力間違いを自動修正する"</string>
+ <string name="hit_correction_land" msgid="2567691684825205448">"横表示での入力修正"</string>
+ <string name="hit_correction_land_summary" msgid="4076803842198368328">"入力間違いを自動修正する"</string>
+ <string name="auto_correction" msgid="7911639788808958255">"入力候補表示"</string>
+ <string name="auto_correction_summary" msgid="6881047311475758267">"前の単語を自動修正する"</string>
+ <string name="prediction" msgid="466220283138359837">"入力候補表示"</string>
+ <string name="prediction_category" msgid="7027100625580696660">"入力候補の設定"</string>
+ <string name="prediction_summary" msgid="459788228830873110">"オートコンプリートを使用する"</string>
+ <string name="auto_complete_dialog_title" msgid="2172048590607201920">"オートコンプリート"</string>
+ <string name="prediction_landscape" msgid="4874601565593216183">"入力作業スペースを広げる"</string>
+ <string name="prediction_landscape_summary" msgid="6736551095997839472">"横表示では入力候補を表示しない"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"自動大文字変換"</string>
+ <string name="auto_cap_summary" msgid="3260681697600786825">"英字入力で文頭文字を大文字にする"</string>
+ <string name="auto_punctuate" msgid="7276672334264521751">"句読点を自動入力"</string>
+ <string name="auto_punctuate_summary" msgid="6589441565817502132"></string>
+ <string name="quick_fixes" msgid="5353213327680897927">"クイックフィックス"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"よくある誤字・脱字を修正します"</string>
+ <string name="show_suggestions" msgid="507074425254289133">"入力候補を表示"</string>
+ <string name="show_suggestions_summary" msgid="1989672863935759654">"入力時に入力候補を表示する"</string>
+ <string name="auto_complete" msgid="1103196318775486023">"オートコンプリート"</string>
+ <string name="auto_complete_summary" msgid="6113149638718274624">"誤入力をスペースまたは句読点キーで修正する"</string>
+ <string name="prefs_settings_key" msgid="4623341240804046498">"設定キーを表示"</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"自動"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"常に表示"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"常に非表示"</string>
+ <!-- no translation found for settings_key_modes:0 (8549888726962891527) -->
+ <!-- no translation found for settings_key_modes:1 (881280041213210923) -->
+ <!-- no translation found for settings_key_modes:2 (7317310620171067848) -->
+ <string name="bigram_suggestion" msgid="1323347224043514969">"バイグラム入力候補表示"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"直前の単語から入力候補を予測します"</string>
+ <string-array name="prediction_modes">
+ <item msgid="4870266572388153286">"なし"</item>
+ <item msgid="1669461741568287396">"基本"</item>
+ <item msgid="4894328801530136615">"高度"</item>
+ </string-array>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>:保存しました"</string>
+ <string name="tip_long_press" msgid="6101270866284343344">"キー長押しでアクセント文字を表示(ø、öなど)"</string>
+ <string name="tip_dismiss" msgid="7585579046862204381">"戻るキーでキーボードを閉じます"</string>
+ <string name="tip_access_symbols" msgid="6344098517525531652">"数字と記号"</string>
+ <string name="tip_add_to_dictionary" msgid="1487293888469227817">"一番左の単語を長押しすると辞書に追加されます"</string>
+ <string name="touch_to_continue" msgid="7869803257948414531">"続けるにはここをタッチ"</string>
+ <string name="touch_to_finish" msgid="7990196086480585789">"タッチしてこのヒントを終了し、入力を開始してください。"</string>
+ <string name="tip_to_open_keyboard" msgid="6821200275486950452"><b>"テキストフィールドを選択するとキーボードが表示されます"</b></string>
+ <string name="tip_to_view_accents" msgid="5433158573693308501"><b>"キーを長押しするとアクセント付き文字"\n"(ø、ö、ô、óなど)が表示されます"</b></string>
+ <string name="tip_to_open_symbols" msgid="7345139325622444880"><b>"このキーを押すと、数字/記号入力に切り替わります"</b></string>
+ <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"このキーを押すと、文字入力に再度切り替わります"</b></string>
+ <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"オートコンプリートなどのキーボードの設定を変更するには、このキーを長押しします"</b></string>
+ <string name="tip_to_start_typing" msgid="7213843601369174313"><b>"試してみてください。"</b></string>
+ <string name="label_go_key" msgid="1635148082137219148">"実行"</string>
+ <string name="label_next_key" msgid="362972844525672568">"次へ"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"完了"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"送信"</string>
+ <string name="label_symbol_key" msgid="6175820506864489453">"?123"</string>
+ <string name="label_phone_key" msgid="4275497665515080551">"123"</string>
+ <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string>
+ <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string>
+ <string name="voice_warning_title" msgid="4419354150908395008">"音声入力"</string>
+ <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"音声入力は現在英語には対応していますが、日本語には対応していません。"</string>
+ <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"音声入力はGoogleのネットワーク音声認識技術を利用した試験段階の機能です。"</string>
+ <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"音声入力をOFFにするには、キーボードの設定を開きます。"</string>
+ <string name="voice_hint_dialog_message" msgid="6892342981545727994">"音声入力するには、マイクボタンを押すか画面キーボードをスワイプしてください。"</string>
+ <string name="voice_listening" msgid="467518160751321844">"お話しください"</string>
+ <string name="voice_working" msgid="6666937792815731889">"処理中"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"エラーです。もう一度お試しください。"</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"接続できませんでした"</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"音声が長すぎてエラーになりました。"</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"オーディオエラー"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"サーバーエラー"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"音声が聞き取れません"</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"該当なし"</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"Voice Searchはインストールされていません"</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"ヒント:"</b>" 音声入力するにはキーボードをスワイプします"</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"ヒント:"</b>" 次回は句読点として「period」、「comma」、「question mark」などの音声入力を試してみてください。"</string>
+ <string name="cancel" msgid="6830980399865683324">"キャンセル"</string>
+ <string name="ok" msgid="7898366843681727667">"OK"</string>
+ <string name="voice_input" msgid="2466640768843347841">"音声入力"</string>
+ <string-array name="voice_input_modes">
+ <item msgid="1349082139076086774">"メインキーボード上"</item>
+ <item msgid="8529385602829095903">"記号キーボード上"</item>
+ <item msgid="7283103513488381103">"OFF"</item>
+ </string-array>
+ <string-array name="voice_input_modes_summary">
+ <item msgid="554248625705084903">"メインキーボードのマイク"</item>
+ <item msgid="6907837061058876770">"記号キーボードのマイク"</item>
+ <item msgid="3664304608587798036">"音声入力は無効です"</item>
+ </string-array>
+ <string name="auto_submit" msgid="9151008027068358518">"入力後に自動送信する"</string>
+ <string name="auto_submit_summary" msgid="4961875269610384226">"検索または次のフィールドに進む際、Enterキーが自動的に押されます。"</string>
+ <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"キーボードを開く"\n</b></font><font size="3">\n</font>"テキストフィールドをタップします。"</string>
+ <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"キーボードを閉じる"\n</b></font><font size="3">\n</font>"[戻る]キーを押します。"</string>
+ <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"キーを長押しして選択する"\n</b></font><font size="3">\n</font>"句読点キーとアクセント文字を表示します。"</string>
+ <string name="keyboard_settings" msgid="4585753477617374032"><font size="17"><b>"キーボードの設定"\n</b></font><font size="3">\n</font>"["<b>"?123"</b>"]キーを長押しします。"</string>
+ <string name="popular_domain_0" msgid="3745279225122472969">".com"</string>
+ <string name="popular_domain_1" msgid="1370572248164278467">".net"</string>
+ <string name="popular_domain_2" msgid="3036812463748402878">".org"</string>
+ <string name="popular_domain_3" msgid="8718639560809452028">".gov"</string>
+ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"入力方法の選択"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"入力言語"</string>
+ <string name="language_selection_summary" msgid="187110938289512256">"スペースバーで指をスライドさせて言語を変更する"</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"←保存するにはもう一度タップ"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"辞書を利用できます"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"ユーザーフィードバックを有効にする"</string>
+ <string name="prefs_description_log" msgid="5827825607258246003">"IMEの機能向上のため、使用統計状況やクラッシュレポートをGoogleに自動送信します。"</string>
+ <string name="prefs_enable_recorrection" msgid="4588408906649533582">"タップして語句を修正"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="1056068922330206170">"入力した語句をタップして修正"</string>
+ <string name="keyboard_layout" msgid="437433231038683666">"キーボードテーマ"</string>
+ <string name="subtype_mode_keyboard" msgid="2242090416595003881">"キーボード"</string>
+ <string name="subtype_mode_voice" msgid="4394113125441627771">"音声"</string>
+</resources>
diff --git a/java/res/values-ko/donottranslate-altchars.xml b/java/res/values-ko/donottranslate-altchars.xml
new file mode 100644
index 0000000..4074cdb
--- /dev/null
+++ b/java/res/values-ko/donottranslate-altchars.xml
@@ -0,0 +1,30 @@
+<?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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="alternates_for_a">àáâãäåæ</string>
+ <string name="alternates_for_e">3èéêë</string>
+ <string name="alternates_for_i">8ïîíì</string>
+ <string name="alternates_for_o">9øœöõôóò</string>
+ <string name="alternates_for_u">7üûúù</string>
+ <string name="alternates_for_s">§ß</string>
+ <string name="alternates_for_n">ñ</string>
+ <string name="alternates_for_c">ç</string>
+ <string name="alternates_for_y">6ÿý</string>
+</resources>
diff --git a/java/res/values-ko/strings.xml b/java/res/values-ko/strings.xml
new file mode 100644
index 0000000..cdaa8d4
--- /dev/null
+++ b/java/res/values-ko/strings.xml
@@ -0,0 +1,140 @@
+<?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/org.pocketworkstation.pckeyboard"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- <string name="english_ime_name" msgid="7252517407088836577">"Android 키보드"</string> -->
+ <!-- <string name="english_ime_settings" msgid="6661589557206947774">"Android 키보드 설정"</string> -->
+ <string name="english_ime_input_options" msgid="3909945612939668554">"입력 옵션"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"키를 누를 때 진동 발생"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"키를 누를 때 소리 발생"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"키를 누를 때 팝업"</string>
+ <string name="hit_correction" msgid="4855351009261318389">"입력 오류 수정"</string>
+ <string name="hit_correction_summary" msgid="8761701873008070796">"입력 오류 수정 사용"</string>
+ <string name="hit_correction_land" msgid="2567691684825205448">"가로 입력 오류"</string>
+ <string name="hit_correction_land_summary" msgid="4076803842198368328">"입력 오류 수정 사용"</string>
+ <string name="auto_correction" msgid="7911639788808958255">"단어 추천"</string>
+ <string name="auto_correction_summary" msgid="6881047311475758267">"이전 단어를 자동으로 수정"</string>
+ <string name="prediction" msgid="466220283138359837">"단어 추천"</string>
+ <string name="prediction_category" msgid="7027100625580696660">"단어 추천 설정"</string>
+ <string name="prediction_summary" msgid="459788228830873110">"입력할 때 자동 완성 사용"</string>
+ <string name="auto_complete_dialog_title" msgid="2172048590607201920">"자동 완성"</string>
+ <string name="prediction_landscape" msgid="4874601565593216183">"입력란 크기 늘리기"</string>
+ <string name="prediction_landscape_summary" msgid="6736551095997839472">"가로 보기에서 추천 단어 숨기기"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"자동 대문자화"</string>
+ <string name="auto_cap_summary" msgid="3260681697600786825">"문장의 첫 글자를 대문자로 표시"</string>
+ <string name="auto_punctuate" msgid="7276672334264521751">"자동 구두점 입력"</string>
+ <string name="auto_punctuate_summary" msgid="6589441565817502132"></string>
+ <string name="quick_fixes" msgid="5353213327680897927">"빠른 수정"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"자주 발생하는 오타를 수정합니다."</string>
+ <string name="show_suggestions" msgid="507074425254289133">"추천 단어 표시"</string>
+ <string name="show_suggestions_summary" msgid="1989672863935759654">"글자를 입력하는 동안 추천 단어를 표시"</string>
+ <string name="auto_complete" msgid="1103196318775486023">"자동 완성"</string>
+ <string name="auto_complete_summary" msgid="6113149638718274624">"스페이스바와 문장부호 키로 강조 표시된 단어를 자동 삽입"</string>
+ <string name="prefs_settings_key" msgid="4623341240804046498">"설정 키 표시"</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"자동"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"항상 표시"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"항상 숨기기"</string>
+ <!-- no translation found for settings_key_modes:0 (8549888726962891527) -->
+ <!-- no translation found for settings_key_modes:1 (881280041213210923) -->
+ <!-- no translation found for settings_key_modes:2 (7317310620171067848) -->
+ <string name="bigram_suggestion" msgid="1323347224043514969">"Bigram 추천"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"이전 단어를 사용하여 추천 기능 개선"</string>
+ <string-array name="prediction_modes">
+ <item msgid="4870266572388153286">"없음"</item>
+ <item msgid="1669461741568287396">"기본"</item>
+ <item msgid="4894328801530136615">"고급"</item>
+ </string-array>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: 저장됨"</string>
+ <string name="tip_long_press" msgid="6101270866284343344">"키를 길게 누르면 악센트(ø, ö 등)가 표시됩니다."</string>
+ <string name="tip_dismiss" msgid="7585579046862204381">"키보드를 닫으려면 언제든지 뒤로 키(↶)를 누르세요."</string>
+ <string name="tip_access_symbols" msgid="6344098517525531652">"숫자 및 기호 사용"</string>
+ <string name="tip_add_to_dictionary" msgid="1487293888469227817">"맨 왼쪽에 있는 단어를 길게 누르면 사전에 추가됩니다."</string>
+ <string name="touch_to_continue" msgid="7869803257948414531">"계속하려면 힌트를 터치하세요. »"</string>
+ <string name="touch_to_finish" msgid="7990196086480585789">"힌트를 닫고 입력을 시작하려면 여기를 터치하세요."</string>
+ <string name="tip_to_open_keyboard" msgid="6821200275486950452"><b>"언제든지 입력란을 터치하면 키보드가 열립니다."</b></string>
+ <string name="tip_to_view_accents" msgid="5433158573693308501"><b>"키를 길게 터치하면 악센트"\n"(ø, ö, ô, ó 등)가 표시됩니다."</b></string>
+ <string name="tip_to_open_symbols" msgid="7345139325622444880"><b>"이 키를 터치하면 숫자 및 기호 키보드로 전환됩니다."</b></string>
+ <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"이 키를 다시 터치하면 문자 키보드로 돌아갑니다."</b></string>
+ <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"자동 완성과 같은 키보드 설정을 변경하려면 이 키를 길게 터치하세요."</b></string>
+ <string name="tip_to_start_typing" msgid="7213843601369174313"><b>"이제 사용해 보세요."</b></string>
+ <string name="label_go_key" msgid="1635148082137219148">"이동"</string>
+ <string name="label_next_key" msgid="362972844525672568">"다음"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"완료"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"전송"</string>
+ <string name="label_symbol_key" msgid="6175820506864489453">"?123"</string>
+ <string name="label_phone_key" msgid="4275497665515080551">"123"</string>
+ <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string>
+ <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string>
+ <string name="voice_warning_title" msgid="4419354150908395008">"음성 입력"</string>
+ <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"음성 입력은 현재 자국어로 지원되지 않으며 영어로 작동됩니다."</string>
+ <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"음성 입력은 Google의 네트워크화된 음성 인식을 사용하는 실험적 기능입니다."</string>
+ <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"음성 입력을 사용하지 않으려면 키보드 설정으로 이동하세요."</string>
+ <string name="voice_hint_dialog_message" msgid="6892342981545727994">"음성 입력을 사용하려면 마이크 버튼을 누르거나 터치 키보드 위로 손가락을 미끄러지듯 움직이세요."</string>
+ <string name="voice_listening" msgid="467518160751321844">"지금 말하세요."</string>
+ <string name="voice_working" msgid="6666937792815731889">"인식 중"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"오류가 발생했습니다. 다시 시도해 보세요."</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"연결할 수 없습니다."</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"음성을 너무 많이 입력했습니다."</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"오디오 문제"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"서버 오류"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"음성이 인식되지 않았습니다."</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"일치하는 항목 없음"</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"음성 검색이 설치되지 않았습니다."</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"도움말:"</b>" 키보드 위로 손가락을 미끄러지듯 움직이고 나서 말하세요."</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"도움말:"</b>" 다음 번에는 \'마침표\', \'쉼표\', \'물음표\'와 같은 구두점을 말해 보세요."</string>
+ <string name="cancel" msgid="6830980399865683324">"취소"</string>
+ <string name="ok" msgid="7898366843681727667">"확인"</string>
+ <string name="voice_input" msgid="2466640768843347841">"음성 입력"</string>
+ <string-array name="voice_input_modes">
+ <item msgid="1349082139076086774">"기본 키보드"</item>
+ <item msgid="8529385602829095903">"기호 키보드"</item>
+ <item msgid="7283103513488381103">"사용 안함"</item>
+ </string-array>
+ <string-array name="voice_input_modes_summary">
+ <item msgid="554248625705084903">"기본 키보드의 마이크"</item>
+ <item msgid="6907837061058876770">"기호 키보드의 마이크"</item>
+ <item msgid="3664304608587798036">"음성 입력이 사용 중지됨"</item>
+ </string-array>
+ <string name="auto_submit" msgid="9151008027068358518">"음성을 입력한 다음 자동 제출"</string>
+ <string name="auto_submit_summary" msgid="4961875269610384226">"검색하거나 다음 입력란으로 이동할 때 자동으로 Enter 키를 누릅니다."</string>
+ <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"키보드 열기"\n</b></font><font size="3">\n</font>"아무 텍스트 입력란이나 터치하세요."</string>
+ <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"키보드 닫기"\n</b></font><font size="3">\n</font>"\'뒤로\' 키를 누르세요."</string>
+ <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"키를 길게 눌러 옵션 보기"\n</b></font><font size="3">\n</font>"문장 부호 및 악센트 기호 입력창이 열립니다."</string>
+ <string name="keyboard_settings" msgid="4585753477617374032"><font size="17"><b>"키보드 설정"\n</b></font><font size="3">\n</font><b>"?123"</b>" 키를 길게 누르세요."</string>
+ <string name="popular_domain_0" msgid="3745279225122472969">".com"</string>
+ <string name="popular_domain_1" msgid="1370572248164278467">".net"</string>
+ <string name="popular_domain_2" msgid="3036812463748402878">".org"</string>
+ <string name="popular_domain_3" msgid="8718639560809452028">".gov"</string>
+ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"입력 방법 선택"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"입력 언어"</string>
+ <string name="language_selection_summary" msgid="187110938289512256">"손가락을 스페이스바에서 미끄러지듯 움직여 언어 변경"</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← 저장하려면 다시 터치하세요."</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"사전 사용 가능"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"사용자 의견 사용"</string>
+ <string name="prefs_description_log" msgid="5827825607258246003">"사용 통계 및 충돌 보고서를 Google에 자동으로 전송하여 입력 방법 편집기의 개선에 도움을 줍니다."</string>
+ <string name="prefs_enable_recorrection" msgid="4588408906649533582">"터치하여 단어 수정"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="1056068922330206170">"입력한 단어를 터치하여 수정"</string>
+ <string name="keyboard_layout" msgid="437433231038683666">"키보드 테마"</string>
+ <string name="subtype_mode_keyboard" msgid="2242090416595003881">"키보드"</string>
+ <string name="subtype_mode_voice" msgid="4394113125441627771">"음성"</string>
+</resources>
diff --git a/java/res/values-land/dimens.xml b/java/res/values-land/dimens.xml
new file mode 100644
index 0000000..c19df28
--- /dev/null
+++ b/java/res/values-land/dimens.xml
@@ -0,0 +1,39 @@
+<?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>
+ <!-- key_height + key_bottom_gap = popup_key_height -->
+ <dimen name="key_height">0.250in</dimen>
+ <dimen name="key_vertical_pad">0.000in</dimen>
+ <dimen name="popup_key_height">0.270in</dimen>
+ <dimen name="keyboard_bottom_padding">0.01in</dimen>
+ <dimen name="candidate_strip_height">38dip</dimen>
+ <dimen name="candidate_strip_fading_edge_length">63dip</dimen>
+ <dimen name="spacebar_vertical_correction">2dip</dimen>
+ <!-- Amount of allowance for selecting keys in a mini popup keyboard by sliding finger. -->
+ <!-- popup_key_height x 1.7 -->
+ <dimen name="mini_keyboard_slide_allowance">0.459in</dimen>
+ <!-- popup_key_height x 1.0 -->
+ <dimen name="mini_keyboard_vertical_correction">-0.270in</dimen>
+ <!-- Key size for 5-row mode. Scaled up by 1.25 for 4-row mode. -->
+ <dimen name="key_text_size">0.138in</dimen>
+ <dimen name="key_label_text_size">0.103in</dimen>
+ <dimen name="key_preview_text_size_large">50sp</dimen>
+</resources>
diff --git a/java/res/values-lo/donottranslate-keymap.xml b/java/res/values-lo/donottranslate-keymap.xml
new file mode 100644
index 0000000..696784b
--- /dev/null
+++ b/java/res/values-lo/donottranslate-keymap.xml
@@ -0,0 +1,221 @@
+<?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.
+**
+**
+** 5-row layout for English QWERTY.
+**
+** See http://code.google.com/p/hackerskeyboard/wiki/AddingNewLayouts for
+** more information.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="key_tlde_main">\"</string>
+ <string name="key_tlde_shift">\'</string>
+ <string name="key_tlde_alt">`~</string>
+
+ <string name="key_ae01_main">ຢ</string>
+ <string name="key_ae01_shift">1</string>
+ <string name="key_ae01_alt">1!¡¹½⅓¼⅛</string>
+
+ <string name="key_ae02_main">ຟ</string>
+ <string name="key_ae02_shift">2</string>
+ <string name="key_ae02_alt">2\@²⅔</string>
+
+ <string name="key_ae03_main">ໂ</string>
+ <string name="key_ae03_shift">3</string>
+ <string name="key_ae03_alt">3#³¾⅜♥♠♦♣</string>
+
+ <string name="key_ae04_main">ຖ</string>
+ <string name="key_ae04_shift">4</string>
+ <string name="key_ae04_alt">4$⁴¢£€¥</string>
+
+ <string name="key_ae05_main">ຸ</string>
+ <string name="key_ae05_shift">໌</string>
+ <string name="key_ae05_alt">5%⅝‰</string>
+
+ <string name="key_ae06_main">ູ</string>
+ <string name="key_ae06_shift">ຼ</string>
+ <string name="key_ae06_alt">6^↑↓←→</string>
+
+ <string name="key_ae07_main">ຄ</string>
+ <string name="key_ae07_shift">5</string>
+ <string name="key_ae07_alt">7&amp;⅞♪</string>
+
+ <string name="key_ae08_main">ຕ</string>
+ <string name="key_ae08_shift">6</string>
+ <string name="key_ae08_alt">8*•★∞†‡</string>
+
+ <string name="key_ae09_main">ຈ</string>
+ <string name="key_ae09_shift">7</string>
+ <string name="key_ae09_alt">9(√</string>
+
+ <string name="key_ae10_main">ຂ</string>
+ <string name="key_ae10_shift">8</string>
+ <string name="key_ae10_alt">0)ⁿ°</string>
+
+ <string name="key_ae11_main">ຊ</string>
+ <string name="key_ae11_shift">9</string>
+ <string name="key_ae11_alt">-_—–</string>
+
+ <string name="key_ae12_main">ໍ</string>
+ <string name="key_ae12_shift">ໍ່</string>
+ <string name="key_ae12_alt">=+≈≠±×÷</string>
+
+
+ <string name="key_ad01_main">ົ</string>
+ <string name="key_ad01_shift">ົ້</string>
+ <string name="key_ad01_alt"></string>
+
+ <string name="key_ad02_main">ໄ</string>
+ <string name="key_ad02_shift">0</string>
+ <string name="key_ad02_alt"></string>
+
+ <string name="key_ad03_main">ຳ</string>
+ <string name="key_ad03_shift">*</string>
+ <string name="key_ad03_alt"></string>
+
+ <string name="key_ad04_main">ພ</string>
+ <string name="key_ad04_shift">_</string>
+ <string name="key_ad04_alt"></string>
+
+ <string name="key_ad05_main">ະ</string>
+ <string name="key_ad05_shift">+</string>
+ <string name="key_ad05_alt"></string>
+
+ <string name="key_ad06_main">ິ</string>
+ <string name="key_ad06_shift">ິ້</string>
+ <string name="key_ad06_alt"></string>
+
+ <string name="key_ad07_main">ີ</string>
+ <string name="key_ad07_shift">ີ້</string>
+ <string name="key_ad07_alt"></string>
+
+ <string name="key_ad08_main">ຮ</string>
+ <string name="key_ad08_shift">ຣ</string>
+ <string name="key_ad08_alt"></string>
+
+ <string name="key_ad09_main">ນ</string>
+ <string name="key_ad09_shift">ໜ</string>
+ <string name="key_ad09_alt"></string>
+
+ <string name="key_ad10_main">ຍ</string>
+ <string name="key_ad10_shift">ຽ</string>
+ <string name="key_ad10_alt"></string>
+
+ <string name="key_ad11_main">ບ</string>
+ <string name="key_ad11_shift">-</string>
+ <string name="key_ad11_alt">[{</string>
+
+ <string name="key_ad12_main">ລ</string>
+ <string name="key_ad12_shift">ຫຼ</string>
+ <string name="key_ad12_alt">]}</string>
+
+ <string name="key_bksl_main">/</string>
+ <string name="key_bksl_shift">\\</string>
+ <string name="key_bksl_alt">\\|</string>
+
+
+ <string name="key_ac01_main">ັ</string>
+ <string name="key_ac01_shift">ັ້</string>
+ <string name="key_ac01_alt"></string>
+
+ <string name="key_ac02_main">ຫ</string>
+ <string name="key_ac02_shift">;</string>
+ <string name="key_ac02_alt"></string>
+
+ <string name="key_ac03_main">ກ</string>
+ <string name="key_ac03_shift">.</string>
+ <string name="key_ac03_alt"></string>
+
+ <string name="key_ac04_main">ດ</string>
+ <string name="key_ac04_shift">,</string>
+ <string name="key_ac04_alt"></string>
+
+ <string name="key_ac05_main">ເ</string>
+ <string name="key_ac05_shift">:</string>
+ <string name="key_ac05_alt"></string>
+
+ <string name="key_ac06_main">້</string>
+ <string name="key_ac06_shift">໊</string>
+ <string name="key_ac06_alt"></string>
+
+ <string name="key_ac07_main">່</string>
+ <string name="key_ac07_shift">໋</string>
+ <string name="key_ac07_alt"></string>
+
+ <string name="key_ac08_main">າ</string>
+ <string name="key_ac08_shift">!</string>
+ <string name="key_ac08_alt"></string>
+
+ <string name="key_ac09_main">ສ</string>
+ <string name="key_ac09_shift">\?</string>
+ <string name="key_ac09_alt"></string>
+
+ <string name="key_ac10_main">ວ</string>
+ <string name="key_ac10_shift">%</string>
+ <string name="key_ac10_alt">;:</string>
+
+ <string name="key_ac11_main">ງ</string>
+ <string name="key_ac11_shift">=</string>
+ <string name="key_ac11_alt">\'\"‘’“”</string>
+
+
+ <string name="key_lsgt_main"></string>
+ <string name="key_lsgt_shift"></string>
+ <string name="key_lsgt_alt"></string>
+
+ <string name="key_ab01_main">ຜ</string>
+ <string name="key_ab01_shift">₭</string>
+ <string name="key_ab01_alt"></string>
+
+ <string name="key_ab02_main">ປ</string>
+ <string name="key_ab02_shift">(</string>
+ <string name="key_ab02_alt"></string>
+
+ <string name="key_ab03_main">ແ</string>
+ <string name="key_ab03_shift">ຯ</string>
+ <string name="key_ab03_alt"></string>
+
+ <string name="key_ab04_main">ອ</string>
+ <string name="key_ab04_shift">x</string>
+ <string name="key_ab04_alt"></string>
+
+ <string name="key_ab05_main">ຶ</string>
+ <string name="key_ab05_shift">ຶ້</string>
+ <string name="key_ab05_alt"></string>
+
+ <string name="key_ab06_main">ື</string>
+ <string name="key_ab06_shift">ື້</string>
+ <string name="key_ab06_alt"></string>
+
+ <string name="key_ab07_main">ທ</string>
+ <string name="key_ab07_shift">ໆ</string>
+ <string name="key_ab07_alt"></string>
+
+ <string name="key_ab08_main">ມ</string>
+ <string name="key_ab08_shift">ໝ</string>
+ <string name="key_ab08_alt">,&lt;≤«‹</string>
+
+ <string name="key_ab09_main">ໃ</string>
+ <string name="key_ab09_shift">$</string>
+ <string name="key_ab09_alt">&gt;≥»›…</string>
+
+ <string name="key_ab10_main">ຝ</string>
+ <string name="key_ab10_shift">)</string>
+ <string name="key_ab10_alt">/\?¿</string>
+</resources>
diff --git a/java/res/values-lt/strings.xml b/java/res/values-lt/strings.xml
new file mode 100644
index 0000000..0ace681
--- /dev/null
+++ b/java/res/values-lt/strings.xml
@@ -0,0 +1,140 @@
+<?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/org.pocketworkstation.pckeyboard"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- <string name="english_ime_name" msgid="7252517407088836577">"„Android“ klaviatūra"</string> -->
+ <!-- <string name="english_ime_settings" msgid="6661589557206947774">"„Android“ klaviatūros nustatymai"</string> -->
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Įvesties parinktys"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibruoti, kai paspaudžiami klavišai"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"Klavišo paspaudimo garsas"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"Iššoka paspaudus klavišą"</string>
+ <string name="hit_correction" msgid="4855351009261318389">"Taisyti rašybos klaidas"</string>
+ <string name="hit_correction_summary" msgid="8761701873008070796">"Įgalinti įvesties klaidos taisymą"</string>
+ <string name="hit_correction_land" msgid="2567691684825205448">"Gulsčia įvestis"</string>
+ <string name="hit_correction_land_summary" msgid="4076803842198368328">"Įgalinti įvesties klaidos taisymą"</string>
+ <string name="auto_correction" msgid="7911639788808958255">"Žodžių pasiūlymai"</string>
+ <string name="auto_correction_summary" msgid="6881047311475758267">"Automatiškai taisyti ankstesnį žodį"</string>
+ <string name="prediction" msgid="466220283138359837">"Žodžių pasiūlymai"</string>
+ <string name="prediction_category" msgid="7027100625580696660">"Žodžių pasiūlymo nustatymai"</string>
+ <string name="prediction_summary" msgid="459788228830873110">"Įgalinti automatinį užbaigimą, kai įvedinėjamas tekstas"</string>
+ <string name="auto_complete_dialog_title" msgid="2172048590607201920">"Automatinis užbaigimas"</string>
+ <string name="prediction_landscape" msgid="4874601565593216183">"Padidinti teksto lauko dydį"</string>
+ <string name="prediction_landscape_summary" msgid="6736551095997839472">"Gulsčiame rodinyje slėpti žodžių pasiūlymus"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"Automatinis didžiųjų raidžių rašymas"</string>
+ <string name="auto_cap_summary" msgid="3260681697600786825">"Sakinio pradžią rašyti didžiąja raide"</string>
+ <string name="auto_punctuate" msgid="7276672334264521751">"Automatiškai dėti skyrybos ženklus"</string>
+ <string name="auto_punctuate_summary" msgid="6589441565817502132"></string>
+ <string name="quick_fixes" msgid="5353213327680897927">"Greiti pataisymai"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"Taiso dažnai padarytas rašybos klaidas"</string>
+ <string name="show_suggestions" msgid="507074425254289133">"Rodyti pasiūlymus"</string>
+ <string name="show_suggestions_summary" msgid="1989672863935759654">"Įvedant tekstą pateikti siūlomus žodžius"</string>
+ <string name="auto_complete" msgid="1103196318775486023">"Automatiškai užbaigti"</string>
+ <string name="auto_complete_summary" msgid="6113149638718274624">"Tarpo klavišas ir skyrybos ženklai automatiškai įterpia paryškintą žodį"</string>
+ <string name="prefs_settings_key" msgid="4623341240804046498">"Rodyti nustatymų raktą"</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automatinis"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Visada rodyti"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"Visada slėpti"</string>
+ <!-- no translation found for settings_key_modes:0 (8549888726962891527) -->
+ <!-- no translation found for settings_key_modes:1 (881280041213210923) -->
+ <!-- no translation found for settings_key_modes:2 (7317310620171067848) -->
+ <string name="bigram_suggestion" msgid="1323347224043514969">"Digramų pasiūlymai"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Naudoti ankstesnį žodį pasiūlymui patobulinti"</string>
+ <string-array name="prediction_modes">
+ <item msgid="4870266572388153286">"Nėra"</item>
+ <item msgid="1669461741568287396">"Paprastas"</item>
+ <item msgid="4894328801530136615">"Išplėstinis"</item>
+ </string-array>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: išsaugota"</string>
+ <string name="tip_long_press" msgid="6101270866284343344">"Laikykite klavišą nuspaudę, kad pamatytumėte kirčius (ø, ö ir t. t.)"</string>
+ <string name="tip_dismiss" msgid="7585579046862204381">"Paspauskite klavišą „Atgal“ ↶, kad uždarytumėte klaviatūrą"</string>
+ <string name="tip_access_symbols" msgid="6344098517525531652">"Pasiekti skaičius ir simbolius"</string>
+ <string name="tip_add_to_dictionary" msgid="1487293888469227817">"Paspauskite ir laikykite nuspaudę kairiausią žodį, kad pridėtumėte jį prie žodyno"</string>
+ <string name="touch_to_continue" msgid="7869803257948414531">"Palieskite šią užuominą, jei norite tęsti »"</string>
+ <string name="touch_to_finish" msgid="7990196086480585789">"Paleiskite čia, kad uždarytumėte šią užuominą ir pradėtumėte įvedinėti tekstą!"</string>
+ <string name="tip_to_open_keyboard" msgid="6821200275486950452"><b>"Klaviatūra atsidarys kaskart, kai paliesite teksto lauką"</b></string>
+ <string name="tip_to_view_accents" msgid="5433158573693308501"><b>"Palieskite ir laikykite klavišą, kad pamatytumėte kirčius"\n"(ø, ö, ô, ó, and so on)"</b></string>
+ <string name="tip_to_open_symbols" msgid="7345139325622444880"><b>"Perjunkite į skaičius ir simbolius, paliesdami šį klavišą"</b></string>
+ <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"Grįžkite prie raidžių dar kartą paliesdami šį klavišą"</b></string>
+ <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"Palieskite ir laikykite šį klavišą, kad pakeistumėte klaviatūros nustatymus, pvz., automatinį užbaigimą"</b></string>
+ <string name="tip_to_start_typing" msgid="7213843601369174313"><b>"Išbandykite tai!"</b></string>
+ <string name="label_go_key" msgid="1635148082137219148">"Pradėti"</string>
+ <string name="label_next_key" msgid="362972844525672568">"Kitas"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"Atlikta"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"Siųsti"</string>
+ <string name="label_symbol_key" msgid="6175820506864489453">"?123"</string>
+ <string name="label_phone_key" msgid="4275497665515080551">"123"</string>
+ <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string>
+ <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string>
+ <string name="voice_warning_title" msgid="4419354150908395008">"Balso įvestis"</string>
+ <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Šiuo metu balso įvestis jūsų kompiuteryje nepalaikoma, bet ji veikia anglų k."</string>
+ <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"Balso įvestis – tai eksperimentinė funkcija, naudojanti „Google“ tinklo kalbos atpažinimą."</string>
+ <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"Jei norite išjungti balso įvestį, eikite į klaviatūros nustatymus."</string>
+ <string name="voice_hint_dialog_message" msgid="6892342981545727994">"Jei norite naudoti balso įvestį, paspauskite mikrofono mygtuką arba pirštu slyskite ekranine klaviatūra."</string>
+ <string name="voice_listening" msgid="467518160751321844">"Kalbėkite dabar"</string>
+ <string name="voice_working" msgid="6666937792815731889">"Veikia"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"Klaida. Bandykite dar kartą."</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"Nepavyko prijungti"</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"Klaida, per daug kalbos."</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"Problema su garsu"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"Serverio klaida"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"Negirdima jokia kalba"</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"Atitikmenų nerasta"</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"Balso paieška neįdiegta"</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Užuomina:"</b>" perbraukite klaviatūra, kad galėtumėte kalbėti"</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Užuomina:"</b>" kitą kartą pabandykite sakyti skyrybos ženklų pavadinimus, pvz., „taškas“, „kablelis“ arba „klaustukas“."</string>
+ <string name="cancel" msgid="6830980399865683324">"Atšaukti"</string>
+ <string name="ok" msgid="7898366843681727667">"Gerai"</string>
+ <string name="voice_input" msgid="2466640768843347841">"Balso įvestis"</string>
+ <string-array name="voice_input_modes">
+ <item msgid="1349082139076086774">"Pagrindinėje klaviatūroje"</item>
+ <item msgid="8529385602829095903">"Simbolių klaviatūroje"</item>
+ <item msgid="7283103513488381103">"Išjungta"</item>
+ </string-array>
+ <string-array name="voice_input_modes_summary">
+ <item msgid="554248625705084903">"Pagrindinės klaviatūros mikrofonas"</item>
+ <item msgid="6907837061058876770">"Mikrofonas simbolių klaviatūroje"</item>
+ <item msgid="3664304608587798036">"Balso įvestis išjungta"</item>
+ </string-array>
+ <string name="auto_submit" msgid="9151008027068358518">"Automatiškai pateikti po balso"</string>
+ <string name="auto_submit_summary" msgid="4961875269610384226">"Automatiškai spausti „Įvesti“ ieškant ar einant į kitą lauką."</string>
+ <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Atidarykite klaviatūrą"\n</b></font><font size="3">\n</font>"Palieskite bet kurį teksto lauką."</string>
+ <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Uždarykite klaviatūrą"\n</b></font><font size="3">\n</font>"Paspauskite klavišą „Atgal“."</string>
+ <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Palieskite ir laikykite klavišą, kad pamatytumėte parinktis"\n</b></font><font size="3">\n</font>"Pasiekite skyrybos ženklus ir kirčius."</string>
+ <string name="keyboard_settings" msgid="4585753477617374032"><font size="17"><b>"Klaviatūros nustatymai"\n</b></font><font size="3">\n</font>"Palieskite ir laikykite klavišą "<b>"?123"</b>"."</string>
+ <string name="popular_domain_0" msgid="3745279225122472969">".com"</string>
+ <string name="popular_domain_1" msgid="1370572248164278467">".net"</string>
+ <string name="popular_domain_2" msgid="3036812463748402878">".org"</string>
+ <string name="popular_domain_3" msgid="8718639560809452028">".gov"</string>
+ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"Pasirinkti įvesties metodą"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Įvesties kalbos"</string>
+ <string name="language_selection_summary" msgid="187110938289512256">"Pirštu slyskite tarpo klavišu, kad pakeistumėte kalbą"</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Kad išsaugotumėte, dar kartą palieskite"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"Žodynas galimas"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"Įgalinti naudotojų atsiliepimus"</string>
+ <string name="prefs_description_log" msgid="5827825607258246003">"Padėkite patobulinti šią įvesties metodo redagavimo programą automatiškai „Google“ siųsdami naudojimo statistiką ir strigčių ataskaitas."</string>
+ <string name="prefs_enable_recorrection" msgid="4588408906649533582">"Jei norite ištais. žodž., paliesk."</string>
+ <string name="prefs_enable_recorrection_summary" msgid="1056068922330206170">"Jei norite ištaisyti įvestus žodžius, palieskite juos"</string>
+ <string name="keyboard_layout" msgid="437433231038683666">"Klaviatūros tema"</string>
+ <string name="subtype_mode_keyboard" msgid="2242090416595003881">"klaviatūra"</string>
+ <string name="subtype_mode_voice" msgid="4394113125441627771">"Voice"</string>
+</resources>
diff --git a/java/res/values-lv/donottranslate-altchars.xml b/java/res/values-lv/donottranslate-altchars.xml
new file mode 100644
index 0000000..249767b
--- /dev/null
+++ b/java/res/values-lv/donottranslate-altchars.xml
@@ -0,0 +1,47 @@
+<?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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="alternates_for_a">ā</string>
+ <string name="alternates_for_b"></string>
+ <string name="alternates_for_c">č</string>
+ <string name="alternates_for_d"></string>
+ <string name="alternates_for_e">3ē€</string>
+ <string name="alternates_for_f"></string>
+ <string name="alternates_for_g">ģ</string>
+ <string name="alternates_for_h"></string>
+ <string name="alternates_for_i">8ī</string>
+ <string name="alternates_for_j"></string>
+ <string name="alternates_for_k">ķ</string>
+ <string name="alternates_for_l">ļ£₤λ</string>
+ <string name="alternates_for_m">μ</string>
+ <string name="alternates_for_n">ņ</string>
+ <string name="alternates_for_o">9ō</string>
+ <string name="alternates_for_p">0π₱</string>
+ <string name="alternates_for_q">1</string>
+ <string name="alternates_for_r">4ŗ</string>
+ <string name="alternates_for_s">š§</string>
+ <string name="alternates_for_t">5</string>
+ <string name="alternates_for_u">7ū</string>
+ <string name="alternates_for_v"></string>
+ <string name="alternates_for_w">2</string>
+ <string name="alternates_for_x"></string>
+ <string name="alternates_for_y">6¥</string>
+ <string name="alternates_for_z">ž</string>
+</resources>
diff --git a/java/res/values-lv/strings.xml b/java/res/values-lv/strings.xml
new file mode 100644
index 0000000..eae12a8
--- /dev/null
+++ b/java/res/values-lv/strings.xml
@@ -0,0 +1,140 @@
+<?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/org.pocketworkstation.pckeyboard"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- <string name="english_ime_name" msgid="7252517407088836577">"Android tastatūra"</string> -->
+ <!-- <string name="english_ime_settings" msgid="6661589557206947774">"Android tastatūras iestatījumi"</string> -->
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Ievades opcijas"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrēt, nospiežot taustiņu"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"Skaņa, nospiežot taustiņu"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"Nospiežot taustiņu, parādīt uznirstošo izvēlni"</string>
+ <string name="hit_correction" msgid="4855351009261318389">"Labot drukas kļūdas"</string>
+ <string name="hit_correction_summary" msgid="8761701873008070796">"Iespējot ievades kļūdu labošanu"</string>
+ <string name="hit_correction_land" msgid="2567691684825205448">"Ainavas orientācijas ievades kļūdas"</string>
+ <string name="hit_correction_land_summary" msgid="4076803842198368328">"Iespējot ievades kļūdu labošanu"</string>
+ <string name="auto_correction" msgid="7911639788808958255">"Vārdu ieteikumi"</string>
+ <string name="auto_correction_summary" msgid="6881047311475758267">"Automātiski labot iepriekšējo vārdu"</string>
+ <string name="prediction" msgid="466220283138359837">"Vārdu ieteikumi"</string>
+ <string name="prediction_category" msgid="7027100625580696660">"Vārdu ieteikumu iestatījumi"</string>
+ <string name="prediction_summary" msgid="459788228830873110">"Iespējot automātisko pabeigšanu ievades laikā"</string>
+ <string name="auto_complete_dialog_title" msgid="2172048590607201920">"Automātiska pabeigšana"</string>
+ <string name="prediction_landscape" msgid="4874601565593216183">"Palielināt teksta lauka lielumu"</string>
+ <string name="prediction_landscape_summary" msgid="6736551095997839472">"Ainavas skatījumā slēpt vārdu ieteikumus"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"Automātiska lielo burtu lietošana"</string>
+ <string name="auto_cap_summary" msgid="3260681697600786825">"Sākt teikumu ar lielo burtu"</string>
+ <string name="auto_punctuate" msgid="7276672334264521751">"Automātiska pieturzīmju lietošana"</string>
+ <string name="auto_punctuate_summary" msgid="6589441565817502132"></string>
+ <string name="quick_fixes" msgid="5353213327680897927">"Ātrie labojumi"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"Nodrošina izplatītu drukas kļūdu labošanu."</string>
+ <string name="show_suggestions" msgid="507074425254289133">"Rādīt ieteikumus"</string>
+ <string name="show_suggestions_summary" msgid="1989672863935759654">"Ievades laikā attēlot ieteiktos vārdus"</string>
+ <string name="auto_complete" msgid="1103196318775486023">"Automātiska pabeigšana"</string>
+ <string name="auto_complete_summary" msgid="6113149638718274624">"Automātiski ievietot iezīmēto vārdu, izmantojot atstarpes taustiņu un pieturzīmes"</string>
+ <string name="prefs_settings_key" msgid="4623341240804046498">"Rādīt iestatījumu taustiņu"</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automātiski"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Vienmēr rādīt"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"Vienmēr slēpt"</string>
+ <!-- no translation found for settings_key_modes:0 (8549888726962891527) -->
+ <!-- no translation found for settings_key_modes:1 (881280041213210923) -->
+ <!-- no translation found for settings_key_modes:2 (7317310620171067848) -->
+ <string name="bigram_suggestion" msgid="1323347224043514969">"Bigram ieteikumi"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Ieteikuma uzlabošanai izmantot iepriekšējo vārdu"</string>
+ <string-array name="prediction_modes">
+ <item msgid="4870266572388153286">"Nav"</item>
+ <item msgid="1669461741568287396">"Pamata"</item>
+ <item msgid="4894328801530136615">"Uzlabots"</item>
+ </string-array>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: saglabāts"</string>
+ <string name="tip_long_press" msgid="6101270866284343344">"Turiet taustiņu nospiestu, lai skatītu uzsvēruma zīmes (ø, ö u.c.)."</string>
+ <string name="tip_dismiss" msgid="7585579046862204381">"Jebkurā brīdī nospiediet taustiņu Atpakaļ ↶, lai aizvērtu tastatūru."</string>
+ <string name="tip_access_symbols" msgid="6344098517525531652">"Piekļūt cipariem un simboliem"</string>
+ <string name="tip_add_to_dictionary" msgid="1487293888469227817">"Nospiediet kreisajā pusē esošo vārdu un turiet, lai pievienotu to vārdnīcai."</string>
+ <string name="touch_to_continue" msgid="7869803257948414531">"Pieskarieties šim ieteikumam, lai turpinātu »"</string>
+ <string name="touch_to_finish" msgid="7990196086480585789">"Pieskarieties šeit, lai aizvērtu šo ieteikumu un sāktu ievadi."</string>
+ <string name="tip_to_open_keyboard" msgid="6821200275486950452"><b>"Tastatūra tiek atvērta ikreiz, kad pieskaraties teksta laukam"</b>"."</string>
+ <string name="tip_to_view_accents" msgid="5433158573693308501"><b>"Pieskarieties taustiņam un turiet, lai skatītu uzsvara zīmes"\n"(ø, ö, ô, ó utt.)."</b></string>
+ <string name="tip_to_open_symbols" msgid="7345139325622444880"><b>"Pieskarieties šim taustiņam, lai izmantotu ciparus un simbolus."</b></string>
+ <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"Vēlreiz pieskarieties šim taustiņam, lai atkal izmantotu burtus."</b></string>
+ <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"Pieskarieties taustiņam un turiet, lai mainītu tastatūras iestatījumus, piemēram, automātisko pabeigšanu."</b></string>
+ <string name="tip_to_start_typing" msgid="7213843601369174313"><b>"Izmēģiniet to!"</b></string>
+ <string name="label_go_key" msgid="1635148082137219148">"Sākt"</string>
+ <string name="label_next_key" msgid="362972844525672568">"Tālāk"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"Gatavs"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"Sūtīt"</string>
+ <string name="label_symbol_key" msgid="6175820506864489453">"?123"</string>
+ <string name="label_phone_key" msgid="4275497665515080551">"123"</string>
+ <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string>
+ <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string>
+ <string name="voice_warning_title" msgid="4419354150908395008">"Balss ievade"</string>
+ <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Balss ievade jūsu valodā pašlaik netiek atbalstīta, taču tā ir pieejama angļu valodā."</string>
+ <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"Balss ievade ir izmēģinājuma funkcija, kuras pamatā ir Google tīkla runas atpazīšanas līdzeklis."</string>
+ <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"Lai izslēgtu balss ievadi, atveriet tastatūras iestatījumus."</string>
+ <string name="voice_hint_dialog_message" msgid="6892342981545727994">"Lai izmantotu balss ievadi, nospiediet mikrofona pogu vai slidiniet pirkstus pāri ekrāna tastatūrai."</string>
+ <string name="voice_listening" msgid="467518160751321844">"Runājiet!"</string>
+ <string name="voice_working" msgid="6666937792815731889">"Notiek apstrāde"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"Kļūda. Lūdzu, mēģiniet vēlreiz."</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"Nevar izveidot savienojumu."</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"Kļūda, pārāk ilga balss ievade."</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"Audio problēma"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"Servera kļūda"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"Nekas nav dzirdams."</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"Nav atrasta neviena atbilstība."</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"Balss meklēšana nav instalēta."</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Ieteikums:"</b>" slidiniet pirkstu pār tastatūru, lai veiktu balss ievadi."</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Ieteikums:"</b>" nākamreiz mēģiniet izrunāt pieturzīmes, piemēram, “punkts”, “komats” vai “jautājuma zīme”."</string>
+ <string name="cancel" msgid="6830980399865683324">"Atcelt"</string>
+ <string name="ok" msgid="7898366843681727667">"Labi"</string>
+ <string name="voice_input" msgid="2466640768843347841">"Balss ievade"</string>
+ <string-array name="voice_input_modes">
+ <item msgid="1349082139076086774">"Izmantojot galveno tastatūru"</item>
+ <item msgid="8529385602829095903">"Izmantojot simbolu tastatūru"</item>
+ <item msgid="7283103513488381103">"Izsl."</item>
+ </string-array>
+ <string-array name="voice_input_modes_summary">
+ <item msgid="554248625705084903">"Galvenās tastatūras mikrofons"</item>
+ <item msgid="6907837061058876770">"Simbolu tastatūras mikrofons"</item>
+ <item msgid="3664304608587798036">"Balss ievade ir atspējota"</item>
+ </string-array>
+ <string name="auto_submit" msgid="9151008027068358518">"Automātiski iesniegt pēc balss ievades"</string>
+ <string name="auto_submit_summary" msgid="4961875269610384226">"Automātiski nospiest ievades taustiņu, meklējot vai pārejot uz nākamo lauku."</string>
+ <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Tastatūras atvēršana"\n</b></font><font size="3">\n</font>"Pieskarieties jebkuram teksta laukam."</string>
+ <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Tastatūras aizvēršana"\n</b></font><font size="3">\n</font>"Nospiediet taustiņu Atpakaļ."</string>
+ <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Pieskarieties taustiņam un turiet, lai skatītu opcijas."\n</b></font><font size="3">\n</font>"Piekļūstiet pieturzīmēm un uzsvara zīmēm."</string>
+ <string name="keyboard_settings" msgid="4585753477617374032"><font size="17"><b>"Tastatūras iestatījumi"\n</b></font><font size="3">\n</font>"Pieskarieties taustiņam "<b>"?123"</b>" un turiet."</string>
+ <string name="popular_domain_0" msgid="3745279225122472969">".com"</string>
+ <string name="popular_domain_1" msgid="1370572248164278467">".net"</string>
+ <string name="popular_domain_2" msgid="3036812463748402878">".org"</string>
+ <string name="popular_domain_3" msgid="8718639560809452028">".gov"</string>
+ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"Atlasīt ievades metodi"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Ievades valodas"</string>
+ <string name="language_selection_summary" msgid="187110938289512256">"Slidiniet pirkstu uz atstarpes taustiņa, lai mainītu valodu"</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Pieskarieties vēlreiz, lai saglabātu"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"Ir pieejama vārdnīca."</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"Iespējot lietotāju atsauksmes"</string>
+ <string name="prefs_description_log" msgid="5827825607258246003">"Palīdziet uzlabot šo ievades metodes redaktoru, automātiski nosūtot lietojuma statistiku un pārskatus par avārijām uzņēmumam Google."</string>
+ <string name="prefs_enable_recorrection" msgid="4588408906649533582">"Pieskarties, lai izlabotu vārdus"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="1056068922330206170">"Pieskarties ievadītajiem vārdiem, lai tos labotu"</string>
+ <string name="keyboard_layout" msgid="437433231038683666">"Tastatūras motīvs"</string>
+ <string name="subtype_mode_keyboard" msgid="2242090416595003881">"tastatūra"</string>
+ <string name="subtype_mode_voice" msgid="4394113125441627771">"balss"</string>
+</resources>
diff --git a/java/res/values-nb/donottranslate-altchars.xml b/java/res/values-nb/donottranslate-altchars.xml
new file mode 100644
index 0000000..79c220c
--- /dev/null
+++ b/java/res/values-nb/donottranslate-altchars.xml
@@ -0,0 +1,37 @@
+<?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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="alternates_for_a">äáàâąã</string>
+ <string name="alternates_for_e">3éèêëę€</string>
+ <string name="alternates_for_i">8ïîìí</string>
+ <string name="alternates_for_o">9õôòóö</string>
+ <string name="alternates_for_u">7ūûùúü</string>
+ <string name="alternates_for_s">śšşß</string>
+ <string name="alternates_for_n">ńñň</string>
+ <string name="alternates_for_c">çćč</string>
+ <string name="alternates_for_y">6ÿý</string>
+ <string name="alternates_for_d">ðď</string>
+ <string name="alternates_for_r">4ř</string>
+ <string name="alternates_for_t">5þť</string>
+ <string name="alternates_for_z">źžż</string>
+ <string name="alternates_for_l">ł</string>
+ <string name="alternates_for_v">w</string>
+ <string name="alternates_for_oe">œ</string>
+</resources>
diff --git a/java/res/values-nb/donottranslate-keymap.xml b/java/res/values-nb/donottranslate-keymap.xml
new file mode 100644
index 0000000..4e4baf1
--- /dev/null
+++ b/java/res/values-nb/donottranslate-keymap.xml
@@ -0,0 +1,223 @@
+<?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.
+**
+**
+** 5-row layout for Norwegian QWERTY.
+** By Håvar Ingmund Henriksen <android-hackerskeyboard-nb@havar.no>
+** Based on 5-row layout for Danish QWERTY.
+** By Christian Holm Christensen <cholmcc@gmail.com>.
+** Based on 5-row layout for Swedish QWERTY.
+**
+** See http://code.google.com/p/hackerskeyboard/wiki/AddingNewLayouts for
+** more information.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="key_tlde_main">|</string>
+ <string name="key_tlde_shift">§</string>
+ <string name="key_tlde_alt">|§¦¶</string>
+
+ <string name="key_ae01_main">1</string>
+ <string name="key_ae01_shift">!</string>
+ <string name="key_ae01_alt">1!¡¹½⅓¼⅛º¢¥</string>
+
+ <string name="key_ae02_main">2</string>
+ <string name="key_ae02_shift">\"</string>
+ <string name="key_ae02_alt">2\"\@²⅔“”</string>
+
+ <string name="key_ae03_main">3</string>
+ <string name="key_ae03_shift">#</string>
+ <string name="key_ae03_alt">3#£³¾⅜♥♠♦♣</string>
+
+ <string name="key_ae04_main">4</string>
+ <string name="key_ae04_shift">¤</string>
+ <string name="key_ae04_alt">4¤$⁴¼¢£€¥</string>
+
+ <string name="key_ae05_main">5</string>
+ <string name="key_ae05_shift">%</string>
+ <string name="key_ae05_alt">5%‰½⅝¢</string>
+
+ <string name="key_ae06_main">6</string>
+ <string name="key_ae06_shift">&amp;</string>
+ <string name="key_ae06_alt">6&amp;¥↑↓←→</string>
+
+ <string name="key_ae07_main">7</string>
+ <string name="key_ae07_shift">/</string>
+ <string name="key_ae07_alt">7/{[(÷⅞♪</string>
+
+ <string name="key_ae08_main">8</string>
+ <string name="key_ae08_shift">(</string>
+ <string name="key_ae08_alt">8([{«•★∞†‡</string>
+
+ <string name="key_ae09_main">9</string>
+ <string name="key_ae09_shift">)</string>
+ <string name="key_ae09_alt">9)]}»√</string>
+
+ <string name="key_ae10_main">0</string>
+ <string name="key_ae10_shift">=</string>
+ <string name="key_ae10_alt">0=}])°≈≠</string>
+
+ <string name="key_ae11_main">+</string>
+ <string name="key_ae11_shift">\?</string>
+ <string name="key_ae11_alt">+\?\\¿±×÷</string>
+
+ <string name="key_ae12_main">\\</string>
+ <string name="key_ae12_shift">`</string>
+ <string name="key_ae12_alt">\\`´&#x301;&#x300;</string>
+
+
+ <string name="key_ad01_main">q</string>
+ <string name="key_ad01_shift">Q</string>
+ <string name="key_ad01_alt">\\@</string>
+
+ <string name="key_ad02_main">w</string>
+ <string name="key_ad02_shift">W</string>
+ <string name="key_ad02_alt">ẅŵ</string>
+
+ <string name="key_ad03_main">e</string>
+ <string name="key_ad03_shift">E</string>
+ <string name="key_ad03_alt">€¢éèêēë</string>
+
+ <string name="key_ad04_main">r</string>
+ <string name="key_ad04_shift">R</string>
+ <string name="key_ad04_alt">r®</string>
+
+ <string name="key_ad05_main">t</string>
+ <string name="key_ad05_shift">T</string>
+ <string name="key_ad05_alt">ŧþ™</string>
+
+ <string name="key_ad06_main">y</string>
+ <string name="key_ad06_shift">Y</string>
+ <string name="key_ad06_alt">ÿýỳŷ←¥</string>
+
+ <string name="key_ad07_main">u</string>
+ <string name="key_ad07_shift">U</string>
+ <string name="key_ad07_alt">üûúùū↓↑</string>
+
+ <string name="key_ad08_main">i</string>
+ <string name="key_ad08_shift">I</string>
+ <string name="key_ad08_alt">íïìîī→ı</string>
+
+ <string name="key_ad09_main">o</string>
+ <string name="key_ad09_shift">O</string>
+ <string name="key_ad09_alt">ôöóòôõōœΩω</string>
+
+ <string name="key_ad10_main">p</string>
+ <string name="key_ad10_shift">P</string>
+ <string name="key_ad10_alt">π₱</string>
+
+ <string name="key_ad11_main">å</string>
+ <string name="key_ad11_shift">Å</string>
+ <string name="key_ad11_alt">&#x308;&#x30a;</string>
+
+ <string name="key_ad12_main">&#x308;</string>
+ <string name="key_ad12_shift">^</string>
+ <string name="key_ad12_alt">&#x308;^~¨ˇ&#x302;&#x303;&#x30c;</string>
+
+ <string name="key_bksl_main">\'</string>
+ <string name="key_bksl_shift">*</string>
+ <string name="key_bksl_alt">\'*×˝</string>
+
+ <string name="key_ac01_main">a</string>
+ <string name="key_ac01_shift">A</string>
+ <string name="key_ac01_alt">äâãáàā\@ªº</string>
+
+ <string name="key_ac02_main">s</string>
+ <string name="key_ac02_shift">S</string>
+ <string name="key_ac02_alt">ߧš</string>
+
+ <string name="key_ac03_main">d</string>
+ <string name="key_ac03_shift">D</string>
+ <string name="key_ac03_alt">ðđ</string>
+
+ <string name="key_ac04_main">f</string>
+ <string name="key_ac04_shift">F</string>
+ <string name="key_ac04_alt">₣</string>
+
+ <string name="key_ac05_main">g</string>
+ <string name="key_ac05_shift">G</string>
+ <string name="key_ac05_alt">ŋǧǥ</string>
+
+ <string name="key_ac06_main">h</string>
+ <string name="key_ac06_shift">H</string>
+ <string name="key_ac06_alt">ħ</string>
+
+ <string name="key_ac07_main">j</string>
+ <string name="key_ac07_shift">J</string>
+ <string name="key_ac07_alt"></string>
+
+ <string name="key_ac08_main">k</string>
+ <string name="key_ac08_shift">K</string>
+ <string name="key_ac08_alt">ĸ&amp;ǩ</string>
+
+ <string name="key_ac09_main">l</string>
+ <string name="key_ac09_shift">L</string>
+ <string name="key_ac09_alt">ł£₤λ</string>
+
+ <string name="key_ac10_main">ø</string>
+ <string name="key_ac10_shift">Ø</string>
+ <string name="key_ac10_alt">ö&#x30c;</string>
+
+ <string name="key_ac11_main">æ</string>
+ <string name="key_ac11_shift">Æ</string>
+ <string name="key_ac11_alt">ä\'˝</string>
+
+ <string name="key_lsgt_main">&gt;</string>
+ <string name="key_lsgt_shift">&lt;</string>
+ <string name="key_lsgt_alt">&lt;|«»‹≤≥›</string>
+
+ <string name="key_ab01_main">z</string>
+ <string name="key_ab01_shift">Z</string>
+ <string name="key_ab01_alt">«&lt;‹≤žʒǯ</string>
+
+ <string name="key_ab02_main">x</string>
+ <string name="key_ab02_shift">X</string>
+ <string name="key_ab02_alt">»&gt;≥›</string>
+
+ <string name="key_ab03_main">c</string>
+ <string name="key_ab03_shift">C</string>
+ <string name="key_ab03_alt">čçć¢©</string>
+
+ <string name="key_ab04_main">v</string>
+ <string name="key_ab04_shift">V</string>
+ <string name="key_ab04_alt">“‘</string>
+
+ <string name="key_ab05_main">b</string>
+ <string name="key_ab05_shift">B</string>
+ <string name="key_ab05_alt">”’</string>
+
+ <string name="key_ab06_main">n</string>
+ <string name="key_ab06_shift">N</string>
+ <string name="key_ab06_alt">ñŋ</string>
+
+ <string name="key_ab07_main">m</string>
+ <string name="key_ab07_shift">M</string>
+ <string name="key_ab07_alt">µº</string>
+
+ <string name="key_ab08_main">,</string>
+ <string name="key_ab08_shift">;</string>
+ <string name="key_ab08_alt">,;</string>
+
+ <string name="key_ab09_main">.</string>
+ <string name="key_ab09_shift">:</string>
+ <string name="key_ab09_alt">.:·˙…</string>
+
+ <string name="key_ab10_main">-</string>
+ <string name="key_ab10_shift">_</string>
+ <string name="key_ab10_alt">-_¯̣ ˙—–</string>
+</resources>
diff --git a/java/res/values-nb/strings.xml b/java/res/values-nb/strings.xml
new file mode 100644
index 0000000..55ab133
--- /dev/null
+++ b/java/res/values-nb/strings.xml
@@ -0,0 +1,140 @@
+<?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/org.pocketworkstation.pckeyboard"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- <string name="english_ime_name" msgid="7252517407088836577">"Skjermtastatur"</string> -->
+ <!-- <string name="english_ime_settings" msgid="6661589557206947774">"Innstillinger for skjermtastatur"</string> -->
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Inndataalternativer"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrer ved tastetrykk"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"Lyd ved tastetrykk"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"Hurtigvindu ved tastetrykk"</string>
+ <string name="hit_correction" msgid="4855351009261318389">"Rett opp skrivefeil"</string>
+ <string name="hit_correction_summary" msgid="8761701873008070796">"Slå på retting av skrivefeil"</string>
+ <string name="hit_correction_land" msgid="2567691684825205448">"Rett opp skrivefeil i breddeformat"</string>
+ <string name="hit_correction_land_summary" msgid="4076803842198368328">"Slå på retting av skrivefeil"</string>
+ <string name="auto_correction" msgid="7911639788808958255">"Autokorrektur"</string>
+ <string name="auto_correction_summary" msgid="6881047311475758267">"Autokorriger forrige ord"</string>
+ <string name="prediction" msgid="466220283138359837">"Ordforslag"</string>
+ <string name="prediction_category" msgid="7027100625580696660">"Innstillinger for ordforslag"</string>
+ <string name="prediction_summary" msgid="459788228830873110">"Skru på autofullføring under skriving"</string>
+ <string name="auto_complete_dialog_title" msgid="2172048590607201920">"Autofullfør"</string>
+ <string name="prediction_landscape" msgid="4874601565593216183">"Større tekstfelt"</string>
+ <string name="prediction_landscape_summary" msgid="6736551095997839472">"Skjul ordforslag i breddeformat"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"Stor forbokstav"</string>
+ <string name="auto_cap_summary" msgid="3260681697600786825">"Start automatisk setninger med stor bokstav"</string>
+ <string name="auto_punctuate" msgid="7276672334264521751">"Automatisk punktum"</string>
+ <string name="auto_punctuate_summary" msgid="6589441565817502132"></string>
+ <string name="quick_fixes" msgid="5353213327680897927">"Autokorrektur"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"Retter vanlige stavefeil"</string>
+ <string name="show_suggestions" msgid="507074425254289133">"Vis forslag"</string>
+ <string name="show_suggestions_summary" msgid="1989672863935759654">"Vis foreslåtte ord under skriving"</string>
+ <string name="auto_complete" msgid="1103196318775486023">"Autofullføring"</string>
+ <string name="auto_complete_summary" msgid="6113149638718274624">"Mellomrom og punktum setter automatisk inn valgt ord"</string>
+ <string name="prefs_settings_key" msgid="4623341240804046498">"Vis innstillingsnøkkel"</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automatisk"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Vis alltid"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"Skjul alltid"</string>
+ <!-- no translation found for settings_key_modes:0 (8549888726962891527) -->
+ <!-- no translation found for settings_key_modes:1 (881280041213210923) -->
+ <!-- no translation found for settings_key_modes:2 (7317310620171067848) -->
+ <string name="bigram_suggestion" msgid="1323347224043514969">"Bigram-forslag"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Bruk forrige ord til å forbedre forslaget"</string>
+ <string-array name="prediction_modes">
+ <item msgid="4870266572388153286">"Ingen"</item>
+ <item msgid="1669461741568287396">"Grunnleggende"</item>
+ <item msgid="4894328801530136615">"Avansert"</item>
+ </string-array>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: Lagret"</string>
+ <string name="tip_long_press" msgid="6101270866284343344">"Hold en tast nede for å se aksenterte tegn (ø, ö, osv.)"</string>
+ <string name="tip_dismiss" msgid="7585579046862204381">"Trykk tilbakeknappen, ↶, for å lukke tastaturet"</string>
+ <string name="tip_access_symbols" msgid="6344098517525531652">"Få tilgang til tall og symboler"</string>
+ <string name="tip_add_to_dictionary" msgid="1487293888469227817">"Trykk lenge på ordet lengst til venstre for å legge det til i ordlisten"</string>
+ <string name="touch_to_continue" msgid="7869803257948414531">"Trykk på dette hintet for å forsette »"</string>
+ <string name="touch_to_finish" msgid="7990196086480585789">"Trykk her for å lukke dette hintet og begynne å skrive!"</string>
+ <string name="tip_to_open_keyboard" msgid="6821200275486950452"><b>"Tastaturet åpnes når du tar på et tekstfelt"</b></string>
+ <string name="tip_to_view_accents" msgid="5433158573693308501"><b>"Trykk på og hold nede en tast for å se aksenter"\n"(ø, ö, ô, ó, osv.)"</b></string>
+ <string name="tip_to_open_symbols" msgid="7345139325622444880"><b>"Bytt til tall og symboler ved å trykke på denne tasten"</b></string>
+ <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"Gå tilbake til bokstaver igjen ved å trykke på denne tasten"</b></string>
+ <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"Trykk på og hold nede denne tasten for å endre tastaturinnstillinger, som autofullføring"</b></string>
+ <string name="tip_to_start_typing" msgid="7213843601369174313"><b>"Prøv det!"</b></string>
+ <string name="label_go_key" msgid="1635148082137219148">"Gå"</string>
+ <string name="label_next_key" msgid="362972844525672568">"Neste"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"Utfør"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"Send"</string>
+ <string name="label_symbol_key" msgid="6175820506864489453">"?123"</string>
+ <string name="label_phone_key" msgid="4275497665515080551">"123"</string>
+ <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string>
+ <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string>
+ <string name="voice_warning_title" msgid="4419354150908395008">"Stemmedata"</string>
+ <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Stemmedata håndteres foreløpig ikke på ditt språk, men fungerer på engelsk."</string>
+ <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"Talekommandoer er en eksperimentell funksjon som bruker Googles nettverksbaserte talegjenkjenning."</string>
+ <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"Gå til innstillinger for tastatur for å slå av stemmedata."</string>
+ <string name="voice_hint_dialog_message" msgid="6892342981545727994">"Du bruker talekommandoer ved å trykke på mikrofonknappen eller skyve fingeren over tastaturet på skjermen."</string>
+ <string name="voice_listening" msgid="467518160751321844">"Snakk nå"</string>
+ <string name="voice_working" msgid="6666937792815731889">"Arbeider"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"Feil. Prøv på nytt."</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"Kunne ikke koble til"</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"Feil – for mye tale"</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"Lydproblem"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"Tjenerfeil"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"Ingen tale høres"</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"Ingen treff"</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"Talesøk ikke installert"</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021">"Hint:"<b>" Sveip over tastaturet for å snakke"</b></string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Hint:"</b>" Neste gang kan du prøve å tale inn tegnsettingen ved for eksempel å si «punktum», «komma» eller «spørsmålstegn»."</string>
+ <string name="cancel" msgid="6830980399865683324">"Avbryt"</string>
+ <string name="ok" msgid="7898366843681727667">"OK"</string>
+ <string name="voice_input" msgid="2466640768843347841">"Talekommando"</string>
+ <string-array name="voice_input_modes">
+ <item msgid="1349082139076086774">"På hovedtastatur"</item>
+ <item msgid="8529385602829095903">"På talltastatur"</item>
+ <item msgid="7283103513488381103">"Av"</item>
+ </string-array>
+ <string-array name="voice_input_modes_summary">
+ <item msgid="554248625705084903">"Mikrofon på hovedtastatur"</item>
+ <item msgid="6907837061058876770">"Mikrofon på talltastatur"</item>
+ <item msgid="3664304608587798036">"Talekommando er deaktivert"</item>
+ </string-array>
+ <string name="auto_submit" msgid="9151008027068358518">"Send inn automatisk etter tale"</string>
+ <string name="auto_submit_summary" msgid="4961875269610384226">"Trykk Enter automatisk ved søk eller flytting til neste felt."</string>
+ <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Åpne tastaturet"\n</b></font><font size="3">\n</font>"Trykk på et tekstfelt."</string>
+ <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Lukke tastaturet"\n</b></font><font size="3">\n</font>"Trykk på tilbaketasten."</string>
+ <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Trykk og hold nede en tast for flere valg"\n</b></font><font size="3">\n</font>"Få tilgang til skilletegn og aksenter."</string>
+ <string name="keyboard_settings" msgid="4585753477617374032"><font size="17"><b>"Innstillinger for tastatur"\n</b></font><font size="3">\n</font>"Trykk på &amp; hold "<b>"?123"</b>"-tasten."</string>
+ <string name="popular_domain_0" msgid="3745279225122472969">".no"</string>
+ <string name="popular_domain_1" msgid="1370572248164278467">".com"</string>
+ <string name="popular_domain_2" msgid="3036812463748402878">".net"</string>
+ <string name="popular_domain_3" msgid="8718639560809452028">".org"</string>
+ <string name="popular_domain_4" msgid="35359437471311470">".info"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"Velg inndatametode"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Inndataspråk"</string>
+ <string name="language_selection_summary" msgid="187110938289512256">"Dra fingeren på mellomromstasten for å endre språk"</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"Trykk på nytt for å lagre"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"Ordbok tilgjengelig"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"Aktiver brukertilbakemelding"</string>
+ <string name="prefs_description_log" msgid="5827825607258246003">"Ved å sende bruksstatistikk og programstopprapporter til Google automatisk, hjelper du oss med å gjøre redigeringsfunksjonen for denne inndatametoden enda bedre."</string>
+ <string name="prefs_enable_recorrection" msgid="4588408906649533582">"Trykk for å endre ord"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="1056068922330206170">"Trykk på ord du har skrevet inn, for å endre dem"</string>
+ <string name="keyboard_layout" msgid="437433231038683666">"Tastaturtema"</string>
+ <string name="subtype_mode_keyboard" msgid="2242090416595003881">"tastatur"</string>
+ <string name="subtype_mode_voice" msgid="4394113125441627771">"stemme"</string>
+</resources>
diff --git a/java/res/values-nl/donottranslate-altchars.xml b/java/res/values-nl/donottranslate-altchars.xml
new file mode 100644
index 0000000..4074cdb
--- /dev/null
+++ b/java/res/values-nl/donottranslate-altchars.xml
@@ -0,0 +1,30 @@
+<?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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="alternates_for_a">àáâãäåæ</string>
+ <string name="alternates_for_e">3èéêë</string>
+ <string name="alternates_for_i">8ïîíì</string>
+ <string name="alternates_for_o">9øœöõôóò</string>
+ <string name="alternates_for_u">7üûúù</string>
+ <string name="alternates_for_s">§ß</string>
+ <string name="alternates_for_n">ñ</string>
+ <string name="alternates_for_c">ç</string>
+ <string name="alternates_for_y">6ÿý</string>
+</resources>
diff --git a/java/res/values-nl/strings.xml b/java/res/values-nl/strings.xml
new file mode 100644
index 0000000..de1ec34
--- /dev/null
+++ b/java/res/values-nl/strings.xml
@@ -0,0 +1,140 @@
+<?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/org.pocketworkstation.pckeyboard"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- <string name="english_ime_name" msgid="7252517407088836577">"Android-toetsenbord"</string> -->
+ <!-- <string name="english_ime_settings" msgid="6661589557206947774">"Instellingen voor Android-toetsenbord"</string> -->
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Invoeropties"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"Trillen bij toetsaanslag"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"Geluid bij toetsaanslag"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"Pop-up bij toetsaanslag"</string>
+ <string name="hit_correction" msgid="4855351009261318389">"Typefouten corrigeren"</string>
+ <string name="hit_correction_summary" msgid="8761701873008070796">"Foutcorrectie tijdens invoer inschakelen"</string>
+ <string name="hit_correction_land" msgid="2567691684825205448">"Invoerfouten in liggende weergave"</string>
+ <string name="hit_correction_land_summary" msgid="4076803842198368328">"Foutcorrectie tijdens invoer inschakelen"</string>
+ <string name="auto_correction" msgid="7911639788808958255">"Woordsuggesties"</string>
+ <string name="auto_correction_summary" msgid="6881047311475758267">"Het vorige woord automatisch corrigeren"</string>
+ <string name="prediction" msgid="466220283138359837">"Woordsuggesties"</string>
+ <string name="prediction_category" msgid="7027100625580696660">"Instellingen voor woordsuggesties"</string>
+ <string name="prediction_summary" msgid="459788228830873110">"Automatisch voltooien tijdens typen inschakelen"</string>
+ <string name="auto_complete_dialog_title" msgid="2172048590607201920">"Automatisch voltooien"</string>
+ <string name="prediction_landscape" msgid="4874601565593216183">"Tekstveld vergroten"</string>
+ <string name="prediction_landscape_summary" msgid="6736551095997839472">"Woordsuggesties verbergen in liggende weergave"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"Auto-hoofdlettergebruik"</string>
+ <string name="auto_cap_summary" msgid="3260681697600786825">"Hoofdletter gebruiken aan het begin van een zin"</string>
+ <string name="auto_punctuate" msgid="7276672334264521751">"Automatische interpunctie"</string>
+ <string name="auto_punctuate_summary" msgid="6589441565817502132"></string>
+ <string name="quick_fixes" msgid="5353213327680897927">"Snelle oplossingen"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"Hiermee worden veelvoorkomende typefouten gecorrigeerd"</string>
+ <string name="show_suggestions" msgid="507074425254289133">"Suggesties weergeven"</string>
+ <string name="show_suggestions_summary" msgid="1989672863935759654">"Voorgestelde woorden weergeven tijdens typen"</string>
+ <string name="auto_complete" msgid="1103196318775486023">"Auto-aanvullen"</string>
+ <string name="auto_complete_summary" msgid="6113149638718274624">"Gemarkeerd woord automatisch invoegen met spatiebalk en interpunctie"</string>
+ <string name="prefs_settings_key" msgid="4623341240804046498">"Instellingscode weergeven"</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automatisch"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Altijd weergeven"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"Altijd verbergen"</string>
+ <!-- no translation found for settings_key_modes:0 (8549888726962891527) -->
+ <!-- no translation found for settings_key_modes:1 (881280041213210923) -->
+ <!-- no translation found for settings_key_modes:2 (7317310620171067848) -->
+ <string name="bigram_suggestion" msgid="1323347224043514969">"Digram-suggesties"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Vorig woord gebruiken om suggestie te verbeteren"</string>
+ <string-array name="prediction_modes">
+ <item msgid="4870266572388153286">"Geen"</item>
+ <item msgid="1669461741568287396">"Basis"</item>
+ <item msgid="4894328801530136615">"Geavanceerd"</item>
+ </string-array>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: opgeslagen"</string>
+ <string name="tip_long_press" msgid="6101270866284343344">"Houd een toets ingedrukt om diakritische tekens weer te geven (ø, ö, enzovoort)"</string>
+ <string name="tip_dismiss" msgid="7585579046862204381">"Druk op elk gewenst moment op de toets Terug ↶ om het toetsenbord te sluiten"</string>
+ <string name="tip_access_symbols" msgid="6344098517525531652">"Toegang tot cijfers en symbolen"</string>
+ <string name="tip_add_to_dictionary" msgid="1487293888469227817">"Blijf drukken op het meest linkse woord om het toe te voegen aan het woordenboek"</string>
+ <string name="touch_to_continue" msgid="7869803257948414531">"Raak deze tip aan om door te gaan »"</string>
+ <string name="touch_to_finish" msgid="7990196086480585789">"Raak dit punt aan om deze tip te sluiten en te beginnen met typen."</string>
+ <string name="tip_to_open_keyboard" msgid="6821200275486950452"><b>"Het toetsenbord wordt geopend wanneer u een tekstveld aanraakt"</b></string>
+ <string name="tip_to_view_accents" msgid="5433158573693308501"><b>"Blijf een toets aanraken om diakritische tekens weer te geven"\n"(ø, ö, ô, ó, enzovoort)"</b></string>
+ <string name="tip_to_open_symbols" msgid="7345139325622444880"><b>"Schakel over naar cijfers en symbolen door deze toets aan te raken"</b></string>
+ <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"Ga terug naar letters door deze toets nogmaals aan te raken"</b></string>
+ <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"Blijf deze toets aanraken om toetsenbordinstellingen te wijzigen, zoals auto-aanvullen"</b></string>
+ <string name="tip_to_start_typing" msgid="7213843601369174313"><b>"Probeer het zelf!"</b></string>
+ <string name="label_go_key" msgid="1635148082137219148">"Beginnen"</string>
+ <string name="label_next_key" msgid="362972844525672568">"Volgende"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"Gereed"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"Verzenden"</string>
+ <string name="label_symbol_key" msgid="6175820506864489453">"?123"</string>
+ <string name="label_phone_key" msgid="4275497665515080551">"123"</string>
+ <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string>
+ <string name="label_alt_key" msgid="2846315350346694811">"Alt"</string>
+ <string name="voice_warning_title" msgid="4419354150908395008">"Spraakinvoer"</string>
+ <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Spraakinvoer wordt momenteel niet ondersteund in uw taal, maar is wel beschikbaar in het Engels."</string>
+ <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"Spraakinvoer is een experimentele functie met de spraakherkenning van het Google-netwerk."</string>
+ <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"Als u spraakinvoer wilt uitschakelen, gaat u naar de toetsenbordinstellingen."</string>
+ <string name="voice_hint_dialog_message" msgid="6892342981545727994">"Als u spraakinvoer gebruikt, drukt u op de microfoonknop of schuift u uw vinger over het schermtoetsenbord."</string>
+ <string name="voice_listening" msgid="467518160751321844">"Nu spreken"</string>
+ <string name="voice_working" msgid="6666937792815731889">"Wordt uitgevoerd"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"Fout. Probeer het opnieuw."</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"Kan geen verbinding maken"</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"Fout, te lange spraakinvoer."</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"Audioprobleem"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"Serverfout"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"Geen spraak te horen"</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"Geen resultaten gevonden"</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"Voice Search is niet geïnstalleerd"</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Hint:"</b>" schuif over het toetsenbord om te spreken"</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Hint:"</b>" spreek de volgende keer interpunctie uit, zoals \'period\' (punt), \'comma\' (komma) of \'question mark\' (vraagteken)."</string>
+ <string name="cancel" msgid="6830980399865683324">"Annuleren"</string>
+ <string name="ok" msgid="7898366843681727667">"OK"</string>
+ <string name="voice_input" msgid="2466640768843347841">"Spraakinvoer"</string>
+ <string-array name="voice_input_modes">
+ <item msgid="1349082139076086774">"Op hoofdtoetsenbord"</item>
+ <item msgid="8529385602829095903">"Op toetsenbord voor symbolen"</item>
+ <item msgid="7283103513488381103">"Uit"</item>
+ </string-array>
+ <string-array name="voice_input_modes_summary">
+ <item msgid="554248625705084903">"Microfoon op hoofdtoetsenbord"</item>
+ <item msgid="6907837061058876770">"Microfoon op toetsenbord voor symbolen"</item>
+ <item msgid="3664304608587798036">"Spraakinvoer is uitgeschakeld"</item>
+ </string-array>
+ <string name="auto_submit" msgid="9151008027068358518">"Automatisch verzenden na spraak"</string>
+ <string name="auto_submit_summary" msgid="4961875269610384226">"Drukt automatisch op Enter tijdens het zoeken of wanneer u naar het volgende veld wilt gaan."</string>
+ <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Het toetsenbord openen"\n</b></font><font size="3">\n</font>"Raak een tekstveld aan."</string>
+ <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Het toetsenbord sluiten"\n</b></font><font size="3">\n</font>"Druk op de terugtoets."</string>
+ <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Een toets blijven aanraken voor opties"\n</b></font><font size="3">\n</font>"Toegang tot interpunctie en diakritische tekens."</string>
+ <string name="keyboard_settings" msgid="4585753477617374032"><font size="17"><b>"Toetsenbordinstellingen"\n</b></font><font size="3">\n</font>"Blijf de toets \'"<b>"?123"</b>"\' aanraken."</string>
+ <string name="popular_domain_0" msgid="3745279225122472969">".com"</string>
+ <string name="popular_domain_1" msgid="1370572248164278467">".net"</string>
+ <string name="popular_domain_2" msgid="3036812463748402878">".org"</string>
+ <string name="popular_domain_3" msgid="8718639560809452028">".gov"</string>
+ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"Invoermethode selecteren"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Invoertalen"</string>
+ <string name="language_selection_summary" msgid="187110938289512256">"Schuif uw vinger over de spatiebalk om de taal te wijzigen"</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Raak nogmaals aan om op te slaan"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"Woordenboek beschikbaar"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"Gebruikersfeedback inschakelen."</string>
+ <string name="prefs_description_log" msgid="5827825607258246003">"Help deze invoermethode te verbeteren door automatisch gebruiksstatistieken en crashmeldingen naar Google te verzenden."</string>
+ <string name="prefs_enable_recorrection" msgid="4588408906649533582">"Raak aan om woorden te corrigeren"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="1056068922330206170">"Raak ingevoerde woorden aan om ze te corrigeren"</string>
+ <string name="keyboard_layout" msgid="437433231038683666">"Toetsenbordthema"</string>
+ <string name="subtype_mode_keyboard" msgid="2242090416595003881">"toetsenbord"</string>
+ <string name="subtype_mode_voice" msgid="4394113125441627771">"spraak"</string>
+</resources>
diff --git a/java/res/values-pl/donottranslate-altchars.xml b/java/res/values-pl/donottranslate-altchars.xml
new file mode 100644
index 0000000..8f235af
--- /dev/null
+++ b/java/res/values-pl/donottranslate-altchars.xml
@@ -0,0 +1,33 @@
+<?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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="alternates_for_a">ą</string>
+ <string name="alternates_for_e">3ę</string>
+ <string name="alternates_for_i">8ïîíì</string>
+ <string name="alternates_for_o">9ó</string>
+ <string name="alternates_for_u">7üûúù</string>
+ <string name="alternates_for_s">ś</string>
+ <string name="alternates_for_n">ń</string>
+ <string name="alternates_for_c">ć</string>
+ <string name="alternates_for_x">ź</string>
+ <string name="alternates_for_y">6ÿý</string>
+ <string name="alternates_for_z">żź</string>
+ <string name="alternates_for_l">ł</string>
+</resources>
diff --git a/java/res/values-pl/strings.xml b/java/res/values-pl/strings.xml
new file mode 100644
index 0000000..2e3cf57
--- /dev/null
+++ b/java/res/values-pl/strings.xml
@@ -0,0 +1,140 @@
+<?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/org.pocketworkstation.pckeyboard"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- <string name="english_ime_name" msgid="7252517407088836577">"Klawiatura Android"</string> -->
+ <!-- <string name="english_ime_settings" msgid="6661589557206947774">"Ustawienia klawiatury Android"</string> -->
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Opcje wprowadzania"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"Wibracja przy naciśnięciu"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"Dźwięk przy naciśnięciu"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"Powiększ po naciśnięciu"</string>
+ <string name="hit_correction" msgid="4855351009261318389">"Popraw błędy pisowni"</string>
+ <string name="hit_correction_summary" msgid="8761701873008070796">"Włącz poprawianie błędów wprowadzania"</string>
+ <string name="hit_correction_land" msgid="2567691684825205448">"Błędy wprowadzania w orientacji poziomej"</string>
+ <string name="hit_correction_land_summary" msgid="4076803842198368328">"Włącz poprawianie błędów wprowadzania"</string>
+ <string name="auto_correction" msgid="7911639788808958255">"Sugestie słów"</string>
+ <string name="auto_correction_summary" msgid="6881047311475758267">"Automatycznie poprawiaj poprzednie słowo"</string>
+ <string name="prediction" msgid="466220283138359837">"Sugestie słów"</string>
+ <string name="prediction_category" msgid="7027100625580696660">"Ustawienia propozycji słów"</string>
+ <string name="prediction_summary" msgid="459788228830873110">"Włącz autouzupełnianie podczas wpisywania"</string>
+ <string name="auto_complete_dialog_title" msgid="2172048590607201920">"Autouzupełnianie"</string>
+ <string name="prediction_landscape" msgid="4874601565593216183">"Zwiększ rozmiar pola tekstowego"</string>
+ <string name="prediction_landscape_summary" msgid="6736551095997839472">"Wyłącz sugestie słów w orientacji poziomej"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"Wstawiaj wielkie litery"</string>
+ <string name="auto_cap_summary" msgid="3260681697600786825">"Zamieniaj na wielką pierwszą literę zdania"</string>
+ <string name="auto_punctuate" msgid="7276672334264521751">"Automatyczna interpunkcja"</string>
+ <string name="auto_punctuate_summary" msgid="6589441565817502132"></string>
+ <string name="quick_fixes" msgid="5353213327680897927">"Szybkie poprawki"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"Poprawia częste błędy wpisywania"</string>
+ <string name="show_suggestions" msgid="507074425254289133">"Pokaż sugestie"</string>
+ <string name="show_suggestions_summary" msgid="1989672863935759654">"Wyświetl sugerowane słowa podczas wpisywania"</string>
+ <string name="auto_complete" msgid="1103196318775486023">"Autouzupełnianie"</string>
+ <string name="auto_complete_summary" msgid="6113149638718274624">"Spacja i znaki przestankowe wstawiają wyróżnione słowo"</string>
+ <string name="prefs_settings_key" msgid="4623341240804046498">"Pokaż klawisz ustawień"</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automatycznie"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Zawsze pokazuj"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"Zawsze ukrywaj"</string>
+ <!-- no translation found for settings_key_modes:0 (8549888726962891527) -->
+ <!-- no translation found for settings_key_modes:1 (881280041213210923) -->
+ <!-- no translation found for settings_key_modes:2 (7317310620171067848) -->
+ <string name="bigram_suggestion" msgid="1323347224043514969">"Sugestie dla bigramów"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Używaj poprzedniego wyrazu, aby polepszyć sugestię"</string>
+ <string-array name="prediction_modes">
+ <item msgid="4870266572388153286">"Brak"</item>
+ <item msgid="1669461741568287396">"Podstawowy"</item>
+ <item msgid="4894328801530136615">"Zaawansowany"</item>
+ </string-array>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Zapisano"</string>
+ <string name="tip_long_press" msgid="6101270866284343344">"Przytrzymaj klawisz, aby wyświetlić znaki akcentowane (ą, ó itp.)"</string>
+ <string name="tip_dismiss" msgid="7585579046862204381">"Naciśnij klawisz cofania ↶, aby zamknąć klawiaturę w dowolnym momencie"</string>
+ <string name="tip_access_symbols" msgid="6344098517525531652">"Przejdź do cyfr i symboli"</string>
+ <string name="tip_add_to_dictionary" msgid="1487293888469227817">"Naciśnij i przytrzymaj słowo po lewej stronie w celu dodania go do słownika"</string>
+ <string name="touch_to_continue" msgid="7869803257948414531">"Dotknij tej podpowiedzi, aby kontynuować »"</string>
+ <string name="touch_to_finish" msgid="7990196086480585789">"Dotknij tutaj, aby zamknąć tę podpowiedź i zacząć pisać!"</string>
+ <string name="tip_to_open_keyboard" msgid="6821200275486950452"><b>"Klawiatura jest otwierana po każdym dotknięciu pola tekstowego."</b></string>
+ <string name="tip_to_view_accents" msgid="5433158573693308501"><b>"Dotknij i przytrzymaj klawisz, aby wyświetlić znaki akcentowane"\n"(ą, ę, ł, ó itd.)."</b></string>
+ <string name="tip_to_open_symbols" msgid="7345139325622444880"><b>"Przełącz na cyfry i symbole, dotykając tego klawisza."</b></string>
+ <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"Wróć do trybu liter, dotykając ponownie tego klawisza."</b></string>
+ <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"Dotknij i przytrzymaj ten klawisz, aby zmienić ustawienia klawiatury, takie jak autouzupełnianie."</b></string>
+ <string name="tip_to_start_typing" msgid="7213843601369174313"><b>"Wypróbuj!"</b></string>
+ <string name="label_go_key" msgid="1635148082137219148">"OK"</string>
+ <string name="label_next_key" msgid="362972844525672568">"Dalej"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"OK"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"Wyślij"</string>
+ <string name="label_symbol_key" msgid="6175820506864489453">"?123"</string>
+ <string name="label_phone_key" msgid="4275497665515080551">"123"</string>
+ <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string>
+ <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string>
+ <string name="voice_warning_title" msgid="4419354150908395008">"Wprowadzanie głosowe"</string>
+ <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Wprowadzanie głosowe obecnie nie jest obsługiwane w Twoim języku, ale działa w języku angielskim."</string>
+ <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"Wprowadzanie głosowe to funkcja eksperymentalna wykorzystująca funkcję firmy Google umożliwiającą rozpoznawanie mowy przy użyciu sieci."</string>
+ <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"Aby wyłączyć wprowadzanie głosowe, przejdź do ustawień klawiatury."</string>
+ <string name="voice_hint_dialog_message" msgid="6892342981545727994">"Aby skorzystać z wprowadzania głosowego, naciśnij przycisk mikrofonu lub przesuń palcem po klawiaturze ekranowej."</string>
+ <string name="voice_listening" msgid="467518160751321844">"Mów teraz"</string>
+ <string name="voice_working" msgid="6666937792815731889">"W toku"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"Błąd. Spróbuj ponownie."</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"Nie można nawiązać połączenia"</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"Błąd, zbyt długa wypowiedź."</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"Problem z dźwiękiem"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"Błąd serwera"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"Nie wykryto mowy"</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"Brak wyników"</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"Wyszukiwanie głosowe nie jest zainstalowane"</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Wskazówka:"</b>" przesuń palcem po klawiaturze, aby mówić."</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Wskazówka:"</b>" następnym razem spróbuj wypowiadać nazwy znaków interpunkcyjnych: „kropka”, „przecinek” lub „pytajnik”."</string>
+ <string name="cancel" msgid="6830980399865683324">"Anuluj"</string>
+ <string name="ok" msgid="7898366843681727667">"OK"</string>
+ <string name="voice_input" msgid="2466640768843347841">"Wprowadzanie głosowe"</string>
+ <string-array name="voice_input_modes">
+ <item msgid="1349082139076086774">"Na klawiaturze głównej"</item>
+ <item msgid="8529385602829095903">"Na klawiaturze z symbolami"</item>
+ <item msgid="7283103513488381103">"Wyłączone"</item>
+ </string-array>
+ <string-array name="voice_input_modes_summary">
+ <item msgid="554248625705084903">"Mikrofon na klawiaturze głównej"</item>
+ <item msgid="6907837061058876770">"Mikrofon na klawiaturze z symbolami"</item>
+ <item msgid="3664304608587798036">"Wprowadzanie głosowe jest wyłączone"</item>
+ </string-array>
+ <string name="auto_submit" msgid="9151008027068358518">"Automatyczne przesyłanie uruchamiane głosem"</string>
+ <string name="auto_submit_summary" msgid="4961875269610384226">"Podczas wyszukiwania lub przechodzenia do następnego pola automatycznie naciśnij klawisz Enter."</string>
+ <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Otwórz klawiaturę"\n</b></font><font size="3">\n</font>"Dotknij dowolnego pola tekstowego."</string>
+ <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Zamknij klawiaturę"\n</b></font><font size="3">\n</font>"Naciśnij klawisz Wróć."</string>
+ <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Dotknij klawisza i przytrzymaj go, aby wyświetlić opcje"\n</b></font><font size="3">\n</font>"Dostęp do znaków przestankowych i akcentowanych."</string>
+ <string name="keyboard_settings" msgid="4585753477617374032"><font size="17"><b>"Ustawienia klawiatury"\n</b></font><font size="3">\n</font>"Dotknij klawisza "<b>"?123"</b>" i przytrzymaj go."</string>
+ <string name="popular_domain_0" msgid="3745279225122472969">".com"</string>
+ <string name="popular_domain_1" msgid="1370572248164278467">".net"</string>
+ <string name="popular_domain_2" msgid="3036812463748402878">".org"</string>
+ <string name="popular_domain_3" msgid="8718639560809452028">".gov"</string>
+ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"Wybierz metodę wprowadzania"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Języki wprowadzania"</string>
+ <string name="language_selection_summary" msgid="187110938289512256">"Przesuń palcem po spacji, aby zmienić język"</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Dotknij ponownie, aby zapisać"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"Słownik dostępny"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"Włącz przesyłanie opinii użytkownika"</string>
+ <string name="prefs_description_log" msgid="5827825607258246003">"Pomóż ulepszyć edytor tej metody wprowadzania, automatycznie wysyłając do Google statystyki użycia i raporty o awariach."</string>
+ <string name="prefs_enable_recorrection" msgid="4588408906649533582">"Popraw dotknięte słowo"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="1056068922330206170">"Dotknięte słowo zostanie poprawione"</string>
+ <string name="keyboard_layout" msgid="437433231038683666">"Motyw klawiatury"</string>
+ <string name="subtype_mode_keyboard" msgid="2242090416595003881">"klawiatura"</string>
+ <string name="subtype_mode_voice" msgid="4394113125441627771">"głosowe"</string>
+</resources>
diff --git a/java/res/values-pt-rPT/donottranslate-altchars.xml b/java/res/values-pt-rPT/donottranslate-altchars.xml
new file mode 100644
index 0000000..26ae1a2
--- /dev/null
+++ b/java/res/values-pt-rPT/donottranslate-altchars.xml
@@ -0,0 +1,30 @@
+<?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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="alternates_for_a">àáâãäåæ</string>
+ <string name="alternates_for_e">3€èéêë</string>
+ <string name="alternates_for_i">8ïîíì</string>
+ <string name="alternates_for_o">9øœöõôóò</string>
+ <string name="alternates_for_u">7üûúù</string>
+ <string name="alternates_for_s">§ß</string>
+ <string name="alternates_for_n">ñ</string>
+ <string name="alternates_for_c">ç</string>
+ <string name="alternates_for_y">6ÿý</string>
+</resources>
diff --git a/java/res/values-pt-rPT/donottranslate-keymap.xml b/java/res/values-pt-rPT/donottranslate-keymap.xml
new file mode 100644
index 0000000..2db4c57
--- /dev/null
+++ b/java/res/values-pt-rPT/donottranslate-keymap.xml
@@ -0,0 +1,221 @@
+<?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.
+**
+**
+** 5-row layout for English QWERTY.
+**
+** See http://code.google.com/p/hackerskeyboard/wiki/AddingNewLayouts for
+** more information.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="key_tlde_main">\\</string>
+ <string name="key_tlde_shift">|</string>
+ <string name="key_tlde_alt">\\|†‡</string>
+
+ <string name="key_ae01_main">1</string>
+ <string name="key_ae01_shift">!</string>
+ <string name="key_ae01_alt">1!¡¹½⅓¼⅛</string>
+
+ <string name="key_ae02_main">2</string>
+ <string name="key_ae02_shift">\"</string>
+ <string name="key_ae02_alt">2\"\@²⅔</string>
+
+ <string name="key_ae03_main">3</string>
+ <string name="key_ae03_shift">#</string>
+ <string name="key_ae03_alt">3#£³¾⅜</string>
+
+ <string name="key_ae04_main">4</string>
+ <string name="key_ae04_shift">$</string>
+ <string name="key_ae04_alt">4$§⁴¢¥</string>
+
+ <string name="key_ae05_main">5</string>
+ <string name="key_ae05_shift">%</string>
+ <string name="key_ae05_alt">5%⅝‰</string>
+
+ <string name="key_ae06_main">6</string>
+ <string name="key_ae06_shift">&amp;</string>
+ <string name="key_ae06_alt">6&amp;↑↓←→</string>
+
+ <string name="key_ae07_main">7</string>
+ <string name="key_ae07_shift">/</string>
+ <string name="key_ae07_alt">7/{⅞♪</string>
+
+ <string name="key_ae08_main">8</string>
+ <string name="key_ae08_shift">(</string>
+ <string name="key_ae08_alt">8([*•★∞</string>
+
+ <string name="key_ae09_main">9</string>
+ <string name="key_ae09_shift">)</string>
+ <string name="key_ae09_alt">9)]√</string>
+
+ <string name="key_ae10_main">0</string>
+ <string name="key_ae10_shift">=</string>
+ <string name="key_ae10_alt">0=}ⁿ°</string>
+
+ <string name="key_ae11_main">\'</string>
+ <string name="key_ae11_shift">\?</string>
+ <string name="key_ae11_alt">\'\?</string>
+
+ <string name="key_ae12_main">«</string>
+ <string name="key_ae12_shift">»</string>
+ <string name="key_ae12_alt">«»♥♠♦♣</string>
+
+
+ <string name="key_ad01_main">q</string>
+ <string name="key_ad01_shift">Q</string>
+ <string name="key_ad01_alt">@string/alternates_for_q</string>
+
+ <string name="key_ad02_main">w</string>
+ <string name="key_ad02_shift">W</string>
+ <string name="key_ad02_alt">@string/alternates_for_w</string>
+
+ <string name="key_ad03_main">e</string>
+ <string name="key_ad03_shift">E</string>
+ <string name="key_ad03_alt">@string/alternates_for_e</string>
+
+ <string name="key_ad04_main">r</string>
+ <string name="key_ad04_shift">R</string>
+ <string name="key_ad04_alt">@string/alternates_for_r</string>
+
+ <string name="key_ad05_main">t</string>
+ <string name="key_ad05_shift">T</string>
+ <string name="key_ad05_alt">@string/alternates_for_t</string>
+
+ <string name="key_ad06_main">y</string>
+ <string name="key_ad06_shift">Y</string>
+ <string name="key_ad06_alt">@string/alternates_for_y</string>
+
+ <string name="key_ad07_main">u</string>
+ <string name="key_ad07_shift">U</string>
+ <string name="key_ad07_alt">@string/alternates_for_u</string>
+
+ <string name="key_ad08_main">i</string>
+ <string name="key_ad08_shift">I</string>
+ <string name="key_ad08_alt">@string/alternates_for_i</string>
+
+ <string name="key_ad09_main">o</string>
+ <string name="key_ad09_shift">O</string>
+ <string name="key_ad09_alt">@string/alternates_for_o</string>
+
+ <string name="key_ad10_main">p</string>
+ <string name="key_ad10_shift">P</string>
+ <string name="key_ad10_alt">@string/alternates_for_p</string>
+
+ <string name="key_ad11_main">+</string>
+ <string name="key_ad11_shift">*</string>
+ <string name="key_ad11_alt">+*&#x308;≈≠±×÷</string>
+
+ <string name="key_ad12_main">&#x301;</string>
+ <string name="key_ad12_shift">&#x300;</string>
+ <string name="key_ad12_alt">&#x301;&#x300;`</string>
+
+ <string name="key_bksl_main">º</string>
+ <string name="key_bksl_shift">ª</string>
+ <string name="key_bksl_alt">ºª</string>
+
+
+ <string name="key_ac01_main">a</string>
+ <string name="key_ac01_shift">A</string>
+ <string name="key_ac01_alt">@string/alternates_for_a</string>
+
+ <string name="key_ac02_main">s</string>
+ <string name="key_ac02_shift">S</string>
+ <string name="key_ac02_alt">@string/alternates_for_s</string>
+
+ <string name="key_ac03_main">d</string>
+ <string name="key_ac03_shift">D</string>
+ <string name="key_ac03_alt">@string/alternates_for_d</string>
+
+ <string name="key_ac04_main">f</string>
+ <string name="key_ac04_shift">F</string>
+ <string name="key_ac04_alt">@string/alternates_for_f</string>
+
+ <string name="key_ac05_main">g</string>
+ <string name="key_ac05_shift">G</string>
+ <string name="key_ac05_alt">@string/alternates_for_g</string>
+
+ <string name="key_ac06_main">h</string>
+ <string name="key_ac06_shift">H</string>
+ <string name="key_ac06_alt">@string/alternates_for_h</string>
+
+ <string name="key_ac07_main">j</string>
+ <string name="key_ac07_shift">J</string>
+ <string name="key_ac07_alt">@string/alternates_for_j</string>
+
+ <string name="key_ac08_main">k</string>
+ <string name="key_ac08_shift">K</string>
+ <string name="key_ac08_alt">@string/alternates_for_k</string>
+
+ <string name="key_ac09_main">l</string>
+ <string name="key_ac09_shift">L</string>
+ <string name="key_ac09_alt">@string/alternates_for_l</string>
+
+ <string name="key_ac10_main">ç</string>
+ <string name="key_ac10_shift">Ç</string>
+ <string name="key_ac10_alt"></string>
+
+ <string name="key_ac11_main">&#x303;</string>
+ <string name="key_ac11_shift">&#x302;</string>
+ <string name="key_ac11_alt">&#x303;&#x302;~^</string>
+
+
+ <string name="key_lsgt_main">&lt;</string>
+ <string name="key_lsgt_shift">&gt;</string>
+ <string name="key_lsgt_alt">&lt;&gt;≤≥‹›\\</string>
+
+ <string name="key_ab01_main">z</string>
+ <string name="key_ab01_shift">Z</string>
+ <string name="key_ab01_alt">@string/alternates_for_z</string>
+
+ <string name="key_ab02_main">x</string>
+ <string name="key_ab02_shift">X</string>
+ <string name="key_ab02_alt">@string/alternates_for_x</string>
+
+ <string name="key_ab03_main">c</string>
+ <string name="key_ab03_shift">C</string>
+ <string name="key_ab03_alt">@string/alternates_for_c</string>
+
+ <string name="key_ab04_main">v</string>
+ <string name="key_ab04_shift">V</string>
+ <string name="key_ab04_alt">@string/alternates_for_v</string>
+
+ <string name="key_ab05_main">b</string>
+ <string name="key_ab05_shift">B</string>
+ <string name="key_ab05_alt">@string/alternates_for_b</string>
+
+ <string name="key_ab06_main">n</string>
+ <string name="key_ab06_shift">N</string>
+ <string name="key_ab06_alt">@string/alternates_for_n</string>
+
+ <string name="key_ab07_main">m</string>
+ <string name="key_ab07_shift">M</string>
+ <string name="key_ab07_alt">@string/alternates_for_m</string>
+
+ <string name="key_ab08_main">,</string>
+ <string name="key_ab08_shift">;</string>
+ <string name="key_ab08_alt">,;</string>
+
+ <string name="key_ab09_main">.</string>
+ <string name="key_ab09_shift">:</string>
+ <string name="key_ab09_alt">.:…</string>
+
+ <string name="key_ab10_main">-</string>
+ <string name="key_ab10_shift">_</string>
+ <string name="key_ab10_alt">-_—–</string>
+</resources>
diff --git a/java/res/values-pt-rPT/strings.xml b/java/res/values-pt-rPT/strings.xml
new file mode 100644
index 0000000..4891d45
--- /dev/null
+++ b/java/res/values-pt-rPT/strings.xml
@@ -0,0 +1,140 @@
+<?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/org.pocketworkstation.pckeyboard"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- <string name="english_ime_name" msgid="7252517407088836577">"Teclado do Android"</string> -->
+ <!-- <string name="english_ime_settings" msgid="6661589557206947774">"Definições de teclado do Android"</string> -->
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Opções de introdução"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrar ao primir as teclas"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"Som ao premir as teclas"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"Mostrar popup ao premir tecla"</string>
+ <string name="hit_correction" msgid="4855351009261318389">"Corrigir erros de escrita"</string>
+ <string name="hit_correction_summary" msgid="8761701873008070796">"Activar a correcção de erros de entrada"</string>
+ <string name="hit_correction_land" msgid="2567691684825205448">"Erros de entrada na horizontal"</string>
+ <string name="hit_correction_land_summary" msgid="4076803842198368328">"Activar a correcção de erros de entrada"</string>
+ <string name="auto_correction" msgid="7911639788808958255">"Sugestões de palavras"</string>
+ <string name="auto_correction_summary" msgid="6881047311475758267">"Corrigir automaticamente a palavra anterior"</string>
+ <string name="prediction" msgid="466220283138359837">"Sugestões de palavras"</string>
+ <string name="prediction_category" msgid="7027100625580696660">"Definições de sugestão de palavras"</string>
+ <string name="prediction_summary" msgid="459788228830873110">"Activar a conclusão automática durante a escrita"</string>
+ <string name="auto_complete_dialog_title" msgid="2172048590607201920">"Conclusão automática"</string>
+ <string name="prediction_landscape" msgid="4874601565593216183">"Aumentar o tamanho do campo de texto"</string>
+ <string name="prediction_landscape_summary" msgid="6736551095997839472">"Ocultar sugestões de palavras na vista horizontal"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"Letras maiúsculas automáticas"</string>
+ <string name="auto_cap_summary" msgid="3260681697600786825">"Colocar inicial maiúscula no início de uma frase"</string>
+ <string name="auto_punctuate" msgid="7276672334264521751">"Pontuação automática"</string>
+ <string name="auto_punctuate_summary" msgid="6589441565817502132"></string>
+ <string name="quick_fixes" msgid="5353213327680897927">"Correcções rápidas"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"Corrige os erros de escrita comuns"</string>
+ <string name="show_suggestions" msgid="507074425254289133">"Mostrar sugestões"</string>
+ <string name="show_suggestions_summary" msgid="1989672863935759654">"Apresentar sugestões de palavras ao escrever"</string>
+ <string name="auto_complete" msgid="1103196318775486023">"Conclusão automática"</string>
+ <string name="auto_complete_summary" msgid="6113149638718274624">"A barra de espaços e a pontuação inserem automaticamente uma palavra realçada"</string>
+ <string name="prefs_settings_key" msgid="4623341240804046498">"Mostrar tecla das definições"</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automático"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Mostrar sempre"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"Ocultar sempre"</string>
+ <!-- no translation found for settings_key_modes:0 (8549888726962891527) -->
+ <!-- no translation found for settings_key_modes:1 (881280041213210923) -->
+ <!-- no translation found for settings_key_modes:2 (7317310620171067848) -->
+ <string name="bigram_suggestion" msgid="1323347224043514969">"Sugestões Bigram"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Utilizar a palavra anterior para melhorar a sugestão"</string>
+ <string-array name="prediction_modes">
+ <item msgid="4870266572388153286">"Nenhum"</item>
+ <item msgid="1669461741568287396">"Básico"</item>
+ <item msgid="4894328801530136615">"Avançados"</item>
+ </string-array>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: guardada"</string>
+ <string name="tip_long_press" msgid="6101270866284343344">"Mantenha uma tecla premida para ver os acentos (ø, ö, etc.)"</string>
+ <string name="tip_dismiss" msgid="7585579046862204381">"Prima a tecla de retrocesso ↶ para fechar o teclado a qualquer momento"</string>
+ <string name="tip_access_symbols" msgid="6344098517525531652">"Aceder a números e símbolos"</string>
+ <string name="tip_add_to_dictionary" msgid="1487293888469227817">"Prima e mantenha premida a palavra mais à esquerda para a adicionar ao dicionário"</string>
+ <string name="touch_to_continue" msgid="7869803257948414531">"Toque nesta sugestão para continuar »"</string>
+ <string name="touch_to_finish" msgid="7990196086480585789">"Toque aqui para fechar esta sugestão e começar a escrever!"</string>
+ <string name="tip_to_open_keyboard" msgid="6821200275486950452"><b>"O teclado abre quando tocar num campo de texto"</b></string>
+ <string name="tip_to_view_accents" msgid="5433158573693308501"><b>"Mantenha premida uma tecla para ver os acentos"\n"(ø, ö, ô, ó, etc.)"</b></string>
+ <string name="tip_to_open_symbols" msgid="7345139325622444880"><b>"Mude para números e símbolos tocando nesta tecla"</b></string>
+ <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"Regresse às letras tocando novamente nesta tecla"</b></string>
+ <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"Mantenha premida esta tecla para alterar definições do teclado, tais como a conclusão automática"</b></string>
+ <string name="tip_to_start_typing" msgid="7213843601369174313"><b>"Experimente!"</b></string>
+ <string name="label_go_key" msgid="1635148082137219148">"Ir"</string>
+ <string name="label_next_key" msgid="362972844525672568">"Seguinte"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"Feito"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"Enviar"</string>
+ <string name="label_symbol_key" msgid="6175820506864489453">"?123"</string>
+ <string name="label_phone_key" msgid="4275497665515080551">"123"</string>
+ <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string>
+ <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string>
+ <string name="voice_warning_title" msgid="4419354150908395008">"Entrada de voz"</string>
+ <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Actualmente, a entrada de voz não é suportada para o seu idioma, mas funciona em inglês."</string>
+ <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"A entrada de voz é uma funcionalidade experimental que utiliza o reconhecimento de voz em rede da Google."</string>
+ <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"Para desactivar a entrada de voz, aceda às definições do teclado."</string>
+ <string name="voice_hint_dialog_message" msgid="6892342981545727994">"Para utilizar a entrada de voz, prima o botão do microfone ou deslize o dedo no teclado do ecrã."</string>
+ <string name="voice_listening" msgid="467518160751321844">"Falar agora"</string>
+ <string name="voice_working" msgid="6666937792815731889">"A executar"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"Erro. Tente novamente."</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"Não foi possível ligar"</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"Erro, discurso demasiado longo."</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"Problema de áudio"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"Erro no servidor"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"Nenhuma voz ouvida"</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"Não foram encontradas correspondências"</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"Pesquisa de voz não instalada"</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Sugestão:"</b>" Deslize no teclado para falar"</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Sugestão:"</b>" Da próxima vez, experimente dizer a pontuação como \"ponto final\", \"vírgula\" ou \"ponto de interrogação\"."</string>
+ <string name="cancel" msgid="6830980399865683324">"Cancelar"</string>
+ <string name="ok" msgid="7898366843681727667">"OK"</string>
+ <string name="voice_input" msgid="2466640768843347841">"Entrada de voz"</string>
+ <string-array name="voice_input_modes">
+ <item msgid="1349082139076086774">"No teclado principal"</item>
+ <item msgid="8529385602829095903">"No teclado de símbolos"</item>
+ <item msgid="7283103513488381103">"Desactivada"</item>
+ </string-array>
+ <string-array name="voice_input_modes_summary">
+ <item msgid="554248625705084903">"Microfone no teclado principal"</item>
+ <item msgid="6907837061058876770">"Microfone no teclado de símbolos"</item>
+ <item msgid="3664304608587798036">"A entrada de voz está desactivada"</item>
+ </string-array>
+ <string name="auto_submit" msgid="9151008027068358518">"Enviar automaticamente depois da voz"</string>
+ <string name="auto_submit_summary" msgid="4961875269610384226">"Premir automaticamente ENTER ao pesquisar ou avançar para o campo seguinte."</string>
+ <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Abra o teclado"\n</b></font><font size="3">\n</font>"Toque em qualquer campo de texto."</string>
+ <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Feche o teclado"\n</b></font><font size="3">\n</font>"Prima a tecla \"Anterior\"."</string>
+ <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Mantenha premida uma tecla para as opções"\n</b></font><font size="3">\n</font>"Aceder a pontuação e acentos."</string>
+ <string name="keyboard_settings" msgid="4585753477617374032"><font size="17"><b>"Definições do teclado"\n</b></font><font size="3">\n</font>"Mantenha premida a tecla "<b>"?123"</b>"."</string>
+ <string name="popular_domain_0" msgid="3745279225122472969">".com"</string>
+ <string name="popular_domain_1" msgid="1370572248164278467">".net"</string>
+ <string name="popular_domain_2" msgid="3036812463748402878">".org"</string>
+ <string name="popular_domain_3" msgid="8718639560809452028">".gov"</string>
+ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"Seleccionar método de entrada"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Idiomas de entrada"</string>
+ <string name="language_selection_summary" msgid="187110938289512256">"Deslize o dedo pela barra de espaço para alterar o idioma"</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Toque novamente para guardar"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"Dicionário disponível"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"Activar comentários do utilizador"</string>
+ <string name="prefs_description_log" msgid="5827825607258246003">"Envie automaticamente estatísticas de utilização e relatórios de falhas para a Google e ajude-nos a melhor este editor de método de introdução."</string>
+ <string name="prefs_enable_recorrection" msgid="4588408906649533582">"Tocar para corrigir palavras"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="1056068922330206170">"Tocar nas palavras introduzidas para as corrigir"</string>
+ <string name="keyboard_layout" msgid="437433231038683666">"Tema do teclado"</string>
+ <string name="subtype_mode_keyboard" msgid="2242090416595003881">"teclado"</string>
+ <string name="subtype_mode_voice" msgid="4394113125441627771">"voz"</string>
+</resources>
diff --git a/java/res/values-pt/donottranslate-altchars.xml b/java/res/values-pt/donottranslate-altchars.xml
new file mode 100644
index 0000000..4074cdb
--- /dev/null
+++ b/java/res/values-pt/donottranslate-altchars.xml
@@ -0,0 +1,30 @@
+<?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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="alternates_for_a">àáâãäåæ</string>
+ <string name="alternates_for_e">3èéêë</string>
+ <string name="alternates_for_i">8ïîíì</string>
+ <string name="alternates_for_o">9øœöõôóò</string>
+ <string name="alternates_for_u">7üûúù</string>
+ <string name="alternates_for_s">§ß</string>
+ <string name="alternates_for_n">ñ</string>
+ <string name="alternates_for_c">ç</string>
+ <string name="alternates_for_y">6ÿý</string>
+</resources>
diff --git a/java/res/values-pt/strings.xml b/java/res/values-pt/strings.xml
new file mode 100644
index 0000000..ee3554d
--- /dev/null
+++ b/java/res/values-pt/strings.xml
@@ -0,0 +1,140 @@
+<?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/org.pocketworkstation.pckeyboard"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- <string name="english_ime_name" msgid="7252517407088836577">"Teclado Android"</string> -->
+ <!-- <string name="english_ime_settings" msgid="6661589557206947774">"Configurações de teclado Android"</string> -->
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Opções de entrada"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrar ao tocar a tecla"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"Som ao tocar a tecla"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"Exibir pop-up ao digitar"</string>
+ <string name="hit_correction" msgid="4855351009261318389">"Corrigir erros de digitação"</string>
+ <string name="hit_correction_summary" msgid="8761701873008070796">"Ativar a correção de erro de entrada"</string>
+ <string name="hit_correction_land" msgid="2567691684825205448">"Erros de entrada de paisagem"</string>
+ <string name="hit_correction_land_summary" msgid="4076803842198368328">"Ativar a correção de erro de entrada"</string>
+ <string name="auto_correction" msgid="7911639788808958255">"Sugestões de palavra"</string>
+ <string name="auto_correction_summary" msgid="6881047311475758267">"Corrigir automaticamente a palavra anterior"</string>
+ <string name="prediction" msgid="466220283138359837">"Sugestões de palavra"</string>
+ <string name="prediction_category" msgid="7027100625580696660">"Configurações de sugestão de palavra"</string>
+ <string name="prediction_summary" msgid="459788228830873110">"Ativar a conclusão automática durante a digitação"</string>
+ <string name="auto_complete_dialog_title" msgid="2172048590607201920">"Conclusão automática"</string>
+ <string name="prediction_landscape" msgid="4874601565593216183">"Aumentar o tamanho do arquivo de texto"</string>
+ <string name="prediction_landscape_summary" msgid="6736551095997839472">"Ocultar sugestões de palavra na visualização da paisagem"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"Capitaliz. automática"</string>
+ <string name="auto_cap_summary" msgid="3260681697600786825">"Colocar em maiúscula o início de uma frase"</string>
+ <string name="auto_punctuate" msgid="7276672334264521751">"Pontuação automática"</string>
+ <string name="auto_punctuate_summary" msgid="6589441565817502132"></string>
+ <string name="quick_fixes" msgid="5353213327680897927">"Reparos rápidos"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"Corrige erros comuns de digitação"</string>
+ <string name="show_suggestions" msgid="507074425254289133">"Mostrar sugestões"</string>
+ <string name="show_suggestions_summary" msgid="1989672863935759654">"Exibir sugestões de palavras durante a digitação"</string>
+ <string name="auto_complete" msgid="1103196318775486023">"Conclusão automática"</string>
+ <string name="auto_complete_summary" msgid="6113149638718274624">"Barra de espaço e pontuação inserem a palavra destacada"</string>
+ <string name="prefs_settings_key" msgid="4623341240804046498">"Mostrar tecla de config."</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automático"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Mostrar sempre"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"Sempre ocultar"</string>
+ <!-- no translation found for settings_key_modes:0 (8549888726962891527) -->
+ <!-- no translation found for settings_key_modes:1 (881280041213210923) -->
+ <!-- no translation found for settings_key_modes:2 (7317310620171067848) -->
+ <string name="bigram_suggestion" msgid="1323347224043514969">"Sugestões de bigrama"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Usar palavra anterior para melhorar a sugestão"</string>
+ <string-array name="prediction_modes">
+ <item msgid="4870266572388153286">"Nenhum"</item>
+ <item msgid="1669461741568287396">"Básico"</item>
+ <item msgid="4894328801530136615">"Avançado"</item>
+ </string-array>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Salvo"</string>
+ <string name="tip_long_press" msgid="6101270866284343344">"Segure uma tecla pressionada para ver os acentos (ø, ö, etc.)"</string>
+ <string name="tip_dismiss" msgid="7585579046862204381">"Apertar a tecla voltar ↶ para fechar o teclado, em qualquer ponto"</string>
+ <string name="tip_access_symbols" msgid="6344098517525531652">"Acessar números e símbolos"</string>
+ <string name="tip_add_to_dictionary" msgid="1487293888469227817">"Pressione e segure a palavra mais à esquerda para adicioná-la ao dicionário"</string>
+ <string name="touch_to_continue" msgid="7869803257948414531">"Toque nesta dica para continuar »"</string>
+ <string name="touch_to_finish" msgid="7990196086480585789">"Toque aqui para fechar esta dica e começar a digitar!"</string>
+ <string name="tip_to_open_keyboard" msgid="6821200275486950452"><b>"O teclado abre toda vez que você tocar em um campo de texto"</b></string>
+ <string name="tip_to_view_accents" msgid="5433158573693308501"><b>"Tocar e segurar uma tecla para visualizar acentos"\n"(ø, ö, ô, ó e assim por diante)"</b></string>
+ <string name="tip_to_open_symbols" msgid="7345139325622444880"><b>"Alternar para números e símbolos tocando nessa tecla"</b></string>
+ <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"Voltar às letras tocando novamente nessa tecla"</b></string>
+ <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"Tocar e segurar esta tecla para alterar as configurações do teclado, como a conclusão automática"</b></string>
+ <string name="tip_to_start_typing" msgid="7213843601369174313"><b>"Experimente!"</b></string>
+ <string name="label_go_key" msgid="1635148082137219148">"Ir"</string>
+ <string name="label_next_key" msgid="362972844525672568">"Avançar"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"Feito"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"Enviar"</string>
+ <string name="label_symbol_key" msgid="6175820506864489453">"?123"</string>
+ <string name="label_phone_key" msgid="4275497665515080551">"123"</string>
+ <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string>
+ <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string>
+ <string name="voice_warning_title" msgid="4419354150908395008">"Entrada de voz"</string>
+ <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"A entrada de voz não é suportada no momento para o seu idioma, mas funciona em inglês."</string>
+ <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"A entrada de voz é um recurso experimental que usa o reconhecimento de fala de rede do Google."</string>
+ <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"Para desativar a entrada de voz, vá para as configurações do teclado."</string>
+ <string name="voice_hint_dialog_message" msgid="6892342981545727994">"Para usar a entrada de voz, pressione o botão com o microfone ou deslize o dedo sobre o teclado na tela."</string>
+ <string name="voice_listening" msgid="467518160751321844">"Fale agora"</string>
+ <string name="voice_working" msgid="6666937792815731889">"Trabalhando"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"Erro. Tente novamente."</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"Não foi possível conectar"</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"Erro, fala muito longa."</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"Problema com o áudio"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"Erro do servidor"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"Nenhuma fala ouvida"</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"Não há resultados compatíveis"</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"A pesquisa por voz não está instalada"</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Dica:"</b>" Deslize sobre o teclado para falar"</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Dica:"</b>" Da próxima vez, tente falar o nome da pontuação como \"ponto\", \"vírgula\" ou \"ponto de interrogação\"."</string>
+ <string name="cancel" msgid="6830980399865683324">"Cancelar"</string>
+ <string name="ok" msgid="7898366843681727667">"OK"</string>
+ <string name="voice_input" msgid="2466640768843347841">"Entrada de voz"</string>
+ <string-array name="voice_input_modes">
+ <item msgid="1349082139076086774">"No teclado principal"</item>
+ <item msgid="8529385602829095903">"No teclado de símbolos"</item>
+ <item msgid="7283103513488381103">"Desativado"</item>
+ </string-array>
+ <string-array name="voice_input_modes_summary">
+ <item msgid="554248625705084903">"Microfone no teclado principal"</item>
+ <item msgid="6907837061058876770">"Microfone no teclado de símbolos"</item>
+ <item msgid="3664304608587798036">"Entrada de voz desativada"</item>
+ </string-array>
+ <string name="auto_submit" msgid="9151008027068358518">"Enviar automaticamente depois de falar"</string>
+ <string name="auto_submit_summary" msgid="4961875269610384226">"Pressione Enter automaticamente ao pesquisar ou ir para o próximo campo."</string>
+ <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Abra o teclado"\n</b></font><font size="3">\n</font>"Toque em qualquer campo de texto."</string>
+ <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Feche o teclado"\n</b></font><font size="3">\n</font>"Pressione a tecla Voltar."</string>
+ <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Toque e mantenha pressionada uma tecla para ver as opções"\n</b></font><font size="3">\n</font>"Acesse a pontuação e as pronúncias."</string>
+ <string name="keyboard_settings" msgid="4585753477617374032"><font size="17"><b>"Configurações de teclado"\n</b></font><font size="3">\n</font>"Toque e mantenha pressionada a tecla "<b>"?123"</b>"."</string>
+ <string name="popular_domain_0" msgid="3745279225122472969">".com"</string>
+ <string name="popular_domain_1" msgid="1370572248164278467">".net"</string>
+ <string name="popular_domain_2" msgid="3036812463748402878">".org"</string>
+ <string name="popular_domain_3" msgid="8718639560809452028">".gov"</string>
+ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"Selecionar método de entrada"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Idiomas de entrada"</string>
+ <string name="language_selection_summary" msgid="187110938289512256">"Deslize o dedo na barra de espaços para alterar o idioma"</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Toque novamente para salvar"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"Dicionário disponível"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"Ativar comentário do usuário"</string>
+ <string name="prefs_description_log" msgid="5827825607258246003">"Ajude a melhorar este editor de método de entrada enviando automaticamente ao Google estatísticas de uso e relatórios de falhas."</string>
+ <string name="prefs_enable_recorrection" msgid="4588408906649533582">"Tocar para corrigir"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="1056068922330206170">"Toque as palavras para corrigi-las"</string>
+ <string name="keyboard_layout" msgid="437433231038683666">"Tema do teclado"</string>
+ <string name="subtype_mode_keyboard" msgid="2242090416595003881">"teclado"</string>
+ <string name="subtype_mode_voice" msgid="4394113125441627771">"voz"</string>
+</resources>
diff --git a/java/res/values-rm/donottranslate-altchars.xml b/java/res/values-rm/donottranslate-altchars.xml
new file mode 100644
index 0000000..e697980
--- /dev/null
+++ b/java/res/values-rm/donottranslate-altchars.xml
@@ -0,0 +1,30 @@
+<?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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="alternates_for_a">àáâãäåæ</string>
+ <string name="alternates_for_e">3èéêë</string>
+ <string name="alternates_for_i">8ïîíì</string>
+ <string name="alternates_for_o">9øœõôöóò</string>
+ <string name="alternates_for_u">7üûúù</string>
+ <string name="alternates_for_s">§ß</string>
+ <string name="alternates_for_n">ñ</string>
+ <string name="alternates_for_c">ç</string>
+ <string name="alternates_for_y">6ÿý</string>
+</resources>
diff --git a/java/res/values-rm/strings.xml b/java/res/values-rm/strings.xml
new file mode 100644
index 0000000..27a1a3a
--- /dev/null
+++ b/java/res/values-rm/strings.xml
@@ -0,0 +1,148 @@
+<?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/org.pocketworkstation.pckeyboard"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- <string name="english_ime_name" msgid="7252517407088836577">"Tastatura Android"</string> -->
+ <!-- <string name="english_ime_settings" msgid="6661589557206947774">"Parameters da la tastatura Android"</string> -->
+ <!-- no translation found for english_ime_input_options (3909945612939668554) -->
+ <skip />
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrar cun smatgar in buttun"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"Tun cun smatgar in buttun"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"Pop-up cun smatgar ina tasta"</string>
+ <string name="hit_correction" msgid="4855351009261318389">"Curreger sbagls d\'endataziun"</string>
+ <string name="hit_correction_summary" msgid="8761701873008070796">"Activar la correctura da sbagls d\'endataziun"</string>
+ <string name="hit_correction_land" msgid="2567691684825205448">"Sbagls d\'endataziun en il format orizontal"</string>
+ <string name="hit_correction_land_summary" msgid="4076803842198368328">"Activar la correctura da sbagls d\'endataziun"</string>
+ <string name="auto_correction" msgid="7911639788808958255">"Propostas da pleds"</string>
+ <string name="auto_correction_summary" msgid="6881047311475758267">"Curreger automaticamain il pled precedent"</string>
+ <string name="prediction" msgid="466220283138359837">"Propostas da pleds"</string>
+ <string name="prediction_category" msgid="7027100625580696660">"Parameters da las propostas per pleds"</string>
+ <string name="prediction_summary" msgid="459788228830873110">"Activar la cumplettaziun automatica durant l\'endataziun"</string>
+ <string name="auto_complete_dialog_title" msgid="2172048590607201920">"Cumplettaziun automatica"</string>
+ <string name="prediction_landscape" msgid="4874601565593216183">"Engrondir il champ da text"</string>
+ <string name="prediction_landscape_summary" msgid="6736551095997839472">"Zuppentar propostas da pleds en il format orizontal"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"Maiusclas automaticas"</string>
+ <string name="auto_cap_summary" msgid="3260681697600786825">"Scriver grond l\'entschatta da mintga frasa"</string>
+ <string name="auto_punctuate" msgid="7276672334264521751">"Interpuncziun automatica"</string>
+ <string name="auto_punctuate_summary" msgid="6589441565817502132"></string>
+ <string name="quick_fixes" msgid="5353213327680897927">"Correcturas sveltas"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"Curregia sbagls da tippar currents"</string>
+ <string name="show_suggestions" msgid="507074425254289133">"Mussar las propostas"</string>
+ <string name="show_suggestions_summary" msgid="1989672863935759654">"Mussar pleds proponids durant l\'endataziun"</string>
+ <string name="auto_complete" msgid="1103196318775486023">"Cumplettaziun automatica"</string>
+ <string name="auto_complete_summary" msgid="6113149638718274624">"Inserir auto. il pled marcà cun la tasta da vid/interpuncziun"</string>
+ <!-- no translation found for prefs_settings_key (4623341240804046498) -->
+ <skip />
+ <!-- no translation found for settings_key_mode_auto_name (2993460277873684680) -->
+ <skip />
+ <!-- no translation found for settings_key_mode_always_show_name (3047567041784760575) -->
+ <skip />
+ <!-- no translation found for settings_key_mode_always_hide_name (7833948046716923994) -->
+ <skip />
+ <!-- no translation found for settings_key_modes:0 (8549888726962891527) -->
+ <!-- no translation found for settings_key_modes:1 (881280041213210923) -->
+ <!-- no translation found for settings_key_modes:2 (7317310620171067848) -->
+ <string name="bigram_suggestion" msgid="1323347224043514969">"Propostas da tip bigram"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Meglierar la proposta cun agid dal pled precedent"</string>
+ <string-array name="prediction_modes">
+ <item msgid="4870266572388153286">"Nagin"</item>
+ <item msgid="1669461741568287396">"Simpel"</item>
+ <item msgid="4894328801530136615">"Avanzà"</item>
+ </string-array>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Memorisà"</string>
+ <string name="tip_long_press" msgid="6101270866284343344">"\"Tegnair smatgà per mussar ils accents (à, é, etc.)\""</string>
+ <string name="tip_dismiss" msgid="7585579046862204381">"Smatgar ↶ per serrar la tastatura"</string>
+ <string name="tip_access_symbols" msgid="6344098517525531652">"Acceder a cifras e simbols"</string>
+ <string name="tip_add_to_dictionary" msgid="1487293888469227817">"Smatgar ditg sin il pled dal tut a sanestra per l\'agiuntar al dicziunari"</string>
+ <string name="touch_to_continue" msgid="7869803257948414531">"Tutgar quest commentari per cuntinuar »"</string>
+ <string name="touch_to_finish" msgid="7990196086480585789">"\"Tutgar qua, per serrar quest commentari e cumenzar a tippar!\""</string>
+ <string name="tip_to_open_keyboard" msgid="6821200275486950452"><b>"La tastatura vegn adina averta sche Vus tutgais in champ da text."</b></string>
+ <string name="tip_to_view_accents" msgid="5433158573693308501">"\""<b>"Tegnai smatgà ina tasta per mussar ils segns spezials"\n"(ø, ö, ô, ó etc.)."</b>"\""</string>
+ <string name="tip_to_open_symbols" msgid="7345139325622444880"><b>"Midai a numers e simbols cun tutgar quest buttun."</b></string>
+ <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"Turnai a letras cun smatgar danovamain quest buttun."</b></string>
+ <string name="tip_to_launch_settings" msgid="8402961128983196128">"\""<b>"Tegnai smatgà quest buttun per midar ils parameters da tastatura, sco p. ex. la cumplettaziun automatica."</b>"\""</string>
+ <string name="tip_to_start_typing" msgid="7213843601369174313"><b>"Empruvai!"</b></string>
+ <string name="label_go_key" msgid="1635148082137219148">"Dai"</string>
+ <string name="label_next_key" msgid="362972844525672568">"Vinavant"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"Finì"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"Trametter"</string>
+ <string name="label_symbol_key" msgid="6175820506864489453">"?123"</string>
+ <string name="label_phone_key" msgid="4275497665515080551">"123"</string>
+ <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string>
+ <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string>
+ <string name="voice_warning_title" msgid="4419354150908395008">"Cumonds vocals"</string>
+ <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"\"Cumonds vocals en Vossa lingua na vegnan actualmain betg sustegnids, ma la funcziun è disponibla per englais.\""</string>
+ <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"Ils cumonds vocals èn ina funcziunalitad experimentala che utilisescha la renconuschientscha vocala da rait da Google."</string>
+ <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"\"Per deactivar ils cumonds vocals, avri ils parameters da tastatura.\""</string>
+ <string name="voice_hint_dialog_message" msgid="6892342981545727994">"\"Per utilisar ils cumonds vocals, smatgai il buttun dal microfon u stritgai cun il det sur la tastatura dal visur.\""</string>
+ <string name="voice_listening" msgid="467518160751321844">"Ussa discurrer"</string>
+ <string name="voice_working" msgid="6666937792815731889">"Operaziun en progress"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"Errur. Empruvai anc ina giada."</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"Impussibel da connectar."</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"Errur - discurrì memia ditg."</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"Problem audio"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"Errur dal server"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"Betg udì ina frasa vocala"</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"Betg chattà correspundenzas"</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"Betg installà la tschertga vocala"</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Commentari:"</b>" Stritgai cun il det sur la tastatura per discurrer."</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754">"\""<b>"Commentari:"</b>" Empruvai la proxima giada d\'agiuntar segns d\'interpuncziun sco \"\"punct\"\", \"\"comma\"\" u \"\"segn da dumonda\"\" cun cumonds vocals.\""</string>
+ <string name="cancel" msgid="6830980399865683324">"Interrumper"</string>
+ <string name="ok" msgid="7898366843681727667">"OK"</string>
+ <string name="voice_input" msgid="2466640768843347841">"Cumonds vocals"</string>
+ <string-array name="voice_input_modes">
+ <item msgid="1349082139076086774">"Sin la tastatura principala"</item>
+ <item msgid="8529385602829095903">"Sin la tastatura da simbols"</item>
+ <item msgid="7283103513488381103">"Deactivà"</item>
+ </string-array>
+ <string-array name="voice_input_modes_summary">
+ <item msgid="554248625705084903">"Microfon sin la tastatura principala"</item>
+ <item msgid="6907837061058876770">"Microfon sin la tastatura da simbols"</item>
+ <item msgid="3664304608587798036">"Ils cumonds vocals èn deactivads"</item>
+ </string-array>
+ <string name="auto_submit" msgid="9151008027068358518">"Trametter automaticamain suenter il cumond vocal"</string>
+ <string name="auto_submit_summary" msgid="4961875269610384226">"Smatgai sin la tasta enter sche Vus exequis ina tschertga u siglis al proxim champ."</string>
+ <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Avrir la tastatura"\n</b></font><font size="3">\n</font>"Tutgai inqual champ da text."</string>
+ <string name="close_the_keyboard" msgid="6251022259044940103">"\""<font size="17"><b>"Serrar la tastatura"\n</b></font><font size="3">\n</font>"Smatgai il buttun \"\"Enavos\"\".\""</string>
+ <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Tutgar e tegnair smatgà in buttun per acceder a las opziuns"\n</b></font><font size="3">\n</font>"Accedi a segns d\'interpuncziun ed accents."</string>
+ <string name="keyboard_settings" msgid="4585753477617374032"><font size="17"><b>"Parameters da tastatura"\n</b></font><font size="3">\n</font>"Tutgai e tegnai smatgà il buttun "<b>"?123"</b>"."</string>
+ <string name="popular_domain_0" msgid="3745279225122472969">".com"</string>
+ <string name="popular_domain_1" msgid="1370572248164278467">".net"</string>
+ <string name="popular_domain_2" msgid="3036812463748402878">".org"</string>
+ <string name="popular_domain_3" msgid="8718639560809452028">".gov"</string>
+ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string>
+ <!-- no translation found for selectInputMethod (315076553378705821) -->
+ <skip />
+ <string name="language_selection_title" msgid="1651299598555326750">"Linguas da cumonds vocals"</string>
+ <string name="language_selection_summary" msgid="187110938289512256">"Stritgar cun il det sur la tasta da vid per midar la lingua"</string>
+ <!-- outdated translation 8058519710062071085 --> <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Tippar danovamain per memorisar"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"Dicziunari disponibel"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"Activar il feedback da l\'utilisader"</string>
+ <string name="prefs_description_log" msgid="5827825607258246003">"Gidai a meglierar quest editur da la metoda d\'endataziun cun trametter automaticamain datas statisticas davart l\'utilisaziun e rapports da collaps a Google."</string>
+ <!-- no translation found for prefs_enable_recorrection (4588408906649533582) -->
+ <skip />
+ <!-- no translation found for prefs_enable_recorrection_summary (1056068922330206170) -->
+ <skip />
+ <string name="keyboard_layout" msgid="437433231038683666">"Design da la tastatura"</string>
+ <string name="subtype_mode_keyboard" msgid="2242090416595003881">"tastatura"</string>
+ <string name="subtype_mode_voice" msgid="4394113125441627771">"vusch"</string>
+</resources>
diff --git a/java/res/values-ro/donottranslate-altchars.xml b/java/res/values-ro/donottranslate-altchars.xml
new file mode 100644
index 0000000..b5da92b
--- /dev/null
+++ b/java/res/values-ro/donottranslate-altchars.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="alternates_for_a">ăâáàãäå</string>
+ <string name="alternates_for_i">8îíìï</string>
+ <string name="alternates_for_s">ș§ßš</string>
+ <string name="alternates_for_t">5ț</string>
+</resources>
diff --git a/java/res/values-ro/donottranslate-keymap.xml b/java/res/values-ro/donottranslate-keymap.xml
new file mode 100644
index 0000000..8711884
--- /dev/null
+++ b/java/res/values-ro/donottranslate-keymap.xml
@@ -0,0 +1,221 @@
+<?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.
+**
+**
+** 5-row layout for English QWERTY.
+**
+** See http://code.google.com/p/hackerskeyboard/wiki/AddingNewLayouts for
+** more information.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="key_tlde_main">`</string>
+ <string name="key_tlde_shift">~</string>
+ <string name="key_tlde_alt">`~</string>
+
+ <string name="key_ae01_main">1</string>
+ <string name="key_ae01_shift">!</string>
+ <string name="key_ae01_alt">1!¡¹½⅓¼⅛</string>
+
+ <string name="key_ae02_main">2</string>
+ <string name="key_ae02_shift">\@</string>
+ <string name="key_ae02_alt">2\@²⅔</string>
+
+ <string name="key_ae03_main">3</string>
+ <string name="key_ae03_shift">#</string>
+ <string name="key_ae03_alt">3#³¾⅜♥♠♦♣</string>
+
+ <string name="key_ae04_main">4</string>
+ <string name="key_ae04_shift">$</string>
+ <string name="key_ae04_alt">4$⁴¢£€¥</string>
+
+ <string name="key_ae05_main">5</string>
+ <string name="key_ae05_shift">%</string>
+ <string name="key_ae05_alt">5%⅝‰</string>
+
+ <string name="key_ae06_main">6</string>
+ <string name="key_ae06_shift">^</string>
+ <string name="key_ae06_alt">6^↑↓←→</string>
+
+ <string name="key_ae07_main">7</string>
+ <string name="key_ae07_shift">&amp;</string>
+ <string name="key_ae07_alt">7&amp;⅞♪</string>
+
+ <string name="key_ae08_main">8</string>
+ <string name="key_ae08_shift">*</string>
+ <string name="key_ae08_alt">8*•★∞†‡</string>
+
+ <string name="key_ae09_main">9</string>
+ <string name="key_ae09_shift">(</string>
+ <string name="key_ae09_alt">9(√</string>
+
+ <string name="key_ae10_main">0</string>
+ <string name="key_ae10_shift">)</string>
+ <string name="key_ae10_alt">0)ⁿ°</string>
+
+ <string name="key_ae11_main">-</string>
+ <string name="key_ae11_shift">_</string>
+ <string name="key_ae11_alt">-_—–</string>
+
+ <string name="key_ae12_main">=</string>
+ <string name="key_ae12_shift">+</string>
+ <string name="key_ae12_alt">=+≈≠±×÷</string>
+
+
+ <string name="key_ad01_main">q</string>
+ <string name="key_ad01_shift">Q</string>
+ <string name="key_ad01_alt">@string/alternates_for_q</string>
+
+ <string name="key_ad02_main">w</string>
+ <string name="key_ad02_shift">W</string>
+ <string name="key_ad02_alt">@string/alternates_for_w</string>
+
+ <string name="key_ad03_main">e</string>
+ <string name="key_ad03_shift">E</string>
+ <string name="key_ad03_alt">@string/alternates_for_e</string>
+
+ <string name="key_ad04_main">r</string>
+ <string name="key_ad04_shift">R</string>
+ <string name="key_ad04_alt">@string/alternates_for_r</string>
+
+ <string name="key_ad05_main">t</string>
+ <string name="key_ad05_shift">T</string>
+ <string name="key_ad05_alt">@string/alternates_for_t</string>
+
+ <string name="key_ad06_main">y</string>
+ <string name="key_ad06_shift">Y</string>
+ <string name="key_ad06_alt">@string/alternates_for_y</string>
+
+ <string name="key_ad07_main">u</string>
+ <string name="key_ad07_shift">U</string>
+ <string name="key_ad07_alt">@string/alternates_for_u</string>
+
+ <string name="key_ad08_main">i</string>
+ <string name="key_ad08_shift">I</string>
+ <string name="key_ad08_alt">@string/alternates_for_i</string>
+
+ <string name="key_ad09_main">o</string>
+ <string name="key_ad09_shift">O</string>
+ <string name="key_ad09_alt">@string/alternates_for_o</string>
+
+ <string name="key_ad10_main">p</string>
+ <string name="key_ad10_shift">P</string>
+ <string name="key_ad10_alt">@string/alternates_for_p</string>
+
+ <string name="key_ad11_main">ă</string>
+ <string name="key_ad11_shift">Ă</string>
+ <string name="key_ad11_alt">[{</string>
+
+ <string name="key_ad12_main">î</string>
+ <string name="key_ad12_shift">Î</string>
+ <string name="key_ad12_alt">]}</string>
+
+ <string name="key_bksl_main">â</string>
+ <string name="key_bksl_shift">Â</string>
+ <string name="key_bksl_alt">\\|</string>
+
+
+ <string name="key_ac01_main">a</string>
+ <string name="key_ac01_shift">A</string>
+ <string name="key_ac01_alt">@string/alternates_for_a</string>
+
+ <string name="key_ac02_main">s</string>
+ <string name="key_ac02_shift">S</string>
+ <string name="key_ac02_alt">@string/alternates_for_s</string>
+
+ <string name="key_ac03_main">d</string>
+ <string name="key_ac03_shift">D</string>
+ <string name="key_ac03_alt">@string/alternates_for_d</string>
+
+ <string name="key_ac04_main">f</string>
+ <string name="key_ac04_shift">F</string>
+ <string name="key_ac04_alt">@string/alternates_for_f</string>
+
+ <string name="key_ac05_main">g</string>
+ <string name="key_ac05_shift">G</string>
+ <string name="key_ac05_alt">@string/alternates_for_g</string>
+
+ <string name="key_ac06_main">h</string>
+ <string name="key_ac06_shift">H</string>
+ <string name="key_ac06_alt">@string/alternates_for_h</string>
+
+ <string name="key_ac07_main">j</string>
+ <string name="key_ac07_shift">J</string>
+ <string name="key_ac07_alt">@string/alternates_for_j</string>
+
+ <string name="key_ac08_main">k</string>
+ <string name="key_ac08_shift">K</string>
+ <string name="key_ac08_alt">@string/alternates_for_k</string>
+
+ <string name="key_ac09_main">l</string>
+ <string name="key_ac09_shift">L</string>
+ <string name="key_ac09_alt">@string/alternates_for_l</string>
+
+ <string name="key_ac10_main">ș</string>
+ <string name="key_ac10_shift">Ș</string>
+ <string name="key_ac10_alt">;:</string>
+
+ <string name="key_ac11_main">ț</string>
+ <string name="key_ac11_shift">Ț</string>
+ <string name="key_ac11_alt">\'\"‘’“”</string>
+
+
+ <string name="key_lsgt_main"></string>
+ <string name="key_lsgt_shift"></string>
+ <string name="key_lsgt_alt"></string>
+
+ <string name="key_ab01_main">z</string>
+ <string name="key_ab01_shift">Z</string>
+ <string name="key_ab01_alt">@string/alternates_for_z</string>
+
+ <string name="key_ab02_main">x</string>
+ <string name="key_ab02_shift">X</string>
+ <string name="key_ab02_alt">@string/alternates_for_x</string>
+
+ <string name="key_ab03_main">c</string>
+ <string name="key_ab03_shift">C</string>
+ <string name="key_ab03_alt">@string/alternates_for_c</string>
+
+ <string name="key_ab04_main">v</string>
+ <string name="key_ab04_shift">V</string>
+ <string name="key_ab04_alt">@string/alternates_for_v</string>
+
+ <string name="key_ab05_main">b</string>
+ <string name="key_ab05_shift">B</string>
+ <string name="key_ab05_alt">@string/alternates_for_b</string>
+
+ <string name="key_ab06_main">n</string>
+ <string name="key_ab06_shift">N</string>
+ <string name="key_ab06_alt">@string/alternates_for_n</string>
+
+ <string name="key_ab07_main">m</string>
+ <string name="key_ab07_shift">M</string>
+ <string name="key_ab07_alt">@string/alternates_for_m</string>
+
+ <string name="key_ab08_main">,</string>
+ <string name="key_ab08_shift">&lt;</string>
+ <string name="key_ab08_alt">,&lt;≤«‹</string>
+
+ <string name="key_ab09_main">.</string>
+ <string name="key_ab09_shift">&gt;</string>
+ <string name="key_ab09_alt">&gt;≥»›…</string>
+
+ <string name="key_ab10_main">/</string>
+ <string name="key_ab10_shift">\?</string>
+ <string name="key_ab10_alt">/\?¿</string>
+</resources>
diff --git a/java/res/values-ro/strings.xml b/java/res/values-ro/strings.xml
new file mode 100644
index 0000000..5323984
--- /dev/null
+++ b/java/res/values-ro/strings.xml
@@ -0,0 +1,140 @@
+<?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/org.pocketworkstation.pckeyboard"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- <string name="english_ime_name" msgid="7252517407088836577">"Tastatură Android"</string> -->
+ <!-- <string name="english_ime_settings" msgid="6661589557206947774">"Setările tastaturii Android"</string> -->
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Opţiuni de introducere text"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrare la apăsarea tastei"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"Sunet la apăsarea tastei"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"Fereastră pop-up la apăsarea tastei"</string>
+ <string name="hit_correction" msgid="4855351009261318389">"Corectaţi erorile de dactilografiere"</string>
+ <string name="hit_correction_summary" msgid="8761701873008070796">"Activaţi corectarea erorii de intrare"</string>
+ <string name="hit_correction_land" msgid="2567691684825205448">"Erori de introducere în modul peisaj"</string>
+ <string name="hit_correction_land_summary" msgid="4076803842198368328">"Activaţi corectarea erorii de intrare"</string>
+ <string name="auto_correction" msgid="7911639788808958255">"Sugestii de cuvinte"</string>
+ <string name="auto_correction_summary" msgid="6881047311475758267">"Corecţie automată a cuvântului anterior"</string>
+ <string name="prediction" msgid="466220283138359837">"Sugestii de cuvinte"</string>
+ <string name="prediction_category" msgid="7027100625580696660">"Setările sugestiei de cuvinte"</string>
+ <string name="prediction_summary" msgid="459788228830873110">"Activaţi completarea automată în timpul introducerii textului"</string>
+ <string name="auto_complete_dialog_title" msgid="2172048590607201920">"Completare automată"</string>
+ <string name="prediction_landscape" msgid="4874601565593216183">"Măriţi dimensiunea câmpului text"</string>
+ <string name="prediction_landscape_summary" msgid="6736551095997839472">"Ascundeţi sugestiile de cuvinte în vizualizarea de tip peisaj"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"Auto-capitalizare"</string>
+ <string name="auto_cap_summary" msgid="3260681697600786825">"Doresc să se scrie cu majusculă începutul propoziţiilor"</string>
+ <string name="auto_punctuate" msgid="7276672334264521751">"Punctuaţie automată"</string>
+ <string name="auto_punctuate_summary" msgid="6589441565817502132"></string>
+ <string name="quick_fixes" msgid="5353213327680897927">"Remedieri rapide"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"Corectează greşelile introduse frecvent"</string>
+ <string name="show_suggestions" msgid="507074425254289133">"Afişaţi sugestiile"</string>
+ <string name="show_suggestions_summary" msgid="1989672863935759654">"Afişare sugestii de cuvinte în timpul introducerii de text"</string>
+ <string name="auto_complete" msgid="1103196318775486023">"Completare automată"</string>
+ <string name="auto_complete_summary" msgid="6113149638718274624">"Bara de spaţiu şi punctuaţia inserează automat un cuvânt evidenţiat"</string>
+ <string name="prefs_settings_key" msgid="4623341240804046498">"Afişaţi tasta setări"</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automat"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Afişaţi întotdeauna"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"Ascundeţi întotdeauna"</string>
+ <!-- no translation found for settings_key_modes:0 (8549888726962891527) -->
+ <!-- no translation found for settings_key_modes:1 (881280041213210923) -->
+ <!-- no translation found for settings_key_modes:2 (7317310620171067848) -->
+ <string name="bigram_suggestion" msgid="1323347224043514969">"Sugestii pentru cuvinte de două litere"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Utilizaţi cuvântul anterior pentru a îmbunătăţi sugestia"</string>
+ <string-array name="prediction_modes">
+ <item msgid="4870266572388153286">"Niciunul"</item>
+ <item msgid="1669461741568287396">"De bază"</item>
+ <item msgid="4894328801530136615">"Avansat"</item>
+ </string-array>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: salvat"</string>
+ <string name="tip_long_press" msgid="6101270866284343344">"Ţineţi o tastă apăsată pentru a vedea accentele (ø, ö, etc.)"</string>
+ <string name="tip_dismiss" msgid="7585579046862204381">"Apăsaţi tasta Înapoi ↶ pentru a închide oricând tastatura"</string>
+ <string name="tip_access_symbols" msgid="6344098517525531652">"Accesaţi numere şi simboluri"</string>
+ <string name="tip_add_to_dictionary" msgid="1487293888469227817">"Apăsaţi şi ţineţi apăsat pe cuvântul cel mai din stânga, pentru a-l adăuga la dicţionar"</string>
+ <string name="touch_to_continue" msgid="7869803257948414531">"Atingeţi acest indiciu pentru a continua »"</string>
+ <string name="touch_to_finish" msgid="7990196086480585789">"Atingeţi aici pentru a închide acest indiciu şi începeţi să introduceţi text!"</string>
+ <string name="tip_to_open_keyboard" msgid="6821200275486950452"><b>"Tastatura se deschide de fiecare dată când atingeţi un câmp text"</b></string>
+ <string name="tip_to_view_accents" msgid="5433158573693308501"><b>"Atingeţi şi ţineţi apăsată o tastă pentru a vizualiza accentele"\n"(ø, ö, ô, ó etc.)"</b></string>
+ <string name="tip_to_open_symbols" msgid="7345139325622444880"><b>"Comutaţi între numere şi simboluri atingând această tastă"</b></string>
+ <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"Reveniţi la litere prin atingerea acestei taste din nou"</b></string>
+ <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"Apăsaţi şi ţineţi apăsată această tastă pentru a schimba setările tastaturii, cum ar fi completarea automată"</b></string>
+ <string name="tip_to_start_typing" msgid="7213843601369174313"><b>"Încercaţi!"</b></string>
+ <string name="label_go_key" msgid="1635148082137219148">"Accesaţi"</string>
+ <string name="label_next_key" msgid="362972844525672568">"Înainte"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"Terminat"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"Trimiteţi"</string>
+ <string name="label_symbol_key" msgid="6175820506864489453">"?123"</string>
+ <string name="label_phone_key" msgid="4275497665515080551">"123"</string>
+ <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string>
+ <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string>
+ <string name="voice_warning_title" msgid="4419354150908395008">"Intrare voce"</string>
+ <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Intrarea vocală nu este acceptată în prezent pentru limba dvs., însă funcţionează în limba engleză."</string>
+ <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"Intrarea vocală este o funcţie experimentală ce utilizează recunoaşterea vocală în reţea oferită de Google."</string>
+ <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"Pentru a dezactiva intrarea vocală, accesaţi setările tastaturii."</string>
+ <string name="voice_hint_dialog_message" msgid="6892342981545727994">"Pentru a utiliza intrarea vocală, apăsaţi butonul de microfon sau glisaţi degetul de-a lungul tastaturii de pe ecran."</string>
+ <string name="voice_listening" msgid="467518160751321844">"Vorbiţi acum"</string>
+ <string name="voice_working" msgid="6666937792815731889">"Se analizează"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"Eroare. Încercaţi din nou."</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"Conectare imposibilă"</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"Eroare, discurs prea lung."</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"Problemă audio"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"Eroare de server"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"Nu s-a auzit vorbirea"</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"Nicio potrivire"</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"Căutarea vocală nu este instalată"</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Indiciu:"</b>" glisaţi de-a lungul tastaturii pentru a vorbi"</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Indiciu:"</b>" data viitoare, încercaţi să rostiţi şi punctuaţia, cum ar fi „punct”, „virgulă”, sau „semn de întrebare”."</string>
+ <string name="cancel" msgid="6830980399865683324">"Anulaţi"</string>
+ <string name="ok" msgid="7898366843681727667">"OK"</string>
+ <string name="voice_input" msgid="2466640768843347841">"Intrare voce"</string>
+ <string-array name="voice_input_modes">
+ <item msgid="1349082139076086774">"Pe tastatura principală"</item>
+ <item msgid="8529385602829095903">"Pe tastatura de simboluri"</item>
+ <item msgid="7283103513488381103">"Dezactivat"</item>
+ </string-array>
+ <string-array name="voice_input_modes_summary">
+ <item msgid="554248625705084903">"Microfon pe tastatura principală"</item>
+ <item msgid="6907837061058876770">"Microfon pe tastatura de simboluri"</item>
+ <item msgid="3664304608587798036">"Intrarea vocală este dezactivată"</item>
+ </string-array>
+ <string name="auto_submit" msgid="9151008027068358518">"Trimitere automată după intrarea vocală"</string>
+ <string name="auto_submit_summary" msgid="4961875269610384226">"Apăsaţi automat tasta Enter atunci când se face o căutare sau când se trece la câmpul următor."</string>
+ <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Deschideţi tastatura"\n</b></font><font size="3">\n</font>"Atingeţi orice câmp de text."</string>
+ <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Închideţi tastatura"\n</b></font><font size="3">\n</font>"Apăsaţi pe tasta Înapoi."</string>
+ <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Atingeţi şi ţineţi apăsată o tastă pentru opţiuni"\n</b></font><font size="3">\n</font>"Accesaţi punctuaţia şi accentele."</string>
+ <string name="keyboard_settings" msgid="4585753477617374032"><font size="17"><b>"Setările tastaturii"\n</b></font><font size="3">\n</font>"Atingeţi şi ţineţi apăsată tasta "<b>"?123"</b>"."</string>
+ <string name="popular_domain_0" msgid="3745279225122472969">".com"</string>
+ <string name="popular_domain_1" msgid="1370572248164278467">".net"</string>
+ <string name="popular_domain_2" msgid="3036812463748402878">".org"</string>
+ <string name="popular_domain_3" msgid="8718639560809452028">".gov"</string>
+ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"Selectaţi metoda de introducere a textului"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Selectaţi limba"</string>
+ <string name="language_selection_summary" msgid="187110938289512256">"Glisaţi degetul pe bara de spaţiu pentru a schimba limba"</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Atingeţi din nou pentru a salva"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"Dicţionar disponibil"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"Activaţi feedback de la utilizatori"</string>
+ <string name="prefs_description_log" msgid="5827825607258246003">"Ajutaţi la îmbunătăţirea acestui instrument de editare a metodelor de introducere a textului trimiţând în mod automat la Google statistici de utilizare şi rapoarte de blocare."</string>
+ <string name="prefs_enable_recorrection" msgid="4588408906649533582">"Atingeţi pentru a corecta cuvintele"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="1056068922330206170">"Atingeţi cuvintele introduse pentru a le corecta"</string>
+ <string name="keyboard_layout" msgid="437433231038683666">"Temă pentru tastatură"</string>
+ <string name="subtype_mode_keyboard" msgid="2242090416595003881">"tastatură"</string>
+ <string name="subtype_mode_voice" msgid="4394113125441627771">"voce"</string>
+</resources>
diff --git a/java/res/values-ru-rPH/donottranslate-keymap.xml b/java/res/values-ru-rPH/donottranslate-keymap.xml
new file mode 100644
index 0000000..942f47a
--- /dev/null
+++ b/java/res/values-ru-rPH/donottranslate-keymap.xml
@@ -0,0 +1,221 @@
+<?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.
+**
+**
+** 5-row layout for Russian, contributed by Igor Tonky.
+**
+** See http://code.google.com/p/hackerskeyboard/wiki/AddingNewLayouts for
+** more information.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="key_tlde_main">ё</string>
+ <string name="key_tlde_shift">Ё</string>
+ <string name="key_tlde_alt">`~</string>
+
+ <string name="key_ae01_main">1</string>
+ <string name="key_ae01_shift">!</string>
+ <string name="key_ae01_alt">1!¡¹½⅓¼⅛</string>
+
+ <string name="key_ae02_main">2</string>
+ <string name="key_ae02_shift">\"</string>
+ <string name="key_ae02_alt">2\"\'²⅔</string>
+
+ <string name="key_ae03_main">3</string>
+ <string name="key_ae03_shift">№</string>
+ <string name="key_ae03_alt">3№#³¾⅜</string>
+
+ <string name="key_ae04_main">4</string>
+ <string name="key_ae04_shift">;</string>
+ <string name="key_ae04_alt">4;⁴$¢£€¥</string>
+
+ <string name="key_ae05_main">5</string>
+ <string name="key_ae05_shift">%</string>
+ <string name="key_ae05_alt">5%⅝‰</string>
+
+ <string name="key_ae06_main">6</string>
+ <string name="key_ae06_shift">:</string>
+ <string name="key_ae06_alt">6:^↑↓←→</string>
+
+ <string name="key_ae07_main">7</string>
+ <string name="key_ae07_shift">\?</string>
+ <string name="key_ae07_alt">7\?&amp;⅞♪</string>
+
+ <string name="key_ae08_main">8</string>
+ <string name="key_ae08_shift">*</string>
+ <string name="key_ae08_alt">8*•★∞†‡</string>
+
+ <string name="key_ae09_main">9</string>
+ <string name="key_ae09_shift">(</string>
+ <string name="key_ae09_alt">9([{√</string>
+
+ <string name="key_ae10_main">0</string>
+ <string name="key_ae10_shift">)</string>
+ <string name="key_ae10_alt">0)]}ⁿ°</string>
+
+ <string name="key_ae11_main">-</string>
+ <string name="key_ae11_shift">_</string>
+ <string name="key_ae11_alt">-_—–</string>
+
+ <string name="key_ae12_main">=</string>
+ <string name="key_ae12_shift">+</string>
+ <string name="key_ae12_alt">=+≈≠±×÷</string>
+
+
+ <string name="key_ad01_main">я</string>
+ <string name="key_ad01_shift">Я</string>
+ <string name="key_ad01_alt">1q</string>
+
+ <string name="key_ad02_main">в</string>
+ <string name="key_ad02_shift">В</string>
+ <string name="key_ad02_alt">2w</string>
+
+ <string name="key_ad03_main">е</string>
+ <string name="key_ad03_shift">Е</string>
+ <string name="key_ad03_alt">3e</string>
+
+ <string name="key_ad04_main">р</string>
+ <string name="key_ad04_shift">Р</string>
+ <string name="key_ad04_alt">4r</string>
+
+ <string name="key_ad05_main">т</string>
+ <string name="key_ad05_shift">Т</string>
+ <string name="key_ad05_alt">5t</string>
+
+ <string name="key_ad06_main">ы</string>
+ <string name="key_ad06_shift">Ы</string>
+ <string name="key_ad06_alt">6y</string>
+
+ <string name="key_ad07_main">у</string>
+ <string name="key_ad07_shift">У</string>
+ <string name="key_ad07_alt">7u</string>
+
+ <string name="key_ad08_main">и</string>
+ <string name="key_ad08_shift">И</string>
+ <string name="key_ad08_alt">8i</string>
+
+ <string name="key_ad09_main">о</string>
+ <string name="key_ad09_shift">О</string>
+ <string name="key_ad09_alt">9o</string>
+
+ <string name="key_ad10_main">п</string>
+ <string name="key_ad10_shift">П</string>
+ <string name="key_ad10_alt">0p</string>
+
+ <string name="key_ad11_main">ш</string>
+ <string name="key_ad11_shift">Ш</string>
+ <string name="key_ad11_alt">[{</string>
+
+ <string name="key_ad12_main">щ</string>
+ <string name="key_ad12_shift">Щ</string>
+ <string name="key_ad12_alt">*~]}</string>
+
+ <string name="key_bksl_main">\\</string>
+ <string name="key_bksl_shift">/</string>
+ <string name="key_bksl_alt">\\/</string>
+
+
+ <string name="key_ac01_main">а</string>
+ <string name="key_ac01_shift">А</string>
+ <string name="key_ac01_alt">a</string>
+
+ <string name="key_ac02_main">с</string>
+ <string name="key_ac02_shift">С</string>
+ <string name="key_ac02_alt">s</string>
+
+ <string name="key_ac03_main">д</string>
+ <string name="key_ac03_shift">Д</string>
+ <string name="key_ac03_alt">d</string>
+
+ <string name="key_ac04_main">ф</string>
+ <string name="key_ac04_shift">Ф</string>
+ <string name="key_ac04_alt">f</string>
+
+ <string name="key_ac05_main">г</string>
+ <string name="key_ac05_shift">Г</string>
+ <string name="key_ac05_alt">g</string>
+
+ <string name="key_ac06_main">х</string>
+ <string name="key_ac06_shift">Х</string>
+ <string name="key_ac06_alt">h</string>
+
+ <string name="key_ac07_main">й</string>
+ <string name="key_ac07_shift">Й</string>
+ <string name="key_ac07_alt">j</string>
+
+ <string name="key_ac08_main">к</string>
+ <string name="key_ac08_shift">К</string>
+ <string name="key_ac08_alt">k</string>
+
+ <string name="key_ac09_main">л</string>
+ <string name="key_ac09_shift">Л</string>
+ <string name="key_ac09_alt">l</string>
+
+ <string name="key_ac10_main">ч</string>
+ <string name="key_ac10_shift">Ч</string>
+ <string name="key_ac10_alt">;:</string>
+
+ <string name="key_ac11_main">э</string>
+ <string name="key_ac11_shift">Э</string>
+ <string name="key_ac11_alt">\'&quot;</string>
+
+
+ <string name="key_lsgt_main">&lt;</string>
+ <string name="key_lsgt_shift">&gt;</string>
+ <string name="key_lsgt_alt">&lt;&gt;|\@</string>
+
+ <string name="key_ab01_main">з</string>
+ <string name="key_ab01_shift">З</string>
+ <string name="key_ab01_alt">z</string>
+
+ <string name="key_ab02_main">ь</string>
+ <string name="key_ab02_shift">Ь</string>
+ <string name="key_ab02_alt">x</string>
+
+ <string name="key_ab03_main">ц</string>
+ <string name="key_ab03_shift">Ц</string>
+ <string name="key_ab03_alt">c</string>
+
+ <string name="key_ab04_main">ж</string>
+ <string name="key_ab04_shift">Ж</string>
+ <string name="key_ab04_alt">v</string>
+
+ <string name="key_ab05_main">б</string>
+ <string name="key_ab05_shift">Б</string>
+ <string name="key_ab05_alt">b</string>
+
+ <string name="key_ab06_main">н</string>
+ <string name="key_ab06_shift">Н</string>
+ <string name="key_ab06_alt">n</string>
+
+ <string name="key_ab07_main">м</string>
+ <string name="key_ab07_shift">М</string>
+ <string name="key_ab07_alt">m</string>
+
+ <string name="key_ab08_main">ъ</string>
+ <string name="key_ab08_shift">Ъ</string>
+ <string name="key_ab08_alt">,&lt;</string>
+
+ <string name="key_ab09_main">ю</string>
+ <string name="key_ab09_shift">Ю</string>
+ <string name="key_ab09_alt">.&gt;</string>
+
+ <string name="key_ab10_main">.</string>
+ <string name="key_ab10_shift">,</string>
+ <string name="key_ab10_alt">.,/\?</string>
+</resources>
diff --git a/java/res/values-ru/donottranslate-altchars.xml b/java/res/values-ru/donottranslate-altchars.xml
new file mode 100644
index 0000000..c8c6801
--- /dev/null
+++ b/java/res/values-ru/donottranslate-altchars.xml
@@ -0,0 +1,23 @@
+<?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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="alternates_for_cyrillic_e">5ё</string>
+ <string name="alternates_for_cyrillic_soft_sign">ъ</string>
+</resources>
diff --git a/java/res/values-ru/donottranslate-keymap.xml b/java/res/values-ru/donottranslate-keymap.xml
new file mode 100644
index 0000000..bebbc92
--- /dev/null
+++ b/java/res/values-ru/donottranslate-keymap.xml
@@ -0,0 +1,221 @@
+<?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.
+**
+**
+** 5-row layout for Russian, contributed by Igor Tonky.
+**
+** See http://code.google.com/p/hackerskeyboard/wiki/AddingNewLayouts for
+** more information.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="key_tlde_main">ё</string>
+ <string name="key_tlde_shift">Ё</string>
+ <string name="key_tlde_alt">`~</string>
+
+ <string name="key_ae01_main">1</string>
+ <string name="key_ae01_shift">!</string>
+ <string name="key_ae01_alt">1!¡¹½⅓¼⅛</string>
+
+ <string name="key_ae02_main">2</string>
+ <string name="key_ae02_shift">\"</string>
+ <string name="key_ae02_alt">2\"\'²⅔</string>
+
+ <string name="key_ae03_main">3</string>
+ <string name="key_ae03_shift">№</string>
+ <string name="key_ae03_alt">3№#³¾⅜</string>
+
+ <string name="key_ae04_main">4</string>
+ <string name="key_ae04_shift">;</string>
+ <string name="key_ae04_alt">4;⁴$¢£€¥</string>
+
+ <string name="key_ae05_main">5</string>
+ <string name="key_ae05_shift">%</string>
+ <string name="key_ae05_alt">5%⅝‰</string>
+
+ <string name="key_ae06_main">6</string>
+ <string name="key_ae06_shift">:</string>
+ <string name="key_ae06_alt">6:^↑↓←→</string>
+
+ <string name="key_ae07_main">7</string>
+ <string name="key_ae07_shift">\?</string>
+ <string name="key_ae07_alt">7\?&amp;⅞♪</string>
+
+ <string name="key_ae08_main">8</string>
+ <string name="key_ae08_shift">*</string>
+ <string name="key_ae08_alt">8*•★∞†‡</string>
+
+ <string name="key_ae09_main">9</string>
+ <string name="key_ae09_shift">(</string>
+ <string name="key_ae09_alt">9([{√</string>
+
+ <string name="key_ae10_main">0</string>
+ <string name="key_ae10_shift">)</string>
+ <string name="key_ae10_alt">0)]}ⁿ°</string>
+
+ <string name="key_ae11_main">-</string>
+ <string name="key_ae11_shift">_</string>
+ <string name="key_ae11_alt">-_—–</string>
+
+ <string name="key_ae12_main">=</string>
+ <string name="key_ae12_shift">+</string>
+ <string name="key_ae12_alt">=+≈≠±×÷</string>
+
+
+ <string name="key_ad01_main">й</string>
+ <string name="key_ad01_shift">Й</string>
+ <string name="key_ad01_alt">1q</string>
+
+ <string name="key_ad02_main">ц</string>
+ <string name="key_ad02_shift">Ц</string>
+ <string name="key_ad02_alt">2w</string>
+
+ <string name="key_ad03_main">у</string>
+ <string name="key_ad03_shift">У</string>
+ <string name="key_ad03_alt">3e</string>
+
+ <string name="key_ad04_main">к</string>
+ <string name="key_ad04_shift">К</string>
+ <string name="key_ad04_alt">4r</string>
+
+ <string name="key_ad05_main">е</string>
+ <string name="key_ad05_shift">Е</string>
+ <string name="key_ad05_alt">5t</string>
+
+ <string name="key_ad06_main">н</string>
+ <string name="key_ad06_shift">Н</string>
+ <string name="key_ad06_alt">6y</string>
+
+ <string name="key_ad07_main">г</string>
+ <string name="key_ad07_shift">Г</string>
+ <string name="key_ad07_alt">7u</string>
+
+ <string name="key_ad08_main">ш</string>
+ <string name="key_ad08_shift">Ш</string>
+ <string name="key_ad08_alt">8i</string>
+
+ <string name="key_ad09_main">щ</string>
+ <string name="key_ad09_shift">Щ</string>
+ <string name="key_ad09_alt">9o</string>
+
+ <string name="key_ad10_main">з</string>
+ <string name="key_ad10_shift">З</string>
+ <string name="key_ad10_alt">0p</string>
+
+ <string name="key_ad11_main">х</string>
+ <string name="key_ad11_shift">Х</string>
+ <string name="key_ad11_alt">[{</string>
+
+ <string name="key_ad12_main">ъ</string>
+ <string name="key_ad12_shift">Ъ</string>
+ <string name="key_ad12_alt">*~]}</string>
+
+ <string name="key_bksl_main">\\</string>
+ <string name="key_bksl_shift">/</string>
+ <string name="key_bksl_alt">\\/</string>
+
+
+ <string name="key_ac01_main">ф</string>
+ <string name="key_ac01_shift">Ф</string>
+ <string name="key_ac01_alt">a</string>
+
+ <string name="key_ac02_main">ы</string>
+ <string name="key_ac02_shift">Ы</string>
+ <string name="key_ac02_alt">s</string>
+
+ <string name="key_ac03_main">в</string>
+ <string name="key_ac03_shift">В</string>
+ <string name="key_ac03_alt">d</string>
+
+ <string name="key_ac04_main">а</string>
+ <string name="key_ac04_shift">А</string>
+ <string name="key_ac04_alt">f</string>
+
+ <string name="key_ac05_main">п</string>
+ <string name="key_ac05_shift">П</string>
+ <string name="key_ac05_alt">g</string>
+
+ <string name="key_ac06_main">р</string>
+ <string name="key_ac06_shift">Р</string>
+ <string name="key_ac06_alt">h</string>
+
+ <string name="key_ac07_main">о</string>
+ <string name="key_ac07_shift">О</string>
+ <string name="key_ac07_alt">j</string>
+
+ <string name="key_ac08_main">л</string>
+ <string name="key_ac08_shift">Л</string>
+ <string name="key_ac08_alt">k</string>
+
+ <string name="key_ac09_main">д</string>
+ <string name="key_ac09_shift">Д</string>
+ <string name="key_ac09_alt">l</string>
+
+ <string name="key_ac10_main">ж</string>
+ <string name="key_ac10_shift">Ж</string>
+ <string name="key_ac10_alt">;:</string>
+
+ <string name="key_ac11_main">э</string>
+ <string name="key_ac11_shift">Э</string>
+ <string name="key_ac11_alt">\'&quot;</string>
+
+
+ <string name="key_lsgt_main">&lt;</string>
+ <string name="key_lsgt_shift">&gt;</string>
+ <string name="key_lsgt_alt">&lt;&gt;|\@</string>
+
+ <string name="key_ab01_main">я</string>
+ <string name="key_ab01_shift">Я</string>
+ <string name="key_ab01_alt">z</string>
+
+ <string name="key_ab02_main">ч</string>
+ <string name="key_ab02_shift">Ч</string>
+ <string name="key_ab02_alt">x</string>
+
+ <string name="key_ab03_main">с</string>
+ <string name="key_ab03_shift">С</string>
+ <string name="key_ab03_alt">c</string>
+
+ <string name="key_ab04_main">м</string>
+ <string name="key_ab04_shift">М</string>
+ <string name="key_ab04_alt">v</string>
+
+ <string name="key_ab05_main">и</string>
+ <string name="key_ab05_shift">И</string>
+ <string name="key_ab05_alt">b</string>
+
+ <string name="key_ab06_main">т</string>
+ <string name="key_ab06_shift">Т</string>
+ <string name="key_ab06_alt">n</string>
+
+ <string name="key_ab07_main">ь</string>
+ <string name="key_ab07_shift">Ь</string>
+ <string name="key_ab07_alt">m</string>
+
+ <string name="key_ab08_main">б</string>
+ <string name="key_ab08_shift">Б</string>
+ <string name="key_ab08_alt">,&lt;</string>
+
+ <string name="key_ab09_main">ю</string>
+ <string name="key_ab09_shift">Ю</string>
+ <string name="key_ab09_alt">.&gt;</string>
+
+ <string name="key_ab10_main">.</string>
+ <string name="key_ab10_shift">,</string>
+ <string name="key_ab10_alt">.,/\?</string>
+</resources>
diff --git a/java/res/values-ru/strings.xml b/java/res/values-ru/strings.xml
new file mode 100644
index 0000000..e144eb3
--- /dev/null
+++ b/java/res/values-ru/strings.xml
@@ -0,0 +1,140 @@
+<?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/org.pocketworkstation.pckeyboard"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- <string name="english_ime_name" msgid="7252517407088836577">"Клавиатура Android"</string> -->
+ <!-- <string name="english_ime_settings" msgid="6661589557206947774">"Настройки клавиатуры Android"</string> -->
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Параметры ввода"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"Виброотклик клавиш"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"Звук клавиш"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"Увеличение нажатых"</string>
+ <string name="hit_correction" msgid="4855351009261318389">"Исправлять опечатки"</string>
+ <string name="hit_correction_summary" msgid="8761701873008070796">"Включить исправление ошибок при вводе"</string>
+ <string name="hit_correction_land" msgid="2567691684825205448">"Ошибки при вводе в горизонтальной ориентации"</string>
+ <string name="hit_correction_land_summary" msgid="4076803842198368328">"Включить исправление ошибок при вводе"</string>
+ <string name="auto_correction" msgid="7911639788808958255">"Предложение слов"</string>
+ <string name="auto_correction_summary" msgid="6881047311475758267">"Автоматически исправлять предыдущее слово"</string>
+ <string name="prediction" msgid="466220283138359837">"Предложение слов"</string>
+ <string name="prediction_category" msgid="7027100625580696660">"Настройки подсказок"</string>
+ <string name="prediction_summary" msgid="459788228830873110">"Включить автоматическое завершение слов при вводе"</string>
+ <string name="auto_complete_dialog_title" msgid="2172048590607201920">"Автоматическое завершение"</string>
+ <string name="prediction_landscape" msgid="4874601565593216183">"Увеличить размер текстового поля"</string>
+ <string name="prediction_landscape_summary" msgid="6736551095997839472">"Скрывать предложение слов в горизонтальной ориентации"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"Автоподст. заглавных"</string>
+ <string name="auto_cap_summary" msgid="3260681697600786825">"Делать заглавной первую букву предложения"</string>
+ <string name="auto_punctuate" msgid="7276672334264521751">"Автопунктуация"</string>
+ <string name="auto_punctuate_summary" msgid="6589441565817502132"></string>
+ <string name="quick_fixes" msgid="5353213327680897927">"Быстрое исправление"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"Исправлять распространенные опечатки"</string>
+ <string name="show_suggestions" msgid="507074425254289133">"Предлагать варианты"</string>
+ <string name="show_suggestions_summary" msgid="1989672863935759654">"Предлагать варианты слов во время ввода"</string>
+ <string name="auto_complete" msgid="1103196318775486023">"Автозавершение"</string>
+ <string name="auto_complete_summary" msgid="6113149638718274624">"При нажатии пробела вставлять предложенное слово"</string>
+ <string name="prefs_settings_key" msgid="4623341240804046498">"Кнопка настроек"</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Автоматически"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Всегда показывать"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"Всегда скрывать"</string>
+ <!-- no translation found for settings_key_modes:0 (8549888726962891527) -->
+ <!-- no translation found for settings_key_modes:1 (881280041213210923) -->
+ <!-- no translation found for settings_key_modes:2 (7317310620171067848) -->
+ <string name="bigram_suggestion" msgid="1323347224043514969">"Биграммные подсказки"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Используйте предыдущее слово, чтобы исправить подсказку"</string>
+ <string-array name="prediction_modes">
+ <item msgid="4870266572388153286">"Нет"</item>
+ <item msgid="1669461741568287396">"Основной"</item>
+ <item msgid="4894328801530136615">"Дополнительно"</item>
+ </string-array>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: сохранено"</string>
+ <string name="tip_long_press" msgid="6101270866284343344">"Удерживайте клавишу, чтобы увидеть варианты с диакритическими знаками (ø, ö и т.д.)"</string>
+ <string name="tip_dismiss" msgid="7585579046862204381">"Нажмите клавишу \"Назад\" ↶, чтобы закрыть клавиатуру в любой момент"</string>
+ <string name="tip_access_symbols" msgid="6344098517525531652">"Открыть цифры и символы"</string>
+ <string name="tip_add_to_dictionary" msgid="1487293888469227817">"Нажмите и удерживайте слово слева, чтобы добавить его в словарь"</string>
+ <string name="touch_to_continue" msgid="7869803257948414531">"Чтобы продолжить, нажмите на эту подсказку »"</string>
+ <string name="touch_to_finish" msgid="7990196086480585789">"Нажмите здесь, чтобы закрыть подсказку и начать вводить текст."</string>
+ <string name="tip_to_open_keyboard" msgid="6821200275486950452"><b>"Клавиатура появляется автоматически при касании текстового поля"</b></string>
+ <string name="tip_to_view_accents" msgid="5433158573693308501"><b>"Нажмите и удерживайте клавишу для отображения вариантов с диакритическими знаками "\n"(ø, ö, ô, ó и т. п.)"</b></string>
+ <string name="tip_to_open_symbols" msgid="7345139325622444880"><b>"Для переключения между вводом цифр и символов используйте эту клавишу"</b></string>
+ <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"Чтобы вернуться к буквенной клавиатуре, снова нажмите на эту клавишу"</b></string>
+ <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"Чтобы изменить настройки клавиатуры (такие как автозавершение), нажмите и удерживайте эту клавишу"</b></string>
+ <string name="tip_to_start_typing" msgid="7213843601369174313"><b>"Попробуйте!"</b></string>
+ <string name="label_go_key" msgid="1635148082137219148">"Поиск"</string>
+ <string name="label_next_key" msgid="362972844525672568">"Далее"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"Готово"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"Отправить"</string>
+ <string name="label_symbol_key" msgid="6175820506864489453">"?123"</string>
+ <string name="label_phone_key" msgid="4275497665515080551">"123"</string>
+ <string name="label_alpha_key" msgid="8864943487292437456">"АБВ"</string>
+ <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string>
+ <string name="voice_warning_title" msgid="4419354150908395008">"Голосовой ввод"</string>
+ <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"В настоящее время функция голосового ввода не поддерживает ваш язык, но вы можете пользоваться ей на английском."</string>
+ <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"Голосовой ввод – экспериментальная функция на основе технологии сетевого распознавания речи от Google."</string>
+ <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"Функция голосового ввода отключается в настройках клавиатуры."</string>
+ <string name="voice_hint_dialog_message" msgid="6892342981545727994">"Чтобы использовать голосовой ввод, нажмите кнопку микрофона или проведите пальцем по экранной клавиатуре."</string>
+ <string name="voice_listening" msgid="467518160751321844">"Говорите"</string>
+ <string name="voice_working" msgid="6666937792815731889">"Обработка запроса"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"Ошибка. Повторите попытку."</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"Ошибка подключения"</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"Слишком длинная фраза"</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"Неполадка со звуком"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"Ошибка сервера"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"Речи не слышно"</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"Соответствий не найдено"</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"Голосовой поиск не установлен"</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Совет"</b>". Проведите пальцем по клавиатуре для голосового ввода."</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Совет"</b>". В следующий раз проговаривайте знаки препинания, например \"точка\", \"запятая\", \"вопросительный знак\"."</string>
+ <string name="cancel" msgid="6830980399865683324">"Отмена"</string>
+ <string name="ok" msgid="7898366843681727667">"ОК"</string>
+ <string name="voice_input" msgid="2466640768843347841">"Голосовой ввод"</string>
+ <string-array name="voice_input_modes">
+ <item msgid="1349082139076086774">"На основной клавиатуре"</item>
+ <item msgid="8529385602829095903">"На клавиатуре символов"</item>
+ <item msgid="7283103513488381103">"Выкл."</item>
+ </string-array>
+ <string-array name="voice_input_modes_summary">
+ <item msgid="554248625705084903">"Микрофон на основной клавиатуре"</item>
+ <item msgid="6907837061058876770">"Микрофон на клавиатуре символов"</item>
+ <item msgid="3664304608587798036">"Голосовой ввод отключен"</item>
+ </string-array>
+ <string name="auto_submit" msgid="9151008027068358518">"Автоматически отправлять по окончании голосового ввода"</string>
+ <string name="auto_submit_summary" msgid="4961875269610384226">"Автоматически нажимать \"Ввод\" при поиске или переходе к следующему полю."</string>
+ <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Открытие клавиатуры"\n</b></font><font size="3">\n</font>"Нажмите на любое текстовое поле."</string>
+ <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Закрытие клавиатуры"\n</b></font><font size="3">\n</font>"Нажмите клавишу \"Назад\"."</string>
+ <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Нажмите и удерживайте клавишу для вызова параметров"\n</b></font><font size="3">\n</font>"Доступ к пунктуационным и диакритическим знакам."</string>
+ <string name="keyboard_settings" msgid="4585753477617374032"><font size="17"><b>"Настройки клавиатуры"\n</b></font><font size="3">\n</font>"Нажмите и удерживайте клавишу "<b>"?123"</b>"."</string>
+ <string name="popular_domain_0" msgid="3745279225122472969">".com"</string>
+ <string name="popular_domain_1" msgid="1370572248164278467">".net"</string>
+ <string name="popular_domain_2" msgid="3036812463748402878">".org"</string>
+ <string name="popular_domain_3" msgid="8718639560809452028">".gov"</string>
+ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"Выбрать способ ввода"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Языки ввода"</string>
+ <string name="language_selection_summary" msgid="187110938289512256">"Для изменения языка проведите пальцем по пробелу"</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Нажмите еще раз, чтобы сохранить"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"Доступен словарь"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"Включить отправку сведений"</string>
+ <string name="prefs_description_log" msgid="5827825607258246003">"Помогите усовершенствовать редактор способа ввода, разрешив отправку статистики и отчетов о сбоях в Google."</string>
+ <string name="prefs_enable_recorrection" msgid="4588408906649533582">"Исправление нажатием"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="1056068922330206170">"Введенные слова исправляются нажатием"</string>
+ <string name="keyboard_layout" msgid="437433231038683666">"Вид клавиатуры"</string>
+ <string name="subtype_mode_keyboard" msgid="2242090416595003881">"клавиатура"</string>
+ <string name="subtype_mode_voice" msgid="4394113125441627771">"голосовой"</string>
+</resources>
diff --git a/java/res/values-si/donottranslate-keymap.xml b/java/res/values-si/donottranslate-keymap.xml
new file mode 100644
index 0000000..74e58f5
--- /dev/null
+++ b/java/res/values-si/donottranslate-keymap.xml
@@ -0,0 +1,222 @@
+<?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.
+**
+**
+** 5-row layout for Sinhala(Wijesekara), contributed by Prabath Ranasinghe.
+** Wijesekara layout can be found at http://www.ucsc.cmb.ac.lk/ltrl/services/layout/
+**
+** See http://code.google.com/p/hackerskeyboard/wiki/AddingNewLayouts for
+** more information.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="key_tlde_main">්‍ර</string>
+ <string name="key_tlde_shift">ර්‍‍</string>
+ <string name="key_tlde_alt">`~</string>
+
+ <string name="key_ae01_main">1</string>
+ <string name="key_ae01_shift">!</string>
+ <string name="key_ae01_alt">1!¡¹½⅓¼⅛</string>
+
+ <string name="key_ae02_main">2</string>
+ <string name="key_ae02_shift">\@</string>
+ <string name="key_ae02_alt">2\@²⅔</string>
+
+ <string name="key_ae03_main">3</string>
+ <string name="key_ae03_shift">#</string>
+ <string name="key_ae03_alt">3#³¾⅜♥♠♦♣</string>
+
+ <string name="key_ae04_main">4</string>
+ <string name="key_ae04_shift">$</string>
+ <string name="key_ae04_alt">4$⁴¢£€¥</string>
+
+ <string name="key_ae05_main">5</string>
+ <string name="key_ae05_shift">%</string>
+ <string name="key_ae05_alt">5%⅝‰</string>
+
+ <string name="key_ae06_main">6</string>
+ <string name="key_ae06_shift">^</string>
+ <string name="key_ae06_alt">6^↑↓←→</string>
+
+ <string name="key_ae07_main">7</string>
+ <string name="key_ae07_shift">&amp;</string>
+ <string name="key_ae07_alt">7&amp;⅞♪</string>
+
+ <string name="key_ae08_main">8</string>
+ <string name="key_ae08_shift">*</string>
+ <string name="key_ae08_alt">8*•★∞†‡</string>
+
+ <string name="key_ae09_main">9</string>
+ <string name="key_ae09_shift">(</string>
+ <string name="key_ae09_alt">9(√</string>
+
+ <string name="key_ae10_main">0</string>
+ <string name="key_ae10_shift">)</string>
+ <string name="key_ae10_alt">0)ⁿ°</string>
+
+ <string name="key_ae11_main">-</string>
+ <string name="key_ae11_shift">_</string>
+ <string name="key_ae11_alt">-_—–</string>
+
+ <string name="key_ae12_main">=</string>
+ <string name="key_ae12_shift">+</string>
+ <string name="key_ae12_alt">=+≈≠±×÷</string>
+
+
+ <string name="key_ad01_main">ු</string>
+ <string name="key_ad01_shift">ූ</string>
+ <string name="key_ad01_alt">@string/alternates_for_q</string>
+
+ <string name="key_ad02_main">අ</string>
+ <string name="key_ad02_shift">උ</string>
+ <string name="key_ad02_alt">@string/alternates_for_w</string>
+
+ <string name="key_ad03_main">ැ</string>
+ <string name="key_ad03_shift">ෑ</string>
+ <string name="key_ad03_alt">@string/alternates_for_e</string>
+
+ <string name="key_ad04_main">ර</string>
+ <string name="key_ad04_shift">ඍ</string>
+ <string name="key_ad04_alt">@string/alternates_for_r</string>
+
+ <string name="key_ad05_main">එ</string>
+ <string name="key_ad05_shift">ඔ</string>
+ <string name="key_ad05_alt">@string/alternates_for_t</string>
+
+ <string name="key_ad06_main">හ</string>
+ <string name="key_ad06_shift">ශ</string>
+ <string name="key_ad06_alt">@string/alternates_for_y</string>
+
+ <string name="key_ad07_main">ම</string>
+ <string name="key_ad07_shift">ඹ</string>
+ <string name="key_ad07_alt">@string/alternates_for_u</string>
+
+ <string name="key_ad08_main">ස</string>
+ <string name="key_ad08_shift">ෂ</string>
+ <string name="key_ad08_alt">@string/alternates_for_i</string>
+
+ <string name="key_ad09_main">ද</string>
+ <string name="key_ad09_shift">ධ</string>
+ <string name="key_ad09_alt">ඳ</string>
+
+ <string name="key_ad10_main">ච</string>
+ <string name="key_ad10_shift">ඡ</string>
+ <string name="key_ad10_alt">@string/alternates_for_p</string>
+
+ <string name="key_ad11_main">ඤ</string>
+ <string name="key_ad11_shift">ඥ</string>
+ <string name="key_ad11_alt">[{</string>
+
+ <string name="key_ad12_main">;</string>
+ <string name="key_ad12_shift">:</string>
+ <string name="key_ad12_alt">]}</string>
+
+ <string name="key_bksl_main">\\</string>
+ <string name="key_bksl_shift">|</string>
+ <string name="key_bksl_alt">\\|</string>
+
+
+ <string name="key_ac01_main">්</string>
+ <string name="key_ac01_shift">ෟ</string>
+ <string name="key_ac01_alt">@string/alternates_for_a</string>
+
+ <string name="key_ac02_main">ි</string>
+ <string name="key_ac02_shift">ී</string>
+ <string name="key_ac02_alt">@string/alternates_for_s</string>
+
+ <string name="key_ac03_main">ා</string>
+ <string name="key_ac03_shift">ෘ</string>
+ <string name="key_ac03_alt">@string/alternates_for_d</string>
+
+ <string name="key_ac04_main">‍ෙ</string>
+ <string name="key_ac04_shift">ෆ</string>
+ <string name="key_ac04_alt">@string/alternates_for_f</string>
+
+ <string name="key_ac05_main">ට</string>
+ <string name="key_ac05_shift">ඨ</string>
+ <string name="key_ac05_alt">@string/alternates_for_g</string>
+
+ <string name="key_ac06_main">ය</string>
+ <string name="key_ac06_shift">්‍ය</string>
+ <string name="key_ac06_alt">@string/alternates_for_h</string>
+
+ <string name="key_ac07_main">ව</string>
+ <string name="key_ac07_shift">ළු</string>
+ <string name="key_ac07_alt">@string/alternates_for_j</string>
+
+ <string name="key_ac08_main">න</string>
+ <string name="key_ac08_shift">ණ</string>
+ <string name="key_ac08_alt">@string/alternates_for_k</string>
+
+ <string name="key_ac09_main">ක</string>
+ <string name="key_ac09_shift">ඛ</string>
+ <string name="key_ac09_alt">@string/alternates_for_l</string>
+
+ <string name="key_ac10_main">ත</string>
+ <string name="key_ac10_shift">ථ</string>
+ <string name="key_ac10_alt">;:</string>
+
+ <string name="key_ac11_main">,</string>
+ <string name="key_ac11_shift">.</string>
+ <string name="key_ac11_alt">\'\"෴</string>
+
+
+ <string name="key_lsgt_main"></string>
+ <string name="key_lsgt_shift"></string>
+ <string name="key_lsgt_alt"></string>
+
+ <string name="key_ab01_main">\'</string>
+ <string name="key_ab01_shift">\"</string>
+ <string name="key_ab01_alt">@string/alternates_for_z</string>
+
+ <string name="key_ab02_main">ං</string>
+ <string name="key_ab02_shift">ඃ</string>
+ <string name="key_ab02_alt">ඦ</string>
+
+ <string name="key_ab03_main">ජ</string>
+ <string name="key_ab03_shift">ඣ</string>
+ <string name="key_ab03_alt">@string/alternates_for_c</string>
+
+ <string name="key_ab04_main">ඩ</string>
+ <string name="key_ab04_shift">ඪ</string>
+ <string name="key_ab04_alt">ඬ</string>
+
+ <string name="key_ab05_main">ඉ</string>
+ <string name="key_ab05_shift">ඊ</string>
+ <string name="key_ab05_alt">@string/alternates_for_b</string>
+
+ <string name="key_ab06_main">බ</string>
+ <string name="key_ab06_shift">භ</string>
+ <string name="key_ab06_alt">@string/alternates_for_n</string>
+
+ <string name="key_ab07_main">ප</string>
+ <string name="key_ab07_shift">ඵ</string>
+ <string name="key_ab07_alt">@string/alternates_for_m</string>
+
+ <string name="key_ab08_main">ල</string>
+ <string name="key_ab08_shift">ළ</string>
+ <string name="key_ab08_alt">ඏ</string>
+
+ <string name="key_ab09_main">ග</string>
+ <string name="key_ab09_shift">ඝ</string>
+ <string name="key_ab09_alt">ඟ</string>
+
+ <string name="key_ab10_main">/</string>
+ <string name="key_ab10_shift">\?</string>
+ <string name="key_ab10_alt">/\?¿</string>
+</resources>
diff --git a/java/res/values-sk-rQY/donottranslate-altchars.xml b/java/res/values-sk-rQY/donottranslate-altchars.xml
new file mode 100644
index 0000000..a7389f6
--- /dev/null
+++ b/java/res/values-sk-rQY/donottranslate-altchars.xml
@@ -0,0 +1,43 @@
+<?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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="alternates_for_a">áäàâãåæ</string>
+ <string name="alternates_for_b">{</string>
+ <string name="alternates_for_c">&amp;čç</string>
+ <string name="alternates_for_d">ďĐ</string>
+ <string name="alternates_for_e">3é€ěèêë</string>
+ <string name="alternates_for_f">[</string>
+ <string name="alternates_for_g">]</string>
+ <string name="alternates_for_i">8íïîìí</string>
+ <string name="alternates_for_k">ł</string>
+ <string name="alternates_for_l">ľĺŁ</string>
+ <string name="alternates_for_n">}ňñ</string>
+ <string name="alternates_for_o">9óôøœöõò</string>
+ <string name="alternates_for_q">1\\</string>
+ <string name="alternates_for_r">4ř</string>
+ <string name="alternates_for_s">š§ßđ</string>
+ <string name="alternates_for_t">5ť</string>
+ <string name="alternates_for_u">7úüůûù</string>
+ <string name="alternates_for_v">\@</string>
+ <string name="alternates_for_w">2|</string>
+ <string name="alternates_for_x">#</string>
+ <string name="alternates_for_y">6ýÿ</string>
+ <string name="alternates_for_z">ž</string>
+</resources>
diff --git a/java/res/values-sk-rQY/donottranslate-keymap.xml b/java/res/values-sk-rQY/donottranslate-keymap.xml
new file mode 100644
index 0000000..30dc25d
--- /dev/null
+++ b/java/res/values-sk-rQY/donottranslate-keymap.xml
@@ -0,0 +1,222 @@
+<?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.
+**
+**
+** 5-row layout for Slovak QWERTY.
+**
+** See http://code.google.com/p/hackerskeyboard/wiki/AddingNewLayouts for
+** more information.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="key_tlde_main">;</string>
+ <string name="key_tlde_shift">°</string>
+ <string name="key_tlde_alt">;°`~</string>
+
+ <string name="key_ae01_main">+</string>
+ <string name="key_ae01_shift">1</string>
+ <string name="key_ae01_alt">+1~!¹¡½⅓¼⅛</string>
+
+ <string name="key_ae02_main">ľ</string>
+ <string name="key_ae02_shift">2</string>
+ <string name="key_ae02_alt">ľ2\@²⅛⅔</string>
+
+ <string name="key_ae03_main">š</string>
+ <string name="key_ae03_shift">3</string>
+ <string name="key_ae03_alt">š3#³£¾⅜</string>
+
+ <string name="key_ae04_main">č</string>
+ <string name="key_ae04_shift">4</string>
+ <string name="key_ae04_alt">č4$¼¤⁴¢¥</string>
+
+ <string name="key_ae05_main">ť</string>
+ <string name="key_ae05_shift">5</string>
+ <string name="key_ae05_alt">ť5%½⅜‰</string>
+
+ <string name="key_ae06_main">ž</string>
+ <string name="key_ae06_shift">6</string>
+ <string name="key_ae06_alt">ž6^¬⅝</string>
+
+ <string name="key_ae07_main">ý</string>
+ <string name="key_ae07_shift">7</string>
+ <string name="key_ae07_alt">ý7&amp;{⅞♪√</string>
+
+ <string name="key_ae08_main">á</string>
+ <string name="key_ae08_shift">8</string>
+ <string name="key_ae08_alt">á8*[™∞</string>
+
+ <string name="key_ae09_main">í</string>
+ <string name="key_ae09_shift">9</string>
+ <string name="key_ae09_alt">í9(]±</string>
+
+ <string name="key_ae10_main">é</string>
+ <string name="key_ae10_shift">0</string>
+ <string name="key_ae10_alt">é0)}°ⁿ≈≠</string>
+
+ <string name="key_ae11_main">=</string>
+ <string name="key_ae11_shift">%</string>
+ <string name="key_ae11_alt">=%-_\?\¿</string>
+
+ <string name="key_ae12_main">&#x0301;</string>
+ <string name="key_ae12_shift">&#x030c;</string>
+ <string name="key_ae12_alt">&#x0301;&#x030c;&lt;&gt;|</string>
+
+
+ <string name="key_ad01_main">q</string>
+ <string name="key_ad01_shift">Q</string>
+ <string name="key_ad01_alt">@string/alternates_for_q</string>
+
+ <string name="key_ad02_main">w</string>
+ <string name="key_ad02_shift">W</string>
+ <string name="key_ad02_alt">@string/alternates_for_w</string>
+
+ <string name="key_ad03_main">e</string>
+ <string name="key_ad03_shift">E</string>
+ <string name="key_ad03_alt">@string/alternates_for_e</string>
+
+ <string name="key_ad04_main">r</string>
+ <string name="key_ad04_shift">R</string>
+ <string name="key_ad04_alt">@string/alternates_for_r</string>
+
+ <string name="key_ad05_main">t</string>
+ <string name="key_ad05_shift">T</string>
+ <string name="key_ad05_alt">@string/alternates_for_t</string>
+
+ <string name="key_ad06_main">y</string>
+ <string name="key_ad06_shift">Y</string>
+ <string name="key_ad06_alt">@string/alternates_for_y</string>
+
+ <string name="key_ad07_main">u</string>
+ <string name="key_ad07_shift">U</string>
+ <string name="key_ad07_alt">@string/alternates_for_u</string>
+
+ <string name="key_ad08_main">i</string>
+ <string name="key_ad08_shift">I</string>
+ <string name="key_ad08_alt">@string/alternates_for_i</string>
+
+ <string name="key_ad09_main">o</string>
+ <string name="key_ad09_shift">O</string>
+ <string name="key_ad09_alt">@string/alternates_for_o</string>
+
+ <string name="key_ad10_main">p</string>
+ <string name="key_ad10_shift">P</string>
+ <string name="key_ad10_alt">@string/alternates_for_p</string>
+
+ <string name="key_ad11_main">ú</string>
+ <string name="key_ad11_shift">/</string>
+ <string name="key_ad11_alt">ú/÷[{</string>
+
+ <string name="key_ad12_main">ä</string>
+ <string name="key_ad12_shift">(</string>
+ <string name="key_ad12_alt">ä(×]}</string>
+
+ <string name="key_bksl_main">ň</string>
+ <string name="key_bksl_shift">)</string>
+ <string name="key_bksl_alt">ň)\|¤</string>
+
+
+ <string name="key_ac01_main">a</string>
+ <string name="key_ac01_shift">A</string>
+ <string name="key_ac01_alt">@string/alternates_for_a</string>
+
+ <string name="key_ac02_main">s</string>
+ <string name="key_ac02_shift">S</string>
+ <string name="key_ac02_alt">@string/alternates_for_s</string>
+
+ <string name="key_ac03_main">d</string>
+ <string name="key_ac03_shift">D</string>
+ <string name="key_ac03_alt">@string/alternates_for_d</string>
+
+ <string name="key_ac04_main">f</string>
+ <string name="key_ac04_shift">F</string>
+ <string name="key_ac04_alt">@string/alternates_for_f</string>
+
+ <string name="key_ac05_main">g</string>
+ <string name="key_ac05_shift">G</string>
+ <string name="key_ac05_alt">@string/alternates_for_g</string>
+
+ <string name="key_ac06_main">h</string>
+ <string name="key_ac06_shift">H</string>
+ <string name="key_ac06_alt">@string/alternates_for_h</string>
+
+ <string name="key_ac07_main">j</string>
+ <string name="key_ac07_shift">J</string>
+ <string name="key_ac07_alt">@string/alternates_for_j</string>
+
+ <string name="key_ac08_main">k</string>
+ <string name="key_ac08_shift">K</string>
+ <string name="key_ac08_alt">@string/alternates_for_k</string>
+
+ <string name="key_ac09_main">l</string>
+ <string name="key_ac09_shift">L</string>
+ <string name="key_ac09_alt">@string/alternates_for_l</string>
+
+ <string name="key_ac10_main">ô</string>
+ <string name="key_ac10_shift">\"</string>
+ <string name="key_ac10_alt">ô\"$;:</string>
+
+ <string name="key_ac11_main">§</string>
+ <string name="key_ac11_shift">!</string>
+ <string name="key_ac11_alt">§!ß\'\"‘’“”</string>
+
+
+ <string name="key_lsgt_main"></string>
+ <string name="key_lsgt_shift"></string>
+ <string name="key_lsgt_alt"></string>
+
+ <string name="key_ab01_main">z</string>
+ <string name="key_ab01_shift">Z</string>
+ <string name="key_ab01_alt">@string/alternates_for_z</string>
+
+ <string name="key_ab02_main">x</string>
+ <string name="key_ab02_shift">X</string>
+ <string name="key_ab02_alt">@string/alternates_for_x</string>
+
+ <string name="key_ab03_main">c</string>
+ <string name="key_ab03_shift">C</string>
+ <string name="key_ab03_alt">@string/alternates_for_c</string>
+
+ <string name="key_ab04_main">v</string>
+ <string name="key_ab04_shift">V</string>
+ <string name="key_ab04_alt">@string/alternates_for_v</string>
+
+ <string name="key_ab05_main">b</string>
+ <string name="key_ab05_shift">B</string>
+ <string name="key_ab05_alt">@string/alternates_for_b</string>
+
+ <string name="key_ab06_main">n</string>
+ <string name="key_ab06_shift">N</string>
+ <string name="key_ab06_alt">@string/alternates_for_n</string>
+
+ <string name="key_ab07_main">m</string>
+ <string name="key_ab07_shift">M</string>
+ <string name="key_ab07_alt">@string/alternates_for_m</string>
+
+ <string name="key_ab08_main">,</string>
+ <string name="key_ab08_shift">\?</string>
+ <string name="key_ab08_alt">,\?&lt;≤«‹</string>
+
+ <string name="key_ab09_main">.</string>
+ <string name="key_ab09_shift">:</string>
+ <string name="key_ab09_alt">.:&gt;≥»›…</string>
+
+ <string name="key_ab10_main">-</string>
+ <string name="key_ab10_shift">_</string>
+ <string name="key_ab10_alt">-_\?¿*</string>
+</resources>
+ \ No newline at end of file
diff --git a/java/res/values-sk/donottranslate-altchars.xml b/java/res/values-sk/donottranslate-altchars.xml
new file mode 100644
index 0000000..eab52b7
--- /dev/null
+++ b/java/res/values-sk/donottranslate-altchars.xml
@@ -0,0 +1,43 @@
+<?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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="alternates_for_a">áäàâãåæ</string>
+ <string name="alternates_for_b">{</string>
+ <string name="alternates_for_c">&amp;čç</string>
+ <string name="alternates_for_d">ďĐ</string>
+ <string name="alternates_for_e">3é€ěèêë</string>
+ <string name="alternates_for_f">[</string>
+ <string name="alternates_for_g">]</string>
+ <string name="alternates_for_i">8íïîìí</string>
+ <string name="alternates_for_k">łŁ</string>
+ <string name="alternates_for_l">ľĺŁ</string>
+ <string name="alternates_for_n">}ňñ</string>
+ <string name="alternates_for_o">9óôøœöõò</string>
+ <string name="alternates_for_q">1\\</string>
+ <string name="alternates_for_r">4ř</string>
+ <string name="alternates_for_s">š§ßđ</string>
+ <string name="alternates_for_t">5ť</string>
+ <string name="alternates_for_u">7úüůûù</string>
+ <string name="alternates_for_v">\@</string>
+ <string name="alternates_for_w">2|</string>
+ <string name="alternates_for_x">#</string>
+ <string name="alternates_for_y">ýÿ</string>
+ <string name="alternates_for_z">6ž</string>
+</resources>
diff --git a/java/res/values-sk/donottranslate-keymap.xml b/java/res/values-sk/donottranslate-keymap.xml
new file mode 100644
index 0000000..dbe740a
--- /dev/null
+++ b/java/res/values-sk/donottranslate-keymap.xml
@@ -0,0 +1,222 @@
+<?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.
+**
+**
+** 5-row layout for Slovak QWERTZ.
+**
+** See http://code.google.com/p/hackerskeyboard/wiki/AddingNewLayouts for
+** more information.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="key_tlde_main">;</string>
+ <string name="key_tlde_shift">°</string>
+ <string name="key_tlde_alt">;°`~</string>
+
+ <string name="key_ae01_main">+</string>
+ <string name="key_ae01_shift">1</string>
+ <string name="key_ae01_alt">+1~!¹¡½⅓¼⅛</string>
+
+ <string name="key_ae02_main">ľ</string>
+ <string name="key_ae02_shift">2</string>
+ <string name="key_ae02_alt">ľ2\@²⅛⅔</string>
+
+ <string name="key_ae03_main">š</string>
+ <string name="key_ae03_shift">3</string>
+ <string name="key_ae03_alt">š3#³£¾⅜</string>
+
+ <string name="key_ae04_main">č</string>
+ <string name="key_ae04_shift">4</string>
+ <string name="key_ae04_alt">č4$¼¤⁴¢¥</string>
+
+ <string name="key_ae05_main">ť</string>
+ <string name="key_ae05_shift">5</string>
+ <string name="key_ae05_alt">ť5%½⅜‰</string>
+
+ <string name="key_ae06_main">ž</string>
+ <string name="key_ae06_shift">6</string>
+ <string name="key_ae06_alt">ž6^¬⅝</string>
+
+ <string name="key_ae07_main">ý</string>
+ <string name="key_ae07_shift">7</string>
+ <string name="key_ae07_alt">ý7&amp;{⅞♪√</string>
+
+ <string name="key_ae08_main">á</string>
+ <string name="key_ae08_shift">8</string>
+ <string name="key_ae08_alt">á8*[™∞</string>
+
+ <string name="key_ae09_main">í</string>
+ <string name="key_ae09_shift">9</string>
+ <string name="key_ae09_alt">í9(]±</string>
+
+ <string name="key_ae10_main">é</string>
+ <string name="key_ae10_shift">0</string>
+ <string name="key_ae10_alt">é0)}°ⁿ≈≠</string>
+
+ <string name="key_ae11_main">=</string>
+ <string name="key_ae11_shift">%</string>
+ <string name="key_ae11_alt">=%-_\?\¿</string>
+
+ <string name="key_ae12_main">&#x0301;</string>
+ <string name="key_ae12_shift">&#x030c;</string>
+ <string name="key_ae12_alt">&#x0301;&#x030c;&lt;&gt;|</string>
+
+
+ <string name="key_ad01_main">q</string>
+ <string name="key_ad01_shift">Q</string>
+ <string name="key_ad01_alt">@string/alternates_for_q</string>
+
+ <string name="key_ad02_main">w</string>
+ <string name="key_ad02_shift">W</string>
+ <string name="key_ad02_alt">@string/alternates_for_w</string>
+
+ <string name="key_ad03_main">e</string>
+ <string name="key_ad03_shift">E</string>
+ <string name="key_ad03_alt">@string/alternates_for_e</string>
+
+ <string name="key_ad04_main">r</string>
+ <string name="key_ad04_shift">R</string>
+ <string name="key_ad04_alt">@string/alternates_for_r</string>
+
+ <string name="key_ad05_main">t</string>
+ <string name="key_ad05_shift">T</string>
+ <string name="key_ad05_alt">@string/alternates_for_t</string>
+
+ <string name="key_ad06_main">z</string>
+ <string name="key_ad06_shift">Z</string>
+ <string name="key_ad06_alt">@string/alternates_for_z</string>
+
+ <string name="key_ad07_main">u</string>
+ <string name="key_ad07_shift">U</string>
+ <string name="key_ad07_alt">@string/alternates_for_u</string>
+
+ <string name="key_ad08_main">i</string>
+ <string name="key_ad08_shift">I</string>
+ <string name="key_ad08_alt">@string/alternates_for_i</string>
+
+ <string name="key_ad09_main">o</string>
+ <string name="key_ad09_shift">O</string>
+ <string name="key_ad09_alt">@string/alternates_for_o</string>
+
+ <string name="key_ad10_main">p</string>
+ <string name="key_ad10_shift">P</string>
+ <string name="key_ad10_alt">@string/alternates_for_p</string>
+
+ <string name="key_ad11_main">ú</string>
+ <string name="key_ad11_shift">/</string>
+ <string name="key_ad11_alt">ú/÷[{</string>
+
+ <string name="key_ad12_main">ä</string>
+ <string name="key_ad12_shift">(</string>
+ <string name="key_ad12_alt">ä(×]}</string>
+
+ <string name="key_bksl_main">ň</string>
+ <string name="key_bksl_shift">)</string>
+ <string name="key_bksl_alt">ň)\|¤</string>
+
+
+ <string name="key_ac01_main">a</string>
+ <string name="key_ac01_shift">A</string>
+ <string name="key_ac01_alt">@string/alternates_for_a</string>
+
+ <string name="key_ac02_main">s</string>
+ <string name="key_ac02_shift">S</string>
+ <string name="key_ac02_alt">@string/alternates_for_s</string>
+
+ <string name="key_ac03_main">d</string>
+ <string name="key_ac03_shift">D</string>
+ <string name="key_ac03_alt">@string/alternates_for_d</string>
+
+ <string name="key_ac04_main">f</string>
+ <string name="key_ac04_shift">F</string>
+ <string name="key_ac04_alt">@string/alternates_for_f</string>
+
+ <string name="key_ac05_main">g</string>
+ <string name="key_ac05_shift">G</string>
+ <string name="key_ac05_alt">@string/alternates_for_g</string>
+
+ <string name="key_ac06_main">h</string>
+ <string name="key_ac06_shift">H</string>
+ <string name="key_ac06_alt">@string/alternates_for_h</string>
+
+ <string name="key_ac07_main">j</string>
+ <string name="key_ac07_shift">J</string>
+ <string name="key_ac07_alt">@string/alternates_for_j</string>
+
+ <string name="key_ac08_main">k</string>
+ <string name="key_ac08_shift">K</string>
+ <string name="key_ac08_alt">@string/alternates_for_k</string>
+
+ <string name="key_ac09_main">l</string>
+ <string name="key_ac09_shift">L</string>
+ <string name="key_ac09_alt">@string/alternates_for_l</string>
+
+ <string name="key_ac10_main">ô</string>
+ <string name="key_ac10_shift">\"</string>
+ <string name="key_ac10_alt">ô\"$;:</string>
+
+ <string name="key_ac11_main">§</string>
+ <string name="key_ac11_shift">!</string>
+ <string name="key_ac11_alt">§!ß\'\"‘’“”</string>
+
+
+ <string name="key_lsgt_main"></string>
+ <string name="key_lsgt_shift"></string>
+ <string name="key_lsgt_alt"></string>
+
+ <string name="key_ab01_main">y</string>
+ <string name="key_ab01_shift">Y</string>
+ <string name="key_ab01_alt">@string/alternates_for_y</string>
+
+ <string name="key_ab02_main">x</string>
+ <string name="key_ab02_shift">X</string>
+ <string name="key_ab02_alt">@string/alternates_for_x</string>
+
+ <string name="key_ab03_main">c</string>
+ <string name="key_ab03_shift">C</string>
+ <string name="key_ab03_alt">@string/alternates_for_c</string>
+
+ <string name="key_ab04_main">v</string>
+ <string name="key_ab04_shift">V</string>
+ <string name="key_ab04_alt">@string/alternates_for_v</string>
+
+ <string name="key_ab05_main">b</string>
+ <string name="key_ab05_shift">B</string>
+ <string name="key_ab05_alt">@string/alternates_for_b</string>
+
+ <string name="key_ab06_main">n</string>
+ <string name="key_ab06_shift">N</string>
+ <string name="key_ab06_alt">@string/alternates_for_n</string>
+
+ <string name="key_ab07_main">m</string>
+ <string name="key_ab07_shift">M</string>
+ <string name="key_ab07_alt">@string/alternates_for_m</string>
+
+ <string name="key_ab08_main">,</string>
+ <string name="key_ab08_shift">\?</string>
+ <string name="key_ab08_alt">,\?&lt;≤«‹</string>
+
+ <string name="key_ab09_main">.</string>
+ <string name="key_ab09_shift">:</string>
+ <string name="key_ab09_alt">.:&gt;≥»›…</string>
+
+ <string name="key_ab10_main">-</string>
+ <string name="key_ab10_shift">_</string>
+ <string name="key_ab10_alt">-_\?¿*</string>
+</resources>
+ \ No newline at end of file
diff --git a/java/res/values-sk/strings.xml b/java/res/values-sk/strings.xml
new file mode 100644
index 0000000..8f97351
--- /dev/null
+++ b/java/res/values-sk/strings.xml
@@ -0,0 +1,140 @@
+<?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/org.pocketworkstation.pckeyboard"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- <string name="english_ime_name" msgid="7252517407088836577">"Klávesnica Android"</string> -->
+ <!-- <string name="english_ime_settings" msgid="6661589557206947774">"Nastavenia klávesnice Android"</string> -->
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Možnosti zadávania textu a údajov"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"Pri stlačení klávesu vibrovať"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"Zvuk pri stlačení klávesu"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"Zobraziť znaky pri stlačení klávesu"</string>
+ <string name="hit_correction" msgid="4855351009261318389">"Opravovať preklepy"</string>
+ <string name="hit_correction_summary" msgid="8761701873008070796">"Povoliť opravu chýb vstupu"</string>
+ <string name="hit_correction_land" msgid="2567691684825205448">"Chyby vstupu v zobrazení na šírku"</string>
+ <string name="hit_correction_land_summary" msgid="4076803842198368328">"Povoliť opravu chýb vstupu"</string>
+ <string name="auto_correction" msgid="7911639788808958255">"Návrhy slov"</string>
+ <string name="auto_correction_summary" msgid="6881047311475758267">"Automaticky opraviť predchádzajúce slovo"</string>
+ <string name="prediction" msgid="466220283138359837">"Návrhy slov"</string>
+ <string name="prediction_category" msgid="7027100625580696660">"Nastavenia návrhov slov"</string>
+ <string name="prediction_summary" msgid="459788228830873110">"Povoliť automatické dokončovanie pri písaní"</string>
+ <string name="auto_complete_dialog_title" msgid="2172048590607201920">"Automatické dokončovanie"</string>
+ <string name="prediction_landscape" msgid="4874601565593216183">"Zväčšiť textové pole"</string>
+ <string name="prediction_landscape_summary" msgid="6736551095997839472">"Skryť návrhy slov v zobrazení na šírku"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"Veľké písmená automaticky"</string>
+ <string name="auto_cap_summary" msgid="3260681697600786825">"Začať vetu veľkým písmenom"</string>
+ <string name="auto_punctuate" msgid="7276672334264521751">"Automatická interpunkcia"</string>
+ <string name="auto_punctuate_summary" msgid="6589441565817502132"></string>
+ <string name="quick_fixes" msgid="5353213327680897927">"Rýchle opravy"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"Opravuje najčastejšie chyby pri písaní"</string>
+ <string name="show_suggestions" msgid="507074425254289133">"Zobraziť návrhy"</string>
+ <string name="show_suggestions_summary" msgid="1989672863935759654">"Zobrazovať navrhované slová počas písania"</string>
+ <string name="auto_complete" msgid="1103196318775486023">"Automatické dokončovanie"</string>
+ <string name="auto_complete_summary" msgid="6113149638718274624">"Stlačením medzerníka alebo interpunkčného znamienka automaticky vložíte zvýraznené slovo."</string>
+ <string name="prefs_settings_key" msgid="4623341240804046498">"Zobraziť kláves Nastavenia"</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automaticky"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Vždy zobrazovať"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"Vždy skrývať"</string>
+ <!-- no translation found for settings_key_modes:0 (8549888726962891527) -->
+ <!-- no translation found for settings_key_modes:1 (881280041213210923) -->
+ <!-- no translation found for settings_key_modes:2 (7317310620171067848) -->
+ <string name="bigram_suggestion" msgid="1323347224043514969">"Návrh Bigram"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Na zlepšenie návrhu použiť predchádzajúce slovo"</string>
+ <string-array name="prediction_modes">
+ <item msgid="4870266572388153286">"Žiadne"</item>
+ <item msgid="1669461741568287396">"Základné"</item>
+ <item msgid="4894328801530136615">"Rozšírené"</item>
+ </string-array>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Uložené"</string>
+ <string name="tip_long_press" msgid="6101270866284343344">"Podržaním klávesu zobrazíte diakritiku (á, ž atď.)"</string>
+ <string name="tip_dismiss" msgid="7585579046862204381">"Stlačením klávesu Späť ↶ môžete klávesnicu kedykoľvek zavrieť."</string>
+ <string name="tip_access_symbols" msgid="6344098517525531652">"Prístup k číslam a symbolom"</string>
+ <string name="tip_add_to_dictionary" msgid="1487293888469227817">"Stlačením a podržaním slova úplne vľavo toto slovo pridáte do slovníka."</string>
+ <string name="touch_to_continue" msgid="7869803257948414531">"Ak chcete pokračovať, dotknite sa tohto tipu »"</string>
+ <string name="touch_to_finish" msgid="7990196086480585789">"Ak chcete tento tip zavrieť a začať písať, dotknite sa tu."</string>
+ <string name="tip_to_open_keyboard" msgid="6821200275486950452"><b>"Klávesnica sa otvorí vždy, keď sa dotknete textového poľa."</b></string>
+ <string name="tip_to_view_accents" msgid="5433158573693308501"><b>"Pridržaním klávesu zobrazíte diakritiku"\n"(ó, ø, ö, ô apod.)"</b></string>
+ <string name="tip_to_open_symbols" msgid="7345139325622444880"><b>"Ak chcete prepnúť na režim zadávania číslic a symbolov, dotknite sa tohto klávesu."</b></string>
+ <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"Ak chcete prejsť späť na zadávanie písmen, dotknite sa znova tohto klávesu."</b></string>
+ <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"Pridržaním tohto klávesu zmeníte nastavenia klávesnice (napr. automatické dokončovanie)."</b></string>
+ <string name="tip_to_start_typing" msgid="7213843601369174313"><b>"Skúste si to."</b></string>
+ <string name="label_go_key" msgid="1635148082137219148">"Hľadať"</string>
+ <string name="label_next_key" msgid="362972844525672568">"Ďalej"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"Hotovo"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"Odoslať"</string>
+ <string name="label_symbol_key" msgid="6175820506864489453">"?123"</string>
+ <string name="label_phone_key" msgid="4275497665515080551">"123"</string>
+ <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string>
+ <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string>
+ <string name="voice_warning_title" msgid="4419354150908395008">"Hlasový vstup"</string>
+ <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Pre váš jazyk aktuálne nie je hlasový vstup podporovaný, ale funguje v angličtine."</string>
+ <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"Hlasový vstup je experimentálna funkcia, ktorá využíva sieťové rozpoznanie reči spoločnosti Google."</string>
+ <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"Ak chcete vypnúť hlasový vstup, prejdite na nastavenia klávesnice."</string>
+ <string name="voice_hint_dialog_message" msgid="6892342981545727994">"Ak chcete použiť hlasový vstup, stlačte tlačidlo mikrofónu alebo prejdite prstom po klávesnici na obrazovke."</string>
+ <string name="voice_listening" msgid="467518160751321844">"Hovorte"</string>
+ <string name="voice_working" msgid="6666937792815731889">"Prebieha spracovanie"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"Chyba. Skúste to znova."</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"Pripojenie sa nepodarilo."</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"Chyba, reč je príliš dlhá."</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"Problém so zvukom"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"Chyba servera"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"Nebola zistená žiadna reč."</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"Nenašli sa žiadne zhody"</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"Hlasové vyhľadávanie nie je nainštalované"</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Tip:"</b>" Ak chcete aktivovať hlasový vstup, prejdite prstom po klávesnici."</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Tip:"</b>" Nabudúce skúste vysloviť interpunkciu, napríklad „bodka“, „čiarka“ alebo „otáznik“."</string>
+ <string name="cancel" msgid="6830980399865683324">"Zrušiť"</string>
+ <string name="ok" msgid="7898366843681727667">"OK"</string>
+ <string name="voice_input" msgid="2466640768843347841">"Hlasový vstup"</string>
+ <string-array name="voice_input_modes">
+ <item msgid="1349082139076086774">"Na hlavnej klávesnici"</item>
+ <item msgid="8529385602829095903">"Na klávesnici so symbolmi"</item>
+ <item msgid="7283103513488381103">"Vypnuté"</item>
+ </string-array>
+ <string-array name="voice_input_modes_summary">
+ <item msgid="554248625705084903">"Mikrofón na hlavnej klávesnici"</item>
+ <item msgid="6907837061058876770">"Mikrofón na klávesnici so symbolmi"</item>
+ <item msgid="3664304608587798036">"Hlasový vstup je zakázaný"</item>
+ </string-array>
+ <string name="auto_submit" msgid="9151008027068358518">"Po hlasovom vstupe automaticky odoslať"</string>
+ <string name="auto_submit_summary" msgid="4961875269610384226">"Pri vyhľadávaní alebo prechode na ďalšie pole automaticky stlačiť kláves Enter."</string>
+ <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Otvorte klávesnicu"\n</b></font><font size="3">\n</font>"Dotknite sa ľubovoľného textového poľa."</string>
+ <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Zatvorte klávesnicu"\n</b></font><font size="3">\n</font>"Stlačte tlačidlo Späť."</string>
+ <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Dotknutím a pridržaním klávesu zobrazíte možnosti"\n</b></font><font size="3">\n</font>"Prístup k interpunkčným znamienkam a diakritike."</string>
+ <string name="keyboard_settings" msgid="4585753477617374032"><font size="17"><b>"Nastavenia klávesnice"\n</b></font><font size="3">\n</font>"Dotknite sa klávesu "<b>"?123"</b>" a podržte ho."</string>
+ <string name="popular_domain_0" msgid="3745279225122472969">".com"</string>
+ <string name="popular_domain_1" msgid="1370572248164278467">".sk"</string>
+ <string name="popular_domain_2" msgid="3036812463748402878">".org"</string>
+ <string name="popular_domain_3" msgid="8718639560809452028">".net"</string>
+ <string name="popular_domain_4" msgid="35359437471311470">".eu"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"Výber metódy vstupu"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Jazyky vstupu"</string>
+ <string name="language_selection_summary" msgid="187110938289512256">"Jazyk môžete zmeniť posunutím prsta po medzerníku."</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Ďalším dotykom slovo uložíte"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"K dispozícii je slovník"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"Povoliť spätnú väzbu od používateľov"</string>
+ <string name="prefs_description_log" msgid="5827825607258246003">"Automatickým zasielaním štatistík o využívaní editora metódy vstupu a správ o jeho zlyhaní do služby Google môžete prispieť k vylepšeniu tohto nástroja."</string>
+ <string name="prefs_enable_recorrection" msgid="4588408906649533582">"Dotykom opravíte slová"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="1056068922330206170">"Dotykom zadaným slov ich opravíte"</string>
+ <string name="keyboard_layout" msgid="437433231038683666">"Motív klávesnice"</string>
+ <string name="subtype_mode_keyboard" msgid="2242090416595003881">"klávesnica"</string>
+ <string name="subtype_mode_voice" msgid="4394113125441627771">"hlasová"</string>
+</resources>
diff --git a/java/res/values-sl/donottranslate-altchars.xml b/java/res/values-sl/donottranslate-altchars.xml
new file mode 100644
index 0000000..308f060
--- /dev/null
+++ b/java/res/values-sl/donottranslate-altchars.xml
@@ -0,0 +1,39 @@
+<?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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="alternates_for_a">äáàâãåāæ</string>
+ <string name="alternates_for_b">{</string>
+ <string name="alternates_for_c">čć¢</string>
+ <string name="alternates_for_e">3€éèêë</string>
+ <string name="alternates_for_f">[</string>
+ <string name="alternates_for_g">]</string>
+ <string name="alternates_for_k">ł</string>
+ <string name="alternates_for_l">ł</string>
+ <string name="alternates_for_m">§</string>
+ <string name="alternates_for_n">}</string>
+ <string name="alternates_for_o">9öóòôõōø</string>
+ <string name="alternates_for_u">7üúùûū</string>
+ <string name="alternates_for_q">1\\</string>
+ <string name="alternates_for_s">š§ß</string>
+ <string name="alternates_for_v">\@</string>
+ <string name="alternates_for_w">2|</string>
+ <string name="alternates_for_y">ýÿ¥</string>
+ <string name="alternates_for_z">6ž</string>
+</resources>
diff --git a/java/res/values-sl/donottranslate-keymap.xml b/java/res/values-sl/donottranslate-keymap.xml
new file mode 100644
index 0000000..5d31d0c
--- /dev/null
+++ b/java/res/values-sl/donottranslate-keymap.xml
@@ -0,0 +1,126 @@
+<?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.
+**
+**
+** 5-row layout for Slovenian, Bosnian, Croatian, and Latin Serbian,
+** contributed by Uroš Vampl.
+**
+** See http://code.google.com/p/hackerskeyboard/wiki/AddingNewLayouts for
+** more information.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="key_tlde_main">`</string>
+ <string name="key_tlde_shift">~</string>
+ <string name="key_tlde_alt">`~^°</string>
+
+ <string name="key_ae01_main">1</string>
+ <string name="key_ae01_shift">!</string>
+ <string name="key_ae01_alt">1!¹¡½⅓¼⅛</string>
+
+ <string name="key_ae02_main">2</string>
+ <string name="key_ae02_shift">\"</string>
+ <string name="key_ae02_alt">2\"²⅔</string>
+
+ <string name="key_ae03_main">3</string>
+ <string name="key_ae03_shift">#</string>
+ <string name="key_ae03_alt">3#³¾⅜♥♠♦♣</string>
+
+ <string name="key_ae04_main">4</string>
+ <string name="key_ae04_shift">$</string>
+ <string name="key_ae04_alt">4$⁴¼¥</string>
+
+ <string name="key_ae05_main">5</string>
+ <string name="key_ae05_shift">%</string>
+ <string name="key_ae05_alt">5%⅝‰</string>
+
+ <string name="key_ae06_main">6</string>
+ <string name="key_ae06_shift">&amp;</string>
+ <string name="key_ae06_alt">6&amp;↑↓←→</string>
+
+ <string name="key_ae07_main">7</string>
+ <string name="key_ae07_shift">/</string>
+ <string name="key_ae07_alt">7/⅞♪</string>
+
+ <string name="key_ae08_main">8</string>
+ <string name="key_ae08_shift">(</string>
+ <string name="key_ae08_alt">8(™∞†‡</string>
+
+ <string name="key_ae09_main">9</string>
+ <string name="key_ae09_shift">)</string>
+ <string name="key_ae09_alt">9)√</string>
+
+ <string name="key_ae10_main">0</string>
+ <string name="key_ae10_shift">=</string>
+ <string name="key_ae10_alt">0=ⁿ°≈≠</string>
+
+ <string name="key_ae11_main">\'</string>
+ <string name="key_ae11_shift">\?</string>
+ <string name="key_ae11_alt">\'\?</string>
+
+ <string name="key_ae12_main">+</string>
+ <string name="key_ae12_shift">*</string>
+ <string name="key_ae12_alt">+*•★±</string>
+
+
+ <string name="key_ad06_main">z</string>
+ <string name="key_ad06_shift">Z</string>
+ <string name="key_ad06_alt">@string/alternates_for_z</string>
+
+ <string name="key_ad11_main">š</string>
+ <string name="key_ad11_shift">Š</string>
+ <string name="key_ad11_alt">š÷</string>
+
+ <string name="key_ad12_main">đ</string>
+ <string name="key_ad12_shift">Đ</string>
+ <string name="key_ad12_alt">đ×</string>
+
+ <string name="key_bksl_main">ž</string>
+ <string name="key_bksl_shift">Ž</string>
+ <string name="key_bksl_alt">ž¤</string>
+
+
+ <string name="key_ac10_main">č</string>
+ <string name="key_ac10_shift">Č</string>
+ <string name="key_ac10_alt">č</string>
+
+ <string name="key_ac11_main">ć</string>
+ <string name="key_ac11_shift">Ć</string>
+ <string name="key_ac11_alt">ćß</string>
+
+
+ <string name="key_lsgt_main">&lt;</string>
+ <string name="key_lsgt_shift">&gt;</string>
+ <string name="key_lsgt_alt">&lt;&gt;|</string>
+
+ <string name="key_ab01_main">y</string>
+ <string name="key_ab01_shift">Y</string>
+ <string name="key_ab01_alt">@string/alternates_for_y</string>
+
+ <string name="key_ab08_main">,</string>
+ <string name="key_ab08_shift">;</string>
+ <string name="key_ab08_alt">;&lt;≤«‹</string>
+
+ <string name="key_ab09_main">.</string>
+ <string name="key_ab09_shift">:</string>
+ <string name="key_ab09_alt">:&gt;≥»›…</string>
+
+ <string name="key_ab10_main">-</string>
+ <string name="key_ab10_shift">_</string>
+ <string name="key_ab10_alt">-_–—</string>
+</resources>
diff --git a/java/res/values-sl/strings.xml b/java/res/values-sl/strings.xml
new file mode 100644
index 0000000..5c704ee
--- /dev/null
+++ b/java/res/values-sl/strings.xml
@@ -0,0 +1,140 @@
+<?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/org.pocketworkstation.pckeyboard"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- <string name="english_ime_name" msgid="7252517407088836577">"Tipkovnica Android"</string> -->
+ <!-- <string name="english_ime_settings" msgid="6661589557206947774">"Nastavitve tipkovnice Android"</string> -->
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Možnosti vnosa"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibriranje ob pritisku tipke"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"Zvok ob pritisku tipke"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"Pojavno okno ob pritisku tipke"</string>
+ <string name="hit_correction" msgid="4855351009261318389">"Popravljanje tipkarskih napak"</string>
+ <string name="hit_correction_summary" msgid="8761701873008070796">"Omogoči popravljanje napak pri vnosu"</string>
+ <string name="hit_correction_land" msgid="2567691684825205448">"Napake pri vnosu v ležečem položaju"</string>
+ <string name="hit_correction_land_summary" msgid="4076803842198368328">"Omogoči popravljanje napak pri vnosu"</string>
+ <string name="auto_correction" msgid="7911639788808958255">"Predlogi besed"</string>
+ <string name="auto_correction_summary" msgid="6881047311475758267">"Samodejno popravi prejšnjo besedo"</string>
+ <string name="prediction" msgid="466220283138359837">"Predlogi besed"</string>
+ <string name="prediction_category" msgid="7027100625580696660">"Nastavitve za predlaganje besede"</string>
+ <string name="prediction_summary" msgid="459788228830873110">"Omogoči samodokončanje med tipkanjem"</string>
+ <string name="auto_complete_dialog_title" msgid="2172048590607201920">"Samodokončanje"</string>
+ <string name="prediction_landscape" msgid="4874601565593216183">"Povečaj velikost besedilnega polja"</string>
+ <string name="prediction_landscape_summary" msgid="6736551095997839472">"Skrij predloge besed v ležečem pogledu"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"Samodejne velike začetnice"</string>
+ <string name="auto_cap_summary" msgid="3260681697600786825">"Napiši začetek stavka z veliko začetnico"</string>
+ <string name="auto_punctuate" msgid="7276672334264521751">"Samodejno vstavljanje ločil"</string>
+ <string name="auto_punctuate_summary" msgid="6589441565817502132"></string>
+ <string name="quick_fixes" msgid="5353213327680897927">"Hitri popravki"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"Popravi pogoste tipkarske napake"</string>
+ <string name="show_suggestions" msgid="507074425254289133">"Pokaži predloge"</string>
+ <string name="show_suggestions_summary" msgid="1989672863935759654">"Prikaži predlagane besede med tipkanjem"</string>
+ <string name="auto_complete" msgid="1103196318775486023">"Samodokončanje"</string>
+ <string name="auto_complete_summary" msgid="6113149638718274624">"Preslednica in ločila samodejno vnesejo označeno besedo"</string>
+ <string name="prefs_settings_key" msgid="4623341240804046498">"Pokaži tipko za nastavitve"</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Samodejno"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Vedno pokaži"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"Vedno skrij"</string>
+ <!-- no translation found for settings_key_modes:0 (8549888726962891527) -->
+ <!-- no translation found for settings_key_modes:1 (881280041213210923) -->
+ <!-- no translation found for settings_key_modes:2 (7317310620171067848) -->
+ <string name="bigram_suggestion" msgid="1323347224043514969">"Bigramni predlogi"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Predlog izboljšaj s prejšnjo besedo"</string>
+ <string-array name="prediction_modes">
+ <item msgid="4870266572388153286">"Brez"</item>
+ <item msgid="1669461741568287396">"Osnovni"</item>
+ <item msgid="4894328801530136615">"Dodatno"</item>
+ </string-array>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: shranjeno"</string>
+ <string name="tip_long_press" msgid="6101270866284343344">"Držite tipko, da prikažete poudarke (ø, ö itd.)"</string>
+ <string name="tip_dismiss" msgid="7585579046862204381">"Kadar koli lahko pritisnete tipko »Nazaj« ↶, da zaprete tipkovnico"</string>
+ <string name="tip_access_symbols" msgid="6344098517525531652">"Dostop do številk in simbolov"</string>
+ <string name="tip_add_to_dictionary" msgid="1487293888469227817">"Če besedo želite dodati v slovar, jo pridržite"</string>
+ <string name="touch_to_continue" msgid="7869803257948414531">"Dotaknite se tega nasveta za nadaljevanje »"</string>
+ <string name="touch_to_finish" msgid="7990196086480585789">"Dotaknite se tukaj, da zaprete nasvet in začnete tipkati!"</string>
+ <string name="tip_to_open_keyboard" msgid="6821200275486950452"><b>"Tipkovnice se odpre, kadar se dotaknete besedilnega polja"</b></string>
+ <string name="tip_to_view_accents" msgid="5433158573693308501"><b>"Za ogled poudarkov pridržite tipko"\n"(ø, ö, ô, ó itd.)"</b></string>
+ <string name="tip_to_open_symbols" msgid="7345139325622444880"><b>"Preklopite na številke in simbole z dotikom te tipke"</b></string>
+ <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"Na črke se vrnete, če se še enkrat dotaknete te tipke"</b></string>
+ <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"Pridržite to tipko, če želite spremeniti nastavitve tipkovnice, npr. samodokončanje"</b></string>
+ <string name="tip_to_start_typing" msgid="7213843601369174313"><b>"Poskusite!"</b></string>
+ <string name="label_go_key" msgid="1635148082137219148">"Pojdi"</string>
+ <string name="label_next_key" msgid="362972844525672568">"Naprej"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"Dokončano"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"Pošlji"</string>
+ <string name="label_symbol_key" msgid="6175820506864489453">"?123"</string>
+ <string name="label_phone_key" msgid="4275497665515080551">"123"</string>
+ <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string>
+ <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string>
+ <string name="voice_warning_title" msgid="4419354150908395008">"Glasovni vnos"</string>
+ <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Glasovni vnos trenutno ni podprt v vašem jeziku, deluje pa v angleščini."</string>
+ <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"Glasovni vnos je poskusna funkcija, ki uporablja Googlovo omrežno prepoznavanje govora."</string>
+ <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"Če želite izklopiti glasovni vnos, pojdite na nastavitve tipkovnice."</string>
+ <string name="voice_hint_dialog_message" msgid="6892342981545727994">"Če želite uporabiti glasovni vnos, pritisnite gumb z mikrofonom ali podrsajte s prstom po zaslonski tipkovnici."</string>
+ <string name="voice_listening" msgid="467518160751321844">"Začnite govoriti"</string>
+ <string name="voice_working" msgid="6666937792815731889">"Obdelava"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"Napaka. Poskusite znova."</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"Povezava ni mogoča"</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"Napaka, preveč govora."</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"Težave z zvokom"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"Napaka strežnika"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"Govora se ne sliši"</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"Ni rezultatov"</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"Glasovno iskanje ni nameščeno"</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Nasvet:"</b>" za govorjenje s prstom povlecite po tipkovnici"</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Nasvet:"</b>" naslednjič poskusite ločila izgovoriti, npr. »pika«, »vejica« ali »vprašaj«."</string>
+ <string name="cancel" msgid="6830980399865683324">"Prekliči"</string>
+ <string name="ok" msgid="7898366843681727667">"V redu"</string>
+ <string name="voice_input" msgid="2466640768843347841">"Glasovni vnos"</string>
+ <string-array name="voice_input_modes">
+ <item msgid="1349082139076086774">"Na glavni tipkovnici"</item>
+ <item msgid="8529385602829095903">"Na tipkovnici s simboli"</item>
+ <item msgid="7283103513488381103">"Izklopljeno"</item>
+ </string-array>
+ <string-array name="voice_input_modes_summary">
+ <item msgid="554248625705084903">"Mikrofon na glavni tipkovnici"</item>
+ <item msgid="6907837061058876770">"Mikrofon na tipkovnici s simboli"</item>
+ <item msgid="3664304608587798036">"Glasovni vnos je onemogočen"</item>
+ </string-array>
+ <string name="auto_submit" msgid="9151008027068358518">"Samodejno pošlji po govoru"</string>
+ <string name="auto_submit_summary" msgid="4961875269610384226">"Samodejno pritisni »Enter« pri iskanju ali prehodu na naslednje polje."</string>
+ <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Odprite tipkovnico"\n</b></font><font size="3">\n</font>"Dotaknite se katerega koli besedilnega polja."</string>
+ <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Zaprite tipkovnico"\n</b></font><font size="3">\n</font>"Pritisnite tipko »Nazaj«."</string>
+ <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Pridržite tipko za ogled možnosti"\n</b></font><font size="3">\n</font>"Dostop do ločil in poudarkov."</string>
+ <string name="keyboard_settings" msgid="4585753477617374032"><font size="17"><b>"Nastavitve "\n</b></font><font size="3">\n</font>"Pridržite tipko "<b>"?123"</b>"."</string>
+ <string name="popular_domain_0" msgid="3745279225122472969">".com"</string>
+ <string name="popular_domain_1" msgid="1370572248164278467">".net"</string>
+ <string name="popular_domain_2" msgid="3036812463748402878">".org"</string>
+ <string name="popular_domain_3" msgid="8718639560809452028">".gov"</string>
+ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"Izberite način vnosa"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Jeziki vnosa"</string>
+ <string name="language_selection_summary" msgid="187110938289512256">"Podrsajte s prstom po preslednici, da zamenjate jezik"</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Še enkrat se dotaknite, da shranite"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"Slovar je na voljo"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"Omogoči povratne informacije uporabnikov"</string>
+ <string name="prefs_description_log" msgid="5827825607258246003">"S samodejnim pošiljanjem statističnih podatkov o uporabi in poročil o zrušitvah Googlu nam lahko pomagate izboljšati urejevalnik načina vnosa."</string>
+ <string name="prefs_enable_recorrection" msgid="4588408906649533582">"Dotaknite se besed in jih popravite"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="1056068922330206170">"Dotaknite se vnesenih besed in jih popravite"</string>
+ <string name="keyboard_layout" msgid="437433231038683666">"Tema tipkovnice"</string>
+ <string name="subtype_mode_keyboard" msgid="2242090416595003881">"tipkovnica"</string>
+ <string name="subtype_mode_voice" msgid="4394113125441627771">"govor"</string>
+</resources>
diff --git a/java/res/values-sr/donottranslate-keymap.xml b/java/res/values-sr/donottranslate-keymap.xml
new file mode 100644
index 0000000..c69da93
--- /dev/null
+++ b/java/res/values-sr/donottranslate-keymap.xml
@@ -0,0 +1,197 @@
+<?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.
+**
+**
+** 5-row layout for English QWERTY.
+**
+** See http://code.google.com/p/hackerskeyboard/wiki/AddingNewLayouts for
+** more information.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="key_ae02_main">2</string>
+ <string name="key_ae02_shift">\"</string>
+ <string name="key_ae02_alt">2\"²⅔</string>
+
+ <string name="key_ae06_main">6</string>
+ <string name="key_ae06_shift">&amp;</string>
+ <string name="key_ae06_alt">6&amp;↑↓←→</string>
+
+ <string name="key_ae07_main">7</string>
+ <string name="key_ae07_shift">/</string>
+ <string name="key_ae07_alt">7/⅞♪</string>
+
+ <string name="key_ae08_main">8</string>
+ <string name="key_ae08_shift">(</string>
+ <string name="key_ae08_alt">8(•★∞†‡</string>
+
+ <string name="key_ae09_main">9</string>
+ <string name="key_ae09_shift">)</string>
+ <string name="key_ae09_alt">9)√</string>
+
+ <string name="key_ae10_main">0</string>
+ <string name="key_ae10_shift">=</string>
+ <string name="key_ae10_alt">0=ⁿ°</string>
+
+ <string name="key_ae11_main">\'</string>
+ <string name="key_ae11_shift">\?</string>
+ <string name="key_ae11_alt">\'\?—–</string>
+
+ <string name="key_ae12_main">+</string>
+ <string name="key_ae12_shift">*</string>
+ <string name="key_ae12_alt">+*≈≠±×÷</string>
+
+
+ <string name="key_ad01_main">љ</string>
+ <string name="key_ad01_shift">Љ</string>
+ <string name="key_ad01_alt"></string>
+
+ <string name="key_ad02_main">њ</string>
+ <string name="key_ad02_shift">Њ</string>
+ <string name="key_ad02_alt"></string>
+
+ <string name="key_ad03_main">е</string>
+ <string name="key_ad03_shift">Е</string>
+ <string name="key_ad03_alt"></string>
+
+ <string name="key_ad04_main">р</string>
+ <string name="key_ad04_shift">Р</string>
+ <string name="key_ad04_alt"></string>
+
+ <string name="key_ad05_main">т</string>
+ <string name="key_ad05_shift">Т</string>
+ <string name="key_ad05_alt"></string>
+
+ <string name="key_ad06_main">з</string>
+ <string name="key_ad06_shift">З</string>
+ <string name="key_ad06_alt"></string>
+
+ <string name="key_ad07_main">у</string>
+ <string name="key_ad07_shift">У</string>
+ <string name="key_ad07_alt"></string>
+
+ <string name="key_ad08_main">и</string>
+ <string name="key_ad08_shift">И</string>
+ <string name="key_ad08_alt"></string>
+
+ <string name="key_ad09_main">о</string>
+ <string name="key_ad09_shift">О</string>
+ <string name="key_ad09_alt"></string>
+
+ <string name="key_ad10_main">п</string>
+ <string name="key_ad10_shift">П</string>
+ <string name="key_ad10_alt"></string>
+
+ <string name="key_ad11_main">ш</string>
+ <string name="key_ad11_shift">Ш</string>
+ <string name="key_ad11_alt">[{</string>
+
+ <string name="key_ad12_main">ђ</string>
+ <string name="key_ad12_shift">Ђ</string>
+ <string name="key_ad12_alt">]}</string>
+
+
+ <string name="key_ac01_main">а</string>
+ <string name="key_ac01_shift">А</string>
+ <string name="key_ac01_alt"></string>
+
+ <string name="key_ac02_main">с</string>
+ <string name="key_ac02_shift">С</string>
+ <string name="key_ac02_alt"></string>
+
+ <string name="key_ac03_main">д</string>
+ <string name="key_ac03_shift">Д</string>
+ <string name="key_ac03_alt"></string>
+
+ <string name="key_ac04_main">ф</string>
+ <string name="key_ac04_shift">Ф</string>
+ <string name="key_ac04_alt"></string>
+
+ <string name="key_ac05_main">г</string>
+ <string name="key_ac05_shift">Г</string>
+ <string name="key_ac05_alt"></string>
+
+ <string name="key_ac06_main">х</string>
+ <string name="key_ac06_shift">Х</string>
+ <string name="key_ac06_alt"></string>
+
+ <string name="key_ac07_main">ј</string>
+ <string name="key_ac07_shift">Ј</string>
+ <string name="key_ac07_alt"></string>
+
+ <string name="key_ac08_main">к</string>
+ <string name="key_ac08_shift">К</string>
+ <string name="key_ac08_alt"></string>
+
+ <string name="key_ac09_main">л</string>
+ <string name="key_ac09_shift">Л</string>
+ <string name="key_ac09_alt"></string>
+
+ <string name="key_ac10_main">ч</string>
+ <string name="key_ac10_shift">Ч</string>
+ <string name="key_ac10_alt">;:</string>
+
+ <string name="key_ac11_main">ћ</string>
+ <string name="key_ac11_shift">Ћ</string>
+ <string name="key_ac11_alt">\'\"‘’“”</string>
+
+
+ <string name="key_lsgt_main"></string>
+ <string name="key_lsgt_shift"></string>
+ <string name="key_lsgt_alt"></string>
+
+ <string name="key_ab01_main">ж</string>
+ <string name="key_ab01_shift">Ж</string>
+ <string name="key_ab01_alt"></string>
+
+ <string name="key_ab02_main">џ</string>
+ <string name="key_ab02_shift">Џ</string>
+ <string name="key_ab02_alt"></string>
+
+ <string name="key_ab03_main">ц</string>
+ <string name="key_ab03_shift">Ц</string>
+ <string name="key_ab03_alt"></string>
+
+ <string name="key_ab04_main">в</string>
+ <string name="key_ab04_shift">В</string>
+ <string name="key_ab04_alt"></string>
+
+ <string name="key_ab05_main">б</string>
+ <string name="key_ab05_shift">Б</string>
+ <string name="key_ab05_alt"></string>
+
+ <string name="key_ab06_main">н</string>
+ <string name="key_ab06_shift">Н</string>
+ <string name="key_ab06_alt"></string>
+
+ <string name="key_ab07_main">м</string>
+ <string name="key_ab07_shift">М</string>
+ <string name="key_ab07_alt"></string>
+
+ <string name="key_ab08_main">,</string>
+ <string name="key_ab08_shift">;</string>
+ <string name="key_ab08_alt">,;&lt;≤«‹</string>
+
+ <string name="key_ab09_main">.</string>
+ <string name="key_ab09_shift">:</string>
+ <string name="key_ab09_alt">.:&gt;≥»›…</string>
+
+ <string name="key_ab10_main">-</string>
+ <string name="key_ab10_shift">_</string>
+ <string name="key_ab10_alt">-_/\?¿</string>
+</resources>
diff --git a/java/res/values-sr/strings.xml b/java/res/values-sr/strings.xml
new file mode 100644
index 0000000..91fbbc4
--- /dev/null
+++ b/java/res/values-sr/strings.xml
@@ -0,0 +1,140 @@
+<?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/org.pocketworkstation.pckeyboard"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- <string name="english_ime_name" msgid="7252517407088836577">"Android тастатура"</string> -->
+ <!-- <string name="english_ime_settings" msgid="6661589557206947774">"Подешавања Android тастатуре"</string> -->
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Опције уноса"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"Вибрирај на притисак тастера"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"Звук на притисак тастера"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"Искачући прозор приликом притиска тастера"</string>
+ <string name="hit_correction" msgid="4855351009261318389">"Исправи грешке у куцању"</string>
+ <string name="hit_correction_summary" msgid="8761701873008070796">"Омогућавање исправљања грешака током уноса"</string>
+ <string name="hit_correction_land" msgid="2567691684825205448">"Грешке приликом уноса у положеном приказу"</string>
+ <string name="hit_correction_land_summary" msgid="4076803842198368328">"Омогућавање исправљања грешака током уноса"</string>
+ <string name="auto_correction" msgid="7911639788808958255">"Предлагање речи"</string>
+ <string name="auto_correction_summary" msgid="6881047311475758267">"Аутоматско исправљање претходне речи"</string>
+ <string name="prediction" msgid="466220283138359837">"Предлагање речи"</string>
+ <string name="prediction_category" msgid="7027100625580696660">"Подешавања за предлагање речи"</string>
+ <string name="prediction_summary" msgid="459788228830873110">"Омогућавање аутоматског довршавања током уноса текста"</string>
+ <string name="auto_complete_dialog_title" msgid="2172048590607201920">"Аутоматско довршавање"</string>
+ <string name="prediction_landscape" msgid="4874601565593216183">"Повећај величину поља за текст"</string>
+ <string name="prediction_landscape_summary" msgid="6736551095997839472">"Скривање предложених речи у положеном приказу"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"Аутоматски унос великих слова"</string>
+ <string name="auto_cap_summary" msgid="3260681697600786825">"Унос великог слова на почетку реченице"</string>
+ <string name="auto_punctuate" msgid="7276672334264521751">"Аутоматска интерпункција"</string>
+ <string name="auto_punctuate_summary" msgid="6589441565817502132"></string>
+ <string name="quick_fixes" msgid="5353213327680897927">"Брзе исправке"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"Исправља честе грешке у куцању"</string>
+ <string name="show_suggestions" msgid="507074425254289133">"Прикажи предлоге"</string>
+ <string name="show_suggestions_summary" msgid="1989672863935759654">"Приказивање предложених речи током уноса текста"</string>
+ <string name="auto_complete" msgid="1103196318775486023">"Аутоматско довршавање"</string>
+ <string name="auto_complete_summary" msgid="6113149638718274624">"Означена реч се аутоматски умеће када притиснете размак или знак интерпункције"</string>
+ <string name="prefs_settings_key" msgid="4623341240804046498">"Прикажи тастер за подешавања"</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Аутоматски"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Увек прикажи"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"Увек сакриј"</string>
+ <!-- no translation found for settings_key_modes:0 (8549888726962891527) -->
+ <!-- no translation found for settings_key_modes:1 (881280041213210923) -->
+ <!-- no translation found for settings_key_modes:2 (7317310620171067848) -->
+ <string name="bigram_suggestion" msgid="1323347224043514969">"Bigram предлози"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Користи претходну реч за побољшање предлога"</string>
+ <string-array name="prediction_modes">
+ <item msgid="4870266572388153286">"Ништа"</item>
+ <item msgid="1669461741568287396">"Основни"</item>
+ <item msgid="4894328801530136615">"Напредно"</item>
+ </string-array>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Сачувано"</string>
+ <string name="tip_long_press" msgid="6101270866284343344">"Држите тастер да бисте видели акценте (ø, ö итд.)"</string>
+ <string name="tip_dismiss" msgid="7585579046862204381">"Притисните тастер „Назад“ ↶ у било ком тренутку да бисте затворили тастатуру"</string>
+ <string name="tip_access_symbols" msgid="6344098517525531652">"Приступите бројевима и симболима"</string>
+ <string name="tip_add_to_dictionary" msgid="1487293888469227817">"Притисните и држите прву реч са леве стране да бисте је додали у речник"</string>
+ <string name="touch_to_continue" msgid="7869803257948414531">"Додирните овај савет да бисте наставили »"</string>
+ <string name="touch_to_finish" msgid="7990196086480585789">"Додирните овде да бисте затворили овај савет и почели да уносите текст!"</string>
+ <string name="tip_to_open_keyboard" msgid="6821200275486950452"><b>"Тастатура се отвара сваки пут када додирнете поље за текст"</b></string>
+ <string name="tip_to_view_accents" msgid="5433158573693308501"><b>"Додирните и држите тастер да бисте видели акценте"\n"(ø, ö, ô, ó, и тако даље)"</b></string>
+ <string name="tip_to_open_symbols" msgid="7345139325622444880"><b>"Пређите на бројеве и симболе тако што ћете додирнути овај тастер"</b></string>
+ <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"Вратите се на слова тако што ћете поново додирнути овај тастер"</b></string>
+ <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"Додирните и држите овај тастер да бисте променили подешавања тастатуре, као што је аутоматско довршавање"</b></string>
+ <string name="tip_to_start_typing" msgid="7213843601369174313"><b>"Пробајте!"</b></string>
+ <string name="label_go_key" msgid="1635148082137219148">"Иди"</string>
+ <string name="label_next_key" msgid="362972844525672568">"Следеће"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"Готово"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"Пошаљи"</string>
+ <string name="label_symbol_key" msgid="6175820506864489453">"?123"</string>
+ <string name="label_phone_key" msgid="4275497665515080551">"123"</string>
+ <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string>
+ <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string>
+ <string name="voice_warning_title" msgid="4419354150908395008">"Гласовни унос"</string>
+ <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Гласовни унос тренутно није подржан за ваш језик, али функционише на енглеском."</string>
+ <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"Гласовни унос је експериментална функција која користи Google-ово мрежно препознавање гласа."</string>
+ <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"Да бисте искључили гласовни унос, идите на подешавања тастатуре."</string>
+ <string name="voice_hint_dialog_message" msgid="6892342981545727994">"Да бисте користили гласовни унос, притисните дугме за микрофон или превуците прст преко тастатуре на екрану."</string>
+ <string name="voice_listening" msgid="467518160751321844">"Говорите сада"</string>
+ <string name="voice_working" msgid="6666937792815731889">"Обрада"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"Грешка. Покушајте поново."</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"Повезивање није могуће"</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"Грешка, говорите предуго."</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"Проблем са звуком"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"Грешка сервера"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"Не чује се говор"</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"Нема подударања"</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"Гласовна претрага није инсталирана"</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Савет:"</b>" Превуците прстом преко тастатуре за гласовни унос"</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Савет:"</b>" Следећи пут покушајте да изговорите знакове интерпункције као што су „тачка“, „зарез“ или „знак питања“."</string>
+ <string name="cancel" msgid="6830980399865683324">"Откажи"</string>
+ <string name="ok" msgid="7898366843681727667">"Потврди"</string>
+ <string name="voice_input" msgid="2466640768843347841">"Гласовни унос"</string>
+ <string-array name="voice_input_modes">
+ <item msgid="1349082139076086774">"На главној тастатури"</item>
+ <item msgid="8529385602829095903">"На тастатури са симболима"</item>
+ <item msgid="7283103513488381103">"Искључено"</item>
+ </string-array>
+ <string-array name="voice_input_modes_summary">
+ <item msgid="554248625705084903">"Микрофон на главној тастатури"</item>
+ <item msgid="6907837061058876770">"Микрофон на тастатури са симболима"</item>
+ <item msgid="3664304608587798036">"Гласовни унос је онемогућен"</item>
+ </string-array>
+ <string name="auto_submit" msgid="9151008027068358518">"Аутоматски пошаљи после гласа"</string>
+ <string name="auto_submit_summary" msgid="4961875269610384226">"Аутоматски притисак на enter приликом претраге или преласка на следеће поље."</string>
+ <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Активирање тастатуре"\n</b></font><font size="3">\n</font>"Додирните било које поље за текст."</string>
+ <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Затварање тастатуре"\n</b></font><font size="3">\n</font>"Притисните тастер „Назад“."</string>
+ <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Додирните и држите тастер да би се приказале опције"\n</b></font><font size="3">\n</font>"Приступ знаковима интерпункције и акцентима."</string>
+ <string name="keyboard_settings" msgid="4585753477617374032"><font size="17"><b>"Подешавања тастатуре"\n</b></font><font size="3">\n</font>"Додирните и држите тастер "<b>"?123"</b>"."</string>
+ <string name="popular_domain_0" msgid="3745279225122472969">".com"</string>
+ <string name="popular_domain_1" msgid="1370572248164278467">".net"</string>
+ <string name="popular_domain_2" msgid="3036812463748402878">".org"</string>
+ <string name="popular_domain_3" msgid="8718639560809452028">".gov"</string>
+ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"Изаберите метод уноса"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Језици за унос"</string>
+ <string name="language_selection_summary" msgid="187110938289512256">"Превуците прст преко тастера за размак да бисте променили језик"</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Поново додирните да бисте сачували"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"Речник је доступан"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"Омогући повратну информацију корисника"</string>
+ <string name="prefs_description_log" msgid="5827825607258246003">"Помозите да се побољша овај уређивач режима уноса тако што ће се аутоматски послати статистика о коришћењу и извештаји о грешкама компанији Google."</string>
+ <string name="prefs_enable_recorrection" msgid="4588408906649533582">"Додирните да бисте исправили речи"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="1056068922330206170">"Додирните унете речи да бисте их исправили"</string>
+ <string name="keyboard_layout" msgid="437433231038683666">"Тема тастатуре"</string>
+ <string name="subtype_mode_keyboard" msgid="2242090416595003881">"тастатура"</string>
+ <string name="subtype_mode_voice" msgid="4394113125441627771">"глас"</string>
+</resources>
diff --git a/java/res/values-sv/donottranslate-altchars.xml b/java/res/values-sv/donottranslate-altchars.xml
new file mode 100644
index 0000000..cb2099b
--- /dev/null
+++ b/java/res/values-sv/donottranslate-altchars.xml
@@ -0,0 +1,38 @@
+<?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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="alternates_for_a">áàâąã</string>
+ <string name="alternates_for_e">3éèêëę€</string>
+ <string name="alternates_for_i">8ïîìí</string>
+ <string name="alternates_for_o">9õôòó</string>
+ <string name="alternates_for_u">7ūûùú</string>
+ <string name="alternates_for_s">śšşß</string>
+ <string name="alternates_for_n">ńñň</string>
+ <string name="alternates_for_c">çćč</string>
+ <string name="alternates_for_y">6üÿý</string>
+ <string name="alternates_for_d">ðď</string>
+ <string name="alternates_for_r">4ř</string>
+ <string name="alternates_for_t">5þť</string>
+ <string name="alternates_for_z">źžż</string>
+ <string name="alternates_for_l">ł</string>
+ <string name="alternates_for_v"></string>
+ <string name="alternates_for_a_umlaut">æ</string>
+ <string name="alternates_for_o_umlaut">øœ</string>
+</resources>
diff --git a/java/res/values-sv/donottranslate-keymap.xml b/java/res/values-sv/donottranslate-keymap.xml
new file mode 100644
index 0000000..aee7dbc
--- /dev/null
+++ b/java/res/values-sv/donottranslate-keymap.xml
@@ -0,0 +1,219 @@
+<?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.
+**
+**
+** 5-row layout for English QWERTY.
+**
+** See http://code.google.com/p/hackerskeyboard/wiki/AddingNewLayouts for
+** more information.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="key_tlde_main">§</string>
+ <string name="key_tlde_shift">½</string>
+ <string name="key_tlde_alt">½¼¾</string>
+
+ <string name="key_ae01_main">1</string>
+ <string name="key_ae01_shift">!</string>
+ <string name="key_ae01_alt">1º¢¥¡¹</string>
+
+ <string name="key_ae02_main">2</string>
+ <string name="key_ae02_shift">\"</string>
+ <string name="key_ae02_alt">2\@²</string>
+
+ <string name="key_ae03_main">3</string>
+ <string name="key_ae03_shift">#</string>
+ <string name="key_ae03_alt">3£³</string>
+
+ <string name="key_ae04_main">4</string>
+ <string name="key_ae04_shift">¤</string>
+ <string name="key_ae04_alt">4$</string>
+
+ <string name="key_ae05_main">5</string>
+ <string name="key_ae05_shift">%</string>
+ <string name="key_ae05_alt">5</string>
+
+ <string name="key_ae06_main">6</string>
+ <string name="key_ae06_shift">&amp;</string>
+ <string name="key_ae06_alt"></string>
+
+ <string name="key_ae07_main">7</string>
+ <string name="key_ae07_shift">/</string>
+ <string name="key_ae07_alt">7{</string>
+
+ <string name="key_ae08_main">8</string>
+ <string name="key_ae08_shift">(</string>
+ <string name="key_ae08_alt">8[</string>
+
+ <string name="key_ae09_main">9</string>
+ <string name="key_ae09_shift">)</string>
+ <string name="key_ae09_alt">9]</string>
+
+ <string name="key_ae10_main">0</string>
+ <string name="key_ae10_shift">=</string>
+ <string name="key_ae10_alt">0}</string>
+
+ <string name="key_ae11_main">+</string>
+ <string name="key_ae11_shift">\?</string>
+ <string name="key_ae11_alt">+\\¿±</string>
+
+ <string name="key_ae12_main">´</string>
+ <string name="key_ae12_shift">`</string>
+ <string name="key_ae12_alt"></string>
+
+
+ <string name="key_ad01_main">q</string>
+ <string name="key_ad01_shift">Q</string>
+ <string name="key_ad01_alt"></string>
+
+ <string name="key_ad02_main">w</string>
+ <string name="key_ad02_shift">W</string>
+ <string name="key_ad02_alt"></string>
+
+ <string name="key_ad03_main">e</string>
+ <string name="key_ad03_shift">E</string>
+ <string name="key_ad03_alt">€éèêë</string>
+
+ <string name="key_ad04_main">r</string>
+ <string name="key_ad04_shift">R</string>
+ <string name="key_ad04_alt">r®</string>
+
+ <string name="key_ad05_main">t</string>
+ <string name="key_ad05_shift">T</string>
+ <string name="key_ad05_alt">þ</string>
+
+ <string name="key_ad06_main">y</string>
+ <string name="key_ad06_shift">Y</string>
+ <string name="key_ad06_alt">ÿ</string>
+
+ <string name="key_ad07_main">u</string>
+ <string name="key_ad07_shift">U</string>
+ <string name="key_ad07_alt">üû</string>
+
+ <string name="key_ad08_main">i</string>
+ <string name="key_ad08_shift">I</string>
+ <string name="key_ad08_alt">íï</string>
+
+ <string name="key_ad09_main">o</string>
+ <string name="key_ad09_shift">O</string>
+ <string name="key_ad09_alt">ôõ</string>
+
+ <string name="key_ad10_main">p</string>
+ <string name="key_ad10_shift">P</string>
+ <string name="key_ad10_alt"></string>
+
+ <string name="key_ad11_main">å</string>
+ <string name="key_ad11_shift">Å</string>
+ <string name="key_ad11_alt"></string>
+
+ <string name="key_ad12_main">¨</string>
+ <string name="key_ad12_shift">^</string>
+ <string name="key_ad12_alt">¨~</string>
+
+ <string name="key_bksl_main">&gt;</string>
+ <string name="key_bksl_shift">&lt;</string>
+ <string name="key_bksl_alt">&gt;|«»</string>
+
+ <string name="key_ac01_main">a</string>
+ <string name="key_ac01_shift">A</string>
+ <string name="key_ac01_alt">âãáà</string>
+
+ <string name="key_ac02_main">s</string>
+ <string name="key_ac02_shift">S</string>
+ <string name="key_ac02_alt"></string>
+
+ <string name="key_ac03_main">d</string>
+ <string name="key_ac03_shift">D</string>
+ <string name="key_ac03_alt"></string>
+
+ <string name="key_ac04_main">f</string>
+ <string name="key_ac04_shift">F</string>
+ <string name="key_ac04_alt"></string>
+
+ <string name="key_ac05_main">g</string>
+ <string name="key_ac05_shift">G</string>
+ <string name="key_ac05_alt"></string>
+
+ <string name="key_ac06_main">h</string>
+ <string name="key_ac06_shift">H</string>
+ <string name="key_ac06_alt"></string>
+
+ <string name="key_ac07_main">j</string>
+ <string name="key_ac07_shift">J</string>
+ <string name="key_ac07_alt"></string>
+
+ <string name="key_ac08_main">k</string>
+ <string name="key_ac08_shift">K</string>
+ <string name="key_ac08_alt"></string>
+
+ <string name="key_ac09_main">l</string>
+ <string name="key_ac09_shift">L</string>
+ <string name="key_ac09_alt"></string>
+
+ <string name="key_ac10_main">ö</string>
+ <string name="key_ac10_shift">Ö</string>
+ <string name="key_ac10_alt"></string>
+
+ <string name="key_ac11_main">ä</string>
+ <string name="key_ac11_shift">Ä</string>
+ <string name="key_ac11_alt"></string>
+
+ <string name="key_lsgt_main">\'</string>
+ <string name="key_lsgt_shift">*</string>
+ <string name="key_lsgt_alt"></string>
+
+ <string name="key_ab01_main">z</string>
+ <string name="key_ab01_shift">Z</string>
+ <string name="key_ab01_alt"></string>
+
+ <string name="key_ab02_main">x</string>
+ <string name="key_ab02_shift">X</string>
+ <string name="key_ab02_alt"></string>
+
+ <string name="key_ab03_main">c</string>
+ <string name="key_ab03_shift">C</string>
+ <string name="key_ab03_alt">©</string>
+
+ <string name="key_ab04_main">v</string>
+ <string name="key_ab04_shift">V</string>
+ <string name="key_ab04_alt"></string>
+
+ <string name="key_ab05_main">b</string>
+ <string name="key_ab05_shift">B</string>
+ <string name="key_ab05_alt"></string>
+
+ <string name="key_ab06_main">n</string>
+ <string name="key_ab06_shift">N</string>
+ <string name="key_ab06_alt">ñ</string>
+
+ <string name="key_ab07_main">m</string>
+ <string name="key_ab07_shift">M</string>
+ <string name="key_ab07_alt">µ</string>
+
+ <string name="key_ab08_main">,</string>
+ <string name="key_ab08_shift">;</string>
+ <string name="key_ab08_alt"></string>
+
+ <string name="key_ab09_main">.</string>
+ <string name="key_ab09_shift">:</string>
+ <string name="key_ab09_alt"></string>
+
+ <string name="key_ab10_main">-</string>
+ <string name="key_ab10_shift">_</string>
+ <string name="key_ab10_alt">-¯</string>
+</resources>
diff --git a/java/res/values-sv/strings.xml b/java/res/values-sv/strings.xml
new file mode 100644
index 0000000..8f8ab86
--- /dev/null
+++ b/java/res/values-sv/strings.xml
@@ -0,0 +1,140 @@
+<?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/org.pocketworkstation.pckeyboard"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- <string name="english_ime_name" msgid="7252517407088836577">"Androids tangentbord"</string> -->
+ <!-- <string name="english_ime_settings" msgid="6661589557206947774">"Inställningar för Androids tangentbord"</string> -->
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Inmatningsalternativ"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrera vid tangenttryck"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"Knappljud"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"Popup vid knapptryck"</string>
+ <string name="hit_correction" msgid="4855351009261318389">"Rätta skrivfel"</string>
+ <string name="hit_correction_summary" msgid="8761701873008070796">"Aktivera rättning av felaktiga inmatningar"</string>
+ <string name="hit_correction_land" msgid="2567691684825205448">"Inmatningsfel i liggande vy"</string>
+ <string name="hit_correction_land_summary" msgid="4076803842198368328">"Aktivera rättning av felaktiga inmatningar"</string>
+ <string name="auto_correction" msgid="7911639788808958255">"Ordförslag"</string>
+ <string name="auto_correction_summary" msgid="6881047311475758267">"Rätta automatiskt föregående ord"</string>
+ <string name="prediction" msgid="466220283138359837">"Ordförslag"</string>
+ <string name="prediction_category" msgid="7027100625580696660">"Inställningar för ordförslag"</string>
+ <string name="prediction_summary" msgid="459788228830873110">"Aktivera Komplettera automatiskt när du skriver"</string>
+ <string name="auto_complete_dialog_title" msgid="2172048590607201920">"Komplettera automatiskt"</string>
+ <string name="prediction_landscape" msgid="4874601565593216183">"Gör textfältet större"</string>
+ <string name="prediction_landscape_summary" msgid="6736551095997839472">"Dölj ordförslag i liggande vy"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"Automatiska versaler"</string>
+ <string name="auto_cap_summary" msgid="3260681697600786825">"Använd versal i början av mening"</string>
+ <string name="auto_punctuate" msgid="7276672334264521751">"Automatiska punkter"</string>
+ <string name="auto_punctuate_summary" msgid="6589441565817502132"></string>
+ <string name="quick_fixes" msgid="5353213327680897927">"Snabba lösningar"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"Åtgärdar automatiskt vanliga misstag"</string>
+ <string name="show_suggestions" msgid="507074425254289133">"Visa förslag"</string>
+ <string name="show_suggestions_summary" msgid="1989672863935759654">"Visar ordförslag när du skriver"</string>
+ <string name="auto_complete" msgid="1103196318775486023">"Komplettera automatiskt"</string>
+ <string name="auto_complete_summary" msgid="6113149638718274624">"Blanksteg och punkt infogar automatiskt markerat ord"</string>
+ <string name="prefs_settings_key" msgid="4623341240804046498">"Visa inställningsknapp"</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automatiskt"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Visa alltid"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"Dölj alltid"</string>
+ <!-- no translation found for settings_key_modes:0 (8549888726962891527) -->
+ <!-- no translation found for settings_key_modes:1 (881280041213210923) -->
+ <!-- no translation found for settings_key_modes:2 (7317310620171067848) -->
+ <string name="bigram_suggestion" msgid="1323347224043514969">"Bigramförslag"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Förbättra förslaget med föregående ord"</string>
+ <string-array name="prediction_modes">
+ <item msgid="4870266572388153286">"Inget"</item>
+ <item msgid="1669461741568287396">"Grundinställningar"</item>
+ <item msgid="4894328801530136615">"Avancerade"</item>
+ </string-array>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: sparat"</string>
+ <string name="tip_long_press" msgid="6101270866284343344">"Håll nere en tangent om du vill visa accenter (ø, ö, etc.)"</string>
+ <string name="tip_dismiss" msgid="7585579046862204381">"Tryck på Tillbaka ↶ om du vill stänga tangentbordet"</string>
+ <string name="tip_access_symbols" msgid="6344098517525531652">"För siffror och symboler"</string>
+ <string name="tip_add_to_dictionary" msgid="1487293888469227817">"Tryck och håll ned ordet längst till vänster om du vill lägga till det i ordlistan"</string>
+ <string name="touch_to_continue" msgid="7869803257948414531">"Tryck på tipset för att fortsätta »"</string>
+ <string name="touch_to_finish" msgid="7990196086480585789">"Tryck här om du vill stänga tipset och börja skriva!"</string>
+ <string name="tip_to_open_keyboard" msgid="6821200275486950452"><b>"Tangentbordet öppnas när du trycker på ett textfält"</b></string>
+ <string name="tip_to_view_accents" msgid="5433158573693308501"><b>"Tryck och håll nere en tangent om du vill visa accenter"\n"(ø, ö, ô, ó och så vidare)"</b></string>
+ <string name="tip_to_open_symbols" msgid="7345139325622444880"><b>"Växla till siffror och symboler med den här tangenten"</b></string>
+ <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"Återvänd till bokstäver genom att trycka på tangenten en gång till"</b></string>
+ <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"Tryck och håll ned tangenten om du vill ändra inställningarna för tangentbordet, till exempel Komplettera automatiskt"</b></string>
+ <string name="tip_to_start_typing" msgid="7213843601369174313"><b>"Testa!"</b></string>
+ <string name="label_go_key" msgid="1635148082137219148">"Kör"</string>
+ <string name="label_next_key" msgid="362972844525672568">"Nästa"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"Färdig"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"Skicka"</string>
+ <string name="label_symbol_key" msgid="6175820506864489453">"?123"</string>
+ <string name="label_phone_key" msgid="4275497665515080551">"123"</string>
+ <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string>
+ <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string>
+ <string name="voice_warning_title" msgid="4419354150908395008">"Röstindata"</string>
+ <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Röstindata stöds inte på ditt språk än, men tjänsten fungerar på engelska."</string>
+ <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"Röstinmatning är en funktion på experimentstadiet som använder Googles nätverks taligenkänning."</string>
+ <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"Om du vill stänga av röstindata öppnar du inställningarna för tangentbordet."</string>
+ <string name="voice_hint_dialog_message" msgid="6892342981545727994">"Om du vill använda röstinmatning trycker du på mikrofonknappen eller drar fingret över tangentbordet på skärmen."</string>
+ <string name="voice_listening" msgid="467518160751321844">"Tala nu"</string>
+ <string name="voice_working" msgid="6666937792815731889">"Fungerar"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"Fel. Försök igen."</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"Det gick inte att ansluta"</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"Fel, för mycket tal."</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"Ljudproblem"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"Serverfel"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"Hörde inget tal"</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"Inga träffar hittades"</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"Voice Search är inte installerat"</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Tips!"</b>" Dra över tangentbordet om du vill tala"</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Tips!"</b>" Nästa gång testar du att säga skiljetecknen, som \"punkt\", \"komma\" eller \"frågetecken\"."</string>
+ <string name="cancel" msgid="6830980399865683324">"Avbryt"</string>
+ <string name="ok" msgid="7898366843681727667">"OK"</string>
+ <string name="voice_input" msgid="2466640768843347841">"Röstindata"</string>
+ <string-array name="voice_input_modes">
+ <item msgid="1349082139076086774">"På huvudtangentbordet"</item>
+ <item msgid="8529385602829095903">"På symboltangentbordet"</item>
+ <item msgid="7283103513488381103">"Av"</item>
+ </string-array>
+ <string-array name="voice_input_modes_summary">
+ <item msgid="554248625705084903">"Mikrofon på huvudtangentbordet"</item>
+ <item msgid="6907837061058876770">"Mikrofon på symboltangentbordet"</item>
+ <item msgid="3664304608587798036">"Röstindata är inaktiverat"</item>
+ </string-array>
+ <string name="auto_submit" msgid="9151008027068358518">"Skicka automatiskt efter röst"</string>
+ <string name="auto_submit_summary" msgid="4961875269610384226">"Tryck automatiskt på retur vid sökning eller när du fortsätter till nästa fält."</string>
+ <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Öppna tangentbordet"\n</b></font><font size="3">\n</font>"Tryck på ett textfält."</string>
+ <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Stäng tangentbordet"\n</b></font><font size="3">\n</font>"Tryck på Tillbaka."</string>
+ <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Tryck länge på en tangent om du vill se alternativ"\n</b></font><font size="3">\n</font>"Använda skiljetecken och accenter."</string>
+ <string name="keyboard_settings" msgid="4585753477617374032"><font size="17"><b>"Tangentbordsinställningar"\n</b></font><font size="3">\n</font>"Tryck länge på tangenten"<b>"?123"</b>"."</string>
+ <string name="popular_domain_0" msgid="3745279225122472969">".com"</string>
+ <string name="popular_domain_1" msgid="1370572248164278467">".net"</string>
+ <string name="popular_domain_2" msgid="3036812463748402878">".org"</string>
+ <string name="popular_domain_3" msgid="8718639560809452028">".gov"</string>
+ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"Välj inmatningsmetod"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Inmatningsspråk"</string>
+ <string name="language_selection_summary" msgid="187110938289512256">"Dra med fingret på blanksteg om du vill ändra språk"</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Tryck igen för att spara"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"En ordlista är tillgänglig"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"Aktivera synpunkter från användare"</string>
+ <string name="prefs_description_log" msgid="5827825607258246003">"Du kan hjälpa till att förbättra inmatningsmetoden genom att automatiskt skicka användningsstatistik och felrapporter till Google."</string>
+ <string name="prefs_enable_recorrection" msgid="4588408906649533582">"Tryck om du vill korrigera ord"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="1056068922330206170">"Tryck på skrivna ord om du vill korrigera dem"</string>
+ <string name="keyboard_layout" msgid="437433231038683666">"Tangentbordstema"</string>
+ <string name="subtype_mode_keyboard" msgid="2242090416595003881">"tangentbord"</string>
+ <string name="subtype_mode_voice" msgid="4394113125441627771">"röst"</string>
+</resources>
diff --git a/java/res/values-th/donottranslate-keymap.xml b/java/res/values-th/donottranslate-keymap.xml
new file mode 100644
index 0000000..cea9569
--- /dev/null
+++ b/java/res/values-th/donottranslate-keymap.xml
@@ -0,0 +1,211 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2010, The Android Open Source Project
+** Copyright 2011, Darren Salt
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="key_tlde_main">_</string>
+ <string name="key_tlde_shift">%</string>
+ <string name="key_tlde_alt">%`~</string>
+
+ <string name="key_ae01_main">ๅ</string>
+ <string name="key_ae01_shift">+</string>
+ <string name="key_ae01_alt">+1!¡¹½⅓¼⅛</string>
+
+ <string name="key_ae02_main">/</string>
+ <string name="key_ae02_shift">๑</string>
+ <string name="key_ae02_alt">๑2@\"²⅔“”</string>
+
+ <string name="key_ae03_main">-</string>
+ <string name="key_ae03_shift">๒</string>
+ <string name="key_ae03_alt">๒3#£³¾⅜♥♠♦♣</string>
+
+ <string name="key_ae04_main">ภ</string>
+ <string name="key_ae04_shift">๓</string>
+ <string name="key_ae04_alt">๓4$⁴¢£€¥</string>
+
+ <string name="key_ae05_main">ถ</string>
+ <string name="key_ae05_shift">๔</string>
+ <string name="key_ae05_alt">๔5%⅝‰</string>
+
+ <string name="key_ae06_main">ุ</string>
+ <string name="key_ae06_shift">ู</string>
+ <string name="key_ae06_alt">ู6^↑↓←→</string>
+
+ <string name="key_ae07_main">ึ</string>
+ <string name="key_ae07_shift">฿</string>
+ <string name="key_ae07_alt">฿7&amp;⅞♪</string>
+
+ <string name="key_ae08_main">ค</string>
+ <string name="key_ae08_shift">๕</string>
+ <string name="key_ae08_alt">๕8*•★∞†‡</string>
+
+ <string name="key_ae09_main">ต</string>
+ <string name="key_ae09_shift">๖</string>
+ <string name="key_ae09_alt">๖9(√</string>
+
+ <string name="key_ae10_main">จ</string>
+ <string name="key_ae10_shift">๗</string>
+ <string name="key_ae10_alt">๗0)ⁿ°</string>
+
+ <string name="key_ae11_main">ข</string>
+ <string name="key_ae11_shift">๘</string>
+ <string name="key_ae11_alt">๘-_—–</string>
+
+ <string name="key_ae12_main">ช</string>
+ <string name="key_ae12_shift">๙</string>
+ <string name="key_ae12_alt">๙=+≈≠±×÷</string>
+
+
+ <string name="key_ad01_main">ๆ</string>
+ <string name="key_ad01_shift">๐</string>
+ <string name="key_ad01_alt">๐qQ</string>
+
+ <string name="key_ad02_main">ไ</string>
+ <string name="key_ad02_shift">\"</string>
+ <string name="key_ad02_alt">\"wW</string>
+
+ <string name="key_ad03_main">ำ</string>
+ <string name="key_ad03_shift">ฎ</string>
+ <string name="key_ad03_alt">ฎeE</string>
+
+ <string name="key_ad04_main">พ</string>
+ <string name="key_ad04_shift">ฑ</string>
+ <string name="key_ad04_alt">ฑrR</string>
+
+ <string name="key_ad05_main">ะ</string>
+ <string name="key_ad05_shift">ธ</string>
+ <string name="key_ad05_alt">ธtT</string>
+
+ <string name="key_ad06_main">ั</string>
+ <string name="key_ad06_shift">ํ</string>
+ <string name="key_ad06_alt">ํyY</string>
+
+ <string name="key_ad07_main">ี</string>
+ <string name="key_ad07_shift">๊</string>
+ <string name="key_ad07_alt">๊uU</string>
+
+ <string name="key_ad08_main">ร</string>
+ <string name="key_ad08_shift">ณ</string>
+ <string name="key_ad08_alt">ณiI</string>
+
+ <string name="key_ad09_main">น</string>
+ <string name="key_ad09_shift">ฯ</string>
+ <string name="key_ad09_alt">ฯoO</string>
+
+ <string name="key_ad10_main">ย</string>
+ <string name="key_ad10_shift">ญ</string>
+ <string name="key_ad10_alt">ญpP</string>
+
+ <string name="key_ad11_main">บ</string>
+ <string name="key_ad11_shift">ฐ</string>
+ <string name="key_ad11_alt">ฐ[{</string>
+
+ <string name="key_ad12_main">ล</string>
+ <string name="key_ad12_shift">,</string>
+ <string name="key_ad12_alt">,]}</string>
+
+ <string name="key_bksl_main">ฃ</string>
+ <string name="key_bksl_shift">ฅ</string>
+ <string name="key_bksl_alt">ฅ\\|#~</string>
+
+
+ <string name="key_ac01_main">ฟ</string>
+ <string name="key_ac01_shift">ฤ</string>
+ <string name="key_ac01_alt">ฤaA</string>
+
+ <string name="key_ac02_main">ห</string>
+ <string name="key_ac02_shift">ฆ</string>
+ <string name="key_ac02_alt">ฆsS</string>
+
+ <string name="key_ac03_main">ก</string>
+ <string name="key_ac03_shift">ฏ</string>
+ <string name="key_ac03_alt">ฏdD</string>
+
+ <string name="key_ac04_main">ด</string>
+ <string name="key_ac04_shift">โ</string>
+ <string name="key_ac04_alt">โfF</string>
+
+ <string name="key_ac05_main">เ</string>
+ <string name="key_ac05_shift">ฌ</string>
+ <string name="key_ac05_alt">ฌgG</string>
+
+ <string name="key_ac06_main">้</string>
+ <string name="key_ac06_shift">็</string>
+ <string name="key_ac06_alt">็hH</string>
+
+ <string name="key_ac07_main">่</string>
+ <string name="key_ac07_shift">๋</string>
+ <string name="key_ac07_alt">๋jJ</string>
+
+ <string name="key_ac08_main">า</string>
+ <string name="key_ac08_shift">ษ</string>
+ <string name="key_ac08_alt">ษkK</string>
+
+ <string name="key_ac09_main">ส</string>
+ <string name="key_ac09_shift">ศ</string>
+ <string name="key_ac09_alt">ศlL</string>
+
+ <string name="key_ac10_main">ว</string>
+ <string name="key_ac10_shift">ซ</string>
+ <string name="key_ac10_alt">ซ;:</string>
+
+ <string name="key_ac11_main">ง</string>
+ <string name="key_ac11_shift">.</string>
+ <string name="key_ac11_alt">.\'\"‘’</string>
+
+
+ <string name="key_ab01_main">ผ</string>
+ <string name="key_ab01_shift">(</string>
+ <string name="key_ab01_alt">(zZ</string>
+
+ <string name="key_ab02_main">ป</string>
+ <string name="key_ab02_shift">)</string>
+ <string name="key_ab02_alt">)xX</string>
+
+ <string name="key_ab03_main">แ</string>
+ <string name="key_ab03_shift">ฉ</string>
+ <string name="key_ab03_alt">ฉcC</string>
+
+ <string name="key_ab04_main">อ</string>
+ <string name="key_ab04_shift">ฮ</string>
+ <string name="key_ab04_alt">ฮvV</string>
+
+ <string name="key_ab05_main">ิ</string>
+ <string name="key_ab05_shift">ฺ</string>
+ <string name="key_ab05_alt">ฺbB</string>
+
+ <string name="key_ab06_main">ื</string>
+ <string name="key_ab06_shift">์</string>
+ <string name="key_ab06_alt">์nN</string>
+
+ <string name="key_ab07_main">ท</string>
+ <string name="key_ab07_shift">\?</string>
+ <string name="key_ab07_alt">\?mM</string>
+
+ <string name="key_ab08_main">ม</string>
+ <string name="key_ab08_shift">ฒ</string>
+ <string name="key_ab08_alt">ฒ,&lt;≤«‹</string>
+
+ <string name="key_ab09_main">ใ</string>
+ <string name="key_ab09_shift">ฬ</string>
+ <string name="key_ab09_alt">ฬ.&gt;≥»›…</string>
+
+ <string name="key_ab10_main">ฝ</string>
+ <string name="key_ab10_shift">ฦ</string>
+ <string name="key_ab10_alt">ฦ/\?¿</string>
+</resources>
diff --git a/java/res/values-th/strings.xml b/java/res/values-th/strings.xml
new file mode 100644
index 0000000..ba1e380
--- /dev/null
+++ b/java/res/values-th/strings.xml
@@ -0,0 +1,140 @@
+<?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/org.pocketworkstation.pckeyboard"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- <string name="english_ime_name" msgid="7252517407088836577">"แป้นพิมพ์ Android"</string> -->
+ <!-- <string name="english_ime_settings" msgid="6661589557206947774">"การตั้งค่าแป้นพิมพ์ Android"</string> -->
+ <string name="english_ime_input_options" msgid="3909945612939668554">"ตัวเลือกการป้อนข้อมูล"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"สั่นเมื่อกดปุ่ม"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"ส่งเสียงเมื่อกดปุ่ม"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"ป๊อปอัปเมื่อกดแป้น"</string>
+ <string name="hit_correction" msgid="4855351009261318389">"แก้ไขข้อผิดพลาดในการพิมพ์"</string>
+ <string name="hit_correction_summary" msgid="8761701873008070796">"เปิดการใช้งานการแก้ไขข้อผิดพลาดในการป้อนข้อมูล"</string>
+ <string name="hit_correction_land" msgid="2567691684825205448">"ข้อผิดพลาดในการป้อนข้อมูลแนวนอน"</string>
+ <string name="hit_correction_land_summary" msgid="4076803842198368328">"เปิดการใช้งานการแก้ไขข้อผิดพลาดในการป้อนข้อมูล"</string>
+ <string name="auto_correction" msgid="7911639788808958255">"การแนะนำคำ"</string>
+ <string name="auto_correction_summary" msgid="6881047311475758267">"แก้ไขคำก่อนหน้าอัตโนมัติ"</string>
+ <string name="prediction" msgid="466220283138359837">"การแนะนำคำ"</string>
+ <string name="prediction_category" msgid="7027100625580696660">"การตั้งค่าการแนะนำคำ"</string>
+ <string name="prediction_summary" msgid="459788228830873110">"เปิดใช้งานการเติมคำอัตโนมัติขณะพิมพ์"</string>
+ <string name="auto_complete_dialog_title" msgid="2172048590607201920">"เติมคำอัตโนมัติ"</string>
+ <string name="prediction_landscape" msgid="4874601565593216183">"เพิ่มขนาดฟิลด์ข้อความ"</string>
+ <string name="prediction_landscape_summary" msgid="6736551095997839472">"ซ่อนการแนะนำคำในมุมมองแนวนอน"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"ปรับเป็นตัวพิมพ์ใหญ่อัตโนมัติ"</string>
+ <string name="auto_cap_summary" msgid="3260681697600786825">"ใช้ตัวพิมพ์ใหญ่เมื่อขึ้นต้นประโยค"</string>
+ <string name="auto_punctuate" msgid="7276672334264521751">"ใส่เครื่องหมายวรรคตอนอัตโนมัติ"</string>
+ <string name="auto_punctuate_summary" msgid="6589441565817502132"></string>
+ <string name="quick_fixes" msgid="5353213327680897927">"แก้ไขด่วน"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"แก้ไขข้อผิดพลาดในการพิมพ์ที่พบบ่อย"</string>
+ <string name="show_suggestions" msgid="507074425254289133">"แสดงคำแนะนำ"</string>
+ <string name="show_suggestions_summary" msgid="1989672863935759654">"แสดงคำที่แนะนำขณะพิมพ์"</string>
+ <string name="auto_complete" msgid="1103196318775486023">"เติมคำอัตโนมัติ"</string>
+ <string name="auto_complete_summary" msgid="6113149638718274624">"ใช้แป้นเคาะวรรคและเครื่องหมายวรรคตอนเพื่อแทรกคำที่ไฮไลต์โดยอัตโนมัติ"</string>
+ <string name="prefs_settings_key" msgid="4623341240804046498">"แสดงแป้นการตั้งค่า"</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"อัตโนมัติ"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"แสดงตลอดเวลา"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"ซ่อนตลอดเวลา"</string>
+ <!-- no translation found for settings_key_modes:0 (8549888726962891527) -->
+ <!-- no translation found for settings_key_modes:1 (881280041213210923) -->
+ <!-- no translation found for settings_key_modes:2 (7317310620171067848) -->
+ <string name="bigram_suggestion" msgid="1323347224043514969">"คำแนะนำ Bigram"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"ใช้คำก่อนหน้านี้เพื่อปรับปรุงคำแนะนำ"</string>
+ <string-array name="prediction_modes">
+ <item msgid="4870266572388153286">"ไม่มี"</item>
+ <item msgid="1669461741568287396">"พื้นฐาน"</item>
+ <item msgid="4894328801530136615">"ขั้นสูง"</item>
+ </string-array>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : บันทึกแล้ว"</string>
+ <string name="tip_long_press" msgid="6101270866284343344">"กดปุ่มค้างไว้เพื่อดูการออกเสียง (ø, ö, ฯลฯ)"</string>
+ <string name="tip_dismiss" msgid="7585579046862204381">"กดปุ่ม ย้อนกลับ เพื่อปิดแป้นพิมพ์เมื่อใดก็ได้"</string>
+ <string name="tip_access_symbols" msgid="6344098517525531652">"เข้าถึงหมายเลขและสัญลักษณ์"</string>
+ <string name="tip_add_to_dictionary" msgid="1487293888469227817">"กดคำซ้ายสุดค้างไว้เพื่อเพิ่มลงในพจนานุกรม"</string>
+ <string name="touch_to_continue" msgid="7869803257948414531">"แตะคำแนะนำนี้เพื่อทำงานต่อ »"</string>
+ <string name="touch_to_finish" msgid="7990196086480585789">"แตะที่นี่เพื่อปิดคำแนะนำนี้และเริ่มพิมพ์!"</string>
+ <string name="tip_to_open_keyboard" msgid="6821200275486950452"><b>"แป้นพิมพ์จะเปิดขึ้นเมื่อคุณแตะฟิลด์ข้อความ"</b></string>
+ <string name="tip_to_view_accents" msgid="5433158573693308501"><b>"แตะปุ่มค้างไว้เพื่อดูการออกเสียง"\n"(ø, ö, ô, ó และอื่นๆ)"</b></string>
+ <string name="tip_to_open_symbols" msgid="7345139325622444880"><b>"เปลี่ยนเป็นตัวเลขและสัญลักษณ์เมื่อแตะปุ่มนี้"</b></string>
+ <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"กลับไปที่ตัวอักษรโดยการแตะปุ่มนี้อีกครั้ง"</b></string>
+ <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"แตะปุ่มนี้ค้างไว้เพื่อเปลี่ยนการตั้งค่าแป้นพิมพ์ เช่น การเติมคำอัตโนมัติ"</b></string>
+ <string name="tip_to_start_typing" msgid="7213843601369174313"><b>"ลองดูสิ!"</b></string>
+ <string name="label_go_key" msgid="1635148082137219148">"ไป"</string>
+ <string name="label_next_key" msgid="362972844525672568">"ถัดไป"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"เสร็จสิ้น"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"ส่ง"</string>
+ <string name="label_symbol_key" msgid="6175820506864489453">"?123"</string>
+ <string name="label_phone_key" msgid="4275497665515080551">"123"</string>
+ <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string>
+ <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string>
+ <string name="voice_warning_title" msgid="4419354150908395008">"การป้อนข้อมูลด้วยเสียง"</string>
+ <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"ขณะนี้การป้อนข้อมูลด้วยเสียงยังไม่ได้รับการสนับสนุนในภาษาของคุณ แต่ใช้ได้ในภาษาอังกฤษ"</string>
+ <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"การป้อนข้อมูลด้วยเสียงเป็นคุณลักษณะทดลองที่ใช้การจดจำเสียงที่มีการสร้างเครือข่ายไว้ของ Google"</string>
+ <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"หากต้องการปิดการป้อนข้อมูลด้วยเสียง ไปที่การตั้งค่าแป้นพิมพ์"</string>
+ <string name="voice_hint_dialog_message" msgid="6892342981545727994">"หากต้องการใช้การป้อนข้อมูลด้วยเสียง กดปุ่มไมโครโฟนหรือเลื่อนนิ้วผ่านแป้นพิมพ์บนหน้าจอ"</string>
+ <string name="voice_listening" msgid="467518160751321844">"พูดได้เลย"</string>
+ <string name="voice_working" msgid="6666937792815731889">"กำลังทำงาน"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"ข้อผิดพลาด โปรดลองอีกครั้ง"</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"ไม่สามารถเชื่อมต่อได้"</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"ข้อผิดพลาด คำพูดยาวเกินไป"</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"ปัญหาด้านเสียง"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"ข้อผิดพลาดของเซิร์ฟเวอร์"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"ไม่ได้ยินเสียง"</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"ไม่พบรายการที่ตรงกัน"</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"ไม่ได้ติดตั้ง Voice Search"</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"คำแนะนำ:"</b>" กวาดผ่านแป้นพิมพ์เพื่อพูด"</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"คำแนะนำ:"</b>" ครั้งต่อไป ให้ลองเอ่ยถึงเครื่องหมายวรรคตอน เช่น \"มหัพภาค\" \"จุลภาค\" หรือ \"เครื่องหมายคำถาม\""</string>
+ <string name="cancel" msgid="6830980399865683324">"ยกเลิก"</string>
+ <string name="ok" msgid="7898366843681727667">"ตกลง"</string>
+ <string name="voice_input" msgid="2466640768843347841">"การป้อนข้อมูลด้วยเสียง"</string>
+ <string-array name="voice_input_modes">
+ <item msgid="1349082139076086774">"บนแป้นพิมพ์หลัก"</item>
+ <item msgid="8529385602829095903">"บนแป้นพิมพ์สัญลักษณ์"</item>
+ <item msgid="7283103513488381103">"ปิด"</item>
+ </string-array>
+ <string-array name="voice_input_modes_summary">
+ <item msgid="554248625705084903">"ไมโครโฟนบนแป้นพิมพ์หลัก"</item>
+ <item msgid="6907837061058876770">"ไมโครโฟนบนแป้นพิมพ์สัญลักษณ์"</item>
+ <item msgid="3664304608587798036">"การป้อนข้อมูลด้วยเสียงถูกปิดการใช้งาน"</item>
+ </string-array>
+ <string name="auto_submit" msgid="9151008027068358518">"ส่งอัตโนมัติหลังบันทึกเสียง"</string>
+ <string name="auto_submit_summary" msgid="4961875269610384226">"กด Enter อัตโนมัติเมื่อค้นหาหรือไปที่ฟิลด์ถัดไป"</string>
+ <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"เปิดแป้นพิมพ์"\n</b></font><font size="3">\n</font>"แตะฟิลด์ข้อความใดก็ได้"</string>
+ <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"ปิดแป้นพิมพ์"\n</b></font><font size="3">\n</font>"กดปุ่ม ย้อนกลับ"</string>
+ <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"แตะปุ่มค้างไว้เพื่อดูตัวเลือก "\n</b></font><font size="3">\n</font>"เข้าถึงเครื่องหมายวรรคตอนและการออกเสียง"</string>
+ <string name="keyboard_settings" msgid="4585753477617374032"><font size="17"><b>"การตั้งค่าแป้นพิมพ์"\n</b></font><font size="3">\n</font>"แตะปุ่ม "<b>"?123"</b>"ค้างไว้"</string>
+ <string name="popular_domain_0" msgid="3745279225122472969">".com"</string>
+ <string name="popular_domain_1" msgid="1370572248164278467">".net"</string>
+ <string name="popular_domain_2" msgid="3036812463748402878">".org"</string>
+ <string name="popular_domain_3" msgid="8718639560809452028">".gov"</string>
+ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"เลือกวิธีการป้อนข้อมูล"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"ภาษาในการป้อนข้อมูล"</string>
+ <string name="language_selection_summary" msgid="187110938289512256">"เลื่อนนิ้วไปบนแป้นเคาะวรรคเพื่อเปลี่ยนภาษา"</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← แตะอีกครั้งเพื่อบันทึก"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"มีพจนานุกรมให้ใช้งาน"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"เปิดใช้งานการแสดงความคิดเห็นจากผู้ใช้"</string>
+ <string name="prefs_description_log" msgid="5827825607258246003">"ช่วยปรับปรุงตัวแก้ไขวิธีการป้อนข้อมูลนี้โดยการส่งสถิติการใช้งานและรายงานการขัดข้องถึง Google โดยอัตโนมัติ"</string>
+ <string name="prefs_enable_recorrection" msgid="4588408906649533582">"แตะเพื่อแก้ไขคำ"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="1056068922330206170">"แตะคำที่ป้อนไว้เพื่อแก้ไข"</string>
+ <string name="keyboard_layout" msgid="437433231038683666">"ชุดรูปแบบแป้นพิมพ์"</string>
+ <string name="subtype_mode_keyboard" msgid="2242090416595003881">"แป้นพิมพ์"</string>
+ <string name="subtype_mode_voice" msgid="4394113125441627771">"เสียง"</string>
+</resources>
diff --git a/java/res/values-tl/strings.xml b/java/res/values-tl/strings.xml
new file mode 100644
index 0000000..d1f5a71
--- /dev/null
+++ b/java/res/values-tl/strings.xml
@@ -0,0 +1,140 @@
+<?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/org.pocketworkstation.pckeyboard"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- <string name="english_ime_name" msgid="7252517407088836577">"Android keyboard"</string> -->
+ <!-- <string name="english_ime_settings" msgid="6661589557206947774">"Mga setting ng Android keyboard"</string> -->
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Mga pagpipilian sa input"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"Mag-vibrate sa keypress"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"Tunog sa keypress"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"Popup sa keypress"</string>
+ <string name="hit_correction" msgid="4855351009261318389">"Itama ang mga error sa pag-type"</string>
+ <string name="hit_correction_summary" msgid="8761701873008070796">"Paganahin ang pagtatama ng error sa pag-input"</string>
+ <string name="hit_correction_land" msgid="2567691684825205448">"Mga error sa pag-input ng landscape"</string>
+ <string name="hit_correction_land_summary" msgid="4076803842198368328">"Paganahin ang pagtatama ng error sa pag-input"</string>
+ <string name="auto_correction" msgid="7911639788808958255">"Mga suhestiyon ng salita"</string>
+ <string name="auto_correction_summary" msgid="6881047311475758267">"Awtomatikong itama ang nakaraang salita"</string>
+ <string name="prediction" msgid="466220283138359837">"Mga suhestiyon ng salita"</string>
+ <string name="prediction_category" msgid="7027100625580696660">"Mga setting ng suhestiyon ng salita"</string>
+ <string name="prediction_summary" msgid="459788228830873110">"Paganahin ang awtomatikong pagkumpleto habang nagta-type"</string>
+ <string name="auto_complete_dialog_title" msgid="2172048590607201920">"Awtomatikong pagkumpleto"</string>
+ <string name="prediction_landscape" msgid="4874601565593216183">"Taasan ang laki ng field ng teksto"</string>
+ <string name="prediction_landscape_summary" msgid="6736551095997839472">"Itago ang mga suhestiyon ng salita sa lanscape na view"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"Auto-capitalization"</string>
+ <string name="auto_cap_summary" msgid="3260681697600786825">"I-capitalize ang simula ng isang pangungusap"</string>
+ <string name="auto_punctuate" msgid="7276672334264521751">"I-auto-punctuate"</string>
+ <string name="auto_punctuate_summary" msgid="6589441565817502132"></string>
+ <string name="quick_fixes" msgid="5353213327680897927">"Mga mabilisang pagsasaayos"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"Itinatama ang mga karaniwang na-type na mali"</string>
+ <string name="show_suggestions" msgid="507074425254289133">"Ipakita ang mga suhestiyon"</string>
+ <string name="show_suggestions_summary" msgid="1989672863935759654">"Ipakita ang mga iminumungkahing salita habang nagta-type"</string>
+ <string name="auto_complete" msgid="1103196318775486023">"I-auto-complete"</string>
+ <string name="auto_complete_summary" msgid="6113149638718274624">"Awtomatikong ipinapasok ng spacebar at bantas ang naka-highlight na salita"</string>
+ <string name="prefs_settings_key" msgid="4623341240804046498">"Ipakita ang key ng mga setting"</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Awtomatiko"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Palaging ipakita"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"Palaging itago"</string>
+ <!-- no translation found for settings_key_modes:0 (8549888726962891527) -->
+ <!-- no translation found for settings_key_modes:1 (881280041213210923) -->
+ <!-- no translation found for settings_key_modes:2 (7317310620171067848) -->
+ <string name="bigram_suggestion" msgid="1323347224043514969">"Mga Suhestiyon na Bigram"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Gamitin ang nakaraang salita upang pahusayin ang suhestiyon"</string>
+ <string-array name="prediction_modes">
+ <item msgid="4870266572388153286">"Wala"</item>
+ <item msgid="1669461741568287396">"Batayan"</item>
+ <item msgid="4894328801530136615">"Advanced"</item>
+ </string-array>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Na-save"</string>
+ <string name="tip_long_press" msgid="6101270866284343344">"Pinduting nang matagal ang isang key pababa upang makita ang mga accent (ø, ö, atbp.)"</string>
+ <string name="tip_dismiss" msgid="7585579046862204381">"Pindutin ang key na bumalik ↶ upang isara ang keyboard anumang oras"</string>
+ <string name="tip_access_symbols" msgid="6344098517525531652">"I-access ang mga numero at simbolo"</string>
+ <string name="tip_add_to_dictionary" msgid="1487293888469227817">"Pindutin nang matagal ang salita sa kaliwang bahagi upang idagdag ito sa diksyunaryo"</string>
+ <string name="touch_to_continue" msgid="7869803257948414531">"Galawin ang pahiwatig na ito upang magpatuloy »"</string>
+ <string name="touch_to_finish" msgid="7990196086480585789">"Galawin dito upang isara ang pahiwatig na ito at simulan ang pag-type!"</string>
+ <string name="tip_to_open_keyboard" msgid="6821200275486950452"><b>"Nagbubukas ang keyboard anumang oras na galawin mo ang field ng teksto"</b></string>
+ <string name="tip_to_view_accents" msgid="5433158573693308501"><b>"Galawin &amp; pinduting nang matagal ang isang key upang tingnan ang mga accent"\n"(ø, ö, ô, ó, at iba pa)"</b></string>
+ <string name="tip_to_open_symbols" msgid="7345139325622444880"><b>"Lumipat sa mga numero at simbolo sa pamamagitan ng paggalaw sa key na "</b>" na ito"</string>
+ <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"Pumunta muli sa mga titik sa pamamagitan ng muling paggalaw sa key na ito"</b></string>
+ <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"Galawin &amp; pinduting nang matagal ang key na ito upang baguhin ang mga setting ng keyboard, tulad ng awtomatikong pagkumpleto"</b></string>
+ <string name="tip_to_start_typing" msgid="7213843601369174313"><b>"Subukan ito!"</b></string>
+ <string name="label_go_key" msgid="1635148082137219148">"Pumunta"</string>
+ <string name="label_next_key" msgid="362972844525672568">"Susunod"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"Tapos na"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"Ipadala"</string>
+ <string name="label_symbol_key" msgid="6175820506864489453">"?123"</string>
+ <string name="label_phone_key" msgid="4275497665515080551">"123"</string>
+ <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string>
+ <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string>
+ <string name="voice_warning_title" msgid="4419354150908395008">"Pag-input ng boses"</string>
+ <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Hindi kasalukuyang suportado ang pag-input ng boses para sa iyong wika, ngunit gumagana sa Ingles."</string>
+ <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"Ang pag-input ng boses ay isang tampok na pang-eksperimento na gumagamit ng naka-network na pagkilala sa pananalita ng Google."</string>
+ <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"Upang i-off ang pag-input ng boses, pumunta sa mga setting ng keyboard."</string>
+ <string name="voice_hint_dialog_message" msgid="6892342981545727994">"Upang gumamit ng pag-input ng boses, pindutin ang pindutang microphone o i-slide ang iyong daliri sa screen keyboard."</string>
+ <string name="voice_listening" msgid="467518160751321844">"Magsalita ngayon"</string>
+ <string name="voice_working" msgid="6666937792815731889">"Nagtatrabaho"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"Error. Pakisubukang muli."</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"Hindi makakonekta"</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"Error, masyadong maraming pananalita."</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"Problema sa audio"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"Error sa server"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"Walang narinig na pananalita"</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"Walang nakitang mga tugma"</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"Hindi naka-install ang paghahanap ng boses"</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Pahiwatig:"</b>" Mag-swipe sa keyboard upang magsalita"</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Pahiwatig:"</b>" Sa susunod, subukang magsalita ng bantas tulad ng \"tuldok\", \"kuwit\", o \"tandang pananong\"."</string>
+ <string name="cancel" msgid="6830980399865683324">"Kanselahin"</string>
+ <string name="ok" msgid="7898366843681727667">"OK"</string>
+ <string name="voice_input" msgid="2466640768843347841">"Pag-input ng boses"</string>
+ <string-array name="voice_input_modes">
+ <item msgid="1349082139076086774">"I-on ang pangunahing keyboard"</item>
+ <item msgid="8529385602829095903">"Sa mga simbolo ng keyboard"</item>
+ <item msgid="7283103513488381103">"Naka-off"</item>
+ </string-array>
+ <string-array name="voice_input_modes_summary">
+ <item msgid="554248625705084903">"Mic sa pangunahing keyboard"</item>
+ <item msgid="6907837061058876770">"Mic sa keyboard ng mga simbolo"</item>
+ <item msgid="3664304608587798036">"Hindi pinagana ang pag-input ng boses"</item>
+ </string-array>
+ <string name="auto_submit" msgid="9151008027068358518">"Awtomatikong isumite pagkatapos ng boses"</string>
+ <string name="auto_submit_summary" msgid="4961875269610384226">"Awtomatikong pindutin ang enter kapag naghahanap o pupunta sa susunod na field."</string>
+ <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Buksan ang keyboard"\n</b></font><font size="3">\n</font>"Galawin ang kahit anong field ng teksto."</string>
+ <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Isara ang keyboard"\n</b></font><font size="3">\n</font>"Pindutin ang key na Bumalik."</string>
+ <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Galawin &amp; pinduting nang matagal ang isang key para sa mga pagpipilian"\n</b></font><font size="3">\n</font>"I-access ang bantas at mga accent."</string>
+ <string name="keyboard_settings" msgid="4585753477617374032"><font size="17"><b>"Mga setting ng keyboard"\n</b></font><font size="3">\n</font>"Galawin &amp; pindutin nang matagal ang "<b>"?123"</b>" na key."</string>
+ <string name="popular_domain_0" msgid="3745279225122472969">".com"</string>
+ <string name="popular_domain_1" msgid="1370572248164278467">".net"</string>
+ <string name="popular_domain_2" msgid="3036812463748402878">".org"</string>
+ <string name="popular_domain_3" msgid="8718639560809452028">".gov"</string>
+ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"Pumili ng paraan ng pag-input"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Mag-input ng mga wika"</string>
+ <string name="language_selection_summary" msgid="187110938289512256">"I-slide ang daliri sa spacebar upang palitan ang wika"</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Pinduting muli upang i-save"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"Available ang diksyunaryo"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"Paganahin ang feedback ng user"</string>
+ <string name="prefs_description_log" msgid="5827825607258246003">"Tumulong na pahusayin ang editor ng paraan ng pag-input na ito sa pamamagitan ng awtomatikong pagpapadala ng mga istatistika ng paggamit at mga ulat ng crash sa Google."</string>
+ <string name="prefs_enable_recorrection" msgid="4588408906649533582">"Pindutin upang itama ang mga salita"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="1056068922330206170">"Pindutin ang mga ipinasok na salita upang itama ang mga ito"</string>
+ <string name="keyboard_layout" msgid="437433231038683666">"Tema ng Keyboard"</string>
+ <string name="subtype_mode_keyboard" msgid="2242090416595003881">"keyboard"</string>
+ <string name="subtype_mode_voice" msgid="4394113125441627771">"boses"</string>
+</resources>
diff --git a/java/res/values-tr/donottranslate-altchars.xml b/java/res/values-tr/donottranslate-altchars.xml
new file mode 100644
index 0000000..b86ebff
--- /dev/null
+++ b/java/res/values-tr/donottranslate-altchars.xml
@@ -0,0 +1,35 @@
+<?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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="alternates_for_a">âàáãäåæ</string>
+ <string name="alternates_for_c">ç</string>
+ <string name="alternates_for_d"></string>
+ <string name="alternates_for_e">3éèë</string>
+ <string name="alternates_for_f"></string>
+ <string name="alternates_for_g">ğ</string>
+ <string name="alternates_for_i">8ıiîïíì</string>
+ <string name="alternates_for_n"></string>
+ <string name="alternates_for_o">9öøœõóò</string>
+ <string name="alternates_for_q">1@</string>
+ <string name="alternates_for_s">ş§ß</string>
+ <string name="alternates_for_u">7üûúù</string>
+ <string name="alternates_for_y">6ÿý</string>
+ <string name="alternates_for_z"></string>
+</resources>
diff --git a/java/res/values-tr/donottranslate-keymap.xml b/java/res/values-tr/donottranslate-keymap.xml
new file mode 100644
index 0000000..b2e8593
--- /dev/null
+++ b/java/res/values-tr/donottranslate-keymap.xml
@@ -0,0 +1,221 @@
+<?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.
+**
+**
+** 5-row layout for English QWERTY.
+**
+** See http://code.google.com/p/hackerskeyboard/wiki/AddingNewLayouts for
+** more information.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="key_tlde_main">\"</string>
+ <string name="key_tlde_shift">é</string>
+ <string name="key_tlde_alt">&lt;°É</string>
+
+ <string name="key_ae01_main">1</string>
+ <string name="key_ae01_shift">!</string>
+ <string name="key_ae01_alt">&gt;¡</string>
+
+ <string name="key_ae02_main">2</string>
+ <string name="key_ae02_shift">\'</string>
+ <string name="key_ae02_alt">£²</string>
+
+ <string name="key_ae03_main">3</string>
+ <string name="key_ae03_shift">^</string>
+ <string name="key_ae03_alt">#³&#x0302;</string>
+
+ <string name="key_ae04_main">4</string>
+ <string name="key_ae04_shift">+</string>
+ <string name="key_ae04_alt">$¼</string>
+
+ <string name="key_ae05_main">5</string>
+ <string name="key_ae05_shift">%</string>
+ <string name="key_ae05_alt">½⅜</string>
+
+ <string name="key_ae06_main">6</string>
+ <string name="key_ae06_shift">&amp;</string>
+ <string name="key_ae06_alt">¾</string>
+
+ <string name="key_ae07_main">7</string>
+ <string name="key_ae07_shift">/</string>
+ <string name="key_ae07_alt">{</string>
+
+ <string name="key_ae08_main">8</string>
+ <string name="key_ae08_shift">(</string>
+ <string name="key_ae08_alt">[</string>
+
+ <string name="key_ae09_main">9</string>
+ <string name="key_ae09_shift">)</string>
+ <string name="key_ae09_alt">]±</string>
+
+ <string name="key_ae10_main">0</string>
+ <string name="key_ae10_shift">=</string>
+ <string name="key_ae10_alt">}°</string>
+
+ <string name="key_ae11_main">*</string>
+ <string name="key_ae11_shift">\?</string>
+ <string name="key_ae11_alt">\\¿</string>
+
+ <string name="key_ae12_main">-</string>
+ <string name="key_ae12_shift">_</string>
+ <string name="key_ae12_alt">|</string>
+
+
+ <string name="key_ad01_main">q</string>
+ <string name="key_ad01_shift">Q</string>
+ <string name="key_ad01_alt">\@Ω</string>
+
+ <string name="key_ad02_main">w</string>
+ <string name="key_ad02_shift">W</string>
+ <string name="key_ad02_alt"></string>
+
+ <string name="key_ad03_main">e</string>
+ <string name="key_ad03_shift">E</string>
+ <string name="key_ad03_alt">€</string>
+
+ <string name="key_ad04_main">r</string>
+ <string name="key_ad04_shift">R</string>
+ <string name="key_ad04_alt">¶®</string>
+
+ <string name="key_ad05_main">t</string>
+ <string name="key_ad05_shift">T</string>
+ <string name="key_ad05_alt">™</string>
+
+ <string name="key_ad06_main">y</string>
+ <string name="key_ad06_shift">Y</string>
+ <string name="key_ad06_alt">←¥</string>
+
+ <string name="key_ad07_main">u</string>
+ <string name="key_ad07_shift">U</string>
+ <string name="key_ad07_alt">û</string>
+
+ <string name="key_ad08_main">ı</string>
+ <string name="key_ad08_shift">I</string>
+ <string name="key_ad08_alt">î</string>
+
+ <string name="key_ad09_main">o</string>
+ <string name="key_ad09_shift">O</string>
+ <string name="key_ad09_alt">ô</string>
+
+ <string name="key_ad10_main">p</string>
+ <string name="key_ad10_shift">P</string>
+ <string name="key_ad10_alt"></string>
+
+ <string name="key_ad11_main">ğ</string>
+ <string name="key_ad11_shift">Ğ</string>
+ <string name="key_ad11_alt">&#x0308;&#x030A;</string>
+
+ <string name="key_ad12_main">ü</string>
+ <string name="key_ad12_shift">Ü</string>
+ <string name="key_ad12_alt">~&#x0304;</string>
+
+ <string name="key_bksl_main">,</string>
+ <string name="key_bksl_shift">;</string>
+ <string name="key_bksl_alt">`&#x0300;</string>
+
+
+ <string name="key_ac01_main">a</string>
+ <string name="key_ac01_shift">A</string>
+ <string name="key_ac01_alt">â</string>
+
+ <string name="key_ac02_main">s</string>
+ <string name="key_ac02_shift">S</string>
+ <string name="key_ac02_alt">§</string>
+
+ <string name="key_ac03_main">d</string>
+ <string name="key_ac03_shift">D</string>
+ <string name="key_ac03_alt"></string>
+
+ <string name="key_ac04_main">f</string>
+ <string name="key_ac04_shift">F</string>
+ <string name="key_ac04_alt"></string>
+
+ <string name="key_ac05_main">g</string>
+ <string name="key_ac05_shift">G</string>
+ <string name="key_ac05_alt"></string>
+
+ <string name="key_ac06_main">h</string>
+ <string name="key_ac06_shift">H</string>
+ <string name="key_ac06_alt"></string>
+
+ <string name="key_ac07_main">j</string>
+ <string name="key_ac07_shift">J</string>
+ <string name="key_ac07_alt"></string>
+
+ <string name="key_ac08_main">k</string>
+ <string name="key_ac08_shift">K</string>
+ <string name="key_ac08_alt"></string>
+
+ <string name="key_ac09_main">l</string>
+ <string name="key_ac09_shift">L</string>
+ <string name="key_ac09_alt"></string>
+
+ <string name="key_ac10_main">ş</string>
+ <string name="key_ac10_shift">Ş</string>
+ <string name="key_ac10_alt">´&#x0301;</string>
+
+ <string name="key_ac11_main">i</string>
+ <string name="key_ac11_shift">İ</string>
+ <string name="key_ac11_alt">\'&#x030c;</string>
+
+
+ <string name="key_lsgt_main">&lt;</string>
+ <string name="key_lsgt_shift">&gt;</string>
+ <string name="key_lsgt_alt">|</string>
+
+ <string name="key_ab01_main">z</string>
+ <string name="key_ab01_shift">Z</string>
+ <string name="key_ab01_alt">«</string>
+
+ <string name="key_ab02_main">x</string>
+ <string name="key_ab02_shift">X</string>
+ <string name="key_ab02_alt">»</string>
+
+ <string name="key_ab03_main">c</string>
+ <string name="key_ab03_shift">C</string>
+ <string name="key_ab03_alt">¢©</string>
+
+ <string name="key_ab04_main">v</string>
+ <string name="key_ab04_shift">V</string>
+ <string name="key_ab04_alt">“‘</string>
+
+ <string name="key_ab05_main">b</string>
+ <string name="key_ab05_shift">B</string>
+ <string name="key_ab05_alt">”’</string>
+
+ <string name="key_ab06_main">n</string>
+ <string name="key_ab06_shift">N</string>
+ <string name="key_ab06_alt"></string>
+
+ <string name="key_ab07_main">m</string>
+ <string name="key_ab07_shift">M</string>
+ <string name="key_ab07_alt">µº</string>
+
+ <string name="key_ab08_main">ö</string>
+ <string name="key_ab08_shift">Ö</string>
+ <string name="key_ab08_alt">×</string>
+
+ <string name="key_ab09_main">ç</string>
+ <string name="key_ab09_shift">Ç</string>
+ <string name="key_ab09_alt">·÷</string>
+
+ <string name="key_ab10_main">.</string>
+ <string name="key_ab10_shift">:</string>
+ <string name="key_ab10_alt">&#x0307;</string>
+</resources>
diff --git a/java/res/values-tr/strings.xml b/java/res/values-tr/strings.xml
new file mode 100644
index 0000000..825bb90
--- /dev/null
+++ b/java/res/values-tr/strings.xml
@@ -0,0 +1,140 @@
+<?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/org.pocketworkstation.pckeyboard"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- <string name="english_ime_name" msgid="7252517407088836577">"Android klavyesi"</string> -->
+ <!-- <string name="english_ime_settings" msgid="6661589557206947774">"Android klavye ayarları"</string> -->
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Giriş seçenekleri"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"Tuşa basıldığında titret"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"Tuşa basıldığında ses çıkar"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"Tuşa basıldığında pop-up aç"</string>
+ <string name="hit_correction" msgid="4855351009261318389">"Yazım hatalarını düzelt"</string>
+ <string name="hit_correction_summary" msgid="8761701873008070796">"Giriş hatası düzeltmeyi etkinleştir"</string>
+ <string name="hit_correction_land" msgid="2567691684825205448">"Yatay giriş hataları"</string>
+ <string name="hit_correction_land_summary" msgid="4076803842198368328">"Giriş hatası düzeltmeyi etkinleştir"</string>
+ <string name="auto_correction" msgid="7911639788808958255">"Kelime önerileri"</string>
+ <string name="auto_correction_summary" msgid="6881047311475758267">"Önceki kelimeyi otomatik olarak düzelt"</string>
+ <string name="prediction" msgid="466220283138359837">"Kelime önerileri"</string>
+ <string name="prediction_category" msgid="7027100625580696660">"Kelime önerme ayarları"</string>
+ <string name="prediction_summary" msgid="459788228830873110">"Yazarken otomatik tamamlamayı etkinleştir"</string>
+ <string name="auto_complete_dialog_title" msgid="2172048590607201920">"Otomatik tamamlama"</string>
+ <string name="prediction_landscape" msgid="4874601565593216183">"Metin alanı boyutunu artır"</string>
+ <string name="prediction_landscape_summary" msgid="6736551095997839472">"Yatay görünümde kelime önerilerini gizle"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"Otomatik olarak büyük harf yap"</string>
+ <string name="auto_cap_summary" msgid="3260681697600786825">"Cümlenin baş harfini büyük yap"</string>
+ <string name="auto_punctuate" msgid="7276672334264521751">"Otomatik noktalama"</string>
+ <string name="auto_punctuate_summary" msgid="6589441565817502132"></string>
+ <string name="quick_fixes" msgid="5353213327680897927">"Hızlı onarımlar"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"Yaygın olarak yapılan yazım hatalarını düzeltir"</string>
+ <string name="show_suggestions" msgid="507074425254289133">"Önerileri göster"</string>
+ <string name="show_suggestions_summary" msgid="1989672863935759654">"Yazarken önerilen kelimeleri görüntüle"</string>
+ <string name="auto_complete" msgid="1103196318775486023">"Otomatik tamamla"</string>
+ <string name="auto_complete_summary" msgid="6113149638718274624">"Boşluk tuşu ve noktalama vurgulanan kelimeyi otomatik ekler"</string>
+ <string name="prefs_settings_key" msgid="4623341240804046498">"Ayarları göster tuşu"</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Otomatik"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Her zaman göster"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"Her zaman gizle"</string>
+ <!-- no translation found for settings_key_modes:0 (8549888726962891527) -->
+ <!-- no translation found for settings_key_modes:1 (881280041213210923) -->
+ <!-- no translation found for settings_key_modes:2 (7317310620171067848) -->
+ <string name="bigram_suggestion" msgid="1323347224043514969">"Bigram Önerileri"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Öneriyi geliştirmek için önceki kelimeyi kullanın"</string>
+ <string-array name="prediction_modes">
+ <item msgid="4870266572388153286">"Yok"</item>
+ <item msgid="1669461741568287396">"Temel"</item>
+ <item msgid="4894328801530136615">"Gelişmiş"</item>
+ </string-array>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Kaydedildi"</string>
+ <string name="tip_long_press" msgid="6101270866284343344">"Vurguları görmek için bir tuşu basılı tutun (ø, ö, v.b.)"</string>
+ <string name="tip_dismiss" msgid="7585579046862204381">"Klavyeyi herhangi bir anda kapatmak için geri tuşuna ↶ basın"</string>
+ <string name="tip_access_symbols" msgid="6344098517525531652">"Sayılara ve simgelere erişin"</string>
+ <string name="tip_add_to_dictionary" msgid="1487293888469227817">"Sözlüğe eklemek için en soldaki kelimeye basın ve basılı tutun"</string>
+ <string name="touch_to_continue" msgid="7869803257948414531">"Devam etmek için bu ipucuna dokunun »"</string>
+ <string name="touch_to_finish" msgid="7990196086480585789">"Bu ipucunu kapatmak için buraya dokunun ve yazmaya başlayın!"</string>
+ <string name="tip_to_open_keyboard" msgid="6821200275486950452"><b>"Bir metin alanına dokunduğunuzda klavye açılır"</b></string>
+ <string name="tip_to_view_accents" msgid="5433158573693308501"><b>"Vurguları görüntülemek için bir tuşa basın ve basılı tutun"\n"(ø, ö, ô, ó v.b.)"</b></string>
+ <string name="tip_to_open_symbols" msgid="7345139325622444880"><b>"Bu tuşa dokunarak sayılar ve simgeler arasında geçiş yap"</b></string>
+ <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"Bu tuşa tekrar dokunarak harflere geri dönün"</b></string>
+ <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"Otomatik tamamlama gibi klavye ayarlarını değiştirmek için bu tuşa basın ve basılı tutun"</b></string>
+ <string name="tip_to_start_typing" msgid="7213843601369174313"><b>"Deneyin!"</b></string>
+ <string name="label_go_key" msgid="1635148082137219148">"Git"</string>
+ <string name="label_next_key" msgid="362972844525672568">"İleri"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"Bitti"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"Gönder"</string>
+ <string name="label_symbol_key" msgid="6175820506864489453">"?123"</string>
+ <string name="label_phone_key" msgid="4275497665515080551">"123"</string>
+ <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string>
+ <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string>
+ <string name="voice_warning_title" msgid="4419354150908395008">"Ses girişi"</string>
+ <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Ses girişi, şu anda sizin diliniz için desteklenmiyor ama İngilizce dilinde kullanılabilir."</string>
+ <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"Ses girişi, Google\'ın ağ bağlantılı ses tanıma işlevini kullanan deneysel bir özelliktir."</string>
+ <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"Ses girişini kapatmak için klavye ayarlarına gidin."</string>
+ <string name="voice_hint_dialog_message" msgid="6892342981545727994">"Ses girişini kullanmak için mikrofon düğmesine basın veya parmağınızı dokunmatik klavye üzerinde kaydırın."</string>
+ <string name="voice_listening" msgid="467518160751321844">"Şimdi konuşun"</string>
+ <string name="voice_working" msgid="6666937792815731889">"Çalışıyor"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"Hata. Lütfen tekrar deneyin."</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"Bağlanamadı"</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"Hata, çok uzun konuşma."</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"Ses sorunu"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"Sunucu hatası"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"Konuşma duyulmadı"</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"Eşleşme bulunamadı"</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"Sesle arama yüklenmedi"</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"İpucu:"</b>" Konuşmak için parmağınızı klavye üzerinde kaydırın"</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"İpucu:"</b>" Sonraki sefer, \"nokta\", \"virgül\" veya \"soru işareti\" gibi noktalama işaretlerini telaffuz etmeyi deneyin."</string>
+ <string name="cancel" msgid="6830980399865683324">"İptal"</string>
+ <string name="ok" msgid="7898366843681727667">"Tamam"</string>
+ <string name="voice_input" msgid="2466640768843347841">"Ses girişi"</string>
+ <string-array name="voice_input_modes">
+ <item msgid="1349082139076086774">"Ana klavyede"</item>
+ <item msgid="8529385602829095903">"Simge klavyesinde"</item>
+ <item msgid="7283103513488381103">"Kapalı"</item>
+ </string-array>
+ <string-array name="voice_input_modes_summary">
+ <item msgid="554248625705084903">"Ana klavyedeki mikrofon"</item>
+ <item msgid="6907837061058876770">"Simge klavyesindeki mikrofon"</item>
+ <item msgid="3664304608587798036">"Sesle giriş devre dışı bırakıldı"</item>
+ </string-array>
+ <string name="auto_submit" msgid="9151008027068358518">"Sesten sonra otomatik gönder"</string>
+ <string name="auto_submit_summary" msgid="4961875269610384226">"Arama yaparken veya bir sonraki alana giderken enter tuşuna otomatik olarak basın."</string>
+ <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Klavyeyi açın"\n</b></font><font size="3">\n</font>"Herhangi bir metin alanına dokunun."</string>
+ <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Klavyeyi kapatın"\n</b></font><font size="3">\n</font>"Geri tuşuna basın."</string>
+ <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Seçenekler için bir tuşa dokunun ve basılı tutun"\n</b></font><font size="3">\n</font>"Noktalama ve vurgulama işaretlerine erişin."</string>
+ <string name="keyboard_settings" msgid="4585753477617374032"><font size="17"><b>"Klavye ayarları"\n</b></font><font size="3">\n</font><b>"?123"</b>" tuşuna dokunun ve basılı tutun."</string>
+ <string name="popular_domain_0" msgid="3745279225122472969">".com"</string>
+ <string name="popular_domain_1" msgid="1370572248164278467">".net"</string>
+ <string name="popular_domain_2" msgid="3036812463748402878">".org"</string>
+ <string name="popular_domain_3" msgid="8718639560809452028">".gov"</string>
+ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"Giriş yöntemini seç"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Giriş dilleri"</string>
+ <string name="language_selection_summary" msgid="187110938289512256">"Dili değiştirmek için parmağınızı boşluk çubuğu üzerinde kaydırın"</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Kaydetmek için tekrar dokunun"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"Sözlük kullanılabilir"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"Kullanıcı geri bildirimini etkinleştir"</string>
+ <string name="prefs_description_log" msgid="5827825607258246003">"Kullanım istatistiklerini ve kilitlenme raporlarını Google\'a otomatik olarak göndererek bu giriş yöntemi düzenleyicisinin iyileştirilmesine yardımcı olun."</string>
+ <string name="prefs_enable_recorrection" msgid="4588408906649533582">"Kelimeleri düzeltmek için dokunun"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="1056068922330206170">"Düzeltmek için, girilen kelimelere dokunun"</string>
+ <string name="keyboard_layout" msgid="437433231038683666">"Klavye Teması"</string>
+ <string name="subtype_mode_keyboard" msgid="2242090416595003881">"klavye"</string>
+ <string name="subtype_mode_voice" msgid="4394113125441627771">"ses"</string>
+</resources>
diff --git a/java/res/values-uk/donottranslate-keymap.xml b/java/res/values-uk/donottranslate-keymap.xml
new file mode 100644
index 0000000..ba750a0
--- /dev/null
+++ b/java/res/values-uk/donottranslate-keymap.xml
@@ -0,0 +1,224 @@
+<?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.
+**
+**
+** 5-row layout for Ukrainian, contributed by shodan
+** Adapted from the 5-row layout for Russian, contributed by Igor Tonky.
+**
+** See http://code.google.com/p/hackerskeyboard/wiki/AddingNewLayouts
+for
+** more information.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="key_tlde_main">`</string>
+ <string name="key_tlde_shift">~</string>
+ <string name="key_tlde_alt">`~</string>
+
+ <string name="key_ae01_main">1</string>
+ <string name="key_ae01_shift">!</string>
+ <string name="key_ae01_alt">1!¡¹½⅓¼⅛</string>
+
+ <string name="key_ae02_main">2</string>
+ <string name="key_ae02_shift">\"</string>
+ <string name="key_ae02_alt">2\"\'²⅔</string>
+
+ <string name="key_ae03_main">3</string>
+ <string name="key_ae03_shift">№</string>
+ <string name="key_ae03_alt">3№#³¾⅜</string>
+
+ <string name="key_ae04_main">4</string>
+ <string name="key_ae04_shift">;</string>
+ <string name="key_ae04_alt">4;⁴$¢£€¥</string>
+
+ <string name="key_ae05_main">5</string>
+ <string name="key_ae05_shift">%</string>
+ <string name="key_ae05_alt">5%⅝‰</string>
+
+ <string name="key_ae06_main">6</string>
+ <string name="key_ae06_shift">:</string>
+ <string name="key_ae06_alt">6:^↑↓←→</string>
+
+ <string name="key_ae07_main">7</string>
+ <string name="key_ae07_shift">\?</string>
+ <string name="key_ae07_alt">7\?&amp;⅞♪</string>
+
+ <string name="key_ae08_main">8</string>
+ <string name="key_ae08_shift">*</string>
+ <string name="key_ae08_alt">8*•★∞†‡</string>
+
+ <string name="key_ae09_main">9</string>
+ <string name="key_ae09_shift">(</string>
+ <string name="key_ae09_alt">9([{√</string>
+
+ <string name="key_ae10_main">0</string>
+ <string name="key_ae10_shift">)</string>
+ <string name="key_ae10_alt">0)]}ⁿ°</string>
+
+ <string name="key_ae11_main">-</string>
+ <string name="key_ae11_shift">_</string>
+ <string name="key_ae11_alt">-_—–</string>
+
+ <string name="key_ae12_main">=</string>
+ <string name="key_ae12_shift">+</string>
+ <string name="key_ae12_alt">=+≈≠±×÷</string>
+
+
+ <string name="key_ad01_main">й</string>
+ <string name="key_ad01_shift">Й</string>
+ <string name="key_ad01_alt"></string>
+
+ <string name="key_ad02_main">ц</string>
+ <string name="key_ad02_shift">Ц</string>
+ <string name="key_ad02_alt"></string>
+
+ <string name="key_ad03_main">у</string>
+ <string name="key_ad03_shift">У</string>
+ <string name="key_ad03_alt"></string>
+
+ <string name="key_ad04_main">к</string>
+ <string name="key_ad04_shift">К</string>
+ <string name="key_ad04_alt"></string>
+
+ <string name="key_ad05_main">е</string>
+ <string name="key_ad05_shift">Е</string>
+ <string name="key_ad05_alt">ё</string>
+
+ <string name="key_ad06_main">н</string>
+ <string name="key_ad06_shift">Н</string>
+ <string name="key_ad06_alt"></string>
+
+ <string name="key_ad07_main">г</string>
+ <string name="key_ad07_shift">Г</string>
+ <string name="key_ad07_alt"></string>
+
+ <string name="key_ad08_main">ш</string>
+ <string name="key_ad08_shift">Ш</string>
+ <string name="key_ad08_alt"></string>
+
+ <string name="key_ad09_main">щ</string>
+ <string name="key_ad09_shift">Щ</string>
+ <string name="key_ad09_alt"></string>
+
+ <string name="key_ad10_main">з</string>
+ <string name="key_ad10_shift">З</string>
+ <string name="key_ad10_alt"></string>
+
+ <string name="key_ad11_main">х</string>
+ <string name="key_ad11_shift">Х</string>
+ <string name="key_ad11_alt"></string>
+
+ <string name="key_ad12_main">ї</string>
+ <string name="key_ad12_shift">Ї</string>
+ <string name="key_ad12_alt">ъ</string>
+
+ <string name="key_bksl_main">\\</string>
+ <string name="key_bksl_shift">/</string>
+ <string name="key_bksl_alt">\\/</string>
+
+
+ <string name="key_ac01_main">ф</string>
+ <string name="key_ac01_shift">Ф</string>
+ <string name="key_ac01_alt"></string>
+
+ <string name="key_ac02_main">і</string>
+ <string name="key_ac02_shift">І</string>
+ <string name="key_ac02_alt">ы</string>
+
+ <string name="key_ac03_main">в</string>
+ <string name="key_ac03_shift">В</string>
+ <string name="key_ac03_alt"></string>
+
+ <string name="key_ac04_main">а</string>
+ <string name="key_ac04_shift">А</string>
+ <string name="key_ac04_alt"></string>
+
+ <string name="key_ac05_main">п</string>
+ <string name="key_ac05_shift">П</string>
+ <string name="key_ac05_alt"></string>
+
+ <string name="key_ac06_main">р</string>
+ <string name="key_ac06_shift">Р</string>
+ <string name="key_ac06_alt"></string>
+
+ <string name="key_ac07_main">о</string>
+ <string name="key_ac07_shift">О</string>
+ <string name="key_ac07_alt"></string>
+
+ <string name="key_ac08_main">л</string>
+ <string name="key_ac08_shift">Л</string>
+ <string name="key_ac08_alt"></string>
+
+ <string name="key_ac09_main">д</string>
+ <string name="key_ac09_shift">Д</string>
+ <string name="key_ac09_alt"></string>
+
+ <string name="key_ac10_main">ж</string>
+ <string name="key_ac10_shift">Ж</string>
+ <string name="key_ac10_alt"></string>
+
+ <string name="key_ac11_main">є</string>
+ <string name="key_ac11_shift">Є</string>
+ <string name="key_ac11_alt">э</string>
+
+
+ <string name="key_lsgt_main">&lt;</string>
+ <string name="key_lsgt_shift">&gt;</string>
+ <string name="key_lsgt_alt">&lt;&gt;|\@</string>
+
+ <string name="key_ab01_main">я</string>
+ <string name="key_ab01_shift">Я</string>
+ <string name="key_ab01_alt"></string>
+
+ <string name="key_ab02_main">ч</string>
+ <string name="key_ab02_shift">Ч</string>
+ <string name="key_ab02_alt"></string>
+
+ <string name="key_ab03_main">с</string>
+ <string name="key_ab03_shift">С</string>
+ <string name="key_ab03_alt"></string>
+
+ <string name="key_ab04_main">м</string>
+ <string name="key_ab04_shift">М</string>
+ <string name="key_ab04_alt"></string>
+
+ <string name="key_ab05_main">и</string>
+ <string name="key_ab05_shift">И</string>
+ <string name="key_ab05_alt"></string>
+
+ <string name="key_ab06_main">т</string>
+ <string name="key_ab06_shift">Т</string>
+ <string name="key_ab06_alt"></string>
+
+ <string name="key_ab07_main">ь</string>
+ <string name="key_ab07_shift">Ь</string>
+ <string name="key_ab07_alt"></string>
+
+ <string name="key_ab08_main">б</string>
+ <string name="key_ab08_shift">Б</string>
+ <string name="key_ab08_alt"></string>
+
+ <string name="key_ab09_main">ю</string>
+ <string name="key_ab09_shift">Ю</string>
+ <string name="key_ab09_alt"></string>
+
+ <string name="key_ab10_main">.</string>
+ <string name="key_ab10_shift">,</string>
+ <string name="key_ab10_alt">.,</string>
+</resources>
diff --git a/java/res/values-uk/strings.xml b/java/res/values-uk/strings.xml
new file mode 100644
index 0000000..5487016
--- /dev/null
+++ b/java/res/values-uk/strings.xml
@@ -0,0 +1,140 @@
+<?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/org.pocketworkstation.pckeyboard"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- <string name="english_ime_name" msgid="7252517407088836577">"Клавіатура Android"</string> -->
+ <!-- <string name="english_ime_settings" msgid="6661589557206947774">"Налашт-ня клавіат. Android"</string> -->
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Парам. введення"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"Вібр при натиску клав."</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"Звук при натиску клав."</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"Сплив. при нат.клав."</string>
+ <string name="hit_correction" msgid="4855351009261318389">"Виправ. помилки вводу"</string>
+ <string name="hit_correction_summary" msgid="8761701873008070796">"Увімкн. виправл. помилок вводу"</string>
+ <string name="hit_correction_land" msgid="2567691684825205448">"Помилки альбомного вводу"</string>
+ <string name="hit_correction_land_summary" msgid="4076803842198368328">"Увімкн. виправл. помилок вводу"</string>
+ <string name="auto_correction" msgid="7911639788808958255">"Пропозиції слів"</string>
+ <string name="auto_correction_summary" msgid="6881047311475758267">"Автоматично виправляти попереднє слово"</string>
+ <string name="prediction" msgid="466220283138359837">"Пропозиції слів"</string>
+ <string name="prediction_category" msgid="7027100625580696660">"Налашт-ня пропозицій слів"</string>
+ <string name="prediction_summary" msgid="459788228830873110">"Увімкн. автозаповнення при вводі"</string>
+ <string name="auto_complete_dialog_title" msgid="2172048590607201920">"Автозаповнення"</string>
+ <string name="prediction_landscape" msgid="4874601565593216183">"Збільш. розмір текст. поля"</string>
+ <string name="prediction_landscape_summary" msgid="6736551095997839472">"Сховати пропозиції слів в альбом. режимі"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"Авто викор. вел. літер"</string>
+ <string name="auto_cap_summary" msgid="3260681697600786825">"Поч. писати речення з великої літери"</string>
+ <string name="auto_punctuate" msgid="7276672334264521751">"Авто пунктуація"</string>
+ <string name="auto_punctuate_summary" msgid="6589441565817502132"></string>
+ <string name="quick_fixes" msgid="5353213327680897927">"Шв. виправлення"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"Виправляє поширені помилки"</string>
+ <string name="show_suggestions" msgid="507074425254289133">"Показати пропозиції"</string>
+ <string name="show_suggestions_summary" msgid="1989672863935759654">"Відображати при вводі пропоновані слова"</string>
+ <string name="auto_complete" msgid="1103196318775486023">"Автозаповнення"</string>
+ <string name="auto_complete_summary" msgid="6113149638718274624">"Пробіл і пунктуація автоматично вставляє виділене слово"</string>
+ <string name="prefs_settings_key" msgid="4623341240804046498">"Показ. клав. налашт."</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Автоматично"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Завжди показ."</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"Завжди ховати"</string>
+ <!-- no translation found for settings_key_modes:0 (8549888726962891527) -->
+ <!-- no translation found for settings_key_modes:1 (881280041213210923) -->
+ <!-- no translation found for settings_key_modes:2 (7317310620171067848) -->
+ <string name="bigram_suggestion" msgid="1323347224043514969">"Двобуквені пропозиції"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Викор. попер. слово для покращ. пропозиції"</string>
+ <string-array name="prediction_modes">
+ <item msgid="4870266572388153286">"Немає"</item>
+ <item msgid="1669461741568287396">"Базовий"</item>
+ <item msgid="4894328801530136615">"Розшир."</item>
+ </string-array>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : збережено"</string>
+ <string name="tip_long_press" msgid="6101270866284343344">"Утр. клав. натис., щоб див. нагол. (ø, ö, тощо)"</string>
+ <string name="tip_dismiss" msgid="7585579046862204381">"Натисн. клавішу назад ↶, щоб будь-коли закрити клавіат."</string>
+ <string name="tip_access_symbols" msgid="6344098517525531652">"Доступ до цифр і символів"</string>
+ <string name="tip_add_to_dictionary" msgid="1487293888469227817">"Натисн. і утримуйте ліве крайнє слово, щоб додати його до словн."</string>
+ <string name="touch_to_continue" msgid="7869803257948414531">"Натис. цю підказку для продовж.»"</string>
+ <string name="touch_to_finish" msgid="7990196086480585789">"Натисн. тут, щоб закрити цю підказку і почати ввод."</string>
+ <string name="tip_to_open_keyboard" msgid="6821200275486950452"><b>"Клавіатура відривається при торканні текстового поля"</b></string>
+ <string name="tip_to_view_accents" msgid="5433158573693308501"><b>"Натис. і утрим. клавішу для перегл. наголосів"\n"(ø, ö, ô, ó тощо)"</b></string>
+ <string name="tip_to_open_symbols" msgid="7345139325622444880"><b>"Перемк. до цифр і символів, натиснувши цю кнопку "</b></string>
+ <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"Поверніться до літер, знову натиснувши цю клавішу"</b></string>
+ <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"Натис. і утрим. клавішу, щоб змін. налашт-ння клавіат., такі як автозапов."</b></string>
+ <string name="tip_to_start_typing" msgid="7213843601369174313"><b>"Спробуйте!"</b></string>
+ <string name="label_go_key" msgid="1635148082137219148">"Іти"</string>
+ <string name="label_next_key" msgid="362972844525672568">"Далі"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"Готово"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"Надісл."</string>
+ <string name="label_symbol_key" msgid="6175820506864489453">"?123"</string>
+ <string name="label_phone_key" msgid="4275497665515080551">"123"</string>
+ <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string>
+ <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string>
+ <string name="voice_warning_title" msgid="4419354150908395008">"Голос. ввід"</string>
+ <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Голос. ввід наразі не підтрим. для вашої мови, але можна користуватися англійською."</string>
+ <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"Голос. ввід є експеремент. ф-цією, яка викор. мережеве розпізнавання голосу Google."</string>
+ <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"Щоб вимкн. голос ввід, йдіть до налашт-нь клавіатури."</string>
+ <string name="voice_hint_dialog_message" msgid="6892342981545727994">"Щоб викор. голос. ввід, натисніть кнопку мікрофона або пересуньте палець на екранній клавіатурі."</string>
+ <string name="voice_listening" msgid="467518160751321844">"Диктуйте"</string>
+ <string name="voice_working" msgid="6666937792815731889">"Працює"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"Помилка. Спробуйте ще раз."</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"Неможл. під\'єднатися"</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"Помилка. Забагато продикт."</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"Проблема з аудіо"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"Помилка сервера"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"Не чути диктув."</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"Збігів не знайдено"</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"Голос. пошук не встановлено"</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Підк:"</b>" горт. на клавіат., щоб продикт."</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Підказка:"</b>" наступного разу продикт. знаки пункт. такі як \"крапка\", \"кома\" чи \"знак пит\"."</string>
+ <string name="cancel" msgid="6830980399865683324">"Скасувати"</string>
+ <string name="ok" msgid="7898366843681727667">"OK"</string>
+ <string name="voice_input" msgid="2466640768843347841">"Голос. ввід"</string>
+ <string-array name="voice_input_modes">
+ <item msgid="1349082139076086774">"На осн. клавіатурі"</item>
+ <item msgid="8529385602829095903">"Символьна клавіатура"</item>
+ <item msgid="7283103513488381103">"Вимк."</item>
+ </string-array>
+ <string-array name="voice_input_modes_summary">
+ <item msgid="554248625705084903">"Miкр. на осн. клавіатурі"</item>
+ <item msgid="6907837061058876770">"Miкр. на символ. клавіатурі"</item>
+ <item msgid="3664304608587798036">"Голос. ввід вимкнуто"</item>
+ </string-array>
+ <string name="auto_submit" msgid="9151008027068358518">"Авто подав. після гол. пош."</string>
+ <string name="auto_submit_summary" msgid="4961875269610384226">"Автомат. натиск. enter під час пошуку або переходу до наступного поля."</string>
+ <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Відкр. клавіатуру"\n</b></font><font size="3">\n</font>"Натисн. якесь текст. поле."</string>
+ <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Закрити клавіатуру"\n</b></font><font size="3">\n</font>"Натисн. клавішу Назад."</string>
+ <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Натис.і утрим. клавішк для отрим. парам."\n</b></font><font size="3">\n</font>"Доступ до пункт. та наголос."</string>
+ <string name="keyboard_settings" msgid="4585753477617374032"><font size="17"><b>"Налашт-ння клавіатури"\n</b></font><font size="3">\n</font>"Натисн. і утрим. клавішу "<b>"?123"</b></string>
+ <string name="popular_domain_0" msgid="3745279225122472969">".com"</string>
+ <string name="popular_domain_1" msgid="1370572248164278467">".net"</string>
+ <string name="popular_domain_2" msgid="3036812463748402878">".org"</string>
+ <string name="popular_domain_3" msgid="8718639560809452028">".gov"</string>
+ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"Вибрати метод введення"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Мови вводу"</string>
+ <string name="language_selection_summary" msgid="187110938289512256">"Переміст. палець на пробіл, щоб змін. мову"</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Торкн. ще, щоб збер."</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"Словник доступний"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"Увімк. відгуки корист."</string>
+ <string name="prefs_description_log" msgid="5827825607258246003">"Допоможіть покращ. редактор методу введ., автомат. надсилаючи в Google статистику використ. та звіти про збої."</string>
+ <string name="prefs_enable_recorrection" msgid="4588408906649533582">"Торкн., щоб виправ. слова"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="1056068922330206170">"Торкн. введених слів, щоб виправити їх"</string>
+ <string name="keyboard_layout" msgid="437433231038683666">"Тема клавіатури"</string>
+ <string name="subtype_mode_keyboard" msgid="2242090416595003881">"клавіатура"</string>
+ <string name="subtype_mode_voice" msgid="4394113125441627771">"голос."</string>
+</resources>
diff --git a/java/res/values-vi/strings.xml b/java/res/values-vi/strings.xml
new file mode 100644
index 0000000..26c8238
--- /dev/null
+++ b/java/res/values-vi/strings.xml
@@ -0,0 +1,140 @@
+<?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/org.pocketworkstation.pckeyboard"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- <string name="english_ime_name" msgid="7252517407088836577">"Bàn phím Android"</string> -->
+ <!-- <string name="english_ime_settings" msgid="6661589557206947774">"Cài đặt bàn phím Android"</string> -->
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Tùy chọn nhập"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"Rung khi nhấn phím"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"Âm thanh khi nhấn phím"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"Cửa sổ bật lên khi nhấn phím"</string>
+ <string name="hit_correction" msgid="4855351009261318389">"Sửa lỗi đánh máy"</string>
+ <string name="hit_correction_summary" msgid="8761701873008070796">"Bật sửa lỗi nhập"</string>
+ <string name="hit_correction_land" msgid="2567691684825205448">"Lỗi nhập theo khổ ngang"</string>
+ <string name="hit_correction_land_summary" msgid="4076803842198368328">"Bật sửa lỗi nhập"</string>
+ <string name="auto_correction" msgid="7911639788808958255">"Đề xuất từ"</string>
+ <string name="auto_correction_summary" msgid="6881047311475758267">"Tự động sửa từ trước đó"</string>
+ <string name="prediction" msgid="466220283138359837">"Đề xuất từ"</string>
+ <string name="prediction_category" msgid="7027100625580696660">"Cài đặt đề xuất từ"</string>
+ <string name="prediction_summary" msgid="459788228830873110">"Bật tự động hoàn tất khi nhập"</string>
+ <string name="auto_complete_dialog_title" msgid="2172048590607201920">"Tự động hoàn tất"</string>
+ <string name="prediction_landscape" msgid="4874601565593216183">"Tăng kích cỡ trường văn bản"</string>
+ <string name="prediction_landscape_summary" msgid="6736551095997839472">"Ẩn đề xuất từ trong chế độ xem ngang"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"Tự động viết hoa"</string>
+ <string name="auto_cap_summary" msgid="3260681697600786825">"Viết hoa chữ cái đầu câu"</string>
+ <string name="auto_punctuate" msgid="7276672334264521751">"Tự động chấm câu"</string>
+ <string name="auto_punctuate_summary" msgid="6589441565817502132"></string>
+ <string name="quick_fixes" msgid="5353213327680897927">"Sửa nhanh"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"Sửa lỗi nhập thông thường"</string>
+ <string name="show_suggestions" msgid="507074425254289133">"Hiển thị đề xuất"</string>
+ <string name="show_suggestions_summary" msgid="1989672863935759654">"Hiển thị từ được đề xuất khi nhập"</string>
+ <string name="auto_complete" msgid="1103196318775486023">"Tự động hoàn tất"</string>
+ <string name="auto_complete_summary" msgid="6113149638718274624">"Dấu cách và dấu câu tự động chèn vào từ được đánh dấu"</string>
+ <string name="prefs_settings_key" msgid="4623341240804046498">"Hiển thị phím cài đặt"</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Tự động"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Luôn hiển thị"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"Luôn ẩn"</string>
+ <!-- no translation found for settings_key_modes:0 (8549888726962891527) -->
+ <!-- no translation found for settings_key_modes:1 (881280041213210923) -->
+ <!-- no translation found for settings_key_modes:2 (7317310620171067848) -->
+ <string name="bigram_suggestion" msgid="1323347224043514969">"Đề xuất Bigram"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Sử dụng từ trước đó để cải tiến đề xuất"</string>
+ <string-array name="prediction_modes">
+ <item msgid="4870266572388153286">"Không"</item>
+ <item msgid="1669461741568287396">"Cơ bản"</item>
+ <item msgid="4894328801530136615">"Nâng cao"</item>
+ </string-array>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Đã lưu"</string>
+ <string name="tip_long_press" msgid="6101270866284343344">"Giữ phím xuống để xem dấu trọng âm (ø, ö, v.v...)"</string>
+ <string name="tip_dismiss" msgid="7585579046862204381">"Nhấn phím quay lại ↶ để đóng bàn phím bất kỳ lúc nào"</string>
+ <string name="tip_access_symbols" msgid="6344098517525531652">"Truy cập các số và ký hiệu"</string>
+ <string name="tip_add_to_dictionary" msgid="1487293888469227817">"Nhấn và giữ từ ngoài cùng bên trái để thêm từ đó vào từ điển"</string>
+ <string name="touch_to_continue" msgid="7869803257948414531">"Chạm vào gợi ý này để tiếp tục »"</string>
+ <string name="touch_to_finish" msgid="7990196086480585789">"Chạm vào đây để đóng gợi ý này và bắt đầu nhập"</string>
+ <string name="tip_to_open_keyboard" msgid="6821200275486950452"><b>"Bàn phím mở ra bất cứ khi nào bạn chạm vào trường văn bản"</b></string>
+ <string name="tip_to_view_accents" msgid="5433158573693308501"><b>"Chạm &amp; giữ phím để xem dấu trọng âm"\n"(ø, ö, ô, ó, v.v...)"</b></string>
+ <string name="tip_to_open_symbols" msgid="7345139325622444880"><b>"Chuyển sang số và ký hiệu bằng cách chạm vào phím này"</b></string>
+ <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"Quay lại các chữ cái bằng cách chạm vào phím này lần nữa"</b></string>
+ <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"Chạm &amp; giữ phím này để thay đổi cài đặt bàn phím, như tự động hoàn tất"</b></string>
+ <string name="tip_to_start_typing" msgid="7213843601369174313"><b>"Hãy dùng thử!"</b></string>
+ <string name="label_go_key" msgid="1635148082137219148">"Đến"</string>
+ <string name="label_next_key" msgid="362972844525672568">"Tiếp theo"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"Xong"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"Gửi"</string>
+ <string name="label_symbol_key" msgid="6175820506864489453">"?123"</string>
+ <string name="label_phone_key" msgid="4275497665515080551">"123"</string>
+ <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string>
+ <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string>
+ <string name="voice_warning_title" msgid="4419354150908395008">"Nhập liệu bằng giọng nói"</string>
+ <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Nhập liệu bằng giọng nói hiện không được hỗ trợ cho ngôn ngữ của bạn nhưng hoạt động với ngôn ngữ tiếng Anh."</string>
+ <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"Nhập liệu bằng giọng nói là tính năng thử nghiệm sử dụng nhận dạng tiếng nói được kết nối mạng của Google."</string>
+ <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"Để tắt nhập liệu bằng giọng nói, đi tới cài đặt bàn phím."</string>
+ <string name="voice_hint_dialog_message" msgid="6892342981545727994">"Để sử dụng nhập liệu bằng giọng nói, hãy nhấn nút micrô hoặc trượt ngón tay trên bàn phím ảo."</string>
+ <string name="voice_listening" msgid="467518160751321844">"Xin mời nói"</string>
+ <string name="voice_working" msgid="6666937792815731889">"Đang hoạt động"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"Lỗi. Vui lòng thử lại."</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"Không thể kết nối"</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"Lỗi, quá nhiều câu thoại."</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"Sự cố âm thanh"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"Lỗi máy chủ"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"Không nghe thấy tiếng nói nào"</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"Không tìm thấy kết quả phù hợp"</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"Tìm kiếm bằng giọng nói chưa được cài đặt"</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Gợi ý:"</b>" Trượt qua bàn phím để nói"</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Gợi ý:"</b>" Lần tới, thử nói dấu câu như \"dấu chấm\", \"dấu phẩy\" hoặc \"dấu hỏi\"."</string>
+ <string name="cancel" msgid="6830980399865683324">"Huỷ"</string>
+ <string name="ok" msgid="7898366843681727667">"OK"</string>
+ <string name="voice_input" msgid="2466640768843347841">"Nhập liệu bằng giọng nói"</string>
+ <string-array name="voice_input_modes">
+ <item msgid="1349082139076086774">"Trên bàn phím chính"</item>
+ <item msgid="8529385602829095903">"Trên bàn phím có biểu tượng"</item>
+ <item msgid="7283103513488381103">"Tắt"</item>
+ </string-array>
+ <string-array name="voice_input_modes_summary">
+ <item msgid="554248625705084903">"Micrô trên bàn phím chính"</item>
+ <item msgid="6907837061058876770">"Micrô trên bàn phím có biểu tượng"</item>
+ <item msgid="3664304608587798036">"Nhập liệu bằng giọng nói đã bị vô hiệu hoá"</item>
+ </string-array>
+ <string name="auto_submit" msgid="9151008027068358518">"Tự động gửi sau thoại"</string>
+ <string name="auto_submit_summary" msgid="4961875269610384226">"Tự đông nhấn enter khi tìm kiếm hoặc đi tới trường tiếp theo."</string>
+ <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Mở bàn phím"\n</b></font><font size="3">\n</font>"Chạm vào bất kỳ trường văn bản nào."</string>
+ <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Đóng bàn phím"\n</b></font><font size="3">\n</font>"Nhấn phím Quay lại."</string>
+ <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Chạm &amp; giữ phím cho các tuỳ chọn"\n</b></font><font size="3">\n</font>"Truy cập dấu câu và dấu trọng âm."</string>
+ <string name="keyboard_settings" msgid="4585753477617374032"><font size="17"><b>"Cài đặt bàn phím"\n</b></font><font size="3">\n</font>"Chạm &amp; giữ phím "<b>"?123"</b>"."</string>
+ <string name="popular_domain_0" msgid="3745279225122472969">".com"</string>
+ <string name="popular_domain_1" msgid="1370572248164278467">".net"</string>
+ <string name="popular_domain_2" msgid="3036812463748402878">".org"</string>
+ <string name="popular_domain_3" msgid="8718639560809452028">".gov"</string>
+ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"Chọn phương thức nhập"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Ngôn ngữ nhập"</string>
+ <string name="language_selection_summary" msgid="187110938289512256">"Trượt ngón tay trên phím cách để thay đổi ngôn ngữ"</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Chạm lại để lưu"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"Có sẵn từ điển"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"Bật phản hồi của người dùng"</string>
+ <string name="prefs_description_log" msgid="5827825607258246003">"Giúp nâng cao trình chỉnh sửa phương thức nhập này bằng cách tự động gửi thống kê sử dụng và báo cáo sự cố cho Google."</string>
+ <string name="prefs_enable_recorrection" msgid="4588408906649533582">"Chạm để sửa từ"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="1056068922330206170">"Chạm các từ đã nhập để sửa"</string>
+ <string name="keyboard_layout" msgid="437433231038683666">"Chủ đề bàn phím"</string>
+ <string name="subtype_mode_keyboard" msgid="2242090416595003881">"bàn phím"</string>
+ <string name="subtype_mode_voice" msgid="4394113125441627771">"thoại"</string>
+</resources>
diff --git a/java/res/values-xlarge-land/dimens.xml b/java/res/values-xlarge-land/dimens.xml
new file mode 100644
index 0000000..8bb4faa
--- /dev/null
+++ b/java/res/values-xlarge-land/dimens.xml
@@ -0,0 +1,29 @@
+<?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>
+ <!-- key_height + key_bottom_gap = popup_key_height -->
+ <dimen name="key_height">0.5in</dimen>
+ <dimen name="key_horizontal_pad">0.04in</dimen>
+ <dimen name="key_vertical_pad">0.04in</dimen>
+ <dimen name="popup_key_height">0.5in</dimen>
+ <dimen name="key_text_size">0.26in</dimen>
+ <dimen name="key_label_text_size">0.2in</dimen>
+</resources>
diff --git a/java/res/values-xlarge/bools.xml b/java/res/values-xlarge/bools.xml
new file mode 100644
index 0000000..dfb53d6
--- /dev/null
+++ b/java/res/values-xlarge/bools.xml
@@ -0,0 +1,23 @@
+<?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>
+ <!-- Whether or not Popup on key press is enabled by default -->
+ <bool name="default_popup_preview">false</bool>
+</resources>
diff --git a/java/res/values-xlarge/dimens.xml b/java/res/values-xlarge/dimens.xml
new file mode 100644
index 0000000..f4284bb
--- /dev/null
+++ b/java/res/values-xlarge/dimens.xml
@@ -0,0 +1,31 @@
+<?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>
+ <!-- key_height + key_bottom_gap = popup_key_height -->
+ <dimen name="key_height">0.5in</dimen>
+ <dimen name="key_horizontal_pad">0.04in</dimen>
+ <dimen name="key_vertical_pad">0.04in</dimen>
+ <dimen name="key_vertical_pad_compact">0.04in</dimen>
+ <dimen name="popup_key_height">0.5in</dimen>
+ <dimen name="keyboard_bottom_padding">0.06in</dimen>
+ <dimen name="key_text_size">0.20in</dimen>
+ <dimen name="key_label_text_size">0.17in</dimen>
+</resources>
diff --git a/java/res/values-xlarge/size-defaults.xml b/java/res/values-xlarge/size-defaults.xml
new file mode 100644
index 0000000..3a4c86b
--- /dev/null
+++ b/java/res/values-xlarge/size-defaults.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, Klaus Weidner
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT 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>
+ <string name="default_height_portrait">25%</string>
+ <string name="default_height_landscape">45%</string>
+ <string name="default_keyboard_mode_portrait">2</string>
+</resources> \ No newline at end of file
diff --git a/java/res/values-zh-rCN/donottranslate-altchars.xml b/java/res/values-zh-rCN/donottranslate-altchars.xml
new file mode 100644
index 0000000..c165b11
--- /dev/null
+++ b/java/res/values-zh-rCN/donottranslate-altchars.xml
@@ -0,0 +1,30 @@
+<?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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="alternates_for_a">àáâãäåæ</string>
+ <string name="alternates_for_e">èéêë</string>
+ <string name="alternates_for_i">ìíîï</string>
+ <string name="alternates_for_o">òóôõöœø</string>
+ <string name="alternates_for_u">ùúûü</string>
+ <string name="alternates_for_s">§ß</string>
+ <string name="alternates_for_n">ñ</string>
+ <string name="alternates_for_c">ç</string>
+ <string name="alternates_for_y">ýÿ</string>
+</resources>
diff --git a/java/res/values-zh-rCN/strings.xml b/java/res/values-zh-rCN/strings.xml
new file mode 100644
index 0000000..416a293
--- /dev/null
+++ b/java/res/values-zh-rCN/strings.xml
@@ -0,0 +1,140 @@
+<?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/org.pocketworkstation.pckeyboard"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- <string name="english_ime_name" msgid="7252517407088836577">"Android 键盘"</string> -->
+ <!-- <string name="english_ime_settings" msgid="6661589557206947774">"Android 键盘设置"</string> -->
+ <string name="english_ime_input_options" msgid="3909945612939668554">"输入选项"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"按键时振动"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"按键时播放音效"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"按键时显示弹出窗口"</string>
+ <string name="hit_correction" msgid="4855351009261318389">"纠正输入错误"</string>
+ <string name="hit_correction_summary" msgid="8761701873008070796">"启用输入错误纠正功能"</string>
+ <string name="hit_correction_land" msgid="2567691684825205448">"横向输入错误"</string>
+ <string name="hit_correction_land_summary" msgid="4076803842198368328">"启用输入错误纠正功能"</string>
+ <string name="auto_correction" msgid="7911639788808958255">"字词建议"</string>
+ <string name="auto_correction_summary" msgid="6881047311475758267">"自动纠正前面的字词"</string>
+ <string name="prediction" msgid="466220283138359837">"字词建议"</string>
+ <string name="prediction_category" msgid="7027100625580696660">"字词建议设置"</string>
+ <string name="prediction_summary" msgid="459788228830873110">"输入时启用自动填写功能"</string>
+ <string name="auto_complete_dialog_title" msgid="2172048590607201920">"自动完成"</string>
+ <string name="prediction_landscape" msgid="4874601565593216183">"扩大文字字段"</string>
+ <string name="prediction_landscape_summary" msgid="6736551095997839472">"在横向视图中隐藏字词建议"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"自动大写"</string>
+ <string name="auto_cap_summary" msgid="3260681697600786825">"句首字母大写"</string>
+ <string name="auto_punctuate" msgid="7276672334264521751">"自动加标点"</string>
+ <string name="auto_punctuate_summary" msgid="6589441565817502132"></string>
+ <string name="quick_fixes" msgid="5353213327680897927">"快速纠正"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"纠正常见的输入错误"</string>
+ <string name="show_suggestions" msgid="507074425254289133">"显示建议"</string>
+ <string name="show_suggestions_summary" msgid="1989672863935759654">"输入时启用联想提示"</string>
+ <string name="auto_complete" msgid="1103196318775486023">"自动填写"</string>
+ <string name="auto_complete_summary" msgid="6113149638718274624">"按空格键和标点符号时自动插入突出显示的字词"</string>
+ <string name="prefs_settings_key" msgid="4623341240804046498">"显示设置键"</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"自动"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"始终显示"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"始终隐藏"</string>
+ <!-- no translation found for settings_key_modes:0 (8549888726962891527) -->
+ <!-- no translation found for settings_key_modes:1 (881280041213210923) -->
+ <!-- no translation found for settings_key_modes:2 (7317310620171067848) -->
+ <string name="bigram_suggestion" msgid="1323347224043514969">"双连词建议"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"使用以前的字词改进建议"</string>
+ <string-array name="prediction_modes">
+ <item msgid="4870266572388153286">"无"</item>
+ <item msgid="1669461741568287396">"基本模式"</item>
+ <item msgid="4894328801530136615">"高级"</item>
+ </string-array>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>:已保存"</string>
+ <string name="tip_long_press" msgid="6101270866284343344">"按住某个键可看到重音符号(例如 ø、ö 等)"</string>
+ <string name="tip_dismiss" msgid="7585579046862204381">"随时可以通过按后退键 ↶ 关闭键盘"</string>
+ <string name="tip_access_symbols" msgid="6344098517525531652">"访问数字和符号"</string>
+ <string name="tip_add_to_dictionary" msgid="1487293888469227817">"长按最左侧的字可将其添加到词典中"</string>
+ <string name="touch_to_continue" msgid="7869803257948414531">"轻触此提示继续 »"</string>
+ <string name="touch_to_finish" msgid="7990196086480585789">"轻触此处可关闭该提示,然后便可开始输入内容!"</string>
+ <string name="tip_to_open_keyboard" msgid="6821200275486950452"><b>"您可以随时通过触摸文字字段打开键盘"</b></string>
+ <string name="tip_to_view_accents" msgid="5433158573693308501"><b>"轻触并按住某个键可以查看重音符号"\n"(ø、ö、ô、ó 等)"</b></string>
+ <string name="tip_to_open_symbols" msgid="7345139325622444880"><b>"轻触该键即可切换到数字和符号键盘"</b></string>
+ <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"再次轻触该键即可返回字母键盘"</b></string>
+ <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"触摸并按住该键可更改键盘设置,例如自动完成"</b></string>
+ <string name="tip_to_start_typing" msgid="7213843601369174313"><b>"试试吧!"</b></string>
+ <string name="label_go_key" msgid="1635148082137219148">"开始"</string>
+ <string name="label_next_key" msgid="362972844525672568">"下一步"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"完成"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"发送"</string>
+ <string name="label_symbol_key" msgid="6175820506864489453">"?123"</string>
+ <string name="label_phone_key" msgid="4275497665515080551">"123"</string>
+ <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string>
+ <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string>
+ <string name="voice_warning_title" msgid="4419354150908395008">"语音输入"</string>
+ <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"语音输入功能当前还不支持您的语言,您只能输入英语语音。"</string>
+ <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"语音输入是一项试验性的功能,它采用了 Google 的网络语音识别功能。"</string>
+ <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"要关闭语音输入功能,请转至键盘设置。"</string>
+ <string name="voice_hint_dialog_message" msgid="6892342981545727994">"要使用语音输入,请按麦克风按钮或者在屏幕键盘上滑动手指。"</string>
+ <string name="voice_listening" msgid="467518160751321844">"请开始说话"</string>
+ <string name="voice_working" msgid="6666937792815731889">"正在处理"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"出错,请重试。"</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"无法连接"</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"出错,语音过长。"</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"音频问题"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"服务器出错"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"未听到语音"</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"未找到匹配项"</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"未安装语音搜索"</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"提示:"</b>"在键盘上滑动手指可激活语音功能"</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"提示:"</b>"稍后,请尝试使用语音输入标点符号,如“句号”、“逗号”或“问号”。"</string>
+ <string name="cancel" msgid="6830980399865683324">"取消"</string>
+ <string name="ok" msgid="7898366843681727667">"确定"</string>
+ <string name="voice_input" msgid="2466640768843347841">"语音输入"</string>
+ <string-array name="voice_input_modes">
+ <item msgid="1349082139076086774">"主键盘上"</item>
+ <item msgid="8529385602829095903">"符号键盘上"</item>
+ <item msgid="7283103513488381103">"关"</item>
+ </string-array>
+ <string-array name="voice_input_modes_summary">
+ <item msgid="554248625705084903">"主键盘上的麦克风"</item>
+ <item msgid="6907837061058876770">"符号键盘上的麦克风"</item>
+ <item msgid="3664304608587798036">"已停用语音输入"</item>
+ </string-array>
+ <string name="auto_submit" msgid="9151008027068358518">"语音结束后自动提交"</string>
+ <string name="auto_submit_summary" msgid="4961875269610384226">"搜索或转到下一字段时自动按 Enter。"</string>
+ <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"打开键盘"\n</b></font><font size="3">\n</font>"触摸任意文本字段。"</string>
+ <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"关闭键盘"\n</b></font><font size="3">\n</font>"按“返回”键。"</string>
+ <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"触摸并按住选项键"\n</b></font><font size="3">\n</font>"进入标点/重音符号界面。"</string>
+ <string name="keyboard_settings" msgid="4585753477617374032"><font size="17"><b>"键盘设置"\n</b></font><font size="3">\n</font>"触摸并按住 "<b>"?123"</b>" 键。"</string>
+ <string name="popular_domain_0" msgid="3745279225122472969">".com"</string>
+ <string name="popular_domain_1" msgid="1370572248164278467">".net"</string>
+ <string name="popular_domain_2" msgid="3036812463748402878">".org"</string>
+ <string name="popular_domain_3" msgid="8718639560809452028">".gov"</string>
+ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"选择输入法"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"输入语言"</string>
+ <string name="language_selection_summary" msgid="187110938289512256">"在空格键上滑动手指可更改语言"</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← 再次触摸即可保存"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"提供字典"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"启用用户反馈"</string>
+ <string name="prefs_description_log" msgid="5827825607258246003">"自动向 Google 发送使用情况统计信息和崩溃报告,帮助改进该输入法编辑器。"</string>
+ <string name="prefs_enable_recorrection" msgid="4588408906649533582">"触摸以更正字词"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="1056068922330206170">"触摸所输入字词以进行更正"</string>
+ <string name="keyboard_layout" msgid="437433231038683666">"键盘主题"</string>
+ <string name="subtype_mode_keyboard" msgid="2242090416595003881">"键盘"</string>
+ <string name="subtype_mode_voice" msgid="4394113125441627771">"语音"</string>
+</resources>
diff --git a/java/res/values-zh-rTW/donottranslate-altchars.xml b/java/res/values-zh-rTW/donottranslate-altchars.xml
new file mode 100644
index 0000000..c165b11
--- /dev/null
+++ b/java/res/values-zh-rTW/donottranslate-altchars.xml
@@ -0,0 +1,30 @@
+<?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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="alternates_for_a">àáâãäåæ</string>
+ <string name="alternates_for_e">èéêë</string>
+ <string name="alternates_for_i">ìíîï</string>
+ <string name="alternates_for_o">òóôõöœø</string>
+ <string name="alternates_for_u">ùúûü</string>
+ <string name="alternates_for_s">§ß</string>
+ <string name="alternates_for_n">ñ</string>
+ <string name="alternates_for_c">ç</string>
+ <string name="alternates_for_y">ýÿ</string>
+</resources>
diff --git a/java/res/values-zh-rTW/strings.xml b/java/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000..646173f
--- /dev/null
+++ b/java/res/values-zh-rTW/strings.xml
@@ -0,0 +1,140 @@
+<?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/org.pocketworkstation.pckeyboard"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- <string name="english_ime_name" msgid="7252517407088836577">"Android 鍵盤"</string> -->
+ <!-- <string name="english_ime_settings" msgid="6661589557206947774">"Android 鍵盤設定"</string> -->
+ <string name="english_ime_input_options" msgid="3909945612939668554">"輸入選項"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"按鍵時震動"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"按鍵時播放音效"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"按鍵時顯示彈出式視窗"</string>
+ <string name="hit_correction" msgid="4855351009261318389">"修正輸入錯誤"</string>
+ <string name="hit_correction_summary" msgid="8761701873008070796">"啟用輸入錯誤修正功能"</string>
+ <string name="hit_correction_land" msgid="2567691684825205448">"橫向輸入錯誤"</string>
+ <string name="hit_correction_land_summary" msgid="4076803842198368328">"啟用輸入錯誤修正功能"</string>
+ <string name="auto_correction" msgid="7911639788808958255">"字詞建議"</string>
+ <string name="auto_correction_summary" msgid="6881047311475758267">"自動修正前一個字詞"</string>
+ <string name="prediction" msgid="466220283138359837">"字詞建議"</string>
+ <string name="prediction_category" msgid="7027100625580696660">"字詞建議設定"</string>
+ <string name="prediction_summary" msgid="459788228830873110">"輸入時啟用自動完成"</string>
+ <string name="auto_complete_dialog_title" msgid="2172048590607201920">"自動完成"</string>
+ <string name="prediction_landscape" msgid="4874601565593216183">"放大文字欄位大小"</string>
+ <string name="prediction_landscape_summary" msgid="6736551095997839472">"在橫向檢視模式中隱藏字詞建議"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"自動大寫"</string>
+ <string name="auto_cap_summary" msgid="3260681697600786825">"句首字母大寫"</string>
+ <string name="auto_punctuate" msgid="7276672334264521751">"自動標點"</string>
+ <string name="auto_punctuate_summary" msgid="6589441565817502132"></string>
+ <string name="quick_fixes" msgid="5353213327680897927">"快速修正"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"修正一般打字錯誤"</string>
+ <string name="show_suggestions" msgid="507074425254289133">"顯示建議"</string>
+ <string name="show_suggestions_summary" msgid="1989672863935759654">"打字時顯示建議字詞"</string>
+ <string name="auto_complete" msgid="1103196318775486023">"自動完成"</string>
+ <string name="auto_complete_summary" msgid="6113149638718274624">"在反白顯示的字詞處自動插入空白鍵和標點符號鍵盤"</string>
+ <string name="prefs_settings_key" msgid="4623341240804046498">"顯示設定金鑰"</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"自動"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"永遠顯示"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"永遠隱藏"</string>
+ <!-- no translation found for settings_key_modes:0 (8549888726962891527) -->
+ <!-- no translation found for settings_key_modes:1 (881280041213210923) -->
+ <!-- no translation found for settings_key_modes:2 (7317310620171067848) -->
+ <string name="bigram_suggestion" msgid="1323347224043514969">"雙連詞建議"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"根據前一個字詞自動找出更適合的建議"</string>
+ <string-array name="prediction_modes">
+ <item msgid="4870266572388153286">"無"</item>
+ <item msgid="1669461741568287396">"基本模式"</item>
+ <item msgid="4894328801530136615">"進階模式"</item>
+ </string-array>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>:已儲存"</string>
+ <string name="tip_long_press" msgid="6101270866284343344">"按住按鍵可查看重音符號 (ø、ö 等)"</string>
+ <string name="tip_dismiss" msgid="7585579046862204381">"隨時可以透過按後退鍵 ↶ 關閉鍵盤"</string>
+ <string name="tip_access_symbols" msgid="6344098517525531652">"使用數字和符號"</string>
+ <string name="tip_add_to_dictionary" msgid="1487293888469227817">"按住最左邊的字詞,將其新增到字典中"</string>
+ <string name="touch_to_continue" msgid="7869803257948414531">"輕觸此提示繼續 »"</string>
+ <string name="touch_to_finish" msgid="7990196086480585789">"輕觸此處以關閉提示,並開始打字!"</string>
+ <string name="tip_to_open_keyboard" msgid="6821200275486950452"><b>"輕觸文字欄位時即會開啟鍵盤"</b></string>
+ <string name="tip_to_view_accents" msgid="5433158573693308501"><b>"輕觸並按住某個鍵即可查看聲調"\n"(ø、ö、ô、ó 等)"</b></string>
+ <string name="tip_to_open_symbols" msgid="7345139325622444880"><b>"輕觸此鍵即可切換到數字和符號鍵盤"</b></string>
+ <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"再次輕觸此鍵即可返回到字母鍵盤"</b></string>
+ <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"輕觸並按住此鍵即可變更鍵盤設定,例如自動完成"</b></string>
+ <string name="tip_to_start_typing" msgid="7213843601369174313"><b>"試試看!"</b></string>
+ <string name="label_go_key" msgid="1635148082137219148">"開始"</string>
+ <string name="label_next_key" msgid="362972844525672568">"繼續"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"完成"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"傳送"</string>
+ <string name="label_symbol_key" msgid="6175820506864489453">"?123"</string>
+ <string name="label_phone_key" msgid="4275497665515080551">"123"</string>
+ <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string>
+ <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string>
+ <string name="voice_warning_title" msgid="4419354150908395008">"語音輸入"</string>
+ <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"語音輸入目前不支援您的語言,但是可以辨識英文。"</string>
+ <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"語音輸入這項實驗功能運用了 Google 的網路語音辨識系統。"</string>
+ <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"請前往鍵盤設定來關閉語音輸入。"</string>
+ <string name="voice_hint_dialog_message" msgid="6892342981545727994">"如要使用語音輸入,按下 [麥克風] 按鈕,或將手指滑過螢幕小鍵盤即可。"</string>
+ <string name="voice_listening" msgid="467518160751321844">"請說話"</string>
+ <string name="voice_working" msgid="6666937792815731889">"辨識中"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"發生錯誤,請再試一次。"</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"無法連線"</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"錯誤:語音內容過長。"</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"音訊問題"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"伺服器錯誤"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"沒有聽到任何聲音"</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"找不到相符的項目"</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"未安裝語音搜尋"</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"提示:"</b>"滑過鍵盤即可說話"</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"提示:"</b>"下次可嘗試說出標點符號,例如「句號」、「逗號」或「問號」。"</string>
+ <string name="cancel" msgid="6830980399865683324">"取消"</string>
+ <string name="ok" msgid="7898366843681727667">"確定"</string>
+ <string name="voice_input" msgid="2466640768843347841">"語音輸入"</string>
+ <string-array name="voice_input_modes">
+ <item msgid="1349082139076086774">"於主鍵盤"</item>
+ <item msgid="8529385602829095903">"符號鍵盤上"</item>
+ <item msgid="7283103513488381103">"關閉"</item>
+ </string-array>
+ <string-array name="voice_input_modes_summary">
+ <item msgid="554248625705084903">"主鍵盤上的麥克風"</item>
+ <item msgid="6907837061058876770">"符號鍵盤上的麥克風"</item>
+ <item msgid="3664304608587798036">"已停用語音輸入"</item>
+ </string-array>
+ <string name="auto_submit" msgid="9151008027068358518">"說話後自動提交"</string>
+ <string name="auto_submit_summary" msgid="4961875269610384226">"搜尋或前往下一個欄位時自動按下輸入。"</string>
+ <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"開啟鍵盤"\n</b></font><font size="3">\n</font>"輕觸任何文字欄位。"</string>
+ <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"關閉鍵盤"\n</b></font><font size="3">\n</font>"按下 Back 鍵。"</string>
+ <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>\n"輕觸並按住按鍵開啟選項"</b></font><font size="3">\n</font>"輸入標點與輕重音。"</string>
+ <string name="keyboard_settings" msgid="4585753477617374032"><font size="17"><b>"鍵盤設定"\n</b></font><font size="3">\n</font>"輕觸並按住 "<b>"?123"</b>" 鍵。"</string>
+ <string name="popular_domain_0" msgid="3745279225122472969">".com"</string>
+ <string name="popular_domain_1" msgid="1370572248164278467">".net"</string>
+ <string name="popular_domain_2" msgid="3036812463748402878">".org"</string>
+ <string name="popular_domain_3" msgid="8718639560809452028">".gov"</string>
+ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"選取輸入法"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"輸入語言"</string>
+ <string name="language_selection_summary" msgid="187110938289512256">"以手指在空白鍵上滑動可變更語言"</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← 再次輕觸即可儲存"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"可使用字典"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"啟用使用者意見回饋"</string>
+ <string name="prefs_description_log" msgid="5827825607258246003">"自動將使用統計資料和當機報告傳送給 Google,協助改善這個輸入法編輯器。"</string>
+ <string name="prefs_enable_recorrection" msgid="4588408906649533582">"輕觸此處可修正字詞"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="1056068922330206170">"輕觸輸入的字詞即可加以修正"</string>
+ <string name="keyboard_layout" msgid="437433231038683666">"鍵盤主題"</string>
+ <string name="subtype_mode_keyboard" msgid="2242090416595003881">"鍵盤"</string>
+ <string name="subtype_mode_voice" msgid="4394113125441627771">"語音"</string>
+</resources>
diff --git a/java/res/values/attrs-keyboard.xml b/java/res/values/attrs-keyboard.xml
new file mode 100644
index 0000000..ce3e0bc
--- /dev/null
+++ b/java/res/values/attrs-keyboard.xml
@@ -0,0 +1,90 @@
+<?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>
+
+ <declare-styleable name="Keyboard">
+ <!-- Default width of a key, in pixels or percentage of display width. -->
+ <attr name="keyWidth" format="dimension|fraction" />
+ <!-- Default height of a key, in pixels or percentage of display width. -->
+ <attr name="keyHeight" format="dimension|fraction" />
+ <!-- Default horizontal gap between keys. Added to key size. -->
+ <attr name="horizontalGap" format="dimension|fraction" />
+ <!-- Default vertical gap between rows of keys. Added to key size. -->
+ <attr name="verticalGap" format="dimension|fraction" />
+ <!-- Horizontal padding around key. Included in key size. -->
+ <attr name="horizontalPad" format="dimension|fraction" />
+ <!-- Vertical padding around key. Included in key size. -->
+ <attr name="verticalPad" format="dimension|fraction" />
+ <!-- Layout info for key sizing purposes, giving rows/column counts of the base grid -->
+ <attr name="layoutRows" format="integer" />
+ <attr name="layoutColumns" format="integer" />
+ </declare-styleable>
+
+ <declare-styleable name="Keyboard_Row">
+ <!-- Row edge flags. -->
+ <attr name="rowEdgeFlags">
+ <!-- Row is anchored to the top of the keyboard. -->
+ <flag name="top" value="4" />
+ <!-- Row is anchored to the bottom of the keyboard. -->
+ <flag name="bottom" value="8" />
+ </attr>
+ <!-- Mode of the keyboard. If the mode doesn't match the
+ requested keyboard mode, the row will be skipped. -->
+ <attr name="keyboardMode" format="reference" />
+ <attr name="extension" format="boolean" />
+ </declare-styleable>
+
+ <declare-styleable name="Keyboard_Key">
+ <!-- The unicode value or comma-separated values that this key outputs. -->
+ <attr name="codes" format="integer|string" />
+ <!-- The XML keyboard layout of any popup keyboard. -->
+ <attr name="popupKeyboard" format="reference" />
+ <!-- The characters to display in the popup keyboard. -->
+ <attr name="popupCharacters" format="string" />
+ <!-- Key edge flags. -->
+ <attr name="keyEdgeFlags">
+ <!-- Key is anchored to the left of the keyboard. -->
+ <flag name="left" value="1" />
+ <!-- Key is anchored to the right of the keyboard. -->
+ <flag name="right" value="2" />
+ </attr>
+ <!-- Whether this is a modifier key such as Alt or Shift. -->
+ <attr name="isModifier" format="boolean" />
+ <!-- Whether this is a toggle key. -->
+ <attr name="isSticky" format="boolean" />
+ <!-- Whether this is a cursor key (modifies styling). -->
+ <attr name="isCursor" format="boolean" />
+ <!-- Whether long-pressing on this key will make it repeat. -->
+ <attr name="isRepeatable" format="boolean" />
+ <!-- The icon to show in the popup preview. -->
+ <attr name="iconPreview" format="reference" />
+ <!-- The string of characters to output when this key is pressed. -->
+ <attr name="keyOutputText" format="string" />
+ <!-- The label to display on the key. -->
+ <attr name="keyLabel" format="string" />
+ <!-- The label to display on the shifted key. -->
+ <attr name="shiftLabel" format="string" />
+ <!-- The label to display on the caps-shifted key. -->
+ <attr name="capsLabel" format="string" />
+ <!-- The icon to display on the key instead of the label. -->
+ <attr name="keyIcon" format="reference" />
+ <!-- Mode of the keyboard. If the mode doesn't match the
+ requested keyboard mode, the key will be skipped. -->
+ <attr name="keyboardMode" />
+ </declare-styleable>
+
+</resources>
diff --git a/java/res/values/attrs-seekbarpref.xml b/java/res/values/attrs-seekbarpref.xml
new file mode 100644
index 0000000..09dce69
--- /dev/null
+++ b/java/res/values/attrs-seekbarpref.xml
@@ -0,0 +1,26 @@
+<?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>
+ <declare-styleable name="SeekBarPreference">
+ <attr name="minValue" format="float" />
+ <attr name="maxValue" format="float" />
+ <attr name="asPercent" format="boolean" />
+ <attr name="step" format="float" />
+ <attr name="logScale" format="boolean" />
+ <attr name="displayFormat" format="string" />
+ </declare-styleable>
+</resources>
diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml
new file mode 100644
index 0000000..9ddaa7b
--- /dev/null
+++ b/java/res/values/attrs.xml
@@ -0,0 +1,84 @@
+<?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>
+
+ <declare-styleable name="LatinKeyboardBaseView">
+ <!-- Default KeyboardView style. -->
+ <attr name="keyboardViewStyle" format="reference" />
+
+ <!-- Image for the key. This image needs to be a StateListDrawable, with the following
+ possible states: normal, pressed, checkable, checkable+pressed, checkable+checked,
+ checkable+checked+pressed. -->
+ <attr name="keyBackground" format="reference" />
+
+ <!-- Size of the text for character keys. -->
+ <attr name="keyTextSize" format="dimension" />
+
+ <!-- Size of the text for custom keys with some text and no icon. -->
+ <attr name="labelTextSize" format="dimension" />
+
+ <!-- Color to use for the label in a key. -->
+ <attr name="keyTextColor" format="color" />
+
+ <!-- Color to use for key hint labels. -->
+ <attr name="keyHintColor" format="color" />
+
+ <!-- Color to use for cursor key labels. -->
+ <attr name="keyCursorColor" format="color" />
+
+ <!-- Do symbols need to be recolored? -->
+ <attr name="recolorSymbols" format="boolean" />
+
+ <!-- Transparent key background? 0=fully transparent, 255=opaque (fast) -->
+ <attr name="backgroundAlpha" format="integer" />
+
+ <!-- Layout resource for key press feedback.-->
+ <attr name="keyPreviewLayout" format="reference" />
+
+ <!-- Vertical offset of the key press feedback from the key. -->
+ <attr name="keyPreviewOffset" format="dimension" />
+
+ <!-- Height of the key press feedback popup. -->
+ <attr name="keyPreviewHeight" format="dimension" />
+
+ <!-- Hysteresis distance for key debouncing -->
+ <attr name="keyHysteresisDistance" format="dimension" />
+
+ <!-- Amount to offset the touch Y coordinate by, for bias correction. -->
+ <attr name="verticalCorrection" format="dimension" />
+
+ <!-- Layout resource for popup keyboards. -->
+ <attr name="popupLayout" format="reference" />
+
+ <attr name="shadowColor" format="color" />
+ <attr name="shadowRadius" format="float" />
+ <attr name="backgroundDimAmount" format="float" />
+
+ <attr name="keyTextStyle">
+ <flag name="normal" value="0" />
+ <flag name="bold" value="1" />
+ <flag name="italic" value="2" />
+ </attr>
+
+ <attr name="symbolColorScheme">
+ <flag name="white" value="0" />
+ <flag name="black" value="1" />
+ </attr>
+
+ </declare-styleable>
+
+</resources>
diff --git a/java/res/values/bools.xml b/java/res/values/bools.xml
new file mode 100644
index 0000000..c53a90a
--- /dev/null
+++ b/java/res/values/bools.xml
@@ -0,0 +1,45 @@
+<?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>
+ <!-- Whether or not auto-correction should be enabled by default -->
+ <bool name="enable_autocorrect">false</bool>
+ <bool name="default_auto_cap">true</bool>
+ <bool name="default_quick_fixes">true</bool>
+ <bool name="default_suggestions">true</bool>
+ <bool name="default_suggestions_in_landscape">false</bool>
+ <!-- Whether this input method should be used as the default for a locale. Override it
+ for latin languages. -->
+ <bool name="im_is_default">false</bool>
+ <!-- Whether or not voice input is enabled by default. -->
+ <bool name="voice_input_default">true</bool>
+ <bool name="config_swipeDisambiguation">true</bool>
+ <!-- Whether or not Popup on key press is enabled by default -->
+ <bool name="default_popup_preview">true</bool>
+ <bool name="default_recorrection_enabled">false</bool>
+ <bool name="config_long_press_comma_for_settings_enabled">true</bool>
+ <bool name="default_connectbot_tab_hack">true</bool>
+ <bool name="default_fullscreen_override">false</bool>
+ <bool name="default_force_keyboard_on">false</bool>
+ <bool name="default_keyboard_notification">false</bool>
+ <bool name="default_add_shift_to_popup">false</bool>
+ <bool name="default_compact_mode_enabled">false</bool>
+ <bool name="default_caps_lock">true</bool>
+ <bool name="default_shift_lock_modifiers">true</bool>
+</resources>
diff --git a/java/res/values/colors.xml b/java/res/values/colors.xml
new file mode 100644
index 0000000..4bc59f2
--- /dev/null
+++ b/java/res/values/colors.xml
@@ -0,0 +1,36 @@
+<?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.
+*/
+// <color name="candidate_recommended">#FF33B5E5</color>
+// <color name="candidate_other">#FF33B5E5</color>
+// android:color/holo_blue_light=#FF33B5E5
+-->
+<resources>
+ <color name="candidate_normal">#FFFFFFFF</color>
+ <color name="candidate_recommended">#FFFCAE00</color>
+ <color name="candidate_other">#FFFCAE00</color>
+ <color name="latinkeyboard_transparent">#00000000</color>
+ <color name="latinkeyboard_bar_language_shadow_white">#80000000</color>
+ <color name="latinkeyboard_bar_language_shadow_black">#80FFFFFF</color>
+ <color name="latinkeyboard_dim_color_white">#FFDDDDDD</color>
+ <color name="latinkeyboard_dim_color_black">#FF222222</color>
+ <color name="latinkeyboard_extension_background">#A0000000</color>
+ <color name="latinkeyboard_feedback_language_text">#FFFFFFFF</color>
+ <color name="latinkeyboard_key_color_white">#FFFFFFFF</color>
+ <color name="latinkeyboard_key_color_black">#FF000000</color>
+</resources>
diff --git a/java/res/values/config.xml b/java/res/values/config.xml
new file mode 100644
index 0000000..6ee4511
--- /dev/null
+++ b/java/res/values/config.xml
@@ -0,0 +1,34 @@
+<?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.
+*/
+-->
+
+<resources>
+ <integer name="config_delay_before_preview">0</integer>
+ <integer name="config_delay_before_space_preview">200</integer>
+ <integer name="config_delay_after_preview">10</integer>
+ <integer name="config_preview_fadein_anim_time">0</integer>
+ <integer name="config_preview_fadeout_anim_time">70</integer>
+ <integer name="config_mini_keyboard_fadein_anim_time">0</integer>
+ <integer name="config_mini_keyboard_fadeout_anim_time">100</integer>
+ <integer name="config_delay_before_key_repeat_start">400</integer>
+ <integer name="config_key_repeat_interval">50</integer>
+ <string name="default_long_press_duration">400 ms</string>
+ <integer name="config_multi_tap_key_timeout">800</integer>
+ <string name="default_render_mode">1</string>
+</resources>
diff --git a/java/res/values/dimens.xml b/java/res/values/dimens.xml
new file mode 100644
index 0000000..40ba388
--- /dev/null
+++ b/java/res/values/dimens.xml
@@ -0,0 +1,54 @@
+<?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>
+ <!-- key_height + key_bottom_gap = popup_key_height -->
+ <dimen name="key_height">0.290in</dimen>
+ <dimen name="key_bottom_gap">0.000in</dimen>
+ <dimen name="key_horizontal_pad">0.000in</dimen>
+ <dimen name="key_vertical_pad">0.025in</dimen>
+ <dimen name="key_vertical_pad_compact">0.000in</dimen>
+ <dimen name="popup_key_height">0.325in</dimen>
+ <dimen name="keyboard_bottom_padding">0.06in</dimen>
+ <dimen name="bubble_pointer_offset">22dip</dimen>
+ <dimen name="candidate_strip_height">42dip</dimen>
+ <dimen name="candidate_strip_fading_edge_length">63dip</dimen>
+ <dimen name="spacebar_vertical_correction">4dip</dimen>
+ <!-- If the screen height in landscape is larger than the below value, then the keyboard
+ will not go into extract (fullscreen) mode. -->
+ <dimen name="max_height_for_fullscreen">2.5in</dimen>
+ <!-- Key size for 5-row mode. Scaled up by 1.25 for 4-row mode. -->
+ <dimen name="key_text_size">0.11in</dimen>
+ <dimen name="key_label_text_size">0.083in</dimen>
+ <dimen name="key_preview_text_size_large">40sp</dimen>
+ <dimen name="key_preview_offset">0.000in</dimen>
+ <!-- key_preview_text_size_large x 2 -->
+ <dimen name="key_preview_height">80sp</dimen>
+ <!-- Amount of allowance for selecting keys in a mini popup keyboard by sliding finger. -->
+ <!-- popup_key_height x 1.7 -->
+ <dimen name="mini_keyboard_slide_allowance">0.553in</dimen>
+ <!-- popup_key_height x 1.0 -->
+ <dimen name="mini_keyboard_vertical_correction">-0.325in</dimen>
+ <dimen name="key_hysteresis_distance">0.05in</dimen>
+ <!-- We use "inch", not "dip" because this value tries dealing with physical distance related
+ to user's finger. -->
+ <dimen name="keyboard_vertical_correction">-0.05in</dimen>
+ <dimen name="candidate_min_touchable_width">0.3in</dimen>
+</resources>
diff --git a/java/res/values/donottranslate-altchars.xml b/java/res/values/donottranslate-altchars.xml
new file mode 100644
index 0000000..51c7faf
--- /dev/null
+++ b/java/res/values/donottranslate-altchars.xml
@@ -0,0 +1,54 @@
+<?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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="alternates_for_a">áàâãäåāæ</string>
+ <string name="alternates_for_b"></string>
+ <string name="alternates_for_c">çčć¢</string>
+ <string name="alternates_for_d">đ</string>
+ <string name="alternates_for_e">3éèêëē€</string>
+ <string name="alternates_for_f">₣</string>
+ <string name="alternates_for_g"></string>
+ <string name="alternates_for_h"></string>
+ <string name="alternates_for_i">8íìîïī</string>
+ <string name="alternates_for_j"></string>
+ <string name="alternates_for_k"></string>
+ <string name="alternates_for_l">£₤λ</string>
+ <string name="alternates_for_m">μ</string>
+ <string name="alternates_for_n">ñ</string>
+ <string name="alternates_for_o">9óòôõöōø</string>
+ <string name="alternates_for_p">0π₱</string>
+ <string name="alternates_for_q">1</string>
+ <string name="alternates_for_r">4</string>
+ <string name="alternates_for_s">§ßš</string>
+ <string name="alternates_for_t">5</string>
+ <string name="alternates_for_u">7úùûüū</string>
+ <string name="alternates_for_v"></string>
+ <string name="alternates_for_w">2</string>
+ <string name="alternates_for_x"></string>
+ <string name="alternates_for_y">6ýÿ¥</string>
+ <string name="alternates_for_z">ž</string>
+
+ <string name="alternates_for_a_umlaut"></string>
+ <string name="alternates_for_ae"></string>
+ <string name="alternates_for_cyrillic_e"></string>
+ <string name="alternates_for_cyrillic_soft_sign"></string>
+ <string name="alternates_for_o_umlaut"></string>
+ <string name="alternates_for_oe"></string>
+</resources>
diff --git a/java/res/values/donottranslate-keymap.xml b/java/res/values/donottranslate-keymap.xml
new file mode 100644
index 0000000..7d6d316
--- /dev/null
+++ b/java/res/values/donottranslate-keymap.xml
@@ -0,0 +1,223 @@
+<?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.
+**
+**
+** 5-row layout for English QWERTY.
+**
+** See http://code.google.com/p/hackerskeyboard/wiki/AddingNewLayouts for
+** more information.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="key_tlde_main">`</string>
+ <string name="key_tlde_shift">~</string>
+ <string name="key_tlde_alt">`~</string>
+
+ <string name="key_ae01_main">1</string>
+ <string name="key_ae01_shift">!</string>
+ <string name="key_ae01_alt">1!¡¹½⅓¼⅛</string>
+
+ <string name="key_ae02_main">2</string>
+ <string name="key_ae02_shift">\@</string>
+ <string name="key_ae02_alt">2\@²⅔</string>
+
+ <string name="key_ae03_main">3</string>
+ <string name="key_ae03_shift">#</string>
+ <string name="key_ae03_alt">3#³¾⅜♥♠♦♣</string>
+
+ <string name="key_ae04_main">4</string>
+ <string name="key_ae04_shift">$</string>
+ <string name="key_ae04_alt">4$⁴¢£€¥</string>
+
+ <string name="key_ae05_main">5</string>
+ <string name="key_ae05_shift">%</string>
+ <string name="key_ae05_alt">5%⅝‰</string>
+
+ <string name="key_ae06_main">6</string>
+ <string name="key_ae06_shift">^</string>
+ <string name="key_ae06_alt">6^↑↓←→</string>
+
+ <string name="key_ae07_main">7</string>
+ <string name="key_ae07_shift">&amp;</string>
+ <string name="key_ae07_alt">7&amp;⅞♪</string>
+
+ <string name="key_ae08_main">8</string>
+ <string name="key_ae08_shift">*</string>
+ <string name="key_ae08_alt">8*•★∞†‡</string>
+
+ <string name="key_ae09_main">9</string>
+ <string name="key_ae09_shift">(</string>
+ <string name="key_ae09_alt">9(√</string>
+
+ <string name="key_ae10_main">0</string>
+ <string name="key_ae10_shift">)</string>
+ <string name="key_ae10_alt">0)ⁿ°</string>
+
+ <string name="key_ae11_main">-</string>
+ <string name="key_ae11_shift">_</string>
+ <string name="key_ae11_alt">-_—–</string>
+
+ <string name="key_ae12_main">=</string>
+ <string name="key_ae12_shift">+</string>
+ <string name="key_ae12_alt">=+≈≠±×÷</string>
+
+
+ <string name="key_ad01_main">q</string>
+ <string name="key_ad01_shift"></string>
+ <string name="key_ad01_alt">@string/alternates_for_q</string>
+
+ <string name="key_ad02_main">w</string>
+ <string name="key_ad02_shift"></string>
+ <string name="key_ad02_alt">@string/alternates_for_w</string>
+
+ <string name="key_ad03_main">e</string>
+ <string name="key_ad03_shift"></string>
+ <string name="key_ad03_alt">@string/alternates_for_e</string>
+
+ <string name="key_ad04_main">r</string>
+ <string name="key_ad04_shift"></string>
+ <string name="key_ad04_alt">@string/alternates_for_r</string>
+
+ <string name="key_ad05_main">t</string>
+ <string name="key_ad05_shift"></string>
+ <string name="key_ad05_alt">@string/alternates_for_t</string>
+
+ <string name="key_ad06_main">y</string>
+ <string name="key_ad06_shift"></string>
+ <string name="key_ad06_alt">@string/alternates_for_y</string>
+
+ <string name="key_ad07_main">u</string>
+ <string name="key_ad07_shift"></string>
+ <string name="key_ad07_alt">@string/alternates_for_u</string>
+
+ <string name="key_ad08_main">i</string>
+ <string name="key_ad08_shift"></string>
+ <string name="key_ad08_alt">@string/alternates_for_i</string>
+
+ <string name="key_ad09_main">o</string>
+ <string name="key_ad09_shift"></string>
+ <string name="key_ad09_alt">@string/alternates_for_o</string>
+
+ <string name="key_ad10_main">p</string>
+ <string name="key_ad10_shift"></string>
+ <string name="key_ad10_alt">@string/alternates_for_p</string>
+
+ <string name="key_ad11_main">[</string>
+ <string name="key_ad11_shift">{</string>
+ <string name="key_ad11_alt">[{</string>
+
+ <string name="key_ad12_main">]</string>
+ <string name="key_ad12_shift">}</string>
+ <string name="key_ad12_alt">]}</string>
+
+ <string name="key_bksl_main">\\</string>
+ <string name="key_bksl_shift">|</string>
+ <string name="key_bksl_alt">\\|</string>
+
+
+ <string name="key_ac01_main">a</string>
+ <string name="key_ac01_shift"></string>
+ <string name="key_ac01_alt">@string/alternates_for_a</string>
+
+ <string name="key_ac02_main">s</string>
+ <string name="key_ac02_shift"></string>
+ <string name="key_ac02_alt">@string/alternates_for_s</string>
+
+ <string name="key_ac03_main">d</string>
+ <string name="key_ac03_shift"></string>
+ <string name="key_ac03_alt">@string/alternates_for_d</string>
+
+ <string name="key_ac04_main">f</string>
+ <string name="key_ac04_shift"></string>
+ <string name="key_ac04_alt">@string/alternates_for_f</string>
+
+ <string name="key_ac05_main">g</string>
+ <string name="key_ac05_shift"></string>
+ <string name="key_ac05_alt">@string/alternates_for_g</string>
+
+ <string name="key_ac06_main">h</string>
+ <string name="key_ac06_shift"></string>
+ <string name="key_ac06_alt">@string/alternates_for_h</string>
+
+ <string name="key_ac07_main">j</string>
+ <string name="key_ac07_shift"></string>
+ <string name="key_ac07_alt">@string/alternates_for_j</string>
+
+ <string name="key_ac08_main">k</string>
+ <string name="key_ac08_shift"></string>
+ <string name="key_ac08_alt">@string/alternates_for_k</string>
+
+ <string name="key_ac09_main">l</string>
+ <string name="key_ac09_shift"></string>
+ <string name="key_ac09_alt">@string/alternates_for_l</string>
+
+ <string name="key_ac10_main">;</string>
+ <string name="key_ac10_shift">:</string>
+ <string name="key_ac10_alt">;:</string>
+
+ <string name="key_ac11_main">\'</string>
+ <string name="key_ac11_shift">\"</string>
+ <string name="key_ac11_alt">\'\"‘’“”</string>
+
+
+ <string name="key_lsgt_main"></string>
+ <string name="key_lsgt_shift"></string>
+ <string name="key_lsgt_alt"></string>
+
+ <string name="key_ab01_main">z</string>
+ <string name="key_ab01_shift"></string>
+ <string name="key_ab01_alt">@string/alternates_for_z</string>
+
+ <string name="key_ab02_main">x</string>
+ <string name="key_ab02_shift"></string>
+ <string name="key_ab02_alt">@string/alternates_for_x</string>
+
+ <string name="key_ab03_main">c</string>
+ <string name="key_ab03_shift"></string>
+ <string name="key_ab03_alt">@string/alternates_for_c</string>
+
+ <string name="key_ab04_main">v</string>
+ <string name="key_ab04_shift"></string>
+ <string name="key_ab04_alt">@string/alternates_for_v</string>
+
+ <string name="key_ab05_main">b</string>
+ <string name="key_ab05_shift"></string>
+ <string name="key_ab05_alt">@string/alternates_for_b</string>
+
+ <string name="key_ab06_main">n</string>
+ <string name="key_ab06_shift"></string>
+ <string name="key_ab06_alt">@string/alternates_for_n</string>
+
+ <string name="key_ab07_main">m</string>
+ <string name="key_ab07_shift"></string>
+ <string name="key_ab07_alt">@string/alternates_for_m</string>
+
+ <string name="key_ab08_main">,</string>
+ <string name="key_ab08_shift">&lt;</string>
+ <string name="key_ab08_alt">,&lt;≤«‹</string>
+
+ <string name="key_ab09_main">.</string>
+ <string name="key_ab09_shift">&gt;</string>
+ <string name="key_ab09_alt">.&gt;≥»›…</string>
+
+ <string name="key_ab10_main">/</string>
+ <string name="key_ab10_shift">\?</string>
+ <string name="key_ab10_alt">/\?¿</string>
+
+ <string name="key_space_shift"></string>
+</resources>
diff --git a/java/res/values/donottranslate.xml b/java/res/values/donottranslate.xml
new file mode 100644
index 0000000..dd4f468
--- /dev/null
+++ b/java/res/values/donottranslate.xml
@@ -0,0 +1,36 @@
+<?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 commonly considered word separators in this language -->
+ <string name="word_separators">.\u0009\u0020,;:!?\n()[]*&amp;@{}/&lt;&gt;_+=|\u0022</string>
+ <!-- Symbols that are sentence separators, for purposes of making it hug the last sentence. -->
+ <string name="sentence_separators">.,!?);:</string>
+ <!-- Symbols that are suggested between words -->
+ <string name="suggested_punctuations_default">!?,\u0022\u0027:;()-/@_</string>
+ <string name="suggested_punctuations">!?,\u0022\u0027:;()-/@_</string>
+
+ <!-- Option values to show/hide the settings key in onscreen keyboard -->
+ <!-- Automatically decide to show or hide the settings key -->
+ <string name="settings_key_mode_auto" translatable="false">0</string>
+ <!-- Always show the settings key -->
+ <string name="settings_key_mode_always_show" translatable="false">1</string>
+ <!-- Always hide the settings key -->
+ <string name="settings_key_mode_always_hide" translatable="false">2</string>
+</resources>
diff --git a/java/res/values/durations.xml b/java/res/values/durations.xml
new file mode 100644
index 0000000..7242f84
--- /dev/null
+++ b/java/res/values/durations.xml
@@ -0,0 +1,25 @@
+<?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>
+ <!-- Vibration duration in milliseconds, for key presses in the IME. This can be hardware
+ dependent and may require overriding with a device specific overlay. -->
+ <string name="vibrate_duration_ms">40 ms</string>
+</resources>
diff --git a/java/res/values/keycodes.xml b/java/res/values/keycodes.xml
new file mode 100644
index 0000000..e42a63c
--- /dev/null
+++ b/java/res/values/keycodes.xml
@@ -0,0 +1,65 @@
+<?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>
+ <integer name="key_tab">9</integer>
+ <integer name="key_return">10</integer>
+ <integer name="key_space">32</integer>
+ <integer name="key_shift">-1</integer>
+ <integer name="key_symbol">-2</integer>
+ <integer name="key_delete">-5</integer>
+ <!-- Keycode for F1 (function) key. This one switches between language switch & comma/.com -->
+ <integer name="key_settings">-100</integer>
+ <integer name="key_voice">-102</integer>
+ <integer name="key_f1">-103</integer>
+ <!-- Keycodes for special keys, using negative KeyEvent keycode numbers -->
+ <integer name="key_dpad_up">-19</integer>
+ <integer name="key_dpad_down">-20</integer>
+ <integer name="key_dpad_left">-21</integer>
+ <integer name="key_dpad_right">-22</integer>
+ <integer name="key_dpad_center">-23</integer>
+ <integer name="key_alt_left">-57</integer>
+ <integer name="key_page_up">-92</integer>
+ <integer name="key_page_down">-93</integer>
+ <integer name="key_escape">-111</integer>
+ <integer name="key_forward_del">-112</integer>
+ <integer name="key_ctrl_left">-113</integer>
+ <integer name="key_caps_lock">-115</integer>
+ <integer name="key_scroll_lock">-116</integer>
+ <integer name="key_fn">-119</integer>
+ <integer name="key_sysrq">-120</integer>
+ <integer name="key_break">-121</integer>
+ <integer name="key_home">-122</integer>
+ <integer name="key_end">-123</integer>
+ <integer name="key_insert">-124</integer>
+ <integer name="key_fkey_f1">-131</integer>
+ <integer name="key_fkey_f2">-132</integer>
+ <integer name="key_fkey_f3">-133</integer>
+ <integer name="key_fkey_f4">-134</integer>
+ <integer name="key_fkey_f5">-135</integer>
+ <integer name="key_fkey_f6">-136</integer>
+ <integer name="key_fkey_f7">-137</integer>
+ <integer name="key_fkey_f8">-138</integer>
+ <integer name="key_fkey_f9">-139</integer>
+ <integer name="key_fkey_f10">-140</integer>
+ <integer name="key_fkey_f11">-141</integer>
+ <integer name="key_fkey_f12">-142</integer>
+ <integer name="key_num_lock">-143</integer>
+</resources>
diff --git a/java/res/values/size-defaults.xml b/java/res/values/size-defaults.xml
new file mode 100644
index 0000000..de153ad
--- /dev/null
+++ b/java/res/values/size-defaults.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, Klaus Weidner
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT 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>
+ <string name="default_height_portrait">35%</string>
+ <string name="default_height_landscape">55%</string>
+ <string name="default_keyboard_mode_portrait">0</string>
+ <string name="default_keyboard_mode_landscape">2</string>
+</resources>
diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml
new file mode 100644
index 0000000..0a410c6
--- /dev/null
+++ b/java/res/values/strings.xml
@@ -0,0 +1,654 @@
+<?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:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Title for Latin keyboard -->
+ <string name="english_ime_name">Hacker\'s Keyboard</string>
+ <!-- Title for Latin keyboard settings activity / dialog -->
+ <string name="english_ime_settings">Settings for Hacker\'s Keyboard</string>
+ <!-- Title for Latin keyboard input options dialog -->
+ <string name="english_ime_input_options">Input options</string>
+
+ <!-- Various configuration titles -->
+ <string name="title_keyboard_view_settings">Keyboard view settings</string>
+ <string name="title_keyboard_height_portrait">Keyboard height, portrait</string>
+ <string name="title_keyboard_height_landscape">Keyboard height, landscape</string>
+ <string name="title_key_layout_options">Key layout options</string>
+ <string name="title_key_behavior_settings">Key behavior settings</string>
+ <string name="title_long_press_alternate_keys">Long-press alternate keys</string>
+ <string name="title_suggested_punctuation">Suggested punctuation</string>
+ <string name="title_input_mode_settings">Input mode settings</string>
+ <string name="title_debugging">Debugging</string>
+ <string name="title_input_connection_details">Input connection details</string>
+ <string name="title_version">Version</string>
+ <string name="title_swipe_gestures">Swipe gestures (experimental)</string>
+ <string name="title_hardware_key_actions">Hardware key actions</string>
+
+ <!-- Option to provide vibrate/haptic feedback on keypress -->
+ <string name="vibrate_on_keypress">Vibrate on keypress</string>
+
+ <!-- Option to play back sound on keypress in soft keyboard -->
+ <string name="sound_on_keypress">Sound on keypress</string>
+
+ <!-- Option to pop up the character with a larger font above soft keyboard -->
+ <string name="popup_on_keypress">Popup on keypress</string>
+
+ <!-- Option to enable using nearby keys when correcting/predicting -->
+ <string name="hit_correction">Correct typing errors</string>
+
+ <!-- Description for hit_correction -->
+ <string name="hit_correction_summary">Enable input error correction</string>
+
+ <!-- Option to enable using nearby keys when correcting/predicting in landscape-->
+ <string name="hit_correction_land">Landscape input errors</string>
+
+ <!-- Description for hit_correction in landscape -->
+ <string name="hit_correction_land_summary">Enable input error correction</string>
+
+ <!-- Option to automatically correct word on hitting space -->
+ <string name="auto_correction">Word suggestions</string>
+
+ <!-- Description for auto_correction -->
+ <string name="auto_correction_summary">Automatically correct the previous word</string>
+
+ <!-- Option to enable text prediction -->
+ <string name="prediction">Word suggestions</string>
+ <!-- Category title for text prediction -->
+ <string name="prediction_category">Word suggestion settings</string>
+ <!-- Description for text prediction -->
+ <string name="prediction_summary">Enable auto completion while typing</string>
+
+ <!-- Dialog title for auto complete choices -->
+ <string name="auto_complete_dialog_title">Auto completion</string>
+
+ <!-- Option to enable text prediction in landscape -->
+ <string name="prediction_landscape">Increase text field size</string>
+ <!-- Description for text prediction -->
+ <string name="prediction_landscape_summary">Hide word suggestions in landscape view</string>
+
+ <!-- Option to enable auto capitalization of sentences -->
+ <string name="auto_cap">Auto-capitalization</string>
+ <!-- Description for auto cap -->
+ <string name="auto_cap_summary">Capitalize the start of a sentence</string>
+ <!-- Option to enable auto punctuate -->
+ <string name="auto_punctuate">Auto-punctuate</string>
+ <!-- Description for auto punctuate -->
+ <string name="auto_punctuate_summary"></string>
+
+ <!-- Option to enable quick fixes -->
+ <string name="quick_fixes">Quick fixes</string>
+ <!-- Description for quick fixes -->
+ <string name="quick_fixes_summary">Corrects commonly typed mistakes</string>
+
+ <!-- Option to enable showing suggestions -->
+ <string name="show_suggestions">Show suggestions</string>
+ <!-- Description for show suggestions -->
+ <string name="show_suggestions_summary">Display suggested words while typing</string>
+
+ <!-- Option to enable auto completion -->
+ <string name="auto_complete">Auto-complete</string>
+ <!-- Description for auto completion -->
+ <string name="auto_complete_summary">Spacebar and punctuation automatically insert highlighted word</string>
+
+ <!-- Option to show/hide the settings key -->
+ <string name="prefs_settings_key">Show settings key</string>
+ <!-- Array of the settings key mode values -->
+ <string-array name="settings_key_modes_values" translatable="false">
+ <item>@string/settings_key_mode_auto</item>
+ <item>@string/settings_key_mode_always_show</item>
+ <item>@string/settings_key_mode_always_hide</item>
+ </string-array>
+ <!-- Option to automatically decide to show/hide the settings key -->
+ <string name="settings_key_mode_auto_name">Automatic</string>
+ <!-- Option to always show the settings key -->
+ <string name="settings_key_mode_always_show_name">Always show</string>
+ <!-- Option to always hide the settings key -->
+ <string name="settings_key_mode_always_hide_name">Always hide</string>
+ <!-- Array of the settings key modes -->
+ <string-array name="settings_key_modes">
+ <item>@string/settings_key_mode_auto_name</item>
+ <item>@string/settings_key_mode_always_show_name</item>
+ <item>@string/settings_key_mode_always_hide_name</item>
+ </string-array>
+
+ <!-- Option to enable bigram completion -->
+ <string name="bigram_suggestion">Bigram Suggestions</string>
+ <!-- Description for auto completion -->
+ <string name="bigram_suggestion_summary">Use previous word to improve suggestion</string>
+
+ <!-- Array of prediction modes -->
+ <string-array name="prediction_modes">
+ <item>None</item>
+ <item>Basic</item>
+ <item>Advanced</item>
+ </string-array>
+
+ <!-- Don't translate -->
+ <string name="prediction_none" translatable="false">0</string>
+ <!-- Don't translate -->
+ <string name="prediction_basic" translatable="false">1</string>
+ <!-- Don't translate -->
+ <string name="prediction_full" translatable="false">2</string>
+
+ <string-array name="prediction_modes_values" translatable="false">
+ <item>@string/prediction_none</item>
+ <item>@string/prediction_basic</item>
+ <item>@string/prediction_full</item>
+ </string-array>
+
+ <!-- Indicates that a word has been added to the dictionary -->
+ <string name="added_word"><xliff:g id="word">%s</xliff:g> : Saved</string>
+
+ <!-- Tip to long press on keys -->
+ <string name="tip_long_press">Hold a key down to see accents (ø, ö, etc.)</string>
+ <!-- Tip to dismiss keyboard -->
+ <string name="tip_dismiss">Press the back key \u21B6 to close the keyboard at any point</string>
+ <!-- Tip to press ?123 to access numbers and symbols -->
+ <string name="tip_access_symbols">Access numbers and symbols</string>
+ <!-- Tip to long press on typed word to add to dictionary -->
+ <string name="tip_add_to_dictionary">Press and hold the left-most word to add it to the dictionary
+ </string>
+
+ <!-- Instruction to touch the bubble to continue -->
+ <string name="touch_to_continue">Touch this hint to continue »</string>
+
+ <!-- Instruction to touch the bubble to start typing -->
+ <string name="touch_to_finish">Touch here to close this hint and start typing!</string>
+
+ <!-- Tutorial tip 1 - The keyboard opens any time you touch a text field -->
+ <string name="tip_to_open_keyboard"><b>The keyboard opens any time you touch a text field</b></string>
+
+ <!-- Tutorial tip 2 - Touch and hold a key to view accents (examples) -->
+ <string name="tip_to_view_accents"><b>Touch &amp; hold a key to view accents\n(ø, ö, ô, ó, and so on)</b>
+ </string>
+
+ <!-- Tutorial tip 3 - How to switch to number/symbol keyboard -->
+ <string name="tip_to_open_symbols"><b>Switch to numbers and symbols by touching this key</b></string>
+
+ <!-- Tutorial tip 4 - How to switch back to alphabet keyboard -->
+ <string name="tip_to_close_symbols"><b>Go back to letters by touching this key again</b></string>
+
+ <!-- Tutorial tip 5 - How to launch keyboard settings -->
+ <string name="tip_to_launch_settings"><b>Touch &amp; hold this key to change keyboard settings, like auto complete</b></string>
+
+ <!-- Tutorial tip 6 - Done with the tutorial -->
+ <string name="tip_to_start_typing"><b>Try it!</b></string>
+
+
+ <!-- Label for soft enter key when it performs GO action. Must be short to fit on key! -->
+ <string name="label_go_key">Go</string>
+ <!-- Label for soft enter key when it performs NEXT action. Must be short to fit on key! -->
+ <string name="label_next_key">Next</string>
+ <!-- Label for soft enter key when it performs DONE action. Must be short to fit on key! -->
+ <string name="label_done_key">Done</string>
+ <!-- Label for soft enter key when it performs SEND action. Must be short to fit on key! -->
+ <string name="label_send_key">Send</string>
+ <!-- Label for "switch to symbols" key. Must be short to fit on key! -->
+ <string name="label_symbol_key">\?123</string>
+ <!-- Label for "switch to numeric" key. Must be short to fit on key! -->
+ <string name="label_phone_key">123</string>
+ <!-- Label for "switch to alphabetic" key. Must be short to fit on key! -->
+ <string name="label_alpha_key">ABC</string>
+ <!-- Label for ALT modifier key. Must be short to fit on key! -->
+ <string name="label_alt_key">ALT</string>
+
+ <!-- Voice related labels -->
+
+ <!-- Title of the warning dialog that shows when a user initiates voice input for
+ the first time. -->
+ <string name="voice_warning_title">Voice input</string>
+
+ <!-- Message that gets put at the top of the warning dialog if the user is attempting to use
+ voice input in a currently unsupported locale. Voice input will work for such a user,
+ but it will only recognize them in English. -->
+ <string name="voice_warning_locale_not_supported">Voice input is not currently supported for your language, but does work in English.</string>
+
+ <!-- Message of the warning dialog that shows when a user initiates voice input for
+ the first time, or turns it on in settings. -->
+ <string name="voice_warning_may_not_understand">Voice input is an experimental feature using Google\'s networked speech recognition.</string>
+
+ <!-- An additional part of the warning dialog for voice input that only shows when the user
+ actually initiates voice input, rather than just turning it on in settings. -->
+ <string name="voice_warning_how_to_turn_off">To turn off voice input, go to keyboard settings.</string>
+
+ <!-- Message to show when user clicks the swiping hint (which says
+ "Swipe across keyboard to speak"). Also shown when enabling settings. -->
+ <string name="voice_hint_dialog_message">To use voice input, press the microphone button or slide your finger across the on-screen keyboard.</string>
+
+ <!-- Short message to tell the user the system is ready for them to speak. -->
+ <string name="voice_listening">Speak now</string>
+
+ <!-- Short message shown after the user finishes speaking. -->
+ <string name="voice_working">Working</string>
+
+ <!-- Short message shown before the user should speak. -->
+ <string name="voice_initializing"></string>
+
+ <!-- Short message shown when a generic error occurs. -->
+ <string name="voice_error">Error. Please try again.</string>
+
+ <!-- Short message shown for a network error. -->
+ <string name="voice_network_error">Couldn\'t connect</string>
+
+ <!-- Short message shown for a network error where the utterance was really long,
+ in which case we should suggest that the user speak less. -->
+ <string name="voice_too_much_speech">Error, too much speech.</string>
+
+ <!-- Short message shown for an audio error. -->
+ <string name="voice_audio_error">Audio problem</string>
+
+ <!-- Short message shown for an error with the voice server. -->
+ <string name="voice_server_error">Server error</string>
+
+ <!-- Short message shown when no speech is heard. -->
+ <string name="voice_speech_timeout">No speech heard</string>
+
+ <!-- Short message shown when the server couldn't parse any speech. -->
+ <string name="voice_no_match">No matches found</string>
+
+ <!-- Short message shown when the user initiates voice and voice
+ search is not installed. -->
+ <string name="voice_not_installed">Voice search not installed</string>
+
+ <!-- Short hint shown in candidate view to explain voice input. -->
+ <string name="voice_swipe_hint"><b>Hint:</b> Swipe across keyboard to speak</string>
+
+ <!-- Short hint shown in candidate view to explain that user can speak punctuation. -->
+ <string name="voice_punctuation_hint"><b>Hint:</b> Next time, try speaking punctuation like \"period\", \"comma\", or \"question mark\".</string>
+
+ <!-- Label on button to stop recognition. Must be short to fit on button. -->
+ <string name="cancel">Cancel</string>
+
+ <!-- Label on button when an error occurs -->
+ <string name="ok">OK</string>
+
+ <!-- Preferences item for enabling speech input -->
+ <string name="voice_input">Voice input</string>
+
+ <!-- Array of Voice Input modes -->
+ <string-array name="voice_input_modes">
+ <item>On main keyboard</item>
+ <item>On symbols keyboard</item>
+ <item>Off</item>
+ </string-array>
+
+ <!-- Don't translate -->
+ <string name="voice_mode_main" translatable="false">0</string>
+ <!-- Don't translate -->
+ <string name="voice_mode_symbols" translatable="false">1</string>
+ <!-- Don't translate -->
+ <string name="voice_mode_off" translatable="false">2</string>
+
+ <string-array name="voice_input_modes_values" translatable="false">
+ <item>@string/voice_mode_main</item>
+ <item>@string/voice_mode_symbols</item>
+ <item>@string/voice_mode_off</item>
+ </string-array>
+
+ <!-- Array of Voice Input modes summary -->
+ <string-array name="voice_input_modes_summary">
+ <item>Mic on main keyboard</item>
+ <item>Mic on symbols keyboard</item>
+ <item>Voice input is disabled</item>
+ </string-array>
+
+ <!-- Press the "enter" key after the user speaks. Option on settings.-->
+ <string name="auto_submit">Auto submit after voice</string>
+
+ <!-- Press the "enter" key after the user speaks. Summary of option in settings.-->
+ <string name="auto_submit_summary">Automatically press enter when searching or going to the next field.</string>
+
+ <!-- IME Tutorial screen (ROMAN) --><skip />
+ <!-- appears above image showing the user to click on a TextView to show the IME -->
+ <string name="open_the_keyboard"><font size="17"><b>Open the keyboard\n</b></font><font size="3">\n</font>Touch any text field.</string>
+
+ <!-- appears above the image showing the back button used to close the keyboard -->
+ <string name="close_the_keyboard"><font size="17"><b>Close the keyboard\n</b></font><font size="3">\n</font>Press the Back key.</string>
+
+ <!-- appears above image showing how to use touch and hold -->
+ <string name="touch_and_hold"><font size="17"><b>Touch \u0026 hold a key for options\n</b></font><font size="3">\n</font>Access punctuation and accents.</string>
+
+ <!-- appears above image showing how to access keyboard settings -->
+ <string name="keyboard_settings"><font size="17"><b>Keyboard settings\n</b></font><font size="3">\n</font>Touch \u0026 hold the <b>\?123\</b> key.</string>
+
+ <!-- popular web domains for the locale - most popular, displayed on the keyboard -->
+ <string name="popular_domain_0">".com"</string>
+ <!-- popular web domains for the locale - item 1, displayed in the popup -->
+ <string name="popular_domain_1">".net"</string>
+ <!-- popular web domains for the locale - item 2, displayed in the popup -->
+ <string name="popular_domain_2">".org"</string>
+ <!-- popular web domains for the locale - item 3, displayed in the popup -->
+ <string name="popular_domain_3">".gov"</string>
+ <!-- popular web domains for the locale - item 4, displayed in the popup -->
+ <string name="popular_domain_4">".edu"</string>
+
+ <!-- Menu item for launching Input method picker -->
+ <string name="selectInputMethod">Select input method</string>
+
+ <!-- Title for input language selection screen -->
+ <string name="language_selection_title">Input languages</string>
+ <!-- Title summary for input language selection screen -->
+ <string name="language_selection_summary">Slide finger on spacebar to change language</string>
+
+ <!-- Add to dictionary hint -->
+ <string name="hint_add_to_dictionary">\u2190 Touch again to save</string>
+
+ <!-- Inform the user that a particular language has an available dictionary -->
+ <string name="has_dictionary">Dictionary available</string>
+
+ <!-- Preferences item for enabling to send user statistics to Google -->
+ <string name="prefs_enable_log">Enable user feedback</string>
+ <!-- Description for enabling to send user statistics to Google -->
+ <string name="prefs_description_log">Help improve this input method editor by automatically sending usage statistics and crash reports to Google.</string>
+ <!-- Preferences item for enabling to correct suggestions by touching words you have typed -->
+ <string name="prefs_enable_recorrection">Touch to correct words</string>
+ <!-- The summary for the preferences item for enabling to correct suggestions by touching words you have typed -->
+ <string name="prefs_enable_recorrection_summary">Touch entered words to correct them</string>
+
+ <string name="pref_screen_feedback_title">Key feedback settings</string>
+
+ <string name="pref_screen_view_title">Theme and label settings</string>
+
+ <!-- Description for keyboard theme switcher -->
+ <string name="keyboard_layout">Keyboard Theme</string>
+ <string name="layout_basic" translatable="false">Basic</string>
+ <string name="layout_high_contrast" translatable="false">Basic (High Contrast)</string>
+ <string name="layout_stone_bold" translatable="false">Stone (bold)</string>
+ <string name="layout_stone_normal" translatable="false">Stone (normal)</string>
+ <string name="layout_gingerbread" translatable="false">Gingerbread</string>
+ <string name="layout_ics" translatable="false">Ice Cream Sandwich</string>
+ <string name="layout_trans" translatable="false">Transparent</string>
+ <string name="layout_trans_neon" translatable="false">Transparent (experimental)</string>
+
+ <string-array name="keyboard_layout_modes" translatable="false">
+ <item>@string/layout_ics</item>
+ <item>@string/layout_gingerbread</item>
+ <item>@string/layout_stone_bold</item>
+ <item>@string/layout_trans_neon</item>
+ </string-array>
+
+ <string-array name="keyboard_layout_modes_values" translatable="false">
+ <item>0</item>
+ <item>1</item>
+ <item>2</item>
+ <item>3</item>
+ </string-array>
+
+ <string name="subtype_mode_keyboard">keyboard</string>
+ <string name="subtype_mode_voice">voice</string>
+
+ <string name="title_keyboard_mode_portrait">Keyboard mode, portrait</string>
+ <string name="title_keyboard_mode_landscape">Keyboard mode, landscape</string>
+ <string name="title_compact_mode_enabled">Enable compact 5-row keyboard mode</string>
+ <string name="summary_compact_mode_enabled">US QWERTY only, and experimental!</string>
+ <string-array name="keyboard_mode_entries">
+ <item>4-row Gingerbread layout</item>
+ <item>5-row compact layout (US QWERTY only!)</item>
+ <item>Full 5-row layout</item>
+ </string-array>
+ <string-array name="keyboard_mode_values">
+ <item>0</item>
+ <item>1</item>
+ <item>2</item>
+ </string-array>
+
+ <string name="title_chording_ctrl_key">Ctrl key code</string>
+ <string name="default_chording_ctrl_key">0</string>
+ <string-array name="chording_ctrl_key_entries">
+ <item>None (ignored when not modifying other keys)</item>
+ <item>Left Ctrl</item>
+ <item>Right Ctrl</item>
+ </string-array>
+ <string-array name="chording_ctrl_key_values">
+ <item>0</item>
+ <item>113</item>
+ <item>114</item>
+ </string-array>
+
+ <string name="title_chording_alt_key">Alt key code</string>
+ <string name="default_chording_alt_key">0</string>
+ <string-array name="chording_alt_key_entries">
+ <item>None (ignored when not modifying other keys)</item>
+ <item>Left Alt</item>
+ <item>Right Alt</item>
+ </string-array>
+ <string-array name="chording_alt_key_values">
+ <item>0</item>
+ <item>57</item>
+ <item>58</item>
+ </string-array>
+
+ <string name="title_suggestions_in_landscape">Suggestions in landscape mode</string>
+ <string name="summary_suggestions_in_landscape_true">Same as in portrait mode</string>
+ <string name="summary_suggestions_in_landscape_false">Hide suggestions in landscape mode</string>
+
+ <string name="title_fullscreen_override">Landscape mode fullscreen editor</string>
+ <string name="summary_fullscreen_override_true">Disabled, use standard view</string>
+ <string name="summary_fullscreen_override_false">Enabled on small devices</string>
+
+ <string name="title_force_keyboard_on">Show soft keyboard</string>
+ <string name="summary_force_keyboard_on_true">Always</string>
+ <string name="summary_force_keyboard_on_false">When no hardware keyboard is available</string>
+
+ <string name="title_keyboard_notification">Use permanent notification</string>
+ <string name="summary_keyboard_notification_true">Activate the keyboard by tapping the notification</string>
+ <string name="summary_keyboard_notification_false">No notification</string>
+
+ <string name="title_application_category">Application-specific settings</string>
+
+ <string name="title_connectbot_tab_hack">ConnectBot tab key mode</string>
+ <string name="summary_connectbot_tab_hack_true">Enable compatibility workaround</string>
+ <string name="summary_connectbot_tab_hack_false">Send plain Tab key event</string>
+
+ <string name="title_caps_lock">Double-tap Shift mode</string>
+ <string name="summary_caps_lock_true">Caps Lock (q1 => Q1)</string>
+ <string name="summary_caps_lock_false">Shift Lock (q1 => Q!)</string>
+
+ <string name="title_shift_lock_modifiers">Apply Shift Lock to modifier keys?</string>
+ <string name="summary_shift_lock_modifiers_true">Yes, including arrow keys</string>
+ <string name="summary_shift_lock_modifiers_false">No, normal keys only</string>
+
+ <string name="title_hint_mode">Labeled alternate keys</string>
+ <string-array name="hint_modes">
+ <item>Hide hint labels</item>
+ <item>Show ASCII punctuation</item>
+ <item>Show all hint labels</item>
+ </string-array>
+
+ <string-array name="hint_modes_values">
+ <item>0</item>
+ <item>1</item>
+ <item>2</item>
+ </string-array>
+ <string name="default_hint_mode">1</string>
+
+ <string name="title_touch_pos">Debug touch screen position</string>
+ <string name="summary_touch_pos_true">Show feedback for touch screen location</string>
+ <string name="summary_touch_pos_false">Off</string>
+
+ <string name="title_slide_keys">Sliding key events</string>
+ <!-- Values are a bitmap, see use in PointerTracker -->
+ <string-array name="slide_keys_entries">
+ <item>Ignore keys during sliding movement (Recommended)</item>
+ <item>Send first key touched</item>
+ <item>Send last key touched</item>
+ <item>Send first and last key</item>
+ <item>Send all keys touched during sliding movement</item>
+ </string-array>
+ <string-array name="slide_keys_values">
+ <item>0</item>
+ <item>1</item>
+ <item>2</item>
+ <item>3</item>
+ <item>4</item>
+ </string-array>
+
+ <string name="percent">percent</string>
+
+ <string name="title_top_row_scale">5th row height adjustment</string>
+
+ <string name="title_label_scale">Key label scaling</string>
+ <string name="title_candidate_scale">Suggestion label scaling</string>
+
+ <string name="title_vibrate_len">Vibrate duration</string>
+
+ <string name="title_click_volume">Key click volume</string>
+ <string name="default_click_volume">0.2</string>
+ <string name="title_click_method">Click volume control method</string>
+ <string name="default_click_method">0</string>
+ <string-array name="click_method_entries">
+ <item>System default (ignore click volume)</item>
+ <item>Absolute click volume</item>
+ <item>Follow media volume</item>
+ <item>Reverse media volume</item>
+ </string-array>
+ <string-array name="click_method_values">
+ <item>0</item>
+ <item>1</item>
+ <item>2</item>
+ <item>3</item>
+ </string-array>
+
+ <string name="title_long_press_duration">Long-press duration</string>
+
+ <string name="title_render_mode">Drawing method</string>
+ <string name="render_mode_unavailable">(not changeable on this device)</string>
+ <string-array name="render_mode_entries">
+ <item>Direct draw (saves memory)</item>
+ <item>Software buffered (default)</item>
+ <item>Hardware accelerated (experimental)</item>
+ </string-array>
+ <!-- Keep these values in sync with android.view.View LAYER_TYPE_* definitions -->
+ <string-array name="render_mode_values">
+ <item>0</item>
+ <item>1</item>
+ <item>2</item>
+ </string-array>
+
+ <string name="pref_screen_actions_title">Gesture and key actions</string>
+ <string name="title_swipe_up">Swipe up</string>
+ <string name="title_swipe_down">Swipe down</string>
+ <string name="title_swipe_left">Swipe left</string>
+ <string name="title_swipe_right">Swipe right</string>
+ <string name="title_vol_up">Volume up</string>
+ <string name="title_vol_down">Volume down</string>
+ <string-array name="swipe_action_entries">
+ <item>(no action)</item>
+ <item>Close keyboard</item>
+ <item>Toggle extension row</item>
+ <item>Launch Settings</item>
+ <item>Toggle suggestions</item>
+ <item>Voice input</item>
+ <item>Switch keyboard layout</item>
+ <item>Increase height</item>
+ <item>Decrease height</item>
+ <item>Previous language</item>
+- <item>Next language</item>
+ </string-array>
+ <string-array name="swipe_action_values">
+ <item>none</item>
+ <item>close</item>
+ <item>extension</item>
+ <item>settings</item>
+ <item>suggestions</item>
+ <item>voice_input</item>
+ <item>full_mode</item>
+ <item>height_up</item>
+ <item>height_down</item>
+ <item>lang_prev</item>
+- <item>lang_next</item>
+ </string-array>
+ <string name="default_swipe_up">extension</string>
+ <string name="default_swipe_down">close</string>
+ <string name="default_swipe_left">none</string>
+ <string name="default_swipe_right">none</string>
+ <string name="default_vol_up">none</string>
+ <string name="default_vol_down">none</string>
+
+ <string name="title_popup_content">Popup mini-keyboard contents</string>
+ <string-array name="popup_content_entries">
+ <item>No popups</item>
+ <item>No popups, use auto-repeat</item>
+ <item>Unique only: 3 &#x21d2; ³, e &#x21d2; é</item>
+ <item>Add shifted: 3 &#x21d2; #³, e &#x21d2; é</item>
+ <item>Add upper: 3 &#x21d2; #³, e &#x21d2; Eé</item>
+ <item>Add self: 3 &#x21d2; 3#³, e &#x21d2; eEé</item>
+ </string-array>
+ <!-- The values are a bitmap, keep in sync with Keyboard.java -->
+ <string-array name="popup_content_values">
+ <item>256</item>
+ <item>768</item>
+ <item>0</item>
+ <item>1</item>
+ <item>3</item>
+ <item>7</item>
+ </string-array>
+ <string name="default_popup_content">1</string>
+
+ <string name="voice_not_enabled_warning">Voice input is not available in this version.</string>
+ <string name="recorrect_warning">FYI: recorrection does not work correctly on pre-Gingerbread devices due to missing operating system support.</string>
+ <string name="no_market_warning">Unable to launch Market.</string>
+ <!-- Title for Latin keyboard debug settings activity / dialog -->
+ <string name="english_ime_debug_settings" translatable="false">Debug settings</string>
+ <string name="prefs_debug_mode" translatable="false">Debug Mode</string>
+ <string name="main_setup_configure_imes">Enable keyboard</string>
+ <string name="main_setup_set_ime">Set input method</string>
+ <string name="main_setup_get_dicts">Get dictionaries</string>
+ <string name="main_setup_input_lang">Input languages</string>
+ <string name="main_body"><Data>
+ <![CDATA["
+ <h2>Enabling Hacker's Keyboard</h2>
+
+ <p><i>Hacker's Keyboard</i> provides a new Android input method. It is <b>disabled by default</b>, and for security reasons Android doesn't allow programs to change input method settings. Please follow the following steps to activate it.<p>
+
+ <h3>Add the keyboard to the system's input method list:</h3>
+ <blockquote>
+ <p>&#8226; Open the system input settings configuration by pressing the <b>Enable Keyboard</b> button above.</p>
+ <p>&#8226; Find <i>Hacker's Keyboard</i> in the input method list, tap the checkmark to switch it on.</p>
+ <p>&#8226; Acknowledge the warning shown by the system. The system always shows this message when enabling a third-party input method.</p>
+ <p>&#8226; Press the <i>Back</i> button to return to this page.</p>
+ </blockquote>
+
+ <h3>Choose the currently active input method:</h3>
+ <blockquote>
+ <p>&#8226; Press the <b>Set input method</b> button above.</p>
+ <p>&#8226; Select <i>Hacker's Keyboard</i> from the list.</p>
+ </blockquote>
+
+ <h3>Optional: Select input languages:</h3>
+ <blockquote>
+ <p>&#8226; Press the <b>Input languages</b> button above to select which keyboard layouts you want to use. You <b>must</b> configure this if you want to use a language or layout other than the one corresponding to your system's default language.</p>
+ <p>&#8226; Press the <i>Back</i> button to return to this page.</p>
+ <p>&#8226; When typing, slide the space bar horizontally to switch between selected layouts.
+ </blockquote>
+
+ <h3>Optional: Install completion dictionary packages:</h3>
+ <blockquote>
+ <p>&#8226; Press the <b>Get dictionaries</b> button above to do a Market search.</p>
+ </blockquote>
+
+ <h2>Additional information</h2>
+ <p>Please refer to the <a href='http://code.google.com/p/hackerskeyboard/'>project web page</a> for more information, including the user's guide, issue tracker, and discussion group.</p>
+ "]]>
+ </Data></string>
+ <string name="text_test">Test</string>
+ <string name="seek_pref_0">0%</string>
+ <string name="seek_pref_val">x%</string>
+ <string name="seek_pref_max">100%</string>
+</resources>
diff --git a/java/res/values/styles.xml b/java/res/values/styles.xml
new file mode 100644
index 0000000..0f6a73e
--- /dev/null
+++ b/java/res/values/styles.xml
@@ -0,0 +1,48 @@
+<?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>
+ <style name="LatinKeyboardBaseView">
+ <item name="android:background">@drawable/keyboard_background</item>
+
+ <item name="keyBackground">@drawable/btn_keyboard_key_ics</item>
+ <item name="keyTextSize">@dimen/key_text_size</item>
+ <item name="keyTextColor">#FFFFFFFF</item>
+ <item name="keyHintColor">#FF222222</item>
+ <item name="keyCursorColor">#FFBBBBBB</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="labelTextSize">@dimen/key_label_text_size</item>
+ <item name="popupLayout">@layout/keyboard_popup</item>
+ <item name="keyHysteresisDistance">@dimen/key_hysteresis_distance</item>
+ <item name="verticalCorrection">@dimen/keyboard_vertical_correction</item>
+ <item name="shadowColor">#BB000000</item>
+ <item name="shadowRadius">2.75</item>
+ <item name="backgroundDimAmount">0.5</item>
+ <item name="symbolColorScheme">white</item>
+ <item name="recolorSymbols">false</item>
+ <item name="backgroundAlpha">255</item>
+ </style>
+ <style name="KeyPreviewAnimation">
+ <item name="android:windowEnterAnimation">@anim/key_preview_fadein</item>
+ <item name="android:windowExitAnimation">@anim/key_preview_fadeout</item>
+ </style>
+ <style name="MiniKeyboardAnimation">
+ <item name="android:windowEnterAnimation">@anim/mini_keyboard_fadein</item>
+ <item name="android:windowExitAnimation">@anim/mini_keyboard_fadeout</item>
+ </style>
+</resources>
diff --git a/java/res/xml-ar/kbd_qwerty.xml b/java/res/xml-ar/kbd_qwerty.xml
new file mode 100644
index 0000000..47fb858
--- /dev/null
+++ b/java/res/xml-ar/kbd_qwerty.xml
@@ -0,0 +1,525 @@
+<?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.
+**
+**
+** Based on Yahya Hamidaddin's layout as distributed under Apache 2.0 license:
+** http://code.google.com/p/softkeyboard/source/browse/trunk/LanguagePacks/Arabic/res/xml/arabic_qwerty.xml
+*/
+-->
+
+<Keyboard
+ xmlns:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="10%p"
+ android:horizontalGap="0px"
+ android:verticalGap="@dimen/key_bottom_gap"
+>
+ <Row
+ android:rowEdgeFlags="top"
+ >
+ <Key
+ android:keyLabel="ض"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="1ًٌٍَُِّْ"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="ص"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="2" />
+ <Key
+ android:keyLabel="ق"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="3" />
+ <Key
+ android:keyLabel="ف"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="4ڤ" />
+ <Key
+ android:keyLabel="غ"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="5" />
+ <Key
+ android:keyLabel="ع"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="6" />
+ <Key
+ android:keyLabel="ه"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="7" />
+ <Key
+ android:keyLabel="خ"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="8" />
+ <Key
+ android:keyLabel="ح"
+ android:popupKeyboard="@xml/kbd_popup_narrow_template"
+ android:popupCharacters="9" />
+ <Key
+ android:keyLabel="ج"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="0چ"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:keyLabel="ش"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters=""
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="س"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="" />
+ <Key
+ android:keyLabel="ي"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="ىئ" />
+ <Key
+ android:keyLabel="ب"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="پ" />
+ <Key
+ android:keyLabel="ل"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="" />
+ <Key
+ android:keyLabel="ا"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="أإآء" />
+ <Key
+ android:keyLabel="ت"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="" />
+ <Key
+ android:keyLabel="ن"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="" />
+ <Key
+ android:keyLabel="م"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="" />
+ <Key
+ android:keyLabel="ك"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="گ"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:keyLabel="ظ"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="؟،؛"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="ط"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="" />
+ <Key
+ android:keyLabel="ذ"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="" />
+ <Key
+ android:keyLabel="د"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="" />
+ <Key
+ android:keyLabel="ز"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="ژ" />
+ <Key
+ android:keyLabel="ر"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="" />
+ <Key
+ android:keyLabel="و"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="ؤ" />
+ <Key
+ android:keyLabel="ة"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="" />
+ <Key
+ android:keyLabel="ث"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="" />
+ <Key
+ android:codes="@integer/key_delete"
+ android:keyIcon="@drawable/sym_keyboard_delete"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:keyWidth="10%p"
+ android:isModifier="true"
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal_with_settings_key"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url_with_settings_key"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email_with_settings_key"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im_with_settings_key"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry_with_settings_key"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+</Keyboard>
diff --git a/java/res/xml-bg/kbd_qwerty.xml b/java/res/xml-bg/kbd_qwerty.xml
new file mode 100644
index 0000000..fe526d0
--- /dev/null
+++ b/java/res/xml-bg/kbd_qwerty.xml
@@ -0,0 +1,516 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<Keyboard
+ xmlns:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="8.33%p"
+ android:horizontalGap="0px"
+ android:verticalGap="@dimen/key_bottom_gap"
+>
+ <Row
+ android:rowEdgeFlags="top"
+ >
+ <Key
+ android:keyLabel="я"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="1"
+ android:keyWidth="8.75%p"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="в"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="2" />
+ <Key
+ android:keyLabel="е"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="3" />
+ <Key
+ android:keyLabel="р"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="4" />
+ <Key
+ android:keyLabel="т"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="5ё" />
+ <Key
+ android:keyLabel="ъ"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="6" />
+ <Key
+ android:keyLabel="у"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="7" />
+ <Key
+ android:keyLabel="и"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="8" />
+ <Key
+ android:keyLabel="о"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="9" />
+ <Key
+ android:keyLabel="п"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="0" />
+ <Key
+ android:keyLabel="ш"
+ android:popupCharacters="[" /> />
+
+ <Key
+ android:keyLabel="щ"
+ android:popupCharacters="]"
+ android:keyWidth="8.75%p"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyWidth="9.0909%p">
+ <Key
+ android:keyLabel="а"
+ android:keyWidth="8.75%p"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="с"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="ы" />
+ <Key
+ android:keyLabel="д" />
+ <Key
+ android:keyLabel="ф" />
+ <Key
+ android:keyLabel="г" />
+ <Key
+ android:keyLabel="х" />
+ <Key
+ android:keyLabel="й" />
+ <Key
+ android:keyLabel="к" />
+ <Key
+ android:keyLabel="л" />
+ <Key
+ android:keyLabel="ю" />
+ <Key
+ android:keyLabel="ч"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:keyWidth="8.75%p"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyWidth="10.92%p"
+ >
+ <Key
+ android:codes="@integer/key_shift"
+ android:keyIcon="@drawable/sym_keyboard_shift"
+ android:iconPreview="@drawable/sym_keyboard_feedback_shift"
+ android:keyWidth="11.75%p"
+ android:isModifier="true"
+ android:isSticky="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="з" />
+ <Key
+ android:keyLabel="ь" />
+ <Key
+ android:keyLabel="ц" />
+ <Key
+ android:keyLabel="ж" />
+ <Key
+ android:keyLabel="б" />
+ <Key
+ android:keyLabel="н" />
+ <Key
+ android:keyLabel="м" />
+ <Key
+ android:codes="@integer/key_delete"
+ android:keyIcon="@drawable/sym_keyboard_delete"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:keyWidth="11.75%p"
+ android:isModifier="true"
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="20%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:keyWidth="20%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+</Keyboard>
diff --git a/java/res/xml-cs-rQY/kbd_qwerty.xml b/java/res/xml-cs-rQY/kbd_qwerty.xml
new file mode 100644
index 0000000..9f8a1e1
--- /dev/null
+++ b/java/res/xml-cs-rQY/kbd_qwerty.xml
@@ -0,0 +1,527 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<Keyboard
+ xmlns:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="10%p"
+ android:horizontalGap="0px"
+ android:verticalGap="@dimen/key_bottom_gap"
+>
+ <Row
+ android:rowEdgeFlags="top"
+ >
+ <Key
+ android:keyLabel="q"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_q"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="w"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_w" />
+ <Key
+ android:keyLabel="e"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_e" />
+ <Key
+ android:keyLabel="r"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_r" />
+ <Key
+ android:keyLabel="t"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_t" />
+ <Key
+ android:keyLabel="y"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_y" />
+ <Key
+ android:keyLabel="u"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_u" />
+ <Key
+ android:keyLabel="i"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_i" />
+ <Key
+ android:keyLabel="o"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_o" />
+ <Key
+ android:keyLabel="p"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_p"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:keyLabel="a"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_a"
+ android:horizontalGap="5%p"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="s"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_s" />
+ <Key
+ android:keyLabel="d"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_d" />
+ <Key
+ android:keyLabel="f"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_f" />
+ <Key
+ android:keyLabel="g"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_g" />
+ <Key
+ android:keyLabel="h"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_h" />
+ <Key
+ android:keyLabel="j"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_j" />
+ <Key
+ android:keyLabel="k"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_k" />
+ <Key
+ android:keyLabel="l"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_l"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:codes="@integer/key_shift"
+ android:keyIcon="@drawable/sym_keyboard_shift"
+ android:iconPreview="@drawable/sym_keyboard_feedback_shift"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:isSticky="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="z"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_z" />
+ <Key
+ android:keyLabel="x"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_x" />
+ <Key
+ android:keyLabel="c"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_c" />
+ <Key
+ android:keyLabel="v"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_v" />
+ <Key
+ android:keyLabel="b"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_b" />
+ <Key
+ android:keyLabel="n"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_n" />
+ <Key
+ android:keyLabel="m"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_m" />
+ <Key
+ android:codes="@integer/key_delete"
+ android:keyIcon="@drawable/sym_keyboard_delete"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+</Keyboard>
diff --git a/java/res/xml-cs/kbd_qwerty.xml b/java/res/xml-cs/kbd_qwerty.xml
new file mode 100644
index 0000000..de86879
--- /dev/null
+++ b/java/res/xml-cs/kbd_qwerty.xml
@@ -0,0 +1,527 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<Keyboard
+ xmlns:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="10%p"
+ android:horizontalGap="0px"
+ android:verticalGap="@dimen/key_bottom_gap"
+>
+ <Row
+ android:rowEdgeFlags="top"
+ >
+ <Key
+ android:keyLabel="q"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_q"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="w"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_w" />
+ <Key
+ android:keyLabel="e"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_e" />
+ <Key
+ android:keyLabel="r"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_r" />
+ <Key
+ android:keyLabel="t"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_t" />
+ <Key
+ android:keyLabel="z"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_z" />
+ <Key
+ android:keyLabel="u"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_u" />
+ <Key
+ android:keyLabel="i"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_i" />
+ <Key
+ android:keyLabel="o"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_o" />
+ <Key
+ android:keyLabel="p"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_p"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:keyLabel="a"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_a"
+ android:horizontalGap="5%p"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="s"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_s" />
+ <Key
+ android:keyLabel="d"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_d" />
+ <Key
+ android:keyLabel="f"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_f" />
+ <Key
+ android:keyLabel="g"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_g" />
+ <Key
+ android:keyLabel="h"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_h" />
+ <Key
+ android:keyLabel="j"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_j" />
+ <Key
+ android:keyLabel="k"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_k" />
+ <Key
+ android:keyLabel="l"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_l"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:codes="@integer/key_shift"
+ android:keyIcon="@drawable/sym_keyboard_shift"
+ android:iconPreview="@drawable/sym_keyboard_feedback_shift"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:isSticky="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="y"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_y" />
+ <Key
+ android:keyLabel="x"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_x" />
+ <Key
+ android:keyLabel="c"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_c" />
+ <Key
+ android:keyLabel="v"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_v" />
+ <Key
+ android:keyLabel="b"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_b" />
+ <Key
+ android:keyLabel="n"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_n" />
+ <Key
+ android:keyLabel="m"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_m" />
+ <Key
+ android:codes="@integer/key_delete"
+ android:keyIcon="@drawable/sym_keyboard_delete"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+</Keyboard>
diff --git a/java/res/xml-da/kbd_qwerty.xml b/java/res/xml-da/kbd_qwerty.xml
new file mode 100644
index 0000000..3beebd8
--- /dev/null
+++ b/java/res/xml-da/kbd_qwerty.xml
@@ -0,0 +1,532 @@
+<?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.
+*/
+-->
+
+<!--
+ Norwegian Keyboard Layout
+
+ Just a copy of the Swedish layout, with ä/æ and ö/ø switched.
+-->
+
+<Keyboard
+ xmlns:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="9.09%p"
+ android:horizontalGap="0px"
+ android:verticalGap="@dimen/key_bottom_gap"
+>
+ <Row
+ android:rowEdgeFlags="top"
+ >
+ <Key
+ android:keyLabel="q"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_q"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="w"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_w" />
+ <Key
+ android:keyLabel="e"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_e" />
+ <Key
+ android:keyLabel="r"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_r" />
+ <Key
+ android:keyLabel="t"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_t" />
+ <Key
+ android:keyLabel="y"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_y" />
+ <Key
+ android:keyLabel="u"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_u" />
+ <Key
+ android:keyLabel="i"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_i" />
+ <Key
+ android:keyLabel="o"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_o" />
+ <Key
+ android:keyLabel="p"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_p" />
+ <Key
+ android:keyLabel="å"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:keyLabel="a"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_a"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="s"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_s" />
+ <Key
+ android:keyLabel="d"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_d" />
+ <Key
+ android:keyLabel="f" />
+ <Key
+ android:keyLabel="g"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_g" />
+ <Key
+ android:keyLabel="h" />
+ <Key
+ android:keyLabel="j" />
+ <Key
+ android:keyLabel="k" />
+ <Key
+ android:keyLabel="l"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_l" />
+ <Key
+ android:keyLabel="æ"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_ae" />
+ <Key
+ android:keyLabel="ø"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_oe"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:codes="@integer/key_shift"
+ android:keyIcon="@drawable/sym_keyboard_shift"
+ android:iconPreview="@drawable/sym_keyboard_feedback_shift"
+ android:keyWidth="13.63%p"
+ android:isModifier="true"
+ android:isSticky="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="z"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_z" />
+ <Key
+ android:keyLabel="x" />
+ <Key
+ android:keyLabel="c"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_c" />
+ <Key
+ android:keyLabel="v"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_v" />
+ <Key
+ android:keyLabel="b" />
+ <Key
+ android:keyLabel="n"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_n" />
+ <Key
+ android:keyLabel="m" />
+ <Key
+ android:keyLabel="\'"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="&#x300;&#x301;&#x302;&#x308;&#x303;" />
+ <Key
+ android:codes="@integer/key_delete"
+ android:keyIcon="@drawable/sym_keyboard_delete"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:keyWidth="13.63%p"
+ android:isModifier="true"
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+</Keyboard>
diff --git a/java/res/xml-de/kbd_qwerty.xml b/java/res/xml-de/kbd_qwerty.xml
new file mode 100644
index 0000000..8c052f3
--- /dev/null
+++ b/java/res/xml-de/kbd_qwerty.xml
@@ -0,0 +1,513 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<Keyboard
+ xmlns:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="10%p"
+ android:horizontalGap="0px"
+ android:verticalGap="@dimen/key_bottom_gap"
+>
+ <Row
+ android:rowEdgeFlags="top"
+ >
+ <Key
+ android:keyLabel="q"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_q"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="w"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_w" />
+ <Key
+ android:keyLabel="e"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_e" />
+ <Key
+ android:keyLabel="r"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_r" />
+ <Key
+ android:keyLabel="t"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_t" />
+ <Key
+ android:keyLabel="z"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_z" />
+ <Key
+ android:keyLabel="u"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_u" />
+ <Key
+ android:keyLabel="i"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_i" />
+ <Key
+ android:keyLabel="o"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_o" />
+ <Key
+ android:keyLabel="p"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_p"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:keyLabel="a"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_a"
+ android:horizontalGap="5%p"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="s"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_s" />
+ <Key
+ android:keyLabel="d"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_d" />
+ <Key
+ android:keyLabel="f" />
+ <Key
+ android:keyLabel="g"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_g" />
+ <Key
+ android:keyLabel="h" />
+ <Key
+ android:keyLabel="j" />
+ <Key
+ android:keyLabel="k" />
+ <Key
+ android:keyLabel="l"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_l"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:codes="@integer/key_shift"
+ android:keyIcon="@drawable/sym_keyboard_shift"
+ android:iconPreview="@drawable/sym_keyboard_feedback_shift"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:isSticky="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="y"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_y" />
+ <Key
+ android:keyLabel="x" />
+ <Key
+ android:keyLabel="c"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_c" />
+ <Key
+ android:keyLabel="v"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_v" />
+ <Key
+ android:keyLabel="b" />
+ <Key
+ android:keyLabel="n"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_n" />
+ <Key
+ android:keyLabel="m" />
+ <Key
+ android:codes="@integer/key_delete"
+ android:keyIcon="@drawable/sym_keyboard_delete"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+</Keyboard>
diff --git a/java/res/xml-el/kbd_qwerty.xml b/java/res/xml-el/kbd_qwerty.xml
new file mode 100644
index 0000000..897a26f
--- /dev/null
+++ b/java/res/xml-el/kbd_qwerty.xml
@@ -0,0 +1,136 @@
+<?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
+**
+** 4-row layout for Greek Keyboard
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT 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:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard" android:keyWidth="10%p" android:horizontalGap="0px" android:verticalGap="@dimen/key_bottom_gap">
+ <Row android:rowEdgeFlags="top">
+ <Key android:keyLabel=";" android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters=";:&#301;&#308;&#300;&#306;&#304;&#302;&#313;&#314;"
+ android:keyEdgeFlags="left"/>
+ <Key android:keyLabel="ς" android:popupKeyboard="@xml/kbd_popup_template" android:popupCharacters="ςΣσ"/>
+ <Key android:keyLabel="ε" android:popupKeyboard="@xml/kbd_popup_template" android:popupCharacters="εΕέΈ"/>
+ <Key android:keyLabel="ρ" android:popupKeyboard="@xml/kbd_popup_template" android:popupCharacters="ρΡ"/>
+ <Key android:keyLabel="τ" android:popupKeyboard="@xml/kbd_popup_template" android:popupCharacters="τΤ"/>
+ <Key android:keyLabel="υ" android:popupKeyboard="@xml/kbd_popup_template" android:popupCharacters="υΥύΎϋΫΰ"/>
+ <Key android:keyLabel="θ" android:popupKeyboard="@xml/kbd_popup_template" android:popupCharacters="θΘ"/>
+ <Key android:keyLabel="ι" android:popupKeyboard="@xml/kbd_popup_template" android:popupCharacters="ιΙίΊϊΪΐ"/>
+ <Key android:keyLabel="ο" android:popupKeyboard="@xml/kbd_popup_narrow_template" android:popupCharacters="οΟόΌ"/>
+ <Key android:keyLabel="π" android:popupKeyboard="@xml/kbd_popup_template" android:popupCharacters="πΠ" android:keyEdgeFlags="right"/>
+ </Row>
+ <Row>
+ <Key android:keyLabel="α" android:popupKeyboard="@xml/kbd_popup_template" android:popupCharacters="αΑάΆ" android:horizontalGap="5%p" android:keyEdgeFlags="left"/>
+ <Key android:keyLabel="σ" android:popupKeyboard="@xml/kbd_popup_template" android:popupCharacters="σΣς"/>
+ <Key android:keyLabel="δ" android:popupKeyboard="@xml/kbd_popup_template" android:popupCharacters="δΔ"/>
+ <Key android:keyLabel="φ" android:popupKeyboard="@xml/kbd_popup_template" android:popupCharacters="φΦ"/>
+ <Key android:keyLabel="γ" android:popupKeyboard="@xml/kbd_popup_template" android:popupCharacters="γΓ"/>
+ <Key android:keyLabel="η" android:popupKeyboard="@xml/kbd_popup_template" android:popupCharacters="ηΗήΉ"/>
+ <Key android:keyLabel="ξ" android:popupKeyboard="@xml/kbd_popup_template" android:popupCharacters="ξΞ"/>
+ <Key android:keyLabel="κ" android:popupKeyboard="@xml/kbd_popup_template" android:popupCharacters="κΚ"/>
+ <Key android:keyLabel="λ" android:popupKeyboard="@xml/kbd_popup_template" android:popupCharacters="λΛ" android:keyEdgeFlags="right"/>
+ </Row>
+ <Row>
+ <Key android:codes="@integer/key_shift" android:keyIcon="@drawable/sym_keyboard_shift" android:iconPreview="@drawable/sym_keyboard_feedback_shift" android:keyWidth="15%p" android:isModifier="true" android:isSticky="true" android:keyEdgeFlags="left"/>
+ <Key android:keyLabel="ζ" android:popupKeyboard="@xml/kbd_popup_template" android:popupCharacters="ζΖ"/>
+ <Key android:keyLabel="χ" android:popupKeyboard="@xml/kbd_popup_template" android:popupCharacters="χΧ"/>
+ <Key android:keyLabel="ψ" android:popupKeyboard="@xml/kbd_popup_template" android:popupCharacters="ψΨ"/>
+ <Key android:keyLabel="ω" android:popupKeyboard="@xml/kbd_popup_template" android:popupCharacters="ωΩώΏ"/>
+ <Key android:keyLabel="β" android:popupKeyboard="@xml/kbd_popup_template" android:popupCharacters="βΒ"/>
+ <Key android:keyLabel="ν" android:popupKeyboard="@xml/kbd_popup_template" android:popupCharacters="νΝ"/>
+ <Key android:keyLabel="μ" android:popupKeyboard="@xml/kbd_popup_template" android:popupCharacters="μΜ"/>
+ <Key android:codes="@integer/key_delete" android:keyIcon="@drawable/sym_keyboard_delete" android:iconPreview="@drawable/sym_keyboard_feedback_delete" android:keyWidth="15%p" android:isModifier="true" android:isRepeatable="true" android:keyEdgeFlags="right"/>
+ </Row>
+ <Row android:keyboardMode="@+id/mode_normal" android:rowEdgeFlags="bottom">
+ <Key android:codes="@integer/key_symbol" android:keyLabel="@string/label_symbol_key" android:keyWidth="20%p" android:isModifier="true" android:keyEdgeFlags="left"/>
+ <Key android:codes="@integer/key_f1" android:isModifier="true"/>
+ <Key android:codes="@integer/key_space" android:keyIcon="@drawable/sym_keyboard_space" android:iconPreview="@drawable/sym_keyboard_feedback_space" android:keyWidth="40%p" android:isModifier="true"/>
+ <Key android:keyLabel="." android:keyIcon="@drawable/hint_popup" android:popupKeyboard="@xml/popup_punctuation" android:isModifier="true"/>
+ <Key android:codes="@integer/key_return" android:keyIcon="@drawable/sym_keyboard_return" android:iconPreview="@drawable/sym_keyboard_feedback_return" android:keyWidth="20%p" android:isModifier="true" android:keyEdgeFlags="right"/>
+ </Row>
+ <Row android:keyboardMode="@+id/mode_url" android:rowEdgeFlags="bottom">
+ <Key android:codes="@integer/key_symbol" android:keyLabel="@string/label_symbol_key" android:keyWidth="20%p" android:isModifier="true" android:keyEdgeFlags="left"/>
+ <Key android:codes="@integer/key_f1" android:isModifier="true"/>
+ <Key android:codes="@integer/key_space" android:keyIcon="@drawable/sym_keyboard_space" android:iconPreview="@drawable/sym_keyboard_feedback_space" android:keyWidth="40%p" android:isModifier="true"/>
+ <Key android:keyLabel="." android:keyIcon="@drawable/hint_popup" android:popupKeyboard="@xml/popup_punctuation" android:isModifier="true"/>
+ <Key android:codes="@integer/key_return" android:keyIcon="@drawable/sym_keyboard_return" android:iconPreview="@drawable/sym_keyboard_feedback_return" android:keyWidth="20%p" android:isModifier="true" android:keyEdgeFlags="right"/>
+ </Row>
+ <Row android:keyboardMode="@+id/mode_email" android:rowEdgeFlags="bottom">
+ <Key android:codes="@integer/key_symbol" android:keyLabel="@string/label_symbol_key" android:keyWidth="20%p" android:isModifier="true" android:keyEdgeFlags="left"/>
+ <Key android:codes="@integer/key_f1" android:isModifier="true"/>
+ <Key android:codes="@integer/key_space" android:keyIcon="@drawable/sym_keyboard_space" android:iconPreview="@drawable/sym_keyboard_feedback_space" android:keyWidth="40%p" android:isModifier="true"/>
+ <Key android:keyLabel="." android:keyIcon="@drawable/hint_popup" android:popupKeyboard="@xml/popup_punctuation" android:isModifier="true"/>
+ <Key android:codes="@integer/key_return" android:keyIcon="@drawable/sym_keyboard_return" android:iconPreview="@drawable/sym_keyboard_feedback_return" android:keyWidth="20%p" android:isModifier="true" android:keyEdgeFlags="right"/>
+ </Row>
+ <Row android:keyboardMode="@+id/mode_im" android:rowEdgeFlags="bottom">
+ <Key android:codes="@integer/key_symbol" android:keyLabel="@string/label_symbol_key" android:keyWidth="20%p" android:isModifier="true" android:keyEdgeFlags="left"/>
+ <Key android:codes="@integer/key_f1" android:isModifier="true"/>
+ <Key android:codes="@integer/key_space" android:keyIcon="@drawable/sym_keyboard_space" android:iconPreview="@drawable/sym_keyboard_feedback_space" android:keyWidth="40%p" android:isModifier="true"/>
+ <Key android:keyLabel="." android:keyIcon="@drawable/hint_popup" android:popupKeyboard="@xml/popup_punctuation" android:isModifier="true"/>
+ <Key android:keyLabel=":-)" android:keyOutputText=":-) " android:keyIcon="@drawable/hint_popup" android:popupKeyboard="@xml/popup_smileys" android:keyWidth="20%p" android:isModifier="true" android:keyEdgeFlags="right"/>
+ </Row>
+ <Row android:keyboardMode="@+id/mode_webentry" android:rowEdgeFlags="bottom">
+ <Key android:codes="@integer/key_symbol" android:keyLabel="@string/label_symbol_key" android:keyWidth="20%p" android:isModifier="true" android:keyEdgeFlags="left"/>
+ <Key android:codes="@integer/key_f1" android:isModifier="true"/>
+ <Key android:codes="@integer/key_space" android:keyIcon="@drawable/sym_keyboard_space" android:iconPreview="@drawable/sym_keyboard_feedback_space" android:keyWidth="30%p" android:isModifier="true"/>
+ <Key android:codes="@integer/key_tab" android:keyIcon="@drawable/sym_keyboard_tab" android:iconPreview="@drawable/sym_keyboard_feedback_tab" android:isModifier="true"/>
+ <Key android:keyLabel="." android:keyIcon="@drawable/hint_popup" android:popupKeyboard="@xml/popup_punctuation" android:isModifier="true"/>
+ <Key android:codes="@integer/key_return" android:keyIcon="@drawable/sym_keyboard_return" android:iconPreview="@drawable/sym_keyboard_feedback_return" android:keyWidth="20%p" android:isModifier="true" android:keyEdgeFlags="right"/>
+ </Row>
+ <Row android:keyboardMode="@+id/mode_normal_with_settings_key" android:rowEdgeFlags="bottom">
+ <Key android:codes="@integer/key_symbol" android:keyLabel="@string/label_symbol_key" android:keyWidth="15%p" android:isModifier="true" android:keyEdgeFlags="left"/>
+ <Key android:codes="@integer/key_settings" android:keyIcon="@drawable/sym_keyboard_settings" android:iconPreview="@drawable/sym_keyboard_feedback_settings" android:isModifier="true"/>
+ <Key android:codes="@integer/key_f1" android:isModifier="true"/>
+ <Key android:codes="@integer/key_space" android:keyIcon="@drawable/sym_keyboard_space" android:iconPreview="@drawable/sym_keyboard_feedback_space" android:keyWidth="30%p" android:isModifier="true"/>
+ <Key android:keyLabel="." android:keyIcon="@drawable/hint_popup" android:popupKeyboard="@xml/popup_punctuation" android:isModifier="true"/>
+ <Key android:codes="@integer/key_return" android:keyIcon="@drawable/sym_keyboard_return" android:iconPreview="@drawable/sym_keyboard_feedback_return" android:keyWidth="25%p" android:isModifier="true" android:keyEdgeFlags="right"/>
+ </Row>
+ <Row android:keyboardMode="@+id/mode_url_with_settings_key" android:rowEdgeFlags="bottom">
+ <Key android:codes="@integer/key_symbol" android:keyLabel="@string/label_symbol_key" android:keyWidth="15%p" android:isModifier="true" android:keyEdgeFlags="left"/>
+ <Key android:codes="@integer/key_settings" android:keyIcon="@drawable/sym_keyboard_settings" android:iconPreview="@drawable/sym_keyboard_feedback_settings" android:isModifier="true"/>
+ <Key android:codes="@integer/key_f1" android:isModifier="true"/>
+ <Key android:codes="@integer/key_space" android:keyIcon="@drawable/sym_keyboard_space" android:iconPreview="@drawable/sym_keyboard_feedback_space" android:keyWidth="30%p" android:isModifier="true"/>
+ <Key android:keyLabel="." android:keyIcon="@drawable/hint_popup" android:popupKeyboard="@xml/popup_punctuation" android:isModifier="true"/>
+ <Key android:codes="@integer/key_return" android:keyIcon="@drawable/sym_keyboard_return" android:iconPreview="@drawable/sym_keyboard_feedback_return" android:keyWidth="25%p" android:isModifier="true" android:keyEdgeFlags="right"/>
+ </Row>
+ <Row android:keyboardMode="@+id/mode_email_with_settings_key" android:rowEdgeFlags="bottom">
+ <Key android:codes="@integer/key_symbol" android:keyLabel="@string/label_symbol_key" android:keyWidth="15%p" android:isModifier="true" android:keyEdgeFlags="left"/>
+ <Key android:codes="@integer/key_settings" android:keyIcon="@drawable/sym_keyboard_settings" android:iconPreview="@drawable/sym_keyboard_feedback_settings" android:isModifier="true"/>
+ <Key android:codes="@integer/key_f1" android:isModifier="true"/>
+ <Key android:codes="@integer/key_space" android:keyIcon="@drawable/sym_keyboard_space" android:iconPreview="@drawable/sym_keyboard_feedback_space" android:keyWidth="30%p" android:isModifier="true"/>
+ <Key android:keyLabel="." android:keyIcon="@drawable/hint_popup" android:popupKeyboard="@xml/popup_punctuation" android:isModifier="true"/>
+ <Key android:codes="@integer/key_return" android:keyIcon="@drawable/sym_keyboard_return" android:iconPreview="@drawable/sym_keyboard_feedback_return" android:keyWidth="25%p" android:isModifier="true" android:keyEdgeFlags="right"/>
+ </Row>
+ <Row android:keyboardMode="@+id/mode_im_with_settings_key" android:rowEdgeFlags="bottom">
+ <Key android:codes="@integer/key_symbol" android:keyLabel="@string/label_symbol_key" android:keyWidth="15%p" android:isModifier="true" android:keyEdgeFlags="left"/>
+ <Key android:codes="@integer/key_settings" android:keyIcon="@drawable/sym_keyboard_settings" android:iconPreview="@drawable/sym_keyboard_feedback_settings" android:isModifier="true"/>
+ <Key android:codes="@integer/key_f1" android:isModifier="true"/>
+ <Key android:codes="@integer/key_space" android:keyIcon="@drawable/sym_keyboard_space" android:iconPreview="@drawable/sym_keyboard_feedback_space" android:keyWidth="30%p" android:isModifier="true"/>
+ <Key android:keyLabel="." android:keyIcon="@drawable/hint_popup" android:popupKeyboard="@xml/popup_punctuation" android:isModifier="true"/>
+ <Key android:keyLabel=":-)" android:keyOutputText=":-) " android:keyIcon="@drawable/hint_popup" android:popupKeyboard="@xml/popup_smileys" android:keyWidth="25%p" android:isModifier="true" android:keyEdgeFlags="right"/>
+ </Row>
+ <Row android:keyboardMode="@+id/mode_webentry_with_settings_key" android:rowEdgeFlags="bottom">
+ <Key android:codes="@integer/key_symbol" android:keyLabel="@string/label_symbol_key" android:keyWidth="15%p" android:isModifier="true" android:keyEdgeFlags="left"/>
+ <Key android:codes="@integer/key_settings" android:keyIcon="@drawable/sym_keyboard_settings" android:iconPreview="@drawable/sym_keyboard_feedback_settings" android:isModifier="true"/>
+ <Key android:codes="@integer/key_f1" android:isModifier="true"/>
+ <Key android:codes="@integer/key_space" android:keyIcon="@drawable/sym_keyboard_space" android:iconPreview="@drawable/sym_keyboard_feedback_space" android:keyWidth="30%p" android:isModifier="true"/>
+ <Key android:codes="@integer/key_tab" android:keyIcon="@drawable/sym_keyboard_tab" android:iconPreview="@drawable/sym_keyboard_feedback_tab" android:isModifier="true"/>
+ <Key android:keyLabel="." android:keyIcon="@drawable/hint_popup" android:popupKeyboard="@xml/popup_punctuation" android:isModifier="true"/>
+ <Key android:codes="@integer/key_return" android:keyIcon="@drawable/sym_keyboard_return" android:iconPreview="@drawable/sym_keyboard_feedback_return" android:keyWidth="15%p" android:isModifier="true" android:keyEdgeFlags="right"/>
+ </Row>
+</Keyboard> \ No newline at end of file
diff --git a/java/res/xml-en-rDV/kbd_qwerty.xml b/java/res/xml-en-rDV/kbd_qwerty.xml
new file mode 100644
index 0000000..5ed6566
--- /dev/null
+++ b/java/res/xml-en-rDV/kbd_qwerty.xml
@@ -0,0 +1,538 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<Keyboard
+ xmlns:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="9.09090909%p"
+ android:horizontalGap="0px"
+ android:verticalGap="@dimen/key_bottom_gap"
+>
+ <Row
+ android:rowEdgeFlags="top"
+ >
+ <Key
+ android:keyLabel="\'"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="1&quot;~`"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel=","
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="2&lt;" />
+ <Key
+ android:keyLabel="."
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="3&gt;" />
+ <Key
+ android:keyLabel="p"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_p" />
+ <Key
+ android:keyLabel="y"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_y" />
+ <Key
+ android:keyLabel="f"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_f" />
+ <Key
+ android:keyLabel="g"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_g" />
+ <Key
+ android:keyLabel="c"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_c" />
+ <Key
+ android:keyLabel="r"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_r" />
+ <Key
+ android:keyLabel="l"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_l" />
+ <Key
+ android:codes="@integer/key_delete"
+ android:keyIcon="@drawable/sym_keyboard_delete"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:isModifier="true"
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:keyLabel="a"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_a"
+ android:horizontalGap="4.5454545%p"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="o"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_o" />
+ <Key
+ android:keyLabel="e"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_e" />
+ <Key
+ android:keyLabel="u"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_u" />
+ <Key
+ android:keyLabel="i"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_i" />
+ <Key
+ android:keyLabel="d"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_d" />
+ <Key
+ android:keyLabel="h"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_h" />
+ <Key
+ android:keyLabel="t"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_t" />
+ <Key
+ android:keyLabel="n"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_n" />
+ <Key
+ android:keyLabel="s"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_s"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:codes="@integer/key_shift"
+ android:keyIcon="@drawable/sym_keyboard_shift"
+ android:iconPreview="@drawable/sym_keyboard_feedback_shift"
+ android:keyWidth="18.18181818%p"
+ android:isModifier="true"
+ android:isSticky="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="q"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_q" />
+ <Key
+ android:keyLabel="j"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_j" />
+ <Key
+ android:keyLabel="k"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_k" />
+ <Key
+ android:keyLabel="x"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_x" />
+ <Key
+ android:keyLabel="b"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_b" />
+ <Key
+ android:keyLabel="m"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_m" />
+ <Key
+ android:keyLabel="w"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_w" />
+ <Key
+ android:keyLabel="v"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_v" />
+ <Key
+ android:keyLabel="z"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_z"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+</Keyboard>
diff --git a/java/res/xml-en/kbd_extension.xml b/java/res/xml-en/kbd_extension.xml
new file mode 100644
index 0000000..96c88b4
--- /dev/null
+++ b/java/res/xml-en/kbd_extension.xml
@@ -0,0 +1,61 @@
+<?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.
+*/
+ android:keyHeight="@dimen/key_height"
+-->
+
+<Keyboard xmlns:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="10%p"
+ android:horizontalGap="0px"
+ android:verticalGap="0px"
+ >
+
+ <Row android:rowEdgeFlags="top">
+ <Key android:keyLabel="!" android:keyEdgeFlags="left"/>
+ <Key android:keyLabel="\@"/>
+ <Key android:keyLabel="\#"/>
+ <Key android:keyLabel="&amp;"/>
+ <Key android:keyLabel="-"/>
+ <Key android:keyLabel="\'"/>
+ <Key android:keyLabel=":"/>
+ <Key android:keyLabel="&quot;"/>
+ <Key android:keyLabel="/"/>
+ <Key android:keyLabel="\?" android:keyEdgeFlags="right"
+ />
+ </Row>
+
+ <Row android:rowEdgeFlags="bottom">
+ <Key android:codes="49" android:keyLabel="1" android:keyEdgeFlags="left"
+ />
+ <Key android:codes="50" android:keyLabel="2"
+ />
+ <Key android:codes="51" android:keyLabel="3"
+ />
+ <Key android:codes="52" android:keyLabel="4"
+ />
+ <Key android:codes="53" android:keyLabel="5"
+ />
+ <Key android:codes="54" android:keyLabel="6"/>
+ <Key android:codes="55" android:keyLabel="7"
+ />
+ <Key android:codes="56" android:keyLabel="8"/>
+ <Key android:codes="57" android:keyLabel="9"/>
+ <Key android:codes="48" android:keyLabel="0"
+ android:keyEdgeFlags="right"/>
+ </Row>
+</Keyboard>
diff --git a/java/res/xml-en/kbd_qwerty.xml b/java/res/xml-en/kbd_qwerty.xml
new file mode 100644
index 0000000..ed247fa
--- /dev/null
+++ b/java/res/xml-en/kbd_qwerty.xml
@@ -0,0 +1,527 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<Keyboard
+ xmlns:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="10%p"
+ android:horizontalGap="0px"
+ android:verticalGap="@dimen/key_bottom_gap"
+>
+ <Row android:extension="true">
+ <Key android:keyLabel="1" android:shiftLabel="!" />
+ <Key android:keyLabel="2" android:shiftLabel="\@" />
+ <Key android:keyLabel="3" android:shiftLabel="\#" />
+ <Key android:keyLabel="4" android:shiftLabel="&amp;" />
+ <Key android:keyLabel="5" android:shiftLabel="-" />
+ <Key android:keyLabel="6" android:shiftLabel="\'" />
+ <Key android:keyLabel="7" android:shiftLabel=":" />
+ <Key android:keyLabel="8" android:shiftLabel="&quot;" />
+ <Key android:keyLabel="9" android:shiftLabel="/" />
+ <Key android:keyLabel="0" android:shiftLabel="\?" />
+ </Row>
+ <Row>
+ <Key
+ android:keyLabel="q"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_q"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="w"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_w" />
+ <Key
+ android:keyLabel="e"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_e" />
+ <Key
+ android:keyLabel="r"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_r" />
+ <Key
+ android:keyLabel="t"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_t" />
+ <Key
+ android:keyLabel="y"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_y" />
+ <Key
+ android:keyLabel="u"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_u" />
+ <Key
+ android:keyLabel="i"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_i" />
+ <Key
+ android:keyLabel="o"
+ android:popupKeyboard="@xml/kbd_popup_narrow_template"
+ android:popupCharacters="@string/alternates_for_o" />
+ <Key
+ android:keyLabel="p"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_p"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:keyLabel="a"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_a"
+ android:horizontalGap="5%p"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="s"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_s" />
+ <Key
+ android:keyLabel="d"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_d" />
+ <Key
+ android:keyLabel="f"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_f" />
+ <Key
+ android:keyLabel="g"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_g" />
+ <Key
+ android:keyLabel="h"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_h" />
+ <Key
+ android:keyLabel="j"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_j" />
+ <Key
+ android:keyLabel="k"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_k" />
+ <Key
+ android:keyLabel="l"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_l"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:codes="@integer/key_shift"
+ android:keyIcon="@drawable/sym_keyboard_shift"
+ android:iconPreview="@drawable/sym_keyboard_feedback_shift"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:isSticky="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="z"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_z" />
+ <Key
+ android:keyLabel="x"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_x" />
+ <Key
+ android:keyLabel="c"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_c" />
+ <Key
+ android:keyLabel="v"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_v" />
+ <Key
+ android:keyLabel="b"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_b" />
+ <Key
+ android:keyLabel="n"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_n" />
+ <Key
+ android:keyLabel="m"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_m" />
+ <Key
+ android:codes="@integer/key_delete"
+ android:keyIcon="@drawable/sym_keyboard_delete"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal_with_settings_key"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url_with_settings_key"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email_with_settings_key"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im_with_settings_key"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry_with_settings_key"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+</Keyboard>
diff --git a/java/res/xml-en/kbd_symbols.xml b/java/res/xml-en/kbd_symbols.xml
new file mode 100644
index 0000000..82eebbb
--- /dev/null
+++ b/java/res/xml-en/kbd_symbols.xml
@@ -0,0 +1,213 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<Keyboard
+ xmlns:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="10%p"
+ android:horizontalGap="0px"
+ android:verticalGap="@dimen/key_bottom_gap"
+>
+ <Row
+ android:rowEdgeFlags="top"
+ >
+ <Key
+ android:keyLabel="1"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="¹½⅓¼⅛"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="2"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="²⅔" />
+ <Key
+ android:keyLabel="3"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="³¾⅜" />
+ <Key
+ android:keyLabel="4"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="⁴" />
+ <Key
+ android:keyLabel="5"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="⅝" />
+ <Key
+ android:keyLabel="6" />
+ <Key
+ android:keyLabel="7"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="⅞" />
+ <Key
+ android:keyLabel="8" />
+ <Key
+ android:keyLabel="9" />
+ <Key
+ android:keyLabel="0"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="ⁿ∅"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:keyLabel="\@"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="\#" />
+ <Key
+ android:keyLabel="$"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="¢£€¥₣₤₱" />
+ <Key
+ android:keyLabel="%"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="‰" />
+ <Key
+ android:keyLabel="&amp;" />
+ <Key
+ android:keyLabel="*"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="†‡★" />
+ <Key
+ android:keyLabel="-"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="_–—" />
+ <Key
+ android:keyLabel="+"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="±" />
+ <Key
+ android:keyLabel="("
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="[{&lt;" />
+ <Key
+ android:keyLabel=")"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="]}&gt;"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:codes="@integer/key_shift"
+ android:keyLabel="@string/label_alt_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:isSticky="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="!"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="¡" />
+ <Key
+ android:keyLabel="&quot;"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="“”«»˝" />
+ <Key
+ android:keyLabel="\'"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="‘’" />
+ <Key
+ android:keyLabel=":" />
+ <Key
+ android:keyLabel=";" />
+ <Key
+ android:keyLabel="/" />
+ <Key
+ android:keyLabel="\?"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="¿" />
+ <Key
+ android:codes="@integer/key_delete"
+ android:keyIcon="@drawable/sym_keyboard_delete"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_symbols"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_alpha_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_symbols_with_settings_key"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_alpha_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+</Keyboard>
diff --git a/java/res/xml-fa/kbd_qwerty.xml b/java/res/xml-fa/kbd_qwerty.xml
new file mode 100644
index 0000000..0c506af
--- /dev/null
+++ b/java/res/xml-fa/kbd_qwerty.xml
@@ -0,0 +1,525 @@
+<?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.
+**
+**
+** Based on Yahya Hamidaddin's layout as distributed under Apache 2.0 license:
+** http://code.google.com/p/softkeyboard/source/browse/trunk/LanguagePacks/Arabic/res/xml/arabic_qwerty.xml
+*/
+-->
+
+<Keyboard
+ xmlns:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="10%p"
+ android:horizontalGap="0px"
+ android:verticalGap="@dimen/key_bottom_gap"
+>
+ <Row
+ android:rowEdgeFlags="top"
+ >
+ <Key
+ android:keyLabel="ض"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="۱"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="ص"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="۲" />
+ <Key
+ android:keyLabel="ق"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="۳" />
+ <Key
+ android:keyLabel="ف"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="۴" />
+ <Key
+ android:keyLabel="غ"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="۵" />
+ <Key
+ android:keyLabel="ع"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="۶" />
+ <Key
+ android:keyLabel="ه"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="۷" />
+ <Key
+ android:keyLabel="خ"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="۸" />
+ <Key
+ android:keyLabel="ح"
+ android:popupKeyboard="@xml/kbd_popup_narrow_template"
+ android:popupCharacters="۹" />
+ <Key
+ android:keyLabel="ج"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="۰"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:keyLabel="ش"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters=""
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="س"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="" />
+ <Key
+ android:keyLabel="ی"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="ٔئ" />
+ <Key
+ android:keyLabel="ب"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="" />
+ <Key
+ android:keyLabel="ل"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="" />
+ <Key
+ android:keyLabel="ا"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="آءأإ" />
+ <Key
+ android:keyLabel="ت"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="ثة" />
+ <Key
+ android:keyLabel="ن"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="ّْ" />
+ <Key
+ android:keyLabel="م"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="ًٌٍ" />
+ <Key
+ android:keyLabel="چ"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="َُِ"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:keyLabel="ظ"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters=""
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="ط"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="" />
+ <Key
+ android:keyLabel="ز"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="ژ" />
+ <Key
+ android:keyLabel="ر"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="" />
+ <Key
+ android:keyLabel="د"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="ذ" />
+ <Key
+ android:keyLabel="پ"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="&#x200c;" />
+ <Key
+ android:keyLabel="و"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="ؤ" />
+ <Key
+ android:keyLabel="ک"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="«»*-_" />
+ <Key
+ android:keyLabel="گ"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="!؟،:؛" />
+ <Key
+ android:codes="@integer/key_delete"
+ android:keyIcon="@drawable/sym_keyboard_delete"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:keyWidth="10%p"
+ android:isModifier="true"
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal_with_settings_key"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url_with_settings_key"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email_with_settings_key"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im_with_settings_key"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry_with_settings_key"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+</Keyboard>
diff --git a/java/res/xml-fr-rCA/kbd_qwerty.xml b/java/res/xml-fr-rCA/kbd_qwerty.xml
new file mode 100644
index 0000000..1f17cca
--- /dev/null
+++ b/java/res/xml-fr-rCA/kbd_qwerty.xml
@@ -0,0 +1,503 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<Keyboard
+ xmlns:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="10%p"
+ android:horizontalGap="0px"
+ android:verticalGap="@dimen/key_bottom_gap"
+>
+ <Row
+ android:rowEdgeFlags="top"
+ >
+ <Key
+ android:keyLabel="q"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_q"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="w"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_w" />
+ <Key
+ android:keyLabel="e"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_e" />
+ <Key
+ android:keyLabel="r"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_r" />
+ <Key
+ android:keyLabel="t"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_t" />
+ <Key
+ android:keyLabel="y"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_y" />
+ <Key
+ android:keyLabel="u"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_u" />
+ <Key
+ android:keyLabel="i"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_i" />
+ <Key
+ android:keyLabel="o"
+ android:popupKeyboard="@xml/kbd_popup_narrow_template"
+ android:popupCharacters="@string/alternates_for_o" />
+ <Key
+ android:keyLabel="p"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_p"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:keyLabel="a"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_a"
+ android:horizontalGap="5%p"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="s"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_s" />
+ <Key
+ android:keyLabel="d"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_d" />
+ <Key
+ android:keyLabel="f" />
+ <Key
+ android:keyLabel="g"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_g" />
+ <Key
+ android:keyLabel="h" />
+ <Key
+ android:keyLabel="j" />
+ <Key
+ android:keyLabel="k" />
+ <Key
+ android:keyLabel="l"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_l"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:codes="@integer/key_shift"
+ android:keyIcon="@drawable/sym_keyboard_shift"
+ android:iconPreview="@drawable/sym_keyboard_feedback_shift"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:isSticky="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="z"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_z" />
+ <Key
+ android:keyLabel="x" />
+ <Key
+ android:keyLabel="c"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_c" />
+ <Key
+ android:keyLabel="v"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_v" />
+ <Key
+ android:keyLabel="b" />
+ <Key
+ android:keyLabel="n"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_n" />
+ <Key
+ android:keyLabel="m" />
+ <Key
+ android:codes="@integer/key_delete"
+ android:keyIcon="@drawable/sym_keyboard_delete"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal_with_settings_key"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url_with_settings_key"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email_with_settings_key"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im_with_settings_key"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry_with_settings_key"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+</Keyboard>
diff --git a/java/res/xml-fr/kbd_qwerty.xml b/java/res/xml-fr/kbd_qwerty.xml
new file mode 100644
index 0000000..4677d87
--- /dev/null
+++ b/java/res/xml-fr/kbd_qwerty.xml
@@ -0,0 +1,516 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<Keyboard
+ xmlns:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="10%p"
+ android:horizontalGap="0px"
+ android:verticalGap="@dimen/key_bottom_gap"
+>
+ <Row
+ android:rowEdgeFlags="top"
+ >
+ <Key
+ android:keyLabel="a"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_a"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="z"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_z" />
+ <Key
+ android:keyLabel="e"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_e" />
+ <Key
+ android:keyLabel="r"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_r" />
+ <Key
+ android:keyLabel="t"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_t" />
+ <Key
+ android:keyLabel="y"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_y" />
+ <Key
+ android:keyLabel="u"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_u" />
+ <Key
+ android:keyLabel="i"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_i" />
+ <Key
+ android:keyLabel="o"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_o" />
+ <Key
+ android:keyLabel="p"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_p"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:keyLabel="q"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_q"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="s"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_s" />
+ <Key
+ android:keyLabel="d"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_d" />
+ <Key
+ android:keyLabel="f" />
+ <Key
+ android:keyLabel="g"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_g" />
+ <Key
+ android:keyLabel="h" />
+ <Key
+ android:keyLabel="j" />
+ <Key
+ android:keyLabel="k" />
+ <Key
+ android:keyLabel="l"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_l" />
+ <Key
+ android:keyLabel="m"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:codes="@integer/key_shift"
+ android:keyIcon="@drawable/sym_keyboard_shift"
+ android:iconPreview="@drawable/sym_keyboard_feedback_shift"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:isSticky="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="w"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_w" />
+ <Key
+ android:keyLabel="x" />
+ <Key
+ android:keyLabel="c"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_c" />
+ <Key
+ android:keyLabel="v"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_v" />
+ <Key
+ android:keyLabel="b" />
+ <Key
+ android:keyLabel="n"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_n" />
+ <Key
+ android:keyLabel="\'"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="&#x300;&#x301;&#x302;&#x308;&#x303;" />
+ <Key
+ android:codes="@integer/key_delete"
+ android:keyIcon="@drawable/sym_keyboard_delete"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+</Keyboard>
diff --git a/java/res/xml-he/kbd_qwerty.xml b/java/res/xml-he/kbd_qwerty.xml
new file mode 100644
index 0000000..0362269
--- /dev/null
+++ b/java/res/xml-he/kbd_qwerty.xml
@@ -0,0 +1,472 @@
+<?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:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="10%p"
+ android:horizontalGap="0px"
+ android:verticalGap="@dimen/key_bottom_gap"
+>
+ <Row
+ android:rowEdgeFlags="top"
+ >
+ <Key
+ android:keyLabel="ק"
+ android:horizontalGap="5%p"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="ר" />
+ <Key
+ android:keyLabel="א" />
+ <Key
+ android:keyLabel="ט" />
+ <Key
+ android:keyLabel="ו" />
+ <Key
+ android:keyLabel="ן" />
+ <Key
+ android:keyLabel="ם" />
+ <Key
+ android:keyLabel="פ" />
+ <Key
+ android:codes="@integer/key_delete"
+ android:keyIcon="@drawable/sym_keyboard_delete"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:keyWidth="13.75%p"
+ android:isModifier="true"
+ android:horizontalGap="1.25%p"
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:keyLabel="ש"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="ד" />
+ <Key
+ android:keyLabel="ג" />
+ <Key
+ android:keyLabel="כ" />
+ <Key
+ android:keyLabel="ע" />
+ <Key
+ android:keyLabel="י" />
+ <Key
+ android:keyLabel="ח" />
+ <Key
+ android:keyLabel="ל" />
+ <Key
+ android:keyLabel="ך" />
+ <Key
+ android:keyLabel="ף"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:keyLabel="ז"
+ android:horizontalGap="5%p"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="ס" />
+ <Key
+ android:keyLabel="ב" />
+ <Key
+ android:keyLabel="ה" />
+ <Key
+ android:keyLabel="נ" />
+ <Key
+ android:keyLabel="מ" />
+ <Key
+ android:keyLabel="צ" />
+ <Key
+ android:keyLabel="ת" />
+ <Key
+ android:keyLabel="ץ"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+</Keyboard>
diff --git a/java/res/xml-hr/kbd_qwerty.xml b/java/res/xml-hr/kbd_qwerty.xml
new file mode 100644
index 0000000..de86879
--- /dev/null
+++ b/java/res/xml-hr/kbd_qwerty.xml
@@ -0,0 +1,527 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<Keyboard
+ xmlns:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="10%p"
+ android:horizontalGap="0px"
+ android:verticalGap="@dimen/key_bottom_gap"
+>
+ <Row
+ android:rowEdgeFlags="top"
+ >
+ <Key
+ android:keyLabel="q"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_q"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="w"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_w" />
+ <Key
+ android:keyLabel="e"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_e" />
+ <Key
+ android:keyLabel="r"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_r" />
+ <Key
+ android:keyLabel="t"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_t" />
+ <Key
+ android:keyLabel="z"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_z" />
+ <Key
+ android:keyLabel="u"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_u" />
+ <Key
+ android:keyLabel="i"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_i" />
+ <Key
+ android:keyLabel="o"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_o" />
+ <Key
+ android:keyLabel="p"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_p"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:keyLabel="a"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_a"
+ android:horizontalGap="5%p"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="s"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_s" />
+ <Key
+ android:keyLabel="d"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_d" />
+ <Key
+ android:keyLabel="f"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_f" />
+ <Key
+ android:keyLabel="g"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_g" />
+ <Key
+ android:keyLabel="h"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_h" />
+ <Key
+ android:keyLabel="j"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_j" />
+ <Key
+ android:keyLabel="k"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_k" />
+ <Key
+ android:keyLabel="l"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_l"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:codes="@integer/key_shift"
+ android:keyIcon="@drawable/sym_keyboard_shift"
+ android:iconPreview="@drawable/sym_keyboard_feedback_shift"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:isSticky="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="y"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_y" />
+ <Key
+ android:keyLabel="x"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_x" />
+ <Key
+ android:keyLabel="c"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_c" />
+ <Key
+ android:keyLabel="v"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_v" />
+ <Key
+ android:keyLabel="b"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_b" />
+ <Key
+ android:keyLabel="n"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_n" />
+ <Key
+ android:keyLabel="m"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_m" />
+ <Key
+ android:codes="@integer/key_delete"
+ android:keyIcon="@drawable/sym_keyboard_delete"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+</Keyboard>
diff --git a/java/res/xml-iw/kbd_qwerty.xml b/java/res/xml-iw/kbd_qwerty.xml
new file mode 100644
index 0000000..0362269
--- /dev/null
+++ b/java/res/xml-iw/kbd_qwerty.xml
@@ -0,0 +1,472 @@
+<?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:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="10%p"
+ android:horizontalGap="0px"
+ android:verticalGap="@dimen/key_bottom_gap"
+>
+ <Row
+ android:rowEdgeFlags="top"
+ >
+ <Key
+ android:keyLabel="ק"
+ android:horizontalGap="5%p"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="ר" />
+ <Key
+ android:keyLabel="א" />
+ <Key
+ android:keyLabel="ט" />
+ <Key
+ android:keyLabel="ו" />
+ <Key
+ android:keyLabel="ן" />
+ <Key
+ android:keyLabel="ם" />
+ <Key
+ android:keyLabel="פ" />
+ <Key
+ android:codes="@integer/key_delete"
+ android:keyIcon="@drawable/sym_keyboard_delete"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:keyWidth="13.75%p"
+ android:isModifier="true"
+ android:horizontalGap="1.25%p"
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:keyLabel="ש"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="ד" />
+ <Key
+ android:keyLabel="ג" />
+ <Key
+ android:keyLabel="כ" />
+ <Key
+ android:keyLabel="ע" />
+ <Key
+ android:keyLabel="י" />
+ <Key
+ android:keyLabel="ח" />
+ <Key
+ android:keyLabel="ל" />
+ <Key
+ android:keyLabel="ך" />
+ <Key
+ android:keyLabel="ף"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:keyLabel="ז"
+ android:horizontalGap="5%p"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="ס" />
+ <Key
+ android:keyLabel="ב" />
+ <Key
+ android:keyLabel="ה" />
+ <Key
+ android:keyLabel="נ" />
+ <Key
+ android:keyLabel="מ" />
+ <Key
+ android:keyLabel="צ" />
+ <Key
+ android:keyLabel="ת" />
+ <Key
+ android:keyLabel="ץ"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+</Keyboard>
diff --git a/java/res/xml-nb/kbd_qwerty.xml b/java/res/xml-nb/kbd_qwerty.xml
new file mode 100644
index 0000000..9350d1a
--- /dev/null
+++ b/java/res/xml-nb/kbd_qwerty.xml
@@ -0,0 +1,532 @@
+<?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.
+*/
+-->
+
+<!--
+ Norwegian Keyboard Layout
+
+ Just a copy of the Swedish layout, with ä/æ and ö/ø switched.
+-->
+
+<Keyboard
+ xmlns:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="9.09%p"
+ android:horizontalGap="0px"
+ android:verticalGap="@dimen/key_bottom_gap"
+>
+ <Row
+ android:rowEdgeFlags="top"
+ >
+ <Key
+ android:keyLabel="q"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_q"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="w"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_w" />
+ <Key
+ android:keyLabel="e"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_e" />
+ <Key
+ android:keyLabel="r"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_r" />
+ <Key
+ android:keyLabel="t"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_t" />
+ <Key
+ android:keyLabel="y"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_y" />
+ <Key
+ android:keyLabel="u"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_u" />
+ <Key
+ android:keyLabel="i"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_i" />
+ <Key
+ android:keyLabel="o"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_o" />
+ <Key
+ android:keyLabel="p"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_p" />
+ <Key
+ android:keyLabel="å"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:keyLabel="a"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_a"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="s"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_s" />
+ <Key
+ android:keyLabel="d"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_d" />
+ <Key
+ android:keyLabel="f" />
+ <Key
+ android:keyLabel="g"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_g" />
+ <Key
+ android:keyLabel="h" />
+ <Key
+ android:keyLabel="j" />
+ <Key
+ android:keyLabel="k" />
+ <Key
+ android:keyLabel="l"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_l" />
+ <Key
+ android:keyLabel="ø"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_oe" />
+ <Key
+ android:keyLabel="æ"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_ae"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:codes="@integer/key_shift"
+ android:keyIcon="@drawable/sym_keyboard_shift"
+ android:iconPreview="@drawable/sym_keyboard_feedback_shift"
+ android:keyWidth="13.63%p"
+ android:isModifier="true"
+ android:isSticky="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="z"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_z" />
+ <Key
+ android:keyLabel="x" />
+ <Key
+ android:keyLabel="c"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_c" />
+ <Key
+ android:keyLabel="v"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_v" />
+ <Key
+ android:keyLabel="b" />
+ <Key
+ android:keyLabel="n"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_n" />
+ <Key
+ android:keyLabel="m" />
+ <Key
+ android:keyLabel="\'"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="&#x300;&#x301;&#x302;&#x308;&#x303;" />
+ <Key
+ android:codes="@integer/key_delete"
+ android:keyIcon="@drawable/sym_keyboard_delete"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:keyWidth="13.63%p"
+ android:isModifier="true"
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+</Keyboard>
diff --git a/java/res/xml-ru-rPH/kbd_qwerty.xml b/java/res/xml-ru-rPH/kbd_qwerty.xml
new file mode 100644
index 0000000..ccf1120
--- /dev/null
+++ b/java/res/xml-ru-rPH/kbd_qwerty.xml
@@ -0,0 +1,515 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<Keyboard
+ xmlns:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="9.09%p"
+ android:horizontalGap="0px"
+ android:verticalGap="@dimen/key_bottom_gap"
+>
+ <Row
+ android:rowEdgeFlags="top"
+ >
+ <Key
+ android:keyLabel="я"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="1"
+ android:keyWidth="8.75%p"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="в"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="2" />
+ <Key
+ android:keyLabel="е"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="3ё" />
+ <Key
+ android:keyLabel="р"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="4" />
+ <Key
+ android:keyLabel="т"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="5" />
+ <Key
+ android:keyLabel="ы"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="6" />
+ <Key
+ android:keyLabel="у"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="7" />
+ <Key
+ android:keyLabel="и"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="8" />
+ <Key
+ android:keyLabel="о"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="9" />
+ <Key
+ android:keyLabel="п"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="0" />
+ <Key
+ android:keyLabel="ш"
+ android:keyWidth="8.75%p"
+ android:popupCharacters="щ"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:keyLabel="а"
+ android:keyWidth="8.75%p"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="с" />
+ <Key
+ android:keyLabel="д" />
+ <Key
+ android:keyLabel="ф" />
+ <Key
+ android:keyLabel="г" />
+ <Key
+ android:keyLabel="х" />
+ <Key
+ android:keyLabel="й" />
+ <Key
+ android:keyLabel="к" />
+ <Key
+ android:keyLabel="л" />
+ <Key
+ android:keyLabel="ч" />
+ <Key
+ android:keyLabel="э"
+ android:keyWidth="8.75%p"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyWidth="8.5%p"
+ >
+ <Key
+ android:codes="@integer/key_shift"
+ android:keyIcon="@drawable/sym_keyboard_shift"
+ android:iconPreview="@drawable/sym_keyboard_feedback_shift"
+ android:keyWidth="11.75%p"
+ android:isModifier="true"
+ android:isSticky="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="з" />
+ <Key
+ android:keyLabel="ь" />
+ <Key
+ android:keyLabel="ц" />
+ <Key
+ android:keyLabel="ж" />
+ <Key
+ android:keyLabel="б" />
+ <Key
+ android:keyLabel="н" />
+ <Key
+ android:keyLabel="м"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ />
+ <Key
+ android:keyLabel="ъ"
+ android:popupCharacters="@string/alternates_for_cyrillic_soft_sign"
+ />
+ <Key
+ android:keyLabel="ю" />
+ <Key
+ android:codes="@integer/key_delete"
+ android:keyIcon="@drawable/sym_keyboard_delete"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:keyWidth="11.75%p"
+ android:isModifier="true"
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+</Keyboard>
diff --git a/java/res/xml-ru/kbd_qwerty.xml b/java/res/xml-ru/kbd_qwerty.xml
new file mode 100644
index 0000000..90aa21a
--- /dev/null
+++ b/java/res/xml-ru/kbd_qwerty.xml
@@ -0,0 +1,512 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<Keyboard
+ xmlns:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="9.09%p"
+ android:horizontalGap="0px"
+ android:verticalGap="@dimen/key_bottom_gap"
+>
+ <Row
+ android:rowEdgeFlags="top"
+ >
+ <Key
+ android:keyLabel="й"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="1"
+ android:keyWidth="8.75%p"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="ц"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="2" />
+ <Key
+ android:keyLabel="у"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="3" />
+ <Key
+ android:keyLabel="к"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="4" />
+ <Key
+ android:keyLabel="е"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_cyrillic_e" />
+ <Key
+ android:keyLabel="н"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="6" />
+ <Key
+ android:keyLabel="г"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="7" />
+ <Key
+ android:keyLabel="ш"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="8" />
+ <Key
+ android:keyLabel="щ"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="9" />
+ <Key
+ android:keyLabel="з"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="0" />
+ <Key
+ android:keyLabel="х"
+ android:keyWidth="8.75%p"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:keyLabel="ф"
+ android:keyWidth="8.75%p"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="ы" />
+ <Key
+ android:keyLabel="в" />
+ <Key
+ android:keyLabel="а" />
+ <Key
+ android:keyLabel="п" />
+ <Key
+ android:keyLabel="р" />
+ <Key
+ android:keyLabel="о" />
+ <Key
+ android:keyLabel="л" />
+ <Key
+ android:keyLabel="д" />
+ <Key
+ android:keyLabel="ж" />
+ <Key
+ android:keyLabel="э"
+ android:keyWidth="8.75%p"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyWidth="8.5%p"
+ >
+ <Key
+ android:codes="@integer/key_shift"
+ android:keyIcon="@drawable/sym_keyboard_shift"
+ android:iconPreview="@drawable/sym_keyboard_feedback_shift"
+ android:keyWidth="11.75%p"
+ android:isModifier="true"
+ android:isSticky="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="я" />
+ <Key
+ android:keyLabel="ч" />
+ <Key
+ android:keyLabel="с" />
+ <Key
+ android:keyLabel="м" />
+ <Key
+ android:keyLabel="и" />
+ <Key
+ android:keyLabel="т" />
+ <Key
+ android:keyLabel="ь"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_cyrillic_soft_sign" />
+ <Key
+ android:keyLabel="б" />
+ <Key
+ android:keyLabel="ю" />
+ <Key
+ android:codes="@integer/key_delete"
+ android:keyIcon="@drawable/sym_keyboard_delete"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:keyWidth="11.75%p"
+ android:isModifier="true"
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+</Keyboard>
diff --git a/java/res/xml-sk-rQY/kbd_qwerty.xml b/java/res/xml-sk-rQY/kbd_qwerty.xml
new file mode 100644
index 0000000..9f8a1e1
--- /dev/null
+++ b/java/res/xml-sk-rQY/kbd_qwerty.xml
@@ -0,0 +1,527 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<Keyboard
+ xmlns:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="10%p"
+ android:horizontalGap="0px"
+ android:verticalGap="@dimen/key_bottom_gap"
+>
+ <Row
+ android:rowEdgeFlags="top"
+ >
+ <Key
+ android:keyLabel="q"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_q"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="w"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_w" />
+ <Key
+ android:keyLabel="e"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_e" />
+ <Key
+ android:keyLabel="r"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_r" />
+ <Key
+ android:keyLabel="t"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_t" />
+ <Key
+ android:keyLabel="y"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_y" />
+ <Key
+ android:keyLabel="u"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_u" />
+ <Key
+ android:keyLabel="i"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_i" />
+ <Key
+ android:keyLabel="o"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_o" />
+ <Key
+ android:keyLabel="p"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_p"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:keyLabel="a"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_a"
+ android:horizontalGap="5%p"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="s"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_s" />
+ <Key
+ android:keyLabel="d"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_d" />
+ <Key
+ android:keyLabel="f"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_f" />
+ <Key
+ android:keyLabel="g"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_g" />
+ <Key
+ android:keyLabel="h"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_h" />
+ <Key
+ android:keyLabel="j"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_j" />
+ <Key
+ android:keyLabel="k"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_k" />
+ <Key
+ android:keyLabel="l"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_l"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:codes="@integer/key_shift"
+ android:keyIcon="@drawable/sym_keyboard_shift"
+ android:iconPreview="@drawable/sym_keyboard_feedback_shift"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:isSticky="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="z"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_z" />
+ <Key
+ android:keyLabel="x"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_x" />
+ <Key
+ android:keyLabel="c"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_c" />
+ <Key
+ android:keyLabel="v"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_v" />
+ <Key
+ android:keyLabel="b"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_b" />
+ <Key
+ android:keyLabel="n"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_n" />
+ <Key
+ android:keyLabel="m"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_m" />
+ <Key
+ android:codes="@integer/key_delete"
+ android:keyIcon="@drawable/sym_keyboard_delete"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+</Keyboard>
diff --git a/java/res/xml-sk/kbd_qwerty.xml b/java/res/xml-sk/kbd_qwerty.xml
new file mode 100644
index 0000000..de86879
--- /dev/null
+++ b/java/res/xml-sk/kbd_qwerty.xml
@@ -0,0 +1,527 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<Keyboard
+ xmlns:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="10%p"
+ android:horizontalGap="0px"
+ android:verticalGap="@dimen/key_bottom_gap"
+>
+ <Row
+ android:rowEdgeFlags="top"
+ >
+ <Key
+ android:keyLabel="q"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_q"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="w"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_w" />
+ <Key
+ android:keyLabel="e"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_e" />
+ <Key
+ android:keyLabel="r"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_r" />
+ <Key
+ android:keyLabel="t"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_t" />
+ <Key
+ android:keyLabel="z"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_z" />
+ <Key
+ android:keyLabel="u"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_u" />
+ <Key
+ android:keyLabel="i"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_i" />
+ <Key
+ android:keyLabel="o"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_o" />
+ <Key
+ android:keyLabel="p"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_p"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:keyLabel="a"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_a"
+ android:horizontalGap="5%p"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="s"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_s" />
+ <Key
+ android:keyLabel="d"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_d" />
+ <Key
+ android:keyLabel="f"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_f" />
+ <Key
+ android:keyLabel="g"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_g" />
+ <Key
+ android:keyLabel="h"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_h" />
+ <Key
+ android:keyLabel="j"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_j" />
+ <Key
+ android:keyLabel="k"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_k" />
+ <Key
+ android:keyLabel="l"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_l"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:codes="@integer/key_shift"
+ android:keyIcon="@drawable/sym_keyboard_shift"
+ android:iconPreview="@drawable/sym_keyboard_feedback_shift"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:isSticky="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="y"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_y" />
+ <Key
+ android:keyLabel="x"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_x" />
+ <Key
+ android:keyLabel="c"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_c" />
+ <Key
+ android:keyLabel="v"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_v" />
+ <Key
+ android:keyLabel="b"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_b" />
+ <Key
+ android:keyLabel="n"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_n" />
+ <Key
+ android:keyLabel="m"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_m" />
+ <Key
+ android:codes="@integer/key_delete"
+ android:keyIcon="@drawable/sym_keyboard_delete"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+</Keyboard>
diff --git a/java/res/xml-sl/kbd_qwerty.xml b/java/res/xml-sl/kbd_qwerty.xml
new file mode 100644
index 0000000..de86879
--- /dev/null
+++ b/java/res/xml-sl/kbd_qwerty.xml
@@ -0,0 +1,527 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<Keyboard
+ xmlns:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="10%p"
+ android:horizontalGap="0px"
+ android:verticalGap="@dimen/key_bottom_gap"
+>
+ <Row
+ android:rowEdgeFlags="top"
+ >
+ <Key
+ android:keyLabel="q"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_q"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="w"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_w" />
+ <Key
+ android:keyLabel="e"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_e" />
+ <Key
+ android:keyLabel="r"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_r" />
+ <Key
+ android:keyLabel="t"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_t" />
+ <Key
+ android:keyLabel="z"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_z" />
+ <Key
+ android:keyLabel="u"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_u" />
+ <Key
+ android:keyLabel="i"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_i" />
+ <Key
+ android:keyLabel="o"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_o" />
+ <Key
+ android:keyLabel="p"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_p"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:keyLabel="a"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_a"
+ android:horizontalGap="5%p"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="s"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_s" />
+ <Key
+ android:keyLabel="d"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_d" />
+ <Key
+ android:keyLabel="f"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_f" />
+ <Key
+ android:keyLabel="g"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_g" />
+ <Key
+ android:keyLabel="h"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_h" />
+ <Key
+ android:keyLabel="j"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_j" />
+ <Key
+ android:keyLabel="k"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_k" />
+ <Key
+ android:keyLabel="l"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_l"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:codes="@integer/key_shift"
+ android:keyIcon="@drawable/sym_keyboard_shift"
+ android:iconPreview="@drawable/sym_keyboard_feedback_shift"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:isSticky="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="y"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_y" />
+ <Key
+ android:keyLabel="x"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_x" />
+ <Key
+ android:keyLabel="c"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_c" />
+ <Key
+ android:keyLabel="v"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_v" />
+ <Key
+ android:keyLabel="b"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_b" />
+ <Key
+ android:keyLabel="n"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_n" />
+ <Key
+ android:keyLabel="m"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_m" />
+ <Key
+ android:codes="@integer/key_delete"
+ android:keyIcon="@drawable/sym_keyboard_delete"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+</Keyboard>
diff --git a/java/res/xml-sr/kbd_qwerty.xml b/java/res/xml-sr/kbd_qwerty.xml
new file mode 100644
index 0000000..e36fac2
--- /dev/null
+++ b/java/res/xml-sr/kbd_qwerty.xml
@@ -0,0 +1,503 @@
+<?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.
+*/
+-->
+
+<!-- Serbian keyboard layout, based on the X11 layout for Serbian -->
+<Keyboard
+ xmlns:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="9.09%p"
+ android:horizontalGap="0px"
+ android:verticalGap="@dimen/key_bottom_gap"
+>
+ <Row
+ android:rowEdgeFlags="top"
+ >
+ <Key
+ android:keyLabel="љ"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="1"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="њ"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="2" />
+ <Key
+ android:keyLabel="е"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="3" />
+ <Key
+ android:keyLabel="р"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="4" />
+ <Key
+ android:keyLabel="т"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="5" />
+ <Key
+ android:keyLabel="з"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="6" />
+ <Key
+ android:keyLabel="у"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="7" />
+ <Key
+ android:keyLabel="и"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="8" />
+ <Key
+ android:keyLabel="о"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="9" />
+ <Key
+ android:keyLabel="п"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="0" />
+ <Key
+ android:keyLabel="ш"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:keyLabel="а"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="с" />
+ <Key
+ android:keyLabel="д" />
+ <Key
+ android:keyLabel="ф" />
+ <Key
+ android:keyLabel="г" />
+ <Key
+ android:keyLabel="х" />
+ <Key
+ android:keyLabel="ј" />
+ <Key
+ android:keyLabel="к" />
+ <Key
+ android:keyLabel="л" />
+ <Key
+ android:keyLabel="ч" />
+ <Key
+ android:keyLabel="ћ"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:codes="@integer/key_shift"
+ android:keyIcon="@drawable/sym_keyboard_shift"
+ android:iconPreview="@drawable/sym_keyboard_feedback_shift"
+ android:keyWidth="13.64%p"
+ android:isModifier="true"
+ android:isSticky="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="ж" />
+ <Key
+ android:keyLabel="џ" />
+ <Key
+ android:keyLabel="ц" />
+ <Key
+ android:keyLabel="в" />
+ <Key
+ android:keyLabel="б" />
+ <Key
+ android:keyLabel="н" />
+ <Key
+ android:keyLabel="м" />
+ <Key
+ android:keyLabel="ђ" />
+ <Key
+ android:codes="@integer/key_delete"
+ android:keyIcon="@drawable/sym_keyboard_delete"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:keyWidth="13.64%p"
+ android:isModifier="true"
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+</Keyboard>
diff --git a/java/res/xml-sv/kbd_qwerty.xml b/java/res/xml-sv/kbd_qwerty.xml
new file mode 100644
index 0000000..761447e
--- /dev/null
+++ b/java/res/xml-sv/kbd_qwerty.xml
@@ -0,0 +1,535 @@
+<?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.
+*/
+-->
+
+<!--
+ Swedish Keyboard Layout
+
+ Key positioning: Svensk standard SS 66 22 41
+ Foreign letters: Svenska skrivregler (2:a uppl.) §302
+ Local additions: ۧ
+-->
+
+<Keyboard
+ xmlns:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="9.09%p"
+ android:horizontalGap="0px"
+ android:verticalGap="@dimen/key_bottom_gap"
+>
+ <Row
+ android:rowEdgeFlags="top"
+ >
+ <Key
+ android:keyLabel="q"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_q"
+ android:keyWidth="8.75%p"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="w"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_w" />
+ <Key
+ android:keyLabel="e"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_e" />
+ <Key
+ android:keyLabel="r"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_r" />
+ <Key
+ android:keyLabel="t"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_t" />
+ <Key
+ android:keyLabel="y"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_y" />
+ <Key
+ android:keyLabel="u"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_u" />
+ <Key
+ android:keyLabel="i"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_i" />
+ <Key
+ android:keyLabel="o"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_o" />
+ <Key
+ android:keyLabel="p"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_p" />
+ <Key
+ android:keyLabel="å"
+ android:keyWidth="8.75%p"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:keyLabel="a"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_a"
+ android:keyWidth="8.75%p"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="s"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_s" />
+ <Key
+ android:keyLabel="d"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_d" />
+ <Key
+ android:keyLabel="f" />
+ <Key
+ android:keyLabel="g"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_g" />
+ <Key
+ android:keyLabel="h" />
+ <Key
+ android:keyLabel="j" />
+ <Key
+ android:keyLabel="k" />
+ <Key
+ android:keyLabel="l"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_l" />
+ <Key
+ android:keyLabel="ö"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_o_umlaut" />
+ <Key
+ android:keyLabel="ä"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_a_umlaut"
+ android:keyWidth="8.75%p"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyWidth="10%p"
+ >
+ <Key
+ android:codes="@integer/key_shift"
+ android:keyIcon="@drawable/sym_keyboard_shift"
+ android:iconPreview="@drawable/sym_keyboard_feedback_shift"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:isSticky="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="z"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_z" />
+ <Key
+ android:keyLabel="x" />
+ <Key
+ android:keyLabel="c"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_c" />
+ <Key
+ android:keyLabel="v"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_v" />
+ <Key
+ android:keyLabel="b" />
+ <Key
+ android:keyLabel="n"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_n" />
+ <Key
+ android:keyLabel="m" />
+ <Key
+ android:codes="@integer/key_delete"
+ android:keyIcon="@drawable/sym_keyboard_delete"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:keyWidth="15%p"
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+</Keyboard>
diff --git a/java/res/xml-tr/kbd_qwerty.xml b/java/res/xml-tr/kbd_qwerty.xml
new file mode 100644
index 0000000..d868dcb
--- /dev/null
+++ b/java/res/xml-tr/kbd_qwerty.xml
@@ -0,0 +1,530 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<Keyboard
+ xmlns:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="10%p"
+ android:horizontalGap="0px"
+ android:verticalGap="@dimen/key_bottom_gap"
+>
+
+ <Row android:extension="true" >
+ <Key android:keyLabel="ç" />
+ <Key android:keyLabel="ğ" />
+ <Key android:keyLabel="ş" />
+ <Key android:keyLabel="ı" />
+ <Key android:keyLabel="i" />
+ <Key android:keyLabel="ö" />
+ <Key android:keyLabel="ü" />
+ <Key android:keyLabel="!" android:shiftLabel=":" />
+ <Key android:keyLabel="\?" android:shiftLabel=";" />
+ <Key android:keyLabel="\'" android:shiftLabel="&quot;" />
+ </Row>
+ <Row>
+ <Key
+ android:keyLabel="q"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_q"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="w"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_w" />
+ <Key
+ android:keyLabel="e"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_e" />
+ <Key
+ android:keyLabel="r"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_r" />
+ <Key
+ android:keyLabel="t"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_t" />
+ <Key
+ android:keyLabel="y"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_y" />
+ <Key
+ android:keyLabel="u"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_u" />
+ <Key
+ android:keyLabel="i"
+ android:shiftLabel="I"
+ android:capsLabel="I"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_i" />
+ <Key
+ android:keyLabel="o"
+ android:popupKeyboard="@xml/kbd_popup_narrow_template"
+ android:popupCharacters="@string/alternates_for_o" />
+ <Key
+ android:keyLabel="p"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_p"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:keyLabel="a"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_a"
+ android:horizontalGap="5%p"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="s"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_s" />
+ <Key
+ android:keyLabel="d"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_d" />
+ <Key
+ android:keyLabel="f"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_f" />
+ <Key
+ android:keyLabel="g"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_g" />
+ <Key
+ android:keyLabel="h"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_h" />
+ <Key
+ android:keyLabel="j"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_j" />
+ <Key
+ android:keyLabel="k"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_k" />
+ <Key
+ android:keyLabel="l"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_l"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:codes="@integer/key_shift"
+ android:keyIcon="@drawable/sym_keyboard_shift"
+ android:iconPreview="@drawable/sym_keyboard_feedback_shift"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:isSticky="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="z"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_z" />
+ <Key
+ android:keyLabel="x"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_x" />
+ <Key
+ android:keyLabel="c"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_c" />
+ <Key
+ android:keyLabel="v"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_v" />
+ <Key
+ android:keyLabel="b"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_b" />
+ <Key
+ android:keyLabel="n"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_n" />
+ <Key
+ android:keyLabel="m"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_m" />
+ <Key
+ android:codes="@integer/key_delete"
+ android:keyIcon="@drawable/sym_keyboard_delete"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal_with_settings_key"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url_with_settings_key"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email_with_settings_key"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im_with_settings_key"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry_with_settings_key"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+</Keyboard>
diff --git a/java/res/xml-uk/kbd_qwerty.xml b/java/res/xml-uk/kbd_qwerty.xml
new file mode 100644
index 0000000..af23950
--- /dev/null
+++ b/java/res/xml-uk/kbd_qwerty.xml
@@ -0,0 +1,516 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<Keyboard
+ xmlns:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="9.09%p"
+ android:horizontalGap="0px"
+ android:verticalGap="@dimen/key_bottom_gap"
+>
+ <Row
+ android:rowEdgeFlags="top"
+ >
+ <Key
+ android:keyLabel="й"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="1"
+ android:keyWidth="8.75%p"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="ц"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="2" />
+ <Key
+ android:keyLabel="у"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="3" />
+ <Key
+ android:keyLabel="к"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="4" />
+ <Key
+ android:keyLabel="е"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="5ё" />
+ <Key
+ android:keyLabel="н"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="6" />
+ <Key
+ android:keyLabel="г"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="7" />
+ <Key
+ android:keyLabel="ш"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="8" />
+ <Key
+ android:keyLabel="щ"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="9" />
+ <Key
+ android:keyLabel="з"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="0" />
+ <Key
+ android:keyLabel="х"
+ android:keyWidth="8.75%p"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:keyLabel="ф"
+ android:keyWidth="8.75%p"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="і"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="ы" />
+ <Key
+ android:keyLabel="в" />
+ <Key
+ android:keyLabel="а" />
+ <Key
+ android:keyLabel="п" />
+ <Key
+ android:keyLabel="р" />
+ <Key
+ android:keyLabel="о" />
+ <Key
+ android:keyLabel="л" />
+ <Key
+ android:keyLabel="д" />
+ <Key
+ android:keyLabel="ж" />
+ <Key
+ android:keyLabel="є"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="э"
+ android:keyWidth="8.75%p"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyWidth="8.5%p"
+ >
+ <Key
+ android:codes="@integer/key_shift"
+ android:keyIcon="@drawable/sym_keyboard_shift"
+ android:iconPreview="@drawable/sym_keyboard_feedback_shift"
+ android:keyWidth="11.75%p"
+ android:isModifier="true"
+ android:isSticky="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="я" />
+ <Key
+ android:keyLabel="ч" />
+ <Key
+ android:keyLabel="с" />
+ <Key
+ android:keyLabel="м" />
+ <Key
+ android:keyLabel="и" />
+ <Key
+ android:keyLabel="т" />
+ <Key
+ android:keyLabel="ї"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="ьъ" />
+ <Key
+ android:keyLabel="б" />
+ <Key
+ android:keyLabel="ю" />
+ <Key
+ android:codes="@integer/key_delete"
+ android:keyIcon="@drawable/sym_keyboard_delete"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:keyWidth="11.75%p"
+ android:isModifier="true"
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry_with_settings_key"
+ android:keyWidth="10%p"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+</Keyboard>
diff --git a/java/res/xml/dictionary.xml b/java/res/xml/dictionary.xml
new file mode 100644
index 0000000..7b770a8
--- /dev/null
+++ b/java/res/xml/dictionary.xml
@@ -0,0 +1,23 @@
+<?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.
+*/
+-->
+
+<dictionary>
+ <part name = "main" />
+</dictionary> \ No newline at end of file
diff --git a/java/res/xml/kbd_compact.xml b/java/res/xml/kbd_compact.xml
new file mode 100644
index 0000000..d0a869f
--- /dev/null
+++ b/java/res/xml/kbd_compact.xml
@@ -0,0 +1,330 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<Keyboard
+ xmlns:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="9.09090909%p"
+ android:horizontalGap="0px"
+ android:verticalGap="0px"
+ android:verticalPad="@dimen/key_vertical_pad_compact"
+ android:layoutRows="5"
+ android:layoutColumns="11"
+ >
+ <Row android:extension="true">
+ <Key android:codes="@integer/key_escape" android:keyLabel="Esc" android:isModifier="true" />
+ <Key android:keyLabel="`" android:shiftLabel="~" />
+ <Key android:keyLabel="-" android:shiftLabel="_" />
+ <Key android:keyLabel="\\" android:shiftLabel="|" />
+ <Key android:keyLabel=";" android:shiftLabel=":" />
+ <Key android:keyLabel="=" android:shiftLabel="+" />
+ <Key android:keyLabel="[" android:shiftLabel="{" />
+ <Key android:keyLabel="]" android:shiftLabel="}" />
+ <Key android:codes="@integer/key_home" android:isModifier="true" android:keyLabel="Home" />
+ <Key android:codes="@integer/key_end" android:isModifier="true" android:keyLabel="End" />
+ <Key android:codes="@integer/key_forward_del" android:isModifier="true" android:keyLabel="Del" />
+ </Row>
+
+ <Row>
+ <Key
+ android:keyLabel="1"
+ android:shiftLabel="!"
+ android:keyEdgeFlags="left"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="`"
+ android:keyWidth="7.09090909%p"
+ />
+ <Key
+ android:keyLabel="2"
+ android:shiftLabel="\@"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="~"
+ />
+ <Key
+ android:keyLabel="3"
+ android:shiftLabel="#"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="-"
+ />
+ <Key
+ android:keyLabel="4"
+ android:shiftLabel="$"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="_"
+ />
+ <Key
+ android:keyLabel="5"
+ android:shiftLabel="%"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="="
+ />
+ <Key
+ android:keyLabel="6"
+ android:shiftLabel="^"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="+"
+ />
+ <Key
+ android:keyLabel="7"
+ android:shiftLabel="&amp;"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="{"
+ />
+ <Key
+ android:keyLabel="8"
+ android:shiftLabel="*"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="}"
+ />
+ <Key
+ android:keyLabel="9"
+ android:shiftLabel="("
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="["
+ />
+ <Key
+ android:keyLabel="0"
+ android:shiftLabel=")"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="]"
+ />
+ <Key
+ android:codes="@integer/key_delete"
+ android:keyWidth="11.09090909%p"
+ android:keyIcon="@drawable/sym_keyboard_delete"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:isModifier="true"
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:keyLabel="q"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_q"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="w"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_w" />
+ <Key
+ android:keyLabel="e"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_e" />
+ <Key
+ android:keyLabel="r"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_r" />
+ <Key
+ android:keyLabel="t"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_t" />
+ <Key
+ android:keyLabel="y"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_y" />
+ <Key
+ android:keyLabel="u"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_u" />
+ <Key
+ android:keyLabel="i"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_i" />
+ <Key
+ android:keyLabel="o"
+ android:popupKeyboard="@xml/kbd_popup_narrow_template"
+ android:popupCharacters="@string/alternates_for_o" />
+ <Key
+ android:keyLabel="p"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_p" />
+ <Key
+ android:keyLabel="'"
+ android:shiftLabel="&quot;"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="|"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:keyLabel="a"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_a"
+ android:horizontalGap="4.54545454%p"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="s"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_s" />
+ <Key
+ android:keyLabel="d"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_d" />
+ <Key
+ android:keyLabel="f"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_f" />
+ <Key
+ android:keyLabel="g"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_g" />
+ <Key
+ android:keyLabel="h"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_h" />
+ <Key
+ android:keyLabel="j"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_j" />
+ <Key
+ android:keyLabel="k"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_k" />
+ <Key
+ android:keyLabel="l"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_l" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:isModifier="true"
+ android:keyWidth="13.6363636%p"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:codes="@integer/key_shift"
+ android:keyWidth="11.09090909%p"
+ android:keyIcon="@drawable/sym_keyboard_shift"
+ android:iconPreview="@drawable/sym_keyboard_feedback_shift"
+ android:isModifier="true"
+ android:isSticky="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="z"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_z" />
+ <Key
+ android:keyLabel="x"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_x" />
+ <Key
+ android:keyLabel="c"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_c" />
+ <Key
+ android:keyLabel="v"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_v" />
+ <Key
+ android:keyLabel="b"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_b" />
+ <Key
+ android:keyLabel="n"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_n" />
+ <Key
+ android:keyLabel="m"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_m" />
+ <Key
+ android:keyLabel=","
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters=";"
+ android:shiftLabel="&lt;" />
+ <Key
+ android:keyLabel="."
+ android:shiftLabel="&gt;"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters=":"
+ android:keyIcon="@drawable/hint_popup" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:keyLabel="/"
+ android:shiftLabel="\?"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="\\"
+ android:keyWidth="7.09090909%p"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row android:rowEdgeFlags="bottom">
+ <Key
+ android:codes="@integer/key_fn"
+ android:keyLabel="Fn"
+ android:isModifier="true"
+ android:keyWidth="8.29090909%p"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="Ctrl"
+ android:codes="@integer/key_ctrl_left"
+ android:isSticky="true"
+ android:keyWidth="8.29090909%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_alt_left"
+ android:keyLabel="Alt"
+ android:isSticky="true"
+ android:keyWidth="8.29090909%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:keyWidth="8.29090909%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="33.67272727%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_dpad_left"
+ android:isModifier="true"
+ android:isRepeatable="true"
+ android:isCursor="true"
+ android:keyWidth="8.29090909%p"
+ android:keyLabel="&#x25c1;" />
+ <Key
+ android:codes="@integer/key_dpad_down"
+ android:isModifier="true"
+ android:isRepeatable="true"
+ android:isCursor="true"
+ android:keyWidth="8.29090909%p"
+ android:keyLabel="&#x25bd;" />
+ <Key
+ android:codes="@integer/key_dpad_up"
+ android:isRepeatable="true"
+ android:keyLabel="&#x25b3;"
+ android:isCursor="true"
+ android:keyWidth="8.29090909%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_dpad_right"
+ android:isModifier="true"
+ android:keyLabel="&#x25b7;"
+ android:isRepeatable="true"
+ android:isCursor="true"
+ android:keyWidth="8.29090909%p"
+ android:keyEdgeFlags="right" />
+ </Row>
+</Keyboard>
diff --git a/java/res/xml/kbd_compact_fn.xml b/java/res/xml/kbd_compact_fn.xml
new file mode 100644
index 0000000..cef63c7
--- /dev/null
+++ b/java/res/xml/kbd_compact_fn.xml
@@ -0,0 +1,282 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<Keyboard
+ xmlns:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="10%p"
+ android:horizontalGap="0px"
+ android:verticalGap="0px"
+ android:verticalPad="@dimen/key_vertical_pad_compact"
+ android:layoutRows="5"
+ android:layoutColumns="11"
+>
+ <Row
+ android:rowEdgeFlags="top"
+ >
+ <Key
+ android:keyLabel="Esc"
+ android:codes="@integer/key_escape"
+ android:keyWidth="12%p"
+ android:keyEdgeFlags="left"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:keyWidth="9%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_fkey_f1"
+ android:isModifier="true"
+ android:keyWidth="9%p"
+ android:keyLabel="F1" />
+ <Key
+ android:codes="@integer/key_fkey_f2"
+ android:isModifier="true"
+ android:keyWidth="9%p"
+ android:keyLabel="F2" />
+ <Key
+ android:codes="@integer/key_fkey_f3"
+ android:isModifier="true"
+ android:keyWidth="9%p"
+ android:keyLabel="F3" />
+ <Key
+ android:codes="@integer/key_fkey_f4"
+ android:isModifier="true"
+ android:keyWidth="9%p"
+ android:keyLabel="F4" />
+ <Key
+ android:codes="@integer/key_fkey_f5"
+ android:isModifier="true"
+ android:keyWidth="9%p"
+ android:keyLabel="F5" />
+ <Key
+ android:codes="@integer/key_fkey_f6"
+ android:isModifier="true"
+ android:keyWidth="9%p"
+ android:keyLabel="F6" />
+
+ <Key
+ android:codes="@integer/key_break"
+ android:isModifier="true"
+ android:keyWidth="12%p"
+ android:keyLabel="Brk" />
+
+ <Key
+ android:codes="@integer/key_delete"
+ android:keyIcon="@drawable/sym_keyboard_delete"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:isModifier="true"
+ android:isRepeatable="true"
+ android:keyWidth="13%p"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:codes="@integer/key_sysrq"
+ android:isModifier="true"
+ android:keyWidth="12%p"
+ android:keyEdgeFlags="left"
+ android:keyLabel="SyRq" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:keyWidth="9%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_fkey_f7"
+ android:isModifier="true"
+ android:keyWidth="9%p"
+ android:keyLabel="F7" />
+ <Key
+ android:codes="@integer/key_fkey_f8"
+ android:isModifier="true"
+ android:keyWidth="9%p"
+ android:keyLabel="F8" />
+ <Key
+ android:codes="@integer/key_fkey_f9"
+ android:isModifier="true"
+ android:keyWidth="9%p"
+ android:keyLabel="F9" />
+ <Key
+ android:codes="@integer/key_fkey_f10"
+ android:isModifier="true"
+ android:keyWidth="9%p"
+ android:keyLabel="F10" />
+ <Key
+ android:codes="@integer/key_fkey_f11"
+ android:isModifier="true"
+ android:keyWidth="9%p"
+ android:keyLabel="F11" />
+ <Key
+ android:codes="@integer/key_fkey_f12"
+ android:isModifier="true"
+ android:keyWidth="9%p"
+ android:keyLabel="F12" />
+
+ <Key
+ android:codes="@integer/key_insert"
+ android:keyLabel="Ins"
+ android:isRepeatable="true"
+ android:keyWidth="12%p"
+ android:isModifier="true" />
+
+ <Key
+ android:codes="@integer/key_page_up"
+ android:isModifier="true"
+ android:isRepeatable="true"
+ android:keyWidth="13%p"
+ android:keyEdgeFlags="right"
+ android:keyLabel="PgUp" />
+ </Row>
+ <Row>
+ <Key
+ android:codes="@integer/key_scroll_lock"
+ android:isModifier="true"
+ android:keyWidth="12%p"
+ android:keyEdgeFlags="left"
+ android:keyLabel="ScrL" />
+ <Key android:keyLabel="~" android:keyWidth="9%p" />
+ <Key android:keyLabel="_" android:keyWidth="9%p" />
+ <Key android:keyLabel="+" android:keyWidth="9%p" />
+ <Key android:keyLabel="{" android:keyWidth="9%p" />
+ <Key android:keyLabel="}" android:keyWidth="9%p" />
+ <Key android:keyLabel="|" android:keyWidth="9%p" />
+ <Key android:keyLabel=":" android:keyWidth="9%p" />
+
+ <Key
+ android:codes="@integer/key_forward_del"
+ android:keyLabel="Del"
+ android:isRepeatable="true"
+ android:isModifier="true"
+ android:keyWidth="12%p" />
+ <Key
+ android:codes="@integer/key_page_down"
+ android:isModifier="true"
+ android:isRepeatable="true"
+ android:keyWidth="13%p"
+ android:keyLabel="PgDn"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:codes="@integer/key_num_lock"
+ android:keyWidth="12%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left"
+ android:keyLabel="NumL" />
+
+ <Key android:keyLabel="`" android:keyWidth="9%p" />
+ <Key android:keyLabel="-" android:keyWidth="9%p" />
+ <Key android:keyLabel="=" android:keyWidth="9%p" />
+ <Key android:keyLabel="[" android:keyWidth="9%p" />
+ <Key android:keyLabel="]" android:keyWidth="9%p" />
+ <Key android:keyLabel="\\" android:keyWidth="9%p" />
+ <Key android:keyLabel=";" android:keyWidth="9%p" />
+
+ <Key
+ android:codes="@integer/key_home"
+ android:keyWidth="12%p"
+ android:keyLabel="Home"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_end"
+ android:keyLabel="End"
+ android:keyWidth="13%p"
+ android:keyEdgeFlags="right"
+ android:isModifier="true" />
+ </Row>
+
+ <Row android:rowEdgeFlags="bottom"
+ android:keyWidth="9.09090909%p"
+ >
+ <Key
+ android:codes="@integer/key_fn"
+ android:keyLabel="Fn"
+ android:isModifier="true"
+ android:keyWidth="8.29090909%p"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="Ctrl"
+ android:codes="@integer/key_ctrl_left"
+ android:isSticky="true"
+ android:keyWidth="8.29090909%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_alt_left"
+ android:keyLabel="Alt"
+ android:isSticky="true"
+ android:keyWidth="8.29090909%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_shift"
+ android:keyWidth="8.29090909%p"
+ android:keyIcon="@drawable/sym_keyboard_shift"
+ android:iconPreview="@drawable/sym_keyboard_feedback_shift"
+ android:isModifier="true"
+ android:isSticky="true" />
+ <Key
+ android:keyLabel=".com"
+ android:keyOutputText=".com"
+ android:popupKeyboard="@xml/popup_domains"
+ android:keyWidth="12.69090909%p"
+ android:keyIcon="@drawable/hint_popup" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="12.69090909%p"
+ android:keyIcon="@drawable/hint_popup" />
+ <Key
+ android:codes="@integer/key_dpad_center"
+ android:isModifier="true"
+ android:isCursor="true"
+ android:keyWidth="8.29090909%p"
+ android:keyLabel="&#x25cb;" />
+ <Key
+ android:codes="@integer/key_dpad_left"
+ android:isModifier="true"
+ android:isRepeatable="true"
+ android:isCursor="true"
+ android:keyWidth="8.29090909%p"
+ android:keyLabel="&#x25c1;" />
+ <Key
+ android:codes="@integer/key_dpad_down"
+ android:isModifier="true"
+ android:isRepeatable="true"
+ android:isCursor="true"
+ android:keyWidth="8.29090909%p"
+ android:keyLabel="&#x25bd;" />
+ <Key
+ android:codes="@integer/key_dpad_up"
+ android:isRepeatable="true"
+ android:keyLabel="&#x25b3;"
+ android:isCursor="true"
+ android:keyWidth="8.29090909%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_dpad_right"
+ android:isModifier="true"
+ android:keyLabel="&#x25b7;"
+ android:isRepeatable="true"
+ android:isCursor="true"
+ android:keyWidth="8.29090909%p"
+ android:keyEdgeFlags="right" />
+ </Row>
+</Keyboard>
diff --git a/java/res/xml/kbd_extension.xml b/java/res/xml/kbd_extension.xml
new file mode 100644
index 0000000..96c88b4
--- /dev/null
+++ b/java/res/xml/kbd_extension.xml
@@ -0,0 +1,61 @@
+<?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.
+*/
+ android:keyHeight="@dimen/key_height"
+-->
+
+<Keyboard xmlns:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="10%p"
+ android:horizontalGap="0px"
+ android:verticalGap="0px"
+ >
+
+ <Row android:rowEdgeFlags="top">
+ <Key android:keyLabel="!" android:keyEdgeFlags="left"/>
+ <Key android:keyLabel="\@"/>
+ <Key android:keyLabel="\#"/>
+ <Key android:keyLabel="&amp;"/>
+ <Key android:keyLabel="-"/>
+ <Key android:keyLabel="\'"/>
+ <Key android:keyLabel=":"/>
+ <Key android:keyLabel="&quot;"/>
+ <Key android:keyLabel="/"/>
+ <Key android:keyLabel="\?" android:keyEdgeFlags="right"
+ />
+ </Row>
+
+ <Row android:rowEdgeFlags="bottom">
+ <Key android:codes="49" android:keyLabel="1" android:keyEdgeFlags="left"
+ />
+ <Key android:codes="50" android:keyLabel="2"
+ />
+ <Key android:codes="51" android:keyLabel="3"
+ />
+ <Key android:codes="52" android:keyLabel="4"
+ />
+ <Key android:codes="53" android:keyLabel="5"
+ />
+ <Key android:codes="54" android:keyLabel="6"/>
+ <Key android:codes="55" android:keyLabel="7"
+ />
+ <Key android:codes="56" android:keyLabel="8"/>
+ <Key android:codes="57" android:keyLabel="9"/>
+ <Key android:codes="48" android:keyLabel="0"
+ android:keyEdgeFlags="right"/>
+ </Row>
+</Keyboard>
diff --git a/java/res/xml/kbd_extension_full.xml b/java/res/xml/kbd_extension_full.xml
new file mode 100644
index 0000000..7a0c87e
--- /dev/null
+++ b/java/res/xml/kbd_extension_full.xml
@@ -0,0 +1,56 @@
+<?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.
+*/
+ android:keyHeight="@dimen/key_height"
+
+Unavailable accents:
+ <Key android:keyLabel="&#x309;"/>
+ <Key android:keyLabel="&#x30D;"/>
+-->
+
+<Keyboard xmlns:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="7.1428571485%p"
+ android:horizontalGap="0px"
+ android:verticalGap="0px"
+ >
+
+ <Row android:rowEdgeFlags="top|bottom">
+ <Key android:keyLabel="&#x300;" android:keyEdgeFlags="left"/>
+ <Key android:keyLabel="&#x301;"/>
+ <Key android:keyLabel="&#x302;"/>
+ <Key android:keyLabel="&#x303;"/>
+ <Key android:keyLabel="&#x304;"/>
+ <Key android:keyLabel="&#x305;"/>
+ <Key android:keyLabel="&#x306;"/>
+ <Key android:keyLabel="&#x307;"/>
+ <Key android:keyLabel="&#x308;"/>
+ <Key android:keyLabel="&#x30A;"/>
+ <Key android:keyLabel="&#x30B;"/>
+ <Key android:keyLabel="&#x30C;"/>
+ <Key
+ android:codes="@integer/key_home"
+ android:isModifier="true"
+ android:keyLabel="Home" />
+ <Key
+ android:codes="@integer/key_end"
+ android:isModifier="true"
+ android:keyLabel="End"
+ android:keyEdgeFlags="right" />
+ />
+ </Row>
+</Keyboard> \ No newline at end of file
diff --git a/java/res/xml/kbd_full.xml b/java/res/xml/kbd_full.xml
new file mode 100644
index 0000000..088d7f3
--- /dev/null
+++ b/java/res/xml/kbd_full.xml
@@ -0,0 +1,407 @@
+<?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:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="7.1428571485%p"
+ android:horizontalGap="0px"
+ android:verticalGap="@dimen/key_bottom_gap"
+ android:layoutRows="5"
+ android:layoutColumns="14"
+>
+ <Row android:rowEdgeFlags="top" android:extension="true">
+ <Key android:keyLabel="F1" android:codes="@integer/key_fkey_f1" android:isModifier="true" android:keyEdgeFlags="left"/>
+ <Key android:keyLabel="F2" android:codes="@integer/key_fkey_f2" android:isModifier="true" />
+ <Key android:keyLabel="F3" android:codes="@integer/key_fkey_f3" android:isModifier="true" />
+ <Key android:keyLabel="F4" android:codes="@integer/key_fkey_f4" android:isModifier="true" />
+ <Key android:keyLabel="F5" android:codes="@integer/key_fkey_f5" android:isModifier="true" />
+ <Key android:keyLabel="F6" android:codes="@integer/key_fkey_f6" android:isModifier="true" />
+ <Key android:keyLabel="F7" android:codes="@integer/key_fkey_f7" android:isModifier="true" />
+ <Key android:keyLabel="F8" android:codes="@integer/key_fkey_f8" android:isModifier="true" />
+ <Key android:keyLabel="F9" android:codes="@integer/key_fkey_f9" android:isModifier="true" />
+ <Key android:keyLabel="F10" android:codes="@integer/key_fkey_f10" android:isModifier="true" />
+ <Key android:keyLabel="F11" android:codes="@integer/key_fkey_f11" android:isModifier="true" />
+ <Key android:keyLabel="F12" android:codes="@integer/key_fkey_f12" android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_home"
+ android:isModifier="true"
+ android:keyLabel="Home" />
+ <Key
+ android:codes="@integer/key_end"
+ android:isModifier="true"
+ android:keyLabel="End"
+ android:keyEdgeFlags="right" />
+ />
+ </Row>
+ <Row
+ android:rowEdgeFlags="top"
+ >
+ <Key
+ android:keyLabel="@string/key_tlde_main"
+ android:shiftLabel="@string/key_tlde_shift"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/key_tlde_alt"
+ android:keyWidth="4.5714285%p"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="@string/key_ae01_main"
+ android:shiftLabel="@string/key_ae01_shift"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/key_ae01_alt" />
+ <Key
+ android:keyLabel="@string/key_ae02_main"
+ android:shiftLabel="@string/key_ae02_shift"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/key_ae02_alt" />
+ <Key
+ android:keyLabel="@string/key_ae03_main"
+ android:shiftLabel="@string/key_ae03_shift"
+ android:popupKeyboard="@xml/kbd_popup_narrow_template"
+ android:popupCharacters="@string/key_ae03_alt" />
+ <Key
+ android:keyLabel="@string/key_ae04_main"
+ android:shiftLabel="@string/key_ae04_shift"
+ android:popupKeyboard="@xml/kbd_popup_narrow_template"
+ android:popupCharacters="@string/key_ae04_alt" />
+ <Key
+ android:keyLabel="@string/key_ae05_main"
+ android:shiftLabel="@string/key_ae05_shift"
+ android:popupKeyboard="@xml/kbd_popup_narrow_template"
+ android:popupCharacters="@string/key_ae05_alt" />
+ <Key
+ android:keyLabel="@string/key_ae06_main"
+ android:shiftLabel="@string/key_ae06_shift"
+ android:popupKeyboard="@xml/kbd_popup_narrow_template"
+ android:popupCharacters="@string/key_ae06_alt" />
+ <Key
+ android:keyLabel="@string/key_ae07_main"
+ android:shiftLabel="@string/key_ae07_shift"
+ android:popupKeyboard="@xml/kbd_popup_narrow_template"
+ android:popupCharacters="@string/key_ae07_alt" />
+ <Key
+ android:keyLabel="@string/key_ae08_main"
+ android:shiftLabel="@string/key_ae08_shift"
+ android:popupKeyboard="@xml/kbd_popup_narrow_template"
+ android:popupCharacters="@string/key_ae08_alt" />
+ <Key
+ android:keyLabel="@string/key_ae09_main"
+ android:shiftLabel="@string/key_ae09_shift"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/key_ae09_alt" />
+ <Key
+ android:keyLabel="@string/key_ae10_main"
+ android:shiftLabel="@string/key_ae10_shift"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/key_ae10_alt" />
+ <Key
+ android:keyLabel="@string/key_ae11_main"
+ android:shiftLabel="@string/key_ae11_shift"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/key_ae11_alt" />
+ <Key
+ android:keyLabel="@string/key_ae12_main"
+ android:shiftLabel="@string/key_ae12_shift"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/key_ae12_alt" />
+ <Key
+ android:codes="@integer/key_delete"
+ android:keyIcon="@drawable/sym_keyboard_delete"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:keyWidth="9.7142855%p"
+ android:isModifier="true"
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:keyEdgeFlags="left"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="@string/key_ad01_main"
+ android:shiftLabel="@string/key_ad01_shift"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/key_ad01_alt" />
+ <Key
+ android:keyLabel="@string/key_ad02_main"
+ android:shiftLabel="@string/key_ad02_shift"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/key_ad02_alt" />
+ <Key
+ android:keyLabel="@string/key_ad03_main"
+ android:shiftLabel="@string/key_ad03_shift"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/key_ad03_alt" />
+ <Key
+ android:keyLabel="@string/key_ad04_main"
+ android:shiftLabel="@string/key_ad04_shift"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/key_ad04_alt" />
+ <Key
+ android:keyLabel="@string/key_ad05_main"
+ android:shiftLabel="@string/key_ad05_shift"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/key_ad05_alt" />
+ <Key
+ android:keyLabel="@string/key_ad06_main"
+ android:shiftLabel="@string/key_ad06_shift"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/key_ad06_alt" />
+ <Key
+ android:keyLabel="@string/key_ad07_main"
+ android:shiftLabel="@string/key_ad07_shift"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/key_ad07_alt" />
+ <Key
+ android:keyLabel="@string/key_ad08_main"
+ android:shiftLabel="@string/key_ad08_shift"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/key_ad08_alt" />
+ <Key
+ android:keyLabel="@string/key_ad09_main"
+ android:shiftLabel="@string/key_ad09_shift"
+ android:popupKeyboard="@xml/kbd_popup_narrow_template"
+ android:popupCharacters="@string/key_ad09_alt" />
+
+ <Key
+ android:keyLabel="@string/key_ad10_main"
+ android:shiftLabel="@string/key_ad10_shift"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/key_ad10_alt"
+ />
+ <Key
+ android:keyLabel="@string/key_ad11_main"
+ android:shiftLabel="@string/key_ad11_shift"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/key_ad11_alt" />res/xml/kbd_full.xml
+ <Key
+ android:keyLabel="@string/key_ad12_main"
+ android:shiftLabel="@string/key_ad12_shift"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/key_ad12_alt" />
+ <Key
+ android:keyLabel="@string/key_bksl_main"
+ android:shiftLabel="@string/key_bksl_shift"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/key_bksl_alt"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:keyLabel="Ctrl"
+ android:keyWidth="10.7142855%p"
+ android:codes="@integer/key_ctrl_left"
+ android:isSticky="true"
+ android:keyEdgeFlags="left"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="@string/key_ac01_main"
+ android:shiftLabel="@string/key_ac01_shift"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/key_ac01_alt" />
+ <Key
+ android:keyLabel="@string/key_ac02_main"
+ android:shiftLabel="@string/key_ac02_shift"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/key_ac02_alt" />
+ <Key
+ android:keyLabel="@string/key_ac03_main"
+ android:shiftLabel="@string/key_ac03_shift"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/key_ac03_alt" />
+ <Key
+ android:keyLabel="@string/key_ac04_main"
+ android:shiftLabel="@string/key_ac04_shift"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/key_ac04_alt" />
+ <Key
+ android:keyLabel="@string/key_ac05_main"
+ android:shiftLabel="@string/key_ac05_shift"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/key_ac05_alt" />
+ <Key
+ android:keyLabel="@string/key_ac06_main"
+ android:shiftLabel="@string/key_ac06_shift"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/key_ac06_alt" />
+ <Key
+ android:keyLabel="@string/key_ac07_main"
+ android:shiftLabel="@string/key_ac07_shift"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/key_ac07_alt" />
+ <Key
+ android:keyLabel="@string/key_ac08_main"
+ android:shiftLabel="@string/key_ac08_shift"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/key_ac08_alt" />
+ <Key
+ android:keyLabel="@string/key_ac09_main"
+ android:shiftLabel="@string/key_ac09_shift"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/key_ac09_alt" />
+ <Key
+ android:keyLabel="@string/key_ac10_main"
+ android:shiftLabel="@string/key_ac10_shift"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/key_ac10_alt" />
+ <Key
+ android:keyLabel="@string/key_ac11_main"
+ android:shiftLabel="@string/key_ac11_shift"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/key_ac11_alt" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="10.7142855%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:codes="@integer/key_shift"
+ android:keyIcon="@drawable/sym_keyboard_shift"
+ android:iconPreview="@drawable/sym_keyboard_feedback_shift"
+ android:isModifier="true"
+ android:isSticky="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="@string/key_lsgt_main"
+ android:shiftLabel="@string/key_lsgt_shift"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/key_lsgt_alt" />
+ <Key
+ android:keyLabel="@string/key_ab01_main"
+ android:shiftLabel="@string/key_ab01_shift"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/key_ab01_alt" />
+ <Key
+ android:keyLabel="@string/key_ab02_main"
+ android:shiftLabel="@string/key_ab02_shift"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/key_ab02_alt" />
+ <Key
+ android:keyLabel="@string/key_ab03_main"
+ android:shiftLabel="@string/key_ab03_shift"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/key_ab03_alt" />
+ <Key
+ android:keyLabel="@string/key_ab04_main"
+ android:shiftLabel="@string/key_ab04_shift"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/key_ab04_alt" />
+ <Key
+ android:keyLabel="@string/key_ab05_main"
+ android:shiftLabel="@string/key_ab05_shift"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/key_ab05_alt" />
+ <Key
+ android:keyLabel="@string/key_ab06_main"
+ android:shiftLabel="@string/key_ab06_shift"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/key_ab06_alt" />
+ <Key
+ android:keyLabel="@string/key_ab07_main"
+ android:shiftLabel="@string/key_ab07_shift"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/key_ab07_alt" />
+ <Key
+ android:keyLabel="@string/key_ab08_main"
+ android:shiftLabel="@string/key_ab08_shift"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/key_ab08_alt" />
+ <Key
+ android:keyLabel="@string/key_ab09_main"
+ android:shiftLabel="@string/key_ab09_shift"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/key_ab09_alt" />
+ <Key
+ android:keyLabel="@string/key_ab10_main"
+ android:shiftLabel="@string/key_ab10_shift"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/key_ab10_alt" />
+ <Key
+ android:codes="@integer/key_dpad_up"
+ android:isRepeatable="true"
+ android:keyLabel="&#x25b3;"
+ android:isCursor="true"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_shift"
+ android:keyIcon="@drawable/sym_keyboard_shift"
+ android:keyEdgeFlags="right"
+ android:isModifier="true" />
+ </Row>
+ <Row
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:keyLabel="Esc"
+ android:codes="@integer/key_escape"
+ android:keyWidth="10.7142855%p"
+ android:keyEdgeFlags="left"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_alt_left"
+ android:keyLabel="Alt"
+ android:isSticky="true"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:shiftLabel="@string/key_space_shift"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="39.2857142857%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_fn"
+ android:keyLabel="Fn"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_dpad_center"
+ android:isModifier="true"
+ android:isCursor="true"
+ android:keyLabel="&#x25cb;" />
+ <Key
+ android:codes="@integer/key_dpad_left"
+ android:isModifier="true"
+ android:isRepeatable="true"
+ android:isCursor="true"
+ android:keyLabel="&#x25c1;" />
+ <Key
+ android:codes="@integer/key_dpad_down"
+ android:isModifier="true"
+ android:isRepeatable="true"
+ android:isCursor="true"
+ android:keyLabel="&#x25bd;" />
+ <Key
+ android:codes="@integer/key_dpad_right"
+ android:isModifier="true"
+ android:keyLabel="&#x25b7;"
+ android:isRepeatable="true"
+ android:isCursor="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+</Keyboard>
diff --git a/java/res/xml/kbd_full_fn.xml b/java/res/xml/kbd_full_fn.xml
new file mode 100644
index 0000000..65c4e0d
--- /dev/null
+++ b/java/res/xml/kbd_full_fn.xml
@@ -0,0 +1,320 @@
+<?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:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="7.1428571485%p"
+ android:horizontalGap="0px"
+ android:verticalGap="@dimen/key_bottom_gap"
+ android:layoutRows="5"
+ android:layoutColumns="14"
+>
+ <Row
+ android:rowEdgeFlags="top"
+ >
+ <Key
+ android:codes="@integer/key_f1"
+ android:keyWidth="10.7142855%p"
+ android:keyEdgeFlags="left"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_fkey_f1"
+ android:keyWidth="8.035714%p"
+ android:isModifier="true"
+ android:keyLabel="F1" />
+ <Key
+ android:codes="@integer/key_fkey_f2"
+ android:keyWidth="8.035714%p"
+ android:isModifier="true"
+ android:keyLabel="F2" />
+ <Key
+ android:codes="@integer/key_fkey_f3"
+ android:keyWidth="8.035714%p"
+ android:isModifier="true"
+ android:keyLabel="F3" />
+ <Key
+ android:codes="@integer/key_fkey_f4"
+ android:keyWidth="8.035714%p"
+ android:isModifier="true"
+ android:keyLabel="F4" />
+ <Key
+ android:keyWidth="8.035714%p"
+ android:keyLabel="7" />
+ <Key
+ android:keyWidth="8.035714%p"
+ android:keyLabel="8" />
+ <Key
+ android:keyWidth="8.035714%p"
+ android:keyLabel="9" />
+ <Key
+ android:keyWidth="8.035714%p"
+ android:keyLabel="/" />
+ <Key
+ android:codes="@integer/key_home"
+ android:keyWidth="10.7142855%p"
+ android:isModifier="true"
+ android:isRepeatable="true"
+ android:keyLabel="Home" />
+ <Key
+ android:codes="@integer/key_delete"
+ android:keyIcon="@drawable/sym_keyboard_delete"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:keyWidth="14.2857142%p"
+ android:isModifier="true"
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:keyWidth="10.7142855%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_fkey_f5"
+ android:keyWidth="8.035714%p"
+ android:isModifier="true"
+ android:keyLabel="F5" />
+ <Key
+ android:codes="@integer/key_fkey_f6"
+ android:keyWidth="8.035714%p"
+ android:isModifier="true"
+ android:keyLabel="F6" />
+ <Key
+ android:codes="@integer/key_fkey_f7"
+ android:keyWidth="8.035714%p"
+ android:isModifier="true"
+ android:keyLabel="F7" />
+ <Key
+ android:codes="@integer/key_fkey_f8"
+ android:keyWidth="8.035714%p"
+ android:isModifier="true"
+ android:keyLabel="F8" />
+
+ <Key
+ android:keyWidth="8.035714%p"
+ android:keyLabel="4" />
+ <Key
+ android:keyWidth="8.035714%p"
+ android:keyLabel="5" />
+ <Key
+ android:keyWidth="8.035714%p"
+ android:keyLabel="6" />
+ <Key
+ android:keyWidth="8.035714%p"
+ android:keyLabel="*" />
+
+ <Key
+ android:codes="@integer/key_end"
+ android:keyWidth="10.7142855%p"
+ android:isModifier="true"
+ android:keyLabel="End"
+ android:isRepeatable="true" />
+
+ <Key
+ android:codes="@integer/key_insert"
+ android:keyLabel="Ins"
+ android:isRepeatable="true"
+ android:isModifier="true" />
+
+ <Key
+ android:codes="@integer/key_forward_del"
+ android:keyLabel="Del"
+ android:isRepeatable="true"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:keyLabel="Ctrl"
+ android:keyWidth="10.7142855%p"
+ android:codes="@integer/key_ctrl_left"
+ android:isSticky="true"
+ android:keyEdgeFlags="left"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_fkey_f9"
+ android:keyWidth="8.035714%p"
+ android:isModifier="true"
+ android:keyLabel="F9" />
+ <Key
+ android:codes="@integer/key_fkey_f10"
+ android:keyWidth="8.035714%p"
+ android:isModifier="true"
+ android:keyLabel="F10" />
+ <Key
+ android:codes="@integer/key_fkey_f11"
+ android:keyWidth="8.035714%p"
+ android:isModifier="true"
+ android:keyLabel="F11" />
+ <Key
+ android:codes="@integer/key_fkey_f12"
+ android:keyWidth="8.035714%p"
+ android:isModifier="true"
+ android:keyLabel="F12" />
+
+ <Key
+ android:keyWidth="8.035714%p"
+ android:keyLabel="1" />
+ <Key
+ android:keyWidth="8.035714%p"
+ android:keyLabel="2" />
+ <Key
+ android:keyWidth="8.035714%p"
+ android:keyLabel="3" />
+ <Key
+ android:keyWidth="8.035714%p"
+ android:keyLabel="-" />
+
+ <Key
+ android:codes="@integer/key_page_up"
+ android:keyWidth="10.7142855%p"
+ android:isModifier="true"
+ android:isRepeatable="true"
+ android:keyLabel="PgUp" />
+
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="14.2857142%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:codes="@integer/key_shift"
+ android:keyIcon="@drawable/sym_keyboard_shift"
+ android:iconPreview="@drawable/sym_keyboard_feedback_shift"
+ android:keyWidth="10.7142855%p"
+ android:isModifier="true"
+ android:isSticky="true"
+ android:keyEdgeFlags="left" />
+
+ <Key
+ android:codes="@integer/key_sysrq"
+ android:keyWidth="8.035714%p"
+ android:isModifier="true"
+ android:keyLabel="SyRq" />
+ <Key
+ android:codes="@integer/key_scroll_lock"
+ android:keyWidth="8.035714%p"
+ android:isModifier="true"
+ android:keyLabel="ScrL" />
+ <Key
+ android:codes="@integer/key_break"
+ android:keyWidth="8.035714%p"
+ android:isModifier="true"
+ android:keyLabel="Brk" />
+ <Key
+ android:codes="@integer/key_num_lock"
+ android:keyWidth="8.035714%p"
+ android:isModifier="true"
+ android:keyLabel="NumL" />
+
+ <Key
+ android:keyWidth="8.035714%p"
+ android:keyLabel="0" />
+ <Key
+ android:keyWidth="8.035714%p"
+ android:keyLabel="," />
+ <Key
+ android:keyWidth="8.035714%p"
+ android:keyLabel="." />
+ <Key
+ android:keyWidth="8.035714%p"
+ android:keyLabel="+" />
+
+ <Key
+ android:codes="@integer/key_page_down"
+ android:keyWidth="10.7142857143%p"
+ android:isModifier="true"
+ android:isRepeatable="true"
+ android:keyLabel="PgDn" />
+
+ <Key
+ android:codes="@integer/key_dpad_up"
+ android:isRepeatable="true"
+ android:keyLabel="&#x25b3;"
+ android:isCursor="true"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_shift"
+ android:keyIcon="@drawable/sym_keyboard_shift"
+ android:keyEdgeFlags="right"
+ android:isModifier="true" />
+ </Row>
+ <Row
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:keyLabel="Esc"
+ android:codes="@integer/key_escape"
+ android:keyWidth="10.7142855%p"
+ android:keyEdgeFlags="left"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_alt_left"
+ android:keyLabel="Alt"
+ android:isSticky="true"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="39.2857142857%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_fn"
+ android:keyLabel="Fn"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_dpad_center"
+ android:isModifier="true"
+ android:isCursor="true"
+ android:keyLabel="&#x25cb;" />
+ <Key
+ android:codes="@integer/key_dpad_left"
+ android:isModifier="true"
+ android:isRepeatable="true"
+ android:isCursor="true"
+ android:keyLabel="&#x25c1;" />
+ <Key
+ android:codes="@integer/key_dpad_down"
+ android:isModifier="true"
+ android:isRepeatable="true"
+ android:isCursor="true"
+ android:keyLabel="&#x25bd;" />
+ <Key
+ android:codes="@integer/key_dpad_right"
+ android:isModifier="true"
+ android:keyLabel="&#x25b7;"
+ android:isRepeatable="true"
+ android:isCursor="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+</Keyboard>
diff --git a/java/res/xml/kbd_phone.xml b/java/res/xml/kbd_phone.xml
new file mode 100644
index 0000000..9586956
--- /dev/null
+++ b/java/res/xml/kbd_phone.xml
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<Keyboard
+ xmlns:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="26.67%p"
+ android:horizontalGap="0px"
+ android:verticalGap="@dimen/key_bottom_gap"
+>
+ <Row
+ android:rowEdgeFlags="top"
+ >
+ <Key
+ android:codes="49"
+ android:keyIcon="@drawable/sym_keyboard_num1"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="50"
+ android:keyIcon="@drawable/sym_keyboard_num2" />
+ <Key
+ android:codes="51"
+ android:keyIcon="@drawable/sym_keyboard_num3" />
+ <Key
+ android:keyLabel="-"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:codes="52"
+ android:keyIcon="@drawable/sym_keyboard_num4"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="53"
+ android:keyIcon="@drawable/sym_keyboard_num5" />
+ <Key
+ android:codes="54"
+ android:keyIcon="@drawable/sym_keyboard_num6" />
+ <Key
+ android:keyLabel="."
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:codes="55"
+ android:keyIcon="@drawable/sym_keyboard_num7"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="56"
+ android:keyIcon="@drawable/sym_keyboard_num8" />
+ <Key
+ android:codes="57"
+ android:keyIcon="@drawable/sym_keyboard_num9" />
+ <Key
+ android:codes="@integer/key_delete"
+ android:keyIcon="@drawable/sym_keyboard_delete"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyIcon="@drawable/sym_keyboard_numalt"
+ android:iconPreview="@drawable/sym_keyboard_feedback_numalt"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="48"
+ android:keyIcon="@drawable/sym_keyboard_num0" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+</Keyboard>
diff --git a/java/res/xml/kbd_phone_symbols.xml b/java/res/xml/kbd_phone_symbols.xml
new file mode 100644
index 0000000..34ba050
--- /dev/null
+++ b/java/res/xml/kbd_phone_symbols.xml
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<Keyboard
+ xmlns:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="26.67%p"
+ android:horizontalGap="0px"
+ android:verticalGap="@dimen/key_bottom_gap"
+>
+ <Row
+ android:rowEdgeFlags="top"
+ >
+ <Key
+ android:keyLabel="("
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="/" />
+ <Key
+ android:keyLabel=")" />
+ <Key
+ android:keyLabel="-"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:keyLabel="N"
+ android:keyEdgeFlags="left" />
+ <!-- Pause is a comma. Check PhoneNumberUtils.java to see if this
+ has changed. -->
+ <Key
+ android:codes="44"
+ android:keyLabel="Pause" />
+ <Key
+ android:keyLabel="," />
+ <Key
+ android:keyLabel="."
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:codes="42"
+ android:keyIcon="@drawable/sym_keyboard_numstar"
+ android:keyEdgeFlags="left" />
+ <!-- Wait is a semicolon. -->
+ <Key
+ android:codes="59"
+ android:keyLabel="Wait" />
+ <Key
+ android:codes="35"
+ android:keyIcon="@drawable/sym_keyboard_numpound" />
+ <Key
+ android:codes="@integer/key_delete"
+ android:keyIcon="@drawable/sym_keyboard_delete"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_phone_key"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="+" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+</Keyboard>
diff --git a/java/res/xml/kbd_popup_narrow_template.xml b/java/res/xml/kbd_popup_narrow_template.xml
new file mode 100644
index 0000000..6138d8f
--- /dev/null
+++ b/java/res/xml/kbd_popup_narrow_template.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2010, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT 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:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="9%p"
+ android:horizontalGap="0px"
+ android:verticalGap="0px"
+ android:keyHeight="@dimen/popup_key_height"
+ >
+</Keyboard>
diff --git a/java/res/xml/kbd_popup_template.xml b/java/res/xml/kbd_popup_template.xml
new file mode 100644
index 0000000..9586093
--- /dev/null
+++ b/java/res/xml/kbd_popup_template.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<Keyboard xmlns:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="10%p"
+ android:horizontalGap="0px"
+ android:verticalGap="0px"
+ android:keyHeight="@dimen/popup_key_height"
+ >
+</Keyboard>
diff --git a/java/res/xml/kbd_qwerty.xml b/java/res/xml/kbd_qwerty.xml
new file mode 100644
index 0000000..ed247fa
--- /dev/null
+++ b/java/res/xml/kbd_qwerty.xml
@@ -0,0 +1,527 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<Keyboard
+ xmlns:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="10%p"
+ android:horizontalGap="0px"
+ android:verticalGap="@dimen/key_bottom_gap"
+>
+ <Row android:extension="true">
+ <Key android:keyLabel="1" android:shiftLabel="!" />
+ <Key android:keyLabel="2" android:shiftLabel="\@" />
+ <Key android:keyLabel="3" android:shiftLabel="\#" />
+ <Key android:keyLabel="4" android:shiftLabel="&amp;" />
+ <Key android:keyLabel="5" android:shiftLabel="-" />
+ <Key android:keyLabel="6" android:shiftLabel="\'" />
+ <Key android:keyLabel="7" android:shiftLabel=":" />
+ <Key android:keyLabel="8" android:shiftLabel="&quot;" />
+ <Key android:keyLabel="9" android:shiftLabel="/" />
+ <Key android:keyLabel="0" android:shiftLabel="\?" />
+ </Row>
+ <Row>
+ <Key
+ android:keyLabel="q"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_q"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="w"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_w" />
+ <Key
+ android:keyLabel="e"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_e" />
+ <Key
+ android:keyLabel="r"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_r" />
+ <Key
+ android:keyLabel="t"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_t" />
+ <Key
+ android:keyLabel="y"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_y" />
+ <Key
+ android:keyLabel="u"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_u" />
+ <Key
+ android:keyLabel="i"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_i" />
+ <Key
+ android:keyLabel="o"
+ android:popupKeyboard="@xml/kbd_popup_narrow_template"
+ android:popupCharacters="@string/alternates_for_o" />
+ <Key
+ android:keyLabel="p"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_p"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:keyLabel="a"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_a"
+ android:horizontalGap="5%p"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="s"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_s" />
+ <Key
+ android:keyLabel="d"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_d" />
+ <Key
+ android:keyLabel="f"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_f" />
+ <Key
+ android:keyLabel="g"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_g" />
+ <Key
+ android:keyLabel="h"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_h" />
+ <Key
+ android:keyLabel="j"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_j" />
+ <Key
+ android:keyLabel="k"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_k" />
+ <Key
+ android:keyLabel="l"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_l"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:codes="@integer/key_shift"
+ android:keyIcon="@drawable/sym_keyboard_shift"
+ android:iconPreview="@drawable/sym_keyboard_feedback_shift"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:isSticky="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="z"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_z" />
+ <Key
+ android:keyLabel="x"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_x" />
+ <Key
+ android:keyLabel="c"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_c" />
+ <Key
+ android:keyLabel="v"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_v" />
+ <Key
+ android:keyLabel="b"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_b" />
+ <Key
+ android:keyLabel="n"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_n" />
+ <Key
+ android:keyLabel="m"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="@string/alternates_for_m" />
+ <Key
+ android:codes="@integer/key_delete"
+ android:keyIcon="@drawable/sym_keyboard_delete"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_normal_with_settings_key"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_url_with_settings_key"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_email_with_settings_key"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_im_with_settings_key"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_smileys"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_webentry_with_settings_key"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_symbol_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyIcon="@drawable/sym_keyboard_tab"
+ android:iconPreview="@drawable/sym_keyboard_feedback_tab"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+</Keyboard>
diff --git a/java/res/xml/kbd_symbols.xml b/java/res/xml/kbd_symbols.xml
new file mode 100644
index 0000000..82eebbb
--- /dev/null
+++ b/java/res/xml/kbd_symbols.xml
@@ -0,0 +1,213 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<Keyboard
+ xmlns:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="10%p"
+ android:horizontalGap="0px"
+ android:verticalGap="@dimen/key_bottom_gap"
+>
+ <Row
+ android:rowEdgeFlags="top"
+ >
+ <Key
+ android:keyLabel="1"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="¹½⅓¼⅛"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="2"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="²⅔" />
+ <Key
+ android:keyLabel="3"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="³¾⅜" />
+ <Key
+ android:keyLabel="4"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="⁴" />
+ <Key
+ android:keyLabel="5"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="⅝" />
+ <Key
+ android:keyLabel="6" />
+ <Key
+ android:keyLabel="7"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="⅞" />
+ <Key
+ android:keyLabel="8" />
+ <Key
+ android:keyLabel="9" />
+ <Key
+ android:keyLabel="0"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="ⁿ∅"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:keyLabel="\@"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="\#" />
+ <Key
+ android:keyLabel="$"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="¢£€¥₣₤₱" />
+ <Key
+ android:keyLabel="%"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="‰" />
+ <Key
+ android:keyLabel="&amp;" />
+ <Key
+ android:keyLabel="*"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="†‡★" />
+ <Key
+ android:keyLabel="-"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="_–—" />
+ <Key
+ android:keyLabel="+"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="±" />
+ <Key
+ android:keyLabel="("
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="[{&lt;" />
+ <Key
+ android:keyLabel=")"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="]}&gt;"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:codes="@integer/key_shift"
+ android:keyLabel="@string/label_alt_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:isSticky="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="!"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="¡" />
+ <Key
+ android:keyLabel="&quot;"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="“”«»˝" />
+ <Key
+ android:keyLabel="\'"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="‘’" />
+ <Key
+ android:keyLabel=":" />
+ <Key
+ android:keyLabel=";" />
+ <Key
+ android:keyLabel="/" />
+ <Key
+ android:keyLabel="\?"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="¿" />
+ <Key
+ android:codes="@integer/key_delete"
+ android:keyIcon="@drawable/sym_keyboard_delete"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_symbols"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_alpha_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_symbols_with_settings_key"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_alpha_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_f1"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="."
+ android:keyIcon="@drawable/hint_popup"
+ android:popupKeyboard="@xml/popup_punctuation"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+</Keyboard>
diff --git a/java/res/xml/kbd_symbols_shift.xml b/java/res/xml/kbd_symbols_shift.xml
new file mode 100644
index 0000000..6c9f1f9
--- /dev/null
+++ b/java/res/xml/kbd_symbols_shift.xml
@@ -0,0 +1,188 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<Keyboard
+ xmlns:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="10%p"
+ android:horizontalGap="0px"
+ android:verticalGap="@dimen/key_bottom_gap"
+>
+ <Row
+ android:rowEdgeFlags="top"
+ >
+ <Key
+ android:keyLabel="~"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="`" />
+ <Key
+ android:keyLabel="|" />
+ <Key
+ android:keyLabel="•"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="♪♥♠♦♣" />
+ <Key
+ android:keyLabel="√" />
+ <Key
+ android:keyLabel="π"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="Π" />
+ <Key
+ android:keyLabel="÷" />
+ <Key
+ android:keyLabel="×" />
+ <Key
+ android:keyLabel="{" />
+ <Key
+ android:keyLabel="}"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:codes="@integer/key_tab"
+ android:keyLabel="\u21E5"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="£" />
+ <Key
+ android:keyLabel="¢" />
+ <Key
+ android:keyLabel="€" />
+ <Key
+ android:keyLabel="°" />
+ <Key
+ android:keyLabel="^"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="↑↓←→" />
+ <Key
+ android:keyLabel="_" />
+ <Key
+ android:keyLabel="="
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="≠≈∞" />
+ <Key
+ android:keyLabel="[" />
+ <Key
+ android:keyLabel="]"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:codes="@integer/key_shift"
+ android:keyLabel="@string/label_alt_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:isSticky="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="™" />
+ <Key
+ android:keyLabel="®" />
+ <Key
+ android:keyLabel="©" />
+ <Key
+ android:keyLabel="¶"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="§" />
+ <Key
+ android:keyLabel="\\" />
+ <Key
+ android:keyLabel="&lt;"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="≤«‹" />
+ <Key
+ android:keyLabel="&gt;"
+ android:popupKeyboard="@xml/kbd_popup_template"
+ android:popupCharacters="≥»›" />
+ <Key
+ android:codes="@integer/key_delete"
+ android:keyIcon="@drawable/sym_keyboard_delete"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_symbols"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_alpha_key"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="„"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="40%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="…"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="20%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:keyboardMode="@+id/mode_symbols_with_settings_key"
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:codes="@integer/key_symbol"
+ android:keyLabel="@string/label_alpha_key"
+ android:keyWidth="15%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:iconPreview="@drawable/sym_keyboard_feedback_settings"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="„"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_space"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="30%p"
+ android:isModifier="true" />
+ <Key
+ android:keyLabel="…"
+ android:isModifier="true" />
+ <Key
+ android:codes="@integer/key_return"
+ android:keyIcon="@drawable/sym_keyboard_return"
+ android:iconPreview="@drawable/sym_keyboard_feedback_return"
+ android:keyWidth="25%p"
+ android:isModifier="true"
+ android:keyEdgeFlags="right" />
+ </Row>
+</Keyboard>
diff --git a/java/res/xml/language_prefs.xml b/java/res/xml/language_prefs.xml
new file mode 100644
index 0000000..b7a4c07
--- /dev/null
+++ b/java/res/xml/language_prefs.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 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.
+-->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+ android:title="@string/language_selection_title">
+</PreferenceScreen>
diff --git a/java/res/xml/method.xml b/java/res/xml/method.xml
new file mode 100644
index 0000000..31a997d
--- /dev/null
+++ b/java/res/xml/method.xml
@@ -0,0 +1,26 @@
+<?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.
+ */
+-->
+
+<!-- The attributes in this XML file provide configuration information -->
+<!-- for the Input Method Manager. -->
+
+<input-method xmlns:android="http://schemas.android.com/apk/res/android"
+ android:settingsActivity="org.pocketworkstation.pckeyboard.LatinIMESettings"
+ android:isDefault="@bool/im_is_default"
+/>
diff --git a/java/res/xml/popup_at.xml b/java/res/xml/popup_at.xml
new file mode 100644
index 0000000..fe0c94c
--- /dev/null
+++ b/java/res/xml/popup_at.xml
@@ -0,0 +1,39 @@
+<?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:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="10%p"
+ android:horizontalGap="0px"
+ android:verticalGap="0px"
+ android:keyHeight="@dimen/popup_key_height"
+>
+ <Row
+ android:rowEdgeFlags="top|bottom"
+ >
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="\@"
+ android:keyEdgeFlags="right" />
+ </Row>
+</Keyboard>
diff --git a/java/res/xml/popup_comma.xml b/java/res/xml/popup_comma.xml
new file mode 100644
index 0000000..5dbbd01
--- /dev/null
+++ b/java/res/xml/popup_comma.xml
@@ -0,0 +1,39 @@
+<?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:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="10%p"
+ android:horizontalGap="0px"
+ android:verticalGap="0px"
+ android:keyHeight="@dimen/popup_key_height"
+>
+ <Row
+ android:rowEdgeFlags="top|bottom"
+ >
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel=","
+ android:keyEdgeFlags="right" />
+ </Row>
+</Keyboard>
diff --git a/java/res/xml/popup_domains.xml b/java/res/xml/popup_domains.xml
new file mode 100644
index 0000000..a82bda8
--- /dev/null
+++ b/java/res/xml/popup_domains.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<Keyboard
+ xmlns:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="15%p"
+ android:horizontalGap="0px"
+ android:verticalGap="0px"
+ android:keyHeight="@dimen/popup_key_height"
+>
+ <Row
+ android:rowEdgeFlags="top|bottom"
+ >
+ <Key
+ android:keyLabel="@string/popular_domain_1"
+ android:keyOutputText="@string/popular_domain_1"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="@string/popular_domain_2"
+ android:keyOutputText="@string/popular_domain_2" />
+ <Key
+ android:keyLabel="@string/popular_domain_3"
+ android:keyOutputText="@string/popular_domain_3" />
+ <Key
+ android:keyLabel="@string/popular_domain_4"
+ android:keyOutputText="@string/popular_domain_4"
+ android:keyEdgeFlags="right" />
+ </Row>
+</Keyboard>
diff --git a/java/res/xml/popup_mic.xml b/java/res/xml/popup_mic.xml
new file mode 100644
index 0000000..45fafc7
--- /dev/null
+++ b/java/res/xml/popup_mic.xml
@@ -0,0 +1,40 @@
+<?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:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="10%p"
+ android:horizontalGap="0px"
+ android:verticalGap="0px"
+ android:keyHeight="@dimen/popup_key_height"
+>
+ <Row
+ android:rowEdgeFlags="top|bottom"
+ >
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:codes="@integer/key_voice"
+ android:keyIcon="@drawable/sym_keyboard_mic"
+ android:keyEdgeFlags="right" />
+ </Row>
+</Keyboard>
diff --git a/java/res/xml/popup_punctuation.xml b/java/res/xml/popup_punctuation.xml
new file mode 100644
index 0000000..9b0b4be
--- /dev/null
+++ b/java/res/xml/popup_punctuation.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<Keyboard
+ xmlns:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="10%p"
+ android:horizontalGap="0px"
+ android:verticalGap="0px"
+ android:keyHeight="@dimen/popup_key_height"
+>
+ <Row
+ android:rowEdgeFlags="top"
+ >
+ <Key
+ android:keyLabel=":"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="/" />
+ <Key
+ android:keyLabel="&amp;" />
+ <Key
+ android:keyLabel="(" />
+ <Key
+ android:keyLabel=")" />
+ <Key
+ android:keyLabel="-" />
+ <Key
+ android:keyLabel="+"
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:keyLabel=";"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="\@" />
+ <Key
+ android:keyLabel="\'" />
+ <Key
+ android:keyLabel="&quot;" />
+ <Key
+ android:keyLabel="\?" />
+ <Key
+ android:keyLabel="!" />
+ <Key
+ android:keyLabel=","
+ android:keyEdgeFlags="right" />
+ </Row>
+</Keyboard>
diff --git a/java/res/xml/popup_slash.xml b/java/res/xml/popup_slash.xml
new file mode 100644
index 0000000..1c52096
--- /dev/null
+++ b/java/res/xml/popup_slash.xml
@@ -0,0 +1,39 @@
+<?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:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="10%p"
+ android:horizontalGap="0px"
+ android:verticalGap="0px"
+ android:keyHeight="@dimen/popup_key_height"
+>
+ <Row
+ android:rowEdgeFlags="top|bottom"
+ >
+ <Key
+ android:codes="@integer/key_settings"
+ android:keyIcon="@drawable/sym_keyboard_settings"
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="/"
+ android:keyEdgeFlags="right" />
+ </Row>
+</Keyboard>
diff --git a/java/res/xml/popup_smileys.xml b/java/res/xml/popup_smileys.xml
new file mode 100644
index 0000000..02cefb9
--- /dev/null
+++ b/java/res/xml/popup_smileys.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<Keyboard
+ xmlns:android="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:keyWidth="15%p"
+ android:horizontalGap="0px"
+ android:verticalGap="0px"
+ android:keyHeight="@dimen/popup_key_height"
+>
+ <Row
+ android:rowEdgeFlags="top"
+ >
+ <Key
+ android:keyLabel=":-)"
+ android:keyOutputText=":-) "
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel=":-("
+ android:keyOutputText=":-( " />
+ <Key
+ android:keyLabel=";-)"
+ android:keyOutputText=";-) " />
+ <Key
+ android:keyLabel=":-P"
+ android:keyOutputText=":-P " />
+ <Key
+ android:keyLabel="=-O"
+ android:keyOutputText="=-O "
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row>
+ <Key
+ android:keyLabel=":-*"
+ android:keyOutputText=":-* "
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel=":O"
+ android:keyOutputText=":O " />
+ <Key
+ android:keyLabel="B-)"
+ android:keyOutputText="B-) " />
+ <Key
+ android:keyLabel=":-$"
+ android:keyOutputText=":-$ " />
+ <Key
+ android:keyLabel=":-!"
+ android:keyOutputText=":-! "
+ android:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ android:rowEdgeFlags="bottom"
+ >
+ <Key
+ android:keyLabel=":-["
+ android:keyOutputText=":-[ "
+ android:keyEdgeFlags="left" />
+ <Key
+ android:keyLabel="O:-)"
+ android:keyOutputText="O:-) " />
+ <Key
+ android:keyLabel=":-\\"
+ android:keyOutputText=":-\\ " />
+ <Key
+ android:keyLabel=":'("
+ android:keyOutputText=":'( " />
+ <Key
+ android:keyLabel=":-D"
+ android:keyOutputText=":-D "
+ android:keyEdgeFlags="right" />
+ </Row>
+</Keyboard>
diff --git a/java/res/xml/prefs.xml b/java/res/xml/prefs.xml
new file mode 100644
index 0000000..edcbb12
--- /dev/null
+++ b/java/res/xml/prefs.xml
@@ -0,0 +1,325 @@
+<?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.
+-->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:hk="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:title="@string/english_ime_settings"
+ android:key="english_ime_settings">
+
+ <PreferenceCategory
+ android:title="@string/title_keyboard_view_settings"
+ android:key="graphics_settings">
+
+ <org.pocketworkstation.pckeyboard.SeekBarPreferenceString
+ android:defaultValue="@string/default_height_portrait"
+ hk:minValue="15"
+ hk:maxValue="75"
+ hk:step="1"
+ hk:displayFormat="%.0f%%"
+ android:key="settings_height_portrait"
+ android:title="@string/title_keyboard_height_portrait"
+ android:persistent="true"
+ />
+
+ <org.pocketworkstation.pckeyboard.SeekBarPreferenceString
+ android:defaultValue="@string/default_height_landscape"
+ hk:minValue="15"
+ hk:maxValue="75"
+ hk:step="1"
+ hk:displayFormat="%.0f%%"
+ android:key="settings_height_landscape"
+ android:title="@string/title_keyboard_height_landscape"
+ android:persistent="true"
+ />
+
+ <org.pocketworkstation.pckeyboard.AutoSummaryListPreference
+ android:key="pref_keyboard_mode_portrait"
+ android:title="@string/title_keyboard_mode_portrait"
+ android:entryValues="@array/keyboard_mode_values"
+ android:entries="@array/keyboard_mode_entries"
+ android:defaultValue="@string/default_keyboard_mode_portrait"
+ android:persistent="true"
+ />
+
+ <org.pocketworkstation.pckeyboard.AutoSummaryListPreference
+ android:key="pref_keyboard_mode_landscape"
+ android:title="@string/title_keyboard_mode_landscape"
+ android:entryValues="@array/keyboard_mode_values"
+ android:entries="@array/keyboard_mode_entries"
+ android:defaultValue="@string/default_keyboard_mode_landscape"
+ android:persistent="true"
+ />
+
+ <CheckBoxPreference
+ android:key="suggestions_in_landscape"
+ android:title="@string/title_suggestions_in_landscape"
+ android:persistent="true"
+ android:defaultValue="@bool/default_suggestions_in_landscape"
+ android:summaryOn="@string/summary_suggestions_in_landscape_true"
+ android:summaryOff="@string/summary_suggestions_in_landscape_false"
+ />
+
+ <PreferenceScreen
+ android:title="@string/pref_screen_view_title"
+ android:summary="Configure theming and label display">
+ <intent android:action="org.pocketworkstation.pckeyboard.PREFS_VIEW"/>
+ </PreferenceScreen>
+
+ </PreferenceCategory>
+
+ <PreferenceCategory
+ android:title="@string/title_key_layout_options"
+ android:key="layout_settings">
+
+ <ListPreference
+ android:key="settings_key"
+ android:title="@string/prefs_settings_key"
+ android:persistent="true"
+ android:entryValues="@array/settings_key_modes_values"
+ android:entries="@array/settings_key_modes"
+ android:defaultValue="@string/settings_key_mode_auto"
+ />
+
+ <ListPreference
+ android:key="voice_mode"
+ android:title="@string/voice_input"
+ android:persistent="true"
+ android:entryValues="@array/voice_input_modes_values"
+ android:entries="@array/voice_input_modes"
+ android:defaultValue="@string/voice_mode_main"
+ />
+
+ <PreferenceScreen
+ android:title="@string/language_selection_title"
+ android:summary="@string/language_selection_summary">
+ <intent
+ android:action="org.pocketworkstation.pckeyboard.INPUT_LANGUAGE_SELECTION"/>
+ </PreferenceScreen>
+ </PreferenceCategory>
+
+ <PreferenceCategory
+ android:title="@string/title_key_behavior_settings"
+ android:key="key_settings">
+
+ <CheckBoxPreference
+ android:key="auto_cap"
+ android:title="@string/auto_cap"
+ android:persistent="true"
+ android:defaultValue="@bool/default_auto_cap"
+ />
+
+ <CheckBoxPreference
+ android:key="pref_caps_lock"
+ android:title="@string/title_caps_lock"
+ android:persistent="true"
+ android:defaultValue="@bool/default_caps_lock"
+ android:summaryOn="@string/summary_caps_lock_true"
+ android:summaryOff="@string/summary_caps_lock_false"
+ />
+
+ <CheckBoxPreference
+ android:key="pref_shift_lock_modifiers"
+ android:title="@string/title_shift_lock_modifiers"
+ android:persistent="true"
+ android:defaultValue="@bool/default_shift_lock_modifiers"
+ android:summaryOn="@string/summary_shift_lock_modifiers_true"
+ android:summaryOff="@string/summary_shift_lock_modifiers_false"
+ />
+
+ <PreferenceScreen
+ android:title="@string/pref_screen_feedback_title"
+ android:summary="Configure key sound, vibrate, preview popup etc.">
+ <intent
+ android:action="org.pocketworkstation.pckeyboard.PREFS_FEEDBACK"/>
+ </PreferenceScreen>
+
+ <PreferenceScreen
+ android:title="@string/pref_screen_actions_title"
+ android:summary="Configure actions for swipe gestures and hardware keys">
+ <intent android:action="org.pocketworkstation.pckeyboard.PREFS_ACTIONS"/>
+ </PreferenceScreen>
+
+ <org.pocketworkstation.pckeyboard.AutoSummaryListPreference
+ android:key="pref_chording_ctrl_key"
+ android:title="@string/title_chording_ctrl_key"
+ android:persistent="true"
+ android:entries="@array/chording_ctrl_key_entries"
+ android:entryValues="@array/chording_ctrl_key_values"
+ android:defaultValue="@string/default_chording_ctrl_key"
+ />
+
+ <org.pocketworkstation.pckeyboard.AutoSummaryListPreference
+ android:key="pref_chording_alt_key"
+ android:title="@string/title_chording_alt_key"
+ android:persistent="true"
+ android:entries="@array/chording_alt_key_entries"
+ android:entryValues="@array/chording_alt_key_values"
+ android:defaultValue="@string/default_chording_alt_key"
+ />
+
+ <org.pocketworkstation.pckeyboard.AutoSummaryListPreference
+ android:key="pref_slide_keys_int"
+ android:title="@string/title_slide_keys"
+ android:persistent="true"
+ android:entries="@array/slide_keys_entries"
+ android:entryValues="@array/slide_keys_values"
+ android:defaultValue="0"
+ />
+ </PreferenceCategory>
+
+ <PreferenceCategory
+ android:title="@string/title_long_press_alternate_keys"
+ android:key="altchar_settings">
+
+ <org.pocketworkstation.pckeyboard.AutoSummaryListPreference
+ android:key="pref_popup_content"
+ android:title="@string/title_popup_content"
+ android:persistent="true"
+ android:entryValues="@array/popup_content_values"
+ android:entries="@array/popup_content_entries"
+ android:defaultValue="@string/default_popup_content"
+ />
+
+ <org.pocketworkstation.pckeyboard.SeekBarPreferenceString
+ android:defaultValue="@string/default_long_press_duration"
+ hk:minValue="100"
+ hk:maxValue="2000"
+ hk:logScale="true"
+ hk:displayFormat="%.0f ms"
+ android:key="pref_long_press_duration"
+ android:title="@string/title_long_press_duration"
+ android:persistent="true"
+ />
+
+ </PreferenceCategory>
+
+ <PreferenceCategory
+ android:title="@string/prediction_category"
+ android:key="prediction_settings">
+
+ <CheckBoxPreference
+ android:key="quick_fixes"
+ android:title="@string/quick_fixes"
+ android:summary="@string/quick_fixes_summary"
+ android:persistent="true"
+ android:defaultValue="@bool/default_quick_fixes"
+ />
+
+ <CheckBoxPreference
+ android:key="show_suggestions"
+ android:title="@string/show_suggestions"
+ android:summary="@string/show_suggestions_summary"
+ android:persistent="true"
+ android:defaultValue="@bool/default_suggestions"
+ />
+
+ <CheckBoxPreference
+ android:key="auto_complete"
+ android:title="@string/auto_complete"
+ android:summary="@string/auto_complete_summary"
+ android:persistent="true"
+ android:defaultValue="@bool/enable_autocorrect"
+ android:dependency="show_suggestions"
+ />
+
+ <org.pocketworkstation.pckeyboard.AutoSummaryEditTextPreference
+ android:key="pref_suggested_punctuation"
+ android:title="@string/title_suggested_punctuation"
+ android:defaultValue="@string/suggested_punctuations"
+ />
+ </PreferenceCategory>
+
+ <PreferenceCategory
+ android:title="@string/title_input_mode_settings"
+ android:key="graphics_settings">
+
+ <CheckBoxPreference
+ android:key="recorrection_enabled"
+ android:title="@string/prefs_enable_recorrection"
+ android:summary="@string/prefs_enable_recorrection_summary"
+ android:persistent="true"
+ android:defaultValue="@bool/default_recorrection_enabled"
+ />
+
+ <CheckBoxPreference
+ android:key="fullscreen_override"
+ android:title="@string/title_fullscreen_override"
+ android:persistent="true"
+ android:defaultValue="@bool/default_fullscreen_override"
+ android:summaryOn="@string/summary_fullscreen_override_true"
+ android:summaryOff="@string/summary_fullscreen_override_false"
+ />
+
+ <CheckBoxPreference
+ android:key="force_keyboard_on"
+ android:title="@string/title_force_keyboard_on"
+ android:persistent="true"
+ android:defaultValue="@bool/default_force_keyboard_on"
+ android:summaryOn="@string/summary_force_keyboard_on_true"
+ android:summaryOff="@string/summary_force_keyboard_on_false"
+ />
+
+ <CheckBoxPreference
+ android:key="keyboard_notification"
+ android:title="@string/title_keyboard_notification"
+ android:persistent="true"
+ android:defaultValue="@bool/default_keyboard_notification"
+ android:summaryOn="@string/summary_keyboard_notification_true"
+ android:summaryOff="@string/summary_keyboard_notification_false"
+ />
+ </PreferenceCategory>
+
+ <PreferenceCategory
+ android:title="@string/title_application_category"
+ android:key="application_settings">
+
+ <CheckBoxPreference
+ android:key="connectbot_tab_hack"
+ android:title="@string/title_connectbot_tab_hack"
+ android:persistent="true"
+ android:defaultValue="true"
+ android:summaryOn="@string/summary_connectbot_tab_hack_true"
+ android:summaryOff="@string/summary_connectbot_tab_hack_false"
+ />
+
+ </PreferenceCategory>
+
+ <PreferenceCategory
+ android:title="@string/title_debugging"
+ android:key="debugging">
+
+ <CheckBoxPreference
+ android:key="pref_touch_pos"
+ android:title="@string/title_touch_pos"
+ android:persistent="true"
+ android:defaultValue="false"
+ android:summaryOn="@string/summary_touch_pos_true"
+ android:summaryOff="@string/summary_touch_pos_false"
+ />
+
+ <Preference
+ android:key="input_connection_info"
+ android:title="@string/title_input_connection_details"
+ />
+
+ <Preference
+ android:key="label_version"
+ android:title="@string/title_version"
+ android:summary="@string/auto_version"
+ />
+ </PreferenceCategory>
+
+</PreferenceScreen>
diff --git a/java/res/xml/prefs_actions.xml b/java/res/xml/prefs_actions.xml
new file mode 100644
index 0000000..bad7aa1
--- /dev/null
+++ b/java/res/xml/prefs_actions.xml
@@ -0,0 +1,77 @@
+<?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.
+-->
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+ android:key="prefs_actions"
+ android:title="@string/pref_screen_actions_title" >
+
+ <PreferenceCategory
+ android:key="swipe_actions"
+ android:title="@string/title_swipe_gestures" >
+
+ <org.pocketworkstation.pckeyboard.AutoSummaryListPreference
+ android:defaultValue="@string/default_swipe_up"
+ android:entries="@array/swipe_action_entries"
+ android:entryValues="@array/swipe_action_values"
+ android:key="pref_swipe_up"
+ android:persistent="true"
+ android:title="@string/title_swipe_up" />
+
+ <org.pocketworkstation.pckeyboard.AutoSummaryListPreference
+ android:defaultValue="@string/default_swipe_down"
+ android:entries="@array/swipe_action_entries"
+ android:entryValues="@array/swipe_action_values"
+ android:key="pref_swipe_down"
+ android:persistent="true"
+ android:title="@string/title_swipe_down" />
+
+ <org.pocketworkstation.pckeyboard.AutoSummaryListPreference
+ android:defaultValue="@string/default_swipe_left"
+ android:entries="@array/swipe_action_entries"
+ android:entryValues="@array/swipe_action_values"
+ android:key="pref_swipe_left"
+ android:persistent="true"
+ android:title="@string/title_swipe_left" />
+
+ <org.pocketworkstation.pckeyboard.AutoSummaryListPreference
+ android:defaultValue="@string/default_swipe_right"
+ android:entries="@array/swipe_action_entries"
+ android:entryValues="@array/swipe_action_values"
+ android:key="pref_swipe_right"
+ android:persistent="true"
+ android:title="@string/title_swipe_right" />
+ </PreferenceCategory>
+
+ <PreferenceCategory
+ android:key="key_actions"
+ android:title="@string/title_hardware_key_actions" >
+
+ <org.pocketworkstation.pckeyboard.AutoSummaryListPreference
+ android:defaultValue="@string/default_vol_up"
+ android:entries="@array/swipe_action_entries"
+ android:entryValues="@array/swipe_action_values"
+ android:key="pref_vol_up"
+ android:persistent="true"
+ android:title="@string/title_vol_up" />
+
+ <org.pocketworkstation.pckeyboard.AutoSummaryListPreference
+ android:defaultValue="@string/default_vol_down"
+ android:entries="@array/swipe_action_entries"
+ android:entryValues="@array/swipe_action_values"
+ android:key="pref_vol_down"
+ android:persistent="true"
+ android:title="@string/title_vol_down" />
+ </PreferenceCategory>
+</PreferenceScreen> \ No newline at end of file
diff --git a/java/res/xml/prefs_feedback.xml b/java/res/xml/prefs_feedback.xml
new file mode 100644
index 0000000..5f2fd18
--- /dev/null
+++ b/java/res/xml/prefs_feedback.xml
@@ -0,0 +1,71 @@
+<?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.
+-->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:hk="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:title="@string/pref_screen_feedback_title"
+ android:key="feedback_settings">
+
+ <CheckBoxPreference
+ android:key="vibrate_on"
+ android:title="@string/vibrate_on_keypress"
+ android:persistent="true"
+ />
+
+ <org.pocketworkstation.pckeyboard.SeekBarPreferenceString
+ android:defaultValue="40"
+ hk:minValue="5"
+ hk:maxValue="200"
+ hk:logScale="true"
+ hk:displayFormat="%.0f ms"
+ android:key="vibrate_len"
+ android:title="@string/title_vibrate_len"
+ android:persistent="true"
+ />
+
+ <CheckBoxPreference
+ android:key="sound_on"
+ android:title="@string/sound_on_keypress"
+ android:persistent="true"
+ />
+
+ <org.pocketworkstation.pckeyboard.AutoSummaryListPreference
+ android:key="pref_click_method"
+ android:title="@string/title_click_method"
+ android:entryValues="@array/click_method_values"
+ android:entries="@array/click_method_entries"
+ android:defaultValue="@string/default_click_method"
+ android:persistent="true"
+ />
+
+ <org.pocketworkstation.pckeyboard.SeekBarPreferenceString
+ android:defaultValue="@string/default_click_volume"
+ hk:minValue="0"
+ hk:maxValue="1"
+ hk:asPercent="true"
+ android:key="pref_click_volume"
+ android:title="@string/title_click_volume"
+ android:persistent="true"
+ />
+
+ <CheckBoxPreference
+ android:key="popup_on"
+ android:title="@string/popup_on_keypress"
+ android:persistent="true"
+ android:defaultValue="@bool/default_popup_preview"
+ />
+
+</PreferenceScreen>
diff --git a/java/res/xml/prefs_for_debug.xml b/java/res/xml/prefs_for_debug.xml
new file mode 100644
index 0000000..8177d3c
--- /dev/null
+++ b/java/res/xml/prefs_for_debug.xml
@@ -0,0 +1,45 @@
+<?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.
+-->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+ android:title="@string/prefs_debug_mode"
+ android:key="english_ime_debug_settings">
+
+ <CheckBoxPreference
+ android:key="enable_logging"
+ android:title="@string/prefs_enable_log"
+ android:summary="@string/prefs_description_log"
+ android:persistent="true"
+ android:defaultValue="false"
+ />
+
+ <ListPreference
+ android:key="pref_keyboard_layout_20100902"
+ android:title="@string/keyboard_layout"
+ android:persistent="true"
+ android:entryValues="@array/keyboard_layout_modes_values"
+ android:entries="@array/keyboard_layout_modes"
+ android:defaultValue="4"
+ />
+
+ <CheckBoxPreference
+ android:key="debug_mode"
+ android:title="@string/prefs_debug_mode"
+ android:persistent="true"
+ android:defaultValue="false"
+ />
+
+</PreferenceScreen>
diff --git a/java/res/xml/prefs_view.xml b/java/res/xml/prefs_view.xml
new file mode 100644
index 0000000..8b83378
--- /dev/null
+++ b/java/res/xml/prefs_view.xml
@@ -0,0 +1,89 @@
+<?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.
+-->
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:hk="http://schemas.android.com/apk/res/org.pocketworkstation.pckeyboard"
+ android:key="prefs_view"
+ android:title="@string/pref_screen_view_title" >
+
+ <PreferenceCategory
+ android:key="graphics_settings"
+ android:title="@string/pref_screen_view_title" >
+
+ <org.pocketworkstation.pckeyboard.AutoSummaryListPreference
+ android:defaultValue="@string/default_hint_mode"
+ android:entries="@array/hint_modes"
+ android:entryValues="@array/hint_modes_values"
+ android:key="pref_hint_mode"
+ android:persistent="true"
+ android:title="@string/title_hint_mode" />
+
+ <org.pocketworkstation.pckeyboard.SeekBarPreferenceString
+ android:defaultValue="1.0"
+ hk:minValue="0.5"
+ hk:maxValue="8.0"
+ hk:logScale="true"
+ hk:asPercent="true"
+ android:key="pref_label_scale"
+ android:persistent="true"
+ android:title="@string/title_label_scale" />
+
+ <org.pocketworkstation.pckeyboard.SeekBarPreferenceString
+ android:defaultValue="1.0"
+ hk:minValue="0.5"
+ hk:maxValue="8.0"
+ hk:logScale="true"
+ hk:asPercent="true"
+ android:key="pref_candidate_scale"
+ android:persistent="true"
+ android:title="@string/title_candidate_scale" />
+
+ <org.pocketworkstation.pckeyboard.SeekBarPreferenceString
+ android:defaultValue="1.0"
+ hk:minValue="0.5"
+ hk:maxValue="1.0"
+ hk:step="0.05"
+ hk:asPercent="true"
+ android:key="pref_top_row_scale"
+ android:persistent="true"
+ android:title="@string/title_top_row_scale" />
+
+ <org.pocketworkstation.pckeyboard.AutoSummaryListPreference
+ android:defaultValue="0"
+ android:entries="@array/keyboard_layout_modes"
+ android:entryValues="@array/keyboard_layout_modes_values"
+ android:key="pref_keyboard_layout"
+ android:persistent="true"
+ android:title="@string/keyboard_layout" />
+
+ <CheckBoxPreference
+ android:key="pref_compact_mode_enabled"
+ android:title="@string/title_compact_mode_enabled"
+ android:persistent="true"
+ android:defaultValue="@bool/default_compact_mode_enabled"
+ android:summaryOn="@string/summary_compact_mode_enabled"
+ android:summaryOff="@string/summary_compact_mode_enabled"
+ />
+
+ <org.pocketworkstation.pckeyboard.AutoSummaryListPreference
+ android:defaultValue="@string/default_render_mode"
+ android:entries="@array/render_mode_entries"
+ android:entryValues="@array/render_mode_values"
+ android:key="pref_render_mode"
+ android:persistent="true"
+ android:title="@string/title_render_mode" />
+ </PreferenceCategory>
+
+</PreferenceScreen> \ No newline at end of file
diff --git a/java/src/com/android/inputmethod/voice/FieldContext.java b/java/src/com/android/inputmethod/voice/FieldContext.java
new file mode 100644
index 0000000..5fbacfb
--- /dev/null
+++ b/java/src/com/android/inputmethod/voice/FieldContext.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.android.inputmethod.voice;
+
+import android.os.Bundle;
+import android.util.Log;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.ExtractedText;
+import android.view.inputmethod.ExtractedTextRequest;
+import android.view.inputmethod.InputConnection;
+
+/**
+ * Represents information about a given text field, which can be passed
+ * to the speech recognizer as context information.
+ */
+public class FieldContext {
+ private static final boolean DBG = false;
+
+ static final String LABEL = "label";
+ static final String HINT = "hint";
+ static final String PACKAGE_NAME = "packageName";
+ static final String FIELD_ID = "fieldId";
+ static final String FIELD_NAME = "fieldName";
+ static final String SINGLE_LINE = "singleLine";
+ static final String INPUT_TYPE = "inputType";
+ static final String IME_OPTIONS = "imeOptions";
+ static final String SELECTED_LANGUAGE = "selectedLanguage";
+ static final String ENABLED_LANGUAGES = "enabledLanguages";
+
+ Bundle mFieldInfo;
+
+ public FieldContext(InputConnection conn, EditorInfo info,
+ String selectedLanguage, String[] enabledLanguages) {
+ mFieldInfo = new Bundle();
+ addEditorInfoToBundle(info, mFieldInfo);
+ addInputConnectionToBundle(conn, mFieldInfo);
+ addLanguageInfoToBundle(selectedLanguage, enabledLanguages, mFieldInfo);
+ if (DBG) Log.i("FieldContext", "Bundle = " + mFieldInfo.toString());
+ }
+
+ private static String safeToString(Object o) {
+ if (o == null) {
+ return "";
+ }
+ return o.toString();
+ }
+
+ private static void addEditorInfoToBundle(EditorInfo info, Bundle bundle) {
+ if (info == null) {
+ return;
+ }
+
+ bundle.putString(LABEL, safeToString(info.label));
+ bundle.putString(HINT, safeToString(info.hintText));
+ bundle.putString(PACKAGE_NAME, safeToString(info.packageName));
+ bundle.putInt(FIELD_ID, info.fieldId);
+ bundle.putString(FIELD_NAME, safeToString(info.fieldName));
+ bundle.putInt(INPUT_TYPE, info.inputType);
+ bundle.putInt(IME_OPTIONS, info.imeOptions);
+ }
+
+ private static void addInputConnectionToBundle(
+ InputConnection conn, Bundle bundle) {
+ if (conn == null) {
+ return;
+ }
+
+ ExtractedText et = conn.getExtractedText(new ExtractedTextRequest(), 0);
+ if (et == null) {
+ return;
+ }
+ bundle.putBoolean(SINGLE_LINE, (et.flags & et.FLAG_SINGLE_LINE) > 0);
+ }
+
+ private static void addLanguageInfoToBundle(
+ String selectedLanguage, String[] enabledLanguages, Bundle bundle) {
+ bundle.putString(SELECTED_LANGUAGE, selectedLanguage);
+ bundle.putStringArray(ENABLED_LANGUAGES, enabledLanguages);
+ }
+
+ public Bundle getBundle() {
+ return mFieldInfo;
+ }
+
+ public String toString() {
+ return mFieldInfo.toString();
+ }
+}
diff --git a/java/src/com/android/inputmethod/voice/RecognitionView.java b/java/src/com/android/inputmethod/voice/RecognitionView.java
new file mode 100644
index 0000000..26ac05c
--- /dev/null
+++ b/java/src/com/android/inputmethod/voice/RecognitionView.java
@@ -0,0 +1,323 @@
+/*
+ * Copyright (C) 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.android.inputmethod.voice;
+
+import java.io.ByteArrayOutputStream;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.ShortBuffer;
+import java.util.ArrayList;
+import java.util.List;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.CornerPathEffect;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.PathEffect;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.util.TypedValue;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup.MarginLayoutParams;
+import android.widget.ImageView;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+import org.pocketworkstation.pckeyboard.R;
+
+/**
+ * The user interface for the "Speak now" and "working" states.
+ * Displays a recognition dialog (with waveform, voice meter, etc.),
+ * plays beeps, shows errors, etc.
+ */
+public class RecognitionView {
+ private static final String TAG = "RecognitionView";
+
+ private Handler mUiHandler; // Reference to UI thread
+ private View mView;
+ private Context mContext;
+
+ private ImageView mImage;
+ private TextView mText;
+ private View mButton;
+ private TextView mButtonText;
+ private View mProgress;
+
+ private Drawable mInitializing;
+ private Drawable mError;
+ private List<Drawable> mSpeakNow;
+
+ private float mVolume = 0.0f;
+ private int mLevel = 0;
+
+ private enum State {LISTENING, WORKING, READY}
+ private State mState = State.READY;
+
+ private float mMinMicrophoneLevel;
+ private float mMaxMicrophoneLevel;
+
+ /** Updates the microphone icon to show user their volume.*/
+ private Runnable mUpdateVolumeRunnable = new Runnable() {
+ public void run() {
+ if (mState != State.LISTENING) {
+ return;
+ }
+
+ final float min = mMinMicrophoneLevel;
+ final float max = mMaxMicrophoneLevel;
+ final int maxLevel = mSpeakNow.size() - 1;
+
+ int index = (int) ((mVolume - min) / (max - min) * maxLevel);
+ final int level = Math.min(Math.max(0, index), maxLevel);
+
+ if (level != mLevel) {
+ mImage.setImageDrawable(mSpeakNow.get(level));
+ mLevel = level;
+ }
+ mUiHandler.postDelayed(mUpdateVolumeRunnable, 50);
+ }
+ };
+
+ public RecognitionView(Context context, OnClickListener clickListener) {
+ mUiHandler = new Handler();
+
+ LayoutInflater inflater = (LayoutInflater) context.getSystemService(
+ Context.LAYOUT_INFLATER_SERVICE);
+ mView = inflater.inflate(R.layout.recognition_status, null);
+ ContentResolver cr = context.getContentResolver();
+ mMinMicrophoneLevel = SettingsUtil.getSettingsFloat(
+ cr, SettingsUtil.LATIN_IME_MIN_MICROPHONE_LEVEL, 15.f);
+ mMaxMicrophoneLevel = SettingsUtil.getSettingsFloat(
+ cr, SettingsUtil.LATIN_IME_MAX_MICROPHONE_LEVEL, 30.f);
+
+ // Pre-load volume level images
+ Resources r = context.getResources();
+
+ mSpeakNow = new ArrayList<Drawable>();
+ mSpeakNow.add(r.getDrawable(R.drawable.speak_now_level0));
+ mSpeakNow.add(r.getDrawable(R.drawable.speak_now_level1));
+ mSpeakNow.add(r.getDrawable(R.drawable.speak_now_level2));
+ mSpeakNow.add(r.getDrawable(R.drawable.speak_now_level3));
+ mSpeakNow.add(r.getDrawable(R.drawable.speak_now_level4));
+ mSpeakNow.add(r.getDrawable(R.drawable.speak_now_level5));
+ mSpeakNow.add(r.getDrawable(R.drawable.speak_now_level6));
+
+ mInitializing = r.getDrawable(R.drawable.mic_slash);
+ mError = r.getDrawable(R.drawable.caution);
+
+ mImage = (ImageView) mView.findViewById(R.id.image);
+ mButton = mView.findViewById(R.id.button);
+ mButton.setOnClickListener(clickListener);
+ mText = (TextView) mView.findViewById(R.id.text);
+ mButtonText = (TextView) mView.findViewById(R.id.button_text);
+ mProgress = mView.findViewById(R.id.progress);
+
+ mContext = context;
+ }
+
+ public View getView() {
+ return mView;
+ }
+
+ public void restoreState() {
+ mUiHandler.post(new Runnable() {
+ public void run() {
+ // Restart the spinner
+ if (mState == State.WORKING) {
+ ((ProgressBar)mProgress).setIndeterminate(false);
+ ((ProgressBar)mProgress).setIndeterminate(true);
+ }
+ }
+ });
+ }
+
+ public void showInitializing() {
+ mUiHandler.post(new Runnable() {
+ public void run() {
+ prepareDialog(false, mContext.getText(R.string.voice_initializing), mInitializing,
+ mContext.getText(R.string.cancel));
+ }
+ });
+ }
+
+ public void showListening() {
+ mUiHandler.post(new Runnable() {
+ public void run() {
+ mState = State.LISTENING;
+ prepareDialog(false, mContext.getText(R.string.voice_listening), mSpeakNow.get(0),
+ mContext.getText(R.string.cancel));
+ }
+ });
+ mUiHandler.postDelayed(mUpdateVolumeRunnable, 50);
+ }
+
+ public void updateVoiceMeter(final float rmsdB) {
+ mVolume = rmsdB;
+ }
+
+ public void showError(final String message) {
+ mUiHandler.post(new Runnable() {
+ public void run() {
+ mState = State.READY;
+ prepareDialog(false, message, mError, mContext.getText(R.string.ok));
+ }
+ });
+ }
+
+ public void showWorking(
+ final ByteArrayOutputStream waveBuffer,
+ final int speechStartPosition,
+ final int speechEndPosition) {
+
+ mUiHandler.post(new Runnable() {
+ public void run() {
+ mState = State.WORKING;
+ prepareDialog(true, mContext.getText(R.string.voice_working), null, mContext
+ .getText(R.string.cancel));
+ final ShortBuffer buf = ByteBuffer.wrap(waveBuffer.toByteArray()).order(
+ ByteOrder.nativeOrder()).asShortBuffer();
+ buf.position(0);
+ waveBuffer.reset();
+ showWave(buf, speechStartPosition / 2, speechEndPosition / 2);
+ }
+ });
+ }
+
+ private void prepareDialog(boolean spinVisible, CharSequence text, Drawable image,
+ CharSequence btnTxt) {
+ if (spinVisible) {
+ mProgress.setVisibility(View.VISIBLE);
+ mImage.setVisibility(View.GONE);
+ } else {
+ mProgress.setVisibility(View.GONE);
+ mImage.setImageDrawable(image);
+ mImage.setVisibility(View.VISIBLE);
+ }
+ mText.setText(text);
+ mButtonText.setText(btnTxt);
+ }
+
+ /**
+ * @return an average abs of the specified buffer.
+ */
+ private static int getAverageAbs(ShortBuffer buffer, int start, int i, int npw) {
+ int from = start + i * npw;
+ int end = from + npw;
+ int total = 0;
+ for (int x = from; x < end; x++) {
+ total += Math.abs(buffer.get(x));
+ }
+ return total / npw;
+ }
+
+
+ /**
+ * Shows waveform of input audio.
+ *
+ * Copied from version in VoiceSearch's RecognitionActivity.
+ *
+ * TODO: adjust stroke width based on the size of data.
+ * TODO: use dip rather than pixels.
+ */
+ private void showWave(ShortBuffer waveBuffer, int startPosition, int endPosition) {
+ final int w = ((View) mImage.getParent()).getWidth();
+ final int h = mImage.getHeight();
+ if (w <= 0 || h <= 0) {
+ // view is not visible this time. Skip drawing.
+ return;
+ }
+ final Bitmap b = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
+ final Canvas c = new Canvas(b);
+ final Paint paint = new Paint();
+ paint.setColor(0xFFFFFFFF); // 0xAARRGGBB
+ paint.setAntiAlias(true);
+ paint.setStyle(Paint.Style.STROKE);
+ paint.setAlpha(0x90);
+
+ final PathEffect effect = new CornerPathEffect(3);
+ paint.setPathEffect(effect);
+
+ final int numSamples = waveBuffer.remaining();
+ int endIndex;
+ if (endPosition == 0) {
+ endIndex = numSamples;
+ } else {
+ endIndex = Math.min(endPosition, numSamples);
+ }
+
+ int startIndex = startPosition - 2000; // include 250ms before speech
+ if (startIndex < 0) {
+ startIndex = 0;
+ }
+ final int numSamplePerWave = 200; // 8KHz 25ms = 200 samples
+ final float scale = 10.0f / 65536.0f;
+
+ final int count = (endIndex - startIndex) / numSamplePerWave;
+ final float deltaX = 1.0f * w / count;
+ int yMax = h / 2 - 8;
+ Path path = new Path();
+ c.translate(0, yMax);
+ float x = 0;
+ path.moveTo(x, 0);
+ for (int i = 0; i < count; i++) {
+ final int avabs = getAverageAbs(waveBuffer, startIndex, i , numSamplePerWave);
+ int sign = ( (i & 01) == 0) ? -1 : 1;
+ final float y = Math.min(yMax, avabs * h * scale) * sign;
+ path.lineTo(x, y);
+ x += deltaX;
+ path.lineTo(x, y);
+ }
+ if (deltaX > 4) {
+ paint.setStrokeWidth(3);
+ } else {
+ paint.setStrokeWidth(Math.max(1, (int) (deltaX -.05)));
+ }
+ c.drawPath(path, paint);
+ mImage.setImageBitmap(b);
+ mImage.setVisibility(View.VISIBLE);
+ MarginLayoutParams mProgressParams = (MarginLayoutParams)mProgress.getLayoutParams();
+ mProgressParams.topMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX,
+ -h , mContext.getResources().getDisplayMetrics());
+
+ // Tweak the padding manually to fill out the whole view horizontally.
+ // TODO: Do this in the xml layout instead.
+ ((View) mImage.getParent()).setPadding(4, ((View) mImage.getParent()).getPaddingTop(), 3,
+ ((View) mImage.getParent()).getPaddingBottom());
+ mProgress.setLayoutParams(mProgressParams);
+ }
+
+
+ public void finish() {
+ mUiHandler.post(new Runnable() {
+ public void run() {
+ mState = State.READY;
+ exitWorking();
+ }
+ });
+ }
+
+ private void exitWorking() {
+ mProgress.setVisibility(View.GONE);
+ mImage.setVisibility(View.VISIBLE);
+ }
+}
diff --git a/java/src/com/android/inputmethod/voice/SettingsUtil.java b/java/src/com/android/inputmethod/voice/SettingsUtil.java
new file mode 100644
index 0000000..abf5204
--- /dev/null
+++ b/java/src/com/android/inputmethod/voice/SettingsUtil.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.android.inputmethod.voice;
+
+import android.content.ContentResolver;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.Settings;
+import android.util.Log;
+
+/**
+ * Utility for retrieving settings from Settings.Secure.
+ */
+public class SettingsUtil {
+ /**
+ * A whitespace-separated list of supported locales for voice input from the keyboard.
+ */
+ public static final String LATIN_IME_VOICE_INPUT_SUPPORTED_LOCALES =
+ "latin_ime_voice_input_supported_locales";
+
+ /**
+ * A whitespace-separated list of recommended app packages for voice input from the
+ * keyboard.
+ */
+ public static final String LATIN_IME_VOICE_INPUT_RECOMMENDED_PACKAGES =
+ "latin_ime_voice_input_recommended_packages";
+
+ /**
+ * The maximum number of unique days to show the swipe hint for voice input.
+ */
+ public static final String LATIN_IME_VOICE_INPUT_SWIPE_HINT_MAX_DAYS =
+ "latin_ime_voice_input_swipe_hint_max_days";
+
+ /**
+ * The maximum number of times to show the punctuation hint for voice input.
+ */
+ public static final String LATIN_IME_VOICE_INPUT_PUNCTUATION_HINT_MAX_DISPLAYS =
+ "latin_ime_voice_input_punctuation_hint_max_displays";
+
+ /**
+ * Endpointer parameters for voice input from the keyboard.
+ */
+ public static final String LATIN_IME_SPEECH_MINIMUM_LENGTH_MILLIS =
+ "latin_ime_speech_minimum_length_millis";
+ public static final String LATIN_IME_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS =
+ "latin_ime_speech_input_complete_silence_length_millis";
+ public static final String LATIN_IME_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS =
+ "latin_ime_speech_input_possibly_complete_silence_length_millis";
+
+ /**
+ * Min and max volume levels that can be displayed on the "speak now" screen.
+ */
+ public static final String LATIN_IME_MIN_MICROPHONE_LEVEL =
+ "latin_ime_min_microphone_level";
+ public static final String LATIN_IME_MAX_MICROPHONE_LEVEL =
+ "latin_ime_max_microphone_level";
+
+ /**
+ * The number of sentence-level alternates to request of the server.
+ */
+ public static final String LATIN_IME_MAX_VOICE_RESULTS = "latin_ime_max_voice_results";
+
+ /**
+ * Get a string-valued setting.
+ *
+ * @param cr The content resolver to use
+ * @param key The setting to look up
+ * @param defaultValue The default value to use if none can be found
+ * @return The value of the setting, or defaultValue if it couldn't be found
+ */
+ public static String getSettingsString(ContentResolver cr, String key, String defaultValue) {
+ String result = Settings.Secure.getString(cr, key);
+ return (result == null) ? defaultValue : result;
+ }
+
+ /**
+ * Get an int-valued setting.
+ *
+ * @param cr The content resolver to use
+ * @param key The setting to look up
+ * @param defaultValue The default value to use if the setting couldn't be found or parsed
+ * @return The value of the setting, or defaultValue if it couldn't be found or parsed
+ */
+ public static int getSettingsInt(ContentResolver cr, String key, int defaultValue) {
+ return Settings.Secure.getInt(cr, key, defaultValue);
+ }
+
+ /**
+ * Get a float-valued setting.
+ *
+ * @param cr The content resolver to use
+ * @param key The setting to look up
+ * @param defaultValue The default value to use if the setting couldn't be found or parsed
+ * @return The value of the setting, or defaultValue if it couldn't be found or parsed
+ */
+ public static float getSettingsFloat(ContentResolver cr, String key, float defaultValue) {
+ return Settings.Secure.getFloat(cr, key, defaultValue);
+ }
+}
diff --git a/java/src/com/android/inputmethod/voice/VoiceInput.java b/java/src/com/android/inputmethod/voice/VoiceInput.java
new file mode 100644
index 0000000..1d8179a
--- /dev/null
+++ b/java/src/com/android/inputmethod/voice/VoiceInput.java
@@ -0,0 +1,649 @@
+/*
+ * Copyright (C) 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.android.inputmethod.voice;
+
+import org.pocketworkstation.pckeyboard.EditingUtil;
+import org.pocketworkstation.pckeyboard.R;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.Parcelable;
+import android.speech.RecognitionListener;
+import android.speech.SpeechRecognizer;
+import android.speech.RecognizerIntent;
+import android.util.Log;
+import android.view.inputmethod.InputConnection;
+import android.view.View;
+import android.view.View.OnClickListener;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * Speech recognition input, including both user interface and a background
+ * process to stream audio to the network recognizer. This class supplies a
+ * View (getView()), which it updates as recognition occurs. The user of this
+ * class is responsible for making the view visible to the user, as well as
+ * handling various events returned through UiListener.
+ */
+public class VoiceInput implements OnClickListener {
+ private static final String TAG = "VoiceInput";
+ private static final String EXTRA_RECOGNITION_CONTEXT =
+ "android.speech.extras.RECOGNITION_CONTEXT";
+ private static final String EXTRA_CALLING_PACKAGE = "calling_package";
+ private static final String EXTRA_ALTERNATES = "android.speech.extra.ALTERNATES";
+ private static final int MAX_ALT_LIST_LENGTH = 6;
+
+ private static final String DEFAULT_RECOMMENDED_PACKAGES =
+ "com.android.mms " +
+ "com.google.android.gm " +
+ "com.google.android.talk " +
+ "com.google.android.apps.googlevoice " +
+ "com.android.email " +
+ "com.android.browser ";
+
+ // WARNING! Before enabling this, fix the problem with calling getExtractedText() in
+ // landscape view. It causes Extracted text updates to be rejected due to a token mismatch
+ public static boolean ENABLE_WORD_CORRECTIONS = true;
+
+ // Dummy word suggestion which means "delete current word"
+ public static final String DELETE_SYMBOL = " \u00D7 "; // times symbol
+
+ private Whitelist mRecommendedList;
+ private Whitelist mBlacklist;
+
+ private VoiceInputLogger mLogger;
+
+ // Names of a few extras defined in VoiceSearch's RecognitionController
+ // Note, the version of voicesearch that shipped in Froyo returns the raw
+ // RecognitionClientAlternates protocol buffer under the key "alternates",
+ // so a VS market update must be installed on Froyo devices in order to see
+ // alternatives.
+ private static final String ALTERNATES_BUNDLE = "alternates_bundle";
+
+ // This is copied from the VoiceSearch app.
+ private static final class AlternatesBundleKeys {
+ public static final String ALTERNATES = "alternates";
+ public static final String CONFIDENCE = "confidence";
+ public static final String LENGTH = "length";
+ public static final String MAX_SPAN_LENGTH = "max_span_length";
+ public static final String SPANS = "spans";
+ public static final String SPAN_KEY_DELIMITER = ":";
+ public static final String START = "start";
+ public static final String TEXT = "text";
+ }
+
+ // Names of a few intent extras defined in VoiceSearch's RecognitionService.
+ // These let us tweak the endpointer parameters.
+ private static final String EXTRA_SPEECH_MINIMUM_LENGTH_MILLIS =
+ "android.speech.extras.SPEECH_INPUT_MINIMUM_LENGTH_MILLIS";
+ private static final String EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS =
+ "android.speech.extras.SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS";
+ private static final String EXTRA_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS =
+ "android.speech.extras.SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS";
+
+ // The usual endpointer default value for input complete silence length is 0.5 seconds,
+ // but that's used for things like voice search. For dictation-like voice input like this,
+ // we go with a more liberal value of 1 second. This value will only be used if a value
+ // is not provided from Gservices.
+ private static final String INPUT_COMPLETE_SILENCE_LENGTH_DEFAULT_VALUE_MILLIS = "1000";
+
+ // Used to record part of that state for logging purposes.
+ public static final int DEFAULT = 0;
+ public static final int LISTENING = 1;
+ public static final int WORKING = 2;
+ public static final int ERROR = 3;
+
+ private int mAfterVoiceInputDeleteCount = 0;
+ private int mAfterVoiceInputInsertCount = 0;
+ private int mAfterVoiceInputInsertPunctuationCount = 0;
+ private int mAfterVoiceInputCursorPos = 0;
+ private int mAfterVoiceInputSelectionSpan = 0;
+
+ private int mState = DEFAULT;
+
+ private final static int MSG_CLOSE_ERROR_DIALOG = 1;
+
+ private final Handler mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ if (msg.what == MSG_CLOSE_ERROR_DIALOG) {
+ mState = DEFAULT;
+ mRecognitionView.finish();
+ mUiListener.onCancelVoice();
+ }
+ }
+ };
+
+ /**
+ * Events relating to the recognition UI. You must implement these.
+ */
+ public interface UiListener {
+
+ /**
+ * @param recognitionResults a set of transcripts for what the user
+ * spoke, sorted by likelihood.
+ */
+ public void onVoiceResults(
+ List<String> recognitionResults,
+ Map<String, List<CharSequence>> alternatives);
+
+ /**
+ * Called when the user cancels speech recognition.
+ */
+ public void onCancelVoice();
+ }
+
+ private SpeechRecognizer mSpeechRecognizer;
+ private RecognitionListener mRecognitionListener;
+ private RecognitionView mRecognitionView;
+ private UiListener mUiListener;
+ private Context mContext;
+
+ /**
+ * @param context the service or activity in which we're running.
+ * @param uiHandler object to receive events from VoiceInput.
+ */
+ public VoiceInput(Context context, UiListener uiHandler) {
+ mLogger = VoiceInputLogger.getLogger(context);
+ mRecognitionListener = new ImeRecognitionListener();
+ mSpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(context);
+ mSpeechRecognizer.setRecognitionListener(mRecognitionListener);
+ mUiListener = uiHandler;
+ mContext = context;
+ newView();
+
+ String recommendedPackages = SettingsUtil.getSettingsString(
+ context.getContentResolver(),
+ SettingsUtil.LATIN_IME_VOICE_INPUT_RECOMMENDED_PACKAGES,
+ DEFAULT_RECOMMENDED_PACKAGES);
+
+ mRecommendedList = new Whitelist();
+ for (String recommendedPackage : recommendedPackages.split("\\s+")) {
+ mRecommendedList.addApp(recommendedPackage);
+ }
+
+ mBlacklist = new Whitelist();
+ mBlacklist.addApp("com.android.setupwizard");
+ }
+
+ public void setCursorPos(int pos) {
+ mAfterVoiceInputCursorPos = pos;
+ }
+
+ public int getCursorPos() {
+ return mAfterVoiceInputCursorPos;
+ }
+
+ public void setSelectionSpan(int span) {
+ mAfterVoiceInputSelectionSpan = span;
+ }
+
+ public int getSelectionSpan() {
+ return mAfterVoiceInputSelectionSpan;
+ }
+
+ public void incrementTextModificationDeleteCount(int count){
+ mAfterVoiceInputDeleteCount += count;
+ // Send up intents for other text modification types
+ if (mAfterVoiceInputInsertCount > 0) {
+ logTextModifiedByTypingInsertion(mAfterVoiceInputInsertCount);
+ mAfterVoiceInputInsertCount = 0;
+ }
+ if (mAfterVoiceInputInsertPunctuationCount > 0) {
+ logTextModifiedByTypingInsertionPunctuation(mAfterVoiceInputInsertPunctuationCount);
+ mAfterVoiceInputInsertPunctuationCount = 0;
+ }
+
+ }
+
+ public void incrementTextModificationInsertCount(int count){
+ mAfterVoiceInputInsertCount += count;
+ if (mAfterVoiceInputSelectionSpan > 0) {
+ // If text was highlighted before inserting the char, count this as
+ // a delete.
+ mAfterVoiceInputDeleteCount += mAfterVoiceInputSelectionSpan;
+ }
+ // Send up intents for other text modification types
+ if (mAfterVoiceInputDeleteCount > 0) {
+ logTextModifiedByTypingDeletion(mAfterVoiceInputDeleteCount);
+ mAfterVoiceInputDeleteCount = 0;
+ }
+ if (mAfterVoiceInputInsertPunctuationCount > 0) {
+ logTextModifiedByTypingInsertionPunctuation(mAfterVoiceInputInsertPunctuationCount);
+ mAfterVoiceInputInsertPunctuationCount = 0;
+ }
+ }
+
+ public void incrementTextModificationInsertPunctuationCount(int count){
+ mAfterVoiceInputInsertPunctuationCount += 1;
+ if (mAfterVoiceInputSelectionSpan > 0) {
+ // If text was highlighted before inserting the char, count this as
+ // a delete.
+ mAfterVoiceInputDeleteCount += mAfterVoiceInputSelectionSpan;
+ }
+ // Send up intents for aggregated non-punctuation insertions
+ if (mAfterVoiceInputDeleteCount > 0) {
+ logTextModifiedByTypingDeletion(mAfterVoiceInputDeleteCount);
+ mAfterVoiceInputDeleteCount = 0;
+ }
+ if (mAfterVoiceInputInsertCount > 0) {
+ logTextModifiedByTypingInsertion(mAfterVoiceInputInsertCount);
+ mAfterVoiceInputInsertCount = 0;
+ }
+ }
+
+ public void flushAllTextModificationCounters() {
+ if (mAfterVoiceInputInsertCount > 0) {
+ logTextModifiedByTypingInsertion(mAfterVoiceInputInsertCount);
+ mAfterVoiceInputInsertCount = 0;
+ }
+ if (mAfterVoiceInputDeleteCount > 0) {
+ logTextModifiedByTypingDeletion(mAfterVoiceInputDeleteCount);
+ mAfterVoiceInputDeleteCount = 0;
+ }
+ if (mAfterVoiceInputInsertPunctuationCount > 0) {
+ logTextModifiedByTypingInsertionPunctuation(mAfterVoiceInputInsertPunctuationCount);
+ mAfterVoiceInputInsertPunctuationCount = 0;
+ }
+ }
+
+ /**
+ * The configuration of the IME changed and may have caused the views to be layed out
+ * again. Restore the state of the recognition view.
+ */
+ public void onConfigurationChanged() {
+ mRecognitionView.restoreState();
+ }
+
+ /**
+ * @return true if field is blacklisted for voice
+ */
+ public boolean isBlacklistedField(FieldContext context) {
+ return mBlacklist.matches(context);
+ }
+
+ /**
+ * Used to decide whether to show voice input hints for this field, etc.
+ *
+ * @return true if field is recommended for voice
+ */
+ public boolean isRecommendedField(FieldContext context) {
+ return mRecommendedList.matches(context);
+ }
+
+ /**
+ * Start listening for speech from the user. This will grab the microphone
+ * and start updating the view provided by getView(). It is the caller's
+ * responsibility to ensure that the view is visible to the user at this stage.
+ *
+ * @param context the same FieldContext supplied to voiceIsEnabled()
+ * @param swipe whether this voice input was started by swipe, for logging purposes
+ */
+ public void startListening(FieldContext context, boolean swipe) {
+ mState = DEFAULT;
+
+ Locale locale = Locale.getDefault();
+ String localeString = locale.getLanguage() + "-" + locale.getCountry();
+
+ mLogger.start(localeString, swipe);
+
+ mState = LISTENING;
+
+ mRecognitionView.showInitializing();
+ startListeningAfterInitialization(context);
+ }
+
+ /**
+ * Called only when the recognition manager's initialization completed
+ *
+ * @param context context with which {@link #startListening(FieldContext, boolean)} was executed
+ */
+ private void startListeningAfterInitialization(FieldContext context) {
+ Intent intent = makeIntent();
+ intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, "");
+ intent.putExtra(EXTRA_RECOGNITION_CONTEXT, context.getBundle());
+ intent.putExtra(EXTRA_CALLING_PACKAGE, "VoiceIME");
+ intent.putExtra(EXTRA_ALTERNATES, true);
+ intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS,
+ SettingsUtil.getSettingsInt(
+ mContext.getContentResolver(),
+ SettingsUtil.LATIN_IME_MAX_VOICE_RESULTS,
+ 1));
+ // Get endpointer params from Gservices.
+ // TODO: Consider caching these values for improved performance on slower devices.
+ final ContentResolver cr = mContext.getContentResolver();
+ putEndpointerExtra(
+ cr,
+ intent,
+ SettingsUtil.LATIN_IME_SPEECH_MINIMUM_LENGTH_MILLIS,
+ EXTRA_SPEECH_MINIMUM_LENGTH_MILLIS,
+ null /* rely on endpointer default */);
+ putEndpointerExtra(
+ cr,
+ intent,
+ SettingsUtil.LATIN_IME_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS,
+ EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS,
+ INPUT_COMPLETE_SILENCE_LENGTH_DEFAULT_VALUE_MILLIS
+ /* our default value is different from the endpointer's */);
+ putEndpointerExtra(
+ cr,
+ intent,
+ SettingsUtil.
+ LATIN_IME_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS,
+ EXTRA_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS,
+ null /* rely on endpointer default */);
+
+ mSpeechRecognizer.startListening(intent);
+ }
+
+ /**
+ * Gets the value of the provided Gservices key, attempts to parse it into a long,
+ * and if successful, puts the long value as an extra in the provided intent.
+ */
+ private void putEndpointerExtra(ContentResolver cr, Intent i,
+ String gservicesKey, String intentExtraKey, String defaultValue) {
+ long l = -1;
+ String s = SettingsUtil.getSettingsString(cr, gservicesKey, defaultValue);
+ if (s != null) {
+ try {
+ l = Long.valueOf(s);
+ } catch (NumberFormatException e) {
+ Log.e(TAG, "could not parse value for " + gservicesKey + ": " + s);
+ }
+ }
+
+ if (l != -1) i.putExtra(intentExtraKey, l);
+ }
+
+ public void destroy() {
+ mSpeechRecognizer.destroy();
+ }
+
+ /**
+ * Creates a new instance of the view that is returned by {@link #getView()}
+ * Clients should use this when a previously returned view is stuck in a
+ * layout that is being thrown away and a new one is need to show to the
+ * user.
+ */
+ public void newView() {
+ mRecognitionView = new RecognitionView(mContext, this);
+ }
+
+ /**
+ * @return a view that shows the recognition flow--e.g., "Speak now" and
+ * "working" dialogs.
+ */
+ public View getView() {
+ return mRecognitionView.getView();
+ }
+
+ /**
+ * Handle the cancel button.
+ */
+ public void onClick(View view) {
+ switch(view.getId()) {
+ case R.id.button:
+ cancel();
+ break;
+ }
+ }
+
+ public void logTextModifiedByTypingInsertion(int length) {
+ mLogger.textModifiedByTypingInsertion(length);
+ }
+
+ public void logTextModifiedByTypingInsertionPunctuation(int length) {
+ mLogger.textModifiedByTypingInsertionPunctuation(length);
+ }
+
+ public void logTextModifiedByTypingDeletion(int length) {
+ mLogger.textModifiedByTypingDeletion(length);
+ }
+
+ public void logTextModifiedByChooseSuggestion(String suggestion, int index,
+ String wordSeparators, InputConnection ic) {
+ EditingUtil.Range range = new EditingUtil.Range();
+ String wordToBeReplaced = EditingUtil.getWordAtCursor(ic, wordSeparators, range);
+ // If we enable phrase-based alternatives, only send up the first word
+ // in suggestion and wordToBeReplaced.
+ mLogger.textModifiedByChooseSuggestion(suggestion.length(), wordToBeReplaced.length(),
+ index, wordToBeReplaced, suggestion);
+ }
+
+ public void logKeyboardWarningDialogShown() {
+ mLogger.keyboardWarningDialogShown();
+ }
+
+ public void logKeyboardWarningDialogDismissed() {
+ mLogger.keyboardWarningDialogDismissed();
+ }
+
+ public void logKeyboardWarningDialogOk() {
+ mLogger.keyboardWarningDialogOk();
+ }
+
+ public void logKeyboardWarningDialogCancel() {
+ mLogger.keyboardWarningDialogCancel();
+ }
+
+ public void logSwipeHintDisplayed() {
+ mLogger.swipeHintDisplayed();
+ }
+
+ public void logPunctuationHintDisplayed() {
+ mLogger.punctuationHintDisplayed();
+ }
+
+ public void logVoiceInputDelivered(int length) {
+ mLogger.voiceInputDelivered(length);
+ }
+
+ public void logInputEnded() {
+ mLogger.inputEnded();
+ }
+
+ public void flushLogs() {
+ mLogger.flush();
+ }
+
+ private static Intent makeIntent() {
+ Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
+
+ // On Cupcake, use VoiceIMEHelper since VoiceSearch doesn't support.
+ // On Donut, always use VoiceSearch, since VoiceIMEHelper and
+ // VoiceSearch may conflict.
+ if (Build.VERSION.RELEASE.equals("1.5")) {
+ intent = intent.setClassName(
+ "com.google.android.voiceservice",
+ "com.google.android.voiceservice.IMERecognitionService");
+ } else {
+ intent = intent.setClassName(
+ "com.google.android.voicesearch",
+ "com.google.android.voicesearch.RecognitionService");
+ }
+
+ return intent;
+ }
+
+ /**
+ * Cancel in-progress speech recognition.
+ */
+ public void cancel() {
+ switch (mState) {
+ case LISTENING:
+ mLogger.cancelDuringListening();
+ break;
+ case WORKING:
+ mLogger.cancelDuringWorking();
+ break;
+ case ERROR:
+ mLogger.cancelDuringError();
+ break;
+ }
+ mState = DEFAULT;
+
+ // Remove all pending tasks (e.g., timers to cancel voice input)
+ mHandler.removeMessages(MSG_CLOSE_ERROR_DIALOG);
+
+ mSpeechRecognizer.cancel();
+ mUiListener.onCancelVoice();
+ mRecognitionView.finish();
+ }
+
+ private int getErrorStringId(int errorType, boolean endpointed) {
+ switch (errorType) {
+ // We use CLIENT_ERROR to signify that voice search is not available on the device.
+ case SpeechRecognizer.ERROR_CLIENT:
+ return R.string.voice_not_installed;
+ case SpeechRecognizer.ERROR_NETWORK:
+ return R.string.voice_network_error;
+ case SpeechRecognizer.ERROR_NETWORK_TIMEOUT:
+ return endpointed ?
+ R.string.voice_network_error : R.string.voice_too_much_speech;
+ case SpeechRecognizer.ERROR_AUDIO:
+ return R.string.voice_audio_error;
+ case SpeechRecognizer.ERROR_SERVER:
+ return R.string.voice_server_error;
+ case SpeechRecognizer.ERROR_SPEECH_TIMEOUT:
+ return R.string.voice_speech_timeout;
+ case SpeechRecognizer.ERROR_NO_MATCH:
+ return R.string.voice_no_match;
+ default: return R.string.voice_error;
+ }
+ }
+
+ private void onError(int errorType, boolean endpointed) {
+ Log.i(TAG, "error " + errorType);
+ mLogger.error(errorType);
+ onError(mContext.getString(getErrorStringId(errorType, endpointed)));
+ }
+
+ private void onError(String error) {
+ mState = ERROR;
+ mRecognitionView.showError(error);
+ // Wait a couple seconds and then automatically dismiss message.
+ mHandler.sendMessageDelayed(Message.obtain(mHandler, MSG_CLOSE_ERROR_DIALOG), 2000);
+ }
+
+ private class ImeRecognitionListener implements RecognitionListener {
+ // Waveform data
+ final ByteArrayOutputStream mWaveBuffer = new ByteArrayOutputStream();
+ int mSpeechStart;
+ private boolean mEndpointed = false;
+
+ public void onReadyForSpeech(Bundle noiseParams) {
+ mRecognitionView.showListening();
+ }
+
+ public void onBeginningOfSpeech() {
+ mEndpointed = false;
+ mSpeechStart = mWaveBuffer.size();
+ }
+
+ public void onRmsChanged(float rmsdB) {
+ mRecognitionView.updateVoiceMeter(rmsdB);
+ }
+
+ public void onBufferReceived(byte[] buf) {
+ try {
+ mWaveBuffer.write(buf);
+ } catch (IOException e) {}
+ }
+
+ public void onEndOfSpeech() {
+ mEndpointed = true;
+ mState = WORKING;
+ mRecognitionView.showWorking(mWaveBuffer, mSpeechStart, mWaveBuffer.size());
+ }
+
+ public void onError(int errorType) {
+ mState = ERROR;
+ VoiceInput.this.onError(errorType, mEndpointed);
+ }
+
+ public void onResults(Bundle resultsBundle) {
+ List<String> results = resultsBundle
+ .getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
+ // VS Market update is needed for IME froyo clients to access the alternatesBundle
+ // TODO: verify this.
+ Bundle alternatesBundle = resultsBundle.getBundle(ALTERNATES_BUNDLE);
+ mState = DEFAULT;
+
+ final Map<String, List<CharSequence>> alternatives =
+ new HashMap<String, List<CharSequence>>();
+
+ if (ENABLE_WORD_CORRECTIONS && alternatesBundle != null && results.size() > 0) {
+ // Use the top recognition result to map each alternative's start:length to a word.
+ String[] words = results.get(0).split(" ");
+ Bundle spansBundle = alternatesBundle.getBundle(AlternatesBundleKeys.SPANS);
+ for (String key : spansBundle.keySet()) {
+ // Get the word for which these alternates correspond to.
+ Bundle spanBundle = spansBundle.getBundle(key);
+ int start = spanBundle.getInt(AlternatesBundleKeys.START);
+ int length = spanBundle.getInt(AlternatesBundleKeys.LENGTH);
+ // Only keep single-word based alternatives.
+ if (length == 1 && start < words.length) {
+ // Get the alternatives associated with the span.
+ // If a word appears twice in a recognition result,
+ // concatenate the alternatives for the word.
+ List<CharSequence> altList = alternatives.get(words[start]);
+ if (altList == null) {
+ altList = new ArrayList<CharSequence>();
+ alternatives.put(words[start], altList);
+ }
+ Parcelable[] alternatesArr = spanBundle
+ .getParcelableArray(AlternatesBundleKeys.ALTERNATES);
+ for (int j = 0; j < alternatesArr.length &&
+ altList.size() < MAX_ALT_LIST_LENGTH; j++) {
+ Bundle alternateBundle = (Bundle) alternatesArr[j];
+ String alternate = alternateBundle.getString(AlternatesBundleKeys.TEXT);
+ // Don't allow duplicates in the alternates list.
+ if (!altList.contains(alternate)) {
+ altList.add(alternate);
+ }
+ }
+ }
+ }
+ }
+
+ if (results.size() > 5) {
+ results = results.subList(0, 5);
+ }
+ mUiListener.onVoiceResults(results, alternatives);
+ mRecognitionView.finish();
+ }
+
+ public void onPartialResults(final Bundle partialResults) {
+ // currently - do nothing
+ }
+
+ public void onEvent(int eventType, Bundle params) {
+ // do nothing - reserved for events that might be added in the future
+ }
+ }
+}
diff --git a/java/src/com/android/inputmethod/voice/VoiceInputLogger.java b/java/src/com/android/inputmethod/voice/VoiceInputLogger.java
new file mode 100644
index 0000000..c409fa3
--- /dev/null
+++ b/java/src/com/android/inputmethod/voice/VoiceInputLogger.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.android.inputmethod.voice;
+
+import android.content.Context;
+
+/**
+ * Provides the logging facility for voice input events. This fires broadcasts back to
+ * the voice search app which then logs on our behalf.
+ *
+ * Note that debug console logging does not occur in this class. If you want to
+ * see console output of these logging events, there is a boolean switch to turn
+ * on on the VoiceSearch side.
+ */
+public class VoiceInputLogger {
+ private static VoiceInputLogger sVoiceInputLogger;
+
+ // The base intent used to form all broadcast intents to the logger
+ // in VoiceSearch.
+
+ // This flag is used to indicate when there are voice events that
+ // need to be flushed.
+
+ /**
+ * Returns the singleton of the logger.
+ *
+ * @param contextHint a hint context used when creating the logger instance.
+ * Ignored if the singleton instance already exists.
+ */
+ public static synchronized VoiceInputLogger getLogger(Context contextHint) {
+ if (sVoiceInputLogger == null) {
+ sVoiceInputLogger = new VoiceInputLogger(contextHint);
+ }
+ return sVoiceInputLogger;
+ }
+
+ public VoiceInputLogger(Context context) {
+ }
+
+ public void flush() {
+ }
+
+ public void keyboardWarningDialogShown() {
+ }
+
+ public void keyboardWarningDialogDismissed() {
+ }
+
+ public void keyboardWarningDialogOk() {
+ }
+
+ public void keyboardWarningDialogCancel() {
+ }
+
+ public void settingsWarningDialogShown() {
+ }
+
+ public void settingsWarningDialogDismissed() {
+ }
+
+ public void settingsWarningDialogOk() {
+ }
+
+ public void settingsWarningDialogCancel() {
+ }
+
+ public void swipeHintDisplayed() {
+ }
+
+ public void cancelDuringListening() {
+ }
+
+ public void cancelDuringWorking() {
+ }
+
+ public void cancelDuringError() {
+ }
+
+ public void punctuationHintDisplayed() {
+ }
+
+ public void error(int code) {
+ }
+
+ public void start(String locale, boolean swipe) {
+ }
+
+ public void voiceInputDelivered(int length) {
+ }
+
+ public void textModifiedByTypingInsertion(int length) {
+ }
+
+ public void textModifiedByTypingInsertionPunctuation(int length) {
+ }
+
+ public void textModifiedByTypingDeletion(int length) {
+ }
+
+ public void textModifiedByChooseSuggestion(int suggestionLength, int replacedPhraseLength,
+ int index, String before, String after) {
+ }
+
+ public void inputEnded() {
+ }
+
+ public void voiceInputSettingEnabled() {
+ }
+
+ public void voiceInputSettingDisabled() {
+ }
+
+}
diff --git a/java/src/com/android/inputmethod/voice/WaveformImage.java b/java/src/com/android/inputmethod/voice/WaveformImage.java
new file mode 100644
index 0000000..08d87c8
--- /dev/null
+++ b/java/src/com/android/inputmethod/voice/WaveformImage.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2008-2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.android.inputmethod.voice;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+
+import java.io.ByteArrayOutputStream;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.ShortBuffer;
+
+/**
+ * Utility class to draw a waveform into a bitmap, given a byte array
+ * that represents the waveform as a sequence of 16-bit integers.
+ * Adapted from RecognitionActivity.java.
+ */
+public class WaveformImage {
+ private static final int SAMPLING_RATE = 8000;
+
+ private WaveformImage() {}
+
+ public static Bitmap drawWaveform(
+ ByteArrayOutputStream waveBuffer, int w, int h, int start, int end) {
+ final Bitmap b = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
+ final Canvas c = new Canvas(b);
+ final Paint paint = new Paint();
+ paint.setColor(0xFFFFFFFF); // 0xRRGGBBAA
+ paint.setAntiAlias(true);
+ paint.setStrokeWidth(0);
+
+ final ShortBuffer buf = ByteBuffer
+ .wrap(waveBuffer.toByteArray())
+ .order(ByteOrder.nativeOrder())
+ .asShortBuffer();
+ buf.position(0);
+
+ final int numSamples = waveBuffer.size() / 2;
+ final int delay = (SAMPLING_RATE * 100 / 1000);
+ int endIndex = end / 2 + delay;
+ if (end == 0 || endIndex >= numSamples) {
+ endIndex = numSamples;
+ }
+ int index = start / 2 - delay;
+ if (index < 0) {
+ index = 0;
+ }
+ final int size = endIndex - index;
+ int numSamplePerPixel = 32;
+ int delta = size / (numSamplePerPixel * w);
+ if (delta == 0) {
+ numSamplePerPixel = size / w;
+ delta = 1;
+ }
+
+ final float scale = 3.5f / 65536.0f;
+ // do one less column to make sure we won't read past
+ // the buffer.
+ try {
+ for (int i = 0; i < w - 1 ; i++) {
+ final float x = i;
+ for (int j = 0; j < numSamplePerPixel; j++) {
+ final short s = buf.get(index);
+ final float y = (h / 2) - (s * h * scale);
+ c.drawPoint(x, y, paint);
+ index += delta;
+ }
+ }
+ } catch (IndexOutOfBoundsException e) {
+ // this can happen, but we don't care
+ }
+
+ return b;
+ }
+}
diff --git a/java/src/com/android/inputmethod/voice/Whitelist.java b/java/src/com/android/inputmethod/voice/Whitelist.java
new file mode 100644
index 0000000..167b688
--- /dev/null
+++ b/java/src/com/android/inputmethod/voice/Whitelist.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.android.inputmethod.voice;
+
+import android.os.Bundle;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A set of text fields where speech has been explicitly enabled.
+ */
+public class Whitelist {
+ private List<Bundle> mConditions;
+
+ public Whitelist() {
+ mConditions = new ArrayList<Bundle>();
+ }
+
+ public Whitelist(List<Bundle> conditions) {
+ this.mConditions = conditions;
+ }
+
+ public void addApp(String app) {
+ Bundle bundle = new Bundle();
+ bundle.putString("packageName", app);
+ mConditions.add(bundle);
+ }
+
+ /**
+ * @return true if the field is a member of the whitelist.
+ */
+ public boolean matches(FieldContext context) {
+ for (Bundle condition : mConditions) {
+ if (matches(condition, context.getBundle())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @return true of all values in condition are matched by a value
+ * in target.
+ */
+ private boolean matches(Bundle condition, Bundle target) {
+ for (String key : condition.keySet()) {
+ if (!condition.getString(key).equals(target.getString(key))) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
diff --git a/java/src/org/pocketworkstation/pckeyboard/AutoDictionary.java b/java/src/org/pocketworkstation/pckeyboard/AutoDictionary.java
new file mode 100644
index 0000000..bd10013
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/AutoDictionary.java
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.pocketworkstation.pckeyboard;
+
+import java.util.HashMap;
+import java.util.Set;
+import java.util.Map.Entry;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.database.sqlite.SQLiteQueryBuilder;
+import android.os.AsyncTask;
+import android.provider.BaseColumns;
+import android.util.Log;
+
+/**
+ * Stores new words temporarily until they are promoted to the user dictionary
+ * for longevity. Words in the auto dictionary are used to determine if it's ok
+ * to accept a word that's not in the main or user dictionary. Using a new word
+ * repeatedly will promote it to the user dictionary.
+ */
+public class AutoDictionary extends ExpandableDictionary {
+ // Weight added to a user picking a new word from the suggestion strip
+ static final int FREQUENCY_FOR_PICKED = 3;
+ // Weight added to a user typing a new word that doesn't get corrected (or is reverted)
+ static final int FREQUENCY_FOR_TYPED = 1;
+ // A word that is frequently typed and gets promoted to the user dictionary, uses this
+ // frequency.
+ static final int FREQUENCY_FOR_AUTO_ADD = 250;
+ // If the user touches a typed word 2 times or more, it will become valid.
+ private static final int VALIDITY_THRESHOLD = 2 * FREQUENCY_FOR_PICKED;
+ // If the user touches a typed word 4 times or more, it will be added to the user dict.
+ private static final int PROMOTION_THRESHOLD = 4 * FREQUENCY_FOR_PICKED;
+
+ private LatinIME mIme;
+ // Locale for which this auto dictionary is storing words
+ private String mLocale;
+
+ private HashMap<String,Integer> mPendingWrites = new HashMap<String,Integer>();
+ private final Object mPendingWritesLock = new Object();
+
+ private static final String DATABASE_NAME = "auto_dict.db";
+ private static final int DATABASE_VERSION = 1;
+
+ // These are the columns in the dictionary
+ // TODO: Consume less space by using a unique id for locale instead of the whole
+ // 2-5 character string.
+ private static final String COLUMN_ID = BaseColumns._ID;
+ private static final String COLUMN_WORD = "word";
+ private static final String COLUMN_FREQUENCY = "freq";
+ private static final String COLUMN_LOCALE = "locale";
+
+ /** Sort by descending order of frequency. */
+ public static final String DEFAULT_SORT_ORDER = COLUMN_FREQUENCY + " DESC";
+
+ /** Name of the words table in the auto_dict.db */
+ private static final String AUTODICT_TABLE_NAME = "words";
+
+ private static HashMap<String, String> sDictProjectionMap;
+
+ static {
+ sDictProjectionMap = new HashMap<String, String>();
+ sDictProjectionMap.put(COLUMN_ID, COLUMN_ID);
+ sDictProjectionMap.put(COLUMN_WORD, COLUMN_WORD);
+ sDictProjectionMap.put(COLUMN_FREQUENCY, COLUMN_FREQUENCY);
+ sDictProjectionMap.put(COLUMN_LOCALE, COLUMN_LOCALE);
+ }
+
+ private static DatabaseHelper sOpenHelper = null;
+
+ public AutoDictionary(Context context, LatinIME ime, String locale, int dicTypeId) {
+ super(context, dicTypeId);
+ mIme = ime;
+ mLocale = locale;
+ if (sOpenHelper == null) {
+ sOpenHelper = new DatabaseHelper(getContext());
+ }
+ if (mLocale != null && mLocale.length() > 1) {
+ loadDictionary();
+ }
+ }
+
+ @Override
+ public boolean isValidWord(CharSequence word) {
+ final int frequency = getWordFrequency(word);
+ return frequency >= VALIDITY_THRESHOLD;
+ }
+
+ @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();
+ super.close();
+ }
+
+ @Override
+ public void loadDictionaryAsync() {
+ // Load the words that correspond to the current input locale
+ Cursor cursor = query(COLUMN_LOCALE + "=?", new String[] { mLocale });
+ try {
+ if (cursor.moveToFirst()) {
+ int wordIndex = cursor.getColumnIndex(COLUMN_WORD);
+ int frequencyIndex = cursor.getColumnIndex(COLUMN_FREQUENCY);
+ while (!cursor.isAfterLast()) {
+ String word = cursor.getString(wordIndex);
+ int frequency = cursor.getInt(frequencyIndex);
+ // Safeguard against adding really long words. Stack may overflow due
+ // to recursive lookup
+ if (word.length() < getMaxWordLength()) {
+ super.addWord(word, frequency);
+ }
+ cursor.moveToNext();
+ }
+ }
+ } finally {
+ cursor.close();
+ }
+ }
+
+ @Override
+ public void addWord(String word, int addFrequency) {
+ final int length = word.length();
+ // Don't add very short or very long words.
+ if (length < 2 || length > getMaxWordLength()) return;
+ if (mIme.getCurrentWord().isAutoCapitalized()) {
+ // Remove caps before adding
+ word = Character.toLowerCase(word.charAt(0)) + word.substring(1);
+ }
+ int freq = getWordFrequency(word);
+ freq = freq < 0 ? addFrequency : freq + addFrequency;
+ super.addWord(word, freq);
+
+ if (freq >= PROMOTION_THRESHOLD) {
+ mIme.promoteToUserDictionary(word, FREQUENCY_FOR_AUTO_ADD);
+ freq = 0;
+ }
+
+ synchronized (mPendingWritesLock) {
+ // Write a null frequency if it is to be deleted from the db
+ mPendingWrites.put(word, freq == 0 ? null : new Integer(freq));
+ }
+ }
+
+ /**
+ * Schedules a background thread to write any pending words to the database.
+ */
+ public void flushPendingWrites() {
+ synchronized (mPendingWritesLock) {
+ // Nothing pending? Return
+ if (mPendingWrites.isEmpty()) return;
+ // Create a background thread to write the pending entries
+ new UpdateDbTask(getContext(), sOpenHelper, mPendingWrites, mLocale).execute();
+ // Create a new map for writing new entries into while the old one is written to db
+ mPendingWrites = new HashMap<String, Integer>();
+ }
+ }
+
+ /**
+ * This class helps open, create, and upgrade the database file.
+ */
+ private static class DatabaseHelper extends SQLiteOpenHelper {
+
+ DatabaseHelper(Context context) {
+ super(context, DATABASE_NAME, null, DATABASE_VERSION);
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ db.execSQL("CREATE TABLE " + AUTODICT_TABLE_NAME + " ("
+ + COLUMN_ID + " INTEGER PRIMARY KEY,"
+ + COLUMN_WORD + " TEXT,"
+ + COLUMN_FREQUENCY + " INTEGER,"
+ + COLUMN_LOCALE + " TEXT"
+ + ");");
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ Log.w("AutoDictionary", "Upgrading database from version " + oldVersion + " to "
+ + newVersion + ", which will destroy all old data");
+ db.execSQL("DROP TABLE IF EXISTS " + AUTODICT_TABLE_NAME);
+ onCreate(db);
+ }
+ }
+
+ private Cursor query(String selection, String[] selectionArgs) {
+ SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
+ qb.setTables(AUTODICT_TABLE_NAME);
+ qb.setProjectionMap(sDictProjectionMap);
+
+ // Get the database and run the query
+ SQLiteDatabase db = sOpenHelper.getReadableDatabase();
+ Cursor c = qb.query(db, null, selection, selectionArgs, null, null,
+ DEFAULT_SORT_ORDER);
+ return c;
+ }
+
+ /**
+ * Async task to write pending words to the database so that it stays in sync with
+ * the in-memory trie.
+ */
+ private static class UpdateDbTask extends AsyncTask<Void, Void, Void> {
+ private final HashMap<String, Integer> mMap;
+ private final DatabaseHelper mDbHelper;
+ private final String mLocale;
+
+ public UpdateDbTask(Context context, DatabaseHelper openHelper,
+ HashMap<String, Integer> pendingWrites, String locale) {
+ mMap = pendingWrites;
+ mLocale = locale;
+ mDbHelper = openHelper;
+ }
+
+ @Override
+ protected Void doInBackground(Void... v) {
+ SQLiteDatabase db = mDbHelper.getWritableDatabase();
+ // Write all the entries to the db
+ Set<Entry<String,Integer>> mEntries = mMap.entrySet();
+ for (Entry<String,Integer> entry : mEntries) {
+ Integer freq = entry.getValue();
+ db.delete(AUTODICT_TABLE_NAME, COLUMN_WORD + "=? AND " + COLUMN_LOCALE + "=?",
+ new String[] { entry.getKey(), mLocale });
+ if (freq != null) {
+ db.insert(AUTODICT_TABLE_NAME, null,
+ getContentValues(entry.getKey(), freq, mLocale));
+ }
+ }
+ return null;
+ }
+
+ private ContentValues getContentValues(String word, int frequency, String locale) {
+ ContentValues values = new ContentValues(4);
+ values.put(COLUMN_WORD, word);
+ values.put(COLUMN_FREQUENCY, frequency);
+ values.put(COLUMN_LOCALE, locale);
+ return values;
+ }
+ }
+}
diff --git a/java/src/org/pocketworkstation/pckeyboard/AutoSummaryEditTextPreference.java b/java/src/org/pocketworkstation/pckeyboard/AutoSummaryEditTextPreference.java
new file mode 100644
index 0000000..10c6a2b
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/AutoSummaryEditTextPreference.java
@@ -0,0 +1,27 @@
+package org.pocketworkstation.pckeyboard;
+
+import android.content.Context;
+import android.preference.EditTextPreference;
+import android.util.AttributeSet;
+
+public class AutoSummaryEditTextPreference extends EditTextPreference {
+
+ public AutoSummaryEditTextPreference(Context context) {
+ super(context);
+ }
+
+ public AutoSummaryEditTextPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public AutoSummaryEditTextPreference(Context context, AttributeSet attrs,
+ int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ @Override
+ public void setText(String text) {
+ super.setText(text);
+ setSummary(text);
+ }
+}
diff --git a/java/src/org/pocketworkstation/pckeyboard/AutoSummaryListPreference.java b/java/src/org/pocketworkstation/pckeyboard/AutoSummaryListPreference.java
new file mode 100644
index 0000000..cc0001c
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/AutoSummaryListPreference.java
@@ -0,0 +1,53 @@
+/**
+ *
+ */
+package org.pocketworkstation.pckeyboard;
+
+import android.content.Context;
+import android.preference.ListPreference;
+import android.util.AttributeSet;
+import android.util.Log;
+
+public class AutoSummaryListPreference extends ListPreference {
+ private static final String TAG = "HK/AutoSummaryListPreference";
+
+ public AutoSummaryListPreference(Context context) {
+ super(context);
+ }
+
+ public AutoSummaryListPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ private void trySetSummary() {
+ CharSequence entry = null;
+ try {
+ entry = getEntry();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ Log.i(TAG, "Malfunctioning ListPreference, can't get entry");
+ }
+ if (entry != null) {
+ //String percent = getResources().getString(R.string.percent);
+ String percent = "percent";
+ setSummary(entry.toString().replace("%", " " + percent));
+ }
+ }
+
+ @Override
+ public void setEntries(CharSequence[] entries) {
+ super.setEntries(entries);
+ trySetSummary();
+ }
+
+ @Override
+ public void setEntryValues(CharSequence[] entryValues) {
+ super.setEntryValues(entryValues);
+ trySetSummary();
+ }
+
+ @Override
+ public void setValue(String value) {
+ super.setValue(value);
+ trySetSummary();
+ }
+}
diff --git a/java/src/org/pocketworkstation/pckeyboard/BinaryDictionary.java b/java/src/org/pocketworkstation/pckeyboard/BinaryDictionary.java
new file mode 100644
index 0000000..bdb42f8
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/BinaryDictionary.java
@@ -0,0 +1,287 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.pocketworkstation.pckeyboard;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.channels.Channels;
+import java.util.Arrays;
+
+import android.content.Context;
+import android.util.Log;
+
+/**
+ * Implements a static, compacted, binary dictionary of standard words.
+ */
+public class BinaryDictionary extends Dictionary {
+
+ /**
+ * There is difference between what java and native code can handle.
+ * This value should only be used in BinaryDictionary.java
+ * It is necessary to keep it at this value because some languages e.g. German have
+ * really long words.
+ */
+ protected static final int MAX_WORD_LENGTH = 48;
+
+ private static final String TAG = "BinaryDictionary";
+ private static final int MAX_ALTERNATIVES = 16;
+ private static final int MAX_WORDS = 18;
+ private static final int MAX_BIGRAMS = 60;
+
+ private static final int TYPED_LETTER_MULTIPLIER = 2;
+ private static final boolean ENABLE_MISSED_CHARACTERS = true;
+
+ private int mDicTypeId;
+ private int mNativeDict;
+ private int mDictLength;
+ private int[] mInputCodes = new int[MAX_WORD_LENGTH * MAX_ALTERNATIVES];
+ private char[] mOutputChars = new char[MAX_WORD_LENGTH * MAX_WORDS];
+ private char[] mOutputChars_bigrams = new char[MAX_WORD_LENGTH * MAX_BIGRAMS];
+ private int[] mFrequencies = new int[MAX_WORDS];
+ private int[] mFrequencies_bigrams = new int[MAX_BIGRAMS];
+ // Keep a reference to the native dict direct buffer in Java to avoid
+ // unexpected deallocation of the direct buffer.
+ private ByteBuffer mNativeDictDirectBuffer;
+
+ static {
+ try {
+ System.loadLibrary("jni_pckeyboard");
+ Log.i("PCKeyboard", "loaded jni_pckeyboard");
+ } catch (UnsatisfiedLinkError ule) {
+ Log.e("BinaryDictionary", "Could not load native library jni_pckeyboard");
+ }
+ }
+
+ /**
+ * Create a dictionary from a raw resource file
+ * @param context application context for reading resources
+ * @param resId the resource containing the raw binary dictionary
+ */
+ public BinaryDictionary(Context context, int[] resId, int dicTypeId) {
+ if (resId != null && resId.length > 0 && resId[0] != 0) {
+ loadDictionary(context, resId);
+ }
+ mDicTypeId = dicTypeId;
+ }
+
+ /**
+ * Create a dictionary from input streams
+ * @param context application context for reading resources
+ * @param streams the resource streams containing the raw binary dictionary
+ */
+ public BinaryDictionary(Context context, InputStream[] streams, int dicTypeId) {
+ if (streams != null && streams.length > 0) {
+ loadDictionary(streams);
+ }
+ mDicTypeId = dicTypeId;
+ }
+
+ /**
+ * Create a dictionary from a byte buffer. This is used for testing.
+ * @param context application context for reading resources
+ * @param byteBuffer a ByteBuffer containing the binary dictionary
+ */
+ public BinaryDictionary(Context context, ByteBuffer byteBuffer, int dicTypeId) {
+ if (byteBuffer != null) {
+ if (byteBuffer.isDirect()) {
+ mNativeDictDirectBuffer = byteBuffer;
+ } else {
+ mNativeDictDirectBuffer = ByteBuffer.allocateDirect(byteBuffer.capacity());
+ byteBuffer.rewind();
+ mNativeDictDirectBuffer.put(byteBuffer);
+ }
+ mDictLength = byteBuffer.capacity();
+ mNativeDict = openNative(mNativeDictDirectBuffer,
+ TYPED_LETTER_MULTIPLIER, FULL_WORD_FREQ_MULTIPLIER, mDictLength);
+ }
+ mDicTypeId = dicTypeId;
+ }
+
+ private native int openNative(ByteBuffer bb, int typedLetterMultiplier,
+ int fullWordMultiplier, int dictSize);
+ private native void closeNative(int dict);
+ private native boolean isValidWordNative(int nativeData, char[] word, int wordLength);
+ private native int getSuggestionsNative(int dict, int[] inputCodes, int codesSize,
+ char[] outputChars, int[] frequencies, int maxWordLength, int maxWords,
+ int maxAlternatives, int skipPos, int[] nextLettersFrequencies, int nextLettersSize);
+ private native int getBigramsNative(int dict, char[] prevWord, int prevWordLength,
+ int[] inputCodes, int inputCodesLength, char[] outputChars, int[] frequencies,
+ int maxWordLength, int maxBigrams, int maxAlternatives);
+
+ private final void loadDictionary(InputStream[] is) {
+ try {
+ // merging separated dictionary into one if dictionary is separated
+ int total = 0;
+
+ for (int i = 0; i < is.length; i++) {
+ total += is[i].available();
+ }
+
+ mNativeDictDirectBuffer =
+ ByteBuffer.allocateDirect(total).order(ByteOrder.nativeOrder());
+ int got = 0;
+ for (int i = 0; i < is.length; i++) {
+ got += Channels.newChannel(is[i]).read(mNativeDictDirectBuffer);
+ }
+ if (got != total) {
+ Log.e(TAG, "Read " + got + " bytes, expected " + total);
+ } else {
+ mNativeDict = openNative(mNativeDictDirectBuffer,
+ TYPED_LETTER_MULTIPLIER, FULL_WORD_FREQ_MULTIPLIER, total);
+ mDictLength = total;
+ }
+ if (mDictLength > 10000) Log.i("PCKeyboard", "Loaded dictionary, len=" + mDictLength);
+ } catch (IOException e) {
+ Log.w(TAG, "No available memory for binary dictionary");
+ } catch (UnsatisfiedLinkError e) {
+ Log.w(TAG, "Failed to load native dictionary", e);
+ } finally {
+ try {
+ if (is != null) {
+ for (int i = 0; i < is.length; i++) {
+ is[i].close();
+ }
+ }
+ } catch (IOException e) {
+ Log.w(TAG, "Failed to close input stream");
+ }
+ }
+ }
+
+ private final void loadDictionary(Context context, int[] resId) {
+ InputStream[] is = null;
+ is = new InputStream[resId.length];
+ for (int i = 0; i < resId.length; i++) {
+ is[i] = context.getResources().openRawResource(resId[i]);
+ }
+ loadDictionary(is);
+ }
+
+
+ @Override
+ public void getBigrams(final WordComposer codes, final CharSequence previousWord,
+ final WordCallback callback, int[] nextLettersFrequencies) {
+
+ char[] chars = previousWord.toString().toCharArray();
+ Arrays.fill(mOutputChars_bigrams, (char) 0);
+ Arrays.fill(mFrequencies_bigrams, 0);
+
+ int codesSize = codes.size();
+ Arrays.fill(mInputCodes, -1);
+ int[] alternatives = codes.getCodesAt(0);
+ System.arraycopy(alternatives, 0, mInputCodes, 0,
+ Math.min(alternatives.length, MAX_ALTERNATIVES));
+
+ int count = getBigramsNative(mNativeDict, chars, chars.length, mInputCodes, codesSize,
+ mOutputChars_bigrams, mFrequencies_bigrams, MAX_WORD_LENGTH, MAX_BIGRAMS,
+ MAX_ALTERNATIVES);
+
+ for (int j = 0; j < count; j++) {
+ if (mFrequencies_bigrams[j] < 1) break;
+ int start = j * MAX_WORD_LENGTH;
+ int len = 0;
+ while (mOutputChars_bigrams[start + len] != 0) {
+ len++;
+ }
+ if (len > 0) {
+ callback.addWord(mOutputChars_bigrams, start, len, mFrequencies_bigrams[j],
+ mDicTypeId, DataType.BIGRAM);
+ }
+ }
+ }
+
+ @Override
+ public void getWords(final WordComposer codes, final WordCallback callback,
+ int[] nextLettersFrequencies) {
+ final int codesSize = codes.size();
+ // Won't deal with really long words.
+ if (codesSize > MAX_WORD_LENGTH - 1) return;
+
+ Arrays.fill(mInputCodes, -1);
+ for (int i = 0; i < codesSize; i++) {
+ int[] alternatives = codes.getCodesAt(i);
+ System.arraycopy(alternatives, 0, mInputCodes, i * MAX_ALTERNATIVES,
+ Math.min(alternatives.length, MAX_ALTERNATIVES));
+ }
+ Arrays.fill(mOutputChars, (char) 0);
+ Arrays.fill(mFrequencies, 0);
+
+ if (mNativeDict == 0)
+ return;
+
+ int count = getSuggestionsNative(mNativeDict, mInputCodes, codesSize,
+ mOutputChars, mFrequencies,
+ MAX_WORD_LENGTH, MAX_WORDS, MAX_ALTERNATIVES, -1,
+ nextLettersFrequencies,
+ nextLettersFrequencies != null ? nextLettersFrequencies.length : 0);
+
+ // If there aren't sufficient suggestions, search for words by allowing wild cards at
+ // the different character positions. This feature is not ready for prime-time as we need
+ // to figure out the best ranking for such words compared to proximity corrections and
+ // completions.
+ if (ENABLE_MISSED_CHARACTERS && count < 5) {
+ for (int skip = 0; skip < codesSize; skip++) {
+ int tempCount = getSuggestionsNative(mNativeDict, mInputCodes, codesSize,
+ mOutputChars, mFrequencies,
+ MAX_WORD_LENGTH, MAX_WORDS, MAX_ALTERNATIVES, skip,
+ null, 0);
+ count = Math.max(count, tempCount);
+ if (tempCount > 0) break;
+ }
+ }
+
+ for (int j = 0; j < count; j++) {
+ if (mFrequencies[j] < 1) break;
+ int start = j * MAX_WORD_LENGTH;
+ int len = 0;
+ while (mOutputChars[start + len] != 0) {
+ len++;
+ }
+ if (len > 0) {
+ callback.addWord(mOutputChars, start, len, mFrequencies[j], mDicTypeId,
+ DataType.UNIGRAM);
+ }
+ }
+ }
+
+ @Override
+ public boolean isValidWord(CharSequence word) {
+ if (word == null || mNativeDict == 0) return false;
+ char[] chars = word.toString().toCharArray();
+ return isValidWordNative(mNativeDict, chars, chars.length);
+ }
+
+ public int getSize() {
+ return mDictLength; // This value is initialized on the call to openNative()
+ }
+
+ @Override
+ public synchronized void close() {
+ if (mNativeDict != 0) {
+ closeNative(mNativeDict);
+ mNativeDict = 0;
+ }
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ close();
+ super.finalize();
+ }
+}
diff --git a/java/src/org/pocketworkstation/pckeyboard/CandidateView.java b/java/src/org/pocketworkstation/pckeyboard/CandidateView.java
new file mode 100755
index 0000000..f63273d
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/CandidateView.java
@@ -0,0 +1,487 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.pocketworkstation.pckeyboard;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Paint.Align;
+import android.graphics.Rect;
+import android.graphics.Typeface;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.view.GestureDetector;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup.LayoutParams;
+import android.widget.PopupWindow;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class CandidateView extends View {
+
+ private static final int OUT_OF_BOUNDS_WORD_INDEX = -1;
+ private static final int OUT_OF_BOUNDS_X_COORD = -1;
+
+ private LatinIME mService;
+ private final ArrayList<CharSequence> mSuggestions = new ArrayList<CharSequence>();
+ private boolean mShowingCompletions;
+ private CharSequence mSelectedString;
+ private int mSelectedIndex;
+ private int mTouchX = OUT_OF_BOUNDS_X_COORD;
+ private final Drawable mSelectionHighlight;
+ private boolean mTypedWordValid;
+
+ private boolean mHaveMinimalSuggestion;
+
+ private Rect mBgPadding;
+
+ private final TextView mPreviewText;
+ private final PopupWindow mPreviewPopup;
+ private int mCurrentWordIndex;
+ private Drawable mDivider;
+
+ private static final int MAX_SUGGESTIONS = 32;
+ private static final int SCROLL_PIXELS = 20;
+
+ private final int[] mWordWidth = new int[MAX_SUGGESTIONS];
+ private final int[] mWordX = new int[MAX_SUGGESTIONS];
+ private int mPopupPreviewX;
+ private int mPopupPreviewY;
+
+ private static final int X_GAP = 10;
+
+ private final int mColorNormal;
+ private final int mColorRecommended;
+ private final int mColorOther;
+ private final Paint mPaint;
+ private final int mDescent;
+ private boolean mScrolled;
+ private boolean mShowingAddToDictionary;
+ private CharSequence mAddToDictionaryHint;
+
+ private int mTargetScrollX;
+
+ private final int mMinTouchableWidth;
+
+ private int mTotalWidth;
+
+ private final GestureDetector mGestureDetector;
+
+ /**
+ * Construct a CandidateView for showing suggested words for completion.
+ * @param context
+ * @param attrs
+ */
+ public CandidateView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ mSelectionHighlight = context.getResources().getDrawable(
+ R.drawable.list_selector_background_pressed);
+
+ LayoutInflater inflate =
+ (LayoutInflater) context
+ .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ Resources res = context.getResources();
+ mPreviewPopup = new PopupWindow(context);
+ mPreviewText = (TextView) inflate.inflate(R.layout.candidate_preview, null);
+ mPreviewPopup.setWindowLayoutMode(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
+ mPreviewPopup.setContentView(mPreviewText);
+ mPreviewPopup.setBackgroundDrawable(null);
+ mPreviewPopup.setAnimationStyle(R.style.KeyPreviewAnimation);
+ mColorNormal = res.getColor(R.color.candidate_normal);
+ mColorRecommended = res.getColor(R.color.candidate_recommended);
+ mColorOther = res.getColor(R.color.candidate_other);
+ mDivider = res.getDrawable(R.drawable.keyboard_suggest_strip_divider);
+ mAddToDictionaryHint = res.getString(R.string.hint_add_to_dictionary);
+
+ mPaint = new Paint();
+ mPaint.setColor(mColorNormal);
+ mPaint.setAntiAlias(true);
+ mPaint.setTextSize(mPreviewText.getTextSize() * LatinIME.sKeyboardSettings.candidateScalePref);
+ mPaint.setStrokeWidth(0);
+ mPaint.setTextAlign(Align.CENTER);
+ mDescent = (int) mPaint.descent();
+ mMinTouchableWidth = (int)res.getDimension(R.dimen.candidate_min_touchable_width);
+
+ mGestureDetector = new GestureDetector(
+ new CandidateStripGestureListener(mMinTouchableWidth));
+ setWillNotDraw(false);
+ setHorizontalScrollBarEnabled(false);
+ setVerticalScrollBarEnabled(false);
+ scrollTo(0, getScrollY());
+ }
+
+ private class CandidateStripGestureListener extends GestureDetector.SimpleOnGestureListener {
+ private final int mTouchSlopSquare;
+
+ public CandidateStripGestureListener(int touchSlop) {
+ // Slightly reluctant to scroll to be able to easily choose the suggestion
+ mTouchSlopSquare = touchSlop * touchSlop;
+ }
+
+ @Override
+ public void onLongPress(MotionEvent me) {
+ if (mSuggestions.size() > 0) {
+ if (me.getX() + getScrollX() < mWordWidth[0] && getScrollX() < 10) {
+ longPressFirstWord();
+ }
+ }
+ }
+
+ @Override
+ public boolean onDown(MotionEvent e) {
+ mScrolled = false;
+ return false;
+ }
+
+ @Override
+ public boolean onScroll(MotionEvent e1, MotionEvent e2,
+ float distanceX, float distanceY) {
+ if (!mScrolled) {
+ // This is applied only when we recognize that scrolling is starting.
+ final int deltaX = (int) (e2.getX() - e1.getX());
+ final int deltaY = (int) (e2.getY() - e1.getY());
+ final int distance = (deltaX * deltaX) + (deltaY * deltaY);
+ if (distance < mTouchSlopSquare) {
+ return true;
+ }
+ mScrolled = true;
+ }
+
+ final int width = getWidth();
+ mScrolled = true;
+ int scrollX = getScrollX();
+ scrollX += (int) distanceX;
+ if (scrollX < 0) {
+ scrollX = 0;
+ }
+ if (distanceX > 0 && scrollX + width > mTotalWidth) {
+ scrollX -= (int) distanceX;
+ }
+ mTargetScrollX = scrollX;
+ scrollTo(scrollX, getScrollY());
+ hidePreview();
+ invalidate();
+ return true;
+ }
+ }
+
+ /**
+ * A connection back to the service to communicate with the text field
+ * @param listener
+ */
+ public void setService(LatinIME listener) {
+ mService = listener;
+ }
+
+ @Override
+ public int computeHorizontalScrollRange() {
+ return mTotalWidth;
+ }
+
+ /**
+ * If the canvas is null, then only touch calculations are performed to pick the target
+ * candidate.
+ */
+ @Override
+ protected void onDraw(Canvas canvas) {
+ if (canvas != null) {
+ super.onDraw(canvas);
+ }
+ mTotalWidth = 0;
+
+ final int height = getHeight();
+ if (mBgPadding == null) {
+ mBgPadding = new Rect(0, 0, 0, 0);
+ if (getBackground() != null) {
+ getBackground().getPadding(mBgPadding);
+ }
+ mDivider.setBounds(0, 0, mDivider.getIntrinsicWidth(),
+ mDivider.getIntrinsicHeight());
+ }
+
+ final int count = mSuggestions.size();
+ final Rect bgPadding = mBgPadding;
+ final Paint paint = mPaint;
+ final int touchX = mTouchX;
+ final int scrollX = getScrollX();
+ final boolean scrolled = mScrolled;
+ final boolean typedWordValid = mTypedWordValid;
+ final int y = (int) (height + mPaint.getTextSize() - mDescent) / 2;
+
+ boolean existsAutoCompletion = false;
+
+ int x = 0;
+ for (int i = 0; i < count; i++) {
+ CharSequence suggestion = mSuggestions.get(i);
+ if (suggestion == null) continue;
+ final int wordLength = suggestion.length();
+
+ paint.setColor(mColorNormal);
+ if (mHaveMinimalSuggestion
+ && ((i == 1 && !typedWordValid) || (i == 0 && typedWordValid))) {
+ paint.setTypeface(Typeface.DEFAULT_BOLD);
+ paint.setColor(mColorRecommended);
+ existsAutoCompletion = true;
+ } else if (i != 0 || (wordLength == 1 && count > 1)) {
+ // HACK: even if i == 0, we use mColorOther when this suggestion's length is 1 and
+ // there are multiple suggestions, such as the default punctuation list.
+ paint.setColor(mColorOther);
+ }
+ int wordWidth;
+ if ((wordWidth = mWordWidth[i]) == 0) {
+ float textWidth = paint.measureText(suggestion, 0, wordLength);
+ wordWidth = Math.max(mMinTouchableWidth, (int) textWidth + X_GAP * 2);
+ mWordWidth[i] = wordWidth;
+ }
+
+ mWordX[i] = x;
+
+ if (touchX != OUT_OF_BOUNDS_X_COORD && !scrolled
+ && touchX + scrollX >= x && touchX + scrollX < x + wordWidth) {
+ if (canvas != null && !mShowingAddToDictionary) {
+ canvas.translate(x, 0);
+ mSelectionHighlight.setBounds(0, bgPadding.top, wordWidth, height);
+ mSelectionHighlight.draw(canvas);
+ canvas.translate(-x, 0);
+ }
+ mSelectedString = suggestion;
+ mSelectedIndex = i;
+ }
+
+ if (canvas != null) {
+ canvas.drawText(suggestion, 0, wordLength, x + wordWidth / 2, y, paint);
+ paint.setColor(mColorOther);
+ canvas.translate(x + wordWidth, 0);
+ // Draw a divider unless it's after the hint
+ if (!(mShowingAddToDictionary && i == 1)) {
+ mDivider.draw(canvas);
+ }
+ canvas.translate(-x - wordWidth, 0);
+ }
+ paint.setTypeface(Typeface.DEFAULT);
+ x += wordWidth;
+ }
+ mService.onAutoCompletionStateChanged(existsAutoCompletion);
+ mTotalWidth = x;
+ if (mTargetScrollX != scrollX) {
+ scrollToTarget();
+ }
+ }
+
+ private void scrollToTarget() {
+ int scrollX = getScrollX();
+ if (mTargetScrollX > scrollX) {
+ scrollX += SCROLL_PIXELS;
+ if (scrollX >= mTargetScrollX) {
+ scrollX = mTargetScrollX;
+ scrollTo(scrollX, getScrollY());
+ requestLayout();
+ } else {
+ scrollTo(scrollX, getScrollY());
+ }
+ } else {
+ scrollX -= SCROLL_PIXELS;
+ if (scrollX <= mTargetScrollX) {
+ scrollX = mTargetScrollX;
+ scrollTo(scrollX, getScrollY());
+ requestLayout();
+ } else {
+ scrollTo(scrollX, getScrollY());
+ }
+ }
+ invalidate();
+ }
+
+ public void setSuggestions(List<CharSequence> suggestions, boolean completions,
+ boolean typedWordValid, boolean haveMinimalSuggestion) {
+ clear();
+ if (suggestions != null) {
+ int insertCount = Math.min(suggestions.size(), MAX_SUGGESTIONS);
+ for (CharSequence suggestion : suggestions) {
+ mSuggestions.add(suggestion);
+ if (--insertCount == 0)
+ break;
+ }
+ }
+ mShowingCompletions = completions;
+ mTypedWordValid = typedWordValid;
+ scrollTo(0, getScrollY());
+ mTargetScrollX = 0;
+ mHaveMinimalSuggestion = haveMinimalSuggestion;
+ // Compute the total width
+ onDraw(null);
+ invalidate();
+ requestLayout();
+ }
+
+ public boolean isShowingAddToDictionaryHint() {
+ return mShowingAddToDictionary;
+ }
+
+ public void showAddToDictionaryHint(CharSequence word) {
+ ArrayList<CharSequence> suggestions = new ArrayList<CharSequence>();
+ suggestions.add(word);
+ suggestions.add(mAddToDictionaryHint);
+ setSuggestions(suggestions, false, false, false);
+ mShowingAddToDictionary = true;
+ }
+
+ public boolean dismissAddToDictionaryHint() {
+ if (!mShowingAddToDictionary) return false;
+ clear();
+ return true;
+ }
+
+ /* package */ List<CharSequence> getSuggestions() {
+ return mSuggestions;
+ }
+
+ public void clear() {
+ // Don't call mSuggestions.clear() because it's being used for logging
+ // in LatinIME.pickSuggestionManually().
+ mSuggestions.clear();
+ mTouchX = OUT_OF_BOUNDS_X_COORD;
+ mSelectedString = null;
+ mSelectedIndex = -1;
+ mShowingAddToDictionary = false;
+ invalidate();
+ Arrays.fill(mWordWidth, 0);
+ Arrays.fill(mWordX, 0);
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent me) {
+
+ if (mGestureDetector.onTouchEvent(me)) {
+ return true;
+ }
+
+ int action = me.getAction();
+ int x = (int) me.getX();
+ int y = (int) me.getY();
+ mTouchX = x;
+
+ switch (action) {
+ case MotionEvent.ACTION_DOWN:
+ invalidate();
+ break;
+ case MotionEvent.ACTION_MOVE:
+ if (y <= 0) {
+ // Fling up!?
+ if (mSelectedString != null) {
+ // If there are completions from the application, we don't change the state to
+ // STATE_PICKED_SUGGESTION
+ if (!mShowingCompletions) {
+ // This "acceptedSuggestion" will not be counted as a word because
+ // it will be counted in pickSuggestion instead.
+ //TextEntryState.acceptedSuggestion(mSuggestions.get(0), mSelectedString);
+ //TextEntryState.manualTyped(mSelectedString);
+ }
+ mService.pickSuggestionManually(mSelectedIndex, mSelectedString);
+ mSelectedString = null;
+ mSelectedIndex = -1;
+ }
+ }
+ break;
+ case MotionEvent.ACTION_UP:
+ if (!mScrolled) {
+ if (mSelectedString != null) {
+ if (mShowingAddToDictionary) {
+ longPressFirstWord();
+ clear();
+ } else {
+ if (!mShowingCompletions) {
+ //TextEntryState.acceptedSuggestion(mSuggestions.get(0), mSelectedString);
+ //TextEntryState.manualTyped(mSelectedString);
+ }
+ mService.pickSuggestionManually(mSelectedIndex, mSelectedString);
+ }
+ }
+ }
+ mSelectedString = null;
+ mSelectedIndex = -1;
+ requestLayout();
+ hidePreview();
+ invalidate();
+ break;
+ }
+ return true;
+ }
+
+ private void hidePreview() {
+ mTouchX = OUT_OF_BOUNDS_X_COORD;
+ mCurrentWordIndex = OUT_OF_BOUNDS_WORD_INDEX;
+ mPreviewPopup.dismiss();
+ }
+
+ private void showPreview(int wordIndex, String altText) {
+ int oldWordIndex = mCurrentWordIndex;
+ mCurrentWordIndex = wordIndex;
+ // If index changed or changing text
+ if (oldWordIndex != mCurrentWordIndex || altText != null) {
+ if (wordIndex == OUT_OF_BOUNDS_WORD_INDEX) {
+ hidePreview();
+ } else {
+ CharSequence word = altText != null? altText : mSuggestions.get(wordIndex);
+ mPreviewText.setText(word);
+ mPreviewText.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
+ MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
+ int wordWidth = (int) (mPaint.measureText(word, 0, word.length()) + X_GAP * 2);
+ final int popupWidth = wordWidth
+ + mPreviewText.getPaddingLeft() + mPreviewText.getPaddingRight();
+ final int popupHeight = mPreviewText.getMeasuredHeight();
+ //mPreviewText.setVisibility(INVISIBLE);
+ mPopupPreviewX = mWordX[wordIndex] - mPreviewText.getPaddingLeft() - getScrollX()
+ + (mWordWidth[wordIndex] - wordWidth) / 2;
+ mPopupPreviewY = - popupHeight;
+ int [] offsetInWindow = new int[2];
+ getLocationInWindow(offsetInWindow);
+ if (mPreviewPopup.isShowing()) {
+ mPreviewPopup.update(mPopupPreviewX, mPopupPreviewY + offsetInWindow[1],
+ popupWidth, popupHeight);
+ } else {
+ mPreviewPopup.setWidth(popupWidth);
+ mPreviewPopup.setHeight(popupHeight);
+ mPreviewPopup.showAtLocation(this, Gravity.NO_GRAVITY, mPopupPreviewX,
+ mPopupPreviewY + offsetInWindow[1]);
+ }
+ mPreviewText.setVisibility(VISIBLE);
+ }
+ }
+ }
+
+ private void longPressFirstWord() {
+ CharSequence word = mSuggestions.get(0);
+ if (word.length() < 2) return;
+ if (mService.addWordToDictionary(word.toString())) {
+ showPreview(0, getContext().getResources().getString(R.string.added_word, word));
+ }
+ }
+
+ @Override
+ public void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ hidePreview();
+ }
+}
diff --git a/java/src/org/pocketworkstation/pckeyboard/ComposeBase.java b/java/src/org/pocketworkstation/pckeyboard/ComposeBase.java
new file mode 100644
index 0000000..2c83402
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/ComposeBase.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2011 Darren Salt
+ *
+ * Licensed under the Apache License, Version 2.0 (the "Licence"); you may
+ * not use this file except in compliance with the Licence. You may obtain
+ * a copy of the Licence at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * Licence for the specific language governing permissions and limitations
+ * under the Licence.
+ */
+
+package org.pocketworkstation.pckeyboard;
+
+import android.inputmethodservice.InputMethodService;
+import android.util.Log;
+import android.view.inputmethod.EditorInfo;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+interface ComposeSequencing {
+ public void onText(CharSequence text);
+ public void updateShiftKeyState(EditorInfo attr);
+ public EditorInfo getCurrentInputEditorInfo();
+}
+
+public abstract class ComposeBase {
+ private static final String TAG = "HK/ComposeBase";
+
+ protected static final Map<String, String> mMap =
+ new HashMap<String, String>();
+
+ protected static final Set<String> mPrefixes =
+ new HashSet<String>();
+
+ protected static String get(String key) {
+ if (key == null || key.length() == 0) {
+ return null;
+ }
+ //Log.i(TAG, "ComposeBase get, key=" + showString(key) + " result=" + mMap.get(key));
+ return mMap.get(key);
+ }
+
+ private static String showString(String in) {
+ // TODO Auto-generated method stub
+ StringBuilder out = new StringBuilder(in);
+ out.append("{");
+ for (int i = 0; i < in.length(); ++i) {
+ if (i > 0) out.append(",");
+ out.append((int) in.charAt(i));
+ }
+ out.append("}");
+ return out.toString();
+ }
+
+ private static boolean isValid(String partialKey) {
+ if (partialKey == null || partialKey.length() == 0) {
+ return false;
+ }
+ return mPrefixes.contains(partialKey);
+ }
+
+ protected static void put(String key, String value) {
+ mMap.put(key, value);
+ for (int i = 1; i < key.length(); ++i) {
+ mPrefixes.add(key.substring(0, i));
+ }
+ }
+
+ protected StringBuilder composeBuffer = new StringBuilder(10);
+ protected ComposeSequencing composeUser;
+
+ protected void init(ComposeSequencing user) {
+ clear();
+ composeUser = user;
+ }
+
+ public void clear() {
+ composeBuffer.setLength(0);
+ }
+
+ public void bufferKey(char code) {
+ composeBuffer.append(code);
+ //Log.i(TAG, "bufferKey code=" + (int) code + " => " + showString(composeBuffer.toString()));
+ }
+
+ // returns true if the compose sequence is valid but incomplete
+ public String executeToString(int code) {
+ KeyboardSwitcher ks = KeyboardSwitcher.getInstance();
+ if (ks.getInputView().isShiftCaps()
+ && ks.isAlphabetMode()
+ && Character.isLowerCase(code)) {
+ code = Character.toUpperCase(code);
+ }
+ bufferKey((char) code);
+ composeUser.updateShiftKeyState(composeUser.getCurrentInputEditorInfo());
+
+ String composed = get(composeBuffer.toString());
+ if (composed != null) {
+ // If we get here, we have a complete compose sequence
+ return composed;
+ } else if (!isValid(composeBuffer.toString())) {
+ // If we get here, then the sequence typed isn't recognised
+ return "";
+ }
+ return null;
+ }
+
+ public boolean execute(int code) {
+ String composed = executeToString(code);
+ if (composed != null) {
+ clear();
+ composeUser.onText(composed);
+ return false;
+ }
+ return true;
+ }
+
+ public boolean execute(CharSequence sequence) {
+ int i, len = sequence.length();
+ boolean result = true;
+ for (i = 0; i < len; ++i) {
+ result = execute(sequence.charAt(i));
+ }
+ return result; // only last one matters
+ }
+}
diff --git a/java/src/org/pocketworkstation/pckeyboard/ComposeSequence.java b/java/src/org/pocketworkstation/pckeyboard/ComposeSequence.java
new file mode 100644
index 0000000..ae5bbd9
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/ComposeSequence.java
@@ -0,0 +1,910 @@
+/*
+ * Copyright (C) 2011 Darren Salt
+ *
+ * Licensed under the Apache License, Version 2.0 (the "Licence"); you may
+ * not use this file except in compliance with the Licence. You may obtain
+ * a copy of the Licence at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * Licence for the specific language governing permissions and limitations
+ * under the Licence.
+ */
+
+package org.pocketworkstation.pckeyboard;
+
+public class ComposeSequence extends ComposeBase {
+ public ComposeSequence(ComposeSequencing user) {
+ init(user);
+ }
+
+ static {
+ put("++", "#");
+ put("' ", "'");
+ put(" '", "'");
+ put("AT", "@");
+ put("((", "[");
+ put("//", "\\");
+ put("/<", "\\");
+ put("</", "\\");
+ put("))", "]");
+ put("^ ", "^");
+ put(" ^", "^");
+ put("> ", "^");
+ put(" >", "^");
+ put("` ", "`");
+ put(" `", "`");
+ put(", ", "¸");
+ put(" ,", "¸");
+ put("(-", "{");
+ put("-(", "{");
+ put("/^", "|");
+ put("^/", "|");
+ put("VL", "|");
+ put("LV", "|");
+ put("vl", "|");
+ put("lv", "|");
+ put(")-", "}");
+ put("-)", "}");
+ put("~ ", "~");
+ put(" ~", "~");
+ put("- ", "~");
+ put(" -", "~");
+ put(" ", " ");
+ put(" .", " ");
+ put("oc", "©");
+ put("oC", "©");
+ put("Oc", "©");
+ put("OC", "©");
+ put("or", "®");
+ put("oR", "®");
+ put("Or", "®");
+ put("OR", "®");
+ put(".>", "›");
+ put(".<", "‹");
+ put("..", "…");
+ put(".-", "·");
+ put(".=", "•");
+ put("!^", "¦");
+ put("!!", "¡");
+ put("p!", "¶");
+ put("P!", "¶");
+ put("+-", "±");
+ put("??", "¿");
+ put("-d", "đ");
+ put("-D", "Đ");
+ put("ss", "ß");
+ put("SS", "ẞ");
+ put("oe", "œ");
+ put("OE", "Œ");
+ put("ae", "æ");
+ put("AE", "Æ");
+ put("oo", "°");
+ put("\"\\", "〝");
+ put("\"/", "〞");
+ put("<<", "«");
+ put(">>", "»");
+ put("<'", "‘");
+ put("'<", "‘");
+ put(">'", "’");
+ put("'>", "’");
+ put(",'", "‚");
+ put("',", "‚");
+ put("<\"", "“");
+ put("\"<", "“");
+ put(">\"", "”");
+ put("\">", "”");
+ put(",\"", "„");
+ put("\",", "„");
+ put("%o", "‰");
+ put("CE", "₠");
+ put("C/", "₡");
+ put("/C", "₡");
+ put("Cr", "₢");
+ put("Fr", "₣");
+ put("L=", "₤");
+ put("=L", "₤");
+ put("m/", "₥");
+ put("/m", "₥");
+ put("N=", "₦");
+ put("=N", "₦");
+ put("Pt", "₧");
+ put("Rs", "₨");
+ put("W=", "₩");
+ put("=W", "₩");
+ put("d-", "₫");
+ put("C=", "€");
+ put("=C", "€");
+ put("c=", "€");
+ put("=c", "€");
+ put("E=", "€");
+ put("=E", "€");
+ put("e=", "€");
+ put("=e", "€");
+ put("|c", "¢");
+ put("c|", "¢");
+ put("c/", "¢");
+ put("/c", "¢");
+ put("L-", "£");
+ put("-L", "£");
+ put("Y=", "¥");
+ put("=Y", "¥");
+ put("fs", "ſ");
+ put("fS", "ſ");
+ put("--.", "–");
+ put("---", "—");
+ put("#b", "♭");
+ put("#f", "♮");
+ put("##", "♯");
+ put("so", "§");
+ put("os", "§");
+ put("ox", "¤");
+ put("xo", "¤");
+ put("PP", "¶");
+ put("No", "№");
+ put("NO", "№");
+ put("?!", "⸘");
+ put("!?", "‽");
+ put("CCCP", "☭");
+ put("OA", "Ⓐ");
+ put("<3", "♥");
+ put(":)", "☺");
+ put(":(", "☹");
+ put(",-", "¬");
+ put("-,", "¬");
+ put("^_a", "ª");
+ put("^2", "²");
+ put("^3", "³");
+ put("mu", "µ");
+ put("^1", "¹");
+ put("^_o", "º");
+ put("14", "¼");
+ put("12", "½");
+ put("34", "¾");
+ put("`A", "À");
+ put("'A", "Á");
+ put("^A", "Â");
+ put("~A", "Ã");
+ put("\"A", "Ä");
+ put("oA", "Å");
+ put(",C", "Ç");
+ put("`E", "È");
+ put("'E", "É");
+ put("^E", "Ê");
+ put("\"E", "Ë");
+ put("`I", "Ì");
+ put("'I", "Í");
+ put("^I", "Î");
+ put("\"I", "Ï");
+ put("DH", "Ð");
+ put("~N", "Ñ");
+ put("`O", "Ò");
+ put("'O", "Ó");
+ put("^O", "Ô");
+ put("~O", "Õ");
+ put("\"O", "Ö");
+ put("xx", "×");
+ put("/O", "Ø");
+ put("`U", "Ù");
+ put("'U", "Ú");
+ put("^U", "Û");
+ put("\"U", "Ü");
+ put("'Y", "Ý");
+ put("TH", "Þ");
+ put("`a", "à");
+ put("'a", "á");
+ put("^a", "â");
+ put("~a", "ã");
+ put("\"a", "ä");
+ put("oa", "å");
+ put(",c", "ç");
+ put("`e", "è");
+ put("'e", "é");
+ put("^e", "ê");
+ put("\"e", "ë");
+ put("`i", "ì");
+ put("'i", "í");
+ put("^i", "î");
+ put("\"i", "ï");
+ put("dh", "ð");
+ put("~n", "ñ");
+ put("`o", "ò");
+ put("'o", "ó");
+ put("^o", "ô");
+ put("~o", "õ");
+ put("\"o", "ö");
+ put(":-", "÷");
+ put("-:", "÷");
+ put("/o", "ø");
+ put("`u", "ù");
+ put("'u", "ú");
+ put("^u", "û");
+ put("\"u", "ü");
+ put("'y", "ý");
+ put("th", "þ");
+ put("\"y", "ÿ");
+ put("_A", "Ā");
+ put("_a", "ā");
+ put("UA", "Ă");
+ put("bA", "Ă");
+ put("Ua", "ă");
+ put("ba", "ă");
+ put(";A", "Ą");
+ put(",A", "Ą");
+ put(";a", "ą");
+ put(",a", "ą");
+ put("'C", "Ć");
+ put("'c", "ć");
+ put("^C", "Ĉ");
+ put("^c", "ĉ");
+ put(".C", "Ċ");
+ put(".c", "ċ");
+ put("cC", "Č");
+ put("cc", "č");
+ put("cD", "Ď");
+ put("cd", "ď");
+ put("/D", "Đ");
+ put("/d", "đ");
+ put("_E", "Ē");
+ put("_e", "ē");
+ put("UE", "Ĕ");
+ put("bE", "Ĕ");
+ put("Ue", "ĕ");
+ put("be", "ĕ");
+ put(".E", "Ė");
+ put(".e", "ė");
+ put(";E", "Ę");
+ put(",E", "Ę");
+ put(";e", "ę");
+ put(",e", "ę");
+ put("cE", "Ě");
+ put("ce", "ě");
+ //put("ff", "ff"); // Not usable, interferes with ffi/ffl prefix
+ put("+f", "ff");
+ put("f+", "ff");
+ put("fi", "fi");
+ put("fl", "fl");
+ put("ffi", "ffi");
+ put("ffl", "ffl");
+ put("^G", "Ĝ");
+ put("^g", "ĝ");
+ put("UG", "Ğ");
+ put("bG", "Ğ");
+ put("Ug", "ğ");
+ put("bg", "ğ");
+ put(".G", "Ġ");
+ put(".g", "ġ");
+ put(",G", "Ģ");
+ put(",g", "ģ");
+ put("^H", "Ĥ");
+ put("^h", "ĥ");
+ put("/H", "Ħ");
+ put("/h", "ħ");
+ put("~I", "Ĩ");
+ put("~i", "ĩ");
+ put("_I", "Ī");
+ put("_i", "ī");
+ put("UI", "Ĭ");
+ put("bI", "Ĭ");
+ put("Ui", "ĭ");
+ put("bi", "ĭ");
+ put(";I", "Į");
+ put(",I", "Į");
+ put(";i", "į");
+ put(",i", "į");
+ put(".I", "İ");
+ put("i.", "ı");
+ put("^J", "Ĵ");
+ put("^j", "ĵ");
+ put(",K", "Ķ");
+ put(",k", "ķ");
+ put("kk", "ĸ");
+ put("'L", "Ĺ");
+ put("'l", "ĺ");
+ put(",L", "Ļ");
+ put(",l", "ļ");
+ put("cL", "Ľ");
+ put("cl", "ľ");
+ put("/L", "Ł");
+ put("/l", "ł");
+ put("'N", "Ń");
+ put("'n", "ń");
+ put(",N", "Ņ");
+ put(",n", "ņ");
+ put("cN", "Ň");
+ put("cn", "ň");
+ put("NG", "Ŋ");
+ put("ng", "ŋ");
+ put("_O", "Ō");
+ put("_o", "ō");
+ put("UO", "Ŏ");
+ put("bO", "Ŏ");
+ put("Uo", "ŏ");
+ put("bo", "ŏ");
+ put("=O", "Ő");
+ put("=o", "ő");
+ put("'R", "Ŕ");
+ put("'r", "ŕ");
+ put(",R", "Ŗ");
+ put(",r", "ŗ");
+ put("cR", "Ř");
+ put("cr", "ř");
+ put("'S", "Ś");
+ put("'s", "ś");
+ put("^S", "Ŝ");
+ put("^s", "ŝ");
+ put(",S", "Ş");
+ put(",s", "ş");
+ put("cS", "Š");
+ put("cs", "š");
+ put(",T", "Ţ");
+ put(",t", "ţ");
+ put("cT", "Ť");
+ put("ct", "ť");
+ put("/T", "Ŧ");
+ put("/t", "ŧ");
+ put("~U", "Ũ");
+ put("~u", "ũ");
+ put("_U", "Ū");
+ put("_u", "ū");
+ put("UU", "Ŭ");
+ put("bU", "Ŭ");
+ put("Uu", "ŭ");
+ put("uu", "ŭ");
+ put("bu", "ŭ");
+ put("oU", "Ů");
+ put("ou", "ů");
+ put("=U", "Ű");
+ put("=u", "ű");
+ put(";U", "Ų");
+ put(",U", "Ų");
+ put(";u", "ų");
+ put(",u", "ų");
+ put("^W", "Ŵ");
+ put("^w", "ŵ");
+ put("^Y", "Ŷ");
+ put("^y", "ŷ");
+ put("\"Y", "Ÿ");
+ put("'Z", "Ź");
+ put("'z", "ź");
+ put(".Z", "Ż");
+ put(".z", "ż");
+ put("cZ", "Ž");
+ put("cz", "ž");
+ put("/b", "ƀ");
+ put("/I", "Ɨ");
+ put("+O", "Ơ");
+ put("+o", "ơ");
+ put("+U", "Ư");
+ put("+u", "ư");
+ put("/Z", "Ƶ");
+ put("/z", "ƶ");
+ put("cA", "Ǎ");
+ put("ca", "ǎ");
+ put("cI", "Ǐ");
+ put("ci", "ǐ");
+ put("cO", "Ǒ");
+ put("co", "ǒ");
+ put("cU", "Ǔ");
+ put("cu", "ǔ");
+ put("_Ü", "Ǖ");
+ put("_\"U", "Ǖ");
+ put("_ü", "ǖ");
+ put("_\"u", "ǖ");
+ put("'Ü", "Ǘ");
+ put("'\"U", "Ǘ");
+ put("'ü", "ǘ");
+ put("'\"u", "ǘ");
+ put("cÜ", "Ǚ");
+ put("c\"U", "Ǚ");
+ put("cü", "ǚ");
+ put("c\"u", "ǚ");
+ put("`Ü", "Ǜ");
+ put("`\"U", "Ǜ");
+ put("`ü", "ǜ");
+ put("`\"u", "ǜ");
+ put("_Ä", "Ǟ");
+ put("_\"A", "Ǟ");
+ put("_ä", "ǟ");
+ put("_\"a", "ǟ");
+ put("_.A", "Ǡ");
+ put("_.a", "ǡ");
+ put("_Æ", "Ǣ");
+ put("_æ", "ǣ");
+ put("/G", "Ǥ");
+ put("/g", "ǥ");
+ put("cG", "Ǧ");
+ put("cg", "ǧ");
+ put("cK", "Ǩ");
+ put("ck", "ǩ");
+ put(";O", "Ǫ");
+ put(";o", "ǫ");
+ put("_;O", "Ǭ");
+ put("_;o", "ǭ");
+ put("cj", "ǰ");
+ put("'G", "Ǵ");
+ put("'g", "ǵ");
+ put("`N", "Ǹ");
+ put("`n", "ǹ");
+ put("'Å", "Ǻ");
+ put("o'A", "Ǻ");
+ put("'å", "ǻ");
+ put("o'a", "ǻ");
+ put("'Æ", "Ǽ");
+ put("'æ", "ǽ");
+ put("'Ø", "Ǿ");
+ put("'/O", "Ǿ");
+ put("'ø", "ǿ");
+ put("'/o", "ǿ");
+ put("cH", "Ȟ");
+ put("ch", "ȟ");
+ put(".A", "Ȧ");
+ put(".a", "ȧ");
+ put("_Ö", "Ȫ");
+ put("_\"O", "Ȫ");
+ put("_ö", "ȫ");
+ put("_\"o", "ȫ");
+ put("_Õ", "Ȭ");
+ put("_~O", "Ȭ");
+ put("_õ", "ȭ");
+ put("_~o", "ȭ");
+ put(".O", "Ȯ");
+ put(".o", "ȯ");
+ put("_.O", "Ȱ");
+ put("_.o", "ȱ");
+ put("_Y", "Ȳ");
+ put("_y", "ȳ");
+ put("ee", "ə");
+ put("/i", "ɨ");
+ put("^_h", "ʰ");
+ put("^_j", "ʲ");
+ put("^_r", "ʳ");
+ put("^_w", "ʷ");
+ put("^_y", "ʸ");
+ put("^_l", "ˡ");
+ put("^_s", "ˢ");
+ put("^_x", "ˣ");
+ put("\"'", "̈́");
+ put(".B", "Ḃ");
+ put(".b", "ḃ");
+ put("!B", "Ḅ");
+ put("!b", "ḅ");
+ put("'Ç", "Ḉ");
+ put("'ç", "ḉ");
+ put(".D", "Ḋ");
+ put(".d", "ḋ");
+ put("!D", "Ḍ");
+ put("!d", "ḍ");
+ put(",D", "Ḑ");
+ put(",d", "ḑ");
+ put("`Ē", "Ḕ");
+ put("`_E", "Ḕ");
+ put("`ē", "ḕ");
+ put("`_e", "ḕ");
+ put("'Ē", "Ḗ");
+ put("'_E", "Ḗ");
+ put("'ē", "ḗ");
+ put("'_e", "ḗ");
+ put("U,E", "Ḝ");
+ put("b,E", "Ḝ");
+ put("U,e", "ḝ");
+ put("b,e", "ḝ");
+ put(".F", "Ḟ");
+ put(".f", "ḟ");
+ put("_G", "Ḡ");
+ put("_g", "ḡ");
+ put(".H", "Ḣ");
+ put(".h", "ḣ");
+ put("!H", "Ḥ");
+ put("!h", "ḥ");
+ put("\"H", "Ḧ");
+ put("\"h", "ḧ");
+ put(",H", "Ḩ");
+ put(",h", "ḩ");
+ put("'Ï", "Ḯ");
+ put("'\"I", "Ḯ");
+ put("'ï", "ḯ");
+ put("'\"i", "ḯ");
+ put("'K", "Ḱ");
+ put("'k", "ḱ");
+ put("!K", "Ḳ");
+ put("!k", "ḳ");
+ put("!L", "Ḷ");
+ put("!l", "ḷ");
+ put("_!L", "Ḹ");
+ put("_!l", "ḹ");
+ put("'M", "Ḿ");
+ put("'m", "ḿ");
+ put(".M", "Ṁ");
+ put(".m", "ṁ");
+ put("!M", "Ṃ");
+ put("!m", "ṃ");
+ put(".N", "Ṅ");
+ put(".n", "ṅ");
+ put("!N", "Ṇ");
+ put("!n", "ṇ");
+ put("'Õ", "Ṍ");
+ put("'~O", "Ṍ");
+ put("'õ", "ṍ");
+ put("'~o", "ṍ");
+ put("\"Õ", "Ṏ");
+ put("\"~O", "Ṏ");
+ put("\"õ", "ṏ");
+ put("\"~o", "ṏ");
+ put("`Ō", "Ṑ");
+ put("`_O", "Ṑ");
+ put("`ō", "ṑ");
+ put("`_o", "ṑ");
+ put("'Ō", "Ṓ");
+ put("'_O", "Ṓ");
+ put("'ō", "ṓ");
+ put("'_o", "ṓ");
+ put("'P", "Ṕ");
+ put("'p", "ṕ");
+ put(".P", "Ṗ");
+ put(".p", "ṗ");
+ put(".R", "Ṙ");
+ put(".r", "ṙ");
+ put("!R", "Ṛ");
+ put("!r", "ṛ");
+ put("_!R", "Ṝ");
+ put("_!r", "ṝ");
+ put(".S", "Ṡ");
+ put(".s", "ṡ");
+ put("!S", "Ṣ");
+ put("!s", "ṣ");
+ put(".Ś", "Ṥ");
+ put(".'S", "Ṥ");
+ put(".ś", "ṥ");
+ put(".'s", "ṥ");
+ put(".Š", "Ṧ");
+ put(".š", "ṧ");
+ put(".!S", "Ṩ");
+ put(".!s", "ṩ");
+ put(".T", "Ṫ");
+ put(".t", "ṫ");
+ put("!T", "Ṭ");
+ put("!t", "ṭ");
+ put("'Ũ", "Ṹ");
+ put("'~U", "Ṹ");
+ put("'ũ", "ṹ");
+ put("'~u", "ṹ");
+ put("\"Ū", "Ṻ");
+ put("\"_U", "Ṻ");
+ put("\"ū", "ṻ");
+ put("\"_u", "ṻ");
+ put("~V", "Ṽ");
+ put("~v", "ṽ");
+ put("!V", "Ṿ");
+ put("!v", "ṿ");
+ put("`W", "Ẁ");
+ put("`w", "ẁ");
+ put("'W", "Ẃ");
+ put("'w", "ẃ");
+ put("\"W", "Ẅ");
+ put("\"w", "ẅ");
+ put(".W", "Ẇ");
+ put(".w", "ẇ");
+ put("!W", "Ẉ");
+ put("!w", "ẉ");
+ put(".X", "Ẋ");
+ put(".x", "ẋ");
+ put("\"X", "Ẍ");
+ put("\"x", "ẍ");
+ put(".Y", "Ẏ");
+ put(".y", "ẏ");
+ put("^Z", "Ẑ");
+ put("^z", "ẑ");
+ put("!Z", "Ẓ");
+ put("!z", "ẓ");
+ put("\"t", "ẗ");
+ put("ow", "ẘ");
+ put("oy", "ẙ");
+ put("!A", "Ạ");
+ put("!a", "ạ");
+ put("?A", "Ả");
+ put("?a", "ả");
+ put("'Â", "Ấ");
+ put("'^A", "Ấ");
+ put("'â", "ấ");
+ put("'^a", "ấ");
+ put("`Â", "Ầ");
+ put("`^A", "Ầ");
+ put("`â", "ầ");
+ put("`^a", "ầ");
+ put("?Â", "Ẩ");
+ put("?^A", "Ẩ");
+ put("?â", "ẩ");
+ put("?^a", "ẩ");
+ put("~Â", "Ẫ");
+ put("~^A", "Ẫ");
+ put("~â", "ẫ");
+ put("~^a", "ẫ");
+ put("^!A", "Ậ");
+ put("^!a", "ậ");
+ put("'Ă", "Ắ");
+ put("'bA", "Ắ");
+ put("'ă", "ắ");
+ put("'ba", "ắ");
+ put("`Ă", "Ằ");
+ put("`bA", "Ằ");
+ put("`ă", "ằ");
+ put("`ba", "ằ");
+ put("?Ă", "Ẳ");
+ put("?bA", "Ẳ");
+ put("?ă", "ẳ");
+ put("?ba", "ẳ");
+ put("~Ă", "Ẵ");
+ put("~bA", "Ẵ");
+ put("~ă", "ẵ");
+ put("~ba", "ẵ");
+ put("U!A", "Ặ");
+ put("b!A", "Ặ");
+ put("U!a", "ặ");
+ put("b!a", "ặ");
+ put("!E", "Ẹ");
+ put("!e", "ẹ");
+ put("?E", "Ẻ");
+ put("?e", "ẻ");
+ put("~E", "Ẽ");
+ put("~e", "ẽ");
+ put("'Ê", "Ế");
+ put("'^E", "Ế");
+ put("'ê", "ế");
+ put("'^e", "ế");
+ put("`Ê", "Ề");
+ put("`^E", "Ề");
+ put("`ê", "ề");
+ put("`^e", "ề");
+ put("?Ê", "Ể");
+ put("?^E", "Ể");
+ put("?ê", "ể");
+ put("?^e", "ể");
+ put("~Ê", "Ễ");
+ put("~^E", "Ễ");
+ put("~ê", "ễ");
+ put("~^e", "ễ");
+ put("^!E", "Ệ");
+ put("^!e", "ệ");
+ put("?I", "Ỉ");
+ put("?i", "ỉ");
+ put("!I", "Ị");
+ put("!i", "ị");
+ put("!O", "Ọ");
+ put("!o", "ọ");
+ put("?O", "Ỏ");
+ put("?o", "ỏ");
+ put("'Ô", "Ố");
+ put("'^O", "Ố");
+ put("'ô", "ố");
+ put("'^o", "ố");
+ put("`Ô", "Ồ");
+ put("`^O", "Ồ");
+ put("`ô", "ồ");
+ put("`^o", "ồ");
+ put("?Ô", "Ổ");
+ put("?^O", "Ổ");
+ put("?ô", "ổ");
+ put("?^o", "ổ");
+ put("~Ô", "Ỗ");
+ put("~^O", "Ỗ");
+ put("~ô", "ỗ");
+ put("~^o", "ỗ");
+ put("^!O", "Ộ");
+ put("^!o", "ộ");
+ put("'Ơ", "Ớ");
+ put("'+O", "Ớ");
+ put("'ơ", "ớ");
+ put("'+o", "ớ");
+ put("`Ơ", "Ờ");
+ put("`+O", "Ờ");
+ put("`ơ", "ờ");
+ put("`+o", "ờ");
+ put("?Ơ", "Ở");
+ put("?+O", "Ở");
+ put("?ơ", "ở");
+ put("?+o", "ở");
+ put("~Ơ", "Ỡ");
+ put("~+O", "Ỡ");
+ put("~ơ", "ỡ");
+ put("~+o", "ỡ");
+ put("!Ơ", "Ợ");
+ put("!+O", "Ợ");
+ put("!ơ", "ợ");
+ put("!+o", "ợ");
+ put("!U", "Ụ");
+ put("!u", "ụ");
+ put("?U", "Ủ");
+ put("?u", "ủ");
+ put("'Ư", "Ứ");
+ put("'+U", "Ứ");
+ put("'ư", "ứ");
+ put("'+u", "ứ");
+ put("`Ư", "Ừ");
+ put("`+U", "Ừ");
+ put("`ư", "ừ");
+ put("`+u", "ừ");
+ put("?Ư", "Ử");
+ put("?+U", "Ử");
+ put("?ư", "ử");
+ put("?+u", "ử");
+ put("~Ư", "Ữ");
+ put("~+U", "Ữ");
+ put("~ư", "ữ");
+ put("~+u", "ữ");
+ put("!Ư", "Ự");
+ put("!+U", "Ự");
+ put("!ư", "ự");
+ put("!+u", "ự");
+ put("`Y", "Ỳ");
+ put("`y", "ỳ");
+ put("!Y", "Ỵ");
+ put("!y", "ỵ");
+ put("?Y", "Ỷ");
+ put("?y", "ỷ");
+ put("~Y", "Ỹ");
+ put("~y", "ỹ");
+ put("^0", "⁰");
+ put("^_i", "ⁱ");
+ put("^4", "⁴");
+ put("^5", "⁵");
+ put("^6", "⁶");
+ put("^7", "⁷");
+ put("^8", "⁸");
+ put("^9", "⁹");
+ put("^+", "⁺");
+ put("^=", "⁼");
+ put("^(", "⁽");
+ put("^)", "⁾");
+ put("^_n", "ⁿ");
+ put("_0", "₀");
+ put("_1", "₁");
+ put("_2", "₂");
+ put("_3", "₃");
+ put("_4", "₄");
+ put("_5", "₅");
+ put("_6", "₆");
+ put("_7", "₇");
+ put("_8", "₈");
+ put("_9", "₉");
+ put("_+", "₊");
+ put("_=", "₌");
+ put("_(", "₍");
+ put("_)", "₎");
+ put("SM", "℠");
+ put("sM", "℠");
+ put("Sm", "℠");
+ put("sm", "℠");
+ put("TM", "™");
+ put("tM", "™");
+ put("Tm", "™");
+ put("tm", "™");
+ put("13", "⅓");
+ put("23", "⅔");
+ put("15", "⅕");
+ put("25", "⅖");
+ put("35", "⅗");
+ put("45", "⅘");
+ put("16", "⅙");
+ put("56", "⅚");
+ put("18", "⅛");
+ put("38", "⅜");
+ put("58", "⅝");
+ put("78", "⅞");
+ put("/←", "↚");
+ put("/→", "↛");
+ put("<-", "←");
+ put("->", "→");
+ put("/=", "≠");
+ put("=/", "≠");
+ put("<=", "≤");
+ put(">=", "≥");
+ put("(1)", "①");
+ put("(2)", "②");
+ put("(3)", "③");
+ put("(4)", "④");
+ put("(5)", "⑤");
+ put("(6)", "⑥");
+ put("(7)", "⑦");
+ put("(8)", "⑧");
+ put("(9)", "⑨");
+ put("(10)", "⑩");
+ put("(11)", "⑪");
+ put("(12)", "⑫");
+ put("(13)", "⑬");
+ put("(14)", "⑭");
+ put("(15)", "⑮");
+ put("(16)", "⑯");
+ put("(17)", "⑰");
+ put("(18)", "⑱");
+ put("(19)", "⑲");
+ put("(20)", "⑳");
+ put("(A)", "Ⓐ");
+ put("(B)", "Ⓑ");
+ put("(C)", "Ⓒ");
+ put("(D)", "Ⓓ");
+ put("(E)", "Ⓔ");
+ put("(F)", "Ⓕ");
+ put("(G)", "Ⓖ");
+ put("(H)", "Ⓗ");
+ put("(I)", "Ⓘ");
+ put("(J)", "Ⓙ");
+ put("(K)", "Ⓚ");
+ put("(L)", "Ⓛ");
+ put("(M)", "Ⓜ");
+ put("(N)", "Ⓝ");
+ put("(O)", "Ⓞ");
+ put("(P)", "Ⓟ");
+ put("(Q)", "Ⓠ");
+ put("(R)", "Ⓡ");
+ put("(S)", "Ⓢ");
+ put("(T)", "Ⓣ");
+ put("(U)", "Ⓤ");
+ put("(V)", "Ⓥ");
+ put("(W)", "Ⓦ");
+ put("(X)", "Ⓧ");
+ put("(Y)", "Ⓨ");
+ put("(Z)", "Ⓩ");
+ put("(a)", "ⓐ");
+ put("(b)", "ⓑ");
+ put("(c)", "ⓒ");
+ put("(d)", "ⓓ");
+ put("(e)", "ⓔ");
+ put("(f)", "ⓕ");
+ put("(g)", "ⓖ");
+ put("(h)", "ⓗ");
+ put("(i)", "ⓘ");
+ put("(j)", "ⓙ");
+ put("(k)", "ⓚ");
+ put("(l)", "ⓛ");
+ put("(m)", "ⓜ");
+ put("(n)", "ⓝ");
+ put("(o)", "ⓞ");
+ put("(p)", "ⓟ");
+ put("(q)", "ⓠ");
+ put("(r)", "ⓡ");
+ put("(s)", "ⓢ");
+ put("(t)", "ⓣ");
+ put("(u)", "ⓤ");
+ put("(v)", "ⓥ");
+ put("(w)", "ⓦ");
+ put("(x)", "ⓧ");
+ put("(y)", "ⓨ");
+ put("(z)", "ⓩ");
+ put("(0)", "⓪");
+ put("(21)", "㉑");
+ put("(22)", "㉒");
+ put("(23)", "㉓");
+ put("(24)", "㉔");
+ put("(25)", "㉕");
+ put("(26)", "㉖");
+ put("(27)", "㉗");
+ put("(28)", "㉘");
+ put("(29)", "㉙");
+ put("(30)", "㉚");
+ put("(31)", "㉛");
+ put("(32)", "㉜");
+ put("(33)", "㉝");
+ put("(34)", "㉞");
+ put("(35)", "㉟");
+ put("(36)", "㊱");
+ put("(37)", "㊲");
+ put("(38)", "㊳");
+ put("(39)", "㊴");
+ put("(40)", "㊵");
+ put("(41)", "㊶");
+ put("(42)", "㊷");
+ put("(43)", "㊸");
+ put("(44)", "㊹");
+ put("(45)", "㊺");
+ put("(46)", "㊻");
+ put("(47)", "㊼");
+ put("(48)", "㊽");
+ put("(49)", "㊾");
+ put("(50)", "㊿");
+ put("\\o/", "🙌");
+ }
+}
diff --git a/java/src/org/pocketworkstation/pckeyboard/ContactsDictionary.java b/java/src/org/pocketworkstation/pckeyboard/ContactsDictionary.java
new file mode 100644
index 0000000..001abc8
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/ContactsDictionary.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.pocketworkstation.pckeyboard;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.database.Cursor;
+import android.os.SystemClock;
+import android.provider.ContactsContract.Contacts;
+import android.text.TextUtils;
+import android.util.Log;
+
+public class ContactsDictionary extends ExpandableDictionary {
+
+ private static final String[] PROJECTION = {
+ Contacts._ID,
+ Contacts.DISPLAY_NAME,
+ };
+
+ private static final String TAG = "ContactsDictionary";
+
+ /**
+ * Frequency for contacts information into the dictionary
+ */
+ private static final int FREQUENCY_FOR_CONTACTS = 128;
+ private static final int FREQUENCY_FOR_CONTACTS_BIGRAM = 90;
+
+ private static final int INDEX_NAME = 1;
+
+ private ContentObserver mObserver;
+
+ private long mLastLoadedContacts;
+
+ public ContactsDictionary(Context context, int dicTypeId) {
+ super(context, dicTypeId);
+ // Perform a managed query. The Activity will handle closing and requerying the cursor
+ // when needed.
+ ContentResolver cres = context.getContentResolver();
+
+ cres.registerContentObserver(
+ Contacts.CONTENT_URI, true,mObserver = new ContentObserver(null) {
+ @Override
+ public void onChange(boolean self) {
+ setRequiresReload(true);
+ }
+ });
+ loadDictionary();
+ }
+
+ @Override
+ public synchronized void close() {
+ if (mObserver != null) {
+ getContext().getContentResolver().unregisterContentObserver(mObserver);
+ mObserver = null;
+ }
+ super.close();
+ }
+
+ @Override
+ public void startDictionaryLoadingTaskLocked() {
+ long now = SystemClock.uptimeMillis();
+ if (mLastLoadedContacts == 0
+ || now - mLastLoadedContacts > 30 * 60 * 1000 /* 30 minutes */) {
+ super.startDictionaryLoadingTaskLocked();
+ }
+ }
+
+ @Override
+ public void loadDictionaryAsync() {
+ try {
+ Cursor cursor = getContext().getContentResolver()
+ .query(Contacts.CONTENT_URI, PROJECTION, null, null, null);
+ if (cursor != null) {
+ addWords(cursor);
+ }
+ } catch(IllegalStateException e) {
+ Log.e(TAG, "Contacts DB is having problems");
+ }
+ mLastLoadedContacts = SystemClock.uptimeMillis();
+ }
+
+ private void addWords(Cursor cursor) {
+ clearDictionary();
+
+ final int maxWordLength = getMaxWordLength();
+ try {
+ if (cursor.moveToFirst()) {
+ while (!cursor.isAfterLast()) {
+ String name = cursor.getString(INDEX_NAME);
+
+ if (name != null) {
+ int len = name.length();
+ String prevWord = null;
+
+ // TODO: Better tokenization for non-Latin writing systems
+ for (int i = 0; i < len; i++) {
+ if (Character.isLetter(name.charAt(i))) {
+ int j;
+ for (j = i + 1; j < len; j++) {
+ char c = name.charAt(j);
+
+ if (!(c == '-' || c == '\'' ||
+ Character.isLetter(c))) {
+ break;
+ }
+ }
+
+ String word = name.substring(i, j);
+ i = j - 1;
+
+ // Safeguard against adding really long words. Stack
+ // may overflow due to recursion
+ // Also don't add single letter words, possibly confuses
+ // capitalization of i.
+ final int wordLen = word.length();
+ if (wordLen < maxWordLength && wordLen > 1) {
+ super.addWord(word, FREQUENCY_FOR_CONTACTS);
+ if (!TextUtils.isEmpty(prevWord)) {
+ // TODO Do not add email address
+ // Not so critical
+ super.setBigram(prevWord, word,
+ FREQUENCY_FOR_CONTACTS_BIGRAM);
+ }
+ prevWord = word;
+ }
+ }
+ }
+ }
+ cursor.moveToNext();
+ }
+ }
+ cursor.close();
+ } catch(IllegalStateException e) {
+ Log.e(TAG, "Contacts DB is having problems");
+ }
+ }
+}
diff --git a/java/src/org/pocketworkstation/pckeyboard/DeadAccentSequence.java b/java/src/org/pocketworkstation/pckeyboard/DeadAccentSequence.java
new file mode 100644
index 0000000..da0ff75
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/DeadAccentSequence.java
@@ -0,0 +1,1063 @@
+/*
+ * Copyright (C) 2011 Darren Salt
+ *
+ * Licensed under the Apache License, Version 2.0 (the "Licence"); you may
+ * not use this file except in compliance with the Licence. You may obtain
+ * a copy of the Licence at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * Licence for the specific language governing permissions and limitations
+ * under the Licence.
+ */
+
+package org.pocketworkstation.pckeyboard;
+
+import java.text.Normalizer;
+
+import android.util.Log;
+
+public class DeadAccentSequence extends ComposeBase {
+ private static final String TAG = "HK/DeadAccent";
+
+ public DeadAccentSequence(ComposeSequencing user) {
+ init(user);
+ }
+
+ private static void putAccent(String nonSpacing, String spacing, String ascii) {
+ if (ascii == null) ascii = spacing;
+ put("" + nonSpacing + " ", ascii);
+ put(nonSpacing + nonSpacing, spacing);
+ put(Keyboard.DEAD_KEY_PLACEHOLDER + nonSpacing, spacing);
+ }
+
+ public static String getSpacing(char nonSpacing) {
+ String spacing = get("" + Keyboard.DEAD_KEY_PLACEHOLDER + nonSpacing);
+ if (spacing == null) spacing = DeadAccentSequence.normalize(" " + nonSpacing);
+ if (spacing == null) return "" + nonSpacing;
+ return spacing;
+ }
+
+ static {
+ // space + combining diacritical
+ // cf. http://unicode.org/charts/PDF/U0300.pdf
+ putAccent("\u0300", "\u02cb", "`"); // grave
+ putAccent("\u0301", "\u02ca", "´"); // acute
+ putAccent("\u0302", "\u02c6", "^"); // circumflex
+ putAccent("\u0303", "\u02dc", "~"); // small tilde
+ putAccent("\u0304", "\u02c9", "¯"); // macron
+ putAccent("\u0305", "\u00af", "¯"); // overline
+ putAccent("\u0306", "\u02d8", null); // breve
+ putAccent("\u0307", "\u02d9", null); // dot above
+ putAccent("\u0308", "\u00a8", "¨"); // diaeresis
+ putAccent("\u0309", "\u02c0", null); // hook above
+ putAccent("\u030a", "\u02da", "°"); // ring above
+ putAccent("\u030b", "\u02dd", "\""); // double acute
+ putAccent("\u030c", "\u02c7", null); // caron
+ putAccent("\u030d", "\u02c8", null); // vertical line above
+ putAccent("\u030e", "\"", "\""); // double vertical line above
+ putAccent("\u0313", "\u02bc", null); // comma above
+ putAccent("\u0314", "\u02bd", null); // reversed comma above
+
+ put("\u0308\u0301\u03b9", "\u0390"); // Greek Dialytika+Tonos, iota
+ put("\u0301\u0308\u03b9", "\u0390"); // Greek Dialytika+Tonos, iota
+ put("\u0301\u03ca", "\u0390"); // Greek Dialytika+Tonos, iota
+ put("\u0308\u0301\u03c5", "\u03b0"); // Greek Dialytika+Tonos, upsilon
+ put("\u0301\u0308\u03c5", "\u03b0"); // Greek Dialytika+Tonos, upsilon
+ put("\u0301\u03cb", "\u03b0"); // Greek Dialytika+Tonos, upsilon
+
+/*
+// include?
+ put("̃ ", "~");
+ put("̃̃", "~");
+ put("́ ", "'");
+ put("́́", "´");
+ put("̀ ", "`");
+ put("̀̀", "`");
+ put("̂ ", "^");
+ put("̂̂", "^");
+ put("̊ ", "°");
+ put("̊̊", "°");
+ put("̄ ", "¯");
+ put("̄̄", "¯");
+ put("̆ ", "˘");
+ put("̆̆", "˘");
+ put("̇ ", "˙");
+ put("̇̇", "˙");
+ put("̈̈", "¨");
+ put("̈ ", "\"");
+ put("̋ ", "˝");
+ put("̋̋", "˝");
+ put("̌ ", "ˇ");
+ put("̌̌", "ˇ");
+ put("̧ ", "¸");
+ put("̧̧", "¸");
+ put("̨ ", "˛");
+ put("̨̨", "˛");
+ put("̂2", "²");
+ put("̂3", "³");
+ put("̂1", "¹");
+// include end?
+ put("̀A", "À");
+ put("́A", "Á");
+ put("̂A", "Â");
+ put("̃A", "Ã");
+ put("̈A", "Ä");
+ put("̊A", "Å");
+ put("̧C", "Ç");
+ put("̀E", "È");
+ put("́E", "É");
+ put("̂E", "Ê");
+ put("̈E", "Ë");
+ put("̀I", "Ì");
+ put("́I", "Í");
+ put("̂I", "Î");
+ put("̈I", "Ï");
+ put("̃N", "Ñ");
+ put("̀O", "Ò");
+ put("́O", "Ó");
+ put("̂O", "Ô");
+ put("̃O", "Õ");
+ put("̈O", "Ö");
+ put("̀U", "Ù");
+ put("́U", "Ú");
+ put("̂U", "Û");
+ put("̈U", "Ü");
+ put("́Y", "Ý");
+ put("̀a", "à");
+ put("́a", "á");
+ put("̂a", "â");
+ put("̃a", "ã");
+ put("̈a", "ä");
+ put("̊a", "å");
+ put("̧c", "ç");
+ put("̀e", "è");
+ put("́e", "é");
+ put("̂e", "ê");
+ put("̈e", "ë");
+ put("̀i", "ì");
+ put("́i", "í");
+ put("̂i", "î");
+ put("̈i", "ï");
+ put("̃n", "ñ");
+ put("̀o", "ò");
+ put("́o", "ó");
+ put("̂o", "ô");
+ put("̃o", "õ");
+ put("̈o", "ö");
+ put("̀u", "ù");
+ put("́u", "ú");
+ put("̂u", "û");
+ put("̈u", "ü");
+ put("́y", "ý");
+ put("̈y", "ÿ");
+ put("̄A", "Ā");
+ put("̄a", "ā");
+ put("̆A", "Ă");
+ put("̆a", "ă");
+ put("̨A", "Ą");
+ put("̨a", "ą");
+ put("́C", "Ć");
+ put("́c", "ć");
+ put("̂C", "Ĉ");
+ put("̂c", "ĉ");
+ put("̇C", "Ċ");
+ put("̇c", "ċ");
+ put("̌C", "Č");
+ put("̌c", "č");
+ put("̌D", "Ď");
+ put("̌d", "ď");
+ put("̄E", "Ē");
+ put("̄e", "ē");
+ put("̆E", "Ĕ");
+ put("̆e", "ĕ");
+ put("̇E", "Ė");
+ put("̇e", "ė");
+ put("̨E", "Ę");
+ put("̨e", "ę");
+ put("̌E", "Ě");
+ put("̌e", "ě");
+ put("̂G", "Ĝ");
+ put("̂g", "ĝ");
+ put("̆G", "Ğ");
+ put("̆g", "ğ");
+ put("̇G", "Ġ");
+ put("̇g", "ġ");
+ put("̧G", "Ģ");
+ put("̧g", "ģ");
+ put("̂H", "Ĥ");
+ put("̂h", "ĥ");
+ put("̃I", "Ĩ");
+ put("̃i", "ĩ");
+ put("̄I", "Ī");
+ put("̄i", "ī");
+ put("̆I", "Ĭ");
+ put("̆i", "ĭ");
+ put("̨I", "Į");
+ put("̨i", "į");
+ put("̇I", "İ");
+ put("̇i", "ı");
+ put("̂J", "Ĵ");
+ put("̂j", "ĵ");
+ put("̧K", "Ķ");
+ put("̧k", "ķ");
+ put("́L", "Ĺ");
+ put("́l", "ĺ");
+ put("̧L", "Ļ");
+ put("̧l", "ļ");
+ put("̌L", "Ľ");
+ put("̌l", "ľ");
+ put("́N", "Ń");
+ put("́n", "ń");
+ put("̧N", "Ņ");
+ put("̧n", "ņ");
+ put("̌N", "Ň");
+ put("̌n", "ň");
+ put("̄O", "Ō");
+ put("̄o", "ō");
+ put("̆O", "Ŏ");
+ put("̆o", "ŏ");
+ put("̋O", "Ő");
+ put("̋o", "ő");
+ put("́R", "Ŕ");
+ put("́r", "ŕ");
+ put("̧R", "Ŗ");
+ put("̧r", "ŗ");
+ put("̌R", "Ř");
+ put("̌r", "ř");
+ put("́S", "Ś");
+ put("́s", "ś");
+ put("̂S", "Ŝ");
+ put("̂s", "ŝ");
+ put("̧S", "Ş");
+ put("̧s", "ş");
+ put("̌S", "Š");
+ put("̌s", "š");
+ put("̧T", "Ţ");
+ put("̧t", "ţ");
+ put("̌T", "Ť");
+ put("̌t", "ť");
+ put("̃U", "Ũ");
+ put("̃u", "ũ");
+ put("̄U", "Ū");
+ put("̄u", "ū");
+ put("̆U", "Ŭ");
+ put("̆u", "ŭ");
+ put("̊U", "Ů");
+ put("̊u", "ů");
+ put("̋U", "Ű");
+ put("̋u", "ű");
+ put("̨U", "Ų");
+ put("̨u", "ų");
+ put("̂W", "Ŵ");
+ put("̂w", "ŵ");
+ put("̂Y", "Ŷ");
+ put("̂y", "ŷ");
+ put("̈Y", "Ÿ");
+ put("́Z", "Ź");
+ put("́z", "ź");
+ put("̇Z", "Ż");
+ put("̇z", "ż");
+ put("̌Z", "Ž");
+ put("̌z", "ž");
+ put("̛O", "Ơ");
+ put("̛o", "ơ");
+ put("̛U", "Ư");
+ put("̛u", "ư");
+ put("̌A", "Ǎ");
+ put("̌a", "ǎ");
+ put("̌I", "Ǐ");
+ put("̌i", "ǐ");
+ put("̌O", "Ǒ");
+ put("̌o", "ǒ");
+ put("̌U", "Ǔ");
+ put("̌u", "ǔ");
+ put("̄Ü", "Ǖ");
+ put("̄̈U", "Ǖ");
+ put("̄ü", "ǖ");
+ put("̄̈u", "ǖ");
+ put("́Ü", "Ǘ");
+ put("́̈U", "Ǘ");
+ put("́ü", "ǘ");
+ put("́̈u", "ǘ");
+ put("̌Ü", "Ǚ");
+ put("̌̈U", "Ǚ");
+ put("̌ü", "ǚ");
+ put("̌̈u", "ǚ");
+ put("̀Ü", "Ǜ");
+ put("̀̈U", "Ǜ");
+ put("̀ü", "ǜ");
+ put("̀̈u", "ǜ");
+ put("̄Ä", "Ǟ");
+ put("̄̈A", "Ǟ");
+ put("̄ä", "ǟ");
+ put("̄̈a", "ǟ");
+ put("̄Ȧ", "Ǡ");
+ put("̄̇A", "Ǡ");
+ put("̄ȧ", "ǡ");
+ put("̄̇a", "ǡ");
+ put("̄Æ", "Ǣ");
+ put("̄æ", "ǣ");
+ put("̌G", "Ǧ");
+ put("̌g", "ǧ");
+ put("̌K", "Ǩ");
+ put("̌k", "ǩ");
+ put("̨O", "Ǫ");
+ put("̨o", "ǫ");
+ put("̄Ǫ", "Ǭ");
+ put("̨̄O", "Ǭ");
+ put("̄ǫ", "ǭ");
+ put("̨̄o", "ǭ");
+ put("̌Ʒ", "Ǯ");
+ put("̌ʒ", "ǯ");
+ put("̌j", "ǰ");
+ put("́G", "Ǵ");
+ put("́g", "ǵ");
+ put("̀N", "Ǹ");
+ put("̀n", "ǹ");
+ put("́Å", "Ǻ");
+ put("́̊A", "Ǻ");
+ put("́å", "ǻ");
+ put("́̊a", "ǻ");
+ put("́Æ", "Ǽ");
+ put("́æ", "ǽ");
+ put("́Ø", "Ǿ");
+ put("́ø", "ǿ");
+ put("̏A", "Ȁ");
+ put("̏a", "ȁ");
+ put("̑A", "Ȃ");
+ put("̑a", "ȃ");
+ put("̏E", "Ȅ");
+ put("̏e", "ȅ");
+ put("̑E", "Ȇ");
+ put("̑e", "ȇ");
+ put("̏I", "Ȉ");
+ put("̏i", "ȉ");
+ put("̑I", "Ȋ");
+ put("̑i", "ȋ");
+ put("̏O", "Ȍ");
+ put("̏o", "ȍ");
+ put("̑O", "Ȏ");
+ put("̑o", "ȏ");
+ put("̏R", "Ȑ");
+ put("̏r", "ȑ");
+ put("̑R", "Ȓ");
+ put("̑r", "ȓ");
+ put("̏U", "Ȕ");
+ put("̏u", "ȕ");
+ put("̑U", "Ȗ");
+ put("̑u", "ȗ");
+ put("̌H", "Ȟ");
+ put("̌h", "ȟ");
+ put("̇A", "Ȧ");
+ put("̇a", "ȧ");
+ put("̧E", "Ȩ");
+ put("̧e", "ȩ");
+ put("̄Ö", "Ȫ");
+ put("̄̈O", "Ȫ");
+ put("̄ö", "ȫ");
+ put("̄̈o", "ȫ");
+ put("̄Õ", "Ȭ");
+ put("̄ ̃O", "Ȭ");
+ put("̄õ", "ȭ");
+ put("̄ ̃o", "ȭ");
+ put("̇O", "Ȯ");
+ put("̇o", "ȯ");
+ put("̄Ȯ", "Ȱ");
+ put("̄̇O", "Ȱ");
+ put("̄ȯ", "ȱ");
+ put("̄̇o", "ȱ");
+ put("̄Y", "Ȳ");
+ put("̄y", "ȳ");
+ put("̥A", "Ḁ");
+ put("̥a", "ḁ");
+ put("̇B", "Ḃ");
+ put("̇b", "ḃ");
+ put("̣B", "Ḅ");
+ put("̣b", "ḅ");
+ put("̱B", "Ḇ");
+ put("̱b", "ḇ");
+ put("́Ç", "Ḉ");
+ put("̧́C", "Ḉ");
+ put("́ç", "ḉ");
+ put("̧́c", "ḉ");
+ put("̇D", "Ḋ");
+ put("̇d", "ḋ");
+ put("̣D", "Ḍ");
+ put("̣d", "ḍ");
+ put("̱D", "Ḏ");
+ put("̱d", "ḏ");
+ put("̧D", "Ḑ");
+ put("̧d", "ḑ");
+ put("̭D", "Ḓ");
+ put("̭d", "ḓ");
+ put("̀Ē", "Ḕ");
+ put("̀ ̄E", "Ḕ");
+ put("̀ē", "ḕ");
+ put("̀ ̄e", "ḕ");
+ put("́Ē", "Ḗ");
+ put("́ ̄E", "Ḗ");
+ put("́ē", "ḗ");
+ put("́ ̄e", "ḗ");
+ put("̭E", "Ḙ");
+ put("̭e", "ḙ");
+ put("̰E", "Ḛ");
+ put("̰e", "ḛ");
+ put("̆Ȩ", "Ḝ");
+ put("̧̆E", "Ḝ");
+ put("̆ȩ", "ḝ");
+ put("̧̆e", "ḝ");
+ put("̇F", "Ḟ");
+ put("̇f", "ḟ");
+ put("̄G", "Ḡ");
+ put("̄g", "ḡ");
+ put("̇H", "Ḣ");
+ put("̇h", "ḣ");
+ put("̣H", "Ḥ");
+ put("̣h", "ḥ");
+ put("̈H", "Ḧ");
+ put("̈h", "ḧ");
+ put("̧H", "Ḩ");
+ put("̧h", "ḩ");
+ put("̮H", "Ḫ");
+ put("̮h", "ḫ");
+ put("̰I", "Ḭ");
+ put("̰i", "ḭ");
+ put("́Ï", "Ḯ");
+ put("́̈I", "Ḯ");
+ put("́ï", "ḯ");
+ put("́̈i", "ḯ");
+ put("́K", "Ḱ");
+ put("́k", "ḱ");
+ put("̣K", "Ḳ");
+ put("̣k", "ḳ");
+ put("̱K", "Ḵ");
+ put("̱k", "ḵ");
+ put("̣L", "Ḷ");
+ put("̣l", "ḷ");
+ put("̄Ḷ", "Ḹ");
+ put("̣̄L", "Ḹ");
+ put("̄ḷ", "ḹ");
+ put("̣̄l", "ḹ");
+ put("̱L", "Ḻ");
+ put("̱l", "ḻ");
+ put("̭L", "Ḽ");
+ put("̭l", "ḽ");
+ put("́M", "Ḿ");
+ put("́m", "ḿ");
+ put("̇M", "Ṁ");
+ put("̇m", "ṁ");
+ put("̣M", "Ṃ");
+ put("̣m", "ṃ");
+ put("̇N", "Ṅ");
+ put("̇n", "ṅ");
+ put("̣N", "Ṇ");
+ put("̣n", "ṇ");
+ put("̱N", "Ṉ");
+ put("̱n", "ṉ");
+ put("̭N", "Ṋ");
+ put("̭n", "ṋ");
+ put("́Õ", "Ṍ");
+ put("́ ̃O", "Ṍ");
+ put("́õ", "ṍ");
+ put("́ ̃o", "ṍ");
+ put("̈Õ", "Ṏ");
+ put("̈ ̃O", "Ṏ");
+ put("̈õ", "ṏ");
+ put("̈ ̃o", "ṏ");
+ put("̀Ō", "Ṑ");
+ put("̀ ̄O", "Ṑ");
+ put("̀ō", "ṑ");
+ put("̀ ̄o", "ṑ");
+ put("́Ō", "Ṓ");
+ put("́ ̄O", "Ṓ");
+ put("́ō", "ṓ");
+ put("́ ̄o", "ṓ");
+ put("́P", "Ṕ");
+ put("́p", "ṕ");
+ put("̇P", "Ṗ");
+ put("̇p", "ṗ");
+ put("̇R", "Ṙ");
+ put("̇r", "ṙ");
+ put("̣R", "Ṛ");
+ put("̣r", "ṛ");
+ put("̄Ṛ", "Ṝ");
+ put("̣̄R", "Ṝ");
+ put("̄ṛ", "ṝ");
+ put("̣̄r", "ṝ");
+ put("̱R", "Ṟ");
+ put("̱r", "ṟ");
+ put("̇S", "Ṡ");
+ put("̇s", "ṡ");
+ put("̣S", "Ṣ");
+ put("̣s", "ṣ");
+ put("̇Ś", "Ṥ");
+ put("̇ ́S", "Ṥ");
+ put("̇ś", "ṥ");
+ put("̇ ́s", "ṥ");
+ put("̇Š", "Ṧ");
+ put("̇̌S", "Ṧ");
+ put("̇š", "ṧ");
+ put("̇̌s", "ṧ");
+ put("̇Ṣ", "Ṩ");
+ put("̣̇S", "Ṩ");
+ put("̇ṣ", "ṩ");
+ put("̣̇s", "ṩ");
+ put("̇T", "Ṫ");
+ put("̇t", "ṫ");
+ put("̣T", "Ṭ");
+ put("̣t", "ṭ");
+ put("̱T", "Ṯ");
+ put("̱t", "ṯ");
+ put("̭T", "Ṱ");
+ put("̭t", "ṱ");
+ put("̤U", "Ṳ");
+ put("̤u", "ṳ");
+ put("̰U", "Ṵ");
+ put("̰u", "ṵ");
+ put("̭U", "Ṷ");
+ put("̭u", "ṷ");
+ put("́Ũ", "Ṹ");
+ put("́ ̃U", "Ṹ");
+ put("́ũ", "ṹ");
+ put("́ ̃u", "ṹ");
+ put("̈Ū", "Ṻ");
+ put("̈ ̄U", "Ṻ");
+ put("̈ū", "ṻ");
+ put("̈ ̄u", "ṻ");
+ put("̃V", "Ṽ");
+ put("̃v", "ṽ");
+ put("̣V", "Ṿ");
+ put("̣v", "ṿ");
+ put("̀W", "Ẁ");
+ put("̀w", "ẁ");
+ put("́W", "Ẃ");
+ put("́w", "ẃ");
+ put("̈W", "Ẅ");
+ put("̈w", "ẅ");
+ put("̇W", "Ẇ");
+ put("̇w", "ẇ");
+ put("̣W", "Ẉ");
+ put("̣w", "ẉ");
+ put("̇X", "Ẋ");
+ put("̇x", "ẋ");
+ put("̈X", "Ẍ");
+ put("̈x", "ẍ");
+ put("̇Y", "Ẏ");
+ put("̇y", "ẏ");
+ put("̂Z", "Ẑ");
+ put("̂z", "ẑ");
+ put("̣Z", "Ẓ");
+ put("̣z", "ẓ");
+ put("̱Z", "Ẕ");
+ put("̱z", "ẕ");
+ put("̱h", "ẖ");
+ put("̈t", "ẗ");
+ put("̊w", "ẘ");
+ put("̊y", "ẙ");
+ put("̇ſ", "ẛ");
+ put("̣A", "Ạ");
+ put("̣a", "ạ");
+ put("̉A", "Ả");
+ put("̉a", "ả");
+ put("́Â", "Ấ");
+ put("́ ̂A", "Ấ");
+ put("́â", "ấ");
+ put("́ ̂a", "ấ");
+ put("̀Â", "Ầ");
+ put("̀ ̂A", "Ầ");
+ put("̀â", "ầ");
+ put("̀ ̂a", "ầ");
+ put("̉Â", "Ẩ");
+ put("̉ ̂A", "Ẩ");
+ put("̉â", "ẩ");
+ put("̉ ̂a", "ẩ");
+ put("̃Â", "Ẫ");
+ put("̃ ̂A", "Ẫ");
+ put("̃â", "ẫ");
+ put("̃ ̂a", "ẫ");
+ put("̂Ạ", "Ậ");
+ put("̣̂A", "Ậ");
+ put("̣Â", "Ậ");
+ put("̂ạ", "ậ");
+ put("̣̂a", "ậ");
+ put("̣â", "ậ");
+ put("́Ă", "Ắ");
+ put("́̆A", "Ắ");
+ put("́ă", "ắ");
+ put("́̆a", "ắ");
+ put("̀Ă", "Ằ");
+ put("̀̆A", "Ằ");
+ put("̀ă", "ằ");
+ put("̀̆a", "ằ");
+ put("̉Ă", "Ẳ");
+ put("̉̆A", "Ẳ");
+ put("̉ă", "ẳ");
+ put("̉̆a", "ẳ");
+ put("̃Ă", "Ẵ");
+ put("̃̆A", "Ẵ");
+ put("̃ă", "ẵ");
+ put("̃̆a", "ẵ");
+ put("̆Ạ", "Ặ");
+ put("̣̆A", "Ặ");
+ put("̣Ă", "Ặ");
+ put("̆ạ", "ặ");
+ put("̣̆a", "ặ");
+ put("̣ă", "ặ");
+ put("̣E", "Ẹ");
+ put("̣e", "ẹ");
+ put("̉E", "Ẻ");
+ put("̉e", "ẻ");
+ put("̃E", "Ẽ");
+ put("̃e", "ẽ");
+ put("́Ê", "Ế");
+ put("́ ̂E", "Ế");
+ put("́ê", "ế");
+ put("́ ̂e", "ế");
+ put("̀Ê", "Ề");
+ put("̀ ̂E", "Ề");
+ put("̀ê", "ề");
+ put("̀ ̂e", "ề");
+ put("̉Ê", "Ể");
+ put("̉ ̂E", "Ể");
+ put("̉ê", "ể");
+ put("̉ ̂e", "ể");
+ put("̃Ê", "Ễ");
+ put("̃ ̂E", "Ễ");
+ put("̃ê", "ễ");
+ put("̃ ̂e", "ễ");
+ put("̂Ẹ", "Ệ");
+ put("̣̂E", "Ệ");
+ put("̣Ê", "Ệ");
+ put("̂ẹ", "ệ");
+ put("̣̂e", "ệ");
+ put("̣ê", "ệ");
+ put("̉I", "Ỉ");
+ put("̉i", "ỉ");
+ put("̣I", "Ị");
+ put("̣i", "ị");
+ put("̣O", "Ọ");
+ put("̣o", "ọ");
+ put("̉O", "Ỏ");
+ put("̉o", "ỏ");
+ put("́Ô", "Ố");
+ put("́ ̂O", "Ố");
+ put("́ô", "ố");
+ put("́ ̂o", "ố");
+ put("̀Ô", "Ồ");
+ put("̀ ̂O", "Ồ");
+ put("̀ô", "ồ");
+ put("̀ ̂o", "ồ");
+ put("̉Ô", "Ổ");
+ put("̉ ̂O", "Ổ");
+ put("̉ô", "ổ");
+ put("̉ ̂o", "ổ");
+ put("̃Ô", "Ỗ");
+ put("̃ ̂O", "Ỗ");
+ put("̃ô", "ỗ");
+ put("̃ ̂o", "ỗ");
+ put("̂Ọ", "Ộ");
+ put("̣̂O", "Ộ");
+ put("̣Ô", "Ộ");
+ put("̂ọ", "ộ");
+ put("̣̂o", "ộ");
+ put("̣ô", "ộ");
+ put("́Ơ", "Ớ");
+ put("̛́O", "Ớ");
+ put("́ơ", "ớ");
+ put("̛́o", "ớ");
+ put("̀Ơ", "Ờ");
+ put("̛̀O", "Ờ");
+ put("̀ơ", "ờ");
+ put("̛̀o", "ờ");
+ put("̉Ơ", "Ở");
+ put("̛̉O", "Ở");
+ put("̉ơ", "ở");
+ put("̛̉o", "ở");
+ put("̃Ơ", "Ỡ");
+ put("̛̃O", "Ỡ");
+ put("̃ơ", "ỡ");
+ put("̛̃o", "ỡ");
+ put("̣Ơ", "Ợ");
+ put("̛̣O", "Ợ");
+ put("̣ơ", "ợ");
+ put("̛̣o", "ợ");
+ put("̣U", "Ụ");
+ put("̣u", "ụ");
+ put("̉U", "Ủ");
+ put("̉u", "ủ");
+ put("́Ư", "Ứ");
+ put("̛́U", "Ứ");
+ put("́ư", "ứ");
+ put("̛́u", "ứ");
+ put("̀Ư", "Ừ");
+ put("̛̀U", "Ừ");
+ put("̀ư", "ừ");
+ put("̛̀u", "ừ");
+ put("̉Ư", "Ử");
+ put("̛̉U", "Ử");
+ put("̉ư", "ử");
+ put("̛̉u", "ử");
+ put("̃Ư", "Ữ");
+ put("̛̃U", "Ữ");
+ put("̃ư", "ữ");
+ put("̛̃u", "ữ");
+ put("̣Ư", "Ự");
+ put("̛̣U", "Ự");
+ put("̣ư", "ự");
+ put("̛̣u", "ự");
+ put("̀Y", "Ỳ");
+ put("̀y", "ỳ");
+ put("̣Y", "Ỵ");
+ put("̣y", "ỵ");
+ put("̉Y", "Ỷ");
+ put("̉y", "ỷ");
+ put("̃Y", "Ỹ");
+ put("̃y", "ỹ");
+// include?
+ put("̂0", "⁰");
+ put("̂4", "⁴");
+ put("̂5", "⁵");
+ put("̂6", "⁶");
+ put("̂7", "⁷");
+ put("̂8", "⁸");
+ put("̂9", "⁹");
+ put("̂+", "⁺");
+ put("̂−", "⁻");
+ put("̂=", "⁼");
+ put("̂(", "⁽");
+ put("̂)", "⁾");
+ put("̣+", "⨥");
+ put("̰+", "⨦");
+ put("̣-", "⨪");
+ put("̣=", "⩦");
+ put("̤̈=", "⩷");
+ put("̤̈=", "⩷");
+// include end?
+ put("̥|", "⫰");
+ put("̇Ā", "Ǡ");
+ put("̇ā", "ǡ");
+ put("̇j", "ȷ");
+ put("̇L", "Ŀ");
+ put("̇l", "ŀ");
+ put("̇Ō", "Ȱ");
+ put("̇ō", "ȱ");
+ put("́Ṡ", "Ṥ");
+ put("́ṡ", "ṥ");
+ put("́V", "Ǘ");
+ put("́v", "ǘ");
+ put("̣Ṡ", "Ṩ");
+ put("̣ṡ", "ṩ");
+ put("̣̣", "̣");
+ put("̣ ", "̣");
+ put("̆Á", "Ắ");
+ put("̆À", "Ằ");
+ put("̆Ả", "Ẳ");
+ put("̆Ã", "Ẵ");
+ put("̆a", "ắ");
+ put("̆à", "ằ");
+ put("̆ả", "ẳ");
+ put("̆ã", "ẵ");
+// include?
+ put("̌(", "₍");
+ put("̌)", "₎");
+ put("̌+", "₊");
+ put("̌-", "₋");
+ put("̌0", "₀");
+ put("̌1", "₁");
+ put("̌2", "₂");
+ put("̌3", "₃");
+ put("̌4", "₄");
+ put("̌5", "₅");
+ put("̌6", "₆");
+ put("̌7", "₇");
+ put("̌8", "₈");
+ put("̌9", "₉");
+ put("̌=", "₌");
+// include end?
+ put("̌Dz", "Dž");
+ put("̌Ṡ", "Ṧ");
+ put("̌ṡ", "ṧ");
+ put("̌V", "Ǚ");
+ put("̌v", "ǚ");
+ put("̧C", "Ḉ");
+ put("̧c", "ḉ");
+ put("̧¢", "₵");
+ put("̧Ĕ", "Ḝ");
+ put("̧ĕ", "ḝ");
+ put("̂-", "⁻");
+ put("̂Á", "Ấ");
+ put("̂À", "Ầ");
+ put("̂Ả", "Ẩ");
+ put("̂Ã", "Ẫ");
+ put("̂á", "ấ");
+ put("̂à", "ầ");
+ put("̂ả", "ẩ");
+ put("̂ã", "ẫ");
+ put("̂É", "Ế");
+ put("̂È", "Ề");
+ put("̂Ẻ", "Ể");
+ put("̂Ẽ", "Ễ");
+ put("̂é", "ế");
+ put("̂è", "ề");
+ put("̂ẻ", "ể");
+ put("̂ẽ", "ễ");
+ put("̂Ó", "Ố");
+ put("̂Ò", "Ồ");
+ put("̂Ỏ", "Ổ");
+ put("̂Õ", "Ỗ");
+ put("̂ó", "ố");
+ put("̂ò", "ồ");
+ put("̂ỏ", "ổ");
+ put("̂õ", "ỗ");
+ put("̦S", "Ș");
+ put("̦s", "ș");
+ put("̦T", "Ț");
+ put("̦t", "ț");
+ put("̦̦", ",");
+ put("̦ ", ",");
+ put("̈Ā", "Ǟ");
+ put("̈ā", "ǟ");
+ put("̈Í", "Ḯ");
+ put("̈í", "ḯ");
+ put("̈Ō", "Ȫ");
+ put("̈ō", "ȫ");
+ put("̈Ú", "Ǘ");
+ put("̈Ǔ", "Ǚ");
+ put("̈Ù", "Ǜ");
+ put("̈ú", "ǘ");
+ put("̈ǔ", "ǚ");
+ put("̈ù", "ǜ");
+ put("̀V", "Ǜ");
+ put("̀v", "ǜ");
+ put("̉B", "Ɓ");
+ put("̉b", "ɓ");
+ put("̉C", "Ƈ");
+ put("̉c", "ƈ");
+ put("̉D", "Ɗ");
+ put("̉d", "ɗ");
+ put("̉ɖ", "ᶑ");
+ put("̉F", "Ƒ");
+ put("̉f", "ƒ");
+ put("̉G", "Ɠ");
+ put("̉g", "ɠ");
+ put("̉h", "ɦ");
+ put("̉ɟ", "ʄ");
+ put("̉K", "Ƙ");
+ put("̉k", "ƙ");
+ put("̉M", "Ɱ");
+ put("̉m", "ɱ");
+ put("̉N", "Ɲ");
+ put("̉n", "ɲ");
+ put("̉P", "Ƥ");
+ put("̉p", "ƥ");
+ put("̉q", "ʠ");
+ put("̉ɜ", "ɝ");
+ put("̉s", "ʂ");
+ put("̉ə", "ɚ");
+ put("̉T", "Ƭ");
+ put("̉t", "ƭ");
+ put("̉ɹ", "ɻ");
+ put("̉V", "Ʋ");
+ put("̉v", "ʋ");
+ put("̉W", "Ⱳ");
+ put("̉w", "ⱳ");
+ put("̉Z", "Ȥ");
+ put("̉z", "ȥ");
+ put("̉̉", "̉");
+ put("̉ ", "̉");
+ put("̛Ó", "Ớ");
+ put("̛O", "Ợ");
+ put("̛Ò", "Ờ");
+ put("̛Ỏ", "Ở");
+ put("̛Õ", "Ỡ");
+ put("̛ó", "ớ");
+ put("̛ọ", "ợ");
+ put("̛ò", "ờ");
+ put("̛ỏ", "ở");
+ put("̛õ", "ỡ");
+ put("̛Ú", "Ứ");
+ put("̛Ụ", "Ự");
+ put("̛Ù", "Ừ");
+ put("̛Ủ", "Ử");
+ put("̛Ũ", "Ữ");
+ put("̛ú", "ứ");
+ put("̛ụ", "ự");
+ put("̛ù", "ừ");
+ put("̛ủ", "ử");
+ put("̛ũ", "ữ");
+ put("̛̛", "̛");
+ put("̛ ", "̛");
+ put("̄É", "Ḗ");
+ put("̄È", "Ḕ");
+ put("̄é", "ḗ");
+ put("̄è", "ḕ");
+ put("̄Ó", "Ṓ");
+ put("̄Ò", "Ṑ");
+ put("̄ó", "ṓ");
+ put("̄ò", "ṑ");
+ put("̄V", "Ǖ");
+ put("̄v", "ǖ");
+ put("̨Ō", "Ǭ");
+ put("̨ō", "ǭ");
+ put("̊Á", "Ǻ");
+ put("̊á", "ǻ");
+ put("̃Ó", "Ṍ");
+ put("̃Ö", "Ṏ");
+ put("̃Ō", "Ȭ");
+ put("̃ó", "ṍ");
+ put("̃ö", "ṏ");
+ put("̃ō", "ȭ");
+ put("̃Ú", "Ṹ");
+ put("̃ú", "ṹ");
+ put("̃=", "≃");
+ put("̃<", "≲");
+ put("̃>", "≳");
+ put("́̇S", "Ṥ");
+ put("́̇s", "ṥ");
+ put("̣̇S", "Ṩ");
+ put("̣̇s", "ṩ");
+ put("̌̇S", "Ṧ");
+ put("̌̇s", "ṧ");
+ put("̇ ̄A", "Ǡ");
+ put("̇ ̄a", "ǡ");
+ put("̇ ̄O", "Ȱ");
+ put("̇ ̄o", "ȱ");
+ put("̆ ́A", "Ắ");
+ put("̆ ́a", "ắ");
+ put("̧ ́C", "Ḉ");
+ put("̧ ́c", "ḉ");
+ put("̂ ́A", "Ấ");
+ put("̂ ́a", "ấ");
+ put("̂ ́E", "Ế");
+ put("̂ ́e", "ế");
+ put("̂ ́O", "Ố");
+ put("̂ ́o", "ố");
+ put("̈ ́I", "Ḯ");
+ put("̈ ́i", "ḯ");
+ put("̈ ́U", "Ǘ");
+ put("̈ ́u", "ǘ");
+ put("̛ ́O", "Ớ");
+ put("̛ ́o", "ớ");
+ put("̛ ́U", "Ứ");
+ put("̛ ́u", "ứ");
+ put("̄ ́E", "Ḗ");
+ put("̄ ́e", "ḗ");
+ put("̄ ́O", "Ṓ");
+ put("̄ ́o", "ṓ");
+ put("̊ ́A", "Ǻ");
+ put("̊ ́a", "ǻ");
+ put("̃ ́O", "Ṍ");
+ put("̃ ́o", "ṍ");
+ put("̃ ́U", "Ṹ");
+ put("̃ ́u", "ṹ");
+ put("̣̆A", "Ặ");
+ put("̣̆a", "ặ");
+ put("̣ ̂A", "Ậ");
+ put("̣ ̂a", "ậ");
+ put("̣ ̂E", "Ệ");
+ put("̣ ̂e", "ệ");
+ put("̣ ̂O", "Ộ");
+ put("̣ ̂o", "ộ");
+ put("̛̣O", "Ợ");
+ put("̛̣o", "ợ");
+ put("̛̣U", "Ự");
+ put("̛̣u", "ự");
+ put("̣ ̄L", "Ḹ");
+ put("̣ ̄l", "ḹ");
+ put("̣ ̄R", "Ṝ");
+ put("̣ ̄r", "ṝ");
+ put("̧̆E", "Ḝ");
+ put("̧̆e", "ḝ");
+ put("̆ ̀A", "Ằ");
+ put("̆ ̀a", "ằ");
+ put("̆̉A", "Ẳ");
+ put("̆̉a", "ẳ");
+ put("̆ ̃A", "Ẵ");
+ put("̆ ̃a", "ẵ");
+ put("̈̌U", "Ǚ");
+ put("̈̌u", "ǚ");
+ put("̂ ̀A", "Ầ");
+ put("̂ ̀a", "ầ");
+ put("̂ ̀E", "Ề");
+ put("̂ ̀e", "ề");
+ put("̂ ̀O", "Ồ");
+ put("̂ ̀o", "ồ");
+ put("̂̉A", "Ẩ");
+ put("̂̉a", "ẩ");
+ put("̂̉E", "Ể");
+ put("̂̉e", "ể");
+ put("̂̉O", "Ổ");
+ put("̂̉o", "ổ");
+ put("̂ ̃A", "Ẫ");
+ put("̂ ̃a", "ẫ");
+ put("̂ ̃E", "Ễ");
+ put("̂ ̃e", "ễ");
+ put("̂ ̃O", "Ỗ");
+ put("̂ ̃o", "ỗ");
+ put("̈ ̀U", "Ǜ");
+ put("̈ ̀u", "ǜ");
+ put("̈ ̄A", "Ǟ");
+ put("̈ ̄a", "ǟ");
+ put("̈ ̄O", "Ȫ");
+ put("̈ ̄o", "ȫ");
+ put("̃̈O", "Ṏ");
+ put("̃̈o", "ṏ");
+ put("̛ ̀O", "Ờ");
+ put("̛ ̀o", "ờ");
+ put("̛ ̀U", "Ừ");
+ put("̛ ̀u", "ừ");
+ put("̄ ̀E", "Ḕ");
+ put("̄ ̀e", "ḕ");
+ put("̄ ̀O", "Ṑ");
+ put("̄ ̀o", "ṑ");
+ put("̛̉O", "Ở");
+ put("̛̉o", "ở");
+ put("̛̉U", "Ử");
+ put("̛̉u", "ử");
+ put("̛ ̃O", "Ỡ");
+ put("̛ ̃o", "ỡ");
+ put("̛ ̃U", "Ữ");
+ put("̛ ̃u", "ữ");
+ put("̨ ̄O", "Ǭ");
+ put("̨ ̄o", "ǭ");
+ put("̃ ̄O", "Ȭ");
+ put("̃ ̄o", "ȭ");
+*/
+ }
+
+ public static String normalize(String input) {
+ String lookup = mMap.get(input);
+ if (lookup != null) return lookup;
+ return Normalizer.normalize(input, Normalizer.Form.NFC);
+ }
+
+ public boolean execute(int code) {
+ String composed = executeToString(code);
+ if (composed != null) {
+ //Log.i(TAG, "composed=" + composed + " len=" + composed.length());
+ if (composed.equals("")) {
+ // Unrecognised - try to use the built-in Java text normalisation
+ int c = composeBuffer.codePointAt(composeBuffer.length() - 1);
+ if (Character.getType(c) != Character.NON_SPACING_MARK) {
+ // Put the combining character(s) at the end, else this won't work
+ composeBuffer.reverse();
+ composed = Normalizer.normalize(composeBuffer.toString(), Normalizer.Form.NFC);
+ if (composed.equals("")) {
+ return true; // incomplete :-)
+ }
+ } else {
+ return true; // there may be multiple combining accents
+ }
+ }
+
+ clear();
+ composeUser.onText(composed);
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/java/src/org/pocketworkstation/pckeyboard/Dictionary.java b/java/src/org/pocketworkstation/pckeyboard/Dictionary.java
new file mode 100644
index 0000000..c92caa2
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/Dictionary.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.pocketworkstation.pckeyboard;
+
+/**
+ * Abstract base class for a dictionary that can do a fuzzy search for words based on a set of key
+ * strokes.
+ */
+abstract public class Dictionary {
+ /**
+ * Whether or not to replicate the typed word in the suggested list, even if it's valid.
+ */
+ protected static final boolean INCLUDE_TYPED_WORD_IF_VALID = false;
+
+ /**
+ * The weight to give to a word if it's length is the same as the number of typed characters.
+ */
+ protected static final int FULL_WORD_FREQ_MULTIPLIER = 2;
+
+ public static enum DataType {
+ UNIGRAM, BIGRAM
+ }
+
+ /**
+ * Interface to be implemented by classes requesting words to be fetched from the dictionary.
+ * @see #getWords(WordComposer, WordCallback)
+ */
+ public interface WordCallback {
+ /**
+ * Adds a word to a list of suggestions. The word is expected to be ordered based on
+ * the provided frequency.
+ * @param word the character array containing the word
+ * @param wordOffset starting offset of the word in the character array
+ * @param wordLength length of valid characters in the character array
+ * @param frequency the frequency of occurence. This is normalized between 1 and 255, but
+ * can exceed those limits
+ * @param dicTypeId of the dictionary where word was from
+ * @param dataType tells type of this data
+ * @return true if the word was added, false if no more words are required
+ */
+ boolean addWord(char[] word, int wordOffset, int wordLength, int frequency, int dicTypeId,
+ DataType dataType);
+ }
+
+ /**
+ * Searches for words in the dictionary that match the characters in the composer. Matched
+ * words are added through the callback object.
+ * @param composer the key sequence to match
+ * @param callback the callback object to send matched words to as possible candidates
+ * @param nextLettersFrequencies array of frequencies of next letters that could follow the
+ * word so far. For instance, "bracke" can be followed by "t", so array['t'] will have
+ * a non-zero value on returning from this method.
+ * Pass in null if you don't want the dictionary to look up next letters.
+ * @see WordCallback#addWord(char[], int, int)
+ */
+ abstract public void getWords(final WordComposer composer, final WordCallback callback,
+ int[] nextLettersFrequencies);
+
+ /**
+ * Searches for pairs in the bigram dictionary that matches the previous word and all the
+ * possible words following are added through the callback object.
+ * @param composer the key sequence to match
+ * @param callback the callback object to send possible word following previous word
+ * @param nextLettersFrequencies array of frequencies of next letters that could follow the
+ * word so far. For instance, "bracke" can be followed by "t", so array['t'] will have
+ * a non-zero value on returning from this method.
+ * Pass in null if you don't want the dictionary to look up next letters.
+ */
+ public void getBigrams(final WordComposer composer, final CharSequence previousWord,
+ final WordCallback callback, int[] nextLettersFrequencies) {
+ // empty base implementation
+ }
+
+ /**
+ * Checks if the given word occurs in the dictionary
+ * @param word the word to search for. The search should be case-insensitive.
+ * @return true if the word exists, false otherwise
+ */
+ abstract public boolean isValidWord(CharSequence word);
+
+ /**
+ * Compares the contents of the character array with the typed word and returns true if they
+ * are the same.
+ * @param word the array of characters that make up the word
+ * @param length the number of valid characters in the character array
+ * @param typedWord the word to compare with
+ * @return true if they are the same, false otherwise.
+ */
+ protected boolean same(final char[] word, final int length, final CharSequence typedWord) {
+ if (typedWord.length() != length) {
+ return false;
+ }
+ for (int i = 0; i < length; i++) {
+ if (word[i] != typedWord.charAt(i)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Override to clean up any resources.
+ */
+ public void close() {
+ }
+}
diff --git a/java/src/org/pocketworkstation/pckeyboard/EditingUtil.java b/java/src/org/pocketworkstation/pckeyboard/EditingUtil.java
new file mode 100644
index 0000000..afa471c
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/EditingUtil.java
@@ -0,0 +1,337 @@
+/*
+ * Copyright (C) 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.pocketworkstation.pckeyboard;
+
+import android.text.TextUtils;
+import android.view.inputmethod.ExtractedText;
+import android.view.inputmethod.ExtractedTextRequest;
+import android.view.inputmethod.InputConnection;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.regex.Pattern;
+
+/**
+ * Utility methods to deal with editing text through an InputConnection.
+ */
+public class EditingUtil {
+ /**
+ * Number of characters we want to look back in order to identify the previous word
+ */
+ private static final int LOOKBACK_CHARACTER_NUM = 15;
+
+ // Cache Method pointers
+ private static boolean sMethodsInitialized;
+ private static Method sMethodGetSelectedText;
+ private static Method sMethodSetComposingRegion;
+
+ private EditingUtil() {};
+
+ /**
+ * Append newText to the text field represented by connection.
+ * The new text becomes selected.
+ */
+ public static void appendText(InputConnection connection, String newText) {
+ if (connection == null) {
+ return;
+ }
+
+ // Commit the composing text
+ connection.finishComposingText();
+
+ // Add a space if the field already has text.
+ CharSequence charBeforeCursor = connection.getTextBeforeCursor(1, 0);
+ if (charBeforeCursor != null
+ && !charBeforeCursor.equals(" ")
+ && (charBeforeCursor.length() > 0)) {
+ newText = " " + newText;
+ }
+
+ connection.setComposingText(newText, 1);
+ }
+
+ private static int getCursorPosition(InputConnection connection) {
+ ExtractedText extracted = connection.getExtractedText(
+ new ExtractedTextRequest(), 0);
+ if (extracted == null) {
+ return -1;
+ }
+ return extracted.startOffset + extracted.selectionStart;
+ }
+
+ /**
+ * @param connection connection to the current text field.
+ * @param sep characters which may separate words
+ * @param range the range object to store the result into
+ * @return the word that surrounds the cursor, including up to one trailing
+ * separator. For example, if the field contains "he|llo world", where |
+ * represents the cursor, then "hello " will be returned.
+ */
+ public static String getWordAtCursor(
+ InputConnection connection, String separators, Range range) {
+ Range r = getWordRangeAtCursor(connection, separators, range);
+ return (r == null) ? null : r.word;
+ }
+
+ /**
+ * Removes the word surrounding the cursor. Parameters are identical to
+ * getWordAtCursor.
+ */
+ public static void deleteWordAtCursor(
+ InputConnection connection, String separators) {
+
+ Range range = getWordRangeAtCursor(connection, separators, null);
+ if (range == null) return;
+
+ connection.finishComposingText();
+ // Move cursor to beginning of word, to avoid crash when cursor is outside
+ // of valid range after deleting text.
+ int newCursor = getCursorPosition(connection) - range.charsBefore;
+ connection.setSelection(newCursor, newCursor);
+ connection.deleteSurroundingText(0, range.charsBefore + range.charsAfter);
+ }
+
+ /**
+ * Represents a range of text, relative to the current cursor position.
+ */
+ public static class Range {
+ /** Characters before selection start */
+ public int charsBefore;
+
+ /**
+ * Characters after selection start, including one trailing word
+ * separator.
+ */
+ public int charsAfter;
+
+ /** The actual characters that make up a word */
+ public String word;
+
+ public Range() {}
+
+ public Range(int charsBefore, int charsAfter, String word) {
+ if (charsBefore < 0 || charsAfter < 0) {
+ throw new IndexOutOfBoundsException();
+ }
+ this.charsBefore = charsBefore;
+ this.charsAfter = charsAfter;
+ this.word = word;
+ }
+ }
+
+ private static Range getWordRangeAtCursor(
+ InputConnection connection, String sep, Range range) {
+ if (connection == null || sep == null) {
+ return null;
+ }
+ CharSequence before = connection.getTextBeforeCursor(1000, 0);
+ CharSequence after = connection.getTextAfterCursor(1000, 0);
+ if (before == null || after == null) {
+ return null;
+ }
+
+ // Find first word separator before the cursor
+ int start = before.length();
+ while (start > 0 && !isWhitespace(before.charAt(start - 1), sep)) start--;
+
+ // Find last word separator after the cursor
+ int end = -1;
+ while (++end < after.length() && !isWhitespace(after.charAt(end), sep));
+
+ int cursor = getCursorPosition(connection);
+ if (start >= 0 && cursor + end <= after.length() + before.length()) {
+ String word = before.toString().substring(start, before.length())
+ + after.toString().substring(0, end);
+
+ Range returnRange = range != null? range : new Range();
+ returnRange.charsBefore = before.length() - start;
+ returnRange.charsAfter = end;
+ returnRange.word = word;
+ return returnRange;
+ }
+
+ return null;
+ }
+
+ private static boolean isWhitespace(int code, String whitespace) {
+ return whitespace.contains(String.valueOf((char) code));
+ }
+
+ private static final Pattern spaceRegex = Pattern.compile("\\s+");
+
+ public static CharSequence getPreviousWord(InputConnection connection,
+ String sentenceSeperators) {
+ //TODO: Should fix this. This could be slow!
+ CharSequence prev = connection.getTextBeforeCursor(LOOKBACK_CHARACTER_NUM, 0);
+ if (prev == null) {
+ return null;
+ }
+ String[] w = spaceRegex.split(prev);
+ if (w.length >= 2 && w[w.length-2].length() > 0) {
+ char lastChar = w[w.length-2].charAt(w[w.length-2].length() -1);
+ if (sentenceSeperators.contains(String.valueOf(lastChar))) {
+ return null;
+ }
+ return w[w.length-2];
+ } else {
+ return null;
+ }
+ }
+
+ public static class SelectedWord {
+ public int start;
+ public int end;
+ public CharSequence word;
+ }
+
+ /**
+ * Takes a character sequence with a single character and checks if the character occurs
+ * in a list of word separators or is empty.
+ * @param singleChar A CharSequence with null, zero or one character
+ * @param wordSeparators A String containing the word separators
+ * @return true if the character is at a word boundary, false otherwise
+ */
+ private static boolean isWordBoundary(CharSequence singleChar, String wordSeparators) {
+ return TextUtils.isEmpty(singleChar) || wordSeparators.contains(singleChar);
+ }
+
+ /**
+ * Checks if the cursor is inside a word or the current selection is a whole word.
+ * @param ic the InputConnection for accessing the text field
+ * @param selStart the start position of the selection within the text field
+ * @param selEnd the end position of the selection within the text field. This could be
+ * the same as selStart, if there's no selection.
+ * @param wordSeparators the word separator characters for the current language
+ * @return an object containing the text and coordinates of the selected/touching word,
+ * null if the selection/cursor is not marking a whole word.
+ */
+ public static SelectedWord getWordAtCursorOrSelection(final InputConnection ic,
+ int selStart, int selEnd, String wordSeparators) {
+ if (selStart == selEnd) {
+ // There is just a cursor, so get the word at the cursor
+ EditingUtil.Range range = new EditingUtil.Range();
+ CharSequence touching = getWordAtCursor(ic, wordSeparators, range);
+ if (!TextUtils.isEmpty(touching)) {
+ SelectedWord selWord = new SelectedWord();
+ selWord.word = touching;
+ selWord.start = selStart - range.charsBefore;
+ selWord.end = selEnd + range.charsAfter;
+ return selWord;
+ }
+ } else {
+ // Is the previous character empty or a word separator? If not, return null.
+ CharSequence charsBefore = ic.getTextBeforeCursor(1, 0);
+ if (!isWordBoundary(charsBefore, wordSeparators)) {
+ return null;
+ }
+
+ // Is the next character empty or a word separator? If not, return null.
+ CharSequence charsAfter = ic.getTextAfterCursor(1, 0);
+ if (!isWordBoundary(charsAfter, wordSeparators)) {
+ return null;
+ }
+
+ // Extract the selection alone
+ CharSequence touching = getSelectedText(ic, selStart, selEnd);
+ if (TextUtils.isEmpty(touching)) return null;
+ // Is any part of the selection a separator? If so, return null.
+ final int length = touching.length();
+ for (int i = 0; i < length; i++) {
+ if (wordSeparators.contains(touching.subSequence(i, i + 1))) {
+ return null;
+ }
+ }
+ // Prepare the selected word
+ SelectedWord selWord = new SelectedWord();
+ selWord.start = selStart;
+ selWord.end = selEnd;
+ selWord.word = touching;
+ return selWord;
+ }
+ return null;
+ }
+
+ /**
+ * Cache method pointers for performance
+ */
+ private static void initializeMethodsForReflection() {
+ try {
+ // These will either both exist or not, so no need for separate try/catch blocks.
+ // If other methods are added later, use separate try/catch blocks.
+ sMethodGetSelectedText = InputConnection.class.getMethod("getSelectedText", int.class);
+ sMethodSetComposingRegion = InputConnection.class.getMethod("setComposingRegion",
+ int.class, int.class);
+ } catch (NoSuchMethodException exc) {
+ // Ignore
+ }
+ sMethodsInitialized = true;
+ }
+
+ /**
+ * Returns the selected text between the selStart and selEnd positions.
+ */
+ private static CharSequence getSelectedText(InputConnection ic, int selStart, int selEnd) {
+ // Use reflection, for backward compatibility
+ CharSequence result = null;
+ if (!sMethodsInitialized) {
+ initializeMethodsForReflection();
+ }
+ if (sMethodGetSelectedText != null) {
+ try {
+ result = (CharSequence) sMethodGetSelectedText.invoke(ic, 0);
+ return result;
+ } catch (InvocationTargetException exc) {
+ // Ignore
+ } catch (IllegalArgumentException e) {
+ // Ignore
+ } catch (IllegalAccessException e) {
+ // Ignore
+ }
+ }
+ // Reflection didn't work, try it the poor way, by moving the cursor to the start,
+ // getting the text after the cursor and moving the text back to selected mode.
+ // TODO: Verify that this works properly in conjunction with
+ // LatinIME#onUpdateSelection
+ ic.setSelection(selStart, selEnd);
+ result = ic.getTextAfterCursor(selEnd - selStart, 0);
+ ic.setSelection(selStart, selEnd);
+ return result;
+ }
+
+ /**
+ * Tries to set the text into composition mode if there is support for it in the framework.
+ */
+ public static void underlineWord(InputConnection ic, SelectedWord word) {
+ // Use reflection, for backward compatibility
+ // If method not found, there's nothing we can do. It still works but just wont underline
+ // the word.
+ if (!sMethodsInitialized) {
+ initializeMethodsForReflection();
+ }
+ if (sMethodSetComposingRegion != null) {
+ try {
+ sMethodSetComposingRegion.invoke(ic, word.start, word.end);
+ } catch (InvocationTargetException exc) {
+ // Ignore
+ } catch (IllegalArgumentException e) {
+ // Ignore
+ } catch (IllegalAccessException e) {
+ // Ignore
+ }
+ }
+ }
+}
diff --git a/java/src/org/pocketworkstation/pckeyboard/ExpandableDictionary.java b/java/src/org/pocketworkstation/pckeyboard/ExpandableDictionary.java
new file mode 100644
index 0000000..f329a0e
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/ExpandableDictionary.java
@@ -0,0 +1,691 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.pocketworkstation.pckeyboard;
+
+import java.util.LinkedList;
+
+import android.content.Context;
+import android.os.AsyncTask;
+
+/**
+ * Base class for an in-memory dictionary that can grow dynamically and can
+ * be searched for suggestions and valid words.
+ */
+public class ExpandableDictionary extends Dictionary {
+ /**
+ * There is difference between what java and native code can handle.
+ * It uses 32 because Java stack overflows when greater value is used.
+ */
+ protected static final int MAX_WORD_LENGTH = 32;
+
+ private Context mContext;
+ private char[] mWordBuilder = new char[MAX_WORD_LENGTH];
+ private int mDicTypeId;
+ private int mMaxDepth;
+ private int mInputLength;
+ private int[] mNextLettersFrequencies;
+ private StringBuilder sb = new StringBuilder(MAX_WORD_LENGTH);
+
+ private static final char QUOTE = '\'';
+
+ private boolean mRequiresReload;
+
+ private boolean mUpdatingDictionary;
+
+ // Use this lock before touching mUpdatingDictionary & mRequiresDownload
+ private Object mUpdatingLock = new Object();
+
+ static class Node {
+ char code;
+ int frequency;
+ boolean terminal;
+ Node parent;
+ NodeArray children;
+ LinkedList<NextWord> ngrams; // Supports ngram
+ }
+
+ static class NodeArray {
+ Node[] data;
+ int length = 0;
+ private static final int INCREMENT = 2;
+
+ NodeArray() {
+ data = new Node[INCREMENT];
+ }
+
+ void add(Node n) {
+ if (length + 1 > data.length) {
+ Node[] tempData = new Node[length + INCREMENT];
+ if (length > 0) {
+ System.arraycopy(data, 0, tempData, 0, length);
+ }
+ data = tempData;
+ }
+ data[length++] = n;
+ }
+ }
+
+ static class NextWord {
+ Node word;
+ NextWord nextWord;
+ int frequency;
+
+ NextWord(Node word, int frequency) {
+ this.word = word;
+ this.frequency = frequency;
+ }
+ }
+
+
+ private NodeArray mRoots;
+
+ private int[][] mCodes;
+
+ ExpandableDictionary(Context context, int dicTypeId) {
+ mContext = context;
+ clearDictionary();
+ mCodes = new int[MAX_WORD_LENGTH][];
+ mDicTypeId = dicTypeId;
+ }
+
+ public void loadDictionary() {
+ synchronized (mUpdatingLock) {
+ startDictionaryLoadingTaskLocked();
+ }
+ }
+
+ public void startDictionaryLoadingTaskLocked() {
+ if (!mUpdatingDictionary) {
+ mUpdatingDictionary = true;
+ mRequiresReload = false;
+ new LoadDictionaryTask().execute();
+ }
+ }
+
+ public void setRequiresReload(boolean reload) {
+ synchronized (mUpdatingLock) {
+ mRequiresReload = reload;
+ }
+ }
+
+ public boolean getRequiresReload() {
+ return mRequiresReload;
+ }
+
+ /** Override to load your dictionary here, on a background thread. */
+ public void loadDictionaryAsync() {
+ }
+
+ Context getContext() {
+ return mContext;
+ }
+
+ int getMaxWordLength() {
+ return MAX_WORD_LENGTH;
+ }
+
+ public void addWord(String word, int frequency) {
+ addWordRec(mRoots, word, 0, frequency, null);
+ }
+
+ private void addWordRec(NodeArray children, final String word, final int depth,
+ final int frequency, Node parentNode) {
+ final int wordLength = word.length();
+ final char c = word.charAt(depth);
+ // Does children have the current character?
+ final int childrenLength = children.length;
+ Node childNode = null;
+ boolean found = false;
+ for (int i = 0; i < childrenLength; i++) {
+ childNode = children.data[i];
+ if (childNode.code == c) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ childNode = new Node();
+ childNode.code = c;
+ childNode.parent = parentNode;
+ children.add(childNode);
+ }
+ if (wordLength == depth + 1) {
+ // Terminate this word
+ childNode.terminal = true;
+ childNode.frequency = Math.max(frequency, childNode.frequency);
+ if (childNode.frequency > 255) childNode.frequency = 255;
+ return;
+ }
+ if (childNode.children == null) {
+ childNode.children = new NodeArray();
+ }
+ addWordRec(childNode.children, word, depth + 1, frequency, childNode);
+ }
+
+ @Override
+ public void getWords(final WordComposer codes, final WordCallback callback,
+ int[] nextLettersFrequencies) {
+ synchronized (mUpdatingLock) {
+ // If we need to update, start off a background task
+ if (mRequiresReload) startDictionaryLoadingTaskLocked();
+ // Currently updating contacts, don't return any results.
+ if (mUpdatingDictionary) return;
+ }
+
+ mInputLength = codes.size();
+ mNextLettersFrequencies = nextLettersFrequencies;
+ if (mCodes.length < mInputLength) mCodes = new int[mInputLength][];
+ // Cache the codes so that we don't have to lookup an array list
+ for (int i = 0; i < mInputLength; i++) {
+ mCodes[i] = codes.getCodesAt(i);
+ }
+ mMaxDepth = mInputLength * 3;
+ getWordsRec(mRoots, codes, mWordBuilder, 0, false, 1, 0, -1, callback);
+ for (int i = 0; i < mInputLength; i++) {
+ getWordsRec(mRoots, codes, mWordBuilder, 0, false, 1, 0, i, callback);
+ }
+ }
+
+ @Override
+ public synchronized boolean isValidWord(CharSequence word) {
+ synchronized (mUpdatingLock) {
+ // If we need to update, start off a background task
+ if (mRequiresReload) startDictionaryLoadingTaskLocked();
+ if (mUpdatingDictionary) return false;
+ }
+ final int freq = getWordFrequency(word);
+ return freq > -1;
+ }
+
+ /**
+ * Returns the word's frequency or -1 if not found
+ */
+ public int getWordFrequency(CharSequence word) {
+ Node node = searchNode(mRoots, word, 0, word.length());
+ return (node == null) ? -1 : node.frequency;
+ }
+
+ /**
+ * Recursively traverse the tree for words that match the input. Input consists of
+ * a list of arrays. Each item in the list is one input character position. An input
+ * character is actually an array of multiple possible candidates. This function is not
+ * optimized for speed, assuming that the user dictionary will only be a few hundred words in
+ * size.
+ * @param roots node whose children have to be search for matches
+ * @param codes the input character codes
+ * @param word the word being composed as a possible match
+ * @param depth the depth of traversal - the length of the word being composed thus far
+ * @param completion whether the traversal is now in completion mode - meaning that we've
+ * exhausted the input and we're looking for all possible suffixes.
+ * @param snr current weight of the word being formed
+ * @param inputIndex position in the input characters. This can be off from the depth in
+ * case we skip over some punctuations such as apostrophe in the traversal. That is, if you type
+ * "wouldve", it could be matching "would've", so the depth will be one more than the
+ * inputIndex
+ * @param callback the callback class for adding a word
+ */
+ protected void getWordsRec(NodeArray roots, final WordComposer codes, final char[] word,
+ final int depth, boolean completion, int snr, int inputIndex, int skipPos,
+ WordCallback callback) {
+ final int count = roots.length;
+ final int codeSize = mInputLength;
+ // Optimization: Prune out words that are too long compared to how much was typed.
+ if (depth > mMaxDepth) {
+ return;
+ }
+ int[] currentChars = null;
+ if (codeSize <= inputIndex) {
+ completion = true;
+ } else {
+ currentChars = mCodes[inputIndex];
+ }
+
+ for (int i = 0; i < count; i++) {
+ final Node node = roots.data[i];
+ final char c = node.code;
+ final char lowerC = toLowerCase(c);
+ final boolean terminal = node.terminal;
+ final NodeArray children = node.children;
+ final int freq = node.frequency;
+ if (completion) {
+ word[depth] = c;
+ if (terminal) {
+ if (!callback.addWord(word, 0, depth + 1, freq * snr, mDicTypeId,
+ DataType.UNIGRAM)) {
+ return;
+ }
+ // Add to frequency of next letters for predictive correction
+ if (mNextLettersFrequencies != null && depth >= inputIndex && skipPos < 0
+ && mNextLettersFrequencies.length > word[inputIndex]) {
+ mNextLettersFrequencies[word[inputIndex]]++;
+ }
+ }
+ if (children != null) {
+ getWordsRec(children, codes, word, depth + 1, completion, snr, inputIndex,
+ skipPos, callback);
+ }
+ } else if ((c == QUOTE && currentChars[0] != QUOTE) || depth == skipPos) {
+ // Skip the ' and continue deeper
+ word[depth] = c;
+ if (children != null) {
+ getWordsRec(children, codes, word, depth + 1, completion, snr, inputIndex,
+ skipPos, callback);
+ }
+ } else {
+ // Don't use alternatives if we're looking for missing characters
+ final int alternativesSize = skipPos >= 0? 1 : currentChars.length;
+ for (int j = 0; j < alternativesSize; j++) {
+ final int addedAttenuation = (j > 0 ? 1 : 2);
+ final int currentChar = currentChars[j];
+ if (currentChar == -1) {
+ break;
+ }
+ if (currentChar == lowerC || currentChar == c) {
+ word[depth] = c;
+
+ if (codeSize == inputIndex + 1) {
+ if (terminal) {
+ if (INCLUDE_TYPED_WORD_IF_VALID
+ || !same(word, depth + 1, codes.getTypedWord())) {
+ int finalFreq = freq * snr * addedAttenuation;
+ if (skipPos < 0) finalFreq *= FULL_WORD_FREQ_MULTIPLIER;
+ callback.addWord(word, 0, depth + 1, finalFreq, mDicTypeId,
+ DataType.UNIGRAM);
+ }
+ }
+ if (children != null) {
+ getWordsRec(children, codes, word, depth + 1,
+ true, snr * addedAttenuation, inputIndex + 1,
+ skipPos, callback);
+ }
+ } else if (children != null) {
+ getWordsRec(children, codes, word, depth + 1,
+ false, snr * addedAttenuation, inputIndex + 1,
+ skipPos, callback);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ protected int setBigram(String word1, String word2, int frequency) {
+ return addOrSetBigram(word1, word2, frequency, false);
+ }
+
+ protected int addBigram(String word1, String word2, int frequency) {
+ return addOrSetBigram(word1, word2, frequency, true);
+ }
+
+ /**
+ * Adds bigrams to the in-memory trie structure that is being used to retrieve any word
+ * @param frequency frequency for this bigrams
+ * @param addFrequency if true, it adds to current frequency
+ * @return returns the final frequency
+ */
+ private int addOrSetBigram(String word1, String word2, int frequency, boolean addFrequency) {
+ Node firstWord = searchWord(mRoots, word1, 0, null);
+ Node secondWord = searchWord(mRoots, word2, 0, null);
+ LinkedList<NextWord> bigram = firstWord.ngrams;
+ if (bigram == null || bigram.size() == 0) {
+ firstWord.ngrams = new LinkedList<NextWord>();
+ bigram = firstWord.ngrams;
+ } else {
+ for (NextWord nw : bigram) {
+ if (nw.word == secondWord) {
+ if (addFrequency) {
+ nw.frequency += frequency;
+ } else {
+ nw.frequency = frequency;
+ }
+ return nw.frequency;
+ }
+ }
+ }
+ NextWord nw = new NextWord(secondWord, frequency);
+ firstWord.ngrams.add(nw);
+ return frequency;
+ }
+
+ /**
+ * Searches for the word and add the word if it does not exist.
+ * @return Returns the terminal node of the word we are searching for.
+ */
+ private Node searchWord(NodeArray children, String word, int depth, Node parentNode) {
+ final int wordLength = word.length();
+ final char c = word.charAt(depth);
+ // Does children have the current character?
+ final int childrenLength = children.length;
+ Node childNode = null;
+ boolean found = false;
+ for (int i = 0; i < childrenLength; i++) {
+ childNode = children.data[i];
+ if (childNode.code == c) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ childNode = new Node();
+ childNode.code = c;
+ childNode.parent = parentNode;
+ children.add(childNode);
+ }
+ if (wordLength == depth + 1) {
+ // Terminate this word
+ childNode.terminal = true;
+ return childNode;
+ }
+ if (childNode.children == null) {
+ childNode.children = new NodeArray();
+ }
+ return searchWord(childNode.children, word, depth + 1, childNode);
+ }
+
+ // @VisibleForTesting
+ boolean reloadDictionaryIfRequired() {
+ synchronized (mUpdatingLock) {
+ // If we need to update, start off a background task
+ if (mRequiresReload) startDictionaryLoadingTaskLocked();
+ // Currently updating contacts, don't return any results.
+ return mUpdatingDictionary;
+ }
+ }
+
+ private void runReverseLookUp(final CharSequence previousWord, final WordCallback callback) {
+ Node prevWord = searchNode(mRoots, previousWord, 0, previousWord.length());
+ if (prevWord != null && prevWord.ngrams != null) {
+ reverseLookUp(prevWord.ngrams, callback);
+ }
+ }
+
+ @Override
+ public void getBigrams(final WordComposer codes, final CharSequence previousWord,
+ final WordCallback callback, int[] nextLettersFrequencies) {
+ if (!reloadDictionaryIfRequired()) {
+ runReverseLookUp(previousWord, callback);
+ }
+ }
+
+ /**
+ * Used only for testing purposes
+ * This function will wait for loading from database to be done
+ */
+ void waitForDictionaryLoading() {
+ while (mUpdatingDictionary) {
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+
+ /**
+ * reverseLookUp retrieves the full word given a list of terminal nodes and adds those words
+ * through callback.
+ * @param terminalNodes list of terminal nodes we want to add
+ */
+ private void reverseLookUp(LinkedList<NextWord> terminalNodes,
+ final WordCallback callback) {
+ Node node;
+ int freq;
+ for (NextWord nextWord : terminalNodes) {
+ node = nextWord.word;
+ freq = nextWord.frequency;
+ // TODO Not the best way to limit suggestion threshold
+ if (freq >= UserBigramDictionary.SUGGEST_THRESHOLD) {
+ sb.setLength(0);
+ do {
+ sb.insert(0, node.code);
+ node = node.parent;
+ } while(node != null);
+
+ // TODO better way to feed char array?
+ callback.addWord(sb.toString().toCharArray(), 0, sb.length(), freq, mDicTypeId,
+ DataType.BIGRAM);
+ }
+ }
+ }
+
+ /**
+ * Search for the terminal node of the word
+ * @return Returns the terminal node of the word if the word exists
+ */
+ private Node searchNode(final NodeArray children, final CharSequence word, final int offset,
+ final int length) {
+ // TODO Consider combining with addWordRec
+ final int count = children.length;
+ char currentChar = word.charAt(offset);
+ for (int j = 0; j < count; j++) {
+ final Node node = children.data[j];
+ if (node.code == currentChar) {
+ if (offset == length - 1) {
+ if (node.terminal) {
+ return node;
+ }
+ } else {
+ if (node.children != null) {
+ Node returnNode = searchNode(node.children, word, offset + 1, length);
+ if (returnNode != null) return returnNode;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ protected void clearDictionary() {
+ mRoots = new NodeArray();
+ }
+
+ private class LoadDictionaryTask extends AsyncTask<Void, Void, Void> {
+ @Override
+ protected Void doInBackground(Void... v) {
+ loadDictionaryAsync();
+ synchronized (mUpdatingLock) {
+ mUpdatingDictionary = false;
+ }
+ return null;
+ }
+ }
+
+ static char toLowerCase(char c) {
+ if (c < BASE_CHARS.length) {
+ c = BASE_CHARS[c];
+ }
+ if (c >= 'A' && c <= 'Z') {
+ c = (char) (c | 32);
+ } else if (c > 127) {
+ c = Character.toLowerCase(c);
+ }
+ return c;
+ }
+
+ /**
+ * Table mapping most combined Latin, Greek, and Cyrillic characters
+ * to their base characters. If c is in range, BASE_CHARS[c] == c
+ * if c is not a combined character, or the base character if it
+ * is combined.
+ */
+ static final char BASE_CHARS[] = {
+ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
+ 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
+ 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
+ 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
+ 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
+ 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
+ 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
+ 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
+ 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
+ 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
+ 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
+ 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
+ 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
+ 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
+ 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
+ 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f,
+ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
+ 0x0020, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7,
+ 0x0020, 0x00a9, 0x0061, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x0020,
+ 0x00b0, 0x00b1, 0x0032, 0x0033, 0x0020, 0x03bc, 0x00b6, 0x00b7,
+ 0x0020, 0x0031, 0x006f, 0x00bb, 0x0031, 0x0031, 0x0033, 0x00bf,
+ 0x0041, 0x0041, 0x0041, 0x0041, 0x0041, 0x0041, 0x00c6, 0x0043,
+ 0x0045, 0x0045, 0x0045, 0x0045, 0x0049, 0x0049, 0x0049, 0x0049,
+ 0x00d0, 0x004e, 0x004f, 0x004f, 0x004f, 0x004f, 0x004f, 0x00d7,
+ 0x004f, 0x0055, 0x0055, 0x0055, 0x0055, 0x0059, 0x00de, 0x0073, // Manually changed d8 to 4f
+ // Manually changed df to 73
+ 0x0061, 0x0061, 0x0061, 0x0061, 0x0061, 0x0061, 0x00e6, 0x0063,
+ 0x0065, 0x0065, 0x0065, 0x0065, 0x0069, 0x0069, 0x0069, 0x0069,
+ 0x00f0, 0x006e, 0x006f, 0x006f, 0x006f, 0x006f, 0x006f, 0x00f7,
+ 0x006f, 0x0075, 0x0075, 0x0075, 0x0075, 0x0079, 0x00fe, 0x0079, // Manually changed f8 to 6f
+ 0x0041, 0x0061, 0x0041, 0x0061, 0x0041, 0x0061, 0x0043, 0x0063,
+ 0x0043, 0x0063, 0x0043, 0x0063, 0x0043, 0x0063, 0x0044, 0x0064,
+ 0x0110, 0x0111, 0x0045, 0x0065, 0x0045, 0x0065, 0x0045, 0x0065,
+ 0x0045, 0x0065, 0x0045, 0x0065, 0x0047, 0x0067, 0x0047, 0x0067,
+ 0x0047, 0x0067, 0x0047, 0x0067, 0x0048, 0x0068, 0x0126, 0x0127,
+ 0x0049, 0x0069, 0x0049, 0x0069, 0x0049, 0x0069, 0x0049, 0x0069,
+ 0x0049, 0x0131, 0x0049, 0x0069, 0x004a, 0x006a, 0x004b, 0x006b,
+ 0x0138, 0x004c, 0x006c, 0x004c, 0x006c, 0x004c, 0x006c, 0x004c,
+ 0x006c, 0x0141, 0x0142, 0x004e, 0x006e, 0x004e, 0x006e, 0x004e,
+ 0x006e, 0x02bc, 0x014a, 0x014b, 0x004f, 0x006f, 0x004f, 0x006f,
+ 0x004f, 0x006f, 0x0152, 0x0153, 0x0052, 0x0072, 0x0052, 0x0072,
+ 0x0052, 0x0072, 0x0053, 0x0073, 0x0053, 0x0073, 0x0053, 0x0073,
+ 0x0053, 0x0073, 0x0054, 0x0074, 0x0054, 0x0074, 0x0166, 0x0167,
+ 0x0055, 0x0075, 0x0055, 0x0075, 0x0055, 0x0075, 0x0055, 0x0075,
+ 0x0055, 0x0075, 0x0055, 0x0075, 0x0057, 0x0077, 0x0059, 0x0079,
+ 0x0059, 0x005a, 0x007a, 0x005a, 0x007a, 0x005a, 0x007a, 0x0073,
+ 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185, 0x0186, 0x0187,
+ 0x0188, 0x0189, 0x018a, 0x018b, 0x018c, 0x018d, 0x018e, 0x018f,
+ 0x0190, 0x0191, 0x0192, 0x0193, 0x0194, 0x0195, 0x0196, 0x0197,
+ 0x0198, 0x0199, 0x019a, 0x019b, 0x019c, 0x019d, 0x019e, 0x019f,
+ 0x004f, 0x006f, 0x01a2, 0x01a3, 0x01a4, 0x01a5, 0x01a6, 0x01a7,
+ 0x01a8, 0x01a9, 0x01aa, 0x01ab, 0x01ac, 0x01ad, 0x01ae, 0x0055,
+ 0x0075, 0x01b1, 0x01b2, 0x01b3, 0x01b4, 0x01b5, 0x01b6, 0x01b7,
+ 0x01b8, 0x01b9, 0x01ba, 0x01bb, 0x01bc, 0x01bd, 0x01be, 0x01bf,
+ 0x01c0, 0x01c1, 0x01c2, 0x01c3, 0x0044, 0x0044, 0x0064, 0x004c,
+ 0x004c, 0x006c, 0x004e, 0x004e, 0x006e, 0x0041, 0x0061, 0x0049,
+ 0x0069, 0x004f, 0x006f, 0x0055, 0x0075, 0x00dc, 0x00fc, 0x00dc,
+ 0x00fc, 0x00dc, 0x00fc, 0x00dc, 0x00fc, 0x01dd, 0x00c4, 0x00e4,
+ 0x0226, 0x0227, 0x00c6, 0x00e6, 0x01e4, 0x01e5, 0x0047, 0x0067,
+ 0x004b, 0x006b, 0x004f, 0x006f, 0x01ea, 0x01eb, 0x01b7, 0x0292,
+ 0x006a, 0x0044, 0x0044, 0x0064, 0x0047, 0x0067, 0x01f6, 0x01f7,
+ 0x004e, 0x006e, 0x00c5, 0x00e5, 0x00c6, 0x00e6, 0x00d8, 0x00f8,
+ 0x0041, 0x0061, 0x0041, 0x0061, 0x0045, 0x0065, 0x0045, 0x0065,
+ 0x0049, 0x0069, 0x0049, 0x0069, 0x004f, 0x006f, 0x004f, 0x006f,
+ 0x0052, 0x0072, 0x0052, 0x0072, 0x0055, 0x0075, 0x0055, 0x0075,
+ 0x0053, 0x0073, 0x0054, 0x0074, 0x021c, 0x021d, 0x0048, 0x0068,
+ 0x0220, 0x0221, 0x0222, 0x0223, 0x0224, 0x0225, 0x0041, 0x0061,
+ 0x0045, 0x0065, 0x00d6, 0x00f6, 0x00d5, 0x00f5, 0x004f, 0x006f,
+ 0x022e, 0x022f, 0x0059, 0x0079, 0x0234, 0x0235, 0x0236, 0x0237,
+ 0x0238, 0x0239, 0x023a, 0x023b, 0x023c, 0x023d, 0x023e, 0x023f,
+ 0x0240, 0x0241, 0x0242, 0x0243, 0x0244, 0x0245, 0x0246, 0x0247,
+ 0x0248, 0x0249, 0x024a, 0x024b, 0x024c, 0x024d, 0x024e, 0x024f,
+ 0x0250, 0x0251, 0x0252, 0x0253, 0x0254, 0x0255, 0x0256, 0x0257,
+ 0x0258, 0x0259, 0x025a, 0x025b, 0x025c, 0x025d, 0x025e, 0x025f,
+ 0x0260, 0x0261, 0x0262, 0x0263, 0x0264, 0x0265, 0x0266, 0x0267,
+ 0x0268, 0x0269, 0x026a, 0x026b, 0x026c, 0x026d, 0x026e, 0x026f,
+ 0x0270, 0x0271, 0x0272, 0x0273, 0x0274, 0x0275, 0x0276, 0x0277,
+ 0x0278, 0x0279, 0x027a, 0x027b, 0x027c, 0x027d, 0x027e, 0x027f,
+ 0x0280, 0x0281, 0x0282, 0x0283, 0x0284, 0x0285, 0x0286, 0x0287,
+ 0x0288, 0x0289, 0x028a, 0x028b, 0x028c, 0x028d, 0x028e, 0x028f,
+ 0x0290, 0x0291, 0x0292, 0x0293, 0x0294, 0x0295, 0x0296, 0x0297,
+ 0x0298, 0x0299, 0x029a, 0x029b, 0x029c, 0x029d, 0x029e, 0x029f,
+ 0x02a0, 0x02a1, 0x02a2, 0x02a3, 0x02a4, 0x02a5, 0x02a6, 0x02a7,
+ 0x02a8, 0x02a9, 0x02aa, 0x02ab, 0x02ac, 0x02ad, 0x02ae, 0x02af,
+ 0x0068, 0x0266, 0x006a, 0x0072, 0x0279, 0x027b, 0x0281, 0x0077,
+ 0x0079, 0x02b9, 0x02ba, 0x02bb, 0x02bc, 0x02bd, 0x02be, 0x02bf,
+ 0x02c0, 0x02c1, 0x02c2, 0x02c3, 0x02c4, 0x02c5, 0x02c6, 0x02c7,
+ 0x02c8, 0x02c9, 0x02ca, 0x02cb, 0x02cc, 0x02cd, 0x02ce, 0x02cf,
+ 0x02d0, 0x02d1, 0x02d2, 0x02d3, 0x02d4, 0x02d5, 0x02d6, 0x02d7,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x02de, 0x02df,
+ 0x0263, 0x006c, 0x0073, 0x0078, 0x0295, 0x02e5, 0x02e6, 0x02e7,
+ 0x02e8, 0x02e9, 0x02ea, 0x02eb, 0x02ec, 0x02ed, 0x02ee, 0x02ef,
+ 0x02f0, 0x02f1, 0x02f2, 0x02f3, 0x02f4, 0x02f5, 0x02f6, 0x02f7,
+ 0x02f8, 0x02f9, 0x02fa, 0x02fb, 0x02fc, 0x02fd, 0x02fe, 0x02ff,
+ 0x0300, 0x0301, 0x0302, 0x0303, 0x0304, 0x0305, 0x0306, 0x0307,
+ 0x0308, 0x0309, 0x030a, 0x030b, 0x030c, 0x030d, 0x030e, 0x030f,
+ 0x0310, 0x0311, 0x0312, 0x0313, 0x0314, 0x0315, 0x0316, 0x0317,
+ 0x0318, 0x0319, 0x031a, 0x031b, 0x031c, 0x031d, 0x031e, 0x031f,
+ 0x0320, 0x0321, 0x0322, 0x0323, 0x0324, 0x0325, 0x0326, 0x0327,
+ 0x0328, 0x0329, 0x032a, 0x032b, 0x032c, 0x032d, 0x032e, 0x032f,
+ 0x0330, 0x0331, 0x0332, 0x0333, 0x0334, 0x0335, 0x0336, 0x0337,
+ 0x0338, 0x0339, 0x033a, 0x033b, 0x033c, 0x033d, 0x033e, 0x033f,
+ 0x0300, 0x0301, 0x0342, 0x0313, 0x0308, 0x0345, 0x0346, 0x0347,
+ 0x0348, 0x0349, 0x034a, 0x034b, 0x034c, 0x034d, 0x034e, 0x034f,
+ 0x0350, 0x0351, 0x0352, 0x0353, 0x0354, 0x0355, 0x0356, 0x0357,
+ 0x0358, 0x0359, 0x035a, 0x035b, 0x035c, 0x035d, 0x035e, 0x035f,
+ 0x0360, 0x0361, 0x0362, 0x0363, 0x0364, 0x0365, 0x0366, 0x0367,
+ 0x0368, 0x0369, 0x036a, 0x036b, 0x036c, 0x036d, 0x036e, 0x036f,
+ 0x0370, 0x0371, 0x0372, 0x0373, 0x02b9, 0x0375, 0x0376, 0x0377,
+ 0x0378, 0x0379, 0x0020, 0x037b, 0x037c, 0x037d, 0x003b, 0x037f,
+ 0x0380, 0x0381, 0x0382, 0x0383, 0x0020, 0x00a8, 0x0391, 0x00b7,
+ 0x0395, 0x0397, 0x0399, 0x038b, 0x039f, 0x038d, 0x03a5, 0x03a9,
+ 0x03ca, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
+ 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f,
+ 0x03a0, 0x03a1, 0x03a2, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7,
+ 0x03a8, 0x03a9, 0x0399, 0x03a5, 0x03b1, 0x03b5, 0x03b7, 0x03b9,
+ 0x03cb, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7,
+ 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf,
+ 0x03c0, 0x03c1, 0x03c2, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7,
+ 0x03c8, 0x03c9, 0x03b9, 0x03c5, 0x03bf, 0x03c5, 0x03c9, 0x03cf,
+ 0x03b2, 0x03b8, 0x03a5, 0x03d2, 0x03d2, 0x03c6, 0x03c0, 0x03d7,
+ 0x03d8, 0x03d9, 0x03da, 0x03db, 0x03dc, 0x03dd, 0x03de, 0x03df,
+ 0x03e0, 0x03e1, 0x03e2, 0x03e3, 0x03e4, 0x03e5, 0x03e6, 0x03e7,
+ 0x03e8, 0x03e9, 0x03ea, 0x03eb, 0x03ec, 0x03ed, 0x03ee, 0x03ef,
+ 0x03ba, 0x03c1, 0x03c2, 0x03f3, 0x0398, 0x03b5, 0x03f6, 0x03f7,
+ 0x03f8, 0x03a3, 0x03fa, 0x03fb, 0x03fc, 0x03fd, 0x03fe, 0x03ff,
+ 0x0415, 0x0415, 0x0402, 0x0413, 0x0404, 0x0405, 0x0406, 0x0406,
+ 0x0408, 0x0409, 0x040a, 0x040b, 0x041a, 0x0418, 0x0423, 0x040f,
+ 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
+ 0x0418, 0x0418, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f,
+ 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
+ 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f,
+ 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
+ 0x0438, 0x0438, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f,
+ 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
+ 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f,
+ 0x0435, 0x0435, 0x0452, 0x0433, 0x0454, 0x0455, 0x0456, 0x0456,
+ 0x0458, 0x0459, 0x045a, 0x045b, 0x043a, 0x0438, 0x0443, 0x045f,
+ 0x0460, 0x0461, 0x0462, 0x0463, 0x0464, 0x0465, 0x0466, 0x0467,
+ 0x0468, 0x0469, 0x046a, 0x046b, 0x046c, 0x046d, 0x046e, 0x046f,
+ 0x0470, 0x0471, 0x0472, 0x0473, 0x0474, 0x0475, 0x0474, 0x0475,
+ 0x0478, 0x0479, 0x047a, 0x047b, 0x047c, 0x047d, 0x047e, 0x047f,
+ 0x0480, 0x0481, 0x0482, 0x0483, 0x0484, 0x0485, 0x0486, 0x0487,
+ 0x0488, 0x0489, 0x048a, 0x048b, 0x048c, 0x048d, 0x048e, 0x048f,
+ 0x0490, 0x0491, 0x0492, 0x0493, 0x0494, 0x0495, 0x0496, 0x0497,
+ 0x0498, 0x0499, 0x049a, 0x049b, 0x049c, 0x049d, 0x049e, 0x049f,
+ 0x04a0, 0x04a1, 0x04a2, 0x04a3, 0x04a4, 0x04a5, 0x04a6, 0x04a7,
+ 0x04a8, 0x04a9, 0x04aa, 0x04ab, 0x04ac, 0x04ad, 0x04ae, 0x04af,
+ 0x04b0, 0x04b1, 0x04b2, 0x04b3, 0x04b4, 0x04b5, 0x04b6, 0x04b7,
+ 0x04b8, 0x04b9, 0x04ba, 0x04bb, 0x04bc, 0x04bd, 0x04be, 0x04bf,
+ 0x04c0, 0x0416, 0x0436, 0x04c3, 0x04c4, 0x04c5, 0x04c6, 0x04c7,
+ 0x04c8, 0x04c9, 0x04ca, 0x04cb, 0x04cc, 0x04cd, 0x04ce, 0x04cf,
+ 0x0410, 0x0430, 0x0410, 0x0430, 0x04d4, 0x04d5, 0x0415, 0x0435,
+ 0x04d8, 0x04d9, 0x04d8, 0x04d9, 0x0416, 0x0436, 0x0417, 0x0437,
+ 0x04e0, 0x04e1, 0x0418, 0x0438, 0x0418, 0x0438, 0x041e, 0x043e,
+ 0x04e8, 0x04e9, 0x04e8, 0x04e9, 0x042d, 0x044d, 0x0423, 0x0443,
+ 0x0423, 0x0443, 0x0423, 0x0443, 0x0427, 0x0447, 0x04f6, 0x04f7,
+ 0x042b, 0x044b, 0x04fa, 0x04fb, 0x04fc, 0x04fd, 0x04fe, 0x04ff,
+ };
+
+ // generated with:
+ // cat UnicodeData.txt | perl -e 'while (<>) { @foo = split(/;/); $foo[5] =~ s/<.*> //; $base[hex($foo[0])] = hex($foo[5]);} for ($i = 0; $i < 0x500; $i += 8) { for ($j = $i; $j < $i + 8; $j++) { printf("0x%04x, ", $base[$j] ? $base[$j] : $j)}; print "\n"; }'
+
+}
diff --git a/java/src/org/pocketworkstation/pckeyboard/GlobalKeyboardSettings.java b/java/src/org/pocketworkstation/pckeyboard/GlobalKeyboardSettings.java
new file mode 100644
index 0000000..0786ea1
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/GlobalKeyboardSettings.java
@@ -0,0 +1,266 @@
+package org.pocketworkstation.pckeyboard;
+
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import android.content.SharedPreferences;
+import android.content.res.Resources;
+import android.util.Log;
+
+/**
+ * Global current settings for the keyboard.
+ *
+ * <p>
+ * Yes, globals are evil. But the persisted shared preferences are global data
+ * by definition, and trying to hide this by propagating the current manually
+ * just adds a lot of complication. This is especially annoying due to Views
+ * getting constructed in a way that doesn't support adding additional
+ * constructor arguments, requiring post-construction method calls, which is
+ * error-prone and fragile.
+ *
+ * <p>
+ * The comments below indicate which class is responsible for updating the
+ * value, and for recreating keyboards or views as necessary. Other classes
+ * MUST treat the fields as read-only values, and MUST NOT attempt to save
+ * these values or results derived from them across re-initializations.
+
+ *
+ * @author klaus.weidner@gmail.com
+ */
+public final class GlobalKeyboardSettings {
+ protected static final String TAG = "HK/Globals";
+
+ /* Simple prefs updated by this class */
+ //
+ // Read by Keyboard
+ public int popupKeyboardFlags = 0x1;
+ public float topRowScale = 1.0f;
+ //
+ // Read by LatinKeyboardView
+ public boolean showTouchPos = false;
+ //
+ // Read by LatinIME
+ public String suggestedPunctuation = "!?,.";
+ public int keyboardModePortrait = 0;
+ public int keyboardModeLandscape = 2;
+ public boolean compactModeEnabled = false;
+ public int chordingCtrlKey = 0;
+ public int chordingAltKey = 0;
+ public float keyClickVolume = 0.0f;
+ public int keyClickMethod = 0;
+ public boolean capsLock = true;
+ public boolean shiftLockModifiers = false;
+ //
+ // Read by LatinKeyboardBaseView
+ public float labelScalePref = 1.0f;
+ //
+ // Read by CandidateView
+ public float candidateScalePref = 1.0f;
+ //
+ // Read by PointerTracker
+ public int sendSlideKeys = 0;
+
+ /* Updated by LatinIME */
+ //
+ // Read by KeyboardSwitcher
+ public int keyboardMode = 0;
+ public boolean useExtension = false;
+ //
+ // Read by LatinKeyboardView and KeyboardSwitcher
+ public float keyboardHeightPercent = 40.0f; // percent of screen height
+ //
+ // Read by LatinKeyboardBaseView
+ public int hintMode = 0;
+ public int renderMode = 1;
+ //
+ // Read by PointerTracker
+ public int longpressTimeout = 400;
+ //
+ // Read by LatinIMESettings
+ // These are cached values for informational display, don't use for other purposes
+ public String editorPackageName;
+ public String editorFieldName;
+ public int editorFieldId;
+ public int editorInputType;
+
+ /* Updated by KeyboardSwitcher */
+ //
+ // Used by LatinKeyboardBaseView and LatinIME
+
+ /* Updated by LanguageSwitcher */
+ //
+ // Used by Keyboard and KeyboardSwitcher
+ public Locale inputLocale = Locale.getDefault();
+
+ // Auto pref implementation follows
+ private Map<String, BooleanPref> mBoolPrefs = new HashMap<String, BooleanPref>();
+ private Map<String, StringPref> mStringPrefs = new HashMap<String, StringPref>();
+ public static final int FLAG_PREF_NONE = 0;
+ public static final int FLAG_PREF_NEED_RELOAD = 0x1;
+ public static final int FLAG_PREF_NEW_PUNC_LIST = 0x2;
+ public static final int FLAG_PREF_RECREATE_INPUT_VIEW = 0x4;
+ public static final int FLAG_PREF_RESET_KEYBOARDS = 0x8;
+ public static final int FLAG_PREF_RESET_MODE_OVERRIDE = 0x10;
+ private int mCurrentFlags = 0;
+
+ private interface BooleanPref {
+ void set(boolean val);
+ boolean getDefault();
+ int getFlags();
+ }
+
+ private interface StringPref {
+ void set(String val);
+ String getDefault();
+ int getFlags();
+ }
+
+ public void initPrefs(SharedPreferences prefs, Resources resources) {
+ final Resources res = resources;
+
+ addBooleanPref("pref_compact_mode_enabled", new BooleanPref() {
+ public void set(boolean val) { compactModeEnabled = val; Log.i(TAG, "Setting compactModeEnabled to " + val); }
+ public boolean getDefault() { return res.getBoolean(R.bool.default_compact_mode_enabled); }
+ public int getFlags() { return FLAG_PREF_RESET_MODE_OVERRIDE; }
+ });
+
+ addStringPref("pref_keyboard_mode_portrait", new StringPref() {
+ public void set(String val) { keyboardModePortrait = Integer.valueOf(val); }
+ public String getDefault() { return res.getString(R.string.default_keyboard_mode_portrait); }
+ public int getFlags() { return FLAG_PREF_RESET_KEYBOARDS | FLAG_PREF_RESET_MODE_OVERRIDE; }
+ });
+
+ addStringPref("pref_keyboard_mode_landscape", new StringPref() {
+ public void set(String val) { keyboardModeLandscape = Integer.valueOf(val); }
+ public String getDefault() { return res.getString(R.string.default_keyboard_mode_landscape); }
+ public int getFlags() { return FLAG_PREF_RESET_KEYBOARDS | FLAG_PREF_RESET_MODE_OVERRIDE; }
+ });
+
+ addStringPref("pref_slide_keys_int", new StringPref() {
+ public void set(String val) { sendSlideKeys = Integer.valueOf(val); }
+ public String getDefault() { return "0"; }
+ public int getFlags() { return FLAG_PREF_NONE; }
+ });
+
+ addBooleanPref("pref_touch_pos", new BooleanPref() {
+ public void set(boolean val) { showTouchPos = val; }
+ public boolean getDefault() { return false; }
+ public int getFlags() { return FLAG_PREF_NONE; }
+ });
+
+ addStringPref("pref_popup_content", new StringPref() {
+ public void set(String val) { popupKeyboardFlags = Integer.valueOf(val); }
+ public String getDefault() { return res.getString(R.string.default_popup_content); }
+ public int getFlags() { return FLAG_PREF_RESET_KEYBOARDS; }
+ });
+
+ addStringPref("pref_suggested_punctuation", new StringPref() {
+ public void set(String val) { suggestedPunctuation = val; }
+ public String getDefault() { return res.getString(R.string.suggested_punctuations_default); }
+ public int getFlags() { return FLAG_PREF_NEW_PUNC_LIST; }
+ });
+
+ addStringPref("pref_label_scale", new StringPref() {
+ public void set(String val) { labelScalePref = Float.valueOf(val); }
+ public String getDefault() { return "1.0"; }
+ public int getFlags() { return FLAG_PREF_RECREATE_INPUT_VIEW; }
+ });
+
+ addStringPref("pref_candidate_scale", new StringPref() {
+ public void set(String val) { candidateScalePref = Float.valueOf(val); }
+ public String getDefault() { return "1.0"; }
+ public int getFlags() { return FLAG_PREF_RESET_KEYBOARDS; }
+ });
+
+ addStringPref("pref_top_row_scale", new StringPref() {
+ public void set(String val) { topRowScale = Float.valueOf(val); }
+ public String getDefault() { return "1.0"; }
+ public int getFlags() { return FLAG_PREF_RESET_KEYBOARDS; }
+ });
+
+ addStringPref("pref_chording_ctrl_key", new StringPref() {
+ public void set(String val) { chordingCtrlKey = Integer.valueOf(val); }
+ public String getDefault() { return res.getString(R.string.default_chording_ctrl_key); }
+ public int getFlags() { return FLAG_PREF_RESET_KEYBOARDS; }
+ });
+
+ addStringPref("pref_chording_alt_key", new StringPref() {
+ public void set(String val) { chordingAltKey = Integer.valueOf(val); }
+ public String getDefault() { return res.getString(R.string.default_chording_alt_key); }
+ public int getFlags() { return FLAG_PREF_RESET_KEYBOARDS; }
+ });
+
+ addStringPref("pref_click_volume", new StringPref() {
+ public void set(String val) { keyClickVolume = Float.valueOf(val); }
+ public String getDefault() { return res.getString(R.string.default_click_volume); }
+ public int getFlags() { return FLAG_PREF_NONE; }
+ });
+
+ addStringPref("pref_click_method", new StringPref() {
+ public void set(String val) { keyClickMethod = Integer.valueOf(val); }
+ public String getDefault() { return res.getString(R.string.default_click_method); }
+ public int getFlags() { return FLAG_PREF_NONE; }
+ });
+
+ addBooleanPref("pref_caps_lock", new BooleanPref() {
+ public void set(boolean val) { capsLock = val; }
+ public boolean getDefault() { return res.getBoolean(R.bool.default_caps_lock); }
+ public int getFlags() { return FLAG_PREF_NONE; }
+ });
+
+ addBooleanPref("pref_shift_lock_modifiers", new BooleanPref() {
+ public void set(boolean val) { shiftLockModifiers = val; }
+ public boolean getDefault() { return res.getBoolean(R.bool.default_shift_lock_modifiers); }
+ public int getFlags() { return FLAG_PREF_NONE; }
+ });
+
+ // Set initial values
+ for (String key : mBoolPrefs.keySet()) {
+ BooleanPref pref = mBoolPrefs.get(key);
+ pref.set(prefs.getBoolean(key, pref.getDefault()));
+ }
+ for (String key : mStringPrefs.keySet()) {
+ StringPref pref = mStringPrefs.get(key);
+ pref.set(prefs.getString(key, pref.getDefault()));
+ }
+ }
+
+ public void sharedPreferenceChanged(SharedPreferences prefs, String key) {
+ boolean found = false;
+ mCurrentFlags = FLAG_PREF_NONE;
+ BooleanPref bPref = mBoolPrefs.get(key);
+ if (bPref != null) {
+ found = true;
+ bPref.set(prefs.getBoolean(key, bPref.getDefault()));
+ mCurrentFlags |= bPref.getFlags();
+ }
+ StringPref sPref = mStringPrefs.get(key);
+ if (sPref != null) {
+ found = true;
+ sPref.set(prefs.getString(key, sPref.getDefault()));
+ mCurrentFlags |= sPref.getFlags();
+ }
+ //if (!found) Log.i(TAG, "sharedPreferenceChanged: unhandled key=" + key);
+ }
+
+ public boolean hasFlag(int flag) {
+ if ((mCurrentFlags & flag) != 0) {
+ mCurrentFlags &= ~flag;
+ return true;
+ }
+ return false;
+ }
+
+ public int unhandledFlags() {
+ return mCurrentFlags;
+ }
+
+ private void addBooleanPref(String key, BooleanPref setter) {
+ mBoolPrefs.put(key, setter);
+ }
+
+ private void addStringPref(String key, StringPref setter) {
+ mStringPrefs.put(key, setter);
+ }
+}
diff --git a/java/src/org/pocketworkstation/pckeyboard/Hints.java b/java/src/org/pocketworkstation/pckeyboard/Hints.java
new file mode 100644
index 0000000..f6c2a7f
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/Hints.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.pocketworkstation.pckeyboard;
+
+import com.android.inputmethod.voice.SettingsUtil;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
+import android.view.inputmethod.InputConnection;
+
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Logic to determine when to display hints on usage to the user.
+ */
+public class Hints {
+ public interface Display {
+ public void showHint(int viewResource);
+ }
+
+ private static final String PREF_VOICE_HINT_NUM_UNIQUE_DAYS_SHOWN =
+ "voice_hint_num_unique_days_shown";
+ private static final String PREF_VOICE_HINT_LAST_TIME_SHOWN =
+ "voice_hint_last_time_shown";
+ private static final String PREF_VOICE_INPUT_LAST_TIME_USED =
+ "voice_input_last_time_used";
+ private static final String PREF_VOICE_PUNCTUATION_HINT_VIEW_COUNT =
+ "voice_punctuation_hint_view_count";
+ private static final int DEFAULT_SWIPE_HINT_MAX_DAYS_TO_SHOW = 7;
+ private static final int DEFAULT_PUNCTUATION_HINT_MAX_DISPLAYS = 7;
+
+ private Context mContext;
+ private Display mDisplay;
+ private boolean mVoiceResultContainedPunctuation;
+ private int mSwipeHintMaxDaysToShow;
+ private int mPunctuationHintMaxDisplays;
+
+ // Only show punctuation hint if voice result did not contain punctuation.
+ static final Map<CharSequence, String> SPEAKABLE_PUNCTUATION
+ = new HashMap<CharSequence, String>();
+ static {
+ SPEAKABLE_PUNCTUATION.put(",", "comma");
+ SPEAKABLE_PUNCTUATION.put(".", "period");
+ SPEAKABLE_PUNCTUATION.put("?", "question mark");
+ }
+
+ public Hints(Context context, Display display) {
+ mContext = context;
+ mDisplay = display;
+
+ ContentResolver cr = mContext.getContentResolver();
+ mSwipeHintMaxDaysToShow = SettingsUtil.getSettingsInt(
+ cr,
+ SettingsUtil.LATIN_IME_VOICE_INPUT_SWIPE_HINT_MAX_DAYS,
+ DEFAULT_SWIPE_HINT_MAX_DAYS_TO_SHOW);
+ mPunctuationHintMaxDisplays = SettingsUtil.getSettingsInt(
+ cr,
+ SettingsUtil.LATIN_IME_VOICE_INPUT_PUNCTUATION_HINT_MAX_DISPLAYS,
+ DEFAULT_PUNCTUATION_HINT_MAX_DISPLAYS);
+ }
+
+ public boolean showSwipeHintIfNecessary(boolean fieldRecommended) {
+ if (fieldRecommended && shouldShowSwipeHint()) {
+ showHint(R.layout.voice_swipe_hint);
+ return true;
+ }
+
+ return false;
+ }
+
+ public boolean showPunctuationHintIfNecessary(InputConnection ic) {
+ if (!mVoiceResultContainedPunctuation
+ && ic != null
+ && getAndIncrementPref(PREF_VOICE_PUNCTUATION_HINT_VIEW_COUNT)
+ < mPunctuationHintMaxDisplays) {
+ CharSequence charBeforeCursor = ic.getTextBeforeCursor(1, 0);
+ if (SPEAKABLE_PUNCTUATION.containsKey(charBeforeCursor)) {
+ showHint(R.layout.voice_punctuation_hint);
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public void registerVoiceResult(String text) {
+ // Update the current time as the last time voice input was used.
+ SharedPreferences.Editor editor =
+ PreferenceManager.getDefaultSharedPreferences(mContext).edit();
+ editor.putLong(PREF_VOICE_INPUT_LAST_TIME_USED, System.currentTimeMillis());
+ SharedPreferencesCompat.apply(editor);
+
+ mVoiceResultContainedPunctuation = false;
+ for (CharSequence s : SPEAKABLE_PUNCTUATION.keySet()) {
+ if (text.indexOf(s.toString()) >= 0) {
+ mVoiceResultContainedPunctuation = true;
+ break;
+ }
+ }
+ }
+
+ private boolean shouldShowSwipeHint() {
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
+
+ int numUniqueDaysShown = sp.getInt(PREF_VOICE_HINT_NUM_UNIQUE_DAYS_SHOWN, 0);
+
+ // If we've already shown the hint for enough days, we'll return false.
+ if (numUniqueDaysShown < mSwipeHintMaxDaysToShow) {
+
+ long lastTimeVoiceWasUsed = sp.getLong(PREF_VOICE_INPUT_LAST_TIME_USED, 0);
+
+ // If the user has used voice today, we'll return false. (We don't show the hint on
+ // any day that the user has already used voice.)
+ if (!isFromToday(lastTimeVoiceWasUsed)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Determines whether the provided time is from some time today (i.e., this day, month,
+ * and year).
+ */
+ private boolean isFromToday(long timeInMillis) {
+ if (timeInMillis == 0) return false;
+
+ Calendar today = Calendar.getInstance();
+ today.setTimeInMillis(System.currentTimeMillis());
+
+ Calendar timestamp = Calendar.getInstance();
+ timestamp.setTimeInMillis(timeInMillis);
+
+ return (today.get(Calendar.YEAR) == timestamp.get(Calendar.YEAR) &&
+ today.get(Calendar.DAY_OF_MONTH) == timestamp.get(Calendar.DAY_OF_MONTH) &&
+ today.get(Calendar.MONTH) == timestamp.get(Calendar.MONTH));
+ }
+
+ private void showHint(int hintViewResource) {
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
+
+ int numUniqueDaysShown = sp.getInt(PREF_VOICE_HINT_NUM_UNIQUE_DAYS_SHOWN, 0);
+ long lastTimeHintWasShown = sp.getLong(PREF_VOICE_HINT_LAST_TIME_SHOWN, 0);
+
+ // If this is the first time the hint is being shown today, increase the saved values
+ // to represent that. We don't need to increase the last time the hint was shown unless
+ // it is a different day from the current value.
+ if (!isFromToday(lastTimeHintWasShown)) {
+ SharedPreferences.Editor editor = sp.edit();
+ editor.putInt(PREF_VOICE_HINT_NUM_UNIQUE_DAYS_SHOWN, numUniqueDaysShown + 1);
+ editor.putLong(PREF_VOICE_HINT_LAST_TIME_SHOWN, System.currentTimeMillis());
+ SharedPreferencesCompat.apply(editor);
+ }
+
+ if (mDisplay != null) {
+ mDisplay.showHint(hintViewResource);
+ }
+ }
+
+ private int getAndIncrementPref(String pref) {
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
+ int value = sp.getInt(pref, 0);
+ SharedPreferences.Editor editor = sp.edit();
+ editor.putInt(pref, value + 1);
+ SharedPreferencesCompat.apply(editor);
+ return value;
+ }
+}
diff --git a/java/src/org/pocketworkstation/pckeyboard/InputLanguageSelection.java b/java/src/org/pocketworkstation/pckeyboard/InputLanguageSelection.java
new file mode 100644
index 0000000..ba2f174
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/InputLanguageSelection.java
@@ -0,0 +1,367 @@
+/*
+ * Copyright (C) 2008-2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.pocketworkstation.pckeyboard;
+
+import java.text.Collator;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.preference.CheckBoxPreference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceGroup;
+import android.preference.PreferenceManager;
+import android.text.TextUtils;
+import android.util.Log;
+
+public class InputLanguageSelection extends PreferenceActivity {
+ private static final String TAG = "PCKeyboardILS";
+ private ArrayList<Loc> mAvailableLanguages = new ArrayList<Loc>();
+ private static final String[] BLACKLIST_LANGUAGES = {
+ "ko", "ja", "zh"
+ };
+
+ // Languages for which auto-caps should be disabled
+ public static final Set<String> NOCAPS_LANGUAGES = new HashSet<String>();
+ static {
+ NOCAPS_LANGUAGES.add("ar");
+ NOCAPS_LANGUAGES.add("iw");
+ NOCAPS_LANGUAGES.add("th");
+ }
+
+ // Languages which should not use dead key logic. The modifier is entered after the base character.
+ public static final Set<String> NODEADKEY_LANGUAGES = new HashSet<String>();
+ static {
+ NODEADKEY_LANGUAGES.add("ar");
+ NODEADKEY_LANGUAGES.add("iw"); // TODO: currently no niqqud in the keymap?
+ NODEADKEY_LANGUAGES.add("th");
+ }
+
+ // Languages which should not auto-add space after completions
+ public static final Set<String> NOAUTOSPACE_LANGUAGES = new HashSet<String>();
+ static {
+ NOAUTOSPACE_LANGUAGES.add("th");
+ }
+
+ // Run the GetLanguages.sh script to update the following lists based on
+ // the available keyboard resources and dictionaries.
+ private static final String[] KBD_LOCALIZATIONS = {
+ "ar", "bg", "ca", "cs", "cs_QY", "da", "de", "el", "en", "en_DV",
+ "en_GB", "es", "es_US", "fa", "fi", "fr", "fr_CA", "he", "hr", "hu",
+ "hy", "in", "it", "iw", "ja", "ka", "ko", "lo", "lt", "lv", "nb",
+ "nl", "pl", "pt", "pt_PT", "rm", "ro", "ru", "ru_PH", "si", "sk",
+ "sk_QY", "sl", "sr", "sv", "th", "tl", "tr", "uk", "vi", "zh_CN",
+ "zh_TW"
+ };
+
+ private static final String[] KBD_5_ROW = {
+ "ar", "bg", "cs", "cs_QY", "da", "de", "el", "en", "en_DV", "en_GB",
+ "es", "fa", "fi", "fr", "fr_CA", "he", "hr", "hy", "it", "iw",
+ "lo", "nb", "pt_PT", "ro", "ru", "ru_PH", "si", "sk", "sk_QY",
+ "sl", "sr", "sv", "th", "tr", "uk"
+ };
+
+ private static final String[] KBD_4_ROW = {
+ "ar", "bg", "cs", "cs_QY", "da", "de", "el", "en", "en_DV", "fa",
+ "fr", "fr_CA", "he", "hr", "iw", "nb", "ru", "ru_PH", "sk", "sk_QY",
+ "sl", "sr", "sv", "tr", "uk"
+ };
+
+ private static String getLocaleName(Locale l) {
+ String lang = l.getLanguage();
+ String country = l.getCountry();
+ if (lang.equals("en") && country.equals("DV")) {
+ return "English (Dvorak)";
+ } else if (lang.equals("en") && country.equals("EX")) {
+ return "English (4x11)";
+ } else if (lang.equals("cs") && country.equals("QY")) {
+ return "Čeština (QWERTY)";
+ } else if (lang.equals("sk") && country.equals("QY")) {
+ return "Slovenčina (QWERTY)";
+ } else if (lang.equals("ru") && country.equals("PH")) {
+ return "Русский (Phonetic)";
+ } else {
+ return LanguageSwitcher.toTitleCase(l.getDisplayName(l));
+ }
+ }
+
+ private static class Loc implements Comparable<Object> {
+ static Collator sCollator = Collator.getInstance();
+
+ String label;
+ Locale locale;
+
+ public Loc(String label, Locale locale) {
+ this.label = label;
+ this.locale = locale;
+ }
+
+ @Override
+ public String toString() {
+ return this.label;
+ }
+
+ public int compareTo(Object o) {
+ return sCollator.compare(this.label, ((Loc) o).label);
+ }
+ }
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ addPreferencesFromResource(R.xml.language_prefs);
+ // Get the settings preferences
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
+ String selectedLanguagePref = sp.getString(LatinIME.PREF_SELECTED_LANGUAGES, "");
+ Log.i(TAG, "selected languages: " + selectedLanguagePref);
+ String[] languageList = selectedLanguagePref.split(",");
+
+ mAvailableLanguages = getUniqueLocales();
+
+ // Compatibility hack for v1.22 and older - if a selected language 5-code isn't
+ // found in the current list of available languages, try adding the 2-letter
+ // language code. For example, "en_US" is no longer listed, so use "en" instead.
+ Set<String> availableLanguages = new HashSet<String>();
+ for (int i = 0; i < mAvailableLanguages.size(); i++) {
+ Locale locale = mAvailableLanguages.get(i).locale;
+ availableLanguages.add(get5Code(locale));
+ }
+ Set<String> languageSelections = new HashSet<String>();
+ for (int i = 0; i < languageList.length; ++i) {
+ String spec = languageList[i];
+ if (availableLanguages.contains(spec)) {
+ languageSelections.add(spec);
+ } else if (spec.length() > 2) {
+ String lang = spec.substring(0, 2);
+ if (availableLanguages.contains(lang)) languageSelections.add(lang);
+ }
+ }
+
+ PreferenceGroup parent = getPreferenceScreen();
+ for (int i = 0; i < mAvailableLanguages.size(); i++) {
+ CheckBoxPreference pref = new CheckBoxPreference(this);
+ Locale locale = mAvailableLanguages.get(i).locale;
+ pref.setTitle(mAvailableLanguages.get(i).label +
+ " [" + locale.toString() + "]");
+ String fivecode = get5Code(locale);
+ String language = locale.getLanguage();
+ boolean checked = languageSelections.contains(fivecode);
+ pref.setChecked(checked);
+ boolean has4Row = arrayContains(KBD_4_ROW, fivecode) || arrayContains(KBD_4_ROW, language);
+ boolean has5Row = arrayContains(KBD_5_ROW, fivecode) || arrayContains(KBD_5_ROW, language);
+ List<String> summaries = new ArrayList<String>(3);
+ if (has5Row) summaries.add("5-row");
+ if (has4Row) summaries.add("4-row");
+ if (hasDictionary(locale)) {
+ summaries.add(getResources().getString(R.string.has_dictionary));
+ }
+ if (!summaries.isEmpty()) {
+ StringBuilder summary = new StringBuilder();
+ for (int j = 0; j < summaries.size(); ++j) {
+ if (j > 0) summary.append(", ");
+ summary.append(summaries.get(j));
+ }
+ pref.setSummary(summary.toString());
+ }
+ parent.addPreference(pref);
+ }
+ }
+
+ private boolean hasDictionary(Locale locale) {
+ Resources res = getResources();
+ Configuration conf = res.getConfiguration();
+ Locale saveLocale = conf.locale;
+ boolean haveDictionary = false;
+ conf.locale = locale;
+ res.updateConfiguration(conf, res.getDisplayMetrics());
+
+ int[] dictionaries = LatinIME.getDictionary(res);
+ BinaryDictionary bd = new BinaryDictionary(this, dictionaries, Suggest.DIC_MAIN);
+
+ // Is the dictionary larger than a placeholder? Arbitrarily chose a lower limit of
+ // 4000-5000 words, whereas the LARGE_DICTIONARY is about 20000+ words.
+ if (bd.getSize() > Suggest.LARGE_DICTIONARY_THRESHOLD / 4) {
+ haveDictionary = true;
+ } else {
+ BinaryDictionary plug = PluginManager.getDictionary(getApplicationContext(), locale.getLanguage());
+ if (plug != null) {
+ bd.close();
+ bd = plug;
+ haveDictionary = true;
+ }
+ }
+
+ bd.close();
+ conf.locale = saveLocale;
+ res.updateConfiguration(conf, res.getDisplayMetrics());
+ return haveDictionary;
+ }
+
+ private String get5Code(Locale locale) {
+ String country = locale.getCountry();
+ return locale.getLanguage()
+ + (TextUtils.isEmpty(country) ? "" : "_" + country);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ // Save the selected languages
+ String checkedLanguages = "";
+ PreferenceGroup parent = getPreferenceScreen();
+ int count = parent.getPreferenceCount();
+ for (int i = 0; i < count; i++) {
+ CheckBoxPreference pref = (CheckBoxPreference) parent.getPreference(i);
+ if (pref.isChecked()) {
+ Locale locale = mAvailableLanguages.get(i).locale;
+ checkedLanguages += get5Code(locale) + ",";
+ }
+ }
+ if (checkedLanguages.length() < 1) checkedLanguages = null; // Save null
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
+ Editor editor = sp.edit();
+ editor.putString(LatinIME.PREF_SELECTED_LANGUAGES, checkedLanguages);
+ SharedPreferencesCompat.apply(editor);
+ }
+
+ private static String asString(Set<String> set) {
+ StringBuilder out = new StringBuilder();
+ out.append("set(");
+ String[] parts = new String[set.size()];
+ parts = set.toArray(parts);
+ Arrays.sort(parts);
+ for (int i = 0; i < parts.length; ++i) {
+ if (i > 0) out.append(", ");
+ out.append(parts[i]);
+ }
+ out.append(")");
+ return out.toString();
+ }
+
+ ArrayList<Loc> getUniqueLocales() {
+ Set<String> localeSet = new HashSet<String>();
+ Set<String> langSet = new HashSet<String>();
+ // Ignore the system (asset) locale list, it's inconsistent and incomplete
+// String[] sysLocales = getAssets().getLocales();
+//
+// // First, add zz_ZZ style full language+country locales
+// for (int i = 0; i < sysLocales.length; ++i) {
+// String sl = sysLocales[i];
+// if (sl.length() != 5) continue;
+// localeSet.add(sl);
+// langSet.add(sl.substring(0, 2));
+// }
+//
+// // Add entries for system languages without country, but only if there's
+// // no full locale for that language yet.
+// for (int i = 0; i < sysLocales.length; ++i) {
+// String sl = sysLocales[i];
+// if (sl.length() != 2 || langSet.contains(sl)) continue;
+// localeSet.add(sl);
+// }
+
+ // Add entries for additional languages supported by the keyboard.
+ for (int i = 0; i < KBD_LOCALIZATIONS.length; ++i) {
+ String kl = KBD_LOCALIZATIONS[i];
+ if (kl.length() == 2 && langSet.contains(kl)) continue;
+ // replace zz_rYY with zz_YY
+ if (kl.length() == 6) kl = kl.substring(0, 2) + "_" + kl.substring(4, 6);
+ localeSet.add(kl);
+ }
+ Log.i(TAG, "localeSet=" + asString(localeSet));
+ Log.i(TAG, "langSet=" + asString(langSet));
+
+ // Now build the locale list for display
+ String[] locales = new String[localeSet.size()];
+ locales = localeSet.toArray(locales);
+ Arrays.sort(locales);
+
+ ArrayList<Loc> uniqueLocales = new ArrayList<Loc>();
+
+ final int origSize = locales.length;
+ Loc[] preprocess = new Loc[origSize];
+ int finalSize = 0;
+ for (int i = 0 ; i < origSize; i++ ) {
+ String s = locales[i];
+ int len = s.length();
+ if (len == 2 || len == 5 || len == 6) {
+ String language = s.substring(0, 2);
+ Locale l;
+ if (len == 5) {
+ // zz_YY
+ String country = s.substring(3, 5);
+ l = new Locale(language, country);
+ } else if (len == 6) {
+ // zz_rYY
+ l = new Locale(language, s.substring(4, 6));
+ } else {
+ l = new Locale(language);
+ }
+
+ // Exclude languages that are not relevant to LatinIME
+ if (arrayContains(BLACKLIST_LANGUAGES, language)) continue;
+
+ if (finalSize == 0) {
+ preprocess[finalSize++] =
+ new Loc(LanguageSwitcher.toTitleCase(l.getDisplayName(l)), l);
+ } else {
+ // check previous entry:
+ // same lang and a country -> upgrade to full name and
+ // insert ours with full name
+ // diff lang -> insert ours with lang-only name
+ if (preprocess[finalSize-1].locale.getLanguage().equals(
+ language)) {
+ preprocess[finalSize-1].label = getLocaleName(preprocess[finalSize-1].locale);
+ preprocess[finalSize++] =
+ new Loc(getLocaleName(l), l);
+ } else {
+ String displayName;
+ if (s.equals("zz_ZZ")) {
+ } else {
+ displayName = getLocaleName(l);
+ preprocess[finalSize++] = new Loc(displayName, l);
+ }
+ }
+ }
+ }
+ }
+ for (int i = 0; i < finalSize ; i++) {
+ uniqueLocales.add(preprocess[i]);
+ }
+ return uniqueLocales;
+ }
+
+ private boolean arrayContains(String[] array, String value) {
+ for (int i = 0; i < array.length; i++) {
+ if (array[i].equalsIgnoreCase(value)) return true;
+ }
+ return false;
+ }
+}
diff --git a/java/src/org/pocketworkstation/pckeyboard/KeyDetector.java b/java/src/org/pocketworkstation/pckeyboard/KeyDetector.java
new file mode 100644
index 0000000..6aa7068
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/KeyDetector.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.pocketworkstation.pckeyboard;
+
+import org.pocketworkstation.pckeyboard.Keyboard.Key;
+
+import java.util.Arrays;
+import java.util.List;
+
+abstract class KeyDetector {
+ protected Keyboard mKeyboard;
+
+ private Key[] mKeys;
+
+ protected int mCorrectionX;
+
+ protected int mCorrectionY;
+
+ protected boolean mProximityCorrectOn;
+
+ protected int mProximityThresholdSquare;
+
+ public Key[] setKeyboard(Keyboard keyboard, float correctionX, float correctionY) {
+ if (keyboard == null)
+ throw new NullPointerException();
+ mCorrectionX = (int)correctionX;
+ mCorrectionY = (int)correctionY;
+ mKeyboard = keyboard;
+ List<Key> keys = mKeyboard.getKeys();
+ Key[] array = keys.toArray(new Key[keys.size()]);
+ mKeys = array;
+ return array;
+ }
+
+ protected int getTouchX(int x) {
+ return x + mCorrectionX;
+ }
+
+ protected int getTouchY(int y) {
+ return y + mCorrectionY;
+ }
+
+ protected Key[] getKeys() {
+ if (mKeys == null)
+ throw new IllegalStateException("keyboard isn't set");
+ // mKeyboard is guaranteed not to be null at setKeybaord() method if mKeys is not null
+ return mKeys;
+ }
+
+ public void setProximityCorrectionEnabled(boolean enabled) {
+ mProximityCorrectOn = enabled;
+ }
+
+ public boolean isProximityCorrectionEnabled() {
+ return mProximityCorrectOn;
+ }
+
+ public void setProximityThreshold(int threshold) {
+ mProximityThresholdSquare = threshold * threshold;
+ }
+
+ /**
+ * Allocates array that can hold all key indices returned by {@link #getKeyIndexAndNearbyCodes}
+ * method. The maximum size of the array should be computed by {@link #getMaxNearbyKeys}.
+ *
+ * @return Allocates and returns an array that can hold all key indices returned by
+ * {@link #getKeyIndexAndNearbyCodes} method. All elements in the returned array are
+ * initialized by {@link org.pocketworkstation.pckeyboard.LatinKeyboardView.NOT_A_KEY}
+ * value.
+ */
+ public int[] newCodeArray() {
+ int[] codes = new int[getMaxNearbyKeys()];
+ Arrays.fill(codes, LatinKeyboardBaseView.NOT_A_KEY);
+ return codes;
+ }
+
+ /**
+ * Computes maximum size of the array that can contain all nearby key indices returned by
+ * {@link #getKeyIndexAndNearbyCodes}.
+ *
+ * @return Returns maximum size of the array that can contain all nearby key indices returned
+ * by {@link #getKeyIndexAndNearbyCodes}.
+ */
+ abstract protected int getMaxNearbyKeys();
+
+ /**
+ * Finds all possible nearby key indices around a touch event point and returns the nearest key
+ * index. The algorithm to determine the nearby keys depends on the threshold set by
+ * {@link #setProximityThreshold(int)} and the mode set by
+ * {@link #setProximityCorrectionEnabled(boolean)}.
+ *
+ * @param x The x-coordinate of a touch point
+ * @param y The y-coordinate of a touch point
+ * @param allKeys All nearby key indices are returned in this array
+ * @return The nearest key index
+ */
+ abstract public int getKeyIndexAndNearbyCodes(int x, int y, int[] allKeys);
+}
diff --git a/java/src/org/pocketworkstation/pckeyboard/Keyboard.java b/java/src/org/pocketworkstation/pckeyboard/Keyboard.java
new file mode 100644
index 0000000..fa551cc
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/Keyboard.java
@@ -0,0 +1,1314 @@
+/*
+ * Copyright (C) 2008-2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.pocketworkstation.pckeyboard;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
+import android.graphics.drawable.Drawable;
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.TypedValue;
+import android.util.Xml;
+import android.util.DisplayMetrics;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+
+/**
+ * Loads an XML description of a keyboard and stores the attributes of the keys. A keyboard
+ * consists of rows of keys.
+ * <p>The layout file for a keyboard contains XML that looks like the following snippet:</p>
+ * <pre>
+ * &lt;Keyboard
+ * android:keyWidth="%10p"
+ * android:keyHeight="50px"
+ * android:horizontalGap="2px"
+ * android:verticalGap="2px" &gt;
+ * &lt;Row android:keyWidth="32px" &gt;
+ * &lt;Key android:keyLabel="A" /&gt;
+ * ...
+ * &lt;/Row&gt;
+ * ...
+ * &lt;/Keyboard&gt;
+ * </pre>
+ * @attr ref android.R.styleable#Keyboard_keyWidth
+ * @attr ref android.R.styleable#Keyboard_keyHeight
+ * @attr ref android.R.styleable#Keyboard_horizontalGap
+ * @attr ref android.R.styleable#Keyboard_verticalGap
+ */
+public class Keyboard {
+
+ static final String TAG = "Keyboard";
+
+ public final static char DEAD_KEY_PLACEHOLDER = 0x25cc; // dotted small circle
+ public final static String DEAD_KEY_PLACEHOLDER_STRING = Character.toString(DEAD_KEY_PLACEHOLDER);
+
+ // Keyboard XML Tags
+ private static final String TAG_KEYBOARD = "Keyboard";
+ private static final String TAG_ROW = "Row";
+ private static final String TAG_KEY = "Key";
+
+ public static final int EDGE_LEFT = 0x01;
+ public static final int EDGE_RIGHT = 0x02;
+ public static final int EDGE_TOP = 0x04;
+ public static final int EDGE_BOTTOM = 0x08;
+
+ public static final int KEYCODE_SHIFT = -1;
+ public static final int KEYCODE_MODE_CHANGE = -2;
+ public static final int KEYCODE_CANCEL = -3;
+ public static final int KEYCODE_DONE = -4;
+ public static final int KEYCODE_DELETE = -5;
+ public static final int KEYCODE_ALT_SYM = -6;
+
+ // Backwards compatible setting to avoid having to change all the kbd_qwerty files
+ public static final int DEFAULT_LAYOUT_ROWS = 4;
+ public static final int DEFAULT_LAYOUT_COLUMNS = 10;
+
+ // Flag values for popup key contents. Keep in sync with strings.xml values.
+ public static final int POPUP_ADD_SHIFT = 1;
+ public static final int POPUP_ADD_CASE = 2;
+ public static final int POPUP_ADD_SELF = 4;
+ public static final int POPUP_DISABLE = 256;
+ public static final int POPUP_AUTOREPEAT = 512;
+
+ /** Horizontal gap default for all rows */
+ private float mDefaultHorizontalGap;
+
+ private float mHorizontalPad;
+ private float mVerticalPad;
+
+ /** Default key width */
+ private float mDefaultWidth;
+
+ /** Default key height */
+ private int mDefaultHeight;
+
+ /** Default gap between rows */
+ private int mDefaultVerticalGap;
+
+ public static final int SHIFT_OFF = 0;
+ public static final int SHIFT_ON = 1;
+ public static final int SHIFT_LOCKED = 2;
+ public static final int SHIFT_CAPS = 3;
+ public static final int SHIFT_CAPS_LOCKED = 4;
+
+ /** Is the keyboard in the shifted state */
+ private int mShiftState = SHIFT_OFF;
+
+ /** Key instance for the shift key, if present */
+ private Key mShiftKey;
+ private Key mAltKey;
+ private Key mCtrlKey;
+
+ /** Key index for the shift key, if present */
+ private int mShiftKeyIndex = -1;
+
+ /** Total height of the keyboard, including the padding and keys */
+ private int mTotalHeight;
+
+ /**
+ * Total width of the keyboard, including left side gaps and keys, but not any gaps on the
+ * right side.
+ */
+ private int mTotalWidth;
+
+ /** List of keys in this keyboard */
+ private List<Key> mKeys;
+
+ /** List of modifier keys such as Shift & Alt, if any */
+ private List<Key> mModifierKeys;
+
+ /** Width of the screen available to fit the keyboard */
+ private int mDisplayWidth;
+
+ /** Height of the screen and keyboard */
+ private int mDisplayHeight;
+ private int mKeyboardHeight;
+
+ /** Keyboard mode, or zero, if none. */
+ private int mKeyboardMode;
+
+ private boolean mUseExtension;
+
+ public int mLayoutRows;
+ public int mLayoutColumns;
+ public int mRowCount = 1;
+ public int mExtensionRowCount = 0;
+
+ // Variables for pre-computing nearest keys.
+ private int mCellWidth;
+ private int mCellHeight;
+ private int[][] mGridNeighbors;
+ private int mProximityThreshold;
+ /** Number of key widths from current touch point to search for nearest keys. */
+ private static float SEARCH_DISTANCE = 1.8f;
+
+ /**
+ * Container for keys in the keyboard. All keys in a row are at the same Y-coordinate.
+ * Some of the key size defaults can be overridden per row from what the {@link Keyboard}
+ * defines.
+ * @attr ref android.R.styleable#Keyboard_keyWidth
+ * @attr ref android.R.styleable#Keyboard_keyHeight
+ * @attr ref android.R.styleable#Keyboard_horizontalGap
+ * @attr ref android.R.styleable#Keyboard_verticalGap
+ * @attr ref android.R.styleable#Keyboard_Row_keyboardMode
+ */
+ public static class Row {
+ /** Default width of a key in this row. */
+ public float defaultWidth;
+ /** Default height of a key in this row. */
+ public int defaultHeight;
+ /** Default horizontal gap between keys in this row. */
+ public float defaultHorizontalGap;
+ /** Vertical gap following this row. */
+ public int verticalGap;
+
+ /** The keyboard mode for this row */
+ public int mode;
+
+ public boolean extension;
+
+ private Keyboard parent;
+
+ public Row(Keyboard parent) {
+ this.parent = parent;
+ }
+
+ public Row(Resources res, Keyboard parent, XmlResourceParser parser) {
+ this.parent = parent;
+ TypedArray a = res.obtainAttributes(Xml.asAttributeSet(parser),
+ R.styleable.Keyboard);
+ defaultWidth = getDimensionOrFraction(a,
+ R.styleable.Keyboard_keyWidth,
+ parent.mDisplayWidth, parent.mDefaultWidth);
+ defaultHeight = Math.round(getDimensionOrFraction(a,
+ R.styleable.Keyboard_keyHeight,
+ parent.mDisplayHeight, parent.mDefaultHeight));
+ defaultHorizontalGap = getDimensionOrFraction(a,
+ R.styleable.Keyboard_horizontalGap,
+ parent.mDisplayWidth, parent.mDefaultHorizontalGap);
+ verticalGap = Math.round(getDimensionOrFraction(a,
+ R.styleable.Keyboard_verticalGap,
+ parent.mDisplayHeight, parent.mDefaultVerticalGap));
+ a.recycle();
+ a = res.obtainAttributes(Xml.asAttributeSet(parser),
+ R.styleable.Keyboard_Row);
+ mode = a.getResourceId(R.styleable.Keyboard_Row_keyboardMode,
+ 0);
+ extension = a.getBoolean(R.styleable.Keyboard_Row_extension, false);
+
+ if (parent.mLayoutRows >= 5) {
+ boolean isTop = (extension || parent.mRowCount - parent.mExtensionRowCount <= 0);
+ float topScale = LatinIME.sKeyboardSettings.topRowScale;
+ float scale = isTop ? topScale : 1.0f + (1.0f - topScale) / (parent.mLayoutRows - 1);
+ defaultHeight = Math.round(defaultHeight * scale);
+ }
+ a.recycle();
+ }
+ }
+
+ /**
+ * Class for describing the position and characteristics of a single key in the keyboard.
+ *
+ * @attr ref android.R.styleable#Keyboard_keyWidth
+ * @attr ref android.R.styleable#Keyboard_keyHeight
+ * @attr ref android.R.styleable#Keyboard_horizontalGap
+ * @attr ref android.R.styleable#Keyboard_Key_codes
+ * @attr ref android.R.styleable#Keyboard_Key_keyIcon
+ * @attr ref android.R.styleable#Keyboard_Key_keyLabel
+ * @attr ref android.R.styleable#Keyboard_Key_iconPreview
+ * @attr ref android.R.styleable#Keyboard_Key_isSticky
+ * @attr ref android.R.styleable#Keyboard_Key_isRepeatable
+ * @attr ref android.R.styleable#Keyboard_Key_isModifier
+ * @attr ref android.R.styleable#Keyboard_Key_popupKeyboard
+ * @attr ref android.R.styleable#Keyboard_Key_popupCharacters
+ * @attr ref android.R.styleable#Keyboard_Key_keyOutputText
+ */
+ public static class Key {
+ /**
+ * All the key codes (unicode or custom code) that this key could generate, zero'th
+ * being the most important.
+ */
+ public int[] codes;
+
+ /** Label to display */
+ public CharSequence label;
+ public CharSequence shiftLabel;
+ public CharSequence capsLabel;
+
+ /** Icon to display instead of a label. Icon takes precedence over a label */
+ public Drawable icon;
+ /** Preview version of the icon, for the preview popup */
+ public Drawable iconPreview;
+ /** Width of the key, not including the gap */
+ public int width;
+ /** Height of the key, not including the gap */
+ private float realWidth;
+ public int height;
+ /** The horizontal gap before this key */
+ public int gap;
+ private float realGap;
+ /** Whether this key is sticky, i.e., a toggle key */
+ public boolean sticky;
+ /** X coordinate of the key in the keyboard layout */
+ public int x;
+ private float realX;
+ /** Y coordinate of the key in the keyboard layout */
+ public int y;
+ /** The current pressed state of this key */
+ public boolean pressed;
+ /** If this is a sticky key, is it on or locked? */
+ public boolean on;
+ public boolean locked;
+ /** Text to output when pressed. This can be multiple characters, like ".com" */
+ public CharSequence text;
+ /** Popup characters */
+ public CharSequence popupCharacters;
+ public boolean popupReversed;
+ public boolean isCursor;
+ public String hint; // Set by LatinKeyboardBaseView
+ public String altHint; // Set by LatinKeyboardBaseView
+
+ /**
+ * Flags that specify the anchoring to edges of the keyboard for detecting touch events
+ * that are just out of the boundary of the key. This is a bit mask of
+ * {@link Keyboard#EDGE_LEFT}, {@link Keyboard#EDGE_RIGHT}, {@link Keyboard#EDGE_TOP} and
+ * {@link Keyboard#EDGE_BOTTOM}.
+ */
+ public int edgeFlags;
+ /** Whether this is a modifier key, such as Shift or Alt */
+ public boolean modifier;
+ /** The keyboard that this key belongs to */
+ private Keyboard keyboard;
+ /**
+ * If this key pops up a mini keyboard, this is the resource id for the XML layout for that
+ * keyboard.
+ */
+ public int popupResId;
+ /** Whether this key repeats itself when held down */
+ public boolean repeatable;
+ /** Is the shifted character the uppercase equivalent of the unshifted one? */
+ private boolean isSimpleUppercase;
+ /** Is the shifted character a distinct uppercase char that's different from the shifted char? */
+ private boolean isDistinctUppercase;
+
+ private final static int[] KEY_STATE_NORMAL_ON = {
+ android.R.attr.state_checkable,
+ android.R.attr.state_checked
+ };
+
+ private final static int[] KEY_STATE_PRESSED_ON = {
+ android.R.attr.state_pressed,
+ android.R.attr.state_checkable,
+ android.R.attr.state_checked
+ };
+
+ private final static int[] KEY_STATE_NORMAL_LOCK = {
+ android.R.attr.state_active,
+ android.R.attr.state_checkable,
+ android.R.attr.state_checked
+ };
+
+ private final static int[] KEY_STATE_PRESSED_LOCK = {
+ android.R.attr.state_active,
+ android.R.attr.state_pressed,
+ android.R.attr.state_checkable,
+ android.R.attr.state_checked
+ };
+
+ private final static int[] KEY_STATE_NORMAL_OFF = {
+ android.R.attr.state_checkable
+ };
+
+ private final static int[] KEY_STATE_PRESSED_OFF = {
+ android.R.attr.state_pressed,
+ android.R.attr.state_checkable
+ };
+
+ private final static int[] KEY_STATE_NORMAL = {
+ };
+
+ private final static int[] KEY_STATE_PRESSED = {
+ android.R.attr.state_pressed
+ };
+
+ /** Create an empty key with no attributes. */
+ public Key(Row parent) {
+ keyboard = parent.parent;
+ height = parent.defaultHeight;
+ width = Math.round(parent.defaultWidth);
+ realWidth = parent.defaultWidth;
+ gap = Math.round(parent.defaultHorizontalGap);
+ realGap = parent.defaultHorizontalGap;
+ }
+
+ /** Create a key with the given top-left coordinate and extract its attributes from
+ * the XML parser.
+ * @param res resources associated with the caller's context
+ * @param parent the row that this key belongs to. The row must already be attached to
+ * a {@link Keyboard}.
+ * @param x the x coordinate of the top-left
+ * @param y the y coordinate of the top-left
+ * @param parser the XML parser containing the attributes for this key
+ */
+ public Key(Resources res, Row parent, int x, int y, XmlResourceParser parser) {
+ this(parent);
+
+ this.x = x;
+ this.y = y;
+
+ TypedArray a = res.obtainAttributes(Xml.asAttributeSet(parser),
+ R.styleable.Keyboard);
+
+ realWidth = getDimensionOrFraction(a,
+ R.styleable.Keyboard_keyWidth,
+ keyboard.mDisplayWidth, parent.defaultWidth);
+ float realHeight = getDimensionOrFraction(a,
+ R.styleable.Keyboard_keyHeight,
+ keyboard.mDisplayHeight, parent.defaultHeight);
+ realHeight -= parent.parent.mVerticalPad;
+ height = Math.round(realHeight);
+ this.y += parent.parent.mVerticalPad / 2;
+ realGap = getDimensionOrFraction(a,
+ R.styleable.Keyboard_horizontalGap,
+ keyboard.mDisplayWidth, parent.defaultHorizontalGap);
+ realGap += parent.parent.mHorizontalPad;
+ realWidth -= parent.parent.mHorizontalPad;
+ width = Math.round(realWidth);
+ gap = Math.round(realGap);
+ a.recycle();
+ a = res.obtainAttributes(Xml.asAttributeSet(parser),
+ R.styleable.Keyboard_Key);
+ this.realX = this.x + realGap - parent.parent.mHorizontalPad / 2;
+ this.x = Math.round(this.realX);
+ TypedValue codesValue = new TypedValue();
+ a.getValue(R.styleable.Keyboard_Key_codes,
+ codesValue);
+ if (codesValue.type == TypedValue.TYPE_INT_DEC
+ || codesValue.type == TypedValue.TYPE_INT_HEX) {
+ codes = new int[] { codesValue.data };
+ } else if (codesValue.type == TypedValue.TYPE_STRING) {
+ codes = parseCSV(codesValue.string.toString());
+ }
+
+ iconPreview = a.getDrawable(R.styleable.Keyboard_Key_iconPreview);
+ if (iconPreview != null) {
+ iconPreview.setBounds(0, 0, iconPreview.getIntrinsicWidth(),
+ iconPreview.getIntrinsicHeight());
+ }
+ popupCharacters = a.getText(
+ R.styleable.Keyboard_Key_popupCharacters);
+ popupResId = a.getResourceId(
+ R.styleable.Keyboard_Key_popupKeyboard, 0);
+ repeatable = a.getBoolean(
+ R.styleable.Keyboard_Key_isRepeatable, false);
+ modifier = a.getBoolean(
+ R.styleable.Keyboard_Key_isModifier, false);
+ sticky = a.getBoolean(
+ R.styleable.Keyboard_Key_isSticky, false);
+ isCursor = a.getBoolean(
+ R.styleable.Keyboard_Key_isCursor, false);
+
+ icon = a.getDrawable(
+ R.styleable.Keyboard_Key_keyIcon);
+ if (icon != null) {
+ icon.setBounds(0, 0, icon.getIntrinsicWidth(), icon.getIntrinsicHeight());
+ }
+ label = a.getText(R.styleable.Keyboard_Key_keyLabel);
+ shiftLabel = a.getText(R.styleable.Keyboard_Key_shiftLabel);
+ if (shiftLabel != null && shiftLabel.length() == 0) shiftLabel = null;
+ capsLabel = a.getText(R.styleable.Keyboard_Key_capsLabel);
+ if (capsLabel != null && capsLabel.length() == 0) capsLabel = null;
+ text = a.getText(R.styleable.Keyboard_Key_keyOutputText);
+
+ if (codes == null && !TextUtils.isEmpty(label)) {
+ codes = getFromString(label);
+ if (codes != null && codes.length == 1) {
+ final Locale locale = LatinIME.sKeyboardSettings.inputLocale;
+ String upperLabel = label.toString().toUpperCase(locale);
+ if (shiftLabel == null) {
+ // No shiftLabel supplied, auto-set to uppercase if possible.
+ if (!upperLabel.equals(label.toString()) && upperLabel.length() == 1) {
+ shiftLabel = upperLabel;
+ isSimpleUppercase = true;
+ }
+ } else {
+ // Both label and shiftLabel supplied. Check if
+ // the shiftLabel is the uppercased normal label.
+ // If not, treat it as a distinct uppercase variant.
+ if (capsLabel != null) {
+ isDistinctUppercase = true;
+ } else if (upperLabel.equals(shiftLabel.toString())) {
+ isSimpleUppercase = true;
+ } else if (upperLabel.length() == 1) {
+ capsLabel = upperLabel;
+ isDistinctUppercase = true;
+ }
+ }
+ }
+ if ((LatinIME.sKeyboardSettings.popupKeyboardFlags & POPUP_DISABLE) != 0) {
+ popupCharacters = null;
+ popupResId = 0;
+ }
+ if ((LatinIME.sKeyboardSettings.popupKeyboardFlags & POPUP_AUTOREPEAT) != 0) {
+ // Assume POPUP_DISABLED is set too, otherwise things may get weird.
+ repeatable = true;
+ }
+ }
+ //Log.i(TAG, "added key definition: " + this);
+ a.recycle();
+ }
+
+ public boolean isDistinctCaps() {
+ return isDistinctUppercase && keyboard.isShiftCaps();
+ }
+
+ public boolean isShifted() {
+ boolean shifted = keyboard.isShifted(isSimpleUppercase);
+ //Log.i(TAG, "FIXME isShifted=" + shifted + " for " + this);
+ return shifted;
+ }
+
+ public int getPrimaryCode(boolean isShiftCaps, boolean isShifted) {
+ if (isDistinctUppercase && isShiftCaps) {
+ return capsLabel.charAt(0);
+ }
+ //Log.i(TAG, "getPrimaryCode(), shifted=" + shifted);
+ if (isShifted && shiftLabel != null) {
+ if (shiftLabel.charAt(0) == DEAD_KEY_PLACEHOLDER && shiftLabel.length() >= 2) {
+ return shiftLabel.charAt(1);
+ } else {
+ return shiftLabel.charAt(0);
+ }
+ } else {
+ return codes[0];
+ }
+ }
+
+ public int getPrimaryCode() {
+ return getPrimaryCode(keyboard.isShiftCaps(), keyboard.isShifted(isSimpleUppercase));
+ }
+
+ public boolean isDeadKey() {
+ if (codes == null || codes.length < 1) return false;
+ return Character.getType(codes[0]) == Character.NON_SPACING_MARK;
+ }
+
+ public int[] getFromString(CharSequence str) {
+ if (str.length() > 1) {
+ if (str.charAt(0) == DEAD_KEY_PLACEHOLDER && str.length() >= 2) {
+ return new int[] { str.charAt(1) }; // FIXME: >1 length?
+ } else {
+ text = str; // TODO: add space?
+ return new int[] { 0 };
+ }
+ } else {
+ char c = str.charAt(0);
+ return new int[] { c };
+ }
+ }
+
+ public String getCaseLabel() {
+ if (isDistinctUppercase && keyboard.isShiftCaps()) {
+ return capsLabel.toString();
+ }
+ boolean isShifted = keyboard.isShifted(isSimpleUppercase);
+ if (isShifted && shiftLabel != null) {
+ return shiftLabel.toString();
+ } else {
+ return label != null ? label.toString() : null;
+ }
+ }
+
+ private String getPopupKeyboardContent(boolean isShiftCaps, boolean isShifted, boolean addExtra) {
+ int mainChar = getPrimaryCode(false, false);
+ int shiftChar = getPrimaryCode(false, true);
+ int capsChar = getPrimaryCode(true, true);
+
+ // Remove duplicates
+ if (shiftChar == mainChar) shiftChar = 0;
+ if (capsChar == shiftChar || capsChar == mainChar) capsChar = 0;
+
+ int popupLen = (popupCharacters == null) ? 0 : popupCharacters.length();
+ StringBuilder popup = new StringBuilder(popupLen);
+ for (int i = 0; i < popupLen; ++i) {
+ char c = popupCharacters.charAt(i);
+ if (isShifted || isShiftCaps) {
+ String upper = Character.toString(c).toUpperCase(LatinIME.sKeyboardSettings.inputLocale);
+ if (upper.length() == 1) c = upper.charAt(0);
+ }
+
+ if (c == mainChar || c == shiftChar || c == capsChar) continue;
+ popup.append(c);
+ }
+
+ if (addExtra) {
+ StringBuilder extra = new StringBuilder(3 + popup.length());
+ int flags = LatinIME.sKeyboardSettings.popupKeyboardFlags;
+ if ((flags & POPUP_ADD_SELF) != 0) {
+ // if shifted, add unshifted key to extra, and vice versa
+ if (isDistinctUppercase && isShiftCaps) {
+ if (capsChar > 0) { extra.append((char) capsChar); capsChar = 0; }
+ } else if (isShifted) {
+ if (shiftChar > 0) { extra.append((char) shiftChar); shiftChar = 0; }
+ } else {
+ if (mainChar > 0) { extra.append((char) mainChar); mainChar = 0; }
+ }
+ }
+
+ if ((flags & POPUP_ADD_CASE) != 0) {
+ // if shifted, add unshifted key to popup, and vice versa
+ if (isDistinctUppercase && isShiftCaps) {
+ if (mainChar > 0) { extra.append((char) mainChar); mainChar = 0; }
+ if (shiftChar > 0) { extra.append((char) shiftChar); shiftChar = 0; }
+ } else if (isShifted) {
+ if (mainChar > 0) { extra.append((char) mainChar); mainChar = 0; }
+ if (capsChar > 0) { extra.append((char) capsChar); capsChar = 0; }
+ } else {
+ if (shiftChar > 0) { extra.append((char) shiftChar); shiftChar = 0; }
+ if (capsChar > 0) { extra.append((char) capsChar); capsChar = 0; }
+ }
+ }
+
+ if (!isSimpleUppercase && (flags & POPUP_ADD_SHIFT) != 0) {
+ // if shifted, add unshifted key to popup, and vice versa
+ if (isShifted) {
+ if (mainChar > 0) { extra.append((char) mainChar); mainChar = 0; }
+ } else {
+ if (shiftChar > 0) { extra.append((char) shiftChar); shiftChar = 0; }
+ }
+ }
+
+ extra.append(popup);
+ return extra.toString();
+ }
+
+ return popup.toString();
+ }
+
+ public Keyboard getPopupKeyboard(Context context, int padding) {
+ if (popupCharacters == null) {
+ if (popupResId != 0) {
+ return new Keyboard(context, keyboard.mDefaultHeight, popupResId);
+ } else {
+ if (modifier) return null; // Space, Return etc.
+ }
+ }
+
+ if ((LatinIME.sKeyboardSettings.popupKeyboardFlags & POPUP_DISABLE) != 0) return null;
+
+ String popup = getPopupKeyboardContent(keyboard.isShiftCaps(), keyboard.isShifted(isSimpleUppercase), true);
+ //Log.i(TAG, "getPopupKeyboard: popup='" + popup + "' for " + this);
+ if (popup.length() > 0) {
+ int resId = popupResId;
+ if (resId == 0) resId = R.xml.kbd_popup_template;
+ return new Keyboard(context, keyboard.mDefaultHeight, resId, popup, popupReversed, -1, padding);
+ } else {
+ return null;
+ }
+ }
+
+ public String getHintLabel(boolean wantAscii, boolean wantAll) {
+ if (hint == null) {
+ hint = "";
+ if (shiftLabel != null && !isSimpleUppercase) {
+ char c = shiftLabel.charAt(0);
+ if (wantAll || wantAscii && is7BitAscii(c)) {
+ hint = Character.toString(c);
+ }
+ }
+ }
+ return hint;
+ }
+
+ public String getAltHintLabel(boolean wantAscii, boolean wantAll) {
+ if (altHint == null) {
+ altHint = "";
+ String popup = getPopupKeyboardContent(false, false, false);
+ if (popup.length() > 0) {
+ char c = popup.charAt(0);
+ if (wantAll || wantAscii && is7BitAscii(c)) {
+ altHint = Character.toString(c);
+ }
+ }
+ }
+ return altHint;
+ }
+
+ private static boolean is7BitAscii(char c) {
+ if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) return false;
+ return c >= 32 && c < 127;
+ }
+
+ /**
+ * Informs the key that it has been pressed, in case it needs to change its appearance or
+ * state.
+ * @see #onReleased(boolean)
+ */
+ public void onPressed() {
+ pressed = !pressed;
+ }
+
+ /**
+ * Changes the pressed state of the key. Sticky key indicators are handled explicitly elsewhere.
+ * @param inside whether the finger was released inside the key
+ * @see #onPressed()
+ */
+ public void onReleased(boolean inside) {
+ pressed = !pressed;
+ }
+
+ int[] parseCSV(String value) {
+ int count = 0;
+ int lastIndex = 0;
+ if (value.length() > 0) {
+ count++;
+ while ((lastIndex = value.indexOf(",", lastIndex + 1)) > 0) {
+ count++;
+ }
+ }
+ int[] values = new int[count];
+ count = 0;
+ StringTokenizer st = new StringTokenizer(value, ",");
+ while (st.hasMoreTokens()) {
+ try {
+ values[count++] = Integer.parseInt(st.nextToken());
+ } catch (NumberFormatException nfe) {
+ Log.e(TAG, "Error parsing keycodes " + value);
+ }
+ }
+ return values;
+ }
+
+ /**
+ * Detects if a point falls inside this key.
+ * @param x the x-coordinate of the point
+ * @param y the y-coordinate of the point
+ * @return whether or not the point falls inside the key. If the key is attached to an edge,
+ * it will assume that all points between the key and the edge are considered to be inside
+ * the key.
+ */
+ public boolean isInside(int x, int y) {
+ boolean leftEdge = (edgeFlags & EDGE_LEFT) > 0;
+ boolean rightEdge = (edgeFlags & EDGE_RIGHT) > 0;
+ boolean topEdge = (edgeFlags & EDGE_TOP) > 0;
+ boolean bottomEdge = (edgeFlags & EDGE_BOTTOM) > 0;
+ if ((x >= this.x || (leftEdge && x <= this.x + this.width))
+ && (x < this.x + this.width || (rightEdge && x >= this.x))
+ && (y >= this.y || (topEdge && y <= this.y + this.height))
+ && (y < this.y + this.height || (bottomEdge && y >= this.y))) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Returns the square of the distance between the center of the key and the given point.
+ * @param x the x-coordinate of the point
+ * @param y the y-coordinate of the point
+ * @return the square of the distance of the point from the center of the key
+ */
+ public int squaredDistanceFrom(int x, int y) {
+ int xDist = this.x + width / 2 - x;
+ int yDist = this.y + height / 2 - y;
+ return xDist * xDist + yDist * yDist;
+ }
+
+ /**
+ * Returns the drawable state for the key, based on the current state and type of the key.
+ * @return the drawable state of the key.
+ * @see android.graphics.drawable.StateListDrawable#setState(int[])
+ */
+ public int[] getCurrentDrawableState() {
+ int[] states = KEY_STATE_NORMAL;
+
+ if (locked) {
+ if (pressed) {
+ states = KEY_STATE_PRESSED_LOCK;
+ } else {
+ states = KEY_STATE_NORMAL_LOCK;
+ }
+ } else if (on) {
+ if (pressed) {
+ states = KEY_STATE_PRESSED_ON;
+ } else {
+ states = KEY_STATE_NORMAL_ON;
+ }
+ } else {
+ if (sticky) {
+ if (pressed) {
+ states = KEY_STATE_PRESSED_OFF;
+ } else {
+ states = KEY_STATE_NORMAL_OFF;
+ }
+ } else {
+ if (pressed) {
+ states = KEY_STATE_PRESSED;
+ }
+ }
+ }
+ return states;
+ }
+
+ public String toString() {
+ int code = (codes != null && codes.length > 0) ? codes[0] : 0;
+ String edges = (
+ ((edgeFlags & Keyboard.EDGE_LEFT) != 0 ? "L" : "-") +
+ ((edgeFlags & Keyboard.EDGE_RIGHT) != 0 ? "R" : "-") +
+ ((edgeFlags & Keyboard.EDGE_TOP) != 0 ? "T" : "-") +
+ ((edgeFlags & Keyboard.EDGE_BOTTOM) != 0 ? "B" : "-"));
+ return "KeyDebugFIXME(label=" + label +
+ (shiftLabel != null ? " shift=" + shiftLabel : "") +
+ (capsLabel != null ? " caps=" + capsLabel : "") +
+ (text != null ? " text=" + text : "" ) +
+ " code=" + code +
+ (code <= 0 || Character.isWhitespace(code) ? "" : ":'" + (char)code + "'" ) +
+ " x=" + x + ".." + (x+width) + " y=" + y + ".." + (y+height) +
+ " edgeFlags=" + edges +
+ (popupCharacters != null ? " pop=" + popupCharacters : "" ) +
+ " res=" + popupResId +
+ ")";
+ }
+ }
+
+ /**
+ * Creates a keyboard from the given xml key layout file.
+ * @param context the application or service context
+ * @param xmlLayoutResId the resource file that contains the keyboard layout and keys.
+ */
+ public Keyboard(Context context, int defaultHeight, int xmlLayoutResId) {
+ this(context, defaultHeight, xmlLayoutResId, 0);
+ }
+
+ public Keyboard(Context context, int defaultHeight, int xmlLayoutResId, int modeId) {
+ this(context, defaultHeight, xmlLayoutResId, modeId, 0);
+ }
+
+ /**
+ * Creates a keyboard from the given xml key layout file. Weeds out rows
+ * that have a keyboard mode defined but don't match the specified mode.
+ * @param context the application or service context
+ * @param xmlLayoutResId the resource file that contains the keyboard layout and keys.
+ * @param modeId keyboard mode identifier
+ * @param rowHeightPercent height of each row as percentage of screen height
+ */
+ public Keyboard(Context context, int defaultHeight, int xmlLayoutResId, int modeId, float kbHeightPercent) {
+ DisplayMetrics dm = context.getResources().getDisplayMetrics();
+ mDisplayWidth = dm.widthPixels;
+ mDisplayHeight = dm.heightPixels;
+ Log.v(TAG, "keyboard's display metrics:" + dm + ", mDisplayWidth=" + mDisplayWidth);
+
+ mDefaultHorizontalGap = 0;
+ mDefaultWidth = mDisplayWidth / 10;
+ mDefaultVerticalGap = 0;
+ mDefaultHeight = defaultHeight; // may be zero, to be adjusted below
+ mKeyboardHeight = Math.round(mDisplayHeight * kbHeightPercent / 100);
+ //Log.i("PCKeyboard", "mDefaultHeight=" + mDefaultHeight + "(arg=" + defaultHeight + ")" + " kbHeight=" + mKeyboardHeight + " displayHeight="+mDisplayHeight+")");
+ mKeys = new ArrayList<Key>();
+ mModifierKeys = new ArrayList<Key>();
+ mKeyboardMode = modeId;
+ mUseExtension = LatinIME.sKeyboardSettings.useExtension;
+ loadKeyboard(context, context.getResources().getXml(xmlLayoutResId));
+ setEdgeFlags();
+ fixAltChars(LatinIME.sKeyboardSettings.inputLocale);
+ }
+
+ /**
+ * <p>Creates a blank keyboard from the given resource file and populates it with the specified
+ * characters in left-to-right, top-to-bottom fashion, using the specified number of columns.
+ * </p>
+ * <p>If the specified number of columns is -1, then the keyboard will fit as many keys as
+ * possible in each row.</p>
+ * @param context the application or service context
+ * @param layoutTemplateResId the layout template file, containing no keys.
+ * @param characters the list of characters to display on the keyboard. One key will be created
+ * for each character.
+ * @param columns the number of columns of keys to display. If this number is greater than the
+ * number of keys that can fit in a row, it will be ignored. If this number is -1, the
+ * keyboard will fit as many keys as possible in each row.
+ */
+ private Keyboard(Context context, int defaultHeight, int layoutTemplateResId,
+ CharSequence characters, boolean reversed, int columns, int horizontalPadding) {
+ this(context, defaultHeight, layoutTemplateResId);
+ int x = 0;
+ int y = 0;
+ int column = 0;
+ mTotalWidth = 0;
+
+ Row row = new Row(this);
+ row.defaultHeight = mDefaultHeight;
+ row.defaultWidth = mDefaultWidth;
+ row.defaultHorizontalGap = mDefaultHorizontalGap;
+ row.verticalGap = mDefaultVerticalGap;
+ final int maxColumns = columns == -1 ? Integer.MAX_VALUE : columns;
+ mLayoutRows = 1;
+ int start = reversed ? characters.length()-1 : 0;
+ int end = reversed ? -1 : characters.length();
+ int step = reversed ? -1 : 1;
+ for (int i = start; i != end; i+=step) {
+ char c = characters.charAt(i);
+ if (column >= maxColumns
+ || x + mDefaultWidth + horizontalPadding > mDisplayWidth) {
+ x = 0;
+ y += mDefaultVerticalGap + mDefaultHeight;
+ column = 0;
+ ++mLayoutRows;
+ }
+ final Key key = new Key(row);
+ key.x = x;
+ key.realX = x;
+ key.y = y;
+ key.label = String.valueOf(c);
+ key.codes = key.getFromString(key.label);
+ column++;
+ x += key.width + key.gap;
+ mKeys.add(key);
+ if (x > mTotalWidth) {
+ mTotalWidth = x;
+ }
+ }
+ mTotalHeight = y + mDefaultHeight;
+ mLayoutColumns = columns == -1 ? column : maxColumns;
+ setEdgeFlags();
+ }
+
+ private void setEdgeFlags() {
+ if (mRowCount == 0) mRowCount = 1; // Assume one row if not set
+ int row = 0;
+ Key prevKey = null;
+ int rowFlags = 0;
+ for (Key key : mKeys) {
+ int keyFlags = 0;
+ if (prevKey == null || key.x <= prevKey.x) {
+ // Start new row.
+ if (prevKey != null) {
+ // Add "right edge" to rightmost key of previous row.
+ // Need to do the last key separately below.
+ prevKey.edgeFlags |= Keyboard.EDGE_RIGHT;
+ }
+
+ // Set the row flags for the current row.
+ rowFlags = 0;
+ if (row == 0) rowFlags |= Keyboard.EDGE_TOP;
+ if (row == mRowCount - 1) rowFlags |= Keyboard.EDGE_BOTTOM;
+ ++row;
+
+ // Mark current key as "left edge"
+ keyFlags |= Keyboard.EDGE_LEFT;
+ }
+ key.edgeFlags = rowFlags | keyFlags;
+ prevKey = key;
+ }
+ // Fix up the last key
+ if (prevKey != null) prevKey.edgeFlags |= Keyboard.EDGE_RIGHT;
+
+// Log.i(TAG, "setEdgeFlags() done:");
+// for (Key key : mKeys) {
+// Log.i(TAG, "key=" + key);
+// }
+ }
+
+ private void fixAltChars(Locale locale) {
+ if (locale == null) locale = Locale.getDefault();
+ Set<Character> mainKeys = new HashSet<Character>();
+ for (Key key : mKeys) {
+ // Remember characters on the main keyboard so that they can be removed from popups.
+ // This makes it easy to share popup char maps between the normal and shifted
+ // keyboards.
+ if (key.label != null && !key.modifier && key.label.length() == 1) {
+ char c = key.label.charAt(0);
+ mainKeys.add(c);
+ }
+ }
+
+ for (Key key : mKeys) {
+ if (key.popupCharacters == null) continue;
+ int popupLen = key.popupCharacters.length();
+ if (popupLen == 0) {
+ continue;
+ }
+ if (key.x >= mTotalWidth / 2) {
+ key.popupReversed = true;
+ }
+
+ // Uppercase the alt chars if the main key is uppercase
+ boolean needUpcase = key.label != null && key.label.length() == 1 && Character.isUpperCase(key.label.charAt(0));
+ if (needUpcase) {
+ key.popupCharacters = key.popupCharacters.toString().toUpperCase();
+ popupLen = key.popupCharacters.length();
+ }
+
+ StringBuilder newPopup = new StringBuilder(popupLen);
+ for (int i = 0; i < popupLen; ++i) {
+ char c = key.popupCharacters.charAt(i);
+
+ if (Character.isDigit(c) && mainKeys.contains(c)) continue; // already present elsewhere
+
+ // Skip extra digit alt keys on 5-row keyboards
+ if ((key.edgeFlags & EDGE_TOP) == 0 && Character.isDigit(c)) continue;
+
+ newPopup.append(c);
+ }
+ //Log.i("PCKeyboard", "popup for " + key.label + " '" + key.popupCharacters + "' => '"+ newPopup + "' length " + newPopup.length());
+
+ key.popupCharacters = newPopup.toString();
+ }
+ }
+
+ public List<Key> getKeys() {
+ return mKeys;
+ }
+
+ public List<Key> getModifierKeys() {
+ return mModifierKeys;
+ }
+
+ protected int getHorizontalGap() {
+ return Math.round(mDefaultHorizontalGap);
+ }
+
+ protected void setHorizontalGap(int gap) {
+ mDefaultHorizontalGap = gap;
+ }
+
+ protected int getVerticalGap() {
+ return mDefaultVerticalGap;
+ }
+
+ protected void setVerticalGap(int gap) {
+ mDefaultVerticalGap = gap;
+ }
+
+ protected int getKeyHeight() {
+ return mDefaultHeight;
+ }
+
+ protected void setKeyHeight(int height) {
+ mDefaultHeight = height;
+ }
+
+ protected int getKeyWidth() {
+ return Math.round(mDefaultWidth);
+ }
+
+ protected void setKeyWidth(int width) {
+ mDefaultWidth = width;
+ }
+
+ /**
+ * Returns the total height of the keyboard
+ * @return the total height of the keyboard
+ */
+ public int getHeight() {
+ return mTotalHeight;
+ }
+
+ public int getScreenHeight() {
+ return mDisplayHeight;
+ }
+
+ public int getMinWidth() {
+ return mTotalWidth;
+ }
+
+ public boolean setShiftState(int shiftState, boolean updateKey) {
+ //Log.i(TAG, "setShiftState " + mShiftState + " -> " + shiftState);
+ if (updateKey && mShiftKey != null) {
+ mShiftKey.on = (shiftState != SHIFT_OFF);
+ }
+ if (mShiftState != shiftState) {
+ mShiftState = shiftState;
+ return true;
+ }
+ return false;
+ }
+
+ public boolean setShiftState(int shiftState) {
+ return setShiftState(shiftState, true);
+ }
+
+ public Key setCtrlIndicator(boolean active) {
+ //Log.i(TAG, "setCtrlIndicator " + active + " ctrlKey=" + mCtrlKey);
+ if (mCtrlKey != null) mCtrlKey.on = active;
+ return mCtrlKey;
+ }
+
+ public Key setAltIndicator(boolean active) {
+ if (mAltKey != null) mAltKey.on = active;
+ return mAltKey;
+ }
+
+ public boolean isShiftCaps() {
+ return mShiftState == SHIFT_CAPS || mShiftState == SHIFT_CAPS_LOCKED;
+ }
+
+ public boolean isShifted(boolean applyCaps) {
+ if (applyCaps) {
+ return mShiftState != SHIFT_OFF;
+ } else {
+ return mShiftState == SHIFT_ON || mShiftState == SHIFT_LOCKED;
+ }
+ }
+
+ public int getShiftState() {
+ return mShiftState;
+ }
+
+ public int getShiftKeyIndex() {
+ return mShiftKeyIndex;
+ }
+
+ private void computeNearestNeighbors() {
+ // Round-up so we don't have any pixels outside the grid
+ mCellWidth = (getMinWidth() + mLayoutColumns - 1) / mLayoutColumns;
+ mCellHeight = (getHeight() + mLayoutRows - 1) / mLayoutRows;
+ mGridNeighbors = new int[mLayoutColumns * mLayoutRows][];
+ int[] indices = new int[mKeys.size()];
+ final int gridWidth = mLayoutColumns * mCellWidth;
+ final int gridHeight = mLayoutRows * mCellHeight;
+ for (int x = 0; x < gridWidth; x += mCellWidth) {
+ for (int y = 0; y < gridHeight; y += mCellHeight) {
+ int count = 0;
+ for (int i = 0; i < mKeys.size(); i++) {
+ final Key key = mKeys.get(i);
+ boolean isSpace = key.codes != null && key.codes.length > 0 &&
+ key.codes[0] == LatinIME.ASCII_SPACE;
+ if (key.squaredDistanceFrom(x, y) < mProximityThreshold ||
+ key.squaredDistanceFrom(x + mCellWidth - 1, y) < mProximityThreshold ||
+ key.squaredDistanceFrom(x + mCellWidth - 1, y + mCellHeight - 1)
+ < mProximityThreshold ||
+ key.squaredDistanceFrom(x, y + mCellHeight - 1) < mProximityThreshold ||
+ isSpace && !(
+ x + mCellWidth - 1 < key.x ||
+ x > key.x + key.width ||
+ y + mCellHeight - 1 < key.y ||
+ y > key.y + key.height)) {
+ //if (isSpace) Log.i(TAG, "space at grid" + x + "," + y);
+ indices[count++] = i;
+ }
+ }
+ int [] cell = new int[count];
+ System.arraycopy(indices, 0, cell, 0, count);
+ mGridNeighbors[(y / mCellHeight) * mLayoutColumns + (x / mCellWidth)] = cell;
+ }
+ }
+ }
+
+ /**
+ * Returns the indices of the keys that are closest to the given point.
+ * @param x the x-coordinate of the point
+ * @param y the y-coordinate of the point
+ * @return the array of integer indices for the nearest keys to the given point. If the given
+ * point is out of range, then an array of size zero is returned.
+ */
+ public int[] getNearestKeys(int x, int y) {
+ if (mGridNeighbors == null) computeNearestNeighbors();
+ if (x >= 0 && x < getMinWidth() && y >= 0 && y < getHeight()) {
+ int index = (y / mCellHeight) * mLayoutColumns + (x / mCellWidth);
+ if (index < mLayoutRows * mLayoutColumns) {
+ return mGridNeighbors[index];
+ }
+ }
+ return new int[0];
+ }
+
+ protected Row createRowFromXml(Resources res, XmlResourceParser parser) {
+ return new Row(res, this, parser);
+ }
+
+ protected Key createKeyFromXml(Resources res, Row parent, int x, int y,
+ XmlResourceParser parser) {
+ return new Key(res, parent, x, y, parser);
+ }
+
+ private void loadKeyboard(Context context, XmlResourceParser parser) {
+ boolean inKey = false;
+ boolean inRow = false;
+ float x = 0;
+ int y = 0;
+ Key key = null;
+ Row currentRow = null;
+ Resources res = context.getResources();
+ boolean skipRow = false;
+ mRowCount = 0;
+
+ try {
+ int event;
+ Key prevKey = null;
+ while ((event = parser.next()) != XmlResourceParser.END_DOCUMENT) {
+ if (event == XmlResourceParser.START_TAG) {
+ String tag = parser.getName();
+ if (TAG_ROW.equals(tag)) {
+ inRow = true;
+ x = 0;
+ currentRow = createRowFromXml(res, parser);
+ skipRow = currentRow.mode != 0 && currentRow.mode != mKeyboardMode;
+ if (currentRow.extension) {
+ if (mUseExtension) {
+ ++mExtensionRowCount;
+ } else {
+ skipRow = true;
+ }
+ }
+ if (skipRow) {
+ skipToEndOfRow(parser);
+ inRow = false;
+ }
+ } else if (TAG_KEY.equals(tag)) {
+ inKey = true;
+ key = createKeyFromXml(res, currentRow, Math.round(x), y, parser);
+ key.realX = x;
+ if (key.codes == null) {
+ // skip this key, adding its width to the previous one
+ if (prevKey != null) {
+ prevKey.width += key.width;
+ }
+ } else {
+ mKeys.add(key);
+ prevKey = key;
+ if (key.codes[0] == KEYCODE_SHIFT) {
+ if (mShiftKeyIndex == -1) {
+ mShiftKey = key;
+ mShiftKeyIndex = mKeys.size()-1;
+ }
+ mModifierKeys.add(key);
+ } else if (key.codes[0] == KEYCODE_ALT_SYM) {
+ mModifierKeys.add(key);
+ } else if (key.codes[0] == LatinKeyboardView.KEYCODE_CTRL_LEFT) {
+ mCtrlKey = key;
+ } else if (key.codes[0] == LatinKeyboardView.KEYCODE_ALT_LEFT) {
+ mAltKey = key;
+ }
+ }
+ } else if (TAG_KEYBOARD.equals(tag)) {
+ parseKeyboardAttributes(res, parser);
+ }
+ } else if (event == XmlResourceParser.END_TAG) {
+ if (inKey) {
+ inKey = false;
+ x += key.realGap + key.realWidth;
+ if (x > mTotalWidth) {
+ mTotalWidth = Math.round(x);
+ }
+ } else if (inRow) {
+ inRow = false;
+ y += currentRow.verticalGap;
+ y += currentRow.defaultHeight;
+ mRowCount++;
+ } else {
+ // TODO: error or extend?
+ }
+ }
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Parse error:" + e);
+ e.printStackTrace();
+ }
+ mTotalHeight = y - mDefaultVerticalGap;
+ }
+
+ public void setKeyboardWidth(int newWidth) {
+ Log.i(TAG, "setKeyboardWidth newWidth=" + newWidth + ", mTotalWidth=" + mTotalWidth);
+ if (newWidth <= 0) return; // view not initialized?
+ if (mTotalWidth <= newWidth) return; // it already fits
+ float scale = (float) newWidth / mDisplayWidth;
+ Log.i("PCKeyboard", "Rescaling keyboard: " + mTotalWidth + " => " + newWidth);
+ for (Key key : mKeys) {
+ key.x = Math.round(key.realX * scale);
+ }
+ mTotalWidth = newWidth;
+ }
+
+ private void skipToEndOfRow(XmlResourceParser parser)
+ throws XmlPullParserException, IOException {
+ int event;
+ while ((event = parser.next()) != XmlResourceParser.END_DOCUMENT) {
+ if (event == XmlResourceParser.END_TAG
+ && parser.getName().equals(TAG_ROW)) {
+ break;
+ }
+ }
+ }
+
+ private void parseKeyboardAttributes(Resources res, XmlResourceParser parser) {
+ TypedArray a = res.obtainAttributes(Xml.asAttributeSet(parser),
+ R.styleable.Keyboard);
+
+ mDefaultWidth = getDimensionOrFraction(a,
+ R.styleable.Keyboard_keyWidth,
+ mDisplayWidth, mDisplayWidth / 10);
+ mDefaultHeight = Math.round(getDimensionOrFraction(a,
+ R.styleable.Keyboard_keyHeight,
+ mDisplayHeight, mDefaultHeight));
+ mDefaultHorizontalGap = getDimensionOrFraction(a,
+ R.styleable.Keyboard_horizontalGap,
+ mDisplayWidth, 0);
+ mDefaultVerticalGap = Math.round(getDimensionOrFraction(a,
+ R.styleable.Keyboard_verticalGap,
+ mDisplayHeight, 0));
+ mHorizontalPad = getDimensionOrFraction(a,
+ R.styleable.Keyboard_horizontalPad,
+ mDisplayWidth, res.getDimension(R.dimen.key_horizontal_pad));
+ mVerticalPad = getDimensionOrFraction(a,
+ R.styleable.Keyboard_verticalPad,
+ mDisplayHeight, res.getDimension(R.dimen.key_vertical_pad));
+ mLayoutRows = a.getInteger(R.styleable.Keyboard_layoutRows, DEFAULT_LAYOUT_ROWS);
+ mLayoutColumns = a.getInteger(R.styleable.Keyboard_layoutColumns, DEFAULT_LAYOUT_COLUMNS);
+ if (mDefaultHeight == 0 && mKeyboardHeight > 0 && mLayoutRows > 0) {
+ mDefaultHeight = mKeyboardHeight / mLayoutRows;
+ //Log.i(TAG, "got mLayoutRows=" + mLayoutRows + ", mDefaultHeight=" + mDefaultHeight);
+ }
+ mProximityThreshold = (int) (mDefaultWidth * SEARCH_DISTANCE);
+ mProximityThreshold = mProximityThreshold * mProximityThreshold; // Square it for comparison
+ a.recycle();
+ }
+
+ static float getDimensionOrFraction(TypedArray a, int index, int base, float defValue) {
+ TypedValue value = a.peekValue(index);
+ if (value == null) return defValue;
+ if (value.type == TypedValue.TYPE_DIMENSION) {
+ return a.getDimensionPixelOffset(index, Math.round(defValue));
+ } else if (value.type == TypedValue.TYPE_FRACTION) {
+ // Round it to avoid values like 47.9999 from getting truncated
+ //return Math.round(a.getFraction(index, base, base, defValue));
+ return a.getFraction(index, base, base, defValue);
+ }
+ return defValue;
+ }
+
+ @Override
+ public String toString() {
+ return "Keyboard(" + mLayoutColumns + "x" + mLayoutRows +
+ " keys=" + mKeys.size() +
+ " rowCount=" + mRowCount +
+ " mode=" + mKeyboardMode +
+ " size=" + mTotalWidth + "x" + mTotalHeight +
+ ")";
+
+ }
+}
diff --git a/java/src/org/pocketworkstation/pckeyboard/KeyboardSwitcher.java b/java/src/org/pocketworkstation/pckeyboard/KeyboardSwitcher.java
new file mode 100644
index 0000000..b0023fb
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/KeyboardSwitcher.java
@@ -0,0 +1,685 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.pocketworkstation.pckeyboard;
+
+import android.content.SharedPreferences;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.preference.PreferenceManager;
+import android.util.Log;
+import android.view.InflateException;
+
+import java.lang.ref.SoftReference;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Locale;
+
+public class KeyboardSwitcher implements
+ SharedPreferences.OnSharedPreferenceChangeListener {
+ private static String TAG = "PCKeyboardKbSw";
+
+ public static final int MODE_NONE = 0;
+ public static final int MODE_TEXT = 1;
+ public static final int MODE_SYMBOLS = 2;
+ public static final int MODE_PHONE = 3;
+ public static final int MODE_URL = 4;
+ public static final int MODE_EMAIL = 5;
+ public static final int MODE_IM = 6;
+ public static final int MODE_WEB = 7;
+
+ // Main keyboard layouts without the settings key
+ public static final int KEYBOARDMODE_NORMAL = R.id.mode_normal;
+ public static final int KEYBOARDMODE_URL = R.id.mode_url;
+ public static final int KEYBOARDMODE_EMAIL = R.id.mode_email;
+ public static final int KEYBOARDMODE_IM = R.id.mode_im;
+ public static final int KEYBOARDMODE_WEB = R.id.mode_webentry;
+ // Main keyboard layouts with the settings key
+ public static final int KEYBOARDMODE_NORMAL_WITH_SETTINGS_KEY = R.id.mode_normal_with_settings_key;
+ public static final int KEYBOARDMODE_URL_WITH_SETTINGS_KEY = R.id.mode_url_with_settings_key;
+ public static final int KEYBOARDMODE_EMAIL_WITH_SETTINGS_KEY = R.id.mode_email_with_settings_key;
+ public static final int KEYBOARDMODE_IM_WITH_SETTINGS_KEY = R.id.mode_im_with_settings_key;
+ public static final int KEYBOARDMODE_WEB_WITH_SETTINGS_KEY = R.id.mode_webentry_with_settings_key;
+
+ // Symbols keyboard layout without the settings key
+ public static final int KEYBOARDMODE_SYMBOLS = R.id.mode_symbols;
+ // Symbols keyboard layout with the settings key
+ public static final int KEYBOARDMODE_SYMBOLS_WITH_SETTINGS_KEY = R.id.mode_symbols_with_settings_key;
+
+ public static final String DEFAULT_LAYOUT_ID = "0";
+ public static final String PREF_KEYBOARD_LAYOUT = "pref_keyboard_layout";
+ private static final int[] THEMES = new int[] {
+ R.layout.input_ics,
+ R.layout.input_gingerbread,
+ R.layout.input_stone_bold,
+ R.layout.input_trans_neon,
+ };
+
+ // Tables which contains resource ids for each character theme color
+ private static final int KBD_PHONE = R.xml.kbd_phone;
+ private static final int KBD_PHONE_SYMBOLS = R.xml.kbd_phone_symbols;
+ private static final int KBD_SYMBOLS = R.xml.kbd_symbols;
+ private static final int KBD_SYMBOLS_SHIFT = R.xml.kbd_symbols_shift;
+ private static final int KBD_QWERTY = R.xml.kbd_qwerty;
+ private static final int KBD_FULL = R.xml.kbd_full;
+ private static final int KBD_FULL_FN = R.xml.kbd_full_fn;
+ private static final int KBD_COMPACT = R.xml.kbd_compact;
+ private static final int KBD_COMPACT_FN = R.xml.kbd_compact_fn;
+
+ private LatinKeyboardView mInputView;
+ private static final int[] ALPHABET_MODES = { KEYBOARDMODE_NORMAL,
+ KEYBOARDMODE_URL, KEYBOARDMODE_EMAIL, KEYBOARDMODE_IM,
+ KEYBOARDMODE_WEB, KEYBOARDMODE_NORMAL_WITH_SETTINGS_KEY,
+ KEYBOARDMODE_URL_WITH_SETTINGS_KEY,
+ KEYBOARDMODE_EMAIL_WITH_SETTINGS_KEY,
+ KEYBOARDMODE_IM_WITH_SETTINGS_KEY,
+ KEYBOARDMODE_WEB_WITH_SETTINGS_KEY };
+
+ private LatinIME mInputMethodService;
+
+ private KeyboardId mSymbolsId;
+ private KeyboardId mSymbolsShiftedId;
+
+ private KeyboardId mCurrentId;
+ private final HashMap<KeyboardId, SoftReference<LatinKeyboard>> mKeyboards = new HashMap<KeyboardId, SoftReference<LatinKeyboard>>();
+
+ private int mMode = MODE_NONE;
+ /** One of the MODE_XXX values */
+ private int mImeOptions;
+ private boolean mIsSymbols;
+ private int mFullMode;
+ /**
+ * mIsAutoCompletionActive indicates that auto completed word will be input
+ * instead of what user actually typed.
+ */
+ private boolean mIsAutoCompletionActive;
+ private boolean mHasVoice;
+ private boolean mVoiceOnPrimary;
+ private boolean mPreferSymbols;
+
+ private static final int AUTO_MODE_SWITCH_STATE_ALPHA = 0;
+ private static final int AUTO_MODE_SWITCH_STATE_SYMBOL_BEGIN = 1;
+ private static final int AUTO_MODE_SWITCH_STATE_SYMBOL = 2;
+ // The following states are used only on the distinct multi-touch panel
+ // devices.
+ private static final int AUTO_MODE_SWITCH_STATE_MOMENTARY = 3;
+ private static final int AUTO_MODE_SWITCH_STATE_CHORDING = 4;
+ private int mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_ALPHA;
+
+ // Indicates whether or not we have the settings key
+ private boolean mHasSettingsKey;
+ private static final int SETTINGS_KEY_MODE_AUTO = R.string.settings_key_mode_auto;
+ private static final int SETTINGS_KEY_MODE_ALWAYS_SHOW = R.string.settings_key_mode_always_show;
+ // NOTE: No need to have SETTINGS_KEY_MODE_ALWAYS_HIDE here because it's not
+ // being referred to
+ // in the source code now.
+ // Default is SETTINGS_KEY_MODE_AUTO.
+ private static final int DEFAULT_SETTINGS_KEY_MODE = SETTINGS_KEY_MODE_AUTO;
+
+ private int mLastDisplayWidth;
+ private LanguageSwitcher mLanguageSwitcher;
+
+ private int mLayoutId;
+
+ private static final KeyboardSwitcher sInstance = new KeyboardSwitcher();
+
+ public static KeyboardSwitcher getInstance() {
+ return sInstance;
+ }
+
+ private KeyboardSwitcher() {
+ // Intentional empty constructor for singleton.
+ }
+
+ public static void init(LatinIME ims) {
+ sInstance.mInputMethodService = ims;
+
+ final SharedPreferences prefs = PreferenceManager
+ .getDefaultSharedPreferences(ims);
+ sInstance.mLayoutId = Integer.valueOf(prefs.getString(
+ PREF_KEYBOARD_LAYOUT, DEFAULT_LAYOUT_ID));
+
+ sInstance.updateSettingsKeyState(prefs);
+ prefs.registerOnSharedPreferenceChangeListener(sInstance);
+
+ sInstance.mSymbolsId = sInstance.makeSymbolsId(false);
+ sInstance.mSymbolsShiftedId = sInstance.makeSymbolsShiftedId(false);
+ }
+
+ /**
+ * Sets the input locale, when there are multiple locales for input. If no
+ * locale switching is required, then the locale should be set to null.
+ *
+ * @param locale
+ * the current input locale, or null for default locale with no
+ * locale button.
+ */
+ public void setLanguageSwitcher(LanguageSwitcher languageSwitcher) {
+ mLanguageSwitcher = languageSwitcher;
+ languageSwitcher.getInputLocale(); // for side effect
+ }
+
+ private KeyboardId makeSymbolsId(boolean hasVoice) {
+ if (mFullMode == 1) {
+ return new KeyboardId(KBD_COMPACT_FN, KEYBOARDMODE_SYMBOLS, true, hasVoice);
+ } else if (mFullMode == 2) {
+ return new KeyboardId(KBD_FULL_FN, KEYBOARDMODE_SYMBOLS, true, hasVoice);
+ }
+ return new KeyboardId(KBD_SYMBOLS,
+ mHasSettingsKey ? KEYBOARDMODE_SYMBOLS_WITH_SETTINGS_KEY
+ : KEYBOARDMODE_SYMBOLS, false, hasVoice);
+ }
+
+ private KeyboardId makeSymbolsShiftedId(boolean hasVoice) {
+ if (mFullMode > 0)
+ return null;
+ return new KeyboardId(KBD_SYMBOLS_SHIFT,
+ mHasSettingsKey ? KEYBOARDMODE_SYMBOLS_WITH_SETTINGS_KEY
+ : KEYBOARDMODE_SYMBOLS, false, hasVoice);
+ }
+
+ public void makeKeyboards(boolean forceCreate) {
+ mFullMode = LatinIME.sKeyboardSettings.keyboardMode;
+ mSymbolsId = makeSymbolsId(mHasVoice && !mVoiceOnPrimary);
+ mSymbolsShiftedId = makeSymbolsShiftedId(mHasVoice && !mVoiceOnPrimary);
+
+ if (forceCreate)
+ mKeyboards.clear();
+ // Configuration change is coming after the keyboard gets recreated. So
+ // don't rely on that.
+ // If keyboards have already been made, check if we have a screen width
+ // change and
+ // create the keyboard layouts again at the correct orientation
+ int displayWidth = mInputMethodService.getMaxWidth();
+ if (displayWidth == mLastDisplayWidth)
+ return;
+ mLastDisplayWidth = displayWidth;
+ if (!forceCreate)
+ mKeyboards.clear();
+ }
+
+ /**
+ * Represents the parameters necessary to construct a new LatinKeyboard,
+ * which also serve as a unique identifier for each keyboard type.
+ */
+ private static class KeyboardId {
+ // TODO: should have locale and portrait/landscape orientation?
+ public final int mXml;
+ public final int mKeyboardMode;
+ /** A KEYBOARDMODE_XXX value */
+ public final boolean mEnableShiftLock;
+ public final boolean mHasVoice;
+ public final float mKeyboardHeightPercent;
+ public final boolean mUsingExtension;
+
+ private final int mHashCode;
+
+ public KeyboardId(int xml, int mode, boolean enableShiftLock,
+ boolean hasVoice) {
+ this.mXml = xml;
+ this.mKeyboardMode = mode;
+ this.mEnableShiftLock = enableShiftLock;
+ this.mHasVoice = hasVoice;
+ this.mKeyboardHeightPercent = LatinIME.sKeyboardSettings.keyboardHeightPercent;
+ this.mUsingExtension = LatinIME.sKeyboardSettings.useExtension;
+
+ this.mHashCode = Arrays.hashCode(new Object[] { xml, mode,
+ enableShiftLock, hasVoice });
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ return other instanceof KeyboardId && equals((KeyboardId) other);
+ }
+
+ private boolean equals(KeyboardId other) {
+ return other != null
+ && other.mXml == this.mXml
+ && other.mKeyboardMode == this.mKeyboardMode
+ && other.mUsingExtension == this.mUsingExtension
+ && other.mEnableShiftLock == this.mEnableShiftLock
+ && other.mHasVoice == this.mHasVoice;
+ }
+
+ @Override
+ public int hashCode() {
+ return mHashCode;
+ }
+ }
+
+ public void setVoiceMode(boolean enableVoice, boolean voiceOnPrimary) {
+ if (enableVoice != mHasVoice || voiceOnPrimary != mVoiceOnPrimary) {
+ mKeyboards.clear();
+ }
+ mHasVoice = enableVoice;
+ mVoiceOnPrimary = voiceOnPrimary;
+ setKeyboardMode(mMode, mImeOptions, mHasVoice, mIsSymbols);
+ }
+
+ private boolean hasVoiceButton(boolean isSymbols) {
+ return mHasVoice && (isSymbols != mVoiceOnPrimary);
+ }
+
+ public void setKeyboardMode(int mode, int imeOptions, boolean enableVoice) {
+ mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_ALPHA;
+ mPreferSymbols = mode == MODE_SYMBOLS;
+ if (mode == MODE_SYMBOLS) {
+ mode = MODE_TEXT;
+ }
+ try {
+ setKeyboardMode(mode, imeOptions, enableVoice, mPreferSymbols);
+ } catch (RuntimeException e) {
+ LatinImeLogger.logOnException(mode + "," + imeOptions + ","
+ + mPreferSymbols, e);
+ }
+ }
+
+ private void setKeyboardMode(int mode, int imeOptions, boolean enableVoice,
+ boolean isSymbols) {
+ if (mInputView == null)
+ return;
+ mMode = mode;
+ mImeOptions = imeOptions;
+ if (enableVoice != mHasVoice) {
+ // TODO clean up this unnecessary recursive call.
+ setVoiceMode(enableVoice, mVoiceOnPrimary);
+ }
+ mIsSymbols = isSymbols;
+
+ mInputView.setPreviewEnabled(mInputMethodService.getPopupOn());
+
+ KeyboardId id = getKeyboardId(mode, imeOptions, isSymbols);
+ LatinKeyboard keyboard = null;
+ keyboard = getKeyboard(id);
+
+ if (mode == MODE_PHONE) {
+ mInputView.setPhoneKeyboard(keyboard);
+ }
+
+ mCurrentId = id;
+ mInputView.setKeyboard(keyboard);
+ keyboard.setShiftState(Keyboard.SHIFT_OFF);
+ keyboard.setImeOptions(mInputMethodService.getResources(), mMode,
+ imeOptions);
+ keyboard.updateSymbolIcons(mIsAutoCompletionActive);
+ }
+
+ private LatinKeyboard getKeyboard(KeyboardId id) {
+ SoftReference<LatinKeyboard> ref = mKeyboards.get(id);
+ LatinKeyboard keyboard = (ref == null) ? null : ref.get();
+ if (keyboard == null) {
+ Resources orig = mInputMethodService.getResources();
+ Configuration conf = orig.getConfiguration();
+ Locale saveLocale = conf.locale;
+ conf.locale = LatinIME.sKeyboardSettings.inputLocale;
+ orig.updateConfiguration(conf, null);
+ keyboard = new LatinKeyboard(mInputMethodService, id.mXml,
+ id.mKeyboardMode, id.mKeyboardHeightPercent);
+ keyboard.setVoiceMode(hasVoiceButton(id.mXml == R.xml.kbd_symbols), mHasVoice);
+ keyboard.setLanguageSwitcher(mLanguageSwitcher, mIsAutoCompletionActive);
+// if (isFullMode()) {
+// keyboard.setExtension(new LatinKeyboard(mInputMethodService,
+// R.xml.kbd_extension_full, 0, id.mRowHeightPercent));
+// } else if (isAlphabetMode()) { // TODO: not in full keyboard mode? Per-mode extension kbd?
+// keyboard.setExtension(new LatinKeyboard(mInputMethodService,
+// R.xml.kbd_extension, 0, id.mRowHeightPercent));
+// }
+
+ if (id.mEnableShiftLock) {
+ keyboard.enableShiftLock();
+ }
+ mKeyboards.put(id, new SoftReference<LatinKeyboard>(keyboard));
+
+ conf.locale = saveLocale;
+ orig.updateConfiguration(conf, null);
+ }
+ return keyboard;
+ }
+
+ public boolean isFullMode() {
+ return mFullMode > 0;
+ }
+
+ private KeyboardId getKeyboardId(int mode, int imeOptions, boolean isSymbols) {
+ boolean hasVoice = hasVoiceButton(isSymbols);
+ if (mFullMode > 0) {
+ switch (mode) {
+ case MODE_TEXT:
+ case MODE_URL:
+ case MODE_EMAIL:
+ case MODE_IM:
+ case MODE_WEB:
+ return new KeyboardId(mFullMode == 1 ? KBD_COMPACT : KBD_FULL,
+ KEYBOARDMODE_NORMAL, true, hasVoice);
+ }
+ }
+ // TODO: generalize for any KeyboardId
+ int keyboardRowsResId = KBD_QWERTY;
+ if (isSymbols) {
+ if (mode == MODE_PHONE) {
+ return new KeyboardId(KBD_PHONE_SYMBOLS, 0, false, hasVoice);
+ } else {
+ return new KeyboardId(
+ KBD_SYMBOLS,
+ mHasSettingsKey ? KEYBOARDMODE_SYMBOLS_WITH_SETTINGS_KEY
+ : KEYBOARDMODE_SYMBOLS, false, hasVoice);
+ }
+ }
+ switch (mode) {
+ case MODE_NONE:
+ LatinImeLogger.logOnWarning("getKeyboardId:" + mode + ","
+ + imeOptions + "," + isSymbols);
+ /* fall through */
+ case MODE_TEXT:
+ return new KeyboardId(keyboardRowsResId,
+ mHasSettingsKey ? KEYBOARDMODE_NORMAL_WITH_SETTINGS_KEY
+ : KEYBOARDMODE_NORMAL, true, hasVoice);
+ case MODE_SYMBOLS:
+ return new KeyboardId(KBD_SYMBOLS,
+ mHasSettingsKey ? KEYBOARDMODE_SYMBOLS_WITH_SETTINGS_KEY
+ : KEYBOARDMODE_SYMBOLS, false, hasVoice);
+ case MODE_PHONE:
+ return new KeyboardId(KBD_PHONE, 0, false, hasVoice);
+ case MODE_URL:
+ return new KeyboardId(keyboardRowsResId,
+ mHasSettingsKey ? KEYBOARDMODE_URL_WITH_SETTINGS_KEY
+ : KEYBOARDMODE_URL, true, hasVoice);
+ case MODE_EMAIL:
+ return new KeyboardId(keyboardRowsResId,
+ mHasSettingsKey ? KEYBOARDMODE_EMAIL_WITH_SETTINGS_KEY
+ : KEYBOARDMODE_EMAIL, true, hasVoice);
+ case MODE_IM:
+ return new KeyboardId(keyboardRowsResId,
+ mHasSettingsKey ? KEYBOARDMODE_IM_WITH_SETTINGS_KEY
+ : KEYBOARDMODE_IM, true, hasVoice);
+ case MODE_WEB:
+ return new KeyboardId(keyboardRowsResId,
+ mHasSettingsKey ? KEYBOARDMODE_WEB_WITH_SETTINGS_KEY
+ : KEYBOARDMODE_WEB, true, hasVoice);
+ }
+ return null;
+ }
+
+ public int getKeyboardMode() {
+ return mMode;
+ }
+
+ public boolean isAlphabetMode() {
+ if (mCurrentId == null) {
+ return false;
+ }
+ int currentMode = mCurrentId.mKeyboardMode;
+ if (mFullMode > 0 && currentMode == KEYBOARDMODE_NORMAL)
+ return true;
+ for (Integer mode : ALPHABET_MODES) {
+ if (currentMode == mode) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void setShiftState(int shiftState) {
+ if (mInputView != null) {
+ mInputView.setShiftState(shiftState);
+ }
+ }
+
+ public void setFn(boolean useFn) {
+ if (mInputView == null) return;
+ int oldShiftState = mInputView.getShiftState();
+ if (useFn) {
+ LatinKeyboard kbd = getKeyboard(mSymbolsId);
+ kbd.enableShiftLock();
+ mCurrentId = mSymbolsId;
+ mInputView.setKeyboard(kbd);
+ mInputView.setShiftState(oldShiftState);
+ } else {
+ // Return to default keyboard state
+ setKeyboardMode(mMode, mImeOptions, mHasVoice, false);
+ mInputView.setShiftState(oldShiftState);
+ }
+ }
+
+ public void setCtrlIndicator(boolean active) {
+ if (mInputView == null) return;
+ mInputView.setCtrlIndicator(active);
+ }
+
+ public void setAltIndicator(boolean active) {
+ if (mInputView == null) return;
+ mInputView.setAltIndicator(active);
+ }
+
+ public void toggleShift() {
+ //Log.i(TAG, "toggleShift isAlphabetMode=" + isAlphabetMode() + " mSettings.fullMode=" + mSettings.fullMode);
+ if (isAlphabetMode())
+ return;
+ if (mFullMode > 0) {
+ boolean shifted = mInputView.isShiftAll();
+ mInputView.setShiftState(shifted ? Keyboard.SHIFT_OFF : Keyboard.SHIFT_ON);
+ return;
+ }
+ if (mCurrentId.equals(mSymbolsId)
+ || !mCurrentId.equals(mSymbolsShiftedId)) {
+ LatinKeyboard symbolsShiftedKeyboard = getKeyboard(mSymbolsShiftedId);
+ mCurrentId = mSymbolsShiftedId;
+ mInputView.setKeyboard(symbolsShiftedKeyboard);
+ // Symbol shifted keyboard has a ALT_SYM key that has a caps lock style indicator.
+ // To enable the indicator, we need to set the shift state appropriately.
+ symbolsShiftedKeyboard.enableShiftLock();
+ symbolsShiftedKeyboard.setShiftState(Keyboard.SHIFT_LOCKED);
+ symbolsShiftedKeyboard.setImeOptions(mInputMethodService
+ .getResources(), mMode, mImeOptions);
+ } else {
+ LatinKeyboard symbolsKeyboard = getKeyboard(mSymbolsId);
+ mCurrentId = mSymbolsId;
+ mInputView.setKeyboard(symbolsKeyboard);
+ symbolsKeyboard.enableShiftLock();
+ symbolsKeyboard.setShiftState(Keyboard.SHIFT_OFF);
+ symbolsKeyboard.setImeOptions(mInputMethodService.getResources(),
+ mMode, mImeOptions);
+ }
+ }
+
+ public void onCancelInput() {
+ // Snap back to the previous keyboard mode if the user cancels sliding
+ // input.
+ if (mAutoModeSwitchState == AUTO_MODE_SWITCH_STATE_MOMENTARY
+ && getPointerCount() == 1)
+ mInputMethodService.changeKeyboardMode();
+ }
+
+ public void toggleSymbols() {
+ setKeyboardMode(mMode, mImeOptions, mHasVoice, !mIsSymbols);
+ if (mIsSymbols && !mPreferSymbols) {
+ mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_SYMBOL_BEGIN;
+ } else {
+ mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_ALPHA;
+ }
+ }
+
+ public boolean hasDistinctMultitouch() {
+ return mInputView != null && mInputView.hasDistinctMultitouch();
+ }
+
+ public void setAutoModeSwitchStateMomentary() {
+ mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_MOMENTARY;
+ }
+
+ public boolean isInMomentaryAutoModeSwitchState() {
+ return mAutoModeSwitchState == AUTO_MODE_SWITCH_STATE_MOMENTARY;
+ }
+
+ public boolean isInChordingAutoModeSwitchState() {
+ return mAutoModeSwitchState == AUTO_MODE_SWITCH_STATE_CHORDING;
+ }
+
+ public boolean isVibrateAndSoundFeedbackRequired() {
+ return mInputView != null && !mInputView.isInSlidingKeyInput();
+ }
+
+ private int getPointerCount() {
+ return mInputView == null ? 0 : mInputView.getPointerCount();
+ }
+
+ /**
+ * Updates state machine to figure out when to automatically snap back to
+ * the previous mode.
+ */
+ public void onKey(int key) {
+ // Switch back to alpha mode if user types one or more non-space/enter
+ // characters
+ // followed by a space/enter
+ switch (mAutoModeSwitchState) {
+ case AUTO_MODE_SWITCH_STATE_MOMENTARY:
+ // Only distinct multi touch devices can be in this state.
+ // On non-distinct multi touch devices, mode change key is handled
+ // by {@link onKey},
+ // not by {@link onPress} and {@link onRelease}. So, on such
+ // devices,
+ // {@link mAutoModeSwitchState} starts from {@link
+ // AUTO_MODE_SWITCH_STATE_SYMBOL_BEGIN},
+ // or {@link AUTO_MODE_SWITCH_STATE_ALPHA}, not from
+ // {@link AUTO_MODE_SWITCH_STATE_MOMENTARY}.
+ if (key == LatinKeyboard.KEYCODE_MODE_CHANGE) {
+ // Detected only the mode change key has been pressed, and then
+ // released.
+ if (mIsSymbols) {
+ mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_SYMBOL_BEGIN;
+ } else {
+ mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_ALPHA;
+ }
+ } else if (getPointerCount() == 1) {
+ // Snap back to the previous keyboard mode if the user pressed
+ // the mode change key
+ // and slid to other key, then released the finger.
+ // If the user cancels the sliding input, snapping back to the
+ // previous keyboard
+ // mode is handled by {@link #onCancelInput}.
+ mInputMethodService.changeKeyboardMode();
+ } else {
+ // Chording input is being started. The keyboard mode will be
+ // snapped back to the
+ // previous mode in {@link onReleaseSymbol} when the mode change
+ // key is released.
+ mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_CHORDING;
+ }
+ break;
+ case AUTO_MODE_SWITCH_STATE_SYMBOL_BEGIN:
+ if (key != LatinIME.ASCII_SPACE && key != LatinIME.ASCII_ENTER
+ && key >= 0) {
+ mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_SYMBOL;
+ }
+ break;
+ case AUTO_MODE_SWITCH_STATE_SYMBOL:
+ // Snap back to alpha keyboard mode if user types one or more
+ // non-space/enter
+ // characters followed by a space/enter.
+ if (key == LatinIME.ASCII_ENTER || key == LatinIME.ASCII_SPACE) {
+ mInputMethodService.changeKeyboardMode();
+ }
+ break;
+ }
+ }
+
+ public LatinKeyboardView getInputView() {
+ return mInputView;
+ }
+
+ public void recreateInputView() {
+ changeLatinKeyboardView(mLayoutId, true);
+ }
+
+ private void changeLatinKeyboardView(int newLayout, boolean forceReset) {
+ if (mLayoutId != newLayout || mInputView == null || forceReset) {
+ if (mInputView != null) {
+ mInputView.closing();
+ }
+ if (THEMES.length <= newLayout) {
+ newLayout = Integer.valueOf(DEFAULT_LAYOUT_ID);
+ }
+
+ LatinIMEUtil.GCUtils.getInstance().reset();
+ boolean tryGC = true;
+ for (int i = 0; i < LatinIMEUtil.GCUtils.GC_TRY_LOOP_MAX && tryGC; ++i) {
+ try {
+ mInputView = (LatinKeyboardView) mInputMethodService
+ .getLayoutInflater().inflate(THEMES[newLayout],
+ null);
+ tryGC = false;
+ } catch (OutOfMemoryError e) {
+ tryGC = LatinIMEUtil.GCUtils.getInstance().tryGCOrWait(
+ mLayoutId + "," + newLayout, e);
+ } catch (InflateException e) {
+ tryGC = LatinIMEUtil.GCUtils.getInstance().tryGCOrWait(
+ mLayoutId + "," + newLayout, e);
+ }
+ }
+ mInputView.setExtensionLayoutResId(THEMES[newLayout]);
+ mInputView.setOnKeyboardActionListener(mInputMethodService);
+ mInputView.setPadding(0, 0, 0, 0);
+ mLayoutId = newLayout;
+ }
+ mInputMethodService.mHandler.post(new Runnable() {
+ public void run() {
+ if (mInputView != null) {
+ mInputMethodService.setInputView(mInputView);
+ }
+ mInputMethodService.updateInputViewShown();
+ }
+ });
+ }
+
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
+ String key) {
+ if (PREF_KEYBOARD_LAYOUT.equals(key)) {
+ changeLatinKeyboardView(Integer.valueOf(sharedPreferences
+ .getString(key, DEFAULT_LAYOUT_ID)), true);
+ } else if (LatinIMESettings.PREF_SETTINGS_KEY.equals(key)) {
+ updateSettingsKeyState(sharedPreferences);
+ recreateInputView();
+ }
+ }
+
+ public void onAutoCompletionStateChanged(boolean isAutoCompletion) {
+ if (isAutoCompletion != mIsAutoCompletionActive) {
+ LatinKeyboardView keyboardView = getInputView();
+ mIsAutoCompletionActive = isAutoCompletion;
+ keyboardView.invalidateKey(((LatinKeyboard) keyboardView
+ .getKeyboard())
+ .onAutoCompletionStateChanged(isAutoCompletion));
+ }
+ }
+
+ private void updateSettingsKeyState(SharedPreferences prefs) {
+ Resources resources = mInputMethodService.getResources();
+ final String settingsKeyMode = prefs.getString(
+ LatinIMESettings.PREF_SETTINGS_KEY, resources
+ .getString(DEFAULT_SETTINGS_KEY_MODE));
+ // We show the settings key when 1) SETTINGS_KEY_MODE_ALWAYS_SHOW or
+ // 2) SETTINGS_KEY_MODE_AUTO and there are two or more enabled IMEs on
+ // the system
+ if (settingsKeyMode.equals(resources
+ .getString(SETTINGS_KEY_MODE_ALWAYS_SHOW))
+ || (settingsKeyMode.equals(resources
+ .getString(SETTINGS_KEY_MODE_AUTO)))) {
+ mHasSettingsKey = true;
+ } else {
+ mHasSettingsKey = false;
+ }
+ }
+}
diff --git a/java/src/org/pocketworkstation/pckeyboard/LanguageSwitcher.java b/java/src/org/pocketworkstation/pckeyboard/LanguageSwitcher.java
new file mode 100644
index 0000000..5807c12
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/LanguageSwitcher.java
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.pocketworkstation.pckeyboard;
+
+import java.util.Locale;
+
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import android.preference.PreferenceManager;
+import android.text.TextUtils;
+import android.util.Log;
+
+/**
+ * Keeps track of list of selected input languages and the current
+ * input language that the user has selected.
+ */
+public class LanguageSwitcher {
+
+ private static final String TAG = "HK/LanguageSwitcher";
+ private Locale[] mLocales;
+ private LatinIME mIme;
+ private String[] mSelectedLanguageArray;
+ private String mSelectedLanguages;
+ private int mCurrentIndex = 0;
+ private String mDefaultInputLanguage;
+ private Locale mDefaultInputLocale;
+ private Locale mSystemLocale;
+
+ public LanguageSwitcher(LatinIME ime) {
+ mIme = ime;
+ mLocales = new Locale[0];
+ }
+
+ public Locale[] getLocales() {
+ return mLocales;
+ }
+
+ public int getLocaleCount() {
+ return mLocales.length;
+ }
+
+ /**
+ * Loads the currently selected input languages from shared preferences.
+ * @param sp
+ * @return whether there was any change
+ */
+ public boolean loadLocales(SharedPreferences sp) {
+ String selectedLanguages = sp.getString(LatinIME.PREF_SELECTED_LANGUAGES, null);
+ String currentLanguage = sp.getString(LatinIME.PREF_INPUT_LANGUAGE, null);
+ if (selectedLanguages == null || selectedLanguages.length() < 1) {
+ loadDefaults();
+ if (mLocales.length == 0) {
+ return false;
+ }
+ mLocales = new Locale[0];
+ return true;
+ }
+ if (selectedLanguages.equals(mSelectedLanguages)) {
+ return false;
+ }
+ mSelectedLanguageArray = selectedLanguages.split(",");
+ mSelectedLanguages = selectedLanguages; // Cache it for comparison later
+ constructLocales();
+ mCurrentIndex = 0;
+ if (currentLanguage != null) {
+ // Find the index
+ mCurrentIndex = 0;
+ for (int i = 0; i < mLocales.length; i++) {
+ if (mSelectedLanguageArray[i].equals(currentLanguage)) {
+ mCurrentIndex = i;
+ break;
+ }
+ }
+ // If we didn't find the index, use the first one
+ }
+ return true;
+ }
+
+ private void loadDefaults() {
+ mDefaultInputLocale = mIme.getResources().getConfiguration().locale;
+ String country = mDefaultInputLocale.getCountry();
+ mDefaultInputLanguage = mDefaultInputLocale.getLanguage() +
+ (TextUtils.isEmpty(country) ? "" : "_" + country);
+ }
+
+ private void constructLocales() {
+ mLocales = new Locale[mSelectedLanguageArray.length];
+ for (int i = 0; i < mLocales.length; i++) {
+ final String lang = mSelectedLanguageArray[i];
+ mLocales[i] = new Locale(lang.substring(0, 2),
+ lang.length() > 4 ? lang.substring(3, 5) : "");
+ }
+ }
+
+ /**
+ * Returns the currently selected input language code, or the display language code if
+ * no specific locale was selected for input.
+ */
+ public String getInputLanguage() {
+ if (getLocaleCount() == 0) return mDefaultInputLanguage;
+
+ return mSelectedLanguageArray[mCurrentIndex];
+ }
+
+ public boolean allowAutoCap() {
+ String lang = getInputLanguage();
+ if (lang.length() > 2) lang = lang.substring(0, 2);
+ return !InputLanguageSelection.NOCAPS_LANGUAGES.contains(lang);
+ }
+
+ public boolean allowDeadKeys() {
+ String lang = getInputLanguage();
+ if (lang.length() > 2) lang = lang.substring(0, 2);
+ return !InputLanguageSelection.NODEADKEY_LANGUAGES.contains(lang);
+ }
+
+ public boolean allowAutoSpace() {
+ String lang = getInputLanguage();
+ if (lang.length() > 2) lang = lang.substring(0, 2);
+ return !InputLanguageSelection.NOAUTOSPACE_LANGUAGES.contains(lang);
+ }
+
+ /**
+ * Returns the list of enabled language codes.
+ */
+ public String[] getEnabledLanguages() {
+ return mSelectedLanguageArray;
+ }
+
+ /**
+ * Returns the currently selected input locale, or the display locale if no specific
+ * locale was selected for input.
+ * @return
+ */
+ public Locale getInputLocale() {
+ Locale locale;
+ if (getLocaleCount() == 0) {
+ locale = mDefaultInputLocale;
+ } else {
+ locale = mLocales[mCurrentIndex];
+ }
+ LatinIME.sKeyboardSettings.inputLocale = (locale != null) ? locale : Locale.getDefault();
+ return locale;
+ }
+
+ /**
+ * Returns the next input locale in the list. Wraps around to the beginning of the
+ * list if we're at the end of the list.
+ * @return
+ */
+ public Locale getNextInputLocale() {
+ if (getLocaleCount() == 0) return mDefaultInputLocale;
+
+ return mLocales[(mCurrentIndex + 1) % mLocales.length];
+ }
+
+ /**
+ * Sets the system locale (display UI) used for comparing with the input language.
+ * @param locale the locale of the system
+ */
+ public void setSystemLocale(Locale locale) {
+ mSystemLocale = locale;
+ }
+
+ /**
+ * Returns the system locale.
+ * @return the system locale
+ */
+ public Locale getSystemLocale() {
+ return mSystemLocale;
+ }
+
+ /**
+ * Returns the previous input locale in the list. Wraps around to the end of the
+ * list if we're at the beginning of the list.
+ * @return
+ */
+ public Locale getPrevInputLocale() {
+ if (getLocaleCount() == 0) return mDefaultInputLocale;
+
+ return mLocales[(mCurrentIndex - 1 + mLocales.length) % mLocales.length];
+ }
+
+ public void reset() {
+ mCurrentIndex = 0;
+ mSelectedLanguages = "";
+ loadLocales(PreferenceManager.getDefaultSharedPreferences(mIme));
+ }
+
+ public void next() {
+ mCurrentIndex++;
+ if (mCurrentIndex >= mLocales.length) mCurrentIndex = 0; // Wrap around
+ }
+
+ public void prev() {
+ mCurrentIndex--;
+ if (mCurrentIndex < 0) mCurrentIndex = mLocales.length - 1; // Wrap around
+ }
+
+ public void persist() {
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mIme);
+ Editor editor = sp.edit();
+ editor.putString(LatinIME.PREF_INPUT_LANGUAGE, getInputLanguage());
+ SharedPreferencesCompat.apply(editor);
+ }
+
+ static String toTitleCase(String s) {
+ if (s.length() == 0) {
+ return s;
+ }
+
+ return Character.toUpperCase(s.charAt(0)) + s.substring(1);
+ }
+}
diff --git a/java/src/org/pocketworkstation/pckeyboard/LatinIME.java b/java/src/org/pocketworkstation/pckeyboard/LatinIME.java
new file mode 100644
index 0000000..5710549
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/LatinIME.java
@@ -0,0 +1,3976 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.pocketworkstation.pckeyboard;
+
+import org.pocketworkstation.pckeyboard.LatinIMEUtil.RingCharBuffer;
+
+import com.android.inputmethod.voice.FieldContext;
+import com.android.inputmethod.voice.SettingsUtil;
+import com.android.inputmethod.voice.VoiceInput;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import android.app.AlertDialog;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.SharedPreferences;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.content.res.XmlResourceParser;
+import android.inputmethodservice.InputMethodService;
+import android.media.AudioManager;
+import android.os.Debug;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.SystemClock;
+import android.os.Vibrator;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceManager;
+import android.speech.SpeechRecognizer;
+import android.text.ClipboardManager;
+import android.text.TextUtils;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.util.PrintWriterPrinter;
+import android.util.Printer;
+import android.view.HapticFeedbackConstants;
+import android.view.KeyCharacterMap;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewParent;
+import android.view.Window;
+import android.view.WindowManager;
+import android.view.inputmethod.CompletionInfo;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.ExtractedText;
+import android.view.inputmethod.ExtractedTextRequest;
+import android.view.inputmethod.InputConnection;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.LinearLayout;
+import android.widget.Toast;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+
+/**
+ * Input method implementation for Qwerty'ish keyboard.
+ */
+public class LatinIME extends InputMethodService implements
+ ComposeSequencing,
+ LatinKeyboardBaseView.OnKeyboardActionListener, VoiceInput.UiListener,
+ SharedPreferences.OnSharedPreferenceChangeListener {
+ private static final String TAG = "PCKeyboardIME";
+ private static final boolean PERF_DEBUG = false;
+ static final boolean DEBUG = false;
+ static final boolean TRACE = false;
+ static final boolean VOICE_INSTALLED = true;
+ static final boolean ENABLE_VOICE_BUTTON = true;
+ static Map<Integer, String> ESC_SEQUENCES;
+ static Map<Integer, Integer> CTRL_SEQUENCES;
+
+ private static final String PREF_VIBRATE_ON = "vibrate_on";
+ static final String PREF_VIBRATE_LEN = "vibrate_len";
+ private static final String PREF_SOUND_ON = "sound_on";
+ private static final String PREF_POPUP_ON = "popup_on";
+ private static final String PREF_AUTO_CAP = "auto_cap";
+ private static final String PREF_QUICK_FIXES = "quick_fixes";
+ private static final String PREF_SHOW_SUGGESTIONS = "show_suggestions";
+ private static final String PREF_AUTO_COMPLETE = "auto_complete";
+ // private static final String PREF_BIGRAM_SUGGESTIONS =
+ // "bigram_suggestion";
+ private static final String PREF_VOICE_MODE = "voice_mode";
+
+ // Whether or not the user has used voice input before (and thus, whether to
+ // show the
+ // first-run warning dialog or not).
+ private static final String PREF_HAS_USED_VOICE_INPUT = "has_used_voice_input";
+
+ // Whether or not the user has used voice input from an unsupported locale
+ // UI before.
+ // For example, the user has a Chinese UI but activates voice input.
+ private static final String PREF_HAS_USED_VOICE_INPUT_UNSUPPORTED_LOCALE = "has_used_voice_input_unsupported_locale";
+
+ // A list of locales which are supported by default for voice input, unless
+ // we get a
+ // different list from Gservices.
+ public static final String DEFAULT_VOICE_INPUT_SUPPORTED_LOCALES = "en "
+ + "en_US " + "en_GB " + "en_AU " + "en_CA " + "en_IE " + "en_IN "
+ + "en_NZ " + "en_SG " + "en_ZA ";
+
+ // The private IME option used to indicate that no microphone should be
+ // shown for a
+ // given text field. For instance this is specified by the search dialog
+ // when the
+ // dialog is already showing a voice search button.
+ private static final String IME_OPTION_NO_MICROPHONE = "nm";
+
+ public static final String PREF_SELECTED_LANGUAGES = "selected_languages";
+ public static final String PREF_INPUT_LANGUAGE = "input_language";
+ private static final String PREF_RECORRECTION_ENABLED = "recorrection_enabled";
+ static final String PREF_FULLSCREEN_OVERRIDE = "fullscreen_override";
+ static final String PREF_FORCE_KEYBOARD_ON = "force_keyboard_on";
+ static final String PREF_KEYBOARD_NOTIFICATION = "keyboard_notification";
+ static final String PREF_CONNECTBOT_TAB_HACK = "connectbot_tab_hack";
+ static final String PREF_FULL_KEYBOARD_IN_PORTRAIT = "full_keyboard_in_portrait";
+ static final String PREF_SUGGESTIONS_IN_LANDSCAPE = "suggestions_in_landscape";
+ static final String PREF_HEIGHT_PORTRAIT = "settings_height_portrait";
+ static final String PREF_HEIGHT_LANDSCAPE = "settings_height_landscape";
+ static final String PREF_HINT_MODE = "pref_hint_mode";
+ static final String PREF_LONGPRESS_TIMEOUT = "pref_long_press_duration";
+ static final String PREF_RENDER_MODE = "pref_render_mode";
+ static final String PREF_SWIPE_UP = "pref_swipe_up";
+ static final String PREF_SWIPE_DOWN = "pref_swipe_down";
+ static final String PREF_SWIPE_LEFT = "pref_swipe_left";
+ static final String PREF_SWIPE_RIGHT = "pref_swipe_right";
+ static final String PREF_VOL_UP = "pref_vol_up";
+ static final String PREF_VOL_DOWN = "pref_vol_down";
+
+ private static final int MSG_UPDATE_SUGGESTIONS = 0;
+ private static final int MSG_START_TUTORIAL = 1;
+ private static final int MSG_UPDATE_SHIFT_STATE = 2;
+ private static final int MSG_VOICE_RESULTS = 3;
+ private static final int MSG_UPDATE_OLD_SUGGESTIONS = 4;
+
+ // How many continuous deletes at which to start deleting at a higher speed.
+ private static final int DELETE_ACCELERATE_AT = 20;
+ // Key events coming any faster than this are long-presses.
+ private static final int QUICK_PRESS = 200;
+
+ static final int ASCII_ENTER = '\n';
+ static final int ASCII_SPACE = ' ';
+ static final int ASCII_PERIOD = '.';
+
+ // Contextual menu positions
+ private static final int POS_METHOD = 0;
+ private static final int POS_SETTINGS = 1;
+
+ // private LatinKeyboardView mInputView;
+ private LinearLayout mCandidateViewContainer;
+ private CandidateView mCandidateView;
+ private Suggest mSuggest;
+ private CompletionInfo[] mCompletions;
+
+ private AlertDialog mOptionsDialog;
+ private AlertDialog mVoiceWarningDialog;
+
+ /* package */KeyboardSwitcher mKeyboardSwitcher;
+
+ private UserDictionary mUserDictionary;
+ private UserBigramDictionary mUserBigramDictionary;
+ private ContactsDictionary mContactsDictionary;
+ private AutoDictionary mAutoDictionary;
+
+ private Hints mHints;
+
+ private Resources mResources;
+
+ private String mInputLocale;
+ private String mSystemLocale;
+ private LanguageSwitcher mLanguageSwitcher;
+
+ private StringBuilder mComposing = new StringBuilder();
+ private WordComposer mWord = new WordComposer();
+ private int mCommittedLength;
+ private boolean mPredicting;
+ private boolean mRecognizing;
+ private boolean mAfterVoiceInput;
+ private boolean mImmediatelyAfterVoiceInput;
+ private boolean mShowingVoiceSuggestions;
+ private boolean mVoiceInputHighlighted;
+ private boolean mEnableVoiceButton;
+ private CharSequence mBestWord;
+ private boolean mPredictionOnForMode;
+ private boolean mPredictionOnPref;
+ private boolean mCompletionOn;
+ private boolean mHasDictionary;
+ private boolean mAutoSpace;
+ private boolean mJustAddedAutoSpace;
+ private boolean mAutoCorrectEnabled;
+ private boolean mReCorrectionEnabled;
+ // Bigram Suggestion is disabled in this version.
+ private final boolean mBigramSuggestionEnabled = false;
+ private boolean mAutoCorrectOn;
+ // TODO move this state variable outside LatinIME
+ private boolean mModCtrl;
+ private boolean mModAlt;
+ private boolean mModFn;
+ // Saved shift state when leaving alphabet mode, or when applying multitouch shift
+ private int mSavedShiftState;
+ private boolean mPasswordText;
+ private boolean mVibrateOn;
+ private int mVibrateLen;
+ private boolean mSoundOn;
+ private boolean mPopupOn;
+ private boolean mAutoCapPref;
+ private boolean mAutoCapActive;
+ private boolean mDeadKeysActive;
+ private boolean mQuickFixes;
+ private boolean mHasUsedVoiceInput;
+ private boolean mHasUsedVoiceInputUnsupportedLocale;
+ private boolean mLocaleSupportedForVoiceInput;
+ private boolean mShowSuggestions;
+ private boolean mIsShowingHint;
+ private boolean mConnectbotTabHack;
+ private boolean mFullscreenOverride;
+ private boolean mForceKeyboardOn;
+ private boolean mKeyboardNotification;
+ private boolean mSuggestionsInLandscape;
+ private boolean mSuggestionForceOn;
+ private boolean mSuggestionForceOff;
+ private String mSwipeUpAction;
+ private String mSwipeDownAction;
+ private String mSwipeLeftAction;
+ private String mSwipeRightAction;
+ private String mVolUpAction;
+ private String mVolDownAction;
+
+ public static final GlobalKeyboardSettings sKeyboardSettings = new GlobalKeyboardSettings();
+
+ private int mHeightPortrait;
+ private int mHeightLandscape;
+ private int mNumKeyboardModes = 3;
+ private int mKeyboardModeOverridePortrait;
+ private int mKeyboardModeOverrideLandscape;
+ private int mCorrectionMode;
+ private boolean mEnableVoice = true;
+ private boolean mVoiceOnPrimary;
+ private int mOrientation;
+ private List<CharSequence> mSuggestPuncList;
+ // Keep track of the last selection range to decide if we need to show word
+ // alternatives
+ private int mLastSelectionStart;
+ private int mLastSelectionEnd;
+
+ // Input type is such that we should not auto-correct
+ private boolean mInputTypeNoAutoCorrect;
+
+ // Indicates whether the suggestion strip is to be on in landscape
+ private boolean mJustAccepted;
+ private CharSequence mJustRevertedSeparator;
+ private int mDeleteCount;
+ private long mLastKeyTime;
+
+ // Modifier keys state
+ private ModifierKeyState mShiftKeyState = new ModifierKeyState();
+ private ModifierKeyState mSymbolKeyState = new ModifierKeyState();
+ private ModifierKeyState mCtrlKeyState = new ModifierKeyState();
+ private ModifierKeyState mAltKeyState = new ModifierKeyState();
+ private ModifierKeyState mFnKeyState = new ModifierKeyState();
+
+ // Compose sequence handling
+ private boolean mComposeMode = false;
+ private ComposeBase mComposeBuffer = new ComposeSequence(this);
+ private ComposeBase mDeadAccentBuffer = new DeadAccentSequence(this);
+
+ private Tutorial mTutorial;
+
+ private AudioManager mAudioManager;
+ // Align sound effect volume on music volume
+ private final float FX_VOLUME = -1.0f;
+ private final float FX_VOLUME_RANGE_DB = 72.0f;
+ private boolean mSilentMode;
+
+ /* package */String mWordSeparators;
+ private String mSentenceSeparators;
+ private VoiceInput mVoiceInput;
+ private VoiceResults mVoiceResults = new VoiceResults();
+ private boolean mConfigurationChanging;
+
+ // Keeps track of most recently inserted text (multi-character key) for
+ // reverting
+ private CharSequence mEnteredText;
+ private boolean mRefreshKeyboardRequired;
+
+ // For each word, a list of potential replacements, usually from voice.
+ private Map<String, List<CharSequence>> mWordToSuggestions = new HashMap<String, List<CharSequence>>();
+
+ private ArrayList<WordAlternatives> mWordHistory = new ArrayList<WordAlternatives>();
+
+ private PluginManager mPluginManager;
+ private NotificationReceiver mNotificationReceiver;
+
+ private class VoiceResults {
+ List<String> candidates;
+ Map<String, List<CharSequence>> alternatives;
+ }
+
+ public abstract static class WordAlternatives {
+ protected CharSequence mChosenWord;
+
+ public WordAlternatives() {
+ // Nothing
+ }
+
+ public WordAlternatives(CharSequence chosenWord) {
+ mChosenWord = chosenWord;
+ }
+
+ @Override
+ public int hashCode() {
+ return mChosenWord.hashCode();
+ }
+
+ public abstract CharSequence getOriginalWord();
+
+ public CharSequence getChosenWord() {
+ return mChosenWord;
+ }
+
+ public abstract List<CharSequence> getAlternatives();
+ }
+
+ public class TypedWordAlternatives extends WordAlternatives {
+ private WordComposer word;
+
+ public TypedWordAlternatives() {
+ // Nothing
+ }
+
+ public TypedWordAlternatives(CharSequence chosenWord,
+ WordComposer wordComposer) {
+ super(chosenWord);
+ word = wordComposer;
+ }
+
+ @Override
+ public CharSequence getOriginalWord() {
+ return word.getTypedWord();
+ }
+
+ @Override
+ public List<CharSequence> getAlternatives() {
+ return getTypedSuggestions(word);
+ }
+ }
+
+ /* package */Handler mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_UPDATE_SUGGESTIONS:
+ updateSuggestions();
+ break;
+ case MSG_UPDATE_OLD_SUGGESTIONS:
+ setOldSuggestions();
+ break;
+ case MSG_START_TUTORIAL:
+ if (mTutorial == null) {
+ if (mKeyboardSwitcher.getInputView().isShown()) {
+ mTutorial = new Tutorial(LatinIME.this,
+ mKeyboardSwitcher.getInputView());
+ mTutorial.start();
+ } else {
+ // Try again soon if the view is not yet showing
+ sendMessageDelayed(obtainMessage(MSG_START_TUTORIAL),
+ 100);
+ }
+ }
+ break;
+ case MSG_UPDATE_SHIFT_STATE:
+ updateShiftKeyState(getCurrentInputEditorInfo());
+ break;
+ case MSG_VOICE_RESULTS:
+ handleVoiceResults();
+ break;
+ }
+ }
+ };
+
+ @Override
+ public void onCreate() {
+ Log.i("PCKeyboard", "onCreate(), os.version=" + System.getProperty("os.version"));
+ LatinImeLogger.init(this);
+ KeyboardSwitcher.init(this);
+ super.onCreate();
+ // setStatusIcon(R.drawable.ime_qwerty);
+ mResources = getResources();
+ final Configuration conf = mResources.getConfiguration();
+ mOrientation = conf.orientation;
+ final SharedPreferences prefs = PreferenceManager
+ .getDefaultSharedPreferences(this);
+ mLanguageSwitcher = new LanguageSwitcher(this);
+ mLanguageSwitcher.loadLocales(prefs);
+ mKeyboardSwitcher = KeyboardSwitcher.getInstance();
+ mKeyboardSwitcher.setLanguageSwitcher(mLanguageSwitcher);
+ mSystemLocale = conf.locale.toString();
+ mLanguageSwitcher.setSystemLocale(conf.locale);
+ String inputLanguage = mLanguageSwitcher.getInputLanguage();
+ if (inputLanguage == null) {
+ inputLanguage = conf.locale.toString();
+ }
+ Resources res = getResources();
+ mReCorrectionEnabled = prefs.getBoolean(PREF_RECORRECTION_ENABLED,
+ res.getBoolean(R.bool.default_recorrection_enabled));
+ mConnectbotTabHack = prefs.getBoolean(PREF_CONNECTBOT_TAB_HACK,
+ res.getBoolean(R.bool.default_connectbot_tab_hack));
+ mFullscreenOverride = prefs.getBoolean(PREF_FULLSCREEN_OVERRIDE,
+ res.getBoolean(R.bool.default_fullscreen_override));
+ mForceKeyboardOn = prefs.getBoolean(PREF_FORCE_KEYBOARD_ON,
+ res.getBoolean(R.bool.default_force_keyboard_on));
+ mKeyboardNotification = prefs.getBoolean(PREF_KEYBOARD_NOTIFICATION,
+ res.getBoolean(R.bool.default_keyboard_notification));
+ mSuggestionsInLandscape = prefs.getBoolean(PREF_SUGGESTIONS_IN_LANDSCAPE,
+ res.getBoolean(R.bool.default_suggestions_in_landscape));
+ mHeightPortrait = getHeight(prefs, PREF_HEIGHT_PORTRAIT, res.getString(R.string.default_height_portrait));
+ mHeightLandscape = getHeight(prefs, PREF_HEIGHT_LANDSCAPE, res.getString(R.string.default_height_landscape));
+ LatinIME.sKeyboardSettings.hintMode = Integer.parseInt(prefs.getString(PREF_HINT_MODE, res.getString(R.string.default_hint_mode)));
+ LatinIME.sKeyboardSettings.longpressTimeout = getPrefInt(prefs, PREF_LONGPRESS_TIMEOUT, res.getString(R.string.default_long_press_duration));
+ LatinIME.sKeyboardSettings.renderMode = getPrefInt(prefs, PREF_RENDER_MODE, res.getString(R.string.default_render_mode));
+ mSwipeUpAction = prefs.getString(PREF_SWIPE_UP, res.getString(R.string.default_swipe_up));
+ mSwipeDownAction = prefs.getString(PREF_SWIPE_DOWN, res.getString(R.string.default_swipe_down));
+ mSwipeLeftAction = prefs.getString(PREF_SWIPE_LEFT, res.getString(R.string.default_swipe_left));
+ mSwipeRightAction = prefs.getString(PREF_SWIPE_RIGHT, res.getString(R.string.default_swipe_right));
+ mVolUpAction = prefs.getString(PREF_VOL_UP, res.getString(R.string.default_vol_up));
+ mVolDownAction = prefs.getString(PREF_VOL_DOWN, res.getString(R.string.default_vol_down));
+ sKeyboardSettings.initPrefs(prefs, res);
+
+ updateKeyboardOptions();
+
+ PluginManager.getPluginDictionaries(getApplicationContext());
+ mPluginManager = new PluginManager(this);
+ final IntentFilter pFilter = new IntentFilter();
+ pFilter.addDataScheme("package");
+ pFilter.addAction("android.intent.action.PACKAGE_ADDED");
+ pFilter.addAction("android.intent.action.PACKAGE_REPLACED");
+ pFilter.addAction("android.intent.action.PACKAGE_REMOVED");
+ registerReceiver(mPluginManager, pFilter);
+
+ LatinIMEUtil.GCUtils.getInstance().reset();
+ boolean tryGC = true;
+ for (int i = 0; i < LatinIMEUtil.GCUtils.GC_TRY_LOOP_MAX && tryGC; ++i) {
+ try {
+ initSuggest(inputLanguage);
+ tryGC = false;
+ } catch (OutOfMemoryError e) {
+ tryGC = LatinIMEUtil.GCUtils.getInstance().tryGCOrWait(
+ inputLanguage, e);
+ }
+ }
+
+ mOrientation = conf.orientation;
+
+ // register to receive ringer mode changes for silent mode
+ IntentFilter filter = new IntentFilter(
+ AudioManager.RINGER_MODE_CHANGED_ACTION);
+ registerReceiver(mReceiver, filter);
+ if (VOICE_INSTALLED) {
+ mVoiceInput = new VoiceInput(this, this);
+ mHints = new Hints(this, new Hints.Display() {
+ public void showHint(int viewResource) {
+ LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ View view = inflater.inflate(viewResource, null);
+ setCandidatesView(view);
+ setCandidatesViewShown(true);
+ mIsShowingHint = true;
+ }
+ });
+ }
+ prefs.registerOnSharedPreferenceChangeListener(this);
+ setNotification(mKeyboardNotification);
+ }
+
+ private int getKeyboardModeNum(int origMode, int override) {
+ if (mNumKeyboardModes == 2 && origMode == 2) origMode = 1; // skip "compact". FIXME!
+ int num = (origMode + override) % mNumKeyboardModes;
+ if (mNumKeyboardModes == 2 && num == 1) num = 2; // skip "compact". FIXME!
+ return num;
+ }
+
+ private void updateKeyboardOptions() {
+ //Log.i(TAG, "setFullKeyboardOptions " + fullInPortrait + " " + heightPercentPortrait + " " + heightPercentLandscape);
+ boolean isPortrait = isPortrait();
+ int kbMode;
+ mNumKeyboardModes = sKeyboardSettings.compactModeEnabled ? 3 : 2; // FIXME!
+ if (isPortrait) {
+ kbMode = getKeyboardModeNum(sKeyboardSettings.keyboardModePortrait, mKeyboardModeOverridePortrait);
+ } else {
+ kbMode = getKeyboardModeNum(sKeyboardSettings.keyboardModeLandscape, mKeyboardModeOverrideLandscape);
+ }
+ // Convert overall keyboard height to per-row percentage
+ int screenHeightPercent = isPortrait ? mHeightPortrait : mHeightLandscape;
+ LatinIME.sKeyboardSettings.keyboardMode = kbMode;
+ LatinIME.sKeyboardSettings.keyboardHeightPercent = (float) screenHeightPercent;
+ }
+
+ private void setNotification(boolean visible) {
+ final String ACTION = "org.pocketworkstation.pckeyboard.SHOW";
+ final int ID = 1;
+ String ns = Context.NOTIFICATION_SERVICE;
+ NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
+
+ if (visible && mNotificationReceiver == null) {
+ int icon = R.drawable.icon;
+ CharSequence text = "Keyboard notification enabled.";
+ long when = System.currentTimeMillis();
+ Notification notification = new Notification(icon, text, when);
+
+ // TODO: clean this up?
+ mNotificationReceiver = new NotificationReceiver(this);
+ final IntentFilter pFilter = new IntentFilter(ACTION);
+ registerReceiver(mNotificationReceiver, pFilter);
+
+ Intent notificationIntent = new Intent(ACTION);
+
+ PendingIntent contentIntent = PendingIntent.getBroadcast(getApplicationContext(), 1, notificationIntent, 0);
+ //PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
+
+ String title = "Show Hacker's Keyboard";
+ String body = "Select this to open the keyboard. Disable in settings.";
+
+ notification.flags |= Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR;
+ notification.setLatestEventInfo(getApplicationContext(), title, body, contentIntent);
+ mNotificationManager.notify(ID, notification);
+ } else if (mNotificationReceiver != null) {
+ mNotificationManager.cancel(ID);
+ unregisterReceiver(mNotificationReceiver);
+ mNotificationReceiver = null;
+ }
+ }
+
+ private boolean isPortrait() {
+ return (mOrientation == Configuration.ORIENTATION_PORTRAIT);
+ }
+
+ private boolean suggestionsDisabled() {
+ if (mSuggestionForceOff) return true;
+ if (mSuggestionForceOn) return false;
+ return !(mSuggestionsInLandscape || isPortrait());
+ }
+
+ /**
+ * Loads a dictionary or multiple separated dictionary
+ *
+ * @return returns array of dictionary resource ids
+ */
+ /* package */static int[] getDictionary(Resources res) {
+ String packageName = LatinIME.class.getPackage().getName();
+ XmlResourceParser xrp = res.getXml(R.xml.dictionary);
+ ArrayList<Integer> dictionaries = new ArrayList<Integer>();
+
+ try {
+ int current = xrp.getEventType();
+ while (current != XmlResourceParser.END_DOCUMENT) {
+ if (current == XmlResourceParser.START_TAG) {
+ String tag = xrp.getName();
+ if (tag != null) {
+ if (tag.equals("part")) {
+ String dictFileName = xrp.getAttributeValue(null,
+ "name");
+ dictionaries.add(res.getIdentifier(dictFileName,
+ "raw", packageName));
+ }
+ }
+ }
+ xrp.next();
+ current = xrp.getEventType();
+ }
+ } catch (XmlPullParserException e) {
+ Log.e(TAG, "Dictionary XML parsing failure");
+ } catch (IOException e) {
+ Log.e(TAG, "Dictionary XML IOException");
+ }
+
+ int count = dictionaries.size();
+ int[] dict = new int[count];
+ for (int i = 0; i < count; i++) {
+ dict[i] = dictionaries.get(i);
+ }
+
+ return dict;
+ }
+
+ private void initSuggest(String locale) {
+ mInputLocale = locale;
+
+ Resources orig = getResources();
+ Configuration conf = orig.getConfiguration();
+ Locale saveLocale = conf.locale;
+ conf.locale = new Locale(locale);
+ orig.updateConfiguration(conf, orig.getDisplayMetrics());
+ if (mSuggest != null) {
+ mSuggest.close();
+ }
+ SharedPreferences sp = PreferenceManager
+ .getDefaultSharedPreferences(this);
+ mQuickFixes = sp.getBoolean(PREF_QUICK_FIXES, getResources()
+ .getBoolean(R.bool.default_quick_fixes));
+
+ int[] dictionaries = getDictionary(orig);
+ mSuggest = new Suggest(this, dictionaries);
+ updateAutoTextEnabled(saveLocale);
+ if (mUserDictionary != null)
+ mUserDictionary.close();
+ mUserDictionary = new UserDictionary(this, mInputLocale);
+ if (mContactsDictionary == null) {
+ mContactsDictionary = new ContactsDictionary(this,
+ Suggest.DIC_CONTACTS);
+ }
+ if (mAutoDictionary != null) {
+ mAutoDictionary.close();
+ }
+ mAutoDictionary = new AutoDictionary(this, this, mInputLocale,
+ Suggest.DIC_AUTO);
+ if (mUserBigramDictionary != null) {
+ mUserBigramDictionary.close();
+ }
+ mUserBigramDictionary = new UserBigramDictionary(this, this,
+ mInputLocale, Suggest.DIC_USER);
+ mSuggest.setUserBigramDictionary(mUserBigramDictionary);
+ mSuggest.setUserDictionary(mUserDictionary);
+ mSuggest.setContactsDictionary(mContactsDictionary);
+ mSuggest.setAutoDictionary(mAutoDictionary);
+ updateCorrectionMode();
+ mWordSeparators = mResources.getString(R.string.word_separators);
+ mSentenceSeparators = mResources
+ .getString(R.string.sentence_separators);
+ initSuggestPuncList();
+
+ conf.locale = saveLocale;
+ orig.updateConfiguration(conf, orig.getDisplayMetrics());
+ }
+
+ @Override
+ public void onDestroy() {
+ if (mUserDictionary != null) {
+ mUserDictionary.close();
+ }
+ if (mContactsDictionary != null) {
+ mContactsDictionary.close();
+ }
+ unregisterReceiver(mReceiver);
+ unregisterReceiver(mPluginManager);
+ if (mNotificationReceiver != null) {
+ unregisterReceiver(mNotificationReceiver);
+ mNotificationReceiver = null;
+ }
+ if (VOICE_INSTALLED && mVoiceInput != null) {
+ mVoiceInput.destroy();
+ }
+ LatinImeLogger.commit();
+ LatinImeLogger.onDestroy();
+ super.onDestroy();
+ }
+
+ @Override
+ public void onConfigurationChanged(Configuration conf) {
+ Log.i("PCKeyboard", "onConfigurationChanged()");
+ // If the system locale changes and is different from the saved
+ // locale (mSystemLocale), then reload the input locale list from the
+ // latin ime settings (shared prefs) and reset the input locale
+ // to the first one.
+ final String systemLocale = conf.locale.toString();
+ if (!TextUtils.equals(systemLocale, mSystemLocale)) {
+ mSystemLocale = systemLocale;
+ if (mLanguageSwitcher != null) {
+ mLanguageSwitcher.loadLocales(PreferenceManager
+ .getDefaultSharedPreferences(this));
+ mLanguageSwitcher.setSystemLocale(conf.locale);
+ toggleLanguage(true, true);
+ } else {
+ reloadKeyboards();
+ }
+ }
+ // If orientation changed while predicting, commit the change
+ if (conf.orientation != mOrientation) {
+ InputConnection ic = getCurrentInputConnection();
+ commitTyped(ic, true);
+ if (ic != null)
+ ic.finishComposingText(); // For voice input
+ mOrientation = conf.orientation;
+ reloadKeyboards();
+ removeCandidateViewContainer();
+ }
+ mConfigurationChanging = true;
+ super.onConfigurationChanged(conf);
+ if (mRecognizing) {
+ switchToRecognitionStatusView();
+ }
+ mConfigurationChanging = false;
+ }
+
+ @Override
+ public View onCreateInputView() {
+ setCandidatesViewShown(false); // Workaround for "already has a parent" when reconfiguring
+ mKeyboardSwitcher.recreateInputView();
+ mKeyboardSwitcher.makeKeyboards(true);
+ mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_TEXT, 0,
+ shouldShowVoiceButton(makeFieldContext(),
+ getCurrentInputEditorInfo()));
+ return mKeyboardSwitcher.getInputView();
+ }
+
+ @Override
+ public AbstractInputMethodImpl onCreateInputMethodInterface() {
+ return new MyInputMethodImpl();
+ }
+
+ IBinder mToken;
+ public class MyInputMethodImpl extends InputMethodImpl {
+ @Override
+ public void attachToken(IBinder token) {
+ super.attachToken(token);
+ Log.i(TAG, "attachToken " + token);
+ if (mToken == null) {
+ mToken = token;
+ }
+ }
+ }
+
+ @Override
+ public View onCreateCandidatesView() {
+ //Log.i(TAG, "onCreateCandidatesView(), mCandidateViewContainer=" + mCandidateViewContainer);
+ //mKeyboardSwitcher.makeKeyboards(true);
+ if (mCandidateViewContainer == null) {
+ mCandidateViewContainer = (LinearLayout) getLayoutInflater().inflate(
+ R.layout.candidates, null);
+ mCandidateView = (CandidateView) mCandidateViewContainer
+ .findViewById(R.id.candidates);
+ mCandidateView.setPadding(0, 0, 0, 0);
+ mCandidateView.setService(this);
+ setCandidatesView(mCandidateViewContainer);
+ }
+ return mCandidateViewContainer;
+ }
+
+ private void removeCandidateViewContainer() {
+ //Log.i(TAG, "removeCandidateViewContainer(), mCandidateViewContainer=" + mCandidateViewContainer);
+ if (mCandidateViewContainer != null) {
+ mCandidateViewContainer.removeAllViews();
+ ViewParent parent = mCandidateViewContainer.getParent();
+ if (parent != null && parent instanceof ViewGroup) {
+ ((ViewGroup) parent).removeView(mCandidateViewContainer);
+ }
+ mCandidateViewContainer = null;
+ mCandidateView = null;
+ }
+ resetPrediction();
+ }
+
+ private void resetPrediction() {
+ mComposing.setLength(0);
+ mPredicting = false;
+ mDeleteCount = 0;
+ mJustAddedAutoSpace = false;
+ }
+
+ @Override
+ public void onStartInputView(EditorInfo attribute, boolean restarting) {
+ sKeyboardSettings.editorPackageName = attribute.packageName;
+ sKeyboardSettings.editorFieldName = attribute.fieldName;
+ sKeyboardSettings.editorFieldId = attribute.fieldId;
+ sKeyboardSettings.editorInputType = attribute.inputType;
+
+ //Log.i("PCKeyboard", "onStartInputView " + attribute + ", inputType= " + Integer.toHexString(attribute.inputType) + ", restarting=" + restarting);
+ LatinKeyboardView inputView = mKeyboardSwitcher.getInputView();
+ // In landscape mode, this method gets called without the input view
+ // being created.
+ if (inputView == null) {
+ return;
+ }
+
+ if (mRefreshKeyboardRequired) {
+ mRefreshKeyboardRequired = false;
+ toggleLanguage(true, true);
+ }
+
+ mKeyboardSwitcher.makeKeyboards(false);
+
+ TextEntryState.newSession(this);
+
+ // Most such things we decide below in the switch statement, but we need to know
+ // now whether this is a password text field, because we need to know now (before
+ // the switch statement) whether we want to enable the voice button.
+ mPasswordText = false;
+ int variation = attribute.inputType & EditorInfo.TYPE_MASK_VARIATION;
+ if (variation == EditorInfo.TYPE_TEXT_VARIATION_PASSWORD
+ || variation == EditorInfo.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
+ || variation == 0xe0 /* EditorInfo.TYPE_TEXT_VARIATION_WEB_PASSWORD */
+ ) {
+ if ((attribute.inputType & EditorInfo.TYPE_MASK_CLASS) == EditorInfo.TYPE_CLASS_TEXT) {
+ mPasswordText = true;
+ }
+ }
+
+ mEnableVoiceButton = shouldShowVoiceButton(makeFieldContext(),
+ attribute);
+ final boolean enableVoiceButton = mEnableVoiceButton && mEnableVoice;
+
+ mAfterVoiceInput = false;
+ mImmediatelyAfterVoiceInput = false;
+ mShowingVoiceSuggestions = false;
+ mVoiceInputHighlighted = false;
+ mInputTypeNoAutoCorrect = false;
+ mPredictionOnForMode = false;
+ mCompletionOn = false;
+ mCompletions = null;
+ mModCtrl = false;
+ mModAlt = false;
+ mModFn = false;
+ mEnteredText = null;
+ mSuggestionForceOn = false;
+ mSuggestionForceOff = false;
+ mKeyboardModeOverridePortrait = 0;
+ mKeyboardModeOverrideLandscape = 0;
+ sKeyboardSettings.useExtension = false;
+
+ switch (attribute.inputType & EditorInfo.TYPE_MASK_CLASS) {
+ case EditorInfo.TYPE_CLASS_NUMBER:
+ case EditorInfo.TYPE_CLASS_DATETIME:
+ // fall through
+ // NOTE: For now, we use the phone keyboard for NUMBER and DATETIME
+ // until we get
+ // a dedicated number entry keypad.
+ // TODO: Use a dedicated number entry keypad here when we get one.
+ case EditorInfo.TYPE_CLASS_PHONE:
+ mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_PHONE,
+ attribute.imeOptions, enableVoiceButton);
+ break;
+ case EditorInfo.TYPE_CLASS_TEXT:
+ mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_TEXT,
+ attribute.imeOptions, enableVoiceButton);
+ // startPrediction();
+ mPredictionOnForMode = true;
+ // Make sure that passwords are not displayed in candidate view
+ if (mPasswordText) {
+ mPredictionOnForMode = false;
+ }
+ if (variation == EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS
+ || variation == EditorInfo.TYPE_TEXT_VARIATION_PERSON_NAME
+ || !mLanguageSwitcher.allowAutoSpace()) {
+ mAutoSpace = false;
+ } else {
+ mAutoSpace = true;
+ }
+ if (variation == EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS) {
+ mPredictionOnForMode = false;
+ mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_EMAIL,
+ attribute.imeOptions, enableVoiceButton);
+ } else if (variation == EditorInfo.TYPE_TEXT_VARIATION_URI) {
+ mPredictionOnForMode = false;
+ mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_URL,
+ attribute.imeOptions, enableVoiceButton);
+ } else if (variation == EditorInfo.TYPE_TEXT_VARIATION_SHORT_MESSAGE) {
+ mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_IM,
+ attribute.imeOptions, enableVoiceButton);
+ } else if (variation == EditorInfo.TYPE_TEXT_VARIATION_FILTER) {
+ mPredictionOnForMode = false;
+ } else if (variation == EditorInfo.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT) {
+ mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_WEB,
+ attribute.imeOptions, enableVoiceButton);
+ // If it's a browser edit field and auto correct is not ON
+ // explicitly, then
+ // disable auto correction, but keep suggestions on.
+ if ((attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_AUTO_CORRECT) == 0) {
+ mInputTypeNoAutoCorrect = true;
+ }
+ }
+
+ // If NO_SUGGESTIONS is set, don't do prediction.
+ if ((attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_NO_SUGGESTIONS) != 0) {
+ mPredictionOnForMode = false;
+ mInputTypeNoAutoCorrect = true;
+ }
+ // If it's not multiline and the autoCorrect flag is not set, then
+ // don't correct
+ if ((attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_AUTO_CORRECT) == 0
+ && (attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE) == 0) {
+ mInputTypeNoAutoCorrect = true;
+ }
+ if ((attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_AUTO_COMPLETE) != 0) {
+ mPredictionOnForMode = false;
+ mCompletionOn = isFullscreenMode();
+ }
+ break;
+ default:
+ mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_TEXT,
+ attribute.imeOptions, enableVoiceButton);
+ }
+ inputView.closing();
+ resetPrediction();
+ loadSettings();
+ updateShiftKeyState(attribute);
+
+ mPredictionOnPref = (mCorrectionMode > 0 || mShowSuggestions);
+ setCandidatesViewShownInternal(isCandidateStripVisible()
+ || mCompletionOn, false /* needsInputViewShown */);
+ updateSuggestions();
+
+ // If the dictionary is not big enough, don't auto correct
+ mHasDictionary = mSuggest.hasMainDictionary();
+
+ updateCorrectionMode();
+
+ inputView.setPreviewEnabled(mPopupOn);
+ inputView.setProximityCorrectionEnabled(true);
+ // If we just entered a text field, maybe it has some old text that
+ // requires correction
+ checkReCorrectionOnStart();
+ checkTutorial(attribute.privateImeOptions);
+ if (TRACE)
+ Debug.startMethodTracing("/data/trace/latinime");
+ }
+
+ private void checkReCorrectionOnStart() {
+ if (mReCorrectionEnabled && isPredictionOn()) {
+ // First get the cursor position. This is required by
+ // setOldSuggestions(), so that
+ // it can pass the correct range to setComposingRegion(). At this
+ // point, we don't
+ // have valid values for mLastSelectionStart/Stop because
+ // onUpdateSelection() has
+ // not been called yet.
+ InputConnection ic = getCurrentInputConnection();
+ if (ic == null)
+ return;
+ ExtractedTextRequest etr = new ExtractedTextRequest();
+ etr.token = 0; // anything is fine here
+ ExtractedText et = ic.getExtractedText(etr, 0);
+ if (et == null)
+ return;
+
+ mLastSelectionStart = et.startOffset + et.selectionStart;
+ mLastSelectionEnd = et.startOffset + et.selectionEnd;
+
+ // Then look for possible corrections in a delayed fashion
+ if (!TextUtils.isEmpty(et.text) && isCursorTouchingWord()) {
+ postUpdateOldSuggestions();
+ }
+ }
+ }
+
+ @Override
+ public void onFinishInput() {
+ super.onFinishInput();
+
+ LatinImeLogger.commit();
+ onAutoCompletionStateChanged(false);
+
+ if (VOICE_INSTALLED && !mConfigurationChanging) {
+ if (mAfterVoiceInput) {
+ mVoiceInput.flushAllTextModificationCounters();
+ mVoiceInput.logInputEnded();
+ }
+ mVoiceInput.flushLogs();
+ mVoiceInput.cancel();
+ }
+ if (mKeyboardSwitcher.getInputView() != null) {
+ mKeyboardSwitcher.getInputView().closing();
+ }
+ if (mAutoDictionary != null)
+ mAutoDictionary.flushPendingWrites();
+ if (mUserBigramDictionary != null)
+ mUserBigramDictionary.flushPendingWrites();
+ }
+
+ @Override
+ public void onFinishInputView(boolean finishingInput) {
+ super.onFinishInputView(finishingInput);
+ // Remove penging messages related to update suggestions
+ mHandler.removeMessages(MSG_UPDATE_SUGGESTIONS);
+ mHandler.removeMessages(MSG_UPDATE_OLD_SUGGESTIONS);
+ }
+
+ @Override
+ public void onUpdateExtractedText(int token, ExtractedText text) {
+ super.onUpdateExtractedText(token, text);
+ InputConnection ic = getCurrentInputConnection();
+ if (!mImmediatelyAfterVoiceInput && mAfterVoiceInput && ic != null) {
+ if (mHints.showPunctuationHintIfNecessary(ic)) {
+ mVoiceInput.logPunctuationHintDisplayed();
+ }
+ }
+ mImmediatelyAfterVoiceInput = false;
+ }
+
+ @Override
+ public void onUpdateSelection(int oldSelStart, int oldSelEnd,
+ int newSelStart, int newSelEnd, int candidatesStart,
+ int candidatesEnd) {
+ super.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd,
+ candidatesStart, candidatesEnd);
+
+ if (DEBUG) {
+ Log.i(TAG, "onUpdateSelection: oss=" + oldSelStart + ", ose="
+ + oldSelEnd + ", nss=" + newSelStart + ", nse=" + newSelEnd
+ + ", cs=" + candidatesStart + ", ce=" + candidatesEnd);
+ }
+
+ if (mAfterVoiceInput) {
+ mVoiceInput.setCursorPos(newSelEnd);
+ mVoiceInput.setSelectionSpan(newSelEnd - newSelStart);
+ }
+
+ // If the current selection in the text view changes, we should
+ // clear whatever candidate text we have.
+ if ((((mComposing.length() > 0 && mPredicting) || mVoiceInputHighlighted)
+ && (newSelStart != candidatesEnd || newSelEnd != candidatesEnd) && mLastSelectionStart != newSelStart)) {
+ mComposing.setLength(0);
+ mPredicting = false;
+ postUpdateSuggestions();
+ TextEntryState.reset();
+ InputConnection ic = getCurrentInputConnection();
+ if (ic != null) {
+ ic.finishComposingText();
+ }
+ mVoiceInputHighlighted = false;
+ } else if (!mPredicting && !mJustAccepted) {
+ switch (TextEntryState.getState()) {
+ case ACCEPTED_DEFAULT:
+ TextEntryState.reset();
+ // fall through
+ case SPACE_AFTER_PICKED:
+ mJustAddedAutoSpace = false; // The user moved the cursor.
+ break;
+ }
+ }
+ mJustAccepted = false;
+ postUpdateShiftKeyState();
+
+ // Make a note of the cursor position
+ mLastSelectionStart = newSelStart;
+ mLastSelectionEnd = newSelEnd;
+
+ if (mReCorrectionEnabled) {
+ // Don't look for corrections if the keyboard is not visible
+ if (mKeyboardSwitcher != null
+ && mKeyboardSwitcher.getInputView() != null
+ && mKeyboardSwitcher.getInputView().isShown()) {
+ // Check if we should go in or out of correction mode.
+ if (isPredictionOn()
+ && mJustRevertedSeparator == null
+ && (candidatesStart == candidatesEnd
+ || newSelStart != oldSelStart || TextEntryState
+ .isCorrecting())
+ && (newSelStart < newSelEnd - 1 || (!mPredicting))
+ && !mVoiceInputHighlighted) {
+ if (isCursorTouchingWord()
+ || mLastSelectionStart < mLastSelectionEnd) {
+ postUpdateOldSuggestions();
+ } else {
+ abortCorrection(false);
+ // Show the punctuation suggestions list if the current
+ // one is not
+ // and if not showing "Touch again to save".
+ if (mCandidateView != null
+ && !mSuggestPuncList.equals(mCandidateView
+ .getSuggestions())
+ && !mCandidateView
+ .isShowingAddToDictionaryHint()) {
+ setNextSuggestions();
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * This is called when the user has clicked on the extracted text view, when
+ * running in fullscreen mode. The default implementation hides the
+ * candidates view when this happens, but only if the extracted text editor
+ * has a vertical scroll bar because its text doesn't fit. Here we override
+ * the behavior due to the possibility that a re-correction could cause the
+ * candidate strip to disappear and re-appear.
+ */
+ @Override
+ public void onExtractedTextClicked() {
+ if (mReCorrectionEnabled && isPredictionOn())
+ return;
+
+ super.onExtractedTextClicked();
+ }
+
+ /**
+ * This is called when the user has performed a cursor movement in the
+ * extracted text view, when it is running in fullscreen mode. The default
+ * implementation hides the candidates view when a vertical movement
+ * happens, but only if the extracted text editor has a vertical scroll bar
+ * because its text doesn't fit. Here we override the behavior due to the
+ * possibility that a re-correction could cause the candidate strip to
+ * disappear and re-appear.
+ */
+ @Override
+ public void onExtractedCursorMovement(int dx, int dy) {
+ if (mReCorrectionEnabled && isPredictionOn())
+ return;
+
+ super.onExtractedCursorMovement(dx, dy);
+ }
+
+ @Override
+ public void hideWindow() {
+ LatinImeLogger.commit();
+ onAutoCompletionStateChanged(false);
+
+ if (TRACE)
+ Debug.stopMethodTracing();
+ if (mOptionsDialog != null && mOptionsDialog.isShowing()) {
+ mOptionsDialog.dismiss();
+ mOptionsDialog = null;
+ }
+ if (!mConfigurationChanging) {
+ if (mAfterVoiceInput)
+ mVoiceInput.logInputEnded();
+ if (mVoiceWarningDialog != null && mVoiceWarningDialog.isShowing()) {
+ mVoiceInput.logKeyboardWarningDialogDismissed();
+ mVoiceWarningDialog.dismiss();
+ mVoiceWarningDialog = null;
+ }
+ if (VOICE_INSTALLED & mRecognizing) {
+ mVoiceInput.cancel();
+ }
+ }
+ mWordToSuggestions.clear();
+ mWordHistory.clear();
+ super.hideWindow();
+ TextEntryState.endSession();
+ }
+
+ @Override
+ public void onDisplayCompletions(CompletionInfo[] completions) {
+ if (DEBUG) {
+ Log.i("foo", "Received completions:");
+ for (int i = 0; i < (completions != null ? completions.length : 0); i++) {
+ Log.i("foo", " #" + i + ": " + completions[i]);
+ }
+ }
+ if (mCompletionOn) {
+ mCompletions = completions;
+ if (completions == null) {
+ clearSuggestions();
+ return;
+ }
+
+ List<CharSequence> stringList = new ArrayList<CharSequence>();
+ for (int i = 0; i < (completions != null ? completions.length : 0); i++) {
+ CompletionInfo ci = completions[i];
+ if (ci != null)
+ stringList.add(ci.getText());
+ }
+ // When in fullscreen mode, show completions generated by the
+ // application
+ setSuggestions(stringList, true, true, true);
+ mBestWord = null;
+ setCandidatesViewShown(true);
+ }
+ }
+
+ private void setCandidatesViewShownInternal(boolean shown,
+ boolean needsInputViewShown) {
+// Log.i(TAG, "setCandidatesViewShownInternal(" + shown + ", " + needsInputViewShown +
+// " mCompletionOn=" + mCompletionOn +
+// " mPredictionOnForMode=" + mPredictionOnForMode +
+// " mPredictionOnPref=" + mPredictionOnPref +
+// " mPredicting=" + mPredicting
+// );
+ // TODO: Remove this if we support candidates with hard keyboard
+ boolean visible = shown
+ && onEvaluateInputViewShown()
+ && mKeyboardSwitcher.getInputView() != null
+ && isPredictionOn()
+ && (needsInputViewShown
+ ? mKeyboardSwitcher.getInputView().isShown()
+ : true);
+ if (visible) {
+ if (mCandidateViewContainer == null) {
+ onCreateCandidatesView();
+ setNextSuggestions();
+ }
+ } else {
+ if (mCandidateViewContainer != null) {
+ removeCandidateViewContainer();
+ commitTyped(getCurrentInputConnection(), true);
+ }
+ }
+ super.setCandidatesViewShown(visible);
+ }
+
+ @Override
+ public void onFinishCandidatesView(boolean finishingInput) {
+ //Log.i(TAG, "onFinishCandidatesView(), mCandidateViewContainer=" + mCandidateViewContainer);
+ super.onFinishCandidatesView(finishingInput);
+ if (mCandidateViewContainer != null) {
+ removeCandidateViewContainer();
+ }
+ }
+
+ @Override
+ public boolean onEvaluateInputViewShown() {
+ boolean parent = super.onEvaluateInputViewShown();
+ boolean wanted = mForceKeyboardOn || parent;
+ //Log.i(TAG, "OnEvaluateInputViewShown, parent=" + parent + " + " wanted=" + wanted);
+ return wanted;
+ }
+
+ @Override
+ public void setCandidatesViewShown(boolean shown) {
+ setCandidatesViewShownInternal(shown, true /* needsInputViewShown */);
+ }
+
+ @Override
+ public void onComputeInsets(InputMethodService.Insets outInsets) {
+ super.onComputeInsets(outInsets);
+ if (!isFullscreenMode()) {
+ outInsets.contentTopInsets = outInsets.visibleTopInsets;
+ }
+ }
+
+ @Override
+ public boolean onEvaluateFullscreenMode() {
+ DisplayMetrics dm = getResources().getDisplayMetrics();
+ float displayHeight = dm.heightPixels;
+ // If the display is more than X inches high, don't go to fullscreen
+ // mode
+ float dimen = getResources().getDimension(
+ R.dimen.max_height_for_fullscreen);
+ if (displayHeight > dimen || mFullscreenOverride || isConnectbot()) {
+ return false;
+ } else {
+ return super.onEvaluateFullscreenMode();
+ }
+ }
+
+ public boolean isKeyboardVisible() {
+ return (mKeyboardSwitcher != null
+ && mKeyboardSwitcher.getInputView() != null
+ && mKeyboardSwitcher.getInputView().isShown());
+ }
+
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_BACK:
+ if (event.getRepeatCount() == 0
+ && mKeyboardSwitcher.getInputView() != null) {
+ if (mKeyboardSwitcher.getInputView().handleBack()) {
+ return true;
+ } else if (mTutorial != null) {
+ mTutorial.close();
+ mTutorial = null;
+ }
+ }
+ break;
+ case KeyEvent.KEYCODE_DPAD_DOWN:
+ case KeyEvent.KEYCODE_DPAD_UP:
+ case KeyEvent.KEYCODE_DPAD_LEFT:
+ case KeyEvent.KEYCODE_DPAD_RIGHT:
+ // If tutorial is visible, don't allow dpad to work
+ if (mTutorial != null) {
+ return true;
+ }
+ break;
+ case KeyEvent.KEYCODE_VOLUME_UP:
+ if (!mVolUpAction.equals("none") && isKeyboardVisible()) {
+ return true;
+ }
+ break;
+ case KeyEvent.KEYCODE_VOLUME_DOWN:
+ if (!mVolDownAction.equals("none") && isKeyboardVisible()) {
+ return true;
+ }
+ break;
+ }
+ return super.onKeyDown(keyCode, event);
+ }
+
+ @Override
+ public boolean onKeyUp(int keyCode, KeyEvent event) {
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_DPAD_DOWN:
+ case KeyEvent.KEYCODE_DPAD_UP:
+ case KeyEvent.KEYCODE_DPAD_LEFT:
+ case KeyEvent.KEYCODE_DPAD_RIGHT:
+ // If tutorial is visible, don't allow dpad to work
+ if (mTutorial != null) {
+ return true;
+ }
+ LatinKeyboardView inputView = mKeyboardSwitcher.getInputView();
+ // Enable shift key and DPAD to do selections
+ if (inputView != null && inputView.isShown()
+ && inputView.getShiftState() == Keyboard.SHIFT_ON) {
+ event = new KeyEvent(event.getDownTime(), event.getEventTime(),
+ event.getAction(), event.getKeyCode(), event
+ .getRepeatCount(), event.getDeviceId(), event
+ .getScanCode(), KeyEvent.META_SHIFT_LEFT_ON
+ | KeyEvent.META_SHIFT_ON);
+ InputConnection ic = getCurrentInputConnection();
+ if (ic != null)
+ ic.sendKeyEvent(event);
+ return true;
+ }
+ break;
+ case KeyEvent.KEYCODE_VOLUME_UP:
+ if (!mVolUpAction.equals("none") && isKeyboardVisible()) {
+ return doSwipeAction(mVolUpAction);
+ }
+ break;
+ case KeyEvent.KEYCODE_VOLUME_DOWN:
+ if (!mVolDownAction.equals("none") && isKeyboardVisible()) {
+ return doSwipeAction(mVolDownAction);
+ }
+ break;
+ }
+ return super.onKeyUp(keyCode, event);
+ }
+
+ private void revertVoiceInput() {
+ InputConnection ic = getCurrentInputConnection();
+ if (ic != null)
+ ic.commitText("", 1);
+ updateSuggestions();
+ mVoiceInputHighlighted = false;
+ }
+
+ private void commitVoiceInput() {
+ InputConnection ic = getCurrentInputConnection();
+ if (ic != null)
+ ic.finishComposingText();
+ updateSuggestions();
+ mVoiceInputHighlighted = false;
+ }
+
+ private void reloadKeyboards() {
+ mKeyboardSwitcher.setLanguageSwitcher(mLanguageSwitcher);
+ if (mKeyboardSwitcher.getInputView() != null
+ && mKeyboardSwitcher.getKeyboardMode() != KeyboardSwitcher.MODE_NONE) {
+ mKeyboardSwitcher.setVoiceMode(mEnableVoice && mEnableVoiceButton,
+ mVoiceOnPrimary);
+ }
+ updateKeyboardOptions();
+ mKeyboardSwitcher.makeKeyboards(true);
+ }
+
+ private void commitTyped(InputConnection inputConnection, boolean manual) {
+ if (mPredicting) {
+ mPredicting = false;
+ if (mComposing.length() > 0) {
+ if (inputConnection != null) {
+ inputConnection.commitText(mComposing, 1);
+ }
+ mCommittedLength = mComposing.length();
+ if (manual) {
+ TextEntryState.manualTyped(mComposing);
+ } else {
+ TextEntryState.acceptedTyped(mComposing);
+ }
+ addToDictionaries(mComposing,
+ AutoDictionary.FREQUENCY_FOR_TYPED);
+ }
+ updateSuggestions();
+ }
+ }
+
+ private void postUpdateShiftKeyState() {
+ // TODO(klausw): disabling, I have no idea what this is supposed to accomplish.
+// //updateShiftKeyState(getCurrentInputEditorInfo());
+//
+// // FIXME: why the delay?
+// mHandler.removeMessages(MSG_UPDATE_SHIFT_STATE);
+// // TODO: Should remove this 300ms delay?
+// mHandler.sendMessageDelayed(mHandler
+// .obtainMessage(MSG_UPDATE_SHIFT_STATE), 300);
+ }
+
+ public void updateShiftKeyState(EditorInfo attr) {
+ InputConnection ic = getCurrentInputConnection();
+ if (ic != null && attr != null && mKeyboardSwitcher.isAlphabetMode()) {
+ int oldState = getShiftState();
+ boolean isShifted = mShiftKeyState.isMomentary();
+ boolean isCapsLock = (oldState == Keyboard.SHIFT_CAPS_LOCKED || oldState == Keyboard.SHIFT_LOCKED);
+ boolean isCaps = isCapsLock || getCursorCapsMode(ic, attr) != 0;
+ //Log.i(TAG, "updateShiftKeyState isShifted=" + isShifted + " isCaps=" + isCaps + " isMomentary=" + mShiftKeyState.isMomentary() + " cursorCaps=" + getCursorCapsMode(ic, attr));
+ int newState = Keyboard.SHIFT_OFF;
+ if (isShifted) {
+ newState = (mSavedShiftState == Keyboard.SHIFT_LOCKED) ? Keyboard.SHIFT_CAPS : Keyboard.SHIFT_ON;
+ } else if (isCaps) {
+ newState = isCapsLock ? getCapsOrShiftLockState() : Keyboard.SHIFT_CAPS;
+ }
+ //Log.i(TAG, "updateShiftKeyState " + oldState + " -> " + newState);
+ mKeyboardSwitcher.setShiftState(newState);
+ }
+ if (ic != null) {
+ // Clear modifiers other than shift, to avoid them getting stuck
+ int states =
+ KeyEvent.META_ALT_ON
+ | KeyEvent.META_ALT_LEFT_ON
+ | KeyEvent.META_ALT_RIGHT_ON
+ | 0x8 // KeyEvent.META_FUNCTION_ON;
+ | 0x7000 // KeyEvent.META_CTRL_MASK
+ | 0x70000 // KeyEvent.META_META_MASK
+ | KeyEvent.META_SYM_ON;
+ ic.clearMetaKeyStates(states);
+ }
+ }
+
+ private int getShiftState() {
+ if (mKeyboardSwitcher != null) {
+ LatinKeyboardView view = mKeyboardSwitcher.getInputView();
+ if (view != null) {
+ return view.getShiftState();
+ }
+ }
+ return Keyboard.SHIFT_OFF;
+ }
+
+ private boolean isShiftCapsMode() {
+ if (mKeyboardSwitcher != null) {
+ LatinKeyboardView view = mKeyboardSwitcher.getInputView();
+ if (view != null) {
+ return view.isShiftCaps();
+ }
+ }
+ return false;
+ }
+
+ private int getCursorCapsMode(InputConnection ic, EditorInfo attr) {
+ int caps = 0;
+ EditorInfo ei = getCurrentInputEditorInfo();
+ if (mAutoCapActive && ei != null && ei.inputType != EditorInfo.TYPE_NULL) {
+ caps = ic.getCursorCapsMode(attr.inputType);
+ }
+ return caps;
+ }
+
+ private void swapPunctuationAndSpace() {
+ final InputConnection ic = getCurrentInputConnection();
+ if (ic == null)
+ return;
+ CharSequence lastTwo = ic.getTextBeforeCursor(2, 0);
+ if (lastTwo != null && lastTwo.length() == 2
+ && lastTwo.charAt(0) == ASCII_SPACE
+ && isSentenceSeparator(lastTwo.charAt(1))) {
+ ic.beginBatchEdit();
+ ic.deleteSurroundingText(2, 0);
+ ic.commitText(lastTwo.charAt(1) + " ", 1);
+ ic.endBatchEdit();
+ updateShiftKeyState(getCurrentInputEditorInfo());
+ mJustAddedAutoSpace = true;
+ }
+ }
+
+ private void reswapPeriodAndSpace() {
+ final InputConnection ic = getCurrentInputConnection();
+ if (ic == null)
+ return;
+ CharSequence lastThree = ic.getTextBeforeCursor(3, 0);
+ if (lastThree != null && lastThree.length() == 3
+ && lastThree.charAt(0) == ASCII_PERIOD
+ && lastThree.charAt(1) == ASCII_SPACE
+ && lastThree.charAt(2) == ASCII_PERIOD) {
+ ic.beginBatchEdit();
+ ic.deleteSurroundingText(3, 0);
+ ic.commitText(" ..", 1);
+ ic.endBatchEdit();
+ updateShiftKeyState(getCurrentInputEditorInfo());
+ }
+ }
+
+ private void doubleSpace() {
+ // if (!mAutoPunctuate) return;
+ if (mCorrectionMode == Suggest.CORRECTION_NONE)
+ return;
+ final InputConnection ic = getCurrentInputConnection();
+ if (ic == null)
+ return;
+ CharSequence lastThree = ic.getTextBeforeCursor(3, 0);
+ if (lastThree != null && lastThree.length() == 3
+ && Character.isLetterOrDigit(lastThree.charAt(0))
+ && lastThree.charAt(1) == ASCII_SPACE
+ && lastThree.charAt(2) == ASCII_SPACE) {
+ ic.beginBatchEdit();
+ ic.deleteSurroundingText(2, 0);
+ ic.commitText(". ", 1);
+ ic.endBatchEdit();
+ updateShiftKeyState(getCurrentInputEditorInfo());
+ mJustAddedAutoSpace = true;
+ }
+ }
+
+ private void maybeRemovePreviousPeriod(CharSequence text) {
+ final InputConnection ic = getCurrentInputConnection();
+ if (ic == null || text.length() == 0)
+ return;
+
+ // When the text's first character is '.', remove the previous period
+ // if there is one.
+ CharSequence lastOne = ic.getTextBeforeCursor(1, 0);
+ if (lastOne != null && lastOne.length() == 1
+ && lastOne.charAt(0) == ASCII_PERIOD
+ && text.charAt(0) == ASCII_PERIOD) {
+ ic.deleteSurroundingText(1, 0);
+ }
+ }
+
+ private void removeTrailingSpace() {
+ final InputConnection ic = getCurrentInputConnection();
+ if (ic == null)
+ return;
+
+ CharSequence lastOne = ic.getTextBeforeCursor(1, 0);
+ if (lastOne != null && lastOne.length() == 1
+ && lastOne.charAt(0) == ASCII_SPACE) {
+ ic.deleteSurroundingText(1, 0);
+ }
+ }
+
+ public boolean addWordToDictionary(String word) {
+ mUserDictionary.addWord(word, 128);
+ // Suggestion strip should be updated after the operation of adding word
+ // to the
+ // user dictionary
+ postUpdateSuggestions();
+ return true;
+ }
+
+ private boolean isAlphabet(int code) {
+ if (Character.isLetter(code)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ private void showInputMethodPicker() {
+ ((InputMethodManager) getSystemService(INPUT_METHOD_SERVICE))
+ .showInputMethodPicker();
+ }
+
+ private void onOptionKeyPressed() {
+ if (!isShowingOptionDialog()) {
+ showOptionsMenu();
+ }
+ }
+
+ private void onOptionKeyLongPressed() {
+ if (!isShowingOptionDialog()) {
+ showInputMethodPicker();
+ }
+ }
+
+ private boolean isShowingOptionDialog() {
+ return mOptionsDialog != null && mOptionsDialog.isShowing();
+ }
+
+ private boolean isConnectbot() {
+ EditorInfo ei = getCurrentInputEditorInfo();
+ String pkg = ei.packageName;
+ if (ei == null || pkg == null) return false;
+ return ((pkg.equalsIgnoreCase("org.connectbot")
+ || pkg.equalsIgnoreCase("org.woltage.irssiconnectbot")
+ || pkg.equalsIgnoreCase("com.pslib.connectbot")
+ || pkg.equalsIgnoreCase("sk.vx.connectbot")
+ ) && ei.inputType == 0); // FIXME
+ }
+
+ private int getMetaState(boolean shifted) {
+ int meta = 0;
+ if (shifted) meta |= KeyEvent.META_SHIFT_ON | KeyEvent.META_SHIFT_LEFT_ON;
+ if (mModCtrl) meta |= 0x3000; // KeyEvent.META_CTRL_ON | KeyEvent.META_CTRL_LEFT_ON;
+ if (mModAlt) meta |= 0x30000; // KeyEvent.META_ALT_ON | KeyEvent.META_ALT_LEFT_ON;
+ return meta;
+ }
+
+ private void sendKeyDown(InputConnection ic, int key, int meta) {
+ long now = System.currentTimeMillis();
+ if (ic != null) ic.sendKeyEvent(new KeyEvent(
+ now, now, KeyEvent.ACTION_DOWN, key, 0, meta));
+ }
+
+ private void sendKeyUp(InputConnection ic, int key, int meta) {
+ long now = System.currentTimeMillis();
+ if (ic != null) ic.sendKeyEvent(new KeyEvent(
+ now, now, KeyEvent.ACTION_UP, key, 0, meta));
+ }
+
+ private void sendModifiedKeyDownUp(int key, boolean shifted) {
+ InputConnection ic = getCurrentInputConnection();
+ int meta = getMetaState(shifted);
+ sendModifierKeysDown(shifted);
+ sendKeyDown(ic, key, meta);
+ sendKeyUp(ic, key, meta);
+ sendModifierKeysUp(shifted);
+ }
+
+ private boolean isShiftMod() {
+ if (mShiftKeyState.isMomentary()) return true;
+ if (mKeyboardSwitcher != null) {
+ LatinKeyboardView kb = mKeyboardSwitcher.getInputView();
+ if (kb != null) return kb.isShiftAll();
+ }
+ return false;
+ }
+
+ private boolean delayChordingCtrlModifier() {
+ return sKeyboardSettings.chordingCtrlKey == 0;
+ }
+
+ private boolean delayChordingAltModifier() {
+ return sKeyboardSettings.chordingAltKey == 0;
+ }
+
+ private void sendModifiedKeyDownUp(int key) {
+ sendModifiedKeyDownUp(key, isShiftMod());
+ }
+
+ private void sendShiftKey(InputConnection ic, boolean isDown) {
+ int key = KeyEvent.KEYCODE_SHIFT_LEFT;
+ int meta = KeyEvent.META_SHIFT_ON | KeyEvent.META_SHIFT_LEFT_ON;
+ if (isDown) {
+ sendKeyDown(ic, key, meta);
+ } else {
+ sendKeyUp(ic, key, meta);
+ }
+ }
+
+ private void sendCtrlKey(InputConnection ic, boolean isDown, boolean chording) {
+ if (chording && delayChordingCtrlModifier()) return;
+
+ int key = sKeyboardSettings.chordingCtrlKey;
+ if (key == 0) key = 113; // KeyEvent.KEYCODE_CTRL_LEFT
+ int meta = 0x3000; // KeyEvent.META_CTRL_ON | KeyEvent.META_CTRL_LEFT_ON
+ if (isDown) {
+ sendKeyDown(ic, key, meta);
+ } else {
+ sendKeyUp(ic, key, meta);
+ }
+ }
+
+ private void sendAltKey(InputConnection ic, boolean isDown, boolean chording) {
+ if (chording && delayChordingAltModifier()) return;
+
+ int key = sKeyboardSettings.chordingAltKey;
+ if (key == 0) key = 57; // KeyEvent.KEYCODE_ALT_LEFT
+ int meta = 0x30000; // KeyEvent.META_ALT_ON | KeyEvent.META_ALT_LEFT_ON
+ if (isDown) {
+ sendKeyDown(ic, key, meta);
+ } else {
+ sendKeyUp(ic, key, meta);
+ }
+ }
+
+ private void sendModifierKeysDown(boolean shifted) {
+ InputConnection ic = getCurrentInputConnection();
+ if (shifted) {
+ //Log.i(TAG, "send SHIFT down");
+ sendShiftKey(ic, true);
+ }
+ if (mModCtrl && (!mCtrlKeyState.isMomentary() || delayChordingCtrlModifier())) {
+ sendCtrlKey(ic, true, false);
+ }
+ if (mModAlt && (!mAltKeyState.isMomentary() || delayChordingAltModifier())) {
+ sendAltKey(ic, true, false);
+ }
+ }
+
+ private void handleModifierKeysUp(boolean shifted, boolean sendKey) {
+ InputConnection ic = getCurrentInputConnection();
+ if (mModAlt && !mAltKeyState.isMomentary()) {
+ if (sendKey) sendAltKey(ic, false, false);
+ setModAlt(false);
+ }
+ if (mModCtrl && !mCtrlKeyState.isMomentary()) {
+ if (sendKey) sendCtrlKey(ic, false, false);
+ setModCtrl(false);
+ }
+ if (shifted) {
+ //Log.i(TAG, "send SHIFT up");
+ if (sendKey) sendShiftKey(ic, false);
+ int shiftState = getShiftState();
+ if (!(mShiftKeyState.isMomentary() || shiftState == Keyboard.SHIFT_LOCKED)) {
+ resetShift();
+ }
+ }
+ }
+
+ private void sendModifierKeysUp(boolean shifted) {
+ handleModifierKeysUp(shifted, true);
+ }
+
+ private void sendSpecialKey(int code) {
+ if (!isConnectbot()) {
+ commitTyped(getCurrentInputConnection(), true);
+ sendModifiedKeyDownUp(code);
+ return;
+ }
+
+ // TODO(klausw): properly support xterm sequences for Ctrl/Alt modifiers?
+ // See http://slackware.osuosl.org/slackware-12.0/source/l/ncurses/xterm.terminfo
+ // and the output of "$ infocmp -1L". Support multiple sets, and optional
+ // true numpad keys?
+ if (ESC_SEQUENCES == null) {
+ ESC_SEQUENCES = new HashMap<Integer, String>();
+ CTRL_SEQUENCES = new HashMap<Integer, Integer>();
+
+ // VT escape sequences without leading Escape
+ ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_HOME, "[1~");
+ ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_END, "[4~");
+ ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_PAGE_UP, "[5~");
+ ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_PAGE_DOWN, "[6~");
+ ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FKEY_F1, "OP");
+ ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FKEY_F2, "OQ");
+ ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FKEY_F3, "OR");
+ ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FKEY_F4, "OS");
+ ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FKEY_F5, "[15~");
+ ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FKEY_F6, "[17~");
+ ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FKEY_F7, "[18~");
+ ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FKEY_F8, "[19~");
+ ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FKEY_F9, "[20~");
+ ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FKEY_F10, "[21~");
+ ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FKEY_F11, "[23~");
+ ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FKEY_F12, "[24~");
+ ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FORWARD_DEL, "[3~");
+ ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_INSERT, "[2~");
+
+ // Special ConnectBot hack: Ctrl-1 to Ctrl-0 for F1-F10.
+ CTRL_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FKEY_F1, KeyEvent.KEYCODE_1);
+ CTRL_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FKEY_F2, KeyEvent.KEYCODE_2);
+ CTRL_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FKEY_F3, KeyEvent.KEYCODE_3);
+ CTRL_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FKEY_F4, KeyEvent.KEYCODE_4);
+ CTRL_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FKEY_F5, KeyEvent.KEYCODE_5);
+ CTRL_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FKEY_F6, KeyEvent.KEYCODE_6);
+ CTRL_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FKEY_F7, KeyEvent.KEYCODE_7);
+ CTRL_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FKEY_F8, KeyEvent.KEYCODE_8);
+ CTRL_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FKEY_F9, KeyEvent.KEYCODE_9);
+ CTRL_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FKEY_F10, KeyEvent.KEYCODE_0);
+
+ // Natively supported by ConnectBot
+ // ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_DPAD_UP, "OA");
+ // ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_DPAD_DOWN, "OB");
+ // ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_DPAD_LEFT, "OD");
+ // ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_DPAD_RIGHT, "OC");
+
+ // No VT equivalents?
+ // ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_DPAD_CENTER, "");
+ // ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_SYSRQ, "");
+ // ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_BREAK, "");
+ // ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_NUM_LOCK, "");
+ // ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_SCROLL_LOCK, "");
+ }
+ InputConnection ic = getCurrentInputConnection();
+ Integer ctrlseq = null;
+ if (mConnectbotTabHack) {
+ ctrlseq = CTRL_SEQUENCES.get(code);
+ }
+ String seq = ESC_SEQUENCES.get(code);
+
+ if (ctrlseq != null) {
+ if (mModAlt) {
+ // send ESC prefix for "Meta"
+ ic.commitText(Character.toString((char) 27), 1);
+ }
+ ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN,
+ KeyEvent.KEYCODE_DPAD_CENTER));
+ ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP,
+ KeyEvent.KEYCODE_DPAD_CENTER));
+ ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN,
+ ctrlseq));
+ ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP,
+ ctrlseq));
+ } else if (seq != null) {
+ if (mModAlt) {
+ // send ESC prefix for "Meta"
+ ic.commitText(Character.toString((char) 27), 1);
+ }
+ // send ESC prefix of escape sequence
+ ic.commitText(Character.toString((char) 27), 1);
+ ic.commitText(seq, 1);
+ } else {
+ // send key code, let connectbot handle it
+ sendDownUpKeyEvents(code);
+ }
+ handleModifierKeysUp(false, false);
+ }
+
+ private final static int asciiToKeyCode[] = new int[127];
+ private final static int KF_MASK = 0xffff;
+ private final static int KF_SHIFTABLE = 0x10000;
+ private final static int KF_UPPER = 0x20000;
+ private final static int KF_LETTER = 0x40000;
+
+ {
+ // Include RETURN in this set even though it's not printable.
+ // Most other non-printable keys get handled elsewhere.
+ asciiToKeyCode['\n'] = KeyEvent.KEYCODE_ENTER | KF_SHIFTABLE;
+
+ // Non-alphanumeric ASCII codes which have their own keys
+ // (on some keyboards)
+ asciiToKeyCode[' '] = KeyEvent.KEYCODE_SPACE | KF_SHIFTABLE;
+ //asciiToKeyCode['!'] = KeyEvent.KEYCODE_;
+ //asciiToKeyCode['"'] = KeyEvent.KEYCODE_;
+ asciiToKeyCode['#'] = KeyEvent.KEYCODE_POUND;
+ //asciiToKeyCode['$'] = KeyEvent.KEYCODE_;
+ //asciiToKeyCode['%'] = KeyEvent.KEYCODE_;
+ //asciiToKeyCode['&'] = KeyEvent.KEYCODE_;
+ asciiToKeyCode['\''] = KeyEvent.KEYCODE_APOSTROPHE;
+ //asciiToKeyCode['('] = KeyEvent.KEYCODE_;
+ //asciiToKeyCode[')'] = KeyEvent.KEYCODE_;
+ asciiToKeyCode['*'] = KeyEvent.KEYCODE_STAR;
+ asciiToKeyCode['+'] = KeyEvent.KEYCODE_PLUS;
+ asciiToKeyCode[','] = KeyEvent.KEYCODE_COMMA;
+ asciiToKeyCode['-'] = KeyEvent.KEYCODE_MINUS;
+ asciiToKeyCode['.'] = KeyEvent.KEYCODE_PERIOD;
+ asciiToKeyCode['/'] = KeyEvent.KEYCODE_SLASH;
+ //asciiToKeyCode[':'] = KeyEvent.KEYCODE_;
+ asciiToKeyCode[';'] = KeyEvent.KEYCODE_SEMICOLON;
+ //asciiToKeyCode['<'] = KeyEvent.KEYCODE_;
+ asciiToKeyCode['='] = KeyEvent.KEYCODE_EQUALS;
+ //asciiToKeyCode['>'] = KeyEvent.KEYCODE_;
+ //asciiToKeyCode['?'] = KeyEvent.KEYCODE_;
+ asciiToKeyCode['@'] = KeyEvent.KEYCODE_AT;
+ asciiToKeyCode['['] = KeyEvent.KEYCODE_LEFT_BRACKET;
+ asciiToKeyCode['\\'] = KeyEvent.KEYCODE_BACKSLASH;
+ asciiToKeyCode[']'] = KeyEvent.KEYCODE_RIGHT_BRACKET;
+ //asciiToKeyCode['^'] = KeyEvent.KEYCODE_;
+ //asciiToKeyCode['_'] = KeyEvent.KEYCODE_;
+ asciiToKeyCode['`'] = KeyEvent.KEYCODE_GRAVE;
+ //asciiToKeyCode['{'] = KeyEvent.KEYCODE_;
+ //asciiToKeyCode['|'] = KeyEvent.KEYCODE_;
+ //asciiToKeyCode['}'] = KeyEvent.KEYCODE_;
+ //asciiToKeyCode['~'] = KeyEvent.KEYCODE_;
+
+
+ for (int i = 0; i <= 25; ++i) {
+ asciiToKeyCode['a' + i] = KeyEvent.KEYCODE_A + i | KF_LETTER;
+ asciiToKeyCode['A' + i] = KeyEvent.KEYCODE_A + i | KF_UPPER | KF_LETTER;
+ }
+
+ for (int i = 0; i <= 9; ++i) {
+ asciiToKeyCode['0' + i] = KeyEvent.KEYCODE_0 + i;
+ }
+ }
+
+ public void sendModifiableKeyChar(char ch) {
+ // Support modified key events
+ boolean modShift = isShiftMod();
+ if ((modShift || mModCtrl || mModAlt) && ch > 0 && ch < 127) {
+ InputConnection ic = getCurrentInputConnection();
+ if (isConnectbot()) {
+ if (mModAlt) {
+ // send ESC prefix
+ ic.commitText(Character.toString((char) 27), 1);
+ }
+ if (mModCtrl) {
+ int code = ch & 31;
+ if (code == 9) {
+ sendTab();
+ } else {
+ ic.commitText(Character.toString((char) code), 1);
+ }
+ } else {
+ ic.commitText(Character.toString(ch), 1);
+ }
+ handleModifierKeysUp(false, false);
+ return;
+ }
+
+ // Non-ConnectBot
+
+ // Restrict Shift modifier to ENTER and SPACE, supporting Shift-Enter etc.
+ // Note that most special keys such as DEL or cursor keys aren't handled
+ // by this charcode-based method.
+
+ int combinedCode = asciiToKeyCode[ch];
+ if (combinedCode > 0) {
+ int code = combinedCode & KF_MASK;
+ boolean shiftable = (combinedCode & KF_SHIFTABLE) > 0;
+ boolean upper = (combinedCode & KF_UPPER) > 0;
+ boolean letter = (combinedCode & KF_LETTER) > 0;
+ boolean shifted = modShift && (upper || shiftable);
+ if (letter && !mModCtrl && !mModAlt) {
+ // Try workaround for issue 179 where letters don't get upcased
+ ic.commitText(Character.toString(ch), 1);
+ handleModifierKeysUp(false, false);
+ } else {
+ sendModifiedKeyDownUp(code, shifted);
+ }
+ return;
+ }
+ }
+
+ if (ch >= '0' && ch <= '9') {
+ //WIP
+ InputConnection ic = getCurrentInputConnection();
+ ic.clearMetaKeyStates(KeyEvent.META_SHIFT_ON | KeyEvent.META_ALT_ON | KeyEvent.META_SYM_ON);
+ //EditorInfo ei = getCurrentInputEditorInfo();
+ //Log.i(TAG, "capsmode=" + ic.getCursorCapsMode(ei.inputType));
+ //sendModifiedKeyDownUp(KeyEvent.KEYCODE_0 + ch - '0');
+ //return;
+ }
+
+ // Default handling for anything else, including unmodified ENTER and SPACE.
+ sendKeyChar(ch);
+ }
+
+ private void sendTab() {
+ InputConnection ic = getCurrentInputConnection();
+ boolean tabHack = isConnectbot() && mConnectbotTabHack;
+
+ // FIXME: tab and ^I don't work in connectbot, hackish workaround
+ if (tabHack) {
+ if (mModAlt) {
+ // send ESC prefix
+ ic.commitText(Character.toString((char) 27), 1);
+ }
+ ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN,
+ KeyEvent.KEYCODE_DPAD_CENTER));
+ ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP,
+ KeyEvent.KEYCODE_DPAD_CENTER));
+ ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN,
+ KeyEvent.KEYCODE_I));
+ ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP,
+ KeyEvent.KEYCODE_I));
+ } else {
+ sendModifiedKeyDownUp(KeyEvent.KEYCODE_TAB);
+ }
+ }
+
+ private void sendEscape() {
+ if (isConnectbot()) {
+ sendKeyChar((char) 27);
+ } else {
+ sendModifiedKeyDownUp(111 /*KeyEvent.KEYCODE_ESCAPE */);
+ }
+ }
+
+ private boolean processMultiKey(int primaryCode) {
+ if (mDeadAccentBuffer.composeBuffer.length() > 0) {
+ //Log.i(TAG, "processMultiKey: pending DeadAccent, length=" + mDeadAccentBuffer.composeBuffer.length());
+ mDeadAccentBuffer.execute(primaryCode);
+ mDeadAccentBuffer.clear();
+ return true;
+ }
+ if (mComposeMode) {
+ mComposeMode = mComposeBuffer.execute(primaryCode);
+ return true;
+ }
+ return false;
+ }
+
+ // Implementation of KeyboardViewListener
+
+ public void onKey(int primaryCode, int[] keyCodes, int x, int y) {
+ long when = SystemClock.uptimeMillis();
+ if (primaryCode != Keyboard.KEYCODE_DELETE
+ || when > mLastKeyTime + QUICK_PRESS) {
+ mDeleteCount = 0;
+ }
+ mLastKeyTime = when;
+ final boolean distinctMultiTouch = mKeyboardSwitcher
+ .hasDistinctMultitouch();
+ switch (primaryCode) {
+ case Keyboard.KEYCODE_DELETE:
+ if (processMultiKey(primaryCode)) {
+ break;
+ }
+ handleBackspace();
+ mDeleteCount++;
+ LatinImeLogger.logOnDelete();
+ break;
+ case Keyboard.KEYCODE_SHIFT:
+ // Shift key is handled in onPress() when device has distinct
+ // multi-touch panel.
+ if (!distinctMultiTouch)
+ handleShift();
+ break;
+ case Keyboard.KEYCODE_MODE_CHANGE:
+ // Symbol key is handled in onPress() when device has distinct
+ // multi-touch panel.
+ if (!distinctMultiTouch)
+ changeKeyboardMode();
+ break;
+ case LatinKeyboardView.KEYCODE_CTRL_LEFT:
+ // Ctrl key is handled in onPress() when device has distinct
+ // multi-touch panel.
+ if (!distinctMultiTouch)
+ setModCtrl(!mModCtrl);
+ break;
+ case LatinKeyboardView.KEYCODE_ALT_LEFT:
+ // Alt key is handled in onPress() when device has distinct
+ // multi-touch panel.
+ if (!distinctMultiTouch)
+ setModAlt(!mModAlt);
+ break;
+ case LatinKeyboardView.KEYCODE_FN:
+ if (!distinctMultiTouch)
+ setModFn(!mModFn);
+ break;
+ case Keyboard.KEYCODE_CANCEL:
+ if (!isShowingOptionDialog()) {
+ handleClose();
+ }
+ break;
+ case LatinKeyboardView.KEYCODE_OPTIONS:
+ onOptionKeyPressed();
+ break;
+ case LatinKeyboardView.KEYCODE_OPTIONS_LONGPRESS:
+ onOptionKeyLongPressed();
+ break;
+ case LatinKeyboardView.KEYCODE_COMPOSE:
+ mComposeMode = !mComposeMode;
+ mComposeBuffer.clear();
+ break;
+ case LatinKeyboardView.KEYCODE_NEXT_LANGUAGE:
+ toggleLanguage(false, true);
+ break;
+ case LatinKeyboardView.KEYCODE_PREV_LANGUAGE:
+ toggleLanguage(false, false);
+ break;
+ case LatinKeyboardView.KEYCODE_VOICE:
+ if (VOICE_INSTALLED) {
+ startListening(false /* was a button press, was not a swipe */);
+ }
+ break;
+ case 9 /* Tab */:
+ if (processMultiKey(primaryCode)) {
+ break;
+ }
+ sendTab();
+ break;
+ case LatinKeyboardView.KEYCODE_ESCAPE:
+ if (processMultiKey(primaryCode)) {
+ break;
+ }
+ sendEscape();
+ break;
+ case LatinKeyboardView.KEYCODE_DPAD_UP:
+ case LatinKeyboardView.KEYCODE_DPAD_DOWN:
+ case LatinKeyboardView.KEYCODE_DPAD_LEFT:
+ case LatinKeyboardView.KEYCODE_DPAD_RIGHT:
+ case LatinKeyboardView.KEYCODE_DPAD_CENTER:
+ case LatinKeyboardView.KEYCODE_HOME:
+ case LatinKeyboardView.KEYCODE_END:
+ case LatinKeyboardView.KEYCODE_PAGE_UP:
+ case LatinKeyboardView.KEYCODE_PAGE_DOWN:
+ case LatinKeyboardView.KEYCODE_FKEY_F1:
+ case LatinKeyboardView.KEYCODE_FKEY_F2:
+ case LatinKeyboardView.KEYCODE_FKEY_F3:
+ case LatinKeyboardView.KEYCODE_FKEY_F4:
+ case LatinKeyboardView.KEYCODE_FKEY_F5:
+ case LatinKeyboardView.KEYCODE_FKEY_F6:
+ case LatinKeyboardView.KEYCODE_FKEY_F7:
+ case LatinKeyboardView.KEYCODE_FKEY_F8:
+ case LatinKeyboardView.KEYCODE_FKEY_F9:
+ case LatinKeyboardView.KEYCODE_FKEY_F10:
+ case LatinKeyboardView.KEYCODE_FKEY_F11:
+ case LatinKeyboardView.KEYCODE_FKEY_F12:
+ case LatinKeyboardView.KEYCODE_FORWARD_DEL:
+ case LatinKeyboardView.KEYCODE_INSERT:
+ case LatinKeyboardView.KEYCODE_SYSRQ:
+ case LatinKeyboardView.KEYCODE_BREAK:
+ case LatinKeyboardView.KEYCODE_NUM_LOCK:
+ case LatinKeyboardView.KEYCODE_SCROLL_LOCK:
+ if (processMultiKey(primaryCode)) {
+ break;
+ }
+ // send as plain keys, or as escape sequence if needed
+ sendSpecialKey(-primaryCode);
+ break;
+ default:
+ if (!mComposeMode && mDeadKeysActive && Character.getType(primaryCode) == Character.NON_SPACING_MARK) {
+ //Log.i(TAG, "possible dead character: " + primaryCode);
+ if (!mDeadAccentBuffer.execute(primaryCode)) {
+ //Log.i(TAG, "double dead key");
+ break; // pressing a dead key twice produces spacing equivalent
+ }
+ updateShiftKeyState(getCurrentInputEditorInfo());
+ break;
+ }
+ if (processMultiKey(primaryCode)) {
+ break;
+ }
+ if (primaryCode != ASCII_ENTER) {
+ mJustAddedAutoSpace = false;
+ }
+ RingCharBuffer.getInstance().push((char) primaryCode, x, y);
+ LatinImeLogger.logOnInputChar();
+ if (isWordSeparator(primaryCode)) {
+ handleSeparator(primaryCode);
+ } else {
+ handleCharacter(primaryCode, keyCodes);
+ }
+ // Cancel the just reverted state
+ mJustRevertedSeparator = null;
+ }
+ mKeyboardSwitcher.onKey(primaryCode);
+ // Reset after any single keystroke
+ mEnteredText = null;
+ //mDeadAccentBuffer.clear(); // FIXME
+ }
+
+ public void onText(CharSequence text) {
+ if (VOICE_INSTALLED && mVoiceInputHighlighted) {
+ commitVoiceInput();
+ }
+ //mDeadAccentBuffer.clear(); // FIXME
+ InputConnection ic = getCurrentInputConnection();
+ if (ic == null)
+ return;
+ abortCorrection(false);
+ ic.beginBatchEdit();
+ if (mPredicting) {
+ commitTyped(ic, true);
+ }
+ maybeRemovePreviousPeriod(text);
+ ic.commitText(text, 1);
+ ic.endBatchEdit();
+ updateShiftKeyState(getCurrentInputEditorInfo());
+ mKeyboardSwitcher.onKey(0); // dummy key code.
+ mJustRevertedSeparator = null;
+ mJustAddedAutoSpace = false;
+ mEnteredText = text;
+ }
+
+ public void onCancel() {
+ // User released a finger outside any key
+ mKeyboardSwitcher.onCancelInput();
+ }
+
+ private void handleBackspace() {
+ if (VOICE_INSTALLED && mVoiceInputHighlighted) {
+ mVoiceInput
+ .incrementTextModificationDeleteCount(mVoiceResults.candidates
+ .get(0).toString().length());
+ revertVoiceInput();
+ return;
+ }
+ boolean deleteChar = false;
+ InputConnection ic = getCurrentInputConnection();
+ if (ic == null)
+ return;
+
+ ic.beginBatchEdit();
+
+ if (mAfterVoiceInput) {
+ // Don't log delete if the user is pressing delete at
+ // the beginning of the text box (hence not deleting anything)
+ if (mVoiceInput.getCursorPos() > 0) {
+ // If anything was selected before the delete was pressed,
+ // increment the
+ // delete count by the length of the selection
+ int deleteLen = mVoiceInput.getSelectionSpan() > 0 ? mVoiceInput
+ .getSelectionSpan()
+ : 1;
+ mVoiceInput.incrementTextModificationDeleteCount(deleteLen);
+ }
+ }
+
+ if (mPredicting) {
+ final int length = mComposing.length();
+ if (length > 0) {
+ mComposing.delete(length - 1, length);
+ mWord.deleteLast();
+ ic.setComposingText(mComposing, 1);
+ if (mComposing.length() == 0) {
+ mPredicting = false;
+ }
+ postUpdateSuggestions();
+ } else {
+ ic.deleteSurroundingText(1, 0);
+ }
+ } else {
+ deleteChar = true;
+ }
+ postUpdateShiftKeyState();
+ TextEntryState.backspace();
+ if (TextEntryState.getState() == TextEntryState.State.UNDO_COMMIT) {
+ revertLastWord(deleteChar);
+ ic.endBatchEdit();
+ return;
+ } else if (mEnteredText != null
+ && sameAsTextBeforeCursor(ic, mEnteredText)) {
+ ic.deleteSurroundingText(mEnteredText.length(), 0);
+ } else if (deleteChar) {
+ if (mCandidateView != null
+ && mCandidateView.dismissAddToDictionaryHint()) {
+ // Go back to the suggestion mode if the user canceled the
+ // "Touch again to save".
+ // NOTE: In gerenal, we don't revert the word when backspacing
+ // from a manual suggestion pick. We deliberately chose a
+ // different behavior only in the case of picking the first
+ // suggestion (typed word). It's intentional to have made this
+ // inconsistent with backspacing after selecting other
+ // suggestions.
+ revertLastWord(deleteChar);
+ } else {
+ sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL);
+ if (mDeleteCount > DELETE_ACCELERATE_AT) {
+ sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL);
+ }
+ }
+ }
+ mJustRevertedSeparator = null;
+ ic.endBatchEdit();
+ }
+
+ private void setModCtrl(boolean val) {
+ // Log.i("LatinIME", "setModCtrl "+ mModCtrl + "->" + val + ", momentary=" + mCtrlKeyState.isMomentary());
+ mKeyboardSwitcher.setCtrlIndicator(val);
+ mModCtrl = val;
+ }
+
+ private void setModAlt(boolean val) {
+ // Log.i("LatinIME", "setModAlt "+ mModAlt + "->" + val + ", momentary=" + mAltKeyState.isMomentary());
+ mKeyboardSwitcher.setAltIndicator(val);
+ mModAlt = val;
+ }
+
+ private void setModFn(boolean val) {
+ //Log.i("LatinIME", "setModFn " + mModFn + "->" + val + ", momentary=" + mFnKeyState.isMomentary());
+ mModFn = val;
+ mKeyboardSwitcher.setFn(val);
+ mKeyboardSwitcher.setCtrlIndicator(mModCtrl);
+ mKeyboardSwitcher.setAltIndicator(mModAlt);
+ }
+
+ private void startMultitouchShift() {
+ int newState = Keyboard.SHIFT_ON;
+ if (mKeyboardSwitcher.isAlphabetMode()) {
+ mSavedShiftState = getShiftState();
+ if (mSavedShiftState == Keyboard.SHIFT_LOCKED) newState = Keyboard.SHIFT_CAPS;
+ }
+ handleShiftInternal(true, newState);
+ }
+
+ private void commitMultitouchShift() {
+ if (mKeyboardSwitcher.isAlphabetMode()) {
+ int newState = nextShiftState(mSavedShiftState, true);
+ handleShiftInternal(true, newState);
+ } else {
+ // do nothing, keyboard is already flipped
+ }
+ }
+
+ private void resetMultitouchShift() {
+ int newState = Keyboard.SHIFT_OFF;
+ if (mSavedShiftState == Keyboard.SHIFT_CAPS_LOCKED || mSavedShiftState == Keyboard.SHIFT_LOCKED) {
+ newState = mSavedShiftState;
+ }
+ handleShiftInternal(true, newState);
+ }
+
+ private void resetShift() {
+ handleShiftInternal(true, Keyboard.SHIFT_OFF);
+ }
+
+ private void handleShift() {
+ handleShiftInternal(false, -1);
+ }
+
+ private static int getCapsOrShiftLockState() {
+ return sKeyboardSettings.capsLock ? Keyboard.SHIFT_CAPS_LOCKED : Keyboard.SHIFT_LOCKED;
+ }
+
+ // Rotate through shift states by successively pressing and releasing the Shift key.
+ private static int nextShiftState(int prevState, boolean allowCapsLock) {
+ if (allowCapsLock) {
+ if (prevState == Keyboard.SHIFT_OFF) {
+ return Keyboard.SHIFT_ON;
+ } else if (prevState == Keyboard.SHIFT_ON) {
+ return getCapsOrShiftLockState();
+ } else {
+ return Keyboard.SHIFT_OFF;
+ }
+ } else {
+ // currently unused, see toggleShift()
+ if (prevState == Keyboard.SHIFT_OFF) {
+ return Keyboard.SHIFT_ON;
+ } else {
+ return Keyboard.SHIFT_OFF;
+ }
+ }
+ }
+
+ private void handleShiftInternal(boolean forceState, int newState) {
+ //Log.i(TAG, "handleShiftInternal forceNormal=" + forceNormal);
+ mHandler.removeMessages(MSG_UPDATE_SHIFT_STATE);
+ KeyboardSwitcher switcher = mKeyboardSwitcher;
+ if (switcher.isAlphabetMode()) {
+ if (forceState) {
+ switcher.setShiftState(newState);
+ } else {
+ switcher.setShiftState(nextShiftState(getShiftState(), true));
+ }
+ } else {
+ switcher.toggleShift();
+ }
+ }
+
+ private void abortCorrection(boolean force) {
+ if (force || TextEntryState.isCorrecting()) {
+ getCurrentInputConnection().finishComposingText();
+ clearSuggestions();
+ }
+ }
+
+ private void handleCharacter(int primaryCode, int[] keyCodes) {
+ if (VOICE_INSTALLED && mVoiceInputHighlighted) {
+ commitVoiceInput();
+ }
+
+ if (mAfterVoiceInput) {
+ // Assume input length is 1. This assumption fails for smiley face
+ // insertions.
+ mVoiceInput.incrementTextModificationInsertCount(1);
+ }
+ if (mLastSelectionStart == mLastSelectionEnd
+ && TextEntryState.isCorrecting()) {
+ abortCorrection(false);
+ }
+
+ if (isAlphabet(primaryCode) && isPredictionOn()
+ && !mModCtrl && !mModAlt
+ && !isCursorTouchingWord()) {
+ if (!mPredicting) {
+ mPredicting = true;
+ mComposing.setLength(0);
+ saveWordInHistory(mBestWord);
+ mWord.reset();
+ }
+ }
+
+ if (mModCtrl || mModAlt) {
+ commitTyped(getCurrentInputConnection(), true); // sets mPredicting=false
+ }
+
+ if (mPredicting) {
+ if (isShiftCapsMode()
+ && mKeyboardSwitcher.isAlphabetMode()
+ && mComposing.length() == 0) {
+ // Show suggestions with initial caps if starting out shifted,
+ // could be either auto-caps or manual shift.
+ mWord.setFirstCharCapitalized(true);
+ }
+ mComposing.append((char) primaryCode);
+ mWord.add(primaryCode, keyCodes);
+ InputConnection ic = getCurrentInputConnection();
+ if (ic != null) {
+ // If it's the first letter, make note of auto-caps state
+ if (mWord.size() == 1) {
+ mWord.setAutoCapitalized(getCursorCapsMode(ic,
+ getCurrentInputEditorInfo()) != 0);
+ }
+ ic.setComposingText(mComposing, 1);
+ }
+ postUpdateSuggestions();
+ } else {
+ sendModifiableKeyChar((char) primaryCode);
+ }
+ updateShiftKeyState(getCurrentInputEditorInfo());
+ if (LatinIME.PERF_DEBUG)
+ measureCps();
+ TextEntryState.typedCharacter((char) primaryCode,
+ isWordSeparator(primaryCode));
+ }
+
+ private void handleSeparator(int primaryCode) {
+ if (VOICE_INSTALLED && mVoiceInputHighlighted) {
+ commitVoiceInput();
+ }
+
+ if (mAfterVoiceInput) {
+ // Assume input length is 1. This assumption fails for smiley face
+ // insertions.
+ mVoiceInput.incrementTextModificationInsertPunctuationCount(1);
+ }
+
+ // Should dismiss the "Touch again to save" message when handling
+ // separator
+ if (mCandidateView != null
+ && mCandidateView.dismissAddToDictionaryHint()) {
+ postUpdateSuggestions();
+ }
+
+ boolean pickedDefault = false;
+ // Handle separator
+ InputConnection ic = getCurrentInputConnection();
+ if (ic != null) {
+ ic.beginBatchEdit();
+ abortCorrection(false);
+ }
+ if (mPredicting) {
+ // In certain languages where single quote is a separator, it's
+ // better
+ // not to auto correct, but accept the typed word. For instance,
+ // in Italian dov' should not be expanded to dove' because the
+ // elision
+ // requires the last vowel to be removed.
+ if (mAutoCorrectOn
+ && primaryCode != '\''
+ && (mJustRevertedSeparator == null
+ || mJustRevertedSeparator.length() == 0
+ || mJustRevertedSeparator.charAt(0) != primaryCode)) {
+ pickedDefault = pickDefaultSuggestion();
+ // Picked the suggestion by the space key. We consider this
+ // as "added an auto space" in autocomplete mode, but as manually
+ // typed space in "quick fixes" mode.
+ if (primaryCode == ASCII_SPACE) {
+ if (mAutoCorrectEnabled) {
+ mJustAddedAutoSpace = true;
+ } else {
+ TextEntryState.manualTyped("");
+ }
+ }
+ } else {
+ commitTyped(ic, true);
+ }
+ }
+ if (mJustAddedAutoSpace && primaryCode == ASCII_ENTER) {
+ removeTrailingSpace();
+ mJustAddedAutoSpace = false;
+ }
+ sendModifiableKeyChar((char) primaryCode);
+
+ // Handle the case of ". ." -> " .." with auto-space if necessary
+ // before changing the TextEntryState.
+ if (TextEntryState.getState() == TextEntryState.State.PUNCTUATION_AFTER_ACCEPTED
+ && primaryCode == ASCII_PERIOD) {
+ reswapPeriodAndSpace();
+ }
+
+ TextEntryState.typedCharacter((char) primaryCode, true);
+ if (TextEntryState.getState() == TextEntryState.State.PUNCTUATION_AFTER_ACCEPTED
+ && primaryCode != ASCII_ENTER) {
+ swapPunctuationAndSpace();
+ } else if (isPredictionOn() && primaryCode == ASCII_SPACE) {
+ doubleSpace();
+ }
+ if (pickedDefault) {
+ TextEntryState.backToAcceptedDefault(mWord.getTypedWord());
+ }
+ updateShiftKeyState(getCurrentInputEditorInfo());
+ if (ic != null) {
+ ic.endBatchEdit();
+ }
+ }
+
+ private void handleClose() {
+ commitTyped(getCurrentInputConnection(), true);
+ if (VOICE_INSTALLED & mRecognizing) {
+ mVoiceInput.cancel();
+ }
+ requestHideSelf(0);
+ if (mKeyboardSwitcher != null) {
+ LatinKeyboardView inputView = mKeyboardSwitcher.getInputView();
+ if (inputView != null) {
+ inputView.closing();
+ }
+ }
+ TextEntryState.endSession();
+ }
+
+ private void saveWordInHistory(CharSequence result) {
+ if (mWord.size() <= 1) {
+ mWord.reset();
+ return;
+ }
+ // Skip if result is null. It happens in some edge case.
+ if (TextUtils.isEmpty(result)) {
+ return;
+ }
+
+ // Make a copy of the CharSequence, since it is/could be a mutable
+ // CharSequence
+ final String resultCopy = result.toString();
+ TypedWordAlternatives entry = new TypedWordAlternatives(resultCopy,
+ new WordComposer(mWord));
+ mWordHistory.add(entry);
+ }
+
+ private void postUpdateSuggestions() {
+ mHandler.removeMessages(MSG_UPDATE_SUGGESTIONS);
+ mHandler.sendMessageDelayed(mHandler
+ .obtainMessage(MSG_UPDATE_SUGGESTIONS), 100);
+ }
+
+ private void postUpdateOldSuggestions() {
+ mHandler.removeMessages(MSG_UPDATE_OLD_SUGGESTIONS);
+ mHandler.sendMessageDelayed(mHandler
+ .obtainMessage(MSG_UPDATE_OLD_SUGGESTIONS), 300);
+ }
+
+ private boolean isPredictionOn() {
+ return mPredictionOnForMode && isPredictionWanted();
+ }
+
+ private boolean isPredictionWanted() {
+ return (mShowSuggestions || mSuggestionForceOn) && !suggestionsDisabled();
+ }
+
+ private boolean isCandidateStripVisible() {
+ return isPredictionOn();
+ }
+
+ public void onCancelVoice() {
+ if (mRecognizing) {
+ switchToKeyboardView();
+ }
+ }
+
+ private void switchToKeyboardView() {
+ mHandler.post(new Runnable() {
+ public void run() {
+ mRecognizing = false;
+ LatinKeyboardView view = mKeyboardSwitcher.getInputView();
+ if (view != null) {
+ ViewParent p = view.getParent();
+ if (p != null && p instanceof ViewGroup) {
+ ((ViewGroup) p).removeView(view);
+ }
+ setInputView(mKeyboardSwitcher.getInputView());
+ }
+ setCandidatesViewShown(true);
+ updateInputViewShown();
+ postUpdateSuggestions();
+ }
+ });
+ }
+
+ private void switchToRecognitionStatusView() {
+ final boolean configChanged = mConfigurationChanging;
+ mHandler.post(new Runnable() {
+ public void run() {
+ setCandidatesViewShown(false);
+ mRecognizing = true;
+ View v = mVoiceInput.getView();
+ ViewParent p = v.getParent();
+ if (p != null && p instanceof ViewGroup) {
+ ((ViewGroup) v.getParent()).removeView(v);
+ }
+ setInputView(v);
+ updateInputViewShown();
+ if (configChanged) {
+ mVoiceInput.onConfigurationChanged();
+ }
+ }
+ });
+ }
+
+ private void startListening(boolean swipe) {
+ if (!mHasUsedVoiceInput
+ || (!mLocaleSupportedForVoiceInput && !mHasUsedVoiceInputUnsupportedLocale)) {
+ // Calls reallyStartListening if user clicks OK, does nothing if
+ // user clicks Cancel.
+ showVoiceWarningDialog(swipe);
+ } else {
+ reallyStartListening(swipe);
+ }
+ }
+
+ private void reallyStartListening(boolean swipe) {
+ if (!mHasUsedVoiceInput) {
+ // The user has started a voice input, so remember that in the
+ // future (so we don't show the warning dialog after the first run).
+ SharedPreferences.Editor editor = PreferenceManager
+ .getDefaultSharedPreferences(this).edit();
+ editor.putBoolean(PREF_HAS_USED_VOICE_INPUT, true);
+ SharedPreferencesCompat.apply(editor);
+ mHasUsedVoiceInput = true;
+ }
+
+ if (!mLocaleSupportedForVoiceInput
+ && !mHasUsedVoiceInputUnsupportedLocale) {
+ // The user has started a voice input from an unsupported locale, so
+ // remember that
+ // in the future (so we don't show the warning dialog the next time
+ // they do this).
+ SharedPreferences.Editor editor = PreferenceManager
+ .getDefaultSharedPreferences(this).edit();
+ editor.putBoolean(PREF_HAS_USED_VOICE_INPUT_UNSUPPORTED_LOCALE,
+ true);
+ SharedPreferencesCompat.apply(editor);
+ mHasUsedVoiceInputUnsupportedLocale = true;
+ }
+
+ // Clear N-best suggestions
+ clearSuggestions();
+
+ FieldContext context = new FieldContext(getCurrentInputConnection(),
+ getCurrentInputEditorInfo(), mLanguageSwitcher
+ .getInputLanguage(), mLanguageSwitcher
+ .getEnabledLanguages());
+ mVoiceInput.startListening(context, swipe);
+ switchToRecognitionStatusView();
+ }
+
+ private void showVoiceWarningDialog(final boolean swipe) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setCancelable(true);
+ builder.setIcon(R.drawable.ic_mic_dialog);
+ builder.setPositiveButton(android.R.string.ok,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int whichButton) {
+ mVoiceInput.logKeyboardWarningDialogOk();
+ reallyStartListening(swipe);
+ }
+ });
+ builder.setNegativeButton(android.R.string.cancel,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int whichButton) {
+ mVoiceInput.logKeyboardWarningDialogCancel();
+ }
+ });
+
+ if (mLocaleSupportedForVoiceInput) {
+ String message = getString(R.string.voice_warning_may_not_understand)
+ + "\n\n"
+ + getString(R.string.voice_warning_how_to_turn_off);
+ builder.setMessage(message);
+ } else {
+ String message = getString(R.string.voice_warning_locale_not_supported)
+ + "\n\n"
+ + getString(R.string.voice_warning_may_not_understand)
+ + "\n\n"
+ + getString(R.string.voice_warning_how_to_turn_off);
+ builder.setMessage(message);
+ }
+
+ builder.setTitle(R.string.voice_warning_title);
+ mVoiceWarningDialog = builder.create();
+
+ Window window = mVoiceWarningDialog.getWindow();
+ WindowManager.LayoutParams lp = window.getAttributes();
+ lp.token = mKeyboardSwitcher.getInputView().getWindowToken();
+ lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
+ window.setAttributes(lp);
+ window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
+ mVoiceInput.logKeyboardWarningDialogShown();
+ mVoiceWarningDialog.show();
+ }
+
+ public void onVoiceResults(List<String> candidates,
+ Map<String, List<CharSequence>> alternatives) {
+ if (!mRecognizing) {
+ return;
+ }
+ mVoiceResults.candidates = candidates;
+ mVoiceResults.alternatives = alternatives;
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_VOICE_RESULTS));
+ }
+
+ private void handleVoiceResults() {
+ mAfterVoiceInput = true;
+ mImmediatelyAfterVoiceInput = true;
+
+ InputConnection ic = getCurrentInputConnection();
+ if (!isFullscreenMode()) {
+ // Start listening for updates to the text from typing, etc.
+ if (ic != null) {
+ ExtractedTextRequest req = new ExtractedTextRequest();
+ ic.getExtractedText(req,
+ InputConnection.GET_EXTRACTED_TEXT_MONITOR);
+ }
+ }
+
+ vibrate();
+ switchToKeyboardView();
+
+ final List<CharSequence> nBest = new ArrayList<CharSequence>();
+ boolean capitalizeFirstWord = preferCapitalization()
+ || (mKeyboardSwitcher.isAlphabetMode()
+ && isShiftCapsMode() );
+ for (String c : mVoiceResults.candidates) {
+ if (capitalizeFirstWord) {
+ c = c.substring(0,1).toUpperCase(sKeyboardSettings.inputLocale)
+ + c.substring(1, c.length());
+ }
+ nBest.add(c);
+ }
+
+ if (nBest.size() == 0) {
+ return;
+ }
+
+ String bestResult = nBest.get(0).toString();
+
+ mVoiceInput.logVoiceInputDelivered(bestResult.length());
+
+ mHints.registerVoiceResult(bestResult);
+
+ if (ic != null)
+ ic.beginBatchEdit(); // To avoid extra updates on committing older
+ // text
+
+ commitTyped(ic, false);
+ EditingUtil.appendText(ic, bestResult);
+
+ if (ic != null)
+ ic.endBatchEdit();
+
+ mVoiceInputHighlighted = true;
+ mWordToSuggestions.putAll(mVoiceResults.alternatives);
+ }
+
+ private void clearSuggestions() {
+ setSuggestions(null, false, false, false);
+ }
+
+ private void setSuggestions(List<CharSequence> suggestions,
+ boolean completions, boolean typedWordValid,
+ boolean haveMinimalSuggestion) {
+
+ if (mIsShowingHint) {
+ setCandidatesViewShown(true);
+ mIsShowingHint = false;
+ }
+
+ if (mCandidateView != null) {
+ mCandidateView.setSuggestions(suggestions, completions,
+ typedWordValid, haveMinimalSuggestion);
+ }
+ }
+
+ private void updateSuggestions() {
+ LatinKeyboardView inputView = mKeyboardSwitcher.getInputView();
+ ((LatinKeyboard) inputView.getKeyboard()).setPreferredLetters(null);
+
+ // Check if we have a suggestion engine attached.
+ if ((mSuggest == null || !isPredictionOn()) && !mVoiceInputHighlighted) {
+ return;
+ }
+
+ if (!mPredicting) {
+ setNextSuggestions();
+ return;
+ }
+ showSuggestions(mWord);
+ }
+
+ private List<CharSequence> getTypedSuggestions(WordComposer word) {
+ List<CharSequence> stringList = mSuggest.getSuggestions(
+ mKeyboardSwitcher.getInputView(), word, false, null);
+ return stringList;
+ }
+
+ private void showCorrections(WordAlternatives alternatives) {
+ List<CharSequence> stringList = alternatives.getAlternatives();
+ ((LatinKeyboard) mKeyboardSwitcher.getInputView().getKeyboard())
+ .setPreferredLetters(null);
+ showSuggestions(stringList, alternatives.getOriginalWord(), false,
+ false);
+ }
+
+ private void showSuggestions(WordComposer word) {
+ // long startTime = System.currentTimeMillis(); // TIME MEASUREMENT!
+ // TODO Maybe need better way of retrieving previous word
+ CharSequence prevWord = EditingUtil.getPreviousWord(
+ getCurrentInputConnection(), mWordSeparators);
+ List<CharSequence> stringList = mSuggest.getSuggestions(
+ mKeyboardSwitcher.getInputView(), word, false, prevWord);
+ // long stopTime = System.currentTimeMillis(); // TIME MEASUREMENT!
+ // Log.d("LatinIME","Suggest Total Time - " + (stopTime - startTime));
+
+ int[] nextLettersFrequencies = mSuggest.getNextLettersFrequencies();
+
+ ((LatinKeyboard) mKeyboardSwitcher.getInputView().getKeyboard())
+ .setPreferredLetters(nextLettersFrequencies);
+
+ boolean correctionAvailable = !mInputTypeNoAutoCorrect
+ && mSuggest.hasMinimalCorrection();
+ // || mCorrectionMode == mSuggest.CORRECTION_FULL;
+ CharSequence typedWord = word.getTypedWord();
+ // If we're in basic correct
+ boolean typedWordValid = mSuggest.isValidWord(typedWord)
+ || (preferCapitalization() && mSuggest.isValidWord(typedWord
+ .toString().toLowerCase()));
+ if (mCorrectionMode == Suggest.CORRECTION_FULL
+ || mCorrectionMode == Suggest.CORRECTION_FULL_BIGRAM) {
+ correctionAvailable |= typedWordValid;
+ }
+ // Don't auto-correct words with multiple capital letter
+ correctionAvailable &= !word.isMostlyCaps();
+ correctionAvailable &= !TextEntryState.isCorrecting();
+
+ showSuggestions(stringList, typedWord, typedWordValid,
+ correctionAvailable);
+ }
+
+ private void showSuggestions(List<CharSequence> stringList,
+ CharSequence typedWord, boolean typedWordValid,
+ boolean correctionAvailable) {
+ setSuggestions(stringList, false, typedWordValid, correctionAvailable);
+ if (stringList.size() > 0) {
+ if (correctionAvailable && !typedWordValid && stringList.size() > 1) {
+ mBestWord = stringList.get(1);
+ } else {
+ mBestWord = typedWord;
+ }
+ } else {
+ mBestWord = null;
+ }
+ setCandidatesViewShown(isCandidateStripVisible() || mCompletionOn);
+ }
+
+ private boolean pickDefaultSuggestion() {
+ // Complete any pending candidate query first
+ if (mHandler.hasMessages(MSG_UPDATE_SUGGESTIONS)) {
+ mHandler.removeMessages(MSG_UPDATE_SUGGESTIONS);
+ updateSuggestions();
+ }
+ if (mBestWord != null && mBestWord.length() > 0) {
+ TextEntryState.acceptedDefault(mWord.getTypedWord(), mBestWord);
+ mJustAccepted = true;
+ pickSuggestion(mBestWord, false);
+ // Add the word to the auto dictionary if it's not a known word
+ addToDictionaries(mBestWord, AutoDictionary.FREQUENCY_FOR_TYPED);
+ return true;
+
+ }
+ return false;
+ }
+
+ public void pickSuggestionManually(int index, CharSequence suggestion) {
+ List<CharSequence> suggestions = mCandidateView.getSuggestions();
+
+ if (mAfterVoiceInput && mShowingVoiceSuggestions) {
+ mVoiceInput.flushAllTextModificationCounters();
+ // send this intent AFTER logging any prior aggregated edits.
+ mVoiceInput.logTextModifiedByChooseSuggestion(
+ suggestion.toString(), index, mWordSeparators,
+ getCurrentInputConnection());
+ }
+
+ final boolean correcting = TextEntryState.isCorrecting();
+ InputConnection ic = getCurrentInputConnection();
+ if (ic != null) {
+ ic.beginBatchEdit();
+ }
+ if (mCompletionOn && mCompletions != null && index >= 0
+ && index < mCompletions.length) {
+ CompletionInfo ci = mCompletions[index];
+ if (ic != null) {
+ ic.commitCompletion(ci);
+ }
+ mCommittedLength = suggestion.length();
+ if (mCandidateView != null) {
+ mCandidateView.clear();
+ }
+ updateShiftKeyState(getCurrentInputEditorInfo());
+ if (ic != null) {
+ ic.endBatchEdit();
+ }
+ return;
+ }
+
+ // If this is a punctuation, apply it through the normal key press
+ if (suggestion.length() == 1
+ && (isWordSeparator(suggestion.charAt(0)) || isSuggestedPunctuation(suggestion
+ .charAt(0)))) {
+ // Word separators are suggested before the user inputs something.
+ // So, LatinImeLogger logs "" as a user's input.
+ LatinImeLogger.logOnManualSuggestion("", suggestion.toString(),
+ index, suggestions);
+ final char primaryCode = suggestion.charAt(0);
+ onKey(primaryCode, new int[] { primaryCode },
+ LatinKeyboardBaseView.NOT_A_TOUCH_COORDINATE,
+ LatinKeyboardBaseView.NOT_A_TOUCH_COORDINATE);
+ if (ic != null) {
+ ic.endBatchEdit();
+ }
+ return;
+ }
+ mJustAccepted = true;
+ pickSuggestion(suggestion, correcting);
+ // Add the word to the auto dictionary if it's not a known word
+ if (index == 0) {
+ addToDictionaries(suggestion, AutoDictionary.FREQUENCY_FOR_PICKED);
+ } else {
+ addToBigramDictionary(suggestion, 1);
+ }
+ LatinImeLogger.logOnManualSuggestion(mComposing.toString(), suggestion
+ .toString(), index, suggestions);
+ TextEntryState.acceptedSuggestion(mComposing.toString(), suggestion);
+ // Follow it with a space
+ if (mAutoSpace && !correcting) {
+ sendSpace();
+ mJustAddedAutoSpace = true;
+ }
+
+ final boolean showingAddToDictionaryHint = index == 0
+ && mCorrectionMode > 0 && !mSuggest.isValidWord(suggestion)
+ && !mSuggest.isValidWord(suggestion.toString().toLowerCase());
+
+ if (!correcting) {
+ // Fool the state watcher so that a subsequent backspace will not do
+ // a revert, unless
+ // we just did a correction, in which case we need to stay in
+ // TextEntryState.State.PICKED_SUGGESTION state.
+ TextEntryState.typedCharacter((char) ASCII_SPACE, true);
+ setNextSuggestions();
+ } else if (!showingAddToDictionaryHint) {
+ // If we're not showing the "Touch again to save", then show
+ // corrections again.
+ // In case the cursor position doesn't change, make sure we show the
+ // suggestions again.
+ clearSuggestions();
+ postUpdateOldSuggestions();
+ }
+ if (showingAddToDictionaryHint) {
+ mCandidateView.showAddToDictionaryHint(suggestion);
+ }
+ if (ic != null) {
+ ic.endBatchEdit();
+ }
+ }
+
+ private void rememberReplacedWord(CharSequence suggestion) {
+ if (mShowingVoiceSuggestions) {
+ // Retain the replaced word in the alternatives array.
+ EditingUtil.Range range = new EditingUtil.Range();
+ String wordToBeReplaced = EditingUtil.getWordAtCursor(
+ getCurrentInputConnection(), mWordSeparators, range);
+ if (!mWordToSuggestions.containsKey(wordToBeReplaced)) {
+ wordToBeReplaced = wordToBeReplaced.toLowerCase();
+ }
+ if (mWordToSuggestions.containsKey(wordToBeReplaced)) {
+ List<CharSequence> suggestions = mWordToSuggestions
+ .get(wordToBeReplaced);
+ if (suggestions.contains(suggestion)) {
+ suggestions.remove(suggestion);
+ }
+ suggestions.add(wordToBeReplaced);
+ mWordToSuggestions.remove(wordToBeReplaced);
+ mWordToSuggestions.put(suggestion.toString(), suggestions);
+ }
+ }
+ }
+
+ /**
+ * Commits the chosen word to the text field and saves it for later
+ * retrieval.
+ *
+ * @param suggestion
+ * the suggestion picked by the user to be committed to the text
+ * field
+ * @param correcting
+ * whether this is due to a correction of an existing word.
+ */
+ private void pickSuggestion(CharSequence suggestion, boolean correcting) {
+ LatinKeyboardView inputView = mKeyboardSwitcher.getInputView();
+ int shiftState = getShiftState();
+ if (shiftState == Keyboard.SHIFT_LOCKED || shiftState == Keyboard.SHIFT_CAPS_LOCKED) {
+ suggestion = suggestion.toString().toUpperCase(); // all UPPERCASE
+ }
+ InputConnection ic = getCurrentInputConnection();
+ if (ic != null) {
+ rememberReplacedWord(suggestion);
+ ic.commitText(suggestion, 1);
+ }
+ saveWordInHistory(suggestion);
+ mPredicting = false;
+ mCommittedLength = suggestion.length();
+ ((LatinKeyboard) inputView.getKeyboard()).setPreferredLetters(null);
+ // If we just corrected a word, then don't show punctuations
+ if (!correcting) {
+ setNextSuggestions();
+ }
+ updateShiftKeyState(getCurrentInputEditorInfo());
+ }
+
+ /**
+ * Tries to apply any voice alternatives for the word if this was a spoken
+ * word and there are voice alternatives.
+ *
+ * @param touching
+ * The word that the cursor is touching, with position
+ * information
+ * @return true if an alternative was found, false otherwise.
+ */
+ private boolean applyVoiceAlternatives(EditingUtil.SelectedWord touching) {
+ // Search for result in spoken word alternatives
+ String selectedWord = touching.word.toString().trim();
+ if (!mWordToSuggestions.containsKey(selectedWord)) {
+ selectedWord = selectedWord.toLowerCase();
+ }
+ if (mWordToSuggestions.containsKey(selectedWord)) {
+ mShowingVoiceSuggestions = true;
+ List<CharSequence> suggestions = mWordToSuggestions
+ .get(selectedWord);
+ // If the first letter of touching is capitalized, make all the
+ // suggestions
+ // start with a capital letter.
+ if (Character.isUpperCase(touching.word.charAt(0))) {
+ for (int i = 0; i < suggestions.size(); i++) {
+ String origSugg = (String) suggestions.get(i);
+ String capsSugg = origSugg.toUpperCase().charAt(0)
+ + origSugg.subSequence(1, origSugg.length())
+ .toString();
+ suggestions.set(i, capsSugg);
+ }
+ }
+ setSuggestions(suggestions, false, true, true);
+ setCandidatesViewShown(true);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Tries to apply any typed alternatives for the word if we have any cached
+ * alternatives, otherwise tries to find new corrections and completions for
+ * the word.
+ *
+ * @param touching
+ * The word that the cursor is touching, with position
+ * information
+ * @return true if an alternative was found, false otherwise.
+ */
+ private boolean applyTypedAlternatives(EditingUtil.SelectedWord touching) {
+ // If we didn't find a match, search for result in typed word history
+ WordComposer foundWord = null;
+ WordAlternatives alternatives = null;
+ for (WordAlternatives entry : mWordHistory) {
+ if (TextUtils.equals(entry.getChosenWord(), touching.word)) {
+ if (entry instanceof TypedWordAlternatives) {
+ foundWord = ((TypedWordAlternatives) entry).word;
+ }
+ alternatives = entry;
+ break;
+ }
+ }
+ // If we didn't find a match, at least suggest completions
+ if (foundWord == null
+ && (mSuggest.isValidWord(touching.word) || mSuggest
+ .isValidWord(touching.word.toString().toLowerCase()))) {
+ foundWord = new WordComposer();
+ for (int i = 0; i < touching.word.length(); i++) {
+ foundWord.add(touching.word.charAt(i),
+ new int[] { touching.word.charAt(i) });
+ }
+ foundWord.setFirstCharCapitalized(Character
+ .isUpperCase(touching.word.charAt(0)));
+ }
+ // Found a match, show suggestions
+ if (foundWord != null || alternatives != null) {
+ if (alternatives == null) {
+ alternatives = new TypedWordAlternatives(touching.word,
+ foundWord);
+ }
+ showCorrections(alternatives);
+ if (foundWord != null) {
+ mWord = new WordComposer(foundWord);
+ } else {
+ mWord.reset();
+ }
+ return true;
+ }
+ return false;
+ }
+
+ private void setOldSuggestions() {
+ mShowingVoiceSuggestions = false;
+ if (mCandidateView != null
+ && mCandidateView.isShowingAddToDictionaryHint()) {
+ return;
+ }
+ InputConnection ic = getCurrentInputConnection();
+ if (ic == null)
+ return;
+ if (!mPredicting) {
+ // Extract the selected or touching text
+ EditingUtil.SelectedWord touching = EditingUtil
+ .getWordAtCursorOrSelection(ic, mLastSelectionStart,
+ mLastSelectionEnd, mWordSeparators);
+
+ if (touching != null && touching.word.length() > 1) {
+ ic.beginBatchEdit();
+
+ if (!applyVoiceAlternatives(touching)
+ && !applyTypedAlternatives(touching)) {
+ abortCorrection(true);
+ } else {
+ TextEntryState.selectedForCorrection();
+ EditingUtil.underlineWord(ic, touching);
+ }
+
+ ic.endBatchEdit();
+ } else {
+ abortCorrection(true);
+ setNextSuggestions(); // Show the punctuation suggestions list
+ }
+ } else {
+ abortCorrection(true);
+ }
+ }
+
+ private void setNextSuggestions() {
+ setSuggestions(mSuggestPuncList, false, false, false);
+ }
+
+ private void addToDictionaries(CharSequence suggestion, int frequencyDelta) {
+ checkAddToDictionary(suggestion, frequencyDelta, false);
+ }
+
+ private void addToBigramDictionary(CharSequence suggestion,
+ int frequencyDelta) {
+ checkAddToDictionary(suggestion, frequencyDelta, true);
+ }
+
+ /**
+ * Adds to the UserBigramDictionary and/or AutoDictionary
+ *
+ * @param addToBigramDictionary
+ * true if it should be added to bigram dictionary if possible
+ */
+ private void checkAddToDictionary(CharSequence suggestion,
+ int frequencyDelta, boolean addToBigramDictionary) {
+ if (suggestion == null || suggestion.length() < 1)
+ return;
+ // Only auto-add to dictionary if auto-correct is ON. Otherwise we'll be
+ // adding words in situations where the user or application really
+ // didn't
+ // want corrections enabled or learned.
+ if (!(mCorrectionMode == Suggest.CORRECTION_FULL || mCorrectionMode == Suggest.CORRECTION_FULL_BIGRAM)) {
+ return;
+ }
+ if (suggestion != null) {
+ if (!addToBigramDictionary
+ && mAutoDictionary.isValidWord(suggestion)
+ || (!mSuggest.isValidWord(suggestion.toString()) && !mSuggest
+ .isValidWord(suggestion.toString().toLowerCase()))) {
+ mAutoDictionary.addWord(suggestion.toString(), frequencyDelta);
+ }
+
+ if (mUserBigramDictionary != null) {
+ CharSequence prevWord = EditingUtil.getPreviousWord(
+ getCurrentInputConnection(), mSentenceSeparators);
+ if (!TextUtils.isEmpty(prevWord)) {
+ mUserBigramDictionary.addBigrams(prevWord.toString(),
+ suggestion.toString());
+ }
+ }
+ }
+ }
+
+ private boolean isCursorTouchingWord() {
+ InputConnection ic = getCurrentInputConnection();
+ if (ic == null)
+ return false;
+ CharSequence toLeft = ic.getTextBeforeCursor(1, 0);
+ CharSequence toRight = ic.getTextAfterCursor(1, 0);
+ if (!TextUtils.isEmpty(toLeft) && !isWordSeparator(toLeft.charAt(0))
+ && !isSuggestedPunctuation(toLeft.charAt(0))) {
+ return true;
+ }
+ if (!TextUtils.isEmpty(toRight) && !isWordSeparator(toRight.charAt(0))
+ && !isSuggestedPunctuation(toRight.charAt(0))) {
+ return true;
+ }
+ return false;
+ }
+
+ private boolean sameAsTextBeforeCursor(InputConnection ic, CharSequence text) {
+ CharSequence beforeText = ic.getTextBeforeCursor(text.length(), 0);
+ return TextUtils.equals(text, beforeText);
+ }
+
+ public void revertLastWord(boolean deleteChar) {
+ final int length = mComposing.length();
+ if (!mPredicting && length > 0) {
+ final InputConnection ic = getCurrentInputConnection();
+ mPredicting = true;
+ mJustRevertedSeparator = ic.getTextBeforeCursor(1, 0);
+ if (deleteChar)
+ ic.deleteSurroundingText(1, 0);
+ int toDelete = mCommittedLength;
+ CharSequence toTheLeft = ic
+ .getTextBeforeCursor(mCommittedLength, 0);
+ if (toTheLeft != null && toTheLeft.length() > 0
+ && isWordSeparator(toTheLeft.charAt(0))) {
+ toDelete--;
+ }
+ ic.deleteSurroundingText(toDelete, 0);
+ ic.setComposingText(mComposing, 1);
+ TextEntryState.backspace();
+ postUpdateSuggestions();
+ } else {
+ sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL);
+ mJustRevertedSeparator = null;
+ }
+ }
+
+ protected String getWordSeparators() {
+ return mWordSeparators;
+ }
+
+ public boolean isWordSeparator(int code) {
+ String separators = getWordSeparators();
+ return separators.contains(String.valueOf((char) code));
+ }
+
+ private boolean isSentenceSeparator(int code) {
+ return mSentenceSeparators.contains(String.valueOf((char) code));
+ }
+
+ private void sendSpace() {
+ sendModifiableKeyChar((char) ASCII_SPACE);
+ updateShiftKeyState(getCurrentInputEditorInfo());
+ // onKey(KEY_SPACE[0], KEY_SPACE);
+ }
+
+ public boolean preferCapitalization() {
+ return mWord.isFirstCharCapitalized();
+ }
+
+ void toggleLanguage(boolean reset, boolean next) {
+ if (reset) {
+ mLanguageSwitcher.reset();
+ } else {
+ if (next) {
+ mLanguageSwitcher.next();
+ } else {
+ mLanguageSwitcher.prev();
+ }
+ }
+ int currentKeyboardMode = mKeyboardSwitcher.getKeyboardMode();
+ reloadKeyboards();
+ mKeyboardSwitcher.makeKeyboards(true);
+ mKeyboardSwitcher.setKeyboardMode(currentKeyboardMode, 0,
+ mEnableVoiceButton && mEnableVoice);
+ initSuggest(mLanguageSwitcher.getInputLanguage());
+ mLanguageSwitcher.persist();
+ mAutoCapActive = mAutoCapPref && mLanguageSwitcher.allowAutoCap();
+ mDeadKeysActive = mLanguageSwitcher.allowDeadKeys();
+ updateShiftKeyState(getCurrentInputEditorInfo());
+ setCandidatesViewShown(isPredictionOn());
+ }
+
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
+ String key) {
+ Log.i("PCKeyboard", "onSharedPreferenceChanged()");
+ boolean needReload = false;
+ Resources res = getResources();
+
+ // Apply globally handled shared prefs
+ sKeyboardSettings.sharedPreferenceChanged(sharedPreferences, key);
+ if (sKeyboardSettings.hasFlag(GlobalKeyboardSettings.FLAG_PREF_NEED_RELOAD)) {
+ needReload = true;
+ }
+ if (sKeyboardSettings.hasFlag(GlobalKeyboardSettings.FLAG_PREF_NEW_PUNC_LIST)) {
+ initSuggestPuncList();
+ }
+ if (sKeyboardSettings.hasFlag(GlobalKeyboardSettings.FLAG_PREF_RECREATE_INPUT_VIEW)) {
+ mKeyboardSwitcher.recreateInputView();
+ }
+ if (sKeyboardSettings.hasFlag(GlobalKeyboardSettings.FLAG_PREF_RESET_MODE_OVERRIDE)) {
+ mKeyboardModeOverrideLandscape = 0;
+ mKeyboardModeOverridePortrait = 0;
+ }
+ if (sKeyboardSettings.hasFlag(GlobalKeyboardSettings.FLAG_PREF_RESET_KEYBOARDS)) {
+ toggleLanguage(true, true);
+ }
+ int unhandledFlags = sKeyboardSettings.unhandledFlags();
+ if (unhandledFlags != GlobalKeyboardSettings.FLAG_PREF_NONE) {
+ Log.w(TAG, "Not all flag settings handled, remaining=" + unhandledFlags);
+ }
+
+ if (PREF_SELECTED_LANGUAGES.equals(key)) {
+ mLanguageSwitcher.loadLocales(sharedPreferences);
+ mRefreshKeyboardRequired = true;
+ } else if (PREF_RECORRECTION_ENABLED.equals(key)) {
+ mReCorrectionEnabled = sharedPreferences.getBoolean(
+ PREF_RECORRECTION_ENABLED, res
+ .getBoolean(R.bool.default_recorrection_enabled));
+ if (mReCorrectionEnabled) {
+ // It doesn't work right on pre-Gingerbread phones.
+ Toast.makeText(getApplicationContext(),
+ res.getString(R.string.recorrect_warning), Toast.LENGTH_LONG)
+ .show();
+ }
+ } else if (PREF_CONNECTBOT_TAB_HACK.equals(key)) {
+ mConnectbotTabHack = sharedPreferences.getBoolean(
+ PREF_CONNECTBOT_TAB_HACK, res
+ .getBoolean(R.bool.default_connectbot_tab_hack));
+ } else if (PREF_FULLSCREEN_OVERRIDE.equals(key)) {
+ mFullscreenOverride = sharedPreferences.getBoolean(
+ PREF_FULLSCREEN_OVERRIDE, res
+ .getBoolean(R.bool.default_fullscreen_override));
+ needReload = true;
+ } else if (PREF_FORCE_KEYBOARD_ON.equals(key)) {
+ mForceKeyboardOn = sharedPreferences.getBoolean(
+ PREF_FORCE_KEYBOARD_ON, res
+ .getBoolean(R.bool.default_force_keyboard_on));
+ needReload = true;
+ } else if (PREF_KEYBOARD_NOTIFICATION.equals(key)) {
+ mKeyboardNotification = sharedPreferences.getBoolean(
+ PREF_KEYBOARD_NOTIFICATION, res
+ .getBoolean(R.bool.default_keyboard_notification));
+ setNotification(mKeyboardNotification);
+ } else if (PREF_SUGGESTIONS_IN_LANDSCAPE.equals(key)) {
+ mSuggestionsInLandscape = sharedPreferences.getBoolean(
+ PREF_SUGGESTIONS_IN_LANDSCAPE, res
+ .getBoolean(R.bool.default_suggestions_in_landscape));
+ // Respect the suggestion settings in legacy Gingerbread mode,
+ // in portrait mode, or if suggestions in landscape enabled.
+ mSuggestionForceOff = false;
+ mSuggestionForceOn = false;
+ setCandidatesViewShown(isPredictionOn());
+ } else if (PREF_SHOW_SUGGESTIONS.equals(key)) {
+ mShowSuggestions = sharedPreferences.getBoolean(
+ PREF_SHOW_SUGGESTIONS, res.getBoolean(R.bool.default_suggestions));
+ mSuggestionForceOff = false;
+ mSuggestionForceOn = false;
+ needReload = true;
+ } else if (PREF_HEIGHT_PORTRAIT.equals(key)) {
+ mHeightPortrait = getHeight(sharedPreferences,
+ PREF_HEIGHT_PORTRAIT, res.getString(R.string.default_height_portrait));
+ needReload = true;
+ } else if (PREF_HEIGHT_LANDSCAPE.equals(key)) {
+ mHeightLandscape = getHeight(sharedPreferences,
+ PREF_HEIGHT_LANDSCAPE, res.getString(R.string.default_height_landscape));
+ needReload = true;
+ } else if (PREF_HINT_MODE.equals(key)) {
+ LatinIME.sKeyboardSettings.hintMode = Integer.parseInt(sharedPreferences.getString(PREF_HINT_MODE,
+ res.getString(R.string.default_hint_mode)));
+ needReload = true;
+ } else if (PREF_LONGPRESS_TIMEOUT.equals(key)) {
+ LatinIME.sKeyboardSettings.longpressTimeout = getPrefInt(sharedPreferences, PREF_LONGPRESS_TIMEOUT,
+ res.getString(R.string.default_long_press_duration));
+ } else if (PREF_RENDER_MODE.equals(key)) {
+ LatinIME.sKeyboardSettings.renderMode = getPrefInt(sharedPreferences, PREF_RENDER_MODE,
+ res.getString(R.string.default_render_mode));
+ needReload = true;
+ } else if (PREF_SWIPE_UP.equals(key)) {
+ mSwipeUpAction = sharedPreferences.getString(PREF_SWIPE_UP, res.getString(R.string.default_swipe_up));
+ } else if (PREF_SWIPE_DOWN.equals(key)) {
+ mSwipeDownAction = sharedPreferences.getString(PREF_SWIPE_DOWN, res.getString(R.string.default_swipe_down));
+ } else if (PREF_SWIPE_LEFT.equals(key)) {
+ mSwipeLeftAction = sharedPreferences.getString(PREF_SWIPE_LEFT, res.getString(R.string.default_swipe_left));
+ } else if (PREF_SWIPE_RIGHT.equals(key)) {
+ mSwipeRightAction = sharedPreferences.getString(PREF_SWIPE_RIGHT, res.getString(R.string.default_swipe_right));
+ } else if (PREF_VOL_UP.equals(key)) {
+ mVolUpAction = sharedPreferences.getString(PREF_VOL_UP, res.getString(R.string.default_vol_up));
+ } else if (PREF_VOL_DOWN.equals(key)) {
+ mVolDownAction = sharedPreferences.getString(PREF_VOL_DOWN, res.getString(R.string.default_vol_down));
+ } else if (PREF_VIBRATE_LEN.equals(key)) {
+ mVibrateLen = getPrefInt(sharedPreferences, PREF_VIBRATE_LEN, getResources().getString(R.string.vibrate_duration_ms));
+ vibrate(); // test setting
+ }
+
+ updateKeyboardOptions();
+ if (needReload) {
+ mKeyboardSwitcher.makeKeyboards(true);
+ }
+ }
+
+ private boolean doSwipeAction(String action) {
+ //Log.i(TAG, "doSwipeAction + " + action);
+ if (action == null || action.equals("") || action.equals("none")) {
+ return false;
+ } else if (action.equals("close")) {
+ handleClose();
+ } else if (action.equals("settings")) {
+ launchSettings();
+ } else if (action.equals("suggestions")) {
+ if (mSuggestionForceOn) {
+ mSuggestionForceOn = false;
+ mSuggestionForceOff = true;
+ } else if (mSuggestionForceOff) {
+ mSuggestionForceOn = true;
+ mSuggestionForceOff = false;
+ } else if (isPredictionWanted()) {
+ mSuggestionForceOff = true;
+ } else {
+ mSuggestionForceOn = true;
+ }
+ setCandidatesViewShown(isPredictionOn());
+ } else if (action.equals("lang_prev")) {
+ toggleLanguage(false, false);
+ } else if (action.equals("lang_next")) {
+ toggleLanguage(false, true);
+ } else if (action.equals("debug_auto_play")) {
+ if (LatinKeyboardView.DEBUG_AUTO_PLAY) {
+ ClipboardManager cm = ((ClipboardManager) getSystemService(CLIPBOARD_SERVICE));
+ CharSequence text = cm.getText();
+ if (!TextUtils.isEmpty(text)) {
+ mKeyboardSwitcher.getInputView().startPlaying(text.toString());
+ }
+ }
+ } else if (action.equals("voice_input")) {
+ if (VOICE_INSTALLED) {
+ startListening(false /* was a button press, was not a swipe */);
+ } else {
+ Toast.makeText(getApplicationContext(),
+ getResources().getString(R.string.voice_not_enabled_warning), Toast.LENGTH_LONG)
+ .show();
+ }
+ } else if (action.equals("full_mode")) {
+ if (isPortrait()) {
+ mKeyboardModeOverridePortrait = (mKeyboardModeOverridePortrait + 1) % mNumKeyboardModes;
+ } else {
+ mKeyboardModeOverrideLandscape = (mKeyboardModeOverrideLandscape + 1) % mNumKeyboardModes;
+ }
+ toggleLanguage(true, true);
+ } else if (action.equals("extension")) {
+ sKeyboardSettings.useExtension = !sKeyboardSettings.useExtension;
+ reloadKeyboards();
+ } else if (action.equals("height_up")) {
+ if (isPortrait()) {
+ mHeightPortrait += 5;
+ if (mHeightPortrait > 70) mHeightPortrait = 70;
+ } else {
+ mHeightLandscape += 5;
+ if (mHeightLandscape > 70) mHeightLandscape = 70;
+ }
+ toggleLanguage(true, true);
+ } else if (action.equals("height_down")) {
+ if (isPortrait()) {
+ mHeightPortrait -= 5;
+ if (mHeightPortrait < 15) mHeightPortrait = 15;
+ } else {
+ mHeightLandscape -= 5;
+ if (mHeightLandscape < 15) mHeightLandscape = 15;
+ }
+ toggleLanguage(true, true);
+ } else {
+ Log.i(TAG, "Unsupported swipe action config: " + action);
+ }
+ return true;
+ }
+
+ public boolean swipeRight() {
+ return doSwipeAction(mSwipeRightAction);
+ }
+
+ public boolean swipeLeft() {
+ return doSwipeAction(mSwipeLeftAction);
+ }
+
+ public boolean swipeDown() {
+ return doSwipeAction(mSwipeDownAction);
+ }
+
+ public boolean swipeUp() {
+ return doSwipeAction(mSwipeUpAction);
+ }
+
+ public void onPress(int primaryCode) {
+ InputConnection ic = getCurrentInputConnection();
+ if (mKeyboardSwitcher.isVibrateAndSoundFeedbackRequired()) {
+ vibrate();
+ playKeyClick(primaryCode);
+ }
+ final boolean distinctMultiTouch = mKeyboardSwitcher
+ .hasDistinctMultitouch();
+ if (distinctMultiTouch && primaryCode == Keyboard.KEYCODE_SHIFT) {
+ mShiftKeyState.onPress();
+ startMultitouchShift();
+ } else if (distinctMultiTouch
+ && primaryCode == Keyboard.KEYCODE_MODE_CHANGE) {
+ changeKeyboardMode();
+ mSymbolKeyState.onPress();
+ mKeyboardSwitcher.setAutoModeSwitchStateMomentary();
+ } else if (distinctMultiTouch
+ && primaryCode == LatinKeyboardView.KEYCODE_CTRL_LEFT) {
+ setModCtrl(!mModCtrl);
+ mCtrlKeyState.onPress();
+ sendCtrlKey(ic, true, true);
+ } else if (distinctMultiTouch
+ && primaryCode == LatinKeyboardView.KEYCODE_ALT_LEFT) {
+ setModAlt(!mModAlt);
+ mAltKeyState.onPress();
+ sendAltKey(ic, true, true);
+ } else if (distinctMultiTouch
+ && primaryCode == LatinKeyboardView.KEYCODE_FN) {
+ setModFn(!mModFn);
+ mFnKeyState.onPress();
+ } else {
+ mShiftKeyState.onOtherKeyPressed();
+ mSymbolKeyState.onOtherKeyPressed();
+ mCtrlKeyState.onOtherKeyPressed();
+ mAltKeyState.onOtherKeyPressed();
+ mFnKeyState.onOtherKeyPressed();
+ }
+ }
+
+ public void onRelease(int primaryCode) {
+ // Reset any drag flags in the keyboard
+ ((LatinKeyboard) mKeyboardSwitcher.getInputView().getKeyboard())
+ .keyReleased();
+ // vibrate();
+ final boolean distinctMultiTouch = mKeyboardSwitcher
+ .hasDistinctMultitouch();
+ InputConnection ic = getCurrentInputConnection();
+ if (distinctMultiTouch && primaryCode == Keyboard.KEYCODE_SHIFT) {
+ if (mShiftKeyState.isMomentary()) {
+ resetMultitouchShift();
+ } else {
+ commitMultitouchShift();
+ }
+ mShiftKeyState.onRelease();
+ } else if (distinctMultiTouch
+ && primaryCode == Keyboard.KEYCODE_MODE_CHANGE) {
+ // Snap back to the previous keyboard mode if the user chords the
+ // mode change key and
+ // other key, then released the mode change key.
+ if (mKeyboardSwitcher.isInChordingAutoModeSwitchState())
+ changeKeyboardMode();
+ mSymbolKeyState.onRelease();
+ } else if (distinctMultiTouch
+ && primaryCode == LatinKeyboardView.KEYCODE_CTRL_LEFT) {
+ if (mCtrlKeyState.isMomentary()) {
+ setModCtrl(false);
+ }
+ sendCtrlKey(ic, false, true);
+ mCtrlKeyState.onRelease();
+ } else if (distinctMultiTouch
+ && primaryCode == LatinKeyboardView.KEYCODE_ALT_LEFT) {
+ if (mAltKeyState.isMomentary()) {
+ setModAlt(false);
+ }
+ sendAltKey(ic, false, true);
+ mAltKeyState.onRelease();
+ } else if (distinctMultiTouch
+ && primaryCode == LatinKeyboardView.KEYCODE_FN) {
+ if (mFnKeyState.isMomentary()) {
+ setModFn(false);
+ }
+ mFnKeyState.onRelease();
+ }
+ }
+
+ private FieldContext makeFieldContext() {
+ return new FieldContext(getCurrentInputConnection(),
+ getCurrentInputEditorInfo(), mLanguageSwitcher
+ .getInputLanguage(), mLanguageSwitcher
+ .getEnabledLanguages());
+ }
+
+ private boolean fieldCanDoVoice(FieldContext fieldContext) {
+ return !mPasswordText && mVoiceInput != null
+ && !mVoiceInput.isBlacklistedField(fieldContext);
+ }
+
+ private boolean shouldShowVoiceButton(FieldContext fieldContext,
+ EditorInfo attribute) {
+ return ENABLE_VOICE_BUTTON
+ && fieldCanDoVoice(fieldContext)
+ && !(attribute != null && IME_OPTION_NO_MICROPHONE
+ .equals(attribute.privateImeOptions))
+ && SpeechRecognizer.isRecognitionAvailable(this);
+ }
+
+ // receive ringer mode changes to detect silent mode
+ private BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ updateRingerMode();
+ }
+ };
+
+ // update flags for silent mode
+ private void updateRingerMode() {
+ if (mAudioManager == null) {
+ mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+ }
+ if (mAudioManager != null) {
+ mSilentMode = (mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL);
+ }
+ }
+
+ private float getKeyClickVolume() {
+ if (mAudioManager == null) return 0.0f; // shouldn't happen
+
+ // The volume calculations are poorly documented, this is the closest I could
+ // find for explaining volume conversions:
+ // http://developer.android.com/reference/android/media/MediaPlayer.html#setAuxEffectSendLevel(float)
+ //
+ // Note that the passed level value is a raw scalar. UI controls should be scaled logarithmically:
+ // the gain applied by audio framework ranges from -72dB to 0dB, so an appropriate conversion
+ // from linear UI input x to level is: x == 0 -> level = 0 0 < x <= R -> level = 10^(72*(x-R)/20/R)
+
+ int method = sKeyboardSettings.keyClickMethod; // See click_method_values in strings.xml
+ if (method == 0) return FX_VOLUME;
+
+ float targetVol = sKeyboardSettings.keyClickVolume;
+
+ if (method > 1) {
+ // TODO(klausw): on some devices the media volume controls the click volume?
+ // If that's the case, try to set a relative target volume.
+ int mediaMax = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
+ int mediaVol = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
+ //Log.i(TAG, "getKeyClickVolume relative, media vol=" + mediaVol + "/" + mediaMax);
+ float channelVol = (float) mediaVol / mediaMax;
+ if (method == 2) {
+ targetVol *= channelVol;
+ } else if (method == 3) {
+ if (channelVol == 0) return 0.0f; // Channel is silent, won't get audio
+ targetVol = Math.min(targetVol / channelVol, 1.0f); // Cap at 1.0
+ }
+ }
+ // Set absolute volume, treating the percentage as a logarithmic control
+ float vol = (float) Math.pow(10.0, FX_VOLUME_RANGE_DB * (targetVol - 1) / 20);
+ //Log.i(TAG, "getKeyClickVolume absolute, target=" + targetVol + " amp=" + vol);
+ return vol;
+ }
+
+ private void playKeyClick(int primaryCode) {
+ // if mAudioManager is null, we don't have the ringer state yet
+ // mAudioManager will be set by updateRingerMode
+ if (mAudioManager == null) {
+ if (mKeyboardSwitcher.getInputView() != null) {
+ updateRingerMode();
+ }
+ }
+ if (mSoundOn && !mSilentMode) {
+ // FIXME: Volume and enable should come from UI settings
+ // FIXME: These should be triggered after auto-repeat logic
+ int sound = AudioManager.FX_KEYPRESS_STANDARD;
+ switch (primaryCode) {
+ case Keyboard.KEYCODE_DELETE:
+ sound = AudioManager.FX_KEYPRESS_DELETE;
+ break;
+ case ASCII_ENTER:
+ sound = AudioManager.FX_KEYPRESS_RETURN;
+ break;
+ case ASCII_SPACE:
+ sound = AudioManager.FX_KEYPRESS_SPACEBAR;
+ break;
+ }
+ mAudioManager.playSoundEffect(sound, getKeyClickVolume());
+ }
+ }
+
+ private void vibrate() {
+ if (!mVibrateOn) {
+ return;
+ }
+ Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
+ if (v != null) {
+ v.vibrate(mVibrateLen);
+ return;
+ }
+
+ if (mKeyboardSwitcher.getInputView() != null) {
+ mKeyboardSwitcher.getInputView().performHapticFeedback(
+ HapticFeedbackConstants.KEYBOARD_TAP,
+ HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
+ }
+ }
+
+ private void checkTutorial(String privateImeOptions) {
+ if (privateImeOptions == null)
+ return;
+ if (privateImeOptions.equals("com.android.setupwizard:ShowTutorial")) {
+ if (mTutorial == null)
+ startTutorial();
+ } else if (privateImeOptions
+ .equals("com.android.setupwizard:HideTutorial")) {
+ if (mTutorial != null) {
+ if (mTutorial.close()) {
+ mTutorial = null;
+ }
+ }
+ }
+ }
+
+ private void startTutorial() {
+ mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_START_TUTORIAL),
+ 500);
+ }
+
+ /* package */void tutorialDone() {
+ mTutorial = null;
+ }
+
+ /* package */void promoteToUserDictionary(String word, int frequency) {
+ if (mUserDictionary.isValidWord(word))
+ return;
+ mUserDictionary.addWord(word, frequency);
+ }
+
+ /* package */WordComposer getCurrentWord() {
+ return mWord;
+ }
+
+ /* package */boolean getPopupOn() {
+ return mPopupOn;
+ }
+
+ private void updateCorrectionMode() {
+ mHasDictionary = mSuggest != null ? mSuggest.hasMainDictionary()
+ : false;
+ mAutoCorrectOn = (mAutoCorrectEnabled || mQuickFixes)
+ && !mInputTypeNoAutoCorrect && mHasDictionary;
+ mCorrectionMode = (mAutoCorrectOn && mAutoCorrectEnabled) ? Suggest.CORRECTION_FULL
+ : (mAutoCorrectOn ? Suggest.CORRECTION_BASIC
+ : Suggest.CORRECTION_NONE);
+ mCorrectionMode = (mBigramSuggestionEnabled && mAutoCorrectOn && mAutoCorrectEnabled) ? Suggest.CORRECTION_FULL_BIGRAM
+ : mCorrectionMode;
+ if (suggestionsDisabled()) {
+ mAutoCorrectOn = false;
+ mCorrectionMode = Suggest.CORRECTION_NONE;
+ }
+ if (mSuggest != null) {
+ mSuggest.setCorrectionMode(mCorrectionMode);
+ }
+ }
+
+ private void updateAutoTextEnabled(Locale systemLocale) {
+ if (mSuggest == null)
+ return;
+ boolean different = !systemLocale.getLanguage().equalsIgnoreCase(
+ mInputLocale.substring(0, 2));
+ mSuggest.setAutoTextEnabled(!different && mQuickFixes);
+ }
+
+ protected void launchSettings() {
+ launchSettings(LatinIMESettings.class);
+ }
+
+ public void launchDebugSettings() {
+ launchSettings(LatinIMEDebugSettings.class);
+ }
+
+ protected void launchSettings(
+ Class<? extends PreferenceActivity> settingsClass) {
+ handleClose();
+ Intent intent = new Intent();
+ intent.setClass(LatinIME.this, settingsClass);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ startActivity(intent);
+ }
+
+ private void loadSettings() {
+ // Get the settings preferences
+ SharedPreferences sp = PreferenceManager
+ .getDefaultSharedPreferences(this);
+ mVibrateOn = sp.getBoolean(PREF_VIBRATE_ON, false);
+ mVibrateLen = getPrefInt(sp, PREF_VIBRATE_LEN, getResources().getString(R.string.vibrate_duration_ms));
+ mSoundOn = sp.getBoolean(PREF_SOUND_ON, false);
+ mPopupOn = sp.getBoolean(PREF_POPUP_ON, mResources
+ .getBoolean(R.bool.default_popup_preview));
+ mAutoCapPref = sp.getBoolean(PREF_AUTO_CAP, getResources().getBoolean(
+ R.bool.default_auto_cap));
+ mQuickFixes = sp.getBoolean(PREF_QUICK_FIXES, true);
+ mHasUsedVoiceInput = sp.getBoolean(PREF_HAS_USED_VOICE_INPUT, false);
+ mHasUsedVoiceInputUnsupportedLocale = sp.getBoolean(
+ PREF_HAS_USED_VOICE_INPUT_UNSUPPORTED_LOCALE, false);
+
+ // Get the current list of supported locales and check the current
+ // locale against that
+ // list. We cache this value so as not to check it every time the user
+ // starts a voice
+ // input. Because this method is called by onStartInputView, this should
+ // mean that as
+ // long as the locale doesn't change while the user is keeping the IME
+ // open, the
+ // value should never be stale.
+ String supportedLocalesString = SettingsUtil.getSettingsString(
+ getContentResolver(),
+ SettingsUtil.LATIN_IME_VOICE_INPUT_SUPPORTED_LOCALES,
+ DEFAULT_VOICE_INPUT_SUPPORTED_LOCALES);
+ ArrayList<String> voiceInputSupportedLocales = newArrayList(supportedLocalesString
+ .split("\\s+"));
+
+ mLocaleSupportedForVoiceInput =
+ voiceInputSupportedLocales.contains(mInputLocale) ||
+ voiceInputSupportedLocales.contains(mInputLocale.substring(0, Math.min(2, mInputLocale.length())));
+
+ mShowSuggestions = sp.getBoolean(PREF_SHOW_SUGGESTIONS, mResources
+ .getBoolean(R.bool.default_suggestions));
+
+ if (VOICE_INSTALLED) {
+ final String voiceMode = sp.getString(PREF_VOICE_MODE,
+ getString(R.string.voice_mode_main));
+ boolean enableVoice = !voiceMode
+ .equals(getString(R.string.voice_mode_off))
+ && mEnableVoiceButton;
+ boolean voiceOnPrimary = voiceMode
+ .equals(getString(R.string.voice_mode_main));
+ if (mKeyboardSwitcher != null
+ && (enableVoice != mEnableVoice || voiceOnPrimary != mVoiceOnPrimary)) {
+ mKeyboardSwitcher.setVoiceMode(enableVoice, voiceOnPrimary);
+ }
+ mEnableVoice = enableVoice;
+ mVoiceOnPrimary = voiceOnPrimary;
+ }
+ mAutoCorrectEnabled = sp.getBoolean(PREF_AUTO_COMPLETE, mResources
+ .getBoolean(R.bool.enable_autocorrect))
+ & mShowSuggestions;
+ // mBigramSuggestionEnabled = sp.getBoolean(
+ // PREF_BIGRAM_SUGGESTIONS, true) & mShowSuggestions;
+ updateCorrectionMode();
+ updateAutoTextEnabled(mResources.getConfiguration().locale);
+ mLanguageSwitcher.loadLocales(sp);
+ mAutoCapActive = mAutoCapPref && mLanguageSwitcher.allowAutoCap();
+ mDeadKeysActive = mLanguageSwitcher.allowDeadKeys();
+ }
+
+ private void initSuggestPuncList() {
+ mSuggestPuncList = new ArrayList<CharSequence>();
+ String suggestPuncs = sKeyboardSettings.suggestedPunctuation;
+ String defaultPuncs = getResources().getString(R.string.suggested_punctuations_default);
+ if (suggestPuncs.equals(defaultPuncs) || suggestPuncs.equals("")) {
+ // Not user-configured, load the language-specific default.
+ suggestPuncs = getResources().getString(R.string.suggested_punctuations);
+ }
+ if (suggestPuncs != null) {
+ for (int i = 0; i < suggestPuncs.length(); i++) {
+ mSuggestPuncList.add(suggestPuncs.subSequence(i, i + 1));
+ }
+ }
+ setNextSuggestions();
+ }
+
+ private boolean isSuggestedPunctuation(int code) {
+ return sKeyboardSettings.suggestedPunctuation.contains(String.valueOf((char) code));
+ }
+
+ private void showOptionsMenu() {
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setCancelable(true);
+ builder.setIcon(R.drawable.ic_dialog_keyboard);
+ builder.setNegativeButton(android.R.string.cancel, null);
+ CharSequence itemSettings = getString(R.string.english_ime_settings);
+ CharSequence itemInputMethod = getString(R.string.selectInputMethod);
+ builder.setItems(new CharSequence[] { itemInputMethod, itemSettings },
+ new DialogInterface.OnClickListener() {
+
+ public void onClick(DialogInterface di, int position) {
+ di.dismiss();
+ switch (position) {
+ case POS_SETTINGS:
+ launchSettings();
+ break;
+ case POS_METHOD:
+ ((InputMethodManager) getSystemService(INPUT_METHOD_SERVICE))
+ .showInputMethodPicker();
+ break;
+ }
+ }
+ });
+ builder.setTitle(mResources
+ .getString(R.string.english_ime_input_options));
+ mOptionsDialog = builder.create();
+ Window window = mOptionsDialog.getWindow();
+ WindowManager.LayoutParams lp = window.getAttributes();
+ lp.token = mKeyboardSwitcher.getInputView().getWindowToken();
+ lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
+ window.setAttributes(lp);
+ window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
+ mOptionsDialog.show();
+ }
+
+ public void changeKeyboardMode() {
+ KeyboardSwitcher switcher = mKeyboardSwitcher;
+ if (switcher.isAlphabetMode()) {
+ mSavedShiftState = getShiftState();
+ }
+ switcher.toggleSymbols();
+ if (switcher.isAlphabetMode()) {
+ switcher.setShiftState(mSavedShiftState);
+ }
+
+ updateShiftKeyState(getCurrentInputEditorInfo());
+ }
+
+ public static <E> ArrayList<E> newArrayList(E... elements) {
+ int capacity = (elements.length * 110) / 100 + 5;
+ ArrayList<E> list = new ArrayList<E>(capacity);
+ Collections.addAll(list, elements);
+ return list;
+ }
+
+ @Override
+ protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
+ super.dump(fd, fout, args);
+
+ final Printer p = new PrintWriterPrinter(fout);
+ p.println("LatinIME state :");
+ p.println(" Keyboard mode = " + mKeyboardSwitcher.getKeyboardMode());
+ p.println(" mComposing=" + mComposing.toString());
+ p.println(" mPredictionOnForMode=" + mPredictionOnForMode);
+ p.println(" mCorrectionMode=" + mCorrectionMode);
+ p.println(" mPredicting=" + mPredicting);
+ p.println(" mAutoCorrectOn=" + mAutoCorrectOn);
+ p.println(" mAutoSpace=" + mAutoSpace);
+ p.println(" mCompletionOn=" + mCompletionOn);
+ p.println(" TextEntryState.state=" + TextEntryState.getState());
+ p.println(" mSoundOn=" + mSoundOn);
+ p.println(" mVibrateOn=" + mVibrateOn);
+ p.println(" mPopupOn=" + mPopupOn);
+ }
+
+ // Characters per second measurement
+
+ private long mLastCpsTime;
+ private static final int CPS_BUFFER_SIZE = 16;
+ private long[] mCpsIntervals = new long[CPS_BUFFER_SIZE];
+ private int mCpsIndex;
+ private static Pattern NUMBER_RE = Pattern.compile("(\\d+).*");
+
+ private void measureCps() {
+ long now = System.currentTimeMillis();
+ if (mLastCpsTime == 0)
+ mLastCpsTime = now - 100; // Initial
+ mCpsIntervals[mCpsIndex] = now - mLastCpsTime;
+ mLastCpsTime = now;
+ mCpsIndex = (mCpsIndex + 1) % CPS_BUFFER_SIZE;
+ long total = 0;
+ for (int i = 0; i < CPS_BUFFER_SIZE; i++)
+ total += mCpsIntervals[i];
+ System.out.println("CPS = " + ((CPS_BUFFER_SIZE * 1000f) / total));
+ }
+
+ public void onAutoCompletionStateChanged(boolean isAutoCompletion) {
+ mKeyboardSwitcher.onAutoCompletionStateChanged(isAutoCompletion);
+ }
+
+ static int getIntFromString(String val, int defVal) {
+ Matcher num = NUMBER_RE.matcher(val);
+ if (!num.matches()) return defVal;
+ return Integer.parseInt(num.group(1));
+ }
+
+ static int getPrefInt(SharedPreferences prefs, String prefName, int defVal) {
+ String prefVal = prefs.getString(prefName, Integer.toString(defVal));
+ //Log.i("PCKeyboard", "getPrefInt " + prefName + " = " + prefVal + ", default " + defVal);
+ return getIntFromString(prefVal, defVal);
+ }
+
+ static int getPrefInt(SharedPreferences prefs, String prefName, String defStr) {
+ int defVal = getIntFromString(defStr, 0);
+ return getPrefInt(prefs, prefName, defVal);
+ }
+
+ static int getHeight(SharedPreferences prefs, String prefName, String defVal) {
+ int val = getPrefInt(prefs, prefName, defVal);
+ if (val < 15)
+ val = 15;
+ if (val > 75)
+ val = 75;
+ return val;
+ }
+}
diff --git a/java/src/org/pocketworkstation/pckeyboard/LatinIMEBackupAgent.java b/java/src/org/pocketworkstation/pckeyboard/LatinIMEBackupAgent.java
new file mode 100644
index 0000000..0e283ad
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/LatinIMEBackupAgent.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.pocketworkstation.pckeyboard;
+
+import android.app.backup.BackupAgentHelper;
+import android.app.backup.SharedPreferencesBackupHelper;
+
+/**
+ * Backs up the Latin IME shared preferences.
+ */
+public class LatinIMEBackupAgent extends BackupAgentHelper {
+
+ @Override
+ public void onCreate() {
+ addHelper("shared_pref", new SharedPreferencesBackupHelper(this,
+ getPackageName() + "_preferences"));
+ }
+}
diff --git a/java/src/org/pocketworkstation/pckeyboard/LatinIMEDebugSettings.java b/java/src/org/pocketworkstation/pckeyboard/LatinIMEDebugSettings.java
new file mode 100644
index 0000000..d7a2797
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/LatinIMEDebugSettings.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.pocketworkstation.pckeyboard;
+
+import android.content.SharedPreferences;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.Bundle;
+import android.preference.CheckBoxPreference;
+import android.preference.PreferenceActivity;
+import android.util.Log;
+
+public class LatinIMEDebugSettings extends PreferenceActivity
+ implements SharedPreferences.OnSharedPreferenceChangeListener {
+
+ private static final String TAG = "LatinIMEDebugSettings";
+ private static final String DEBUG_MODE_KEY = "debug_mode";
+
+ private CheckBoxPreference mDebugMode;
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ addPreferencesFromResource(R.xml.prefs_for_debug);
+ SharedPreferences prefs = getPreferenceManager().getSharedPreferences();
+ prefs.registerOnSharedPreferenceChangeListener(this);
+
+ mDebugMode = (CheckBoxPreference) findPreference(DEBUG_MODE_KEY);
+ updateDebugMode();
+ }
+
+ public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
+ if (key.equals(DEBUG_MODE_KEY)) {
+ if (mDebugMode != null) {
+ mDebugMode.setChecked(prefs.getBoolean(DEBUG_MODE_KEY, false));
+ updateDebugMode();
+ }
+ }
+ }
+
+ private void updateDebugMode() {
+ if (mDebugMode == null) {
+ return;
+ }
+ boolean isDebugMode = mDebugMode.isChecked();
+ String version = "";
+ try {
+ PackageInfo info = getPackageManager().getPackageInfo(getPackageName(), 0);
+ version = "Version " + info.versionName;
+ } catch (NameNotFoundException e) {
+ Log.e(TAG, "Could not find version info.");
+ }
+ if (!isDebugMode) {
+ mDebugMode.setTitle(version);
+ mDebugMode.setSummary("");
+ } else {
+ mDebugMode.setTitle(getResources().getString(R.string.prefs_debug_mode));
+ mDebugMode.setSummary(version);
+ }
+ }
+}
diff --git a/java/src/org/pocketworkstation/pckeyboard/LatinIMESettings.java b/java/src/org/pocketworkstation/pckeyboard/LatinIMESettings.java
new file mode 100644
index 0000000..93de6dd
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/LatinIMESettings.java
@@ -0,0 +1,323 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.pocketworkstation.pckeyboard;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.backup.BackupManager;
+import android.content.DialogInterface;
+import android.content.SharedPreferences;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.preference.CheckBoxPreference;
+import android.preference.ListPreference;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceGroup;
+import android.speech.SpeechRecognizer;
+import android.text.AutoText;
+import android.text.InputType;
+import android.util.Log;
+
+import com.android.inputmethod.voice.SettingsUtil;
+import com.android.inputmethod.voice.VoiceInputLogger;
+
+public class LatinIMESettings extends PreferenceActivity
+ implements SharedPreferences.OnSharedPreferenceChangeListener,
+ DialogInterface.OnDismissListener {
+
+ private static final String QUICK_FIXES_KEY = "quick_fixes";
+ private static final String PREDICTION_SETTINGS_KEY = "prediction_settings";
+ private static final String VOICE_SETTINGS_KEY = "voice_mode";
+ /* package */ static final String PREF_SETTINGS_KEY = "settings_key";
+ static final String INPUT_CONNECTION_INFO = "input_connection_info";
+
+ private static final String TAG = "LatinIMESettings";
+
+ // Dialog ids
+ private static final int VOICE_INPUT_CONFIRM_DIALOG = 0;
+
+ private CheckBoxPreference mQuickFixes;
+ private ListPreference mVoicePreference;
+ private ListPreference mSettingsKeyPreference;
+ private ListPreference mKeyboardModePortraitPreference;
+ private ListPreference mKeyboardModeLandscapePreference;
+ private Preference mInputConnectionInfo;
+ private boolean mVoiceOn;
+
+ private VoiceInputLogger mLogger;
+
+ private boolean mOkClicked = false;
+ private String mVoiceModeOff;
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ addPreferencesFromResource(R.xml.prefs);
+ mQuickFixes = (CheckBoxPreference) findPreference(QUICK_FIXES_KEY);
+ mVoicePreference = (ListPreference) findPreference(VOICE_SETTINGS_KEY);
+ mSettingsKeyPreference = (ListPreference) findPreference(PREF_SETTINGS_KEY);
+ mInputConnectionInfo = (Preference) findPreference(INPUT_CONNECTION_INFO);
+
+ // TODO(klausw): remove these when no longer needed
+ mKeyboardModePortraitPreference = (ListPreference) findPreference("pref_keyboard_mode_portrait");
+ mKeyboardModeLandscapePreference = (ListPreference) findPreference("pref_keyboard_mode_landscape");
+
+ SharedPreferences prefs = getPreferenceManager().getSharedPreferences();
+ prefs.registerOnSharedPreferenceChangeListener(this);
+
+ mVoiceModeOff = getString(R.string.voice_mode_off);
+ mVoiceOn = !(prefs.getString(VOICE_SETTINGS_KEY, mVoiceModeOff).equals(mVoiceModeOff));
+ mLogger = VoiceInputLogger.getLogger(this);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ int autoTextSize = AutoText.getSize(getListView());
+ if (autoTextSize < 1) {
+ ((PreferenceGroup) findPreference(PREDICTION_SETTINGS_KEY))
+ .removePreference(mQuickFixes);
+ }
+ if (!LatinIME.VOICE_INSTALLED
+ || !SpeechRecognizer.isRecognitionAvailable(this)) {
+ getPreferenceScreen().removePreference(mVoicePreference);
+ } else {
+ updateVoiceModeSummary();
+ }
+
+ Log.i(TAG, "compactModeEnabled=" + LatinIME.sKeyboardSettings.compactModeEnabled);
+ if (!LatinIME.sKeyboardSettings.compactModeEnabled) {
+ CharSequence[] oldEntries = mKeyboardModePortraitPreference.getEntries();
+ CharSequence[] oldValues = mKeyboardModePortraitPreference.getEntryValues();
+
+ if (oldEntries.length > 2) {
+ CharSequence[] newEntries = new CharSequence[] { oldEntries[0], oldEntries[2] };
+ CharSequence[] newValues = new CharSequence[] { oldValues[0], oldValues[2] };
+ mKeyboardModePortraitPreference.setEntries(newEntries);
+ mKeyboardModePortraitPreference.setEntryValues(newValues);
+ mKeyboardModeLandscapePreference.setEntries(newEntries);
+ mKeyboardModeLandscapePreference.setEntryValues(newValues);
+ }
+ }
+
+ updateSummaries();
+ }
+
+ @Override
+ protected void onDestroy() {
+ getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(
+ this);
+ super.onDestroy();
+ }
+
+ public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
+ (new BackupManager(this)).dataChanged();
+ // If turning on voice input, show dialog
+ if (key.equals(VOICE_SETTINGS_KEY) && !mVoiceOn) {
+ if (!prefs.getString(VOICE_SETTINGS_KEY, mVoiceModeOff)
+ .equals(mVoiceModeOff)) {
+ showVoiceConfirmation();
+ }
+ }
+ mVoiceOn = !(prefs.getString(VOICE_SETTINGS_KEY, mVoiceModeOff).equals(mVoiceModeOff));
+ updateVoiceModeSummary();
+ updateSummaries();
+ }
+
+ static Map<Integer, String> INPUT_CLASSES = new HashMap<Integer, String>();
+ static Map<Integer, String> DATETIME_VARIATIONS = new HashMap<Integer, String>();
+ static Map<Integer, String> TEXT_VARIATIONS = new HashMap<Integer, String>();
+ static Map<Integer, String> NUMBER_VARIATIONS = new HashMap<Integer, String>();
+ static {
+ INPUT_CLASSES.put(0x00000004, "DATETIME");
+ INPUT_CLASSES.put(0x00000002, "NUMBER");
+ INPUT_CLASSES.put(0x00000003, "PHONE");
+ INPUT_CLASSES.put(0x00000001, "TEXT");
+ INPUT_CLASSES.put(0x00000000, "NULL");
+
+ DATETIME_VARIATIONS.put(0x00000010, "DATE");
+ DATETIME_VARIATIONS.put(0x00000020, "TIME");
+
+ NUMBER_VARIATIONS.put(0x00000010, "PASSWORD");
+
+ TEXT_VARIATIONS.put(0x00000020, "EMAIL_ADDRESS");
+ TEXT_VARIATIONS.put(0x00000030, "EMAIL_SUBJECT");
+ TEXT_VARIATIONS.put(0x000000b0, "FILTER");
+ TEXT_VARIATIONS.put(0x00000050, "LONG_MESSAGE");
+ TEXT_VARIATIONS.put(0x00000080, "PASSWORD");
+ TEXT_VARIATIONS.put(0x00000060, "PERSON_NAME");
+ TEXT_VARIATIONS.put(0x000000c0, "PHONETIC");
+ TEXT_VARIATIONS.put(0x00000070, "POSTAL_ADDRESS");
+ TEXT_VARIATIONS.put(0x00000040, "SHORT_MESSAGE");
+ TEXT_VARIATIONS.put(0x00000010, "URI");
+ TEXT_VARIATIONS.put(0x00000090, "VISIBLE_PASSWORD");
+ TEXT_VARIATIONS.put(0x000000a0, "WEB_EDIT_TEXT");
+ TEXT_VARIATIONS.put(0x000000d0, "WEB_EMAIL_ADDRESS");
+ TEXT_VARIATIONS.put(0x000000e0, "WEB_PASSWORD");
+
+ }
+
+ private static void addBit(StringBuffer buf, int bit, String str) {
+ if (bit != 0) {
+ buf.append("|");
+ buf.append(str);
+ }
+ }
+
+ private static String inputTypeDesc(int type) {
+ int cls = type & 0x0000000f; // MASK_CLASS
+ int flags = type & 0x00fff000; // MASK_FLAGS
+ int var = type & 0x00000ff0; // MASK_VARIATION
+
+ StringBuffer out = new StringBuffer();
+ String clsName = INPUT_CLASSES.get(cls);
+ out.append(clsName != null ? clsName : "?");
+
+ if (cls == InputType.TYPE_CLASS_TEXT) {
+ String varName = TEXT_VARIATIONS.get(var);
+ if (varName != null) {
+ out.append(".");
+ out.append(varName);
+ }
+ addBit(out, flags & 0x00010000, "AUTO_COMPLETE");
+ addBit(out, flags & 0x00008000, "AUTO_CORRECT");
+ addBit(out, flags & 0x00001000, "CAP_CHARACTERS");
+ addBit(out, flags & 0x00004000, "CAP_SENTENCES");
+ addBit(out, flags & 0x00002000, "CAP_WORDS");
+ addBit(out, flags & 0x00040000, "IME_MULTI_LINE");
+ addBit(out, flags & 0x00020000, "MULTI_LINE");
+ addBit(out, flags & 0x00080000, "NO_SUGGESTIONS");
+ } else if (cls == InputType.TYPE_CLASS_NUMBER) {
+ String varName = NUMBER_VARIATIONS.get(var);
+ if (varName != null) {
+ out.append(".");
+ out.append(varName);
+ }
+ addBit(out, flags & 0x00002000, "DECIMAL");
+ addBit(out, flags & 0x00001000, "SIGNED");
+ } else if (cls == InputType.TYPE_CLASS_DATETIME) {
+ String varName = DATETIME_VARIATIONS.get(var);
+ if (varName != null) {
+ out.append(".");
+ out.append(varName);
+ }
+ }
+ return out.toString();
+ }
+
+ private void updateSummaries() {
+ Resources res = getResources();
+ mSettingsKeyPreference.setSummary(
+ res.getStringArray(R.array.settings_key_modes)
+ [mSettingsKeyPreference.findIndexOfValue(mSettingsKeyPreference.getValue())]);
+
+ mInputConnectionInfo.setSummary(String.format("%s type=%s",
+ LatinIME.sKeyboardSettings.editorPackageName,
+ inputTypeDesc(LatinIME.sKeyboardSettings.editorInputType)
+ ));
+ }
+
+ private void showVoiceConfirmation() {
+ mOkClicked = false;
+ showDialog(VOICE_INPUT_CONFIRM_DIALOG);
+ }
+
+ private void updateVoiceModeSummary() {
+ mVoicePreference.setSummary(
+ getResources().getStringArray(R.array.voice_input_modes_summary)
+ [mVoicePreference.findIndexOfValue(mVoicePreference.getValue())]);
+ }
+
+ @Override
+ protected Dialog onCreateDialog(int id) {
+ switch (id) {
+ case VOICE_INPUT_CONFIRM_DIALOG:
+ DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int whichButton) {
+ if (whichButton == DialogInterface.BUTTON_NEGATIVE) {
+ mVoicePreference.setValue(mVoiceModeOff);
+ mLogger.settingsWarningDialogCancel();
+ } else if (whichButton == DialogInterface.BUTTON_POSITIVE) {
+ mOkClicked = true;
+ mLogger.settingsWarningDialogOk();
+ }
+ updateVoicePreference();
+ }
+ };
+ AlertDialog.Builder builder = new AlertDialog.Builder(this)
+ .setTitle(R.string.voice_warning_title)
+ .setPositiveButton(android.R.string.ok, listener)
+ .setNegativeButton(android.R.string.cancel, listener);
+
+ // Get the current list of supported locales and check the current locale against
+ // that list, to decide whether to put a warning that voice input will not work in
+ // the current language as part of the pop-up confirmation dialog.
+ String supportedLocalesString = SettingsUtil.getSettingsString(
+ getContentResolver(),
+ SettingsUtil.LATIN_IME_VOICE_INPUT_SUPPORTED_LOCALES,
+ LatinIME.DEFAULT_VOICE_INPUT_SUPPORTED_LOCALES);
+ ArrayList<String> voiceInputSupportedLocales =
+ LatinIME.newArrayList(supportedLocalesString.split("\\s+"));
+ boolean localeSupported =
+ voiceInputSupportedLocales.contains(Locale.getDefault().toString()) ||
+ voiceInputSupportedLocales.contains(Locale.getDefault().getLanguage());
+
+ if (localeSupported) {
+ String message = getString(R.string.voice_warning_may_not_understand) + "\n\n" +
+ getString(R.string.voice_hint_dialog_message);
+ builder.setMessage(message);
+ } else {
+ String message = getString(R.string.voice_warning_locale_not_supported) +
+ "\n\n" + getString(R.string.voice_warning_may_not_understand) + "\n\n" +
+ getString(R.string.voice_hint_dialog_message);
+ builder.setMessage(message);
+ }
+
+ AlertDialog dialog = builder.create();
+ dialog.setOnDismissListener(this);
+ mLogger.settingsWarningDialogShown();
+ return dialog;
+ default:
+ Log.e(TAG, "unknown dialog " + id);
+ return null;
+ }
+ }
+
+ public void onDismiss(DialogInterface dialog) {
+ mLogger.settingsWarningDialogDismissed();
+ if (!mOkClicked) {
+ // This assumes that onPreferenceClick gets called first, and this if the user
+ // agreed after the warning, we set the mOkClicked value to true.
+ mVoicePreference.setValue(mVoiceModeOff);
+ }
+ }
+
+ private void updateVoicePreference() {
+ boolean isChecked = !mVoicePreference.getValue().equals(mVoiceModeOff);
+ if (isChecked) {
+ mLogger.voiceInputSettingEnabled();
+ } else {
+ mLogger.voiceInputSettingDisabled();
+ }
+ }
+}
diff --git a/java/src/org/pocketworkstation/pckeyboard/LatinIMEUtil.java b/java/src/org/pocketworkstation/pckeyboard/LatinIMEUtil.java
new file mode 100644
index 0000000..537215c
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/LatinIMEUtil.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.pocketworkstation.pckeyboard;
+
+import android.view.inputmethod.InputMethodManager;
+
+import android.content.Context;
+import android.os.AsyncTask;
+import android.text.format.DateUtils;
+import android.util.Log;
+
+public class LatinIMEUtil {
+
+ /**
+ * Cancel an {@link AsyncTask}.
+ *
+ * @param mayInterruptIfRunning <tt>true</tt> if the thread executing this
+ * task should be interrupted; otherwise, in-progress tasks are allowed
+ * to complete.
+ */
+ public static void cancelTask(AsyncTask<?, ?, ?> task, boolean mayInterruptIfRunning) {
+ if (task != null && task.getStatus() != AsyncTask.Status.FINISHED) {
+ task.cancel(mayInterruptIfRunning);
+ }
+ }
+
+ public static class GCUtils {
+ private static final String TAG = "GCUtils";
+ public static final int GC_TRY_COUNT = 2;
+ // GC_TRY_LOOP_MAX is used for the hard limit of GC wait,
+ // GC_TRY_LOOP_MAX should be greater than GC_TRY_COUNT.
+ public static final int GC_TRY_LOOP_MAX = 5;
+ private static final long GC_INTERVAL = DateUtils.SECOND_IN_MILLIS;
+ private static GCUtils sInstance = new GCUtils();
+ private int mGCTryCount = 0;
+
+ public static GCUtils getInstance() {
+ return sInstance;
+ }
+
+ public void reset() {
+ mGCTryCount = 0;
+ }
+
+ public boolean tryGCOrWait(String metaData, Throwable t) {
+ if (mGCTryCount == 0) {
+ System.gc();
+ }
+ if (++mGCTryCount > GC_TRY_COUNT) {
+ LatinImeLogger.logOnException(metaData, t);
+ return false;
+ } else {
+ try {
+ Thread.sleep(GC_INTERVAL);
+ return true;
+ } catch (InterruptedException e) {
+ Log.e(TAG, "Sleep was interrupted.");
+ LatinImeLogger.logOnException(metaData, t);
+ return false;
+ }
+ }
+ }
+ }
+
+ /* package */ static class RingCharBuffer {
+ private static RingCharBuffer sRingCharBuffer = new RingCharBuffer();
+ private static final char PLACEHOLDER_DELIMITER_CHAR = '\uFFFC';
+ private static final int INVALID_COORDINATE = -2;
+ /* package */ static final int BUFSIZE = 20;
+ private Context mContext;
+ private boolean mEnabled = false;
+ private int mEnd = 0;
+ /* package */ int mLength = 0;
+ private char[] mCharBuf = new char[BUFSIZE];
+ private int[] mXBuf = new int[BUFSIZE];
+ private int[] mYBuf = new int[BUFSIZE];
+
+ private RingCharBuffer() {
+ }
+ public static RingCharBuffer getInstance() {
+ return sRingCharBuffer;
+ }
+ public static RingCharBuffer init(Context context, boolean enabled) {
+ sRingCharBuffer.mContext = context;
+ sRingCharBuffer.mEnabled = enabled;
+ return sRingCharBuffer;
+ }
+ private int normalize(int in) {
+ int ret = in % BUFSIZE;
+ return ret < 0 ? ret + BUFSIZE : ret;
+ }
+ public void push(char c, int x, int y) {
+ if (!mEnabled) return;
+ mCharBuf[mEnd] = c;
+ mXBuf[mEnd] = x;
+ mYBuf[mEnd] = y;
+ mEnd = normalize(mEnd + 1);
+ if (mLength < BUFSIZE) {
+ ++mLength;
+ }
+ }
+ public char pop() {
+ if (mLength < 1) {
+ return PLACEHOLDER_DELIMITER_CHAR;
+ } else {
+ mEnd = normalize(mEnd - 1);
+ --mLength;
+ return mCharBuf[mEnd];
+ }
+ }
+ public char getLastChar() {
+ if (mLength < 1) {
+ return PLACEHOLDER_DELIMITER_CHAR;
+ } else {
+ return mCharBuf[normalize(mEnd - 1)];
+ }
+ }
+ public int getPreviousX(char c, int back) {
+ int index = normalize(mEnd - 2 - back);
+ if (mLength <= back
+ || Character.toLowerCase(c) != Character.toLowerCase(mCharBuf[index])) {
+ return INVALID_COORDINATE;
+ } else {
+ return mXBuf[index];
+ }
+ }
+ public int getPreviousY(char c, int back) {
+ int index = normalize(mEnd - 2 - back);
+ if (mLength <= back
+ || Character.toLowerCase(c) != Character.toLowerCase(mCharBuf[index])) {
+ return INVALID_COORDINATE;
+ } else {
+ return mYBuf[index];
+ }
+ }
+ public String getLastString() {
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < mLength; ++i) {
+ char c = mCharBuf[normalize(mEnd - 1 - i)];
+ if (!((LatinIME)mContext).isWordSeparator(c)) {
+ sb.append(c);
+ } else {
+ break;
+ }
+ }
+ return sb.reverse().toString();
+ }
+ public void reset() {
+ mLength = 0;
+ }
+ }
+}
diff --git a/java/src/org/pocketworkstation/pckeyboard/LatinImeLogger.java b/java/src/org/pocketworkstation/pckeyboard/LatinImeLogger.java
new file mode 100644
index 0000000..d3215d1
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/LatinImeLogger.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.pocketworkstation.pckeyboard;
+
+import org.pocketworkstation.pckeyboard.Dictionary.DataType;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import java.util.List;
+
+public class LatinImeLogger implements SharedPreferences.OnSharedPreferenceChangeListener {
+
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
+ }
+
+ public static void init(Context context) {
+ }
+
+ public static void commit() {
+ }
+
+ public static void onDestroy() {
+ }
+
+ public static void logOnManualSuggestion(
+ String before, String after, int position, List<CharSequence> suggestions) {
+ }
+
+ public static void logOnAutoSuggestion(String before, String after) {
+ }
+
+ public static void logOnAutoSuggestionCanceled() {
+ }
+
+ public static void logOnDelete() {
+ }
+
+ public static void logOnInputChar() {
+ }
+
+ public static void logOnException(String metaData, Throwable e) {
+ }
+
+ public static void logOnWarning(String warning) {
+ }
+
+ public static void onStartSuggestion(CharSequence previousWords) {
+ }
+
+ public static void onAddSuggestedWord(String word, int typeId, DataType dataType) {
+ }
+
+ public static void onSetKeyboard(Keyboard kb) {
+ }
+
+}
diff --git a/java/src/org/pocketworkstation/pckeyboard/LatinKeyboard.java b/java/src/org/pocketworkstation/pckeyboard/LatinKeyboard.java
new file mode 100644
index 0000000..7cd7475
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/LatinKeyboard.java
@@ -0,0 +1,967 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.pocketworkstation.pckeyboard;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.Paint;
+import android.graphics.Paint.Align;
+import android.graphics.PixelFormat;
+import android.graphics.PorterDuff;
+import android.graphics.Rect;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.text.TextPaint;
+import android.util.Log;
+import android.view.ViewConfiguration;
+import android.view.inputmethod.EditorInfo;
+
+import java.util.List;
+import java.util.Locale;
+
+public class LatinKeyboard extends Keyboard {
+
+ private static final boolean DEBUG_PREFERRED_LETTER = true;
+ private static final String TAG = "PCKeyboardLK";
+ private static final int OPACITY_FULLY_OPAQUE = 255;
+ private static final int SPACE_LED_LENGTH_PERCENT = 80;
+
+ private Drawable mShiftLockIcon;
+ private Drawable mShiftLockPreviewIcon;
+ private Drawable mOldShiftIcon;
+ private Drawable mSpaceIcon;
+ private Drawable mSpaceAutoCompletionIndicator;
+ private Drawable mSpacePreviewIcon;
+ private Drawable mMicIcon;
+ private Drawable mMicPreviewIcon;
+ private Drawable mSettingsIcon;
+ private Drawable mSettingsPreviewIcon;
+ private Drawable m123MicIcon;
+ private Drawable m123MicPreviewIcon;
+ private final Drawable mButtonArrowLeftIcon;
+ private final Drawable mButtonArrowRightIcon;
+ private Key mShiftKey;
+ private Key mEnterKey;
+ private Key mF1Key;
+ private final Drawable mHintIcon;
+ private Key mSpaceKey;
+ private Key m123Key;
+ private final int[] mSpaceKeyIndexArray;
+ private int mSpaceDragStartX;
+ private int mSpaceDragLastDiff;
+ private Locale mLocale;
+ private LanguageSwitcher mLanguageSwitcher;
+ private final Resources mRes;
+ private final Context mContext;
+ private int mMode;
+ // Whether this keyboard has voice icon on it
+ private boolean mHasVoiceButton;
+ // Whether voice icon is enabled at all
+ private boolean mVoiceEnabled;
+ private final boolean mIsAlphaKeyboard;
+ private final boolean mIsAlphaFullKeyboard;
+ private final boolean mIsFnFullKeyboard;
+ private CharSequence m123Label;
+ private boolean mCurrentlyInSpace;
+ private SlidingLocaleDrawable mSlidingLocaleIcon;
+ private int[] mPrefLetterFrequencies;
+ private int mPrefLetter;
+ private int mPrefLetterX;
+ private int mPrefLetterY;
+ private int mPrefDistance;
+
+ private int mExtensionResId;
+
+ // TODO: remove this attribute when either Keyboard.mDefaultVerticalGap or Key.parent becomes
+ // non-private.
+ private final int mVerticalGap;
+
+ private LatinKeyboard mExtensionKeyboard;
+
+ private static final float SPACEBAR_DRAG_THRESHOLD = 0.51f;
+ private static final float OVERLAP_PERCENTAGE_LOW_PROB = 0.70f;
+ private static final float OVERLAP_PERCENTAGE_HIGH_PROB = 0.85f;
+ // Minimum width of space key preview (proportional to keyboard width)
+ private static final float SPACEBAR_POPUP_MIN_RATIO = 0.4f;
+ // Minimum width of space key preview (proportional to screen height)
+ private static final float SPACEBAR_POPUP_MAX_RATIO = 0.4f;
+ // Height in space key the language name will be drawn. (proportional to space key height)
+ private static final float SPACEBAR_LANGUAGE_BASELINE = 0.6f;
+ // If the full language name needs to be smaller than this value to be drawn on space key,
+ // its short language name will be used instead.
+ private static final float MINIMUM_SCALE_OF_LANGUAGE_NAME = 0.8f;
+
+ private static int sSpacebarVerticalCorrection;
+
+ public LatinKeyboard(Context context, int xmlLayoutResId) {
+ this(context, xmlLayoutResId, 0, 0);
+ }
+
+ public LatinKeyboard(Context context, int xmlLayoutResId, int mode, float kbHeightPercent) {
+ super(context, 0, xmlLayoutResId, mode, kbHeightPercent);
+ final Resources res = context.getResources();
+ //Log.i("PCKeyboard", "keyHeight=" + this.getKeyHeight());
+ //this.setKeyHeight(30); // is useless, see http://code.google.com/p/android/issues/detail?id=4532
+ mContext = context;
+ mMode = mode;
+ mRes = res;
+ mShiftLockIcon = res.getDrawable(R.drawable.sym_keyboard_shift_locked);
+ mShiftLockPreviewIcon = res.getDrawable(R.drawable.sym_keyboard_feedback_shift_locked);
+ setDefaultBounds(mShiftLockPreviewIcon);
+ mSpaceIcon = res.getDrawable(R.drawable.sym_keyboard_space);
+ mSpaceAutoCompletionIndicator = res.getDrawable(R.drawable.sym_keyboard_space_led);
+ mSpacePreviewIcon = res.getDrawable(R.drawable.sym_keyboard_feedback_space);
+ mMicIcon = res.getDrawable(R.drawable.sym_keyboard_mic);
+ mMicPreviewIcon = res.getDrawable(R.drawable.sym_keyboard_feedback_mic);
+ mSettingsIcon = res.getDrawable(R.drawable.sym_keyboard_settings);
+ mSettingsPreviewIcon = res.getDrawable(R.drawable.sym_keyboard_feedback_settings);
+ setDefaultBounds(mMicPreviewIcon);
+ mButtonArrowLeftIcon = res.getDrawable(R.drawable.sym_keyboard_language_arrows_left);
+ mButtonArrowRightIcon = res.getDrawable(R.drawable.sym_keyboard_language_arrows_right);
+ m123MicIcon = res.getDrawable(R.drawable.sym_keyboard_123_mic);
+ m123MicPreviewIcon = res.getDrawable(R.drawable.sym_keyboard_feedback_123_mic);
+ mHintIcon = res.getDrawable(R.drawable.hint_popup);
+ setDefaultBounds(m123MicPreviewIcon);
+ sSpacebarVerticalCorrection = res.getDimensionPixelOffset(
+ R.dimen.spacebar_vertical_correction);
+ mIsAlphaKeyboard = xmlLayoutResId == R.xml.kbd_qwerty;
+ mIsAlphaFullKeyboard = xmlLayoutResId == R.xml.kbd_full;
+ mIsFnFullKeyboard = xmlLayoutResId == R.xml.kbd_full_fn;
+ // The index of space key is available only after Keyboard constructor has finished.
+ mSpaceKeyIndexArray = new int[] { indexOf(LatinIME.ASCII_SPACE) };
+ // TODO remove this initialization after cleanup
+ mVerticalGap = super.getVerticalGap();
+ }
+
+ @Override
+ protected Key createKeyFromXml(Resources res, Row parent, int x, int y,
+ XmlResourceParser parser) {
+ Key key = new LatinKey(res, parent, x, y, parser);
+ if (key.codes == null) return key;
+ switch (key.codes[0]) {
+ case LatinIME.ASCII_ENTER:
+ mEnterKey = key;
+ break;
+ case LatinKeyboardView.KEYCODE_F1:
+ mF1Key = key;
+ break;
+ case LatinIME.ASCII_SPACE:
+ mSpaceKey = key;
+ break;
+ case KEYCODE_MODE_CHANGE:
+ m123Key = key;
+ m123Label = key.label;
+ break;
+ }
+
+ return key;
+ }
+
+ void setImeOptions(Resources res, int mode, int options) {
+ mMode = mode;
+ // TODO should clean up this method
+ if (mEnterKey != null) {
+ // Reset some of the rarely used attributes.
+ mEnterKey.popupCharacters = null;
+ mEnterKey.popupResId = 0;
+ mEnterKey.text = null;
+ switch (options&(EditorInfo.IME_MASK_ACTION|EditorInfo.IME_FLAG_NO_ENTER_ACTION)) {
+ case EditorInfo.IME_ACTION_GO:
+ mEnterKey.iconPreview = null;
+ mEnterKey.icon = null;
+ mEnterKey.label = res.getText(R.string.label_go_key);
+ break;
+ case EditorInfo.IME_ACTION_NEXT:
+ mEnterKey.iconPreview = null;
+ mEnterKey.icon = null;
+ mEnterKey.label = res.getText(R.string.label_next_key);
+ break;
+ case EditorInfo.IME_ACTION_DONE:
+ mEnterKey.iconPreview = null;
+ mEnterKey.icon = null;
+ mEnterKey.label = res.getText(R.string.label_done_key);
+ break;
+ case EditorInfo.IME_ACTION_SEARCH:
+ mEnterKey.iconPreview = res.getDrawable(
+ R.drawable.sym_keyboard_feedback_search);
+ mEnterKey.icon = res.getDrawable(R.drawable.sym_keyboard_search);
+ mEnterKey.label = null;
+ break;
+ case EditorInfo.IME_ACTION_SEND:
+ mEnterKey.iconPreview = null;
+ mEnterKey.icon = null;
+ mEnterKey.label = res.getText(R.string.label_send_key);
+ break;
+ default:
+ // Keep Return key in IM mode, we have a dedicated smiley key.
+ mEnterKey.iconPreview = res.getDrawable(
+ R.drawable.sym_keyboard_feedback_return);
+ mEnterKey.icon = res.getDrawable(R.drawable.sym_keyboard_return);
+ mEnterKey.label = null;
+ break;
+ }
+ // Set the initial size of the preview icon
+ if (mEnterKey.iconPreview != null) {
+ setDefaultBounds(mEnterKey.iconPreview);
+ }
+ }
+ }
+
+ void enableShiftLock() {
+ int index = getShiftKeyIndex();
+ if (index >= 0) {
+ mShiftKey = getKeys().get(index);
+ mOldShiftIcon = mShiftKey.icon;
+ }
+ }
+
+ @Override
+ public boolean setShiftState(int shiftState) {
+ if (mShiftKey != null) {
+ // Tri-state LED tracks "on" and "lock" states, icon shows Caps state.
+ mShiftKey.on = shiftState == SHIFT_ON || shiftState == SHIFT_LOCKED;
+ mShiftKey.locked = shiftState == SHIFT_LOCKED || shiftState == SHIFT_CAPS_LOCKED;
+ mShiftKey.icon = (shiftState == SHIFT_OFF || shiftState == SHIFT_ON || shiftState == SHIFT_LOCKED) ?
+ mOldShiftIcon : mShiftLockIcon;
+ return super.setShiftState(shiftState, false);
+ } else {
+ return super.setShiftState(shiftState, true);
+ }
+ }
+
+ /* package */ boolean isAlphaKeyboard() {
+ return mIsAlphaKeyboard;
+ }
+
+ public void setExtension(LatinKeyboard extKeyboard) {
+ mExtensionKeyboard = extKeyboard;
+ }
+
+ public LatinKeyboard getExtension() {
+ return mExtensionKeyboard;
+ }
+
+ public void updateSymbolIcons(boolean isAutoCompletion) {
+ updateDynamicKeys();
+ if (mSpaceKey != null) {
+ updateSpaceBarForLocale(isAutoCompletion);
+ }
+ }
+
+ private void setDefaultBounds(Drawable drawable) {
+ drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
+ }
+
+ public void setVoiceMode(boolean hasVoiceButton, boolean hasVoice) {
+ mHasVoiceButton = hasVoiceButton;
+ mVoiceEnabled = hasVoice;
+ updateDynamicKeys();
+ }
+
+ private void updateDynamicKeys() {
+ update123Key();
+ updateF1Key();
+ }
+
+ private void update123Key() {
+ // Update KEYCODE_MODE_CHANGE key only on alphabet mode, not on symbol mode.
+ if (m123Key != null && mIsAlphaKeyboard) {
+ if (mVoiceEnabled && !mHasVoiceButton) {
+ m123Key.icon = m123MicIcon;
+ m123Key.iconPreview = m123MicPreviewIcon;
+ m123Key.label = null;
+ } else {
+ m123Key.icon = null;
+ m123Key.iconPreview = null;
+ m123Key.label = m123Label;
+ }
+ }
+ }
+
+ private void updateF1Key() {
+ // Update KEYCODE_F1 key. Please note that some keyboard layouts have no F1 key.
+ if (mF1Key == null)
+ return;
+
+ if (mIsAlphaKeyboard) {
+ if (mMode == KeyboardSwitcher.MODE_URL) {
+ setNonMicF1Key(mF1Key, "/", R.xml.popup_slash);
+ } else if (mMode == KeyboardSwitcher.MODE_EMAIL) {
+ setNonMicF1Key(mF1Key, "@", R.xml.popup_at);
+ } else {
+ if (mVoiceEnabled && mHasVoiceButton) {
+ setMicF1Key(mF1Key);
+ } else {
+ setNonMicF1Key(mF1Key, ",", R.xml.popup_comma);
+ }
+ }
+ } else if (mIsAlphaFullKeyboard) {
+ if (mVoiceEnabled && mHasVoiceButton) {
+ setMicF1Key(mF1Key);
+ } else {
+ setSettingsF1Key(mF1Key);
+ }
+ } else if (mIsFnFullKeyboard) {
+ setMicF1Key(mF1Key);
+ } else { // Symbols keyboard
+ if (mVoiceEnabled && mHasVoiceButton) {
+ setMicF1Key(mF1Key);
+ } else {
+ setNonMicF1Key(mF1Key, ",", R.xml.popup_comma);
+ }
+ }
+ }
+
+ private void setMicF1Key(Key key) {
+ // HACK: draw mMicIcon and mHintIcon at the same time
+ final Drawable micWithSettingsHintDrawable = new BitmapDrawable(mRes,
+ drawSynthesizedSettingsHintImage(key.width, key.height, mMicIcon, mHintIcon));
+
+ if (key.popupResId == 0) {
+ key.popupResId = R.xml.popup_mic;
+ } else {
+ key.modifier = true;
+ if (key.label != null) {
+ key.popupCharacters = (key.popupCharacters == null) ?
+ key.label : key.label + key.popupCharacters.toString();
+ }
+ }
+ key.label = null;
+ key.codes = new int[] { LatinKeyboardView.KEYCODE_VOICE };
+ key.icon = micWithSettingsHintDrawable;
+ key.iconPreview = mMicPreviewIcon;
+ }
+
+ private void setSettingsF1Key(Key key) {
+ if (key.shiftLabel != null && key.label != null) {
+ key.codes = new int[] { key.label.charAt(0) };
+ return; // leave key otherwise unmodified
+ }
+ final Drawable settingsHintDrawable = new BitmapDrawable(mRes,
+ drawSynthesizedSettingsHintImage(key.width, key.height, mSettingsIcon, mHintIcon));
+ key.label = null;
+ key.icon = settingsHintDrawable;
+ key.codes = new int[] { LatinKeyboardView.KEYCODE_OPTIONS };
+ key.popupResId = R.xml.popup_mic;
+ key.iconPreview = mSettingsPreviewIcon;
+ }
+
+ private void setNonMicF1Key(Key key, String label, int popupResId) {
+ if (key.shiftLabel != null) {
+ key.codes = new int[] { key.label.charAt(0) };
+ return; // leave key unmodified
+ }
+ key.label = label;
+ key.codes = new int[] { label.charAt(0) };
+ key.popupResId = popupResId;
+ key.icon = mHintIcon;
+ key.iconPreview = null;
+ }
+
+ public boolean isF1Key(Key key) {
+ return key == mF1Key;
+ }
+
+ public static boolean hasPuncOrSmileysPopup(Key key) {
+ return key.popupResId == R.xml.popup_punctuation || key.popupResId == R.xml.popup_smileys;
+ }
+
+ /**
+ * @return a key which should be invalidated.
+ */
+ public Key onAutoCompletionStateChanged(boolean isAutoCompletion) {
+ updateSpaceBarForLocale(isAutoCompletion);
+ return mSpaceKey;
+ }
+
+ public boolean isLanguageSwitchEnabled() {
+ return mLocale != null;
+ }
+
+ private void updateSpaceBarForLocale(boolean isAutoCompletion) {
+ // If application locales are explicitly selected.
+ if (mLocale != null) {
+ mSpaceKey.icon = new BitmapDrawable(mRes,
+ drawSpaceBar(OPACITY_FULLY_OPAQUE, isAutoCompletion));
+ } else {
+ // sym_keyboard_space_led can be shared with Black and White symbol themes.
+ if (isAutoCompletion) {
+ mSpaceKey.icon = new BitmapDrawable(mRes,
+ drawSpaceBar(OPACITY_FULLY_OPAQUE, isAutoCompletion));
+ } else {
+ mSpaceKey.icon = mRes.getDrawable(R.drawable.sym_keyboard_space);
+ }
+ }
+ }
+
+ // Compute width of text with specified text size using paint.
+ private static int getTextWidth(Paint paint, String text, float textSize, Rect bounds) {
+ paint.setTextSize(textSize);
+ paint.getTextBounds(text, 0, text.length(), bounds);
+ return bounds.width();
+ }
+
+ // Overlay two images: mainIcon and hintIcon.
+ private Bitmap drawSynthesizedSettingsHintImage(
+ int width, int height, Drawable mainIcon, Drawable hintIcon) {
+ if (mainIcon == null || hintIcon == null)
+ return null;
+ Rect hintIconPadding = new Rect(0, 0, 0, 0);
+ hintIcon.getPadding(hintIconPadding);
+ final Bitmap buffer = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+ final Canvas canvas = new Canvas(buffer);
+ canvas.drawColor(mRes.getColor(R.color.latinkeyboard_transparent), PorterDuff.Mode.CLEAR);
+
+ // Draw main icon at the center of the key visual
+ // Assuming the hintIcon shares the same padding with the key's background drawable
+ final int drawableX = (width + hintIconPadding.left - hintIconPadding.right
+ - mainIcon.getIntrinsicWidth()) / 2;
+ final int drawableY = (height + hintIconPadding.top - hintIconPadding.bottom
+ - mainIcon.getIntrinsicHeight()) / 2;
+ setDefaultBounds(mainIcon);
+ canvas.translate(drawableX, drawableY);
+ mainIcon.draw(canvas);
+ canvas.translate(-drawableX, -drawableY);
+
+ // Draw hint icon fully in the key
+ hintIcon.setBounds(0, 0, width, height);
+ hintIcon.draw(canvas);
+ return buffer;
+ }
+
+ // Layout local language name and left and right arrow on space bar.
+ private static String layoutSpaceBar(Paint paint, Locale locale, Drawable lArrow,
+ Drawable rArrow, int width, int height, float origTextSize,
+ boolean allowVariableTextSize) {
+ final float arrowWidth = lArrow.getIntrinsicWidth();
+ final float arrowHeight = lArrow.getIntrinsicHeight();
+ final float maxTextWidth = width - (arrowWidth + arrowWidth);
+ final Rect bounds = new Rect();
+
+ // Estimate appropriate language name text size to fit in maxTextWidth.
+ String language = LanguageSwitcher.toTitleCase(locale.getDisplayLanguage(locale));
+ int textWidth = getTextWidth(paint, language, origTextSize, bounds);
+ // Assuming text width and text size are proportional to each other.
+ float textSize = origTextSize * Math.min(maxTextWidth / textWidth, 1.0f);
+
+ final boolean useShortName;
+ if (allowVariableTextSize) {
+ textWidth = getTextWidth(paint, language, textSize, bounds);
+ // If text size goes too small or text does not fit, use short name
+ useShortName = textSize / origTextSize < MINIMUM_SCALE_OF_LANGUAGE_NAME
+ || textWidth > maxTextWidth;
+ } else {
+ useShortName = textWidth > maxTextWidth;
+ textSize = origTextSize;
+ }
+ if (useShortName) {
+ language = LanguageSwitcher.toTitleCase(locale.getLanguage());
+ textWidth = getTextWidth(paint, language, origTextSize, bounds);
+ textSize = origTextSize * Math.min(maxTextWidth / textWidth, 1.0f);
+ }
+ paint.setTextSize(textSize);
+
+ // Place left and right arrow just before and after language text.
+ final float baseline = height * SPACEBAR_LANGUAGE_BASELINE;
+ final int top = (int)(baseline - arrowHeight);
+ final float remains = (width - textWidth) / 2;
+ lArrow.setBounds((int)(remains - arrowWidth), top, (int)remains, (int)baseline);
+ rArrow.setBounds((int)(remains + textWidth), top, (int)(remains + textWidth + arrowWidth),
+ (int)baseline);
+
+ return language;
+ }
+
+ private Bitmap drawSpaceBar(int opacity, boolean isAutoCompletion) {
+ final int width = mSpaceKey.width;
+ final int height = mSpaceIcon.getIntrinsicHeight();
+ final Bitmap buffer = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+ final Canvas canvas = new Canvas(buffer);
+ canvas.drawColor(mRes.getColor(R.color.latinkeyboard_transparent), PorterDuff.Mode.CLEAR);
+
+ // If application locales are explicitly selected.
+ if (mLocale != null) {
+ final Paint paint = new Paint();
+ paint.setAlpha(opacity);
+ paint.setAntiAlias(true);
+ paint.setTextAlign(Align.CENTER);
+
+ final boolean allowVariableTextSize = true;
+ Locale locale = mLanguageSwitcher.getInputLocale();
+ //Log.i("PCKeyboard", "input locale: " + locale);
+ final String language = layoutSpaceBar(paint, locale,
+ mButtonArrowLeftIcon, mButtonArrowRightIcon, width, height,
+ getTextSizeFromTheme(android.R.style.TextAppearance_Small, 14),
+ allowVariableTextSize);
+
+ // Draw language text with shadow
+ final int shadowColor = mRes.getColor(R.color.latinkeyboard_bar_language_shadow_white);
+ final float baseline = height * SPACEBAR_LANGUAGE_BASELINE;
+ final float descent = paint.descent();
+ paint.setColor(shadowColor);
+ canvas.drawText(language, width / 2, baseline - descent - 1, paint);
+ paint.setColor(mRes.getColor(R.color.latinkeyboard_dim_color_white));
+
+ canvas.drawText(language, width / 2, baseline - descent, paint);
+
+ // Put arrows that are already layed out on either side of the text
+ if (mLanguageSwitcher.getLocaleCount() > 1) {
+ mButtonArrowLeftIcon.draw(canvas);
+ mButtonArrowRightIcon.draw(canvas);
+ }
+ }
+
+ // Draw the spacebar icon at the bottom
+ if (isAutoCompletion) {
+ final int iconWidth = width * SPACE_LED_LENGTH_PERCENT / 100;
+ final int iconHeight = mSpaceAutoCompletionIndicator.getIntrinsicHeight();
+ int x = (width - iconWidth) / 2;
+ int y = height - iconHeight;
+ mSpaceAutoCompletionIndicator.setBounds(x, y, x + iconWidth, y + iconHeight);
+ mSpaceAutoCompletionIndicator.draw(canvas);
+ } else {
+ final int iconWidth = mSpaceIcon.getIntrinsicWidth();
+ final int iconHeight = mSpaceIcon.getIntrinsicHeight();
+ int x = (width - iconWidth) / 2;
+ int y = height - iconHeight;
+ mSpaceIcon.setBounds(x, y, x + iconWidth, y + iconHeight);
+ mSpaceIcon.draw(canvas);
+ }
+ return buffer;
+ }
+
+ private int getSpacePreviewWidth() {
+ final int width = Math.min(
+ Math.max(mSpaceKey.width, (int)(getMinWidth() * SPACEBAR_POPUP_MIN_RATIO)),
+ (int)(getScreenHeight() * SPACEBAR_POPUP_MAX_RATIO));
+ return width;
+ }
+
+ private void updateLocaleDrag(int diff) {
+ if (mSlidingLocaleIcon == null) {
+ final int width = getSpacePreviewWidth();
+ final int height = mSpacePreviewIcon.getIntrinsicHeight();
+ mSlidingLocaleIcon = new SlidingLocaleDrawable(mSpacePreviewIcon, width, height);
+ mSlidingLocaleIcon.setBounds(0, 0, width, height);
+ mSpaceKey.iconPreview = mSlidingLocaleIcon;
+ }
+ mSlidingLocaleIcon.setDiff(diff);
+ if (Math.abs(diff) == Integer.MAX_VALUE) {
+ mSpaceKey.iconPreview = mSpacePreviewIcon;
+ } else {
+ mSpaceKey.iconPreview = mSlidingLocaleIcon;
+ }
+ mSpaceKey.iconPreview.invalidateSelf();
+ }
+
+ public int getLanguageChangeDirection() {
+ if (mSpaceKey == null || mLanguageSwitcher.getLocaleCount() < 2
+ || Math.abs(mSpaceDragLastDiff) < getSpacePreviewWidth() * SPACEBAR_DRAG_THRESHOLD) {
+ return 0; // No change
+ }
+ return mSpaceDragLastDiff > 0 ? 1 : -1;
+ }
+
+ public void setLanguageSwitcher(LanguageSwitcher switcher, boolean isAutoCompletion) {
+ mLanguageSwitcher = switcher;
+ Locale locale = mLanguageSwitcher.getLocaleCount() > 0
+ ? mLanguageSwitcher.getInputLocale()
+ : null;
+ // If the language count is 1 and is the same as the system language, don't show it.
+ if (locale != null
+ && mLanguageSwitcher.getLocaleCount() == 1
+ && mLanguageSwitcher.getSystemLocale().getLanguage()
+ .equalsIgnoreCase(locale.getLanguage())) {
+ locale = null;
+ }
+ mLocale = locale;
+ updateSymbolIcons(isAutoCompletion);
+ }
+
+ boolean isCurrentlyInSpace() {
+ return mCurrentlyInSpace;
+ }
+
+ void setPreferredLetters(int[] frequencies) {
+ mPrefLetterFrequencies = frequencies;
+ mPrefLetter = 0;
+ }
+
+ void keyReleased() {
+ mCurrentlyInSpace = false;
+ mSpaceDragLastDiff = 0;
+ mPrefLetter = 0;
+ mPrefLetterX = 0;
+ mPrefLetterY = 0;
+ mPrefDistance = Integer.MAX_VALUE;
+ if (mSpaceKey != null) {
+ updateLocaleDrag(Integer.MAX_VALUE);
+ }
+ }
+
+ /**
+ * Does the magic of locking the touch gesture into the spacebar when
+ * switching input languages.
+ */
+ boolean isInside(LatinKey key, int x, int y) {
+ final int code = key.codes[0];
+ if (code == KEYCODE_SHIFT ||
+ code == KEYCODE_DELETE) {
+ // Adjust target area for these keys
+ y -= key.height / 10;
+ if (code == KEYCODE_SHIFT) {
+ if (key.x == 0) {
+ x += key.width / 6; // left shift
+ } else {
+ x -= key.width / 6; // right shift
+ }
+ }
+ if (code == KEYCODE_DELETE) x -= key.width / 6;
+ } else if (code == LatinIME.ASCII_SPACE) {
+ y += LatinKeyboard.sSpacebarVerticalCorrection;
+ if (mLanguageSwitcher.getLocaleCount() > 1) {
+ if (mCurrentlyInSpace) {
+ int diff = x - mSpaceDragStartX;
+ if (Math.abs(diff - mSpaceDragLastDiff) > 0) {
+ updateLocaleDrag(diff);
+ }
+ mSpaceDragLastDiff = diff;
+ return true;
+ } else {
+ boolean insideSpace = key.isInsideSuper(x, y);
+ if (insideSpace) {
+ mCurrentlyInSpace = true;
+ mSpaceDragStartX = x;
+ updateLocaleDrag(0);
+ }
+ return insideSpace;
+ }
+ }
+ } else if (mPrefLetterFrequencies != null) {
+ // New coordinate? Reset
+ if (mPrefLetterX != x || mPrefLetterY != y) {
+ mPrefLetter = 0;
+ mPrefDistance = Integer.MAX_VALUE;
+ }
+ // Handle preferred next letter
+ final int[] pref = mPrefLetterFrequencies;
+ if (mPrefLetter > 0) {
+ if (DEBUG_PREFERRED_LETTER) {
+ if (mPrefLetter == code && !key.isInsideSuper(x, y)) {
+ Log.d(TAG, "CORRECTED !!!!!!");
+ }
+ }
+ return mPrefLetter == code;
+ } else {
+ final boolean inside = key.isInsideSuper(x, y);
+ int[] nearby = getNearestKeys(x, y);
+ List<Key> nearbyKeys = getKeys();
+ if (inside) {
+ // If it's a preferred letter
+ if (inPrefList(code, pref)) {
+ // Check if its frequency is much lower than a nearby key
+ mPrefLetter = code;
+ mPrefLetterX = x;
+ mPrefLetterY = y;
+ for (int i = 0; i < nearby.length; i++) {
+ Key k = nearbyKeys.get(nearby[i]);
+ if (k != key && inPrefList(k.codes[0], pref)) {
+ final int dist = distanceFrom(k, x, y);
+ if (dist < (int) (k.width * OVERLAP_PERCENTAGE_LOW_PROB) &&
+ (pref[k.codes[0]] > pref[mPrefLetter] * 3)) {
+ mPrefLetter = k.codes[0];
+ mPrefDistance = dist;
+ if (DEBUG_PREFERRED_LETTER) {
+ Log.d(TAG, "CORRECTED ALTHOUGH PREFERRED !!!!!!");
+ }
+ break;
+ }
+ }
+ }
+
+ return mPrefLetter == code;
+ }
+ }
+
+ // Get the surrounding keys and intersect with the preferred list
+ // For all in the intersection
+ // if distance from touch point is within a reasonable distance
+ // make this the pref letter
+ // If no pref letter
+ // return inside;
+ // else return thiskey == prefletter;
+
+ for (int i = 0; i < nearby.length; i++) {
+ Key k = nearbyKeys.get(nearby[i]);
+ if (inPrefList(k.codes[0], pref)) {
+ final int dist = distanceFrom(k, x, y);
+ if (dist < (int) (k.width * OVERLAP_PERCENTAGE_HIGH_PROB)
+ && dist < mPrefDistance) {
+ mPrefLetter = k.codes[0];
+ mPrefLetterX = x;
+ mPrefLetterY = y;
+ mPrefDistance = dist;
+ }
+ }
+ }
+ // Didn't find any
+ if (mPrefLetter == 0) {
+ return inside;
+ } else {
+ return mPrefLetter == code;
+ }
+ }
+ }
+
+ // Lock into the spacebar
+ if (mCurrentlyInSpace) return false;
+
+ return key.isInsideSuper(x, y);
+ }
+
+ private boolean inPrefList(int code, int[] pref) {
+ if (code < pref.length && code >= 0) return pref[code] > 0;
+ return false;
+ }
+
+ private int distanceFrom(Key k, int x, int y) {
+ if (y > k.y && y < k.y + k.height) {
+ return Math.abs(k.x + k.width / 2 - x);
+ } else {
+ return Integer.MAX_VALUE;
+ }
+ }
+
+ @Override
+ public int[] getNearestKeys(int x, int y) {
+ if (mCurrentlyInSpace) {
+ return mSpaceKeyIndexArray;
+ } else {
+ // Avoid dead pixels at edges of the keyboard
+ return super.getNearestKeys(Math.max(0, Math.min(x, getMinWidth() - 1)),
+ Math.max(0, Math.min(y, getHeight() - 1)));
+ }
+ }
+
+ private int indexOf(int code) {
+ List<Key> keys = getKeys();
+ int count = keys.size();
+ for (int i = 0; i < count; i++) {
+ if (keys.get(i).codes[0] == code) return i;
+ }
+ return -1;
+ }
+
+ private int getTextSizeFromTheme(int style, int defValue) {
+ TypedArray array = mContext.getTheme().obtainStyledAttributes(
+ style, new int[] { android.R.attr.textSize });
+ int resId = array.getResourceId(0, 0);
+ if (resId >= array.length()) {
+ Log.i(TAG, "getTextSizeFromTheme error: resId " + resId + " > " + array.length());
+ return defValue;
+ }
+ int textSize = array.getDimensionPixelSize(resId, defValue);
+ return textSize;
+ }
+
+ // TODO LatinKey could be static class
+ class LatinKey extends Key {
+
+ // functional normal state (with properties)
+ private final int[] KEY_STATE_FUNCTIONAL_NORMAL = {
+ android.R.attr.state_single
+ };
+
+ // functional pressed state (with properties)
+ private final int[] KEY_STATE_FUNCTIONAL_PRESSED = {
+ android.R.attr.state_single,
+ android.R.attr.state_pressed
+ };
+
+ public LatinKey(Resources res, Keyboard.Row parent, int x, int y,
+ XmlResourceParser parser) {
+ super(res, parent, x, y, parser);
+ }
+
+ // sticky is used for shift key. If a key is not sticky and is modifier,
+ // the key will be treated as functional.
+ private boolean isFunctionalKey() {
+ return !sticky && modifier;
+ }
+
+ /**
+ * Overriding this method so that we can reduce the target area for certain keys.
+ */
+ @Override
+ public boolean isInside(int x, int y) {
+ // TODO This should be done by parent.isInside(this, x, y)
+ // if Key.parent were protected.
+ boolean result = LatinKeyboard.this.isInside(this, x, y);
+ return result;
+ }
+
+ boolean isInsideSuper(int x, int y) {
+ return super.isInside(x, y);
+ }
+
+ @Override
+ public int[] getCurrentDrawableState() {
+ if (isFunctionalKey()) {
+ if (pressed) {
+ return KEY_STATE_FUNCTIONAL_PRESSED;
+ } else {
+ return KEY_STATE_FUNCTIONAL_NORMAL;
+ }
+ }
+ return super.getCurrentDrawableState();
+ }
+
+ @Override
+ public int squaredDistanceFrom(int x, int y) {
+ // We should count vertical gap between rows to calculate the center of this Key.
+ final int verticalGap = LatinKeyboard.this.mVerticalGap;
+ final int xDist = this.x + width / 2 - x;
+ final int yDist = this.y + (height + verticalGap) / 2 - y;
+ return xDist * xDist + yDist * yDist;
+ }
+ }
+
+ /**
+ * Animation to be displayed on the spacebar preview popup when switching
+ * languages by swiping the spacebar. It draws the current, previous and
+ * next languages and moves them by the delta of touch movement on the spacebar.
+ */
+ class SlidingLocaleDrawable extends Drawable {
+
+ private final int mWidth;
+ private final int mHeight;
+ private final Drawable mBackground;
+ private final TextPaint mTextPaint;
+ private final int mMiddleX;
+ private final Drawable mLeftDrawable;
+ private final Drawable mRightDrawable;
+ private final int mThreshold;
+ private int mDiff;
+ private boolean mHitThreshold;
+ private String mCurrentLanguage;
+ private String mNextLanguage;
+ private String mPrevLanguage;
+
+ public SlidingLocaleDrawable(Drawable background, int width, int height) {
+ mBackground = background;
+ setDefaultBounds(mBackground);
+ mWidth = width;
+ mHeight = height;
+ mTextPaint = new TextPaint();
+ mTextPaint.setTextSize(getTextSizeFromTheme(android.R.style.TextAppearance_Medium, 18));
+ mTextPaint.setColor(R.color.latinkeyboard_transparent);
+ mTextPaint.setTextAlign(Align.CENTER);
+ mTextPaint.setAlpha(OPACITY_FULLY_OPAQUE);
+ mTextPaint.setAntiAlias(true);
+ mMiddleX = (mWidth - mBackground.getIntrinsicWidth()) / 2;
+ mLeftDrawable =
+ mRes.getDrawable(R.drawable.sym_keyboard_feedback_language_arrows_left);
+ mRightDrawable =
+ mRes.getDrawable(R.drawable.sym_keyboard_feedback_language_arrows_right);
+ mThreshold = ViewConfiguration.get(mContext).getScaledTouchSlop();
+ }
+
+ private void setDiff(int diff) {
+ if (diff == Integer.MAX_VALUE) {
+ mHitThreshold = false;
+ mCurrentLanguage = null;
+ return;
+ }
+ mDiff = diff;
+ if (mDiff > mWidth) mDiff = mWidth;
+ if (mDiff < -mWidth) mDiff = -mWidth;
+ if (Math.abs(mDiff) > mThreshold) mHitThreshold = true;
+ invalidateSelf();
+ }
+
+ private String getLanguageName(Locale locale) {
+ return LanguageSwitcher.toTitleCase(locale.getDisplayLanguage(locale));
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ canvas.save();
+ if (mHitThreshold) {
+ Paint paint = mTextPaint;
+ final int width = mWidth;
+ final int height = mHeight;
+ final int diff = mDiff;
+ final Drawable lArrow = mLeftDrawable;
+ final Drawable rArrow = mRightDrawable;
+ canvas.clipRect(0, 0, width, height);
+ if (mCurrentLanguage == null) {
+ final LanguageSwitcher languageSwitcher = mLanguageSwitcher;
+ mCurrentLanguage = getLanguageName(languageSwitcher.getInputLocale());
+ mNextLanguage = getLanguageName(languageSwitcher.getNextInputLocale());
+ mPrevLanguage = getLanguageName(languageSwitcher.getPrevInputLocale());
+ }
+ // Draw language text with shadow
+ final float baseline = mHeight * SPACEBAR_LANGUAGE_BASELINE - paint.descent();
+ paint.setColor(mRes.getColor(R.color.latinkeyboard_feedback_language_text));
+ canvas.drawText(mCurrentLanguage, width / 2 + diff, baseline, paint);
+ canvas.drawText(mNextLanguage, diff - width / 2, baseline, paint);
+ canvas.drawText(mPrevLanguage, diff + width + width / 2, baseline, paint);
+
+ setDefaultBounds(lArrow);
+ rArrow.setBounds(width - rArrow.getIntrinsicWidth(), 0, width,
+ rArrow.getIntrinsicHeight());
+ lArrow.draw(canvas);
+ rArrow.draw(canvas);
+ }
+ if (mBackground != null) {
+ canvas.translate(mMiddleX, 0);
+ mBackground.draw(canvas);
+ }
+ canvas.restore();
+ }
+
+ @Override
+ public int getOpacity() {
+ return PixelFormat.TRANSLUCENT;
+ }
+
+ @Override
+ public void setAlpha(int alpha) {
+ // Ignore
+ }
+
+ @Override
+ public void setColorFilter(ColorFilter cf) {
+ // Ignore
+ }
+
+ @Override
+ public int getIntrinsicWidth() {
+ return mWidth;
+ }
+
+ @Override
+ public int getIntrinsicHeight() {
+ return mHeight;
+ }
+ }
+}
diff --git a/java/src/org/pocketworkstation/pckeyboard/LatinKeyboardBaseView.java b/java/src/org/pocketworkstation/pckeyboard/LatinKeyboardBaseView.java
new file mode 100644
index 0000000..6940200
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/LatinKeyboardBaseView.java
@@ -0,0 +1,1779 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.pocketworkstation.pckeyboard;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Bitmap;
+import android.graphics.BlurMaskFilter;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.ColorFilter;
+import android.graphics.Paint;
+import android.graphics.PorterDuffColorFilter;
+import android.graphics.Paint.Align;
+import android.graphics.PorterDuff;
+import android.graphics.Rect;
+import android.graphics.Region.Op;
+import android.graphics.Typeface;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.StateListDrawable;
+
+import org.pocketworkstation.pckeyboard.Keyboard.Key;
+
+import android.os.Handler;
+import android.os.Message;
+import android.os.SystemClock;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.TypedValue;
+import android.view.GestureDetector;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup.LayoutParams;
+import android.widget.PopupWindow;
+import android.widget.TextView;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.text.Normalizer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+import java.util.WeakHashMap;
+
+/**
+ * A view that renders a virtual {@link LatinKeyboard}. It handles rendering of keys and
+ * detecting key presses and touch movements.
+ *
+ * TODO: References to LatinKeyboard in this class should be replaced with ones to its base class.
+ *
+ * @attr ref R.styleable#LatinKeyboardBaseView_keyBackground
+ * @attr ref R.styleable#LatinKeyboardBaseView_keyPreviewLayout
+ * @attr ref R.styleable#LatinKeyboardBaseView_keyPreviewOffset
+ * @attr ref R.styleable#LatinKeyboardBaseView_labelTextSize
+ * @attr ref R.styleable#LatinKeyboardBaseView_keyTextSize
+ * @attr ref R.styleable#LatinKeyboardBaseView_keyTextColor
+ * @attr ref R.styleable#LatinKeyboardBaseView_verticalCorrection
+ * @attr ref R.styleable#LatinKeyboardBaseView_popupLayout
+ */
+public class LatinKeyboardBaseView extends View implements PointerTracker.UIProxy {
+ private static final String TAG = "HK/LatinKeyboardBaseView";
+ private static final boolean DEBUG = false;
+
+ public static final int NOT_A_TOUCH_COORDINATE = -1;
+
+ public interface OnKeyboardActionListener {
+
+ /**
+ * Called when the user presses a key. This is sent before the
+ * {@link #onKey} is called. For keys that repeat, this is only
+ * called once.
+ *
+ * @param primaryCode
+ * the unicode of the key being pressed. If the touch is
+ * not on a valid key, the value will be zero.
+ */
+ void onPress(int primaryCode);
+
+ /**
+ * Called when the user releases a key. This is sent after the
+ * {@link #onKey} is called. For keys that repeat, this is only
+ * called once.
+ *
+ * @param primaryCode
+ * the code of the key that was released
+ */
+ void onRelease(int primaryCode);
+
+ /**
+ * Send a key press to the listener.
+ *
+ * @param primaryCode
+ * this is the key that was pressed
+ * @param keyCodes
+ * the codes for all the possible alternative keys with
+ * the primary code being the first. If the primary key
+ * code is a single character such as an alphabet or
+ * number or symbol, the alternatives will include other
+ * characters that may be on the same key or adjacent
+ * keys. These codes are useful to correct for
+ * accidental presses of a key adjacent to the intended
+ * key.
+ * @param x
+ * x-coordinate pixel of touched event. If onKey is not called by onTouchEvent,
+ * the value should be NOT_A_TOUCH_COORDINATE.
+ * @param y
+ * y-coordinate pixel of touched event. If onKey is not called by onTouchEvent,
+ * the value should be NOT_A_TOUCH_COORDINATE.
+ */
+ void onKey(int primaryCode, int[] keyCodes, int x, int y);
+
+ /**
+ * Sends a sequence of characters to the listener.
+ *
+ * @param text
+ * the sequence of characters to be displayed.
+ */
+ void onText(CharSequence text);
+
+ /**
+ * Called when user released a finger outside any key.
+ */
+ void onCancel();
+
+ /**
+ * Called when the user quickly moves the finger from right to
+ * left.
+ */
+ boolean swipeLeft();
+
+ /**
+ * Called when the user quickly moves the finger from left to
+ * right.
+ */
+ boolean swipeRight();
+
+ /**
+ * Called when the user quickly moves the finger from up to down.
+ */
+ boolean swipeDown();
+
+ /**
+ * Called when the user quickly moves the finger from down to up.
+ */
+ boolean swipeUp();
+ }
+
+ // Timing constants
+ private final int mKeyRepeatInterval;
+
+ // Miscellaneous constants
+ /* package */ static final int NOT_A_KEY = -1;
+ private static final int NUMBER_HINT_VERTICAL_ADJUSTMENT_PIXEL = -1;
+
+ // XML attribute
+ private float mKeyTextSize;
+ private float mLabelScale = 1.0f;
+ private int mKeyTextColor;
+ private int mKeyHintColor;
+ private int mKeyCursorColor;
+ private boolean mRecolorSymbols;
+ private Typeface mKeyTextStyle = Typeface.DEFAULT;
+ private float mLabelTextSize;
+ private int mSymbolColorScheme = 0;
+ private int mShadowColor;
+ private float mShadowRadius;
+ private Drawable mKeyBackground;
+ private int mBackgroundAlpha;
+ private float mBackgroundDimAmount;
+ private float mKeyHysteresisDistance;
+ private float mVerticalCorrection;
+ protected int mPreviewOffset;
+ protected int mPreviewHeight;
+ protected int mPopupLayout;
+
+ // Main keyboard
+ private Keyboard mKeyboard;
+ private Key[] mKeys;
+ // TODO this attribute should be gotten from Keyboard.
+ private int mKeyboardVerticalGap;
+
+ // Key preview popup
+ protected TextView mPreviewText;
+ protected PopupWindow mPreviewPopup;
+ protected int mPreviewTextSizeLarge;
+ protected int[] mOffsetInWindow;
+ protected int mOldPreviewKeyIndex = NOT_A_KEY;
+ protected boolean mShowPreview = true;
+ protected boolean mShowTouchPoints = true;
+ protected int mPopupPreviewOffsetX;
+ protected int mPopupPreviewOffsetY;
+ protected int mWindowY;
+ protected int mPopupPreviewDisplayedY;
+ protected final int mDelayBeforePreview;
+ protected final int mDelayBeforeSpacePreview;
+ protected final int mDelayAfterPreview;
+
+ // Popup mini keyboard
+ protected PopupWindow mMiniKeyboardPopup;
+ protected LatinKeyboardBaseView mMiniKeyboard;
+ protected View mMiniKeyboardContainer;
+ protected View mMiniKeyboardParent;
+ protected boolean mMiniKeyboardVisible;
+ protected final WeakHashMap<Key, Keyboard> mMiniKeyboardCacheMain = new WeakHashMap<Key, Keyboard>();
+ protected final WeakHashMap<Key, Keyboard> mMiniKeyboardCacheShift = new WeakHashMap<Key, Keyboard>();
+ protected final WeakHashMap<Key, Keyboard> mMiniKeyboardCacheCaps = new WeakHashMap<Key, Keyboard>();
+ protected int mMiniKeyboardOriginX;
+ protected int mMiniKeyboardOriginY;
+ protected long mMiniKeyboardPopupTime;
+ protected int[] mWindowOffset;
+ protected final float mMiniKeyboardSlideAllowance;
+ protected int mMiniKeyboardTrackerId;
+
+ /** Listener for {@link OnKeyboardActionListener}. */
+ private OnKeyboardActionListener mKeyboardActionListener;
+
+ private final ArrayList<PointerTracker> mPointerTrackers = new ArrayList<PointerTracker>();
+ private boolean mIgnoreMove = false;
+
+ // TODO: Let the PointerTracker class manage this pointer queue
+ private final PointerQueue mPointerQueue = new PointerQueue();
+
+ private final boolean mHasDistinctMultitouch;
+ private int mOldPointerCount = 1;
+
+ protected KeyDetector mKeyDetector = new ProximityKeyDetector();
+
+ // Swipe gesture detector
+ private GestureDetector mGestureDetector;
+ private final SwipeTracker mSwipeTracker = new SwipeTracker();
+ private final int mSwipeThreshold;
+ private final boolean mDisambiguateSwipe;
+
+ // Drawing
+ /** Whether the keyboard bitmap needs to be redrawn before it's blitted. **/
+ private boolean mDrawPending;
+ /** The dirty region in the keyboard bitmap */
+ private final Rect mDirtyRect = new Rect();
+ /** The keyboard bitmap for faster updates */
+ private Bitmap mBuffer;
+ /** Notes if the keyboard just changed, so that we could possibly reallocate the mBuffer. */
+ private boolean mKeyboardChanged;
+ private Key mInvalidatedKey;
+ /** The canvas for the above mutable keyboard bitmap */
+ private Canvas mCanvas;
+ private final Paint mPaint;
+ private final Paint mPaintHint;
+ private final Rect mPadding;
+ private final Rect mClipRegion = new Rect(0, 0, 0, 0);
+ private int mViewWidth;
+ // This map caches key label text height in pixel as value and key label text size as map key.
+ private final HashMap<Integer, Integer> mTextHeightCache = new HashMap<Integer, Integer>();
+ // Distance from horizontal center of the key, proportional to key label text height.
+ private final float KEY_LABEL_VERTICAL_ADJUSTMENT_FACTOR = 0.55f;
+ private final String KEY_LABEL_HEIGHT_REFERENCE_CHAR = "H";
+ /* package */ static Method sSetRenderMode;
+ private static int sPrevRenderMode = -1;
+
+ private final UIHandler mHandler = new UIHandler();
+
+ class UIHandler extends Handler {
+ private static final int MSG_POPUP_PREVIEW = 1;
+ private static final int MSG_DISMISS_PREVIEW = 2;
+ private static final int MSG_REPEAT_KEY = 3;
+ private static final int MSG_LONGPRESS_KEY = 4;
+
+ private boolean mInKeyRepeat;
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_POPUP_PREVIEW:
+ showKey(msg.arg1, (PointerTracker)msg.obj);
+ break;
+ case MSG_DISMISS_PREVIEW:
+ mPreviewPopup.dismiss();
+ break;
+ case MSG_REPEAT_KEY: {
+ final PointerTracker tracker = (PointerTracker)msg.obj;
+ tracker.repeatKey(msg.arg1);
+ startKeyRepeatTimer(mKeyRepeatInterval, msg.arg1, tracker);
+ break;
+ }
+ case MSG_LONGPRESS_KEY: {
+ final PointerTracker tracker = (PointerTracker)msg.obj;
+ openPopupIfRequired(msg.arg1, tracker);
+ break;
+ }
+ }
+ }
+
+ public void popupPreview(long delay, int keyIndex, PointerTracker tracker) {
+ removeMessages(MSG_POPUP_PREVIEW);
+ if (mPreviewPopup.isShowing() && mPreviewText.getVisibility() == VISIBLE) {
+ // Show right away, if it's already visible and finger is moving around
+ showKey(keyIndex, tracker);
+ } else {
+ sendMessageDelayed(obtainMessage(MSG_POPUP_PREVIEW, keyIndex, 0, tracker),
+ delay);
+ }
+ }
+
+ public void cancelPopupPreview() {
+ removeMessages(MSG_POPUP_PREVIEW);
+ }
+
+ public void dismissPreview(long delay) {
+ if (mPreviewPopup.isShowing()) {
+ sendMessageDelayed(obtainMessage(MSG_DISMISS_PREVIEW), delay);
+ }
+ }
+
+ public void cancelDismissPreview() {
+ removeMessages(MSG_DISMISS_PREVIEW);
+ }
+
+ public void startKeyRepeatTimer(long delay, int keyIndex, PointerTracker tracker) {
+ mInKeyRepeat = true;
+ sendMessageDelayed(obtainMessage(MSG_REPEAT_KEY, keyIndex, 0, tracker), delay);
+ }
+
+ public void cancelKeyRepeatTimer() {
+ mInKeyRepeat = false;
+ removeMessages(MSG_REPEAT_KEY);
+ }
+
+ public boolean isInKeyRepeat() {
+ return mInKeyRepeat;
+ }
+
+ public void startLongPressTimer(long delay, int keyIndex, PointerTracker tracker) {
+ removeMessages(MSG_LONGPRESS_KEY);
+ sendMessageDelayed(obtainMessage(MSG_LONGPRESS_KEY, keyIndex, 0, tracker), delay);
+ }
+
+ public void cancelLongPressTimer() {
+ removeMessages(MSG_LONGPRESS_KEY);
+ }
+
+ public void cancelKeyTimers() {
+ cancelKeyRepeatTimer();
+ cancelLongPressTimer();
+ }
+
+ public void cancelAllMessages() {
+ cancelKeyTimers();
+ cancelPopupPreview();
+ cancelDismissPreview();
+ }
+ }
+
+ static class PointerQueue {
+ private LinkedList<PointerTracker> mQueue = new LinkedList<PointerTracker>();
+
+ public void add(PointerTracker tracker) {
+ mQueue.add(tracker);
+ }
+
+ public int lastIndexOf(PointerTracker tracker) {
+ LinkedList<PointerTracker> queue = mQueue;
+ for (int index = queue.size() - 1; index >= 0; index--) {
+ PointerTracker t = queue.get(index);
+ if (t == tracker)
+ return index;
+ }
+ return -1;
+ }
+
+ public void releaseAllPointersOlderThan(PointerTracker tracker, long eventTime) {
+ LinkedList<PointerTracker> queue = mQueue;
+ int oldestPos = 0;
+ for (PointerTracker t = queue.get(oldestPos); t != tracker; t = queue.get(oldestPos)) {
+ if (t.isModifier()) {
+ oldestPos++;
+ } else {
+ t.onUpEvent(t.getLastX(), t.getLastY(), eventTime);
+ t.setAlreadyProcessed();
+ queue.remove(oldestPos);
+ }
+ }
+ }
+
+ public void releaseAllPointersExcept(PointerTracker tracker, long eventTime) {
+ for (PointerTracker t : mQueue) {
+ if (t == tracker)
+ continue;
+ t.onUpEvent(t.getLastX(), t.getLastY(), eventTime);
+ t.setAlreadyProcessed();
+ }
+ mQueue.clear();
+ if (tracker != null)
+ mQueue.add(tracker);
+ }
+
+ public void remove(PointerTracker tracker) {
+ mQueue.remove(tracker);
+ }
+
+ public boolean isInSlidingKeyInput() {
+ for (final PointerTracker tracker : mQueue) {
+ if (tracker.isInSlidingKeyInput())
+ return true;
+ }
+ return false;
+ }
+ }
+
+ static {
+ initCompatibility();
+ }
+
+ static void initCompatibility() {
+ try {
+ sSetRenderMode = View.class.getMethod("setLayerType", int.class, Paint.class);
+ Log.i(TAG, "setRenderMode is supported");
+ } catch (SecurityException e) {
+ Log.w(TAG, "unexpected SecurityException", e);
+ } catch (NoSuchMethodException e) {
+ // ignore, not supported by API level pre-Honeycomb
+ Log.i(TAG, "ignoring render mode, not supported");
+ }
+ }
+
+ private void setRenderModeIfPossible(int mode) {
+ if (sSetRenderMode != null && mode != sPrevRenderMode) {
+ try {
+ sSetRenderMode.invoke(this, mode, null);
+ sPrevRenderMode = mode;
+ Log.i(TAG, "render mode set to " + LatinIME.sKeyboardSettings.renderMode);
+ } catch (IllegalArgumentException e) {
+ e.printStackTrace();
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ } catch (InvocationTargetException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public LatinKeyboardBaseView(Context context, AttributeSet attrs) {
+ this(context, attrs, R.attr.keyboardViewStyle);
+ }
+
+ public LatinKeyboardBaseView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+
+ Log.i(TAG, "Creating new LatinKeyboardBaseView " + this);
+ setRenderModeIfPossible(LatinIME.sKeyboardSettings.renderMode);
+
+ TypedArray a = context.obtainStyledAttributes(
+ attrs, R.styleable.LatinKeyboardBaseView, defStyle, R.style.LatinKeyboardBaseView);
+
+ int n = a.getIndexCount();
+ for (int i = 0; i < n; i++) {
+ int attr = a.getIndex(i);
+
+ switch (attr) {
+ case R.styleable.LatinKeyboardBaseView_keyBackground:
+ mKeyBackground = a.getDrawable(attr);
+ break;
+ case R.styleable.LatinKeyboardBaseView_keyHysteresisDistance:
+ mKeyHysteresisDistance = a.getDimensionPixelOffset(attr, 0);
+ break;
+ case R.styleable.LatinKeyboardBaseView_verticalCorrection:
+ mVerticalCorrection = a.getDimensionPixelOffset(attr, 0);
+ break;
+ case R.styleable.LatinKeyboardBaseView_keyTextSize:
+ mKeyTextSize = a.getDimensionPixelSize(attr, 18);
+ break;
+ case R.styleable.LatinKeyboardBaseView_keyTextColor:
+ mKeyTextColor = a.getColor(attr, 0xFF000000);
+ break;
+ case R.styleable.LatinKeyboardBaseView_keyHintColor:
+ mKeyHintColor = a.getColor(attr, 0xFFBBBBBB);
+ break;
+ case R.styleable.LatinKeyboardBaseView_keyCursorColor:
+ mKeyCursorColor = a.getColor(attr, 0xFF000000);
+ break;
+ case R.styleable.LatinKeyboardBaseView_recolorSymbols:
+ mRecolorSymbols = a.getBoolean(attr, false);
+ break;
+ case R.styleable.LatinKeyboardBaseView_labelTextSize:
+ mLabelTextSize = a.getDimensionPixelSize(attr, 14);
+ break;
+ case R.styleable.LatinKeyboardBaseView_shadowColor:
+ mShadowColor = a.getColor(attr, 0);
+ break;
+ case R.styleable.LatinKeyboardBaseView_shadowRadius:
+ mShadowRadius = a.getFloat(attr, 0f);
+ break;
+ // TODO: Use Theme (android.R.styleable.Theme_backgroundDimAmount)
+ case R.styleable.LatinKeyboardBaseView_backgroundDimAmount:
+ mBackgroundDimAmount = a.getFloat(attr, 0.5f);
+ break;
+ case R.styleable.LatinKeyboardBaseView_backgroundAlpha:
+ mBackgroundAlpha = a.getInteger(attr, 255);
+ break;
+ //case android.R.styleable.
+ case R.styleable.LatinKeyboardBaseView_keyTextStyle:
+ int textStyle = a.getInt(attr, 0);
+ switch (textStyle) {
+ case 0:
+ mKeyTextStyle = Typeface.DEFAULT;
+ break;
+ case 1:
+ mKeyTextStyle = Typeface.DEFAULT_BOLD;
+ break;
+ default:
+ mKeyTextStyle = Typeface.defaultFromStyle(textStyle);
+ break;
+ }
+ break;
+ case R.styleable.LatinKeyboardBaseView_symbolColorScheme:
+ mSymbolColorScheme = a.getInt(attr, 0);
+ break;
+ }
+ }
+
+ final Resources res = getResources();
+
+ mShowPreview = false;
+ mDelayBeforePreview = res.getInteger(R.integer.config_delay_before_preview);
+ mDelayBeforeSpacePreview = res.getInteger(R.integer.config_delay_before_space_preview);
+ mDelayAfterPreview = res.getInteger(R.integer.config_delay_after_preview);
+
+ mPopupLayout = 0;
+
+ mPaint = new Paint();
+ mPaint.setAntiAlias(true);
+ mPaint.setTextAlign(Align.CENTER);
+ mPaint.setAlpha(255);
+
+ mPaintHint = new Paint();
+ mPaintHint.setAntiAlias(true);
+ mPaintHint.setTextAlign(Align.RIGHT);
+ mPaintHint.setAlpha(255);
+ mPaintHint.setTypeface(Typeface.DEFAULT_BOLD);
+
+ mPadding = new Rect(0, 0, 0, 0);
+ mKeyBackground.getPadding(mPadding);
+
+ mSwipeThreshold = (int) (300 * res.getDisplayMetrics().density);
+ // TODO: Refer frameworks/base/core/res/res/values/config.xml
+ // TODO(klausw): turn off mDisambiguateSwipe if no swipe actions are set?
+ mDisambiguateSwipe = res.getBoolean(R.bool.config_swipeDisambiguation);
+ mMiniKeyboardSlideAllowance = res.getDimension(R.dimen.mini_keyboard_slide_allowance);
+
+ GestureDetector.SimpleOnGestureListener listener =
+ new GestureDetector.SimpleOnGestureListener() {
+ @Override
+ public boolean onFling(MotionEvent me1, MotionEvent me2, float velocityX,
+ float velocityY) {
+ final float absX = Math.abs(velocityX);
+ final float absY = Math.abs(velocityY);
+ float deltaX = me2.getX() - me1.getX();
+ float deltaY = me2.getY() - me1.getY();
+ mSwipeTracker.computeCurrentVelocity(1000);
+ final float endingVelocityX = mSwipeTracker.getXVelocity();
+ final float endingVelocityY = mSwipeTracker.getYVelocity();
+ // Calculate swipe distance threshold based on screen width & height,
+ // taking the smaller distance.
+ int travelX = getWidth() / 3;
+ int travelY = getHeight() / 3;
+ int travelMin = Math.min(travelX, travelY);
+// Log.i(TAG, "onFling vX=" + velocityX + " vY=" + velocityY + " threshold=" + mSwipeThreshold
+// + " dX=" + deltaX + " dy=" + deltaY + " min=" + travelMin);
+ if (velocityX > mSwipeThreshold && absY < absX && deltaX > travelMin) {
+ if (mDisambiguateSwipe && endingVelocityX >= velocityX / 4) {
+ if (swipeRight()) return true;
+ }
+ } else if (velocityX < -mSwipeThreshold && absY < absX && deltaX < -travelMin) {
+ if (mDisambiguateSwipe && endingVelocityX <= velocityX / 4) {
+ if (swipeLeft()) return true;
+ }
+ } else if (velocityY < -mSwipeThreshold && absX < absY && deltaY < -travelMin) {
+ if (mDisambiguateSwipe && endingVelocityY <= velocityY / 4) {
+ if (swipeUp()) return true;
+ }
+ } else if (velocityY > mSwipeThreshold && absX < absY / 2 && deltaY > travelMin) {
+ if (mDisambiguateSwipe && endingVelocityY >= velocityY / 4) {
+ if (swipeDown()) return true;
+ }
+ }
+ return false;
+ }
+ };
+
+ final boolean ignoreMultitouch = true;
+ mGestureDetector = new GestureDetector(getContext(), listener, null, ignoreMultitouch);
+ mGestureDetector.setIsLongpressEnabled(false);
+
+ mHasDistinctMultitouch = context.getPackageManager()
+ .hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT);
+ mKeyRepeatInterval = res.getInteger(R.integer.config_key_repeat_interval);
+ }
+
+ private boolean showHints7Bit() {
+ return LatinIME.sKeyboardSettings.hintMode >= 1;
+ }
+
+ private boolean showHintsAll() {
+ return LatinIME.sKeyboardSettings.hintMode >= 2;
+ }
+
+ public void setOnKeyboardActionListener(OnKeyboardActionListener listener) {
+ mKeyboardActionListener = listener;
+ for (PointerTracker tracker : mPointerTrackers) {
+ tracker.setOnKeyboardActionListener(listener);
+ }
+ }
+
+ /**
+ * Returns the {@link OnKeyboardActionListener} object.
+ * @return the listener attached to this keyboard
+ */
+ protected OnKeyboardActionListener getOnKeyboardActionListener() {
+ return mKeyboardActionListener;
+ }
+
+ /**
+ * Attaches a keyboard to this view. The keyboard can be switched at any time and the
+ * view will re-layout itself to accommodate the keyboard.
+ * @see Keyboard
+ * @see #getKeyboard()
+ * @param keyboard the keyboard to display in this view
+ */
+ public void setKeyboard(Keyboard keyboard) {
+ if (mKeyboard != null) {
+ dismissKeyPreview();
+ }
+ //Log.i(TAG, "setKeyboard(" + keyboard + ") for " + this);
+ // Remove any pending messages, except dismissing preview
+ mHandler.cancelKeyTimers();
+ mHandler.cancelPopupPreview();
+ mKeyboard = keyboard;
+ LatinImeLogger.onSetKeyboard(keyboard);
+ mKeys = mKeyDetector.setKeyboard(keyboard, -getPaddingLeft(),
+ -getPaddingTop() + mVerticalCorrection);
+ mKeyboardVerticalGap = (int)getResources().getDimension(R.dimen.key_bottom_gap);
+ for (PointerTracker tracker : mPointerTrackers) {
+ tracker.setKeyboard(mKeys, mKeyHysteresisDistance);
+ }
+ mLabelScale = LatinIME.sKeyboardSettings.labelScalePref;
+ if (keyboard.mLayoutRows >= 4) mLabelScale *= 5.0f / keyboard.mLayoutRows;
+ requestLayout();
+ // Hint to reallocate the buffer if the size changed
+ mKeyboardChanged = true;
+ invalidateAllKeys();
+ computeProximityThreshold(keyboard);
+ mMiniKeyboardCacheMain.clear();
+ mMiniKeyboardCacheShift.clear();
+ mMiniKeyboardCacheCaps.clear();
+ setRenderModeIfPossible(LatinIME.sKeyboardSettings.renderMode);
+ mIgnoreMove = true;
+ }
+
+ /**
+ * Returns the current keyboard being displayed by this view.
+ * @return the currently attached keyboard
+ * @see #setKeyboard(Keyboard)
+ */
+ public Keyboard getKeyboard() {
+ return mKeyboard;
+ }
+
+ /**
+ * Return whether the device has distinct multi-touch panel.
+ * @return true if the device has distinct multi-touch panel.
+ */
+ public boolean hasDistinctMultitouch() {
+ return mHasDistinctMultitouch;
+ }
+
+ /**
+ * Sets the state of the shift key of the keyboard, if any.
+ * @param shifted whether or not to enable the state of the shift key
+ * @return true if the shift key state changed, false if there was no change
+ */
+ public boolean setShiftState(int shiftState) {
+ //Log.i(TAG, "setShifted " + shiftState);
+ if (mKeyboard != null) {
+ if (mKeyboard.setShiftState(shiftState)) {
+ // The whole keyboard probably needs to be redrawn
+ invalidateAllKeys();
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void setCtrlIndicator(boolean active) {
+ if (mKeyboard != null) {
+ invalidateKey(mKeyboard.setCtrlIndicator(active));
+ }
+ }
+
+ public void setAltIndicator(boolean active) {
+ if (mKeyboard != null) {
+ invalidateKey(mKeyboard.setAltIndicator(active));
+ }
+ }
+
+ /**
+ * Returns the state of the shift key of the keyboard, if any.
+ * @return true if the shift is in a pressed state, false otherwise. If there is
+ * no shift key on the keyboard or there is no keyboard attached, it returns false.
+ */
+ public int getShiftState() {
+ if (mKeyboard != null) {
+ return mKeyboard.getShiftState();
+ }
+ return Keyboard.SHIFT_OFF;
+ }
+
+ public boolean isShiftCaps() {
+ return getShiftState() != Keyboard.SHIFT_OFF;
+ }
+
+ public boolean isShiftAll() {
+ int state = getShiftState();
+ if (LatinIME.sKeyboardSettings.shiftLockModifiers) {
+ return state == Keyboard.SHIFT_ON || state == Keyboard.SHIFT_LOCKED;
+ } else {
+ return state == Keyboard.SHIFT_ON;
+ }
+ }
+
+ /**
+ * Enables or disables the key feedback popup. This is a popup that shows a magnified
+ * version of the depressed key. By default the preview is enabled.
+ * @param previewEnabled whether or not to enable the key feedback popup
+ * @see #isPreviewEnabled()
+ */
+ public void setPreviewEnabled(boolean previewEnabled) {
+ mShowPreview = previewEnabled;
+ }
+
+ /**
+ * Returns the enabled state of the key feedback popup.
+ * @return whether or not the key feedback popup is enabled
+ * @see #setPreviewEnabled(boolean)
+ */
+ public boolean isPreviewEnabled() {
+ return mShowPreview;
+ }
+
+ private boolean isBlackSym() {
+ return mSymbolColorScheme == 1;
+ }
+
+ public void setPopupParent(View v) {
+ mMiniKeyboardParent = v;
+ }
+
+ public void setPopupOffset(int x, int y) {
+ mPopupPreviewOffsetX = x;
+ mPopupPreviewOffsetY = y;
+ if (mPreviewPopup != null) mPreviewPopup.dismiss();
+ }
+
+ /**
+ * When enabled, calls to {@link OnKeyboardActionListener#onKey} will include key
+ * codes for adjacent keys. When disabled, only the primary key code will be
+ * reported.
+ * @param enabled whether or not the proximity correction is enabled
+ */
+ public void setProximityCorrectionEnabled(boolean enabled) {
+ mKeyDetector.setProximityCorrectionEnabled(enabled);
+ }
+
+ /**
+ * Returns true if proximity correction is enabled.
+ */
+ public boolean isProximityCorrectionEnabled() {
+ return mKeyDetector.isProximityCorrectionEnabled();
+ }
+
+ @Override
+ public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ // Round up a little
+ if (mKeyboard == null) {
+ setMeasuredDimension(
+ getPaddingLeft() + getPaddingRight(), getPaddingTop() + getPaddingBottom());
+ } else {
+ int width = mKeyboard.getMinWidth() + getPaddingLeft() + getPaddingRight();
+ if (MeasureSpec.getSize(widthMeasureSpec) < width + 10) {
+ width = MeasureSpec.getSize(widthMeasureSpec);
+ }
+ Log.i(TAG, "onMeasure width=" + width);
+ setMeasuredDimension(
+ width, mKeyboard.getHeight() + getPaddingTop() + getPaddingBottom());
+ }
+ }
+
+ /**
+ * Compute the average distance between adjacent keys (horizontally and vertically)
+ * and square it to get the proximity threshold. We use a square here and in computing
+ * the touch distance from a key's center to avoid taking a square root.
+ * @param keyboard
+ */
+ private void computeProximityThreshold(Keyboard keyboard) {
+ if (keyboard == null) return;
+ final Key[] keys = mKeys;
+ if (keys == null) return;
+ int length = keys.length;
+ int dimensionSum = 0;
+ for (int i = 0; i < length; i++) {
+ Key key = keys[i];
+ dimensionSum += Math.min(key.width, key.height + mKeyboardVerticalGap) + key.gap;
+ }
+ if (dimensionSum < 0 || length == 0) return;
+ mKeyDetector.setProximityThreshold((int) (dimensionSum * 1.4f / length));
+ }
+
+ @Override
+ public void onSizeChanged(int w, int h, int oldw, int oldh) {
+ super.onSizeChanged(w, h, oldw, oldh);
+ Log.i(TAG, "onSizeChanged, w=" + w + ", h=" + h);
+ mViewWidth = w;
+ // Release the buffer, if any and it will be reallocated on the next draw
+ mBuffer = null;
+ }
+
+ @Override
+ public void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+ //Log.i(TAG, "onDraw called " + canvas.getClipBounds());
+ mCanvas = canvas;
+ if (mDrawPending || mBuffer == null || mKeyboardChanged) {
+ onBufferDraw(canvas);
+ }
+ if (mBuffer != null) canvas.drawBitmap(mBuffer, 0, 0, null);
+ }
+
+ private void drawDeadKeyLabel(Canvas canvas, String hint, int x, float baseline, Paint paint) {
+ char c = hint.charAt(0);
+ String accent = DeadAccentSequence.getSpacing(c);
+ canvas.drawText(Keyboard.DEAD_KEY_PLACEHOLDER_STRING, x, baseline, paint);
+ canvas.drawText(accent, x, baseline, paint);
+ }
+
+ private int getLabelHeight(Paint paint, int labelSize) {
+ Integer labelHeightValue = mTextHeightCache.get(labelSize);
+ if (labelHeightValue != null) {
+ return labelHeightValue;
+ } else {
+ Rect textBounds = new Rect();
+ paint.getTextBounds(KEY_LABEL_HEIGHT_REFERENCE_CHAR, 0, 1, textBounds);
+ int labelHeight = textBounds.height();
+ mTextHeightCache.put(labelSize, labelHeight);
+ return labelHeight;
+ }
+ }
+
+ private void onBufferDraw(Canvas canvas) {
+ //Log.i(TAG, "onBufferDraw called");
+ if (/*mBuffer == null ||*/ mKeyboardChanged) {
+ mKeyboard.setKeyboardWidth(mViewWidth);
+// if (mBuffer == null || mKeyboardChanged &&
+// (mBuffer.getWidth() != getWidth() || mBuffer.getHeight() != getHeight())) {
+// // Make sure our bitmap is at least 1x1
+// final int width = Math.max(1, getWidth());
+// final int height = Math.max(1, getHeight());
+// mBuffer = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+// mCanvas = new Canvas(mBuffer);
+// }
+ invalidateAllKeys();
+ mKeyboardChanged = false;
+ }
+ //final Canvas canvas = mCanvas;
+ //canvas.clipRect(mDirtyRect, Op.REPLACE);
+ canvas.getClipBounds(mDirtyRect);
+ //canvas.drawColor(Color.BLACK);
+
+ if (mKeyboard == null) return;
+
+ final Paint paint = mPaint;
+ final Paint paintHint = mPaintHint;
+ paintHint.setColor(mKeyHintColor);
+ final Drawable keyBackground = mKeyBackground;
+ final Rect clipRegion = mClipRegion;
+ final Rect padding = mPadding;
+ final int kbdPaddingLeft = getPaddingLeft();
+ final int kbdPaddingTop = getPaddingTop();
+ final Key[] keys = mKeys;
+ final Key invalidKey = mInvalidatedKey;
+
+ ColorFilter iconColorFilter = null;
+ ColorFilter shadowColorFilter = null;
+ if (mRecolorSymbols) {
+ // TODO: cache these?
+ iconColorFilter = new PorterDuffColorFilter(
+ mKeyTextColor, PorterDuff.Mode.SRC_ATOP);
+ shadowColorFilter = new PorterDuffColorFilter(
+ mShadowColor, PorterDuff.Mode.SRC_ATOP);
+ }
+
+ boolean drawSingleKey = false;
+ if (invalidKey != null && canvas.getClipBounds(clipRegion)) {
+ // TODO we should use Rect.inset and Rect.contains here.
+ // Is clipRegion completely contained within the invalidated key?
+ if (invalidKey.x + kbdPaddingLeft - 1 <= clipRegion.left &&
+ invalidKey.y + kbdPaddingTop - 1 <= clipRegion.top &&
+ invalidKey.x + invalidKey.width + kbdPaddingLeft + 1 >= clipRegion.right &&
+ invalidKey.y + invalidKey.height + kbdPaddingTop + 1 >= clipRegion.bottom) {
+ drawSingleKey = true;
+ }
+ }
+ //canvas.drawColor(0x00000000, PorterDuff.Mode.CLEAR);
+ final int keyCount = keys.length;
+
+ int keysDrawn = 0;
+ for (int i = 0; i < keyCount; i++) {
+ final Key key = keys[i];
+ if (drawSingleKey && invalidKey != key) {
+ continue;
+ }
+ if (!mDirtyRect.intersects(
+ key.x + kbdPaddingLeft,
+ key.y + kbdPaddingTop,
+ key.x + key.width + kbdPaddingLeft,
+ key.y + key.height + kbdPaddingTop)) {
+ continue;
+ }
+ keysDrawn++;
+ paint.setColor(key.isCursor ? mKeyCursorColor : mKeyTextColor);
+
+ int[] drawableState = key.getCurrentDrawableState();
+ keyBackground.setState(drawableState);
+
+ // Switch the character to uppercase if shift is pressed
+ String label = key.getCaseLabel();
+
+ float yscale = 1.0f;
+ final Rect bounds = keyBackground.getBounds();
+ if (key.width != bounds.right || key.height != bounds.bottom) {
+ int minHeight = keyBackground.getMinimumHeight();
+ if (minHeight > key.height) {
+ yscale = (float) key.height / minHeight;
+ keyBackground.setBounds(0, 0, key.width, minHeight);
+ } else {
+ keyBackground.setBounds(0, 0, key.width, key.height);
+ }
+ }
+ canvas.translate(key.x + kbdPaddingLeft, key.y + kbdPaddingTop);
+ if (yscale != 1.0f) {
+ canvas.save();
+ canvas.scale(1.0f, yscale);
+ }
+ if (mBackgroundAlpha != 255) {
+ keyBackground.setAlpha(mBackgroundAlpha);
+ }
+ keyBackground.draw(canvas);
+ if (yscale != 1.0f) canvas.restore();
+
+ boolean shouldDrawIcon = true;
+ if (label != null) {
+ // For characters, use large font. For labels like "Done", use small font.
+ final int labelSize;
+ if (label.length() > 1 && key.codes.length < 2) {
+ //Log.i(TAG, "mLabelTextSize=" + mLabelTextSize + " LatinIME.sKeyboardSettings.labelScale=" + LatinIME.sKeyboardSettings.labelScale);
+ labelSize = (int)(mLabelTextSize * mLabelScale);
+ paint.setTypeface(Typeface.DEFAULT);
+ } else {
+ labelSize = (int)(mKeyTextSize * mLabelScale);
+ paint.setTypeface(mKeyTextStyle);
+ }
+ paint.setFakeBoldText(key.isCursor);
+ paint.setTextSize(labelSize);
+
+ final int labelHeight = getLabelHeight(paint, labelSize);
+
+ // Draw a drop shadow for the text
+ paint.setShadowLayer(mShadowRadius, 0, 0, mShadowColor);
+
+ // Draw hint label (if present) behind the main key
+ String hint = key.getHintLabel(showHints7Bit(), showHintsAll());
+ if (!hint.equals("") && !(key.isShifted() && key.shiftLabel != null && hint.charAt(0) == key.shiftLabel.charAt(0))) {
+ int hintTextSize = (int)(mKeyTextSize * 0.6 * mLabelScale);
+ paintHint.setTextSize(hintTextSize);
+
+ final int hintLabelHeight = getLabelHeight(paintHint, hintTextSize);
+ int x = key.width - padding.right;
+ int baseline = padding.top + hintLabelHeight * 12/10;
+ if (Character.getType(hint.charAt(0)) == Character.NON_SPACING_MARK) {
+ drawDeadKeyLabel(canvas, hint, x, baseline, paintHint);
+ } else {
+ canvas.drawText(hint, x, baseline, paintHint);
+ }
+ }
+
+ // Draw alternate hint label (if present) behind the main key
+ String altHint = key.getAltHintLabel(showHints7Bit(), showHintsAll());
+ if (!altHint.equals("")) {
+ int hintTextSize = (int)(mKeyTextSize * 0.6 * mLabelScale);
+ paintHint.setTextSize(hintTextSize);
+
+ final int hintLabelHeight = getLabelHeight(paintHint, hintTextSize);
+ int x = key.width - padding.right;
+ int baseline = padding.top + hintLabelHeight * (hint.equals("") ? 12 : 26)/10;
+ if (Character.getType(altHint.charAt(0)) == Character.NON_SPACING_MARK) {
+ drawDeadKeyLabel(canvas, altHint, x, baseline, paintHint);
+ } else {
+ canvas.drawText(altHint, x, baseline, paintHint);
+ }
+ }
+
+ // Draw main key label
+ final int centerX = (key.width + padding.left - padding.right) / 2;
+ final int centerY = (key.height + padding.top - padding.bottom) / 2;
+ final float baseline = centerY
+ + labelHeight * KEY_LABEL_VERTICAL_ADJUSTMENT_FACTOR;
+ if (key.isDeadKey()) {
+ drawDeadKeyLabel(canvas, label, centerX, baseline, paint);
+ } else {
+ canvas.drawText(label, centerX, baseline, paint);
+ }
+ if (key.isCursor) {
+ // poor man's bold - FIXME
+ // Turn off drop shadow
+ paint.setShadowLayer(0, 0, 0, 0);
+
+ canvas.drawText(label, centerX+0.5f, baseline, paint);
+ canvas.drawText(label, centerX-0.5f, baseline, paint);
+ canvas.drawText(label, centerX, baseline+0.5f, paint);
+ canvas.drawText(label, centerX, baseline-0.5f, paint);
+ }
+
+ // Turn off drop shadow
+ paint.setShadowLayer(0, 0, 0, 0);
+
+ // Usually don't draw icon if label is not null, but we draw icon for the number
+ // hint and popup hint.
+ shouldDrawIcon = shouldDrawLabelAndIcon(key);
+ }
+ Drawable icon = key.icon;
+ if (icon != null && shouldDrawIcon) {
+ // Special handing for the upper-right number hint icons
+ final int drawableWidth;
+ final int drawableHeight;
+ final int drawableX;
+ final int drawableY;
+ if (shouldDrawIconFully(key)) {
+ drawableWidth = key.width;
+ drawableHeight = key.height;
+ drawableX = 0;
+ drawableY = NUMBER_HINT_VERTICAL_ADJUSTMENT_PIXEL;
+ } else {
+ drawableWidth = icon.getIntrinsicWidth();
+ drawableHeight = icon.getIntrinsicHeight();
+ drawableX = (key.width + padding.left - padding.right - drawableWidth) / 2;
+ drawableY = (key.height + padding.top - padding.bottom - drawableHeight) / 2;
+ }
+ canvas.translate(drawableX, drawableY);
+ icon.setBounds(0, 0, drawableWidth, drawableHeight);
+
+ if (shadowColorFilter != null && iconColorFilter != null) {
+ // Re-color the icon to match the theme, and draw a shadow for it manually.
+ //
+ // This doesn't seem to look quite right, possibly a problem with using
+ // premultiplied icon images?
+
+ // Try EmbossMaskFilter, and/or offset? Configurable?
+ BlurMaskFilter shadowBlur = new BlurMaskFilter(mShadowRadius, BlurMaskFilter.Blur.OUTER);
+ Paint blurPaint = new Paint();
+ blurPaint.setMaskFilter(shadowBlur);
+ Bitmap tmpIcon = Bitmap.createBitmap(key.width, key.height, Bitmap.Config.ARGB_8888);
+ Canvas tmpCanvas = new Canvas(tmpIcon);
+ icon.draw(tmpCanvas);
+ int[] offsets = new int[2];
+ Bitmap shadowBitmap = tmpIcon.extractAlpha(blurPaint, offsets);
+ Paint shadowPaint = new Paint();
+ shadowPaint.setColorFilter(shadowColorFilter);
+ canvas.drawBitmap(shadowBitmap, offsets[0], offsets[1], shadowPaint);
+
+ icon.setColorFilter(iconColorFilter);
+ icon.draw(canvas);
+ icon.setColorFilter(null);
+ } else {
+ icon.draw(canvas);
+ }
+ canvas.translate(-drawableX, -drawableY);
+ }
+ canvas.translate(-key.x - kbdPaddingLeft, -key.y - kbdPaddingTop);
+ }
+ //Log.i(TAG, "keysDrawn=" + keysDrawn);
+ mInvalidatedKey = null;
+ // Overlay a dark rectangle to dim the keyboard
+ if (mMiniKeyboardVisible) {
+ paint.setColor((int) (mBackgroundDimAmount * 0xFF) << 24);
+ canvas.drawRect(0, 0, getWidth(), getHeight(), paint);
+ }
+
+ if (LatinIME.sKeyboardSettings.showTouchPos || DEBUG) {
+ if (LatinIME.sKeyboardSettings.showTouchPos || mShowTouchPoints) {
+ for (PointerTracker tracker : mPointerTrackers) {
+ int startX = tracker.getStartX();
+ int startY = tracker.getStartY();
+ int lastX = tracker.getLastX();
+ int lastY = tracker.getLastY();
+ paint.setAlpha(128);
+ paint.setColor(0xFFFF0000);
+ canvas.drawCircle(startX, startY, 3, paint);
+ canvas.drawLine(startX, startY, lastX, lastY, paint);
+ paint.setColor(0xFF0000FF);
+ canvas.drawCircle(lastX, lastY, 3, paint);
+ paint.setColor(0xFF00FF00);
+ canvas.drawCircle((startX + lastX) / 2, (startY + lastY) / 2, 2, paint);
+ }
+ }
+ }
+
+ mDrawPending = false;
+ mDirtyRect.setEmpty();
+ }
+
+ // TODO: clean up this method.
+ private void dismissKeyPreview() {
+ for (PointerTracker tracker : mPointerTrackers)
+ tracker.updateKey(NOT_A_KEY);
+ //Log.i(TAG, "dismissKeyPreview() for " + this);
+ showPreview(NOT_A_KEY, null);
+ }
+
+ public void showPreview(int keyIndex, PointerTracker tracker) {
+ int oldKeyIndex = mOldPreviewKeyIndex;
+ mOldPreviewKeyIndex = keyIndex;
+ final boolean isLanguageSwitchEnabled = (mKeyboard instanceof LatinKeyboard)
+ && ((LatinKeyboard)mKeyboard).isLanguageSwitchEnabled();
+ // We should re-draw popup preview when 1) we need to hide the preview, 2) we will show
+ // the space key preview and 3) pointer moves off the space key to other letter key, we
+ // should hide the preview of the previous key.
+ final boolean hidePreviewOrShowSpaceKeyPreview = (tracker == null)
+ || tracker.isSpaceKey(keyIndex) || tracker.isSpaceKey(oldKeyIndex);
+ // If key changed and preview is on or the key is space (language switch is enabled)
+ if (oldKeyIndex != keyIndex
+ && (mShowPreview
+ || (hidePreviewOrShowSpaceKeyPreview && isLanguageSwitchEnabled))) {
+ if (keyIndex == NOT_A_KEY) {
+ mHandler.cancelPopupPreview();
+ mHandler.dismissPreview(mDelayAfterPreview);
+ } else if (tracker != null) {
+ int delay = mShowPreview ? mDelayBeforePreview : mDelayBeforeSpacePreview;
+ mHandler.popupPreview(delay, keyIndex, tracker);
+ }
+ }
+ }
+
+ private void showKey(final int keyIndex, PointerTracker tracker) {
+ Key key = tracker.getKey(keyIndex);
+ if (key == null)
+ return;
+ //Log.i(TAG, "showKey() for " + this);
+ // Should not draw hint icon in key preview
+ Drawable icon = key.icon;
+ if (icon != null && !shouldDrawLabelAndIcon(key)) {
+ mPreviewText.setCompoundDrawables(null, null, null,
+ key.iconPreview != null ? key.iconPreview : icon);
+ mPreviewText.setText(null);
+ } else {
+ mPreviewText.setCompoundDrawables(null, null, null, null);
+ mPreviewText.setText(key.getCaseLabel());
+ if (key.label.length() > 1 && key.codes.length < 2) {
+ mPreviewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mKeyTextSize);
+ mPreviewText.setTypeface(Typeface.DEFAULT_BOLD);
+ } else {
+ mPreviewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mPreviewTextSizeLarge);
+ mPreviewText.setTypeface(mKeyTextStyle);
+ }
+ }
+ mPreviewText.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
+ MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
+ int popupWidth = Math.max(mPreviewText.getMeasuredWidth(), key.width
+ + mPreviewText.getPaddingLeft() + mPreviewText.getPaddingRight());
+ final int popupHeight = mPreviewHeight;
+ LayoutParams lp = mPreviewText.getLayoutParams();
+ if (lp != null) {
+ lp.width = popupWidth;
+ lp.height = popupHeight;
+ }
+
+ int popupPreviewX = key.x - (popupWidth - key.width) / 2;
+ int popupPreviewY = key.y - popupHeight + mPreviewOffset;
+
+ mHandler.cancelDismissPreview();
+ if (mOffsetInWindow == null) {
+ mOffsetInWindow = new int[2];
+ getLocationInWindow(mOffsetInWindow);
+ mOffsetInWindow[0] += mPopupPreviewOffsetX; // Offset may be zero
+ mOffsetInWindow[1] += mPopupPreviewOffsetY; // Offset may be zero
+ int[] windowLocation = new int[2];
+ getLocationOnScreen(windowLocation);
+ mWindowY = windowLocation[1];
+ }
+ // Set the preview background state.
+ // Retrieve and cache the popup keyboard if any.
+ boolean hasPopup = (getLongPressKeyboard(key) != null);
+ // Set background manually, the StateListDrawable doesn't work.
+ mPreviewText.setBackgroundDrawable(getResources().getDrawable(hasPopup ? R.drawable.keyboard_key_feedback_more_background : R.drawable.keyboard_key_feedback_background));
+ popupPreviewX += mOffsetInWindow[0];
+ popupPreviewY += mOffsetInWindow[1];
+
+ // If the popup cannot be shown above the key, put it on the side
+ if (popupPreviewY + mWindowY < 0) {
+ // If the key you're pressing is on the left side of the keyboard, show the popup on
+ // the right, offset by enough to see at least one key to the left/right.
+ if (key.x + key.width <= getWidth() / 2) {
+ popupPreviewX += (int) (key.width * 2.5);
+ } else {
+ popupPreviewX -= (int) (key.width * 2.5);
+ }
+ popupPreviewY += popupHeight;
+ }
+
+ if (mPreviewPopup.isShowing()) {
+ mPreviewPopup.update(popupPreviewX, popupPreviewY, popupWidth, popupHeight);
+ } else {
+ mPreviewPopup.setWidth(popupWidth);
+ mPreviewPopup.setHeight(popupHeight);
+ mPreviewPopup.showAtLocation(mMiniKeyboardParent, Gravity.NO_GRAVITY,
+ popupPreviewX, popupPreviewY);
+ }
+ // Record popup preview position to display mini-keyboard later at the same positon
+ mPopupPreviewDisplayedY = popupPreviewY;
+ mPreviewText.setVisibility(VISIBLE);
+ }
+
+ /**
+ * Requests a redraw of the entire keyboard. Calling {@link #invalidate} is not sufficient
+ * because the keyboard renders the keys to an off-screen buffer and an invalidate() only
+ * draws the cached buffer.
+ * @see #invalidateKey(Key)
+ */
+ public void invalidateAllKeys() {
+ mDirtyRect.union(0, 0, getWidth(), getHeight());
+ mDrawPending = true;
+ invalidate();
+ }
+
+ /**
+ * Invalidates a key so that it will be redrawn on the next repaint. Use this method if only
+ * one key is changing it's content. Any changes that affect the position or size of the key
+ * may not be honored.
+ * @param key key in the attached {@link Keyboard}.
+ * @see #invalidateAllKeys
+ */
+ public void invalidateKey(Key key) {
+ if (key == null)
+ return;
+ mInvalidatedKey = key;
+ // TODO we should clean up this and record key's region to use in onBufferDraw.
+ mDirtyRect.union(key.x + getPaddingLeft(), key.y + getPaddingTop(),
+ key.x + key.width + getPaddingLeft(), key.y + key.height + getPaddingTop());
+ //onBufferDraw();
+ invalidate(key.x + getPaddingLeft(), key.y + getPaddingTop(),
+ key.x + key.width + getPaddingLeft(), key.y + key.height + getPaddingTop());
+ }
+
+ private boolean openPopupIfRequired(int keyIndex, PointerTracker tracker) {
+ // Check if we have a popup layout specified first.
+ if (mPopupLayout == 0) {
+ return false;
+ }
+
+ Key popupKey = tracker.getKey(keyIndex);
+ if (popupKey == null)
+ return false;
+ if (tracker.isInSlidingKeyInput())
+ return false;
+ boolean result = onLongPress(popupKey);
+ if (result) {
+ dismissKeyPreview();
+ mMiniKeyboardTrackerId = tracker.mPointerId;
+ // Mark this tracker "already processed" and remove it from the pointer queue
+ tracker.setAlreadyProcessed();
+ mPointerQueue.remove(tracker);
+ }
+ return result;
+ }
+
+ private void inflateMiniKeyboardContainer() {
+ //Log.i(TAG, "inflateMiniKeyboardContainer(), mPopupLayout=" + mPopupLayout + " from " + this);
+ LayoutInflater inflater = (LayoutInflater)getContext().getSystemService(
+ Context.LAYOUT_INFLATER_SERVICE);
+ View container = inflater.inflate(mPopupLayout, null);
+
+ mMiniKeyboard =
+ (LatinKeyboardBaseView)container.findViewById(R.id.LatinKeyboardBaseView);
+ mMiniKeyboard.setOnKeyboardActionListener(new OnKeyboardActionListener() {
+ public void onKey(int primaryCode, int[] keyCodes, int x, int y) {
+ mKeyboardActionListener.onKey(primaryCode, keyCodes, x, y);
+ dismissPopupKeyboard();
+ }
+
+ public void onText(CharSequence text) {
+ mKeyboardActionListener.onText(text);
+ dismissPopupKeyboard();
+ }
+
+ public void onCancel() {
+ mKeyboardActionListener.onCancel();
+ dismissPopupKeyboard();
+ }
+
+ public boolean swipeLeft() {
+ return false;
+ }
+ public boolean swipeRight() {
+ return false;
+ }
+ public boolean swipeUp() {
+ return false;
+ }
+ public boolean swipeDown() {
+ return false;
+ }
+ public void onPress(int primaryCode) {
+ mKeyboardActionListener.onPress(primaryCode);
+ }
+ public void onRelease(int primaryCode) {
+ mKeyboardActionListener.onRelease(primaryCode);
+ }
+ });
+ // Override default ProximityKeyDetector.
+ mMiniKeyboard.mKeyDetector = new MiniKeyboardKeyDetector(mMiniKeyboardSlideAllowance);
+ // Remove gesture detector on mini-keyboard
+ mMiniKeyboard.mGestureDetector = null;
+
+ mMiniKeyboard.setPopupParent(this);
+
+ mMiniKeyboardContainer = container;
+ }
+
+ private static boolean isOneRowKeys(List<Key> keys) {
+ if (keys.size() == 0) return false;
+ final int edgeFlags = keys.get(0).edgeFlags;
+ // HACK: The first key of mini keyboard which was inflated from xml and has multiple rows,
+ // does not have both top and bottom edge flags on at the same time. On the other hand,
+ // the first key of mini keyboard that was created with popupCharacters must have both top
+ // and bottom edge flags on.
+ // When you want to use one row mini-keyboard from xml file, make sure that the row has
+ // both top and bottom edge flags set.
+ return (edgeFlags & Keyboard.EDGE_TOP) != 0 && (edgeFlags & Keyboard.EDGE_BOTTOM) != 0;
+ }
+
+ private Keyboard getLongPressKeyboard(Key popupKey) {
+ final WeakHashMap<Key, Keyboard> cache;
+ if (popupKey.isDistinctCaps()) {
+ cache = mMiniKeyboardCacheCaps;
+ } else if (popupKey.isShifted()) {
+ cache = mMiniKeyboardCacheShift;
+ } else {
+ cache = mMiniKeyboardCacheMain;
+ }
+ Keyboard kbd = cache.get(popupKey);
+ if (kbd == null) {
+ kbd = popupKey.getPopupKeyboard(getContext(), getPaddingLeft() + getPaddingRight());
+ if (kbd != null) cache.put(popupKey, kbd);
+ }
+ //Log.i(TAG, "getLongPressKeyboard returns " + kbd + " for " + popupKey);
+ return kbd;
+ }
+
+ /**
+ * Called when a key is long pressed. By default this will open any popup keyboard associated
+ * with this key through the attributes popupLayout and popupCharacters.
+ * @param popupKey the key that was long pressed
+ * @return true if the long press is handled, false otherwise. Subclasses should call the
+ * method on the base class if the subclass doesn't wish to handle the call.
+ */
+ protected boolean onLongPress(Key popupKey) {
+ // TODO if popupKey.popupCharacters has only one letter, send it as key without opening
+ // mini keyboard.
+
+ if (mPopupLayout == 0) return false; // No popups wanted
+
+ Keyboard kbd = getLongPressKeyboard(popupKey);
+ //Log.i(TAG, "onLongPress, kbd=" + kbd);
+ if (kbd == null) return false;
+
+ if (mMiniKeyboardContainer == null) {
+ inflateMiniKeyboardContainer();
+ }
+ if (mMiniKeyboard == null) return false;
+ mMiniKeyboard.setKeyboard(kbd);
+ mMiniKeyboardContainer.measure(MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.AT_MOST),
+ MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.AT_MOST));
+
+ if (mWindowOffset == null) {
+ mWindowOffset = new int[2];
+ getLocationInWindow(mWindowOffset);
+ }
+
+ // Get width of a key in the mini popup keyboard = "miniKeyWidth".
+ // On the other hand, "popupKey.width" is width of the pressed key on the main keyboard.
+ // We adjust the position of mini popup keyboard with the edge key in it:
+ // a) When we have the leftmost key in popup keyboard directly above the pressed key
+ // Right edges of both keys should be aligned for consistent default selection
+ // b) When we have the rightmost key in popup keyboard directly above the pressed key
+ // Left edges of both keys should be aligned for consistent default selection
+
+ final List<Key> miniKeys = mMiniKeyboard.getKeyboard().getKeys();
+ final int miniKeyWidth = miniKeys.size() > 0 ? miniKeys.get(0).width : 0;
+
+ int popupX = popupKey.x + mWindowOffset[0];
+ popupX += getPaddingLeft();
+ if (shouldAlignLeftmost(popupKey)) {
+ popupX += popupKey.width - miniKeyWidth; // adjustment for a) described above
+ popupX -= mMiniKeyboardContainer.getPaddingLeft();
+ } else {
+ popupX += miniKeyWidth; // adjustment for b) described above
+ popupX -= mMiniKeyboardContainer.getMeasuredWidth();
+ popupX += mMiniKeyboardContainer.getPaddingRight();
+ }
+ int popupY = popupKey.y + mWindowOffset[1];
+ popupY += getPaddingTop();
+ popupY -= mMiniKeyboardContainer.getMeasuredHeight();
+ popupY += mMiniKeyboardContainer.getPaddingBottom();
+ final int x = popupX;
+ final int y = mShowPreview && isOneRowKeys(miniKeys) ? mPopupPreviewDisplayedY : popupY;
+
+ int adjustedX = x;
+ if (x < 0) {
+ adjustedX = 0;
+ } else if (x > (getMeasuredWidth() - mMiniKeyboardContainer.getMeasuredWidth())) {
+ adjustedX = getMeasuredWidth() - mMiniKeyboardContainer.getMeasuredWidth();
+ }
+ mMiniKeyboardOriginX = adjustedX + mMiniKeyboardContainer.getPaddingLeft() - mWindowOffset[0];
+ mMiniKeyboardOriginY = y + mMiniKeyboardContainer.getPaddingTop() - mWindowOffset[1];
+ mMiniKeyboard.setPopupOffset(adjustedX, y);
+ mMiniKeyboard.setShiftState(getShiftState());
+ // Mini keyboard needs no pop-up key preview displayed.
+ mMiniKeyboard.setPreviewEnabled(false);
+ mMiniKeyboardPopup.setContentView(mMiniKeyboardContainer);
+ mMiniKeyboardPopup.setWidth(mMiniKeyboardContainer.getMeasuredWidth());
+ mMiniKeyboardPopup.setHeight(mMiniKeyboardContainer.getMeasuredHeight());
+ //Log.i(TAG, "About to show popup " + mMiniKeyboardPopup + " from " + this);
+ mMiniKeyboardPopup.showAtLocation(this, Gravity.NO_GRAVITY, x, y);
+ mMiniKeyboardVisible = true;
+
+ // Inject down event on the key to mini keyboard.
+ long eventTime = SystemClock.uptimeMillis();
+ mMiniKeyboardPopupTime = eventTime;
+ MotionEvent downEvent = generateMiniKeyboardMotionEvent(MotionEvent.ACTION_DOWN, popupKey.x
+ + popupKey.width / 2, popupKey.y + popupKey.height / 2, eventTime);
+ mMiniKeyboard.onTouchEvent(downEvent);
+ downEvent.recycle();
+
+ invalidateAllKeys();
+ return true;
+ }
+
+ private boolean shouldDrawIconFully(Key key) {
+ return isNumberAtEdgeOfPopupChars(key) || isLatinF1Key(key)
+ || LatinKeyboard.hasPuncOrSmileysPopup(key);
+ }
+
+ private boolean shouldDrawLabelAndIcon(Key key) {
+ // isNumberAtEdgeOfPopupChars(key) ||
+ return isNonMicLatinF1Key(key)
+ || LatinKeyboard.hasPuncOrSmileysPopup(key);
+ }
+
+ private boolean shouldAlignLeftmost(Key key) {
+ return !key.popupReversed;
+ }
+
+ private boolean isLatinF1Key(Key key) {
+ return (mKeyboard instanceof LatinKeyboard) && ((LatinKeyboard)mKeyboard).isF1Key(key);
+ }
+
+ private boolean isNonMicLatinF1Key(Key key) {
+ return isLatinF1Key(key) && key.label != null;
+ }
+
+ private static boolean isNumberAtEdgeOfPopupChars(Key key) {
+ return isNumberAtLeftmostPopupChar(key) || isNumberAtRightmostPopupChar(key);
+ }
+
+ /* package */ static boolean isNumberAtLeftmostPopupChar(Key key) {
+ if (key.popupCharacters != null && key.popupCharacters.length() > 0
+ && isAsciiDigit(key.popupCharacters.charAt(0))) {
+ return true;
+ }
+ return false;
+ }
+
+ /* package */ static boolean isNumberAtRightmostPopupChar(Key key) {
+ if (key.popupCharacters != null && key.popupCharacters.length() > 0
+ && isAsciiDigit(key.popupCharacters.charAt(key.popupCharacters.length() - 1))) {
+ return true;
+ }
+ return false;
+ }
+
+ private static boolean isAsciiDigit(char c) {
+ return (c < 0x80) && Character.isDigit(c);
+ }
+
+ private MotionEvent generateMiniKeyboardMotionEvent(int action, int x, int y, long eventTime) {
+ return MotionEvent.obtain(mMiniKeyboardPopupTime, eventTime, action,
+ x - mMiniKeyboardOriginX, y - mMiniKeyboardOriginY, 0);
+ }
+
+ /*package*/ boolean enableSlideKeyHack() {
+ return false;
+ }
+
+ private PointerTracker getPointerTracker(final int id) {
+ final ArrayList<PointerTracker> pointers = mPointerTrackers;
+ final Key[] keys = mKeys;
+ final OnKeyboardActionListener listener = mKeyboardActionListener;
+
+ // Create pointer trackers until we can get 'id+1'-th tracker, if needed.
+ for (int i = pointers.size(); i <= id; i++) {
+ final PointerTracker tracker =
+ new PointerTracker(i, mHandler, mKeyDetector, this, getResources(), enableSlideKeyHack());
+ if (keys != null)
+ tracker.setKeyboard(keys, mKeyHysteresisDistance);
+ if (listener != null)
+ tracker.setOnKeyboardActionListener(listener);
+ pointers.add(tracker);
+ }
+
+ return pointers.get(id);
+ }
+
+ public boolean isInSlidingKeyInput() {
+ if (mMiniKeyboardVisible) {
+ return mMiniKeyboard.isInSlidingKeyInput();
+ } else {
+ return mPointerQueue.isInSlidingKeyInput();
+ }
+ }
+
+ public int getPointerCount() {
+ return mOldPointerCount;
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent me) {
+ return onTouchEvent(me, false);
+ }
+
+ public boolean onTouchEvent(MotionEvent me, boolean continuing) {
+ final int action = me.getActionMasked();
+ final int pointerCount = me.getPointerCount();
+ final int oldPointerCount = mOldPointerCount;
+ mOldPointerCount = pointerCount;
+
+ // TODO: cleanup this code into a multi-touch to single-touch event converter class?
+ // If the device does not have distinct multi-touch support panel, ignore all multi-touch
+ // events except a transition from/to single-touch.
+ if (!mHasDistinctMultitouch && pointerCount > 1 && oldPointerCount > 1) {
+ return true;
+ }
+
+ // Track the last few movements to look for spurious swipes.
+ mSwipeTracker.addMovement(me);
+
+ // Gesture detector must be enabled only when mini-keyboard is not on the screen.
+ if (!mMiniKeyboardVisible
+ && mGestureDetector != null && mGestureDetector.onTouchEvent(me)) {
+ dismissKeyPreview();
+ mHandler.cancelKeyTimers();
+ return true;
+ }
+
+ final long eventTime = me.getEventTime();
+ final int index = me.getActionIndex();
+ final int id = me.getPointerId(index);
+ final int x = (int)me.getX(index);
+ final int y = (int)me.getY(index);
+
+ // Needs to be called after the gesture detector gets a turn, as it may have
+ // displayed the mini keyboard
+ if (mMiniKeyboardVisible) {
+ final int miniKeyboardPointerIndex = me.findPointerIndex(mMiniKeyboardTrackerId);
+ if (miniKeyboardPointerIndex >= 0 && miniKeyboardPointerIndex < pointerCount) {
+ final int miniKeyboardX = (int)me.getX(miniKeyboardPointerIndex);
+ final int miniKeyboardY = (int)me.getY(miniKeyboardPointerIndex);
+ MotionEvent translated = generateMiniKeyboardMotionEvent(action,
+ miniKeyboardX, miniKeyboardY, eventTime);
+ mMiniKeyboard.onTouchEvent(translated);
+ translated.recycle();
+ }
+ return true;
+ }
+
+ if (mHandler.isInKeyRepeat()) {
+ // It will keep being in the key repeating mode while the key is being pressed.
+ if (action == MotionEvent.ACTION_MOVE) {
+ return true;
+ }
+ final PointerTracker tracker = getPointerTracker(id);
+ // Key repeating timer will be canceled if 2 or more keys are in action, and current
+ // event (UP or DOWN) is non-modifier key.
+ if (pointerCount > 1 && !tracker.isModifier()) {
+ mHandler.cancelKeyRepeatTimer();
+ }
+ // Up event will pass through.
+ }
+
+ // TODO: cleanup this code into a multi-touch to single-touch event converter class?
+ // Translate mutli-touch event to single-touch events on the device that has no distinct
+ // multi-touch panel.
+ if (!mHasDistinctMultitouch) {
+ // Use only main (id=0) pointer tracker.
+ PointerTracker tracker = getPointerTracker(0);
+ if (pointerCount == 1 && oldPointerCount == 2) {
+ // Multi-touch to single touch transition.
+ // Send a down event for the latest pointer.
+ tracker.onDownEvent(x, y, eventTime);
+ } else if (pointerCount == 2 && oldPointerCount == 1) {
+ // Single-touch to multi-touch transition.
+ // Send an up event for the last pointer.
+ tracker.onUpEvent(tracker.getLastX(), tracker.getLastY(), eventTime);
+ } else if (pointerCount == 1 && oldPointerCount == 1) {
+ tracker.onTouchEvent(action, x, y, eventTime);
+ } else {
+ Log.w(TAG, "Unknown touch panel behavior: pointer count is " + pointerCount
+ + " (old " + oldPointerCount + ")");
+ }
+ if (continuing)
+ tracker.setSlidingKeyInputState(true);
+ return true;
+ }
+
+ if (action == MotionEvent.ACTION_MOVE) {
+ if (!mIgnoreMove) {
+ for (int i = 0; i < pointerCount; i++) {
+ PointerTracker tracker = getPointerTracker(me.getPointerId(i));
+ tracker.onMoveEvent((int)me.getX(i), (int)me.getY(i), eventTime);
+ }
+ }
+ } else {
+ PointerTracker tracker = getPointerTracker(id);
+ switch (action) {
+ case MotionEvent.ACTION_DOWN:
+ case MotionEvent.ACTION_POINTER_DOWN:
+ mIgnoreMove = false;
+ onDownEvent(tracker, x, y, eventTime);
+ break;
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_POINTER_UP:
+ mIgnoreMove = false;
+ onUpEvent(tracker, x, y, eventTime);
+ break;
+ case MotionEvent.ACTION_CANCEL:
+ onCancelEvent(tracker, x, y, eventTime);
+ break;
+ }
+ if (continuing)
+ tracker.setSlidingKeyInputState(true);
+ }
+
+ return true;
+ }
+
+ private void onDownEvent(PointerTracker tracker, int x, int y, long eventTime) {
+ if (tracker.isOnModifierKey(x, y)) {
+ // Before processing a down event of modifier key, all pointers already being tracked
+ // should be released.
+ mPointerQueue.releaseAllPointersExcept(null, eventTime);
+ }
+ tracker.onDownEvent(x, y, eventTime);
+ mPointerQueue.add(tracker);
+ }
+
+ private void onUpEvent(PointerTracker tracker, int x, int y, long eventTime) {
+ if (tracker.isModifier()) {
+ // Before processing an up event of modifier key, all pointers already being tracked
+ // should be released.
+ mPointerQueue.releaseAllPointersExcept(tracker, eventTime);
+ } else {
+ int index = mPointerQueue.lastIndexOf(tracker);
+ if (index >= 0) {
+ mPointerQueue.releaseAllPointersOlderThan(tracker, eventTime);
+ } else {
+ Log.w(TAG, "onUpEvent: corresponding down event not found for pointer "
+ + tracker.mPointerId);
+ }
+ }
+ tracker.onUpEvent(x, y, eventTime);
+ mPointerQueue.remove(tracker);
+ }
+
+ private void onCancelEvent(PointerTracker tracker, int x, int y, long eventTime) {
+ tracker.onCancelEvent(x, y, eventTime);
+ mPointerQueue.remove(tracker);
+ }
+
+ protected boolean swipeRight() {
+ return mKeyboardActionListener.swipeRight();
+ }
+
+ protected boolean swipeLeft() {
+ return mKeyboardActionListener.swipeLeft();
+ }
+
+ /*package*/ boolean swipeUp() {
+ return mKeyboardActionListener.swipeUp();
+ }
+
+ protected boolean swipeDown() {
+ return mKeyboardActionListener.swipeDown();
+ }
+
+ public void closing() {
+ Log.i(TAG, "closing " + this);
+ if (mPreviewPopup != null) mPreviewPopup.dismiss();
+ mHandler.cancelAllMessages();
+
+ dismissPopupKeyboard();
+ //mMiniKeyboardContainer = null; // TODO: destroy/recycle the views?
+ //mMiniKeyboard = null;
+
+ // TODO(klausw): use a global bitmap repository, keeping two bitmaps permanently -
+ // one for main and one for popup.
+ //
+ // Allow having the backup bitmap be bigger than the canvas needed, only shrinking in rare cases -
+ // for example if reducing the size of the main keyboard.
+ //mBuffer = null;
+ //mCanvas = null;
+ mMiniKeyboardCacheMain.clear();
+ mMiniKeyboardCacheShift.clear();
+ mMiniKeyboardCacheCaps.clear();
+ }
+
+ @Override
+ public void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ //Log.i(TAG, "onDetachedFromWindow() for " + this);
+ closing();
+ }
+
+ protected boolean popupKeyboardIsShowing() {
+ return mMiniKeyboardPopup != null && mMiniKeyboardPopup.isShowing();
+ }
+
+ protected void dismissPopupKeyboard() {
+ if (mMiniKeyboardPopup != null) {
+ //Log.i(TAG, "dismissPopupKeyboard() " + mMiniKeyboardPopup + " showing=" + mMiniKeyboardPopup.isShowing());
+ if (mMiniKeyboardPopup.isShowing()) {
+ mMiniKeyboardPopup.dismiss();
+ }
+ mMiniKeyboardVisible = false;
+ invalidateAllKeys();
+ }
+ }
+
+ public boolean handleBack() {
+ if (mMiniKeyboardPopup != null && mMiniKeyboardPopup.isShowing()) {
+ dismissPopupKeyboard();
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/java/src/org/pocketworkstation/pckeyboard/LatinKeyboardView.java b/java/src/org/pocketworkstation/pckeyboard/LatinKeyboardView.java
new file mode 100644
index 0000000..26f71ce
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/LatinKeyboardView.java
@@ -0,0 +1,650 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.pocketworkstation.pckeyboard;
+
+import java.util.List;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import org.pocketworkstation.pckeyboard.Keyboard.Key;
+
+import android.os.Handler;
+import android.os.Message;
+import android.os.SystemClock;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.widget.PopupWindow;
+import android.widget.TextView;
+
+public class LatinKeyboardView extends LatinKeyboardBaseView {
+ static final String TAG = "HK/LatinKeyboardView";
+
+ // The keycode list needs to stay in sync with the
+ // res/values/keycodes.xml file.
+
+ // FIXME: The following keycodes should really be renumbered
+ // since they conflict with existing KeyEvent keycodes.
+ static final int KEYCODE_OPTIONS = -100;
+ static final int KEYCODE_OPTIONS_LONGPRESS = -101;
+ static final int KEYCODE_VOICE = -102;
+ static final int KEYCODE_F1 = -103;
+ static final int KEYCODE_NEXT_LANGUAGE = -104;
+ static final int KEYCODE_PREV_LANGUAGE = -105;
+ static final int KEYCODE_COMPOSE = -10024;
+
+ // The following keycodes match (negative) KeyEvent keycodes.
+ // Would be better to use the real KeyEvent values, but many
+ // don't exist prior to the Honeycomb API (level 11).
+ static final int KEYCODE_DPAD_UP = -19;
+ static final int KEYCODE_DPAD_DOWN = -20;
+ static final int KEYCODE_DPAD_LEFT = -21;
+ static final int KEYCODE_DPAD_RIGHT = -22;
+ static final int KEYCODE_DPAD_CENTER = -23;
+ static final int KEYCODE_ALT_LEFT = -57;
+ static final int KEYCODE_PAGE_UP = -92;
+ static final int KEYCODE_PAGE_DOWN = -93;
+ static final int KEYCODE_ESCAPE = -111;
+ static final int KEYCODE_FORWARD_DEL = -112;
+ static final int KEYCODE_CTRL_LEFT = -113;
+ static final int KEYCODE_CAPS_LOCK = -115;
+ static final int KEYCODE_SCROLL_LOCK = -116;
+ static final int KEYCODE_FN = -119;
+ static final int KEYCODE_SYSRQ = -120;
+ static final int KEYCODE_BREAK = -121;
+ static final int KEYCODE_HOME = -122;
+ static final int KEYCODE_END = -123;
+ static final int KEYCODE_INSERT = -124;
+ static final int KEYCODE_FKEY_F1 = -131;
+ static final int KEYCODE_FKEY_F2 = -132;
+ static final int KEYCODE_FKEY_F3 = -133;
+ static final int KEYCODE_FKEY_F4 = -134;
+ static final int KEYCODE_FKEY_F5 = -135;
+ static final int KEYCODE_FKEY_F6 = -136;
+ static final int KEYCODE_FKEY_F7 = -137;
+ static final int KEYCODE_FKEY_F8 = -138;
+ static final int KEYCODE_FKEY_F9 = -139;
+ static final int KEYCODE_FKEY_F10 = -140;
+ static final int KEYCODE_FKEY_F11 = -141;
+ static final int KEYCODE_FKEY_F12 = -142;
+ static final int KEYCODE_NUM_LOCK = -143;
+
+ private Keyboard mPhoneKeyboard;
+
+ /** Whether the extension of this keyboard is visible */
+ private boolean mExtensionVisible;
+ /** The view that is shown as an extension of this keyboard view */
+ private LatinKeyboardView mExtension;
+ /** The popup window that contains the extension of this keyboard */
+ private PopupWindow mExtensionPopup;
+ /** Whether this view is an extension of another keyboard */
+ private boolean mIsExtensionType;
+ private boolean mFirstEvent;
+
+ /** Whether we've started dropping move events because we found a big jump */
+ private boolean mDroppingEvents;
+ /**
+ * Whether multi-touch disambiguation needs to be disabled for any reason. There are 2 reasons
+ * for this to happen - (1) if a real multi-touch event has occured and (2) we've opened an
+ * extension keyboard.
+ */
+ private boolean mDisableDisambiguation;
+ /** The distance threshold at which we start treating the touch session as a multi-touch */
+ private int mJumpThresholdSquare = Integer.MAX_VALUE;
+ /** The y coordinate of the last row */
+ private int mLastRowY;
+ private int mExtensionLayoutResId = 0;
+ private LatinKeyboard mExtensionKeyboard;
+
+ public LatinKeyboardView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public LatinKeyboardView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+
+ // TODO(klausw): migrate attribute styles to LatinKeyboardView?
+ TypedArray a = context.obtainStyledAttributes(
+ attrs, R.styleable.LatinKeyboardBaseView, defStyle, R.style.LatinKeyboardBaseView);
+ LayoutInflater inflate =
+ (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+
+ int previewLayout = 0;
+ int n = a.getIndexCount();
+ for (int i = 0; i < n; i++) {
+ int attr = a.getIndex(i);
+
+ switch (attr) {
+ case R.styleable.LatinKeyboardBaseView_keyPreviewLayout:
+ previewLayout = a.getResourceId(attr, 0);
+ if (previewLayout == R.layout.null_layout) previewLayout = 0;
+ break;
+ case R.styleable.LatinKeyboardBaseView_keyPreviewOffset:
+ mPreviewOffset = a.getDimensionPixelOffset(attr, 0);
+ break;
+ case R.styleable.LatinKeyboardBaseView_keyPreviewHeight:
+ mPreviewHeight = a.getDimensionPixelSize(attr, 80);
+ break;
+ case R.styleable.LatinKeyboardBaseView_popupLayout:
+ mPopupLayout = a.getResourceId(attr, 0);
+ if (mPopupLayout == R.layout.null_layout) mPopupLayout = 0;
+ break;
+ }
+ }
+
+ final Resources res = getResources();
+ if (previewLayout != 0) {
+ mPreviewPopup = new PopupWindow(context);
+ Log.i(TAG, "new mPreviewPopup " + mPreviewPopup + " from " + this);
+ mPreviewText = (TextView) inflate.inflate(previewLayout, null);
+ mPreviewTextSizeLarge = (int) res.getDimension(R.dimen.key_preview_text_size_large);
+ mPreviewPopup.setContentView(mPreviewText);
+ mPreviewPopup.setBackgroundDrawable(null);
+ mPreviewPopup.setTouchable(false);
+ mPreviewPopup.setAnimationStyle(R.style.KeyPreviewAnimation);
+ } else {
+ mShowPreview = false;
+ }
+
+ if (mPopupLayout != 0) {
+ mMiniKeyboardParent = this;
+ mMiniKeyboardPopup = new PopupWindow(context);
+ Log.i(TAG, "new mMiniKeyboardPopup " + mMiniKeyboardPopup + " from " + this);
+ mMiniKeyboardPopup.setBackgroundDrawable(null);
+ mMiniKeyboardPopup.setAnimationStyle(R.style.MiniKeyboardAnimation);
+ mMiniKeyboardVisible = false;
+ }
+
+ }
+
+ public void setPhoneKeyboard(Keyboard phoneKeyboard) {
+ mPhoneKeyboard = phoneKeyboard;
+ }
+
+ public void setExtensionLayoutResId (int id) {
+ mExtensionLayoutResId = id;
+ }
+
+ @Override
+ public void setPreviewEnabled(boolean previewEnabled) {
+ if (getKeyboard() == mPhoneKeyboard) {
+ // Phone keyboard never shows popup preview (except language switch).
+ super.setPreviewEnabled(false);
+ } else {
+ super.setPreviewEnabled(previewEnabled);
+ }
+ }
+
+ @Override
+ public void setKeyboard(Keyboard newKeyboard) {
+ final Keyboard oldKeyboard = getKeyboard();
+ if (oldKeyboard instanceof LatinKeyboard) {
+ // Reset old keyboard state before switching to new keyboard.
+ ((LatinKeyboard)oldKeyboard).keyReleased();
+ }
+ super.setKeyboard(newKeyboard);
+ // One-seventh of the keyboard width seems like a reasonable threshold
+ mJumpThresholdSquare = newKeyboard.getMinWidth() / 7;
+ mJumpThresholdSquare *= mJumpThresholdSquare;
+ // Get Y coordinate of the last row based on the row count, assuming equal height
+ int numRows = newKeyboard.mRowCount;
+ mLastRowY = (newKeyboard.getHeight() * (numRows - 1)) / numRows;
+ mExtensionKeyboard = ((LatinKeyboard) newKeyboard).getExtension();
+ if (mExtensionKeyboard != null && mExtension != null) mExtension.setKeyboard(mExtensionKeyboard);
+ setKeyboardLocal(newKeyboard);
+ }
+
+ @Override
+ /*package*/ boolean enableSlideKeyHack() {
+ return true;
+ }
+
+ @Override
+ protected boolean onLongPress(Key key) {
+ PointerTracker.clearSlideKeys();
+
+ int primaryCode = key.codes[0];
+ if (primaryCode == KEYCODE_OPTIONS) {
+ return invokeOnKey(KEYCODE_OPTIONS_LONGPRESS);
+ } else if (primaryCode == KEYCODE_DPAD_CENTER) {
+ return invokeOnKey(KEYCODE_COMPOSE);
+ } else if (primaryCode == '0' && getKeyboard() == mPhoneKeyboard) {
+ // Long pressing on 0 in phone number keypad gives you a '+'.
+ return invokeOnKey('+');
+ } else {
+ return super.onLongPress(key);
+ }
+ }
+
+ private boolean invokeOnKey(int primaryCode) {
+ getOnKeyboardActionListener().onKey(primaryCode, null,
+ LatinKeyboardBaseView.NOT_A_TOUCH_COORDINATE,
+ LatinKeyboardBaseView.NOT_A_TOUCH_COORDINATE);
+ return true;
+ }
+
+ /**
+ * This function checks to see if we need to handle any sudden jumps in the pointer location
+ * that could be due to a multi-touch being treated as a move by the firmware or hardware.
+ * Once a sudden jump is detected, all subsequent move events are discarded
+ * until an UP is received.<P>
+ * When a sudden jump is detected, an UP event is simulated at the last position and when
+ * the sudden moves subside, a DOWN event is simulated for the second key.
+ * @param me the motion event
+ * @return true if the event was consumed, so that it doesn't continue to be handled by
+ * KeyboardView.
+ */
+ private boolean handleSuddenJump(MotionEvent me) {
+ final int action = me.getAction();
+ final int x = (int) me.getX();
+ final int y = (int) me.getY();
+ boolean result = false;
+
+ // Real multi-touch event? Stop looking for sudden jumps
+ if (me.getPointerCount() > 1) {
+ mDisableDisambiguation = true;
+ }
+ if (mDisableDisambiguation) {
+ // If UP, reset the multi-touch flag
+ if (action == MotionEvent.ACTION_UP) mDisableDisambiguation = false;
+ return false;
+ }
+
+ switch (action) {
+ case MotionEvent.ACTION_DOWN:
+ // Reset the "session"
+ mDroppingEvents = false;
+ mDisableDisambiguation = false;
+ break;
+ case MotionEvent.ACTION_MOVE:
+ // Is this a big jump?
+ final int distanceSquare = (mLastX - x) * (mLastX - x) + (mLastY - y) * (mLastY - y);
+ // Check the distance and also if the move is not entirely within the bottom row
+ // If it's only in the bottom row, it might be an intentional slide gesture
+ // for language switching
+ if (distanceSquare > mJumpThresholdSquare
+ && (mLastY < mLastRowY || y < mLastRowY)) {
+ // If we're not yet dropping events, start dropping and send an UP event
+ if (!mDroppingEvents) {
+ mDroppingEvents = true;
+ // Send an up event
+ MotionEvent translated = MotionEvent.obtain(me.getEventTime(), me.getEventTime(),
+ MotionEvent.ACTION_UP,
+ mLastX, mLastY, me.getMetaState());
+ super.onTouchEvent(translated);
+ translated.recycle();
+ }
+ result = true;
+ } else if (mDroppingEvents) {
+ // If moves are small and we're already dropping events, continue dropping
+ result = true;
+ }
+ break;
+ case MotionEvent.ACTION_UP:
+ if (mDroppingEvents) {
+ // Send a down event first, as we dropped a bunch of sudden jumps and assume that
+ // the user is releasing the touch on the second key.
+ MotionEvent translated = MotionEvent.obtain(me.getEventTime(), me.getEventTime(),
+ MotionEvent.ACTION_DOWN,
+ x, y, me.getMetaState());
+ super.onTouchEvent(translated);
+ translated.recycle();
+ mDroppingEvents = false;
+ // Let the up event get processed as well, result = false
+ }
+ break;
+ }
+ // Track the previous coordinate
+ mLastX = x;
+ mLastY = y;
+ return result;
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent me) {
+ LatinKeyboard keyboard = (LatinKeyboard) getKeyboard();
+ if (LatinIME.sKeyboardSettings.showTouchPos || DEBUG_LINE) {
+ mLastX = (int) me.getX();
+ mLastY = (int) me.getY();
+ invalidate();
+ }
+
+ // If an extension keyboard is visible or this is an extension keyboard, don't look
+ // for sudden jumps. Otherwise, if there was a sudden jump, return without processing the
+ // actual motion event.
+ if (!mExtensionVisible && !mIsExtensionType
+ && handleSuddenJump(me)) return true;
+ // Reset any bounding box controls in the keyboard
+ if (me.getAction() == MotionEvent.ACTION_DOWN) {
+ keyboard.keyReleased();
+ }
+
+ if (me.getAction() == MotionEvent.ACTION_UP) {
+ int languageDirection = keyboard.getLanguageChangeDirection();
+ if (languageDirection != 0) {
+ getOnKeyboardActionListener().onKey(
+ languageDirection == 1 ? KEYCODE_NEXT_LANGUAGE : KEYCODE_PREV_LANGUAGE,
+ null, mLastX, mLastY);
+ me.setAction(MotionEvent.ACTION_CANCEL);
+ keyboard.keyReleased();
+ return super.onTouchEvent(me);
+ }
+ }
+
+ // If we don't have an extension keyboard, don't go any further.
+ if (keyboard.getExtension() == null) {
+ return super.onTouchEvent(me);
+ }
+ // If the motion event is above the keyboard and it's not an UP event coming
+ // even before the first MOVE event into the extension area
+ if (me.getY() < 0 && (mExtensionVisible || me.getAction() != MotionEvent.ACTION_UP)) {
+ if (mExtensionVisible) {
+ int action = me.getAction();
+ if (mFirstEvent) action = MotionEvent.ACTION_DOWN;
+ mFirstEvent = false;
+ MotionEvent translated = MotionEvent.obtain(me.getEventTime(), me.getEventTime(),
+ action,
+ me.getX(), me.getY() + mExtension.getHeight(), me.getMetaState());
+ if (me.getActionIndex() > 0)
+ return true; // ignore second touches to avoid "pointerIndex out of range"
+ boolean result = mExtension.onTouchEvent(translated);
+ translated.recycle();
+ if (me.getAction() == MotionEvent.ACTION_UP
+ || me.getAction() == MotionEvent.ACTION_CANCEL) {
+ closeExtension();
+ }
+ return result;
+ } else {
+ if (swipeUp()) {
+ return true;
+ } else if (openExtension()) {
+ MotionEvent cancel = MotionEvent.obtain(me.getDownTime(), me.getEventTime(),
+ MotionEvent.ACTION_CANCEL, me.getX() - 100, me.getY() - 100, 0);
+ super.onTouchEvent(cancel);
+ cancel.recycle();
+ if (mExtension.getHeight() > 0) {
+ MotionEvent translated = MotionEvent.obtain(me.getEventTime(),
+ me.getEventTime(),
+ MotionEvent.ACTION_DOWN,
+ me.getX(), me.getY() + mExtension.getHeight(),
+ me.getMetaState());
+ mExtension.onTouchEvent(translated);
+ translated.recycle();
+ } else {
+ mFirstEvent = true;
+ }
+ // Stop processing multi-touch errors
+ mDisableDisambiguation = true;
+ }
+ return true;
+ }
+ } else if (mExtensionVisible) {
+ closeExtension();
+ // Send a down event into the main keyboard first
+ MotionEvent down = MotionEvent.obtain(me.getEventTime(), me.getEventTime(),
+ MotionEvent.ACTION_DOWN,
+ me.getX(), me.getY(), me.getMetaState());
+ super.onTouchEvent(down, true);
+ down.recycle();
+ // Send the actual event
+ return super.onTouchEvent(me);
+ } else {
+ return super.onTouchEvent(me);
+ }
+ }
+
+ private void setExtensionType(boolean isExtensionType) {
+ mIsExtensionType = isExtensionType;
+ }
+
+ private boolean openExtension() {
+ // If the current keyboard is not visible, or if the mini keyboard is active, don't show the popup
+ if (!isShown() || popupKeyboardIsShowing()) {
+ return false;
+ }
+ PointerTracker.clearSlideKeys();
+ if (((LatinKeyboard) getKeyboard()).getExtension() == null) return false;
+ makePopupWindow();
+ mExtensionVisible = true;
+ return true;
+ }
+
+ private void makePopupWindow() {
+ dismissPopupKeyboard();
+ if (mExtensionPopup == null) {
+ int[] windowLocation = new int[2];
+ mExtensionPopup = new PopupWindow(getContext());
+ mExtensionPopup.setBackgroundDrawable(null);
+ LayoutInflater li = (LayoutInflater) getContext().getSystemService(
+ Context.LAYOUT_INFLATER_SERVICE);
+ mExtension = (LatinKeyboardView) li.inflate(mExtensionLayoutResId == 0 ?
+ R.layout.input_trans : mExtensionLayoutResId, null);
+ Keyboard keyboard = mExtensionKeyboard;
+ mExtension.setKeyboard(keyboard);
+ mExtension.setExtensionType(true);
+ mExtension.setPadding(0, 0, 0, 0);
+ mExtension.setOnKeyboardActionListener(
+ new ExtensionKeyboardListener(getOnKeyboardActionListener()));
+ mExtension.setPopupParent(this);
+ mExtension.setPopupOffset(0, -windowLocation[1]);
+ mExtensionPopup.setContentView(mExtension);
+ mExtensionPopup.setWidth(getWidth());
+ mExtensionPopup.setHeight(keyboard.getHeight());
+ mExtensionPopup.setAnimationStyle(-1);
+ getLocationInWindow(windowLocation);
+ // TODO: Fix the "- 30".
+ mExtension.setPopupOffset(0, -windowLocation[1] - 30);
+ mExtensionPopup.showAtLocation(this, 0, 0, -keyboard.getHeight()
+ + windowLocation[1] + this.getPaddingTop());
+ } else {
+ mExtension.setVisibility(VISIBLE);
+ }
+ mExtension.setShiftState(getShiftState()); // propagate shift state
+ }
+
+ @Override
+ public void closing() {
+ super.closing();
+ if (mExtensionPopup != null && mExtensionPopup.isShowing()) {
+ mExtensionPopup.dismiss();
+ mExtensionPopup = null;
+ }
+ }
+
+ private void closeExtension() {
+ mExtension.closing();
+ mExtension.setVisibility(INVISIBLE);
+ mExtensionVisible = false;
+ }
+
+ private static class ExtensionKeyboardListener implements OnKeyboardActionListener {
+ private OnKeyboardActionListener mTarget;
+ ExtensionKeyboardListener(OnKeyboardActionListener target) {
+ mTarget = target;
+ }
+ public void onKey(int primaryCode, int[] keyCodes, int x, int y) {
+ mTarget.onKey(primaryCode, keyCodes, x, y);
+ }
+ public void onPress(int primaryCode) {
+ mTarget.onPress(primaryCode);
+ }
+ public void onRelease(int primaryCode) {
+ mTarget.onRelease(primaryCode);
+ }
+ public void onText(CharSequence text) {
+ mTarget.onText(text);
+ }
+ public void onCancel() {
+ mTarget.onCancel();
+ }
+ public boolean swipeDown() {
+ // Don't pass through
+ return true;
+ }
+ public boolean swipeLeft() {
+ // Don't pass through
+ return true;
+ }
+ public boolean swipeRight() {
+ // Don't pass through
+ return true;
+ }
+ public boolean swipeUp() {
+ // Don't pass through
+ return true;
+ }
+ }
+
+ /**************************** INSTRUMENTATION *******************************/
+
+ static final boolean DEBUG_AUTO_PLAY = false;
+ static final boolean DEBUG_LINE = false;
+ private static final int MSG_TOUCH_DOWN = 1;
+ private static final int MSG_TOUCH_UP = 2;
+
+ Handler mHandler2;
+
+ private String mStringToPlay;
+ private int mStringIndex;
+ private boolean mDownDelivered;
+ private Key[] mAsciiKeys = new Key[256];
+ private boolean mPlaying;
+ private int mLastX;
+ private int mLastY;
+ private Paint mPaint;
+
+ private void setKeyboardLocal(Keyboard k) {
+ if (DEBUG_AUTO_PLAY) {
+ findKeys();
+ if (mHandler2 == null) {
+ mHandler2 = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ removeMessages(MSG_TOUCH_DOWN);
+ removeMessages(MSG_TOUCH_UP);
+ if (mPlaying == false) return;
+
+ switch (msg.what) {
+ case MSG_TOUCH_DOWN:
+ if (mStringIndex >= mStringToPlay.length()) {
+ mPlaying = false;
+ return;
+ }
+ char c = mStringToPlay.charAt(mStringIndex);
+ while (c > 255 || mAsciiKeys[c] == null) {
+ mStringIndex++;
+ if (mStringIndex >= mStringToPlay.length()) {
+ mPlaying = false;
+ return;
+ }
+ c = mStringToPlay.charAt(mStringIndex);
+ }
+ int x = mAsciiKeys[c].x + 10;
+ int y = mAsciiKeys[c].y + 26;
+ MotionEvent me = MotionEvent.obtain(SystemClock.uptimeMillis(),
+ SystemClock.uptimeMillis(),
+ MotionEvent.ACTION_DOWN, x, y, 0);
+ LatinKeyboardView.this.dispatchTouchEvent(me);
+ me.recycle();
+ sendEmptyMessageDelayed(MSG_TOUCH_UP, 500); // Deliver up in 500ms if nothing else
+ // happens
+ mDownDelivered = true;
+ break;
+ case MSG_TOUCH_UP:
+ char cUp = mStringToPlay.charAt(mStringIndex);
+ int x2 = mAsciiKeys[cUp].x + 10;
+ int y2 = mAsciiKeys[cUp].y + 26;
+ mStringIndex++;
+
+ MotionEvent me2 = MotionEvent.obtain(SystemClock.uptimeMillis(),
+ SystemClock.uptimeMillis(),
+ MotionEvent.ACTION_UP, x2, y2, 0);
+ LatinKeyboardView.this.dispatchTouchEvent(me2);
+ me2.recycle();
+ sendEmptyMessageDelayed(MSG_TOUCH_DOWN, 500); // Deliver up in 500ms if nothing else
+ // happens
+ mDownDelivered = false;
+ break;
+ }
+ }
+ };
+
+ }
+ }
+ }
+
+ private void findKeys() {
+ List<Key> keys = getKeyboard().getKeys();
+ // Get the keys on this keyboard
+ for (int i = 0; i < keys.size(); i++) {
+ int code = keys.get(i).codes[0];
+ if (code >= 0 && code <= 255) {
+ mAsciiKeys[code] = keys.get(i);
+ }
+ }
+ }
+
+ public void startPlaying(String s) {
+ if (DEBUG_AUTO_PLAY) {
+ if (s == null) return;
+ mStringToPlay = s.toLowerCase();
+ mPlaying = true;
+ mDownDelivered = false;
+ mStringIndex = 0;
+ mHandler2.sendEmptyMessageDelayed(MSG_TOUCH_DOWN, 10);
+ }
+ }
+
+ @Override
+ public void draw(Canvas c) {
+ LatinIMEUtil.GCUtils.getInstance().reset();
+ boolean tryGC = true;
+ for (int i = 0; i < LatinIMEUtil.GCUtils.GC_TRY_LOOP_MAX && tryGC; ++i) {
+ try {
+ super.draw(c);
+ tryGC = false;
+ } catch (OutOfMemoryError e) {
+ tryGC = LatinIMEUtil.GCUtils.getInstance().tryGCOrWait("LatinKeyboardView", e);
+ }
+ }
+ if (DEBUG_AUTO_PLAY) {
+ if (mPlaying) {
+ mHandler2.removeMessages(MSG_TOUCH_DOWN);
+ mHandler2.removeMessages(MSG_TOUCH_UP);
+ if (mDownDelivered) {
+ mHandler2.sendEmptyMessageDelayed(MSG_TOUCH_UP, 20);
+ } else {
+ mHandler2.sendEmptyMessageDelayed(MSG_TOUCH_DOWN, 20);
+ }
+ }
+ }
+ if (LatinIME.sKeyboardSettings.showTouchPos || DEBUG_LINE) {
+ if (mPaint == null) {
+ mPaint = new Paint();
+ mPaint.setColor(0x80FFFFFF);
+ mPaint.setAntiAlias(false);
+ }
+ c.drawLine(mLastX, 0, mLastX, getHeight(), mPaint);
+ c.drawLine(0, mLastY, getWidth(), mLastY, mPaint);
+ }
+ }
+}
diff --git a/java/src/org/pocketworkstation/pckeyboard/Main.java b/java/src/org/pocketworkstation/pckeyboard/Main.java
new file mode 100644
index 0000000..bb8e02f
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/Main.java
@@ -0,0 +1,92 @@
+/*
+ * 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 org.pocketworkstation.pckeyboard;
+
+import android.app.Activity;
+import android.content.ActivityNotFoundException;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.text.Html;
+import android.text.Spanned;
+import android.text.method.LinkMovementMethod;
+import android.view.View;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.Button;
+import android.widget.TextView;
+import android.widget.Toast;
+import android.widget.TextView.BufferType;
+
+public class Main extends Activity {
+
+ private final static String MARKET_URI = "market://search?q=pub:\"Klaus Weidner\"";
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+ String html = getString(R.string.main_body);
+ html += "<p><i>Version: " + getString(R.string.auto_version) + "</i></p>";
+ Spanned content = Html.fromHtml(html);
+ TextView description = (TextView) findViewById(R.id.main_description);
+ description.setMovementMethod(LinkMovementMethod.getInstance());
+ description.setText(content, BufferType.SPANNABLE);
+
+
+ final Button setup1 = (Button) findViewById(R.id.main_setup_btn_configure_imes);
+ setup1.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ startActivityForResult(new Intent(android.provider.Settings.ACTION_INPUT_METHOD_SETTINGS), 0);
+ }
+ });
+
+ final Button setup2 = (Button) findViewById(R.id.main_setup_btn_set_ime);
+ setup2.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ InputMethodManager mgr = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
+ mgr.showInputMethodPicker();
+ }
+ });
+
+ final Activity that = this;
+
+ final Button setup4 = (Button) findViewById(R.id.main_setup_btn_input_lang);
+ setup4.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ startActivityForResult(new Intent(that, InputLanguageSelection.class), 0);
+ }
+ });
+
+ final Button setup3 = (Button) findViewById(R.id.main_setup_btn_get_dicts);
+ setup3.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ Intent it = new Intent(Intent.ACTION_VIEW, Uri.parse(MARKET_URI));
+ try {
+ startActivity(it);
+ } catch (ActivityNotFoundException e) {
+ Toast.makeText(getApplicationContext(),
+ getResources().getString(
+ R.string.no_market_warning), Toast.LENGTH_LONG)
+ .show();
+ }
+ }
+ });
+ // PluginManager.getPluginDictionaries(getApplicationContext()); // why?
+ }
+}
+
diff --git a/java/src/org/pocketworkstation/pckeyboard/MiniKeyboardKeyDetector.java b/java/src/org/pocketworkstation/pckeyboard/MiniKeyboardKeyDetector.java
new file mode 100644
index 0000000..102747b
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/MiniKeyboardKeyDetector.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.pocketworkstation.pckeyboard;
+
+import org.pocketworkstation.pckeyboard.Keyboard.Key;
+
+class MiniKeyboardKeyDetector extends KeyDetector {
+ private static final int MAX_NEARBY_KEYS = 1;
+
+ private final int mSlideAllowanceSquare;
+ private final int mSlideAllowanceSquareTop;
+
+ public MiniKeyboardKeyDetector(float slideAllowance) {
+ super();
+ mSlideAllowanceSquare = (int)(slideAllowance * slideAllowance);
+ // Top slide allowance is slightly longer (sqrt(2) times) than other edges.
+ mSlideAllowanceSquareTop = mSlideAllowanceSquare * 2;
+ }
+
+ @Override
+ protected int getMaxNearbyKeys() {
+ return MAX_NEARBY_KEYS;
+ }
+
+ @Override
+ public int getKeyIndexAndNearbyCodes(int x, int y, int[] allKeys) {
+ final Key[] keys = getKeys();
+ final int touchX = getTouchX(x);
+ final int touchY = getTouchY(y);
+ int closestKeyIndex = LatinKeyboardBaseView.NOT_A_KEY;
+ int closestKeyDist = (y < 0) ? mSlideAllowanceSquareTop : mSlideAllowanceSquare;
+ final int keyCount = keys.length;
+ for (int i = 0; i < keyCount; i++) {
+ final Key key = keys[i];
+ int dist = key.squaredDistanceFrom(touchX, touchY);
+ if (dist < closestKeyDist) {
+ closestKeyIndex = i;
+ closestKeyDist = dist;
+ }
+ }
+ if (allKeys != null && closestKeyIndex != LatinKeyboardBaseView.NOT_A_KEY)
+ allKeys[0] = keys[closestKeyIndex].getPrimaryCode();
+ return closestKeyIndex;
+ }
+}
diff --git a/java/src/org/pocketworkstation/pckeyboard/ModifierKeyState.java b/java/src/org/pocketworkstation/pckeyboard/ModifierKeyState.java
new file mode 100644
index 0000000..d7fa782
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/ModifierKeyState.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.pocketworkstation.pckeyboard;
+
+class ModifierKeyState {
+ private static final int RELEASING = 0;
+ private static final int PRESSING = 1;
+ private static final int MOMENTARY = 2;
+
+ private int mState = RELEASING;
+
+ public void onPress() {
+ mState = PRESSING;
+ }
+
+ public void onRelease() {
+ mState = RELEASING;
+ }
+
+ public void onOtherKeyPressed() {
+ if (mState == PRESSING)
+ mState = MOMENTARY;
+ }
+
+ public boolean isMomentary() {
+ return mState == MOMENTARY;
+ }
+
+ public String toString() {
+ return "ModifierKeyState:" + mState;
+ }
+}
diff --git a/java/src/org/pocketworkstation/pckeyboard/NotificationReceiver.java b/java/src/org/pocketworkstation/pckeyboard/NotificationReceiver.java
new file mode 100644
index 0000000..478af99
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/NotificationReceiver.java
@@ -0,0 +1,29 @@
+package org.pocketworkstation.pckeyboard;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+import android.view.inputmethod.InputMethodManager;
+
+public class NotificationReceiver extends BroadcastReceiver {
+ static final String TAG = "PCKeyboard/Notification";
+ private LatinIME mIME;
+
+ NotificationReceiver(LatinIME ime) {
+ super();
+ mIME = ime;
+ Log.i(TAG, "NotificationReceiver created, ime=" + mIME);
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Log.i(TAG, "NotificationReceiver.onReceive called");
+
+ InputMethodManager imm = (InputMethodManager)
+ context.getSystemService(Context.INPUT_METHOD_SERVICE);
+ if (imm != null) {
+ imm.showSoftInputFromInputMethod(mIME.mToken, InputMethodManager.SHOW_FORCED);
+ }
+ }
+}
diff --git a/java/src/org/pocketworkstation/pckeyboard/PluginManager.java b/java/src/org/pocketworkstation/pckeyboard/PluginManager.java
new file mode 100644
index 0000000..cbb9522
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/PluginManager.java
@@ -0,0 +1,259 @@
+package org.pocketworkstation.pckeyboard;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.res.Resources;
+import android.content.res.XmlResourceParser;
+import android.util.Log;
+
+public class PluginManager extends BroadcastReceiver {
+ private static String TAG = "PCKeyboard";
+ private static String HK_INTENT_DICT = "org.pocketworkstation.DICT";
+ private static String SOFTKEYBOARD_INTENT_DICT = "com.menny.android.anysoftkeyboard.DICTIONARY";
+ private LatinIME mIME;
+
+ // Apparently anysoftkeyboard doesn't use ISO 639-1 language codes for its locales?
+ // Add exceptions as needed.
+ private static Map<String, String> SOFTKEYBOARD_LANG_MAP = new HashMap<String, String>();
+ static {
+ SOFTKEYBOARD_LANG_MAP.put("dk", "da");
+ }
+
+ PluginManager(LatinIME ime) {
+ super();
+ mIME = ime;
+ }
+
+ private static Map<String, DictPluginSpec> mPluginDicts =
+ new HashMap<String, DictPluginSpec>();
+
+ static interface DictPluginSpec {
+ BinaryDictionary getDict(Context context);
+ }
+
+ static private abstract class DictPluginSpecBase
+ implements DictPluginSpec {
+ String mPackageName;
+
+ Resources getResources(Context context) {
+ PackageManager packageManager = context.getPackageManager();
+ Resources res = null;
+ try {
+ ApplicationInfo appInfo = packageManager.getApplicationInfo(mPackageName, 0);
+ res = packageManager.getResourcesForApplication(appInfo);
+ } catch (NameNotFoundException e) {
+ Log.i(TAG, "couldn't get resources");
+ }
+ return res;
+ }
+
+ abstract InputStream[] getStreams(Resources res);
+
+ public BinaryDictionary getDict(Context context) {
+ Resources res = getResources(context);
+ if (res == null) return null;
+
+ InputStream[] dicts = getStreams(res);
+ if (dicts == null) return null;
+ BinaryDictionary dict = new BinaryDictionary(
+ context, dicts, Suggest.DIC_MAIN);
+ if (dict.getSize() == 0) return null;
+ //Log.i(TAG, "dict size=" + dict.getSize());
+ return dict;
+ }
+ }
+
+ static private class DictPluginSpecHK
+ extends DictPluginSpecBase {
+
+ int[] mRawIds;
+
+ public DictPluginSpecHK(String pkg, int[] ids) {
+ mPackageName = pkg;
+ mRawIds = ids;
+ }
+
+ @Override
+ InputStream[] getStreams(Resources res) {
+ if (mRawIds == null || mRawIds.length == 0) return null;
+ InputStream[] streams = new InputStream[mRawIds.length];
+ for (int i = 0; i < mRawIds.length; ++i) {
+ streams[i] = res.openRawResource(mRawIds[i]);
+ }
+ return streams;
+ }
+ }
+
+ static private class DictPluginSpecSoftKeyboard
+ extends DictPluginSpecBase {
+
+ String mAssetName;
+
+ public DictPluginSpecSoftKeyboard(String pkg, String asset) {
+ mPackageName = pkg;
+ mAssetName = asset;
+ }
+
+ @Override
+ InputStream[] getStreams(Resources res) {
+ if (mAssetName == null) return null;
+ try {
+ InputStream in = res.getAssets().open(mAssetName);
+ return new InputStream[] {in};
+ } catch (IOException e) {
+ Log.e(TAG, "Dictionary asset loading failure");
+ return null;
+ }
+ }
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Log.i(TAG, "Package information changed, updating dictionaries.");
+ getPluginDictionaries(context);
+ Log.i(TAG, "Finished updating dictionaries.");
+ mIME.toggleLanguage(true, true);
+ }
+
+ static void getSoftKeyboardDictionaries(PackageManager packageManager) {
+ Intent dictIntent = new Intent(SOFTKEYBOARD_INTENT_DICT);
+ List<ResolveInfo> dictPacks = packageManager.queryBroadcastReceivers(
+ dictIntent, PackageManager.GET_RECEIVERS);
+ for (ResolveInfo ri : dictPacks) {
+ ApplicationInfo appInfo = ri.activityInfo.applicationInfo;
+ String pkgName = appInfo.packageName;
+ boolean success = false;
+ try {
+ Resources res = packageManager.getResourcesForApplication(appInfo);
+ //Log.i(TAG, "Found dictionary plugin package: " + pkgName);
+ int dictId = res.getIdentifier("dictionaries", "xml", pkgName);
+ if (dictId == 0) continue;
+ XmlResourceParser xrp = res.getXml(dictId);
+
+ String assetName = null;
+ String lang = null;
+ try {
+ int current = xrp.getEventType();
+ while (current != XmlResourceParser.END_DOCUMENT) {
+ if (current == XmlResourceParser.START_TAG) {
+ String tag = xrp.getName();
+ if (tag != null) {
+ if (tag.equals("Dictionary")) {
+ lang = xrp.getAttributeValue(null, "locale");
+ String convLang = SOFTKEYBOARD_LANG_MAP.get(lang);
+ if (convLang != null) lang = convLang;
+ String type = xrp.getAttributeValue(null, "type");
+ if (type == null || type.equals("raw") || type.equals("binary")) {
+ assetName = xrp.getAttributeValue(null, "dictionaryAssertName"); // sic
+ } else {
+ Log.w(TAG, "Unsupported AnySoftKeyboard dict type " + type);
+ }
+ //Log.i(TAG, "asset=" + assetName + " lang=" + lang);
+ }
+ }
+ }
+ xrp.next();
+ current = xrp.getEventType();
+ }
+ } catch (XmlPullParserException e) {
+ Log.e(TAG, "Dictionary XML parsing failure");
+ } catch (IOException e) {
+ Log.e(TAG, "Dictionary XML IOException");
+ }
+
+ if (assetName == null || lang == null) continue;
+ DictPluginSpec spec = new DictPluginSpecSoftKeyboard(pkgName, assetName);
+ mPluginDicts.put(lang, spec);
+ Log.i(TAG, "Found plugin dictionary: lang=" + lang + ", pkg=" + pkgName);
+ success = true;
+ } catch (NameNotFoundException e) {
+ Log.i(TAG, "bad");
+ } finally {
+ if (!success) {
+ Log.i(TAG, "failed to load plugin dictionary spec from " + pkgName);
+ }
+ }
+ }
+ }
+
+ static void getHKDictionaries(PackageManager packageManager) {
+ Intent dictIntent = new Intent(HK_INTENT_DICT);
+ List<ResolveInfo> dictPacks = packageManager.queryIntentActivities(dictIntent, 0);
+ for (ResolveInfo ri : dictPacks) {
+ ApplicationInfo appInfo = ri.activityInfo.applicationInfo;
+ String pkgName = appInfo.packageName;
+ boolean success = false;
+ try {
+ Resources res = packageManager.getResourcesForApplication(appInfo);
+ //Log.i(TAG, "Found dictionary plugin package: " + pkgName);
+ int langId = res.getIdentifier("dict_language", "string", pkgName);
+ if (langId == 0) continue;
+ String lang = res.getString(langId);
+ int[] rawIds = null;
+
+ // Try single-file version first
+ int rawId = res.getIdentifier("main", "raw", pkgName);
+ if (rawId != 0) {
+ rawIds = new int[] { rawId };
+ } else {
+ // try multi-part version
+ int parts = 0;
+ List<Integer> ids = new ArrayList<Integer>();
+ while (true) {
+ int id = res.getIdentifier("main" + parts, "raw", pkgName);
+ if (id == 0) break;
+ ids.add(id);
+ ++parts;
+ }
+ if (parts == 0) continue; // no parts found
+ rawIds = new int[parts];
+ for (int i = 0; i < parts; ++i) rawIds[i] = ids.get(i);
+ }
+ DictPluginSpec spec = new DictPluginSpecHK(pkgName, rawIds);
+ mPluginDicts.put(lang, spec);
+ Log.i(TAG, "Found plugin dictionary: lang=" + lang + ", pkg=" + pkgName);
+ success = true;
+ } catch (NameNotFoundException e) {
+ Log.i(TAG, "bad");
+ } finally {
+ if (!success) {
+ Log.i(TAG, "failed to load plugin dictionary spec from " + pkgName);
+ }
+ }
+ }
+ }
+
+ static void getPluginDictionaries(Context context) {
+ mPluginDicts.clear();
+ PackageManager packageManager = context.getPackageManager();
+ getSoftKeyboardDictionaries(packageManager);
+ getHKDictionaries(packageManager);
+ }
+
+ static BinaryDictionary getDictionary(Context context, String lang) {
+ //Log.i(TAG, "Looking for plugin dictionary for lang=" + lang);
+ DictPluginSpec spec = mPluginDicts.get(lang);
+ if (spec == null) spec = mPluginDicts.get(lang.substring(0, 2));
+ if (spec == null) {
+ //Log.i(TAG, "No plugin found.");
+ return null;
+ }
+ BinaryDictionary dict = spec.getDict(context);
+ Log.i(TAG, "Found plugin dictionary for " + lang + (dict == null ? " is null" : ", size=" + dict.getSize()));
+ return dict;
+ }
+}
diff --git a/java/src/org/pocketworkstation/pckeyboard/PointerTracker.java b/java/src/org/pocketworkstation/pckeyboard/PointerTracker.java
new file mode 100644
index 0000000..f4e623b
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/PointerTracker.java
@@ -0,0 +1,645 @@
+/*
+ * Copyright (C) 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.pocketworkstation.pckeyboard;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.pocketworkstation.pckeyboard.LatinKeyboardBaseView.OnKeyboardActionListener;
+import org.pocketworkstation.pckeyboard.LatinKeyboardBaseView.UIHandler;
+
+import android.content.res.Resources;
+import org.pocketworkstation.pckeyboard.Keyboard.Key;
+import android.util.Log;
+import android.view.MotionEvent;
+
+public class PointerTracker {
+ private static final String TAG = "PointerTracker";
+ private static final boolean DEBUG = false;
+ private static final boolean DEBUG_MOVE = false;
+
+ public interface UIProxy {
+ public void invalidateKey(Key key);
+ public void showPreview(int keyIndex, PointerTracker tracker);
+ public boolean hasDistinctMultitouch();
+ }
+
+ public final int mPointerId;
+
+ // Timing constants
+ private final int mDelayBeforeKeyRepeatStart;
+ private final int mMultiTapKeyTimeout;
+
+ // Miscellaneous constants
+ private static final int NOT_A_KEY = LatinKeyboardBaseView.NOT_A_KEY;
+ private static final int[] KEY_DELETE = { Keyboard.KEYCODE_DELETE };
+
+ private final UIProxy mProxy;
+ private final UIHandler mHandler;
+ private final KeyDetector mKeyDetector;
+ private OnKeyboardActionListener mListener;
+ private final KeyboardSwitcher mKeyboardSwitcher;
+ private final boolean mHasDistinctMultitouch;
+
+ private Key[] mKeys;
+ private int mKeyHysteresisDistanceSquared = -1;
+
+ private final KeyState mKeyState;
+
+ // true if keyboard layout has been changed.
+ private boolean mKeyboardLayoutHasBeenChanged;
+
+ // true if event is already translated to a key action (long press or mini-keyboard)
+ private boolean mKeyAlreadyProcessed;
+
+ // true if this pointer is repeatable key
+ private boolean mIsRepeatableKey;
+
+ // true if this pointer is in sliding key input
+ private boolean mIsInSlidingKeyInput;
+
+ // For multi-tap
+ private int mLastSentIndex;
+ private int mTapCount;
+ private long mLastTapTime;
+ private boolean mInMultiTap;
+ private final StringBuilder mPreviewLabel = new StringBuilder(1);
+
+ // pressed key
+ private int mPreviousKey = NOT_A_KEY;
+
+ private static boolean sSlideKeyHack;
+ private static List<Key> sSlideKeys = new ArrayList<Key>(10);
+
+ // This class keeps track of a key index and a position where this pointer is.
+ private static class KeyState {
+ private final KeyDetector mKeyDetector;
+
+ // The position and time at which first down event occurred.
+ private int mStartX;
+ private int mStartY;
+ private long mDownTime;
+
+ // The current key index where this pointer is.
+ private int mKeyIndex = NOT_A_KEY;
+ // The position where mKeyIndex was recognized for the first time.
+ private int mKeyX;
+ private int mKeyY;
+
+ // Last pointer position.
+ private int mLastX;
+ private int mLastY;
+
+ public KeyState(KeyDetector keyDetecor) {
+ mKeyDetector = keyDetecor;
+ }
+
+ public int getKeyIndex() {
+ return mKeyIndex;
+ }
+
+ public int getKeyX() {
+ return mKeyX;
+ }
+
+ public int getKeyY() {
+ return mKeyY;
+ }
+
+ public int getStartX() {
+ return mStartX;
+ }
+
+ public int getStartY() {
+ return mStartY;
+ }
+
+ public long getDownTime() {
+ return mDownTime;
+ }
+
+ public int getLastX() {
+ return mLastX;
+ }
+
+ public int getLastY() {
+ return mLastY;
+ }
+
+ public int onDownKey(int x, int y, long eventTime) {
+ mStartX = x;
+ mStartY = y;
+ mDownTime = eventTime;
+
+ return onMoveToNewKey(onMoveKeyInternal(x, y), x, y);
+ }
+
+ private int onMoveKeyInternal(int x, int y) {
+ mLastX = x;
+ mLastY = y;
+ return mKeyDetector.getKeyIndexAndNearbyCodes(x, y, null);
+ }
+
+ public int onMoveKey(int x, int y) {
+ return onMoveKeyInternal(x, y);
+ }
+
+ public int onMoveToNewKey(int keyIndex, int x, int y) {
+ mKeyIndex = keyIndex;
+ mKeyX = x;
+ mKeyY = y;
+ return keyIndex;
+ }
+
+ public int onUpKey(int x, int y) {
+ return onMoveKeyInternal(x, y);
+ }
+ }
+
+ public PointerTracker(int id, UIHandler handler, KeyDetector keyDetector, UIProxy proxy,
+ Resources res, boolean slideKeyHack) {
+ if (proxy == null || handler == null || keyDetector == null)
+ throw new NullPointerException();
+ mPointerId = id;
+ mProxy = proxy;
+ mHandler = handler;
+ mKeyDetector = keyDetector;
+ mKeyboardSwitcher = KeyboardSwitcher.getInstance();
+ mKeyState = new KeyState(keyDetector);
+ mHasDistinctMultitouch = proxy.hasDistinctMultitouch();
+ mDelayBeforeKeyRepeatStart = res.getInteger(R.integer.config_delay_before_key_repeat_start);
+ mMultiTapKeyTimeout = res.getInteger(R.integer.config_multi_tap_key_timeout);
+ sSlideKeyHack = slideKeyHack;
+ resetMultiTap();
+ }
+
+ public void setOnKeyboardActionListener(OnKeyboardActionListener listener) {
+ mListener = listener;
+ }
+
+ public void setKeyboard(Key[] keys, float keyHysteresisDistance) {
+ if (keys == null || keyHysteresisDistance < 0)
+ throw new IllegalArgumentException();
+ mKeys = keys;
+ mKeyHysteresisDistanceSquared = (int)(keyHysteresisDistance * keyHysteresisDistance);
+ // Mark that keyboard layout has been changed.
+ mKeyboardLayoutHasBeenChanged = true;
+ }
+
+ public boolean isInSlidingKeyInput() {
+ return mIsInSlidingKeyInput;
+ }
+
+ public void setSlidingKeyInputState(boolean state) {
+ mIsInSlidingKeyInput = state;
+ }
+
+ private boolean isValidKeyIndex(int keyIndex) {
+ return keyIndex >= 0 && keyIndex < mKeys.length;
+ }
+
+ public Key getKey(int keyIndex) {
+ return isValidKeyIndex(keyIndex) ? mKeys[keyIndex] : null;
+ }
+
+ private boolean isModifierInternal(int keyIndex) {
+ Key key = getKey(keyIndex);
+ if (key == null || key.codes == null)
+ return false;
+ int primaryCode = key.codes[0];
+ return primaryCode == Keyboard.KEYCODE_SHIFT
+ || primaryCode == Keyboard.KEYCODE_MODE_CHANGE
+ || primaryCode == LatinKeyboardView.KEYCODE_CTRL_LEFT
+ || primaryCode == LatinKeyboardView.KEYCODE_ALT_LEFT
+ || primaryCode == LatinKeyboardView.KEYCODE_FN;
+ }
+
+ public boolean isModifier() {
+ return isModifierInternal(mKeyState.getKeyIndex());
+ }
+
+ public boolean isOnModifierKey(int x, int y) {
+ return isModifierInternal(mKeyDetector.getKeyIndexAndNearbyCodes(x, y, null));
+ }
+
+ public boolean isSpaceKey(int keyIndex) {
+ Key key = getKey(keyIndex);
+ return key != null && key.codes != null && key.codes[0] == LatinIME.ASCII_SPACE;
+ }
+
+ public void updateKey(int keyIndex) {
+ if (mKeyAlreadyProcessed)
+ return;
+ int oldKeyIndex = mPreviousKey;
+ mPreviousKey = keyIndex;
+ if (keyIndex != oldKeyIndex) {
+ if (isValidKeyIndex(oldKeyIndex)) {
+ // if new key index is not a key, old key was just released inside of the key.
+ final boolean inside = (keyIndex == NOT_A_KEY);
+ mKeys[oldKeyIndex].onReleased(inside);
+ mProxy.invalidateKey(mKeys[oldKeyIndex]);
+ }
+ if (isValidKeyIndex(keyIndex)) {
+ mKeys[keyIndex].onPressed();
+ mProxy.invalidateKey(mKeys[keyIndex]);
+ }
+ }
+ }
+
+ public void setAlreadyProcessed() {
+ mKeyAlreadyProcessed = true;
+ }
+
+ public void onTouchEvent(int action, int x, int y, long eventTime) {
+ switch (action) {
+ case MotionEvent.ACTION_MOVE:
+ onMoveEvent(x, y, eventTime);
+ break;
+ case MotionEvent.ACTION_DOWN:
+ case MotionEvent.ACTION_POINTER_DOWN:
+ onDownEvent(x, y, eventTime);
+ break;
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_POINTER_UP:
+ onUpEvent(x, y, eventTime);
+ break;
+ case MotionEvent.ACTION_CANCEL:
+ onCancelEvent(x, y, eventTime);
+ break;
+ }
+ }
+
+ public void onDownEvent(int x, int y, long eventTime) {
+ if (DEBUG)
+ debugLog("onDownEvent:", x, y);
+ int keyIndex = mKeyState.onDownKey(x, y, eventTime);
+ mKeyboardLayoutHasBeenChanged = false;
+ mKeyAlreadyProcessed = false;
+ mIsRepeatableKey = false;
+ mIsInSlidingKeyInput = false;
+ checkMultiTap(eventTime, keyIndex);
+ if (mListener != null) {
+ if (isValidKeyIndex(keyIndex)) {
+ Key key = mKeys[keyIndex];
+ if (key.codes != null) mListener.onPress(key.getPrimaryCode());
+ // This onPress call may have changed keyboard layout. Those cases are detected at
+ // {@link #setKeyboard}. In those cases, we should update keyIndex according to the
+ // new keyboard layout.
+ if (mKeyboardLayoutHasBeenChanged) {
+ mKeyboardLayoutHasBeenChanged = false;
+ keyIndex = mKeyState.onDownKey(x, y, eventTime);
+ }
+ }
+ }
+ if (isValidKeyIndex(keyIndex)) {
+ if (mKeys[keyIndex].repeatable) {
+ repeatKey(keyIndex);
+ mHandler.startKeyRepeatTimer(mDelayBeforeKeyRepeatStart, keyIndex, this);
+ mIsRepeatableKey = true;
+ }
+ startLongPressTimer(keyIndex);
+ }
+ showKeyPreviewAndUpdateKey(keyIndex);
+ }
+
+ private static void addSlideKey(Key key) {
+ if (!sSlideKeyHack || LatinIME.sKeyboardSettings.sendSlideKeys == 0) return;
+ if (key == null) return;
+ if (key.modifier) {
+ clearSlideKeys();
+ } else {
+ sSlideKeys.add(key);
+ }
+ }
+
+ /*package*/ static void clearSlideKeys() {
+ sSlideKeys.clear();
+ }
+
+ void sendSlideKeys() {
+ if (!sSlideKeyHack) return;
+ int slideMode = LatinIME.sKeyboardSettings.sendSlideKeys;
+ if ((slideMode & 4) > 0) {
+ // send all
+ for (Key key : sSlideKeys) {
+ detectAndSendKey(key, key.x, key.y, -1);
+ }
+ } else {
+ // Send first and/or last key only.
+ int n = sSlideKeys.size();
+ if (n > 0 && (slideMode & 1) > 0) {
+ Key key = sSlideKeys.get(0);
+ detectAndSendKey(key, key.x, key.y, -1);
+ }
+ if (n > 1 && (slideMode & 2) > 0) {
+ Key key = sSlideKeys.get(n - 1);
+ detectAndSendKey(key, key.x, key.y, -1);
+ }
+ }
+ clearSlideKeys();
+ }
+
+ public void onMoveEvent(int x, int y, long eventTime) {
+ if (DEBUG_MOVE)
+ debugLog("onMoveEvent:", x, y);
+ if (mKeyAlreadyProcessed)
+ return;
+ final KeyState keyState = mKeyState;
+ int keyIndex = keyState.onMoveKey(x, y);
+ final Key oldKey = getKey(keyState.getKeyIndex());
+ if (isValidKeyIndex(keyIndex)) {
+ boolean isMinorMoveBounce = isMinorMoveBounce(x, y, keyIndex);
+ if (DEBUG_MOVE) Log.i(TAG, "isMinorMoveBounce=" +isMinorMoveBounce + " oldKey=" + (oldKey== null ? "null" : oldKey));
+ if (oldKey == null) {
+ // The pointer has been slid in to the new key, but the finger was not on any keys.
+ // In this case, we must call onPress() to notify that the new key is being pressed.
+ if (mListener != null) {
+ Key key = getKey(keyIndex);
+ if (key.codes != null) mListener.onPress(key.getPrimaryCode());
+ // This onPress call may have changed keyboard layout. Those cases are detected
+ // at {@link #setKeyboard}. In those cases, we should update keyIndex according
+ // to the new keyboard layout.
+ if (mKeyboardLayoutHasBeenChanged) {
+ mKeyboardLayoutHasBeenChanged = false;
+ keyIndex = keyState.onMoveKey(x, y);
+ }
+ }
+ keyState.onMoveToNewKey(keyIndex, x, y);
+ startLongPressTimer(keyIndex);
+ } else if (!isMinorMoveBounce) {
+ // The pointer has been slid in to the new key from the previous key, we must call
+ // onRelease() first to notify that the previous key has been released, then call
+ // onPress() to notify that the new key is being pressed.
+ mIsInSlidingKeyInput = true;
+ if (mListener != null && oldKey.codes != null)
+ mListener.onRelease(oldKey.getPrimaryCode());
+ resetMultiTap();
+ if (mListener != null) {
+ Key key = getKey(keyIndex);
+ if (key.codes != null) mListener.onPress(key.getPrimaryCode());
+ // This onPress call may have changed keyboard layout. Those cases are detected
+ // at {@link #setKeyboard}. In those cases, we should update keyIndex according
+ // to the new keyboard layout.
+ if (mKeyboardLayoutHasBeenChanged) {
+ mKeyboardLayoutHasBeenChanged = false;
+ keyIndex = keyState.onMoveKey(x, y);
+ }
+ addSlideKey(oldKey);
+ }
+ keyState.onMoveToNewKey(keyIndex, x, y);
+ startLongPressTimer(keyIndex);
+ }
+ } else {
+ if (oldKey != null && !isMinorMoveBounce(x, y, keyIndex)) {
+ // The pointer has been slid out from the previous key, we must call onRelease() to
+ // notify that the previous key has been released.
+ mIsInSlidingKeyInput = true;
+ if (mListener != null && oldKey.codes != null)
+ mListener.onRelease(oldKey.getPrimaryCode());
+ resetMultiTap();
+ keyState.onMoveToNewKey(keyIndex, x ,y);
+ mHandler.cancelLongPressTimer();
+ }
+ }
+ showKeyPreviewAndUpdateKey(keyState.getKeyIndex());
+ }
+
+ public void onUpEvent(int x, int y, long eventTime) {
+ if (DEBUG)
+ debugLog("onUpEvent :", x, y);
+ mHandler.cancelKeyTimers();
+ mHandler.cancelPopupPreview();
+ showKeyPreviewAndUpdateKey(NOT_A_KEY);
+ mIsInSlidingKeyInput = false;
+ sendSlideKeys();
+ if (mKeyAlreadyProcessed)
+ return;
+ int keyIndex = mKeyState.onUpKey(x, y);
+ if (isMinorMoveBounce(x, y, keyIndex)) {
+ // Use previous fixed key index and coordinates.
+ keyIndex = mKeyState.getKeyIndex();
+ x = mKeyState.getKeyX();
+ y = mKeyState.getKeyY();
+ }
+ if (!mIsRepeatableKey) {
+ detectAndSendKey(keyIndex, x, y, eventTime);
+ }
+
+ if (isValidKeyIndex(keyIndex))
+ mProxy.invalidateKey(mKeys[keyIndex]);
+ }
+
+ public void onCancelEvent(int x, int y, long eventTime) {
+ if (DEBUG)
+ debugLog("onCancelEvt:", x, y);
+ mHandler.cancelKeyTimers();
+ mHandler.cancelPopupPreview();
+ showKeyPreviewAndUpdateKey(NOT_A_KEY);
+ mIsInSlidingKeyInput = false;
+ int keyIndex = mKeyState.getKeyIndex();
+ if (isValidKeyIndex(keyIndex))
+ mProxy.invalidateKey(mKeys[keyIndex]);
+ }
+
+ public void repeatKey(int keyIndex) {
+ Key key = getKey(keyIndex);
+ if (key != null) {
+ // While key is repeating, because there is no need to handle multi-tap key, we can
+ // pass -1 as eventTime argument.
+ detectAndSendKey(keyIndex, key.x, key.y, -1);
+ }
+ }
+
+ public int getLastX() {
+ return mKeyState.getLastX();
+ }
+
+ public int getLastY() {
+ return mKeyState.getLastY();
+ }
+
+ public long getDownTime() {
+ return mKeyState.getDownTime();
+ }
+
+ // These package scope methods are only for debugging purpose.
+ /* package */ int getStartX() {
+ return mKeyState.getStartX();
+ }
+
+ /* package */ int getStartY() {
+ return mKeyState.getStartY();
+ }
+
+ private boolean isMinorMoveBounce(int x, int y, int newKey) {
+ if (mKeys == null || mKeyHysteresisDistanceSquared < 0)
+ throw new IllegalStateException("keyboard and/or hysteresis not set");
+ int curKey = mKeyState.getKeyIndex();
+ if (newKey == curKey) {
+ return true;
+ } else if (isValidKeyIndex(curKey)) {
+ //return false; // TODO(klausw): tweak this?
+ return getSquareDistanceToKeyEdge(x, y, mKeys[curKey]) < mKeyHysteresisDistanceSquared;
+ } else {
+ return false;
+ }
+ }
+
+ private static int getSquareDistanceToKeyEdge(int x, int y, Key key) {
+ final int left = key.x;
+ final int right = key.x + key.width;
+ final int top = key.y;
+ final int bottom = key.y + key.height;
+ final int edgeX = x < left ? left : (x > right ? right : x);
+ final int edgeY = y < top ? top : (y > bottom ? bottom : y);
+ final int dx = x - edgeX;
+ final int dy = y - edgeY;
+ return dx * dx + dy * dy;
+ }
+
+ private void showKeyPreviewAndUpdateKey(int keyIndex) {
+ updateKey(keyIndex);
+ // The modifier key, such as shift key, should not be shown as preview when multi-touch is
+ // supported. On the other hand, if multi-touch is not supported, the modifier key should
+ // be shown as preview.
+ if (mHasDistinctMultitouch && isModifier()) {
+ mProxy.showPreview(NOT_A_KEY, this);
+ } else {
+ mProxy.showPreview(keyIndex, this);
+ }
+ }
+
+ private void startLongPressTimer(int keyIndex) {
+ if (mKeyboardSwitcher.isInMomentaryAutoModeSwitchState()) {
+ // We use longer timeout for sliding finger input started from the symbols mode key.
+ mHandler.startLongPressTimer(LatinIME.sKeyboardSettings.longpressTimeout * 3, keyIndex, this);
+ } else {
+ mHandler.startLongPressTimer(LatinIME.sKeyboardSettings.longpressTimeout, keyIndex, this);
+ }
+ }
+
+ private void detectAndSendKey(int index, int x, int y, long eventTime) {
+ detectAndSendKey(getKey(index), x, y, eventTime);
+ mLastSentIndex = index;
+ }
+
+ private void detectAndSendKey(Key key, int x, int y, long eventTime) {
+ final OnKeyboardActionListener listener = mListener;
+
+ if (key == null) {
+ if (listener != null)
+ listener.onCancel();
+ } else {
+ if (key.text != null) {
+ if (listener != null) {
+ listener.onText(key.text);
+ listener.onRelease(0); // dummy key code
+ }
+ } else {
+ if (key.codes == null) return;
+ int code = key.getPrimaryCode();
+ int[] codes = mKeyDetector.newCodeArray();
+ mKeyDetector.getKeyIndexAndNearbyCodes(x, y, codes);
+ // Multi-tap
+ if (mInMultiTap) {
+ if (mTapCount != -1) {
+ mListener.onKey(Keyboard.KEYCODE_DELETE, KEY_DELETE, x, y);
+ } else {
+ mTapCount = 0;
+ }
+ code = key.codes[mTapCount];
+ }
+ /*
+ * Swap the first and second values in the codes array if the primary code is not
+ * the first value but the second value in the array. This happens when key
+ * debouncing is in effect.
+ */
+ if (codes.length >= 2 && codes[0] != code && codes[1] == code) {
+ codes[1] = codes[0];
+ codes[0] = code;
+ }
+ if (listener != null) {
+ listener.onKey(code, codes, x, y);
+ listener.onRelease(code);
+ }
+ }
+ mLastTapTime = eventTime;
+ }
+ }
+
+ /**
+ * Handle multi-tap keys by producing the key label for the current multi-tap state.
+ */
+ public CharSequence getPreviewText(Key key) {
+ if (mInMultiTap) {
+ // Multi-tap
+ mPreviewLabel.setLength(0);
+ mPreviewLabel.append((char) key.codes[mTapCount < 0 ? 0 : mTapCount]);
+ return mPreviewLabel;
+ } else {
+ if (key.isDeadKey()) {
+ return DeadAccentSequence.normalize(" " + key.label);
+ } else {
+ return key.label;
+ }
+ }
+ }
+
+ private void resetMultiTap() {
+ mLastSentIndex = NOT_A_KEY;
+ mTapCount = 0;
+ mLastTapTime = -1;
+ mInMultiTap = false;
+ }
+
+ private void checkMultiTap(long eventTime, int keyIndex) {
+ Key key = getKey(keyIndex);
+ if (key == null || key.codes == null)
+ return;
+
+ final boolean isMultiTap =
+ (eventTime < mLastTapTime + mMultiTapKeyTimeout && keyIndex == mLastSentIndex);
+ if (key.codes.length > 1) {
+ mInMultiTap = true;
+ if (isMultiTap) {
+ mTapCount = (mTapCount + 1) % key.codes.length;
+ return;
+ } else {
+ mTapCount = -1;
+ return;
+ }
+ }
+ if (!isMultiTap) {
+ resetMultiTap();
+ }
+ }
+
+ private void debugLog(String title, int x, int y) {
+ int keyIndex = mKeyDetector.getKeyIndexAndNearbyCodes(x, y, null);
+ Key key = getKey(keyIndex);
+ final String code;
+ if (key == null || key.codes == null) {
+ code = "----";
+ } else {
+ int primaryCode = key.codes[0];
+ code = String.format((primaryCode < 0) ? "%4d" : "0x%02x", primaryCode);
+ }
+ Log.d(TAG, String.format("%s%s[%d] %3d,%3d %3d(%s) %s", title,
+ (mKeyAlreadyProcessed ? "-" : " "), mPointerId, x, y, keyIndex, code,
+ (isModifier() ? "modifier" : "")));
+ }
+}
diff --git a/java/src/org/pocketworkstation/pckeyboard/PrefScreenActions.java b/java/src/org/pocketworkstation/pckeyboard/PrefScreenActions.java
new file mode 100644
index 0000000..56da49b
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/PrefScreenActions.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.pocketworkstation.pckeyboard;
+
+import android.app.backup.BackupManager;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.PreferenceActivity;
+
+public class PrefScreenActions extends PreferenceActivity
+ implements SharedPreferences.OnSharedPreferenceChangeListener {
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ addPreferencesFromResource(R.xml.prefs_actions);
+ SharedPreferences prefs = getPreferenceManager().getSharedPreferences();
+ prefs.registerOnSharedPreferenceChangeListener(this);
+ }
+
+ @Override
+ protected void onDestroy() {
+ getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(
+ this);
+ super.onDestroy();
+ }
+
+ public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
+ (new BackupManager(this)).dataChanged();
+ }
+}
diff --git a/java/src/org/pocketworkstation/pckeyboard/PrefScreenFeedback.java b/java/src/org/pocketworkstation/pckeyboard/PrefScreenFeedback.java
new file mode 100644
index 0000000..dfd3015
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/PrefScreenFeedback.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.pocketworkstation.pckeyboard;
+
+import android.app.backup.BackupManager;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.ListPreference;
+import android.preference.PreferenceActivity;
+
+public class PrefScreenFeedback extends PreferenceActivity
+ implements SharedPreferences.OnSharedPreferenceChangeListener {
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ addPreferencesFromResource(R.xml.prefs_feedback);
+ SharedPreferences prefs = getPreferenceManager().getSharedPreferences();
+ prefs.registerOnSharedPreferenceChangeListener(this);
+ }
+
+ @Override
+ protected void onDestroy() {
+ getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(
+ this);
+ super.onDestroy();
+ }
+
+ public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
+ (new BackupManager(this)).dataChanged();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ }
+}
diff --git a/java/src/org/pocketworkstation/pckeyboard/PrefScreenView.java b/java/src/org/pocketworkstation/pckeyboard/PrefScreenView.java
new file mode 100644
index 0000000..580ecd8
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/PrefScreenView.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.pocketworkstation.pckeyboard;
+
+import android.app.backup.BackupManager;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.ListPreference;
+import android.preference.PreferenceActivity;
+
+public class PrefScreenView extends PreferenceActivity
+ implements SharedPreferences.OnSharedPreferenceChangeListener {
+
+ private ListPreference mRenderModePreference;
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ addPreferencesFromResource(R.xml.prefs_view);
+ SharedPreferences prefs = getPreferenceManager().getSharedPreferences();
+ prefs.registerOnSharedPreferenceChangeListener(this);
+ mRenderModePreference = (ListPreference) findPreference(LatinIME.PREF_RENDER_MODE);
+ }
+
+ @Override
+ protected void onDestroy() {
+ getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(
+ this);
+ super.onDestroy();
+ }
+
+ public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
+ (new BackupManager(this)).dataChanged();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ if (LatinKeyboardBaseView.sSetRenderMode == null) {
+ mRenderModePreference.setEnabled(false);
+ mRenderModePreference.setSummary(R.string.render_mode_unavailable);
+ }
+
+ }
+}
diff --git a/java/src/org/pocketworkstation/pckeyboard/ProximityKeyDetector.java b/java/src/org/pocketworkstation/pckeyboard/ProximityKeyDetector.java
new file mode 100644
index 0000000..18f04fa
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/ProximityKeyDetector.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.pocketworkstation.pckeyboard;
+
+import org.pocketworkstation.pckeyboard.Keyboard.Key;
+
+import java.util.Arrays;
+
+class ProximityKeyDetector extends KeyDetector {
+ private static final int MAX_NEARBY_KEYS = 12;
+
+ // working area
+ private int[] mDistances = new int[MAX_NEARBY_KEYS];
+
+ @Override
+ protected int getMaxNearbyKeys() {
+ return MAX_NEARBY_KEYS;
+ }
+
+ @Override
+ public int getKeyIndexAndNearbyCodes(int x, int y, int[] allKeys) {
+ final Key[] keys = getKeys();
+ final int touchX = getTouchX(x);
+ final int touchY = getTouchY(y);
+ int primaryIndex = LatinKeyboardBaseView.NOT_A_KEY;
+ int closestKey = LatinKeyboardBaseView.NOT_A_KEY;
+ int closestKeyDist = mProximityThresholdSquare + 1;
+ int[] distances = mDistances;
+ Arrays.fill(distances, Integer.MAX_VALUE);
+ int [] nearestKeyIndices = mKeyboard.getNearestKeys(touchX, touchY);
+ final int keyCount = nearestKeyIndices.length;
+ for (int i = 0; i < keyCount; i++) {
+ final Key key = keys[nearestKeyIndices[i]];
+ int dist = 0;
+ boolean isInside = key.isInside(touchX, touchY);
+ if (isInside) {
+ primaryIndex = nearestKeyIndices[i];
+ }
+
+ if (((mProximityCorrectOn
+ && (dist = key.squaredDistanceFrom(touchX, touchY)) < mProximityThresholdSquare)
+ || isInside)
+ && key.codes[0] > 32) {
+ // Find insertion point
+ final int nCodes = key.codes.length;
+ if (dist < closestKeyDist) {
+ closestKeyDist = dist;
+ closestKey = nearestKeyIndices[i];
+ }
+
+ if (allKeys == null) continue;
+
+ for (int j = 0; j < distances.length; j++) {
+ if (distances[j] > dist) {
+ // Make space for nCodes codes
+ System.arraycopy(distances, j, distances, j + nCodes,
+ distances.length - j - nCodes);
+ System.arraycopy(allKeys, j, allKeys, j + nCodes,
+ allKeys.length - j - nCodes);
+ System.arraycopy(key.codes, 0, allKeys, j, nCodes);
+ Arrays.fill(distances, j, j + nCodes, dist);
+ break;
+ }
+ }
+ }
+ }
+ if (primaryIndex == LatinKeyboardBaseView.NOT_A_KEY) {
+ primaryIndex = closestKey;
+ }
+ return primaryIndex;
+ }
+}
diff --git a/java/src/org/pocketworkstation/pckeyboard/SeekBarPreference.java b/java/src/org/pocketworkstation/pckeyboard/SeekBarPreference.java
new file mode 100644
index 0000000..0ecf254
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/SeekBarPreference.java
@@ -0,0 +1,166 @@
+package org.pocketworkstation.pckeyboard;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.preference.DialogPreference;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.SeekBar;
+import android.widget.TextView;
+
+/**
+ * SeekBarPreference provides a dialog for editing float-valued preferences with a slider.
+ */
+public class SeekBarPreference extends DialogPreference {
+
+ private TextView mMinText;
+ private TextView mMaxText;
+ private TextView mValText;
+ private SeekBar mSeek;
+ private float mMin;
+ private float mMax;
+ private float mVal;
+ private float mPrevVal;
+ private float mStep;
+ private boolean mAsPercent;
+ private boolean mLogScale;
+ private String mDisplayFormat;
+
+ public SeekBarPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init(context, attrs);
+ }
+
+ protected void init(Context context, AttributeSet attrs) {
+ setDialogLayoutResource(R.layout.seek_bar_dialog);
+
+ TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SeekBarPreference);
+ mMin = a.getFloat(R.styleable.SeekBarPreference_minValue, 0.0f);
+ mMax = a.getFloat(R.styleable.SeekBarPreference_maxValue, 100.0f);
+ mStep = a.getFloat(R.styleable.SeekBarPreference_step, 0.0f);
+ mAsPercent = a.getBoolean(R.styleable.SeekBarPreference_asPercent, false);
+ mLogScale = a.getBoolean(R.styleable.SeekBarPreference_logScale, false);
+ mDisplayFormat = a.getString(R.styleable.SeekBarPreference_displayFormat);
+ }
+
+ @Override
+ protected Float onGetDefaultValue(TypedArray a, int index) {
+ return a.getFloat(index, 0.0f);
+ }
+
+ @Override
+ protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) {
+ if (restorePersistedValue) {
+ setVal(getPersistedFloat(0.0f));
+ } else {
+ setVal((Float) defaultValue);
+ }
+ savePrevVal();
+ }
+
+ private String formatFloatDisplay(Float val) {
+ // Use current locale for format, this is for display only.
+ if (mAsPercent) {
+ return String.format("%d%%", (int) (val * 100));
+ }
+
+ if (mDisplayFormat != null) {
+ return String.format(mDisplayFormat, val);
+ } else {
+ return Float.toString(val);
+ }
+ }
+
+ private void showVal() {
+ mValText.setText(formatFloatDisplay(mVal));
+ }
+
+ protected void setVal(Float val) {
+ mVal = val;
+ }
+
+ protected void savePrevVal() {
+ mPrevVal = mVal;
+ }
+
+ protected void restoreVal() {
+ mVal = mPrevVal;
+ }
+
+ protected String getValString() {
+ return Float.toString(mVal);
+ }
+
+ private float percentToSteppedVal(int percent, float min, float max, float step, boolean logScale) {
+ float val;
+ if (logScale) {
+ val = (float) Math.exp(percentToSteppedVal(percent, (float) Math.log(min), (float) Math.log(max), step, false));
+ } else {
+ float delta = percent * (max - min) / 100;
+ if (step != 0.0f) {
+ delta = Math.round(delta / step) * step;
+ }
+ val = min + delta;
+ }
+ // Hack: Round number to 2 significant digits so that it looks nicer.
+ val = Float.valueOf(String.format("%.2g", val));
+ return val;
+ }
+
+ private int getPercent(float val, float min, float max) {
+ return (int) (100 * (val - min) / (max - min));
+ }
+
+ private int getProgressVal() {
+ if (mLogScale) {
+ return getPercent((float) Math.log(mVal), (float) Math.log(mMin), (float) Math.log(mMax));
+ } else {
+ return getPercent(mVal, mMin, mMax);
+ }
+ }
+
+ @Override
+ protected void onBindDialogView(View view) {
+ mSeek = (SeekBar) view.findViewById(R.id.seekBarPref);
+ mMinText = (TextView) view.findViewById(R.id.seekMin);
+ mMaxText = (TextView) view.findViewById(R.id.seekMax);
+ mValText = (TextView) view.findViewById(R.id.seekVal);
+
+ showVal();
+ mMinText.setText(formatFloatDisplay(mMin));
+ mMaxText.setText(formatFloatDisplay(mMax));
+ mSeek.setProgress(getProgressVal());
+
+ mSeek.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+ public void onStopTrackingTouch(SeekBar seekBar) {}
+ public void onStartTrackingTouch(SeekBar seekBar) {}
+ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+ if (fromUser) {
+ setVal(percentToSteppedVal(progress, mMin, mMax, mStep, mLogScale));
+ mSeek.setProgress(getProgressVal());
+ }
+ showVal();
+ }
+ });
+
+ super.onBindDialogView(view);
+ }
+
+ @Override
+ public CharSequence getSummary() {
+ return formatFloatDisplay(mVal);
+ }
+
+ @Override
+ protected void onDialogClosed(boolean positiveResult) {
+ if (!positiveResult) {
+ restoreVal();
+ return;
+ }
+ if (shouldPersist()) {
+ persistFloat(mVal);
+ savePrevVal();
+ }
+ notifyChanged();
+ }
+}
diff --git a/java/src/org/pocketworkstation/pckeyboard/SeekBarPreferenceString.java b/java/src/org/pocketworkstation/pckeyboard/SeekBarPreferenceString.java
new file mode 100644
index 0000000..b96cef1
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/SeekBarPreferenceString.java
@@ -0,0 +1,59 @@
+package org.pocketworkstation.pckeyboard;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.util.AttributeSet;
+
+/**
+ * Variant of SeekBarPreference that stores values as string preferences.
+ *
+ * This is for compatibility with existing preferences, switching types
+ * leads to runtime errors when upgrading or downgrading.
+ */
+public class SeekBarPreferenceString extends SeekBarPreference {
+
+ private static Pattern FLOAT_RE = Pattern.compile("(\\d+\\.?\\d*).*");
+
+ public SeekBarPreferenceString(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init(context, attrs);
+ }
+
+ // Some saved preferences from old versions have " ms" or "%" suffix, remove that.
+ private float floatFromString(String pref) {
+ Matcher num = FLOAT_RE.matcher(pref);
+ if (!num.matches()) return 0.0f;
+ return Float.valueOf(num.group(1));
+ }
+
+ @Override
+ protected Float onGetDefaultValue(TypedArray a, int index) {
+ return floatFromString(a.getString(index));
+ }
+
+ @Override
+ protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) {
+ if (restorePersistedValue) {
+ setVal(floatFromString(getPersistedString("0.0")));
+ } else {
+ setVal(Float.valueOf((Float) defaultValue));
+ }
+ savePrevVal();
+ }
+
+ @Override
+ protected void onDialogClosed(boolean positiveResult) {
+ if (!positiveResult) {
+ restoreVal();
+ return;
+ }
+ if (shouldPersist()) {
+ savePrevVal();
+ persistString(getValString());
+ }
+ notifyChanged();
+ }
+} \ No newline at end of file
diff --git a/java/src/org/pocketworkstation/pckeyboard/SharedPreferencesCompat.java b/java/src/org/pocketworkstation/pckeyboard/SharedPreferencesCompat.java
new file mode 100644
index 0000000..75c4640
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/SharedPreferencesCompat.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.pocketworkstation.pckeyboard;
+
+import android.content.SharedPreferences;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * Reflection utils to call SharedPreferences$Editor.apply when possible,
+ * falling back to commit when apply isn't available.
+ */
+public class SharedPreferencesCompat {
+ private static final Method sApplyMethod = findApplyMethod();
+
+ private static Method findApplyMethod() {
+ try {
+ return SharedPreferences.Editor.class.getMethod("apply");
+ } catch (NoSuchMethodException unused) {
+ // fall through
+ }
+ return null;
+ }
+
+ public static void apply(SharedPreferences.Editor editor) {
+ if (sApplyMethod != null) {
+ try {
+ sApplyMethod.invoke(editor);
+ return;
+ } catch (InvocationTargetException unused) {
+ // fall through
+ } catch (IllegalAccessException unused) {
+ // fall through
+ }
+ }
+ editor.commit();
+ }
+}
diff --git a/java/src/org/pocketworkstation/pckeyboard/Suggest.java b/java/src/org/pocketworkstation/pckeyboard/Suggest.java
new file mode 100755
index 0000000..b5026a1
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/Suggest.java
@@ -0,0 +1,544 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.pocketworkstation.pckeyboard;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale;
+
+import android.content.Context;
+import android.text.AutoText;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.View;
+
+/**
+ * This class loads a dictionary and provides a list of suggestions for a given sequence of
+ * characters. This includes corrections and completions.
+ * @hide pending API Council Approval
+ */
+public class Suggest implements Dictionary.WordCallback {
+ private static String TAG = "PCKeyboard";
+
+ public static final int APPROX_MAX_WORD_LENGTH = 32;
+
+ public static final int CORRECTION_NONE = 0;
+ public static final int CORRECTION_BASIC = 1;
+ public static final int CORRECTION_FULL = 2;
+ public static final int CORRECTION_FULL_BIGRAM = 3;
+
+ /**
+ * Words that appear in both bigram and unigram data gets multiplier ranging from
+ * BIGRAM_MULTIPLIER_MIN to BIGRAM_MULTIPLIER_MAX depending on the frequency score from
+ * bigram data.
+ */
+ public static final double BIGRAM_MULTIPLIER_MIN = 1.2;
+ public static final double BIGRAM_MULTIPLIER_MAX = 1.5;
+
+ /**
+ * Maximum possible bigram frequency. Will depend on how many bits are being used in data
+ * structure. Maximum bigram freqeuncy will get the BIGRAM_MULTIPLIER_MAX as the multiplier.
+ */
+ public static final int MAXIMUM_BIGRAM_FREQUENCY = 127;
+
+ public static final int DIC_USER_TYPED = 0;
+ public static final int DIC_MAIN = 1;
+ public static final int DIC_USER = 2;
+ public static final int DIC_AUTO = 3;
+ public static final int DIC_CONTACTS = 4;
+ // If you add a type of dictionary, increment DIC_TYPE_LAST_ID
+ public static final int DIC_TYPE_LAST_ID = 4;
+
+ static final int LARGE_DICTIONARY_THRESHOLD = 200 * 1000;
+
+ private BinaryDictionary mMainDict;
+
+ private Dictionary mUserDictionary;
+
+ private Dictionary mAutoDictionary;
+
+ private Dictionary mContactsDictionary;
+
+ private Dictionary mUserBigramDictionary;
+
+ private int mPrefMaxSuggestions = 12;
+
+ private static final int PREF_MAX_BIGRAMS = 60;
+
+ private boolean mAutoTextEnabled;
+
+ private int[] mPriorities = new int[mPrefMaxSuggestions];
+ private int[] mBigramPriorities = new int[PREF_MAX_BIGRAMS];
+
+ // Handle predictive correction for only the first 1280 characters for performance reasons
+ // If we support scripts that need latin characters beyond that, we should probably use some
+ // kind of a sparse array or language specific list with a mapping lookup table.
+ // 1280 is the size of the BASE_CHARS array in ExpandableDictionary, which is a basic set of
+ // latin characters.
+ private int[] mNextLettersFrequencies = new int[1280];
+ private ArrayList<CharSequence> mSuggestions = new ArrayList<CharSequence>();
+ ArrayList<CharSequence> mBigramSuggestions = new ArrayList<CharSequence>();
+ private ArrayList<CharSequence> mStringPool = new ArrayList<CharSequence>();
+ private boolean mHaveCorrection;
+ private CharSequence mOriginalWord;
+ private String mLowerOriginalWord;
+
+ // TODO: Remove these member variables by passing more context to addWord() callback method
+ private boolean mIsFirstCharCapitalized;
+ private boolean mIsAllUpperCase;
+
+ private int mCorrectionMode = CORRECTION_BASIC;
+
+ public Suggest(Context context, int[] dictionaryResId) {
+ mMainDict = new BinaryDictionary(context, dictionaryResId, DIC_MAIN);
+ if (!hasMainDictionary()) {
+ Locale locale = context.getResources().getConfiguration().locale;
+ BinaryDictionary plug = PluginManager.getDictionary(context, locale.getLanguage());
+ if (plug != null) {
+ mMainDict.close();
+ mMainDict = plug;
+ }
+ }
+ initPool();
+ }
+
+ public Suggest(Context context, ByteBuffer byteBuffer) {
+ mMainDict = new BinaryDictionary(context, byteBuffer, DIC_MAIN);
+ initPool();
+ }
+
+ private void initPool() {
+ for (int i = 0; i < mPrefMaxSuggestions; i++) {
+ StringBuilder sb = new StringBuilder(getApproxMaxWordLength());
+ mStringPool.add(sb);
+ }
+ }
+
+ public void setAutoTextEnabled(boolean enabled) {
+ mAutoTextEnabled = enabled;
+ }
+
+ public int getCorrectionMode() {
+ return mCorrectionMode;
+ }
+
+ public void setCorrectionMode(int mode) {
+ mCorrectionMode = mode;
+ }
+
+ public boolean hasMainDictionary() {
+ return mMainDict.getSize() > LARGE_DICTIONARY_THRESHOLD;
+ }
+
+ public int getApproxMaxWordLength() {
+ return APPROX_MAX_WORD_LENGTH;
+ }
+
+ /**
+ * Sets an optional user dictionary resource to be loaded. The user dictionary is consulted
+ * before the main dictionary, if set.
+ */
+ public void setUserDictionary(Dictionary userDictionary) {
+ mUserDictionary = userDictionary;
+ }
+
+ /**
+ * Sets an optional contacts dictionary resource to be loaded.
+ */
+ public void setContactsDictionary(Dictionary userDictionary) {
+ mContactsDictionary = userDictionary;
+ }
+
+ public void setAutoDictionary(Dictionary autoDictionary) {
+ mAutoDictionary = autoDictionary;
+ }
+
+ public void setUserBigramDictionary(Dictionary userBigramDictionary) {
+ mUserBigramDictionary = userBigramDictionary;
+ }
+
+ /**
+ * Number of suggestions to generate from the input key sequence. This has
+ * to be a number between 1 and 100 (inclusive).
+ * @param maxSuggestions
+ * @throws IllegalArgumentException if the number is out of range
+ */
+ public void setMaxSuggestions(int maxSuggestions) {
+ if (maxSuggestions < 1 || maxSuggestions > 100) {
+ throw new IllegalArgumentException("maxSuggestions must be between 1 and 100");
+ }
+ mPrefMaxSuggestions = maxSuggestions;
+ mPriorities = new int[mPrefMaxSuggestions];
+ mBigramPriorities = new int[PREF_MAX_BIGRAMS];
+ collectGarbage(mSuggestions, mPrefMaxSuggestions);
+ while (mStringPool.size() < mPrefMaxSuggestions) {
+ StringBuilder sb = new StringBuilder(getApproxMaxWordLength());
+ mStringPool.add(sb);
+ }
+ }
+
+ private boolean haveSufficientCommonality(String original, CharSequence suggestion) {
+ final int originalLength = original.length();
+ final int suggestionLength = suggestion.length();
+ final int minLength = Math.min(originalLength, suggestionLength);
+ if (minLength <= 2) return true;
+ int matching = 0;
+ int lessMatching = 0; // Count matches if we skip one character
+ int i;
+ for (i = 0; i < minLength; i++) {
+ final char origChar = ExpandableDictionary.toLowerCase(original.charAt(i));
+ if (origChar == ExpandableDictionary.toLowerCase(suggestion.charAt(i))) {
+ matching++;
+ lessMatching++;
+ } else if (i + 1 < suggestionLength
+ && origChar == ExpandableDictionary.toLowerCase(suggestion.charAt(i + 1))) {
+ lessMatching++;
+ }
+ }
+ matching = Math.max(matching, lessMatching);
+
+ if (minLength <= 4) {
+ return matching >= 2;
+ } else {
+ return matching > minLength / 2;
+ }
+ }
+
+ /**
+ * Returns a list of words that match the list of character codes passed in.
+ * This list will be overwritten the next time this function is called.
+ * @param view a view for retrieving the context for AutoText
+ * @param wordComposer contains what is currently being typed
+ * @param prevWordForBigram previous word (used only for bigram)
+ * @return list of suggestions.
+ */
+ public List<CharSequence> getSuggestions(View view, WordComposer wordComposer,
+ boolean includeTypedWordIfValid, CharSequence prevWordForBigram) {
+ LatinImeLogger.onStartSuggestion(prevWordForBigram);
+ mHaveCorrection = false;
+ mIsFirstCharCapitalized = wordComposer.isFirstCharCapitalized();
+ mIsAllUpperCase = wordComposer.isAllUpperCase();
+ collectGarbage(mSuggestions, mPrefMaxSuggestions);
+ Arrays.fill(mPriorities, 0);
+ Arrays.fill(mNextLettersFrequencies, 0);
+
+ // Save a lowercase version of the original word
+ mOriginalWord = wordComposer.getTypedWord();
+ if (mOriginalWord != null) {
+ final String mOriginalWordString = mOriginalWord.toString();
+ mOriginalWord = mOriginalWordString;
+ mLowerOriginalWord = mOriginalWordString.toLowerCase();
+ // Treating USER_TYPED as UNIGRAM suggestion for logging now.
+ LatinImeLogger.onAddSuggestedWord(mOriginalWordString, Suggest.DIC_USER_TYPED,
+ Dictionary.DataType.UNIGRAM);
+ } else {
+ mLowerOriginalWord = "";
+ }
+
+ if (wordComposer.size() == 1 && (mCorrectionMode == CORRECTION_FULL_BIGRAM
+ || mCorrectionMode == CORRECTION_BASIC)) {
+ // At first character typed, search only the bigrams
+ Arrays.fill(mBigramPriorities, 0);
+ collectGarbage(mBigramSuggestions, PREF_MAX_BIGRAMS);
+
+ if (!TextUtils.isEmpty(prevWordForBigram)) {
+ CharSequence lowerPrevWord = prevWordForBigram.toString().toLowerCase();
+ if (mMainDict.isValidWord(lowerPrevWord)) {
+ prevWordForBigram = lowerPrevWord;
+ }
+ if (mUserBigramDictionary != null) {
+ mUserBigramDictionary.getBigrams(wordComposer, prevWordForBigram, this,
+ mNextLettersFrequencies);
+ }
+ if (mContactsDictionary != null) {
+ mContactsDictionary.getBigrams(wordComposer, prevWordForBigram, this,
+ mNextLettersFrequencies);
+ }
+ if (mMainDict != null) {
+ mMainDict.getBigrams(wordComposer, prevWordForBigram, this,
+ mNextLettersFrequencies);
+ }
+ char currentChar = wordComposer.getTypedWord().charAt(0);
+ char currentCharUpper = Character.toUpperCase(currentChar);
+ int count = 0;
+ int bigramSuggestionSize = mBigramSuggestions.size();
+ for (int i = 0; i < bigramSuggestionSize; i++) {
+ if (mBigramSuggestions.get(i).charAt(0) == currentChar
+ || mBigramSuggestions.get(i).charAt(0) == currentCharUpper) {
+ int poolSize = mStringPool.size();
+ StringBuilder sb = poolSize > 0 ?
+ (StringBuilder) mStringPool.remove(poolSize - 1)
+ : new StringBuilder(getApproxMaxWordLength());
+ sb.setLength(0);
+ sb.append(mBigramSuggestions.get(i));
+ mSuggestions.add(count++, sb);
+ if (count > mPrefMaxSuggestions) break;
+ }
+ }
+ }
+
+ } else if (wordComposer.size() > 1) {
+ // At second character typed, search the unigrams (scores being affected by bigrams)
+ if (mUserDictionary != null || mContactsDictionary != null) {
+ if (mUserDictionary != null) {
+ mUserDictionary.getWords(wordComposer, this, mNextLettersFrequencies);
+ }
+ if (mContactsDictionary != null) {
+ mContactsDictionary.getWords(wordComposer, this, mNextLettersFrequencies);
+ }
+
+ if (mSuggestions.size() > 0 && isValidWord(mOriginalWord)
+ && (mCorrectionMode == CORRECTION_FULL
+ || mCorrectionMode == CORRECTION_FULL_BIGRAM)) {
+ mHaveCorrection = true;
+ }
+ }
+ mMainDict.getWords(wordComposer, this, mNextLettersFrequencies);
+ if ((mCorrectionMode == CORRECTION_FULL || mCorrectionMode == CORRECTION_FULL_BIGRAM)
+ && mSuggestions.size() > 0) {
+ mHaveCorrection = true;
+ }
+ }
+ if (mOriginalWord != null) {
+ mSuggestions.add(0, mOriginalWord.toString());
+ }
+
+ // Check if the first suggestion has a minimum number of characters in common
+ if (wordComposer.size() > 1 && mSuggestions.size() > 1
+ && (mCorrectionMode == CORRECTION_FULL
+ || mCorrectionMode == CORRECTION_FULL_BIGRAM)) {
+ if (!haveSufficientCommonality(mLowerOriginalWord, mSuggestions.get(1))) {
+ mHaveCorrection = false;
+ }
+ }
+ if (mAutoTextEnabled) {
+ int i = 0;
+ int max = 6;
+ // Don't autotext the suggestions from the dictionaries
+ if (mCorrectionMode == CORRECTION_BASIC) max = 1;
+ while (i < mSuggestions.size() && i < max) {
+ String suggestedWord = mSuggestions.get(i).toString().toLowerCase();
+ CharSequence autoText =
+ AutoText.get(suggestedWord, 0, suggestedWord.length(), view);
+ // Is there an AutoText correction?
+ boolean canAdd = autoText != null;
+ // Is that correction already the current prediction (or original word)?
+ canAdd &= !TextUtils.equals(autoText, mSuggestions.get(i));
+ // Is that correction already the next predicted word?
+ if (canAdd && i + 1 < mSuggestions.size() && mCorrectionMode != CORRECTION_BASIC) {
+ canAdd &= !TextUtils.equals(autoText, mSuggestions.get(i + 1));
+ }
+ if (canAdd) {
+ mHaveCorrection = true;
+ mSuggestions.add(i + 1, autoText);
+ i++;
+ }
+ i++;
+ }
+ }
+ removeDupes();
+ return mSuggestions;
+ }
+
+ public int[] getNextLettersFrequencies() {
+ return mNextLettersFrequencies;
+ }
+
+ private void removeDupes() {
+ final ArrayList<CharSequence> suggestions = mSuggestions;
+ if (suggestions.size() < 2) return;
+ int i = 1;
+ // Don't cache suggestions.size(), since we may be removing items
+ while (i < suggestions.size()) {
+ final CharSequence cur = suggestions.get(i);
+ // Compare each candidate with each previous candidate
+ for (int j = 0; j < i; j++) {
+ CharSequence previous = suggestions.get(j);
+ if (TextUtils.equals(cur, previous)) {
+ removeFromSuggestions(i);
+ i--;
+ break;
+ }
+ }
+ i++;
+ }
+ }
+
+ private void removeFromSuggestions(int index) {
+ CharSequence garbage = mSuggestions.remove(index);
+ if (garbage != null && garbage instanceof StringBuilder) {
+ mStringPool.add(garbage);
+ }
+ }
+
+ public boolean hasMinimalCorrection() {
+ return mHaveCorrection;
+ }
+
+ private boolean compareCaseInsensitive(final String mLowerOriginalWord,
+ final char[] word, final int offset, final int length) {
+ final int originalLength = mLowerOriginalWord.length();
+ if (originalLength == length && Character.isUpperCase(word[offset])) {
+ for (int i = 0; i < originalLength; i++) {
+ if (mLowerOriginalWord.charAt(i) != Character.toLowerCase(word[offset+i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ public boolean addWord(final char[] word, final int offset, final int length, int freq,
+ final int dicTypeId, final Dictionary.DataType dataType) {
+ Dictionary.DataType dataTypeForLog = dataType;
+ ArrayList<CharSequence> suggestions;
+ int[] priorities;
+ int prefMaxSuggestions;
+ if(dataType == Dictionary.DataType.BIGRAM) {
+ suggestions = mBigramSuggestions;
+ priorities = mBigramPriorities;
+ prefMaxSuggestions = PREF_MAX_BIGRAMS;
+ } else {
+ suggestions = mSuggestions;
+ priorities = mPriorities;
+ prefMaxSuggestions = mPrefMaxSuggestions;
+ }
+
+ int pos = 0;
+
+ // Check if it's the same word, only caps are different
+ if (compareCaseInsensitive(mLowerOriginalWord, word, offset, length)) {
+ pos = 0;
+ } else {
+ if (dataType == Dictionary.DataType.UNIGRAM) {
+ // Check if the word was already added before (by bigram data)
+ int bigramSuggestion = searchBigramSuggestion(word,offset,length);
+ if(bigramSuggestion >= 0) {
+ dataTypeForLog = Dictionary.DataType.BIGRAM;
+ // turn freq from bigram into multiplier specified above
+ double multiplier = (((double) mBigramPriorities[bigramSuggestion])
+ / MAXIMUM_BIGRAM_FREQUENCY)
+ * (BIGRAM_MULTIPLIER_MAX - BIGRAM_MULTIPLIER_MIN)
+ + BIGRAM_MULTIPLIER_MIN;
+ /* Log.d(TAG,"bigram num: " + bigramSuggestion
+ + " wordB: " + mBigramSuggestions.get(bigramSuggestion).toString()
+ + " currentPriority: " + freq + " bigramPriority: "
+ + mBigramPriorities[bigramSuggestion]
+ + " multiplier: " + multiplier); */
+ freq = (int)Math.round((freq * multiplier));
+ }
+ }
+
+ // Check the last one's priority and bail
+ if (priorities[prefMaxSuggestions - 1] >= freq) return true;
+ while (pos < prefMaxSuggestions) {
+ if (priorities[pos] < freq
+ || (priorities[pos] == freq && length < suggestions.get(pos).length())) {
+ break;
+ }
+ pos++;
+ }
+ }
+ if (pos >= prefMaxSuggestions) {
+ return true;
+ }
+
+ System.arraycopy(priorities, pos, priorities, pos + 1,
+ prefMaxSuggestions - pos - 1);
+ priorities[pos] = freq;
+ int poolSize = mStringPool.size();
+ StringBuilder sb = poolSize > 0 ? (StringBuilder) mStringPool.remove(poolSize - 1)
+ : new StringBuilder(getApproxMaxWordLength());
+ sb.setLength(0);
+ if (mIsAllUpperCase) {
+ sb.append(new String(word, offset, length).toUpperCase());
+ } else if (mIsFirstCharCapitalized) {
+ sb.append(Character.toUpperCase(word[offset]));
+ if (length > 1) {
+ sb.append(word, offset + 1, length - 1);
+ }
+ } else {
+ sb.append(word, offset, length);
+ }
+ suggestions.add(pos, sb);
+ if (suggestions.size() > prefMaxSuggestions) {
+ CharSequence garbage = suggestions.remove(prefMaxSuggestions);
+ if (garbage instanceof StringBuilder) {
+ mStringPool.add(garbage);
+ }
+ } else {
+ LatinImeLogger.onAddSuggestedWord(sb.toString(), dicTypeId, dataTypeForLog);
+ }
+ return true;
+ }
+
+ private int searchBigramSuggestion(final char[] word, final int offset, final int length) {
+ // TODO This is almost O(n^2). Might need fix.
+ // search whether the word appeared in bigram data
+ int bigramSuggestSize = mBigramSuggestions.size();
+ for(int i = 0; i < bigramSuggestSize; i++) {
+ if(mBigramSuggestions.get(i).length() == length) {
+ boolean chk = true;
+ for(int j = 0; j < length; j++) {
+ if(mBigramSuggestions.get(i).charAt(j) != word[offset+j]) {
+ chk = false;
+ break;
+ }
+ }
+ if(chk) return i;
+ }
+ }
+
+ return -1;
+ }
+
+ public boolean isValidWord(final CharSequence word) {
+ if (word == null || word.length() == 0) {
+ return false;
+ }
+ return mMainDict.isValidWord(word)
+ || (mUserDictionary != null && mUserDictionary.isValidWord(word))
+ || (mAutoDictionary != null && mAutoDictionary.isValidWord(word))
+ || (mContactsDictionary != null && mContactsDictionary.isValidWord(word));
+ }
+
+ private void collectGarbage(ArrayList<CharSequence> suggestions, int prefMaxSuggestions) {
+ int poolSize = mStringPool.size();
+ int garbageSize = suggestions.size();
+ while (poolSize < prefMaxSuggestions && garbageSize > 0) {
+ CharSequence garbage = suggestions.get(garbageSize - 1);
+ if (garbage != null && garbage instanceof StringBuilder) {
+ mStringPool.add(garbage);
+ poolSize++;
+ }
+ garbageSize--;
+ }
+ if (poolSize == prefMaxSuggestions + 1) {
+ Log.w("Suggest", "String pool got too big: " + poolSize);
+ }
+ suggestions.clear();
+ }
+
+ public void close() {
+ if (mMainDict != null) {
+ mMainDict.close();
+ }
+ }
+}
diff --git a/java/src/org/pocketworkstation/pckeyboard/SwipeTracker.java b/java/src/org/pocketworkstation/pckeyboard/SwipeTracker.java
new file mode 100644
index 0000000..60abfd6
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/SwipeTracker.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.pocketworkstation.pckeyboard;
+
+import android.view.MotionEvent;
+
+class SwipeTracker {
+ private static final int NUM_PAST = 4;
+ private static final int LONGEST_PAST_TIME = 200;
+
+ final EventRingBuffer mBuffer = new EventRingBuffer(NUM_PAST);
+
+ private float mYVelocity;
+ private float mXVelocity;
+
+ public void addMovement(MotionEvent ev) {
+ if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+ mBuffer.clear();
+ return;
+ }
+ long time = ev.getEventTime();
+ final int count = ev.getHistorySize();
+ for (int i = 0; i < count; i++) {
+ addPoint(ev.getHistoricalX(i), ev.getHistoricalY(i), ev.getHistoricalEventTime(i));
+ }
+ addPoint(ev.getX(), ev.getY(), time);
+ }
+
+ private void addPoint(float x, float y, long time) {
+ final EventRingBuffer buffer = mBuffer;
+ while (buffer.size() > 0) {
+ long lastT = buffer.getTime(0);
+ if (lastT >= time - LONGEST_PAST_TIME)
+ break;
+ buffer.dropOldest();
+ }
+ buffer.add(x, y, time);
+ }
+
+ public void computeCurrentVelocity(int units) {
+ computeCurrentVelocity(units, Float.MAX_VALUE);
+ }
+
+ public void computeCurrentVelocity(int units, float maxVelocity) {
+ final EventRingBuffer buffer = mBuffer;
+ final float oldestX = buffer.getX(0);
+ final float oldestY = buffer.getY(0);
+ final long oldestTime = buffer.getTime(0);
+
+ float accumX = 0;
+ float accumY = 0;
+ final int count = buffer.size();
+ for (int pos = 1; pos < count; pos++) {
+ final int dur = (int)(buffer.getTime(pos) - oldestTime);
+ if (dur == 0) continue;
+ float dist = buffer.getX(pos) - oldestX;
+ float vel = (dist / dur) * units; // pixels/frame.
+ if (accumX == 0) accumX = vel;
+ else accumX = (accumX + vel) * .5f;
+
+ dist = buffer.getY(pos) - oldestY;
+ vel = (dist / dur) * units; // pixels/frame.
+ if (accumY == 0) accumY = vel;
+ else accumY = (accumY + vel) * .5f;
+ }
+ mXVelocity = accumX < 0.0f ? Math.max(accumX, -maxVelocity)
+ : Math.min(accumX, maxVelocity);
+ mYVelocity = accumY < 0.0f ? Math.max(accumY, -maxVelocity)
+ : Math.min(accumY, maxVelocity);
+ }
+
+ public float getXVelocity() {
+ return mXVelocity;
+ }
+
+ public float getYVelocity() {
+ return mYVelocity;
+ }
+
+ static class EventRingBuffer {
+ private final int bufSize;
+ private final float xBuf[];
+ private final float yBuf[];
+ private final long timeBuf[];
+ private int top; // points new event
+ private int end; // points oldest event
+ private int count; // the number of valid data
+
+ public EventRingBuffer(int max) {
+ this.bufSize = max;
+ xBuf = new float[max];
+ yBuf = new float[max];
+ timeBuf = new long[max];
+ clear();
+ }
+
+ public void clear() {
+ top = end = count = 0;
+ }
+
+ public int size() {
+ return count;
+ }
+
+ // Position 0 points oldest event
+ private int index(int pos) {
+ return (end + pos) % bufSize;
+ }
+
+ private int advance(int index) {
+ return (index + 1) % bufSize;
+ }
+
+ public void add(float x, float y, long time) {
+ xBuf[top] = x;
+ yBuf[top] = y;
+ timeBuf[top] = time;
+ top = advance(top);
+ if (count < bufSize) {
+ count++;
+ } else {
+ end = advance(end);
+ }
+ }
+
+ public float getX(int pos) {
+ return xBuf[index(pos)];
+ }
+
+ public float getY(int pos) {
+ return yBuf[index(pos)];
+ }
+
+ public long getTime(int pos) {
+ return timeBuf[index(pos)];
+ }
+
+ public void dropOldest() {
+ count--;
+ end = advance(end);
+ }
+ }
+} \ No newline at end of file
diff --git a/java/src/org/pocketworkstation/pckeyboard/TextEntryState.java b/java/src/org/pocketworkstation/pckeyboard/TextEntryState.java
new file mode 100644
index 0000000..ae4bc5b
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/TextEntryState.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.pocketworkstation.pckeyboard;
+
+import android.content.Context;
+import org.pocketworkstation.pckeyboard.Keyboard.Key;
+import android.text.format.DateFormat;
+import android.util.Log;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Calendar;
+
+public class TextEntryState {
+
+ private static final boolean DBG = false;
+
+ private static final String TAG = "TextEntryState";
+
+ private static boolean LOGGING = false;
+
+ private static int sBackspaceCount = 0;
+
+ private static int sAutoSuggestCount = 0;
+
+ private static int sAutoSuggestUndoneCount = 0;
+
+ private static int sManualSuggestCount = 0;
+
+ private static int sWordNotInDictionaryCount = 0;
+
+ private static int sSessionCount = 0;
+
+ private static int sTypedChars;
+
+ private static int sActualChars;
+
+ public enum State {
+ UNKNOWN,
+ START,
+ IN_WORD,
+ ACCEPTED_DEFAULT,
+ PICKED_SUGGESTION,
+ PUNCTUATION_AFTER_WORD,
+ PUNCTUATION_AFTER_ACCEPTED,
+ SPACE_AFTER_ACCEPTED,
+ SPACE_AFTER_PICKED,
+ UNDO_COMMIT,
+ CORRECTING,
+ PICKED_CORRECTION;
+ }
+
+ private static State sState = State.UNKNOWN;
+
+ private static FileOutputStream sKeyLocationFile;
+ private static FileOutputStream sUserActionFile;
+
+ public static void newSession(Context context) {
+ sSessionCount++;
+ sAutoSuggestCount = 0;
+ sBackspaceCount = 0;
+ sAutoSuggestUndoneCount = 0;
+ sManualSuggestCount = 0;
+ sWordNotInDictionaryCount = 0;
+ sTypedChars = 0;
+ sActualChars = 0;
+ sState = State.START;
+
+ if (LOGGING) {
+ try {
+ sKeyLocationFile = context.openFileOutput("key.txt", Context.MODE_APPEND);
+ sUserActionFile = context.openFileOutput("action.txt", Context.MODE_APPEND);
+ } catch (IOException ioe) {
+ Log.e("TextEntryState", "Couldn't open file for output: " + ioe);
+ }
+ }
+ }
+
+ public static void endSession() {
+ if (sKeyLocationFile == null) {
+ return;
+ }
+ try {
+ sKeyLocationFile.close();
+ // Write to log file
+ // Write timestamp, settings,
+ String out = DateFormat.format("MM:dd hh:mm:ss", Calendar.getInstance().getTime())
+ .toString()
+ + " BS: " + sBackspaceCount
+ + " auto: " + sAutoSuggestCount
+ + " manual: " + sManualSuggestCount
+ + " typed: " + sWordNotInDictionaryCount
+ + " undone: " + sAutoSuggestUndoneCount
+ + " saved: " + ((float) (sActualChars - sTypedChars) / sActualChars)
+ + "\n";
+ sUserActionFile.write(out.getBytes());
+ sUserActionFile.close();
+ sKeyLocationFile = null;
+ sUserActionFile = null;
+ } catch (IOException ioe) {
+
+ }
+ }
+
+ public static void acceptedDefault(CharSequence typedWord, CharSequence actualWord) {
+ if (typedWord == null) return;
+ if (!typedWord.equals(actualWord)) {
+ sAutoSuggestCount++;
+ }
+ sTypedChars += typedWord.length();
+ sActualChars += actualWord.length();
+ sState = State.ACCEPTED_DEFAULT;
+ LatinImeLogger.logOnAutoSuggestion(typedWord.toString(), actualWord.toString());
+ displayState();
+ }
+
+ // State.ACCEPTED_DEFAULT will be changed to other sub-states
+ // (see "case ACCEPTED_DEFAULT" in typedCharacter() below),
+ // and should be restored back to State.ACCEPTED_DEFAULT after processing for each sub-state.
+ public static void backToAcceptedDefault(CharSequence typedWord) {
+ if (typedWord == null) return;
+ switch (sState) {
+ case SPACE_AFTER_ACCEPTED:
+ case PUNCTUATION_AFTER_ACCEPTED:
+ case IN_WORD:
+ sState = State.ACCEPTED_DEFAULT;
+ break;
+ }
+ displayState();
+ }
+
+ public static void manualTyped(CharSequence typedWord) {
+ sState = State.START;
+ displayState();
+ }
+
+ public static void acceptedTyped(CharSequence typedWord) {
+ sWordNotInDictionaryCount++;
+ sState = State.PICKED_SUGGESTION;
+ displayState();
+ }
+
+ public static void acceptedSuggestion(CharSequence typedWord, CharSequence actualWord) {
+ sManualSuggestCount++;
+ State oldState = sState;
+ if (typedWord.equals(actualWord)) {
+ acceptedTyped(typedWord);
+ }
+ if (oldState == State.CORRECTING || oldState == State.PICKED_CORRECTION) {
+ sState = State.PICKED_CORRECTION;
+ } else {
+ sState = State.PICKED_SUGGESTION;
+ }
+ displayState();
+ }
+
+ public static void selectedForCorrection() {
+ sState = State.CORRECTING;
+ displayState();
+ }
+
+ public static void typedCharacter(char c, boolean isSeparator) {
+ boolean isSpace = c == ' ';
+ switch (sState) {
+ case IN_WORD:
+ if (isSpace || isSeparator) {
+ sState = State.START;
+ } else {
+ // State hasn't changed.
+ }
+ break;
+ case ACCEPTED_DEFAULT:
+ case SPACE_AFTER_PICKED:
+ if (isSpace) {
+ sState = State.SPACE_AFTER_ACCEPTED;
+ } else if (isSeparator) {
+ sState = State.PUNCTUATION_AFTER_ACCEPTED;
+ } else {
+ sState = State.IN_WORD;
+ }
+ break;
+ case PICKED_SUGGESTION:
+ case PICKED_CORRECTION:
+ if (isSpace) {
+ sState = State.SPACE_AFTER_PICKED;
+ } else if (isSeparator) {
+ // Swap
+ sState = State.PUNCTUATION_AFTER_ACCEPTED;
+ } else {
+ sState = State.IN_WORD;
+ }
+ break;
+ case START:
+ case UNKNOWN:
+ case SPACE_AFTER_ACCEPTED:
+ case PUNCTUATION_AFTER_ACCEPTED:
+ case PUNCTUATION_AFTER_WORD:
+ if (!isSpace && !isSeparator) {
+ sState = State.IN_WORD;
+ } else {
+ sState = State.START;
+ }
+ break;
+ case UNDO_COMMIT:
+ if (isSpace || isSeparator) {
+ sState = State.ACCEPTED_DEFAULT;
+ } else {
+ sState = State.IN_WORD;
+ }
+ break;
+ case CORRECTING:
+ sState = State.START;
+ break;
+ }
+ displayState();
+ }
+
+ public static void backspace() {
+ if (sState == State.ACCEPTED_DEFAULT) {
+ sState = State.UNDO_COMMIT;
+ sAutoSuggestUndoneCount++;
+ LatinImeLogger.logOnAutoSuggestionCanceled();
+ } else if (sState == State.UNDO_COMMIT) {
+ sState = State.IN_WORD;
+ }
+ sBackspaceCount++;
+ displayState();
+ }
+
+ public static void reset() {
+ sState = State.START;
+ displayState();
+ }
+
+ public static State getState() {
+ if (DBG) {
+ Log.d(TAG, "Returning state = " + sState);
+ }
+ return sState;
+ }
+
+ public static boolean isCorrecting() {
+ return sState == State.CORRECTING || sState == State.PICKED_CORRECTION;
+ }
+
+ public static void keyPressedAt(Key key, int x, int y) {
+ if (LOGGING && sKeyLocationFile != null && key.codes[0] >= 32) {
+ String out =
+ "KEY: " + (char) key.codes[0]
+ + " X: " + x
+ + " Y: " + y
+ + " MX: " + (key.x + key.width / 2)
+ + " MY: " + (key.y + key.height / 2)
+ + "\n";
+ try {
+ sKeyLocationFile.write(out.getBytes());
+ } catch (IOException ioe) {
+ // TODO: May run out of space
+ }
+ }
+ }
+
+ private static void displayState() {
+ if (DBG) {
+ //Log.w(TAG, "State = " + sState, new Throwable());
+ Log.i(TAG, "State = " + sState);
+ }
+ }
+}
+
diff --git a/java/src/org/pocketworkstation/pckeyboard/Tutorial.java b/java/src/org/pocketworkstation/pckeyboard/Tutorial.java
new file mode 100644
index 0000000..2e1ac51
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/Tutorial.java
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.pocketworkstation.pckeyboard;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.os.Message;
+import android.text.Layout;
+import android.text.SpannableStringBuilder;
+import android.text.StaticLayout;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.View.OnTouchListener;
+import android.widget.PopupWindow;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Tutorial implements OnTouchListener {
+
+ private List<Bubble> mBubbles = new ArrayList<Bubble>();
+ private View mInputView;
+ private LatinIME mIme;
+ private int[] mLocation = new int[2];
+
+ private static final int MSG_SHOW_BUBBLE = 0;
+
+ private int mBubbleIndex;
+
+ Handler mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_SHOW_BUBBLE:
+ Bubble bubba = (Bubble) msg.obj;
+ bubba.show(mLocation[0], mLocation[1]);
+ break;
+ }
+ }
+ };
+
+ class Bubble {
+ Drawable bubbleBackground;
+ int x;
+ int y;
+ int width;
+ int gravity;
+ CharSequence text;
+ boolean dismissOnTouch;
+ boolean dismissOnClose;
+ PopupWindow window;
+ TextView textView;
+ View inputView;
+
+ Bubble(Context context, View inputView,
+ int backgroundResource, int bx, int by, int textResource1, int textResource2) {
+ bubbleBackground = context.getResources().getDrawable(backgroundResource);
+ x = bx;
+ y = by;
+ width = (int) (inputView.getWidth() * 0.9);
+ this.gravity = Gravity.TOP | Gravity.LEFT;
+ text = new SpannableStringBuilder()
+ .append(context.getResources().getText(textResource1))
+ .append("\n")
+ .append(context.getResources().getText(textResource2));
+ this.dismissOnTouch = true;
+ this.dismissOnClose = false;
+ this.inputView = inputView;
+ window = new PopupWindow(context);
+ window.setBackgroundDrawable(null);
+ LayoutInflater inflate =
+ (LayoutInflater) context
+ .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ textView = (TextView) inflate.inflate(R.layout.bubble_text, null);
+ textView.setBackgroundDrawable(bubbleBackground);
+ textView.setText(text);
+ //textView.setText(textResource1);
+ window.setContentView(textView);
+ window.setFocusable(false);
+ window.setTouchable(true);
+ window.setOutsideTouchable(false);
+ }
+
+ private int chooseSize(PopupWindow pop, View parentView, CharSequence text, TextView tv) {
+ int wid = tv.getPaddingLeft() + tv.getPaddingRight();
+ int ht = tv.getPaddingTop() + tv.getPaddingBottom();
+
+ /*
+ * Figure out how big the text would be if we laid it out to the
+ * full width of this view minus the border.
+ */
+ int cap = width - wid;
+
+ Layout l = new StaticLayout(text, tv.getPaint(), cap,
+ Layout.Alignment.ALIGN_NORMAL, 1, 0, true);
+ float max = 0;
+ for (int i = 0; i < l.getLineCount(); i++) {
+ max = Math.max(max, l.getLineWidth(i));
+ }
+
+ /*
+ * Now set the popup size to be big enough for the text plus the border.
+ */
+ pop.setWidth(width);
+ pop.setHeight(ht + l.getHeight());
+ return l.getHeight();
+ }
+
+ void show(int offx, int offy) {
+ int textHeight = chooseSize(window, inputView, text, textView);
+ offy -= textView.getPaddingTop() + textHeight;
+ if (inputView.getVisibility() == View.VISIBLE
+ && inputView.getWindowVisibility() == View.VISIBLE) {
+ try {
+ if ((gravity & Gravity.BOTTOM) == Gravity.BOTTOM) offy -= window.getHeight();
+ if ((gravity & Gravity.RIGHT) == Gravity.RIGHT) offx -= window.getWidth();
+ textView.setOnTouchListener(new View.OnTouchListener() {
+ public boolean onTouch(View view, MotionEvent me) {
+ Tutorial.this.next();
+ return true;
+ }
+ });
+ window.showAtLocation(inputView, Gravity.NO_GRAVITY, x + offx, y + offy);
+ } catch (Exception e) {
+ // Input view is not valid
+ }
+ }
+ }
+
+ void hide() {
+ if (window.isShowing()) {
+ textView.setOnTouchListener(null);
+ window.dismiss();
+ }
+ }
+
+ boolean isShowing() {
+ return window.isShowing();
+ }
+ }
+
+ public Tutorial(LatinIME ime, LatinKeyboardView inputView) {
+ Context context = inputView.getContext();
+ mIme = ime;
+ int inputWidth = inputView.getWidth();
+ final int x = inputWidth / 20; // Half of 1/10th
+ Bubble bWelcome = new Bubble(context, inputView,
+ R.drawable.dialog_bubble_step02, x, 0,
+ R.string.tip_to_open_keyboard, R.string.touch_to_continue);
+ mBubbles.add(bWelcome);
+ Bubble bAccents = new Bubble(context, inputView,
+ R.drawable.dialog_bubble_step02, x, 0,
+ R.string.tip_to_view_accents, R.string.touch_to_continue);
+ mBubbles.add(bAccents);
+ Bubble b123 = new Bubble(context, inputView,
+ R.drawable.dialog_bubble_step07, x, 0,
+ R.string.tip_to_open_symbols, R.string.touch_to_continue);
+ mBubbles.add(b123);
+ Bubble bABC = new Bubble(context, inputView,
+ R.drawable.dialog_bubble_step07, x, 0,
+ R.string.tip_to_close_symbols, R.string.touch_to_continue);
+ mBubbles.add(bABC);
+ Bubble bSettings = new Bubble(context, inputView,
+ R.drawable.dialog_bubble_step07, x, 0,
+ R.string.tip_to_launch_settings, R.string.touch_to_continue);
+ mBubbles.add(bSettings);
+ Bubble bDone = new Bubble(context, inputView,
+ R.drawable.dialog_bubble_step02, x, 0,
+ R.string.tip_to_start_typing, R.string.touch_to_finish);
+ mBubbles.add(bDone);
+ mInputView = inputView;
+ }
+
+ void start() {
+ mInputView.getLocationInWindow(mLocation);
+ mBubbleIndex = -1;
+ mInputView.setOnTouchListener(this);
+ next();
+ }
+
+ boolean next() {
+ if (mBubbleIndex >= 0) {
+ // If the bubble is not yet showing, don't move to the next.
+ if (!mBubbles.get(mBubbleIndex).isShowing()) {
+ return true;
+ }
+ // Hide all previous bubbles as well, as they may have had a delayed show
+ for (int i = 0; i <= mBubbleIndex; i++) {
+ mBubbles.get(i).hide();
+ }
+ }
+ mBubbleIndex++;
+ if (mBubbleIndex >= mBubbles.size()) {
+ mInputView.setOnTouchListener(null);
+ mIme.sendDownUpKeyEvents(-1); // Inform the setupwizard that tutorial is in last bubble
+ mIme.tutorialDone();
+ return false;
+ }
+ if (mBubbleIndex == 3 || mBubbleIndex == 4) {
+ mIme.mKeyboardSwitcher.toggleSymbols();
+ }
+ mHandler.sendMessageDelayed(
+ mHandler.obtainMessage(MSG_SHOW_BUBBLE, mBubbles.get(mBubbleIndex)), 500);
+ return true;
+ }
+
+ void hide() {
+ for (int i = 0; i < mBubbles.size(); i++) {
+ mBubbles.get(i).hide();
+ }
+ mInputView.setOnTouchListener(null);
+ }
+
+ boolean close() {
+ mHandler.removeMessages(MSG_SHOW_BUBBLE);
+ hide();
+ return true;
+ }
+
+ public boolean onTouch(View v, MotionEvent event) {
+ if (event.getAction() == MotionEvent.ACTION_DOWN) {
+ next();
+ }
+ return true;
+ }
+}
diff --git a/java/src/org/pocketworkstation/pckeyboard/UserBigramDictionary.java b/java/src/org/pocketworkstation/pckeyboard/UserBigramDictionary.java
new file mode 100644
index 0000000..1f9d677
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/UserBigramDictionary.java
@@ -0,0 +1,401 @@
+/*
+ * Copyright (C) 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.pocketworkstation.pckeyboard;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.database.sqlite.SQLiteQueryBuilder;
+import android.os.AsyncTask;
+import android.provider.BaseColumns;
+import android.util.Log;
+
+/**
+ * Stores all the pairs user types in databases. Prune the database if the size
+ * gets too big. Unlike AutoDictionary, it even stores the pairs that are already
+ * in the dictionary.
+ */
+public class UserBigramDictionary extends ExpandableDictionary {
+ private static final String TAG = "UserBigramDictionary";
+
+ /** Any pair being typed or picked */
+ private static final int FREQUENCY_FOR_TYPED = 2;
+
+ /** Maximum frequency for all pairs */
+ private static final int FREQUENCY_MAX = 127;
+
+ /**
+ * If this pair is typed 6 times, it would be suggested.
+ * Should be smaller than ContactsDictionary.FREQUENCY_FOR_CONTACTS_BIGRAM
+ */
+ protected static final int SUGGEST_THRESHOLD = 6 * FREQUENCY_FOR_TYPED;
+
+ /** Maximum number of pairs. Pruning will start when databases goes above this number. */
+ private static int sMaxUserBigrams = 10000;
+
+ /**
+ * When it hits maximum bigram pair, it will delete until you are left with
+ * only (sMaxUserBigrams - sDeleteUserBigrams) pairs.
+ * Do not keep this number small to avoid deleting too often.
+ */
+ private static int sDeleteUserBigrams = 1000;
+
+ /**
+ * Database version should increase if the database structure changes
+ */
+ private static final int DATABASE_VERSION = 1;
+
+ private static final String DATABASE_NAME = "userbigram_dict.db";
+
+ /** Name of the words table in the database */
+ private static final String MAIN_TABLE_NAME = "main";
+ // TODO: Consume less space by using a unique id for locale instead of the whole
+ // 2-5 character string. (Same TODO from AutoDictionary)
+ private static final String MAIN_COLUMN_ID = BaseColumns._ID;
+ private static final String MAIN_COLUMN_WORD1 = "word1";
+ private static final String MAIN_COLUMN_WORD2 = "word2";
+ private static final String MAIN_COLUMN_LOCALE = "locale";
+
+ /** Name of the frequency table in the database */
+ private static final String FREQ_TABLE_NAME = "frequency";
+ private static final String FREQ_COLUMN_ID = BaseColumns._ID;
+ private static final String FREQ_COLUMN_PAIR_ID = "pair_id";
+ private static final String FREQ_COLUMN_FREQUENCY = "freq";
+
+ private final LatinIME mIme;
+
+ /** Locale for which this auto dictionary is storing words */
+ private String mLocale;
+
+ private HashSet<Bigram> mPendingWrites = new HashSet<Bigram>();
+ private final Object mPendingWritesLock = new Object();
+ private static volatile boolean sUpdatingDB = false;
+
+ private final static HashMap<String, String> sDictProjectionMap;
+
+ static {
+ sDictProjectionMap = new HashMap<String, String>();
+ sDictProjectionMap.put(MAIN_COLUMN_ID, MAIN_COLUMN_ID);
+ sDictProjectionMap.put(MAIN_COLUMN_WORD1, MAIN_COLUMN_WORD1);
+ sDictProjectionMap.put(MAIN_COLUMN_WORD2, MAIN_COLUMN_WORD2);
+ sDictProjectionMap.put(MAIN_COLUMN_LOCALE, MAIN_COLUMN_LOCALE);
+
+ sDictProjectionMap.put(FREQ_COLUMN_ID, FREQ_COLUMN_ID);
+ sDictProjectionMap.put(FREQ_COLUMN_PAIR_ID, FREQ_COLUMN_PAIR_ID);
+ sDictProjectionMap.put(FREQ_COLUMN_FREQUENCY, FREQ_COLUMN_FREQUENCY);
+ }
+
+ private static DatabaseHelper sOpenHelper = null;
+
+ private static class Bigram {
+ String word1;
+ String word2;
+ int frequency;
+
+ Bigram(String word1, String word2, int frequency) {
+ this.word1 = word1;
+ this.word2 = word2;
+ this.frequency = frequency;
+ }
+
+ @Override
+ public boolean equals(Object bigram) {
+ Bigram bigram2 = (Bigram) bigram;
+ return (word1.equals(bigram2.word1) && word2.equals(bigram2.word2));
+ }
+
+ @Override
+ public int hashCode() {
+ return (word1 + " " + word2).hashCode();
+ }
+ }
+
+ public void setDatabaseMax(int maxUserBigram) {
+ sMaxUserBigrams = maxUserBigram;
+ }
+
+ public void setDatabaseDelete(int deleteUserBigram) {
+ sDeleteUserBigrams = deleteUserBigram;
+ }
+
+ public UserBigramDictionary(Context context, LatinIME ime, String locale, int dicTypeId) {
+ super(context, dicTypeId);
+ mIme = ime;
+ mLocale = locale;
+ if (sOpenHelper == null) {
+ sOpenHelper = new DatabaseHelper(getContext());
+ }
+ if (mLocale != null && mLocale.length() > 1) {
+ loadDictionary();
+ }
+ }
+
+ @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();
+ super.close();
+ }
+
+ /**
+ * Pair will be added to the userbigram database.
+ */
+ public int addBigrams(String word1, String word2) {
+ // remove caps
+ if (mIme != null && mIme.getCurrentWord().isAutoCapitalized()) {
+ word2 = Character.toLowerCase(word2.charAt(0)) + word2.substring(1);
+ }
+
+ int freq = super.addBigram(word1, word2, FREQUENCY_FOR_TYPED);
+ if (freq > FREQUENCY_MAX) freq = FREQUENCY_MAX;
+ synchronized (mPendingWritesLock) {
+ if (freq == FREQUENCY_FOR_TYPED || mPendingWrites.isEmpty()) {
+ mPendingWrites.add(new Bigram(word1, word2, freq));
+ } else {
+ Bigram bi = new Bigram(word1, word2, freq);
+ mPendingWrites.remove(bi);
+ mPendingWrites.add(bi);
+ }
+ }
+
+ return freq;
+ }
+
+ /**
+ * Schedules a background thread to write any pending words to the database.
+ */
+ public void flushPendingWrites() {
+ synchronized (mPendingWritesLock) {
+ // Nothing pending? Return
+ if (mPendingWrites.isEmpty()) return;
+ // Create a background thread to write the pending entries
+ new UpdateDbTask(getContext(), sOpenHelper, mPendingWrites, mLocale).execute();
+ // Create a new map for writing new entries into while the old one is written to db
+ mPendingWrites = new HashSet<Bigram>();
+ }
+ }
+
+ /** Used for testing purpose **/
+ void waitUntilUpdateDBDone() {
+ synchronized (mPendingWritesLock) {
+ while (sUpdatingDB) {
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ }
+ }
+ return;
+ }
+ }
+
+ @Override
+ public void loadDictionaryAsync() {
+ // Load the words that correspond to the current input locale
+ Cursor cursor = query(MAIN_COLUMN_LOCALE + "=?", new String[] { mLocale });
+ try {
+ if (cursor.moveToFirst()) {
+ int word1Index = cursor.getColumnIndex(MAIN_COLUMN_WORD1);
+ int word2Index = cursor.getColumnIndex(MAIN_COLUMN_WORD2);
+ int frequencyIndex = cursor.getColumnIndex(FREQ_COLUMN_FREQUENCY);
+ while (!cursor.isAfterLast()) {
+ String word1 = cursor.getString(word1Index);
+ String word2 = cursor.getString(word2Index);
+ int frequency = cursor.getInt(frequencyIndex);
+ // Safeguard against adding really long words. Stack may overflow due
+ // to recursive lookup
+ if (word1.length() < MAX_WORD_LENGTH && word2.length() < MAX_WORD_LENGTH) {
+ super.setBigram(word1, word2, frequency);
+ }
+ cursor.moveToNext();
+ }
+ }
+ } finally {
+ cursor.close();
+ }
+ }
+
+ /**
+ * Query the database
+ */
+ private Cursor query(String selection, String[] selectionArgs) {
+ SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
+
+ // main INNER JOIN frequency ON (main._id=freq.pair_id)
+ qb.setTables(MAIN_TABLE_NAME + " INNER JOIN " + FREQ_TABLE_NAME + " ON ("
+ + MAIN_TABLE_NAME + "." + MAIN_COLUMN_ID + "=" + FREQ_TABLE_NAME + "."
+ + FREQ_COLUMN_PAIR_ID +")");
+
+ qb.setProjectionMap(sDictProjectionMap);
+
+ // Get the database and run the query
+ SQLiteDatabase db = sOpenHelper.getReadableDatabase();
+ Cursor c = qb.query(db,
+ new String[] { MAIN_COLUMN_WORD1, MAIN_COLUMN_WORD2, FREQ_COLUMN_FREQUENCY },
+ selection, selectionArgs, null, null, null);
+ return c;
+ }
+
+ /**
+ * This class helps open, create, and upgrade the database file.
+ */
+ private static class DatabaseHelper extends SQLiteOpenHelper {
+
+ DatabaseHelper(Context context) {
+ super(context, DATABASE_NAME, null, DATABASE_VERSION);
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ db.execSQL("PRAGMA foreign_keys = ON;");
+ db.execSQL("CREATE TABLE " + MAIN_TABLE_NAME + " ("
+ + MAIN_COLUMN_ID + " INTEGER PRIMARY KEY,"
+ + MAIN_COLUMN_WORD1 + " TEXT,"
+ + MAIN_COLUMN_WORD2 + " TEXT,"
+ + MAIN_COLUMN_LOCALE + " TEXT"
+ + ");");
+ db.execSQL("CREATE TABLE " + FREQ_TABLE_NAME + " ("
+ + FREQ_COLUMN_ID + " INTEGER PRIMARY KEY,"
+ + FREQ_COLUMN_PAIR_ID + " INTEGER,"
+ + FREQ_COLUMN_FREQUENCY + " INTEGER,"
+ + "FOREIGN KEY(" + FREQ_COLUMN_PAIR_ID + ") REFERENCES " + MAIN_TABLE_NAME
+ + "(" + MAIN_COLUMN_ID + ")" + " ON DELETE CASCADE"
+ + ");");
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+ + newVersion + ", which will destroy all old data");
+ db.execSQL("DROP TABLE IF EXISTS " + MAIN_TABLE_NAME);
+ db.execSQL("DROP TABLE IF EXISTS " + FREQ_TABLE_NAME);
+ onCreate(db);
+ }
+ }
+
+ /**
+ * Async task to write pending words to the database so that it stays in sync with
+ * the in-memory trie.
+ */
+ private static class UpdateDbTask extends AsyncTask<Void, Void, Void> {
+ private final HashSet<Bigram> mMap;
+ private final DatabaseHelper mDbHelper;
+ private final String mLocale;
+
+ public UpdateDbTask(Context context, DatabaseHelper openHelper,
+ HashSet<Bigram> pendingWrites, String locale) {
+ mMap = pendingWrites;
+ mLocale = locale;
+ mDbHelper = openHelper;
+ }
+
+ /** Prune any old data if the database is getting too big. */
+ private void checkPruneData(SQLiteDatabase db) {
+ db.execSQL("PRAGMA foreign_keys = ON;");
+ Cursor c = db.query(FREQ_TABLE_NAME, new String[] { FREQ_COLUMN_PAIR_ID },
+ null, null, null, null, null);
+ try {
+ int totalRowCount = c.getCount();
+ // prune out old data if we have too much data
+ if (totalRowCount > sMaxUserBigrams) {
+ int numDeleteRows = (totalRowCount - sMaxUserBigrams) + sDeleteUserBigrams;
+ int pairIdColumnId = c.getColumnIndex(FREQ_COLUMN_PAIR_ID);
+ c.moveToFirst();
+ int count = 0;
+ while (count < numDeleteRows && !c.isAfterLast()) {
+ String pairId = c.getString(pairIdColumnId);
+ // Deleting from MAIN table will delete the frequencies
+ // due to FOREIGN KEY .. ON DELETE CASCADE
+ db.delete(MAIN_TABLE_NAME, MAIN_COLUMN_ID + "=?",
+ new String[] { pairId });
+ c.moveToNext();
+ count++;
+ }
+ }
+ } finally {
+ c.close();
+ }
+ }
+
+ @Override
+ protected void onPreExecute() {
+ sUpdatingDB = true;
+ }
+
+ @Override
+ protected Void doInBackground(Void... v) {
+ SQLiteDatabase db = mDbHelper.getWritableDatabase();
+ db.execSQL("PRAGMA foreign_keys = ON;");
+ // Write all the entries to the db
+ Iterator<Bigram> iterator = mMap.iterator();
+ while (iterator.hasNext()) {
+ Bigram bi = iterator.next();
+
+ // find pair id
+ Cursor c = db.query(MAIN_TABLE_NAME, new String[] { MAIN_COLUMN_ID },
+ MAIN_COLUMN_WORD1 + "=? AND " + MAIN_COLUMN_WORD2 + "=? AND "
+ + MAIN_COLUMN_LOCALE + "=?",
+ new String[] { bi.word1, bi.word2, mLocale }, null, null, null);
+
+ int pairId;
+ if (c.moveToFirst()) {
+ // existing pair
+ pairId = c.getInt(c.getColumnIndex(MAIN_COLUMN_ID));
+ db.delete(FREQ_TABLE_NAME, FREQ_COLUMN_PAIR_ID + "=?",
+ new String[] { Integer.toString(pairId) });
+ } else {
+ // new pair
+ Long pairIdLong = db.insert(MAIN_TABLE_NAME, null,
+ getContentValues(bi.word1, bi.word2, mLocale));
+ pairId = pairIdLong.intValue();
+ }
+ c.close();
+
+ // insert new frequency
+ db.insert(FREQ_TABLE_NAME, null, getFrequencyContentValues(pairId, bi.frequency));
+ }
+ checkPruneData(db);
+ sUpdatingDB = false;
+
+ return null;
+ }
+
+ private ContentValues getContentValues(String word1, String word2, String locale) {
+ ContentValues values = new ContentValues(3);
+ values.put(MAIN_COLUMN_WORD1, word1);
+ values.put(MAIN_COLUMN_WORD2, word2);
+ values.put(MAIN_COLUMN_LOCALE, locale);
+ return values;
+ }
+
+ private ContentValues getFrequencyContentValues(int pairId, int frequency) {
+ ContentValues values = new ContentValues(2);
+ values.put(FREQ_COLUMN_PAIR_ID, pairId);
+ values.put(FREQ_COLUMN_FREQUENCY, frequency);
+ return values;
+ }
+ }
+
+}
diff --git a/java/src/org/pocketworkstation/pckeyboard/UserDictionary.java b/java/src/org/pocketworkstation/pckeyboard/UserDictionary.java
new file mode 100644
index 0000000..7e60d52
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/UserDictionary.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.pocketworkstation.pckeyboard;
+
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.database.Cursor;
+import android.provider.UserDictionary.Words;
+import android.util.Log;
+
+public class UserDictionary extends ExpandableDictionary {
+
+ private static final String[] PROJECTION = {
+ Words._ID,
+ Words.WORD,
+ Words.FREQUENCY
+ };
+
+ private static final int INDEX_WORD = 1;
+ private static final int INDEX_FREQUENCY = 2;
+
+ private static final String TAG = "HK/UserDictionary";
+
+ private ContentObserver mObserver;
+ private String mLocale;
+
+ public UserDictionary(Context context, String locale) {
+ super(context, Suggest.DIC_USER);
+ mLocale = locale;
+ // Perform a managed query. The Activity will handle closing and requerying the cursor
+ // when needed.
+ ContentResolver cres = context.getContentResolver();
+
+ cres.registerContentObserver(Words.CONTENT_URI, true, mObserver = new ContentObserver(null) {
+ @Override
+ public void onChange(boolean self) {
+ setRequiresReload(true);
+ }
+ });
+
+ loadDictionary();
+ }
+
+ @Override
+ public synchronized void close() {
+ if (mObserver != null) {
+ getContext().getContentResolver().unregisterContentObserver(mObserver);
+ mObserver = null;
+ }
+ super.close();
+ }
+
+ @Override
+ public void loadDictionaryAsync() {
+ Cursor cursor = getContext().getContentResolver()
+ .query(Words.CONTENT_URI, PROJECTION, "(locale IS NULL) or (locale=?)",
+ new String[] { mLocale }, null);
+ addWords(cursor);
+ }
+
+ /**
+ * Adds a word to the dictionary and makes it persistent.
+ * @param word the word to add. If the word is capitalized, then the dictionary will
+ * recognize it as a capitalized word when searched.
+ * @param frequency the frequency of occurrence of the word. A frequency of 255 is considered
+ * the highest.
+ * @TODO use a higher or float range for frequency
+ */
+ @Override
+ public synchronized void addWord(String word, int frequency) {
+ // Force load the dictionary here synchronously
+ if (getRequiresReload()) loadDictionaryAsync();
+ // Safeguard against adding long words. Can cause stack overflow.
+ if (word.length() >= getMaxWordLength()) return;
+
+ super.addWord(word, frequency);
+
+ // Update the user dictionary provider
+ final ContentValues values = new ContentValues(5);
+ values.put(Words.WORD, word);
+ values.put(Words.FREQUENCY, frequency);
+ values.put(Words.LOCALE, mLocale);
+ values.put(Words.APP_ID, 0);
+
+ final ContentResolver contentResolver = getContext().getContentResolver();
+ new Thread("addWord") {
+ public void run() {
+ contentResolver.insert(Words.CONTENT_URI, values);
+ }
+ }.start();
+
+ // In case the above does a synchronous callback of the change observer
+ setRequiresReload(false);
+ }
+
+ @Override
+ public synchronized void getWords(final WordComposer codes, final WordCallback callback,
+ int[] nextLettersFrequencies) {
+ super.getWords(codes, callback, nextLettersFrequencies);
+ }
+
+ @Override
+ public synchronized boolean isValidWord(CharSequence word) {
+ return super.isValidWord(word);
+ }
+
+ private void addWords(Cursor cursor) {
+ if (cursor == null) {
+ Log.w(TAG, "Unexpected null cursor in addWords()");
+ return;
+ }
+ clearDictionary();
+
+ final int maxWordLength = getMaxWordLength();
+ if (cursor.moveToFirst()) {
+ while (!cursor.isAfterLast()) {
+ String word = cursor.getString(INDEX_WORD);
+ int frequency = cursor.getInt(INDEX_FREQUENCY);
+ // Safeguard against adding really long words. Stack may overflow due
+ // to recursion
+ if (word.length() < maxWordLength) {
+ super.addWord(word, frequency);
+ }
+ cursor.moveToNext();
+ }
+ }
+ cursor.close();
+ }
+}
diff --git a/java/src/org/pocketworkstation/pckeyboard/WordComposer.java b/java/src/org/pocketworkstation/pckeyboard/WordComposer.java
new file mode 100644
index 0000000..17814a8
--- /dev/null
+++ b/java/src/org/pocketworkstation/pckeyboard/WordComposer.java
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.pocketworkstation.pckeyboard;
+
+import java.util.ArrayList;
+
+/**
+ * A place to store the currently composing word with information such as adjacent key codes as well
+ */
+public class WordComposer {
+ /**
+ * The list of unicode values for each keystroke (including surrounding keys)
+ */
+ private final ArrayList<int[]> mCodes;
+
+ /**
+ * The word chosen from the candidate list, until it is committed.
+ */
+ private String mPreferredWord;
+
+ private final StringBuilder mTypedWord;
+
+ private int mCapsCount;
+
+ private boolean mAutoCapitalized;
+
+ /**
+ * Whether the user chose to capitalize the first char of the word.
+ */
+ private boolean mIsFirstCharCapitalized;
+
+ public WordComposer() {
+ mCodes = new ArrayList<int[]>(12);
+ mTypedWord = new StringBuilder(20);
+ }
+
+ WordComposer(WordComposer copy) {
+ mCodes = new ArrayList<int[]>(copy.mCodes);
+ mPreferredWord = copy.mPreferredWord;
+ mTypedWord = new StringBuilder(copy.mTypedWord);
+ mCapsCount = copy.mCapsCount;
+ mAutoCapitalized = copy.mAutoCapitalized;
+ mIsFirstCharCapitalized = copy.mIsFirstCharCapitalized;
+ }
+
+ /**
+ * Clear out the keys registered so far.
+ */
+ public void reset() {
+ mCodes.clear();
+ mIsFirstCharCapitalized = false;
+ mPreferredWord = null;
+ mTypedWord.setLength(0);
+ mCapsCount = 0;
+ }
+
+ /**
+ * Number of keystrokes in the composing word.
+ * @return the number of keystrokes
+ */
+ public int size() {
+ return mCodes.size();
+ }
+
+ /**
+ * Returns the codes at a particular position in the word.
+ * @param index the position in the word
+ * @return the unicode for the pressed and surrounding keys
+ */
+ public int[] getCodesAt(int index) {
+ return mCodes.get(index);
+ }
+
+ /**
+ * Add a new keystroke, with codes[0] containing the pressed key's unicode and the rest of
+ * the array containing unicode for adjacent keys, sorted by reducing probability/proximity.
+ * @param codes the array of unicode values
+ */
+ public void add(int primaryCode, int[] codes) {
+ mTypedWord.append((char) primaryCode);
+ correctPrimaryJuxtapos(primaryCode, codes);
+ correctCodesCase(codes);
+ mCodes.add(codes);
+ if (Character.isUpperCase((char) primaryCode)) mCapsCount++;
+ }
+
+ /**
+ * Swaps the first and second values in the codes array if the primary code is not the first
+ * value in the array but the second. This happens when the preferred key is not the key that
+ * the user released the finger on.
+ * @param primaryCode the preferred character
+ * @param codes array of codes based on distance from touch point
+ */
+ private void correctPrimaryJuxtapos(int primaryCode, int[] codes) {
+ if (codes.length < 2) return;
+ if (codes[0] > 0 && codes[1] > 0 && codes[0] != primaryCode && codes[1] == primaryCode) {
+ codes[1] = codes[0];
+ codes[0] = primaryCode;
+ }
+ }
+
+ // Prediction expects the keyKodes to be lowercase
+ private void correctCodesCase(int[] codes) {
+ for (int i = 0; i < codes.length; ++i) {
+ int code = codes[i];
+ if (code > 0) codes[i] = Character.toLowerCase(code);
+ }
+ }
+
+ /**
+ * Delete the last keystroke as a result of hitting backspace.
+ */
+ public void deleteLast() {
+ final int codesSize = mCodes.size();
+ if (codesSize > 0) {
+ mCodes.remove(codesSize - 1);
+ final int lastPos = mTypedWord.length() - 1;
+ char last = mTypedWord.charAt(lastPos);
+ mTypedWord.deleteCharAt(lastPos);
+ if (Character.isUpperCase(last)) mCapsCount--;
+ }
+ }
+
+ /**
+ * Returns the word as it was typed, without any correction applied.
+ * @return the word that was typed so far
+ */
+ public CharSequence getTypedWord() {
+ int wordSize = mCodes.size();
+ if (wordSize == 0) {
+ return null;
+ }
+ return mTypedWord;
+ }
+
+ public void setFirstCharCapitalized(boolean capitalized) {
+ mIsFirstCharCapitalized = capitalized;
+ }
+
+ /**
+ * Whether or not the user typed a capital letter as the first letter in the word
+ * @return capitalization preference
+ */
+ public boolean isFirstCharCapitalized() {
+ return mIsFirstCharCapitalized;
+ }
+
+ /**
+ * Whether or not all of the user typed chars are upper case
+ * @return true if all user typed chars are upper case, false otherwise
+ */
+ public boolean isAllUpperCase() {
+ return (mCapsCount > 0) && (mCapsCount == size());
+ }
+
+ /**
+ * Stores the user's selected word, before it is actually committed to the text field.
+ * @param preferred
+ */
+ public void setPreferredWord(String preferred) {
+ mPreferredWord = preferred;
+ }
+
+ /**
+ * Return the word chosen by the user, or the typed word if no other word was chosen.
+ * @return the preferred word
+ */
+ public CharSequence getPreferredWord() {
+ return mPreferredWord != null ? mPreferredWord : getTypedWord();
+ }
+
+ /**
+ * Returns true if more than one character is upper case, otherwise returns false.
+ */
+ public boolean isMostlyCaps() {
+ return mCapsCount > 1;
+ }
+
+ /**
+ * Saves the reason why the word is capitalized - whether it was automatic or
+ * due to the user hitting shift in the middle of a sentence.
+ * @param auto whether it was an automatic capitalization due to start of sentence
+ */
+ public void setAutoCapitalized(boolean auto) {
+ mAutoCapitalized = auto;
+ }
+
+ /**
+ * Returns whether the word was automatically capitalized.
+ * @return whether the word was automatically capitalized
+ */
+ public boolean isAutoCapitalized() {
+ return mAutoCapitalized;
+ }
+}
diff --git a/tests/Android.mk b/tests/Android.mk
new file mode 100644
index 0000000..fba7a8d
--- /dev/null
+++ b/tests/Android.mk
@@ -0,0 +1,17 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# We only want this apk build for tests.
+LOCAL_MODULE_TAGS := tests
+LOCAL_CERTIFICATE := shared
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+# Include all test java files.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := LatinIMETests
+
+LOCAL_INSTRUMENTATION_FOR := LatinIME
+
+include $(BUILD_PACKAGE)
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
new file mode 100644
index 0000000..210e814
--- /dev/null
+++ b/tests/AndroidManifest.xml
@@ -0,0 +1,33 @@
+<?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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.inputmethod.latin.tests">
+
+ <uses-permission android:name="android.permission.READ_CONTACTS" />
+
+ <application>
+ <uses-library android:name="android.test.runner" />
+ <!-- meta-data android:name="com.android.contacts.iconset" android:resource="@xml/iconset" /-->
+ <uses-permission android:name="android.permission.READ_CONTACTS" />
+
+ </application>
+
+ <instrumentation android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.android.inputmethod.latin"
+ android:label="LatinIME tests">
+ </instrumentation>
+</manifest>
diff --git a/tests/data/bigramlist.xml b/tests/data/bigramlist.xml
new file mode 100644
index 0000000..dd3f291
--- /dev/null
+++ b/tests/data/bigramlist.xml
@@ -0,0 +1,36 @@
+<?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.
+*/
+-->
+
+<bigrams>
+ <bi w1="I'm" count="1">
+ <w w2="about" p="100" />
+ </bi>
+ <bi w1="about" count="3">
+ <w w2="part" p="117" />
+ <w w2="business" p="100" />
+ <w w2="being" p="10" />
+ </bi>
+ <bi w1="business" count="1">
+ <w w2="people" p="100" />
+ </bi>
+ <bi w1="from" count="1">
+ <w w2="same" p="117" />
+ </bi>
+</bigrams>
diff --git a/tests/data/wordlist.xml b/tests/data/wordlist.xml
new file mode 100644
index 0000000..b870eb2
--- /dev/null
+++ b/tests/data/wordlist.xml
@@ -0,0 +1,244 @@
+<wordlist>
+ <w f="255">the</w>
+ <w f="246">and</w>
+ <w f="245">of</w>
+ <w f="242">to</w>
+ <w f="231">in</w>
+ <w f="230">that</w>
+ <w f="229">for</w>
+ <w f="224">with</w>
+ <w f="224">on</w>
+ <w f="224">it</w>
+ <w f="223">this</w>
+ <w f="222">you</w>
+ <w f="219">is</w>
+ <w f="219">was</w>
+ <w f="219">by</w>
+ <w f="219">or</w>
+ <w f="218">from</w>
+ <w f="217">but</w>
+ <w f="216">be</w>
+ <w f="216">Sunday</w>
+ <w f="215">are</w>
+ <w f="215">he</w>
+ <w f="214">so</w>
+ <w f="214">not</w>
+ <w f="213">have</w>
+ <w f="213">as</w>
+ <w f="211">all</w>
+ <w f="211">his</w>
+ <w f="210">my</w>
+ <w f="210">if</w>
+ <w f="210">which</w>
+ <w f="210">they</w>
+ <w f="209">at</w>
+ <w f="207">it's</w>
+ <w f="207">an</w>
+ <w f="207">your</w>
+ <w f="206">will</w>
+ <w f="206">about</w>
+ <w f="206">I'm</w>
+ <w f="205">there</w>
+ <w f="205">had</w>
+ <w f="205">has</w>
+ <w f="204">when</w>
+ <w f="203">no</w>
+ <w f="203">were</w>
+ <w f="203">what</w>
+ <w f="203">more</w>
+ <w f="203">out</w>
+ <w f="203">just</w>
+ <w f="202">their</w>
+ <w f="202">up</w>
+ <w f="202">would</w>
+ <w f="202">here</w>
+ <w f="202">can</w>
+ <w f="201">who</w>
+ <w f="200">her</w>
+ <w f="200">me</w>
+ <w f="200">now</w>
+ <w f="200">our</w>
+ <w f="200">do</w>
+ <w f="200">some</w>
+ <w f="199">been</w>
+ <w f="199">two</w>
+ <w f="199">like</w>
+ <w f="199">them</w>
+ <w f="199">new</w>
+ <w f="198">time</w>
+ <w f="198">we</w>
+ <w f="198">she</w>
+ <w f="197">one</w>
+ <w f="197">over</w>
+ <w f="197">may</w>
+ <w f="197">any</w>
+ <w f="197">him</w>
+ <w f="197">calling</w>
+ <w f="196">other</w>
+ <w f="196">how</w>
+ <w f="196">see</w>
+ <w f="195">because</w>
+ <w f="195">then</w>
+ <w f="195">right</w>
+ <w f="195">into</w>
+ <w f="195">well</w>
+ <w f="195">very</w>
+ <w f="195">said</w>
+ <w f="195">people</w>
+ <w f="194">these</w>
+ <w f="194">than</w>
+ <w f="193">only</w>
+ <w f="193">back</w>
+ <w f="193">first</w>
+ <w f="193">dot</w>
+ <w f="193">after</w>
+ <w f="193">where</w>
+ <w f="192">please</w>
+ <w f="192">could</w>
+ <w f="192">its</w>
+ <w f="192">before</w>
+ <w f="192">us</w>
+ <w f="192">again</w>
+ <w f="192">home</w>
+ <w f="191">also</w>
+ <w f="191">that's</w>
+ <w f="191">think</w>
+ <w f="191">three</w>
+ <w f="191">good</w>
+ <w f="191">get</w>
+ <w f="190">know</w>
+ <w f="190">thank</w>
+ <w f="190">should</w>
+ <w f="190">going</w>
+ <w f="190">down</w>
+ <w f="189">last</w>
+ <w f="189">today</w>
+ <w f="189">those</w>
+ <w f="189">go</w>
+ <w f="189">through</w>
+ <w f="189">such</w>
+ <w f="189">don't</w>
+ <w f="189">did</w>
+ <w f="188">most</w>
+ <w f="188">day</w>
+ <w f="188">man</w>
+ <w f="188">number</w>
+ <w f="188">work</w>
+ <w f="187">too</w>
+ <w f="187">show</w>
+ <w f="187">made</w>
+ <w f="187">even</w>
+ <w f="187">being</w>
+ <w f="187">make</w>
+ <w f="187">give</w>
+ <w f="186">off</w>
+ <w f="186">com</w>
+ <w f="186">much</w>
+ <w f="186">great</w>
+ <w f="186">take</w>
+ <w f="186">call</w>
+ <w f="186">way</w>
+ <w f="186">four</w>
+ <w f="186">say</w>
+ <w f="185">information</w>
+ <w f="185">under</w>
+ <w f="185">page</w>
+ <w f="185">many</w>
+ <w f="185">little</w>
+ <w f="185">thanks</w>
+ <w f="185">okay</w>
+ <w f="185">five</w>
+ <w f="185">we're</w>
+ <w f="185">between</w>
+ <w f="184">use</w>
+ <w f="184">come</w>
+ <w f="184">years</w>
+ <w f="184">office</w>
+ <w f="184">house</w>
+ <w f="184">search</w>
+ <w f="184">free</w>
+ <w f="183">next</w>
+ <w f="183">without</w>
+ <w f="183">still</w>
+ <w f="183">around</w>
+ <w f="183">I've</w>
+ <w f="183">business</w>
+ <w f="183">part</w>
+ <w f="183">every</w>
+ <w f="183">bye</w>
+ <w f="183">upon</w>
+ <w f="183">you're</w>
+ <w f="183">state</w>
+ <w f="183">life</w>
+ <w f="183">year</w>
+ <w f="182">thing</w>
+ <w f="182">since</w>
+ <w f="182">things</w>
+ <w f="182">something</w>
+ <w f="182">long</w>
+ <w f="182">got</w>
+ <w f="182">while</w>
+ <w f="182">I'll</w>
+ <w f="182">help</w>
+ <w f="182">service</w>
+ <w f="182">really</w>
+ <w f="182">must</w>
+ <w f="182">does</w>
+ <w f="182">name</w>
+ <w f="181">both</w>
+ <w f="181">six</w>
+ <w f="181">want</w>
+ <w f="181">same</w>
+ <w f="181">each</w>
+ <w f="181">yet</w>
+ <w f="181">let</w>
+ <w f="181">view</w>
+ <w f="181">place</w>
+ <w f="181">another</w>
+ <w f="181">company</w>
+ <w f="181">talk</w>
+ <w f="181">might</w>
+ <w f="181">am</w>
+ <w f="181">though</w>
+ <w f="181">find</w>
+ <w f="180">details</w>
+ <w f="180">look</w>
+ <w f="180">world</w>
+ <w f="180">old</w>
+ <w f="180">called</w>
+ <w f="180">case</w>
+ <w f="180">system</w>
+ <w f="180">news</w>
+ <w f="179">used</w>
+ <w f="179">contact</w>
+ <w f="179">never</w>
+ <w f="179">seven</w>
+ <w f="179">city</w>
+ <w f="179">until</w>
+ <w f="179">during</w>
+ <w f="179">set</w>
+ <w f="179">why</w>
+ <w f="179">point</w>
+ <w f="179">twenty</w>
+ <w f="179">high</w>
+ <w f="179">love</w>
+ <w f="179">services</w>
+ <w f="170">niño</w>
+ <w f="170">María</w>
+ <w f="70">car</w>
+ <w f="0">hmmm</w>
+ <w f="0">hon</w>
+ <w f="0">tty</w>
+ <w f="0">ttyl</w>
+ <w f="0">txt</w>
+ <w f="0">ur</w>
+ <w f="0">wah</w>
+ <w f="0">whatcha</w>
+ <w f="0">woah</w>
+ <w f="0">ya</w>
+ <w f="0">yea</w>
+ <w f="0">yeh</w>
+ <w f="0">yessir</w>
+ <w f="0">yikes</w>
+ <w f="0">yrs</w>
+</wordlist>
diff --git a/tests/res/raw/test.dict b/tests/res/raw/test.dict
new file mode 100644
index 0000000..6a5d6d7
--- /dev/null
+++ b/tests/res/raw/test.dict
Binary files differ
diff --git a/tests/res/raw/testtext.txt b/tests/res/raw/testtext.txt
new file mode 100644
index 0000000..eca20c0
--- /dev/null
+++ b/tests/res/raw/testtext.txt
@@ -0,0 +1,24 @@
+This text is used as test text for measuring performance of dictionary prediction. Any text can be put into this file to test the performance (total keystroke savings).
+When you think about “information,” what probably comes to mind are streams of words and numbers. Google’s pretty good at organizing these types of information, but consider all the things you can’t express with words: what does it look like in the middle of a sandstorm? What are some great examples of Art Nouveau architecture? Should I consider wedding cupcakes instead of a traditional cake?
+This is why we built Google Images in 2001. We realized that for many searches, the best answer wasn’t text—it was an image or a set of images. The service has grown quite a bit since then. In 2001, we indexed around 250 million images. By 2005, we had indexed over 1 billion. And today, we have an index of over 10 billion images.
+It’s not just about quantity, though. Over the past decade we’ve been baking deep computer science into Google Images to make it even faster and easier for you to find precisely the right images. We not only find images for pretty much anything you type in; we can also instantly pull out images of clip art, line drawings, faces and even colors.
+There’s even more sophisticated computer vision technology powering our “Similar images” tool. For example, did you know there are nine subspecies of leopards, each with a distinct pattern of spots? Google Images can recognize the difference, returning just leopards of a particular subspecies. It can tell you the name of the subspecies in a particular image—even if that image isn’t labeled—because other similar leopard images on the web are labeled with that subspecies’s name.
+And our “Similar colors” refinement doesn’t just return images based on the overall color of an image. If it did, lots of images would simply be classified as “white.” If you’re looking for [tulips] and you refine results to “white,” you really want images in which the tulips themselves are white—not the surrounding image. It takes some heavy-duty algorithmic wizardry and processing power for a search engine to understand what the items of interest are in all the images out there.
+Those are just a few of the technologies we’ve built to make Google Images more useful. Meanwhile, the quantity and variety of images on the web has ballooned since 2001, and images have become one of the most popular types of content people search for. So over the next few days we’re rolling out an update to Google Images to match the scope and beauty of this fast-growing visual web, and to bring to the surface some of the powerful technology behind Images.
+Here’s what’s new in this refreshed design of Google Images:
+Dense tiled layout designed to make it easy to look at lots of images at once. We want to get the app out of the way so you can find what you’re really looking for.
+Instant scrolling between pages, without letting you get lost in the images. You can now get up to 1,000 images, all in one scrolling page. And we’ll show small, unobtrusive page numbers so you don’t lose track of where you are.
+Larger thumbnail previews on the results page, designed for modern browsers and high-res screens.
+A hover pane that appears when you mouse over a given thumbnail image, giving you a larger preview, more info about the image and other image-specific features such as “Similar images.”
+Once you click on an image, you’re taken to a new landing page that displays a large image in context, with the website it’s hosted on visible right behind it. Click anywhere outside the image, and you’re right in the original page where you can learn more about the source and context.
+Optimized keyboard navigation for faster scrolling through many pages, taking advantage of standard web keyboard shortcuts such as Page Up / Page Down. It’s all about getting you to the info you need quickly, so you can get on with actually building that treehouse or buying those flowers.
+Apple's not really ready to say it's sorry about the iPhone 4 antenna design, but it is willing to give all you darn squeaky wheels free cases for your trouble. Since Apple can't build its own Bumpers fast enough, it will give you a few options and let you decide, then send it your way for free as long as you purchased the phone before September 30th. Not good enough for you? Well, if you already bought a bumper from Apple you'll get a refund, and you can also return your phone for a full refund within 30 days as long as it's unharmed.
+This solution comes at the end of 22 days of Apple engineers "working their butts off," according to Steve, with "physics" ultimately being pinned as the main culprit. Apple claims you can replicate the left-handed "death grip" bar-dropping problem on the BlackBerry Bold 9700, HTC Droid Eris, and Samsung Omnia II, and that "phones aren't perfect." Steve also claims that only 0.55% of people who bought the iPhone 4 have called into AppleCare to complain about the antenna, and the phone has a 1.7% return rate at AT&T, compared to 6% with the 3GS, though he would cop to a slight increase in dropped calls over the iPhone 3GS. For this Steve has what he confesses to be a pet theory: that 3GS users were using the case they had from the 3G, and therefore weren't met with the horrible reality of a naked, call dropping handset. Hence the free case solution, which will probably satisfy some, infuriate others, and never even blip onto the radar of many of the massive horde of consumers that's devoured this product in unprecedented numbers.
+Update: Our own Richard Lai just waltzed down to the Regent Street Apple Store in London with his iPhone Bumper receipt in hand. A few minutes later he left with cold, hard cash, and kept the Bumper to boot. Seems as if the refund effort is a go, at least over in the UK.
+Update 2: We've heard from several tipsters saying Apple no longer does Bumper refunds at its stores; customers will now have to make an online claim instead. Looks like we got super lucky.
+If you have ever received an instant message, text message, or any text-based chat message that seemed to be written in a foreign language, this Webopedia Quick Reference will help you decipher the text chat lingo by providing the definitions to more than 1,300 chat, text message, and Twitter abbreviations.
+With the popularity and rise in real-time text-based communications, such as Facebook, Twitter, instant messaging, e-mail, Internet and online gaming services, chat rooms, discussion boards and mobile phone text messaging (SMS), came the emergence of a new language tailored to the immediacy and compactness of these new communication media.
+While it does seem incredible that there are so many chat abbreviations, remember that different chat abbreviations are used by different groups of people when communicating online. Some of the following chat abbreviations may be familiar to you, while others may be foreign because they are used by a group of people with different online interests and hobbies than your own. For example, people playing online games are likely to use chat abbreviations that are different than those used by someone running a financial blog updating their Twitter status.
+Twitter is a free microblog, or social messaging tool that lets people stay connected through brief text message updates up to 140 characters in length. Twitter is based on you answering the question "What are you doing?" You then post thoughts, observations and goings-on during the day in answer to that question. Your update is posted on your Twitter profile page through SMS text messaging, the Twitter Web site, instant messaging, RSS, e-mail or through other social applications and sites, such as Facebook.
+As with any new social medium, there is an entire vocabulary that users of the Twitter service adopt. Many of the new lingo Twitter-based terms and phrases are used to describe the collection of people who use the service, while other terms are used in reference to describe specific functions and features of the service itself. Also, there are a number of "chat terms," which are basically shorthand abbreviations that users often include in their tweets. Lastly, our guide also provides descriptions to a number of Twitter tools and applications that you can use to enhance your Twitter experience.
+Here are definitions to more than 100 Twitter-related abbreviations, words, phrases, and tools that are associated with the Twitter microblogging service. If you know of a Twitter slang term or application name that is not included in our Twitter Dictionary, please let us know.
diff --git a/tests/src/com/android/inputmethod/latin/EventRingBufferTests.java b/tests/src/com/android/inputmethod/latin/EventRingBufferTests.java
new file mode 100644
index 0000000..620f036
--- /dev/null
+++ b/tests/src/com/android/inputmethod/latin/EventRingBufferTests.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.android.inputmethod.latin;
+
+import com.android.inputmethod.latin.SwipeTracker.EventRingBuffer;
+
+import android.test.AndroidTestCase;
+
+public class EventRingBufferTests extends AndroidTestCase {
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ private static float X_BASE = 1000f;
+
+ private static float Y_BASE = 2000f;
+
+ private static long TIME_BASE = 3000l;
+
+ private static float x(int id) {
+ return X_BASE + id;
+ }
+
+ private static float y(int id) {
+ return Y_BASE + id;
+ }
+
+ private static long time(int id) {
+ return TIME_BASE + id;
+ }
+
+ private static void addEvent(EventRingBuffer buf, int id) {
+ buf.add(x(id), y(id), time(id));
+ }
+
+ private static void assertEventSize(EventRingBuffer buf, int size) {
+ assertEquals(size, buf.size());
+ }
+
+ private static void assertEvent(EventRingBuffer buf, int pos, int id) {
+ assertEquals(x(id), buf.getX(pos), 0f);
+ assertEquals(y(id), buf.getY(pos), 0f);
+ assertEquals(time(id), buf.getTime(pos));
+ }
+
+ public void testClearBuffer() {
+ EventRingBuffer buf = new EventRingBuffer(4);
+ assertEventSize(buf, 0);
+
+ addEvent(buf, 0);
+ addEvent(buf, 1);
+ addEvent(buf, 2);
+ addEvent(buf, 3);
+ addEvent(buf, 4);
+ assertEventSize(buf, 4);
+
+ buf.clear();
+ assertEventSize(buf, 0);
+ }
+
+ public void testRingBuffer() {
+ EventRingBuffer buf = new EventRingBuffer(4);
+ assertEventSize(buf, 0); // [0]
+
+ addEvent(buf, 0);
+ assertEventSize(buf, 1); // [1] 0
+ assertEvent(buf, 0, 0);
+
+ addEvent(buf, 1);
+ addEvent(buf, 2);
+ assertEventSize(buf, 3); // [3] 2 1 0
+ assertEvent(buf, 0, 0);
+ assertEvent(buf, 1, 1);
+ assertEvent(buf, 2, 2);
+
+ addEvent(buf, 3);
+ assertEventSize(buf, 4); // [4] 3 2 1 0
+ assertEvent(buf, 0, 0);
+ assertEvent(buf, 1, 1);
+ assertEvent(buf, 2, 2);
+ assertEvent(buf, 3, 3);
+
+ addEvent(buf, 4);
+ addEvent(buf, 5);
+ assertEventSize(buf, 4); // [4] 5 4|3 2(1 0)
+ assertEvent(buf, 0, 2);
+ assertEvent(buf, 1, 3);
+ assertEvent(buf, 2, 4);
+ assertEvent(buf, 3, 5);
+
+ addEvent(buf, 6);
+ addEvent(buf, 7);
+ addEvent(buf, 8);
+ assertEventSize(buf, 4); // [4] 8 7 6 5|(4 3 2)1|0
+ assertEvent(buf, 0, 5);
+ assertEvent(buf, 1, 6);
+ assertEvent(buf, 2, 7);
+ assertEvent(buf, 3, 8);
+ }
+
+ public void testDropOldest() {
+ EventRingBuffer buf = new EventRingBuffer(4);
+
+ addEvent(buf, 0);
+ assertEventSize(buf, 1); // [1] 0
+ assertEvent(buf, 0, 0);
+
+ buf.dropOldest();
+ assertEventSize(buf, 0); // [0] (0)
+
+ addEvent(buf, 1);
+ addEvent(buf, 2);
+ addEvent(buf, 3);
+ addEvent(buf, 4);
+ assertEventSize(buf, 4); // [4] 4|3 2 1(0)
+ assertEvent(buf, 0, 1);
+
+ buf.dropOldest();
+ assertEventSize(buf, 3); // [3] 4|3 2(1)0
+ assertEvent(buf, 0, 2);
+
+ buf.dropOldest();
+ assertEventSize(buf, 2); // [2] 4|3(2)10
+ assertEvent(buf, 0, 3);
+
+ buf.dropOldest();
+ assertEventSize(buf, 1); // [1] 4|(3)210
+ assertEvent(buf, 0, 4);
+
+ buf.dropOldest();
+ assertEventSize(buf, 0); // [0] (4)|3210
+ }
+}
diff --git a/tests/src/com/android/inputmethod/latin/SuggestHelper.java b/tests/src/com/android/inputmethod/latin/SuggestHelper.java
new file mode 100644
index 0000000..759bfa1
--- /dev/null
+++ b/tests/src/com/android/inputmethod/latin/SuggestHelper.java
@@ -0,0 +1,268 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.android.inputmethod.latin;
+
+import android.content.Context;
+import android.text.TextUtils;
+import android.util.Log;
+import com.android.inputmethod.latin.Suggest;
+import com.android.inputmethod.latin.UserBigramDictionary;
+import com.android.inputmethod.latin.WordComposer;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.channels.Channels;
+import java.util.List;
+import java.util.Locale;
+import java.util.StringTokenizer;
+
+public class SuggestHelper {
+ private Suggest mSuggest;
+ private UserBigramDictionary mUserBigram;
+ private final String TAG;
+
+ /** Uses main dictionary only **/
+ public SuggestHelper(String tag, Context context, int[] resId) {
+ TAG = tag;
+ InputStream[] is = null;
+ try {
+ // merging separated dictionary into one if dictionary is separated
+ int total = 0;
+ is = new InputStream[resId.length];
+ for (int i = 0; i < resId.length; i++) {
+ is[i] = context.getResources().openRawResource(resId[i]);
+ total += is[i].available();
+ }
+
+ ByteBuffer byteBuffer =
+ ByteBuffer.allocateDirect(total).order(ByteOrder.nativeOrder());
+ int got = 0;
+ for (int i = 0; i < resId.length; i++) {
+ got += Channels.newChannel(is[i]).read(byteBuffer);
+ }
+ if (got != total) {
+ Log.w(TAG, "Read " + got + " bytes, expected " + total);
+ } else {
+ mSuggest = new Suggest(context, byteBuffer);
+ Log.i(TAG, "Created mSuggest " + total + " bytes");
+ }
+ } catch (IOException e) {
+ Log.w(TAG, "No available memory for binary dictionary");
+ } finally {
+ try {
+ if (is != null) {
+ for (int i = 0; i < is.length; i++) {
+ is[i].close();
+ }
+ }
+ } catch (IOException e) {
+ Log.w(TAG, "Failed to close input stream");
+ }
+ }
+ mSuggest.setAutoTextEnabled(false);
+ mSuggest.setCorrectionMode(Suggest.CORRECTION_FULL_BIGRAM);
+ }
+
+ /** Uses both main dictionary and user-bigram dictionary **/
+ public SuggestHelper(String tag, Context context, int[] resId, int userBigramMax,
+ int userBigramDelete) {
+ this(tag, context, resId);
+ mUserBigram = new UserBigramDictionary(context, null, Locale.US.toString(),
+ Suggest.DIC_USER);
+ mUserBigram.setDatabaseMax(userBigramMax);
+ mUserBigram.setDatabaseDelete(userBigramDelete);
+ mSuggest.setUserBigramDictionary(mUserBigram);
+ }
+
+ void changeUserBigramLocale(Context context, Locale locale) {
+ if (mUserBigram != null) {
+ flushUserBigrams();
+ mUserBigram.close();
+ mUserBigram = new UserBigramDictionary(context, null, locale.toString(),
+ Suggest.DIC_USER);
+ mSuggest.setUserBigramDictionary(mUserBigram);
+ }
+ }
+
+ private WordComposer createWordComposer(CharSequence s) {
+ WordComposer word = new WordComposer();
+ for (int i = 0; i < s.length(); i++) {
+ final char c = s.charAt(i);
+ int[] codes;
+ // If it's not a lowercase letter, don't find adjacent letters
+ if (c < 'a' || c > 'z') {
+ codes = new int[] { c };
+ } else {
+ codes = adjacents[c - 'a'];
+ }
+ word.add(c, codes);
+ }
+ return word;
+ }
+
+ private void showList(String title, List<CharSequence> suggestions) {
+ Log.i(TAG, title);
+ for (int i = 0; i < suggestions.size(); i++) {
+ Log.i(title, suggestions.get(i) + ", ");
+ }
+ }
+
+ private boolean isDefaultSuggestion(List<CharSequence> suggestions, CharSequence word) {
+ // Check if either the word is what you typed or the first alternative
+ return suggestions.size() > 0 &&
+ (/*TextUtils.equals(suggestions.get(0), word) || */
+ (suggestions.size() > 1 && TextUtils.equals(suggestions.get(1), word)));
+ }
+
+ boolean isDefaultSuggestion(CharSequence typed, CharSequence expected) {
+ WordComposer word = createWordComposer(typed);
+ List<CharSequence> suggestions = mSuggest.getSuggestions(null, word, false, null);
+ return isDefaultSuggestion(suggestions, expected);
+ }
+
+ boolean isDefaultCorrection(CharSequence typed, CharSequence expected) {
+ WordComposer word = createWordComposer(typed);
+ List<CharSequence> suggestions = mSuggest.getSuggestions(null, word, false, null);
+ return isDefaultSuggestion(suggestions, expected) && mSuggest.hasMinimalCorrection();
+ }
+
+ boolean isASuggestion(CharSequence typed, CharSequence expected) {
+ WordComposer word = createWordComposer(typed);
+ List<CharSequence> suggestions = mSuggest.getSuggestions(null, word, false, null);
+ for (int i = 1; i < suggestions.size(); i++) {
+ if (TextUtils.equals(suggestions.get(i), expected)) return true;
+ }
+ return false;
+ }
+
+ private void getBigramSuggestions(CharSequence previous, CharSequence typed) {
+ if (!TextUtils.isEmpty(previous) && (typed.length() > 1)) {
+ WordComposer firstChar = createWordComposer(Character.toString(typed.charAt(0)));
+ mSuggest.getSuggestions(null, firstChar, false, previous);
+ }
+ }
+
+ boolean isDefaultNextSuggestion(CharSequence previous, CharSequence typed,
+ CharSequence expected) {
+ WordComposer word = createWordComposer(typed);
+ getBigramSuggestions(previous, typed);
+ List<CharSequence> suggestions = mSuggest.getSuggestions(null, word, false, previous);
+ return isDefaultSuggestion(suggestions, expected);
+ }
+
+ boolean isDefaultNextCorrection(CharSequence previous, CharSequence typed,
+ CharSequence expected) {
+ WordComposer word = createWordComposer(typed);
+ getBigramSuggestions(previous, typed);
+ List<CharSequence> suggestions = mSuggest.getSuggestions(null, word, false, previous);
+ return isDefaultSuggestion(suggestions, expected) && mSuggest.hasMinimalCorrection();
+ }
+
+ boolean isASuggestion(CharSequence previous, CharSequence typed,
+ CharSequence expected) {
+ WordComposer word = createWordComposer(typed);
+ getBigramSuggestions(previous, typed);
+ List<CharSequence> suggestions = mSuggest.getSuggestions(null, word, false, previous);
+ for (int i = 1; i < suggestions.size(); i++) {
+ if (TextUtils.equals(suggestions.get(i), expected)) return true;
+ }
+ return false;
+ }
+
+ boolean isValid(CharSequence typed) {
+ return mSuggest.isValidWord(typed);
+ }
+
+ boolean isUserBigramSuggestion(CharSequence previous, char typed,
+ CharSequence expected) {
+ WordComposer word = createWordComposer(Character.toString(typed));
+
+ if (mUserBigram == null) return false;
+
+ flushUserBigrams();
+ if (!TextUtils.isEmpty(previous) && !TextUtils.isEmpty(Character.toString(typed))) {
+ WordComposer firstChar = createWordComposer(Character.toString(typed));
+ mSuggest.getSuggestions(null, firstChar, false, previous);
+ boolean reloading = mUserBigram.reloadDictionaryIfRequired();
+ if (reloading) mUserBigram.waitForDictionaryLoading();
+ mUserBigram.getBigrams(firstChar, previous, mSuggest, null);
+ }
+
+ List<CharSequence> suggestions = mSuggest.mBigramSuggestions;
+ for (int i = 0; i < suggestions.size(); i++) {
+ if (TextUtils.equals(suggestions.get(i), expected)) return true;
+ }
+
+ return false;
+ }
+
+ void addToUserBigram(String sentence) {
+ StringTokenizer st = new StringTokenizer(sentence);
+ String previous = null;
+ while (st.hasMoreTokens()) {
+ String current = st.nextToken();
+ if (previous != null) {
+ addToUserBigram(new String[] {previous, current});
+ }
+ previous = current;
+ }
+ }
+
+ void addToUserBigram(String[] pair) {
+ if (mUserBigram != null && pair.length == 2) {
+ mUserBigram.addBigrams(pair[0], pair[1]);
+ }
+ }
+
+ void flushUserBigrams() {
+ if (mUserBigram != null) {
+ mUserBigram.flushPendingWrites();
+ mUserBigram.waitUntilUpdateDBDone();
+ }
+ }
+
+ final int[][] adjacents = {
+ {'a','s','w','q',-1},
+ {'b','h','v','n','g','j',-1},
+ {'c','v','f','x','g',},
+ {'d','f','r','e','s','x',-1},
+ {'e','w','r','s','d',-1},
+ {'f','g','d','c','t','r',-1},
+ {'g','h','f','y','t','v',-1},
+ {'h','j','u','g','b','y',-1},
+ {'i','o','u','k',-1},
+ {'j','k','i','h','u','n',-1},
+ {'k','l','o','j','i','m',-1},
+ {'l','k','o','p',-1},
+ {'m','k','n','l',-1},
+ {'n','m','j','k','b',-1},
+ {'o','p','i','l',-1},
+ {'p','o',-1},
+ {'q','w',-1},
+ {'r','t','e','f',-1},
+ {'s','d','e','w','a','z',-1},
+ {'t','y','r',-1},
+ {'u','y','i','h','j',-1},
+ {'v','b','g','c','h',-1},
+ {'w','e','q',-1},
+ {'x','c','d','z','f',-1},
+ {'y','u','t','h','g',-1},
+ {'z','s','x','a','d',-1},
+ };
+}
diff --git a/tests/src/com/android/inputmethod/latin/SuggestPerformanceTests.java b/tests/src/com/android/inputmethod/latin/SuggestPerformanceTests.java
new file mode 100644
index 0000000..7eb66d5
--- /dev/null
+++ b/tests/src/com/android/inputmethod/latin/SuggestPerformanceTests.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.android.inputmethod.latin;
+
+import android.test.AndroidTestCase;
+import android.util.Log;
+import com.android.inputmethod.latin.tests.R;
+import java.io.InputStreamReader;
+import java.io.InputStream;
+import java.io.BufferedReader;
+import java.util.StringTokenizer;
+
+public class SuggestPerformanceTests extends AndroidTestCase {
+ private static final String TAG = "SuggestPerformanceTests";
+
+ private String mTestText;
+ private SuggestHelper sh;
+
+ @Override
+ protected void setUp() {
+ // TODO Figure out a way to directly using the dictionary rather than copying it over
+
+ // For testing with real dictionary, TEMPORARILY COPY main dictionary into test directory.
+ // DO NOT SUBMIT real dictionary under test directory.
+ //int[] resId = new int[] { R.raw.main0, R.raw.main1, R.raw.main2 };
+
+ int[] resId = new int[] { R.raw.test };
+
+ sh = new SuggestHelper(TAG, getTestContext(), resId);
+ loadString();
+ }
+
+ private void loadString() {
+ try {
+ InputStream is = getTestContext().getResources().openRawResource(R.raw.testtext);
+ BufferedReader reader = new BufferedReader(new InputStreamReader(is));
+ StringBuilder sb = new StringBuilder();
+ String line = reader.readLine();
+ while (line != null) {
+ sb.append(line + " ");
+ line = reader.readLine();
+ }
+ mTestText = sb.toString();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /************************** Helper functions ************************/
+ private int lookForSuggestion(String prevWord, String currentWord) {
+ for (int i = 1; i < currentWord.length(); i++) {
+ if (i == 1) {
+ if (sh.isDefaultNextSuggestion(prevWord, currentWord.substring(0, i),
+ currentWord)) {
+ return i;
+ }
+ } else {
+ if (sh.isDefaultNextCorrection(prevWord, currentWord.substring(0, i),
+ currentWord)) {
+ return i;
+ }
+ }
+ }
+ return currentWord.length();
+ }
+
+ private double runText(boolean withBigrams) {
+ StringTokenizer st = new StringTokenizer(mTestText);
+ String prevWord = null;
+ int typeCount = 0;
+ int characterCount = 0; // without space
+ int wordCount = 0;
+ while (st.hasMoreTokens()) {
+ String currentWord = st.nextToken();
+ boolean endCheck = false;
+ if (currentWord.matches("[\\w]*[\\.|?|!|*|@|&|/|:|;]")) {
+ currentWord = currentWord.substring(0, currentWord.length() - 1);
+ endCheck = true;
+ }
+ if (withBigrams && prevWord != null) {
+ typeCount += lookForSuggestion(prevWord, currentWord);
+ } else {
+ typeCount += lookForSuggestion(null, currentWord);
+ }
+ characterCount += currentWord.length();
+ if (!endCheck) prevWord = currentWord;
+ wordCount++;
+ }
+
+ double result = (double) (characterCount - typeCount) / characterCount * 100;
+ if (withBigrams) {
+ Log.i(TAG, "with bigrams -> " + result + " % saved!");
+ } else {
+ Log.i(TAG, "without bigrams -> " + result + " % saved!");
+ }
+ Log.i(TAG, "\ttotal number of words: " + wordCount);
+ Log.i(TAG, "\ttotal number of characters: " + mTestText.length());
+ Log.i(TAG, "\ttotal number of characters without space: " + characterCount);
+ Log.i(TAG, "\ttotal number of characters typed: " + typeCount);
+ return result;
+ }
+
+
+ /************************** Performance Tests ************************/
+ /**
+ * Compare the Suggest with and without bigram
+ * Check the log for detail
+ */
+ public void testSuggestPerformance() {
+ assertTrue(runText(false) <= runText(true));
+ }
+}
diff --git a/tests/src/com/android/inputmethod/latin/SuggestTests.java b/tests/src/com/android/inputmethod/latin/SuggestTests.java
new file mode 100644
index 0000000..8463ed3
--- /dev/null
+++ b/tests/src/com/android/inputmethod/latin/SuggestTests.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.android.inputmethod.latin;
+
+import android.test.AndroidTestCase;
+import com.android.inputmethod.latin.tests.R;
+
+public class SuggestTests extends AndroidTestCase {
+ private static final String TAG = "SuggestTests";
+
+ private SuggestHelper sh;
+
+ @Override
+ protected void setUp() {
+ int[] resId = new int[] { R.raw.test };
+ sh = new SuggestHelper(TAG, getTestContext(), resId);
+ }
+
+ /************************** Tests ************************/
+
+ /**
+ * Tests for simple completions of one character.
+ */
+ public void testCompletion1char() {
+ assertTrue(sh.isDefaultSuggestion("peopl", "people"));
+ assertTrue(sh.isDefaultSuggestion("abou", "about"));
+ assertTrue(sh.isDefaultSuggestion("thei", "their"));
+ }
+
+ /**
+ * Tests for simple completions of two characters.
+ */
+ public void testCompletion2char() {
+ assertTrue(sh.isDefaultSuggestion("peop", "people"));
+ assertTrue(sh.isDefaultSuggestion("calli", "calling"));
+ assertTrue(sh.isDefaultSuggestion("busine", "business"));
+ }
+
+ /**
+ * Tests for proximity errors.
+ */
+ public void testProximityPositive() {
+ assertTrue(sh.isDefaultSuggestion("peiple", "people"));
+ assertTrue(sh.isDefaultSuggestion("peoole", "people"));
+ assertTrue(sh.isDefaultSuggestion("pwpple", "people"));
+ }
+
+ /**
+ * Tests for proximity errors - negative, when the error key is not near.
+ */
+ public void testProximityNegative() {
+ assertFalse(sh.isDefaultSuggestion("arout", "about"));
+ assertFalse(sh.isDefaultSuggestion("ire", "are"));
+ }
+
+ /**
+ * Tests for checking if apostrophes are added automatically.
+ */
+ public void testApostropheInsertion() {
+ assertTrue(sh.isDefaultSuggestion("im", "I'm"));
+ assertTrue(sh.isDefaultSuggestion("dont", "don't"));
+ }
+
+ /**
+ * Test to make sure apostrophed word is not suggested for an apostrophed word.
+ */
+ public void testApostrophe() {
+ assertFalse(sh.isDefaultSuggestion("don't", "don't"));
+ }
+
+ /**
+ * Tests for suggestion of capitalized version of a word.
+ */
+ public void testCapitalization() {
+ assertTrue(sh.isDefaultSuggestion("i'm", "I'm"));
+ assertTrue(sh.isDefaultSuggestion("sunday", "Sunday"));
+ assertTrue(sh.isDefaultSuggestion("sundat", "Sunday"));
+ }
+
+ /**
+ * Tests to see if more than one completion is provided for certain prefixes.
+ */
+ public void testMultipleCompletions() {
+ assertTrue(sh.isASuggestion("com", "come"));
+ assertTrue(sh.isASuggestion("com", "company"));
+ assertTrue(sh.isASuggestion("th", "the"));
+ assertTrue(sh.isASuggestion("th", "that"));
+ assertTrue(sh.isASuggestion("th", "this"));
+ assertTrue(sh.isASuggestion("th", "they"));
+ }
+
+ /**
+ * Does the suggestion engine recognize zero frequency words as valid words.
+ */
+ public void testZeroFrequencyAccepted() {
+ assertTrue(sh.isValid("yikes"));
+ assertFalse(sh.isValid("yike"));
+ }
+
+ /**
+ * Tests to make sure that zero frequency words are not suggested as completions.
+ */
+ public void testZeroFrequencySuggestionsNegative() {
+ assertFalse(sh.isASuggestion("yike", "yikes"));
+ assertFalse(sh.isASuggestion("what", "whatcha"));
+ }
+
+ /**
+ * Tests to ensure that words with large edit distances are not suggested, in some cases
+ * and not considered corrections, in some cases.
+ */
+ public void testTooLargeEditDistance() {
+ assertFalse(sh.isASuggestion("sniyr", "about"));
+ assertFalse(sh.isDefaultCorrection("rjw", "the"));
+ }
+
+ /**
+ * Make sure sh.isValid is case-sensitive.
+ */
+ public void testValidityCaseSensitivity() {
+ assertTrue(sh.isValid("Sunday"));
+ assertFalse(sh.isValid("sunday"));
+ }
+
+ /**
+ * Are accented forms of words suggested as corrections?
+ */
+ public void testAccents() {
+ // ni<LATIN SMALL LETTER N WITH TILDE>o
+ assertTrue(sh.isDefaultCorrection("nino", "ni\u00F1o"));
+ // ni<LATIN SMALL LETTER N WITH TILDE>o
+ assertTrue(sh.isDefaultCorrection("nimo", "ni\u00F1o"));
+ // Mar<LATIN SMALL LETTER I WITH ACUTE>a
+ assertTrue(sh.isDefaultCorrection("maria", "Mar\u00EDa"));
+ }
+
+ /**
+ * Make sure bigrams are showing when first character is typed
+ * and don't show any when there aren't any
+ */
+ public void testBigramsAtFirstChar() {
+ assertTrue(sh.isDefaultNextSuggestion("about", "p", "part"));
+ assertTrue(sh.isDefaultNextSuggestion("I'm", "a", "about"));
+ assertTrue(sh.isDefaultNextSuggestion("about", "b", "business"));
+ assertTrue(sh.isASuggestion("about", "b", "being"));
+ assertFalse(sh.isDefaultNextSuggestion("about", "p", "business"));
+ }
+
+ /**
+ * Make sure bigrams score affects the original score
+ */
+ public void testBigramsScoreEffect() {
+ assertTrue(sh.isDefaultCorrection("pa", "page"));
+ assertTrue(sh.isDefaultNextCorrection("about", "pa", "part"));
+ assertTrue(sh.isDefaultCorrection("sa", "said"));
+ assertTrue(sh.isDefaultNextCorrection("from", "sa", "same"));
+ }
+}
diff --git a/tests/src/com/android/inputmethod/latin/UserBigramTests.java b/tests/src/com/android/inputmethod/latin/UserBigramTests.java
new file mode 100644
index 0000000..cbf7bd8
--- /dev/null
+++ b/tests/src/com/android/inputmethod/latin/UserBigramTests.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.android.inputmethod.latin;
+
+import android.test.AndroidTestCase;
+import com.android.inputmethod.latin.tests.R;
+import java.util.Locale;
+
+public class UserBigramTests extends AndroidTestCase {
+ private static final String TAG = "UserBigramTests";
+
+ private static final int SUGGESTION_STARTS = 6;
+ private static final int MAX_DATA = 20;
+ private static final int DELETE_DATA = 10;
+
+ private SuggestHelper sh;
+
+ @Override
+ protected void setUp() {
+ int[] resId = new int[] { R.raw.test };
+ sh = new SuggestHelper(TAG, getTestContext(), resId, MAX_DATA, DELETE_DATA);
+ }
+
+ /************************** Tests ************************/
+
+ /**
+ * Test suggestion started at right time
+ */
+ public void testUserBigram() {
+ for (int i = 0; i < SUGGESTION_STARTS; i++) sh.addToUserBigram(pair1);
+ for (int i = 0; i < (SUGGESTION_STARTS - 1); i++) sh.addToUserBigram(pair2);
+
+ assertTrue(sh.isUserBigramSuggestion("user", 'b', "bigram"));
+ assertFalse(sh.isUserBigramSuggestion("android", 'p', "platform"));
+ }
+
+ /**
+ * Test loading correct (locale) bigrams
+ */
+ public void testOpenAndClose() {
+ for (int i = 0; i < SUGGESTION_STARTS; i++) sh.addToUserBigram(pair1);
+ assertTrue(sh.isUserBigramSuggestion("user", 'b', "bigram"));
+
+ // change to fr_FR
+ sh.changeUserBigramLocale(getTestContext(), Locale.FRANCE);
+ for (int i = 0; i < SUGGESTION_STARTS; i++) sh.addToUserBigram(pair3);
+ assertTrue(sh.isUserBigramSuggestion("locale", 'f', "france"));
+ assertFalse(sh.isUserBigramSuggestion("user", 'b', "bigram"));
+
+ // change back to en_US
+ sh.changeUserBigramLocale(getTestContext(), Locale.US);
+ assertFalse(sh.isUserBigramSuggestion("locale", 'f', "france"));
+ assertTrue(sh.isUserBigramSuggestion("user", 'b', "bigram"));
+ }
+
+ /**
+ * Test data gets pruned when it is over maximum
+ */
+ public void testPruningData() {
+ for (int i = 0; i < SUGGESTION_STARTS; i++) sh.addToUserBigram(sentence0);
+ sh.flushUserBigrams();
+ assertTrue(sh.isUserBigramSuggestion("Hello", 'w', "world"));
+
+ sh.addToUserBigram(sentence1);
+ sh.addToUserBigram(sentence2);
+ assertTrue(sh.isUserBigramSuggestion("Hello", 'w', "world"));
+
+ // pruning should happen
+ sh.addToUserBigram(sentence3);
+ sh.addToUserBigram(sentence4);
+
+ // trying to reopen database to check pruning happened in database
+ sh.changeUserBigramLocale(getTestContext(), Locale.US);
+ assertFalse(sh.isUserBigramSuggestion("Hello", 'w', "world"));
+ }
+
+ final String[] pair1 = new String[] {"user", "bigram"};
+ final String[] pair2 = new String[] {"android","platform"};
+ final String[] pair3 = new String[] {"locale", "france"};
+ final String sentence0 = "Hello world";
+ final String sentence1 = "This is a test for user input based bigram";
+ final String sentence2 = "It learns phrases that contain both dictionary and nondictionary "
+ + "words";
+ final String sentence3 = "This should give better suggestions than the previous version";
+ final String sentence4 = "Android stock keyboard is improving";
+}