diff options
author | 2010-03-09 12:46:57 -0800 | |
---|---|---|
committer | 2010-03-09 15:01:09 -0800 | |
commit | 07b1603a3f9611f6d15dd7fcedf883d6ef8e5817 (patch) | |
tree | 3a88daaee27b886909a5af8a646b41dfb794a9f8 /java | |
parent | 81c52293f84ce475ac6b1661f4a4b92703405247 (diff) | |
download | latinime-07b1603a3f9611f6d15dd7fcedf883d6ef8e5817.tar.gz latinime-07b1603a3f9611f6d15dd7fcedf883d6ef8e5817.tar.xz latinime-07b1603a3f9611f6d15dd7fcedf883d6ef8e5817.zip |
Don't let the native code target be included twice when unbundling.
Move java code to a different directory so that the unbundled
version doesn't try to compile the native code again.
Change-Id: I05cf9e643824ddc448821f69805ccb0240c5b986
Diffstat (limited to 'java')
297 files changed, 14390 insertions, 0 deletions
diff --git a/java/Android.mk b/java/Android.mk new file mode 100755 index 000000000..4bb8986ee --- /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-subdir-java-files) + +LOCAL_PACKAGE_NAME := LatinIME + +LOCAL_CERTIFICATE := shared + +LOCAL_JNI_SHARED_LIBRARIES := libjni_latinime + +LOCAL_STATIC_JAVA_LIBRARIES := android-common + +#LOCAL_AAPT_FLAGS := -0 .dict + +LOCAL_SDK_VERSION := current + +LOCAL_PROGUARD_FLAGS := -include $(LOCAL_PATH)/proguard.flags + +include $(BUILD_PACKAGE) diff --git a/java/AndroidManifest.xml b/java/AndroidManifest.xml new file mode 100755 index 000000000..23dbf7564 --- /dev/null +++ b/java/AndroidManifest.xml @@ -0,0 +1,40 @@ +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.inputmethod.latin" + android:sharedUserId="android.uid.shared"> + + <original-package android:name="com.android.inputmethod.latin" /> + + <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" /> + + <application android:label="@string/english_ime_name" + android:backupAgent="LatinIMEBackupAgent" + android:killAfterRestore="false"> + + <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="LatinIMESettings" android:label="@string/english_ime_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="com.android.inputmethod.latin.INPUT_LANGUAGE_SELECTION"/> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + </activity> + </application> +</manifest> diff --git a/java/proguard.flags b/java/proguard.flags new file mode 100644 index 000000000..0a5d2dda9 --- /dev/null +++ b/java/proguard.flags @@ -0,0 +1,3 @@ +-keep class com.android.inputmethod.latin.BinaryDictionary { + int mDictLength; +} diff --git a/java/res/drawable-en-hdpi/sym_keyboard_delete.png b/java/res/drawable-en-hdpi/sym_keyboard_delete.png Binary files differnew file mode 100755 index 000000000..569369e79 --- /dev/null +++ b/java/res/drawable-en-hdpi/sym_keyboard_delete.png diff --git a/java/res/drawable-en-hdpi/sym_keyboard_feedback_delete.png b/java/res/drawable-en-hdpi/sym_keyboard_feedback_delete.png Binary files differnew file mode 100755 index 000000000..ca7637552 --- /dev/null +++ b/java/res/drawable-en-hdpi/sym_keyboard_feedback_delete.png diff --git a/java/res/drawable-en-mdpi/sym_keyboard_delete.png b/java/res/drawable-en-mdpi/sym_keyboard_delete.png Binary files differnew file mode 100644 index 000000000..f1f7c58cf --- /dev/null +++ b/java/res/drawable-en-mdpi/sym_keyboard_delete.png diff --git a/java/res/drawable-en-mdpi/sym_keyboard_feedback_delete.png b/java/res/drawable-en-mdpi/sym_keyboard_feedback_delete.png Binary files differnew file mode 100644 index 000000000..3c9083972 --- /dev/null +++ b/java/res/drawable-en-mdpi/sym_keyboard_feedback_delete.png diff --git a/java/res/drawable-hdpi/btn_keyboard_key_fulltrans_normal.9.png b/java/res/drawable-hdpi/btn_keyboard_key_fulltrans_normal.9.png Binary files differnew file mode 100644 index 000000000..b6c234c04 --- /dev/null +++ b/java/res/drawable-hdpi/btn_keyboard_key_fulltrans_normal.9.png diff --git a/java/res/drawable-hdpi/btn_keyboard_key_fulltrans_pressed.9.png b/java/res/drawable-hdpi/btn_keyboard_key_fulltrans_pressed.9.png Binary files differnew file mode 100644 index 000000000..73a8cd1c3 --- /dev/null +++ b/java/res/drawable-hdpi/btn_keyboard_key_fulltrans_pressed.9.png diff --git a/java/res/drawable-hdpi/btn_keyboard_key_normal.9.png b/java/res/drawable-hdpi/btn_keyboard_key_normal.9.png Binary files differnew file mode 100644 index 000000000..42c7c146d --- /dev/null +++ b/java/res/drawable-hdpi/btn_keyboard_key_normal.9.png diff --git a/java/res/drawable-hdpi/btn_keyboard_key_normal_off.9.png b/java/res/drawable-hdpi/btn_keyboard_key_normal_off.9.png Binary files differnew file mode 100644 index 000000000..01e2506b0 --- /dev/null +++ b/java/res/drawable-hdpi/btn_keyboard_key_normal_off.9.png diff --git a/java/res/drawable-hdpi/btn_keyboard_key_normal_on.9.png b/java/res/drawable-hdpi/btn_keyboard_key_normal_on.9.png Binary files differnew file mode 100644 index 000000000..83c6eb3fc --- /dev/null +++ b/java/res/drawable-hdpi/btn_keyboard_key_normal_on.9.png diff --git a/java/res/drawable-hdpi/btn_keyboard_key_pressed.9.png b/java/res/drawable-hdpi/btn_keyboard_key_pressed.9.png Binary files differnew file mode 100644 index 000000000..e047eaff1 --- /dev/null +++ b/java/res/drawable-hdpi/btn_keyboard_key_pressed.9.png diff --git a/java/res/drawable-hdpi/btn_keyboard_key_pressed_off.9.png b/java/res/drawable-hdpi/btn_keyboard_key_pressed_off.9.png Binary files differnew file mode 100644 index 000000000..218a2d29e --- /dev/null +++ b/java/res/drawable-hdpi/btn_keyboard_key_pressed_off.9.png diff --git a/java/res/drawable-hdpi/btn_keyboard_key_pressed_on.9.png b/java/res/drawable-hdpi/btn_keyboard_key_pressed_on.9.png Binary files differnew file mode 100644 index 000000000..afe49512e --- /dev/null +++ b/java/res/drawable-hdpi/btn_keyboard_key_pressed_on.9.png diff --git a/java/res/drawable-hdpi/cancel.png b/java/res/drawable-hdpi/cancel.png Binary files differnew file mode 100755 index 000000000..6585bde17 --- /dev/null +++ b/java/res/drawable-hdpi/cancel.png diff --git a/java/res/drawable-hdpi/candidate_feedback_background.9.png b/java/res/drawable-hdpi/candidate_feedback_background.9.png Binary files differnew file mode 100755 index 000000000..203c4e640 --- /dev/null +++ b/java/res/drawable-hdpi/candidate_feedback_background.9.png diff --git a/java/res/drawable-hdpi/caution.png b/java/res/drawable-hdpi/caution.png Binary files differnew file mode 100755 index 000000000..5cb6c54b9 --- /dev/null +++ b/java/res/drawable-hdpi/caution.png diff --git a/java/res/drawable-hdpi/dialog_bubble_step02.9.png b/java/res/drawable-hdpi/dialog_bubble_step02.9.png Binary files differnew file mode 100755 index 000000000..b338364c5 --- /dev/null +++ b/java/res/drawable-hdpi/dialog_bubble_step02.9.png diff --git a/java/res/drawable-hdpi/dialog_bubble_step07.9.png b/java/res/drawable-hdpi/dialog_bubble_step07.9.png Binary files differnew file mode 100755 index 000000000..94b915432 --- /dev/null +++ b/java/res/drawable-hdpi/dialog_bubble_step07.9.png diff --git a/java/res/drawable-hdpi/dialog_top_dark_bottom_medium.png b/java/res/drawable-hdpi/dialog_top_dark_bottom_medium.png Binary files differnew file mode 100755 index 000000000..7c79a4f90 --- /dev/null +++ b/java/res/drawable-hdpi/dialog_top_dark_bottom_medium.png diff --git a/java/res/drawable-hdpi/highlight_pressed.png b/java/res/drawable-hdpi/highlight_pressed.png Binary files differnew file mode 100644 index 000000000..ae04901a0 --- /dev/null +++ b/java/res/drawable-hdpi/highlight_pressed.png diff --git a/java/res/drawable-hdpi/ic_dialog_alert_large.png b/java/res/drawable-hdpi/ic_dialog_alert_large.png Binary files differnew file mode 100755 index 000000000..7e2646d65 --- /dev/null +++ b/java/res/drawable-hdpi/ic_dialog_alert_large.png diff --git a/java/res/drawable-hdpi/ic_dialog_keyboard.png b/java/res/drawable-hdpi/ic_dialog_keyboard.png Binary files differnew file mode 100755 index 000000000..c7729566c --- /dev/null +++ b/java/res/drawable-hdpi/ic_dialog_keyboard.png diff --git a/java/res/drawable-hdpi/ic_dialog_voice_input.png b/java/res/drawable-hdpi/ic_dialog_voice_input.png Binary files differnew file mode 100755 index 000000000..11a3cfe77 --- /dev/null +++ b/java/res/drawable-hdpi/ic_dialog_voice_input.png diff --git a/java/res/drawable-hdpi/ic_dialog_wave_0_0.png b/java/res/drawable-hdpi/ic_dialog_wave_0_0.png Binary files differnew file mode 100755 index 000000000..33023c3f7 --- /dev/null +++ b/java/res/drawable-hdpi/ic_dialog_wave_0_0.png diff --git a/java/res/drawable-hdpi/ic_dialog_wave_1_3.png b/java/res/drawable-hdpi/ic_dialog_wave_1_3.png Binary files differnew file mode 100755 index 000000000..662686c0f --- /dev/null +++ b/java/res/drawable-hdpi/ic_dialog_wave_1_3.png diff --git a/java/res/drawable-hdpi/ic_dialog_wave_2_3.png b/java/res/drawable-hdpi/ic_dialog_wave_2_3.png Binary files differnew file mode 100755 index 000000000..e23ada57e --- /dev/null +++ b/java/res/drawable-hdpi/ic_dialog_wave_2_3.png diff --git a/java/res/drawable-hdpi/ic_dialog_wave_3_3.png b/java/res/drawable-hdpi/ic_dialog_wave_3_3.png Binary files differnew file mode 100755 index 000000000..5fe5492ad --- /dev/null +++ b/java/res/drawable-hdpi/ic_dialog_wave_3_3.png diff --git a/java/res/drawable-hdpi/ic_dialog_wave_4_3.png b/java/res/drawable-hdpi/ic_dialog_wave_4_3.png Binary files differnew file mode 100755 index 000000000..81b803fd0 --- /dev/null +++ b/java/res/drawable-hdpi/ic_dialog_wave_4_3.png diff --git a/java/res/drawable-hdpi/ic_mic_dialog.png b/java/res/drawable-hdpi/ic_mic_dialog.png Binary files differnew file mode 100644 index 000000000..349dc4b37 --- /dev/null +++ b/java/res/drawable-hdpi/ic_mic_dialog.png diff --git a/java/res/drawable-hdpi/ic_suggest_strip_microphone.png b/java/res/drawable-hdpi/ic_suggest_strip_microphone.png Binary files differnew file mode 100644 index 000000000..c00b4aaa6 --- /dev/null +++ b/java/res/drawable-hdpi/ic_suggest_strip_microphone.png diff --git a/java/res/drawable-hdpi/ic_suggest_strip_microphone_swipe.png b/java/res/drawable-hdpi/ic_suggest_strip_microphone_swipe.png Binary files differnew file mode 100644 index 000000000..256dc3d61 --- /dev/null +++ b/java/res/drawable-hdpi/ic_suggest_strip_microphone_swipe.png diff --git a/java/res/drawable-hdpi/ic_suggest_strip_scroll_left_arrow.png b/java/res/drawable-hdpi/ic_suggest_strip_scroll_left_arrow.png Binary files differnew file mode 100755 index 000000000..e375f262f --- /dev/null +++ b/java/res/drawable-hdpi/ic_suggest_strip_scroll_left_arrow.png diff --git a/java/res/drawable-hdpi/ic_suggest_strip_scroll_right_arrow.png b/java/res/drawable-hdpi/ic_suggest_strip_scroll_right_arrow.png Binary files differnew file mode 100755 index 000000000..d38ae7562 --- /dev/null +++ b/java/res/drawable-hdpi/ic_suggest_strip_scroll_right_arrow.png diff --git a/java/res/drawable-hdpi/keyboard_background.9.png b/java/res/drawable-hdpi/keyboard_background.9.png Binary files differnew file mode 100755 index 000000000..edffac5b8 --- /dev/null +++ b/java/res/drawable-hdpi/keyboard_background.9.png diff --git a/java/res/drawable-hdpi/keyboard_suggest_strip.9.png b/java/res/drawable-hdpi/keyboard_suggest_strip.9.png Binary files differnew file mode 100755 index 000000000..0cbb3ed86 --- /dev/null +++ b/java/res/drawable-hdpi/keyboard_suggest_strip.9.png diff --git a/java/res/drawable-hdpi/keyboard_suggest_strip_divider.png b/java/res/drawable-hdpi/keyboard_suggest_strip_divider.png Binary files differnew file mode 100644 index 000000000..a5980388a --- /dev/null +++ b/java/res/drawable-hdpi/keyboard_suggest_strip_divider.png diff --git a/java/res/drawable-hdpi/list_selector_background_pressed.9.png b/java/res/drawable-hdpi/list_selector_background_pressed.9.png Binary files differnew file mode 100644 index 000000000..ba79cf7f8 --- /dev/null +++ b/java/res/drawable-hdpi/list_selector_background_pressed.9.png diff --git a/java/res/drawable-hdpi/mic_slash.png b/java/res/drawable-hdpi/mic_slash.png Binary files differnew file mode 100644 index 000000000..a7b734c71 --- /dev/null +++ b/java/res/drawable-hdpi/mic_slash.png diff --git a/java/res/drawable-hdpi/ok_cancel.png b/java/res/drawable-hdpi/ok_cancel.png Binary files differnew file mode 100755 index 000000000..6a99528ef --- /dev/null +++ b/java/res/drawable-hdpi/ok_cancel.png diff --git a/java/res/drawable-hdpi/speak_now_level0.png b/java/res/drawable-hdpi/speak_now_level0.png Binary files differnew file mode 100755 index 000000000..a681da606 --- /dev/null +++ b/java/res/drawable-hdpi/speak_now_level0.png diff --git a/java/res/drawable-hdpi/speak_now_level1.png b/java/res/drawable-hdpi/speak_now_level1.png Binary files differnew file mode 100755 index 000000000..0dbec69a7 --- /dev/null +++ b/java/res/drawable-hdpi/speak_now_level1.png diff --git a/java/res/drawable-hdpi/speak_now_level2.png b/java/res/drawable-hdpi/speak_now_level2.png Binary files differnew file mode 100755 index 000000000..45cbff2b7 --- /dev/null +++ b/java/res/drawable-hdpi/speak_now_level2.png diff --git a/java/res/drawable-hdpi/speak_now_level3.png b/java/res/drawable-hdpi/speak_now_level3.png Binary files differnew file mode 100755 index 000000000..abda8f683 --- /dev/null +++ b/java/res/drawable-hdpi/speak_now_level3.png diff --git a/java/res/drawable-hdpi/speak_now_level4.png b/java/res/drawable-hdpi/speak_now_level4.png Binary files differnew file mode 100755 index 000000000..18356351a --- /dev/null +++ b/java/res/drawable-hdpi/speak_now_level4.png diff --git a/java/res/drawable-hdpi/speak_now_level5.png b/java/res/drawable-hdpi/speak_now_level5.png Binary files differnew file mode 100755 index 000000000..7d4fd5f20 --- /dev/null +++ b/java/res/drawable-hdpi/speak_now_level5.png diff --git a/java/res/drawable-hdpi/speak_now_level6.png b/java/res/drawable-hdpi/speak_now_level6.png Binary files differnew file mode 100755 index 000000000..e06990faa --- /dev/null +++ b/java/res/drawable-hdpi/speak_now_level6.png diff --git a/java/res/drawable-hdpi/sym_keyboard_123_mic.png b/java/res/drawable-hdpi/sym_keyboard_123_mic.png Binary files differnew file mode 100644 index 000000000..62669803d --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_123_mic.png diff --git a/java/res/drawable-hdpi/sym_keyboard_delete.png b/java/res/drawable-hdpi/sym_keyboard_delete.png Binary files differnew file mode 100755 index 000000000..59d78bec0 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_delete.png diff --git a/java/res/drawable-hdpi/sym_keyboard_done.png b/java/res/drawable-hdpi/sym_keyboard_done.png Binary files differnew file mode 100755 index 000000000..471c5021b --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_done.png diff --git a/java/res/drawable-hdpi/sym_keyboard_feedback_123_mic.png b/java/res/drawable-hdpi/sym_keyboard_feedback_123_mic.png Binary files differnew file mode 100644 index 000000000..f57e581d5 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_feedback_123_mic.png diff --git a/java/res/drawable-hdpi/sym_keyboard_feedback_delete.png b/java/res/drawable-hdpi/sym_keyboard_feedback_delete.png Binary files differnew file mode 100755 index 000000000..ca7637552 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_feedback_delete.png diff --git a/java/res/drawable-hdpi/sym_keyboard_feedback_done.png b/java/res/drawable-hdpi/sym_keyboard_feedback_done.png Binary files differnew file mode 100755 index 000000000..7015e266a --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_feedback_done.png 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 Binary files differnew file mode 100644 index 000000000..c7638bff1 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_feedback_language_arrows_left.png 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 Binary files differnew file mode 100644 index 000000000..7acb07c86 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_feedback_language_arrows_right.png diff --git a/java/res/drawable-hdpi/sym_keyboard_feedback_mic.png b/java/res/drawable-hdpi/sym_keyboard_feedback_mic.png Binary files differnew file mode 100644 index 000000000..cb86a5598 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_feedback_mic.png diff --git a/java/res/drawable-hdpi/sym_keyboard_feedback_numalt.png b/java/res/drawable-hdpi/sym_keyboard_feedback_numalt.png Binary files differnew file mode 100755 index 000000000..728c6f7d4 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_feedback_numalt.png diff --git a/java/res/drawable-hdpi/sym_keyboard_feedback_return.png b/java/res/drawable-hdpi/sym_keyboard_feedback_return.png Binary files differnew file mode 100755 index 000000000..ae57299e4 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_feedback_return.png diff --git a/java/res/drawable-hdpi/sym_keyboard_feedback_search.png b/java/res/drawable-hdpi/sym_keyboard_feedback_search.png Binary files differnew file mode 100755 index 000000000..d931b39e2 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_feedback_search.png diff --git a/java/res/drawable-hdpi/sym_keyboard_feedback_shift.png b/java/res/drawable-hdpi/sym_keyboard_feedback_shift.png Binary files differnew file mode 100755 index 000000000..4db31c849 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_feedback_shift.png diff --git a/java/res/drawable-hdpi/sym_keyboard_feedback_shift_locked.png b/java/res/drawable-hdpi/sym_keyboard_feedback_shift_locked.png Binary files differnew file mode 100755 index 000000000..3fd5659fd --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_feedback_shift_locked.png diff --git a/java/res/drawable-hdpi/sym_keyboard_feedback_space.png b/java/res/drawable-hdpi/sym_keyboard_feedback_space.png Binary files differnew file mode 100755 index 000000000..98266ee52 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_feedback_space.png diff --git a/java/res/drawable-hdpi/sym_keyboard_feedback_tab.png b/java/res/drawable-hdpi/sym_keyboard_feedback_tab.png Binary files differnew file mode 100644 index 000000000..7754752f3 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_feedback_tab.png diff --git a/java/res/drawable-hdpi/sym_keyboard_feedback_tabprev.png b/java/res/drawable-hdpi/sym_keyboard_feedback_tabprev.png Binary files differnew file mode 100644 index 000000000..36f6b5364 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_feedback_tabprev.png diff --git a/java/res/drawable-hdpi/sym_keyboard_globe.png b/java/res/drawable-hdpi/sym_keyboard_globe.png Binary files differnew file mode 100644 index 000000000..fa747642d --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_globe.png diff --git a/java/res/drawable-hdpi/sym_keyboard_language_arrows_left.png b/java/res/drawable-hdpi/sym_keyboard_language_arrows_left.png Binary files differnew file mode 100644 index 000000000..65ccfda87 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_language_arrows_left.png diff --git a/java/res/drawable-hdpi/sym_keyboard_language_arrows_right.png b/java/res/drawable-hdpi/sym_keyboard_language_arrows_right.png Binary files differnew file mode 100644 index 000000000..0d01bc224 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_language_arrows_right.png diff --git a/java/res/drawable-hdpi/sym_keyboard_mic.png b/java/res/drawable-hdpi/sym_keyboard_mic.png Binary files differnew file mode 100644 index 000000000..0a0a68a96 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_mic.png diff --git a/java/res/drawable-hdpi/sym_keyboard_num0.png b/java/res/drawable-hdpi/sym_keyboard_num0.png Binary files differnew file mode 100755 index 000000000..10ac70b9d --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_num0.png diff --git a/java/res/drawable-hdpi/sym_keyboard_num1.png b/java/res/drawable-hdpi/sym_keyboard_num1.png Binary files differnew file mode 100755 index 000000000..0fc03efa5 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_num1.png diff --git a/java/res/drawable-hdpi/sym_keyboard_num2.png b/java/res/drawable-hdpi/sym_keyboard_num2.png Binary files differnew file mode 100755 index 000000000..283560b35 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_num2.png diff --git a/java/res/drawable-hdpi/sym_keyboard_num3.png b/java/res/drawable-hdpi/sym_keyboard_num3.png Binary files differnew file mode 100755 index 000000000..9a3b3294b --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_num3.png diff --git a/java/res/drawable-hdpi/sym_keyboard_num4.png b/java/res/drawable-hdpi/sym_keyboard_num4.png Binary files differnew file mode 100755 index 000000000..f13ff1ae9 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_num4.png diff --git a/java/res/drawable-hdpi/sym_keyboard_num5.png b/java/res/drawable-hdpi/sym_keyboard_num5.png Binary files differnew file mode 100755 index 000000000..c251329fa --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_num5.png diff --git a/java/res/drawable-hdpi/sym_keyboard_num6.png b/java/res/drawable-hdpi/sym_keyboard_num6.png Binary files differnew file mode 100755 index 000000000..4acba4c91 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_num6.png diff --git a/java/res/drawable-hdpi/sym_keyboard_num7.png b/java/res/drawable-hdpi/sym_keyboard_num7.png Binary files differnew file mode 100755 index 000000000..14931c18c --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_num7.png diff --git a/java/res/drawable-hdpi/sym_keyboard_num8.png b/java/res/drawable-hdpi/sym_keyboard_num8.png Binary files differnew file mode 100755 index 000000000..d4973fdc9 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_num8.png diff --git a/java/res/drawable-hdpi/sym_keyboard_num9.png b/java/res/drawable-hdpi/sym_keyboard_num9.png Binary files differnew file mode 100755 index 000000000..49cec66f4 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_num9.png diff --git a/java/res/drawable-hdpi/sym_keyboard_numalt.png b/java/res/drawable-hdpi/sym_keyboard_numalt.png Binary files differnew file mode 100755 index 000000000..3cc5311cd --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_numalt.png diff --git a/java/res/drawable-hdpi/sym_keyboard_numpound.png b/java/res/drawable-hdpi/sym_keyboard_numpound.png Binary files differnew file mode 100755 index 000000000..d09133929 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_numpound.png diff --git a/java/res/drawable-hdpi/sym_keyboard_numstar.png b/java/res/drawable-hdpi/sym_keyboard_numstar.png Binary files differnew file mode 100755 index 000000000..e838e169f --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_numstar.png diff --git a/java/res/drawable-hdpi/sym_keyboard_return.png b/java/res/drawable-hdpi/sym_keyboard_return.png Binary files differnew file mode 100755 index 000000000..58505c5e0 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_return.png diff --git a/java/res/drawable-hdpi/sym_keyboard_search.png b/java/res/drawable-hdpi/sym_keyboard_search.png Binary files differnew file mode 100755 index 000000000..e72cde3bb --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_search.png diff --git a/java/res/drawable-hdpi/sym_keyboard_shift.png b/java/res/drawable-hdpi/sym_keyboard_shift.png Binary files differnew file mode 100755 index 000000000..814908178 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_shift.png diff --git a/java/res/drawable-hdpi/sym_keyboard_shift_locked.png b/java/res/drawable-hdpi/sym_keyboard_shift_locked.png Binary files differnew file mode 100755 index 000000000..31ca27718 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_shift_locked.png diff --git a/java/res/drawable-hdpi/sym_keyboard_space.png b/java/res/drawable-hdpi/sym_keyboard_space.png Binary files differnew file mode 100755 index 000000000..3e98b3014 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_space.png diff --git a/java/res/drawable-hdpi/sym_keyboard_tab.png b/java/res/drawable-hdpi/sym_keyboard_tab.png Binary files differnew file mode 100644 index 000000000..1d4d92bd1 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_tab.png diff --git a/java/res/drawable-hdpi/sym_keyboard_tabprev.png b/java/res/drawable-hdpi/sym_keyboard_tabprev.png Binary files differnew file mode 100644 index 000000000..51bff1bcd --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_tabprev.png diff --git a/java/res/drawable-hdpi/voice_ime_background.9.png b/java/res/drawable-hdpi/voice_ime_background.9.png Binary files differnew file mode 100755 index 000000000..73fb0901e --- /dev/null +++ b/java/res/drawable-hdpi/voice_ime_background.9.png diff --git a/java/res/drawable-hdpi/working.png b/java/res/drawable-hdpi/working.png Binary files differnew file mode 100755 index 000000000..8b51ed116 --- /dev/null +++ b/java/res/drawable-hdpi/working.png diff --git a/java/res/drawable-land-hdpi/btn_keyboard_key_normal.9.png b/java/res/drawable-land-hdpi/btn_keyboard_key_normal.9.png Binary files differnew file mode 100755 index 000000000..603bf0e15 --- /dev/null +++ b/java/res/drawable-land-hdpi/btn_keyboard_key_normal.9.png diff --git a/java/res/drawable-land-hdpi/btn_keyboard_key_normal_off.9.png b/java/res/drawable-land-hdpi/btn_keyboard_key_normal_off.9.png Binary files differnew file mode 100755 index 000000000..6ddd516e7 --- /dev/null +++ b/java/res/drawable-land-hdpi/btn_keyboard_key_normal_off.9.png diff --git a/java/res/drawable-land-hdpi/btn_keyboard_key_normal_on.9.png b/java/res/drawable-land-hdpi/btn_keyboard_key_normal_on.9.png Binary files differnew file mode 100755 index 000000000..65fdeb353 --- /dev/null +++ b/java/res/drawable-land-hdpi/btn_keyboard_key_normal_on.9.png diff --git a/java/res/drawable-land-hdpi/btn_keyboard_key_pressed.9.png b/java/res/drawable-land-hdpi/btn_keyboard_key_pressed.9.png Binary files differnew file mode 100755 index 000000000..7ec915fe8 --- /dev/null +++ b/java/res/drawable-land-hdpi/btn_keyboard_key_pressed.9.png diff --git a/java/res/drawable-land-hdpi/btn_keyboard_key_pressed_off.9.png b/java/res/drawable-land-hdpi/btn_keyboard_key_pressed_off.9.png Binary files differnew file mode 100755 index 000000000..439271723 --- /dev/null +++ b/java/res/drawable-land-hdpi/btn_keyboard_key_pressed_off.9.png diff --git a/java/res/drawable-land-hdpi/btn_keyboard_key_pressed_on.9.png b/java/res/drawable-land-hdpi/btn_keyboard_key_pressed_on.9.png Binary files differnew file mode 100755 index 000000000..c2cc32044 --- /dev/null +++ b/java/res/drawable-land-hdpi/btn_keyboard_key_pressed_on.9.png diff --git a/java/res/drawable-land-hdpi/keyboard_suggest_strip_divider.png b/java/res/drawable-land-hdpi/keyboard_suggest_strip_divider.png Binary files differnew file mode 100755 index 000000000..1a03c52e6 --- /dev/null +++ b/java/res/drawable-land-hdpi/keyboard_suggest_strip_divider.png diff --git a/java/res/drawable-land-mdpi/btn_keyboard_key_normal.9.png b/java/res/drawable-land-mdpi/btn_keyboard_key_normal.9.png Binary files differnew file mode 100644 index 000000000..ea2506c6d --- /dev/null +++ b/java/res/drawable-land-mdpi/btn_keyboard_key_normal.9.png diff --git a/java/res/drawable-land-mdpi/btn_keyboard_key_normal_off.9.png b/java/res/drawable-land-mdpi/btn_keyboard_key_normal_off.9.png Binary files differnew file mode 100644 index 000000000..bda9b8394 --- /dev/null +++ b/java/res/drawable-land-mdpi/btn_keyboard_key_normal_off.9.png diff --git a/java/res/drawable-land-mdpi/btn_keyboard_key_normal_on.9.png b/java/res/drawable-land-mdpi/btn_keyboard_key_normal_on.9.png Binary files differnew file mode 100644 index 000000000..0c16ed509 --- /dev/null +++ b/java/res/drawable-land-mdpi/btn_keyboard_key_normal_on.9.png diff --git a/java/res/drawable-land-mdpi/btn_keyboard_key_pressed.9.png b/java/res/drawable-land-mdpi/btn_keyboard_key_pressed.9.png Binary files differnew file mode 100755 index 000000000..6b5c718c7 --- /dev/null +++ b/java/res/drawable-land-mdpi/btn_keyboard_key_pressed.9.png diff --git a/java/res/drawable-land-mdpi/btn_keyboard_key_pressed_off.9.png b/java/res/drawable-land-mdpi/btn_keyboard_key_pressed_off.9.png Binary files differnew file mode 100644 index 000000000..bdcf06e1b --- /dev/null +++ b/java/res/drawable-land-mdpi/btn_keyboard_key_pressed_off.9.png diff --git a/java/res/drawable-land-mdpi/btn_keyboard_key_pressed_on.9.png b/java/res/drawable-land-mdpi/btn_keyboard_key_pressed_on.9.png Binary files differnew file mode 100644 index 000000000..79621a9e6 --- /dev/null +++ b/java/res/drawable-land-mdpi/btn_keyboard_key_pressed_on.9.png diff --git a/java/res/drawable-land-mdpi/keyboard_suggest_strip_divider.png b/java/res/drawable-land-mdpi/keyboard_suggest_strip_divider.png Binary files differnew file mode 100644 index 000000000..e54c5b099 --- /dev/null +++ b/java/res/drawable-land-mdpi/keyboard_suggest_strip_divider.png diff --git a/java/res/drawable-land/btn_keyboard_key.xml b/java/res/drawable-land/btn_keyboard_key.xml new file mode 100644 index 000000000..45578e582 --- /dev/null +++ b/java/res/drawable-land/btn_keyboard_key.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2008 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + + <!-- Toggle keys. Use checkable/checked state. --> + + <item android:state_checkable="true" android:state_checked="true" + android:state_pressed="true" + android:drawable="@drawable/btn_keyboard_key_pressed_on" /> + <item android:state_checkable="true" android:state_pressed="true" + android:drawable="@drawable/btn_keyboard_key_pressed_off" /> + <item android:state_checkable="true" android:state_checked="true" + android:drawable="@drawable/btn_keyboard_key_normal_on" /> + <item android:state_checkable="true" + android:drawable="@drawable/btn_keyboard_key_normal_off" /> + + <!-- Normal keys --> + + <item android:state_pressed="true" + android:drawable="@drawable/btn_keyboard_key_pressed" /> + <item + android:drawable="@drawable/btn_keyboard_key_normal" /> + +</selector> diff --git a/java/res/drawable-mdpi/btn_keyboard_key_fulltrans_normal.9.png b/java/res/drawable-mdpi/btn_keyboard_key_fulltrans_normal.9.png Binary files differnew file mode 100644 index 000000000..20f3d5087 --- /dev/null +++ b/java/res/drawable-mdpi/btn_keyboard_key_fulltrans_normal.9.png diff --git a/java/res/drawable-mdpi/btn_keyboard_key_fulltrans_pressed.9.png b/java/res/drawable-mdpi/btn_keyboard_key_fulltrans_pressed.9.png Binary files differnew file mode 100644 index 000000000..1ed3065c5 --- /dev/null +++ b/java/res/drawable-mdpi/btn_keyboard_key_fulltrans_pressed.9.png diff --git a/java/res/drawable-mdpi/btn_keyboard_key_normal.9.png b/java/res/drawable-mdpi/btn_keyboard_key_normal.9.png Binary files differnew file mode 100644 index 000000000..7ba18dd25 --- /dev/null +++ b/java/res/drawable-mdpi/btn_keyboard_key_normal.9.png diff --git a/java/res/drawable-mdpi/btn_keyboard_key_normal_off.9.png b/java/res/drawable-mdpi/btn_keyboard_key_normal_off.9.png Binary files differnew file mode 100644 index 000000000..bda9b8394 --- /dev/null +++ b/java/res/drawable-mdpi/btn_keyboard_key_normal_off.9.png diff --git a/java/res/drawable-mdpi/btn_keyboard_key_normal_on.9.png b/java/res/drawable-mdpi/btn_keyboard_key_normal_on.9.png Binary files differnew file mode 100644 index 000000000..0c16ed509 --- /dev/null +++ b/java/res/drawable-mdpi/btn_keyboard_key_normal_on.9.png diff --git a/java/res/drawable-mdpi/btn_keyboard_key_pressed.9.png b/java/res/drawable-mdpi/btn_keyboard_key_pressed.9.png Binary files differnew file mode 100644 index 000000000..39b9314a1 --- /dev/null +++ b/java/res/drawable-mdpi/btn_keyboard_key_pressed.9.png diff --git a/java/res/drawable-mdpi/btn_keyboard_key_pressed_off.9.png b/java/res/drawable-mdpi/btn_keyboard_key_pressed_off.9.png Binary files differnew file mode 100644 index 000000000..bdcf06e1b --- /dev/null +++ b/java/res/drawable-mdpi/btn_keyboard_key_pressed_off.9.png diff --git a/java/res/drawable-mdpi/btn_keyboard_key_pressed_on.9.png b/java/res/drawable-mdpi/btn_keyboard_key_pressed_on.9.png Binary files differnew file mode 100644 index 000000000..79621a9e6 --- /dev/null +++ b/java/res/drawable-mdpi/btn_keyboard_key_pressed_on.9.png diff --git a/java/res/drawable-mdpi/candidate_feedback_background.9.png b/java/res/drawable-mdpi/candidate_feedback_background.9.png Binary files differnew file mode 100644 index 000000000..2a80f096d --- /dev/null +++ b/java/res/drawable-mdpi/candidate_feedback_background.9.png diff --git a/java/res/drawable-mdpi/dialog_bubble_step02.9.png b/java/res/drawable-mdpi/dialog_bubble_step02.9.png Binary files differnew file mode 100755 index 000000000..d77f85fe2 --- /dev/null +++ b/java/res/drawable-mdpi/dialog_bubble_step02.9.png diff --git a/java/res/drawable-mdpi/dialog_bubble_step07.9.png b/java/res/drawable-mdpi/dialog_bubble_step07.9.png Binary files differnew file mode 100755 index 000000000..80f4a0eaa --- /dev/null +++ b/java/res/drawable-mdpi/dialog_bubble_step07.9.png diff --git a/java/res/drawable-mdpi/highlight_pressed.png b/java/res/drawable-mdpi/highlight_pressed.png Binary files differnew file mode 100644 index 000000000..d27f1061a --- /dev/null +++ b/java/res/drawable-mdpi/highlight_pressed.png diff --git a/java/res/drawable-mdpi/ic_dialog_keyboard.png b/java/res/drawable-mdpi/ic_dialog_keyboard.png Binary files differnew file mode 100644 index 000000000..9a5aada8b --- /dev/null +++ b/java/res/drawable-mdpi/ic_dialog_keyboard.png diff --git a/java/res/drawable-mdpi/ic_mic_dialog.png b/java/res/drawable-mdpi/ic_mic_dialog.png Binary files differnew file mode 100644 index 000000000..77613ca05 --- /dev/null +++ b/java/res/drawable-mdpi/ic_mic_dialog.png diff --git a/java/res/drawable-mdpi/ic_suggest_strip_microphone.png b/java/res/drawable-mdpi/ic_suggest_strip_microphone.png Binary files differnew file mode 100644 index 000000000..18f314a61 --- /dev/null +++ b/java/res/drawable-mdpi/ic_suggest_strip_microphone.png diff --git a/java/res/drawable-mdpi/ic_suggest_strip_microphone_swipe.png b/java/res/drawable-mdpi/ic_suggest_strip_microphone_swipe.png Binary files differnew file mode 100644 index 000000000..ff629b674 --- /dev/null +++ b/java/res/drawable-mdpi/ic_suggest_strip_microphone_swipe.png diff --git a/java/res/drawable-mdpi/ic_suggest_strip_scroll_left_arrow.png b/java/res/drawable-mdpi/ic_suggest_strip_scroll_left_arrow.png Binary files differnew file mode 100644 index 000000000..a9adef2ba --- /dev/null +++ b/java/res/drawable-mdpi/ic_suggest_strip_scroll_left_arrow.png diff --git a/java/res/drawable-mdpi/ic_suggest_strip_scroll_right_arrow.png b/java/res/drawable-mdpi/ic_suggest_strip_scroll_right_arrow.png Binary files differnew file mode 100644 index 000000000..639a28711 --- /dev/null +++ b/java/res/drawable-mdpi/ic_suggest_strip_scroll_right_arrow.png diff --git a/java/res/drawable-mdpi/keyboard_background.9.png b/java/res/drawable-mdpi/keyboard_background.9.png Binary files differnew file mode 100644 index 000000000..2bd4b628d --- /dev/null +++ b/java/res/drawable-mdpi/keyboard_background.9.png diff --git a/java/res/drawable-mdpi/keyboard_suggest_strip.9.png b/java/res/drawable-mdpi/keyboard_suggest_strip.9.png Binary files differnew file mode 100644 index 000000000..71bf5e8f4 --- /dev/null +++ b/java/res/drawable-mdpi/keyboard_suggest_strip.9.png diff --git a/java/res/drawable-mdpi/keyboard_suggest_strip_divider.png b/java/res/drawable-mdpi/keyboard_suggest_strip_divider.png Binary files differnew file mode 100644 index 000000000..c9413d7c1 --- /dev/null +++ b/java/res/drawable-mdpi/keyboard_suggest_strip_divider.png diff --git a/java/res/drawable-mdpi/list_selector_background_pressed.9.png b/java/res/drawable-mdpi/list_selector_background_pressed.9.png Binary files differnew file mode 100644 index 000000000..02b4e9a53 --- /dev/null +++ b/java/res/drawable-mdpi/list_selector_background_pressed.9.png diff --git a/java/res/drawable-mdpi/sym_keyboard_123_mic.png b/java/res/drawable-mdpi/sym_keyboard_123_mic.png Binary files differnew file mode 100644 index 000000000..35afe0821 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_123_mic.png diff --git a/java/res/drawable-mdpi/sym_keyboard_delete.png b/java/res/drawable-mdpi/sym_keyboard_delete.png Binary files differnew file mode 100644 index 000000000..43a033ead --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_delete.png diff --git a/java/res/drawable-mdpi/sym_keyboard_done.png b/java/res/drawable-mdpi/sym_keyboard_done.png Binary files differnew file mode 100755 index 000000000..c0d6d1394 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_done.png diff --git a/java/res/drawable-mdpi/sym_keyboard_feedback_123_mic.png b/java/res/drawable-mdpi/sym_keyboard_feedback_123_mic.png Binary files differnew file mode 100644 index 000000000..bc11cf31a --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_feedback_123_mic.png diff --git a/java/res/drawable-mdpi/sym_keyboard_feedback_delete.png b/java/res/drawable-mdpi/sym_keyboard_feedback_delete.png Binary files differnew file mode 100644 index 000000000..1edb10b4e --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_feedback_delete.png diff --git a/java/res/drawable-mdpi/sym_keyboard_feedback_done.png b/java/res/drawable-mdpi/sym_keyboard_feedback_done.png Binary files differnew file mode 100755 index 000000000..0d7ebd4e5 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_feedback_done.png 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 Binary files differnew file mode 100644 index 000000000..e3f80fada --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_feedback_language_arrows_left.png 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 Binary files differnew file mode 100644 index 000000000..3cb0d9913 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_feedback_language_arrows_right.png diff --git a/java/res/drawable-mdpi/sym_keyboard_feedback_mic.png b/java/res/drawable-mdpi/sym_keyboard_feedback_mic.png Binary files differnew file mode 100644 index 000000000..247d5b3a9 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_feedback_mic.png diff --git a/java/res/drawable-mdpi/sym_keyboard_feedback_numalt.png b/java/res/drawable-mdpi/sym_keyboard_feedback_numalt.png Binary files differnew file mode 100644 index 000000000..aac737615 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_feedback_numalt.png diff --git a/java/res/drawable-mdpi/sym_keyboard_feedback_return.png b/java/res/drawable-mdpi/sym_keyboard_feedback_return.png Binary files differnew file mode 100644 index 000000000..03d9c9b2d --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_feedback_return.png diff --git a/java/res/drawable-mdpi/sym_keyboard_feedback_search.png b/java/res/drawable-mdpi/sym_keyboard_feedback_search.png Binary files differnew file mode 100755 index 000000000..f4af341eb --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_feedback_search.png diff --git a/java/res/drawable-mdpi/sym_keyboard_feedback_shift.png b/java/res/drawable-mdpi/sym_keyboard_feedback_shift.png Binary files differnew file mode 100644 index 000000000..97f4661f8 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_feedback_shift.png diff --git a/java/res/drawable-mdpi/sym_keyboard_feedback_shift_locked.png b/java/res/drawable-mdpi/sym_keyboard_feedback_shift_locked.png Binary files differnew file mode 100755 index 000000000..7194b30b0 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_feedback_shift_locked.png diff --git a/java/res/drawable-mdpi/sym_keyboard_feedback_space.png b/java/res/drawable-mdpi/sym_keyboard_feedback_space.png Binary files differnew file mode 100644 index 000000000..739db6879 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_feedback_space.png diff --git a/java/res/drawable-mdpi/sym_keyboard_feedback_tab.png b/java/res/drawable-mdpi/sym_keyboard_feedback_tab.png Binary files differnew file mode 100644 index 000000000..593fa6703 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_feedback_tab.png diff --git a/java/res/drawable-mdpi/sym_keyboard_feedback_tabprev.png b/java/res/drawable-mdpi/sym_keyboard_feedback_tabprev.png Binary files differnew file mode 100644 index 000000000..d4b3e7db3 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_feedback_tabprev.png diff --git a/java/res/drawable-mdpi/sym_keyboard_globe.png b/java/res/drawable-mdpi/sym_keyboard_globe.png Binary files differnew file mode 100644 index 000000000..f30c1b640 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_globe.png diff --git a/java/res/drawable-mdpi/sym_keyboard_language_arrows_left.png b/java/res/drawable-mdpi/sym_keyboard_language_arrows_left.png Binary files differnew file mode 100644 index 000000000..91eda5f2d --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_language_arrows_left.png diff --git a/java/res/drawable-mdpi/sym_keyboard_language_arrows_right.png b/java/res/drawable-mdpi/sym_keyboard_language_arrows_right.png Binary files differnew file mode 100644 index 000000000..62a5beba4 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_language_arrows_right.png diff --git a/java/res/drawable-mdpi/sym_keyboard_mic.png b/java/res/drawable-mdpi/sym_keyboard_mic.png Binary files differnew file mode 100644 index 000000000..a75809549 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_mic.png diff --git a/java/res/drawable-mdpi/sym_keyboard_num0.png b/java/res/drawable-mdpi/sym_keyboard_num0.png Binary files differnew file mode 100644 index 000000000..e7007c871 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_num0.png diff --git a/java/res/drawable-mdpi/sym_keyboard_num1.png b/java/res/drawable-mdpi/sym_keyboard_num1.png Binary files differnew file mode 100644 index 000000000..aaac11b0c --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_num1.png diff --git a/java/res/drawable-mdpi/sym_keyboard_num2.png b/java/res/drawable-mdpi/sym_keyboard_num2.png Binary files differnew file mode 100644 index 000000000..4372eb8f0 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_num2.png diff --git a/java/res/drawable-mdpi/sym_keyboard_num3.png b/java/res/drawable-mdpi/sym_keyboard_num3.png Binary files differnew file mode 100644 index 000000000..6f54c850f --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_num3.png diff --git a/java/res/drawable-mdpi/sym_keyboard_num4.png b/java/res/drawable-mdpi/sym_keyboard_num4.png Binary files differnew file mode 100644 index 000000000..3e50bb957 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_num4.png diff --git a/java/res/drawable-mdpi/sym_keyboard_num5.png b/java/res/drawable-mdpi/sym_keyboard_num5.png Binary files differnew file mode 100644 index 000000000..c39ef4404 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_num5.png diff --git a/java/res/drawable-mdpi/sym_keyboard_num6.png b/java/res/drawable-mdpi/sym_keyboard_num6.png Binary files differnew file mode 100644 index 000000000..ea88ceb94 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_num6.png diff --git a/java/res/drawable-mdpi/sym_keyboard_num7.png b/java/res/drawable-mdpi/sym_keyboard_num7.png Binary files differnew file mode 100644 index 000000000..ce800ba42 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_num7.png diff --git a/java/res/drawable-mdpi/sym_keyboard_num8.png b/java/res/drawable-mdpi/sym_keyboard_num8.png Binary files differnew file mode 100644 index 000000000..1a8ff94bf --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_num8.png diff --git a/java/res/drawable-mdpi/sym_keyboard_num9.png b/java/res/drawable-mdpi/sym_keyboard_num9.png Binary files differnew file mode 100644 index 000000000..8b344c0a6 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_num9.png diff --git a/java/res/drawable-mdpi/sym_keyboard_numalt.png b/java/res/drawable-mdpi/sym_keyboard_numalt.png Binary files differnew file mode 100644 index 000000000..32a2cf3ca --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_numalt.png diff --git a/java/res/drawable-mdpi/sym_keyboard_numpound.png b/java/res/drawable-mdpi/sym_keyboard_numpound.png Binary files differnew file mode 100644 index 000000000..b2419d9ab --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_numpound.png diff --git a/java/res/drawable-mdpi/sym_keyboard_numstar.png b/java/res/drawable-mdpi/sym_keyboard_numstar.png Binary files differnew file mode 100644 index 000000000..cb66f968f --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_numstar.png diff --git a/java/res/drawable-mdpi/sym_keyboard_return.png b/java/res/drawable-mdpi/sym_keyboard_return.png Binary files differnew file mode 100644 index 000000000..17f257439 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_return.png diff --git a/java/res/drawable-mdpi/sym_keyboard_search.png b/java/res/drawable-mdpi/sym_keyboard_search.png Binary files differnew file mode 100755 index 000000000..127755d6b --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_search.png diff --git a/java/res/drawable-mdpi/sym_keyboard_shift.png b/java/res/drawable-mdpi/sym_keyboard_shift.png Binary files differnew file mode 100644 index 000000000..0566e5a88 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_shift.png diff --git a/java/res/drawable-mdpi/sym_keyboard_shift_locked.png b/java/res/drawable-mdpi/sym_keyboard_shift_locked.png Binary files differnew file mode 100755 index 000000000..ccaf05d3b --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_shift_locked.png diff --git a/java/res/drawable-mdpi/sym_keyboard_space.png b/java/res/drawable-mdpi/sym_keyboard_space.png Binary files differnew file mode 100644 index 000000000..4e6273b89 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_space.png diff --git a/java/res/drawable-mdpi/sym_keyboard_tab.png b/java/res/drawable-mdpi/sym_keyboard_tab.png Binary files differnew file mode 100644 index 000000000..cd9daff08 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_tab.png diff --git a/java/res/drawable-mdpi/sym_keyboard_tabprev.png b/java/res/drawable-mdpi/sym_keyboard_tabprev.png Binary files differnew file mode 100644 index 000000000..eb90872fc --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_tabprev.png diff --git a/java/res/drawable/btn_keyboard_key.xml b/java/res/drawable/btn_keyboard_key.xml new file mode 100644 index 000000000..45578e582 --- /dev/null +++ b/java/res/drawable/btn_keyboard_key.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2008 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + + <!-- Toggle keys. Use checkable/checked state. --> + + <item android:state_checkable="true" android:state_checked="true" + android:state_pressed="true" + android:drawable="@drawable/btn_keyboard_key_pressed_on" /> + <item android:state_checkable="true" android:state_pressed="true" + android:drawable="@drawable/btn_keyboard_key_pressed_off" /> + <item android:state_checkable="true" android:state_checked="true" + android:drawable="@drawable/btn_keyboard_key_normal_on" /> + <item android:state_checkable="true" + android:drawable="@drawable/btn_keyboard_key_normal_off" /> + + <!-- Normal keys --> + + <item android:state_pressed="true" + android:drawable="@drawable/btn_keyboard_key_pressed" /> + <item + android:drawable="@drawable/btn_keyboard_key_normal" /> + +</selector> diff --git a/java/res/drawable/btn_keyboard_key_fulltrans.xml b/java/res/drawable/btn_keyboard_key_fulltrans.xml new file mode 100644 index 000000000..bad2a931d --- /dev/null +++ b/java/res/drawable/btn_keyboard_key_fulltrans.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. +--> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + + <!-- Normal keys --> + + <item android:state_pressed="true" + android:drawable="@drawable/btn_keyboard_key_fulltrans_pressed" /> + <item + android:drawable="@drawable/btn_keyboard_key_fulltrans_normal" /> + +</selector> diff --git a/java/res/drawable/cancel.png b/java/res/drawable/cancel.png Binary files differnew file mode 100644 index 000000000..081532bec --- /dev/null +++ b/java/res/drawable/cancel.png diff --git a/java/res/drawable/caution.png b/java/res/drawable/caution.png Binary files differnew file mode 100644 index 000000000..eaef53425 --- /dev/null +++ b/java/res/drawable/caution.png diff --git a/java/res/drawable/dialog_top_dark_bottom_medium.9.png b/java/res/drawable/dialog_top_dark_bottom_medium.9.png Binary files differnew file mode 100644 index 000000000..cf7ecaf1e --- /dev/null +++ b/java/res/drawable/dialog_top_dark_bottom_medium.9.png diff --git a/java/res/drawable/ic_dialog_alert_large.png b/java/res/drawable/ic_dialog_alert_large.png Binary files differnew file mode 100644 index 000000000..2d4a164a7 --- /dev/null +++ b/java/res/drawable/ic_dialog_alert_large.png diff --git a/java/res/drawable/ic_dialog_voice_input.png b/java/res/drawable/ic_dialog_voice_input.png Binary files differnew file mode 100644 index 000000000..d28914132 --- /dev/null +++ b/java/res/drawable/ic_dialog_voice_input.png diff --git a/java/res/drawable/ic_dialog_wave_0_0.png b/java/res/drawable/ic_dialog_wave_0_0.png Binary files differnew file mode 100644 index 000000000..9c3c28f37 --- /dev/null +++ b/java/res/drawable/ic_dialog_wave_0_0.png diff --git a/java/res/drawable/ic_dialog_wave_1_3.png b/java/res/drawable/ic_dialog_wave_1_3.png Binary files differnew file mode 100644 index 000000000..d33bd0d9b --- /dev/null +++ b/java/res/drawable/ic_dialog_wave_1_3.png diff --git a/java/res/drawable/ic_dialog_wave_2_3.png b/java/res/drawable/ic_dialog_wave_2_3.png Binary files differnew file mode 100644 index 000000000..5094a6e6c --- /dev/null +++ b/java/res/drawable/ic_dialog_wave_2_3.png diff --git a/java/res/drawable/ic_dialog_wave_3_3.png b/java/res/drawable/ic_dialog_wave_3_3.png Binary files differnew file mode 100644 index 000000000..69917564d --- /dev/null +++ b/java/res/drawable/ic_dialog_wave_3_3.png diff --git a/java/res/drawable/ic_dialog_wave_4_3.png b/java/res/drawable/ic_dialog_wave_4_3.png Binary files differnew file mode 100644 index 000000000..af5a84c31 --- /dev/null +++ b/java/res/drawable/ic_dialog_wave_4_3.png 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 000000000..9d246e40e --- /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/drawable/mic_slash.png b/java/res/drawable/mic_slash.png Binary files differnew file mode 100644 index 000000000..0b0fb5803 --- /dev/null +++ b/java/res/drawable/mic_slash.png diff --git a/java/res/drawable/ok_cancel.png b/java/res/drawable/ok_cancel.png Binary files differnew file mode 100644 index 000000000..0601d3231 --- /dev/null +++ b/java/res/drawable/ok_cancel.png diff --git a/java/res/drawable/speak_now_level0.png b/java/res/drawable/speak_now_level0.png Binary files differnew file mode 100644 index 000000000..abc845466 --- /dev/null +++ b/java/res/drawable/speak_now_level0.png diff --git a/java/res/drawable/speak_now_level1.png b/java/res/drawable/speak_now_level1.png Binary files differnew file mode 100644 index 000000000..67cb235bf --- /dev/null +++ b/java/res/drawable/speak_now_level1.png diff --git a/java/res/drawable/speak_now_level2.png b/java/res/drawable/speak_now_level2.png Binary files differnew file mode 100644 index 000000000..1e07f26c6 --- /dev/null +++ b/java/res/drawable/speak_now_level2.png diff --git a/java/res/drawable/speak_now_level3.png b/java/res/drawable/speak_now_level3.png Binary files differnew file mode 100644 index 000000000..31991daee --- /dev/null +++ b/java/res/drawable/speak_now_level3.png diff --git a/java/res/drawable/speak_now_level4.png b/java/res/drawable/speak_now_level4.png Binary files differnew file mode 100644 index 000000000..7363ca892 --- /dev/null +++ b/java/res/drawable/speak_now_level4.png diff --git a/java/res/drawable/speak_now_level5.png b/java/res/drawable/speak_now_level5.png Binary files differnew file mode 100644 index 000000000..9034908f4 --- /dev/null +++ b/java/res/drawable/speak_now_level5.png diff --git a/java/res/drawable/speak_now_level6.png b/java/res/drawable/speak_now_level6.png Binary files differnew file mode 100644 index 000000000..3eaa9bdad --- /dev/null +++ b/java/res/drawable/speak_now_level6.png diff --git a/java/res/drawable/voice_ime_background.9.png b/java/res/drawable/voice_ime_background.9.png Binary files differnew file mode 100644 index 000000000..67802492a --- /dev/null +++ b/java/res/drawable/voice_ime_background.9.png diff --git a/java/res/drawable/voice_swipe_hint.png b/java/res/drawable/voice_swipe_hint.png Binary files differnew file mode 100644 index 000000000..bb8873251 --- /dev/null +++ b/java/res/drawable/voice_swipe_hint.png diff --git a/java/res/drawable/working.png b/java/res/drawable/working.png Binary files differnew file mode 100644 index 000000000..6246a6d1c --- /dev/null +++ b/java/res/drawable/working.png diff --git a/java/res/layout/bubble_text.xml b/java/res/layout/bubble_text.xml new file mode 100644 index 000000000..c3957b65e --- /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 100755 index 000000000..fe2002d46 --- /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 100755 index 000000000..068c17e56 --- /dev/null +++ b/java/res/layout/candidates.xml @@ -0,0 +1,79 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** +** Copyright 2008, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> + +<com.android.inputmethod.latin.CandidateViewContainer + 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" + > + + <LinearLayout + android:id="@+id/candidate_left_parent" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:orientation="horizontal"> + <ImageButton + android:id="@+id/candidate_left" + android:background="@drawable/ic_suggest_scroll_background" + android:src="@drawable/ic_suggest_strip_scroll_left_arrow" + android:layout_width="36dp" + android:layout_height="match_parent" + android:clickable="true" + /> + + <ImageView + android:src="@drawable/keyboard_suggest_strip_divider" + android:layout_width="wrap_content" + android:layout_height="match_parent" + /> + </LinearLayout> + + <com.android.inputmethod.latin.CandidateView + android:id="@+id/candidates" + android:layout_width="wrap_content" + android:layout_height="@dimen/candidate_strip_height" + android:layout_weight="1" + /> + + <LinearLayout + android:id="@+id/candidate_right_parent" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:clickable="true" + android:orientation="horizontal"> + <ImageView + android:src="@drawable/keyboard_suggest_strip_divider" + android:layout_width="wrap_content" + android:layout_height="match_parent" + /> + + <ImageButton + android:id="@+id/candidate_right" + android:background="@drawable/ic_suggest_scroll_background" + android:src="@drawable/ic_suggest_strip_scroll_right_arrow" + android:layout_width="36dp" + android:layout_height="match_parent" + android:clickable="true" + /> + </LinearLayout> + +</com.android.inputmethod.latin.CandidateViewContainer> diff --git a/java/res/layout/input.xml b/java/res/layout/input.xml new file mode 100755 index 000000000..1d7c6f746 --- /dev/null +++ b/java/res/layout/input.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. +*/ +--> + +<com.android.inputmethod.latin.LatinKeyboardView + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@android:id/keyboardView" + android:layout_alignParentBottom="true" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="@drawable/keyboard_background" + android:keyBackground="@drawable/btn_keyboard_key" + /> diff --git a/java/res/layout/input_trans.xml b/java/res/layout/input_trans.xml new file mode 100755 index 000000000..a988bcc68 --- /dev/null +++ b/java/res/layout/input_trans.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. +*/ +--> + +<com.android.inputmethod.latin.LatinKeyboardView + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@android:id/keyboardView" + android:layout_alignParentBottom="true" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="#A0000000" + android:keyBackground="@drawable/btn_keyboard_key_fulltrans" + /> diff --git a/java/res/layout/recognition_status.xml b/java/res/layout/recognition_status.xml new file mode 100644 index 000000000..1ec06ba9a --- /dev/null +++ b/java/res/layout/recognition_status.xml @@ -0,0 +1,99 @@ +<?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_marginTop="20dip" + android:layout_gravity="center_horizontal" + 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/voice_punctuation_hint.xml b/java/res/layout/voice_punctuation_hint.xml new file mode 100644 index 000000000..629a7f2b5 --- /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 000000000..4e8859a71 --- /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 Binary files differnew file mode 100755 index 000000000..a456cf3d3 --- /dev/null +++ b/java/res/raw/main.dict diff --git a/java/res/raw/type3.ogg b/java/res/raw/type3.ogg Binary files differnew file mode 100755 index 000000000..20e670807 --- /dev/null +++ b/java/res/raw/type3.ogg diff --git a/java/res/values-cs/bools.xml b/java/res/values-cs/bools.xml new file mode 100644 index 000000000..897f4b3db --- /dev/null +++ b/java/res/values-cs/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="im_is_default">true</bool> +</resources> diff --git a/java/res/values-cs/donottranslate.xml b/java/res/values-cs/donottranslate.xml new file mode 100644 index 000000000..9c2a476a6 --- /dev/null +++ b/java/res/values-cs/donottranslate.xml @@ -0,0 +1,29 @@ +<?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"> + <!-- Accented characters related to "d" --> + <string name="alternates_for_d">ď</string> + <!-- Accented characters related to "r" --> + <string name="alternates_for_r">ř</string> + <!-- Accented characters related to "t" --> + <string name="alternates_for_t">ť</string> + <!-- Accented characters related to "z" --> + <string name="alternates_for_z">ž</string> +</resources> diff --git a/java/res/values-cs/strings.xml b/java/res/values-cs/strings.xml new file mode 100644 index 000000000..02361e1c1 --- /dev/null +++ b/java/res/values-cs/strings.xml @@ -0,0 +1,127 @@ +<?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/android" + 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="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="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> + <!-- no translation found for auto_punctuate_summary (6589441565817502132) --> + <skip /> + <string name="quick_fixes" msgid="5353213327680897927">"Rychlé opravy"</string> + <string name="quick_fixes_summary" msgid="3405028402510332373">"Opravuje běžné překlepy"</string> + <string name="show_suggestions" msgid="507074425254289133">"Zobrazovat návrhy"</string> + <string name="show_suggestions_summary" msgid="1989672863935759654">"Při psaní zobrazovat návrhy slov"</string> + <string name="auto_complete" msgid="1103196318775486023">"Automatické dokončování"</string> + <string name="auto_complete_summary" msgid="6113149638718274624">"Stisknutí mezerníku nebo interpunkce automaticky vloží zvýrazněné slovo"</string> + <string-array name="prediction_modes"> + <item msgid="4870266572388153286">"Není"</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="alternates_for_a" msgid="2566516493365324765">"áàâãäåæ"</string> + <string name="alternates_for_e" msgid="3900510936875547555">"éěèêë"</string> + <string name="alternates_for_i" msgid="7097915268629342242">"íìîï"</string> + <string name="alternates_for_o" msgid="6151402748321267776">"óòôõöœø"</string> + <string name="alternates_for_u" msgid="5899096818189442934">"ůúùûü"</string> + <string name="alternates_for_s" msgid="348762530927662188">"š§ß"</string> + <string name="alternates_for_n" msgid="6257322556221886400">"ňñ"</string> + <string name="alternates_for_c" msgid="151699780720639892">"čç"</string> + <string name="alternates_for_y" msgid="1722776806607271199">"ýÿ"</string> + <string name="tip_long_press" msgid="6101270866284343344">"Podržením klávesy zobrazíte diakritiku (ž, á atd.)"</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 této rady »"</string> + <string name="touch_to_finish" msgid="7990196086480585789">"Chcete-li tuto radu zavřít a začít psát, dotkněte se zde."</string> + <string name="tip_to_open_keyboard" msgid="6821200275486950452"><b>"Klávesnice se zobrazí, kdykoli se dotknete textového pole."</b></string> + <string name="tip_to_view_accents" msgid="5433158573693308501"><b>"Stisknutím a podržením klávesy zobrazíte diakritiku"\n"(ó, ø, ö, ô atd.)"</b></string> + <string name="tip_to_open_symbols" msgid="7345139325622444880"><b>"Stisknutím této klávesy přejdete do režimu číslic a symbolů"</b></string> + <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"Opětovným stisknutím této klávesy se vrátíte zpět do režimu písmen"</b></string> + <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"Chcete-li změnit nastavení klávesnice, jako například automatické dokončování, stiskněte tuto klávesu a podržte ji."</b></string> + <string name="tip_to_start_typing" msgid="7213843601369174313"><b>"Zkuste 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> + <!-- no translation found for voice_initializing (661962047129906646) --> + <skip /> + <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 jakéhokoli 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 klávesu 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>"Použijte interpunkční znaménka a diakritiku."</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="inputMethod" msgid="7854532062009028116">"Metoda 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="8058519710062071085">"← Uložte slovo opětovným klepnutím"</string> +</resources> diff --git a/java/res/values-da/strings.xml b/java/res/values-da/strings.xml new file mode 100644 index 000000000..15f6b1c6b --- /dev/null +++ b/java/res/values-da/strings.xml @@ -0,0 +1,127 @@ +<?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/android" + 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="vibrate_on_keypress" msgid="5258079494276955460">"Vibration ved tastetryk"</string> + <string name="sound_on_keypress" msgid="6093592297198243644">"Lyd ved tastetryk"</string> + <string name="hit_correction" msgid="4855351009261318389">"Ret stavefejl"</string> + <string name="hit_correction_summary" msgid="8761701873008070796">"Aktiver fejlretning af input"</string> + <string name="hit_correction_land" msgid="2567691684825205448">"Inputfejl i landskab"</string> + <string name="hit_correction_land_summary" msgid="4076803842198368328">"Aktiver fejlretning af input"</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">"Aktiver 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> + <!-- no translation found for auto_punctuate_summary (6589441565817502132) --> + <skip /> + <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-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="alternates_for_a" msgid="2566516493365324765">"àáâãäåæ"</string> + <string name="alternates_for_e" msgid="3900510936875547555">"èéêë"</string> + <string name="alternates_for_i" msgid="7097915268629342242">"ìíîï"</string> + <string name="alternates_for_o" msgid="6151402748321267776">"òóôõöœø"</string> + <string name="alternates_for_u" msgid="5899096818189442934">"ùúûü"</string> + <string name="alternates_for_s" msgid="348762530927662188">"§ß"</string> + <string name="alternates_for_n" msgid="6257322556221886400">"ñ"</string> + <string name="alternates_for_c" msgid="151699780720639892">"ç"</string> + <string name="alternates_for_y" msgid="1722776806607271199">"ýÿ"</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å tilbagetasten ↶ 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">"Berør dette tip for at fortsætte »"</string> + <string name="touch_to_finish" msgid="7990196086480585789">"Berør her for at lukke dette tip og begynde at indtaste!"</string> + <string name="tip_to_open_keyboard" msgid="6821200275486950452"><b>"Tastaturet åbnes, når du berører et tekstfelt"</b></string> + <string name="tip_to_view_accents" msgid="5433158573693308501"><b>"Berør og hold en tast nede for at 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 bogstaverne ved at berøre denne tast igen"</b></string> + <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"Berør og hold denne tast nede for at ændre indstillingerne for tastaturet, 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> + <!-- no translation found for voice_initializing (661962047129906646) --> + <skip /> + <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 matches"</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å Tilbagetasten."</string> + <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Tryk på og hold en tast 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>"Indstillinger for tastatur"\n</b></font><font size="3">\n</font>"Tryk på og hold tasten "<b>"?123"</b>" 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="inputMethod" msgid="7854532062009028116">"Inputmetode"</string> + <string name="language_selection_title" msgid="1651299598555326750">"Inputsprog"</string> + <string name="language_selection_summary" msgid="187110938289512256">"Træk fingeren på mellemrumstasten for at skifte sprog"</string> + <string name="hint_add_to_dictionary" msgid="8058519710062071085">"← Tast igen for at gemme"</string> +</resources> diff --git a/java/res/values-de/bools.xml b/java/res/values-de/bools.xml new file mode 100644 index 000000000..897f4b3db --- /dev/null +++ b/java/res/values-de/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="im_is_default">true</bool> +</resources> diff --git a/java/res/values-de/strings.xml b/java/res/values-de/strings.xml new file mode 100644 index 000000000..e203fb394 --- /dev/null +++ b/java/res/values-de/strings.xml @@ -0,0 +1,127 @@ +<?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/android" + 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="vibrate_on_keypress" msgid="5258079494276955460">"Vibrieren bei Tastendruck"</string> + <string name="sound_on_keypress" msgid="6093592297198243644">"Sound 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ß-/Kleinschreibung"</string> + <string name="auto_cap_summary" msgid="3260681697600786825">"Sätze mit Großbuchstaben beginnen"</string> + <string name="auto_punctuate" msgid="7276672334264521751">"Autom. Zeichensetzung"</string> + <!-- no translation found for auto_punctuate_summary (6589441565817502132) --> + <skip /> + <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-array name="prediction_modes"> + <item msgid="4870266572388153286">"Keine"</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="alternates_for_a" msgid="2566516493365324765">"ä"</string> + <string name="alternates_for_e" msgid="3900510936875547555">"èéêë"</string> + <string name="alternates_for_i" msgid="7097915268629342242">"ìíîï"</string> + <string name="alternates_for_o" msgid="6151402748321267776">"ö"</string> + <string name="alternates_for_u" msgid="5899096818189442934">"ùúûü"</string> + <string name="alternates_for_s" msgid="348762530927662188">"§ß"</string> + <string name="alternates_for_n" msgid="6257322556221886400">"ñ"</string> + <string name="alternates_for_c" msgid="151699780720639892">"ç"</string> + <string name="alternates_for_y" msgid="1722776806607271199">"ýÿ"</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 Sonderzeichen anzuzeigen"\n"(ø, ö, ô, ó usw.)."</b></string> + <string name="tip_to_open_symbols" msgid="7345139325622444880"><b>"Wechseln Sie zu Nummern und Symbolen, indem Sie diese Taste berühren."</b></string> + <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"Gehen Sie zurück zu Buchstaben, indem Sie diese Taste erneut drücken."</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!"</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 den Mikrofonknopf 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> + <!-- no translation found for voice_initializing (661962047129906646) --> + <skip /> + <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 Übereinstimmungen gefunden"</string> + <string name="voice_not_installed" msgid="5552450909753842415">"Sprach-Suche 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 Taste \"Zurück\"."</string> + <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Eine Taste für Optionen 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="inputMethod" msgid="7854532062009028116">"Eingabemethode"</string> + <string name="language_selection_title" msgid="1651299598555326750">"Eingabesprachen"</string> + <string name="language_selection_summary" msgid="187110938289512256">"Finger über die Leertaste bewegen, um die Sprache zu ändern"</string> + <string name="hint_add_to_dictionary" msgid="8058519710062071085">"← Zum Speichern erneut tippen"</string> +</resources> diff --git a/java/res/values-el/strings.xml b/java/res/values-el/strings.xml new file mode 100644 index 000000000..85c18dff4 --- /dev/null +++ b/java/res/values-el/strings.xml @@ -0,0 +1,127 @@ +<?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/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="english_ime_name" msgid="7252517407088836577">"Πληκτρολόγιο Android"</string> + <string name="english_ime_settings" msgid="6661589557206947774">"Ρυθμίσεις πληκτρολογίου Android"</string> + <string name="vibrate_on_keypress" msgid="5258079494276955460">"Δόνηση κατά το πάτημα πλήκτρων"</string> + <string name="sound_on_keypress" msgid="6093592297198243644">"Ήχος κατά το πάτημα πλήκτρων"</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> + <!-- no translation found for auto_punctuate_summary (6589441565817502132) --> + <skip /> + <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-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="alternates_for_a" msgid="2566516493365324765">"àáâãäåæ"</string> + <string name="alternates_for_e" msgid="3900510936875547555">"èéêë"</string> + <string name="alternates_for_i" msgid="7097915268629342242">"ìíîï"</string> + <string name="alternates_for_o" msgid="6151402748321267776">"òóôõöœø"</string> + <string name="alternates_for_u" msgid="5899096818189442934">"ùúûü"</string> + <string name="alternates_for_s" msgid="348762530927662188">"§ß"</string> + <string name="alternates_for_n" msgid="6257322556221886400">"ñ"</string> + <string name="alternates_for_c" msgid="151699780720639892">"ç"</string> + <string name="alternates_for_y" msgid="1722776806607271199">"ýÿ"</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> + <!-- no translation found for voice_initializing (661962047129906646) --> + <skip /> + <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="inputMethod" msgid="7854532062009028116">"Μέθοδος εισόδου"</string> + <string name="language_selection_title" msgid="1651299598555326750">"Γλώσσες εισόδου"</string> + <string name="language_selection_summary" msgid="187110938289512256">"Σύρετε το δάχτυλο στο πλήκτρο διαστήματος για να αλλάξετε γλώσσα"</string> + <string name="hint_add_to_dictionary" msgid="8058519710062071085">"← Πατήστε ξανά για αποθήκευση"</string> +</resources> diff --git a/java/res/values-en/bools.xml b/java/res/values-en/bools.xml new file mode 100644 index 000000000..897f4b3db --- /dev/null +++ b/java/res/values-en/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="im_is_default">true</bool> +</resources> diff --git a/java/res/values-es-rUS/strings.xml b/java/res/values-es-rUS/strings.xml new file mode 100644 index 000000000..541e153b3 --- /dev/null +++ b/java/res/values-es-rUS/strings.xml @@ -0,0 +1,127 @@ +<?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/android" + 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="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="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> + <!-- no translation found for auto_punctuate_summary (6589441565817502132) --> + <skip /> + <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-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="alternates_for_a" msgid="2566516493365324765">"àáâãäåæ"</string> + <string name="alternates_for_e" msgid="3900510936875547555">"èéêë"</string> + <string name="alternates_for_i" msgid="7097915268629342242">"ìíîï"</string> + <string name="alternates_for_o" msgid="6151402748321267776">"òóôõöœø"</string> + <string name="alternates_for_u" msgid="5899096818189442934">"ùúûü"</string> + <string name="alternates_for_s" msgid="348762530927662188">"§ß"</string> + <string name="alternates_for_n" msgid="6257322556221886400">"ñ"</string> + <string name="alternates_for_c" msgid="151699780720639892">"ç"</string> + <string name="alternates_for_y" msgid="1722776806607271199">"ýÿ"</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 &amp 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> + <!-- no translation found for voice_initializing (661962047129906646) --> + <skip /> + <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 & 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 & 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="inputMethod" msgid="7854532062009028116">"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="8058519710062071085">"← Presionar nuevamente para guardar"</string> +</resources> diff --git a/java/res/values-es/bools.xml b/java/res/values-es/bools.xml new file mode 100644 index 000000000..897f4b3db --- /dev/null +++ b/java/res/values-es/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="im_is_default">true</bool> +</resources> diff --git a/java/res/values-es/strings.xml b/java/res/values-es/strings.xml new file mode 100644 index 000000000..fbc597ed2 --- /dev/null +++ b/java/res/values-es/strings.xml @@ -0,0 +1,127 @@ +<?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/android" + 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 del teclado de Android"</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="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">"Configuración 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">"Uso de mayúsculas auto."</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> + <!-- no translation found for auto_punctuate_summary (6589441565817502132) --> + <skip /> + <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-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="alternates_for_a" msgid="2566516493365324765">"á"</string> + <string name="alternates_for_e" msgid="3900510936875547555">"é"</string> + <string name="alternates_for_i" msgid="7097915268629342242">"ìíîï"</string> + <string name="alternates_for_o" msgid="6151402748321267776">"ó"</string> + <string name="alternates_for_u" msgid="5899096818189442934">"ùúûü"</string> + <string name="alternates_for_s" msgid="348762530927662188">"§ß"</string> + <string name="alternates_for_n" msgid="6257322556221886400">"ñ"</string> + <string name="alternates_for_c" msgid="151699780720639892">"ç"</string> + <string name="alternates_for_y" msgid="1722776806607271199">"ýÿ"</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>"Toca esta tecla para cambiar al teclado de números y símbolos"</b>"."</string> + <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"Toca esta tecla de nuevo para volver a las letras"</b></string> + <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"Mantén pulsada esta tecla para cambiar la configuración del teclado como, por ejemplo, la opción de 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">"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">"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">"Hablar ahora"</string> + <string name="voice_working" msgid="6666937792815731889">"En curso"</string> + <!-- no translation found for voice_initializing (661962047129906646) --> + <skip /> + <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>"Pulsa 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>"Configuración 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="inputMethod" msgid="7854532062009028116">"Método de introducción de texto"</string> + <string name="language_selection_title" msgid="1651299598555326750">"Idiomas de entrada"</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="8058519710062071085">"← Volver a tocar para guardar"</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 000000000..b56463ed9 --- /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/android" + 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/bools.xml b/java/res/values-fr/bools.xml new file mode 100644 index 000000000..897f4b3db --- /dev/null +++ b/java/res/values-fr/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="im_is_default">true</bool> +</resources> diff --git a/java/res/values-fr/donottranslate.xml b/java/res/values-fr/donottranslate.xml new file mode 100644 index 000000000..b79df7b37 --- /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()[]*&@{}/<>_+=|\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 000000000..085941415 --- /dev/null +++ b/java/res/values-fr/strings.xml @@ -0,0 +1,127 @@ +<?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/android" + 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="vibrate_on_keypress" msgid="5258079494276955460">"Vibrer à chaque touche"</string> + <string name="sound_on_keypress" msgid="6093592297198243644">"Son à chaque touche"</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> + <!-- no translation found for auto_punctuate_summary (6589441565817502132) --> + <skip /> + <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-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="alternates_for_a" msgid="2566516493365324765">"àáâãäåæ"</string> + <string name="alternates_for_e" msgid="3900510936875547555">"èéêë"</string> + <string name="alternates_for_i" msgid="7097915268629342242">"ìíîï"</string> + <string name="alternates_for_o" msgid="6151402748321267776">"òóôõöœø"</string> + <string name="alternates_for_u" msgid="5899096818189442934">"ùúûü"</string> + <string name="alternates_for_s" msgid="348762530927662188">"§ß"</string> + <string name="alternates_for_n" msgid="6257322556221886400">"ñ"</string> + <string name="alternates_for_c" msgid="151699780720639892">"ç"</string> + <string name="alternates_for_y" msgid="1722776806607271199">"ýÿ"</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>"Retourner au clavier en appuyant de nouveau sur cette touche"</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> + <!-- no translation found for voice_initializing (661962047129906646) --> + <skip /> + <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>"Appuyer 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="inputMethod" msgid="7854532062009028116">"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="8058519710062071085">"← Appuyer de nouveau pour enregistrer"</string> +</resources> diff --git a/java/res/values-it/bools.xml b/java/res/values-it/bools.xml new file mode 100644 index 000000000..897f4b3db --- /dev/null +++ b/java/res/values-it/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="im_is_default">true</bool> +</resources> diff --git a/java/res/values-it/donottranslate.xml b/java/res/values-it/donottranslate.xml new file mode 100644 index 000000000..3e3f3ef2a --- /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()[]*&@{}/<>_+=|\u0022</string> +</resources> diff --git a/java/res/values-it/strings.xml b/java/res/values-it/strings.xml new file mode 100644 index 000000000..1135dd00a --- /dev/null +++ b/java/res/values-it/strings.xml @@ -0,0 +1,127 @@ +<?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/android" + 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="vibrate_on_keypress" msgid="5258079494276955460">"Vibra se premi un tasto"</string> + <string name="sound_on_keypress" msgid="6093592297198243644">"Suona se premi 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> + <!-- no translation found for auto_punctuate_summary (6589441565817502132) --> + <skip /> + <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-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="alternates_for_a" msgid="2566516493365324765">"àá"</string> + <string name="alternates_for_e" msgid="3900510936875547555">"èé"</string> + <string name="alternates_for_i" msgid="7097915268629342242">"ìíîï"</string> + <string name="alternates_for_o" msgid="6151402748321267776">"òó"</string> + <string name="alternates_for_u" msgid="5899096818189442934">"ùúûü"</string> + <string name="alternates_for_s" msgid="348762530927662188">"§"</string> + <string name="alternates_for_n" msgid="6257322556221886400">"ñ"</string> + <string name="alternates_for_c" msgid="151699780720639892">"ç"</string> + <string name="alternates_for_y" msgid="1722776806607271199">"ýÿ"</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 tasto 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 tasto"</b></string> + <string name="tip_to_close_symbols" msgid="5227724217206927185"><b>"Torna all\'alfabeto toccando di nuovo questo tasto"</b></string> + <string name="tip_to_launch_settings" msgid="8402961128983196128"><b>"Tocca e tieni premuto questo tasto 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> + <!-- no translation found for voice_initializing (661962047129906646) --> + <skip /> + <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 tasto 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 tasto "<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="inputMethod" msgid="7854532062009028116">"Metodo 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="8058519710062071085">"← Tocca di nuovo per salvare"</string> +</resources> diff --git a/java/res/values-ja/strings.xml b/java/res/values-ja/strings.xml new file mode 100644 index 000000000..9097bd936 --- /dev/null +++ b/java/res/values-ja/strings.xml @@ -0,0 +1,127 @@ +<?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/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="english_ime_name" msgid="7252517407088836577">"Androidキーボード"</string> + <string name="english_ime_settings" msgid="6661589557206947774">"Androidキーボードの設定"</string> + <string name="vibrate_on_keypress" msgid="5258079494276955460">"キー操作バイブ"</string> + <string name="sound_on_keypress" msgid="6093592297198243644">"キー操作音"</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> + <!-- no translation found for auto_punctuate_summary (6589441565817502132) --> + <skip /> + <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-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="alternates_for_a" msgid="2566516493365324765">"àáâãäåæ"</string> + <string name="alternates_for_e" msgid="3900510936875547555">"èéêë"</string> + <string name="alternates_for_i" msgid="7097915268629342242">"ìíîï"</string> + <string name="alternates_for_o" msgid="6151402748321267776">"òóôõöœø"</string> + <string name="alternates_for_u" msgid="5899096818189442934">"ùúûü"</string> + <string name="alternates_for_s" msgid="348762530927662188">"§ß"</string> + <string name="alternates_for_n" msgid="6257322556221886400">"ñ"</string> + <string name="alternates_for_c" msgid="151699780720639892">"ç"</string> + <string name="alternates_for_y" msgid="1722776806607271199">"ýÿ"</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> + <!-- no translation found for voice_initializing (661962047129906646) --> + <skip /> + <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="inputMethod" msgid="7854532062009028116">"入力方法"</string> + <string name="language_selection_title" msgid="1651299598555326750">"入力言語"</string> + <string name="language_selection_summary" msgid="187110938289512256">"スペースバーで指をスライドさせて言語を変更する"</string> + <string name="hint_add_to_dictionary" msgid="8058519710062071085">"←保存するにはもう一度タップ"</string> +</resources> diff --git a/java/res/values-ko/strings.xml b/java/res/values-ko/strings.xml new file mode 100644 index 000000000..15000e655 --- /dev/null +++ b/java/res/values-ko/strings.xml @@ -0,0 +1,127 @@ +<?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/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="english_ime_name" msgid="7252517407088836577">"Android 키보드"</string> + <string name="english_ime_settings" msgid="6661589557206947774">"Android 키보드 설정"</string> + <string name="vibrate_on_keypress" msgid="5258079494276955460">"키를 누를 때 진동 발생"</string> + <string name="sound_on_keypress" msgid="6093592297198243644">"버튼을 누를 때 소리 발생"</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> + <!-- no translation found for auto_punctuate_summary (6589441565817502132) --> + <skip /> + <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-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="alternates_for_a" msgid="2566516493365324765">"àáâãäåæ"</string> + <string name="alternates_for_e" msgid="3900510936875547555">"èéêë"</string> + <string name="alternates_for_i" msgid="7097915268629342242">"ìíîï"</string> + <string name="alternates_for_o" msgid="6151402748321267776">"òóôõöœø"</string> + <string name="alternates_for_u" msgid="5899096818189442934">"ùúûü"</string> + <string name="alternates_for_s" msgid="348762530927662188">"§ß"</string> + <string name="alternates_for_n" msgid="6257322556221886400">"ñ"</string> + <string name="alternates_for_c" msgid="151699780720639892">"ç"</string> + <string name="alternates_for_y" msgid="1722776806607271199">"ýÿ"</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> + <!-- no translation found for voice_initializing (661962047129906646) --> + <skip /> + <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="inputMethod" msgid="7854532062009028116">"입력 방법"</string> + <string name="language_selection_title" msgid="1651299598555326750">"입력 언어"</string> + <string name="language_selection_summary" msgid="187110938289512256">"손가락을 스페이스바에서 미끄러지듯 움직여 언어 변경"</string> + <string name="hint_add_to_dictionary" msgid="8058519710062071085">"← 저장하려면 다시 누르세요."</string> +</resources> diff --git a/java/res/values-land/dimens.xml b/java/res/values-land/dimens.xml new file mode 100644 index 000000000..43951552e --- /dev/null +++ b/java/res/values-land/dimens.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> + <dimen name="key_height">47dip</dimen> + <dimen name="candidate_strip_height">38dip</dimen> + <dimen name="spacebar_vertical_correction">2dip</dimen> +</resources>
\ No newline at end of file diff --git a/java/res/values-nb/strings.xml b/java/res/values-nb/strings.xml new file mode 100644 index 000000000..a7ddc7533 --- /dev/null +++ b/java/res/values-nb/strings.xml @@ -0,0 +1,127 @@ +<?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/android" + 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="vibrate_on_keypress" msgid="5258079494276955460">"Vibrer ved tastetrykk"</string> + <string name="sound_on_keypress" msgid="6093592297198243644">"Lyd 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> + <!-- no translation found for auto_punctuate_summary (6589441565817502132) --> + <skip /> + <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">"Autokomplettering"</string> + <string name="auto_complete_summary" msgid="6113149638718274624">"Mellomrom og punktum setter automatisk inn valgt ord"</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="alternates_for_a" msgid="2566516493365324765">"åæáàâãä"</string> + <string name="alternates_for_e" msgid="3900510936875547555">"éèêë"</string> + <string name="alternates_for_i" msgid="7097915268629342242">"íìîï"</string> + <string name="alternates_for_o" msgid="6151402748321267776">"ôóòöõœø"</string> + <string name="alternates_for_u" msgid="5899096818189442934">"üùúû"</string> + <string name="alternates_for_s" msgid="348762530927662188">"ß§"</string> + <string name="alternates_for_n" msgid="6257322556221886400">"ñ"</string> + <string name="alternates_for_c" msgid="151699780720639892">"ç"</string> + <string name="alternates_for_y" msgid="1722776806607271199">"ýÿ"</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> + <!-- no translation found for voice_initializing (661962047129906646) --> + <skip /> + <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">"Mikronfon på hovedtastatur"</item> + <item msgid="6907837061058876770">"Mikronfon 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å & 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="inputMethod" msgid="7854532062009028116">"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="8058519710062071085">"← Trykk på nytt for å lagre"</string> +</resources> diff --git a/java/res/values-nl/bools.xml b/java/res/values-nl/bools.xml new file mode 100644 index 000000000..897f4b3db --- /dev/null +++ b/java/res/values-nl/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="im_is_default">true</bool> +</resources> diff --git a/java/res/values-nl/strings.xml b/java/res/values-nl/strings.xml new file mode 100644 index 000000000..9a69c128e --- /dev/null +++ b/java/res/values-nl/strings.xml @@ -0,0 +1,127 @@ +<?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/android" + 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="vibrate_on_keypress" msgid="5258079494276955460">"Trillen bij druk op een toets"</string> + <string name="sound_on_keypress" msgid="6093592297198243644">"Geluid bij druk op een toets"</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">"Automatisch 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> + <!-- no translation found for auto_punctuate_summary (6589441565817502132) --> + <skip /> + <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-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="alternates_for_a" msgid="2566516493365324765">"àáâãäåæ"</string> + <string name="alternates_for_e" msgid="3900510936875547555">"èéêë"</string> + <string name="alternates_for_i" msgid="7097915268629342242">"ìíîï"</string> + <string name="alternates_for_o" msgid="6151402748321267776">"òóôõöœø"</string> + <string name="alternates_for_u" msgid="5899096818189442934">"ùúûü"</string> + <string name="alternates_for_s" msgid="348762530927662188">"§ß"</string> + <string name="alternates_for_n" msgid="6257322556221886400">"ñ"</string> + <string name="alternates_for_c" msgid="151699780720639892">"ç"</string> + <string name="alternates_for_y" msgid="1722776806607271199">"ýÿ"</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> + <!-- no translation found for voice_initializing (661962047129906646) --> + <skip /> + <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="inputMethod" msgid="7854532062009028116">"Invoermethode"</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="8058519710062071085">"← Tik nogmaals om op te slaan"</string> +</resources> diff --git a/java/res/values-pl/bools.xml b/java/res/values-pl/bools.xml new file mode 100644 index 000000000..897f4b3db --- /dev/null +++ b/java/res/values-pl/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="im_is_default">true</bool> +</resources> diff --git a/java/res/values-pl/donottranslate.xml b/java/res/values-pl/donottranslate.xml new file mode 100644 index 000000000..196e73c1d --- /dev/null +++ b/java/res/values-pl/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"> + <!-- Accented characters related to "z" --> + <string name="alternates_for_z">źż</string> + <!-- Accented characters related to "l" --> + <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 000000000..a411cc213 --- /dev/null +++ b/java/res/values-pl/strings.xml @@ -0,0 +1,127 @@ +<?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/android" + 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="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="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">"Propozycje słów"</string> + <string name="auto_correction_summary" msgid="6881047311475758267">"Automatycznie poprawiaj poprzednie słowo"</string> + <string name="prediction" msgid="466220283138359837">"Propozycje 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 propozycje 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> + <!-- no translation found for auto_punctuate_summary (6589441565817502132) --> + <skip /> + <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-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="alternates_for_a" msgid="2566516493365324765">"ą"</string> + <string name="alternates_for_e" msgid="3900510936875547555">"ę"</string> + <string name="alternates_for_i" msgid="7097915268629342242">"ìíîï"</string> + <string name="alternates_for_o" msgid="6151402748321267776">"ó"</string> + <string name="alternates_for_u" msgid="5899096818189442934">"ùúûü"</string> + <string name="alternates_for_s" msgid="348762530927662188">"ś"</string> + <string name="alternates_for_n" msgid="6257322556221886400">"ń"</string> + <string name="alternates_for_c" msgid="151699780720639892">"ć"</string> + <string name="alternates_for_y" msgid="1722776806607271199">"ýÿ"</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">"Przejdź"</string> + <string name="label_next_key" msgid="362972844525672568">"Dalej"</string> + <string name="label_done_key" msgid="2441578748772529288">"Gotowe"</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">"Działa"</string> + <!-- no translation found for voice_initializing (661962047129906646) --> + <skip /> + <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">"Nie znaleziono żadnych 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="inputMethod" msgid="7854532062009028116">"Metoda 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="8058519710062071085">"← Dotknij ponownie, aby zapisać"</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 000000000..399975d88 --- /dev/null +++ b/java/res/values-pt-rPT/strings.xml @@ -0,0 +1,127 @@ +<?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/android" + 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="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="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">"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> + <!-- no translation found for auto_punctuate_summary (6589441565817502132) --> + <skip /> + <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 palavras sugeridas durante a escrita"</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-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="alternates_for_a" msgid="2566516493365324765">"àáâãäåæ"</string> + <string name="alternates_for_e" msgid="3900510936875547555">"èéêë"</string> + <string name="alternates_for_i" msgid="7097915268629342242">"ìíîï"</string> + <string name="alternates_for_o" msgid="6151402748321267776">"òóôõöœø"</string> + <string name="alternates_for_u" msgid="5899096818189442934">"ùúûü"</string> + <string name="alternates_for_s" msgid="348762530927662188">"§ß"</string> + <string name="alternates_for_n" msgid="6257322556221886400">"ñ"</string> + <string name="alternates_for_c" msgid="151699780720639892">"ç"</string> + <string name="alternates_for_y" msgid="1722776806607271199">"ýÿ"</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>"Toque e 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>"Toque e mantenha premida esta tecla para alterar definiçõ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">"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> + <!-- no translation found for voice_initializing (661962047129906646) --> + <skip /> + <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="inputMethod" msgid="7854532062009028116">"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="8058519710062071085">"← Toque novamente para guardar"</string> +</resources> diff --git a/java/res/values-pt/strings.xml b/java/res/values-pt/strings.xml new file mode 100644 index 000000000..18ffdf011 --- /dev/null +++ b/java/res/values-pt/strings.xml @@ -0,0 +1,127 @@ +<?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/android" + 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="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="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> + <!-- no translation found for auto_punctuate_summary (6589441565817502132) --> + <skip /> + <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-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="alternates_for_a" msgid="2566516493365324765">"àáâãäåæ"</string> + <string name="alternates_for_e" msgid="3900510936875547555">"èéêë"</string> + <string name="alternates_for_i" msgid="7097915268629342242">"ìíîï"</string> + <string name="alternates_for_o" msgid="6151402748321267776">"òóôõöœø"</string> + <string name="alternates_for_u" msgid="5899096818189442934">"ùúûü"</string> + <string name="alternates_for_s" msgid="348762530927662188">"§ß"</string> + <string name="alternates_for_n" msgid="6257322556221886400">"ñ"</string> + <string name="alternates_for_c" msgid="151699780720639892">"ç"</string> + <string name="alternates_for_y" msgid="1722776806607271199">"ýÿ"</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 arquivo de texto"</b></string> + <string name="tip_to_view_accents" msgid="5433158573693308501"><b>"Tocar e segurar a 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> + <!-- no translation found for voice_initializing (661962047129906646) --> + <skip /> + <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 os acentos."</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="inputMethod" msgid="7854532062009028116">"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="8058519710062071085">"← Toque novamente para salvar"</string> +</resources> diff --git a/java/res/values-ru/strings.xml b/java/res/values-ru/strings.xml new file mode 100644 index 000000000..d4ebc6d60 --- /dev/null +++ b/java/res/values-ru/strings.xml @@ -0,0 +1,127 @@ +<?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/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="english_ime_name" msgid="7252517407088836577">"Клавиатура Android"</string> + <string name="english_ime_settings" msgid="6661589557206947774">"Настройки клавиатуры Android"</string> + <string name="vibrate_on_keypress" msgid="5258079494276955460">"Виброотклик клавиш"</string> + <string name="sound_on_keypress" msgid="6093592297198243644">"Звук клавиш"</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> + <!-- no translation found for auto_punctuate_summary (6589441565817502132) --> + <skip /> + <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-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="alternates_for_a" msgid="2566516493365324765">"àáâãäåæ"</string> + <string name="alternates_for_e" msgid="3900510936875547555">"èéêë"</string> + <string name="alternates_for_i" msgid="7097915268629342242">"ìíîï"</string> + <string name="alternates_for_o" msgid="6151402748321267776">"òóôõöœø"</string> + <string name="alternates_for_u" msgid="5899096818189442934">"ùúûü"</string> + <string name="alternates_for_s" msgid="348762530927662188">"§ß"</string> + <string name="alternates_for_n" msgid="6257322556221886400">"ñ"</string> + <string name="alternates_for_c" msgid="151699780720639892">"ç"</string> + <string name="alternates_for_y" msgid="1722776806607271199">"ýÿ"</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> + <!-- no translation found for voice_initializing (661962047129906646) --> + <skip /> + <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="inputMethod" msgid="7854532062009028116">"Способ ввода"</string> + <string name="language_selection_title" msgid="1651299598555326750">"Языки ввода"</string> + <string name="language_selection_summary" msgid="187110938289512256">"Для изменения языка проведите пальцем по пробелу"</string> + <string name="hint_add_to_dictionary" msgid="8058519710062071085">"← Нажмите повторно, чтобы сохранить"</string> +</resources> diff --git a/java/res/values-sv/strings.xml b/java/res/values-sv/strings.xml new file mode 100644 index 000000000..2d07a076a --- /dev/null +++ b/java/res/values-sv/strings.xml @@ -0,0 +1,127 @@ +<?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/android" + 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="vibrate_on_keypress" msgid="5258079494276955460">"Vibrera vid tangenttryck"</string> + <string name="sound_on_keypress" msgid="6093592297198243644">"Knappljud"</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> + <!-- no translation found for auto_punctuate_summary (6589441565817502132) --> + <skip /> + <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-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="alternates_for_a" msgid="2566516493365324765">"àáâãäåæ"</string> + <string name="alternates_for_e" msgid="3900510936875547555">"èéêë"</string> + <string name="alternates_for_i" msgid="7097915268629342242">"ìíîï"</string> + <string name="alternates_for_o" msgid="6151402748321267776">"òóôõöœø"</string> + <string name="alternates_for_u" msgid="5899096818189442934">"ùúûü"</string> + <string name="alternates_for_s" msgid="348762530927662188">"§ß"</string> + <string name="alternates_for_n" msgid="6257322556221886400">"ñ"</string> + <string name="alternates_for_c" msgid="151699780720639892">"ç"</string> + <string name="alternates_for_y" msgid="1722776806607271199">"ýÿ"</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 ned 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>"Återgå 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> + <!-- no translation found for voice_initializing (661962047129906646) --> + <skip /> + <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="inputMethod" msgid="7854532062009028116">"Indatametod"</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="8058519710062071085">"← Peka igen för att spara"</string> +</resources> diff --git a/java/res/values-tr/donottranslate.xml b/java/res/values-tr/donottranslate.xml new file mode 100644 index 000000000..2154c16bb --- /dev/null +++ b/java/res/values-tr/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"> + <!-- Accented characters related to "g" --> + <string name="alternates_for_g">ğ</string> +</resources>
\ No newline at end of file diff --git a/java/res/values-tr/strings.xml b/java/res/values-tr/strings.xml new file mode 100644 index 000000000..e150a5ee7 --- /dev/null +++ b/java/res/values-tr/strings.xml @@ -0,0 +1,127 @@ +<?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/android" + 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="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="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> + <!-- no translation found for auto_punctuate_summary (6589441565817502132) --> + <skip /> + <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-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="alternates_for_a" msgid="2566516493365324765">"àáâãäåæ"</string> + <string name="alternates_for_e" msgid="3900510936875547555">"èéêë"</string> + <string name="alternates_for_i" msgid="7097915268629342242">"iìíîï"</string> + <string name="alternates_for_o" msgid="6151402748321267776">"öòóôõœø"</string> + <string name="alternates_for_u" msgid="5899096818189442934">"üùúû"</string> + <string name="alternates_for_s" msgid="348762530927662188">"ş§ß"</string> + <string name="alternates_for_n" msgid="6257322556221886400">"ñ"</string> + <string name="alternates_for_c" msgid="151699780720639892">"ç"</string> + <string name="alternates_for_y" msgid="1722776806607271199">"ýÿ"</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> + <!-- no translation found for voice_initializing (661962047129906646) --> + <skip /> + <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="inputMethod" msgid="7854532062009028116">"Giriş yöntemi"</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="8058519710062071085">"← Kaydetmek için tekrar dokunun"</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 000000000..f3729914b --- /dev/null +++ b/java/res/values-zh-rCN/strings.xml @@ -0,0 +1,127 @@ +<?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/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="english_ime_name" msgid="7252517407088836577">"Android 键盘"</string> + <string name="english_ime_settings" msgid="6661589557206947774">"Android 键盘设置"</string> + <string name="vibrate_on_keypress" msgid="5258079494276955460">"按键时振动"</string> + <string name="sound_on_keypress" msgid="6093592297198243644">"按键时播放音效"</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> + <!-- no translation found for auto_punctuate_summary (6589441565817502132) --> + <skip /> + <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-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="alternates_for_a" msgid="2566516493365324765">"àáâãäåæ"</string> + <string name="alternates_for_e" msgid="3900510936875547555">"èéêë"</string> + <string name="alternates_for_i" msgid="7097915268629342242">"ìíîï"</string> + <string name="alternates_for_o" msgid="6151402748321267776">"òóôõöœø"</string> + <string name="alternates_for_u" msgid="5899096818189442934">"ùúûü"</string> + <string name="alternates_for_s" msgid="348762530927662188">"§ß"</string> + <string name="alternates_for_n" msgid="6257322556221886400">"ñ"</string> + <string name="alternates_for_c" msgid="151699780720639892">"ç"</string> + <string name="alternates_for_y" msgid="1722776806607271199">"ýÿ"</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> + <!-- no translation found for voice_initializing (661962047129906646) --> + <skip /> + <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="inputMethod" msgid="7854532062009028116">"输入法"</string> + <string name="language_selection_title" msgid="1651299598555326750">"输入语言"</string> + <string name="language_selection_summary" msgid="187110938289512256">"在空格键上滑动手指可更改语言"</string> + <string name="hint_add_to_dictionary" msgid="8058519710062071085">"← 再次点按即可保存"</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 000000000..f6b4e312f --- /dev/null +++ b/java/res/values-zh-rTW/strings.xml @@ -0,0 +1,129 @@ +<?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/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="english_ime_name" msgid="7252517407088836577">"Android 鍵盤"</string> + <string name="english_ime_settings" msgid="6661589557206947774">"Android 鍵盤設定"</string> + <string name="vibrate_on_keypress" msgid="5258079494276955460">"按鍵時震動"</string> + <string name="sound_on_keypress" msgid="6093592297198243644">"按鍵時播放音效"</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> + <!-- no translation found for auto_punctuate_summary (6589441565817502132) --> + <skip /> + <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-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="alternates_for_a" msgid="2566516493365324765">"àáâãäåæ"</string> + <string name="alternates_for_e" msgid="3900510936875547555">"èéêë"</string> + <string name="alternates_for_i" msgid="7097915268629342242">"ìíîï"</string> + <string name="alternates_for_o" msgid="6151402748321267776">"òóôõöœø"</string> + <string name="alternates_for_u" msgid="5899096818189442934">"ùúûü"</string> + <string name="alternates_for_s" msgid="348762530927662188">"§ß"</string> + <string name="alternates_for_n" msgid="6257322556221886400">"ñ"</string> + <string name="alternates_for_c" msgid="151699780720639892">"ç"</string> + <string name="alternates_for_y" msgid="1722776806607271199">"ýÿ"</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> + <!-- no translation found for voice_initializing (661962047129906646) --> + <skip /> + <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="inputMethod" msgid="7854532062009028116">"輸入方式"</string> + <string name="language_selection_title" msgid="1651299598555326750">"輸入語言"</string> + <string name="language_selection_summary" msgid="187110938289512256">"以手指在空白鍵上滑動可變更語言"</string> + <string name="hint_add_to_dictionary" msgid="8058519710062071085">"← 再次輕按可儲存"</string> + <!-- no translation found for has_dictionary (6071847973466625007) --> + <skip /> +</resources> diff --git a/java/res/values/bools.xml b/java/res/values/bools.xml new file mode 100644 index 000000000..ebe2f04e5 --- /dev/null +++ b/java/res/values/bools.xml @@ -0,0 +1,28 @@ +<?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">true</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> +</resources> diff --git a/java/res/values/colors.xml b/java/res/values/colors.xml new file mode 100644 index 000000000..c90d9f6af --- /dev/null +++ b/java/res/values/colors.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** +** Copyright 2008, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> +<resources> + <color name="candidate_normal">#FF000000</color> + <color name="candidate_recommended">#FFE35900</color> + <color name="candidate_other">#ff808080</color> +</resources>
\ No newline at end of file diff --git a/java/res/values/dimens.xml b/java/res/values/dimens.xml new file mode 100644 index 000000000..5b2095c0e --- /dev/null +++ b/java/res/values/dimens.xml @@ -0,0 +1,26 @@ +<?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> + <dimen name="key_height">54dip</dimen> + <dimen name="bubble_pointer_offset">22dip</dimen> + <dimen name="candidate_strip_height">42dip</dimen> + <dimen name="spacebar_vertical_correction">4dip</dimen> +</resources>
\ No newline at end of file diff --git a/java/res/values/donottranslate.xml b/java/res/values/donottranslate.xml new file mode 100644 index 000000000..d5017353d --- /dev/null +++ b/java/res/values/donottranslate.xml @@ -0,0 +1,39 @@ +<?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()[]*&@{}/<>_+=|\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">!?,@_</string> + <!-- Accented characters related to "d" --> + <string name="alternates_for_d"></string> + <!-- Accented characters related to "r" --> + <string name="alternates_for_r"></string> + <!-- Accented characters related to "t" --> + <string name="alternates_for_t"></string> + <!-- Accented characters related to "z" --> + <string name="alternates_for_z"></string> + <!-- Accented characters related to "l" --> + <string name="alternates_for_l"></string> + <!-- Accented characters related to "g" --> + <string name="alternates_for_g"></string> +</resources> diff --git a/java/res/values/durations.xml b/java/res/values/durations.xml new file mode 100644 index 000000000..92af68e39 --- /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. --> + <integer name="vibrate_duration_ms">40</integer> +</resources> diff --git a/java/res/values/keycodes.xml b/java/res/values/keycodes.xml new file mode 100644 index 000000000..8156c0e07 --- /dev/null +++ b/java/res/values/keycodes.xml @@ -0,0 +1,24 @@ +<?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> + <!-- Keycode for F1 (function) key. This one switches between language switch & comma/.com --> + <integer name="key_f1">-103</integer> +</resources> diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml new file mode 100644 index 000000000..35dd3e089 --- /dev/null +++ b/java/res/values/strings.xml @@ -0,0 +1,325 @@ +<?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">Android keyboard</string> + <!-- Title for Latin keyboard settings activity / dialog --> + <string name="english_ime_settings">Android keyboard settings</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 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> + + <!-- 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> + <!-- Accented forms of "a" --> + <string name="alternates_for_a">àáâãäåæ</string> + <!-- Accented forms of "e" --> + <string name="alternates_for_e">èéêë</string> + <!-- Accented forms of "i" --> + <string name="alternates_for_i">ìíîï</string> + <!-- Accented forms of "o" --> + <string name="alternates_for_o">òóôõöœø</string> + <!-- Accented forms of "u" --> + <string name="alternates_for_u">ùúûü</string> + <!-- Letters associated with "s" --> + <string name="alternates_for_s">§ß</string> + <!-- Accented forms of "n" --> + <string name="alternates_for_n">ñ</string> + <!-- Accented forms of "c" --> + <string name="alternates_for_c">ç</string> + <!-- Accented forms of "y" --> + <string name="alternates_for_y">ýÿ</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 & 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 & 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 switcher --> + <string name="inputMethod">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 Tap again to save</string> + + <!-- Inform the user that a particular language has an available dictionary --> + <string name="has_dictionary">Dictionary available</string> +</resources> diff --git a/java/res/xml-de/kbd_qwerty.xml b/java/res/xml-de/kbd_qwerty.xml new file mode 100755 index 000000000..4e57c6067 --- /dev/null +++ b/java/res/xml-de/kbd_qwerty.xml @@ -0,0 +1,189 @@ +<?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/android" + android:keyWidth="10%p" + android:horizontalGap="0px" + android:verticalGap="0px" + android:keyHeight="@dimen/key_height" + > + + <Row> + <Key android:codes="113" android:keyLabel="q" android:keyEdgeFlags="left"/> + <Key android:codes="119" android:keyLabel="w"/> + <Key android:codes="101" android:keyLabel="e" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_e" + /> + <Key android:codes="114" android:keyLabel="r"/> + <Key android:codes="116" android:keyLabel="t"/> + <Key android:codes="122" android:keyLabel="z" /> + <Key android:codes="117" android:keyLabel="u" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_u" + /> + <Key android:codes="105" android:keyLabel="i" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_i" + /> + <Key android:codes="111" android:keyLabel="o" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_o" + /> + <Key android:codes="112" android:keyLabel="p" android:keyEdgeFlags="right"/> + </Row> + + <Row> + <Key android:codes="97" android:keyLabel="a" android:horizontalGap="5%p" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_a" + android:keyEdgeFlags="left"/> + <Key android:codes="115" android:keyLabel="s" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_s" + /> + <Key android:codes="100" android:keyLabel="d"/> + <Key android:codes="102" android:keyLabel="f"/> + <Key android:codes="103" android:keyLabel="g"/> + <Key android:codes="104" android:keyLabel="h"/> + <Key android:codes="106" android:keyLabel="j"/> + <Key android:codes="107" android:keyLabel="k"/> + <Key android:codes="108" android:keyLabel="l" android:keyEdgeFlags="right"/> + </Row> + + <Row> + <Key android:codes="-1" android:keyIcon="@drawable/sym_keyboard_shift" + android:keyWidth="15%p" android:isModifier="true" + android:iconPreview="@drawable/sym_keyboard_feedback_shift" + android:isSticky="true" android:keyEdgeFlags="left"/> + <Key android:codes="121" android:keyLabel="y" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_y" + /> + <Key android:codes="120" android:keyLabel="x"/> + <Key android:codes="99" android:keyLabel="c" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_c" + /> + <Key android:codes="118" android:keyLabel="v"/> + <Key android:codes="98" android:keyLabel="b"/> + <Key android:codes="110" android:keyLabel="n" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_n" + /> + <Key android:codes="109" android:keyLabel="m"/> + <Key android:codes="-5" android:keyIcon="@drawable/sym_keyboard_delete" + android:keyWidth="15%p" android:keyEdgeFlags="right" + android:iconPreview="@drawable/sym_keyboard_feedback_delete" + android:isRepeatable="true"/> + </Row> + + <Row android:keyboardMode="@+id/mode_normal" android:rowEdgeFlags="bottom"> + <Key android:codes="-2" android:keyLabel="@string/label_symbol_key" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="_" + android:keyWidth="20%p" android:keyEdgeFlags="left"/> + <Key android:codes="@integer/key_f1" + android:keyWidth="10%p"/> + <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" + android:iconPreview="@drawable/sym_keyboard_feedback_space" + android:keyWidth="40%p" android:isRepeatable="true"/> + <Key android:codes="46" android:keyLabel="." android:popupKeyboard="@xml/popup_punctuation" + android:keyWidth="10%p"/> + <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return" + android:iconPreview="@drawable/sym_keyboard_feedback_return" + android:keyWidth="20%p" android:keyEdgeFlags="right"/> + </Row> + + <Row android:keyboardMode="@+id/mode_url" android:rowEdgeFlags="bottom"> + <Key android:codes="-2" android:keyLabel="@string/label_symbol_key" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="_" + android:keyWidth="20%p" android:keyEdgeFlags="left"/> + <Key android:keyLabel="/" android:keyWidth="10%p"/> + <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" + android:iconPreview="@drawable/sym_keyboard_feedback_space" + android:keyWidth="20%p" android:isRepeatable="true"/> + <Key android:keyLabel="@string/popular_domain_0" + android:keyOutputText="@string/popular_domain_0" + android:popupKeyboard="@xml/popup_domains" + android:keyWidth="20%p"/> + <Key android:keyLabel="." android:popupKeyboard="@xml/popup_punctuation" + android:keyWidth="10%p"/> + <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return" + android:iconPreview="@drawable/sym_keyboard_feedback_return" + android:keyWidth="20%p" android:keyEdgeFlags="right"/> + </Row> + + <Row android:keyboardMode="@+id/mode_email" android:rowEdgeFlags="bottom"> + <Key android:codes="-2" android:keyLabel="@string/label_symbol_key" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="_" + android:keyWidth="20%p" android:keyEdgeFlags="left"/> + <Key android:keyLabel="\@"/> + <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" + android:iconPreview="@drawable/sym_keyboard_feedback_space" + android:keyWidth="20%p" android:isRepeatable="true"/> + <Key android:keyLabel="@string/popular_domain_0" + android:keyOutputText="@string/popular_domain_0" + android:popupKeyboard="@xml/popup_domains" + android:keyWidth="20%p"/> + <Key android:keyLabel="." android:popupKeyboard="@xml/popup_punctuation"/> + <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return" + android:iconPreview="@drawable/sym_keyboard_feedback_return" + android:keyWidth="20%p" android:keyEdgeFlags="right"/> + </Row> + + <Row android:keyboardMode="@+id/mode_im" android:rowEdgeFlags="bottom"> + <Key android:codes="-2" android:keyLabel="@string/label_symbol_key" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="_" + android:keyWidth="20%p" android:keyEdgeFlags="left"/> + <Key android:codes="@integer/key_f1" android:keyIcon="@drawable/sym_keyboard_globe" + android:keyWidth="10%p"/> + <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" + android:iconPreview="@drawable/sym_keyboard_feedback_space" + android:keyWidth="40%p" android:isRepeatable="true"/> + <Key android:codes="46" android:keyLabel="." android:popupKeyboard="@xml/popup_punctuation" + android:keyWidth="10%p"/> + <Key android:keyLabel=":-)" android:keyOutputText=":-) " + android:popupKeyboard="@xml/popup_smileys" + android:keyWidth="20%p" android:keyEdgeFlags="right"/> + </Row> + + <Row android:keyboardMode="@+id/mode_webentry" android:rowEdgeFlags="bottom"> + <Key android:codes="-2" android:keyLabel="@string/label_symbol_key" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="_" + android:keyWidth="20%p" android:keyEdgeFlags="left"/> + <Key android:codes="@integer/key_f1" android:keyIcon="@drawable/sym_keyboard_globe" + android:keyWidth="10%p"/> + <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" + android:iconPreview="@drawable/sym_keyboard_feedback_space" + android:keyWidth="20%p" android:isRepeatable="true"/> + <Key android:codes="9" android:keyIcon="@drawable/sym_keyboard_tab" + android:iconPreview="@drawable/sym_keyboard_feedback_tab" + android:keyWidth="20%p"/> + <Key android:keyLabel="." android:popupKeyboard="@xml/popup_punctuation"/> + <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return" + android:iconPreview="@drawable/sym_keyboard_feedback_return" + android:keyWidth="20%p" 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 000000000..1b20c0438 --- /dev/null +++ b/java/res/xml-fr/kbd_qwerty.xml @@ -0,0 +1,193 @@ +<?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/android" + android:keyWidth="10%p" + android:horizontalGap="0px" + android:verticalGap="0px" + android:keyHeight="@dimen/key_height" + > + + <Row> + <Key android:codes="97" android:keyLabel="a" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_a" + android:keyEdgeFlags="left"/> + <Key android:codes="122" android:keyLabel="z"/> + <Key android:codes="101" android:keyLabel="e" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_e" + /> + <Key android:codes="114" android:keyLabel="r"/> + <Key android:codes="116" android:keyLabel="t"/> + <Key android:codes="121" android:keyLabel="y" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_y" + /> + <Key android:codes="117" android:keyLabel="u" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_u" + /> + <Key android:codes="105" android:keyLabel="i" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_i" + /> + <Key android:codes="111" android:keyLabel="o" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_o" + /> + <Key android:codes="112" android:keyLabel="p" android:keyEdgeFlags="right"/> + </Row> + + <Row> + <Key android:codes="113" android:keyLabel="q" android:keyEdgeFlags="left"/> + <Key android:codes="115" android:keyLabel="s" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_s" + /> + <Key android:codes="100" android:keyLabel="d"/> + <Key android:codes="102" android:keyLabel="f"/> + <Key android:codes="103" android:keyLabel="g"/> + <Key android:codes="104" android:keyLabel="h"/> + <Key android:codes="106" android:keyLabel="j"/> + <Key android:codes="107" android:keyLabel="k"/> + <Key android:codes="108" android:keyLabel="l"/> + <Key android:codes="109" android:keyLabel="m" android:keyEdgeFlags="right"/> + </Row> + + <Row> + <Key android:codes="-1" android:keyIcon="@drawable/sym_keyboard_shift" + android:keyWidth="15%p" android:isModifier="true" + android:iconPreview="@drawable/sym_keyboard_feedback_shift" + android:isSticky="true" android:keyEdgeFlags="left"/> + <Key android:codes="119" android:keyLabel="w"/> + <Key android:codes="120" android:keyLabel="x"/> + <Key android:codes="99" android:keyLabel="c" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_c" + /> + <Key android:codes="118" android:keyLabel="v"/> + <Key android:codes="98" android:keyLabel="b"/> + <Key android:codes="110" android:keyLabel="n" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_n" + /> + <!--Key android:codes="233,224,232,234" android:keyLabel="é"/--> + <Key android:keyLabel="\'"/> + <Key android:codes="-5" android:keyIcon="@drawable/sym_keyboard_delete" + android:keyWidth="15%p" android:keyEdgeFlags="right" + android:iconPreview="@drawable/sym_keyboard_feedback_delete" + android:isRepeatable="true"/> + </Row> + + <Row android:keyboardMode="@+id/mode_normal" android:rowEdgeFlags="bottom"> + <Key android:codes="-2" android:keyLabel="@string/label_symbol_key" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="_" + android:keyWidth="20%p" android:keyEdgeFlags="left"/> + <Key android:codes="@integer/key_f1" android:keyIcon="@drawable/sym_keyboard_globe" + android:keyWidth="10%p"/> + <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" + android:iconPreview="@drawable/sym_keyboard_feedback_space" + android:keyWidth="40%p" android:isRepeatable="true"/> + <Key android:codes="46" android:keyLabel="." android:popupKeyboard="@xml/popup_punctuation" + android:keyWidth="10%p"/> + <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return" + android:iconPreview="@drawable/sym_keyboard_feedback_return" + android:keyWidth="20%p" android:keyEdgeFlags="right"/> + </Row> + + <Row android:keyboardMode="@+id/mode_url" android:rowEdgeFlags="bottom"> + <Key android:codes="-2" android:keyLabel="@string/label_symbol_key" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="_" + android:keyWidth="20%p" android:keyEdgeFlags="left"/> + <Key android:keyLabel="/" android:keyWidth="10%p"/> + <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" + android:iconPreview="@drawable/sym_keyboard_feedback_space" + android:keyWidth="20%p" android:isRepeatable="true"/> + <Key android:keyLabel="@string/popular_domain_0" + android:keyOutputText="@string/popular_domain_0" + android:popupKeyboard="@xml/popup_domains" + android:keyWidth="20%p"/> + <Key android:keyLabel="." android:popupKeyboard="@xml/popup_punctuation" + android:keyWidth="10%p"/> + <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return" + android:iconPreview="@drawable/sym_keyboard_feedback_return" + android:keyWidth="20%p" android:keyEdgeFlags="right"/> + </Row> + + <Row android:keyboardMode="@+id/mode_email" android:rowEdgeFlags="bottom"> + <Key android:codes="-2" android:keyLabel="@string/label_symbol_key" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="_" + android:keyWidth="20%p" android:keyEdgeFlags="left"/> + <Key android:keyLabel="\@"/> + <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" + android:iconPreview="@drawable/sym_keyboard_feedback_space" + android:keyWidth="20%p" android:isRepeatable="true"/> + <Key android:keyLabel="@string/popular_domain_0" + android:keyOutputText="@string/popular_domain_0" + android:popupKeyboard="@xml/popup_domains" + android:keyWidth="20%p"/> + <Key android:keyLabel="." android:popupKeyboard="@xml/popup_punctuation"/> + <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return" + android:iconPreview="@drawable/sym_keyboard_feedback_return" + android:keyWidth="20%p" android:keyEdgeFlags="right"/> + </Row> + + <Row android:keyboardMode="@+id/mode_im" android:rowEdgeFlags="bottom"> + <Key android:codes="-2" android:keyLabel="@string/label_symbol_key" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="_" + android:keyWidth="20%p" android:keyEdgeFlags="left"/> + <Key android:codes="@integer/key_f1" android:keyIcon="@drawable/sym_keyboard_globe" + android:keyWidth="10%p"/> + <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" + android:iconPreview="@drawable/sym_keyboard_feedback_space" + android:keyWidth="40%p" android:isRepeatable="true"/> + <Key android:codes="46" android:keyLabel="." android:popupKeyboard="@xml/popup_punctuation" + android:keyWidth="10%p"/> + <Key android:keyLabel=":-)" android:keyOutputText=":-) " + android:popupKeyboard="@xml/popup_smileys" + android:keyWidth="20%p" android:keyEdgeFlags="right"/> + </Row> + + <Row android:keyboardMode="@+id/mode_webentry" android:rowEdgeFlags="bottom"> + <Key android:codes="-2" android:keyLabel="@string/label_symbol_key" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="_" + android:keyWidth="20%p" android:keyEdgeFlags="left"/> + <Key android:codes="@integer/key_f1" android:keyIcon="@drawable/sym_keyboard_globe" + android:keyWidth="10%p"/> + <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" + android:iconPreview="@drawable/sym_keyboard_feedback_space" + android:keyWidth="20%p" android:isRepeatable="true"/> + <Key android:codes="9" android:keyIcon="@drawable/sym_keyboard_tab" + android:iconPreview="@drawable/sym_keyboard_feedback_tab" + android:keyWidth="20%p"/> + <Key android:keyLabel="." android:popupKeyboard="@xml/popup_punctuation"/> + <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return" + android:iconPreview="@drawable/sym_keyboard_feedback_return" + android:keyWidth="20%p" 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 100755 index 000000000..45d355b0f --- /dev/null +++ b/java/res/xml-ru/kbd_qwerty.xml @@ -0,0 +1,174 @@ +<?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/android" + android:keyWidth="9.09%p" + android:horizontalGap="0px" + android:verticalGap="0px" + android:keyHeight="@dimen/key_height" + > + + <Row> + <Key android:keyLabel="й" + 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="г"/> + <Key android:keyLabel="ш"/> + <Key android:keyLabel="щ"/> + <Key android:keyLabel="з"/> + <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 android:keyWidth="8.5%p"> + <Key android:codes="-1" android:keyIcon="@drawable/sym_keyboard_shift" + android:keyWidth="11.75%p" android:isModifier="true" + android:iconPreview="@drawable/sym_keyboard_feedback_shift" + 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:keyLabel="ю"/> + <Key android:codes="-5" android:keyIcon="@drawable/sym_keyboard_delete" + android:keyWidth="11.75%p" android:keyEdgeFlags="right" + android:iconPreview="@drawable/sym_keyboard_feedback_delete" + android:isRepeatable="true"/> + </Row> + + <Row android:keyboardMode="@+id/mode_normal" android:rowEdgeFlags="bottom"> + <Key android:codes="-2" android:keyLabel="@string/label_symbol_key" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="_" + android:keyWidth="20%p" android:keyEdgeFlags="left"/> + <Key android:codes="@integer/key_f1" android:keyIcon="@drawable/sym_keyboard_globe" + android:keyWidth="10%p"/> + <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" + android:iconPreview="@drawable/sym_keyboard_feedback_space" + android:keyWidth="40%p" android:isRepeatable="true"/> + <Key android:codes="46" android:keyLabel="." android:popupKeyboard="@xml/popup_punctuation" + android:keyWidth="10%p"/> + <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return" + android:iconPreview="@drawable/sym_keyboard_feedback_return" + android:keyWidth="20%p" android:keyEdgeFlags="right"/> + </Row> + + <Row android:keyboardMode="@+id/mode_url" android:rowEdgeFlags="bottom"> + <Key android:codes="-2" android:keyLabel="@string/label_symbol_key" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="_" + android:keyWidth="20%p" android:keyEdgeFlags="left"/> + <Key android:keyLabel="/" android:keyWidth="10%p"/> + <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" + android:iconPreview="@drawable/sym_keyboard_feedback_space" + android:keyWidth="20%p" android:isRepeatable="true"/> + <Key android:keyLabel="@string/popular_domain_0" + android:keyOutputText="@string/popular_domain_0" + android:popupKeyboard="@xml/popup_domains" + android:keyWidth="20%p"/> + <Key android:keyLabel="." android:popupKeyboard="@xml/popup_punctuation" + android:keyWidth="10%p"/> + <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return" + android:iconPreview="@drawable/sym_keyboard_feedback_return" + android:keyWidth="20%p" android:keyEdgeFlags="right"/> + </Row> + + <Row android:keyboardMode="@+id/mode_email" android:rowEdgeFlags="bottom"> + <Key android:codes="-2" android:keyLabel="@string/label_symbol_key" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="_" + android:keyWidth="20%p" android:keyEdgeFlags="left"/> + <Key android:keyLabel="\@" android:keyWidth="10%p"/> + <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" + android:iconPreview="@drawable/sym_keyboard_feedback_space" + android:keyWidth="20%p" android:isRepeatable="true"/> + <Key android:keyLabel="@string/popular_domain_0" + android:keyOutputText="@string/popular_domain_0" + android:popupKeyboard="@xml/popup_domains" + android:keyWidth="20%p"/> + <Key android:keyLabel="." android:popupKeyboard="@xml/popup_punctuation"/> + <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return" + android:iconPreview="@drawable/sym_keyboard_feedback_return" + android:keyWidth="20%p" android:keyEdgeFlags="right"/> + </Row> + + <Row android:keyboardMode="@+id/mode_im" android:rowEdgeFlags="bottom"> + <Key android:codes="-2" android:keyLabel="@string/label_symbol_key" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="_" + android:keyWidth="20%p" android:keyEdgeFlags="left"/> + <Key android:codes="@integer/key_f1" android:keyIcon="@drawable/sym_keyboard_globe" + android:keyWidth="10%p"/> + <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" + android:iconPreview="@drawable/sym_keyboard_feedback_space" + android:keyWidth="40%p" android:isRepeatable="true"/> + <Key android:codes="46" android:keyLabel="." android:popupKeyboard="@xml/popup_punctuation" + android:keyWidth="10%p"/> + <Key android:keyLabel=":-)" android:keyOutputText=":-) " + android:popupKeyboard="@xml/popup_smileys" + android:keyWidth="20%p" android:keyEdgeFlags="right"/> + </Row> + + <Row android:keyboardMode="@+id/mode_webentry" android:rowEdgeFlags="bottom"> + <Key android:codes="-2" android:keyLabel="@string/label_symbol_key" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="_" + android:keyWidth="20%p" android:keyEdgeFlags="left"/> + <Key android:codes="@integer/key_f1" android:keyIcon="@drawable/sym_keyboard_globe" + android:keyWidth="10%p"/> + <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" + android:iconPreview="@drawable/sym_keyboard_feedback_space" + android:keyWidth="20%p" android:isRepeatable="true"/> + <Key android:codes="9" android:keyIcon="@drawable/sym_keyboard_tab" + android:iconPreview="@drawable/sym_keyboard_feedback_tab" + android:keyWidth="20%p"/> + <Key android:keyLabel="." android:popupKeyboard="@xml/popup_punctuation"/> + <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return" + android:iconPreview="@drawable/sym_keyboard_feedback_return" + android:keyWidth="20%p" android:keyEdgeFlags="right"/> + </Row> +</Keyboard> + diff --git a/java/res/xml/azerty.xml b/java/res/xml/azerty.xml new file mode 100644 index 000000000..614aa4936 --- /dev/null +++ b/java/res/xml/azerty.xml @@ -0,0 +1,114 @@ +<?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/android" + android:keyWidth="10%p" + android:horizontalGap="0px" + android:verticalGap="0px" + android:keyHeight="@dimen/key_height" + > + + <Row> + <Key android:codes="97" android:keyLabel="a" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_a" + android:keyEdgeFlags="left"/> + <Key android:codes="122" android:keyLabel="z"/> + <Key android:codes="101" android:keyLabel="e" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_e" + /> + <Key android:codes="114" android:keyLabel="r"/> + <Key android:codes="116" android:keyLabel="t"/> + <Key android:codes="121" android:keyLabel="y" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_y" + /> + <Key android:codes="117" android:keyLabel="u" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_u" + /> + <Key android:codes="105" android:keyLabel="i" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_i" + /> + <Key android:codes="111" android:keyLabel="o" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_o" + /> + <Key android:codes="112" android:keyLabel="p" android:keyEdgeFlags="right"/> + </Row> + + <Row> + <Key android:codes="113" android:keyLabel="q" android:keyEdgeFlags="left"/> + <Key android:codes="115" android:keyLabel="s" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_s" + /> + <Key android:codes="100" android:keyLabel="d"/> + <Key android:codes="102" android:keyLabel="f"/> + <Key android:codes="103" android:keyLabel="g"/> + <Key android:codes="104" android:keyLabel="h"/> + <Key android:codes="106" android:keyLabel="j"/> + <Key android:codes="107" android:keyLabel="k"/> + <Key android:codes="108" android:keyLabel="l"/> + <Key android:codes="109" android:keyLabel="m" android:keyEdgeFlags="right"/> + </Row> + + <Row> + <Key android:codes="-1" android:keyIcon="@drawable/sym_keyboard_shift" + android:keyWidth="15%p" android:isModifier="true" + android:iconPreview="@drawable/sym_keyboard_feedback_shift" + android:isSticky="true" android:keyEdgeFlags="left"/> + <Key android:codes="119" android:keyLabel="w"/> + <Key android:codes="120" android:keyLabel="x"/> + <Key android:codes="99" android:keyLabel="c" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_c" + /> + <Key android:codes="118" android:keyLabel="v"/> + <Key android:codes="98" android:keyLabel="b"/> + <Key android:codes="110" android:keyLabel="n" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_n" + /> + <Key android:codes="233,224,232,234" android:keyLabel="é"/> + <Key android:codes="-5" android:keyIcon="@drawable/sym_keyboard_delete" + android:keyWidth="15%p" android:keyEdgeFlags="right" + android:iconPreview="@drawable/sym_keyboard_feedback_delete" + android:isRepeatable="true"/> + </Row> + + <Row android:rowEdgeFlags="bottom"> + <Key android:codes="-3" android:keyIcon="@drawable/sym_keyboard_done" + android:iconPreview="@drawable/sym_keyboard_feedback_done" + android:keyWidth="20%p" android:keyEdgeFlags="left"/> + <Key android:codes="-2" android:keyLabel="123" android:keyWidth="15%p"/> + <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" + android:iconPreview="@drawable/sym_keyboard_feedback_space" + android:keyWidth="30%p" android:isRepeatable="true"/> + <Key android:codes="46,44" android:keyLabel=". ," + android:popupKeyboard="@xml/popup_punctuation" android:keyWidth="15%p"/> + <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return" + android:iconPreview="@drawable/sym_keyboard_feedback_return" + android:keyWidth="20%p" android:keyEdgeFlags="right"/> + </Row> +</Keyboard> +
\ No newline at end of file diff --git a/java/res/xml/kbd_alpha.xml b/java/res/xml/kbd_alpha.xml new file mode 100644 index 000000000..4e8af3399 --- /dev/null +++ b/java/res/xml/kbd_alpha.xml @@ -0,0 +1,106 @@ +<?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/android" + android:keyWidth="10%p" + android:horizontalGap="0px" + android:verticalGap="0px" + android:keyHeight="@dimen/key_height" + > + + <Row> + <Key android:keyLabel="a" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_a" + android:keyEdgeFlags="left" /> + <Key android:keyLabel="b" /> + <Key android:keyLabel="c" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_c" /> + <Key android:keyLabel="d" /> + <Key android:keyLabel="e" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_e" /> + <Key android:keyLabel="f" /> + <Key android:keyLabel="g" /> + <Key android:keyLabel="h" /> + <Key android:keyLabel="i" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_i" /> + <Key android:keyLabel="j" android:keyEdgeFlags="right" /> + </Row> + <Row> + <Key android:keyLabel="k" android:keyEdgeFlags="left" /> + <Key android:keyLabel="l" /> + <Key android:keyLabel="m" /> + <Key android:keyLabel="n" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_n" /> + <Key android:keyLabel="o" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_o" /> + <Key android:keyLabel="p" /> + <Key android:keyLabel="q" /> + <Key android:keyLabel="r" /> + <Key android:keyLabel="s" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_s" /> + <Key android:keyLabel="t" android:keyEdgeFlags="right" /> + </Row> + + <Row> + <Key android:codes="-1" android:keyIcon="@drawable/sym_keyboard_shift" + android:keyWidth="15%p" android:isModifier="true" + android:iconPreview="@drawable/sym_keyboard_feedback_shift" + android:isSticky="true" android:keyEdgeFlags="left"/> + <Key android:keyLabel="u" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_u" /> + <Key android:keyLabel="v"/> + <Key android:keyLabel="w"/> + <Key android:keyLabel="x"/> + <Key android:keyLabel="y" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_y" + /> + <Key android:keyLabel="z"/> + <Key android:keyLabel=","/> + <Key android:codes="-5" android:keyIcon="@drawable/sym_keyboard_delete" + android:keyWidth="15%p" android:keyEdgeFlags="right" + android:iconPreview="@drawable/sym_keyboard_feedback_delete" + android:isRepeatable="true"/> + </Row> + + <Row android:rowEdgeFlags="bottom"> + <Key android:codes="-3" android:keyIcon="@drawable/sym_keyboard_done" + android:iconPreview="@drawable/sym_keyboard_feedback_done" + android:keyWidth="20%p" android:keyEdgeFlags="left"/> + <Key android:codes="-2" android:keyLabel="123" android:keyWidth="15%p"/> + <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" + android:iconPreview="@drawable/sym_keyboard_feedback_space" + android:keyWidth="30%p" android:isRepeatable="true"/> + <Key android:codes="46" android:keyLabel="." + android:popupKeyboard="@xml/popup_punctuation" + android:keyWidth="15%p"/> + <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return" + android:iconPreview="@drawable/sym_keyboard_feedback_return" + android:keyWidth="20%p" android:keyEdgeFlags="right"/> + </Row> +</Keyboard>
\ No newline at end of file diff --git a/java/res/xml/kbd_extension.xml b/java/res/xml/kbd_extension.xml new file mode 100755 index 000000000..c64f666d0 --- /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. +*/ +--> + +<Keyboard xmlns:android="http://schemas.android.com/apk/res/android" + android:keyWidth="10%p" + android:horizontalGap="0px" + android:verticalGap="0px" + android:keyHeight="@dimen/key_height" + > + + <Row android:rowEdgeFlags="top"> + <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 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_phone.xml b/java/res/xml/kbd_phone.xml new file mode 100755 index 000000000..d2bcdac52 --- /dev/null +++ b/java/res/xml/kbd_phone.xml @@ -0,0 +1,67 @@ +<?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/android" + android:keyWidth="26.67%p" + android:horizontalGap="0px" + android:verticalGap="0px" + android:keyHeight="@dimen/key_height" + > + + <Row> + <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: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: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="-5" android:keyIcon="@drawable/sym_keyboard_delete" + android:iconPreview="@drawable/sym_keyboard_feedback_delete" + android:keyWidth="20%p" + android:isRepeatable="true" android:keyEdgeFlags="right"/> + </Row> + + <Row android:rowEdgeFlags="bottom"> + <Key android:codes="-2" android:keyIcon="@drawable/sym_keyboard_numalt" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="_" + android:iconPreview="@drawable/sym_keyboard_feedback_numalt"/> + + <Key android:codes="48" android:keyIcon="@drawable/sym_keyboard_num0"/> + + <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" + android:iconPreview="@drawable/sym_keyboard_feedback_space" + android:isRepeatable="true"/> + <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return" + android:keyWidth="20%p" + android:keyEdgeFlags="right"/> + </Row> + +</Keyboard>
\ No newline at end of file diff --git a/java/res/xml/kbd_phone_symbols.xml b/java/res/xml/kbd_phone_symbols.xml new file mode 100755 index 000000000..9604664fa --- /dev/null +++ b/java/res/xml/kbd_phone_symbols.xml @@ -0,0 +1,70 @@ +<?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/android" + android:keyWidth="26.67%p" + android:horizontalGap="0px" + android:verticalGap="0px" + android:keyHeight="@dimen/key_height" + > + + <Row> + <Key android:keyLabel="(" android:keyEdgeFlags="left"/> + <Key android:keyLabel="/"/> + <Key android:keyLabel=")"/> + <Key android:keyLabel="-" android:keyWidth="20%p" 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: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="-5" android:keyIcon="@drawable/sym_keyboard_delete" + android:iconPreview="@drawable/sym_keyboard_feedback_delete" + android:keyWidth="20%p" + android:isRepeatable="true" android:keyEdgeFlags="right"/> + </Row> + + <Row android:rowEdgeFlags="bottom"> + <Key android:codes="-2" android:keyLabel="@string/label_phone_key" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="_" + android:keyEdgeFlags="left"/> + <Key android:keyLabel="+"/> + <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" + android:iconPreview="@drawable/sym_keyboard_feedback_space" + android:isRepeatable="true"/> + <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return" + android:keyWidth="20%p" + android:keyEdgeFlags="right"/> + </Row> + +</Keyboard>
\ No newline at end of file diff --git a/java/res/xml/kbd_popup_template.xml b/java/res/xml/kbd_popup_template.xml new file mode 100644 index 000000000..aca46930f --- /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/android" + android:keyWidth="10%p" + android:horizontalGap="0px" + android:verticalGap="0px" + android:keyHeight="@dimen/key_height" + > +</Keyboard> diff --git a/java/res/xml/kbd_qwerty.xml b/java/res/xml/kbd_qwerty.xml new file mode 100755 index 000000000..1a9ea5c31 --- /dev/null +++ b/java/res/xml/kbd_qwerty.xml @@ -0,0 +1,208 @@ +<?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/android" + android:keyWidth="10%p" + android:horizontalGap="0px" + android:verticalGap="0px" + android:keyHeight="@dimen/key_height" + > + + <Row> + <Key android:codes="113" android:keyLabel="q" android:keyEdgeFlags="left"/> + <Key android:codes="119" android:keyLabel="w"/> + <Key android:codes="101" android:keyLabel="e" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_e" + /> + <Key android:codes="114" android:keyLabel="r" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_r"/> + <Key android:codes="116" android:keyLabel="t" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_t"/> + <Key android:codes="121" android:keyLabel="y" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_y" + /> + <Key android:codes="117" android:keyLabel="u" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_u" + /> + <Key android:codes="105" android:keyLabel="i" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_i" + /> + <Key android:codes="111" android:keyLabel="o" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_o" + /> + <Key android:codes="112" android:keyLabel="p" android:keyEdgeFlags="right"/> + </Row> + + <Row> + <Key android:codes="97" android:keyLabel="a" android:horizontalGap="5%p" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_a" + android:keyEdgeFlags="left"/> + <Key android:codes="115" android:keyLabel="s" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_s" + /> + <Key android:codes="100" android:keyLabel="d" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_d"/> + <Key android:codes="102" android:keyLabel="f"/> + <Key android:codes="103" android:keyLabel="g" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_g" + /> + <Key android:codes="104" android:keyLabel="h"/> + <Key android:codes="106" android:keyLabel="j"/> + <Key android:codes="107" android:keyLabel="k"/> + <Key android:codes="108" android:keyLabel="l" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_l" + android:keyEdgeFlags="right"/> + </Row> + + <Row> + <Key android:codes="-1" android:keyIcon="@drawable/sym_keyboard_shift" + android:keyWidth="15%p" android:isModifier="true" + android:iconPreview="@drawable/sym_keyboard_feedback_shift" + android:isSticky="true" android:keyEdgeFlags="left"/> + <Key android:codes="122" android:keyLabel="z" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_z"/> + <Key android:codes="120" android:keyLabel="x"/> + <Key android:codes="99" android:keyLabel="c" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_c" + /> + <Key android:codes="118" android:keyLabel="v"/> + <Key android:codes="98" android:keyLabel="b"/> + <Key android:codes="110" android:keyLabel="n" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="@string/alternates_for_n" + /> + <Key android:codes="109" android:keyLabel="m"/> + <Key android:codes="-5" android:keyIcon="@drawable/sym_keyboard_delete" + android:keyWidth="15%p" android:keyEdgeFlags="right" + android:iconPreview="@drawable/sym_keyboard_feedback_delete" + android:isRepeatable="true"/> + </Row> + + <Row android:keyboardMode="@+id/mode_normal" android:rowEdgeFlags="bottom"> + <Key android:codes="-2" android:keyLabel="@string/label_symbol_key" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="_" + android:keyWidth="20%p" android:keyEdgeFlags="left"/> + <Key android:codes="@integer/key_f1" android:keyIcon="@drawable/sym_keyboard_mic" + android:iconPreview="@drawable/sym_keyboard_feedback_mic" + android:keyWidth="10%p"/> + <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" + android:iconPreview="@drawable/sym_keyboard_feedback_space" + android:keyWidth="40%p" android:isRepeatable="true"/> + <Key android:codes="46" android:keyLabel="." android:popupKeyboard="@xml/popup_punctuation" + android:keyWidth="10%p"/> + <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return" + android:iconPreview="@drawable/sym_keyboard_feedback_return" + android:keyWidth="20%p" android:keyEdgeFlags="right"/> + </Row> + + <Row android:keyboardMode="@+id/mode_url" android:rowEdgeFlags="bottom"> + <Key android:codes="-2" android:keyLabel="@string/label_symbol_key" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="_" + android:keyWidth="20%p" android:keyEdgeFlags="left"/> + <Key android:keyLabel="/" android:keyWidth="10%p"/> + <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" + android:iconPreview="@drawable/sym_keyboard_feedback_space" + android:keyWidth="20%p" android:isRepeatable="true"/> + <Key android:keyLabel="@string/popular_domain_0" + android:keyOutputText="@string/popular_domain_0" + android:popupKeyboard="@xml/popup_domains" + android:keyWidth="20%p"/> + <Key android:keyLabel="." android:popupKeyboard="@xml/popup_punctuation" + android:keyWidth="10%p"/> + <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return" + android:iconPreview="@drawable/sym_keyboard_feedback_return" + android:keyWidth="20%p" android:keyEdgeFlags="right"/> + </Row> + + <Row android:keyboardMode="@+id/mode_email" android:rowEdgeFlags="bottom"> + <Key android:codes="-2" android:keyLabel="@string/label_symbol_key" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="_" + android:keyWidth="20%p" android:keyEdgeFlags="left"/> + <Key android:keyLabel="\@"/> + <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" + android:iconPreview="@drawable/sym_keyboard_feedback_space" + android:keyWidth="20%p" android:isRepeatable="true"/> + <Key android:keyLabel="@string/popular_domain_0" + android:keyOutputText="@string/popular_domain_0" + android:popupKeyboard="@xml/popup_domains" + android:keyWidth="20%p"/> + <Key android:keyLabel="." android:popupKeyboard="@xml/popup_punctuation"/> + <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return" + android:iconPreview="@drawable/sym_keyboard_feedback_return" + android:keyWidth="20%p" android:keyEdgeFlags="right"/> + </Row> + + <Row android:keyboardMode="@+id/mode_im" android:rowEdgeFlags="bottom"> + <Key android:codes="-2" android:keyLabel="@string/label_symbol_key" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="_" + android:keyWidth="20%p" android:keyEdgeFlags="left"/> + <Key android:codes="@integer/key_f1" android:keyIcon="@drawable/sym_keyboard_mic" + android:iconPreview="@drawable/sym_keyboard_feedback_mic" + android:keyWidth="10%p"/> + <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" + android:iconPreview="@drawable/sym_keyboard_feedback_space" + android:keyWidth="40%p" android:isRepeatable="true"/> + <Key android:codes="46" android:keyLabel="." android:popupKeyboard="@xml/popup_punctuation" + android:keyWidth="10%p"/> + <Key android:keyLabel=":-)" android:keyOutputText=":-) " + android:popupKeyboard="@xml/popup_smileys" + android:keyWidth="20%p" android:keyEdgeFlags="right"/> + </Row> + + <Row android:keyboardMode="@+id/mode_webentry" android:rowEdgeFlags="bottom"> + <Key android:codes="-2" android:keyLabel="@string/label_symbol_key" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="_" + android:keyWidth="20%p" android:keyEdgeFlags="left"/> + <Key android:codes="@integer/key_f1" android:keyIcon="@drawable/sym_keyboard_mic" + android:iconPreview="@drawable/sym_keyboard_feedback_mic" + android:keyWidth="10%p"/> + <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" + android:iconPreview="@drawable/sym_keyboard_feedback_space" + android:keyWidth="20%p" android:isRepeatable="true"/> + <Key android:codes="9" android:keyIcon="@drawable/sym_keyboard_tab" + android:iconPreview="@drawable/sym_keyboard_feedback_tab" + android:keyWidth="20%p"/> + <Key android:keyLabel="." android:popupKeyboard="@xml/popup_punctuation"/> + <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return" + android:iconPreview="@drawable/sym_keyboard_feedback_return" + android:keyWidth="20%p" android:keyEdgeFlags="right"/> + </Row> + +</Keyboard> + diff --git a/java/res/xml/kbd_symbols.xml b/java/res/xml/kbd_symbols.xml new file mode 100755 index 000000000..ab5792fd1 --- /dev/null +++ b/java/res/xml/kbd_symbols.xml @@ -0,0 +1,141 @@ +<?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/android" + android:keyWidth="10%p" + android:horizontalGap="0px" + android:verticalGap="0px" + android:keyHeight="@dimen/key_height" + > + + <Row> + <Key android:codes="49" android:keyLabel="1" android:keyEdgeFlags="left" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="¹½⅓¼⅛" + /> + <Key android:codes="50" android:keyLabel="2" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="²⅔" + /> + <Key android:codes="51" android:keyLabel="3" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="³¾⅜" + /> + <Key android:codes="52" android:keyLabel="4" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="⁴" + /> + <Key android:codes="53" android:keyLabel="5" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="⅝" + /> + <Key android:codes="54" android:keyLabel="6"/> + <Key android:codes="55" android:keyLabel="7" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="⅞" + /> + <Key android:codes="56" android:keyLabel="8"/> + <Key android:codes="57" android:keyLabel="9"/> + <Key android:codes="48" android:keyLabel="0" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="ⁿ∅" + android:keyEdgeFlags="right"/> + </Row> + + <Row> + <Key android:codes="64" android:keyLabel="\@" android:keyEdgeFlags="left"/> + <Key android:codes="35" android:keyLabel="\#"/> + <Key android:codes="36" android:keyLabel="$" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="¢£€¥₣₤₱" + /> + <Key android:codes="37" android:keyLabel="%" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="‰" + /> + <Key android:codes="38" android:keyLabel="&"/> + <Key android:codes="42" android:keyLabel="*" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="†‡★" + /> + <Key android:codes="45" android:keyLabel="-" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="_–—" + /> + <Key android:keyLabel="+" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="±" + /> + <Key android:codes="40" android:keyLabel="(" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="[{<" + /> + <Key android:codes="41" android:keyLabel=")" android:keyEdgeFlags="right" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="]}>" + /> + </Row> + + <Row> + <Key android:codes="-1" android:keyLabel="@string/label_alt_key" + android:keyWidth="15%p" android:isModifier="true" + android:isSticky="true" android:keyEdgeFlags="left"/> + <Key android:codes="33" android:keyLabel="!" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="¡" + /> + <Key android:codes="34" android:keyLabel=""" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="“”«»˝" + /> + <Key android:codes="39" android:keyLabel="\'" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="‘’" + /> + <Key android:codes="58" android:keyLabel=":"/> + <Key android:codes="59" android:keyLabel=";"/> + <Key android:codes="47" android:keyLabel="/" /> + <Key android:codes="63" android:keyLabel="\?" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="¿" + /> + <Key android:codes="-5" android:keyIcon="@drawable/sym_keyboard_delete" android:keyWidth="15%p" android:keyEdgeFlags="right" + android:iconPreview="@drawable/sym_keyboard_feedback_delete" + android:isRepeatable="true"/> + </Row> + + <Row android:rowEdgeFlags="bottom"> + <Key android:codes="-2" android:keyLabel="@string/label_alpha_key" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="_" + android:keyWidth="20%p" android:keyEdgeFlags="left"/> + <Key android:codes="@integer/key_f1" android:keyWidth="10%p"/> + <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" + android:keyWidth="40%p" + android:iconPreview="@drawable/sym_keyboard_feedback_space" + android:isRepeatable="true"/> + <Key android:codes="46" android:keyLabel="." + android:popupKeyboard="@xml/popup_punctuation" + android:keyWidth="10%p"/> + <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return" android:keyWidth="20%p" android:keyEdgeFlags="right" + android:iconPreview="@drawable/sym_keyboard_feedback_return" + /> + </Row> +</Keyboard> diff --git a/java/res/xml/kbd_symbols_shift.xml b/java/res/xml/kbd_symbols_shift.xml new file mode 100755 index 000000000..09b5c3f9d --- /dev/null +++ b/java/res/xml/kbd_symbols_shift.xml @@ -0,0 +1,104 @@ +<?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/android" + android:keyWidth="10%p" + android:horizontalGap="0px" + android:verticalGap="0px" + android:keyHeight="@dimen/key_height" + > + + <Row> + <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="π"/> + <Key android:keyLabel="÷"/> + <Key android:keyLabel="×"/> + <Key android:keyLabel="{"/> + <Key android:keyLabel="}" android:keyEdgeFlags="right"/> + </Row> + + <Row> + <Key android:codes="9" 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="-1" 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="<" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="≤«‹" + /> + <Key android:keyLabel=">" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="≥»›" + /> + <Key android:codes="-5" android:keyIcon="@drawable/sym_keyboard_delete" android:keyWidth="15%p" android:keyEdgeFlags="right" + android:iconPreview="@drawable/sym_keyboard_feedback_delete" + android:isRepeatable="true"/> + </Row> + + <Row android:rowEdgeFlags="bottom"> + <Key android:codes="-2" android:keyLabel="@string/label_alpha_key" android:keyWidth="20%p" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="_" + android:keyEdgeFlags="left"/> + <Key android:keyLabel="„" android:keyWidth="10%p" /> + <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" + android:keyWidth="40%p" + android:iconPreview="@drawable/sym_keyboard_feedback_space" + android:isRepeatable="true"/> + <Key android:keyLabel="…" android:keyWidth="10%p" /> + <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return" + android:keyWidth="20%p" android:keyEdgeFlags="right" + android:iconPreview="@drawable/sym_keyboard_feedback_return" + /> + </Row> +</Keyboard> diff --git a/java/res/xml/language_prefs.xml b/java/res/xml/language_prefs.xml new file mode 100644 index 000000000..b7a4c07db --- /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 000000000..195691b7b --- /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="com.android.inputmethod.latin.LatinIMESettings" + android:isDefault="true" +/> diff --git a/java/res/xml/popup_domains.xml b/java/res/xml/popup_domains.xml new file mode 100644 index 000000000..b733fe24f --- /dev/null +++ b/java/res/xml/popup_domains.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. +*/ +--> + +<Keyboard xmlns:android="http://schemas.android.com/apk/res/android" + android:keyWidth="15%p" + android:horizontalGap="0px" + android:verticalGap="0px" + android:keyHeight="@dimen/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_punctuation.xml b/java/res/xml/popup_punctuation.xml new file mode 100644 index 000000000..a29fb520d --- /dev/null +++ b/java/res/xml/popup_punctuation.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/android" + android:keyWidth="10%p" + android:horizontalGap="0px" + android:verticalGap="0px" + android:keyHeight="@dimen/key_height" + > + + <Row android:rowEdgeFlags="top"> + <Key android:keyLabel=":" android:keyEdgeFlags="left" /> + <Key android:keyLabel="/" /> + <Key android:keyLabel="&" /> + <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="\'" /> + <Key android:keyLabel=""" /> + <Key android:keyLabel="\?" /> + <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 000000000..5663fefc8 --- /dev/null +++ b/java/res/xml/popup_smileys.xml @@ -0,0 +1,49 @@ +<?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/android" + android:keyWidth="15%p" + android:horizontalGap="0px" + android:verticalGap="0px" + android:keyHeight="@dimen/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 000000000..535b63f3b --- /dev/null +++ b/java/res/xml/prefs.xml @@ -0,0 +1,86 @@ +<?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:title="@string/english_ime_settings" + android:key="english_ime_settings"> + + <CheckBoxPreference + android:key="vibrate_on" + android:title="@string/vibrate_on_keypress" + android:persistent="true" + /> + + <CheckBoxPreference + android:key="sound_on" + android:title="@string/sound_on_keypress" + android:persistent="true" + /> + + <CheckBoxPreference + android:key="auto_cap" + android:title="@string/auto_cap" + android:persistent="true" + android:defaultValue="true" + /> + + <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="com.android.inputmethod.latin.INPUT_LANGUAGE_SELECTION"/> + </PreferenceScreen> + + <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="true" + /> + + <CheckBoxPreference + android:key="show_suggestions" + android:title="@string/show_suggestions" + android:summary="@string/show_suggestions_summary" + android:persistent="true" + android:defaultValue="true" + /> + + <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" + /> + + </PreferenceCategory> +</PreferenceScreen> diff --git a/java/src/com/android/inputmethod/latin/AutoDictionary.java b/java/src/com/android/inputmethod/latin/AutoDictionary.java new file mode 100644 index 000000000..3d76dc301 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/AutoDictionary.java @@ -0,0 +1,217 @@ +/* + * 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 java.util.HashMap; + +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.provider.BaseColumns; +import android.provider.UserDictionary.Words; +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 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 DatabaseHelper mOpenHelper; + + public AutoDictionary(Context context, LatinIME ime, String locale) { + super(context); + mIme = ime; + mLocale = locale; + mOpenHelper = 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; + } + + public void close() { + mOpenHelper.close(); + } + + private void loadDictionary() { + // Load the words that correspond to the current input locale + Cursor cursor = query(COLUMN_LOCALE + "=?", new String[] { mLocale }); + 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(); + } + } + 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); + // Delete the word (for input locale) from the auto dictionary db, as it + // is now in the user dictionary provider. + delete(COLUMN_WORD + "=? AND " + COLUMN_LOCALE + "=?", + new String[] { word, mLocale }); + } else { + update(word, freq, mLocale); + } + } + + /** + * 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 = mOpenHelper.getReadableDatabase(); + Cursor c = qb.query(db, null, selection, selectionArgs, null, null, + DEFAULT_SORT_ORDER); + return c; + } + + private boolean insert(ContentValues values) { + SQLiteDatabase db = mOpenHelper.getWritableDatabase(); + long rowId = db.insert(AUTODICT_TABLE_NAME, Words.WORD, values); + if (rowId > 0) { + return true; + } + return false; + } + + private int delete(String where, String[] whereArgs) { + SQLiteDatabase db = mOpenHelper.getWritableDatabase(); + int count = db.delete(AUTODICT_TABLE_NAME, where, whereArgs); + return count; + } + + private int update(String word, int frequency, String locale) { + SQLiteDatabase db = mOpenHelper.getWritableDatabase(); + long count = db.delete(AUTODICT_TABLE_NAME, COLUMN_WORD + "=? AND " + COLUMN_LOCALE + "=?", + new String[] { word, locale }); + count = db.insert(AUTODICT_TABLE_NAME, null, + getContentValues(word, frequency, locale)); + return (int) count; + } + + 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/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java new file mode 100644 index 000000000..43f4c4cb6 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java @@ -0,0 +1,151 @@ +/* + * 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.latin; + +import java.util.Arrays; + +import android.content.Context; +import android.content.res.AssetManager; +import android.util.Log; + +/** + * Implements a static, compacted, binary dictionary of standard words. + */ +public class BinaryDictionary extends Dictionary { + + public static final int MAX_WORD_LENGTH = 48; + private static final int MAX_ALTERNATIVES = 16; + private static final int MAX_WORDS = 16; + + private static final int TYPED_LETTER_MULTIPLIER = 2; + private static final boolean ENABLE_MISSED_CHARACTERS = true; + + private int mNativeDict; + private int mDictLength; // This value is set from native code, don't change the name!!!! + private int[] mInputCodes = new int[MAX_WORD_LENGTH * MAX_ALTERNATIVES]; + private char[] mOutputChars = new char[MAX_WORD_LENGTH * MAX_WORDS]; + private int[] mFrequencies = new int[MAX_WORDS]; + + static { + try { + System.loadLibrary("jni_latinime"); + } catch (UnsatisfiedLinkError ule) { + Log.e("BinaryDictionary", "Could not load native library jni_latinime"); + } + } + + /** + * 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) { + if (resId != 0) { + loadDictionary(context, resId); + } + } + + private native int openNative(AssetManager am, String resourcePath, int typedLetterMultiplier, + int fullWordMultiplier); + 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 final void loadDictionary(Context context, int resId) { + AssetManager am = context.getResources().getAssets(); + String assetName = context.getResources().getString(resId); + mNativeDict = openNative(am, assetName, TYPED_LETTER_MULTIPLIER, FULL_WORD_FREQ_MULTIPLIER); + } + + @Override + public void getWords(final WordComposer codes, final WordCallback callback, + int[] nextLettersFrequencies) { + final int codesSize = codes.size(); + // Wont 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); + + 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]); + } + } + } + + @Override + public boolean isValidWord(CharSequence word) { + if (word == null) 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/com/android/inputmethod/latin/CandidateView.java b/java/src/com/android/inputmethod/latin/CandidateView.java new file mode 100755 index 000000000..0c0373b3b --- /dev/null +++ b/java/src/com/android/inputmethod/latin/CandidateView.java @@ -0,0 +1,533 @@ +/* + * 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.latin; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Rect; +import android.graphics.Typeface; +import android.graphics.Paint.Align; +import android.graphics.drawable.Drawable; +import android.os.Handler; +import android.os.Message; +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; + +public class CandidateView extends View { + + private static final int OUT_OF_BOUNDS = -1; + private static final List<CharSequence> EMPTY_LIST = new ArrayList<CharSequence>(); + + private LatinIME mService; + private List<CharSequence> mSuggestions = EMPTY_LIST; + private boolean mShowingCompletions; + private CharSequence mSelectedString; + private int mSelectedIndex; + private int mTouchX = OUT_OF_BOUNDS; + private Drawable mSelectionHighlight; + private boolean mTypedWordValid; + + private boolean mHaveMinimalSuggestion; + + private Rect mBgPadding; + + private TextView mPreviewText; + private PopupWindow mPreviewPopup; + private int mCurrentWordIndex; + private Drawable mDivider; + + private static final int MAX_SUGGESTIONS = 32; + private static final int SCROLL_PIXELS = 20; + + private static final int MSG_REMOVE_PREVIEW = 1; + private static final int MSG_REMOVE_THROUGH_PREVIEW = 2; + + private int[] mWordWidth = new int[MAX_SUGGESTIONS]; + private int[] mWordX = new int[MAX_SUGGESTIONS]; + private int mPopupPreviewX; + private int mPopupPreviewY; + + private static final int X_GAP = 10; + + private int mColorNormal; + private int mColorRecommended; + private int mColorOther; + private Paint mPaint; + private int mDescent; + private boolean mScrolled; + private boolean mShowingAddToDictionary; + private CharSequence mWordToAddToDictionary; + private CharSequence mAddToDictionaryHint; + + private int mTargetScrollX; + + private int mMinTouchableWidth; + + private int mTotalWidth; + + private GestureDetector mGestureDetector; + + Handler mHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_REMOVE_PREVIEW: + mPreviewText.setVisibility(GONE); + break; + case MSG_REMOVE_THROUGH_PREVIEW: + mPreviewText.setVisibility(GONE); + if (mTouchX != OUT_OF_BOUNDS) { + removeHighlight(); + } + break; + } + + } + }; + + /** + * 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); + 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()); + mPaint.setStrokeWidth(0); + mPaint.setTextAlign(Align.CENTER); + mDescent = (int) mPaint.descent(); + // 80 pixels for a 160dpi device would mean half an inch + mMinTouchableWidth = (int) (getResources().getDisplayMetrics().density * 50); + + mGestureDetector = new GestureDetector(new GestureDetector.SimpleOnGestureListener() { + @Override + public void onLongPress(MotionEvent me) { + if (mSuggestions.size() > 0) { + if (me.getX() + getScrollX() < mWordWidth[0] && getScrollX() < 10) { + longPressFirstWord(); + } + } + } + + @Override + public boolean onScroll(MotionEvent e1, MotionEvent e2, + float distanceX, float distanceY) { + 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; + } + }); + setHorizontalFadingEdgeEnabled(true); + setWillNotDraw(false); + setHorizontalScrollBarEnabled(false); + setVerticalScrollBarEnabled(false); + scrollTo(0, getScrollY()); + } + + /** + * 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; + if (mSuggestions == null) return; + + 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()); + } + int x = 0; + final int count = mSuggestions.size(); + final int width = getWidth(); + 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; + + for (int i = 0; i < count; i++) { + CharSequence suggestion = mSuggestions.get(i); + if (suggestion == null) continue; + paint.setColor(mColorNormal); + if (mHaveMinimalSuggestion + && ((i == 1 && !typedWordValid) || (i == 0 && typedWordValid))) { + paint.setTypeface(Typeface.DEFAULT_BOLD); + paint.setColor(mColorRecommended); + } else if (i != 0) { + paint.setColor(mColorOther); + } + final int wordWidth; + if (mWordWidth[i] != 0) { + wordWidth = mWordWidth[i]; + } else { + float textWidth = paint.measureText(suggestion, 0, suggestion.length()); + wordWidth = Math.max(mMinTouchableWidth, (int) textWidth + X_GAP * 2); + mWordWidth[i] = wordWidth; + } + + mWordX[i] = x; + + if (touchX + scrollX >= x && touchX + scrollX < x + wordWidth && !scrolled && + touchX != OUT_OF_BOUNDS) { + if (canvas != null && !mShowingAddToDictionary) { + canvas.translate(x, 0); + mSelectionHighlight.setBounds(0, bgPadding.top, wordWidth, height); + mSelectionHighlight.draw(canvas); + canvas.translate(-x, 0); + showPreview(i, null); + } + mSelectedString = suggestion; + mSelectedIndex = i; + } + + if (canvas != null) { + canvas.drawText(suggestion, 0, suggestion.length(), 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; + } + 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) { + mSuggestions = new ArrayList<CharSequence>(suggestions); + } + mShowingCompletions = completions; + mTypedWordValid = typedWordValid; + scrollTo(0, getScrollY()); + mTargetScrollX = 0; + mHaveMinimalSuggestion = haveMinimalSuggestion; + // Compute the total width + onDraw(null); + invalidate(); + requestLayout(); + } + + public void showAddToDictionaryHint(CharSequence word) { + mWordToAddToDictionary = word; + ArrayList<CharSequence> suggestions = new ArrayList<CharSequence>(); + suggestions.add(word); + suggestions.add(mAddToDictionaryHint); + setSuggestions(suggestions, false, false, false); + mShowingAddToDictionary = true; + } + + public void scrollPrev() { + int i = 0; + final int count = mSuggestions.size(); + int firstItem = 0; // Actually just before the first item, if at the boundary + while (i < count) { + if (mWordX[i] < getScrollX() + && mWordX[i] + mWordWidth[i] >= getScrollX() - 1) { + firstItem = i; + break; + } + i++; + } + int leftEdge = mWordX[firstItem] + mWordWidth[firstItem] - getWidth(); + if (leftEdge < 0) leftEdge = 0; + updateScrollPosition(leftEdge); + } + + public void scrollNext() { + int i = 0; + int scrollX = getScrollX(); + int targetX = scrollX; + final int count = mSuggestions.size(); + int rightEdge = scrollX + getWidth(); + while (i < count) { + if (mWordX[i] <= rightEdge && + mWordX[i] + mWordWidth[i] >= rightEdge) { + targetX = Math.min(mWordX[i], mTotalWidth - getWidth()); + break; + } + i++; + } + updateScrollPosition(targetX); + } + + private void updateScrollPosition(int targetX) { + if (targetX != getScrollX()) { + // TODO: Animate + mTargetScrollX = targetX; + requestLayout(); + invalidate(); + mScrolled = true; + } + } + + public void clear() { + mSuggestions = EMPTY_LIST; + mTouchX = OUT_OF_BOUNDS; + mSelectedString = null; + mSelectedIndex = -1; + mShowingAddToDictionary = false; + invalidate(); + Arrays.fill(mWordWidth, 0); + Arrays.fill(mWordX, 0); + if (mPreviewPopup.isShowing()) { + mPreviewPopup.dismiss(); + } + } + + @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: + mScrolled = false; + invalidate(); + break; + case MotionEvent.ACTION_MOVE: + if (y <= 0) { + // Fling up!? + if (mSelectedString != null) { + if (!mShowingCompletions) { + TextEntryState.acceptedSuggestion(mSuggestions.get(0), + mSelectedString); + } + mService.pickSuggestionManually(mSelectedIndex, mSelectedString); + mSelectedString = null; + mSelectedIndex = -1; + } + } + invalidate(); + break; + case MotionEvent.ACTION_UP: + if (!mScrolled) { + if (mSelectedString != null) { + if (mShowingAddToDictionary) { + longPressFirstWord(); + clear(); + } else { + if (!mShowingCompletions) { + TextEntryState.acceptedSuggestion(mSuggestions.get(0), + mSelectedString); + } + mService.pickSuggestionManually(mSelectedIndex, mSelectedString); + } + } + } + mSelectedString = null; + mSelectedIndex = -1; + removeHighlight(); + hidePreview(); + requestLayout(); + break; + } + return true; + } + + /** + * For flick through from keyboard, call this method with the x coordinate of the flick + * gesture. + * @param x + */ + public void takeSuggestionAt(float x) { + mTouchX = (int) x; + // To detect candidate + onDraw(null); + if (mSelectedString != null) { + if (!mShowingCompletions) { + TextEntryState.acceptedSuggestion(mSuggestions.get(0), mSelectedString); + } + mService.pickSuggestionManually(mSelectedIndex, mSelectedString); + } + invalidate(); + mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_REMOVE_THROUGH_PREVIEW), 200); + } + + private void hidePreview() { + mCurrentWordIndex = OUT_OF_BOUNDS; + if (mPreviewPopup.isShowing()) { + mHandler.sendMessageDelayed(mHandler + .obtainMessage(MSG_REMOVE_PREVIEW), 60); + } + } + + 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) { + 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; + mHandler.removeMessages(MSG_REMOVE_PREVIEW); + 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 removeHighlight() { + mTouchX = OUT_OF_BOUNDS; + invalidate(); + } + + 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/com/android/inputmethod/latin/CandidateViewContainer.java b/java/src/com/android/inputmethod/latin/CandidateViewContainer.java new file mode 100644 index 000000000..e13f2738c --- /dev/null +++ b/java/src/com/android/inputmethod/latin/CandidateViewContainer.java @@ -0,0 +1,83 @@ +/* + * 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.latin; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.MotionEvent; +import android.view.View; +import android.view.View.OnTouchListener; +import android.widget.LinearLayout; + +public class CandidateViewContainer extends LinearLayout implements OnTouchListener { + + private View mButtonLeft; + private View mButtonRight; + private View mButtonLeftLayout; + private View mButtonRightLayout; + private CandidateView mCandidates; + + public CandidateViewContainer(Context screen, AttributeSet attrs) { + super(screen, attrs); + } + + public void initViews() { + if (mCandidates == null) { + mButtonLeftLayout = findViewById(R.id.candidate_left_parent); + mButtonLeft = findViewById(R.id.candidate_left); + if (mButtonLeft != null) { + mButtonLeft.setOnTouchListener(this); + } + mButtonRightLayout = findViewById(R.id.candidate_right_parent); + mButtonRight = findViewById(R.id.candidate_right); + if (mButtonRight != null) { + mButtonRight.setOnTouchListener(this); + } + mCandidates = (CandidateView) findViewById(R.id.candidates); + } + } + + @Override + public void requestLayout() { + if (mCandidates != null) { + int availableWidth = mCandidates.getWidth(); + int neededWidth = mCandidates.computeHorizontalScrollRange(); + int x = mCandidates.getScrollX(); + boolean leftVisible = x > 0; + boolean rightVisible = x + availableWidth < neededWidth; + if (mButtonLeftLayout != null) { + mButtonLeftLayout.setVisibility(leftVisible ? VISIBLE : GONE); + } + if (mButtonRightLayout != null) { + mButtonRightLayout.setVisibility(rightVisible ? VISIBLE : GONE); + } + } + super.requestLayout(); + } + + public boolean onTouch(View v, MotionEvent event) { + if (event.getAction() == MotionEvent.ACTION_DOWN) { + if (v == mButtonRight) { + mCandidates.scrollNext(); + } else if (v == mButtonLeft) { + mCandidates.scrollPrev(); + } + } + return false; + } + +} diff --git a/java/src/com/android/inputmethod/latin/ContactsDictionary.java b/java/src/com/android/inputmethod/latin/ContactsDictionary.java new file mode 100644 index 000000000..f53ebf3f5 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/ContactsDictionary.java @@ -0,0 +1,176 @@ +/* + * 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 com.android.inputmethod.latin; + +import android.content.ContentResolver; +import android.content.Context; +import android.database.ContentObserver; +import android.database.Cursor; +import android.os.AsyncTask; +import android.os.SystemClock; +import android.provider.ContactsContract.Contacts; + +public class ContactsDictionary extends ExpandableDictionary { + + private static final String[] PROJECTION = { + Contacts._ID, + Contacts.DISPLAY_NAME, + }; + + private static final int INDEX_NAME = 1; + + private ContentObserver mObserver; + + private boolean mRequiresReload; + + private long mLastLoadedContacts; + + private boolean mUpdatingContacts; + + // Use this lock before touching mUpdatingContacts & mRequiresDownload + private Object mUpdatingLock = new Object(); + + public ContactsDictionary(Context context) { + super(context); + // 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) { + synchronized (mUpdatingLock) { + mRequiresReload = true; + } + } + }); + + synchronized (mUpdatingLock) { + loadDictionaryAsyncLocked(); + } + } + + public synchronized void close() { + if (mObserver != null) { + getContext().getContentResolver().unregisterContentObserver(mObserver); + mObserver = null; + } + } + + private synchronized void loadDictionaryAsyncLocked() { + long now = SystemClock.uptimeMillis(); + if (mLastLoadedContacts == 0 + || now - mLastLoadedContacts > 30 * 60 * 1000 /* 30 minutes */) { + if (!mUpdatingContacts) { + mUpdatingContacts = true; + mRequiresReload = false; + new LoadContactsTask().execute(); + } + } + } + + @Override + public synchronized void getWords(final WordComposer codes, final WordCallback callback, + int[] nextLettersFrequencies) { + synchronized (mUpdatingLock) { + // If we need to update, start off a background task + if (mRequiresReload) loadDictionaryAsyncLocked(); + // Currently updating contacts, don't return any results. + if (mUpdatingContacts) return; + } + super.getWords(codes, callback, nextLettersFrequencies); + } + + @Override + public synchronized boolean isValidWord(CharSequence word) { + synchronized (mUpdatingLock) { + // If we need to update, start off a background task + if (mRequiresReload) loadDictionaryAsyncLocked(); + if (mUpdatingContacts) return false; + } + + return super.isValidWord(word); + } + + private void addWords(Cursor cursor) { + clearDictionary(); + + final int maxWordLength = getMaxWordLength(); + if (cursor.moveToFirst()) { + while (!cursor.isAfterLast()) { + String name = cursor.getString(INDEX_NAME); + + if (name != null) { + int len = name.length(); + + // 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, 128); + } + } + } + } + + cursor.moveToNext(); + } + } + cursor.close(); + } + + private class LoadContactsTask extends AsyncTask<Void, Void, Void> { + @Override + protected Void doInBackground(Void... v) { + Cursor cursor = getContext().getContentResolver() + .query(Contacts.CONTENT_URI, PROJECTION, null, null, null); + if (cursor != null) { + addWords(cursor); + } + mLastLoadedContacts = SystemClock.uptimeMillis(); + return null; + } + + @Override + protected void onPostExecute(Void result) { + // TODO Auto-generated method stub + synchronized (mUpdatingLock) { + mUpdatingContacts = false; + } + super.onPostExecute(result); + } + + } +} diff --git a/java/src/com/android/inputmethod/latin/Dictionary.java b/java/src/com/android/inputmethod/latin/Dictionary.java new file mode 100644 index 000000000..b656d04dc --- /dev/null +++ b/java/src/com/android/inputmethod/latin/Dictionary.java @@ -0,0 +1,99 @@ +/* + * 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.latin; + +/** + * 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; + + /** + * 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 + * @return true if the word was added, false if no more words are required + */ + boolean addWord(char[] word, int wordOffset, int wordLength, int frequency); + } + + /** + * 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); + + /** + * 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/com/android/inputmethod/latin/ExpandableDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java new file mode 100644 index 000000000..006593700 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java @@ -0,0 +1,465 @@ +/* + * 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 com.android.inputmethod.latin; + +import android.content.Context; + +/** + * 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 { + private Context mContext; + private char[] mWordBuilder = new char[MAX_WORD_LENGTH]; + private int mMaxDepth; + private int mInputLength; + private int[] mNextLettersFrequencies; + + public static final int MAX_WORD_LENGTH = 32; + private static final char QUOTE = '\''; + + static class Node { + char code; + int frequency; + boolean terminal; + NodeArray children; + } + + 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; + } + } + + private NodeArray mRoots; + + private int[][] mCodes; + + ExpandableDictionary(Context context) { + mContext = context; + clearDictionary(); + mCodes = new int[MAX_WORD_LENGTH][]; + } + + Context getContext() { + return mContext; + } + + int getMaxWordLength() { + return MAX_WORD_LENGTH; + } + + public void addWord(String word, int frequency) { + addWordRec(mRoots, word, 0, frequency); + } + + private void addWordRec(NodeArray children, final String word, + final int depth, final int frequency) { + + 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; + 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); + } + + @Override + public void getWords(final WordComposer codes, final WordCallback callback, + int[] nextLettersFrequencies) { + 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) { + final int freq = getWordFrequencyRec(mRoots, word, 0, word.length()); + return freq > -1; + } + + /** + * Returns the word's frequency or -1 if not found + */ + public int getWordFrequency(CharSequence word) { + return getWordFrequencyRec(mRoots, word, 0, word.length()); + } + + /** + * Returns the word's frequency or -1 if not found + */ + private int getWordFrequencyRec(final NodeArray children, final CharSequence word, + final int offset, final int length) { + 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.frequency; + } + } else { + if (node.children != null) { + int freq = getWordFrequencyRec(node.children, word, offset + 1, length); + if (freq > -1) return freq; + } + } + } + } + return -1; + } + + /** + * 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)) { + 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); + } + } + 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 void clearDictionary() { + mRoots = new NodeArray(); + } + + 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/com/android/inputmethod/latin/Hints.java b/java/src/com/android/inputmethod/latin/Hints.java new file mode 100644 index 000000000..689c8d852 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/Hints.java @@ -0,0 +1,188 @@ +/* + * 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.latin; + +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 TAG = "Hints"; + 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()); + editor.commit(); + + 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()); + editor.commit(); + } + + 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); + editor.commit(); + return value; + } +} diff --git a/java/src/com/android/inputmethod/latin/InputLanguageSelection.java b/java/src/com/android/inputmethod/latin/InputLanguageSelection.java new file mode 100644 index 000000000..b1ddb2175 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/InputLanguageSelection.java @@ -0,0 +1,183 @@ +/* + * 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.latin; + +import java.text.Collator; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Locale; + +import android.content.SharedPreferences; +import android.content.SharedPreferences.Editor; +import android.os.Bundle; +import android.preference.CheckBoxPreference; +import android.preference.PreferenceActivity; +import android.preference.PreferenceGroup; +import android.preference.PreferenceManager; +import android.text.TextUtils; + +public class InputLanguageSelection extends PreferenceActivity { + + private String mSelectedLanguages; + private ArrayList<Loc> mAvailableLanguages = new ArrayList<Loc>(); + private static final String[] BLACKLIST_LANGUAGES = { + "ko", "ja", "zh" + }; + + private static class Loc implements Comparable { + 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); + mSelectedLanguages = sp.getString(LatinIME.PREF_SELECTED_LANGUAGES, ""); + String[] languageList = mSelectedLanguages.split(","); + mAvailableLanguages = getUniqueLocales(); + PreferenceGroup parent = getPreferenceScreen(); + for (int i = 0; i < mAvailableLanguages.size(); i++) { + CheckBoxPreference pref = new CheckBoxPreference(this); + Locale locale = mAvailableLanguages.get(i).locale; + pref.setTitle(LanguageSwitcher.toTitleCase(locale.getDisplayName(locale))); + boolean checked = isLocaleIn(locale, languageList); + pref.setChecked(checked); + parent.addPreference(pref); + } + } + + private boolean isLocaleIn(Locale locale, String[] list) { + String lang = get5Code(locale); + for (int i = 0; i < list.length; i++) { + if (lang.equalsIgnoreCase(list[i])) return true; + } + // If it matches the current locale + Locale displayLocale = getResources().getConfiguration().locale; + if (lang.equalsIgnoreCase(get5Code(displayLocale))) { + return true; + } + return false; + } + + 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); + editor.commit(); + } + + ArrayList<Loc> getUniqueLocales() { + String[] locales = getAssets().getLocales(); + Arrays.sort(locales); + ArrayList<Loc> uniqueLocales = new ArrayList<Loc>(); + + final int origSize = locales.length; + Loc[] preprocess = new Loc[origSize]; + int finalSize = 0; + for (int i = 0 ; i < origSize; i++ ) { + String s = locales[i]; + int len = s.length(); + if (len == 5) { + String language = s.substring(0, 2); + String country = s.substring(3, 5); + Locale l = new Locale(language, country); + + // Exclude languages that are not relevant to LatinIME + if (arrayContains(BLACKLIST_LANGUAGES, language)) continue; + + if (finalSize == 0) { + preprocess[finalSize++] = + new Loc(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 = LanguageSwitcher.toTitleCase( + preprocess[finalSize-1].locale.getDisplayName()); + preprocess[finalSize++] = + new Loc(LanguageSwitcher.toTitleCase(l.getDisplayName()), l); + } else { + String displayName; + if (s.equals("zz_ZZ")) { + } else { + displayName = LanguageSwitcher.toTitleCase(l.getDisplayName(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/com/android/inputmethod/latin/KeyboardSwitcher.java b/java/src/com/android/inputmethod/latin/KeyboardSwitcher.java new file mode 100644 index 000000000..438680cf8 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/KeyboardSwitcher.java @@ -0,0 +1,351 @@ +/* + * 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.latin; + +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +import android.content.Context; +import android.content.res.Configuration; +import android.content.res.Resources; +import android.inputmethodservice.InputMethodService; + +public class KeyboardSwitcher { + + 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; + + public static final int MODE_TEXT_QWERTY = 0; + public static final int MODE_TEXT_ALPHA = 1; + public static final int MODE_TEXT_COUNT = 2; + + 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; + + private static final int SYMBOLS_MODE_STATE_NONE = 0; + private static final int SYMBOLS_MODE_STATE_BEGIN = 1; + private static final int SYMBOLS_MODE_STATE_SYMBOL = 2; + + LatinKeyboardView mInputView; + private static final int[] ALPHABET_MODES = { + KEYBOARDMODE_NORMAL, + KEYBOARDMODE_URL, + KEYBOARDMODE_EMAIL, + KEYBOARDMODE_IM, + KEYBOARDMODE_WEB}; + + //LatinIME mContext; + Context mContext; + InputMethodService mInputMethodService; + + private KeyboardId mSymbolsId; + private KeyboardId mSymbolsShiftedId; + + private KeyboardId mCurrentId; + private Map<KeyboardId, LatinKeyboard> mKeyboards; + + private int mMode; /** One of the MODE_XXX values */ + private int mImeOptions; + private int mTextMode = MODE_TEXT_QWERTY; + private boolean mIsSymbols; + private boolean mHasVoice; + private boolean mVoiceOnPrimary; + private boolean mPreferSymbols; + private int mSymbolsModeState = SYMBOLS_MODE_STATE_NONE; + + private int mLastDisplayWidth; + private LanguageSwitcher mLanguageSwitcher; + private Locale mInputLocale; + private boolean mEnableMultipleLanguages; + + KeyboardSwitcher(Context context, InputMethodService ims) { + mContext = context; + mKeyboards = new HashMap<KeyboardId, LatinKeyboard>(); + mSymbolsId = new KeyboardId(R.xml.kbd_symbols, false); + mSymbolsShiftedId = new KeyboardId(R.xml.kbd_symbols_shift, false); + mInputMethodService = ims; + } + + /** + * 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. + */ + void setLanguageSwitcher(LanguageSwitcher languageSwitcher) { + mLanguageSwitcher = languageSwitcher; + mInputLocale = mLanguageSwitcher.getInputLocale(); + mEnableMultipleLanguages = mLanguageSwitcher.getLocaleCount() > 1; + } + + void setInputView(LatinKeyboardView inputView) { + mInputView = inputView; + } + + void makeKeyboards(boolean forceCreate) { + 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(); + mSymbolsId = new KeyboardId(R.xml.kbd_symbols, mHasVoice && !mVoiceOnPrimary); + mSymbolsShiftedId = new KeyboardId(R.xml.kbd_symbols_shift, + mHasVoice && !mVoiceOnPrimary); + } + + /** + * Represents the parameters necessary to construct a new LatinKeyboard, + * which also serve as a unique identifier for each keyboard type. + */ + private static class KeyboardId { + public int mXml; + public int mKeyboardMode; /** A KEYBOARDMODE_XXX value */ + public boolean mEnableShiftLock; + public boolean mHasVoice; + + public KeyboardId(int xml, int mode, boolean enableShiftLock, boolean hasVoice) { + this.mXml = xml; + this.mKeyboardMode = mode; + this.mEnableShiftLock = enableShiftLock; + this.mHasVoice = hasVoice; + } + + public KeyboardId(int xml, boolean hasVoice) { + this(xml, 0, false, hasVoice); + } + + public boolean equals(Object other) { + return other instanceof KeyboardId && equals((KeyboardId) other); + } + + public boolean equals(KeyboardId other) { + return other.mXml == this.mXml + && other.mKeyboardMode == this.mKeyboardMode + && other.mEnableShiftLock == this.mEnableShiftLock; + } + + public int hashCode() { + return (mXml + 1) * (mKeyboardMode + 1) * (mEnableShiftLock ? 2 : 1) + * (mHasVoice ? 4 : 8); + } + } + + void setVoiceMode(boolean enableVoice, boolean voiceOnPrimary) { + if (enableVoice != mHasVoice || voiceOnPrimary != mVoiceOnPrimary) { + mKeyboards.clear(); + } + mHasVoice = enableVoice; + mVoiceOnPrimary = voiceOnPrimary; + setKeyboardMode(mMode, mImeOptions, mHasVoice, + mIsSymbols); + } + + boolean hasVoiceButton(boolean isSymbols) { + return mHasVoice && (isSymbols != mVoiceOnPrimary); + } + + void setKeyboardMode(int mode, int imeOptions, boolean enableVoice) { + mSymbolsModeState = SYMBOLS_MODE_STATE_NONE; + mPreferSymbols = mode == MODE_SYMBOLS; + setKeyboardMode(mode == MODE_SYMBOLS ? MODE_TEXT : mode, imeOptions, enableVoice, + mPreferSymbols); + } + + void setKeyboardMode(int mode, int imeOptions, boolean enableVoice, boolean isSymbols) { + if (mInputView == null) return; + mMode = mode; + mImeOptions = imeOptions; + if (enableVoice != mHasVoice) { + setVoiceMode(mHasVoice, mVoiceOnPrimary); + } + mIsSymbols = isSymbols; + + mInputView.setPreviewEnabled(true); + KeyboardId id = getKeyboardId(mode, imeOptions, isSymbols); + + LatinKeyboard keyboard = getKeyboard(id); + + if (mode == MODE_PHONE) { + mInputView.setPhoneKeyboard(keyboard); + mInputView.setPreviewEnabled(false); + } + + mCurrentId = id; + mInputView.setKeyboard(keyboard); + keyboard.setShifted(false); + keyboard.setShiftLocked(keyboard.isShiftLocked()); + keyboard.setImeOptions(mContext.getResources(), mMode, imeOptions); + } + + private LatinKeyboard getKeyboard(KeyboardId id) { + if (!mKeyboards.containsKey(id)) { + Resources orig = mContext.getResources(); + Configuration conf = orig.getConfiguration(); + Locale saveLocale = conf.locale; + conf.locale = mInputLocale; + orig.updateConfiguration(conf, null); + LatinKeyboard keyboard = new LatinKeyboard( + mContext, id.mXml, id.mKeyboardMode); + keyboard.setVoiceMode(hasVoiceButton(id.mXml == R.xml.kbd_symbols), mHasVoice); + keyboard.setLanguageSwitcher(mLanguageSwitcher); + if (id.mKeyboardMode == KEYBOARDMODE_NORMAL + || id.mKeyboardMode == KEYBOARDMODE_URL + || id.mKeyboardMode == KEYBOARDMODE_IM + || id.mKeyboardMode == KEYBOARDMODE_EMAIL + || id.mKeyboardMode == KEYBOARDMODE_WEB + ) { + keyboard.setExtension(R.xml.kbd_extension); + } + + if (id.mEnableShiftLock) { + keyboard.enableShiftLock(); + } + mKeyboards.put(id, keyboard); + + conf.locale = saveLocale; + orig.updateConfiguration(conf, null); + } + return mKeyboards.get(id); + } + + private KeyboardId getKeyboardId(int mode, int imeOptions, boolean isSymbols) { + boolean hasVoice = hasVoiceButton(isSymbols); + if (isSymbols) { + return (mode == MODE_PHONE) + ? new KeyboardId(R.xml.kbd_phone_symbols, hasVoice) + : new KeyboardId(R.xml.kbd_symbols, hasVoice); + } + switch (mode) { + case MODE_TEXT: + if (mTextMode == MODE_TEXT_QWERTY) { + return new KeyboardId(R.xml.kbd_qwerty, KEYBOARDMODE_NORMAL, true, hasVoice); + } else if (mTextMode == MODE_TEXT_ALPHA) { + return new KeyboardId(R.xml.kbd_alpha, KEYBOARDMODE_NORMAL, true, hasVoice); + } + break; + case MODE_SYMBOLS: + return new KeyboardId(R.xml.kbd_symbols, hasVoice); + case MODE_PHONE: + return new KeyboardId(R.xml.kbd_phone, hasVoice); + case MODE_URL: + return new KeyboardId(R.xml.kbd_qwerty, KEYBOARDMODE_URL, true, hasVoice); + case MODE_EMAIL: + return new KeyboardId(R.xml.kbd_qwerty, KEYBOARDMODE_EMAIL, true, hasVoice); + case MODE_IM: + return new KeyboardId(R.xml.kbd_qwerty, KEYBOARDMODE_IM, true, hasVoice); + case MODE_WEB: + return new KeyboardId(R.xml.kbd_qwerty, KEYBOARDMODE_WEB, true, hasVoice); + } + return null; + } + + int getKeyboardMode() { + return mMode; + } + + boolean isTextMode() { + return mMode == MODE_TEXT; + } + + int getTextMode() { + return mTextMode; + } + + void setTextMode(int position) { + if (position < MODE_TEXT_COUNT && position >= 0) { + mTextMode = position; + } + if (isTextMode()) { + setKeyboardMode(MODE_TEXT, mImeOptions, mHasVoice); + } + } + + int getTextModeCount() { + return MODE_TEXT_COUNT; + } + + boolean isAlphabetMode() { + int currentMode = mCurrentId.mKeyboardMode; + for (Integer mode : ALPHABET_MODES) { + if (currentMode == mode) { + return true; + } + } + return false; + } + + void toggleShift() { + if (mCurrentId.equals(mSymbolsId)) { + LatinKeyboard symbolsKeyboard = getKeyboard(mSymbolsId); + LatinKeyboard symbolsShiftedKeyboard = getKeyboard(mSymbolsShiftedId); + symbolsKeyboard.setShifted(true); + mCurrentId = mSymbolsShiftedId; + mInputView.setKeyboard(symbolsShiftedKeyboard); + symbolsShiftedKeyboard.setShifted(true); + symbolsShiftedKeyboard.setImeOptions(mContext.getResources(), mMode, mImeOptions); + } else if (mCurrentId.equals(mSymbolsShiftedId)) { + LatinKeyboard symbolsKeyboard = getKeyboard(mSymbolsId); + LatinKeyboard symbolsShiftedKeyboard = getKeyboard(mSymbolsShiftedId); + symbolsShiftedKeyboard.setShifted(false); + mCurrentId = mSymbolsId; + mInputView.setKeyboard(getKeyboard(mSymbolsId)); + symbolsKeyboard.setShifted(false); + symbolsKeyboard.setImeOptions(mContext.getResources(), mMode, mImeOptions); + } + } + + void toggleSymbols() { + setKeyboardMode(mMode, mImeOptions, mHasVoice, !mIsSymbols); + if (mIsSymbols && !mPreferSymbols) { + mSymbolsModeState = SYMBOLS_MODE_STATE_BEGIN; + } else { + mSymbolsModeState = SYMBOLS_MODE_STATE_NONE; + } + } + + /** + * Updates state machine to figure out when to automatically switch back to alpha mode. + * Returns true if the keyboard needs to switch back + */ + boolean onKey(int key) { + // Switch back to alpha mode if user types one or more non-space/enter characters + // followed by a space/enter + switch (mSymbolsModeState) { + case SYMBOLS_MODE_STATE_BEGIN: + if (key != LatinIME.KEYCODE_SPACE && key != LatinIME.KEYCODE_ENTER && key > 0) { + mSymbolsModeState = SYMBOLS_MODE_STATE_SYMBOL; + } + break; + case SYMBOLS_MODE_STATE_SYMBOL: + if (key == LatinIME.KEYCODE_ENTER || key == LatinIME.KEYCODE_SPACE) return true; + break; + } + return false; + } +} diff --git a/java/src/com/android/inputmethod/latin/LanguageSwitcher.java b/java/src/com/android/inputmethod/latin/LanguageSwitcher.java new file mode 100644 index 000000000..12045125f --- /dev/null +++ b/java/src/com/android/inputmethod/latin/LanguageSwitcher.java @@ -0,0 +1,182 @@ +/* + * 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 java.util.Locale; + +import android.content.SharedPreferences; +import android.content.SharedPreferences.Editor; +import android.preference.PreferenceManager; +import android.text.TextUtils; + +/** + * Keeps track of list of selected input languages and the current + * input language that the user has selected. + */ +public class LanguageSwitcher { + + private Locale[] mLocales; + private LatinIME mIme; + private String[] mSelectedLanguageArray; + private String mSelectedLanguages; + private int mCurrentIndex = 0; + private String mDefaultInputLanguage; + private Locale mDefaultInputLocale; + + 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++) { + mLocales[i] = new Locale(mSelectedLanguageArray[i]); + } + } + + /** + * 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]; + } + + /** + * 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() { + if (getLocaleCount() == 0) return mDefaultInputLocale; + + return mLocales[mCurrentIndex]; + } + + /** + * 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]; + } + + /** + * 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; + } + + 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()); + editor.commit(); + } + + 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/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java new file mode 100644 index 000000000..43972d98b --- /dev/null +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -0,0 +1,1949 @@ +/* + * 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.latin; + +import com.android.inputmethod.voice.EditingUtil; +import com.android.inputmethod.voice.FieldContext; +import com.android.inputmethod.voice.SettingsUtil; +import com.android.inputmethod.voice.VoiceInput; + +import android.app.AlertDialog; +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.inputmethodservice.InputMethodService; +import android.inputmethodservice.Keyboard; +import android.inputmethodservice.KeyboardView; +import android.media.AudioManager; +import android.os.Debug; +import android.os.Handler; +import android.os.Message; +import android.os.SystemClock; +import android.preference.PreferenceManager; +import android.speech.RecognitionManager; +import android.text.AutoText; +import android.text.ClipboardManager; +import android.text.TextUtils; +import android.util.Log; +import android.util.PrintWriterPrinter; +import android.util.Printer; +import android.view.HapticFeedbackConstants; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewParent; +import android.view.ViewGroup; +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 java.io.FileDescriptor; +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; + +/** + * Input method implementation for Qwerty'ish keyboard. + */ +public class LatinIME extends InputMethodService + implements KeyboardView.OnKeyboardActionListener, + VoiceInput.UiListener, + SharedPreferences.OnSharedPreferenceChangeListener { + private static final String TAG = "LatinIME"; + static final boolean DEBUG = false; + static final boolean TRACE = false; + static final boolean VOICE_INSTALLED = true; + static final boolean ENABLE_VOICE_BUTTON = true; + + private static final String PREF_VIBRATE_ON = "vibrate_on"; + private static final String PREF_SOUND_ON = "sound_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_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 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_START_LISTENING_AFTER_SWIPE = 4; + + // If we detect a swipe gesture within N ms of typing, then swipe is + // ignored, since it may in fact be two key presses in quick succession. + private static final long MIN_MILLIS_AFTER_TYPING_BEFORE_SWIPE = 1000; + + // 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 KEYCODE_ENTER = '\n'; + static final int KEYCODE_SPACE = ' '; + static final int KEYCODE_PERIOD = '.'; + + // Contextual menu positions + private static final int POS_SETTINGS = 0; + private static final int POS_METHOD = 1; + + private LatinKeyboardView mInputView; + private CandidateViewContainer mCandidateViewContainer; + private CandidateView mCandidateView; + private Suggest mSuggest; + private CompletionInfo[] mCompletions; + + private AlertDialog mOptionsDialog; + private AlertDialog mVoiceWarningDialog; + + KeyboardSwitcher mKeyboardSwitcher; + + private UserDictionary mUserDictionary; + private ContactsDictionary mContactsDictionary; + private ExpandableDictionary mAutoDictionary; + + private Hints mHints; + + Resources mResources; + + private String mLocale; + 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 mImmediatelyAfterVoiceSuggestions; + private boolean mVoiceInputHighlighted; + private boolean mEnableVoiceButton; + private CharSequence mBestWord; + private boolean mPredictionOn; + private boolean mCompletionOn; + private boolean mHasDictionary; + private boolean mAutoSpace; + private boolean mJustAddedAutoSpace; + private boolean mAutoCorrectEnabled; + private boolean mAutoCorrectOn; + private boolean mCapsLock; + private boolean mPasswordText; + private boolean mEmailText; + private boolean mVibrateOn; + private boolean mSoundOn; + private boolean mAutoCap; + private boolean mQuickFixes; + private boolean mHasUsedVoiceInput; + private boolean mHasUsedVoiceInputUnsupportedLocale; + private boolean mLocaleSupportedForVoiceInput; + private boolean mShowSuggestions; + private boolean mSuggestionShouldReplaceCurrentWord; + private boolean mIsShowingHint; + private int mCorrectionMode; + private boolean mEnableVoice = true; + private boolean mVoiceOnPrimary; + private int mOrientation; + private List<CharSequence> mSuggestPuncList; + + // Indicates whether the suggestion strip is to be on in landscape + private boolean mJustAccepted; + private CharSequence mJustRevertedSeparator; + private int mDeleteCount; + private long mLastKeyTime; + + private Tutorial mTutorial; + + private AudioManager mAudioManager; + // Align sound effect volume on music volume + private final float FX_VOLUME = -1.0f; + private boolean mSilentMode; + + private String mWordSeparators; + private String mSentenceSeparators; + private VoiceInput mVoiceInput; + private VoiceResults mVoiceResults = new VoiceResults(); + private long mSwipeTriggerTimeMillis; + private boolean mConfigurationChanging; + + // For each word, a list of potential replacements, usually from voice. + private Map<String, List<CharSequence>> mWordToSuggestions = + new HashMap<String, List<CharSequence>>(); + + private class VoiceResults { + List<String> candidates; + Map<String, List<CharSequence>> alternatives; + } + private boolean mRefreshKeyboardRequired; + + Handler mHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_UPDATE_SUGGESTIONS: + updateSuggestions(); + break; + case MSG_START_TUTORIAL: + if (mTutorial == null) { + if (mInputView.isShown()) { + mTutorial = new Tutorial(LatinIME.this, mInputView); + 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; + case MSG_START_LISTENING_AFTER_SWIPE: + if (mLastKeyTime < mSwipeTriggerTimeMillis) { + startListening(true); + } + } + } + }; + + @Override public void onCreate() { + super.onCreate(); + //setStatusIcon(R.drawable.ime_qwerty); + mResources = getResources(); + final Configuration conf = mResources.getConfiguration(); + final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + mLanguageSwitcher = new LanguageSwitcher(this); + mLanguageSwitcher.loadLocales(prefs); + mKeyboardSwitcher = new KeyboardSwitcher(this, this); + mKeyboardSwitcher.setLanguageSwitcher(mLanguageSwitcher); + boolean enableMultipleLanguages = mLanguageSwitcher.getLocaleCount() > 0; + String inputLanguage = mLanguageSwitcher.getInputLanguage(); + if (inputLanguage == null) { + inputLanguage = conf.locale.toString(); + } + initSuggest(inputLanguage); + mOrientation = conf.orientation; + initSuggestPuncList(); + + // 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); + } + + private void initSuggest(String locale) { + mLocale = 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, true); + mSuggest = new Suggest(this, R.raw.main); + updateAutoTextEnabled(saveLocale); + if (mUserDictionary != null) mUserDictionary.close(); + mUserDictionary = new UserDictionary(this, mLocale); + if (mContactsDictionary == null) { + mContactsDictionary = new ContactsDictionary(this); + } + if (mAutoDictionary != null) { + mAutoDictionary.close(); + } + mAutoDictionary = new AutoDictionary(this, this, mLocale); + mSuggest.setUserDictionary(mUserDictionary); + mSuggest.setContactsDictionary(mContactsDictionary); + mSuggest.setAutoDictionary(mAutoDictionary); + updateCorrectionMode(); + mWordSeparators = mResources.getString(R.string.word_separators); + mSentenceSeparators = mResources.getString(R.string.sentence_separators); + + conf.locale = saveLocale; + orig.updateConfiguration(conf, orig.getDisplayMetrics()); + } + + @Override + public void onDestroy() { + mUserDictionary.close(); + mContactsDictionary.close(); + unregisterReceiver(mReceiver); + if (VOICE_INSTALLED) { + mVoiceInput.destroy(); + } + super.onDestroy(); + } + + @Override + public void onConfigurationChanged(Configuration conf) { + // If the system locale changes and is different from the saved + // locale (mLocale), then reload the input locale list from the + // latin ime settings (shared prefs) and reset the input locale + // to the first one. + if (!TextUtils.equals(conf.locale.toString(), mLocale)) { + if (mLanguageSwitcher != null) { + mLanguageSwitcher.loadLocales( + PreferenceManager.getDefaultSharedPreferences(this)); + toggleLanguage(true, true); + } else { + reloadKeyboards(); + } + } + // If orientation changed while predicting, commit the change + if (conf.orientation != mOrientation) { + InputConnection ic = getCurrentInputConnection(); + commitTyped(ic); + if (ic != null) ic.finishComposingText(); // For voice input + mOrientation = conf.orientation; + reloadKeyboards(); + } + mConfigurationChanging = true; + super.onConfigurationChanged(conf); + if (mRecognizing) { + switchToRecognitionStatusView(); + } + mConfigurationChanging = false; + } + + @Override + public View onCreateInputView() { + mInputView = (LatinKeyboardView) getLayoutInflater().inflate( + R.layout.input, null); + mKeyboardSwitcher.setInputView(mInputView); + mKeyboardSwitcher.makeKeyboards(true); + mInputView.setOnKeyboardActionListener(this); + mKeyboardSwitcher.setKeyboardMode( + KeyboardSwitcher.MODE_TEXT, 0, + shouldShowVoiceButton(makeFieldContext(), getCurrentInputEditorInfo())); + return mInputView; + } + + @Override + public View onCreateCandidatesView() { + mKeyboardSwitcher.makeKeyboards(true); + mCandidateViewContainer = (CandidateViewContainer) getLayoutInflater().inflate( + R.layout.candidates, null); + mCandidateViewContainer.initViews(); + mCandidateView = (CandidateView) mCandidateViewContainer.findViewById(R.id.candidates); + mCandidateView.setService(this); + setCandidatesViewShown(true); + return mCandidateViewContainer; + } + + @Override + public void onStartInputView(EditorInfo attribute, boolean restarting) { + // In landscape mode, this method gets called without the input view being created. + if (mInputView == 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) { + mPasswordText = true; + } + + mEnableVoiceButton = shouldShowVoiceButton(makeFieldContext(), attribute); + final boolean enableVoiceButton = mEnableVoiceButton && mEnableVoice; + + mAfterVoiceInput = false; + mImmediatelyAfterVoiceInput = false; + mShowingVoiceSuggestions = false; + mImmediatelyAfterVoiceSuggestions = false; + mVoiceInputHighlighted = false; + mWordToSuggestions.clear(); + mInputTypeNoAutoCorrect = false; + mPredictionOn = false; + mCompletionOn = false; + mCompletions = null; + mCapsLock = false; + mEmailText = false; + switch (attribute.inputType & EditorInfo.TYPE_MASK_CLASS) { + case EditorInfo.TYPE_CLASS_NUMBER: + case EditorInfo.TYPE_CLASS_DATETIME: + mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_SYMBOLS, + attribute.imeOptions, enableVoiceButton); + break; + 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(); + mPredictionOn = true; + // Make sure that passwords are not displayed in candidate view + if (variation == EditorInfo.TYPE_TEXT_VARIATION_PASSWORD || + variation == EditorInfo.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD ) { + mPredictionOn = false; + } + if (variation == EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS) { + mEmailText = true; + } + if (variation == EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS + || variation == EditorInfo.TYPE_TEXT_VARIATION_PERSON_NAME) { + mAutoSpace = false; + } else { + mAutoSpace = true; + } + if (variation == EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS) { + mPredictionOn = false; + mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_EMAIL, + attribute.imeOptions, enableVoiceButton); + } else if (variation == EditorInfo.TYPE_TEXT_VARIATION_URI) { + mPredictionOn = 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) { + mPredictionOn = 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) { + mPredictionOn = 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) { + mPredictionOn = false; + mCompletionOn = true && isFullscreenMode(); + } + updateShiftKeyState(attribute); + break; + default: + mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_TEXT, + attribute.imeOptions, enableVoiceButton); + updateShiftKeyState(attribute); + } + mInputView.closing(); + mComposing.setLength(0); + mPredicting = false; + mDeleteCount = 0; + mJustAddedAutoSpace = false; + loadSettings(); + updateShiftKeyState(attribute); + + setCandidatesViewShown(false); + setSuggestions(null, false, false, false); + + // If the dictionary is not big enough, don't auto correct + mHasDictionary = mSuggest.hasMainDictionary(); + + updateCorrectionMode(); + + mInputView.setProximityCorrectionEnabled(true); + mPredictionOn = mPredictionOn && (mCorrectionMode > 0 || mShowSuggestions); + checkTutorial(attribute.privateImeOptions); + if (TRACE) Debug.startMethodTracing("/data/trace/latinime"); + } + + @Override + public void onFinishInput() { + super.onFinishInput(); + + if (VOICE_INSTALLED && !mConfigurationChanging) { + if (mAfterVoiceInput) { + mVoiceInput.logInputEnded(); + } + mVoiceInput.flushLogs(); + mVoiceInput.cancel(); + } + if (mInputView != null) { + mInputView.closing(); + } + } + + @Override + public void onUpdateExtractedText(int token, ExtractedText text) { + super.onUpdateExtractedText(token, text); + InputConnection ic = getCurrentInputConnection(); + if (!mImmediatelyAfterVoiceInput && mAfterVoiceInput && ic != null) { + mVoiceInput.logTextModified(); + + 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); + } + + mSuggestionShouldReplaceCurrentWord = false; + // 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))) { + mComposing.setLength(0); + mPredicting = false; + updateSuggestions(); + TextEntryState.reset(); + InputConnection ic = getCurrentInputConnection(); + if (ic != null) { + ic.finishComposingText(); + } + mVoiceInputHighlighted = false; + } else if (!mPredicting && !mJustAccepted) { + switch (TextEntryState.getState()) { + case TextEntryState.STATE_ACCEPTED_DEFAULT: + TextEntryState.reset(); + // fall through + case TextEntryState.STATE_SPACE_AFTER_PICKED: + mJustAddedAutoSpace = false; // The user moved the cursor. + break; + } + } + mJustAccepted = false; + postUpdateShiftKeyState(); + + if (VOICE_INSTALLED) { + if (mShowingVoiceSuggestions) { + if (mImmediatelyAfterVoiceSuggestions) { + mImmediatelyAfterVoiceSuggestions = false; + } else { + updateSuggestions(); + mShowingVoiceSuggestions = false; + } + } + if (VoiceInput.ENABLE_WORD_CORRECTIONS) { + // If we have alternatives for the current word, then show them. + String word = EditingUtil.getWordAtCursor( + getCurrentInputConnection(), getWordSeparators()); + if (word != null && mWordToSuggestions.containsKey(word.trim())) { + mSuggestionShouldReplaceCurrentWord = true; + final List<CharSequence> suggestions = mWordToSuggestions.get(word.trim()); + + setSuggestions(suggestions, false, true, true); + setCandidatesViewShown(true); + } + } + } + } + + @Override + public void hideWindow() { + 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(); + } + } + super.hideWindow(); + TextEntryState.endSession(); + } + + @Override + public void onDisplayCompletions(CompletionInfo[] completions) { + if (false) { + 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) { + setSuggestions(null, false, false, false); + 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()); + } + //CharSequence typedWord = mWord.getTypedWord(); + setSuggestions(stringList, true, true, true); + mBestWord = null; + setCandidatesViewShown(isCandidateStripVisible() || mCompletionOn); + } + } + + @Override + public void setCandidatesViewShown(boolean shown) { + // TODO: Remove this if we support candidates with hard keyboard + if (onEvaluateInputViewShown()) { + super.setCandidatesViewShown(shown); + } + } + + @Override + public void onComputeInsets(InputMethodService.Insets outInsets) { + super.onComputeInsets(outInsets); + if (!isFullscreenMode()) { + outInsets.contentTopInsets = outInsets.visibleTopInsets; + } + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + switch (keyCode) { + case KeyEvent.KEYCODE_BACK: + if (event.getRepeatCount() == 0 && mInputView != null) { + if (mInputView.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; + } + 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; + } + // Enable shift key and DPAD to do selections + if (mInputView != null && mInputView.isShown() && mInputView.isShifted()) { + 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; + } + 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() { + if (mKeyboardSwitcher == null) { + mKeyboardSwitcher = new KeyboardSwitcher(this, this); + } + mKeyboardSwitcher.setLanguageSwitcher(mLanguageSwitcher); + if (mInputView != null) { + mKeyboardSwitcher.setVoiceMode(mEnableVoice && mEnableVoiceButton, mVoiceOnPrimary); + } + mKeyboardSwitcher.makeKeyboards(true); + } + + private void commitTyped(InputConnection inputConnection) { + if (mPredicting) { + mPredicting = false; + if (mComposing.length() > 0) { + if (inputConnection != null) { + inputConnection.commitText(mComposing, 1); + } + mCommittedLength = mComposing.length(); + TextEntryState.acceptedTyped(mComposing); + checkAddToDictionary(mComposing, AutoDictionary.FREQUENCY_FOR_TYPED); + } + updateSuggestions(); + } + } + + private void postUpdateShiftKeyState() { + mHandler.removeMessages(MSG_UPDATE_SHIFT_STATE); + mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_UPDATE_SHIFT_STATE), 300); + } + + public void updateShiftKeyState(EditorInfo attr) { + InputConnection ic = getCurrentInputConnection(); + if (attr != null && mInputView != null && mKeyboardSwitcher.isAlphabetMode() + && ic != null) { + mInputView.setShifted(mCapsLock || getCursorCapsMode(ic, attr) != 0); + } + } + + private int getCursorCapsMode(InputConnection ic, EditorInfo attr) { + int caps = 0; + EditorInfo ei = getCurrentInputEditorInfo(); + if (mAutoCap && 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) == KEYCODE_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) == KEYCODE_PERIOD + && lastThree.charAt(1) == KEYCODE_SPACE + && lastThree.charAt(2) == KEYCODE_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) == KEYCODE_SPACE && lastThree.charAt(2) == KEYCODE_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) 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) == KEYCODE_PERIOD + && text.charAt(0) == KEYCODE_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) == KEYCODE_SPACE) { + ic.deleteSurroundingText(1, 0); + } + } + + public boolean addWordToDictionary(String word) { + mUserDictionary.addWord(word, 128); + return true; + } + + private boolean isAlphabet(int code) { + if (Character.isLetter(code)) { + return true; + } else { + return false; + } + } + + // Implementation of KeyboardViewListener + + public void onKey(int primaryCode, int[] keyCodes) { + long when = SystemClock.uptimeMillis(); + if (primaryCode != Keyboard.KEYCODE_DELETE || + when > mLastKeyTime + QUICK_PRESS) { + mDeleteCount = 0; + } + mLastKeyTime = when; + switch (primaryCode) { + case Keyboard.KEYCODE_DELETE: + handleBackspace(); + mDeleteCount++; + break; + case Keyboard.KEYCODE_SHIFT: + handleShift(); + break; + case Keyboard.KEYCODE_CANCEL: + if (mOptionsDialog == null || !mOptionsDialog.isShowing()) { + handleClose(); + } + break; + case LatinKeyboardView.KEYCODE_OPTIONS: + showOptionsMenu(); + break; + case LatinKeyboardView.KEYCODE_NEXT_LANGUAGE: + toggleLanguage(false, true); + break; + case LatinKeyboardView.KEYCODE_PREV_LANGUAGE: + toggleLanguage(false, false); + break; + case LatinKeyboardView.KEYCODE_SHIFT_LONGPRESS: + if (mCapsLock) { + handleShift(); + } else { + toggleCapsLock(); + } + break; + case Keyboard.KEYCODE_MODE_CHANGE: + changeKeyboardMode(); + break; + case LatinKeyboardView.KEYCODE_VOICE: + if (VOICE_INSTALLED) { + startListening(false /* was a button press, was not a swipe */); + } + break; + case 9 /*Tab*/: + sendDownUpKeyEvents(KeyEvent.KEYCODE_TAB); + break; + default: + if (primaryCode != KEYCODE_ENTER) { + mJustAddedAutoSpace = false; + } + if (isWordSeparator(primaryCode)) { + handleSeparator(primaryCode); + } else { + handleCharacter(primaryCode, keyCodes); + } + // Cancel the just reverted state + mJustRevertedSeparator = null; + } + if (mKeyboardSwitcher.onKey(primaryCode)) { + changeKeyboardMode(); + } + } + + public void onText(CharSequence text) { + if (VOICE_INSTALLED && mVoiceInputHighlighted) { + commitVoiceInput(); + } + InputConnection ic = getCurrentInputConnection(); + if (ic == null) return; + ic.beginBatchEdit(); + if (mPredicting) { + commitTyped(ic); + } + maybeRemovePreviousPeriod(text); + ic.commitText(text, 1); + ic.endBatchEdit(); + updateShiftKeyState(getCurrentInputEditorInfo()); + mJustRevertedSeparator = null; + mJustAddedAutoSpace = false; + } + + private void handleBackspace() { + if (VOICE_INSTALLED && mVoiceInputHighlighted) { + revertVoiceInput(); + return; + } + boolean deleteChar = false; + InputConnection ic = getCurrentInputConnection(); + if (ic == null) return; + 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); + return; + } else if (deleteChar) { + sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL); + if (mDeleteCount > DELETE_ACCELERATE_AT) { + sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL); + } + } + mJustRevertedSeparator = null; + } + + private void handleShift() { + mHandler.removeMessages(MSG_UPDATE_SHIFT_STATE); + if (mKeyboardSwitcher.isAlphabetMode()) { + // Alphabet keyboard + checkToggleCapsLock(); + mInputView.setShifted(mCapsLock || !mInputView.isShifted()); + } else { + mKeyboardSwitcher.toggleShift(); + } + } + + private void handleCharacter(int primaryCode, int[] keyCodes) { + if (VOICE_INSTALLED && mVoiceInputHighlighted) { + commitVoiceInput(); + } + if (isAlphabet(primaryCode) && isPredictionOn() && !isCursorTouchingWord()) { + if (!mPredicting) { + mPredicting = true; + mComposing.setLength(0); + mWord.reset(); + } + } + if (mInputView.isShifted()) { + // TODO: This doesn't work with ß, need to fix it in the next release. + if (keyCodes == null || keyCodes[0] < Character.MIN_CODE_POINT + || keyCodes[0] > Character.MAX_CODE_POINT) { + return; + } + primaryCode = new String(keyCodes, 0, 1).toUpperCase().charAt(0); + } + if (mPredicting) { + if (mInputView.isShifted() && mComposing.length() == 0) { + mWord.setCapitalized(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 { + sendKeyChar((char)primaryCode); + } + updateShiftKeyState(getCurrentInputEditorInfo()); + measureCps(); + TextEntryState.typedCharacter((char) primaryCode, isWordSeparator(primaryCode)); + } + + private void handleSeparator(int primaryCode) { + if (VOICE_INSTALLED && mVoiceInputHighlighted) { + commitVoiceInput(); + } + boolean pickedDefault = false; + // Handle separator + InputConnection ic = getCurrentInputConnection(); + if (ic != null) { + ic.beginBatchEdit(); + } + 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)) { + pickDefaultSuggestion(); + pickedDefault = true; + // Picked the suggestion by the space key. We consider this + // as "added an auto space". + if (primaryCode == KEYCODE_SPACE) { + mJustAddedAutoSpace = true; + } + } else { + commitTyped(ic); + } + } + if (mJustAddedAutoSpace && primaryCode == KEYCODE_ENTER) { + removeTrailingSpace(); + mJustAddedAutoSpace = false; + } + sendKeyChar((char)primaryCode); + + // Handle the case of ". ." -> " .." with auto-space if necessary + // before changing the TextEntryState. + if (TextEntryState.getState() == TextEntryState.STATE_PUNCTUATION_AFTER_ACCEPTED + && primaryCode == KEYCODE_PERIOD) { + reswapPeriodAndSpace(); + } + + TextEntryState.typedCharacter((char) primaryCode, true); + if (TextEntryState.getState() == TextEntryState.STATE_PUNCTUATION_AFTER_ACCEPTED + && primaryCode != KEYCODE_ENTER) { + swapPunctuationAndSpace(); + } else if (isPredictionOn() && primaryCode == KEYCODE_SPACE) { + //else if (TextEntryState.STATE_SPACE_AFTER_ACCEPTED) { + doubleSpace(); + } + if (pickedDefault && mBestWord != null) { + TextEntryState.acceptedDefault(mWord.getTypedWord(), mBestWord); + } + updateShiftKeyState(getCurrentInputEditorInfo()); + if (ic != null) { + ic.endBatchEdit(); + } + } + + private void handleClose() { + commitTyped(getCurrentInputConnection()); + if (VOICE_INSTALLED & mRecognizing) { + mVoiceInput.cancel(); + } + requestHideSelf(0); + mInputView.closing(); + TextEntryState.endSession(); + } + + private void checkToggleCapsLock() { + if (mInputView.getKeyboard().isShifted()) { + toggleCapsLock(); + } + } + + private void toggleCapsLock() { + mCapsLock = !mCapsLock; + if (mKeyboardSwitcher.isAlphabetMode()) { + ((LatinKeyboard) mInputView.getKeyboard()).setShiftLocked(mCapsLock); + } + } + + private void postUpdateSuggestions() { + mHandler.removeMessages(MSG_UPDATE_SUGGESTIONS); + mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_UPDATE_SUGGESTIONS), 100); + } + + private boolean isPredictionOn() { + boolean predictionOn = mPredictionOn; + return predictionOn; + } + + private boolean isCandidateStripVisible() { + return isPredictionOn() && mShowSuggestions; + } + + public void onCancelVoice() { + if (mRecognizing) { + switchToKeyboardView(); + } + } + + private void switchToKeyboardView() { + mHandler.post(new Runnable() { + public void run() { + mRecognizing = false; + if (mInputView != null) { + setInputView(mInputView); + } + updateInputViewShown(); + }}); + } + + private void switchToRecognitionStatusView() { + final boolean configChanged = mConfigurationChanging; + mHandler.post(new Runnable() { + public void run() { + 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); + editor.commit(); + 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); + editor.commit(); + mHasUsedVoiceInputUnsupportedLocale = true; + } + + // Clear N-best suggestions + setSuggestions(null, false, false, true); + + 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 = mInputView.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() && mInputView.isShifted()); + for (String c : mVoiceResults.candidates) { + if (capitalizeFirstWord) { + c = Character.toUpperCase(c.charAt(0)) + c.substring(1, c.length()); + } + nBest.add(c); + } + + if (nBest.size() == 0) { + return; + } + + String bestResult = nBest.get(0).toString(); + + mVoiceInput.logVoiceInputDelivered(); + + mHints.registerVoiceResult(bestResult); + + if (ic != null) ic.beginBatchEdit(); // To avoid extra updates on committing older text + + commitTyped(ic); + EditingUtil.appendText(ic, bestResult); + + if (ic != null) ic.endBatchEdit(); + + // Show N-Best alternates, if there is more than one choice. + if (nBest.size() > 1) { + mImmediatelyAfterVoiceSuggestions = true; + mShowingVoiceSuggestions = true; + setSuggestions(nBest.subList(1, nBest.size()), false, true, true); + setCandidatesViewShown(true); + } + mVoiceInputHighlighted = true; + mWordToSuggestions.putAll(mVoiceResults.alternatives); + + } + + private void setSuggestions( + List<CharSequence> suggestions, + boolean completions, + + boolean typedWordValid, + boolean haveMinimalSuggestion) { + + if (mIsShowingHint) { + setCandidatesView(mCandidateViewContainer); + mIsShowingHint = false; + } + + if (mCandidateView != null) { + mCandidateView.setSuggestions( + suggestions, completions, typedWordValid, haveMinimalSuggestion); + } + } + + private void updateSuggestions() { + mSuggestionShouldReplaceCurrentWord = false; + + ((LatinKeyboard) mInputView.getKeyboard()).setPreferredLetters(null); + + // Check if we have a suggestion engine attached. + if ((mSuggest == null || !isPredictionOn()) && !mVoiceInputHighlighted) { + return; + } + + if (!mPredicting) { + setNextSuggestions(); + return; + } + + List<CharSequence> stringList = mSuggest.getSuggestions(mInputView, mWord, false); + int[] nextLettersFrequencies = mSuggest.getNextLettersFrequencies(); + + ((LatinKeyboard) mInputView.getKeyboard()).setPreferredLetters(nextLettersFrequencies); + + boolean correctionAvailable = mSuggest.hasMinimalCorrection(); + //|| mCorrectionMode == mSuggest.CORRECTION_FULL; + CharSequence typedWord = mWord.getTypedWord(); + // If we're in basic correct + boolean typedWordValid = mSuggest.isValidWord(typedWord) || + (preferCapitalization() && mSuggest.isValidWord(typedWord.toString().toLowerCase())); + if (mCorrectionMode == Suggest.CORRECTION_FULL) { + correctionAvailable |= typedWordValid; + } + // Don't auto-correct words with multiple capital letter + correctionAvailable &= !mWord.isMostlyCaps(); + + 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 void pickDefaultSuggestion() { + // Complete any pending candidate query first + if (mHandler.hasMessages(MSG_UPDATE_SUGGESTIONS)) { + mHandler.removeMessages(MSG_UPDATE_SUGGESTIONS); + updateSuggestions(); + } + if (mBestWord != null) { + TextEntryState.acceptedDefault(mWord.getTypedWord(), mBestWord); + mJustAccepted = true; + pickSuggestion(mBestWord); + // Add the word to the auto dictionary if it's not a known word + checkAddToDictionary(mBestWord, AutoDictionary.FREQUENCY_FOR_TYPED); + } + } + + public void pickSuggestionManually(int index, CharSequence suggestion) { + if (mAfterVoiceInput && mShowingVoiceSuggestions) mVoiceInput.logNBestChoose(index); + + 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))) { + onKey(suggestion.charAt(0), null); + if (ic != null) { + ic.endBatchEdit(); + } + return; + } + mJustAccepted = true; + pickSuggestion(suggestion); + // Add the word to the auto dictionary if it's not a known word + checkAddToDictionary(suggestion, AutoDictionary.FREQUENCY_FOR_PICKED); + TextEntryState.acceptedSuggestion(mComposing.toString(), suggestion); + // Follow it with a space + if (mAutoSpace) { + sendSpace(); + mJustAddedAutoSpace = true; + } + // Fool the state watcher so that a subsequent backspace will not do a revert + TextEntryState.typedCharacter((char) KEYCODE_SPACE, true); + if (index == 0 && mCorrectionMode > 0 && !mSuggest.isValidWord(suggestion)) { + mCandidateView.showAddToDictionaryHint(suggestion); + } + if (ic != null) { + ic.endBatchEdit(); + } + } + + private void pickSuggestion(CharSequence suggestion) { + if (mCapsLock) { + suggestion = suggestion.toString().toUpperCase(); + } else if (preferCapitalization() + || (mKeyboardSwitcher.isAlphabetMode() && mInputView.isShifted())) { + suggestion = suggestion.toString().toUpperCase().charAt(0) + + suggestion.subSequence(1, suggestion.length()).toString(); + } + InputConnection ic = getCurrentInputConnection(); + if (ic != null) { + if (mSuggestionShouldReplaceCurrentWord) { + EditingUtil.deleteWordAtCursor(ic, getWordSeparators()); + } + if (!VoiceInput.DELETE_SYMBOL.equals(suggestion)) { + ic.commitText(suggestion, 1); + } + } + mPredicting = false; + mCommittedLength = suggestion.length(); + ((LatinKeyboard) mInputView.getKeyboard()).setPreferredLetters(null); + setNextSuggestions(); + updateShiftKeyState(getCurrentInputEditorInfo()); + } + + private void setNextSuggestions() { + setSuggestions(mSuggestPuncList, false, false, false); + } + + private void checkAddToDictionary(CharSequence suggestion, int frequencyDelta) { + if (mAutoDictionary.isValidWord(suggestion) + || !mSuggest.isValidWord(suggestion.toString().toLowerCase())) { + mAutoDictionary.addWord(suggestion.toString(), frequencyDelta); + } + } + + 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))) { + return true; + } + if (!TextUtils.isEmpty(toRight) + && !isWordSeparator(toRight.charAt(0))) { + return true; + } + return false; + } + + public void revertLastWord(boolean deleteChar) { + final int length = mComposing.length(); + if (!mPredicting && length > 0) { + final InputConnection ic = getCurrentInputConnection(); + mPredicting = true; + ic.beginBatchEdit(); + 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(); + ic.endBatchEdit(); + 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)); + } + + public boolean isSentenceSeparator(int code) { + return mSentenceSeparators.contains(String.valueOf((char)code)); + } + + private void sendSpace() { + sendKeyChar((char)KEYCODE_SPACE); + updateShiftKeyState(getCurrentInputEditorInfo()); + //onKey(KEY_SPACE[0], KEY_SPACE); + } + + public boolean preferCapitalization() { + return mWord.isCapitalized(); + } + + public void swipeRight() { + if (userHasNotTypedRecently() && VOICE_INSTALLED && mEnableVoice && + fieldCanDoVoice(makeFieldContext())) { + startListening(true /* was a swipe */); + } + + if (LatinKeyboardView.DEBUG_AUTO_PLAY) { + ClipboardManager cm = ((ClipboardManager)getSystemService(CLIPBOARD_SERVICE)); + CharSequence text = cm.getText(); + if (!TextUtils.isEmpty(text)) { + mInputView.startPlaying(text.toString()); + } + } + } + + private 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(); + updateShiftKeyState(getCurrentInputEditorInfo()); + } + + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, + String key) { + if (PREF_SELECTED_LANGUAGES.equals(key)) { + mLanguageSwitcher.loadLocales(sharedPreferences); + mRefreshKeyboardRequired = true; + } + } + + public void swipeLeft() { + } + + public void swipeDown() { + handleClose(); + } + + public void swipeUp() { + //launchSettings(); + } + + public void onPress(int primaryCode) { + vibrate(); + playKeyClick(primaryCode); + } + + public void onRelease(int primaryCode) { + // Reset any drag flags in the keyboard + ((LatinKeyboard) mInputView.getKeyboard()).keyReleased(); + //vibrate(); + } + + 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 && attribute.privateImeOptions != null + && attribute.privateImeOptions.equals(IME_OPTION_NO_MICROPHONE)) + && RecognitionManager.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 boolean userHasNotTypedRecently() { + return (SystemClock.uptimeMillis() - mLastKeyTime) + > MIN_MILLIS_AFTER_TYPING_BEFORE_SWIPE; + } + + 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 (mInputView != 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 KEYCODE_ENTER: + sound = AudioManager.FX_KEYPRESS_RETURN; + break; + case KEYCODE_SPACE: + sound = AudioManager.FX_KEYPRESS_SPACEBAR; + break; + } + mAudioManager.playSoundEffect(sound, FX_VOLUME); + } + } + + private void vibrate() { + if (!mVibrateOn) { + return; + } + if (mInputView != null) { + mInputView.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); + } + + void tutorialDone() { + mTutorial = null; + } + + void promoteToUserDictionary(String word, int frequency) { + if (mUserDictionary.isValidWord(word)) return; + mUserDictionary.addWord(word, frequency); + } + + WordComposer getCurrentWord() { + return mWord; + } + + 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); + if (mSuggest != null) { + mSuggest.setCorrectionMode(mCorrectionMode); + } + } + + private void updateAutoTextEnabled(Locale systemLocale) { + if (mSuggest == null) return; + boolean different = !systemLocale.getLanguage().equalsIgnoreCase(mLocale.substring(0, 2)); + mSuggest.setAutoTextEnabled(!different && mQuickFixes); + } + + protected void launchSettings() { + launchSettings(LatinIMESettings.class); + } + + protected void launchSettings(Class 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); + mSoundOn = sp.getBoolean(PREF_SOUND_ON, false); + mAutoCap = sp.getBoolean(PREF_AUTO_CAP, true); + 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(mLocale); + + mShowSuggestions = sp.getBoolean(PREF_SHOW_SUGGESTIONS, true); + + 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; + updateCorrectionMode(); + updateAutoTextEnabled(mResources.getConfiguration().locale); + mLanguageSwitcher.loadLocales(sp); + } + + private void initSuggestPuncList() { + mSuggestPuncList = new ArrayList<CharSequence>(); + String suggestPuncs = mResources.getString(R.string.suggested_punctuations); + if (suggestPuncs != null) { + for (int i = 0; i < suggestPuncs.length(); i++) { + mSuggestPuncList.add(suggestPuncs.subSequence(i, i + 1)); + } + } + } + + 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.inputMethod); + builder.setItems(new CharSequence[] { + itemSettings, itemInputMethod}, + 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_name)); + mOptionsDialog = builder.create(); + Window window = mOptionsDialog.getWindow(); + WindowManager.LayoutParams lp = window.getAttributes(); + lp.token = mInputView.getWindowToken(); + lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; + window.setAttributes(lp); + window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); + mOptionsDialog.show(); + } + + private void changeKeyboardMode() { + mKeyboardSwitcher.toggleSymbols(); + if (mCapsLock && mKeyboardSwitcher.isAlphabetMode()) { + ((LatinKeyboard) mInputView.getKeyboard()).setShiftLocked(mCapsLock); + } + + 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(" mCapsLock=" + mCapsLock); + p.println(" mComposing=" + mComposing.toString()); + p.println(" mPredictionOn=" + mPredictionOn); + 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); + } + + // Characters per second measurement + + private static final boolean PERF_DEBUG = false; + private long mLastCpsTime; + private static final int CPS_BUFFER_SIZE = 16; + private long[] mCpsIntervals = new long[CPS_BUFFER_SIZE]; + private int mCpsIndex; + private boolean mInputTypeNoAutoCorrect; + + private void measureCps() { + if (!LatinIME.PERF_DEBUG) return; + 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)); + } + +} diff --git a/java/src/com/android/inputmethod/latin/LatinIMEBackupAgent.java b/java/src/com/android/inputmethod/latin/LatinIMEBackupAgent.java new file mode 100644 index 000000000..62da86cd4 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/LatinIMEBackupAgent.java @@ -0,0 +1,31 @@ +/* + * 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.latin; + +import android.app.backup.BackupHelperAgent; +import android.app.backup.SharedPreferencesBackupHelper; + +/** + * Backs up the Latin IME shared preferences. + */ +public class LatinIMEBackupAgent extends BackupHelperAgent { + + public void onCreate() { + addHelper("shared_pref", new SharedPreferencesBackupHelper(this, + getPackageName() + "_preferences")); + } +} diff --git a/java/src/com/android/inputmethod/latin/LatinIMESettings.java b/java/src/com/android/inputmethod/latin/LatinIMESettings.java new file mode 100644 index 000000000..f76ec99b6 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/LatinIMESettings.java @@ -0,0 +1,200 @@ +/* + * 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.latin; + +import java.util.ArrayList; +import java.util.Locale; + +import android.app.AlertDialog; +import android.app.Dialog; +import android.app.backup.BackupManager; +import android.content.DialogInterface; +import android.content.SharedPreferences; +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.preference.Preference.OnPreferenceClickListener; +import android.speech.RecognitionManager; +import android.text.AutoText; +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 SHOW_SUGGESTIONS_KEY = "show_suggestions"; + private static final String PREDICTION_SETTINGS_KEY = "prediction_settings"; + private static final String VOICE_SETTINGS_KEY = "voice_mode"; + private static final String VOICE_ON_PRIMARY_KEY = "voice_on_main"; + private static final String VOICE_SERVER_KEY = "voice_server_url"; + + private static final String TAG = "LatinIMESettings"; + + // Dialog ids + private static final int VOICE_INPUT_CONFIRM_DIALOG = 0; + + private CheckBoxPreference mQuickFixes; + private CheckBoxPreference mShowSuggestions; + private ListPreference mVoicePreference; + 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); + mShowSuggestions = (CheckBoxPreference) findPreference(SHOW_SUGGESTIONS_KEY); + mVoicePreference = (ListPreference) findPreference(VOICE_SETTINGS_KEY); + 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 + || !RecognitionManager.isRecognitionAvailable(this)) { + getPreferenceScreen().removePreference(mVoicePreference); + } else { + updateVoiceModeSummary(); + } + } + + @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(); + } + + 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()); + + 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/com/android/inputmethod/latin/LatinKeyboard.java b/java/src/com/android/inputmethod/latin/LatinKeyboard.java new file mode 100644 index 000000000..58e1dc767 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/LatinKeyboard.java @@ -0,0 +1,762 @@ +/* + * 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.latin; + +import java.util.List; +import java.util.Locale; + +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.PixelFormat; +import android.graphics.PorterDuff; +import android.graphics.Rect; +import android.graphics.Paint.Align; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.inputmethodservice.Keyboard; +import android.text.TextPaint; +import android.util.Log; +import android.view.ViewConfiguration; +import android.view.inputmethod.EditorInfo; + +public class LatinKeyboard extends Keyboard { + + private static final boolean DEBUG_PREFERRED_LETTER = false; + private static final String TAG = "LatinKeyboard"; + + private Drawable mShiftLockIcon; + private Drawable mShiftLockPreviewIcon; + private Drawable mOldShiftIcon; + private Drawable mOldShiftPreviewIcon; + private Drawable mSpaceIcon; + private Drawable mSpacePreviewIcon; + private Drawable mMicIcon; + private Drawable mMicPreviewIcon; + private Drawable m123MicIcon; + private Drawable m123MicPreviewIcon; + private Drawable mButtonArrowLeftIcon; + private Drawable mButtonArrowRightIcon; + private Key mShiftKey; + private Key mEnterKey; + private Key mF1Key; + private Key mSpaceKey; + private Key m123Key; + private int mSpaceKeyIndex = -1; + private int mSpaceDragStartX; + private int mSpaceDragLastDiff; + /* package */ Locale mLocale; + private LanguageSwitcher mLanguageSwitcher; + private Resources mRes; + private 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 boolean mIsAlphaKeyboard; + private CharSequence m123Label; + private boolean mCurrentlyInSpace; + private SlidingLocaleDrawable mSlidingLocaleIcon; + private Rect mBounds = new Rect(); + private int[] mPrefLetterFrequencies; + private boolean mPreemptiveCorrection; + private int mPrefLetter; + private int mPrefLetterX; + private int mPrefLetterY; + private int mPrefDistance; + + private int mExtensionResId; + + private static final int SHIFT_OFF = 0; + private static final int SHIFT_ON = 1; + private static final int SHIFT_LOCKED = 2; + + private int mShiftState = SHIFT_OFF; + + private static final float SPACEBAR_DRAG_THRESHOLD = 0.8f; + private static final float OVERLAP_PERCENTAGE_LOW_PROB = 0.70f; + private static final float OVERLAP_PERCENTAGE_HIGH_PROB = 0.85f; + + static int sSpacebarVerticalCorrection; + + public LatinKeyboard(Context context, int xmlLayoutResId) { + this(context, xmlLayoutResId, 0); + } + + public LatinKeyboard(Context context, int xmlLayoutResId, int mode) { + super(context, xmlLayoutResId, mode); + final Resources res = context.getResources(); + 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); + mShiftLockPreviewIcon.setBounds(0, 0, + mShiftLockPreviewIcon.getIntrinsicWidth(), + mShiftLockPreviewIcon.getIntrinsicHeight()); + mSpaceIcon = res.getDrawable(R.drawable.sym_keyboard_space); + 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); + 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); + setDefaultBounds(m123MicPreviewIcon); + sSpacebarVerticalCorrection = res.getDimensionPixelOffset( + R.dimen.spacebar_vertical_correction); + mIsAlphaKeyboard = xmlLayoutResId == R.xml.kbd_qwerty; + mSpaceKeyIndex = indexOf((int) ' '); + } + + public LatinKeyboard(Context context, int layoutTemplateResId, + CharSequence characters, int columns, int horizontalPadding) { + super(context, layoutTemplateResId, characters, columns, horizontalPadding); + } + + @Override + protected Key createKeyFromXml(Resources res, Row parent, int x, int y, + XmlResourceParser parser) { + Key key = new LatinKey(res, parent, x, y, parser); + switch (key.codes[0]) { + case 10: + mEnterKey = key; + break; + case LatinKeyboardView.KEYCODE_F1: + mF1Key = key; + break; + case 32: + mSpaceKey = key; + break; + case KEYCODE_MODE_CHANGE: + m123Key = key; + m123Label = key.label; + break; + } + return key; + } + + void setImeOptions(Resources res, int mode, int options) { + 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: + if (mode == KeyboardSwitcher.MODE_IM) { + mEnterKey.icon = null; + mEnterKey.iconPreview = null; + mEnterKey.label = ":-)"; + mEnterKey.text = ":-) "; + mEnterKey.popupResId = R.xml.popup_smileys; + } else { + 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) { + mEnterKey.iconPreview.setBounds(0, 0, + mEnterKey.iconPreview.getIntrinsicWidth(), + mEnterKey.iconPreview.getIntrinsicHeight()); + } + } + } + + void enableShiftLock() { + int index = getShiftKeyIndex(); + if (index >= 0) { + mShiftKey = getKeys().get(index); + if (mShiftKey instanceof LatinKey) { + ((LatinKey)mShiftKey).enableShiftLock(); + } + mOldShiftIcon = mShiftKey.icon; + mOldShiftPreviewIcon = mShiftKey.iconPreview; + } + } + + void setShiftLocked(boolean shiftLocked) { + if (mShiftKey != null) { + if (shiftLocked) { + mShiftKey.on = true; + mShiftKey.icon = mShiftLockIcon; + mShiftState = SHIFT_LOCKED; + } else { + mShiftKey.on = false; + mShiftKey.icon = mShiftLockIcon; + mShiftState = SHIFT_ON; + } + } + } + + boolean isShiftLocked() { + return mShiftState == SHIFT_LOCKED; + } + + @Override + public boolean setShifted(boolean shiftState) { + boolean shiftChanged = false; + if (mShiftKey != null) { + if (shiftState == false) { + shiftChanged = mShiftState != SHIFT_OFF; + mShiftState = SHIFT_OFF; + mShiftKey.on = false; + mShiftKey.icon = mOldShiftIcon; + } else { + if (mShiftState == SHIFT_OFF) { + shiftChanged = mShiftState == SHIFT_OFF; + mShiftState = SHIFT_ON; + mShiftKey.icon = mShiftLockIcon; + } + } + } else { + return super.setShifted(shiftState); + } + return shiftChanged; + } + + @Override + public boolean isShifted() { + if (mShiftKey != null) { + return mShiftState != SHIFT_OFF; + } else { + return super.isShifted(); + } + } + + public void setExtension(int resId) { + mExtensionResId = resId; + } + + public int getExtension() { + return mExtensionResId; + } + + private void setDefaultBounds(Drawable drawable) { + drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); + } + + public void setVoiceMode(boolean hasVoiceButton, boolean hasVoice) { + mHasVoiceButton = hasVoiceButton; + mVoiceEnabled = hasVoice; + updateF1Key(); + } + + private void updateF1Key() { + if (mF1Key == null) return; + 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; + } + } + + if (mHasVoiceButton && mVoiceEnabled) { + mF1Key.codes = new int[] { LatinKeyboardView.KEYCODE_VOICE }; + mF1Key.label = null; + mF1Key.icon = mMicIcon; + mF1Key.iconPreview = mMicPreviewIcon; + } else { + mF1Key.label = ","; + mF1Key.codes = new int[] { ',' }; + mF1Key.icon = null; + mF1Key.iconPreview = null; + } + } + + private void updateSpaceBarForLocale() { + if (mLocale != null) { + // Create the graphic for spacebar + Bitmap buffer = Bitmap.createBitmap(mSpaceKey.width, mSpaceIcon.getIntrinsicHeight(), + Bitmap.Config.ARGB_8888); + Canvas canvas = new Canvas(buffer); + drawSpaceBar(canvas, buffer.getWidth(), buffer.getHeight(), 255); + mSpaceKey.icon = new BitmapDrawable(mRes, buffer); + mSpaceKey.repeatable = mLanguageSwitcher.getLocaleCount() < 2; + } else { + mSpaceKey.icon = mRes.getDrawable(R.drawable.sym_keyboard_space); + mSpaceKey.repeatable = true; + } + } + + private void drawSpaceBar(Canvas canvas, int width, int height, int opacity) { + canvas.drawColor(0x00000000, PorterDuff.Mode.CLEAR); + Paint paint = new Paint(); + paint.setAntiAlias(true); + paint.setAlpha(opacity); + // Get the text size from the theme + paint.setTextSize(getTextSizeFromTheme(android.R.style.TextAppearance_Small, 14)); + paint.setTextAlign(Align.CENTER); + //// Draw a drop shadow for the text + //paint.setShadowLayer(2f, 0, 0, 0xFF000000); + final String language = getInputLanguage(mSpaceKey.width, paint); + final int ascent = (int) -paint.ascent(); + paint.setColor(0x80000000); + canvas.drawText(language, + width / 2, ascent - 1, paint); + paint.setColor(0xFF808080); + canvas.drawText(language, + width / 2, ascent, paint); + // Put arrows on either side of the text + if (mLanguageSwitcher.getLocaleCount() > 1) { + Rect bounds = new Rect(); + paint.getTextBounds(language, 0, language.length(), bounds); + drawButtonArrow(mButtonArrowLeftIcon, canvas, + (mSpaceKey.width - bounds.right) / 2 + - mButtonArrowLeftIcon.getIntrinsicWidth(), + (int) paint.getTextSize()); + drawButtonArrow(mButtonArrowRightIcon, canvas, + (mSpaceKey.width + bounds.right) / 2, (int) paint.getTextSize()); + } + // Draw the spacebar icon at the bottom + int x = (width - mSpaceIcon.getIntrinsicWidth()) / 2; + int y = height - mSpaceIcon.getIntrinsicHeight(); + mSpaceIcon.setBounds(x, y, + x + mSpaceIcon.getIntrinsicWidth(), y + mSpaceIcon.getIntrinsicHeight()); + mSpaceIcon.draw(canvas); + } + + private void drawButtonArrow(Drawable arrow, Canvas canvas, int x, int bottomY) { + arrow.setBounds(x, bottomY - arrow.getIntrinsicHeight(), x + arrow.getIntrinsicWidth(), + bottomY); + arrow.draw(canvas); + } + + private String getInputLanguage(int widthAvail, Paint paint) { + return chooseDisplayName(mLanguageSwitcher.getInputLocale(), widthAvail, paint); + } + + private String getNextInputLanguage(int widthAvail, Paint paint) { + return chooseDisplayName(mLanguageSwitcher.getNextInputLocale(), widthAvail, paint); + } + + private String getPrevInputLanguage(int widthAvail, Paint paint) { + return chooseDisplayName(mLanguageSwitcher.getPrevInputLocale(), widthAvail, paint); + } + + private String chooseDisplayName(Locale locale, int widthAvail, Paint paint) { + if (widthAvail < (int) (.35 * getMinWidth())) { + return LanguageSwitcher.toTitleCase(locale.getLanguage().substring(0, 2)); + } else { + return LanguageSwitcher.toTitleCase(locale.getDisplayLanguage(locale)); + } + } + + private void updateLocaleDrag(int diff) { + if (mSlidingLocaleIcon == null) { + mSlidingLocaleIcon = new SlidingLocaleDrawable(mSpacePreviewIcon, mSpaceKey.width, + mSpacePreviewIcon.getIntrinsicHeight()); + mSlidingLocaleIcon.setBounds(0, 0, mSpaceKey.width, + mSpacePreviewIcon.getIntrinsicHeight()); + 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) < mSpaceKey.width * SPACEBAR_DRAG_THRESHOLD ) { + return 0; // No change + } + return mSpaceDragLastDiff > 0 ? 1 : -1; + } + + public void setLanguageSwitcher(LanguageSwitcher switcher) { + mLanguageSwitcher = switcher; + Locale locale = mLanguageSwitcher.getLocaleCount() > 0 + ? mLanguageSwitcher.getInputLocale() + : null; + if (mLocale != null && mLocale.equals(locale)) return; + mLocale = locale; + updateSpaceBarForLocale(); + } + + 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) { + y -= key.height / 10; + if (code == KEYCODE_SHIFT) x += key.width / 6; + if (code == KEYCODE_DELETE) x -= key.width / 6; + } else if (code == LatinIME.KEYCODE_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 && 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 new int[] { mSpaceKeyIndex }; + } else { + return super.getNearestKeys(x, y); + } + } + + 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 textSize = array.getDimensionPixelSize(array.getResourceId(0, 0), defValue); + return textSize; + } + + class LatinKey extends Keyboard.Key { + + private boolean mShiftLockEnabled; + + public LatinKey(Resources res, Keyboard.Row parent, int x, int y, + XmlResourceParser parser) { + super(res, parent, x, y, parser); + if (popupCharacters != null && popupCharacters.length() == 0) { + // If there is a keyboard with no keys specified in popupCharacters + popupResId = 0; + } + } + + void enableShiftLock() { + mShiftLockEnabled = true; + } + + @Override + public void onReleased(boolean inside) { + if (!mShiftLockEnabled) { + super.onReleased(inside); + } else { + pressed = !pressed; + } + } + + /** + * Overriding this method so that we can reduce the target area for certain keys. + */ + @Override + public boolean isInside(int x, int y) { + boolean result = LatinKeyboard.this.isInside(this, x, y); + return result; + } + + boolean isInsideSuper(int x, int y) { + return super.isInside(x, y); + } + } + + /** + * 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 int mWidth; + private int mHeight; + private Drawable mBackground; + private int mDiff; + private TextPaint mTextPaint; + private int mMiddleX; + private int mAscent; + private Drawable mLeftDrawable; + private Drawable mRightDrawable; + private boolean mHitThreshold; + private int mThreshold; + private String mCurrentLanguage; + private String mNextLanguage; + private String mPrevLanguage; + + public SlidingLocaleDrawable(Drawable background, int width, int height) { + mBackground = background; + mBackground.setBounds(0, 0, + mBackground.getIntrinsicWidth(), mBackground.getIntrinsicHeight()); + mWidth = width; + mHeight = height; + mTextPaint = new TextPaint(); + int textSize = getTextSizeFromTheme(android.R.style.TextAppearance_Medium, 18); + mTextPaint.setTextSize(textSize); + mTextPaint.setColor(0); + mTextPaint.setTextAlign(Align.CENTER); + mTextPaint.setAlpha(255); + mTextPaint.setAntiAlias(true); + mAscent = (int) mTextPaint.ascent(); + 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); + mLeftDrawable.setBounds(0, 0, + mLeftDrawable.getIntrinsicWidth(), mLeftDrawable.getIntrinsicHeight()); + mRightDrawable.setBounds(mWidth - mRightDrawable.getIntrinsicWidth(), 0, + mWidth, mRightDrawable.getIntrinsicHeight()); + mThreshold = ViewConfiguration.get(mContext).getScaledTouchSlop(); + } + + 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(); + } + + @Override + public void draw(Canvas canvas) { + canvas.save(); + if (mHitThreshold) { + mTextPaint.setColor(0xFF000000); + canvas.clipRect(0, 0, mWidth, mHeight); + if (mCurrentLanguage == null) { + mCurrentLanguage = getInputLanguage(mWidth, mTextPaint); + mNextLanguage = getNextInputLanguage(mWidth, mTextPaint); + mPrevLanguage = getPrevInputLanguage(mWidth, mTextPaint); + } + canvas.drawText(mCurrentLanguage, + mWidth / 2 + mDiff, -mAscent + 4, mTextPaint); + canvas.drawText(mNextLanguage, + mDiff - mWidth / 2, -mAscent + 4, mTextPaint); + canvas.drawText(mPrevLanguage, + mDiff + mWidth + mWidth / 2, -mAscent + 4, mTextPaint); + mLeftDrawable.draw(canvas); + mRightDrawable.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/com/android/inputmethod/latin/LatinKeyboardView.java b/java/src/com/android/inputmethod/latin/LatinKeyboardView.java new file mode 100644 index 000000000..2686a93c6 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/LatinKeyboardView.java @@ -0,0 +1,332 @@ +/* + * 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.latin; + +import java.util.List; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.inputmethodservice.Keyboard; +import android.inputmethodservice.KeyboardView; +import android.inputmethodservice.Keyboard.Key; +import android.os.Handler; +import android.os.Message; +import android.os.SystemClock; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.widget.PopupWindow; + +public class LatinKeyboardView extends KeyboardView { + + static final int KEYCODE_OPTIONS = -100; + static final int KEYCODE_SHIFT_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; + + private Keyboard mPhoneKeyboard; + + private boolean mExtensionVisible; + private LatinKeyboardView mExtension; + private PopupWindow mExtensionPopup; + private boolean mFirstEvent; + + public LatinKeyboardView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public LatinKeyboardView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + public void setPhoneKeyboard(Keyboard phoneKeyboard) { + mPhoneKeyboard = phoneKeyboard; + } + + @Override + protected boolean onLongPress(Key key) { + if (key.codes[0] == Keyboard.KEYCODE_MODE_CHANGE) { + getOnKeyboardActionListener().onKey(KEYCODE_OPTIONS, null); + return true; + } else if (key.codes[0] == Keyboard.KEYCODE_SHIFT) { + getOnKeyboardActionListener().onKey(KEYCODE_SHIFT_LONGPRESS, null); + invalidateAllKeys(); + return true; + } else if (key.codes[0] == '0' && getKeyboard() == mPhoneKeyboard) { + // Long pressing on 0 in phone number keypad gives you a '+'. + getOnKeyboardActionListener().onKey('+', null); + return true; + } else { + return super.onLongPress(key); + } + } + + @Override + public boolean onTouchEvent(MotionEvent me) { + LatinKeyboard keyboard = (LatinKeyboard) getKeyboard(); + if (DEBUG_LINE) { + mLastX = (int) me.getX(); + mLastY = (int) me.getY(); + invalidate(); + } + // 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); + 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() == 0) { + return super.onTouchEvent(me); + } + if (me.getY() < 0) { + 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()); + boolean result = mExtension.onTouchEvent(translated); + translated.recycle(); + if (me.getAction() == MotionEvent.ACTION_UP + || me.getAction() == MotionEvent.ACTION_CANCEL) { + closeExtension(); + } + return result; + } 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; + } + } + 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); + down.recycle(); + // Send the actual event + return super.onTouchEvent(me); + } else { + return super.onTouchEvent(me); + } + } + + private boolean openExtension() { + if (((LatinKeyboard) getKeyboard()).getExtension() == 0) return false; + makePopupWindow(); + mExtensionVisible = true; + return true; + } + + private void makePopupWindow() { + 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(R.layout.input_trans, null); + mExtension.setOnKeyboardActionListener((LatinIME) getContext()); + mExtension.setPopupParent(this); + mExtension.setPopupOffset(0, -windowLocation[1]); + Keyboard keyboard; + mExtension.setKeyboard(keyboard = new LatinKeyboard(getContext(), + ((LatinKeyboard) getKeyboard()).getExtension())); + mExtensionPopup.setContentView(mExtension); + mExtensionPopup.setWidth(getWidth()); + mExtensionPopup.setHeight(keyboard.getHeight()); + getLocationInWindow(windowLocation); + // TODO: Fix the "- 30". + mExtension.setPopupOffset(0, -windowLocation[1] - 30); + mExtensionPopup.showAtLocation(this, 0, 0, -keyboard.getHeight() + + windowLocation[1]); + } else { + mExtension.setVisibility(VISIBLE); + } + } + + @Override + public void closing() { + super.closing(); + if (mExtensionPopup != null && mExtensionPopup.isShowing()) { + mExtensionPopup.dismiss(); + mExtensionPopup = null; + } + } + + private void closeExtension() { + mExtension.setVisibility(INVISIBLE); + mExtension.closing(); + mExtensionVisible = false; + } + + /**************************** 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; + + @Override + public void setKeyboard(Keyboard k) { + super.setKeyboard(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[(int) 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); + } + } + } + + void startPlaying(String s) { + if (!DEBUG_AUTO_PLAY) return; + 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) { + super.draw(c); + if (DEBUG_AUTO_PLAY && 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 (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/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java new file mode 100755 index 000000000..712b9cf37 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/Suggest.java @@ -0,0 +1,378 @@ +/* + * 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.latin; + +import android.content.Context; +import android.text.AutoText; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import com.android.inputmethod.latin.WordComposer; + +/** + * 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 { + + public static final int CORRECTION_NONE = 0; + public static final int CORRECTION_BASIC = 1; + public static final int CORRECTION_FULL = 2; + + private static final int LARGE_DICTIONARY_THRESHOLD = 200 * 1000; + + private BinaryDictionary mMainDict; + + private Dictionary mUserDictionary; + + private Dictionary mAutoDictionary; + + private Dictionary mContactsDictionary; + + private int mPrefMaxSuggestions = 12; + + private boolean mAutoTextEnabled; + + private int[] mPriorities = new int[mPrefMaxSuggestions]; + // 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>(); + private ArrayList<CharSequence> mStringPool = new ArrayList<CharSequence>(); + private boolean mHaveCorrection; + private CharSequence mOriginalWord; + private String mLowerOriginalWord; + private boolean mCapitalize; + + private int mCorrectionMode = CORRECTION_BASIC; + + + public Suggest(Context context, int dictionaryResId) { + mMainDict = new BinaryDictionary(context, dictionaryResId); + for (int i = 0; i < mPrefMaxSuggestions; i++) { + StringBuilder sb = new StringBuilder(32); + 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; + } + + /** + * 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; + } + + /** + * 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]; + collectGarbage(); + while (mStringPool.size() < mPrefMaxSuggestions) { + StringBuilder sb = new StringBuilder(32); + 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 a view for retrieving the context for AutoText + * @param codes the list of codes. Each list item contains an array of character codes + * in order of probability where the character at index 0 in the array has the highest + * probability. + * @return list of suggestions. + */ + public List<CharSequence> getSuggestions(View view, WordComposer wordComposer, + boolean includeTypedWordIfValid) { + mHaveCorrection = false; + mCapitalize = wordComposer.isCapitalized(); + collectGarbage(); + Arrays.fill(mPriorities, 0); + Arrays.fill(mNextLettersFrequencies, 0); + + // Save a lowercase version of the original word + mOriginalWord = wordComposer.getTypedWord(); + if (mOriginalWord != null) { + mOriginalWord = mOriginalWord.toString(); + mLowerOriginalWord = mOriginalWord.toString().toLowerCase(); + } else { + mLowerOriginalWord = ""; + } + // Search the dictionary only if there are at least 2 characters + if (wordComposer.size() > 1) { + 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) { + mHaveCorrection = true; + } + } + mMainDict.getWords(wordComposer, this, mNextLettersFrequencies); + if (mCorrectionMode == CORRECTION_FULL && 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 (mCorrectionMode == CORRECTION_FULL && mSuggestions.size() > 1) { + 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, final int freq) { + int pos = 0; + final int[] priorities = mPriorities; + final int prefMaxSuggestions = mPrefMaxSuggestions; + // Check if it's the same word, only caps are different + if (compareCaseInsensitive(mLowerOriginalWord, word, offset, length)) { + pos = 0; + } else { + // 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 < mSuggestions + .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(32); + sb.setLength(0); + if (mCapitalize) { + sb.append(Character.toUpperCase(word[offset])); + if (length > 1) { + sb.append(word, offset + 1, length - 1); + } + } else { + sb.append(word, offset, length); + } + mSuggestions.add(pos, sb); + if (mSuggestions.size() > prefMaxSuggestions) { + CharSequence garbage = mSuggestions.remove(prefMaxSuggestions); + if (garbage instanceof StringBuilder) { + mStringPool.add(garbage); + } + } + return true; + } + + public boolean isValidWord(final CharSequence word) { + if (word == null || word.length() == 0) { + return false; + } + return (mCorrectionMode == CORRECTION_FULL && mMainDict.isValidWord(word)) + || (mCorrectionMode > CORRECTION_NONE && + ((mUserDictionary != null && mUserDictionary.isValidWord(word))) + || (mAutoDictionary != null && mAutoDictionary.isValidWord(word)) + || (mContactsDictionary != null && mContactsDictionary.isValidWord(word))); + } + + private void collectGarbage() { + int poolSize = mStringPool.size(); + int garbageSize = mSuggestions.size(); + while (poolSize < mPrefMaxSuggestions && garbageSize > 0) { + CharSequence garbage = mSuggestions.get(garbageSize - 1); + if (garbage != null && garbage instanceof StringBuilder) { + mStringPool.add(garbage); + poolSize++; + } + garbageSize--; + } + if (poolSize == mPrefMaxSuggestions + 1) { + Log.w("Suggest", "String pool got too big: " + poolSize); + } + mSuggestions.clear(); + } + + public void close() { + if (mMainDict != null) { + mMainDict.close(); + } + } +} diff --git a/java/src/com/android/inputmethod/latin/TextEntryState.java b/java/src/com/android/inputmethod/latin/TextEntryState.java new file mode 100644 index 000000000..c5e8ad9a1 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/TextEntryState.java @@ -0,0 +1,233 @@ +/* + * 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.latin; + +import android.content.Context; +import android.text.format.DateFormat; +import android.util.Log; + +import android.inputmethodservice.Keyboard.Key; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Calendar; + +public class 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; + + private static final String[] STATES = { + "Unknown", + "Start", + "In word", + "Accepted default", + "Picked suggestion", + "Punc. after word", + "Punc. after accepted", + "Space after accepted", + "Space after picked", + "Undo commit" + }; + + public static final int STATE_UNKNOWN = 0; + public static final int STATE_START = 1; + public static final int STATE_IN_WORD = 2; + public static final int STATE_ACCEPTED_DEFAULT = 3; + public static final int STATE_PICKED_SUGGESTION = 4; + public static final int STATE_PUNCTUATION_AFTER_WORD = 5; + public static final int STATE_PUNCTUATION_AFTER_ACCEPTED = 6; + public static final int STATE_SPACE_AFTER_ACCEPTED = 7; + public static final int STATE_SPACE_AFTER_PICKED = 8; + public static final int STATE_UNDO_COMMIT = 9; + + private static int 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; + } + + public static void acceptedTyped(CharSequence typedWord) { + sWordNotInDictionaryCount++; + sState = STATE_PICKED_SUGGESTION; + } + + public static void acceptedSuggestion(CharSequence typedWord, CharSequence actualWord) { + sManualSuggestCount++; + if (typedWord.equals(actualWord)) { + acceptedTyped(typedWord); + } + sState = STATE_PICKED_SUGGESTION; + } + + public static void typedCharacter(char c, boolean isSeparator) { + boolean isSpace = c == ' '; + switch (sState) { + case STATE_IN_WORD: + if (isSpace || isSeparator) { + sState = STATE_START; + } else { + // State hasn't changed. + } + break; + case STATE_ACCEPTED_DEFAULT: + case STATE_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 STATE_PICKED_SUGGESTION: + if (isSpace) { + sState = STATE_SPACE_AFTER_PICKED; + } else if (isSeparator) { + // Swap + sState = STATE_PUNCTUATION_AFTER_ACCEPTED; + } else { + sState = STATE_IN_WORD; + } + break; + case STATE_START: + case STATE_UNKNOWN: + case STATE_SPACE_AFTER_ACCEPTED: + case STATE_PUNCTUATION_AFTER_ACCEPTED: + case STATE_PUNCTUATION_AFTER_WORD: + if (!isSpace && !isSeparator) { + sState = STATE_IN_WORD; + } else { + sState = STATE_START; + } + break; + case STATE_UNDO_COMMIT: + if (isSpace || isSeparator) { + sState = STATE_ACCEPTED_DEFAULT; + } else { + sState = STATE_IN_WORD; + } + } + } + + public static void backspace() { + if (sState == STATE_ACCEPTED_DEFAULT) { + sState = STATE_UNDO_COMMIT; + sAutoSuggestUndoneCount++; + } else if (sState == STATE_UNDO_COMMIT) { + sState = STATE_IN_WORD; + } + sBackspaceCount++; + } + + public static void reset() { + sState = STATE_START; + } + + public static int getState() { + return sState; + } + + 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 + } + } + } +} + diff --git a/java/src/com/android/inputmethod/latin/Tutorial.java b/java/src/com/android/inputmethod/latin/Tutorial.java new file mode 100644 index 000000000..03d4858c4 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/Tutorial.java @@ -0,0 +1,251 @@ +/* + * 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.latin; + +import android.content.Context; +import android.graphics.Rect; +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 long mStartTime; + private static final long MINIMUM_TIME = 6000; + private static final long MAXIMUM_TIME = 20000; + private View mInputView; + private LatinIME mIme; + private int[] mLocation = new int[2]; + private int mBubblePointerOffset; + + 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 + mBubblePointerOffset = inputView.getContext().getResources() + .getDimensionPixelOffset(R.dimen.bubble_pointer_offset); + 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/com/android/inputmethod/latin/UserDictionary.java b/java/src/com/android/inputmethod/latin/UserDictionary.java new file mode 100644 index 000000000..4b98eacce --- /dev/null +++ b/java/src/com/android/inputmethod/latin/UserDictionary.java @@ -0,0 +1,138 @@ +/* + * 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 com.android.inputmethod.latin; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import android.content.ContentResolver; +import android.content.ContentValues; +import android.content.Context; +import android.database.ContentObserver; +import android.database.Cursor; +import android.net.Uri; +import android.provider.UserDictionary.Words; + +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 ContentObserver mObserver; + + private boolean mRequiresReload; + private String mLocale; + + public UserDictionary(Context context, String locale) { + super(context); + 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) { + mRequiresReload = true; + } + }); + + loadDictionary(); + } + + public synchronized void close() { + if (mObserver != null) { + getContext().getContentResolver().unregisterContentObserver(mObserver); + mObserver = null; + } + } + + private synchronized void loadDictionary() { + Cursor cursor = getContext().getContentResolver() + .query(Words.CONTENT_URI, PROJECTION, "(locale IS NULL) or (locale=?)", + new String[] { mLocale }, null); + addWords(cursor); + mRequiresReload = false; + } + + /** + * 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) { + if (mRequiresReload) loadDictionary(); + // Safeguard against adding long words. Can cause stack overflow. + if (word.length() >= getMaxWordLength()) return; + + super.addWord(word, frequency); + + // Update the user dictionary provider + 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); + + getContext().getContentResolver().insert(Words.CONTENT_URI, values); + // In case the above does a synchronous callback of the change observer + mRequiresReload = false; + } + + @Override + public synchronized void getWords(final WordComposer codes, final WordCallback callback, + int[] nextLettersFrequencies) { + if (mRequiresReload) loadDictionary(); + super.getWords(codes, callback, nextLettersFrequencies); + } + + @Override + public synchronized boolean isValidWord(CharSequence word) { + if (mRequiresReload) loadDictionary(); + return super.isValidWord(word); + } + + private void addWords(Cursor cursor) { + 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/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java new file mode 100644 index 000000000..e97cb24ba --- /dev/null +++ b/java/src/com/android/inputmethod/latin/WordComposer.java @@ -0,0 +1,174 @@ +/* + * 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.latin; + +import java.util.ArrayList; +import java.util.List; + +/** + * 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 ArrayList<int[]> mCodes; + + /** + * The word chosen from the candidate list, until it is committed. + */ + private String mPreferredWord; + + private StringBuilder mTypedWord; + + private int mCapsCount; + + private boolean mAutoCapitalized; + + /** + * Whether the user chose to capitalize the word. + */ + private boolean mIsCapitalized; + + WordComposer() { + mCodes = new ArrayList<int[]>(12); + mTypedWord = new StringBuilder(20); + } + + /** + * Clear out the keys registered so far. + */ + public void reset() { + mCodes.clear(); + mIsCapitalized = 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); + mCodes.add(codes); + if (Character.isUpperCase((char) primaryCode)) mCapsCount++; + } + + /** + * Delete the last keystroke as a result of hitting backspace. + */ + public void deleteLast() { + mCodes.remove(mCodes.size() - 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; + } +// StringBuffer sb = new StringBuffer(wordSize); +// for (int i = 0; i < wordSize; i++) { +// char c = (char) mCodes.get(i)[0]; +// if (i == 0 && mIsCapitalized) { +// c = Character.toUpperCase(c); +// } +// sb.append(c); +// } +// return sb; + return mTypedWord; + } + + public void setCapitalized(boolean capitalized) { + mIsCapitalized = capitalized; + } + + /** + * Whether or not the user typed a capital letter as the first letter in the word + * @return capitalization preference + */ + public boolean isCapitalized() { + return mIsCapitalized; + } + + /** + * 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/java/src/com/android/inputmethod/voice/EditingUtil.java b/java/src/com/android/inputmethod/voice/EditingUtil.java new file mode 100644 index 000000000..6316d8ccf --- /dev/null +++ b/java/src/com/android/inputmethod/voice/EditingUtil.java @@ -0,0 +1,162 @@ +/* + * 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.view.inputmethod.ExtractedText; +import android.view.inputmethod.ExtractedTextRequest; +import android.view.inputmethod.InputConnection; + +/** + * Utility methods to deal with editing text through an InputConnection. + */ +public class EditingUtil { + 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; + } + + private static int getSelectionEnd(InputConnection connection) { + ExtractedText extracted = connection.getExtractedText( + new ExtractedTextRequest(), 0); + if (extracted == null) { + return -1; + } + return extracted.startOffset + extracted.selectionEnd; + } + + /** + * @param connection connection to the current text field. + * @param sep characters which may separate words + * @return the word that surrounds the cursor, including up to one trailing + * separator. For example, if the field contains "he|llo world", where | + * represents the cursor, then "hello " will be returned. + */ + public static String getWordAtCursor( + InputConnection connection, String separators) { + Range range = getWordRangeAtCursor(connection, separators); + return (range == null) ? null : range.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); + 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. + */ + private static class Range { + /** Characters before selection start */ + int charsBefore; + + /** + * Characters after selection start, including one trailing word + * separator. + */ + int charsAfter; + + /** The actual characters that make up a word */ + String word; + + 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) { + 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)); + + // Find last word separator after the cursor + int end = -1; + while (++end < after.length() && !isWhitespace(after.charAt(end), sep)); + if (end < after.length() - 1) { + end++; // Include trailing space, if it exists, in word + } + + 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); + return new Range(before.length() - start, end, word); + } + + return null; + } + + private static boolean isWhitespace(int code, String whitespace) { + return whitespace.contains(String.valueOf((char) code)); + } +} 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 000000000..5fbacfb6c --- /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/LatinIMEWithVoice.java b/java/src/com/android/inputmethod/voice/LatinIMEWithVoice.java new file mode 100644 index 000000000..ccbf5b6bc --- /dev/null +++ b/java/src/com/android/inputmethod/voice/LatinIMEWithVoice.java @@ -0,0 +1,28 @@ +/* + * 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.Intent; + +import com.android.inputmethod.latin.LatinIME; + +public class LatinIMEWithVoice extends LatinIME { + @Override + protected void launchSettings() { + launchSettings(LatinIMEWithVoiceSettings.class); + } +} diff --git a/java/src/com/android/inputmethod/voice/LatinIMEWithVoiceSettings.java b/java/src/com/android/inputmethod/voice/LatinIMEWithVoiceSettings.java new file mode 100644 index 000000000..13a58e14d --- /dev/null +++ b/java/src/com/android/inputmethod/voice/LatinIMEWithVoiceSettings.java @@ -0,0 +1,21 @@ +/* + * 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 com.android.inputmethod.latin.LatinIMESettings; + +public class LatinIMEWithVoiceSettings extends LatinIMESettings {} 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 000000000..1e99c3cf7 --- /dev/null +++ b/java/src/com/android/inputmethod/voice/RecognitionView.java @@ -0,0 +1,324 @@ +/* + * 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 com.android.inputmethod.latin.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 - 10; + Path path = new Path(); + c.translate(0, yMax); + float x = 0; + path.moveTo(x, 0); + yMax -= 10; + 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_DIP, + -h / 2 - 18, 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 000000000..abf52047f --- /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 000000000..e881856dd --- /dev/null +++ b/java/src/com/android/inputmethod/voice/VoiceInput.java @@ -0,0 +1,508 @@ +/* + * 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 com.android.inputmethod.latin.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.speech.RecognitionListener; +import android.speech.RecognitionManager; +import android.speech.RecognizerIntent; +import android.util.Log; +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 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 = false; + + // 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 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 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 RecognitionManager mRecognitionManager; + 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(); + mRecognitionManager = RecognitionManager.createRecognitionManager(context); + mRecognitionManager.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"); + } + + /** + * 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(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 */); + + mRecognitionManager.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() { + mRecognitionManager.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 logTextModified() { + mLogger.textModified(); + } + + 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() { + mLogger.voiceInputDelivered(); + } + + public void logNBestChoose(int index) { + mLogger.nBestChoose(index); + } + + 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); + + mRecognitionManager.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 RecognitionManager.ERROR_CLIENT: + return R.string.voice_not_installed; + case RecognitionManager.ERROR_NETWORK: + return R.string.voice_network_error; + case RecognitionManager.ERROR_NETWORK_TIMEOUT: + return endpointed ? + R.string.voice_network_error : R.string.voice_too_much_speech; + case RecognitionManager.ERROR_AUDIO: + return R.string.voice_audio_error; + case RecognitionManager.ERROR_SERVER: + return R.string.voice_server_error; + case RecognitionManager.ERROR_SPEECH_TIMEOUT: + return R.string.voice_speech_timeout; + case RecognitionManager.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(RecognitionManager.RESULTS_RECOGNITION); + mState = DEFAULT; + + final Map<String, List<CharSequence>> alternatives = + new HashMap<String, List<CharSequence>>(); + if (results.size() >= 2 && ENABLE_WORD_CORRECTIONS) { + final String[][] words = new String[results.size()][]; + for (int i = 0; i < words.length; i++) { + words[i] = results.get(i).split(" "); + } + + for (int key = 0; key < words[0].length; key++) { + alternatives.put(words[0][key], new ArrayList<CharSequence>()); + for (int alt = 1; alt < words.length; alt++) { + int keyBegin = key * words[alt].length / words[0].length; + int keyEnd = (key + 1) * words[alt].length / words[0].length; + + for (int i = keyBegin; i < Math.min(words[alt].length, keyEnd); i++) { + List<CharSequence> altList = alternatives.get(words[0][key]); + if (!altList.contains(words[alt][i]) && altList.size() < 6) { + altList.add(words[alt][i]); + } + } + } + } + } + + 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 000000000..659033340 --- /dev/null +++ b/java/src/com/android/inputmethod/voice/VoiceInputLogger.java @@ -0,0 +1,177 @@ +/* + * 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 com.android.common.speech.LoggingEvents; + +import android.content.Context; +import android.content.Intent; + +/** + * 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 final String TAG = VoiceInputLogger.class.getSimpleName(); + + private static VoiceInputLogger sVoiceInputLogger; + + private final Context mContext; + + // The base intent used to form all broadcast intents to the logger + // in VoiceSearch. + private final Intent mBaseIntent; + + /** + * 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) { + mContext = context; + + mBaseIntent = new Intent(LoggingEvents.ACTION_LOG_EVENT); + mBaseIntent.putExtra(LoggingEvents.EXTRA_APP_NAME, LoggingEvents.VoiceIme.APP_NAME); + } + + private Intent newLoggingBroadcast(int event) { + Intent i = new Intent(mBaseIntent); + i.putExtra(LoggingEvents.EXTRA_EVENT, event); + return i; + } + + public void flush() { + Intent i = new Intent(mBaseIntent); + i.putExtra(LoggingEvents.EXTRA_FLUSH, true); + mContext.sendBroadcast(i); + } + + public void keyboardWarningDialogShown() { + mContext.sendBroadcast(newLoggingBroadcast( + LoggingEvents.VoiceIme.KEYBOARD_WARNING_DIALOG_SHOWN)); + } + + public void keyboardWarningDialogDismissed() { + mContext.sendBroadcast(newLoggingBroadcast( + LoggingEvents.VoiceIme.KEYBOARD_WARNING_DIALOG_DISMISSED)); + } + + public void keyboardWarningDialogOk() { + mContext.sendBroadcast(newLoggingBroadcast( + LoggingEvents.VoiceIme.KEYBOARD_WARNING_DIALOG_OK)); + } + + public void keyboardWarningDialogCancel() { + mContext.sendBroadcast(newLoggingBroadcast( + LoggingEvents.VoiceIme.KEYBOARD_WARNING_DIALOG_CANCEL)); + } + + public void settingsWarningDialogShown() { + mContext.sendBroadcast(newLoggingBroadcast( + LoggingEvents.VoiceIme.SETTINGS_WARNING_DIALOG_SHOWN)); + } + + public void settingsWarningDialogDismissed() { + mContext.sendBroadcast(newLoggingBroadcast( + LoggingEvents.VoiceIme.SETTINGS_WARNING_DIALOG_DISMISSED)); + } + + public void settingsWarningDialogOk() { + mContext.sendBroadcast(newLoggingBroadcast( + LoggingEvents.VoiceIme.SETTINGS_WARNING_DIALOG_OK)); + } + + public void settingsWarningDialogCancel() { + mContext.sendBroadcast(newLoggingBroadcast( + LoggingEvents.VoiceIme.SETTINGS_WARNING_DIALOG_CANCEL)); + } + + public void swipeHintDisplayed() { + mContext.sendBroadcast(newLoggingBroadcast(LoggingEvents.VoiceIme.SWIPE_HINT_DISPLAYED)); + } + + public void cancelDuringListening() { + mContext.sendBroadcast(newLoggingBroadcast(LoggingEvents.VoiceIme.CANCEL_DURING_LISTENING)); + } + + public void cancelDuringWorking() { + mContext.sendBroadcast(newLoggingBroadcast(LoggingEvents.VoiceIme.CANCEL_DURING_WORKING)); + } + + public void cancelDuringError() { + mContext.sendBroadcast(newLoggingBroadcast(LoggingEvents.VoiceIme.CANCEL_DURING_ERROR)); + } + + public void punctuationHintDisplayed() { + mContext.sendBroadcast(newLoggingBroadcast( + LoggingEvents.VoiceIme.PUNCTUATION_HINT_DISPLAYED)); + } + + public void error(int code) { + Intent i = newLoggingBroadcast(LoggingEvents.VoiceIme.ERROR); + i.putExtra(LoggingEvents.VoiceIme.EXTRA_ERROR_CODE, code); + mContext.sendBroadcast(i); + } + + public void start(String locale, boolean swipe) { + Intent i = newLoggingBroadcast(LoggingEvents.VoiceIme.START); + i.putExtra(LoggingEvents.VoiceIme.EXTRA_START_LOCALE, locale); + i.putExtra(LoggingEvents.VoiceIme.EXTRA_START_SWIPE, swipe); + i.putExtra(LoggingEvents.EXTRA_TIMESTAMP, System.currentTimeMillis()); + mContext.sendBroadcast(i); + } + + public void voiceInputDelivered() { + mContext.sendBroadcast(newLoggingBroadcast(LoggingEvents.VoiceIme.VOICE_INPUT_DELIVERED)); + } + + public void textModified() { + mContext.sendBroadcast(newLoggingBroadcast(LoggingEvents.VoiceIme.TEXT_MODIFIED)); + } + + public void nBestChoose(int index) { + Intent i = newLoggingBroadcast(LoggingEvents.VoiceIme.N_BEST_CHOOSE); + i.putExtra(LoggingEvents.VoiceIme.EXTRA_N_BEST_CHOOSE_INDEX, index); + mContext.sendBroadcast(i); + } + + public void inputEnded() { + mContext.sendBroadcast(newLoggingBroadcast(LoggingEvents.VoiceIme.INPUT_ENDED)); + } + + public void voiceInputSettingEnabled() { + mContext.sendBroadcast(newLoggingBroadcast( + LoggingEvents.VoiceIme.VOICE_INPUT_SETTING_ENABLED)); + } + + public void voiceInputSettingDisabled() { + mContext.sendBroadcast(newLoggingBroadcast( + LoggingEvents.VoiceIme.VOICE_INPUT_SETTING_DISABLED)); + } +} 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 000000000..08d87c8f3 --- /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 000000000..167b688ca --- /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/com/google/android/voicesearch/LatinIMEWithVoice.java b/java/src/com/google/android/voicesearch/LatinIMEWithVoice.java new file mode 100644 index 000000000..8a339d14a --- /dev/null +++ b/java/src/com/google/android/voicesearch/LatinIMEWithVoice.java @@ -0,0 +1,29 @@ +/* + * + * 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.google.android.voicesearch; + +import android.content.Intent; + +import com.android.inputmethod.latin.LatinIME; + +public class LatinIMEWithVoice extends LatinIME { + @Override + protected void launchSettings() { + launchSettings(LatinIMEWithVoiceSettings.class); + } +} diff --git a/java/src/com/google/android/voicesearch/LatinIMEWithVoiceSettings.java b/java/src/com/google/android/voicesearch/LatinIMEWithVoiceSettings.java new file mode 100644 index 000000000..a53cebfd9 --- /dev/null +++ b/java/src/com/google/android/voicesearch/LatinIMEWithVoiceSettings.java @@ -0,0 +1,5 @@ +package com.google.android.voicesearch; + +import com.android.inputmethod.latin.LatinIMESettings; + +public class LatinIMEWithVoiceSettings extends LatinIMESettings {} |