Merge remote-tracking branch 'goog/master' into mergescriptpackage

Conflicts:
	java/res/values-af/strings.xml
	java/res/values-cs/strings.xml
	java/res/values-et/strings.xml
	java/res/values-fi/strings.xml
	java/res/values-hi/strings.xml
	java/res/values-hr/strings.xml
	java/res/values-hu/strings.xml
	java/res/values-in/strings.xml
	java/res/values-ja/strings.xml
	java/res/values-ko/strings.xml
	java/res/values-lt/strings.xml
	java/res/values-lv/strings.xml
	java/res/values-ms/strings.xml
	java/res/values-pt/strings.xml
	java/res/values-ro/strings.xml
	java/res/values-ru/strings.xml
	java/res/values-sk/strings.xml
	java/res/values-sl/strings.xml
	java/res/values-sr/strings.xml
	java/res/values-sw/strings.xml
	java/res/values-tr/strings.xml
	java/res/values-vi/strings.xml
	java/res/values-zh-rCN/strings.xml
	java/res/values-zh-rTW/strings.xml

Change-Id: Ib4141aca0b35148d62d22d4f32309f890c84303a
main
Satoshi Kataoka 2012-08-06 16:04:07 +09:00
commit 44456dcbf2
159 changed files with 3839 additions and 2114 deletions

View File

@ -28,9 +28,7 @@ LOCAL_JNI_SHARED_LIBRARIES := libjni_latinime
# We want to install libjni_latinime.so to the system partition if LatinIME gets installed. # We want to install libjni_latinime.so to the system partition if LatinIME gets installed.
LOCAL_REQUIRED_MODULES := libjni_latinime LOCAL_REQUIRED_MODULES := libjni_latinime
LOCAL_STATIC_JAVA_LIBRARIES := android-common LOCAL_STATIC_JAVA_LIBRARIES := android-common inputmethod-common android-support-v4
LOCAL_STATIC_JAVA_LIBRARIES += inputmethod-common
LOCAL_STATIC_JAVA_LIBRARIES += android-support-v4
# Do not compress dictionary files to mmap dict data runtime # Do not compress dictionary files to mmap dict data runtime
LOCAL_AAPT_FLAGS := -0 .dict LOCAL_AAPT_FLAGS := -0 .dict

View File

@ -18,6 +18,8 @@
coreApp="true" coreApp="true"
package="com.android.inputmethod.latin"> package="com.android.inputmethod.latin">
<uses-sdk android:minSdkVersion="16" android:targetSdkVersion="16" />
<uses-permission android:name="android.permission.VIBRATE"/> <uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.READ_USER_DICTIONARY" /> <uses-permission android:name="android.permission.READ_USER_DICTIONARY" />
@ -26,7 +28,8 @@
<application android:label="@string/aosp_android_keyboard_ime_name" <application android:label="@string/aosp_android_keyboard_ime_name"
android:icon="@drawable/ic_ime_settings" android:icon="@drawable/ic_ime_settings"
android:backupAgent="BackupAgent" android:backupAgent="BackupAgent"
android:killAfterRestore="false"> android:killAfterRestore="false"
android:supportsRtl="true">
<service android:name="LatinIME" <service android:name="LatinIME"
android:label="@string/aosp_android_keyboard_ime_name" android:label="@string/aosp_android_keyboard_ime_name"

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"Gebaseer op vorige woord"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"Gebaseer op vorige woord"</string>
<string name="gesture_input" msgid="3310827802759290774">"Gebaarinvoer"</string> <string name="gesture_input" msgid="3310827802759290774">"Gebaarinvoer"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"Voer \'n woord in deur die letters van \'n woord te trek"</string> <string name="gesture_input_summary" msgid="7019742443455085809">"Voer \'n woord in deur die letters van \'n woord te trek"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"Wys gebaarspoor"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"Wys gebaar se woord"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"Wys swewende voorskouwoord saam met die gebaar"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Gestoor"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Gestoor"</string>
<string name="label_go_key" msgid="1635148082137219148">"Gaan"</string> <string name="label_go_key" msgid="1635148082137219148">"Gaan"</string>
<string name="label_next_key" msgid="362972844525672568">"Volgende"</string> <string name="label_next_key" msgid="362972844525672568">"Volgende"</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string> <string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"Soek"</string> <string name="spoken_description_search" msgid="1247236163755920808">"Soek"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Punt"</string> <string name="spoken_description_dot" msgid="40711082435231673">"Punt"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"Verander taal"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"Volgende"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"Vorige"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift geaktiveer"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift geaktiveer"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Kasslot geaktiveer"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Kasslot geaktiveer"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift gedeaktiveer"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift gedeaktiveer"</string>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"በቀዳሚው ቃል ላይ የተመሠረተ"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"በቀዳሚው ቃል ላይ የተመሠረተ"</string>
<string name="gesture_input" msgid="3310827802759290774">"የእጅ ምልክት ግብዓት"</string> <string name="gesture_input" msgid="3310827802759290774">"የእጅ ምልክት ግብዓት"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"የአንድ ቃል ፊደሎችን በመከታተል አንድ ቃል አስገባ"</string> <string name="gesture_input_summary" msgid="7019742443455085809">"የአንድ ቃል ፊደሎችን በመከታተል አንድ ቃል አስገባ"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"ምልክት የሚሄድበት መንገድ አሳይ"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"የምልክት ቃል አሳይ"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"ተንሳፋፊ የቅድመ እይታ ቃል ከምልክት ጋር አሳይ"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : ተቀምጧል"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : ተቀምጧል"</string>
<string name="label_go_key" msgid="1635148082137219148">"ሂድ"</string> <string name="label_go_key" msgid="1635148082137219148">"ሂድ"</string>
<string name="label_next_key" msgid="362972844525672568">"በመቀጠል"</string> <string name="label_next_key" msgid="362972844525672568">"በመቀጠል"</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"ተመለስ"</string> <string name="spoken_description_return" msgid="8178083177238315647">"ተመለስ"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"ፍለጋ"</string> <string name="spoken_description_search" msgid="1247236163755920808">"ፍለጋ"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"ነጥብ"</string> <string name="spoken_description_dot" msgid="40711082435231673">"ነጥብ"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"ቋንቋ ቀይር"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"ቀጣይ"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"ቀዳሚ"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"ቅያር ቁልፍ ነቅቷል"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"ቅያር ቁልፍ ነቅቷል"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"አቢያት ማድረጊያ ነቅቷል"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"አቢያት ማድረጊያ ነቅቷል"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"ቅያር ተሰናክሏል"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"ቅያር ተሰናክሏል"</string>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"استنادًا إلى الكلمة السابقة"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"استنادًا إلى الكلمة السابقة"</string>
<string name="gesture_input" msgid="3310827802759290774">"إدخال الإيماءة"</string> <string name="gesture_input" msgid="3310827802759290774">"إدخال الإيماءة"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"يمكنك إدخال كلمة من خلال تتبع أحرف كلمة ما"</string> <string name="gesture_input_summary" msgid="7019742443455085809">"يمكنك إدخال كلمة من خلال تتبع أحرف كلمة ما"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"عرض مسار الإيماءة"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"عرض كلمة الإيماءة"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"عرض كلمة معاينة متحركة مع الإيماءة"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : تم الحفظ"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : تم الحفظ"</string>
<string name="label_go_key" msgid="1635148082137219148">"تنفيذ"</string> <string name="label_go_key" msgid="1635148082137219148">"تنفيذ"</string>
<string name="label_next_key" msgid="362972844525672568">"التالي"</string> <string name="label_next_key" msgid="362972844525672568">"التالي"</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"رجوع"</string> <string name="spoken_description_return" msgid="8178083177238315647">"رجوع"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"بحث"</string> <string name="spoken_description_search" msgid="1247236163755920808">"بحث"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"نقطة"</string> <string name="spoken_description_dot" msgid="40711082435231673">"نقطة"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"تبديل اللغة"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"التالي"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"السابق"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"تم تمكين Shift"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"تم تمكين Shift"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"تم تمكين Caps lock"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"تم تمكين Caps lock"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"تم تعطيل Shift"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"تم تعطيل Shift"</string>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"На аснове папярэдняга слова"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"На аснове папярэдняга слова"</string>
<string name="gesture_input" msgid="3310827802759290774">"Уваход жэстам"</string> <string name="gesture_input" msgid="3310827802759290774">"Уваход жэстам"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"Увядзiце слова, адсочваючы лiтары"</string> <string name="gesture_input_summary" msgid="7019742443455085809">"Увядзiце слова, адсочваючы лiтары"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"Паказаць след жэста"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"Паказаць слова жэста"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"Паказаць плаваючы прагляд слова з жэстам"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Захаваныя"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Захаваныя"</string>
<string name="label_go_key" msgid="1635148082137219148">"Пачаць"</string> <string name="label_go_key" msgid="1635148082137219148">"Пачаць"</string>
<string name="label_next_key" msgid="362972844525672568">"Далей"</string> <string name="label_next_key" msgid="362972844525672568">"Далей"</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"Увод"</string> <string name="spoken_description_return" msgid="8178083177238315647">"Увод"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"Пошук"</string> <string name="spoken_description_search" msgid="1247236163755920808">"Пошук"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Кропка"</string> <string name="spoken_description_dot" msgid="40711082435231673">"Кропка"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"Пераключыць мову"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"Далей"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"Назад"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift уключаны"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift уключаны"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps Lock уключаны"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps Lock уключаны"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift адключаны"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift адключаны"</string>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"Въз основа на предишната дума"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"Въз основа на предишната дума"</string>
<string name="gesture_input" msgid="3310827802759290774">"Въвеждане чрез жест"</string> <string name="gesture_input" msgid="3310827802759290774">"Въвеждане чрез жест"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"Въвеждане на дума чрез проследяване на буквите й"</string> <string name="gesture_input_summary" msgid="7019742443455085809">"Въвеждане на дума чрез проследяване на буквите й"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"Следа на жестовете: Показване"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"Показване на дума при жестове"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"Показване на дума с плаваща визуализация при жест"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Запазено"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Запазено"</string>
<string name="label_go_key" msgid="1635148082137219148">"Старт"</string> <string name="label_go_key" msgid="1635148082137219148">"Старт"</string>
<string name="label_next_key" msgid="362972844525672568">"Напред"</string> <string name="label_next_key" msgid="362972844525672568">"Напред"</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"Return"</string> <string name="spoken_description_return" msgid="8178083177238315647">"Return"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"Търсене"</string> <string name="spoken_description_search" msgid="1247236163755920808">"Търсене"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Точка"</string> <string name="spoken_description_dot" msgid="40711082435231673">"Точка"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"Смяна на езика"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"Следващ"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"Предишен"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"„Shift“ е активиран"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"„Shift“ е активиран"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"„Caps Lock“ е активиран"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"„Caps Lock“ е активиран"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"„Shift“ е деактивиран"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"„Shift“ е деактивиран"</string>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"En funció de la paraula anterior"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"En funció de la paraula anterior"</string>
<string name="gesture_input" msgid="3310827802759290774">"Entrada de gestos"</string> <string name="gesture_input" msgid="3310827802759290774">"Entrada de gestos"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"Dibuixa les lletres d\'una paraula per escriure-la"</string> <string name="gesture_input_summary" msgid="7019742443455085809">"Dibuixa les lletres d\'una paraula per escriure-la"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"Mostra el recorregut del gest"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"Mostra paraules en fer gestos"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"Mostra la paraula de visualització prèvia flotant en fer gestos"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: desada"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: desada"</string>
<string name="label_go_key" msgid="1635148082137219148">"Vés"</string> <string name="label_go_key" msgid="1635148082137219148">"Vés"</string>
<string name="label_next_key" msgid="362972844525672568">"Següent"</string> <string name="label_next_key" msgid="362972844525672568">"Següent"</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"Retorn"</string> <string name="spoken_description_return" msgid="8178083177238315647">"Retorn"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"Cerca"</string> <string name="spoken_description_search" msgid="1247236163755920808">"Cerca"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Punt"</string> <string name="spoken_description_dot" msgid="40711082435231673">"Punt"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"Canvia l\'idioma"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"Següent"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"Anterior"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Maj activat"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Maj activat"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Bloq Maj activat"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Bloq Maj activat"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Maj desactivat"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Maj desactivat"</string>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"Na základě předchozího slova"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"Na základě předchozího slova"</string>
<string name="gesture_input" msgid="3310827802759290774">"Zadávání gesty"</string> <string name="gesture_input" msgid="3310827802759290774">"Zadávání gesty"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"Napište slovo zadáním jeho písmen."</string> <string name="gesture_input_summary" msgid="7019742443455085809">"Napište slovo zadáním jeho písmen."</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"Zobrazovat stopu gesta"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"Zobrazovat slovo gesta"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"Zobrazovat plovoucí náhled slova gesta"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: Uloženo"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: Uloženo"</string>
<string name="label_go_key" msgid="1635148082137219148">"Přejít"</string> <string name="label_go_key" msgid="1635148082137219148">"Přejít"</string>
<string name="label_next_key" msgid="362972844525672568">"Další"</string> <string name="label_next_key" msgid="362972844525672568">"Další"</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string> <string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"vyhledávací tlačítko"</string> <string name="spoken_description_search" msgid="1247236163755920808">"vyhledávací tlačítko"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Tečka"</string> <string name="spoken_description_dot" msgid="40711082435231673">"Tečka"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"Přepnout jazyk"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"Další"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"Předchozí"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Klávesa Shift je aktivní"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Klávesa Shift je aktivní"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Klávesa Caps Lock je aktivní"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Klávesa Caps Lock je aktivní"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Klávesa Shift je neaktivní"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Klávesa Shift je neaktivní"</string>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"Baseret på tidligere ord"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"Baseret på tidligere ord"</string>
<string name="gesture_input" msgid="3310827802759290774">"Berøringsindtastning"</string> <string name="gesture_input" msgid="3310827802759290774">"Berøringsindtastning"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"Indtast et ord ved at skrive bogstaverne for et ord med fingeren"</string> <string name="gesture_input_summary" msgid="7019742443455085809">"Indtast et ord ved at skrive bogstaverne for et ord med fingeren"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"Vis spor af berøring"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"Vis berøringsord"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"Vis flydende eksempelord under berøring"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: Gemt"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: Gemt"</string>
<string name="label_go_key" msgid="1635148082137219148">"Gå"</string> <string name="label_go_key" msgid="1635148082137219148">"Gå"</string>
<string name="label_next_key" msgid="362972844525672568">"Næste"</string> <string name="label_next_key" msgid="362972844525672568">"Næste"</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"Tilbage"</string> <string name="spoken_description_return" msgid="8178083177238315647">"Tilbage"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"Søg"</string> <string name="spoken_description_search" msgid="1247236163755920808">"Søg"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Punktum"</string> <string name="spoken_description_dot" msgid="40711082435231673">"Punktum"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"Skift sprog"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"Næste"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"Forrige"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Skift er aktiveret"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Skift er aktiveret"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps lock er aktiveret"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps lock er aktiveret"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Skift er deaktiveret"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Skift er deaktiveret"</string>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"Auf Grundlage des vorherigen Wortes"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"Auf Grundlage des vorherigen Wortes"</string>
<string name="gesture_input" msgid="3310827802759290774">"Bewegungseingabe"</string> <string name="gesture_input" msgid="3310827802759290774">"Bewegungseingabe"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"Wort durch Nachzeichnen der Buchstaben eingeben"</string> <string name="gesture_input_summary" msgid="7019742443455085809">"Wort durch Nachzeichnen der Buchstaben eingeben"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"Spur der Bewegung anzeigen"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"Wort bei Bewegung anzeigen"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"Vorgeschlagenes Wort bei Bewegung anzeigen"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: gespeichert"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: gespeichert"</string>
<string name="label_go_key" msgid="1635148082137219148">"Los"</string> <string name="label_go_key" msgid="1635148082137219148">"Los"</string>
<string name="label_next_key" msgid="362972844525672568">"Weiter"</string> <string name="label_next_key" msgid="362972844525672568">"Weiter"</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"Eingabe"</string> <string name="spoken_description_return" msgid="8178083177238315647">"Eingabe"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"Suchen"</string> <string name="spoken_description_search" msgid="1247236163755920808">"Suchen"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Aufzählungspunkt"</string> <string name="spoken_description_dot" msgid="40711082435231673">"Aufzählungspunkt"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"Sprache wechseln"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"Nächste"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"Vorherige"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Umschalttaste aktiviert"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Umschalttaste aktiviert"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Feststelltaste aktiviert"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Feststelltaste aktiviert"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Umschalttaste deaktiviert"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Umschalttaste deaktiviert"</string>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"Βάσει προηγούμενης λέξης"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"Βάσει προηγούμενης λέξης"</string>
<string name="gesture_input" msgid="3310827802759290774">"Καταχώριση κίνησης"</string> <string name="gesture_input" msgid="3310827802759290774">"Καταχώριση κίνησης"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"Καταχώριση μιας λέξης με εντοπισμό των γραμμάτων μιας λέξης"</string> <string name="gesture_input_summary" msgid="7019742443455085809">"Καταχώριση μιας λέξης με εντοπισμό των γραμμάτων μιας λέξης"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"Εμφάνιση διαδρομής χειρονομίας"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"Εμφάνιση λέξης χειρονομίας"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"Εμφάνιση κινούμενης προεπισκόπησης λέξης με χειρονομία"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Αποθηκεύτηκε"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Αποθηκεύτηκε"</string>
<string name="label_go_key" msgid="1635148082137219148">"Μετ."</string> <string name="label_go_key" msgid="1635148082137219148">"Μετ."</string>
<string name="label_next_key" msgid="362972844525672568">"Επόμενο"</string> <string name="label_next_key" msgid="362972844525672568">"Επόμενο"</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"Πλήκτρο Return"</string> <string name="spoken_description_return" msgid="8178083177238315647">"Πλήκτρο Return"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"Αναζήτηση"</string> <string name="spoken_description_search" msgid="1247236163755920808">"Αναζήτηση"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Κουκκίδα"</string> <string name="spoken_description_dot" msgid="40711082435231673">"Κουκκίδα"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"Αλλαγή γλώσσας"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"Επόμενο"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"Προηγούμενο"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Το Shift ενεργοποιημένο"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Το Shift ενεργοποιημένο"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Το Caps lock είναι ενεργοποιημένο"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Το Caps lock είναι ενεργοποιημένο"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Το Shift είναι απενεργοποιημένο"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Το Shift είναι απενεργοποιημένο"</string>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"Based on previous word"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"Based on previous word"</string>
<string name="gesture_input" msgid="3310827802759290774">"Gesture input"</string> <string name="gesture_input" msgid="3310827802759290774">"Gesture input"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"Input a word by tracing the letters of a word"</string> <string name="gesture_input_summary" msgid="7019742443455085809">"Input a word by tracing the letters of a word"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"Show gesture trail"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"Show gesture word"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"Show floating preview word with gesture"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Saved"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Saved"</string>
<string name="label_go_key" msgid="1635148082137219148">"Go"</string> <string name="label_go_key" msgid="1635148082137219148">"Go"</string>
<string name="label_next_key" msgid="362972844525672568">"Next"</string> <string name="label_next_key" msgid="362972844525672568">"Next"</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"Return"</string> <string name="spoken_description_return" msgid="8178083177238315647">"Return"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"Search"</string> <string name="spoken_description_search" msgid="1247236163755920808">"Search"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Dot"</string> <string name="spoken_description_dot" msgid="40711082435231673">"Dot"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"Switch language"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"Next"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"Previous"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift enabled"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift enabled"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps lock enabled"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps lock enabled"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift disabled"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift disabled"</string>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"Según la palabra anterior"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"Según la palabra anterior"</string>
<string name="gesture_input" msgid="3310827802759290774">"Entrada de gestos"</string> <string name="gesture_input" msgid="3310827802759290774">"Entrada de gestos"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"Ingresa una palabra trazando sus letras."</string> <string name="gesture_input_summary" msgid="7019742443455085809">"Ingresa una palabra trazando sus letras."</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"Mostrar recorrido de gesto"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"Mostrar palabra de gesto"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"Mostrar palabra de vista previa flotante al realizar gestos"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: guardada"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: guardada"</string>
<string name="label_go_key" msgid="1635148082137219148">"Ir"</string> <string name="label_go_key" msgid="1635148082137219148">"Ir"</string>
<string name="label_next_key" msgid="362972844525672568">"Siguiente"</string> <string name="label_next_key" msgid="362972844525672568">"Siguiente"</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"Volver"</string> <string name="spoken_description_return" msgid="8178083177238315647">"Volver"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"Buscar"</string> <string name="spoken_description_search" msgid="1247236163755920808">"Buscar"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Punto"</string> <string name="spoken_description_dot" msgid="40711082435231673">"Punto"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"Cambiar idioma"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"Siguiente"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"Anterior"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Se activó el modo Mayúscula."</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Se activó el modo Mayúscula."</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Se activó el bloqueo de mayúsculas."</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Se activó el bloqueo de mayúsculas."</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Se desactivó el modo Mayúscula"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Se desactivó el modo Mayúscula"</string>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"Según la palabra anterior"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"Según la palabra anterior"</string>
<string name="gesture_input" msgid="3310827802759290774">"Entrada de gestos"</string> <string name="gesture_input" msgid="3310827802759290774">"Entrada de gestos"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"Trazar las letras de una palabra para introducirla"</string> <string name="gesture_input_summary" msgid="7019742443455085809">"Trazar las letras de una palabra para introducirla"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"Mostrar recorrido del gesto"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"Mostrar palabra del gesto"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"Mostrar la palabra de vista previa flotante al realizar un gesto"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: guardada"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: guardada"</string>
<string name="label_go_key" msgid="1635148082137219148">"Ir"</string> <string name="label_go_key" msgid="1635148082137219148">"Ir"</string>
<string name="label_next_key" msgid="362972844525672568">"Sig."</string> <string name="label_next_key" msgid="362972844525672568">"Sig."</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"Tecla Intro"</string> <string name="spoken_description_return" msgid="8178083177238315647">"Tecla Intro"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"Buscar"</string> <string name="spoken_description_search" msgid="1247236163755920808">"Buscar"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Punto"</string> <string name="spoken_description_dot" msgid="40711082435231673">"Punto"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"Cambiar idioma"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"Siguiente"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"Anterior"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Mayúsculas habilitadas"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Mayúsculas habilitadas"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Bloqueo de mayúsculas habilitado"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Bloqueo de mayúsculas habilitado"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Mayúsculas inhabilitadas"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Mayúsculas inhabilitadas"</string>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"Eelmise sõna põhjal"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"Eelmise sõna põhjal"</string>
<string name="gesture_input" msgid="3310827802759290774">"Liigutusega sisest."</string> <string name="gesture_input" msgid="3310827802759290774">"Liigutusega sisest."</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"Sisestage sõna, kirjutades sõna tähed sõrmega"</string> <string name="gesture_input_summary" msgid="7019742443455085809">"Sisestage sõna, kirjutades sõna tähed sõrmega"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"Näita liigutuse jälge"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"Näita liigutuse sõna"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"Ujuva sõna eelvaate näitamine koos liigutusega"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : salvestatud"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : salvestatud"</string>
<string name="label_go_key" msgid="1635148082137219148">"Mine"</string> <string name="label_go_key" msgid="1635148082137219148">"Mine"</string>
<string name="label_next_key" msgid="362972844525672568">"Edasi"</string> <string name="label_next_key" msgid="362972844525672568">"Edasi"</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"Tagasi"</string> <string name="spoken_description_return" msgid="8178083177238315647">"Tagasi"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"Otsing"</string> <string name="spoken_description_search" msgid="1247236163755920808">"Otsing"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Punkt"</string> <string name="spoken_description_dot" msgid="40711082435231673">"Punkt"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"Keele vahetamine"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"Järgmine"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"Eelmine"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Tõstuklahv on lubatud"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Tõstuklahv on lubatud"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Suurtähelukk on lubatud"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Suurtähelukk on lubatud"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Tõstuklahv on keelatud"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Tõstuklahv on keelatud"</string>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"بر اساس کلمه قبلی"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"بر اساس کلمه قبلی"</string>
<string name="gesture_input" msgid="3310827802759290774">"ورودی اشاره"</string> <string name="gesture_input" msgid="3310827802759290774">"ورودی اشاره"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"با دنبال کردن حروف یک کلمه، کلمه را وارد کنید"</string> <string name="gesture_input_summary" msgid="7019742443455085809">"با دنبال کردن حروف یک کلمه، کلمه را وارد کنید"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"نمایش نسخه آزمایشی حرکت"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"نمایش کلمه در طول ورودی حرکتی"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"نمایش کلمه پیش‌نمایش متحرک با حرکت"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : ذخیره شد"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : ذخیره شد"</string>
<string name="label_go_key" msgid="1635148082137219148">"برو"</string> <string name="label_go_key" msgid="1635148082137219148">"برو"</string>
<string name="label_next_key" msgid="362972844525672568">"بعدی"</string> <string name="label_next_key" msgid="362972844525672568">"بعدی"</string>
@ -94,6 +97,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"Return"</string> <string name="spoken_description_return" msgid="8178083177238315647">"Return"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"جستجو"</string> <string name="spoken_description_search" msgid="1247236163755920808">"جستجو"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"نقطه"</string> <string name="spoken_description_dot" msgid="40711082435231673">"نقطه"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"تغییر زبان"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"بعدی"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"قبلی"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift فعال است"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift فعال است"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps lock فعال شد"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps lock فعال شد"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift غیرفعال است"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift غیرفعال است"</string>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"Perustuu edelliseen sanan"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"Perustuu edelliseen sanan"</string>
<string name="gesture_input" msgid="3310827802759290774">"Eleiden syöttö"</string> <string name="gesture_input" msgid="3310827802759290774">"Eleiden syöttö"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"Syötä sana piirtämällä kirjaimet sormella"</string> <string name="gesture_input_summary" msgid="7019742443455085809">"Syötä sana piirtämällä kirjaimet sormella"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"Näytä eleen jälki"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"Näytä elesanat"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"Näytä eleen yhteydessä kelluva esikatselusana"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Tallennettu"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Tallennettu"</string>
<string name="label_go_key" msgid="1635148082137219148">"Siirry"</string> <string name="label_go_key" msgid="1635148082137219148">"Siirry"</string>
<string name="label_next_key" msgid="362972844525672568">"Seur."</string> <string name="label_next_key" msgid="362972844525672568">"Seur."</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string> <string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"Haku"</string> <string name="spoken_description_search" msgid="1247236163755920808">"Haku"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Piste"</string> <string name="spoken_description_dot" msgid="40711082435231673">"Piste"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"Vaihda kieli"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"Seuraava"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"Edellinen"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Vaihto päällä"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Vaihto päällä"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps lock päällä"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps lock päällä"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Vaihto pois käytöstä"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Vaihto pois käytöstä"</string>

View File

@ -25,5 +25,7 @@
<!-- Symbols that should promote magic spaces into real space --> <!-- Symbols that should promote magic spaces into real space -->
<string name="phantom_space_promoting_symbols">;:!?([*&amp;@{&lt;&gt;+=|</string> <string name="phantom_space_promoting_symbols">;:!?([*&amp;@{&lt;&gt;+=|</string>
<!-- Symbols that do NOT separate words --> <!-- Symbols that do NOT separate words -->
<string name="symbols_excluded_from_word_separators">\'</string> <!-- Note that this is identical to the default value, but since the above ones are different
and those variables only make sense together, this is kept here for readability. -->
<string name="symbols_excluded_from_word_separators">\'-</string>
</resources> </resources>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"Suggestions basées sur le mot précédent"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"Suggestions basées sur le mot précédent"</string>
<string name="gesture_input" msgid="3310827802759290774">"Saisie gestuelle"</string> <string name="gesture_input" msgid="3310827802759290774">"Saisie gestuelle"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"Saisir un mot en traçant ses lettres avec le doigt"</string> <string name="gesture_input_summary" msgid="7019742443455085809">"Saisir un mot en traçant ses lettres avec le doigt"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"Afficher le tracé du geste"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"Afficher un mot lors du geste"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"Afficher un aperçu flottant du mot lors de la saisie gestuelle"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : enregistré"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : enregistré"</string>
<string name="label_go_key" msgid="1635148082137219148">"OK"</string> <string name="label_go_key" msgid="1635148082137219148">"OK"</string>
<string name="label_next_key" msgid="362972844525672568">"Suiv."</string> <string name="label_next_key" msgid="362972844525672568">"Suiv."</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"Entrée"</string> <string name="spoken_description_return" msgid="8178083177238315647">"Entrée"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"Rechercher"</string> <string name="spoken_description_search" msgid="1247236163755920808">"Rechercher"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Point"</string> <string name="spoken_description_dot" msgid="40711082435231673">"Point"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"Changer de langue"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"Touche suivante"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"Touche précédente"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Touche Maj activée"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Touche Maj activée"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Verrouillage des majuscules activé"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Verrouillage des majuscules activé"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Touche Maj désactivée"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Touche Maj désactivée"</string>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"पिछले शब्द के आधार पर"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"पिछले शब्द के आधार पर"</string>
<string name="gesture_input" msgid="3310827802759290774">"जेस्‍चर इनपुट"</string> <string name="gesture_input" msgid="3310827802759290774">"जेस्‍चर इनपुट"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"किसी शब्द के अक्षरों को ट्रेस करके कोई शब्द इनपुट करें"</string> <string name="gesture_input_summary" msgid="7019742443455085809">"किसी शब्द के अक्षरों को ट्रेस करके कोई शब्द इनपुट करें"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"जेस्चर ट्रेल दिखाएं"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"जेस्चर शब्द दिखाएं"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"जेस्चर के साथ फ़्लोटिंग पूर्वावलोकन शब्द दिखाएं"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: सहेजा गया"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: सहेजा गया"</string>
<string name="label_go_key" msgid="1635148082137219148">"जाएं"</string> <string name="label_go_key" msgid="1635148082137219148">"जाएं"</string>
<string name="label_next_key" msgid="362972844525672568">"अगला"</string> <string name="label_next_key" msgid="362972844525672568">"अगला"</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"रिटर्न"</string> <string name="spoken_description_return" msgid="8178083177238315647">"रिटर्न"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"खोजें"</string> <string name="spoken_description_search" msgid="1247236163755920808">"खोजें"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"बिंदु"</string> <string name="spoken_description_dot" msgid="40711082435231673">"बिंदु"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"भाषा स्विच करें"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"अगला"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"पिछला"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift सक्षम किया गया"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift सक्षम किया गया"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps lock सक्षम किया गया"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps lock सक्षम किया गया"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift अक्षम किया गया"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift अक्षम किया गया"</string>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"Na temelju prethodne riječi"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"Na temelju prethodne riječi"</string>
<string name="gesture_input" msgid="3310827802759290774">"Unos pokretom"</string> <string name="gesture_input" msgid="3310827802759290774">"Unos pokretom"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"Unos riječi ispisivanjem slova riječi"</string> <string name="gesture_input_summary" msgid="7019742443455085809">"Unos riječi ispisivanjem slova riječi"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"Prikaži trag pokreta"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"Prikaži riječ pokreta"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"Prikaži lebdeći pregled riječi uz pokret"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Spremljeno"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Spremljeno"</string>
<string name="label_go_key" msgid="1635148082137219148">"Idi"</string> <string name="label_go_key" msgid="1635148082137219148">"Idi"</string>
<string name="label_next_key" msgid="362972844525672568">"Dalje"</string> <string name="label_next_key" msgid="362972844525672568">"Dalje"</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string> <string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"Pretraživanje"</string> <string name="spoken_description_search" msgid="1247236163755920808">"Pretraživanje"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Točka"</string> <string name="spoken_description_dot" msgid="40711082435231673">"Točka"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"Promijeni jezik"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"Sljedeće"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"Prethodno"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Omogućena tipka Shift"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Omogućena tipka Shift"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Omogućeno pisanje velikih slova"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Omogućeno pisanje velikih slova"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Onemogućena tipka Shift"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Onemogućena tipka Shift"</string>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"Az előző szó alapján"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"Az előző szó alapján"</string>
<string name="gesture_input" msgid="3310827802759290774">"Kézi bevitel"</string> <string name="gesture_input" msgid="3310827802759290774">"Kézi bevitel"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"Szó beírása a betűk megrajzolásával"</string> <string name="gesture_input_summary" msgid="7019742443455085809">"Szó beírása a betűk megrajzolásával"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"Mozdulat irányának mutatása"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"Mozdulatot leíró szó mutatása"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"Mozdulatot leíró szó mutatása lebegő előnézetben"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : mentve"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : mentve"</string>
<string name="label_go_key" msgid="1635148082137219148">"Ugrás"</string> <string name="label_go_key" msgid="1635148082137219148">"Ugrás"</string>
<string name="label_next_key" msgid="362972844525672568">"Tovább"</string> <string name="label_next_key" msgid="362972844525672568">"Tovább"</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string> <string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"Keresés"</string> <string name="spoken_description_search" msgid="1247236163755920808">"Keresés"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Pont"</string> <string name="spoken_description_dot" msgid="40711082435231673">"Pont"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"Nyelvek felcserélése"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"Következő"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"Előző"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift bekapcsolva"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift bekapcsolva"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps lock bekapcsolva"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps lock bekapcsolva"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift kikapcsolva"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift kikapcsolva"</string>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"Berdasarkan kata sebelumnya"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"Berdasarkan kata sebelumnya"</string>
<string name="gesture_input" msgid="3310827802759290774">"Masukan isyarat"</string> <string name="gesture_input" msgid="3310827802759290774">"Masukan isyarat"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"Masukkan kata dengan melacak huruf dari sebuah kata"</string> <string name="gesture_input_summary" msgid="7019742443455085809">"Masukkan kata dengan melacak huruf dari sebuah kata"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"Tampilkan jalur isyarat"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"Tampilkan kata isyarat"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"Tampilkan kata pratinjau melayang dengan isyarat"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Telah disimpan"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Telah disimpan"</string>
<string name="label_go_key" msgid="1635148082137219148">"Buka"</string> <string name="label_go_key" msgid="1635148082137219148">"Buka"</string>
<string name="label_next_key" msgid="362972844525672568">"Berikutnya"</string> <string name="label_next_key" msgid="362972844525672568">"Berikutnya"</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"Kembali"</string> <string name="spoken_description_return" msgid="8178083177238315647">"Kembali"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"Telusuri"</string> <string name="spoken_description_search" msgid="1247236163755920808">"Telusuri"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Titik"</string> <string name="spoken_description_dot" msgid="40711082435231673">"Titik"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"Ganti bahasa"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"Berikutnya"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"Sebelumnya"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift diaktifkan"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift diaktifkan"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps lock diaktifkan"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps lock diaktifkan"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift dinonaktifkan"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift dinonaktifkan"</string>

View File

@ -1,23 +0,0 @@
<?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 do NOT separate words -->
<string name="symbols_excluded_from_word_separators"></string>
</resources>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"In base alla parola precedente"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"In base alla parola precedente"</string>
<string name="gesture_input" msgid="3310827802759290774">"Inserimento con gesti"</string> <string name="gesture_input" msgid="3310827802759290774">"Inserimento con gesti"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"Inserisci una parola tracciandone le lettere"</string> <string name="gesture_input_summary" msgid="7019742443455085809">"Inserisci una parola tracciandone le lettere"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"Mostra traccia con gesto"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"Mostra parola con gesto"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"Mostra parola di anteprima floating con gesto"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : parola salvata"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : parola salvata"</string>
<string name="label_go_key" msgid="1635148082137219148">"Vai"</string> <string name="label_go_key" msgid="1635148082137219148">"Vai"</string>
<string name="label_next_key" msgid="362972844525672568">"Avanti"</string> <string name="label_next_key" msgid="362972844525672568">"Avanti"</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"Invio"</string> <string name="spoken_description_return" msgid="8178083177238315647">"Invio"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"Cerca"</string> <string name="spoken_description_search" msgid="1247236163755920808">"Cerca"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Pallino"</string> <string name="spoken_description_dot" msgid="40711082435231673">"Pallino"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"Cambia lingua"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"Successivo"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"Precedente"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Maiuscolo attivo"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Maiuscolo attivo"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Blocco maiuscole attivo"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Blocco maiuscole attivo"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Maiuscolo disattivato"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Maiuscolo disattivato"</string>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"בהתבסס על המילה הקודמת"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"בהתבסס על המילה הקודמת"</string>
<string name="gesture_input" msgid="3310827802759290774">"קלט מחווה"</string> <string name="gesture_input" msgid="3310827802759290774">"קלט מחווה"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"הזן מילה על ידי החלקת האצבע מאות לאות"</string> <string name="gesture_input_summary" msgid="7019742443455085809">"הזן מילה על ידי החלקת האצבע מאות לאות"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"הצג שובל מחווה"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"הצג מילת מחווה"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"הצג תצוגה מקדימה צפה של המילה בזמן המחווה"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : נשמרה"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : נשמרה"</string>
<string name="label_go_key" msgid="1635148082137219148">"בצע"</string> <string name="label_go_key" msgid="1635148082137219148">"בצע"</string>
<string name="label_next_key" msgid="362972844525672568">"הבא"</string> <string name="label_next_key" msgid="362972844525672568">"הבא"</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"חזור"</string> <string name="spoken_description_return" msgid="8178083177238315647">"חזור"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"חיפוש"</string> <string name="spoken_description_search" msgid="1247236163755920808">"חיפוש"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"נקודה"</string> <string name="spoken_description_dot" msgid="40711082435231673">"נקודה"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"החלף שפה"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"הבא"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"הקודם"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift מופעל"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift מופעל"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps Lock מופעל"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps Lock מופעל"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift מושבת"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift מושבת"</string>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"前の語句に基づいた入力候補表示"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"前の語句に基づいた入力候補表示"</string>
<string name="gesture_input" msgid="3310827802759290774">"ジェスチャー入力"</string> <string name="gesture_input" msgid="3310827802759290774">"ジェスチャー入力"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"単語の文字をトレースして単語を入力"</string> <string name="gesture_input_summary" msgid="7019742443455085809">"単語の文字をトレースして単語を入力"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"ジェスチャートレイルを表示"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"ジェスチャーワードを表示"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"ジェスチャーでプレビューワードをフローティング表示できます"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>:保存しました"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>:保存しました"</string>
<string name="label_go_key" msgid="1635148082137219148">"実行"</string> <string name="label_go_key" msgid="1635148082137219148">"実行"</string>
<string name="label_next_key" msgid="362972844525672568">"次へ"</string> <string name="label_next_key" msgid="362972844525672568">"次へ"</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string> <string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"検索"</string> <string name="spoken_description_search" msgid="1247236163755920808">"検索"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"中点"</string> <string name="spoken_description_dot" msgid="40711082435231673">"中点"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"言語を切り替え"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"次へ"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"前へ"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift有効"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift有効"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps lock有効"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps lock有効"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift解除"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift解除"</string>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"이전 단어에 기반한 추천"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"이전 단어에 기반한 추천"</string>
<string name="gesture_input" msgid="3310827802759290774">"동작 입력"</string> <string name="gesture_input" msgid="3310827802759290774">"동작 입력"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"한번에 문자를 그려서 단어 입력"</string> <string name="gesture_input_summary" msgid="7019742443455085809">"한번에 문자를 그려서 단어 입력"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"동작 흔적 표시"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"동작 단어 표시"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"동작에 따라 단어 미리보기 표시"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: 저장됨"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: 저장됨"</string>
<string name="label_go_key" msgid="1635148082137219148">"이동"</string> <string name="label_go_key" msgid="1635148082137219148">"이동"</string>
<string name="label_next_key" msgid="362972844525672568">"다음"</string> <string name="label_next_key" msgid="362972844525672568">"다음"</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"리턴 키"</string> <string name="spoken_description_return" msgid="8178083177238315647">"리턴 키"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"검색"</string> <string name="spoken_description_search" msgid="1247236163755920808">"검색"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"점"</string> <string name="spoken_description_dot" msgid="40711082435231673">"점"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"언어 전환"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"다음"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"이전"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift 사용"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift 사용"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps Lock 사용"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps Lock 사용"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift 사용중지"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift 사용중지"</string>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"Pagal ankstesnį žodį"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"Pagal ankstesnį žodį"</string>
<string name="gesture_input" msgid="3310827802759290774">"Įvestis gestais"</string> <string name="gesture_input" msgid="3310827802759290774">"Įvestis gestais"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"Įveskite žodį brėždami jo raides"</string> <string name="gesture_input_summary" msgid="7019742443455085809">"Įveskite žodį brėždami jo raides"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"Rodyti gestų kelią"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"Rodyti gesto žodį"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"Rodyti kintantį peržiūros žodį gestu"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: išsaugota"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: išsaugota"</string>
<string name="label_go_key" msgid="1635148082137219148">"Pradėti"</string> <string name="label_go_key" msgid="1635148082137219148">"Pradėti"</string>
<string name="label_next_key" msgid="362972844525672568">"Kitas"</string> <string name="label_next_key" msgid="362972844525672568">"Kitas"</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"Grįžti"</string> <string name="spoken_description_return" msgid="8178083177238315647">"Grįžti"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"Ieškoti"</string> <string name="spoken_description_search" msgid="1247236163755920808">"Ieškoti"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Taškas"</string> <string name="spoken_description_dot" msgid="40711082435231673">"Taškas"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"Keisti kalbą"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"Kitas"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"Ankstesnis"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Įgalintas antrasis lygis"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Įgalintas antrasis lygis"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Įgalintos didžiosios raidės"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Įgalintos didžiosios raidės"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Antrasis lygis išjungtas"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Antrasis lygis išjungtas"</string>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"Pamatojoties uz iepriekšējo vārdu"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"Pamatojoties uz iepriekšējo vārdu"</string>
<string name="gesture_input" msgid="3310827802759290774">"Ievade ar žestu"</string> <string name="gesture_input" msgid="3310827802759290774">"Ievade ar žestu"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"Ievadiet vārdu, norādot tā burtus."</string> <string name="gesture_input_summary" msgid="7019742443455085809">"Ievadiet vārdu, norādot tā burtus."</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"Rādīt žesta pēdas"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"Rādīt žesta vārdu"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"Rādīt peldošo priekšskatījuma vārdu ar žestu"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: saglabāts"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: saglabāts"</string>
<string name="label_go_key" msgid="1635148082137219148">"Sākt"</string> <string name="label_go_key" msgid="1635148082137219148">"Sākt"</string>
<string name="label_next_key" msgid="362972844525672568">"Tālāk"</string> <string name="label_next_key" msgid="362972844525672568">"Tālāk"</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"Ievadīšanas taustiņš"</string> <string name="spoken_description_return" msgid="8178083177238315647">"Ievadīšanas taustiņš"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"Meklēt"</string> <string name="spoken_description_search" msgid="1247236163755920808">"Meklēt"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Punkts"</string> <string name="spoken_description_dot" msgid="40711082435231673">"Punkts"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"Mainīt valodu"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"Nākamā"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"Iepriekšējā"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Pārslēgšanas režīms iespējots"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Pārslēgšanas režīms iespējots"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Burtslēgs iespējots"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Burtslēgs iespējots"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Pārslēgšanas režīms atspējots"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Pārslēgšanas režīms atspējots"</string>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"Berdasarkan perkataan sebelumnya"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"Berdasarkan perkataan sebelumnya"</string>
<string name="gesture_input" msgid="3310827802759290774">"Input gerak isyarat"</string> <string name="gesture_input" msgid="3310827802759290774">"Input gerak isyarat"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"Masukkan perkataan dengan menyurih huruf perkataan itu."</string> <string name="gesture_input_summary" msgid="7019742443455085809">"Masukkan perkataan dengan menyurih huruf perkataan itu."</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"Tunjukkan jejak gerak isyarat"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"Tunjukkan perkataan gerak isyarat"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"Tunjukkan perkataan pratonton terapung dengan gerak isyarat"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Disimpan"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Disimpan"</string>
<string name="label_go_key" msgid="1635148082137219148">"Pergi"</string> <string name="label_go_key" msgid="1635148082137219148">"Pergi"</string>
<string name="label_next_key" msgid="362972844525672568">"Seterusnya"</string> <string name="label_next_key" msgid="362972844525672568">"Seterusnya"</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"Return"</string> <string name="spoken_description_return" msgid="8178083177238315647">"Return"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"Carian"</string> <string name="spoken_description_search" msgid="1247236163755920808">"Carian"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Titik"</string> <string name="spoken_description_dot" msgid="40711082435231673">"Titik"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"Tukar bahasa"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"Seterusnya"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"Sebelumnya"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Kunci anjak didayakan"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Kunci anjak didayakan"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Kunci huruf besar didayakan"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Kunci huruf besar didayakan"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Kunci anjak dilumpuhkan"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Kunci anjak dilumpuhkan"</string>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"Basert på det forrige ordet"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"Basert på det forrige ordet"</string>
<string name="gesture_input" msgid="3310827802759290774">"Bevegelseskommandoer"</string> <string name="gesture_input" msgid="3310827802759290774">"Bevegelseskommandoer"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"Angi et ord ved å skrive bokstavene på skjermen med fingeren"</string> <string name="gesture_input_summary" msgid="7019742443455085809">"Angi et ord ved å skrive bokstavene på skjermen med fingeren"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"Vis bevegelsesspor"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"Vis bevegelsesord"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"Vis flytende forhåndsvisningsord under bevegelser"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: Lagret"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: Lagret"</string>
<string name="label_go_key" msgid="1635148082137219148">"Utfør"</string> <string name="label_go_key" msgid="1635148082137219148">"Utfør"</string>
<string name="label_next_key" msgid="362972844525672568">"Neste"</string> <string name="label_next_key" msgid="362972844525672568">"Neste"</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"Return"</string> <string name="spoken_description_return" msgid="8178083177238315647">"Return"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"Søk"</string> <string name="spoken_description_search" msgid="1247236163755920808">"Søk"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Prikk"</string> <string name="spoken_description_dot" msgid="40711082435231673">"Prikk"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"Bytt språk"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"Neste"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"Forrige"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift er aktivert"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift er aktivert"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps Lock er aktivert"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps Lock er aktivert"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift er deaktivert"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift er deaktivert"</string>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"Op basis van het vorige woord"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"Op basis van het vorige woord"</string>
<string name="gesture_input" msgid="3310827802759290774">"Invoer met gebaren"</string> <string name="gesture_input" msgid="3310827802759290774">"Invoer met gebaren"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"Voer een woord in door de letters van een woord te volgen"</string> <string name="gesture_input_summary" msgid="7019742443455085809">"Voer een woord in door de letters van een woord te volgen"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"Gebarenspoor weergeven"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"Woord met gebaar weergeven"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"Zwevend voorbeeldwoord met gebaar weergeven"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: opgeslagen"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: opgeslagen"</string>
<string name="label_go_key" msgid="1635148082137219148">"Start"</string> <string name="label_go_key" msgid="1635148082137219148">"Start"</string>
<string name="label_next_key" msgid="362972844525672568">"Verder"</string> <string name="label_next_key" msgid="362972844525672568">"Verder"</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"Return"</string> <string name="spoken_description_return" msgid="8178083177238315647">"Return"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"Zoeken"</string> <string name="spoken_description_search" msgid="1247236163755920808">"Zoeken"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Stip"</string> <string name="spoken_description_dot" msgid="40711082435231673">"Stip"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"Taal wijzigen"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"Volgende"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"Vorige"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift ingeschakeld"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift ingeschakeld"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps Lock ingeschakeld"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps Lock ingeschakeld"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift uitgeschakeld"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift uitgeschakeld"</string>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"Na podstawie poprzedniego słowa"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"Na podstawie poprzedniego słowa"</string>
<string name="gesture_input" msgid="3310827802759290774">"Wprowadzanie gestem"</string> <string name="gesture_input" msgid="3310827802759290774">"Wprowadzanie gestem"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"Podaj słowo, pisząc litery palcem"</string> <string name="gesture_input_summary" msgid="7019742443455085809">"Podaj słowo, pisząc litery palcem"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"Pokazuj ślad gestu"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"Podpowiadaj przy pisaniu gestem"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"Pokazuj pływający podgląd słowa podczas pisania gestem"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Zapisano"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Zapisano"</string>
<string name="label_go_key" msgid="1635148082137219148">"OK"</string> <string name="label_go_key" msgid="1635148082137219148">"OK"</string>
<string name="label_next_key" msgid="362972844525672568">"Dalej"</string> <string name="label_next_key" msgid="362972844525672568">"Dalej"</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string> <string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"Szukaj"</string> <string name="spoken_description_search" msgid="1247236163755920808">"Szukaj"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Punkt"</string> <string name="spoken_description_dot" msgid="40711082435231673">"Punkt"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"Przełącz język"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"Dalej"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"Wstecz"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift włączony"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift włączony"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps lock włączony"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps lock włączony"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift wyłączony"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift wyłączony"</string>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"Com base na palavra anterior"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"Com base na palavra anterior"</string>
<string name="gesture_input" msgid="3310827802759290774">"Introd. por gestos"</string> <string name="gesture_input" msgid="3310827802759290774">"Introd. por gestos"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"Introduza uma palavra, desenhando as letras de uma palavra"</string> <string name="gesture_input_summary" msgid="7019742443455085809">"Introduza uma palavra, desenhando as letras de uma palavra"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"Mostrar percurso do gesto"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"Mostrar palavra gesto"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"Mostrar palavra de visualização flutuante com gesto"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: guardada"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: guardada"</string>
<string name="label_go_key" msgid="1635148082137219148">"OK"</string> <string name="label_go_key" msgid="1635148082137219148">"OK"</string>
<string name="label_next_key" msgid="362972844525672568">"Avançar"</string> <string name="label_next_key" msgid="362972844525672568">"Avançar"</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string> <string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"Pesquisar"</string> <string name="spoken_description_search" msgid="1247236163755920808">"Pesquisar"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Ponto"</string> <string name="spoken_description_dot" msgid="40711082435231673">"Ponto"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"Mudar de idioma"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"Seguinte"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"Anterior"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift ativado"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift ativado"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps lock ativado"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps lock ativado"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift desativado"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift desativado"</string>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"Com base na palavra anterior"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"Com base na palavra anterior"</string>
<string name="gesture_input" msgid="3310827802759290774">"Entrada por gesto"</string> <string name="gesture_input" msgid="3310827802759290774">"Entrada por gesto"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"Introduza uma palavra traçando suas letras"</string> <string name="gesture_input_summary" msgid="7019742443455085809">"Introduza uma palavra traçando suas letras"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"Mostrar percurso do gesto"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"Mostrar palavra do gesto"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"Mostrar visualização flutuante da palavra com gesto"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Salvo"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Salvo"</string>
<string name="label_go_key" msgid="1635148082137219148">"Ir"</string> <string name="label_go_key" msgid="1635148082137219148">"Ir"</string>
<string name="label_next_key" msgid="362972844525672568">"Avançar"</string> <string name="label_next_key" msgid="362972844525672568">"Avançar"</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"Voltar"</string> <string name="spoken_description_return" msgid="8178083177238315647">"Voltar"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"Pesquisar"</string> <string name="spoken_description_search" msgid="1247236163755920808">"Pesquisar"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Ponto"</string> <string name="spoken_description_dot" msgid="40711082435231673">"Ponto"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"Alterar idioma"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"Próximo"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"Anterior"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift ativado"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift ativado"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps lock ativado"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps lock ativado"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift desativado"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift desativado"</string>

View File

@ -96,6 +96,12 @@
<skip /> <skip />
<!-- no translation found for gesture_input_summary (7019742443455085809) --> <!-- no translation found for gesture_input_summary (7019742443455085809) -->
<skip /> <skip />
<!-- no translation found for gesture_preview_trail (3802333369335722221) -->
<skip />
<!-- no translation found for gesture_floating_preview_text (6859416520117939680) -->
<skip />
<!-- no translation found for gesture_floating_preview_text_summary (3333754126434989709) -->
<skip />
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Memorisà"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Memorisà"</string>
<string name="label_go_key" msgid="1635148082137219148">"Dai"</string> <string name="label_go_key" msgid="1635148082137219148">"Dai"</string>
<string name="label_next_key" msgid="362972844525672568">"Vinavant"</string> <string name="label_next_key" msgid="362972844525672568">"Vinavant"</string>
@ -151,6 +157,12 @@
<skip /> <skip />
<!-- no translation found for spoken_description_dot (40711082435231673) --> <!-- no translation found for spoken_description_dot (40711082435231673) -->
<skip /> <skip />
<!-- no translation found for spoken_description_language_switch (5507091328222331316) -->
<skip />
<!-- no translation found for spoken_description_action_next (8636078276664150324) -->
<skip />
<!-- no translation found for spoken_description_action_previous (800872415009336208) -->
<skip />
<!-- no translation found for spoken_description_shiftmode_on (5700440798609574589) --> <!-- no translation found for spoken_description_shiftmode_on (5700440798609574589) -->
<skip /> <skip />
<!-- no translation found for spoken_description_shiftmode_locked (593175803181701830) --> <!-- no translation found for spoken_description_shiftmode_locked (593175803181701830) -->

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"Bazate pe cuvântul precedent"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"Bazate pe cuvântul precedent"</string>
<string name="gesture_input" msgid="3310827802759290774">"Utilizaţi gesturi"</string> <string name="gesture_input" msgid="3310827802759290774">"Utilizaţi gesturi"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"Introduceţi un cuvânt desenând literele acestuia"</string> <string name="gesture_input_summary" msgid="7019742443455085809">"Introduceţi un cuvânt desenând literele acestuia"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"Se afişează urma gestului"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"Sugestie cuvinte la gesturi"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"Se afişează previzualizarea cuvântului flotant la gesturi"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: salvat"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: salvat"</string>
<string name="label_go_key" msgid="1635148082137219148">"OK"</string> <string name="label_go_key" msgid="1635148082137219148">"OK"</string>
<string name="label_next_key" msgid="362972844525672568">"Înainte"</string> <string name="label_next_key" msgid="362972844525672568">"Înainte"</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string> <string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"Căutaţi"</string> <string name="spoken_description_search" msgid="1247236163755920808">"Căutaţi"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Punct"</string> <string name="spoken_description_dot" msgid="40711082435231673">"Punct"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"Schimbaţi limba"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"Înainte"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"Înapoi"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Tasta Shift a fost activată"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Tasta Shift a fost activată"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Tasta Caps Lock a fost activată"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Tasta Caps Lock a fost activată"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Tasta Shift a fost dezactivată"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Tasta Shift a fost dezactivată"</string>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"Подсказки, основанные на предыдущих словах"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"Подсказки, основанные на предыдущих словах"</string>
<string name="gesture_input" msgid="3310827802759290774">"Ввод жестами"</string> <string name="gesture_input" msgid="3310827802759290774">"Ввод жестами"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"Перемещайте палец от буквы к букве, чтобы составить слово"</string> <string name="gesture_input_summary" msgid="7019742443455085809">"Перемещайте палец от буквы к букве, чтобы составить слово"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"Рисовать линию"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"Подсказывать слово"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"Показывать подсказку во время ввода"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: сохранено"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: сохранено"</string>
<string name="label_go_key" msgid="1635148082137219148">"Поиск"</string> <string name="label_go_key" msgid="1635148082137219148">"Поиск"</string>
<string name="label_next_key" msgid="362972844525672568">"Далее"</string> <string name="label_next_key" msgid="362972844525672568">"Далее"</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"Клавиша \"Ввод\""</string> <string name="spoken_description_return" msgid="8178083177238315647">"Клавиша \"Ввод\""</string>
<string name="spoken_description_search" msgid="1247236163755920808">"Поиск"</string> <string name="spoken_description_search" msgid="1247236163755920808">"Поиск"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Точка"</string> <string name="spoken_description_dot" msgid="40711082435231673">"Точка"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"Сменить язык"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"Далее"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"Назад"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Верхний регистр включен"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Верхний регистр включен"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps Lock включен"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps Lock включен"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Верхний регистр отключен"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Верхний регистр отключен"</string>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"Na základe predchádzajúceho slova"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"Na základe predchádzajúceho slova"</string>
<string name="gesture_input" msgid="3310827802759290774">"Zadávanie gestami"</string> <string name="gesture_input" msgid="3310827802759290774">"Zadávanie gestami"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"Napíšte slovo zadaním jeho písmen"</string> <string name="gesture_input_summary" msgid="7019742443455085809">"Napíšte slovo zadaním jeho písmen"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"Zobrazovať stopu gesta"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"Zobrazovať slovo gesta"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"Zobrazovať plávajúcu ukážku slova gesta"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Uložené"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Uložené"</string>
<string name="label_go_key" msgid="1635148082137219148">"Hľadať"</string> <string name="label_go_key" msgid="1635148082137219148">"Hľadať"</string>
<string name="label_next_key" msgid="362972844525672568">"Ďalej"</string> <string name="label_next_key" msgid="362972844525672568">"Ďalej"</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string> <string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"Hľadať"</string> <string name="spoken_description_search" msgid="1247236163755920808">"Hľadať"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Bodka"</string> <string name="spoken_description_dot" msgid="40711082435231673">"Bodka"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"Prepnúť jazyk"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"Ďalšie"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"Predchádzajúce"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Kláves Shift je povolený"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Kláves Shift je povolený"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Kláves Caps Lock je povolený"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Kláves Caps Lock je povolený"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Kláves Shift je zakázaný"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Kláves Shift je zakázaný"</string>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"Na podlagi prejšnje besede"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"Na podlagi prejšnje besede"</string>
<string name="gesture_input" msgid="3310827802759290774">"Vnos s potezo"</string> <string name="gesture_input" msgid="3310827802759290774">"Vnos s potezo"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"Vnašanje besede z drsenjem po zaslonu od črke do črke"</string> <string name="gesture_input_summary" msgid="7019742443455085809">"Vnašanje besede z drsenjem po zaslonu od črke do črke"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"Prikaži pot poteze"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"Pokaži besedo za potezo"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"Pokaži plavajoči predogled besede za potezo"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: shranjeno"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: shranjeno"</string>
<string name="label_go_key" msgid="1635148082137219148">"Pojdi"</string> <string name="label_go_key" msgid="1635148082137219148">"Pojdi"</string>
<string name="label_next_key" msgid="362972844525672568">"Naprej"</string> <string name="label_next_key" msgid="362972844525672568">"Naprej"</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"Vračalka"</string> <string name="spoken_description_return" msgid="8178083177238315647">"Vračalka"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"Iskanje"</string> <string name="spoken_description_search" msgid="1247236163755920808">"Iskanje"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Pika"</string> <string name="spoken_description_dot" msgid="40711082435231673">"Pika"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"Preklop jezika"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"Naprej"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"Nazaj"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Način »Shift« je omogočen"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Način »Shift« je omogočen"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Način »Caps Lock« je omogočen"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Način »Caps Lock« je omogočen"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Način »Shift« je onemogočen"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Način »Shift« je onemogočen"</string>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"На основу претходне речи"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"На основу претходне речи"</string>
<string name="gesture_input" msgid="3310827802759290774">"Унос покретом"</string> <string name="gesture_input" msgid="3310827802759290774">"Унос покретом"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"Унесите реч исписивањем слова речи"</string> <string name="gesture_input_summary" msgid="7019742443455085809">"Унесите реч исписивањем слова речи"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"Прикажи траг покрета"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"Прикажи реч уз покрет"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"Приказ плутајућег прегледа речи уз покрет"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Сачувано"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Сачувано"</string>
<string name="label_go_key" msgid="1635148082137219148">"Иди"</string> <string name="label_go_key" msgid="1635148082137219148">"Иди"</string>
<string name="label_next_key" msgid="362972844525672568">"Следеће"</string> <string name="label_next_key" msgid="362972844525672568">"Следеће"</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"Return"</string> <string name="spoken_description_return" msgid="8178083177238315647">"Return"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"Претражи"</string> <string name="spoken_description_search" msgid="1247236163755920808">"Претражи"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Тачка"</string> <string name="spoken_description_dot" msgid="40711082435231673">"Тачка"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"Пребаци језик"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"Следеће"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"Претходно"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift је омогућен"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift је омогућен"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps lock је омогућен"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps lock је омогућен"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift је онемогућен"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift је онемогућен"</string>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"Baserat på föregående ord"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"Baserat på föregående ord"</string>
<string name="gesture_input" msgid="3310827802759290774">"Gestinmatning"</string> <string name="gesture_input" msgid="3310827802759290774">"Gestinmatning"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"Skriv ett ord för hand genom att rita bokstäverna i ordet"</string> <string name="gesture_input_summary" msgid="7019742443455085809">"Skriv ett ord för hand genom att rita bokstäverna i ordet"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"Visa spår efter rörelse"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"Visa svävande ord för rörelse"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"Visa förhandsgranskning av svävande ord med rörelse"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: sparat"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: sparat"</string>
<string name="label_go_key" msgid="1635148082137219148">"Kör"</string> <string name="label_go_key" msgid="1635148082137219148">"Kör"</string>
<string name="label_next_key" msgid="362972844525672568">"Nästa"</string> <string name="label_next_key" msgid="362972844525672568">"Nästa"</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"Retur"</string> <string name="spoken_description_return" msgid="8178083177238315647">"Retur"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"Sök"</string> <string name="spoken_description_search" msgid="1247236163755920808">"Sök"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Punkt"</string> <string name="spoken_description_dot" msgid="40711082435231673">"Punkt"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"Byt språk"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"Nästa"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"Föregående"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Skift är aktiverat"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Skift är aktiverat"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps Lock är aktiverat"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps Lock är aktiverat"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Skift är inaktiverat"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Skift är inaktiverat"</string>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"Kulingana na neno la awali"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"Kulingana na neno la awali"</string>
<string name="gesture_input" msgid="3310827802759290774">"Ingizo la ishara"</string> <string name="gesture_input" msgid="3310827802759290774">"Ingizo la ishara"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"Ingiza neno kwa kufuatilia herufi za neno"</string> <string name="gesture_input_summary" msgid="7019742443455085809">"Ingiza neno kwa kufuatilia herufi za neno"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"Onyesha njia ya ishara"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"Onyesha neno la ishara"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"Onyesha neno hakiki linaloelea lililo na ishara"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Imehifadhiwa"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Imehifadhiwa"</string>
<string name="label_go_key" msgid="1635148082137219148">"Nenda"</string> <string name="label_go_key" msgid="1635148082137219148">"Nenda"</string>
<string name="label_next_key" msgid="362972844525672568">"Ifuatayo"</string> <string name="label_next_key" msgid="362972844525672568">"Ifuatayo"</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"Rudi"</string> <string name="spoken_description_return" msgid="8178083177238315647">"Rudi"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"Tafuta"</string> <string name="spoken_description_search" msgid="1247236163755920808">"Tafuta"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Nukta"</string> <string name="spoken_description_dot" msgid="40711082435231673">"Nukta"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"Badili lugha"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"Inayofuata"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"Iliyotangulia"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift imewezeshwa"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift imewezeshwa"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps lock imewezeshwa"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps lock imewezeshwa"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift imelemazwa"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift imelemazwa"</string>

View File

@ -19,6 +19,8 @@
--> -->
<resources> <resources>
<!-- Device form factor. This value must be aligned with {@link KeyboardId.DEVICE_FORM_FACTOR_TABLET7} -->
<integer name="config_device_form_factor">1</integer>
<bool name="config_enable_show_voice_key_option">false</bool> <bool name="config_enable_show_voice_key_option">false</bool>
<bool name="config_enable_show_popup_on_keypress_option">false</bool> <bool name="config_enable_show_popup_on_keypress_option">false</bool>
<bool name="config_enable_bigram_suggestions_option">false</bool> <bool name="config_enable_bigram_suggestions_option">false</bool>

View File

@ -19,6 +19,8 @@
--> -->
<resources> <resources>
<!-- Device form factor. This value must be aligned with {@link KeyboardId.DEVICE_FORM_FACTOR_TABLET10} -->
<integer name="config_device_form_factor">2</integer>
<bool name="config_enable_show_voice_key_option">false</bool> <bool name="config_enable_show_voice_key_option">false</bool>
<bool name="config_enable_show_popup_on_keypress_option">false</bool> <bool name="config_enable_show_popup_on_keypress_option">false</bool>
<bool name="config_enable_bigram_suggestions_option">false</bool> <bool name="config_enable_bigram_suggestions_option">false</bool>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"ตามคำก่อนหน้า"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"ตามคำก่อนหน้า"</string>
<string name="gesture_input" msgid="3310827802759290774">"ป้อนท่าทางสัมผัส"</string> <string name="gesture_input" msgid="3310827802759290774">"ป้อนท่าทางสัมผัส"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"ป้อนคำโดยลากนิ้วเป็นรูปตัวอักษรที่อยู่ในคำ โดยไม่ยกนิ้วขึ้น"</string> <string name="gesture_input_summary" msgid="7019742443455085809">"ป้อนคำโดยลากนิ้วเป็นรูปตัวอักษรที่อยู่ในคำ โดยไม่ยกนิ้วขึ้น"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"แสดงรอยทางเดินของท่าทาง"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"แสดงคำแนะนำท่าทาง"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"แสดงตัวอย่างคำแนะนำพร้อมด้วยท่าทาง"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : บันทึกแล้ว"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : บันทึกแล้ว"</string>
<string name="label_go_key" msgid="1635148082137219148">"ไป"</string> <string name="label_go_key" msgid="1635148082137219148">"ไป"</string>
<string name="label_next_key" msgid="362972844525672568">"ถัดไป"</string> <string name="label_next_key" msgid="362972844525672568">"ถัดไป"</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"Return"</string> <string name="spoken_description_return" msgid="8178083177238315647">"Return"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"ค้นหา"</string> <string name="spoken_description_search" msgid="1247236163755920808">"ค้นหา"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"เครื่องหมายจุด"</string> <string name="spoken_description_dot" msgid="40711082435231673">"เครื่องหมายจุด"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"เปลี่ยนภาษา"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"ถัดไป"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"ก่อนหน้า"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"เปิดใช้งาน Shift แล้ว"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"เปิดใช้งาน Shift แล้ว"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"เปิดใช้งาน Caps Lock แล้ว"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"เปิดใช้งาน Caps Lock แล้ว"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"ปิดใช้งาน Shift แล้ว"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"ปิดใช้งาน Shift แล้ว"</string>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"Batay sa nakaraang salita"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"Batay sa nakaraang salita"</string>
<string name="gesture_input" msgid="3310827802759290774">"Pagpasok ng galaw"</string> <string name="gesture_input" msgid="3310827802759290774">"Pagpasok ng galaw"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"Magpasok ng salita sa gamit ang pagsulat sa mga titik ng salita"</string> <string name="gesture_input_summary" msgid="7019742443455085809">"Magpasok ng salita sa gamit ang pagsulat sa mga titik ng salita"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"Ipakita ang trail ng galaw"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"Ipakita ang salita ng galaw"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"Ipakita ang lumulutang na preview ng salita na may galaw"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Na-save"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Na-save"</string>
<string name="label_go_key" msgid="1635148082137219148">"Punta"</string> <string name="label_go_key" msgid="1635148082137219148">"Punta"</string>
<string name="label_next_key" msgid="362972844525672568">"Susunod"</string> <string name="label_next_key" msgid="362972844525672568">"Susunod"</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"Bumalik"</string> <string name="spoken_description_return" msgid="8178083177238315647">"Bumalik"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"Paghahanap"</string> <string name="spoken_description_search" msgid="1247236163755920808">"Paghahanap"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Tuldok"</string> <string name="spoken_description_dot" msgid="40711082435231673">"Tuldok"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"Magpalit ng wika"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"Susunod"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"Nakaraan"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Pinagana ang shift"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Pinagana ang shift"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Pinagana ang caps lock"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Pinagana ang caps lock"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Hindi pinagana ang shift"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Hindi pinagana ang shift"</string>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"Önceki kelimeye dayanarak"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"Önceki kelimeye dayanarak"</string>
<string name="gesture_input" msgid="3310827802759290774">"Hareket girişi"</string> <string name="gesture_input" msgid="3310827802759290774">"Hareket girişi"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"Bir kelimeyi harflerini izleyerek girin"</string> <string name="gesture_input_summary" msgid="7019742443455085809">"Bir kelimeyi harflerini izleyerek girin"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"Hareket izini göster"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"Hareketle yazılan kelimeyi göster"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"Hareketle kayan önizleme kelimesini göster"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Kaydedildi"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Kaydedildi"</string>
<string name="label_go_key" msgid="1635148082137219148">"Git"</string> <string name="label_go_key" msgid="1635148082137219148">"Git"</string>
<string name="label_next_key" msgid="362972844525672568">"İleri"</string> <string name="label_next_key" msgid="362972844525672568">"İleri"</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string> <string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"Ara"</string> <string name="spoken_description_search" msgid="1247236163755920808">"Ara"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Nokta"</string> <string name="spoken_description_dot" msgid="40711082435231673">"Nokta"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"Dili değiştir"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"Sonraki"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"Önceki"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Üst karakter etkin"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Üst karakter etkin"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Büyük harf kilidi etkin"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Büyük harf kilidi etkin"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Üst karakter devre dışı"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Üst karakter devre dışı"</string>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"На основі попереднього слова"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"На основі попереднього слова"</string>
<string name="gesture_input" msgid="3310827802759290774">"Введення жестами"</string> <string name="gesture_input" msgid="3310827802759290774">"Введення жестами"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"Введіть слово, малюючи літери, з яких воно складається"</string> <string name="gesture_input_summary" msgid="7019742443455085809">"Введіть слово, малюючи літери, з яких воно складається"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"Показувати слід жестів"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"Показувати слово для жесту"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"Показувати спливаючий перегляд слова під час жесту"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : збережено"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : збережено"</string>
<string name="label_go_key" msgid="1635148082137219148">"Іти"</string> <string name="label_go_key" msgid="1635148082137219148">"Іти"</string>
<string name="label_next_key" msgid="362972844525672568">"Далі"</string> <string name="label_next_key" msgid="362972844525672568">"Далі"</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"Клавіша Return"</string> <string name="spoken_description_return" msgid="8178083177238315647">"Клавіша Return"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"Пошук"</string> <string name="spoken_description_search" msgid="1247236163755920808">"Пошук"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Крапка"</string> <string name="spoken_description_dot" msgid="40711082435231673">"Крапка"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"Змінити мову"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"Далі"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"Назад"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift увімкнено"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift увімкнено"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps Lock увімкнено"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps Lock увімкнено"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift вимкнено"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift вимкнено"</string>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"Dựa trên từ trước đó"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"Dựa trên từ trước đó"</string>
<string name="gesture_input" msgid="3310827802759290774">"Nhập bằng cử chỉ"</string> <string name="gesture_input" msgid="3310827802759290774">"Nhập bằng cử chỉ"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"Nhập từ bằng cách lần theo các chữ cái của từ"</string> <string name="gesture_input_summary" msgid="7019742443455085809">"Nhập từ bằng cách lần theo các chữ cái của từ"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"Hiển thị vệt cử chỉ"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"Hiển thị từ theo cử chỉ"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"Hiển thị từ xem trước nổi bằng cử chỉ"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Đã lưu"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Đã lưu"</string>
<string name="label_go_key" msgid="1635148082137219148">"Tìm"</string> <string name="label_go_key" msgid="1635148082137219148">"Tìm"</string>
<string name="label_next_key" msgid="362972844525672568">"Tiếp theo"</string> <string name="label_next_key" msgid="362972844525672568">"Tiếp theo"</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"Quay lại"</string> <string name="spoken_description_return" msgid="8178083177238315647">"Quay lại"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"Tìm kiếm"</string> <string name="spoken_description_search" msgid="1247236163755920808">"Tìm kiếm"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Dấu chấm"</string> <string name="spoken_description_dot" msgid="40711082435231673">"Dấu chấm"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"Chuyển ngôn ngữ"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"Tiếp theo"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"Trước"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Đã bật Shift"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Đã bật Shift"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Đã bật Caps lock"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Đã bật Caps lock"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Đã tắt Shift"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Đã tắt Shift"</string>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"根据上一个字词提供建议"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"根据上一个字词提供建议"</string>
<string name="gesture_input" msgid="3310827802759290774">"手势输入"</string> <string name="gesture_input" msgid="3310827802759290774">"手势输入"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"连笔书写输入字词"</string> <string name="gesture_input_summary" msgid="7019742443455085809">"连笔书写输入字词"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"显示手指操作轨迹"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"显示手指操作文字"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"进行手指操作时显示浮动预览文字"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>:已保存"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>:已保存"</string>
<string name="label_go_key" msgid="1635148082137219148">"开始"</string> <string name="label_go_key" msgid="1635148082137219148">"开始"</string>
<string name="label_next_key" msgid="362972844525672568">"下一步"</string> <string name="label_next_key" msgid="362972844525672568">"下一步"</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"返回"</string> <string name="spoken_description_return" msgid="8178083177238315647">"返回"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"搜索"</string> <string name="spoken_description_search" msgid="1247236163755920808">"搜索"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"点"</string> <string name="spoken_description_dot" msgid="40711082435231673">"点"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"切换语言"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"下一个"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"上一个"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift 模式已启用"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift 模式已启用"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"大写锁定已启用"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"大写锁定已启用"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift 模式已停用"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift 模式已停用"</string>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"根據上一個字詞產生"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"根據上一個字詞產生"</string>
<string name="gesture_input" msgid="3310827802759290774">"手勢輸入"</string> <string name="gesture_input" msgid="3310827802759290774">"手勢輸入"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"以手指寫出字詞中字母的方式來輸入字詞"</string> <string name="gesture_input_summary" msgid="7019742443455085809">"以手指寫出字詞中字母的方式來輸入字詞"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"顯示手勢軌跡"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"顯示手勢字詞"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"使用手勢輸入時顯示浮動預覽字詞"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>:已儲存"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>:已儲存"</string>
<string name="label_go_key" msgid="1635148082137219148">"開始"</string> <string name="label_go_key" msgid="1635148082137219148">"開始"</string>
<string name="label_next_key" msgid="362972844525672568">"繼續"</string> <string name="label_next_key" msgid="362972844525672568">"繼續"</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"返回"</string> <string name="spoken_description_return" msgid="8178083177238315647">"返回"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"搜尋"</string> <string name="spoken_description_search" msgid="1247236163755920808">"搜尋"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"點"</string> <string name="spoken_description_dot" msgid="40711082435231673">"點"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"切換語言"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"下一步"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"上一步"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift 鍵已啟用"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift 鍵已啟用"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"大寫鎖定已啟用"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"大寫鎖定已啟用"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift 鍵已停用"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift 鍵已停用"</string>

View File

@ -60,6 +60,9 @@
<string name="bigram_prediction_summary" msgid="3253961591626441019">"Ngokususela egameni langaphambilini"</string> <string name="bigram_prediction_summary" msgid="3253961591626441019">"Ngokususela egameni langaphambilini"</string>
<string name="gesture_input" msgid="3310827802759290774">"Okokufaka kokuthinta"</string> <string name="gesture_input" msgid="3310827802759290774">"Okokufaka kokuthinta"</string>
<string name="gesture_input_summary" msgid="7019742443455085809">"Faka igama ngokulandela ngomkhondo izinhlamvu zegama"</string> <string name="gesture_input_summary" msgid="7019742443455085809">"Faka igama ngokulandela ngomkhondo izinhlamvu zegama"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"Bonisa i-trail yokuthinta"</string>
<string name="gesture_floating_preview_text" msgid="6859416520117939680">"Bonisa igama lokuthinta"</string>
<string name="gesture_floating_preview_text_summary" msgid="3333754126434989709">"Bonisa igama lokuhlola kuqala elintantayo nokuthinta"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Kulondoloziwe"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Kulondoloziwe"</string>
<string name="label_go_key" msgid="1635148082137219148">"Iya"</string> <string name="label_go_key" msgid="1635148082137219148">"Iya"</string>
<string name="label_next_key" msgid="362972844525672568">"Okulandelayo"</string> <string name="label_next_key" msgid="362972844525672568">"Okulandelayo"</string>
@ -90,6 +93,9 @@
<string name="spoken_description_return" msgid="8178083177238315647">"Buyisela"</string> <string name="spoken_description_return" msgid="8178083177238315647">"Buyisela"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"Sesha"</string> <string name="spoken_description_search" msgid="1247236163755920808">"Sesha"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Icashazi"</string> <string name="spoken_description_dot" msgid="40711082435231673">"Icashazi"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"Shintsha ulimi"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"Okulandelayo"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"Okwangaphambilini"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"U-Shift uvunyelwe"</string> <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"U-Shift uvunyelwe"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Ofeleba bavunyelwe"</string> <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Ofeleba bavunyelwe"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"U-Shift uvimbelwe"</string> <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"U-Shift uvimbelwe"</string>

View File

@ -118,6 +118,18 @@
<enum name="italic" value="2" /> <enum name="italic" value="2" />
<enum name="boldItalic" value="3" /> <enum name="boldItalic" value="3" />
</attr> </attr>
<attr name="gestureFloatingPreviewTextSize" format="dimension" />
<attr name="gestureFloatingPreviewTextColor" format="color" />
<attr name="gestureFloatingPreviewTextOffset" format="dimension" />
<attr name="gestureFloatingPreviewTextShadingColor" format="color" />
<attr name="gestureFloatingPreviewTextShadingBorder" format="dimension" />
<attr name="gestureFloatingPreviewTextShadowColor" format="color" />
<attr name="gestureFloatingPreviewTextShadowBorder" format="dimension" />
<attr name="gestureFloatingPreviewTextConnectorColor" format="color" />
<attr name="gestureFloatingPreviewTextConnectorWidth" format="dimension" />
<attr name="gesturePreviewTrailColor" format="color" />
<attr name="gesturePreviewTrailWidth" format="dimension" />
</declare-styleable> </declare-styleable>
<declare-styleable name="MainKeyboardView"> <declare-styleable name="MainKeyboardView">

View File

@ -19,6 +19,8 @@
--> -->
<resources> <resources>
<!-- Device form factor. This value must be aligned with {@link KeyboardId.DEVICE_FORM_FACTOR_PHONE} -->
<integer name="config_device_form_factor">0</integer>
<bool name="config_use_fullscreen_mode">false</bool> <bool name="config_use_fullscreen_mode">false</bool>
<bool name="config_enable_show_voice_key_option">true</bool> <bool name="config_enable_show_voice_key_option">true</bool>
<bool name="config_enable_show_popup_on_keypress_option">true</bool> <bool name="config_enable_show_popup_on_keypress_option">true</bool>

View File

@ -93,4 +93,12 @@
<dimen name="more_suggestions_hint_text_size">27dp</dimen> <dimen name="more_suggestions_hint_text_size">27dp</dimen>
<integer name="suggestions_count_in_strip">3</integer> <integer name="suggestions_count_in_strip">3</integer>
<integer name="center_suggestion_percentile">36</integer> <integer name="center_suggestion_percentile">36</integer>
<!-- Gesture preview parameters -->
<dimen name="gesture_preview_trail_width">2.5dp</dimen>
<dimen name="gesture_floating_preview_text_size">35dp</dimen>
<dimen name="gesture_floating_preview_text_offset">75dp</dimen>
<dimen name="gesture_floating_preview_text_shadow_border">17.5dp</dimen>
<dimen name="gesture_floating_preview_text_shading_border">7.5dp</dimen>
<dimen name="gesture_floating_preview_text_connector_width">1.0dp</dimen>
</resources> </resources>

View File

@ -111,10 +111,16 @@
<!-- Description for "next word suggestion" option. This displays suggestions even when there is no input, based on the previous word. --> <!-- Description for "next word suggestion" option. This displays suggestions even when there is no input, based on the previous word. -->
<string name="bigram_prediction_summary">Based on previous word</string> <string name="bigram_prediction_summary">Based on previous word</string>
<!-- Option to enable gesture input. The user can input a word by tracing the letters of a word without releasing the finger from the screen. [CHAR LIMIT=20]--> <!-- Option to enable gesture input. The user can input a word by tracing the letters of a word without releasing the finger from the screen. [CHAR LIMIT=30]-->
<string name="gesture_input">Gesture input</string> <string name="gesture_input">Gesture input</string>
<!-- Description for "gesture_input" option. The user can input a word by tracing the letters of a word without releasing the finger from the screen. [CHAR LIMIT=65]--> <!-- Description for "gesture_input" option. The user can input a word by tracing the letters of a word without releasing the finger from the screen. [CHAR LIMIT=65]-->
<string name="gesture_input_summary">Input a word by tracing the letters of a word</string> <string name="gesture_input_summary">Input a word by tracing the letters of a word</string>
<!-- Option to enable gesture trail preview. The user can see a trail of the gesture during gesture input. [CHAR LIMIT=30]-->
<string name="gesture_preview_trail">Show gesture trail</string>
<!-- Option to enable gesture floating text preview. The user can see a suggested word floating under the moving finger during a gesture input. [CHAR LIMIT=30]-->
<string name="gesture_floating_preview_text">Show gesture word</string>
<!-- Description for "gesture_floating_preview_text" option. The user can see a suggested word floating under the moving finger during a gesture input. [CHAR LIMIT=65]-->
<string name="gesture_floating_preview_text_summary">Show floating preview word with gesture</string>
<!-- Indicates that a word has been added to the dictionary --> <!-- Indicates that a word has been added to the dictionary -->
<string name="added_word"><xliff:g id="word">%s</xliff:g> : Saved</string> <string name="added_word"><xliff:g id="word">%s</xliff:g> : Saved</string>
@ -181,6 +187,12 @@
<string name="spoken_description_search">Search</string> <string name="spoken_description_search">Search</string>
<!-- Spoken description for the "U+2022" (BULLET) keyboard key. --> <!-- Spoken description for the "U+2022" (BULLET) keyboard key. -->
<string name="spoken_description_dot">Dot</string> <string name="spoken_description_dot">Dot</string>
<!-- Spoken description for the "Switch language" keyboard key. -->
<string name="spoken_description_language_switch">Switch language</string>
<!-- Spoken description for the "Next" action keyboard key. -->
<string name="spoken_description_action_next">Next</string>
<!-- Spoken description for the "Previous" action keyboard key. -->
<string name="spoken_description_action_previous">Previous</string>
<!-- Spoken feedback after turning "Shift" mode on. --> <!-- Spoken feedback after turning "Shift" mode on. -->
<string name="spoken_description_shiftmode_on">Shift enabled</string> <string name="spoken_description_shiftmode_on">Shift enabled</string>
@ -303,6 +315,15 @@
<!-- Description for English (United States) keyboard subtype with explicit keyboard layout [CHAR LIMIT=25] <!-- Description for English (United States) keyboard subtype with explicit keyboard layout [CHAR LIMIT=25]
This should be identical to subtype_en_US aside from the trailing (%s). --> This should be identical to subtype_en_US aside from the trailing (%s). -->
<string name="subtype_with_layout_en_US">English (US) (<xliff:g id="layout">%s</xliff:g>)</string> <string name="subtype_with_layout_en_US">English (US) (<xliff:g id="layout">%s</xliff:g>)</string>
<!-- TODO: Uncomment once we can handle IETF language tag with script name specified.
Description for Serbian Cyrillic keyboard subtype [CHAR LIMIT=25]
<string name="subtype_serbian_cyrillic">Serbian (Cyrillic)</string>
Description for Serbian Latin keyboard subtype [CHAR LIMIT=25]
<string name="subtype_serbian_latin">Serbian (Latin)</string>
Description for Serbian Latin keyboard subtype with explicit keyboard layout [CHAR LIMIT=25]
This should be identical to subtype_serbian_latin aside from the trailing (%s).
<string name="subtype_with_layout_sr-Latn">Serbian (Latin) (<xliff:g id="layout">%s</xliff:g>)</string>
-->
<!-- Description for language agnostic keyboard subtype [CHAR LIMIT=25] --> <!-- Description for language agnostic keyboard subtype [CHAR LIMIT=25] -->
<string name="subtype_no_language">No language</string> <string name="subtype_no_language">No language</string>
<!-- Description for language agnostic QWERTY keyboard subtype [CHAR LIMIT=25] --> <!-- Description for language agnostic QWERTY keyboard subtype [CHAR LIMIT=25] -->

View File

@ -14,7 +14,7 @@
limitations under the License. limitations under the License.
--> -->
<resources> <resources xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Theme "Basic" --> <!-- Theme "Basic" -->
<style name="Keyboard"> <style name="Keyboard">
<!-- This should be aligned with KeyboardSwitcher.KEYBOARD_THEMES[] --> <!-- This should be aligned with KeyboardSwitcher.KEYBOARD_THEMES[] -->
@ -67,6 +67,18 @@
<item name="shadowColor">#BB000000</item> <item name="shadowColor">#BB000000</item>
<item name="shadowRadius">2.75</item> <item name="shadowRadius">2.75</item>
<item name="backgroundDimAlpha">128</item> <item name="backgroundDimAlpha">128</item>
<!-- android:color/holo_blue_light=#FF33B5E5 -->
<item name="gestureFloatingPreviewTextSize">@dimen/gesture_floating_preview_text_size</item>
<item name="gestureFloatingPreviewTextColor">@android:color/white</item>
<item name="gestureFloatingPreviewTextOffset">@dimen/gesture_floating_preview_text_offset</item>
<item name="gestureFloatingPreviewTextShadingColor">@android:color/holo_blue_light</item>
<item name="gestureFloatingPreviewTextShadingBorder">@dimen/gesture_floating_preview_text_shading_border</item>
<item name="gestureFloatingPreviewTextShadowColor">#FF252525</item>
<item name="gestureFloatingPreviewTextShadowBorder">@dimen/gesture_floating_preview_text_shadow_border</item>
<item name="gestureFloatingPreviewTextConnectorColor">@android:color/white</item>
<item name="gestureFloatingPreviewTextConnectorWidth">@dimen/gesture_floating_preview_text_connector_width</item>
<item name="gesturePreviewTrailColor">@android:color/holo_blue_light</item>
<item name="gesturePreviewTrailWidth">@dimen/gesture_preview_trail_width</item>
<!-- Common attributes of MainKeyboardView --> <!-- Common attributes of MainKeyboardView -->
<item name="keyHysteresisDistance">@dimen/config_key_hysteresis_distance</item> <item name="keyHysteresisDistance">@dimen/config_key_hysteresis_distance</item>
<item name="touchNoiseThresholdTime">@integer/config_touch_noise_threshold_time</item> <item name="touchNoiseThresholdTime">@integer/config_touch_noise_threshold_time</item>

View File

@ -24,15 +24,36 @@
<switch> <switch>
<case <case
latin:languageCode="fa" latin:languageCode="fa"
latin:languageSwitchKeyEnabled="true"
>
<Key
latin:keyStyle="languageSwitchKeyStyle" />
<Key
latin:keyStyle="spaceKeyStyle"
latin:keyWidth="24.141%p" />
<Key
latin:keyStyle="zwnjKeyStyle" />
</case>
<case
latin:languageCode="fa"
latin:languageSwitchKeyEnabled="false"
> >
<Key <Key
latin:keyStyle="spaceKeyStyle" latin:keyStyle="spaceKeyStyle"
latin:keyWidth="32.188%p" /> latin:keyWidth="32.188%p" />
<!-- U+200C: "" ZERO WIDTH NON-JOINER
U+200D: "" ZERO WIDTH JOINER -->
<Key <Key
latin:keyStyle="zwnjKeyStyle" /> latin:keyStyle="zwnjKeyStyle" />
</case> </case>
<case
latin:languageSwitchKeyEnabled="true"
>
<Key
latin:keyStyle="languageSwitchKeyStyle" />
<Key
latin:keyStyle="spaceKeyStyle"
latin:keyWidth="32.188%p" />
</case>
<!-- languageSwitchKeyEnabled="false" -->
<default> <default>
<Key <Key
latin:keyStyle="spaceKeyStyle" latin:keyStyle="spaceKeyStyle"

View File

@ -76,7 +76,7 @@
<key-style <key-style
latin:styleName="spaceKeyStyle" latin:styleName="spaceKeyStyle"
latin:code="!code/key_space" latin:code="!code/key_space"
latin:keyActionFlags="noKeyPreview" /> latin:keyActionFlags="noKeyPreview|enableLongPress" />
<!-- U+200C: ZERO WIDTH NON-JOINER <!-- U+200C: ZERO WIDTH NON-JOINER
U+200D: ZERO WIDTH JOINER --> U+200D: ZERO WIDTH JOINER -->
<key-style <key-style
@ -99,6 +99,12 @@
latin:keyIconDisabled="!icon/shortcut_key_disabled" latin:keyIconDisabled="!icon/shortcut_key_disabled"
latin:keyActionFlags="noKeyPreview" latin:keyActionFlags="noKeyPreview"
latin:backgroundType="functional" /> latin:backgroundType="functional" />
<key-style
latin:styleName="languageSwitchKeyStyle"
latin:code="!code/key_language_switch"
latin:keyIcon="!icon/language_switch_key"
latin:keyActionFlags="noKeyPreview|altCodeWhileTyping|enableLongPress"
latin:altCode="!code/key_space" />
<key-style <key-style
latin:styleName="settingsKeyStyle" latin:styleName="settingsKeyStyle"
latin:code="!code/key_settings" latin:code="!code/key_settings"

View File

@ -33,9 +33,8 @@
<include <include
latin:keyboardLayout="@xml/rowkeys_east_slavic1" latin:keyboardLayout="@xml/rowkeys_east_slavic1"
latin:keyLabelFlags="disableAdditionalMoreKeys|disableKeyHintLabel" /> latin:keyLabelFlags="disableAdditionalMoreKeys|disableKeyHintLabel" />
<!-- U+044A: "ъ" CYRILLIC SMALL LETTER HARD SIGN -->
<Key <Key
latin:keyLabel="&#x044A;" /> latin:keyLabel="!text/keylabel_for_east_slavic_row1_12" />
<Key <Key
latin:keyStyle="deleteKeyStyle" latin:keyStyle="deleteKeyStyle"
latin:keyWidth="fillRight" /> latin:keyWidth="fillRight" />

View File

@ -22,10 +22,12 @@
<!-- Supported subtypes <!-- Supported subtypes
keyboard_locale: script_name/keyboard_layout_set[:keyboard_locale] keyboard_locale: script_name/keyboard_layout_set[:keyboard_locale]
af: Afrikaans/qwerty
ar: Arabic/arabic ar: Arabic/arabic
be: Belarusian/east_slavic be: Belarusian/east_slavic
bg: Bulgarian/bulgarian bg: Bulgarian/bulgarian
bg: Bulgarian/bulgarian_bds bg: Bulgarian/bulgarian_bds
ca: Catalan/spanish
cs: Czech/qwertz cs: Czech/qwertz
da: Danish/nordic da: Danish/nordic
de: German/qwertz de: German/qwertz
@ -41,14 +43,16 @@
hi: Hindi/hindi hi: Hindi/hindi
hr: Croatian/qwertz hr: Croatian/qwertz
hu: Hungarian/qwertz hu: Hungarian/qwertz
in: Indonesian/qwerty # "id" is official language code of Indonesian.
is: Icelandic/qwerty is: Icelandic/qwerty
it: Italian/qwerty it: Italian/qwerty
iw: Hebrew/hebrew iw: Hebrew/hebrew # "he" is official language code of Hebrew.
ka: Georgian/georgian ka: Georgian/georgian
ky: Kyrgyz/east_slavic ky: Kyrgyz/east_slavic
lt: Lithuanian/qwerty lt: Lithuanian/qwerty
lv: Latvian/qwerty lv: Latvian/qwerty
mk: Macedonian/south_slavic mk: Macedonian/south_slavic
ms: Malay/qwerty
nb: Norwegian Bokmål/nordic nb: Norwegian Bokmål/nordic
nl: Dutch/qwerty nl: Dutch/qwerty
pl: Polish/qwerty pl: Polish/qwerty
@ -59,11 +63,15 @@
sk: Slovak/qwerty sk: Slovak/qwerty
sl: Slovenian/qwerty sl: Slovenian/qwerty
sr: Serbian/south_slavic sr: Serbian/south_slavic
(sr-Latn: Serbian/qwerty) # not yet implemented.
sv: Swedish/nordic sv: Swedish/nordic
sw: Swahili/qwerty
th: Thai/thai th: Thai/thai
tl: Tagalog/spanish
tr: Turkish/qwerty tr: Turkish/qwerty
uk: Ukrainian/east_slavic uk: Ukrainian/east_slavic
vi: Vietnamese/qwerty vi: Vietnamese/qwerty
zu: Zulu/qwerty
zz: QWERTY/qwerty zz: QWERTY/qwerty
--> -->
<!-- TODO: use <lang>_keyboard icon instead of a common keyboard icon. --> <!-- TODO: use <lang>_keyboard icon instead of a common keyboard icon. -->
@ -84,6 +92,12 @@
android:imeSubtypeMode="keyboard" android:imeSubtypeMode="keyboard"
android:imeSubtypeExtraValue="TrySuppressingImeSwitcher,AsciiCapable,SupportTouchPositionCorrection" android:imeSubtypeExtraValue="TrySuppressingImeSwitcher,AsciiCapable,SupportTouchPositionCorrection"
/> />
<subtype android:icon="@drawable/ic_subtype_keyboard"
android:label="@string/subtype_generic"
android:imeSubtypeLocale="af"
android:imeSubtypeMode="keyboard"
android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
/>
<subtype android:icon="@drawable/ic_subtype_keyboard" <subtype android:icon="@drawable/ic_subtype_keyboard"
android:label="@string/subtype_generic" android:label="@string/subtype_generic"
android:imeSubtypeLocale="ar" android:imeSubtypeLocale="ar"
@ -108,6 +122,12 @@
android:imeSubtypeMode="keyboard" android:imeSubtypeMode="keyboard"
android:imeSubtypeExtraValue="KeyboardLayoutSet=bulgarian_bds" android:imeSubtypeExtraValue="KeyboardLayoutSet=bulgarian_bds"
/> />
<subtype android:icon="@drawable/ic_subtype_keyboard"
android:label="@string/subtype_generic"
android:imeSubtypeLocale="ca"
android:imeSubtypeMode="keyboard"
android:imeSubtypeExtraValue="KeyboardLayoutSet=spanish,AsciiCapable"
/>
<subtype android:icon="@drawable/ic_subtype_keyboard" <subtype android:icon="@drawable/ic_subtype_keyboard"
android:label="@string/subtype_generic" android:label="@string/subtype_generic"
android:imeSubtypeLocale="cs" android:imeSubtypeLocale="cs"
@ -186,6 +206,13 @@
android:imeSubtypeMode="keyboard" android:imeSubtypeMode="keyboard"
android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection" android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
/> />
<!-- Java uses the deprecated "in" code instead of the standard "id" code for Indonesian. -->
<subtype android:icon="@drawable/ic_subtype_keyboard"
android:label="@string/subtype_generic"
android:imeSubtypeLocale="in"
android:imeSubtypeMode="keyboard"
android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
/>
<subtype android:icon="@drawable/ic_subtype_keyboard" <subtype android:icon="@drawable/ic_subtype_keyboard"
android:label="@string/subtype_generic" android:label="@string/subtype_generic"
android:imeSubtypeLocale="is" android:imeSubtypeLocale="is"
@ -235,6 +262,12 @@
android:imeSubtypeMode="keyboard" android:imeSubtypeMode="keyboard"
android:imeSubtypeExtraValue="KeyboardLayoutSet=south_slavic" android:imeSubtypeExtraValue="KeyboardLayoutSet=south_slavic"
/> />
<subtype android:icon="@drawable/ic_subtype_keyboard"
android:label="@string/subtype_generic"
android:imeSubtypeLocale="ms"
android:imeSubtypeMode="keyboard"
android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
/>
<subtype android:icon="@drawable/ic_subtype_keyboard" <subtype android:icon="@drawable/ic_subtype_keyboard"
android:label="@string/subtype_generic" android:label="@string/subtype_generic"
android:imeSubtypeLocale="nb" android:imeSubtypeLocale="nb"
@ -295,18 +328,44 @@
android:imeSubtypeMode="keyboard" android:imeSubtypeMode="keyboard"
android:imeSubtypeExtraValue="SupportTouchPositionCorrection" android:imeSubtypeExtraValue="SupportTouchPositionCorrection"
/> />
<!-- TODO: Uncomment once we can handle IETF language tag with script name specified.
<subtype android:icon="@drawable/ic_subtype_keyboard"
android:label="@string/subtype_serbian_cyrillic"
android:imeSubtypeLocale="sr"
android:imeSubtypeMode="keyboard"
android:imeSubtypeExtraValue="SupportTouchPositionCorrection"
/>
<subtype android:icon="@drawable/ic_subtype_keyboard"
android:label="@string/subtype_serbian_latin"
android:imeSubtypeLocale="sr-Latn"
android:imeSubtypeMode="keyboard"
android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
/>
-->
<subtype android:icon="@drawable/ic_subtype_keyboard" <subtype android:icon="@drawable/ic_subtype_keyboard"
android:label="@string/subtype_generic" android:label="@string/subtype_generic"
android:imeSubtypeLocale="sv" android:imeSubtypeLocale="sv"
android:imeSubtypeMode="keyboard" android:imeSubtypeMode="keyboard"
android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection" android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
/> />
<subtype android:icon="@drawable/ic_subtype_keyboard"
android:label="@string/subtype_generic"
android:imeSubtypeLocale="sw"
android:imeSubtypeMode="keyboard"
android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
/>
<subtype android:icon="@drawable/ic_subtype_keyboard" <subtype android:icon="@drawable/ic_subtype_keyboard"
android:label="@string/subtype_generic" android:label="@string/subtype_generic"
android:imeSubtypeLocale="th" android:imeSubtypeLocale="th"
android:imeSubtypeMode="keyboard" android:imeSubtypeMode="keyboard"
android:imeSubtypeExtraValue="KeyboardLayoutSet=thai" android:imeSubtypeExtraValue="KeyboardLayoutSet=thai"
/> />
<subtype android:icon="@drawable/ic_subtype_keyboard"
android:label="@string/subtype_generic"
android:imeSubtypeLocale="tl"
android:imeSubtypeMode="keyboard"
android:imeSubtypeExtraValue="KeyboardLayoutSet=spanish,AsciiCapable"
/>
<subtype android:icon="@drawable/ic_subtype_keyboard" <subtype android:icon="@drawable/ic_subtype_keyboard"
android:label="@string/subtype_generic" android:label="@string/subtype_generic"
android:imeSubtypeLocale="tr" android:imeSubtypeLocale="tr"
@ -325,6 +384,12 @@
android:imeSubtypeMode="keyboard" android:imeSubtypeMode="keyboard"
android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable" android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
/> />
<subtype android:icon="@drawable/ic_subtype_keyboard"
android:label="@string/subtype_generic"
android:imeSubtypeLocale="zu"
android:imeSubtypeMode="keyboard"
android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
/>
<subtype android:icon="@drawable/ic_subtype_keyboard" <subtype android:icon="@drawable/ic_subtype_keyboard"
android:label="@string/subtype_no_language_qwerty" android:label="@string/subtype_no_language_qwerty"
android:imeSubtypeLocale="zz" android:imeSubtypeLocale="zz"

View File

@ -101,6 +101,12 @@
android:key="pref_advanced_settings" android:key="pref_advanced_settings"
android:title="@string/advanced_settings" android:title="@string/advanced_settings"
android:summary="@string/advanced_settings_summary"> android:summary="@string/advanced_settings_summary">
<CheckBoxPreference
android:key="pref_key_use_contacts_dict"
android:title="@string/use_contacts_dict"
android:summary="@string/use_contacts_dict_summary"
android:persistent="true"
android:defaultValue="true" />
<CheckBoxPreference <CheckBoxPreference
android:key="pref_suppress_language_switch_key" android:key="pref_suppress_language_switch_key"
android:title="@string/suppress_language_switch_key" android:title="@string/suppress_language_switch_key"
@ -120,18 +126,23 @@
<ListPreference <ListPreference
android:key="pref_key_preview_popup_dismiss_delay" android:key="pref_key_preview_popup_dismiss_delay"
android:title="@string/key_preview_popup_dismiss_delay" /> android:title="@string/key_preview_popup_dismiss_delay" />
<CheckBoxPreference
android:key="pref_key_use_contacts_dict"
android:title="@string/use_contacts_dict"
android:summary="@string/use_contacts_dict_summary"
android:persistent="true"
android:defaultValue="true" />
<PreferenceScreen <PreferenceScreen
android:key="pref_vibration_duration_settings" android:key="pref_vibration_duration_settings"
android:title="@string/prefs_keypress_vibration_duration_settings"/> android:title="@string/prefs_keypress_vibration_duration_settings"/>
<PreferenceScreen <PreferenceScreen
android:key="pref_keypress_sound_volume" android:key="pref_keypress_sound_volume"
android:title="@string/prefs_keypress_sound_volume_settings" /> android:title="@string/prefs_keypress_sound_volume_settings" />
<CheckBoxPreference
android:key="pref_gesture_preview_trail"
android:title="@string/gesture_preview_trail"
android:persistent="true"
android:defaultValue="true" />
<CheckBoxPreference
android:key="pref_gesture_floating_preview_text"
android:title="@string/gesture_floating_preview_text"
android:summary="@string/gesture_floating_preview_text_summary"
android:persistent="true"
android:defaultValue="true" />
</PreferenceScreen> </PreferenceScreen>
</PreferenceCategory> </PreferenceCategory>
</PreferenceScreen> </PreferenceScreen>

View File

@ -47,7 +47,7 @@
latin:keyLabel="&#x0435;" latin:keyLabel="&#x0435;"
latin:keyHintLabel="5" latin:keyHintLabel="5"
latin:additionalMoreKeys="5" latin:additionalMoreKeys="5"
latin:moreKeys="!text/more_keys_for_cyrillic_ye" /> latin:moreKeys="!text/more_keys_for_cyrillic_ie" />
<!-- U+043D: "н" CYRILLIC SMALL LETTER EN --> <!-- U+043D: "н" CYRILLIC SMALL LETTER EN -->
<Key <Key
latin:keyLabel="&#x043D;" latin:keyLabel="&#x043D;"
@ -58,7 +58,8 @@
<Key <Key
latin:keyLabel="&#x0433;" latin:keyLabel="&#x0433;"
latin:keyHintLabel="7" latin:keyHintLabel="7"
latin:additionalMoreKeys="7" /> latin:additionalMoreKeys="7"
latin:moreKeys="!text/more_keys_for_cyrillic_ghe" />
<!-- U+0448: "ш" CYRILLIC SMALL LETTER SHA --> <!-- U+0448: "ш" CYRILLIC SMALL LETTER SHA -->
<Key <Key
latin:keyLabel="&#x0448;" latin:keyLabel="&#x0448;"
@ -75,6 +76,5 @@
latin:additionalMoreKeys="0" /> latin:additionalMoreKeys="0" />
<!-- U+0445: "х" CYRILLIC SMALL LETTER HA --> <!-- U+0445: "х" CYRILLIC SMALL LETTER HA -->
<Key <Key
latin:keyLabel="&#x0445;" latin:keyLabel="&#x0445;" />
latin:moreKeys="!text/more_keys_for_cyrillic_ha" />
</merge> </merge>

View File

@ -52,7 +52,6 @@
<!-- U+0436: "ж" CYRILLIC SMALL LETTER ZHE --> <!-- U+0436: "ж" CYRILLIC SMALL LETTER ZHE -->
<Key <Key
latin:keyLabel="&#x0436;" /> latin:keyLabel="&#x0436;" />
<!-- U+044D: "э" CYRILLIC SMALL LETTER E -->
<Key <Key
latin:keyLabel="&#x044D;" /> latin:keyLabel="!text/keylabel_for_east_slavic_row2_11" />
</merge> </merge>

View File

@ -60,10 +60,8 @@ public class KeyCodeDescriptionMapper {
// Manual label substitutions for key labels with no string resource // Manual label substitutions for key labels with no string resource
mKeyLabelMap.put(":-)", R.string.spoken_description_smiley); mKeyLabelMap.put(":-)", R.string.spoken_description_smiley);
// Symbols that most TTS engines can't speak
mKeyCodeMap.put(' ', R.string.spoken_description_space);
// Special non-character codes defined in Keyboard // Special non-character codes defined in Keyboard
mKeyCodeMap.put(Keyboard.CODE_SPACE, R.string.spoken_description_space);
mKeyCodeMap.put(Keyboard.CODE_DELETE, R.string.spoken_description_delete); mKeyCodeMap.put(Keyboard.CODE_DELETE, R.string.spoken_description_delete);
mKeyCodeMap.put(Keyboard.CODE_ENTER, R.string.spoken_description_return); mKeyCodeMap.put(Keyboard.CODE_ENTER, R.string.spoken_description_return);
mKeyCodeMap.put(Keyboard.CODE_SETTINGS, R.string.spoken_description_settings); mKeyCodeMap.put(Keyboard.CODE_SETTINGS, R.string.spoken_description_settings);
@ -71,6 +69,9 @@ public class KeyCodeDescriptionMapper {
mKeyCodeMap.put(Keyboard.CODE_SHORTCUT, R.string.spoken_description_mic); mKeyCodeMap.put(Keyboard.CODE_SHORTCUT, R.string.spoken_description_mic);
mKeyCodeMap.put(Keyboard.CODE_SWITCH_ALPHA_SYMBOL, R.string.spoken_description_to_symbol); mKeyCodeMap.put(Keyboard.CODE_SWITCH_ALPHA_SYMBOL, R.string.spoken_description_to_symbol);
mKeyCodeMap.put(Keyboard.CODE_TAB, R.string.spoken_description_tab); mKeyCodeMap.put(Keyboard.CODE_TAB, R.string.spoken_description_tab);
mKeyCodeMap.put(Keyboard.CODE_LANGUAGE_SWITCH, R.string.spoken_description_language_switch);
mKeyCodeMap.put(Keyboard.CODE_ACTION_NEXT, R.string.spoken_description_action_next);
mKeyCodeMap.put(Keyboard.CODE_ACTION_PREVIOUS, R.string.spoken_description_action_previous);
} }
/** /**
@ -274,8 +275,7 @@ public class KeyCodeDescriptionMapper {
return context.getString(OBSCURED_KEY_RES_ID); return context.getString(OBSCURED_KEY_RES_ID);
} }
final int resId = mKeyCodeMap.get(code); if (mKeyCodeMap.indexOfKey(code) >= 0) {
if (resId != 0) {
return context.getString(mKeyCodeMap.get(code)); return context.getString(mKeyCodeMap.get(code));
} else if (isDefinedNonCtrl) { } else if (isDefinedNonCtrl) {
return Character.toString((char) code); return Character.toString((char) code);

View File

@ -0,0 +1,34 @@
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.inputmethod.compat;
import android.inputmethodservice.InputMethodService;
import java.lang.reflect.Method;
public class InputMethodServiceCompatUtils {
private static final Method METHOD_enableHardwareAcceleration =
CompatUtils.getMethod(InputMethodService.class, "enableHardwareAcceleration");
private InputMethodServiceCompatUtils() {
// This utility class is not publicly instantiable.
}
public static boolean enableHardwareAcceleration(InputMethodService ims) {
return (Boolean)CompatUtils.invoke(ims, false, METHOD_enableHardwareAcceleration);
}
}

View File

@ -414,8 +414,14 @@ public class Key {
@Override @Override
public String toString() { public String toString() {
return String.format("%s/%s %d,%d %dx%d %s/%s/%s", final String label;
Keyboard.printableCode(mCode), mLabel, mX, mY, mWidth, mHeight, mHintLabel, if (StringUtils.codePointCount(mLabel) == 1 && mLabel.codePointAt(0) == mCode) {
label = "";
} else {
label = "/" + mLabel;
}
return String.format("%s%s %d,%d %dx%d %s/%s/%s",
Keyboard.printableCode(mCode), label, mX, mY, mWidth, mHeight, mHintLabel,
KeyboardIconsSet.getIconName(mIconId), backgroundName(mBackgroundType)); KeyboardIconsSet.getIconName(mIconId), backgroundName(mBackgroundType));
} }

View File

@ -25,7 +25,6 @@ public class KeyDetector {
private Keyboard mKeyboard; private Keyboard mKeyboard;
private int mCorrectionX; private int mCorrectionX;
private int mCorrectionY; private int mCorrectionY;
private boolean mProximityCorrectOn;
/** /**
* This class handles key detection. * This class handles key detection.
@ -38,8 +37,9 @@ public class KeyDetector {
} }
public void setKeyboard(Keyboard keyboard, float correctionX, float correctionY) { public void setKeyboard(Keyboard keyboard, float correctionX, float correctionY) {
if (keyboard == null) if (keyboard == null) {
throw new NullPointerException(); throw new NullPointerException();
}
mCorrectionX = (int)correctionX; mCorrectionX = (int)correctionX;
mCorrectionY = (int)correctionY; mCorrectionY = (int)correctionY;
mKeyboard = keyboard; mKeyboard = keyboard;
@ -59,19 +59,9 @@ public class KeyDetector {
} }
public Keyboard getKeyboard() { public Keyboard getKeyboard() {
if (mKeyboard == null)
throw new IllegalStateException("keyboard isn't set");
return mKeyboard; return mKeyboard;
} }
public void setProximityCorrectionEnabled(boolean enabled) {
mProximityCorrectOn = enabled;
}
public boolean isProximityCorrectionEnabled() {
return mProximityCorrectOn;
}
public boolean alwaysAllowsSlidingInput() { public boolean alwaysAllowsSlidingInput() {
return false; return false;
} }

View File

@ -604,9 +604,6 @@ public class Keyboard {
} }
public float getKeyX(TypedArray keyAttr) { public float getKeyX(TypedArray keyAttr) {
final int widthType = Builder.getEnumValue(keyAttr,
R.styleable.Keyboard_Key_keyWidth, KEYWIDTH_NOT_ENUM);
final int keyboardRightEdge = mParams.mOccupiedWidth final int keyboardRightEdge = mParams.mOccupiedWidth
- mParams.mHorizontalEdgesPadding; - mParams.mHorizontalEdgesPadding;
if (keyAttr.hasValue(R.styleable.Keyboard_Key_keyXPos)) { if (keyAttr.hasValue(R.styleable.Keyboard_Key_keyXPos)) {

View File

@ -55,10 +55,15 @@ public class KeyboardId {
public static final int ELEMENT_PHONE_SYMBOLS = 8; public static final int ELEMENT_PHONE_SYMBOLS = 8;
public static final int ELEMENT_NUMBER = 9; public static final int ELEMENT_NUMBER = 9;
public static final int FORM_FACTOR_PHONE = 0;
public static final int FORM_FACTOR_TABLET7 = 1;
public static final int FORM_FACTOR_TABLET10 = 2;
private static final int IME_ACTION_CUSTOM_LABEL = EditorInfo.IME_MASK_ACTION + 1; private static final int IME_ACTION_CUSTOM_LABEL = EditorInfo.IME_MASK_ACTION + 1;
public final InputMethodSubtype mSubtype; public final InputMethodSubtype mSubtype;
public final Locale mLocale; public final Locale mLocale;
public final int mDeviceFormFactor;
public final int mOrientation; public final int mOrientation;
public final int mWidth; public final int mWidth;
public final int mMode; public final int mMode;
@ -72,11 +77,12 @@ public class KeyboardId {
private final int mHashCode; private final int mHashCode;
public KeyboardId(int elementId, InputMethodSubtype subtype, int orientation, int width, public KeyboardId(int elementId, InputMethodSubtype subtype, int deviceFormFactor,
int mode, EditorInfo editorInfo, boolean clobberSettingsKey, boolean shortcutKeyEnabled, int orientation, int width, int mode, EditorInfo editorInfo, boolean clobberSettingsKey,
boolean hasShortcutKey, boolean languageSwitchKeyEnabled) { boolean shortcutKeyEnabled, boolean hasShortcutKey, boolean languageSwitchKeyEnabled) {
mSubtype = subtype; mSubtype = subtype;
mLocale = SubtypeLocale.getSubtypeLocale(subtype); mLocale = SubtypeLocale.getSubtypeLocale(subtype);
mDeviceFormFactor = deviceFormFactor;
mOrientation = orientation; mOrientation = orientation;
mWidth = width; mWidth = width;
mMode = mode; mMode = mode;
@ -94,6 +100,7 @@ public class KeyboardId {
private static int computeHashCode(KeyboardId id) { private static int computeHashCode(KeyboardId id) {
return Arrays.hashCode(new Object[] { return Arrays.hashCode(new Object[] {
id.mDeviceFormFactor,
id.mOrientation, id.mOrientation,
id.mElementId, id.mElementId,
id.mMode, id.mMode,
@ -115,7 +122,8 @@ public class KeyboardId {
private boolean equals(KeyboardId other) { private boolean equals(KeyboardId other) {
if (other == this) if (other == this)
return true; return true;
return other.mOrientation == mOrientation return other.mDeviceFormFactor == mDeviceFormFactor
&& other.mOrientation == mOrientation
&& other.mElementId == mElementId && other.mElementId == mElementId
&& other.mMode == mMode && other.mMode == mMode
&& other.mWidth == mWidth && other.mWidth == mWidth
@ -184,11 +192,11 @@ public class KeyboardId {
@Override @Override
public String toString() { public String toString() {
return String.format("[%s %s:%s %s%d %s %s %s%s%s%s%s%s%s%s]", return String.format("[%s %s:%s %s-%s:%d %s %s %s%s%s%s%s%s%s%s]",
elementIdToName(mElementId), elementIdToName(mElementId),
mLocale, mLocale,
mSubtype.getExtraValueOf(KEYBOARD_LAYOUT_SET), mSubtype.getExtraValueOf(KEYBOARD_LAYOUT_SET),
(mOrientation == 1 ? "port" : "land"), mWidth, deviceFormFactor(mDeviceFormFactor), (mOrientation == 1 ? "port" : "land"), mWidth,
modeName(mMode), modeName(mMode),
imeAction(), imeAction(),
(navigateNext() ? "navigateNext" : ""), (navigateNext() ? "navigateNext" : ""),
@ -226,6 +234,15 @@ public class KeyboardId {
} }
} }
public static String deviceFormFactor(int devoceFormFactor) {
switch (devoceFormFactor) {
case FORM_FACTOR_PHONE: return "phone";
case FORM_FACTOR_TABLET7: return "tablet7";
case FORM_FACTOR_TABLET10: return "tablet10";
default: return null;
}
}
public static String modeName(int mode) { public static String modeName(int mode) {
switch (mode) { switch (mode) {
case MODE_TEXT: return "text"; case MODE_TEXT: return "text";

View File

@ -115,6 +115,7 @@ public class KeyboardLayoutSet {
boolean mNoSettingsKey; boolean mNoSettingsKey;
boolean mLanguageSwitchKeyEnabled; boolean mLanguageSwitchKeyEnabled;
InputMethodSubtype mSubtype; InputMethodSubtype mSubtype;
int mDeviceFormFactor;
int mOrientation; int mOrientation;
int mWidth; int mWidth;
// Sparse array of KeyboardLayoutSet element parameters indexed by element's id. // Sparse array of KeyboardLayoutSet element parameters indexed by element's id.
@ -211,9 +212,10 @@ public class KeyboardLayoutSet {
final boolean noLanguage = SubtypeLocale.isNoLanguage(params.mSubtype); final boolean noLanguage = SubtypeLocale.isNoLanguage(params.mSubtype);
final boolean voiceKeyEnabled = params.mVoiceKeyEnabled && !noLanguage; final boolean voiceKeyEnabled = params.mVoiceKeyEnabled && !noLanguage;
final boolean hasShortcutKey = voiceKeyEnabled && (isSymbols != params.mVoiceKeyOnMain); final boolean hasShortcutKey = voiceKeyEnabled && (isSymbols != params.mVoiceKeyOnMain);
return new KeyboardId(keyboardLayoutSetElementId, params.mSubtype, params.mOrientation, return new KeyboardId(keyboardLayoutSetElementId, params.mSubtype, params.mDeviceFormFactor,
params.mWidth, params.mMode, params.mEditorInfo, params.mNoSettingsKey, params.mOrientation, params.mWidth, params.mMode, params.mEditorInfo,
voiceKeyEnabled, hasShortcutKey, params.mLanguageSwitchKeyEnabled); params.mNoSettingsKey, voiceKeyEnabled, hasShortcutKey,
params.mLanguageSwitchKeyEnabled);
} }
public static class Builder { public static class Builder {
@ -239,9 +241,11 @@ public class KeyboardLayoutSet {
mPackageName, NO_SETTINGS_KEY, mEditorInfo); mPackageName, NO_SETTINGS_KEY, mEditorInfo);
} }
public Builder setScreenGeometry(int orientation, int widthPixels) { public Builder setScreenGeometry(int deviceFormFactor, int orientation, int widthPixels) {
mParams.mOrientation = orientation; final Params params = mParams;
mParams.mWidth = widthPixels; params.mDeviceFormFactor = deviceFormFactor;
params.mOrientation = orientation;
params.mWidth = widthPixels;
return this; return this;
} }

View File

@ -74,7 +74,6 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions {
private MainKeyboardView mKeyboardView; private MainKeyboardView mKeyboardView;
private LatinIME mLatinIME; private LatinIME mLatinIME;
private Resources mResources; private Resources mResources;
private SettingsValues mCurrentSettingsValues;
private KeyboardState mState; private KeyboardState mState;
@ -136,11 +135,11 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions {
} }
public void loadKeyboard(EditorInfo editorInfo, SettingsValues settingsValues) { public void loadKeyboard(EditorInfo editorInfo, SettingsValues settingsValues) {
mCurrentSettingsValues = settingsValues;
final KeyboardLayoutSet.Builder builder = new KeyboardLayoutSet.Builder( final KeyboardLayoutSet.Builder builder = new KeyboardLayoutSet.Builder(
mThemeContext, editorInfo); mThemeContext, editorInfo);
builder.setScreenGeometry(mThemeContext.getResources().getConfiguration().orientation, final Resources res = mThemeContext.getResources();
mThemeContext.getResources().getDisplayMetrics().widthPixels); builder.setScreenGeometry(res.getInteger(R.integer.config_device_form_factor),
res.getConfiguration().orientation, res.getDisplayMetrics().widthPixels);
builder.setSubtype(mSubtypeSwitcher.getCurrentSubtype()); builder.setSubtype(mSubtypeSwitcher.getCurrentSubtype());
builder.setOptions( builder.setOptions(
settingsValues.isVoiceKeyEnabled(editorInfo), settingsValues.isVoiceKeyEnabled(editorInfo),
@ -171,20 +170,20 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions {
} }
private void setKeyboard(final Keyboard keyboard) { private void setKeyboard(final Keyboard keyboard) {
final Keyboard oldKeyboard = mKeyboardView.getKeyboard(); final MainKeyboardView keyboardView = mKeyboardView;
mKeyboardView.setGestureInputEnabled(mCurrentSettingsValues.mGestureInputEnabled); final Keyboard oldKeyboard = keyboardView.getKeyboard();
mKeyboardView.setKeyboard(keyboard); keyboardView.setKeyboard(keyboard);
mCurrentInputView.setKeyboardGeometry(keyboard.mTopPadding); mCurrentInputView.setKeyboardGeometry(keyboard.mTopPadding);
mKeyboardView.setKeyPreviewPopupEnabled( keyboardView.setKeyPreviewPopupEnabled(
SettingsValues.isKeyPreviewPopupEnabled(mPrefs, mResources), SettingsValues.isKeyPreviewPopupEnabled(mPrefs, mResources),
SettingsValues.getKeyPreviewPopupDismissDelay(mPrefs, mResources)); SettingsValues.getKeyPreviewPopupDismissDelay(mPrefs, mResources));
mKeyboardView.updateAutoCorrectionState(mIsAutoCorrectionActive); keyboardView.updateAutoCorrectionState(mIsAutoCorrectionActive);
mKeyboardView.updateShortcutKey(mSubtypeSwitcher.isShortcutImeReady()); keyboardView.updateShortcutKey(mSubtypeSwitcher.isShortcutImeReady());
final boolean subtypeChanged = (oldKeyboard == null) final boolean subtypeChanged = (oldKeyboard == null)
|| !keyboard.mId.mLocale.equals(oldKeyboard.mId.mLocale); || !keyboard.mId.mLocale.equals(oldKeyboard.mId.mLocale);
final boolean needsToDisplayLanguage = mSubtypeSwitcher.needsToDisplayLanguage( final boolean needsToDisplayLanguage = mSubtypeSwitcher.needsToDisplayLanguage(
keyboard.mId.mLocale); keyboard.mId.mLocale);
mKeyboardView.startDisplayLanguageOnSpacebar(subtypeChanged, needsToDisplayLanguage, keyboardView.startDisplayLanguageOnSpacebar(subtypeChanged, needsToDisplayLanguage,
ImfUtils.hasMultipleEnabledIMEsOrSubtypes(mLatinIME, true)); ImfUtils.hasMultipleEnabledIMEsOrSubtypes(mLatinIME, true));
} }
@ -350,7 +349,7 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions {
return mKeyboardView; return mKeyboardView;
} }
public View onCreateInputView() { public View onCreateInputView(boolean isHardwareAcceleratedDrawingEnabled) {
if (mKeyboardView != null) { if (mKeyboardView != null) {
mKeyboardView.closing(); mKeyboardView.closing();
} }
@ -373,6 +372,10 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions {
} }
mKeyboardView = (MainKeyboardView) mCurrentInputView.findViewById(R.id.keyboard_view); mKeyboardView = (MainKeyboardView) mCurrentInputView.findViewById(R.id.keyboard_view);
if (isHardwareAcceleratedDrawingEnabled) {
mKeyboardView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
// TODO: Should use LAYER_TYPE_SOFTWARE when hardware acceleration is off?
}
mKeyboardView.setKeyboardActionListener(mLatinIME); mKeyboardView.setKeyboardActionListener(mLatinIME);
if (mForceNonDistinctMultitouch) { if (mForceNonDistinctMultitouch) {
mKeyboardView.setDistinctMultitouch(false); mKeyboardView.setDistinctMultitouch(false);

View File

@ -25,7 +25,7 @@ import android.graphics.Paint;
import android.graphics.Paint.Align; import android.graphics.Paint.Align;
import android.graphics.PorterDuff; import android.graphics.PorterDuff;
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.Region.Op; import android.graphics.Region;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Message; import android.os.Message;
@ -35,9 +35,9 @@ import android.util.TypedValue;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.TextView; import android.widget.TextView;
import com.android.inputmethod.keyboard.internal.PreviewPlacerView;
import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.LatinImeLogger;
import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.R;
@ -97,9 +97,6 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
// The maximum key label width in the proportion to the key width. // The maximum key label width in the proportion to the key width.
private static final float MAX_LABEL_RATIO = 0.90f; private static final float MAX_LABEL_RATIO = 0.90f;
private final static int GESTURE_DRAWING_WIDTH = 5;
private final static int GESTURE_DRAWING_COLOR = 0xff33b5e5;
// Main keyboard // Main keyboard
private Keyboard mKeyboard; private Keyboard mKeyboard;
protected final KeyDrawParams mKeyDrawParams; protected final KeyDrawParams mKeyDrawParams;
@ -109,10 +106,10 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
protected final KeyPreviewDrawParams mKeyPreviewDrawParams; protected final KeyPreviewDrawParams mKeyPreviewDrawParams;
private boolean mShowKeyPreviewPopup = true; private boolean mShowKeyPreviewPopup = true;
private int mDelayAfterPreview; private int mDelayAfterPreview;
private ViewGroup mPreviewPlacer; private final PreviewPlacerView mPreviewPlacerView;
/** True if the gesture input is enabled. */ /** True if {@link KeyboardView} should handle gesture events. */
protected boolean mGestureInputEnabled; protected boolean mShouldHandleGesture;
// Drawing // Drawing
/** True if the entire keyboard needs to be dimmed. */ /** True if the entire keyboard needs to be dimmed. */
@ -123,16 +120,15 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
private boolean mInvalidateAllKeys; private boolean mInvalidateAllKeys;
/** The keys that should be drawn */ /** The keys that should be drawn */
private final HashSet<Key> mInvalidatedKeys = new HashSet<Key>(); private final HashSet<Key> mInvalidatedKeys = new HashSet<Key>();
/** The region of invalidated keys */ /** The working rectangle variable */
private final Rect mInvalidatedKeysRect = new Rect(); private final Rect mWorkingRect = new Rect();
/** The region of invalidated gestures */
private final Rect mInvalidatedGesturesRect = new Rect();
/** The keyboard bitmap buffer for faster updates */ /** The keyboard bitmap buffer for faster updates */
private Bitmap mBuffer; /** The clip region to draw keys */
private final Region mClipRegion = new Region();
private Bitmap mOffscreenBuffer;
/** The canvas for the above mutable keyboard bitmap */ /** The canvas for the above mutable keyboard bitmap */
private Canvas mCanvas; private Canvas mOffscreenCanvas;
private final Paint mPaint = new Paint(); private final Paint mPaint = new Paint();
private final Paint mGesturePaint = new Paint();
private final Paint.FontMetrics mFontMetrics = new Paint.FontMetrics(); private final Paint.FontMetrics mFontMetrics = new Paint.FontMetrics();
// This sparse array caches key label text height in pixel indexed by key label text size. // This sparse array caches key label text height in pixel indexed by key label text size.
private static final SparseArray<Float> sTextHeightCache = new SparseArray<Float>(); private static final SparseArray<Float> sTextHeightCache = new SparseArray<Float>();
@ -261,10 +257,12 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
} }
public void updateKeyHeight(int keyHeight) { public void updateKeyHeight(int keyHeight) {
if (mKeyLetterRatio >= 0.0f) if (mKeyLetterRatio >= 0.0f) {
mKeyLetterSize = (int)(keyHeight * mKeyLetterRatio); mKeyLetterSize = (int)(keyHeight * mKeyLetterRatio);
if (mKeyLabelRatio >= 0.0f) }
if (mKeyLabelRatio >= 0.0f) {
mKeyLabelSize = (int)(keyHeight * mKeyLabelRatio); mKeyLabelSize = (int)(keyHeight * mKeyLabelRatio);
}
mKeyLargeLabelSize = (int)(keyHeight * mKeyLargeLabelRatio); mKeyLargeLabelSize = (int)(keyHeight * mKeyLargeLabelRatio);
mKeyLargeLetterSize = (int)(keyHeight * mKeyLargeLetterRatio); mKeyLargeLetterSize = (int)(keyHeight * mKeyLargeLetterRatio);
mKeyHintLetterSize = (int)(keyHeight * mKeyHintLetterRatio); mKeyHintLetterSize = (int)(keyHeight * mKeyHintLetterRatio);
@ -346,13 +344,16 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
} }
public void updateKeyHeight(int keyHeight) { public void updateKeyHeight(int keyHeight) {
mPreviewTextSize = (int)(keyHeight * mPreviewTextRatio); if (mPreviewTextRatio >= 0.0f) {
mKeyLetterSize = (int)(keyHeight * mKeyLetterRatio); mPreviewTextSize = (int)(keyHeight * mPreviewTextRatio);
}
if (mKeyLetterRatio >= 0.0f) {
mKeyLetterSize = (int)(keyHeight * mKeyLetterRatio);
}
} }
private static void setAlpha(Drawable drawable, int alpha) { private static void setAlpha(Drawable drawable, int alpha) {
if (drawable == null) if (drawable == null) return;
return;
drawable.setAlpha(alpha); drawable.setAlpha(alpha);
} }
} }
@ -377,18 +378,12 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
R.styleable.KeyboardView_verticalCorrection, 0); R.styleable.KeyboardView_verticalCorrection, 0);
mMoreKeysLayout = a.getResourceId(R.styleable.KeyboardView_moreKeysLayout, 0); mMoreKeysLayout = a.getResourceId(R.styleable.KeyboardView_moreKeysLayout, 0);
mBackgroundDimAlpha = a.getInt(R.styleable.KeyboardView_backgroundDimAlpha, 0); mBackgroundDimAlpha = a.getInt(R.styleable.KeyboardView_backgroundDimAlpha, 0);
mPreviewPlacerView = new PreviewPlacerView(context, a);
a.recycle(); a.recycle();
mDelayAfterPreview = mKeyPreviewDrawParams.mLingerTimeout; mDelayAfterPreview = mKeyPreviewDrawParams.mLingerTimeout;
mPaint.setAntiAlias(true); mPaint.setAntiAlias(true);
// TODO: These paint parameters should be specified via attribute of the view and styleable.
mGesturePaint.setAntiAlias(true);
mGesturePaint.setStyle(Paint.Style.STROKE);
mGesturePaint.setStrokeJoin(Paint.Join.ROUND);
mGesturePaint.setColor(GESTURE_DRAWING_COLOR);
mGesturePaint.setStrokeWidth(GESTURE_DRAWING_WIDTH);
} }
// Read fraction value in TypedArray as float. // Read fraction value in TypedArray as float.
@ -443,8 +438,11 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
return mShowKeyPreviewPopup; return mShowKeyPreviewPopup;
} }
public void setGestureInputEnabled(boolean gestureInputEnabled) { public void setGestureHandlingMode(boolean shouldHandleGesture,
mGestureInputEnabled = gestureInputEnabled; boolean drawsGesturePreviewTrail, boolean drawsGestureFloatingPreviewText) {
mShouldHandleGesture = shouldHandleGesture;
mPreviewPlacerView.setGesturePreviewMode(
drawsGesturePreviewTrail, drawsGestureFloatingPreviewText);
} }
@Override @Override
@ -461,65 +459,107 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
@Override @Override
public void onDraw(Canvas canvas) { public void onDraw(Canvas canvas) {
super.onDraw(canvas); super.onDraw(canvas);
if (mBufferNeedsUpdate || mBuffer == null) { if (canvas.isHardwareAccelerated()) {
mBufferNeedsUpdate = false; onDrawKeyboard(canvas);
onBufferDraw(); return;
} }
canvas.drawBitmap(mBuffer, 0, 0, null); if (mBufferNeedsUpdate || mOffscreenBuffer == null) {
mBufferNeedsUpdate = false;
if (maybeAllocateOffscreenBuffer()) {
mInvalidateAllKeys = true;
// TODO: Stop using the offscreen canvas even when in software rendering
if (mOffscreenCanvas != null) {
mOffscreenCanvas.setBitmap(mOffscreenBuffer);
} else {
mOffscreenCanvas = new Canvas(mOffscreenBuffer);
}
}
onDrawKeyboard(mOffscreenCanvas);
}
canvas.drawBitmap(mOffscreenBuffer, 0, 0, null);
} }
private void onBufferDraw() { private boolean maybeAllocateOffscreenBuffer() {
final int width = getWidth(); final int width = getWidth();
final int height = getHeight(); final int height = getHeight();
if (width == 0 || height == 0) if (width == 0 || height == 0) {
return; return false;
if (mBuffer == null || mBuffer.getWidth() != width || mBuffer.getHeight() != height) {
if (mBuffer != null)
mBuffer.recycle();
mBuffer = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
mInvalidateAllKeys = true;
if (mCanvas != null) {
mCanvas.setBitmap(mBuffer);
} else {
mCanvas = new Canvas(mBuffer);
}
} }
if (mOffscreenBuffer != null && mOffscreenBuffer.getWidth() == width
&& mOffscreenBuffer.getHeight() == height) {
return false;
}
freeOffscreenBuffer();
mOffscreenBuffer = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
return true;
}
private void freeOffscreenBuffer() {
if (mOffscreenBuffer != null) {
mOffscreenBuffer.recycle();
mOffscreenBuffer = null;
}
}
private void onDrawKeyboard(final Canvas canvas) {
if (mKeyboard == null) return; if (mKeyboard == null) return;
final Canvas canvas = mCanvas; final int width = getWidth();
final int height = getHeight();
final Paint paint = mPaint; final Paint paint = mPaint;
final KeyDrawParams params = mKeyDrawParams; final KeyDrawParams params = mKeyDrawParams;
if (mInvalidateAllKeys || mInvalidatedKeys.isEmpty()) { // Calculate clip region and set.
mInvalidatedKeysRect.set(0, 0, width, height); final boolean drawAllKeys = mInvalidateAllKeys || mInvalidatedKeys.isEmpty();
canvas.clipRect(mInvalidatedKeysRect, Op.REPLACE); final boolean isHardwareAccelerated = canvas.isHardwareAccelerated();
canvas.drawColor(Color.BLACK, PorterDuff.Mode.CLEAR); // TODO: Confirm if it's really required to draw all keys when hardware acceleration is on.
if (drawAllKeys || isHardwareAccelerated) {
mClipRegion.set(0, 0, width, height);
} else {
mClipRegion.setEmpty();
for (final Key key : mInvalidatedKeys) {
if (mKeyboard.hasKey(key)) {
final int x = key.mX + getPaddingLeft();
final int y = key.mY + getPaddingTop();
mWorkingRect.set(x, y, x + key.mWidth, y + key.mHeight);
mClipRegion.union(mWorkingRect);
}
}
}
if (!isHardwareAccelerated) {
canvas.clipRegion(mClipRegion, Region.Op.REPLACE);
}
// Draw keyboard background.
canvas.drawColor(Color.BLACK, PorterDuff.Mode.CLEAR);
final Drawable background = getBackground();
if (background != null) {
background.draw(canvas);
}
// TODO: Confirm if it's really required to draw all keys when hardware acceleration is on.
if (drawAllKeys || isHardwareAccelerated) {
// Draw all keys. // Draw all keys.
for (final Key key : mKeyboard.mKeys) { for (final Key key : mKeyboard.mKeys) {
onDrawKey(key, canvas, paint, params); onDrawKey(key, canvas, paint, params);
} }
if (mNeedsToDimEntireKeyboard) {
drawDimRectangle(canvas, mInvalidatedKeysRect, mBackgroundDimAlpha, paint);
}
} else { } else {
// Draw invalidated keys. // Draw invalidated keys.
for (final Key key : mInvalidatedKeys) { for (final Key key : mInvalidatedKeys) {
if (!mKeyboard.hasKey(key)) { if (mKeyboard.hasKey(key)) {
continue; onDrawKey(key, canvas, paint, params);
}
final int x = key.mX + getPaddingLeft();
final int y = key.mY + getPaddingTop();
mInvalidatedKeysRect.set(x, y, x + key.mWidth, y + key.mHeight);
canvas.clipRect(mInvalidatedKeysRect, Op.REPLACE);
canvas.drawColor(Color.BLACK, PorterDuff.Mode.CLEAR);
onDrawKey(key, canvas, paint, params);
if (mNeedsToDimEntireKeyboard) {
drawDimRectangle(canvas, mInvalidatedKeysRect, mBackgroundDimAlpha, paint);
} }
} }
} }
// Overlay a dark rectangle to dim.
if (mNeedsToDimEntireKeyboard) {
paint.setColor(Color.BLACK);
paint.setAlpha(mBackgroundDimAlpha);
// Note: clipRegion() above is in effect if it was called.
canvas.drawRect(0, 0, width, height, paint);
}
// ResearchLogging indicator. // ResearchLogging indicator.
// TODO: Reimplement using a keyboard background image specific to the ResearchLogger, // TODO: Reimplement using a keyboard background image specific to the ResearchLogger,
// and remove this call. // and remove this call.
@ -528,7 +568,6 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
} }
mInvalidatedKeys.clear(); mInvalidatedKeys.clear();
mInvalidatedKeysRect.setEmpty();
mInvalidateAllKeys = false; mInvalidateAllKeys = false;
} }
@ -853,13 +892,6 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
canvas.translate(-x, -y); canvas.translate(-x, -y);
} }
// Overlay a dark rectangle to dim.
private static void drawDimRectangle(Canvas canvas, Rect rect, int alpha, Paint paint) {
paint.setColor(Color.BLACK);
paint.setAlpha(alpha);
canvas.drawRect(rect, paint);
}
public Paint newDefaultLabelPaint() { public Paint newDefaultLabelPaint() {
final Paint paint = new Paint(); final Paint paint = new Paint();
paint.setAntiAlias(true); paint.setAntiAlias(true);
@ -888,58 +920,33 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
mDrawingHandler.dismissKeyPreview(mDelayAfterPreview, tracker); mDrawingHandler.dismissKeyPreview(mDelayAfterPreview, tracker);
} }
private static class PreviewView extends RelativeLayout {
KeyPreviewDrawParams mParams;
Paint mGesturePaint;
public PreviewView(Context context, KeyPreviewDrawParams params, Paint gesturePaint) {
super(context);
setWillNotDraw(false);
mParams = params;
mGesturePaint = gesturePaint;
}
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.translate(mParams.mCoordinates[0], mParams.mCoordinates[1]);
PointerTracker.drawGestureTrailForAllPointerTrackers(canvas, mGesturePaint);
canvas.translate(-mParams.mCoordinates[0], -mParams.mCoordinates[1]);
}
}
private void addKeyPreview(TextView keyPreview) { private void addKeyPreview(TextView keyPreview) {
if (mPreviewPlacer == null) { locatePreviewPlacerView();
createPreviewPlacer(); mPreviewPlacerView.addView(
} keyPreview, ViewLayoutUtils.newLayoutParam(mPreviewPlacerView, 0, 0));
mPreviewPlacer.addView(
keyPreview, ViewLayoutUtils.newLayoutParam(mPreviewPlacer, 0, 0));
} }
private void createPreviewPlacer() { private void locatePreviewPlacerView() {
mPreviewPlacer = new PreviewView(getContext(), mKeyPreviewDrawParams, mGesturePaint); if (mPreviewPlacerView.getParent() != null) {
return;
}
final int[] viewOrigin = new int[2];
getLocationInWindow(viewOrigin);
mPreviewPlacerView.setOrigin(viewOrigin[0], viewOrigin[1]);
final ViewGroup windowContentView = final ViewGroup windowContentView =
(ViewGroup)getRootView().findViewById(android.R.id.content); (ViewGroup)getRootView().findViewById(android.R.id.content);
windowContentView.addView(mPreviewPlacer); windowContentView.addView(mPreviewPlacerView);
}
public void showGestureFloatingPreviewText(String gestureFloatingPreviewText) {
locatePreviewPlacerView();
mPreviewPlacerView.setGestureFloatingPreviewText(gestureFloatingPreviewText);
} }
@Override @Override
public void showGestureTrail(PointerTracker tracker) { public void showGestureTrail(PointerTracker tracker) {
if (mPreviewPlacer == null) { locatePreviewPlacerView();
createPreviewPlacer(); mPreviewPlacerView.invalidatePointer(tracker);
}
final Rect r = tracker.getBoundingBox();
if (!r.isEmpty()) {
// Invalidate the rectangular region encompassing the gesture. This is needed because
// past points along the gesture will fade and gradually disappear.
final KeyPreviewDrawParams params = mKeyPreviewDrawParams;
mInvalidatedGesturesRect.set(r);
mInvalidatedGesturesRect.offset(params.mCoordinates[0], params.mCoordinates[1]);
mInvalidatedGesturesRect.inset(-GESTURE_DRAWING_WIDTH, -GESTURE_DRAWING_WIDTH);
mPreviewPlacer.invalidate(mInvalidatedGesturesRect);
} else {
mPreviewPlacer.invalidate();
}
} }
@SuppressWarnings("deprecation") // setBackgroundDrawable is replaced by setBackground in API16 @SuppressWarnings("deprecation") // setBackgroundDrawable is replaced by setBackground in API16
@ -1055,9 +1062,9 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
mInvalidatedKeys.add(key); mInvalidatedKeys.add(key);
final int x = key.mX + getPaddingLeft(); final int x = key.mX + getPaddingLeft();
final int y = key.mY + getPaddingTop(); final int y = key.mY + getPaddingTop();
mInvalidatedKeysRect.union(x, y, x + key.mWidth, y + key.mHeight); mWorkingRect.set(x, y, x + key.mWidth, y + key.mHeight);
mBufferNeedsUpdate = true; mBufferNeedsUpdate = true;
invalidate(mInvalidatedKeysRect); invalidate(mWorkingRect);
} }
public void closing() { public void closing() {
@ -1082,12 +1089,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
protected void onDetachedFromWindow() { protected void onDetachedFromWindow() {
super.onDetachedFromWindow(); super.onDetachedFromWindow();
closing(); closing();
if (mPreviewPlacer != null) { mPreviewPlacerView.removeAllViews();
mPreviewPlacer.removeAllViews(); freeOffscreenBuffer();
}
if (mBuffer != null) {
mBuffer.recycle();
mBuffer = null;
}
} }
} }

View File

@ -43,6 +43,7 @@ import com.android.inputmethod.accessibility.AccessibilityUtils;
import com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy; import com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy;
import com.android.inputmethod.keyboard.PointerTracker.DrawingProxy; import com.android.inputmethod.keyboard.PointerTracker.DrawingProxy;
import com.android.inputmethod.keyboard.PointerTracker.TimerProxy; import com.android.inputmethod.keyboard.PointerTracker.TimerProxy;
import com.android.inputmethod.keyboard.internal.SuddenJumpingTouchEventHandler;
import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.LatinIME; import com.android.inputmethod.latin.LatinIME;
import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.LatinImeLogger;
@ -153,8 +154,7 @@ public class MainKeyboardView extends KeyboardView implements PointerTracker.Key
} }
break; break;
case MSG_TYPING_STATE_EXPIRED: case MSG_TYPING_STATE_EXPIRED:
cancelAndStartAnimators(keyboardView.mAltCodeKeyWhileTypingFadeoutAnimator, startWhileTypingFadeinAnimation(keyboardView);
keyboardView.mAltCodeKeyWhileTypingFadeinAnimator);
break; break;
} }
} }
@ -228,7 +228,7 @@ public class MainKeyboardView extends KeyboardView implements PointerTracker.Key
removeMessages(MSG_LONGPRESS_KEY); removeMessages(MSG_LONGPRESS_KEY);
} }
public static void cancelAndStartAnimators(final ObjectAnimator animatorToCancel, private static void cancelAndStartAnimators(final ObjectAnimator animatorToCancel,
final ObjectAnimator animatorToStart) { final ObjectAnimator animatorToStart) {
float startFraction = 0.0f; float startFraction = 0.0f;
if (animatorToCancel.isStarted()) { if (animatorToCancel.isStarted()) {
@ -240,18 +240,39 @@ public class MainKeyboardView extends KeyboardView implements PointerTracker.Key
animatorToStart.setCurrentPlayTime(startTime); animatorToStart.setCurrentPlayTime(startTime);
} }
private static void startWhileTypingFadeinAnimation(final MainKeyboardView keyboardView) {
cancelAndStartAnimators(keyboardView.mAltCodeKeyWhileTypingFadeoutAnimator,
keyboardView.mAltCodeKeyWhileTypingFadeinAnimator);
}
private static void startWhileTypingFadeoutAnimation(final MainKeyboardView keyboardView) {
cancelAndStartAnimators(keyboardView.mAltCodeKeyWhileTypingFadeinAnimator,
keyboardView.mAltCodeKeyWhileTypingFadeoutAnimator);
}
@Override @Override
public void startTypingStateTimer() { public void startTypingStateTimer(Key typedKey) {
if (typedKey.isModifier() || typedKey.altCodeWhileTyping()) {
return;
}
final boolean isTyping = isTypingState(); final boolean isTyping = isTypingState();
removeMessages(MSG_TYPING_STATE_EXPIRED); removeMessages(MSG_TYPING_STATE_EXPIRED);
final MainKeyboardView keyboardView = getOuterInstance();
// When user hits the space or the enter key, just cancel the while-typing timer.
final int typedCode = typedKey.mCode;
if (typedCode == Keyboard.CODE_SPACE || typedCode == Keyboard.CODE_ENTER) {
startWhileTypingFadeinAnimation(keyboardView);
return;
}
sendMessageDelayed( sendMessageDelayed(
obtainMessage(MSG_TYPING_STATE_EXPIRED), mParams.mIgnoreAltCodeKeyTimeout); obtainMessage(MSG_TYPING_STATE_EXPIRED), mParams.mIgnoreAltCodeKeyTimeout);
if (isTyping) { if (isTyping) {
return; return;
} }
final MainKeyboardView keyboardView = getOuterInstance(); startWhileTypingFadeoutAnimation(keyboardView);
cancelAndStartAnimators(keyboardView.mAltCodeKeyWhileTypingFadeinAnimator,
keyboardView.mAltCodeKeyWhileTypingFadeoutAnimator);
} }
@Override @Override
@ -461,7 +482,7 @@ public class MainKeyboardView extends KeyboardView implements PointerTracker.Key
super.setKeyboard(keyboard); super.setKeyboard(keyboard);
mKeyDetector.setKeyboard( mKeyDetector.setKeyboard(
keyboard, -getPaddingLeft(), -getPaddingTop() + mVerticalCorrection); keyboard, -getPaddingLeft(), -getPaddingTop() + mVerticalCorrection);
PointerTracker.setKeyDetector(mKeyDetector, mGestureInputEnabled); PointerTracker.setKeyDetector(mKeyDetector, mShouldHandleGesture);
mTouchScreenRegulator.setKeyboard(keyboard); mTouchScreenRegulator.setKeyboard(keyboard);
mMoreKeysPanelCache.clear(); mMoreKeysPanelCache.clear();
@ -479,6 +500,14 @@ public class MainKeyboardView extends KeyboardView implements PointerTracker.Key
AccessibleKeyboardViewProxy.getInstance().setKeyboard(keyboard); AccessibleKeyboardViewProxy.getInstance().setKeyboard(keyboard);
} }
@Override
public void setGestureHandlingMode(final boolean shouldHandleGesture,
boolean drawsGesturePreviewTrail, boolean drawsGestureFloatingPreviewText) {
super.setGestureHandlingMode(shouldHandleGesture, drawsGesturePreviewTrail,
drawsGestureFloatingPreviewText);
PointerTracker.setKeyDetector(mKeyDetector, shouldHandleGesture);
}
/** /**
* Returns whether the device has distinct multi-touch panel. * Returns whether the device has distinct multi-touch panel.
* @return true if the device has distinct multi-touch panel. * @return true if the device has distinct multi-touch panel.
@ -491,23 +520,6 @@ public class MainKeyboardView extends KeyboardView implements PointerTracker.Key
mHasDistinctMultitouch = hasDistinctMultitouch; mHasDistinctMultitouch = hasDistinctMultitouch;
} }
/**
* When enabled, calls to {@link KeyboardActionListener#onCodeInput} will include key
* codes for adjacent keys. When disabled, only the primary key code will be
* reported.
* @param enabled whether or not the proximity correction is enabled
*/
public void setProximityCorrectionEnabled(boolean enabled) {
mKeyDetector.setProximityCorrectionEnabled(enabled);
}
/**
* Returns true if proximity correction is enabled.
*/
public boolean isProximityCorrectionEnabled() {
return mKeyDetector.isProximityCorrectionEnabled();
}
@Override @Override
protected void onAttachedToWindow() { protected void onAttachedToWindow() {
super.onAttachedToWindow(); super.onAttachedToWindow();

View File

@ -39,7 +39,11 @@ public class MoreKeysDetector extends KeyDetector {
Key nearestKey = null; Key nearestKey = null;
int nearestDist = (y < 0) ? mSlideAllowanceSquareTop : mSlideAllowanceSquare; int nearestDist = (y < 0) ? mSlideAllowanceSquareTop : mSlideAllowanceSquare;
for (final Key key : getKeyboard().mKeys) { final Keyboard keyboard = getKeyboard();
if (keyboard == null) {
throw new NullPointerException("Keyboard isn't set");
}
for (final Key key : keyboard.mKeys) {
final int dist = key.squaredDistanceToEdge(touchX, touchY); final int dist = key.squaredDistanceToEdge(touchX, touchY);
if (dist < nearestDist) { if (dist < nearestDist) {
nearestKey = key; nearestKey = key;

View File

@ -18,7 +18,6 @@ package com.android.inputmethod.keyboard;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.Rect;
import android.os.SystemClock; import android.os.SystemClock;
import android.util.Log; import android.util.Log;
import android.view.MotionEvent; import android.view.MotionEvent;
@ -42,8 +41,8 @@ public class PointerTracker {
private static final boolean DEBUG_LISTENER = false; private static final boolean DEBUG_LISTENER = false;
private static boolean DEBUG_MODE = LatinImeLogger.sDBG; private static boolean DEBUG_MODE = LatinImeLogger.sDBG;
// TODO: There should be an option to turn on/off the gesture input. /** True if {@link PointerTracker}s should handle gesture events. */
private static boolean sIsGestureEnabled = true; private static boolean sShouldHandleGesture = false;
private static final int MIN_GESTURE_RECOGNITION_TIME = 100; // msec private static final int MIN_GESTURE_RECOGNITION_TIME = 100; // msec
@ -83,7 +82,7 @@ public class PointerTracker {
} }
public interface TimerProxy { public interface TimerProxy {
public void startTypingStateTimer(); public void startTypingStateTimer(Key typedKey);
public boolean isTypingState(); public boolean isTypingState();
public void startKeyRepeatTimer(PointerTracker tracker); public void startKeyRepeatTimer(PointerTracker tracker);
public void startLongPressTimer(PointerTracker tracker); public void startLongPressTimer(PointerTracker tracker);
@ -96,7 +95,7 @@ public class PointerTracker {
public static class Adapter implements TimerProxy { public static class Adapter implements TimerProxy {
@Override @Override
public void startTypingStateTimer() {} public void startTypingStateTimer(Key typedKey) {}
@Override @Override
public boolean isTypingState() { return false; } public boolean isTypingState() { return false; }
@Override @Override
@ -199,7 +198,7 @@ public class PointerTracker {
sNeedsPhantomSuddenMoveEventHack = needsPhantomSuddenMoveEventHack; sNeedsPhantomSuddenMoveEventHack = needsPhantomSuddenMoveEventHack;
setParameters(MainKeyboardView.PointerTrackerParams.DEFAULT); setParameters(MainKeyboardView.PointerTrackerParams.DEFAULT);
updateGestureInputEnabledState(null, false /* gestureInputEnabled */); updateGestureHandlingMode(null, false /* shouldHandleGesture */);
} }
public static void setParameters(MainKeyboardView.PointerTrackerParams params) { public static void setParameters(MainKeyboardView.PointerTrackerParams params) {
@ -208,14 +207,13 @@ public class PointerTracker {
params.mTouchNoiseThresholdDistance * params.mTouchNoiseThresholdDistance); params.mTouchNoiseThresholdDistance * params.mTouchNoiseThresholdDistance);
} }
private static void updateGestureInputEnabledState(Keyboard keyboard, private static void updateGestureHandlingMode(Keyboard keyboard, boolean shouldHandleGesture) {
boolean gestureInputEnabled) { if (!shouldHandleGesture
if (!gestureInputEnabled
|| AccessibilityUtils.getInstance().isTouchExplorationEnabled() || AccessibilityUtils.getInstance().isTouchExplorationEnabled()
|| (keyboard != null && keyboard.mId.passwordInput())) { || (keyboard != null && keyboard.mId.passwordInput())) {
sIsGestureEnabled = false; sShouldHandleGesture = false;
} else { } else {
sIsGestureEnabled = true; sShouldHandleGesture = true;
} }
} }
@ -243,7 +241,7 @@ public class PointerTracker {
} }
} }
public static void setKeyDetector(KeyDetector keyDetector, boolean gestureInputEnabledByUser) { public static void setKeyDetector(KeyDetector keyDetector, boolean shouldHandleGesture) {
final int trackersSize = sTrackers.size(); final int trackersSize = sTrackers.size();
for (int i = 0; i < trackersSize; ++i) { for (int i = 0; i < trackersSize; ++i) {
final PointerTracker tracker = sTrackers.get(i); final PointerTracker tracker = sTrackers.get(i);
@ -252,7 +250,7 @@ public class PointerTracker {
tracker.mKeyboardLayoutHasBeenChanged = true; tracker.mKeyboardLayoutHasBeenChanged = true;
} }
final Keyboard keyboard = keyDetector.getKeyboard(); final Keyboard keyboard = keyDetector.getKeyboard();
updateGestureInputEnabledState(keyboard, gestureInputEnabledByUser); updateGestureHandlingMode(keyboard, shouldHandleGesture);
} }
public static void dismissAllKeyPreviews() { public static void dismissAllKeyPreviews() {
@ -297,17 +295,6 @@ public class PointerTracker {
sAggregratedPointers.reset(); sAggregratedPointers.reset();
} }
// TODO: To handle multi-touch gestures we may want to move this method to
// {@link PointerTrackerQueue}.
public static void drawGestureTrailForAllPointerTrackers(Canvas canvas, Paint paint) {
final int trackersSize = sTrackers.size();
for (int i = 0; i < trackersSize; ++i) {
final PointerTracker tracker = sTrackers.get(i);
tracker.mGestureStroke.drawGestureTrail(canvas, paint, tracker.getLastX(),
tracker.getLastY());
}
}
private PointerTracker(int id, KeyEventHandler handler) { private PointerTracker(int id, KeyEventHandler handler) {
if (handler == null) if (handler == null)
throw new NullPointerException(); throw new NullPointerException();
@ -342,9 +329,7 @@ public class PointerTracker {
mListener.onPressKey(key.mCode); mListener.onPressKey(key.mCode);
final boolean keyboardLayoutHasBeenChanged = mKeyboardLayoutHasBeenChanged; final boolean keyboardLayoutHasBeenChanged = mKeyboardLayoutHasBeenChanged;
mKeyboardLayoutHasBeenChanged = false; mKeyboardLayoutHasBeenChanged = false;
if (!key.altCodeWhileTyping() && !key.isModifier()) { mTimerProxy.startTypingStateTimer(key);
mTimerProxy.startTypingStateTimer();
}
return keyboardLayoutHasBeenChanged; return keyboardLayoutHasBeenChanged;
} }
return false; return false;
@ -423,7 +408,7 @@ public class PointerTracker {
if (mDrawingProxy != null) { if (mDrawingProxy != null) {
setReleasedKeyGraphics(mCurrentKey); setReleasedKeyGraphics(mCurrentKey);
} }
mCurrentKey = newKey; // Keep {@link #mCurrentKey} that comes from previous keyboard.
} }
final int keyQuarterWidth = mKeyboard.mMostCommonKeyWidth / 4; final int keyQuarterWidth = mKeyboard.mMostCommonKeyWidth / 4;
mKeyQuarterWidthSquared = keyQuarterWidth * keyQuarterWidth; mKeyQuarterWidthSquared = keyQuarterWidth * keyQuarterWidth;
@ -525,6 +510,12 @@ public class PointerTracker {
mDrawingProxy.invalidateKey(key); mDrawingProxy.invalidateKey(key);
} }
public void drawGestureTrail(Canvas canvas, Paint paint) {
if (mInGesture) {
mGestureStroke.drawGestureTrail(canvas, paint, mLastX, mLastY);
}
}
public int getLastX() { public int getLastX() {
return mLastX; return mLastX;
} }
@ -536,9 +527,6 @@ public class PointerTracker {
public long getDownTime() { public long getDownTime() {
return mDownTime; return mDownTime;
} }
public Rect getBoundingBox() {
return mGestureStroke.getBoundingBox();
}
private Key onDownKey(int x, int y, long eventTime) { private Key onDownKey(int x, int y, long eventTime) {
mDownTime = eventTime; mDownTime = eventTime;
@ -669,8 +657,8 @@ public class PointerTracker {
if (queue != null && queue.size() == 1) { if (queue != null && queue.size() == 1) {
mIsPossibleGesture = false; mIsPossibleGesture = false;
// A gesture should start only from the letter key. // A gesture should start only from the letter key.
if (sIsGestureEnabled && mIsAlphabetKeyboard && !mIsShowingMoreKeysPanel && key != null if (sShouldHandleGesture && mIsAlphabetKeyboard && !mIsShowingMoreKeysPanel
&& Keyboard.isLetterCode(key.mCode)) { && key != null && Keyboard.isLetterCode(key.mCode)) {
mIsPossibleGesture = true; mIsPossibleGesture = true;
// TODO: pointer times should be relative to first down even in entire batch input // TODO: pointer times should be relative to first down even in entire batch input
// instead of resetting to 0 for each new down event. // instead of resetting to 0 for each new down event.
@ -714,7 +702,7 @@ public class PointerTracker {
private void onGestureMoveEvent(PointerTracker tracker, int x, int y, long eventTime, private void onGestureMoveEvent(PointerTracker tracker, int x, int y, long eventTime,
boolean isHistorical, Key key) { boolean isHistorical, Key key) {
final int gestureTime = (int)(eventTime - tracker.getDownTime()); final int gestureTime = (int)(eventTime - tracker.getDownTime());
if (sIsGestureEnabled && mIsPossibleGesture) { if (sShouldHandleGesture && mIsPossibleGesture) {
final GestureStroke stroke = mGestureStroke; final GestureStroke stroke = mGestureStroke;
stroke.addPoint(x, y, gestureTime, isHistorical); stroke.addPoint(x, y, gestureTime, isHistorical);
if (!mInGesture && stroke.isStartOfAGesture(gestureTime, sWasInGesture)) { if (!mInGesture && stroke.isStartOfAGesture(gestureTime, sWasInGesture)) {
@ -804,13 +792,16 @@ public class PointerTracker {
final int dx = x - lastX; final int dx = x - lastX;
final int dy = y - lastY; final int dy = y - lastY;
final int lastMoveSquared = dx * dx + dy * dy; final int lastMoveSquared = dx * dx + dy * dy;
// TODO: Should find a way to balance gesture detection and this hack.
if (sNeedsPhantomSuddenMoveEventHack if (sNeedsPhantomSuddenMoveEventHack
&& lastMoveSquared >= mKeyQuarterWidthSquared) { && lastMoveSquared >= mKeyQuarterWidthSquared
&& !mIsPossibleGesture) {
if (DEBUG_MODE) { if (DEBUG_MODE) {
Log.w(TAG, String.format("onMoveEvent:" Log.w(TAG, String.format("onMoveEvent:"
+ " phantom sudden move event is translated to " + " phantom sudden move event is translated to "
+ "up[%d,%d]/down[%d,%d] events", lastX, lastY, x, y)); + "up[%d,%d]/down[%d,%d] events", lastX, lastY, x, y));
} }
// TODO: This should be moved to outside of this nested if-clause?
if (ProductionFlag.IS_EXPERIMENTAL) { if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.pointerTracker_onMoveEvent(x, y, lastX, lastY); ResearchLogger.pointerTracker_onMoveEvent(x, y, lastX, lastY);
} }
@ -826,7 +817,9 @@ public class PointerTracker {
&& !sPointerTrackerQueue.hasModifierKeyOlderThan(this)) { && !sPointerTrackerQueue.hasModifierKeyOlderThan(this)) {
onUpEventInternal(x, y, eventTime); onUpEventInternal(x, y, eventTime);
} }
mKeyAlreadyProcessed = true; if (!mIsPossibleGesture) {
mKeyAlreadyProcessed = true;
}
setReleasedKeyGraphics(oldKey); setReleasedKeyGraphics(oldKey);
} }
} }
@ -842,7 +835,9 @@ public class PointerTracker {
if (mIsAllowedSlidingKeyInput) { if (mIsAllowedSlidingKeyInput) {
onMoveToNewKey(key, x, y); onMoveToNewKey(key, x, y);
} else { } else {
mKeyAlreadyProcessed = true; if (!mIsPossibleGesture) {
mKeyAlreadyProcessed = true;
}
} }
} }
} }
@ -881,6 +876,7 @@ public class PointerTracker {
private void onUpEventInternal(int x, int y, long eventTime) { private void onUpEventInternal(int x, int y, long eventTime) {
mTimerProxy.cancelKeyTimers(); mTimerProxy.cancelKeyTimers();
mIsInSlidingKeyInput = false; mIsInSlidingKeyInput = false;
mIsPossibleGesture = false;
// Release the last pressed key. // Release the last pressed key.
setReleasedKeyGraphics(mCurrentKey); setReleasedKeyGraphics(mCurrentKey);
if (mIsShowingMoreKeysPanel) { if (mIsShowingMoreKeysPanel) {
@ -958,9 +954,7 @@ public class PointerTracker {
public void onRegisterKey(Key key) { public void onRegisterKey(Key key) {
if (key != null) { if (key != null) {
detectAndSendKey(key, key.mX, key.mY); detectAndSendKey(key, key.mX, key.mY);
if (!key.altCodeWhileTyping() && !key.isModifier()) { mTimerProxy.startTypingStateTimer(key);
mTimerProxy.startTypingStateTimer();
}
} }
} }

View File

@ -16,7 +16,6 @@ package com.android.inputmethod.keyboard.internal;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.Rect;
import android.util.FloatMath; import android.util.FloatMath;
import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.Constants;
@ -41,7 +40,6 @@ public class GestureStroke {
private int mMinGestureLength; private int mMinGestureLength;
private int mMinGestureLengthWhileInGesture; private int mMinGestureLengthWhileInGesture;
private int mMinGestureSampleLength; private int mMinGestureSampleLength;
private final Rect mDrawingRect = new Rect();
// TODO: Move some of these to resource. // TODO: Move some of these to resource.
private static final float MIN_GESTURE_LENGTH_RATIO_TO_KEY_WIDTH = 1.0f; private static final float MIN_GESTURE_LENGTH_RATIO_TO_KEY_WIDTH = 1.0f;
@ -90,7 +88,6 @@ public class GestureStroke {
mEventTimes.setLength(0); mEventTimes.setLength(0);
mXCoordinates.setLength(0); mXCoordinates.setLength(0);
mYCoordinates.setLength(0); mYCoordinates.setLength(0);
mDrawingRect.setEmpty();
} }
private void updateLastPoint(final int x, final int y, final int time) { private void updateLastPoint(final int x, final int y, final int time) {
@ -198,8 +195,4 @@ public class GestureStroke {
} }
} }
} }
public Rect getBoundingBox() {
return mDrawingRect;
}
} }

View File

@ -84,6 +84,19 @@ public class KeySpecParser {
} }
mIconId = getIconId(moreKeySpec); mIconId = getIconId(moreKeySpec);
} }
@Override
public String toString() {
final String label = (mIconId == KeyboardIconsSet.ICON_UNDEFINED ? mLabel
: PREFIX_ICON + KeyboardIconsSet.getIconName(mIconId));
final String output = (mCode == Keyboard.CODE_OUTPUT_TEXT ? mOutputText
: Keyboard.printableCode(mCode));
if (StringUtils.codePointCount(label) == 1 && label.codePointAt(0) == mCode) {
return output;
} else {
return label + "|" + output;
}
}
} }
private KeySpecParser() { private KeySpecParser() {

View File

@ -0,0 +1,185 @@
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.inputmethod.keyboard.internal;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.text.TextUtils;
import android.util.SparseArray;
import android.widget.RelativeLayout;
import com.android.inputmethod.keyboard.PointerTracker;
import com.android.inputmethod.latin.R;
public class PreviewPlacerView extends RelativeLayout {
private final Paint mGesturePaint;
private final Paint mTextPaint;
private final int mGestureFloatingPreviewTextColor;
private final int mGestureFloatingPreviewTextOffset;
private final int mGestureFloatingPreviewTextShadowColor;
private final int mGestureFloatingPreviewTextShadowBorder;
private final int mGestureFloatingPreviewTextShadingColor;
private final int mGestureFloatingPreviewTextShadingBorder;
private final int mGestureFloatingPreviewTextConnectorColor;
private final int mGestureFloatingPreviewTextConnectorWidth;
private int mXOrigin;
private int mYOrigin;
private final SparseArray<PointerTracker> mPointers = new SparseArray<PointerTracker>();
private String mGestureFloatingPreviewText;
private boolean mDrawsGesturePreviewTrail;
private boolean mDrawsGestureFloatingPreviewText;
public PreviewPlacerView(Context context, TypedArray keyboardViewAttr) {
super(context);
setWillNotDraw(false);
final int gestureFloatingPreviewTextSize = keyboardViewAttr.getDimensionPixelSize(
R.styleable.KeyboardView_gestureFloatingPreviewTextSize, 0);
mGestureFloatingPreviewTextColor = keyboardViewAttr.getColor(
R.styleable.KeyboardView_gestureFloatingPreviewTextColor, 0);
mGestureFloatingPreviewTextOffset = keyboardViewAttr.getDimensionPixelOffset(
R.styleable.KeyboardView_gestureFloatingPreviewTextOffset, 0);
mGestureFloatingPreviewTextShadowColor = keyboardViewAttr.getColor(
R.styleable.KeyboardView_gestureFloatingPreviewTextShadowColor, 0);
mGestureFloatingPreviewTextShadowBorder = keyboardViewAttr.getDimensionPixelSize(
R.styleable.KeyboardView_gestureFloatingPreviewTextShadowBorder, 0);
mGestureFloatingPreviewTextShadingColor = keyboardViewAttr.getColor(
R.styleable.KeyboardView_gestureFloatingPreviewTextShadingColor, 0);
mGestureFloatingPreviewTextShadingBorder = keyboardViewAttr.getDimensionPixelSize(
R.styleable.KeyboardView_gestureFloatingPreviewTextShadingBorder, 0);
mGestureFloatingPreviewTextConnectorColor = keyboardViewAttr.getColor(
R.styleable.KeyboardView_gestureFloatingPreviewTextConnectorColor, 0);
mGestureFloatingPreviewTextConnectorWidth = keyboardViewAttr.getDimensionPixelSize(
R.styleable.KeyboardView_gestureFloatingPreviewTextConnectorWidth, 0);
final int gesturePreviewTrailColor = keyboardViewAttr.getColor(
R.styleable.KeyboardView_gesturePreviewTrailColor, 0);
final int gesturePreviewTrailWidth = keyboardViewAttr.getDimensionPixelSize(
R.styleable.KeyboardView_gesturePreviewTrailWidth, 0);
mGesturePaint = new Paint();
mGesturePaint.setAntiAlias(true);
mGesturePaint.setStyle(Paint.Style.STROKE);
mGesturePaint.setStrokeJoin(Paint.Join.ROUND);
mGesturePaint.setColor(gesturePreviewTrailColor);
mGesturePaint.setStrokeWidth(gesturePreviewTrailWidth);
mTextPaint = new Paint();
mTextPaint.setAntiAlias(true);
mTextPaint.setStrokeJoin(Paint.Join.ROUND);
mTextPaint.setTextAlign(Align.CENTER);
mTextPaint.setTextSize(gestureFloatingPreviewTextSize);
}
public void setOrigin(int x, int y) {
mXOrigin = x;
mYOrigin = y;
}
public void setGesturePreviewMode(boolean drawsGesturePreviewTrail,
boolean drawsGestureFloatingPreviewText) {
mDrawsGesturePreviewTrail = drawsGesturePreviewTrail;
mDrawsGestureFloatingPreviewText = drawsGestureFloatingPreviewText;
}
public void invalidatePointer(PointerTracker tracker) {
synchronized (mPointers) {
mPointers.put(tracker.mPointerId, tracker);
// TODO: Should narrow the invalidate region.
invalidate();
}
}
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
synchronized (mPointers) {
canvas.translate(mXOrigin, mYOrigin);
final int trackerCount = mPointers.size();
boolean hasDrawnFloatingPreviewText = false;
for (int index = 0; index < trackerCount; index++) {
final PointerTracker tracker = mPointers.valueAt(index);
if (mDrawsGesturePreviewTrail) {
tracker.drawGestureTrail(canvas, mGesturePaint);
}
// TODO: Figure out more cleaner way to draw gesture preview text.
if (mDrawsGestureFloatingPreviewText && !hasDrawnFloatingPreviewText) {
drawGestureFloatingPreviewText(canvas, tracker, mGestureFloatingPreviewText);
hasDrawnFloatingPreviewText = true;
}
}
canvas.translate(-mXOrigin, -mYOrigin);
}
}
public void setGestureFloatingPreviewText(String gestureFloatingPreviewText) {
mGestureFloatingPreviewText = gestureFloatingPreviewText;
invalidate();
}
private void drawGestureFloatingPreviewText(Canvas canvas, PointerTracker tracker,
String gestureFloatingPreviewText) {
if (TextUtils.isEmpty(gestureFloatingPreviewText)) {
return;
}
final Paint paint = mTextPaint;
final int lastX = tracker.getLastX();
final int lastY = tracker.getLastY();
final int textSize = (int)paint.getTextSize();
final int canvasWidth = canvas.getWidth();
final int halfTextWidth = (int)paint.measureText(gestureFloatingPreviewText) / 2 + textSize;
final int textX = Math.min(Math.max(lastX, halfTextWidth), canvasWidth - halfTextWidth);
int textY = Math.max(-textSize, lastY - mGestureFloatingPreviewTextOffset);
if (textY < 0) {
// Paint black text shadow if preview extends above keyboard region.
paint.setStyle(Paint.Style.FILL_AND_STROKE);
paint.setColor(mGestureFloatingPreviewTextShadowColor);
paint.setStrokeWidth(mGestureFloatingPreviewTextShadowBorder);
canvas.drawText(gestureFloatingPreviewText, textX, textY, paint);
}
// Paint the vertical line connecting the touch point to the preview text.
paint.setStyle(Paint.Style.STROKE);
paint.setColor(mGestureFloatingPreviewTextConnectorColor);
paint.setStrokeWidth(mGestureFloatingPreviewTextConnectorWidth);
final int lineTopY = textY - textSize / 4;
canvas.drawLine(lastX, lastY, lastX, lineTopY, paint);
if (lastX != textX) {
// Paint the horizontal line connection the touch point to the preview text.
canvas.drawLine(lastX, lineTopY, textX, lineTopY, paint);
}
// Paint the shading for the text preview
paint.setStyle(Paint.Style.FILL_AND_STROKE);
paint.setColor(mGestureFloatingPreviewTextShadingColor);
paint.setStrokeWidth(mGestureFloatingPreviewTextShadingBorder);
canvas.drawText(gestureFloatingPreviewText, textX, textY, paint);
// Paint the text preview
paint.setColor(mGestureFloatingPreviewTextColor);
paint.setStyle(Paint.Style.FILL);
canvas.drawText(gestureFloatingPreviewText, textX, textY, paint);
}
}

View File

@ -14,12 +14,14 @@
* the License. * the License.
*/ */
package com.android.inputmethod.keyboard; package com.android.inputmethod.keyboard.internal;
import android.content.Context; import android.content.Context;
import android.util.Log; import android.util.Log;
import android.view.MotionEvent; import android.view.MotionEvent;
import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.keyboard.MainKeyboardView;
import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.LatinImeLogger;
import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.Utils; import com.android.inputmethod.latin.Utils;

View File

@ -654,9 +654,12 @@ public class ExpandableDictionary extends Dictionary {
--index; --index;
mLookedUpString[index] = node.mCode; mLookedUpString[index] = node.mCode;
node = node.mParent; node = node.mParent;
} while (node != null); } while (node != null && index > 0);
if (freq >= 0) { // If node is null, we have a word longer than MAX_WORD_LENGTH in the dictionary.
// It's a little unclear how this can happen, but just in case it does it's safer
// to ignore the word in this case.
if (freq >= 0 && node == null) {
suggestions.add(new SuggestedWordInfo(new String(mLookedUpString, index, suggestions.add(new SuggestedWordInfo(new String(mLookedUpString, index,
BinaryDictionary.MAX_WORD_LENGTH - index), BinaryDictionary.MAX_WORD_LENGTH - index),
freq, SuggestedWordInfo.KIND_CORRECTION, mDictType)); freq, SuggestedWordInfo.KIND_CORRECTION, mDictType));

View File

@ -31,11 +31,7 @@ public class JniUtils {
try { try {
System.loadLibrary(JniLibName.JNI_LIB_NAME); System.loadLibrary(JniLibName.JNI_LIB_NAME);
} catch (UnsatisfiedLinkError ule) { } catch (UnsatisfiedLinkError ule) {
Log.e(TAG, "Could not load native library " + JniLibName.JNI_LIB_NAME); Log.e(TAG, "Could not load native library " + JniLibName.JNI_LIB_NAME, ule);
if (LatinImeLogger.sDBG) {
throw new RuntimeException(
"Could not load native library " + JniLibName.JNI_LIB_NAME);
}
} }
} }
} }

View File

@ -60,6 +60,7 @@ import com.android.inputmethod.accessibility.AccessibilityUtils;
import com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy; import com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy;
import com.android.inputmethod.compat.CompatUtils; import com.android.inputmethod.compat.CompatUtils;
import com.android.inputmethod.compat.InputMethodManagerCompatWrapper; import com.android.inputmethod.compat.InputMethodManagerCompatWrapper;
import com.android.inputmethod.compat.InputMethodServiceCompatUtils;
import com.android.inputmethod.compat.SuggestionSpanUtils; import com.android.inputmethod.compat.SuggestionSpanUtils;
import com.android.inputmethod.keyboard.KeyDetector; import com.android.inputmethod.keyboard.KeyDetector;
import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.keyboard.Keyboard;
@ -82,7 +83,8 @@ import java.util.Locale;
* Input method implementation for Qwerty'ish keyboard. * Input method implementation for Qwerty'ish keyboard.
*/ */
public class LatinIME extends InputMethodService implements KeyboardActionListener, public class LatinIME extends InputMethodService implements KeyboardActionListener,
SuggestionStripView.Listener, TargetApplicationGetter.OnTargetApplicationKnownListener { SuggestionStripView.Listener, TargetApplicationGetter.OnTargetApplicationKnownListener,
Suggest.SuggestInitializationListener {
private static final String TAG = LatinIME.class.getSimpleName(); private static final String TAG = LatinIME.class.getSimpleName();
private static final boolean TRACE = false; private static final boolean TRACE = false;
private static boolean DEBUG; private static boolean DEBUG;
@ -174,6 +176,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private AlertDialog mOptionsDialog; private AlertDialog mOptionsDialog;
private final boolean mIsHardwareAcceleratedDrawingEnabled;
public final UIHandler mHandler = new UIHandler(this); public final UIHandler mHandler = new UIHandler(this);
public static class UIHandler extends StaticInnerHandlerWrapper<LatinIME> { public static class UIHandler extends StaticInnerHandlerWrapper<LatinIME> {
@ -346,6 +350,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
super(); super();
mSubtypeSwitcher = SubtypeSwitcher.getInstance(); mSubtypeSwitcher = SubtypeSwitcher.getInstance();
mKeyboardSwitcher = KeyboardSwitcher.getInstance(); mKeyboardSwitcher = KeyboardSwitcher.getInstance();
mIsHardwareAcceleratedDrawingEnabled =
InputMethodServiceCompatUtils.enableHardwareAcceleration(this);
Log.i(TAG, "Hardware accelerated drawing: " + mIsHardwareAcceleratedDrawingEnabled);
} }
@Override @Override
@ -426,6 +433,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
resetContactsDictionary(null == mSuggest ? null : mSuggest.getContactsDictionary()); resetContactsDictionary(null == mSuggest ? null : mSuggest.getContactsDictionary());
} }
@Override
public void onUpdateMainDictionaryAvailability(boolean isMainDictionaryAvailable) {
mIsMainDictionaryAvailable = isMainDictionaryAvailable;
updateKeyboardViewGestureHandlingModeByMainDictionaryAvailability();
}
private void initSuggest() { private void initSuggest() {
final Locale subtypeLocale = mSubtypeSwitcher.getCurrentSubtypeLocale(); final Locale subtypeLocale = mSubtypeSwitcher.getCurrentSubtypeLocale();
final String localeStr = subtypeLocale.toString(); final String localeStr = subtypeLocale.toString();
@ -437,7 +450,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
} else { } else {
oldContactsDictionary = null; oldContactsDictionary = null;
} }
mSuggest = new Suggest(this, subtypeLocale); mSuggest = new Suggest(this /* Context */, subtypeLocale,
this /* SuggestInitializationListener */);
if (mCurrentSettings.mCorrectionEnabled) { if (mCurrentSettings.mCorrectionEnabled) {
mSuggest.setAutoCorrectionThreshold(mCurrentSettings.mAutoCorrectionThreshold); mSuggest.setAutoCorrectionThreshold(mCurrentSettings.mAutoCorrectionThreshold);
} }
@ -531,15 +545,16 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
commitTyped(LastComposedWord.NOT_A_SEPARATOR); commitTyped(LastComposedWord.NOT_A_SEPARATOR);
mConnection.finishComposingText(); mConnection.finishComposingText();
mConnection.endBatchEdit(); mConnection.endBatchEdit();
if (isShowingOptionDialog()) if (isShowingOptionDialog()) {
mOptionsDialog.dismiss(); mOptionsDialog.dismiss();
}
} }
super.onConfigurationChanged(conf); super.onConfigurationChanged(conf);
} }
@Override @Override
public View onCreateInputView() { public View onCreateInputView() {
return mKeyboardSwitcher.onCreateInputView(); return mKeyboardSwitcher.onCreateInputView(mIsHardwareAcceleratedDrawingEnabled);
} }
@Override @Override
@ -651,40 +666,61 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
accessUtils.onStartInputViewInternal(editorInfo, restarting); accessUtils.onStartInputViewInternal(editorInfo, restarting);
} }
mSubtypeSwitcher.updateParametersOnStartInputView(); if (!restarting) {
mSubtypeSwitcher.updateParametersOnStartInputView();
}
// The EditorInfo might have a flag that affects fullscreen mode. // The EditorInfo might have a flag that affects fullscreen mode.
// Note: This call should be done by InputMethodService? // Note: This call should be done by InputMethodService?
updateFullscreenMode(); updateFullscreenMode();
mLastSelectionStart = editorInfo.initialSelStart;
mLastSelectionEnd = editorInfo.initialSelEnd;
mApplicationSpecifiedCompletions = null; mApplicationSpecifiedCompletions = null;
inputView.closing(); final boolean selectionChanged = mLastSelectionStart != editorInfo.initialSelStart
mEnteredText = null; || mLastSelectionEnd != editorInfo.initialSelEnd;
resetComposingState(true /* alsoResetLastComposedWord */); if (!restarting || selectionChanged) {
mDeleteCount = 0; // If the selection changed, we reset the input state. Essentially, we come here with
mSpaceState = SPACE_STATE_NONE; // restarting == true when the app called setText() or similar. We should reset the
// state if the app set the text to something else, but keep it if it set a suggestion
// or something.
mEnteredText = null;
resetComposingState(true /* alsoResetLastComposedWord */);
mDeleteCount = 0;
mSpaceState = SPACE_STATE_NONE;
loadSettings(); if (mSuggestionStripView != null) {
mSuggestionStripView.clear();
if (mSuggest != null && mCurrentSettings.mCorrectionEnabled) { }
mSuggest.setAutoCorrectionThreshold(mCurrentSettings.mAutoCorrectionThreshold);
} }
switcher.loadKeyboard(editorInfo, mCurrentSettings); if (!restarting) {
inputView.closing();
loadSettings();
if (mSuggestionStripView != null) if (mSuggest != null && mCurrentSettings.mCorrectionEnabled) {
mSuggestionStripView.clear(); mSuggest.setAutoCorrectionThreshold(mCurrentSettings.mAutoCorrectionThreshold);
}
switcher.loadKeyboard(editorInfo, mCurrentSettings);
updateKeyboardViewGestureHandlingModeByMainDictionaryAvailability();
}
setSuggestionStripShownInternal( setSuggestionStripShownInternal(
isSuggestionsStripVisible(), /* needsInputViewShown */ false); isSuggestionsStripVisible(), /* needsInputViewShown */ false);
mLastSelectionStart = editorInfo.initialSelStart;
mLastSelectionEnd = editorInfo.initialSelEnd;
// If we come here something in the text state is very likely to have changed.
// We should update the shift state regardless of whether we are restarting or not, because
// this is not perceived as a layout change that may be disruptive like we may have with
// switcher.loadKeyboard; in apps like Talk, we come here when the text is sent and the
// field gets emptied and we need to re-evaluate the shift state, but not the whole layout
// which would be disruptive.
mKeyboardSwitcher.updateShiftState();
mHandler.cancelUpdateSuggestionStrip(); mHandler.cancelUpdateSuggestionStrip();
mHandler.cancelDoubleSpacesTimer(); mHandler.cancelDoubleSpacesTimer();
inputView.setKeyPreviewPopupEnabled(mCurrentSettings.mKeyPreviewPopupOn, inputView.setKeyPreviewPopupEnabled(mCurrentSettings.mKeyPreviewPopupOn,
mCurrentSettings.mKeyPreviewPopupDismissDelay); mCurrentSettings.mKeyPreviewPopupDismissDelay);
inputView.setProximityCorrectionEnabled(true);
if (TRACE) Debug.startMethodTracing("/data/trace/latinime"); if (TRACE) Debug.startMethodTracing("/data/trace/latinime");
} }
@ -856,13 +892,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
} }
} }
} }
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.latinIME_onDisplayCompletions(applicationSpecifiedCompletions);
}
if (!mCurrentSettings.isApplicationSpecifiedCompletionsOn()) return; if (!mCurrentSettings.isApplicationSpecifiedCompletionsOn()) return;
mApplicationSpecifiedCompletions = applicationSpecifiedCompletions; mApplicationSpecifiedCompletions = applicationSpecifiedCompletions;
if (applicationSpecifiedCompletions == null) { if (applicationSpecifiedCompletions == null) {
clearSuggestionStrip(); clearSuggestionStrip();
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.latinIME_onDisplayCompletions(null);
}
return; return;
} }
@ -884,6 +920,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// this case? This says to keep whatever the user typed. // this case? This says to keep whatever the user typed.
mWordComposer.setAutoCorrection(mWordComposer.getTypedWord()); mWordComposer.setAutoCorrection(mWordComposer.getTypedWord());
setSuggestionStripShown(true); setSuggestionStripShown(true);
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.latinIME_onDisplayCompletions(applicationSpecifiedCompletions);
}
} }
private void setSuggestionStripShownInternal(boolean shown, boolean needsInputViewShown) { private void setSuggestionStripShownInternal(boolean shown, boolean needsInputViewShown) {
@ -1003,15 +1042,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final CharSequence typedWord = mWordComposer.getTypedWord(); final CharSequence typedWord = mWordComposer.getTypedWord();
if (typedWord.length() > 0) { if (typedWord.length() > 0) {
mConnection.commitText(typedWord, 1); mConnection.commitText(typedWord, 1);
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.latinIME_commitText(typedWord);
}
final CharSequence prevWord = addToUserHistoryDictionary(typedWord); final CharSequence prevWord = addToUserHistoryDictionary(typedWord);
mLastComposedWord = mWordComposer.commitWord( mLastComposedWord = mWordComposer.commitWord(
LastComposedWord.COMMIT_TYPE_USER_TYPED_WORD, typedWord.toString(), LastComposedWord.COMMIT_TYPE_USER_TYPED_WORD, typedWord.toString(),
separatorCode, prevWord); separatorCode, prevWord);
} }
updateSuggestionStrip();
} }
// Called from the KeyboardSwitcher which needs to know auto caps state to display // Called from the KeyboardSwitcher which needs to know auto caps state to display
@ -1048,12 +1083,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
if (lastTwo != null && lastTwo.length() == 2 if (lastTwo != null && lastTwo.length() == 2
&& lastTwo.charAt(0) == Keyboard.CODE_SPACE) { && lastTwo.charAt(0) == Keyboard.CODE_SPACE) {
mConnection.deleteSurroundingText(2, 0); mConnection.deleteSurroundingText(2, 0);
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.latinIME_deleteSurroundingText(2);
}
mConnection.commitText(lastTwo.charAt(1) + " ", 1); mConnection.commitText(lastTwo.charAt(1) + " ", 1);
if (ProductionFlag.IS_EXPERIMENTAL) { if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.latinIME_swapSwapperAndSpaceWhileInBatchEdit(); ResearchLogger.latinIME_swapSwapperAndSpace();
} }
mKeyboardSwitcher.updateShiftState(); mKeyboardSwitcher.updateShiftState();
} }
@ -1070,9 +1102,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mHandler.cancelDoubleSpacesTimer(); mHandler.cancelDoubleSpacesTimer();
mConnection.deleteSurroundingText(2, 0); mConnection.deleteSurroundingText(2, 0);
mConnection.commitText(". ", 1); mConnection.commitText(". ", 1);
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.latinIME_doubleSpaceAutoPeriod();
}
mKeyboardSwitcher.updateShiftState(); mKeyboardSwitcher.updateShiftState();
return true; return true;
} }
@ -1136,9 +1165,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private void performEditorAction(int actionId) { private void performEditorAction(int actionId) {
mConnection.performEditorAction(actionId); mConnection.performEditorAction(actionId);
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.latinIME_performEditorAction(actionId);
}
} }
private void handleLanguageSwitchKey() { private void handleLanguageSwitchKey() {
@ -1175,6 +1201,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// For backward compatibility. See {@link InputMethodService#sendKeyChar(char)}. // For backward compatibility. See {@link InputMethodService#sendKeyChar(char)}.
if (code >= '0' && code <= '9') { if (code >= '0' && code <= '9') {
super.sendKeyChar((char)code); super.sendKeyChar((char)code);
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.latinIME_sendKeyCodePoint(code);
}
return; return;
} }
@ -1191,9 +1220,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final String text = new String(new int[] { code }, 0, 1); final String text = new String(new int[] { code }, 0, 1);
mConnection.commitText(text, text.length()); mConnection.commitText(text, text.length());
} }
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.latinIME_sendKeyCodePoint(code);
}
} }
// Implementation of {@link KeyboardActionListener}. // Implementation of {@link KeyboardActionListener}.
@ -1205,11 +1231,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
} }
mLastKeyTime = when; mLastKeyTime = when;
mConnection.beginBatchEdit(); mConnection.beginBatchEdit();
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.latinIME_onCodeInput(primaryCode, x, y);
}
final KeyboardSwitcher switcher = mKeyboardSwitcher; final KeyboardSwitcher switcher = mKeyboardSwitcher;
// The space state depends only on the last character pressed and its own previous // The space state depends only on the last character pressed and its own previous
// state. Here, we revert the space state to neutral if the key is actually modifying // state. Here, we revert the space state to neutral if the key is actually modifying
@ -1291,21 +1312,22 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mLastComposedWord.deactivate(); mLastComposedWord.deactivate();
mEnteredText = null; mEnteredText = null;
mConnection.endBatchEdit(); mConnection.endBatchEdit();
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.latinIME_onCodeInput(primaryCode, x, y);
}
} }
// Called from PointerTracker through the KeyboardActionListener interface // Called from PointerTracker through the KeyboardActionListener interface
@Override @Override
public void onTextInput(CharSequence text) { public void onTextInput(CharSequence rawText) {
mConnection.beginBatchEdit(); mConnection.beginBatchEdit();
commitTyped(LastComposedWord.NOT_A_SEPARATOR); commitTyped(LastComposedWord.NOT_A_SEPARATOR);
text = specificTldProcessingOnTextInput(text); mHandler.postUpdateSuggestionStrip();
final CharSequence text = specificTldProcessingOnTextInput(rawText);
if (SPACE_STATE_PHANTOM == mSpaceState) { if (SPACE_STATE_PHANTOM == mSpaceState) {
sendKeyCodePoint(Keyboard.CODE_SPACE); sendKeyCodePoint(Keyboard.CODE_SPACE);
} }
mConnection.commitText(text, 1); mConnection.commitText(text, 1);
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.latinIME_commitText(text);
}
mConnection.endBatchEdit(); mConnection.endBatchEdit();
mKeyboardSwitcher.updateShiftState(); mKeyboardSwitcher.updateShiftState();
mKeyboardSwitcher.onCodeInput(Keyboard.CODE_OUTPUT_TEXT); mKeyboardSwitcher.onCodeInput(Keyboard.CODE_OUTPUT_TEXT);
@ -1334,6 +1356,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mWordComposer.setBatchInputPointers(batchPointers); mWordComposer.setBatchInputPointers(batchPointers);
final SuggestedWords suggestedWords = getSuggestedWords(); final SuggestedWords suggestedWords = getSuggestedWords();
showSuggestionStrip(suggestedWords, null); showSuggestionStrip(suggestedWords, null);
final String gestureFloatingPreviewText = (suggestedWords.size() > 0)
? suggestedWords.getWord(0) : null;
mKeyboardSwitcher.getKeyboardView()
.showGestureFloatingPreviewText(gestureFloatingPreviewText);
} }
@Override @Override
@ -1341,6 +1367,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mWordComposer.setBatchInputPointers(batchPointers); mWordComposer.setBatchInputPointers(batchPointers);
final SuggestedWords suggestedWords = getSuggestedWords(); final SuggestedWords suggestedWords = getSuggestedWords();
showSuggestionStrip(suggestedWords, null); showSuggestionStrip(suggestedWords, null);
mKeyboardSwitcher.getKeyboardView().showGestureFloatingPreviewText(null);
if (suggestedWords == null || suggestedWords.size() == 0) { if (suggestedWords == null || suggestedWords.size() == 0) {
return; return;
} }
@ -1395,9 +1422,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// like the smiley key or the .com key. // like the smiley key or the .com key.
final int length = mEnteredText.length(); final int length = mEnteredText.length();
mConnection.deleteSurroundingText(length, 0); mConnection.deleteSurroundingText(length, 0);
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.latinIME_deleteSurroundingText(length);
}
// If we have mEnteredText, then we know that mHasUncommittedTypedChars == false. // If we have mEnteredText, then we know that mHasUncommittedTypedChars == false.
// In addition we know that spaceState is false, and that we should not be // In addition we know that spaceState is false, and that we should not be
// reverting any autocorrect at this point. So we can safely return. // reverting any autocorrect at this point. So we can safely return.
@ -1417,9 +1441,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mHandler.postUpdateSuggestionStrip(); mHandler.postUpdateSuggestionStrip();
} else { } else {
mConnection.deleteSurroundingText(1, 0); mConnection.deleteSurroundingText(1, 0);
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.latinIME_deleteSurroundingText(1);
}
} }
} else { } else {
if (mLastComposedWord.canRevertCommit()) { if (mLastComposedWord.canRevertCommit()) {
@ -1448,9 +1469,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final int lengthToDelete = mLastSelectionEnd - mLastSelectionStart; final int lengthToDelete = mLastSelectionEnd - mLastSelectionStart;
mConnection.setSelection(mLastSelectionEnd, mLastSelectionEnd); mConnection.setSelection(mLastSelectionEnd, mLastSelectionEnd);
mConnection.deleteSurroundingText(lengthToDelete, 0); mConnection.deleteSurroundingText(lengthToDelete, 0);
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.latinIME_deleteSurroundingText(lengthToDelete);
}
} else { } else {
// There is no selection, just delete one character. // There is no selection, just delete one character.
if (NOT_A_CURSOR_POSITION == mLastSelectionEnd) { if (NOT_A_CURSOR_POSITION == mLastSelectionEnd) {
@ -1469,14 +1487,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
} else { } else {
mConnection.deleteSurroundingText(1, 0); mConnection.deleteSurroundingText(1, 0);
} }
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.latinIME_deleteSurroundingText(1);
}
if (mDeleteCount > DELETE_ACCELERATE_AT) { if (mDeleteCount > DELETE_ACCELERATE_AT) {
mConnection.deleteSurroundingText(1, 0); mConnection.deleteSurroundingText(1, 0);
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.latinIME_deleteSurroundingText(1);
}
} }
} }
if (mCurrentSettings.isSuggestionsRequested(mDisplayOrientation)) { if (mCurrentSettings.isSuggestionsRequested(mDisplayOrientation)) {
@ -1579,11 +1591,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
boolean didAutoCorrect = false; boolean didAutoCorrect = false;
// Handle separator // Handle separator
if (mWordComposer.isComposingWord()) { if (mWordComposer.isComposingWord()) {
// In certain languages where single quote is a separator, it's better if (mCurrentSettings.mCorrectionEnabled) {
// 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 (mCurrentSettings.mCorrectionEnabled && primaryCode != Keyboard.CODE_SINGLE_QUOTE) {
commitCurrentAutoCorrection(primaryCode); commitCurrentAutoCorrection(primaryCode);
didAutoCorrect = true; didAutoCorrect = true;
} else { } else {
@ -1617,13 +1625,18 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
if (swapWeakSpace) { if (swapWeakSpace) {
swapSwapperAndSpace(); swapSwapperAndSpace();
mSpaceState = SPACE_STATE_SWAP_PUNCTUATION; mSpaceState = SPACE_STATE_SWAP_PUNCTUATION;
} else if (SPACE_STATE_PHANTOM == spaceState) { } else if (SPACE_STATE_PHANTOM == spaceState
&& !mCurrentSettings.isWeakSpaceStripper(primaryCode)) {
// If we are in phantom space state, and the user presses a separator, we want to // If we are in phantom space state, and the user presses a separator, we want to
// stay in phantom space state so that the next keypress has a chance to add the // stay in phantom space state so that the next keypress has a chance to add the
// space. For example, if I type "Good dat", pick "day" from the suggestion strip // space. For example, if I type "Good dat", pick "day" from the suggestion strip
// then insert a comma and go on to typing the next word, I want the space to be // then insert a comma and go on to typing the next word, I want the space to be
// inserted automatically before the next word, the same way it is when I don't // inserted automatically before the next word, the same way it is when I don't
// input the comma. // input the comma.
// The case is a little different if the separator is a space stripper. Such a
// separator does not normally need a space on the right (that's the difference
// between swappers and strippers), so we should not stay in phantom space state if
// the separator is a stripper. Hence the additional test above.
mSpaceState = SPACE_STATE_PHANTOM; mSpaceState = SPACE_STATE_PHANTOM;
} }
@ -1647,8 +1660,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
commitTyped(LastComposedWord.NOT_A_SEPARATOR); commitTyped(LastComposedWord.NOT_A_SEPARATOR);
requestHideSelf(0); requestHideSelf(0);
MainKeyboardView inputView = mKeyboardSwitcher.getKeyboardView(); MainKeyboardView inputView = mKeyboardSwitcher.getKeyboardView();
if (inputView != null) if (inputView != null) {
inputView.closing(); inputView.closing();
}
} }
// TODO: make this private // TODO: make this private
@ -1799,10 +1813,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
+ "is empty? Impossible! I must commit suicide."); + "is empty? Impossible! I must commit suicide.");
} }
Utils.Stats.onAutoCorrection(typedWord, autoCorrection.toString(), separatorCodePoint); Utils.Stats.onAutoCorrection(typedWord, autoCorrection.toString(), separatorCodePoint);
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.latinIME_commitCurrentAutoCorrection(typedWord,
autoCorrection.toString());
}
mExpectingUpdateSelection = true; mExpectingUpdateSelection = true;
commitChosenWord(autoCorrection, LastComposedWord.COMMIT_TYPE_DECIDED_WORD, commitChosenWord(autoCorrection, LastComposedWord.COMMIT_TYPE_DECIDED_WORD,
separatorCodePoint); separatorCodePoint);
@ -1828,13 +1838,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// So, LatinImeLogger logs "" as a user's input. // So, LatinImeLogger logs "" as a user's input.
LatinImeLogger.logOnManualSuggestion("", suggestion.toString(), index, suggestedWords); LatinImeLogger.logOnManualSuggestion("", suggestion.toString(), index, suggestedWords);
// Rely on onCodeInput to do the complicated swapping/stripping logic consistently. // Rely on onCodeInput to do the complicated swapping/stripping logic consistently.
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.latinIME_punctuationSuggestion(index, suggestion, x, y);
}
final int primaryCode = suggestion.charAt(0); final int primaryCode = suggestion.charAt(0);
onCodeInput(primaryCode, onCodeInput(primaryCode,
KeyboardActionListener.SUGGESTION_STRIP_COORDINATE, KeyboardActionListener.SUGGESTION_STRIP_COORDINATE,
KeyboardActionListener.SUGGESTION_STRIP_COORDINATE); KeyboardActionListener.SUGGESTION_STRIP_COORDINATE);
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.latinIME_punctuationSuggestion(index, suggestion, x, y);
}
return; return;
} }
@ -1861,10 +1871,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final CompletionInfo completionInfo = mApplicationSpecifiedCompletions[index]; final CompletionInfo completionInfo = mApplicationSpecifiedCompletions[index];
mConnection.commitCompletion(completionInfo); mConnection.commitCompletion(completionInfo);
mConnection.endBatchEdit(); mConnection.endBatchEdit();
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.latinIME_pickApplicationSpecifiedCompletion(index,
completionInfo.getText(), x, y);
}
return; return;
} }
@ -1873,12 +1879,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final String replacedWord = mWordComposer.getTypedWord().toString(); final String replacedWord = mWordComposer.getTypedWord().toString();
LatinImeLogger.logOnManualSuggestion(replacedWord, LatinImeLogger.logOnManualSuggestion(replacedWord,
suggestion.toString(), index, suggestedWords); suggestion.toString(), index, suggestedWords);
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.latinIME_pickSuggestionManually(replacedWord, index, suggestion, x, y);
}
mExpectingUpdateSelection = true; mExpectingUpdateSelection = true;
commitChosenWord(suggestion, LastComposedWord.COMMIT_TYPE_MANUAL_PICK, commitChosenWord(suggestion, LastComposedWord.COMMIT_TYPE_MANUAL_PICK,
LastComposedWord.NOT_A_SEPARATOR); LastComposedWord.NOT_A_SEPARATOR);
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.latinIME_pickSuggestionManually(replacedWord, index, suggestion, x, y);
}
mConnection.endBatchEdit(); mConnection.endBatchEdit();
// Don't allow cancellation of manual pick // Don't allow cancellation of manual pick
mLastComposedWord.deactivate(); mLastComposedWord.deactivate();
@ -1913,9 +1919,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final SuggestedWords suggestedWords = mSuggestionStripView.getSuggestions(); final SuggestedWords suggestedWords = mSuggestionStripView.getSuggestions();
mConnection.commitText(SuggestionSpanUtils.getTextWithSuggestionSpan( mConnection.commitText(SuggestionSpanUtils.getTextWithSuggestionSpan(
this, chosenWord, suggestedWords, mIsMainDictionaryAvailable), 1); this, chosenWord, suggestedWords, mIsMainDictionaryAvailable), 1);
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.latinIME_commitText(chosenWord);
}
// Add the word to the user history dictionary // Add the word to the user history dictionary
final CharSequence prevWord = addToUserHistoryDictionary(chosenWord); final CharSequence prevWord = addToUserHistoryDictionary(chosenWord);
// TODO: figure out here if this is an auto-correct or if the best word is actually // TODO: figure out here if this is an auto-correct or if the best word is actually
@ -1982,9 +1985,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mWordComposer.setComposingWord(word, mKeyboardSwitcher.getKeyboard()); mWordComposer.setComposingWord(word, mKeyboardSwitcher.getKeyboard());
final int length = word.length(); final int length = word.length();
mConnection.deleteSurroundingText(length, 0); mConnection.deleteSurroundingText(length, 0);
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.latinIME_deleteSurroundingText(length);
}
mConnection.setComposingText(word, 1); mConnection.setComposingText(word, 1);
mHandler.postUpdateSuggestionStrip(); mHandler.postUpdateSuggestionStrip();
} }
@ -2012,9 +2012,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
} }
} }
mConnection.deleteSurroundingText(deleteLength, 0); mConnection.deleteSurroundingText(deleteLength, 0);
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.latinIME_deleteSurroundingText(deleteLength);
}
if (!TextUtils.isEmpty(previousWord) && !TextUtils.isEmpty(committedWord)) { if (!TextUtils.isEmpty(previousWord) && !TextUtils.isEmpty(committedWord)) {
mUserHistoryDictionary.cancelAddingUserHistory( mUserHistoryDictionary.cancelAddingUserHistory(
previousWord.toString(), committedWord.toString()); previousWord.toString(), committedWord.toString());
@ -2044,18 +2041,30 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
public void onRefreshKeyboard() { public void onRefreshKeyboard() {
// When the device locale is changed in SetupWizard etc., this method may get called via // When the device locale is changed in SetupWizard etc., this method may get called via
// onConfigurationChanged before SoftInputWindow is shown. // onConfigurationChanged before SoftInputWindow is shown.
initSuggest();
loadSettings();
if (mKeyboardSwitcher.getKeyboardView() != null) { if (mKeyboardSwitcher.getKeyboardView() != null) {
// Reload keyboard because the current language has been changed. // Reload keyboard because the current language has been changed.
mKeyboardSwitcher.loadKeyboard(getCurrentInputEditorInfo(), mCurrentSettings); mKeyboardSwitcher.loadKeyboard(getCurrentInputEditorInfo(), mCurrentSettings);
updateKeyboardViewGestureHandlingModeByMainDictionaryAvailability();
} }
initSuggest();
loadSettings();
// Since we just changed languages, we should re-evaluate suggestions with whatever word // Since we just changed languages, we should re-evaluate suggestions with whatever word
// we are currently composing. If we are not composing anything, we may want to display // we are currently composing. If we are not composing anything, we may want to display
// predictions or punctuation signs (which is done by the updateSuggestionStrip anyway). // predictions or punctuation signs (which is done by the updateSuggestionStrip anyway).
mHandler.postUpdateSuggestionStrip(); mHandler.postUpdateSuggestionStrip();
} }
private void updateKeyboardViewGestureHandlingModeByMainDictionaryAvailability() {
final MainKeyboardView keyboardView = mKeyboardSwitcher.getKeyboardView();
if (keyboardView != null) {
final boolean shouldHandleGesture = mCurrentSettings.mGestureInputEnabled
&& mIsMainDictionaryAvailable;
keyboardView.setGestureHandlingMode(shouldHandleGesture,
mCurrentSettings.mGesturePreviewTrailEnabled,
mCurrentSettings.mGestureFloatingPreviewTextEnabled);
}
}
// TODO: Remove this method from {@link LatinIME} and move {@link FeedbackManager} to // TODO: Remove this method from {@link LatinIME} and move {@link FeedbackManager} to
// {@link KeyboardSwitcher}. Called from KeyboardSwitcher // {@link KeyboardSwitcher}. Called from KeyboardSwitcher
public void hapticAndAudioFeedback(final int primaryCode) { public void hapticAndAudioFeedback(final int primaryCode) {

View File

@ -55,7 +55,9 @@ public class RichInputConnection {
public void beginBatchEdit() { public void beginBatchEdit() {
if (++mNestLevel == 1) { if (++mNestLevel == 1) {
mIC = mParent.getCurrentInputConnection(); mIC = mParent.getCurrentInputConnection();
if (null != mIC) mIC.beginBatchEdit(); if (null != mIC) {
mIC.beginBatchEdit();
}
} else { } else {
if (DBG) { if (DBG) {
throw new RuntimeException("Nest level too deep"); throw new RuntimeException("Nest level too deep");
@ -66,7 +68,9 @@ public class RichInputConnection {
} }
public void endBatchEdit() { public void endBatchEdit() {
if (mNestLevel <= 0) Log.e(TAG, "Batch edit not in progress!"); // TODO: exception instead if (mNestLevel <= 0) Log.e(TAG, "Batch edit not in progress!"); // TODO: exception instead
if (--mNestLevel == 0 && null != mIC) mIC.endBatchEdit(); if (--mNestLevel == 0 && null != mIC) {
mIC.endBatchEdit();
}
} }
private void checkBatchEdit() { private void checkBatchEdit() {
@ -79,12 +83,22 @@ public class RichInputConnection {
public void finishComposingText() { public void finishComposingText() {
checkBatchEdit(); checkBatchEdit();
if (null != mIC) mIC.finishComposingText(); if (null != mIC) {
mIC.finishComposingText();
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.richInputConnection_finishComposingText();
}
}
} }
public void commitText(final CharSequence text, final int i) { public void commitText(final CharSequence text, final int i) {
checkBatchEdit(); checkBatchEdit();
if (null != mIC) mIC.commitText(text, i); if (null != mIC) {
mIC.commitText(text, i);
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.richInputConnection_commitText(text, i);
}
}
} }
public int getCursorCapsMode(final int inputType) { public int getCursorCapsMode(final int inputType) {
@ -107,37 +121,72 @@ public class RichInputConnection {
public void deleteSurroundingText(final int i, final int j) { public void deleteSurroundingText(final int i, final int j) {
checkBatchEdit(); checkBatchEdit();
if (null != mIC) mIC.deleteSurroundingText(i, j); if (null != mIC) {
mIC.deleteSurroundingText(i, j);
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.richInputConnection_deleteSurroundingText(i, j);
}
}
} }
public void performEditorAction(final int actionId) { public void performEditorAction(final int actionId) {
mIC = mParent.getCurrentInputConnection(); mIC = mParent.getCurrentInputConnection();
if (null != mIC) mIC.performEditorAction(actionId); if (null != mIC) {
mIC.performEditorAction(actionId);
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.richInputConnection_performEditorAction(actionId);
}
}
} }
public void sendKeyEvent(final KeyEvent keyEvent) { public void sendKeyEvent(final KeyEvent keyEvent) {
checkBatchEdit(); checkBatchEdit();
if (null != mIC) mIC.sendKeyEvent(keyEvent); if (null != mIC) {
mIC.sendKeyEvent(keyEvent);
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.richInputConnection_sendKeyEvent(keyEvent);
}
}
} }
public void setComposingText(final CharSequence text, final int i) { public void setComposingText(final CharSequence text, final int i) {
checkBatchEdit(); checkBatchEdit();
if (null != mIC) mIC.setComposingText(text, i); if (null != mIC) {
mIC.setComposingText(text, i);
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.richInputConnection_setComposingText(text, i);
}
}
} }
public void setSelection(final int from, final int to) { public void setSelection(final int from, final int to) {
checkBatchEdit(); checkBatchEdit();
if (null != mIC) mIC.setSelection(from, to); if (null != mIC) {
mIC.setSelection(from, to);
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.richInputConnection_setSelection(from, to);
}
}
} }
public void commitCorrection(final CorrectionInfo correctionInfo) { public void commitCorrection(final CorrectionInfo correctionInfo) {
checkBatchEdit(); checkBatchEdit();
if (null != mIC) mIC.commitCorrection(correctionInfo); if (null != mIC) {
mIC.commitCorrection(correctionInfo);
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.richInputConnection_commitCorrection(correctionInfo);
}
}
} }
public void commitCompletion(final CompletionInfo completionInfo) { public void commitCompletion(final CompletionInfo completionInfo) {
checkBatchEdit(); checkBatchEdit();
if (null != mIC) mIC.commitCompletion(completionInfo); if (null != mIC) {
mIC.commitCompletion(completionInfo);
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.richInputConnection_commitCompletion(completionInfo);
}
}
} }
public CharSequence getNthPreviousWord(final String sentenceSeperators, final int n) { public CharSequence getNthPreviousWord(final String sentenceSeperators, final int n) {
@ -315,9 +364,6 @@ public class RichInputConnection {
if (lastOne != null && lastOne.length() == 1 if (lastOne != null && lastOne.length() == 1
&& lastOne.charAt(0) == Keyboard.CODE_SPACE) { && lastOne.charAt(0) == Keyboard.CODE_SPACE) {
deleteSurroundingText(1, 0); deleteSurroundingText(1, 0);
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.latinIME_deleteSurroundingText(1);
}
} }
} }
@ -382,13 +428,7 @@ public class RichInputConnection {
return false; return false;
} }
deleteSurroundingText(2, 0); deleteSurroundingText(2, 0);
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.latinIME_deleteSurroundingText(2);
}
commitText(" ", 1); commitText(" ", 1);
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.latinIME_revertDoubleSpaceWhileInBatchEdit();
}
return true; return true;
} }
@ -409,13 +449,7 @@ public class RichInputConnection {
return false; return false;
} }
deleteSurroundingText(2, 0); deleteSurroundingText(2, 0);
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.latinIME_deleteSurroundingText(2);
}
commitText(" " + textBeforeCursor.subSequence(0, 1), 1); commitText(" " + textBeforeCursor.subSequence(0, 1), 1);
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.latinIME_revertSwapPunctuation();
}
return true; return true;
} }
} }

View File

@ -62,6 +62,7 @@ public class Settings extends InputMethodSettingsFragment
public static final String PREF_LAST_USER_DICTIONARY_WRITE_TIME = public static final String PREF_LAST_USER_DICTIONARY_WRITE_TIME =
"last_user_dictionary_write_time"; "last_user_dictionary_write_time";
public static final String PREF_ADVANCED_SETTINGS = "pref_advanced_settings"; public static final String PREF_ADVANCED_SETTINGS = "pref_advanced_settings";
public static final String PREF_KEY_USE_CONTACTS_DICT = "pref_key_use_contacts_dict";
public static final String PREF_SUPPRESS_LANGUAGE_SWITCH_KEY = public static final String PREF_SUPPRESS_LANGUAGE_SWITCH_KEY =
"pref_suppress_language_switch_key"; "pref_suppress_language_switch_key";
public static final String PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST = public static final String PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST =
@ -69,13 +70,15 @@ public class Settings extends InputMethodSettingsFragment
public static final String PREF_CUSTOM_INPUT_STYLES = "custom_input_styles"; public static final String PREF_CUSTOM_INPUT_STYLES = "custom_input_styles";
public static final String PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY = public static final String PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY =
"pref_key_preview_popup_dismiss_delay"; "pref_key_preview_popup_dismiss_delay";
public static final String PREF_KEY_USE_CONTACTS_DICT = "pref_key_use_contacts_dict";
public static final String PREF_BIGRAM_PREDICTIONS = "next_word_prediction"; public static final String PREF_BIGRAM_PREDICTIONS = "next_word_prediction";
public static final String PREF_GESTURE_INPUT = "gesture_input"; public static final String PREF_GESTURE_INPUT = "gesture_input";
public static final String PREF_VIBRATION_DURATION_SETTINGS = public static final String PREF_VIBRATION_DURATION_SETTINGS =
"pref_vibration_duration_settings"; "pref_vibration_duration_settings";
public static final String PREF_KEYPRESS_SOUND_VOLUME = public static final String PREF_KEYPRESS_SOUND_VOLUME =
"pref_keypress_sound_volume"; "pref_keypress_sound_volume";
public static final String PREF_GESTURE_PREVIEW_TRAIL = "pref_gesture_preview_trail";
public static final String PREF_GESTURE_FLOATING_PREVIEW_TEXT =
"pref_gesture_floating_preview_text";
public static final String PREF_INPUT_LANGUAGE = "input_language"; public static final String PREF_INPUT_LANGUAGE = "input_language";
public static final String PREF_SELECTED_LANGUAGES = "selected_languages"; public static final String PREF_SELECTED_LANGUAGES = "selected_languages";
@ -94,13 +97,17 @@ public class Settings extends InputMethodSettingsFragment
private TextView mKeypressVibrationDurationSettingsTextView; private TextView mKeypressVibrationDurationSettingsTextView;
private TextView mKeypressSoundVolumeSettingsTextView; private TextView mKeypressSoundVolumeSettingsTextView;
private static void setPreferenceEnabled(Preference preference, boolean enabled) {
if (preference != null) {
preference.setEnabled(enabled);
}
}
private void ensureConsistencyOfAutoCorrectionSettings() { private void ensureConsistencyOfAutoCorrectionSettings() {
final String autoCorrectionOff = getResources().getString( final String autoCorrectionOff = getResources().getString(
R.string.auto_correction_threshold_mode_index_off); R.string.auto_correction_threshold_mode_index_off);
final String currentSetting = mAutoCorrectionThresholdPreference.getValue(); final String currentSetting = mAutoCorrectionThresholdPreference.getValue();
if (null != mBigramPrediction) { setPreferenceEnabled(mBigramPrediction, !currentSetting.equals(autoCorrectionOff));
mBigramPrediction.setEnabled(!currentSetting.equals(autoCorrectionOff));
}
} }
@Override @Override
@ -180,13 +187,11 @@ public class Settings extends InputMethodSettingsFragment
if (null == mKeyPreviewPopupDismissDelay.getValue()) { if (null == mKeyPreviewPopupDismissDelay.getValue()) {
mKeyPreviewPopupDismissDelay.setValue(popupDismissDelayDefaultValue); mKeyPreviewPopupDismissDelay.setValue(popupDismissDelayDefaultValue);
} }
mKeyPreviewPopupDismissDelay.setEnabled( setPreferenceEnabled(mKeyPreviewPopupDismissDelay,
SettingsValues.isKeyPreviewPopupEnabled(prefs, res)); SettingsValues.isKeyPreviewPopupEnabled(prefs, res));
} }
final CheckBoxPreference includeOtherImesInLanguageSwitchList = setPreferenceEnabled(findPreference(PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST),
(CheckBoxPreference)findPreference(PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST);
includeOtherImesInLanguageSwitchList.setEnabled(
!SettingsValues.isLanguageSwitchKeySupressed(prefs)); !SettingsValues.isLanguageSwitchKeySupressed(prefs));
final PreferenceScreen dictionaryLink = final PreferenceScreen dictionaryLink =
@ -200,10 +205,19 @@ public class Settings extends InputMethodSettingsFragment
final boolean gestureInputEnabledByBuildConfig = res.getBoolean( final boolean gestureInputEnabledByBuildConfig = res.getBoolean(
R.bool.config_gesture_input_enabled_by_build_config); R.bool.config_gesture_input_enabled_by_build_config);
final Preference gesturePreviewTrail = findPreference(PREF_GESTURE_PREVIEW_TRAIL);
final Preference gestureFloatingPreviewText = findPreference(
PREF_GESTURE_FLOATING_PREVIEW_TEXT);
if (!gestureInputEnabledByBuildConfig) { if (!gestureInputEnabledByBuildConfig) {
final Preference gestureInputPref = findPreference(PREF_GESTURE_INPUT); miscSettings.removePreference(findPreference(PREF_GESTURE_INPUT));
miscSettings.removePreference(gestureInputPref); miscSettings.removePreference(gesturePreviewTrail);
miscSettings.removePreference(gestureFloatingPreviewText);
} else {
final boolean gestureInputEnabledByUser = prefs.getBoolean(PREF_GESTURE_INPUT, true);
setPreferenceEnabled(gesturePreviewTrail, gestureInputEnabledByUser);
setPreferenceEnabled(gestureFloatingPreviewText, gestureInputEnabledByUser);
} }
final boolean showUsabilityStudyModeOption = final boolean showUsabilityStudyModeOption =
res.getBoolean(R.bool.config_enable_usability_study_mode_option) res.getBoolean(R.bool.config_enable_usability_study_mode_option)
|| ProductionFlag.IS_EXPERIMENTAL || ENABLE_EXPERIMENTAL_SETTINGS; || ProductionFlag.IS_EXPERIMENTAL || ENABLE_EXPERIMENTAL_SETTINGS;
@ -277,17 +291,22 @@ public class Settings extends InputMethodSettingsFragment
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
(new BackupManager(getActivity())).dataChanged(); (new BackupManager(getActivity())).dataChanged();
if (key.equals(PREF_POPUP_ON)) { if (key.equals(PREF_POPUP_ON)) {
final ListPreference popupDismissDelay = setPreferenceEnabled(findPreference(PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY),
(ListPreference)findPreference(PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY); prefs.getBoolean(PREF_POPUP_ON, true));
if (null != popupDismissDelay) {
popupDismissDelay.setEnabled(prefs.getBoolean(PREF_POPUP_ON, true));
}
} else if (key.equals(PREF_SUPPRESS_LANGUAGE_SWITCH_KEY)) { } else if (key.equals(PREF_SUPPRESS_LANGUAGE_SWITCH_KEY)) {
final CheckBoxPreference includeOtherImesInLanguageSwicthList = setPreferenceEnabled(findPreference(PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST),
(CheckBoxPreference)findPreference(
PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST);
includeOtherImesInLanguageSwicthList.setEnabled(
!SettingsValues.isLanguageSwitchKeySupressed(prefs)); !SettingsValues.isLanguageSwitchKeySupressed(prefs));
} else if (key.equals(PREF_GESTURE_INPUT)) {
final boolean gestureInputEnabledByConfig = getResources().getBoolean(
R.bool.config_gesture_input_enabled_by_build_config);
if (gestureInputEnabledByConfig) {
final boolean gestureInputEnabledByUser = prefs.getBoolean(
PREF_GESTURE_INPUT, true);
setPreferenceEnabled(findPreference(PREF_GESTURE_PREVIEW_TRAIL),
gestureInputEnabledByUser);
setPreferenceEnabled(findPreference(PREF_GESTURE_FLOATING_PREVIEW_TEXT),
gestureInputEnabledByUser);
}
} }
ensureConsistencyOfAutoCorrectionSettings(); ensureConsistencyOfAutoCorrectionSettings();
updateVoiceModeSummary(); updateVoiceModeSummary();
@ -335,16 +354,18 @@ public class Settings extends InputMethodSettingsFragment
private void refreshEnablingsOfKeypressSoundAndVibrationSettings( private void refreshEnablingsOfKeypressSoundAndVibrationSettings(
SharedPreferences sp, Resources res) { SharedPreferences sp, Resources res) {
if (mKeypressVibrationDurationSettingsPref != null) { if (mKeypressVibrationDurationSettingsPref != null) {
final boolean hasVibrator = VibratorUtils.getInstance(getActivity()).hasVibrator(); final boolean hasVibratorHardware = VibratorUtils.getInstance(getActivity())
final boolean vibrateOn = hasVibrator && sp.getBoolean(Settings.PREF_VIBRATE_ON, .hasVibrator();
final boolean vibrateOnByUser = sp.getBoolean(Settings.PREF_VIBRATE_ON,
res.getBoolean(R.bool.config_default_vibration_enabled)); res.getBoolean(R.bool.config_default_vibration_enabled));
mKeypressVibrationDurationSettingsPref.setEnabled(vibrateOn); setPreferenceEnabled(mKeypressVibrationDurationSettingsPref,
hasVibratorHardware && vibrateOnByUser);
} }
if (mKeypressSoundVolumeSettingsPref != null) { if (mKeypressSoundVolumeSettingsPref != null) {
final boolean soundOn = sp.getBoolean(Settings.PREF_SOUND_ON, final boolean soundOn = sp.getBoolean(Settings.PREF_SOUND_ON,
res.getBoolean(R.bool.config_default_sound_enabled)); res.getBoolean(R.bool.config_default_sound_enabled));
mKeypressSoundVolumeSettingsPref.setEnabled(soundOn); setPreferenceEnabled(mKeypressSoundVolumeSettingsPref, soundOn);
} }
} }

View File

@ -84,6 +84,8 @@ public class SettingsValues {
private final float mKeypressSoundVolumeRawValue; private final float mKeypressSoundVolumeRawValue;
private final InputMethodSubtype[] mAdditionalSubtypes; private final InputMethodSubtype[] mAdditionalSubtypes;
public final boolean mGestureInputEnabled; public final boolean mGestureInputEnabled;
public final boolean mGesturePreviewTrailEnabled;
public final boolean mGestureFloatingPreviewTextEnabled;
// From the input box // From the input box
private final InputAttributes mInputAttributes; private final InputAttributes mInputAttributes;
@ -174,6 +176,9 @@ public class SettingsValues {
R.bool.config_gesture_input_enabled_by_build_config); R.bool.config_gesture_input_enabled_by_build_config);
mGestureInputEnabled = gestureInputEnabledByBuildConfig mGestureInputEnabled = gestureInputEnabledByBuildConfig
&& prefs.getBoolean(Settings.PREF_GESTURE_INPUT, true); && prefs.getBoolean(Settings.PREF_GESTURE_INPUT, true);
mGesturePreviewTrailEnabled = prefs.getBoolean(Settings.PREF_GESTURE_PREVIEW_TRAIL, true);
mGestureFloatingPreviewTextEnabled = prefs.getBoolean(
Settings.PREF_GESTURE_FLOATING_PREVIEW_TEXT, true);
mCorrectionEnabled = mAutoCorrectEnabled && !mInputAttributes.mInputTypeNoAutoCorrect; mCorrectionEnabled = mAutoCorrectEnabled && !mInputAttributes.mInputTypeNoAutoCorrect;
mSuggestionVisibility = createSuggestionVisibility(res); mSuggestionVisibility = createSuggestionVisibility(res);
} }

View File

@ -42,6 +42,10 @@ public class Suggest {
// TODO: rename this to CORRECTION_ON // TODO: rename this to CORRECTION_ON
public static final int CORRECTION_FULL = 1; public static final int CORRECTION_FULL = 1;
public interface SuggestInitializationListener {
public void onUpdateMainDictionaryAvailability(boolean isMainDictionaryAvailable);
}
private static final boolean DBG = LatinImeLogger.sDBG; private static final boolean DBG = LatinImeLogger.sDBG;
private Dictionary mMainDictionary; private Dictionary mMainDictionary;
@ -55,11 +59,14 @@ public class Suggest {
private float mAutoCorrectionThreshold; private float mAutoCorrectionThreshold;
// Locale used for upper- and title-casing words // Locale used for upper- and title-casing words
final private Locale mLocale; private final Locale mLocale;
private final SuggestInitializationListener mListener;
public Suggest(final Context context, final Locale locale) { public Suggest(final Context context, final Locale locale,
final SuggestInitializationListener listener) {
initAsynchronously(context, locale); initAsynchronously(context, locale);
mLocale = locale; mLocale = locale;
mListener = listener;
} }
/* package for test */ Suggest(final Context context, final File dictionary, /* package for test */ Suggest(final Context context, final File dictionary,
@ -67,6 +74,7 @@ public class Suggest {
final Dictionary mainDict = DictionaryFactory.createDictionaryForTest(context, dictionary, final Dictionary mainDict = DictionaryFactory.createDictionaryForTest(context, dictionary,
startOffset, length /* useFullEditDistance */, false, locale); startOffset, length /* useFullEditDistance */, false, locale);
mLocale = locale; mLocale = locale;
mListener = null;
mMainDictionary = mainDict; mMainDictionary = mainDict;
addOrReplaceDictionary(mDictionaries, Dictionary.TYPE_MAIN, mainDict); addOrReplaceDictionary(mDictionaries, Dictionary.TYPE_MAIN, mainDict);
initWhitelistAndAutocorrectAndPool(context, locale); initWhitelistAndAutocorrectAndPool(context, locale);
@ -98,6 +106,9 @@ public class Suggest {
public void resetMainDict(final Context context, final Locale locale) { public void resetMainDict(final Context context, final Locale locale) {
mMainDictionary = null; mMainDictionary = null;
if (mListener != null) {
mListener.onUpdateMainDictionaryAvailability(hasMainDictionary());
}
new Thread("InitializeBinaryDictionary") { new Thread("InitializeBinaryDictionary") {
@Override @Override
public void run() { public void run() {
@ -105,6 +116,9 @@ public class Suggest {
DictionaryFactory.createMainDictionaryFromManager(context, locale); DictionaryFactory.createMainDictionaryFromManager(context, locale);
addOrReplaceDictionary(mDictionaries, Dictionary.TYPE_MAIN, newMainDict); addOrReplaceDictionary(mDictionaries, Dictionary.TYPE_MAIN, newMainDict);
mMainDictionary = newMainDict; mMainDictionary = newMainDict;
if (mListener != null) {
mListener.onUpdateMainDictionaryAvailability(hasMainDictionary());
}
} }
}.start(); }.start();
} }
@ -219,7 +233,7 @@ public class Suggest {
// the current settings. It may also be useful to know, when the setting is off, whether // the current settings. It may also be useful to know, when the setting is off, whether
// the word *would* have been auto-corrected. // the word *would* have been auto-corrected.
if (!isCorrectionEnabled || !allowsToBeAutoCorrected || !wordComposer.isComposingWord() if (!isCorrectionEnabled || !allowsToBeAutoCorrected || !wordComposer.isComposingWord()
|| suggestionsSet.isEmpty() || suggestionsSet.isEmpty() || wordComposer.hasDigits()
|| wordComposer.isMostlyCaps() || wordComposer.isResumed() || wordComposer.isMostlyCaps() || wordComposer.isResumed()
|| !hasMainDictionary()) { || !hasMainDictionary()) {
// If we don't have a main dictionary, we never want to auto-correct. The reason for // If we don't have a main dictionary, we never want to auto-correct. The reason for

View File

@ -41,6 +41,7 @@ public class WordComposer {
// Cache these values for performance // Cache these values for performance
private int mCapsCount; private int mCapsCount;
private int mDigitsCount;
private boolean mAutoCapitalized; private boolean mAutoCapitalized;
private int mTrailingSingleQuotesCount; private int mTrailingSingleQuotesCount;
private int mCodePointSize; private int mCodePointSize;
@ -65,6 +66,7 @@ public class WordComposer {
mTypedWord = new StringBuilder(source.mTypedWord); mTypedWord = new StringBuilder(source.mTypedWord);
mInputPointers.copy(source.mInputPointers); mInputPointers.copy(source.mInputPointers);
mCapsCount = source.mCapsCount; mCapsCount = source.mCapsCount;
mDigitsCount = source.mDigitsCount;
mIsFirstCharCapitalized = source.mIsFirstCharCapitalized; mIsFirstCharCapitalized = source.mIsFirstCharCapitalized;
mAutoCapitalized = source.mAutoCapitalized; mAutoCapitalized = source.mAutoCapitalized;
mTrailingSingleQuotesCount = source.mTrailingSingleQuotesCount; mTrailingSingleQuotesCount = source.mTrailingSingleQuotesCount;
@ -80,6 +82,7 @@ public class WordComposer {
mTypedWord.setLength(0); mTypedWord.setLength(0);
mAutoCorrection = null; mAutoCorrection = null;
mCapsCount = 0; mCapsCount = 0;
mDigitsCount = 0;
mIsFirstCharCapitalized = false; mIsFirstCharCapitalized = false;
mTrailingSingleQuotesCount = 0; mTrailingSingleQuotesCount = 0;
mIsResumed = false; mIsResumed = false;
@ -141,6 +144,7 @@ public class WordComposer {
mIsFirstCharCapitalized = isFirstCharCapitalized( mIsFirstCharCapitalized = isFirstCharCapitalized(
newIndex, primaryCode, mIsFirstCharCapitalized); newIndex, primaryCode, mIsFirstCharCapitalized);
if (Character.isUpperCase(primaryCode)) mCapsCount++; if (Character.isUpperCase(primaryCode)) mCapsCount++;
if (Character.isDigit(primaryCode)) mDigitsCount++;
if (Keyboard.CODE_SINGLE_QUOTE == primaryCode) { if (Keyboard.CODE_SINGLE_QUOTE == primaryCode) {
++mTrailingSingleQuotesCount; ++mTrailingSingleQuotesCount;
} else { } else {
@ -213,6 +217,7 @@ public class WordComposer {
mTypedWord.deleteCharAt(stringBuilderLength - 1); mTypedWord.deleteCharAt(stringBuilderLength - 1);
} }
if (Character.isUpperCase(lastChar)) mCapsCount--; if (Character.isUpperCase(lastChar)) mCapsCount--;
if (Character.isDigit(lastChar)) mDigitsCount--;
refreshSize(); refreshSize();
} }
// We may have deleted the last one. // We may have deleted the last one.
@ -267,6 +272,13 @@ public class WordComposer {
return mCapsCount > 1; return mCapsCount > 1;
} }
/**
* Returns true if we have digits in the composing word.
*/
public boolean hasDigits() {
return mDigitsCount > 0;
}
/** /**
* Saves the reason why the word is capitalized - whether it was automatic or * 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. * due to the user hitting shift in the middle of a sentence.
@ -322,6 +334,7 @@ public class WordComposer {
lastComposedWord.deactivate(); lastComposedWord.deactivate();
} }
mCapsCount = 0; mCapsCount = 0;
mDigitsCount = 0;
mIsBatchMode = false; mIsBatchMode = false;
mTypedWord.setLength(0); mTypedWord.setLength(0);
mTrailingSingleQuotesCount = 0; mTrailingSingleQuotesCount = 0;

View File

@ -61,8 +61,8 @@ public class FusionDictionary implements Iterable<Word> {
* This represents an "attribute", that is either a bigram or a shortcut. * This represents an "attribute", that is either a bigram or a shortcut.
*/ */
public static class WeightedString { public static class WeightedString {
final String mWord; public final String mWord;
int mFrequency; public int mFrequency;
public WeightedString(String word, int frequency) { public WeightedString(String word, int frequency) {
mWord = word; mWord = word;
mFrequency = frequency; mFrequency = frequency;

View File

@ -27,10 +27,10 @@ import java.util.Arrays;
* This is chiefly used to iterate a dictionary. * This is chiefly used to iterate a dictionary.
*/ */
public class Word implements Comparable<Word> { public class Word implements Comparable<Word> {
final String mWord; public final String mWord;
final int mFrequency; public final int mFrequency;
final ArrayList<WeightedString> mShortcutTargets; public final ArrayList<WeightedString> mShortcutTargets;
final ArrayList<WeightedString> mBigrams; public final ArrayList<WeightedString> mBigrams;
private int mHashCode = 0; private int mHashCode = 0;

View File

@ -18,10 +18,7 @@ package com.android.inputmethod.research;
import android.app.Activity; import android.app.Activity;
import android.os.Bundle; import android.os.Bundle;
import android.text.Editable;
import android.view.View;
import android.widget.CheckBox; import android.widget.CheckBox;
import android.widget.EditText;
import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.R;
@ -31,6 +28,11 @@ public class FeedbackActivity extends Activity {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.research_feedback_activity); setContentView(R.layout.research_feedback_activity);
final FeedbackLayout layout = (FeedbackLayout) findViewById(R.id.research_feedback_layout); final FeedbackLayout layout = (FeedbackLayout) findViewById(R.id.research_feedback_layout);
final CheckBox checkbox = (CheckBox) findViewById(R.id.research_feedback_include_history);
final CharSequence cs = checkbox.getText();
final String actualString = String.format(cs.toString(),
ResearchLogger.FEEDBACK_WORD_BUFFER_SIZE);
checkbox.setText(actualString);
layout.setActivity(this); layout.setActivity(this);
} }

View File

@ -0,0 +1,111 @@
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.android.inputmethod.research;
import java.util.LinkedList;
/**
* A buffer that holds a fixed number of LogUnits.
*
* LogUnits are added in and shifted out in temporal order. Only a subset of the LogUnits are
* actual words; the other LogUnits do not count toward the word limit. Once the buffer reaches
* capacity, adding another LogUnit that is a word evicts the oldest LogUnits out one at a time to
* stay under the capacity limit.
*/
public class LogBuffer {
protected final LinkedList<LogUnit> mLogUnits;
/* package for test */ int mWordCapacity;
// The number of members of mLogUnits that are actual words.
protected int mNumActualWords;
/**
* Create a new LogBuffer that can hold a fixed number of LogUnits that are words (and
* unlimited number of non-word LogUnits), and that outputs its result to a researchLog.
*
* @param wordCapacity maximum number of words
*/
LogBuffer(final int wordCapacity) {
if (wordCapacity <= 0) {
throw new IllegalArgumentException("wordCapacity must be 1 or greater.");
}
mLogUnits = new LinkedList<LogUnit>();
mWordCapacity = wordCapacity;
mNumActualWords = 0;
}
/**
* Adds a new LogUnit to the front of the LIFO queue, evicting existing LogUnit's
* (oldest first) if word capacity is reached.
*/
public void shiftIn(LogUnit newLogUnit) {
if (newLogUnit.getWord() == null) {
// This LogUnit isn't a word, so it doesn't count toward the word-limit.
mLogUnits.add(newLogUnit);
return;
}
if (mNumActualWords == mWordCapacity) {
shiftOutThroughFirstWord();
}
mLogUnits.add(newLogUnit);
mNumActualWords++; // Must be a word, or we wouldn't be here.
}
private void shiftOutThroughFirstWord() {
while (!mLogUnits.isEmpty()) {
final LogUnit logUnit = mLogUnits.removeFirst();
onShiftOut(logUnit);
if (logUnit.hasWord()) {
// Successfully shifted out a word-containing LogUnit and made space for the new
// LogUnit.
mNumActualWords--;
break;
}
}
}
/**
* Removes all LogUnits from the buffer without calling onShiftOut().
*/
public void clear() {
mLogUnits.clear();
mNumActualWords = 0;
}
/**
* Called when a LogUnit is removed from the LogBuffer as a result of a shiftIn. LogUnits are
* removed in the order entered. This method is not called when shiftOut is called directly.
*
* Base class does nothing; subclasses may override.
*/
protected void onShiftOut(LogUnit logUnit) {
}
/**
* Called to deliberately remove the oldest LogUnit. Usually called when draining the
* LogBuffer.
*/
public LogUnit shiftOut() {
if (mLogUnits.isEmpty()) {
return null;
}
final LogUnit logUnit = mLogUnits.removeFirst();
if (logUnit.hasWord()) {
mNumActualWords--;
}
return logUnit;
}
}

View File

@ -0,0 +1,81 @@
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.android.inputmethod.research;
import java.util.ArrayList;
/**
* A group of log statements related to each other.
*
* A LogUnit is collection of LogStatements, each of which is generated by at a particular point
* in the code. (There is no LogStatement class; the data is stored across the instance variables
* here.) A single LogUnit's statements can correspond to all the calls made while in the same
* composing region, or all the calls between committing the last composing region, and the first
* character of the next composing region.
*
* Individual statements in a log may be marked as potentially private. If so, then they are only
* published to a ResearchLog if the ResearchLogger determines that publishing the entire LogUnit
* will not violate the user's privacy. Checks for this may include whether other LogUnits have
* been published recently, or whether the LogUnit contains numbers, etc.
*/
/* package */ class LogUnit {
private final ArrayList<String[]> mKeysList = new ArrayList<String[]>();
private final ArrayList<Object[]> mValuesList = new ArrayList<Object[]>();
private final ArrayList<Boolean> mIsPotentiallyPrivate = new ArrayList<Boolean>();
private String mWord;
private boolean mContainsDigit;
public void addLogStatement(final String[] keys, final Object[] values,
final Boolean isPotentiallyPrivate) {
mKeysList.add(keys);
mValuesList.add(values);
mIsPotentiallyPrivate.add(isPotentiallyPrivate);
}
public void publishTo(final ResearchLog researchLog, final boolean isIncludingPrivateData) {
final int size = mKeysList.size();
for (int i = 0; i < size; i++) {
if (!mIsPotentiallyPrivate.get(i) || isIncludingPrivateData) {
researchLog.outputEvent(mKeysList.get(i), mValuesList.get(i));
}
}
}
public void setWord(String word) {
mWord = word;
}
public String getWord() {
return mWord;
}
public boolean hasWord() {
return mWord != null;
}
public void setContainsDigit() {
mContainsDigit = true;
}
public boolean hasDigit() {
return mContainsDigit;
}
public boolean isEmpty() {
return mKeysList.isEmpty();
}
}

View File

@ -0,0 +1,127 @@
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.android.inputmethod.research;
import com.android.inputmethod.latin.Dictionary;
import com.android.inputmethod.latin.Suggest;
import java.util.Random;
public class MainLogBuffer extends LogBuffer {
// The size of the n-grams logged. E.g. N_GRAM_SIZE = 2 means to sample bigrams.
private static final int N_GRAM_SIZE = 2;
// The number of words between n-grams to omit from the log.
private static final int DEFAULT_NUMBER_OF_WORDS_BETWEEN_SAMPLES = 18;
private final ResearchLog mResearchLog;
private Suggest mSuggest;
// The minimum periodicity with which n-grams can be sampled. E.g. mWinWordPeriod is 10 if
// every 10th bigram is sampled, i.e., words 1-8 are not, but the bigram at words 9 and 10, etc.
// for 11-18, and the bigram at words 19 and 20. If an n-gram is not safe (e.g. it contains a
// number in the middle or an out-of-vocabulary word), then sampling is delayed until a safe
// n-gram does appear.
/* package for test */ int mMinWordPeriod;
// Counter for words left to suppress before an n-gram can be sampled. Reset to mMinWordPeriod
// after a sample is taken.
/* package for test */ int mWordsUntilSafeToSample;
public MainLogBuffer(final ResearchLog researchLog) {
super(N_GRAM_SIZE);
mResearchLog = researchLog;
mMinWordPeriod = DEFAULT_NUMBER_OF_WORDS_BETWEEN_SAMPLES + N_GRAM_SIZE;
final Random random = new Random();
mWordsUntilSafeToSample = random.nextInt(mMinWordPeriod);
}
public void setSuggest(Suggest suggest) {
mSuggest = suggest;
}
@Override
public void shiftIn(final LogUnit newLogUnit) {
super.shiftIn(newLogUnit);
if (newLogUnit.hasWord()) {
if (mWordsUntilSafeToSample > 0) {
mWordsUntilSafeToSample--;
}
}
}
public void resetWordCounter() {
mWordsUntilSafeToSample = mMinWordPeriod;
}
/**
* Determines whether the content of the MainLogBuffer can be safely uploaded in its complete
* form and still protect the user's privacy.
*
* The size of the MainLogBuffer is just enough to hold one n-gram, its corrections, and any
* non-character data that is typed between words. The decision about privacy is made based on
* the buffer's entire content. If it is decided that the privacy risks are too great to upload
* the contents of this buffer, a censored version of the LogItems may still be uploaded. E.g.,
* the screen orientation and other characteristics about the device can be uploaded without
* revealing much about the user.
*/
public boolean isSafeToLog() {
// Check that we are not sampling too frequently. Having sampled recently might disclose
// too much of the user's intended meaning.
if (mWordsUntilSafeToSample > 0) {
return false;
}
if (mSuggest == null || !mSuggest.hasMainDictionary()) {
// Main dictionary is unavailable. Since we cannot check it, we cannot tell if a word
// is out-of-vocabulary or not. Therefore, we must judge the entire buffer contents to
// potentially pose a privacy risk.
return false;
}
// Reload the dictionary in case it has changed (e.g., because the user has changed
// languages).
final Dictionary dictionary = mSuggest.getMainDictionary();
if (dictionary == null) {
return false;
}
// Check each word in the buffer. If any word poses a privacy threat, we cannot upload the
// complete buffer contents in detail.
final int length = mLogUnits.size();
for (int i = 0; i < length; i++) {
final LogUnit logUnit = mLogUnits.get(i);
final String word = logUnit.getWord();
if (word == null) {
// Digits outside words are a privacy threat.
if (logUnit.hasDigit()) {
return false;
}
} else {
// Words not in the dictionary are a privacy threat.
if (!(dictionary.isValidWord(word))) {
return false;
}
}
}
// All checks have passed; this buffer's content can be safely uploaded.
return true;
}
@Override
protected void onShiftOut(LogUnit logUnit) {
if (mResearchLog != null) {
mResearchLog.publish(logUnit, false /* isIncludingPrivateData */);
}
}
}

View File

@ -26,7 +26,6 @@ import com.android.inputmethod.keyboard.Key;
import com.android.inputmethod.latin.SuggestedWords; import com.android.inputmethod.latin.SuggestedWords;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.define.ProductionFlag; import com.android.inputmethod.latin.define.ProductionFlag;
import com.android.inputmethod.research.ResearchLogger.LogUnit;
import java.io.BufferedWriter; import java.io.BufferedWriter;
import java.io.File; import java.io.File;
@ -37,6 +36,7 @@ import java.io.OutputStreamWriter;
import java.util.Map; import java.util.Map;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -51,21 +51,22 @@ import java.util.concurrent.TimeUnit;
*/ */
public class ResearchLog { public class ResearchLog {
private static final String TAG = ResearchLog.class.getSimpleName(); private static final String TAG = ResearchLog.class.getSimpleName();
private static final JsonWriter NULL_JSON_WRITER = new JsonWriter( private static final boolean DEBUG = false;
new OutputStreamWriter(new NullOutputStream())); private static final long FLUSH_DELAY_IN_MS = 1000 * 5;
private static final int ABORT_TIMEOUT_IN_MS = 1000 * 4;
final ScheduledExecutorService mExecutor; /* package */ final ScheduledExecutorService mExecutor;
/* package */ final File mFile; /* package */ final File mFile;
private JsonWriter mJsonWriter = NULL_JSON_WRITER; private JsonWriter mJsonWriter = NULL_JSON_WRITER;
// true if at least one byte of data has been written out to the log file. This must be
// remembered because JsonWriter requires that calls matching calls to beginObject and
// endObject, as well as beginArray and endArray, and the file is opened lazily, only when
// it is certain that data will be written. Alternatively, the matching call exceptions
// could be caught, but this might suppress other errors.
private boolean mHasWrittenData = false;
private int mLoggingState; private static final JsonWriter NULL_JSON_WRITER = new JsonWriter(
private static final int LOGGING_STATE_UNSTARTED = 0; new OutputStreamWriter(new NullOutputStream()));
private static final int LOGGING_STATE_READY = 1; // don't create file until necessary
private static final int LOGGING_STATE_RUNNING = 2;
private static final int LOGGING_STATE_STOPPING = 3;
private static final int LOGGING_STATE_STOPPED = 4;
private static final long FLUSH_DELAY_IN_MS = 1000 * 5;
private static class NullOutputStream extends OutputStream { private static class NullOutputStream extends OutputStream {
/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
@ -84,128 +85,81 @@ public class ResearchLog {
} }
} }
public ResearchLog(File outputFile) { public ResearchLog(final File outputFile) {
mExecutor = Executors.newSingleThreadScheduledExecutor();
if (outputFile == null) { if (outputFile == null) {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
mExecutor = Executors.newSingleThreadScheduledExecutor();
mFile = outputFile; mFile = outputFile;
mLoggingState = LOGGING_STATE_UNSTARTED;
} }
public synchronized void start() throws IOException { public synchronized void close() {
switch (mLoggingState) { mExecutor.submit(new Callable<Object>() {
case LOGGING_STATE_UNSTARTED: @Override
mLoggingState = LOGGING_STATE_READY; public Object call() throws Exception {
break; try {
case LOGGING_STATE_READY: if (mHasWrittenData) {
case LOGGING_STATE_RUNNING: mJsonWriter.endArray();
case LOGGING_STATE_STOPPING: mJsonWriter.flush();
case LOGGING_STATE_STOPPED: mJsonWriter.close();
break; mHasWrittenData = false;
}
}
public synchronized void stop() {
switch (mLoggingState) {
case LOGGING_STATE_UNSTARTED:
mLoggingState = LOGGING_STATE_STOPPED;
break;
case LOGGING_STATE_READY:
case LOGGING_STATE_RUNNING:
mExecutor.submit(new Callable<Object>() {
@Override
public Object call() throws Exception {
try {
mJsonWriter.endArray();
mJsonWriter.flush();
mJsonWriter.close();
} finally {
boolean success = mFile.setWritable(false, false);
mLoggingState = LOGGING_STATE_STOPPED;
}
return null;
} }
}); } catch (Exception e) {
removeAnyScheduledFlush(); Log.d(TAG, "error when closing ResearchLog:");
mExecutor.shutdown(); e.printStackTrace();
mLoggingState = LOGGING_STATE_STOPPING; } finally {
break; if (mFile.exists()) {
case LOGGING_STATE_STOPPING: mFile.setWritable(false, false);
case LOGGING_STATE_STOPPED: }
} }
} return null;
}
public boolean isAlive() { });
switch (mLoggingState) {
case LOGGING_STATE_UNSTARTED:
case LOGGING_STATE_READY:
case LOGGING_STATE_RUNNING:
return true;
}
return false;
}
public void waitUntilStopped(final int timeoutInMs) throws InterruptedException {
removeAnyScheduledFlush(); removeAnyScheduledFlush();
mExecutor.shutdown(); mExecutor.shutdown();
mExecutor.awaitTermination(timeoutInMs, TimeUnit.MILLISECONDS);
} }
private boolean mIsAbortSuccessful;
public synchronized void abort() { public synchronized void abort() {
switch (mLoggingState) { mExecutor.submit(new Callable<Object>() {
case LOGGING_STATE_UNSTARTED: @Override
mLoggingState = LOGGING_STATE_STOPPED; public Object call() throws Exception {
isAbortSuccessful = true; try {
break; if (mHasWrittenData) {
case LOGGING_STATE_READY: mJsonWriter.endArray();
case LOGGING_STATE_RUNNING: mJsonWriter.close();
mExecutor.submit(new Callable<Object>() { mHasWrittenData = false;
@Override
public Object call() throws Exception {
try {
mJsonWriter.endArray();
mJsonWriter.close();
} finally {
isAbortSuccessful = mFile.delete();
}
return null;
} }
}); } finally {
removeAnyScheduledFlush(); mIsAbortSuccessful = mFile.delete();
mExecutor.shutdown(); }
mLoggingState = LOGGING_STATE_STOPPING; return null;
break; }
case LOGGING_STATE_STOPPING: });
case LOGGING_STATE_STOPPED: removeAnyScheduledFlush();
} mExecutor.shutdown();
} }
private boolean isAbortSuccessful; public boolean blockingAbort() throws InterruptedException {
public boolean isAbortSuccessful() { abort();
return isAbortSuccessful; mExecutor.awaitTermination(ABORT_TIMEOUT_IN_MS, TimeUnit.MILLISECONDS);
return mIsAbortSuccessful;
}
public void awaitTermination(int delay, TimeUnit timeUnit) throws InterruptedException {
mExecutor.awaitTermination(delay, timeUnit);
} }
/* package */ synchronized void flush() { /* package */ synchronized void flush() {
switch (mLoggingState) { removeAnyScheduledFlush();
case LOGGING_STATE_UNSTARTED: mExecutor.submit(mFlushCallable);
break;
case LOGGING_STATE_READY:
case LOGGING_STATE_RUNNING:
removeAnyScheduledFlush();
mExecutor.submit(mFlushCallable);
break;
case LOGGING_STATE_STOPPING:
case LOGGING_STATE_STOPPED:
}
} }
private Callable<Object> mFlushCallable = new Callable<Object>() { private final Callable<Object> mFlushCallable = new Callable<Object>() {
@Override @Override
public Object call() throws Exception { public Object call() throws Exception {
if (mLoggingState == LOGGING_STATE_RUNNING) { mJsonWriter.flush();
mJsonWriter.flush();
}
return null; return null;
} }
}; };
@ -224,56 +178,40 @@ public class ResearchLog {
mFlushFuture = mExecutor.schedule(mFlushCallable, FLUSH_DELAY_IN_MS, TimeUnit.MILLISECONDS); mFlushFuture = mExecutor.schedule(mFlushCallable, FLUSH_DELAY_IN_MS, TimeUnit.MILLISECONDS);
} }
public synchronized void publishPublicEvents(final LogUnit logUnit) { public synchronized void publish(final LogUnit logUnit, final boolean isIncludingPrivateData) {
switch (mLoggingState) { try {
case LOGGING_STATE_UNSTARTED: mExecutor.submit(new Callable<Object>() {
break; @Override
case LOGGING_STATE_READY: public Object call() throws Exception {
case LOGGING_STATE_RUNNING: logUnit.publishTo(ResearchLog.this, isIncludingPrivateData);
mExecutor.submit(new Callable<Object>() { scheduleFlush();
@Override return null;
public Object call() throws Exception { }
logUnit.publishPublicEventsTo(ResearchLog.this); });
scheduleFlush(); } catch (RejectedExecutionException e) {
return null; // TODO: Add code to record loss of data, and report.
}
});
break;
case LOGGING_STATE_STOPPING:
case LOGGING_STATE_STOPPED:
}
}
public synchronized void publishAllEvents(final LogUnit logUnit) {
switch (mLoggingState) {
case LOGGING_STATE_UNSTARTED:
break;
case LOGGING_STATE_READY:
case LOGGING_STATE_RUNNING:
mExecutor.submit(new Callable<Object>() {
@Override
public Object call() throws Exception {
logUnit.publishAllEventsTo(ResearchLog.this);
scheduleFlush();
return null;
}
});
break;
case LOGGING_STATE_STOPPING:
case LOGGING_STATE_STOPPED:
} }
} }
private static final String CURRENT_TIME_KEY = "_ct"; private static final String CURRENT_TIME_KEY = "_ct";
private static final String UPTIME_KEY = "_ut"; private static final String UPTIME_KEY = "_ut";
private static final String EVENT_TYPE_KEY = "_ty"; private static final String EVENT_TYPE_KEY = "_ty";
void outputEvent(final String[] keys, final Object[] values) { void outputEvent(final String[] keys, final Object[] values) {
// not thread safe. // Not thread safe.
if (keys.length == 0) {
return;
}
if (DEBUG) {
if (keys.length != values.length + 1) {
Log.d(TAG, "Key and Value list sizes do not match. " + keys[0]);
}
}
try { try {
if (mJsonWriter == NULL_JSON_WRITER) { if (mJsonWriter == NULL_JSON_WRITER) {
mJsonWriter = new JsonWriter(new BufferedWriter(new FileWriter(mFile))); mJsonWriter = new JsonWriter(new BufferedWriter(new FileWriter(mFile)));
mJsonWriter.setLenient(true);
mJsonWriter.beginArray(); mJsonWriter.beginArray();
mHasWrittenData = true;
} }
mJsonWriter.beginObject(); mJsonWriter.beginObject();
mJsonWriter.name(CURRENT_TIME_KEY).value(System.currentTimeMillis()); mJsonWriter.name(CURRENT_TIME_KEY).value(System.currentTimeMillis());
@ -283,8 +221,8 @@ public class ResearchLog {
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
mJsonWriter.name(keys[i + 1]); mJsonWriter.name(keys[i + 1]);
Object value = values[i]; Object value = values[i];
if (value instanceof String) { if (value instanceof CharSequence) {
mJsonWriter.value((String) value); mJsonWriter.value(value.toString());
} else if (value instanceof Number) { } else if (value instanceof Number) {
mJsonWriter.value((Number) value); mJsonWriter.value((Number) value);
} else if (value instanceof Boolean) { } else if (value instanceof Boolean) {
@ -331,14 +269,11 @@ public class ResearchLog {
SuggestedWords words = (SuggestedWords) value; SuggestedWords words = (SuggestedWords) value;
mJsonWriter.beginObject(); mJsonWriter.beginObject();
mJsonWriter.name("typedWordValid").value(words.mTypedWordValid); mJsonWriter.name("typedWordValid").value(words.mTypedWordValid);
mJsonWriter.name("willAutoCorrect") mJsonWriter.name("willAutoCorrect").value(words.mWillAutoCorrect);
.value(words.mWillAutoCorrect);
mJsonWriter.name("isPunctuationSuggestions") mJsonWriter.name("isPunctuationSuggestions")
.value(words.mIsPunctuationSuggestions); .value(words.mIsPunctuationSuggestions);
mJsonWriter.name("isObsoleteSuggestions") mJsonWriter.name("isObsoleteSuggestions").value(words.mIsObsoleteSuggestions);
.value(words.mIsObsoleteSuggestions); mJsonWriter.name("isPrediction").value(words.mIsPrediction);
mJsonWriter.name("isPrediction")
.value(words.mIsPrediction);
mJsonWriter.name("words"); mJsonWriter.name("words");
mJsonWriter.beginArray(); mJsonWriter.beginArray();
final int size = words.size(); final int size = words.size();
@ -363,8 +298,8 @@ public class ResearchLog {
try { try {
mJsonWriter.close(); mJsonWriter.close();
} catch (IllegalStateException e1) { } catch (IllegalStateException e1) {
// assume that this is just the json not being terminated properly. // Assume that this is just the json not being terminated properly.
// ignore // Ignore
} catch (IOException e1) { } catch (IOException e1) {
e1.printStackTrace(); e1.printStackTrace();
} finally { } finally {

View File

@ -27,7 +27,6 @@ import android.os.BatteryManager;
import android.util.Log; import android.util.Log;
import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.R.string;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.File; import java.io.File;
@ -48,6 +47,7 @@ public final class ResearchLogUploader {
private static final String TAG = ResearchLogUploader.class.getSimpleName(); private static final String TAG = ResearchLogUploader.class.getSimpleName();
private static final int UPLOAD_INTERVAL_IN_MS = 1000 * 60 * 15; // every 15 min private static final int UPLOAD_INTERVAL_IN_MS = 1000 * 60 * 15; // every 15 min
private static final int BUF_SIZE = 1024 * 8; private static final int BUF_SIZE = 1024 * 8;
protected static final int TIMEOUT_IN_MS = 1000 * 4;
private final boolean mCanUpload; private final boolean mCanUpload;
private final Context mContext; private final Context mContext;
@ -55,8 +55,6 @@ public final class ResearchLogUploader {
private final URL mUrl; private final URL mUrl;
private final ScheduledExecutorService mExecutor; private final ScheduledExecutorService mExecutor;
private Runnable doUploadRunnable = new UploadRunnable(null, false);
public ResearchLogUploader(final Context context, final File filesDir) { public ResearchLogUploader(final Context context, final File filesDir) {
mContext = context; mContext = context;
mFilesDir = filesDir; mFilesDir = filesDir;
@ -93,11 +91,15 @@ public final class ResearchLogUploader {
public void start() { public void start() {
if (mCanUpload) { if (mCanUpload) {
Log.d(TAG, "scheduling regular uploading"); mExecutor.scheduleWithFixedDelay(new UploadRunnable(null /* logToWaitFor */,
mExecutor.scheduleWithFixedDelay(doUploadRunnable, UPLOAD_INTERVAL_IN_MS, null /* callback */, false /* forceUpload */),
UPLOAD_INTERVAL_IN_MS, TimeUnit.MILLISECONDS); UPLOAD_INTERVAL_IN_MS, UPLOAD_INTERVAL_IN_MS, TimeUnit.MILLISECONDS);
} else { }
Log.d(TAG, "no permission to upload"); }
public void uploadAfterCompletion(final ResearchLog researchLog, final Callback callback) {
if (mCanUpload) {
mExecutor.submit(new UploadRunnable(researchLog, callback, true /* forceUpload */));
} }
} }
@ -106,7 +108,8 @@ public final class ResearchLogUploader {
// another upload happening right now, as it may have missed the latest changes. // another upload happening right now, as it may have missed the latest changes.
// TODO: Reschedule regular upload tests starting from now. // TODO: Reschedule regular upload tests starting from now.
if (mCanUpload) { if (mCanUpload) {
mExecutor.submit(new UploadRunnable(callback, true)); mExecutor.submit(new UploadRunnable(null /* logToWaitFor */, callback,
true /* forceUpload */));
} }
} }
@ -130,19 +133,33 @@ public final class ResearchLogUploader {
} }
class UploadRunnable implements Runnable { class UploadRunnable implements Runnable {
private final ResearchLog mLogToWaitFor;
private final Callback mCallback; private final Callback mCallback;
private final boolean mForceUpload; private final boolean mForceUpload;
public UploadRunnable(final Callback callback, final boolean forceUpload) { public UploadRunnable(final ResearchLog logToWaitFor, final Callback callback,
final boolean forceUpload) {
mLogToWaitFor = logToWaitFor;
mCallback = callback; mCallback = callback;
mForceUpload = forceUpload; mForceUpload = forceUpload;
} }
@Override @Override
public void run() { public void run() {
if (mLogToWaitFor != null) {
waitFor(mLogToWaitFor);
}
doUpload(); doUpload();
} }
private void waitFor(final ResearchLog researchLog) {
try {
researchLog.awaitTermination(TIMEOUT_IN_MS, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void doUpload() { private void doUpload() {
if (!mForceUpload && (!isExternallyPowered() || !hasWifiConnection())) { if (!mForceUpload && (!isExternallyPowered() || !hasWifiConnection())) {
return; return;

Some files were not shown because too many files have changed in this diff Show More