diff options
Diffstat (limited to 'java')
95 files changed, 1067 insertions, 1007 deletions
diff --git a/java/proguard.flags b/java/proguard.flags index ca205b927..752ced3e3 100644 --- a/java/proguard.flags +++ b/java/proguard.flags @@ -3,6 +3,10 @@ <init>(...); } +-keep class com.android.inputmethod.latin.Flag { + *; +} + -keep class com.android.inputmethod.keyboard.ProximityInfo { <init>(com.android.inputmethod.keyboard.ProximityInfo); } diff --git a/java/res/raw/main_en.dict b/java/res/raw/main_en.dict Binary files differindex e02e300e4..98a9361b5 100644 --- a/java/res/raw/main_en.dict +++ b/java/res/raw/main_en.dict diff --git a/java/res/raw/main_fr.dict b/java/res/raw/main_fr.dict Binary files differindex 8e616591c..717078c93 100644 --- a/java/res/raw/main_fr.dict +++ b/java/res/raw/main_fr.dict diff --git a/java/res/values-af/strings.xml b/java/res/values-af/strings.xml index 273832813..22543efe5 100644 --- a/java/res/values-af/strings.xml +++ b/java/res/values-af/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Verstek"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Stel kontakname voor"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Gebruik name van kontakte vir voorstelle en korreksies"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"Aktiveer herkorrigerings"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"Stel voorstelle vir herkorrigerings"</string> <string name="auto_cap" msgid="1719746674854628252">"Outohoofletters"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Voeg woordeboeke by"</string> <string name="main_dictionary" msgid="4798763781818361168">"Hoofwoordeboek"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Matig"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Aggressief"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Baie aggressief"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"Volgende woordvoorstelle"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"Gebaseer op vorige woord"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"Volgendewoordvoorstelle"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Gebruik vorige woord om voorstelle te verbeter"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"Volgendewoordvoorspelling"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Gebruik vorige woord ook vir voorspelling"</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_next_key" msgid="362972844525672568">"Volgende"</string> diff --git a/java/res/values-am/strings.xml b/java/res/values-am/strings.xml index a6373ccb6..a1b168cb7 100644 --- a/java/res/values-am/strings.xml +++ b/java/res/values-am/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"ነባሪ"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"የዕውቂያ ስም ጠቁም"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"ከዕውቂያዎች ለጥቆማዎች እና ማስተካከያዎች ስሞች ተጠቀም"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"ድጋሚ ለማስተካከል አንቃ"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"ድጋሚ ለማስተካከል ጥቆማዎችን አዘጋጅ"</string> <string name="auto_cap" msgid="1719746674854628252">"ራስ-ሰር አቢይ ማድረግ"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"መዝገበ ቃላቶች ጨምር"</string> <string name="main_dictionary" msgid="4798763781818361168">"ዋና መዝገበ ቃላት"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"መጠነኛ"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"ኃይለኛ"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"በጣም ቁጡ"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"የቀጣይ ቃል አስተያየቶች"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"በቀዳሚው ቃል ላይ የተመሠረተ"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"የቀጣይ ቃል አስተያየቶች"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"ምክሮችን ለማሻሻል ቀዳሚ ቃል ተጠቀም"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"የቀጣይ ቃል ግምት"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"ለትንበያ የቀደመ ቃል እንዲሁ ተጠቀም"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : ተቀምጧል"</string> <string name="label_go_key" msgid="1635148082137219148">"ሂድ"</string> <string name="label_next_key" msgid="362972844525672568">"በመቀጠል"</string> diff --git a/java/res/values-ar/strings.xml b/java/res/values-ar/strings.xml index 9e6f1ea51..2a2207447 100644 --- a/java/res/values-ar/strings.xml +++ b/java/res/values-ar/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"افتراضي"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"اقتراح أسماء جهات الاتصال"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"استخدام الأسماء من جهات الاتصال للاقتراحات والتصحيحات"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"تمكين عمليات إعادة التصحيح"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"تعيين اقتراحات لعمليات إعادة التصحيح"</string> <string name="auto_cap" msgid="1719746674854628252">"أحرف كبيرة تلقائيًا"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"القواميس الإضافية"</string> <string name="main_dictionary" msgid="4798763781818361168">"القاموس الرئيسي"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"معتدل"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"حاد"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"شديد الصرامة"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"اقتراحات الكلمات التالية"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"استنادًا إلى الكلمة السابقة"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"اقتراحات الكلمات التالية"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"استخدام الكلمة السابقة لتحسين الاقتراحات"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"تنبؤ الكلمات التالية"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"استخدام الكلمة السابقة أيضًا للتنبؤ"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : تم الحفظ"</string> <string name="label_go_key" msgid="1635148082137219148">"تنفيذ"</string> <string name="label_next_key" msgid="362972844525672568">"التالي"</string> diff --git a/java/res/values-be/strings.xml b/java/res/values-be/strings.xml index fb371f4c3..ff3213ad6 100644 --- a/java/res/values-be/strings.xml +++ b/java/res/values-be/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Па змаўчанні"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Прапан. імёны кантактаў"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Выкарыстоўваць імёны са спісу кантактаў для прапаноў і выпраўл."</string> + <string name="enable_span_insert" msgid="7204653105667167620">"Уключыць карэкцiроўкі"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"Задаць прапановы для карэкцiроўкі"</string> <string name="auto_cap" msgid="1719746674854628252">"Аўтаматычна рабіць вялікія літары"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Дадатковыя слоўнікі"</string> <string name="main_dictionary" msgid="4798763781818361168">"Асноўны слоўнік"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Сціплы"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Агрэсіўны"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Вельмі агрэсіўны"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"Падказкi для наступнага слова"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"На аснове папярэдняга слова"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"Падказкi для наступнага слова"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Выкарыстаць папярэдняе слова, каб палепшыць прапановы"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"Падказка наступнага слова"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Выкарыстанне папярэдняга слова для падказак"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Захаваныя"</string> <string name="label_go_key" msgid="1635148082137219148">"Пачаць"</string> <string name="label_next_key" msgid="362972844525672568">"Далей"</string> diff --git a/java/res/values-bg/strings.xml b/java/res/values-bg/strings.xml index 94945c03b..5e916cef0 100644 --- a/java/res/values-bg/strings.xml +++ b/java/res/values-bg/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"По подразбиране"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Предложения за контакти"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Използване на имена от „Контакти“ за предложения и поправки"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"Повторни поправки: Актив."</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"Задаване на предложения за повторни поправки"</string> <string name="auto_cap" msgid="1719746674854628252">"Автоматично поставяне на главни букви"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Добавени речници"</string> <string name="main_dictionary" msgid="4798763781818361168">"Основен речник"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Умерено"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Агресивно"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Много агресивно"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"Предложения за следващата дума"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"Въз основа на предишната дума"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"Предложения за следващата дума"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Използване на предишната дума за подобряване на предложенията"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"Предвиждане на следващата дума"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Използване на предишната дума и за предвиждане"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Запазено"</string> <string name="label_go_key" msgid="1635148082137219148">"Старт"</string> <string name="label_next_key" msgid="362972844525672568">"Напред"</string> diff --git a/java/res/values-ca/strings.xml b/java/res/values-ca/strings.xml index b6fb56093..1b7cfc255 100644 --- a/java/res/values-ca/strings.xml +++ b/java/res/values-ca/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Predeterminat"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Suggereix noms contactes"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Utilitza els noms de Contactes per a suggeriments i correccions"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"Activa la capacitat de tornar a corregir"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"Estableix suggeriments per tornar a corregir"</string> <string name="auto_cap" msgid="1719746674854628252">"Majúscules automàtiques"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Diccionaris complementaris"</string> <string name="main_dictionary" msgid="4798763781818361168">"Diccionari principal"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Moderada"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Total"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Molt agressiu"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"Suggeriments de paraula següent"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"En funció de la paraula anterior"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"Suggeriments de paraula següent"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Utilitza la paraula anterior per millorar els suggeriments"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"Predicció de paraula següent"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Utilitza també la paraula anterior per a la predicció"</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_next_key" msgid="362972844525672568">"Següent"</string> diff --git a/java/res/values-cs/strings.xml b/java/res/values-cs/strings.xml index 5818d5c6f..7e6ee0b4a 100644 --- a/java/res/values-cs/strings.xml +++ b/java/res/values-cs/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Výchozí"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Navrhovat jména kontaktů"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Použít jména ze seznamu kontaktů k návrhům a opravám"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"Povolit opětovné opravy"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"Nastavit návrhy pro opětovné opravy"</string> <string name="auto_cap" msgid="1719746674854628252">"Velká písmena automaticky"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Doplňkové slovníky"</string> <string name="main_dictionary" msgid="4798763781818361168">"Hlavní slovník"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Mírné"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agresivní"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Velmi agresivní"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"Návrhy dalšího slova"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"Na základě předchozího slova"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"Návrh dalšího slova"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Použít předchozí slovo ke zlepšení návrhů"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"Odhad dalšího slova"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Použít předchozí slovo také pro odhad"</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_next_key" msgid="362972844525672568">"Další"</string> diff --git a/java/res/values-da/strings.xml b/java/res/values-da/strings.xml index dc1df0772..c6800a952 100644 --- a/java/res/values-da/strings.xml +++ b/java/res/values-da/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Standard"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Foreslå navne på kontakter"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Brug navne fra Kontaktpersoner til forslag og rettelser"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"Aktivér fornyet rettelse"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"Angiv forslag til fornyet rettelse"</string> <string name="auto_cap" msgid="1719746674854628252">"Skriv aut. med stort"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Tillægsordbøger"</string> <string name="main_dictionary" msgid="4798763781818361168">"Hovedordbog"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Moderat"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Aggressiv"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Meget aggressiv"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"Forslag til næste ord"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"Baseret på tidligere ord"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"Forslag til næste ord"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Brug forrige ord til at forbedre forslag"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"Forudsigelse af næste ord"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Brug også tidligere ord til forudsigelse"</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_next_key" msgid="362972844525672568">"Næste"</string> diff --git a/java/res/values-de/strings.xml b/java/res/values-de/strings.xml index b24952534..cd2d78e4a 100644 --- a/java/res/values-de/strings.xml +++ b/java/res/values-de/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Standard"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Kontakte vorschlagen"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Namen aus \"Kontakte\" als Vorschläge und Korrekturmöglichkeiten anzeigen"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"Korrekturen aktivieren"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"Vorschläge für Korrekturen festlegen"</string> <string name="auto_cap" msgid="1719746674854628252">"Autom. Groß-/Kleinschr."</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Erweiterte Wörterbücher"</string> <string name="main_dictionary" msgid="4798763781818361168">"Allgemeines Wörterbuch"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Mäßig"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Stark"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Sehr stark"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"Vorschläge für nächstes Wort"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"Auf Grundlage des vorherigen Wortes"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"Vorschläge für nächstes Wort"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Zur Verbesserung von Vorschlägen vorheriges Wort verwenden"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"Vervollständigung für nächstes Wort"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Vorheriges Wort auch für Vervollständigung verwenden"</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_next_key" msgid="362972844525672568">"Weiter"</string> diff --git a/java/res/values-el/strings.xml b/java/res/values-el/strings.xml index d9e1aa8c4..5dcbf43ba 100644 --- a/java/res/values-el/strings.xml +++ b/java/res/values-el/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Προεπιλογή"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Πρόταση ονομάτων επαφών"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Χρησιμοποιήστε ονόματα από τις Επαφές για προτάσεις και διορθ."</string> + <string name="enable_span_insert" msgid="7204653105667167620">"Ενεργ. επανάλ. διορθώσεων"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"Ορισμός προτάσεων για επαναλήψεις διορθώσεων"</string> <string name="auto_cap" msgid="1719746674854628252">"Αυτόματη χρήση κεφαλαίων"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Πρόσθετα λεξικά"</string> <string name="main_dictionary" msgid="4798763781818361168">"Κύριο λεξικό"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Μέτρια"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Υψηλή"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Πολύ επιθετική"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"Προτάσεις επόμενων λέξεων"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"Βάσει προηγούμενης λέξης"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"Προτάσεις επόμενων λέξεων"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Χρήση προηγούμενης λέξης για τη βελτίωση προτάσεων"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"Πρόβλεψη επόμενης λέξης"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Χρησιμοποιήστε, επίσης, την προηγούμενη λέξη για πρόβλεψη"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Αποθηκεύτηκε"</string> <string name="label_go_key" msgid="1635148082137219148">"Μετ."</string> <string name="label_next_key" msgid="362972844525672568">"Επόμενο"</string> diff --git a/java/res/values-en-rGB/strings.xml b/java/res/values-en-rGB/strings.xml index 7241e5df0..cd9b218e7 100644 --- a/java/res/values-en-rGB/strings.xml +++ b/java/res/values-en-rGB/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Default"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Suggest Contact names"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Use names from Contacts for suggestions and corrections"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"Enable recorrections"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"Set suggestions for recorrections"</string> <string name="auto_cap" msgid="1719746674854628252">"Auto-capitalisation"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Add-on dictionaries"</string> <string name="main_dictionary" msgid="4798763781818361168">"Main dictionary"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Modest"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Aggressive"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Very aggressive"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"Next word suggestions"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"Based on previous word"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"Next word suggestions"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Use previous word to improve suggestion"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"Next word prediction"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Use previous word also for prediction"</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_next_key" msgid="362972844525672568">"Next"</string> diff --git a/java/res/values-es-rUS/strings.xml b/java/res/values-es-rUS/strings.xml index 01d9912da..39ca40903 100644 --- a/java/res/values-es-rUS/strings.xml +++ b/java/res/values-es-rUS/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Predeterminada"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Sugerir nombres de contacto"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Usar nombres de los contactos para sugerencias y correcciones"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"Activar correcciones"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"Establecer sugerencias para realizar correcciones"</string> <string name="auto_cap" msgid="1719746674854628252">"Mayúsculas automáticas"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Diccionarios complementarios"</string> <string name="main_dictionary" msgid="4798763781818361168">"Diccionario principal"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Moderado"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Total"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Muy agresivo"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"Sugerencias de palabra siguiente"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"Según la palabra anterior"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"Sugerencias para la palabra siguiente"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Usar la palabra anterior para mejorar las sugerencias"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"Predicción de la palabra siguiente"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Usar la palabra anterior también para predicción."</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_next_key" msgid="362972844525672568">"Siguiente"</string> diff --git a/java/res/values-es/strings.xml b/java/res/values-es/strings.xml index f97d93ddf..79a36cccd 100644 --- a/java/res/values-es/strings.xml +++ b/java/res/values-es/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Predeterminado"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Sugerir contactos"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Utilizar nombres de contactos para sugerencias y correcciones"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"Activar nuevas correcciones"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"Establecer sugerencias para nuevas correcciones"</string> <string name="auto_cap" msgid="1719746674854628252">"Mayúsculas automáticas"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Diccionarios complementarios"</string> <string name="main_dictionary" msgid="4798763781818361168">"Diccionario principal"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Parcial"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Total"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Muy agresiva"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"Sugerir siguiente palabra"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"Según la palabra anterior"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"Sugerir siguiente palabra"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Usar palabra anterior para mejorar las sugerencias"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"Predecir siguiente palabra"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Utilizar también la palabra anterior para realizar la predicción"</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_next_key" msgid="362972844525672568">"Sig."</string> diff --git a/java/res/values-et/strings.xml b/java/res/values-et/strings.xml index e4f0f2f58..45870d3a9 100644 --- a/java/res/values-et/strings.xml +++ b/java/res/values-et/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Vaikeseade"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Soovita kontaktkirjeid"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Kasuta soovitusteks ja parandusteks nimesid kontaktiloendist"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"Uute paranduste lubamine"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"Soovituste seadmine uute paranduste jaoks"</string> <string name="auto_cap" msgid="1719746674854628252">"Automaatne suurtähtede kasutamine"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Pistiksõnaraamatud"</string> <string name="main_dictionary" msgid="4798763781818361168">"Peamine sõnaraamat"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Mõõdukas"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agressiivne"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Väga agressiivne"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"Järgmise sõna soovitused"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"Eelmise sõna põhjal"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"Järgmise sõna soovitused"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Kasuta soovituste täiustamiseks eelmist sõna"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"Järgmise sõna ennustus"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Kasuta ennustuseks ka eelmist sõna"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : salvestatud"</string> <string name="label_go_key" msgid="1635148082137219148">"Mine"</string> <string name="label_next_key" msgid="362972844525672568">"Edasi"</string> diff --git a/java/res/values-fa/strings.xml b/java/res/values-fa/strings.xml index 4ad5025eb..9f0e5aaa4 100644 --- a/java/res/values-fa/strings.xml +++ b/java/res/values-fa/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"پیش فرض"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"پیشنهاد نام های مخاطب"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"برای پیشنهاد و تصحیح از نام مخاطبین استفاده شود"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"فعال کردن تصحیح مجدد"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"تنظیم پیشنهادات برای تصحیح مجدد"</string> <string name="auto_cap" msgid="1719746674854628252">"نوشتن با حروف بزرگ خودکار"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"فرهنگهای لغت افزودنی"</string> <string name="main_dictionary" msgid="4798763781818361168">"فرهنگ لغت اصلی"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"متوسط"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"فعال"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"بسیار پرخاشگرانه"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"پیشنهادات کلمه بعدی"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"بر اساس کلمه قبلی"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"پیشنهادات کلمه بعدی"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"برای بهبود پیشنهاد از کلمه قبلی استفاده شود"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"پیشبینی کلمه بعدی"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"استفاده از کلمه قبلی برای پیش بینی"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : ذخیره شد"</string> <string name="label_go_key" msgid="1635148082137219148">"برو"</string> <string name="label_next_key" msgid="362972844525672568">"بعدی"</string> diff --git a/java/res/values-fi/strings.xml b/java/res/values-fi/strings.xml index 3ca48be5d..f4dff35b9 100644 --- a/java/res/values-fi/strings.xml +++ b/java/res/values-fi/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Oletus"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Ehdota yhteystietojen nimiä"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Käytä yhteystietojen nimiä ehdotuksissa ja korjauksissa"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"Ota korjaukset käyttöön"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"Aseta korjausehdotuksia"</string> <string name="auto_cap" msgid="1719746674854628252">"Automaattiset isot kirjaimet"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Lisäsanakirjat"</string> <string name="main_dictionary" msgid="4798763781818361168">"Pääsanakirja"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Osittainen"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Täysi"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Hyvin aggressiivinen"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"Seuraavan sanan ehdotukset"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"Perustuu edelliseen sanan"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"Seuraavan sanan ehdotukset"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Paranna ehdotuksia aiempien sanojen avulla"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"Seuraavan sanan ennakointi"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Käytä edellistä sanaa myös ennakointiin"</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_next_key" msgid="362972844525672568">"Seur."</string> diff --git a/java/res/values-fr/strings.xml b/java/res/values-fr/strings.xml index e457480c1..1094c4ac3 100644 --- a/java/res/values-fr/strings.xml +++ b/java/res/values-fr/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Par défaut"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Proposer noms de contacts"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Utiliser des noms de contacts pour les suggestions et corrections"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"Activer la recorrection"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"Définir des suggestions de recorrection"</string> <string name="auto_cap" msgid="1719746674854628252">"Majuscules auto"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Dictionnaires complémentaires"</string> <string name="main_dictionary" msgid="4798763781818361168">"Dictionnaire principal"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Simple"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Proactive"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Très exigeante"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"Suggestions pour le mot suivant"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"Suggestions basées sur le mot précédent"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"Suggestions pour le mot suivant"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Améliorer les suggestions grâce au mot précédent"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"Prédiction du mot suivant"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Utiliser le mot précédent pour la prédiction"</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_next_key" msgid="362972844525672568">"Suiv."</string> diff --git a/java/res/values-hi/strings.xml b/java/res/values-hi/strings.xml index 0b76cfde6..c131e1278 100644 --- a/java/res/values-hi/strings.xml +++ b/java/res/values-hi/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"डिफ़ॉल्ट"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"संपर्क नाम सुझाएं"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"सुझाव और सुधार के लिए संपर्क से नामों का उपयोग करें"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"पुन: सुधार सक्षम करें"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"पुन: सुधार के लिए सुझाव सेट करें"</string> <string name="auto_cap" msgid="1719746674854628252">"स्वत: अक्षर बड़े करना"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"एड-ऑन डिक्शनरी"</string> <string name="main_dictionary" msgid="4798763781818361168">"मुख्य डिक्शनरी"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"साधारण"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"तीव्र"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"बहुत तीव्र"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"अगले शब्द सुझाव"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"पिछले शब्दों के आधार पर"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"अगला शब्द सुझाव"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"सुझावों को बेहतर बनाने के लिए पिछले शब्द का उपयोग करें"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"अगला शब्द पूर्वानुमान"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"पूर्वानुमान के लिए पिछले शब्द का उपयोग करें"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: सहेजा गया"</string> <string name="label_go_key" msgid="1635148082137219148">"जाएं"</string> <string name="label_next_key" msgid="362972844525672568">"अगला"</string> diff --git a/java/res/values-hr/strings.xml b/java/res/values-hr/strings.xml index c8649e951..f8a198df2 100644 --- a/java/res/values-hr/strings.xml +++ b/java/res/values-hr/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Zadano"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Predlaži imena kontakata"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Upotreba imena iz Kontakata za prijedloge i ispravke"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"Omogući ponovne ispravke"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"Postavite prijedloge za ponovne ispravke"</string> <string name="auto_cap" msgid="1719746674854628252">"Automatsko pisanje velikih slova"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Rječnici-dodaci"</string> <string name="main_dictionary" msgid="4798763781818361168">"Glavni rječnik"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Skromno"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agresivno"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Vrlo agresivno"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"Prijedlozi za sljedeću riječ"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"Na temelju prethodne riječi"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"Prijedlozi za sljedeću riječ"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Upotrijebi prethodnu riječ radi poboljšanja prijedloga"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"Predviđanje sljedeće riječi"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Upotrijebite prethodnu riječ i za predviđanje"</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_next_key" msgid="362972844525672568">"Dalje"</string> diff --git a/java/res/values-hu/strings.xml b/java/res/values-hu/strings.xml index d2a38cb24..fc1ac1227 100644 --- a/java/res/values-hu/strings.xml +++ b/java/res/values-hu/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Alapbeállítás"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Javasolt névjegyek"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"A névjegyek használata a javaslatokhoz és javításokhoz"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"Újbóli javítás engedélyezése"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"Javaslatok beállítása az újbóli javításokhoz"</string> <string name="auto_cap" msgid="1719746674854628252">"Automatikusan nagy kezdőbetű"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Bővítmények: szótárak"</string> <string name="main_dictionary" msgid="4798763781818361168">"Fő szótár"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Mérsékelt"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agresszív"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Nagyon agresszív"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"Következő szóra vonatkozó javaslatok"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"Az előző szó alapján"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"Következő szóra vonatkozó javaslatok"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Javaslatok fejlesztése az előző szó használatával"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"Következő szó előrejelzése"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Az előző szó használata a prediktív bevitelhez is"</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_next_key" msgid="362972844525672568">"Tovább"</string> diff --git a/java/res/values-in/strings.xml b/java/res/values-in/strings.xml index 2d10e6274..a7a2c0383 100644 --- a/java/res/values-in/strings.xml +++ b/java/res/values-in/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Default"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Sarankan nama Kontak"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Menggunakan nama dari Kontak untuk saran dan koreksi"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"Aktifkan koreksi ulang"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"Setel saran untuk koreksi ulang"</string> <string name="auto_cap" msgid="1719746674854628252">"Kapitalisasi otomatis"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Kamus pengaya"</string> <string name="main_dictionary" msgid="4798763781818361168">"Kamus utama"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Sederhana"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agresif"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Sangat agresif"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"Saran kata berikutnya"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"Berdasarkan kata sebelumnya"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"Saran kata berikutnya"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Gunakan kata sebelumnya untuk meningkatkan saran"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"Prediksi kata berikutnya"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Gunakan kata sebelumnya juga untuk prediksi"</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_next_key" msgid="362972844525672568">"Berikutnya"</string> diff --git a/java/res/values-it/strings.xml b/java/res/values-it/strings.xml index c3a2b5135..e77a0d04d 100644 --- a/java/res/values-it/strings.xml +++ b/java/res/values-it/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Predefinito"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Suggerisci nomi di contatti"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Utilizza nomi di Contatti per suggerimenti e correzioni"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"Attiva nuove correzioni"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"Imposta suggerimenti per nuove correzioni"</string> <string name="auto_cap" msgid="1719746674854628252">"Maiuscole automatiche"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Dizionari aggiuntivi"</string> <string name="main_dictionary" msgid="4798763781818361168">"Dizionario principale"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Media"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Massima"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Massima"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"Suggerimenti parola successiva"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"In base alla parola precedente"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"Suggerimenti parola successiva"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Usa parola precedente per migliorare suggerimenti"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"Previsione parola successiva"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Usa anche la parola precedente per la previsione"</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_next_key" msgid="362972844525672568">"Avanti"</string> diff --git a/java/res/values-iw/strings.xml b/java/res/values-iw/strings.xml index 3859993f9..000c9f337 100644 --- a/java/res/values-iw/strings.xml +++ b/java/res/values-iw/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"ברירת מחדל"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"הצע שמות של אנשי קשר"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"השתמש בשמות מרשימת אנשי הקשר עבור הצעות ותיקונים"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"הפוך תיקונים חוזרים לפעילים"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"הגדר הצעות עבור תיקונים חוזרים"</string> <string name="auto_cap" msgid="1719746674854628252">"הפיכת אותיות לרישיות באופן אוטומטי"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"הוספת מילונים"</string> <string name="main_dictionary" msgid="4798763781818361168">"מילון ראשי"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"מצומצם"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"מחמיר"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"מחמיר מאוד"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"הצעות המילה הבאה"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"בהתבסס על המילה הקודמת"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"הצעות המילה הבאה"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"השתמש במילה הקודמת כדי לשפר את ההצעות"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"חיזוי המילה הבאה"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"השתמש במילה הקודמת גם עבור חיזוי"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : נשמרה"</string> <string name="label_go_key" msgid="1635148082137219148">"בצע"</string> <string name="label_next_key" msgid="362972844525672568">"הבא"</string> diff --git a/java/res/values-ja/strings.xml b/java/res/values-ja/strings.xml index f9349f540..05dd3a364 100644 --- a/java/res/values-ja/strings.xml +++ b/java/res/values-ja/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"デフォルト"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"候補の連絡先名を表示"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"連絡先の名前を使用して候補表示や自動修正を行います"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"再修正を有効にする"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"再修正の候補を挿入する"</string> <string name="auto_cap" msgid="1719746674854628252">"自動大文字変換"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"アドオン辞書"</string> <string name="main_dictionary" msgid="4798763781818361168">"メイン辞書"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"中"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"強"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"最も強い"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"次の入力候補"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"前の語句に基づいた入力候補表示"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"次の入力候補"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"直前の単語から入力候補を予測します"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"次の入力候補を予測"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"前の語句も予測に使用"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>:保存しました"</string> <string name="label_go_key" msgid="1635148082137219148">"実行"</string> <string name="label_next_key" msgid="362972844525672568">"次へ"</string> diff --git a/java/res/values-ko/strings.xml b/java/res/values-ko/strings.xml index cd8cb6b51..6a998838a 100644 --- a/java/res/values-ko/strings.xml +++ b/java/res/values-ko/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"기본값"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"주소록 이름 활용"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"추천 및 수정에 주소록의 이름 사용"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"재수정 가능 설정"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"재수정 추천어 사전 활성화"</string> <string name="auto_cap" msgid="1719746674854628252">"자동 대문자화"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"사전 추가"</string> <string name="main_dictionary" msgid="4798763781818361168">"기본 사전"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"약"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"중"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"강"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"다음 검색어 추천"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"이전 단어에 기반한 추천"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"다음 추천 검색어"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"이전 단어를 사용하여 추천 검색어 개선"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"다음 예상 검색어"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"이전 단어를 사용하여 예상 검색어 표시"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: 저장됨"</string> <string name="label_go_key" msgid="1635148082137219148">"이동"</string> <string name="label_next_key" msgid="362972844525672568">"다음"</string> diff --git a/java/res/values-lt/strings.xml b/java/res/values-lt/strings.xml index 2f6abc856..86bfc3714 100644 --- a/java/res/values-lt/strings.xml +++ b/java/res/values-lt/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Numatytasis"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Siūlyti kontaktų vardus"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Siūlant ir taisant naudoti vardus iš „Kontaktų“"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"Įdiegti pakartotinius pataisymus"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"Nustatyti pakartotinio pataisymo pasiūlymus"</string> <string name="auto_cap" msgid="1719746674854628252">"Automatinis didžiųjų raidžių rašymas"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Papildomi žodynai"</string> <string name="main_dictionary" msgid="4798763781818361168">"Pagrindinis žodynas"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Vidutinis"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Atkaklus"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Labai agresyviai"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"Kito žodžio pasiūlymai"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"Pagal ankstesnį žodį"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"Kito žodžio pasiūlymai"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Naudoti ankstesnį žodį pasiūlymams patobulinti"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"Kito žodžio numatymas"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Numatant naudoti ir ankstesnį žodį"</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_next_key" msgid="362972844525672568">"Kitas"</string> diff --git a/java/res/values-lv/strings.xml b/java/res/values-lv/strings.xml index 66dd1473e..403e0f2d1 100644 --- a/java/res/values-lv/strings.xml +++ b/java/res/values-lv/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Noklusējums"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Ieteikt kontaktp. vārdus"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Izmantot kontaktpersonu vārdus kā ieteikumus un labojumus"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"Iespējot atk. labojumus"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"Iestatīt atkārtotu labojumu ieteikumus"</string> <string name="auto_cap" msgid="1719746674854628252">"Automātiska lielo burtu lietošana"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Papildinājumu vārdnīcas"</string> <string name="main_dictionary" msgid="4798763781818361168">"Galvenā vārdnīca"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Mērena"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agresīva"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Ļoti radikāla"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"Nākamie vārdu ieteikumi"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"Pamatojoties uz iepriekšējo vārdu"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"Nākamā vārda ieteikumi"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Ieteikumu uzlabošanai izmantot iepriekšējo vārdu"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"Nākamā vārda prognozēšana"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Izmantot iepriekšējo vārdu arī prognozēm"</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_next_key" msgid="362972844525672568">"Tālāk"</string> diff --git a/java/res/values-ms/strings.xml b/java/res/values-ms/strings.xml index 53c902039..60f5a4133 100644 --- a/java/res/values-ms/strings.xml +++ b/java/res/values-ms/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Lalai"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Cadangkan nama Kenalan"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Menggunakan nama daripada Kenalan untuk cadangan dan pembetulan"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"Dayakan pembetulan semula"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"Tetapkan cadangan untuk pembetulan semula"</string> <string name="auto_cap" msgid="1719746674854628252">"Huruf besar auto"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Kamus tambahan"</string> <string name="main_dictionary" msgid="4798763781818361168">"Kamus utama"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Sederhana"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agresif"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Sangat agresif"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"Cadangan perkataan seterusnya"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"Berdasarkan perkataan sebelumnya"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"Cadangan perkataan seterusnya"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Gunakan perkataan sebelumnya untuk memperbaik cadangan"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"Ramalan perkataan seterusnya"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Gunakan juga perkataan sebelumnya untuk ramalan"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Disimpan"</string> <string name="label_go_key" msgid="1635148082137219148">"Pergi"</string> <string name="label_next_key" msgid="362972844525672568">"Seterusnya"</string> diff --git a/java/res/values-nb/strings.xml b/java/res/values-nb/strings.xml index bdde36ae8..fc2bd5539 100644 --- a/java/res/values-nb/strings.xml +++ b/java/res/values-nb/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Standard"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Foreslå kontaktnavn"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Bruk navn fra Kontakter til forslag og korrigeringer"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"Aktiver korrigeringer"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"Angi forslag for korrigeringer"</string> <string name="auto_cap" msgid="1719746674854628252">"Stor forbokstav"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Tilleggsordbøker"</string> <string name="main_dictionary" msgid="4798763781818361168">"Hovedordliste"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Moderat"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Omfattende"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Veldig aggressiv"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"Forslag til neste ord"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"Basert på det forrige ordet"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"Forslag til rettelser av neste ord"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Bruk forrige ord til å forbedre forslagene"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"Forslag til neste ord"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Bruk forrige ord også for forslag"</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_next_key" msgid="362972844525672568">"Neste"</string> @@ -142,7 +146,7 @@ <string name="enable" msgid="5031294444630523247">"Aktiver"</string> <string name="not_now" msgid="6172462888202790482">"Ikke nå"</string> <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Inndatastilen finnes allerede: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string> - <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Bruksstudiemodus"</string> + <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Nyttighetsmodus"</string> <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"Innstillinger for vibrasjonsvarighet ved tastetrykk"</string> <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"Innstillinger for lydstyrke ved tastetrykk"</string> </resources> diff --git a/java/res/values-nl/strings.xml b/java/res/values-nl/strings.xml index 9624e176e..26d5e3f20 100644 --- a/java/res/values-nl/strings.xml +++ b/java/res/values-nl/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Standaard"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Contactnamen suggereren"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Namen uit Contacten gebruiken voor suggesties en correcties"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"Verbeteringen inschakelen"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"Suggesties instellen voor verbeteringen"</string> <string name="auto_cap" msgid="1719746674854628252">"Auto-hoofdlettergebruik"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Woordenboeken toevoegen"</string> <string name="main_dictionary" msgid="4798763781818361168">"Algemeen woordenboek"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Normaal"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agressief"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Zeer agressief"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"Suggesties voor volgend woord"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"Op basis van het vorige woord"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"Volgende woordsuggesties"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Vorig woord gebruiken om suggesties te verbeteren"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"Volgende woordvoorspelling"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Het voorgaande woord ook voor voorspelling gebruiken"</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_next_key" msgid="362972844525672568">"Verder"</string> diff --git a/java/res/values-pl/strings.xml b/java/res/values-pl/strings.xml index c8a72b77a..dc4f396a7 100644 --- a/java/res/values-pl/strings.xml +++ b/java/res/values-pl/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Wartość domyślna"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Proponuj osoby z kontaktów"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"W propozycjach i poprawkach użyj nazwisk z kontaktów"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"Włącz poprawki"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"Ustaw sugestie poprawek"</string> <string name="auto_cap" msgid="1719746674854628252">"Wstawiaj wielkie litery"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Dodatkowe słowniki"</string> <string name="main_dictionary" msgid="4798763781818361168">"Słownik główny"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Umiarkowana"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agresywna"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Bardzo agresywna"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"Sugestie kolejnych słów"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"Na podstawie poprzedniego słowa"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"Sugestie kolejnych słów"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Używaj poprzedniego wyrazu, by polepszyć sugestie"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"Przewidywanie następnego wyrazu"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Przewiduj również na podstawie poprzedniego słowa"</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_next_key" msgid="362972844525672568">"Dalej"</string> diff --git a/java/res/values-pt-rPT/strings.xml b/java/res/values-pt-rPT/strings.xml index cef2ce75b..35eedd82a 100644 --- a/java/res/values-pt-rPT/strings.xml +++ b/java/res/values-pt-rPT/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Predefinido"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Sugerir nomes de Contactos"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Utilizar nomes dos Contactos para sugestões e correções"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"Ativar correções"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"Definir sugestões para correções"</string> <string name="auto_cap" msgid="1719746674854628252">"Letras maiúsculas automáticas"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Dicionários extras"</string> <string name="main_dictionary" msgid="4798763781818361168">"Dicionário principal"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Moderada"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agressiva"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Muito agressivo"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"Sugestões da palavra seguinte"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"Com base na palavra anterior"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"Sugestões da palavra seguinte"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Utilizar palavra anterior para melhorar sugestões"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"Previsão da palavra seguinte"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Utilizar a palavra anterior também para predição"</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_next_key" msgid="362972844525672568">"Avançar"</string> diff --git a/java/res/values-pt/strings.xml b/java/res/values-pt/strings.xml index d092879cf..a12fc23e1 100644 --- a/java/res/values-pt/strings.xml +++ b/java/res/values-pt/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Padrão"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Sugerir nomes de contato"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Usar nomes dos Contatos para sugestões e correções"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"Ativar recorreções"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"Definir sugestões para recorreções"</string> <string name="auto_cap" msgid="1719746674854628252">"Capitaliz. automática"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Dicionários complementares"</string> <string name="main_dictionary" msgid="4798763781818361168">"Dicionário principal"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Moderado"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agressivo"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Muito agressivo"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"Sugestões para a palavra seguinte"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"Com base na palavra anterior"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"Sugestões p/ palavra seguinte"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Usar palavra anterior para melhorar as sugestões"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"Previsão da palavra seguinte"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Use também a palavra anterior para prever"</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_next_key" msgid="362972844525672568">"Avançar"</string> diff --git a/java/res/values-rm/strings.xml b/java/res/values-rm/strings.xml index b39691ceb..c6c936e49 100644 --- a/java/res/values-rm/strings.xml +++ b/java/res/values-rm/strings.xml @@ -67,6 +67,10 @@ <skip /> <!-- no translation found for use_contacts_dict_summary (6599983334507879959) --> <skip /> + <!-- no translation found for enable_span_insert (7204653105667167620) --> + <skip /> + <!-- no translation found for enable_span_insert_summary (2947317657871394467) --> + <skip /> <string name="auto_cap" msgid="1719746674854628252">"Maiusclas automaticas"</string> <!-- no translation found for configure_dictionaries_title (4238652338556902049) --> <skip /> @@ -94,9 +98,13 @@ <skip /> <!-- no translation found for auto_correction_threshold_mode_very_aggeressive (3386782235540547678) --> <skip /> - <!-- no translation found for bigram_prediction (5809665643352206540) --> + <!-- no translation found for bigram_suggestion (8169311444438922902) --> + <skip /> + <!-- no translation found for bigram_suggestion_summary (6635527607242625713) --> + <skip /> + <!-- no translation found for bigram_prediction (3216364899483135294) --> <skip /> - <!-- no translation found for bigram_prediction_summary (3253961591626441019) --> + <!-- no translation found for bigram_prediction_summary (1747261921174300098) --> <skip /> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Memorisà"</string> <string name="label_go_key" msgid="1635148082137219148">"Dai"</string> diff --git a/java/res/values-ro/strings.xml b/java/res/values-ro/strings.xml index 08275665c..523a855c7 100644 --- a/java/res/values-ro/strings.xml +++ b/java/res/values-ro/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Prestabilit"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Sugeraţi nume din Agendă"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Utilizaţi numele din Agendă pentru sugestii şi corecţii"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"Activaţi rectificările"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"Setaţi sugestii pentru rectificări"</string> <string name="auto_cap" msgid="1719746674854628252">"Auto-capitalizare"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Dicţionare suplimentare"</string> <string name="main_dictionary" msgid="4798763781818361168">"Dicţionar principal"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Moderată"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agresivă"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Foarte exigentă"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"Sugestii pentru cuvântul următor"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"Bazate pe cuvântul precedent"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"Sugestii pentru cuvântul următor"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Utilizaţi cuvântul anterior pentru a îmbunătăţi sugestiile"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"Predicţia cuvântului următor"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Se utilizează şi cuvântul precedent pentru predicţii"</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_next_key" msgid="362972844525672568">"Înainte"</string> diff --git a/java/res/values-ru/strings.xml b/java/res/values-ru/strings.xml index 77ffe7b55..34fdb0f5c 100644 --- a/java/res/values-ru/strings.xml +++ b/java/res/values-ru/strings.xml @@ -44,8 +44,10 @@ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Задержка закрытия"</string> <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Без задержки"</string> <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"По умолчанию"</string> - <string name="use_contacts_dict" msgid="4435317977804180815">"Подсказывать имена"</string> - <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Подсказывать исправления на основе имен из списка контактов"</string> + <string name="use_contacts_dict" msgid="4435317977804180815">"Подсказки имен контактов"</string> + <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Подсказки и исправления на основе имен из контактов"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"Автоисправление"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"Показывать варианты исправления"</string> <string name="auto_cap" msgid="1719746674854628252">"Заглавные автоматически"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Дополнительные словари"</string> <string name="main_dictionary" msgid="4798763781818361168">"Основной словарь"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Умеренное"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Активное"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Очень активно"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"Подсказка для следующего слова"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"Подсказки, основанные на предыдущих словах"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"Следующие варианты"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Использовать предыдущее слово, чтобы исправить предложенные варианты"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"Следующая подсказка"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Использовать предыдущее слово для прогнозирования"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: сохранено"</string> <string name="label_go_key" msgid="1635148082137219148">"Поиск"</string> <string name="label_next_key" msgid="362972844525672568">"Далее"</string> diff --git a/java/res/values-sk/strings.xml b/java/res/values-sk/strings.xml index 2b31bd858..41fc0cf24 100644 --- a/java/res/values-sk/strings.xml +++ b/java/res/values-sk/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Predvolená"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Navrhnúť mená kontaktov"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Používať mená z Kontaktov na návrhy a opravy"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"Povoliť opätovné opravy"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"Nastaviť návrhy pre opätovné opravy"</string> <string name="auto_cap" msgid="1719746674854628252">"Veľké písmená automaticky"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Doplnkové slovníky"</string> <string name="main_dictionary" msgid="4798763781818361168">"Hlavný slovník"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Mierne"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agresívne"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Veľmi agresívne"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"Návrhy ďalšieho slova"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"Na základe predchádzajúceho slova"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"Návrhy ďalšieho slova"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Na zlepšenie návrhov použiť predchádzajúce slovo"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"Odhad ďalšieho slova"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Použiť predchádzajúce slovo aj pre predpoveď"</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_next_key" msgid="362972844525672568">"Ďalej"</string> diff --git a/java/res/values-sl/strings.xml b/java/res/values-sl/strings.xml index 05e20b04c..f18de78bc 100644 --- a/java/res/values-sl/strings.xml +++ b/java/res/values-sl/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Privzeto"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Predlagaj imena stikov"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Uporaba imen iz stikov za predloge in popravke"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"Omogoči vnovične popravke"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"Nastavitev predlogov za vnovične popravke"</string> <string name="auto_cap" msgid="1719746674854628252">"Samod. velike začetnice"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Dodatni slovarji"</string> <string name="main_dictionary" msgid="4798763781818361168">"Glavni slovar"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Zmerno"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Strogo"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Zelo strogo"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"Predlogi za naslednjo besedo"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"Na podlagi prejšnje besede"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"Predlogi naslednje besede"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Predloge izboljšaj s prejšnjo besedo"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"Predvidevanje naslednje besede"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Uporabi prejšnjo besedo tudi za predvidevanje"</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_next_key" msgid="362972844525672568">"Naprej"</string> diff --git a/java/res/values-sr/strings.xml b/java/res/values-sr/strings.xml index 43fe7003d..11e678ebc 100644 --- a/java/res/values-sr/strings.xml +++ b/java/res/values-sr/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Подразумевано"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Предложи имена контаката"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Користи имена из Контаката за предлоге и исправке"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"Омогући поновне исправке"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"Подешавање предлога за поновне исправке"</string> <string name="auto_cap" msgid="1719746674854628252">"Аутоматски унос великих слова"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Помоћни речници"</string> <string name="main_dictionary" msgid="4798763781818361168">"Главни речник"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Умерено"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Агресивно"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Веома агресивно"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"Предлози за следећу реч"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"На основу претходне речи"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"Предлози за следећу реч"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Користи претходну реч за побољшање предлога"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"Предвиђање следеће речи"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Користи претходну реч и за предвиђање"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Сачувано"</string> <string name="label_go_key" msgid="1635148082137219148">"Иди"</string> <string name="label_next_key" msgid="362972844525672568">"Следеће"</string> diff --git a/java/res/values-sv/strings.xml b/java/res/values-sv/strings.xml index f24446976..bf1e5054f 100644 --- a/java/res/values-sv/strings.xml +++ b/java/res/values-sv/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Standard"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Föreslå kontaktnamn"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Använd namn från Kontakter för förslag och korrigeringar"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"Aktivera omkorrigeringar"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"Ställ in förslag för omkorrigeringar"</string> <string name="auto_cap" msgid="1719746674854628252">"Automatiska versaler"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Tilläggsordlistor"</string> <string name="main_dictionary" msgid="4798763781818361168">"Huvudordlistan"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Måttlig"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Aggressiv"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Mycket aggressivt"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"Föreslå nästa ord"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"Baserat på föregående ord"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"Föreslå nästa ord"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Förbättra förslagen med föregående ord"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"Förutspå nästa ord"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Använd även föregående ord för att ge förslag"</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_next_key" msgid="362972844525672568">"Nästa"</string> diff --git a/java/res/values-sw/strings.xml b/java/res/values-sw/strings.xml index 9cec8679d..f416fcd76 100644 --- a/java/res/values-sw/strings.xml +++ b/java/res/values-sw/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Chaguo-msingi"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Pendekeza majini ya Anwani"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Tumia majina kutoka kwa Anwani kwa mapendekezo na marekebisho"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"Wezesha masahihisho mapya"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"Weka mapendekezo kwa ajili ya kusahihisha upya"</string> <string name="auto_cap" msgid="1719746674854628252">"Uwekaji wa herufi kubwa kiotomatiki"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Nyongeza za kamusi"</string> <string name="main_dictionary" msgid="4798763781818361168">"Kamusi kuu"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Ya wastani"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Ya hima"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Changamfu zaidi"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"Mapendekezo ya neno lifuatalo"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"Kulingana na neno la awali"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"Mapendekezo ya neno lifuatalo"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Tumia neno la awali ili kuboresha mapendekezo"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"Utabiri wa neno lifuatalo"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Tumia neno la awali pia kwa udadisi"</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_next_key" msgid="362972844525672568">"Ifuatayo"</string> diff --git a/java/res/values-th/strings.xml b/java/res/values-th/strings.xml index 174ee4507..6f25a2024 100644 --- a/java/res/values-th/strings.xml +++ b/java/res/values-th/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"ค่าเริ่มต้น"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"แนะนำชื่อผู้ติดต่อ"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"ใช้ชื่อจากรายชื่อติดต่อสำหรับคำแนะนำและการแก้ไข"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"เปิดใช้งานการแก้ไขซ้ำ"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"ตั้งค่าคำแนะนำสำหรับการแก้ไขซ้ำ"</string> <string name="auto_cap" msgid="1719746674854628252">"ปรับเป็นตัวพิมพ์ใหญ่อัตโนมัติ"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"พจนานุกรม Add-On"</string> <string name="main_dictionary" msgid="4798763781818361168">"พจนานุกรมหลัก"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"ปานกลาง"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"เข้มงวด"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"เข้มงวดมาก"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"คำแนะนำสำหรับคำถัดไป"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"ตามคำก่อนหน้า"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"คำแนะนำสำหรับคำถัดไป"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"ใช้คำก่อนหน้านี้เพื่อปรับปรุงคำแนะนำ"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"การคาดคะเนคำถัดไป"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"ใช้คำก่อนหน้านี้สำหรับการคาดคะเน"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : บันทึกแล้ว"</string> <string name="label_go_key" msgid="1635148082137219148">"ไป"</string> <string name="label_next_key" msgid="362972844525672568">"ถัดไป"</string> diff --git a/java/res/values-tl/strings.xml b/java/res/values-tl/strings.xml index 25801ca7d..e2fe6c5b4 100644 --- a/java/res/values-tl/strings.xml +++ b/java/res/values-tl/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Default"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Mungkahi pangalan Contact"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Gamitin pangalan mula Mga Contact sa mga mungkahi\'t pagwawasto"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"Paganahin ang mga muling pagtatama"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"Magtakda ng mga suhestyon para sa mga muling pagtatama"</string> <string name="auto_cap" msgid="1719746674854628252">"Auto-capitalization"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Mga diksyunaryo na add-on"</string> <string name="main_dictionary" msgid="4798763781818361168">"Pangunahing diksyunaryo"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Modest"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agresibo"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Napaka-agresibo"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"Mga suhestiyon sa susunod na salita"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"Batay sa nakaraang salita"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"Mga paghuhula sa susunod na salita"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Gamitin ang naunang salita para mapahusay ang mga suhestiyon"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"Paghuhula sa susunod na salita"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Gamitin ang nakaraang salita para din sa hula"</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_next_key" msgid="362972844525672568">"Susunod"</string> diff --git a/java/res/values-tr/strings.xml b/java/res/values-tr/strings.xml index 190736e82..16411b8ed 100644 --- a/java/res/values-tr/strings.xml +++ b/java/res/values-tr/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Varsayılan"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Kişi Adları öner"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Öneri ve düzeltmeler için Kişiler\'deki adları kullan"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"Düzeltmeleri etkinleştir"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"Yeniden düzeltmeler için önerileri ayarla"</string> <string name="auto_cap" msgid="1719746674854628252">"Otomatik olarak büyük fark yap"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Ek sözlükler"</string> <string name="main_dictionary" msgid="4798763781818361168">"Ana sözlük"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Ölçülü"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agresif"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Çok geniş ölçekte"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"Sonraki kelime önerileri"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"Önceki kelimeye dayanarak"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"Sonraki kelime önerileri"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Önerileri geliştirmek için önceki kelimeyi kullan"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"Sonraki kelime tahmini"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Önceki kelimeyi de tahmin için kullan"</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_next_key" msgid="362972844525672568">"İleri"</string> diff --git a/java/res/values-uk/strings.xml b/java/res/values-uk/strings.xml index 04a8a638e..c2e743b45 100644 --- a/java/res/values-uk/strings.xml +++ b/java/res/values-uk/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"За умовчанням"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Пропон. імена контактів"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Використ. імена зі списку контактів для пропозицій і виправлень"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"Увімкнути виправлення"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"Показувати варіанти автовиправлень"</string> <string name="auto_cap" msgid="1719746674854628252">"Авто викор. вел. літер"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Додані словники"</string> <string name="main_dictionary" msgid="4798763781818361168">"Основний словник"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Помірне"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Активне"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Дуже активне"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"Пропозиції наступного слова"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"На основі попереднього слова"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"Пропозиції наступного слова"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Використати попереднє слово для покращення пропозицій"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"Передбачення наступного слова"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Використовувати попереднє слово також як передбачений запит"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : збережено"</string> <string name="label_go_key" msgid="1635148082137219148">"Іти"</string> <string name="label_next_key" msgid="362972844525672568">"Далі"</string> diff --git a/java/res/values-vi/strings.xml b/java/res/values-vi/strings.xml index c9dc0e644..9ce2d5a78 100644 --- a/java/res/values-vi/strings.xml +++ b/java/res/values-vi/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Mặc định"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Đề xuất tên liên hệ"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Sử dụng tên từ Danh bạ cho các đề xuất và chỉnh sửa"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"Bật sửa đổi lại"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"Đặt đề xuất cho các sửa đổi lại"</string> <string name="auto_cap" msgid="1719746674854628252">"Tự động viết hoa"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Thêm từ điển"</string> <string name="main_dictionary" msgid="4798763781818361168">"Từ điển chính"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Đơn giản"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Linh hoạt"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Rất linh hoạt"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"Đề xuất từ tiếp theo"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"Dựa trên từ trước đó"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"Đề xuất từ tiếp theo"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Sử dụng từ trước đó để cải tiến đề xuất"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"Dự đoán từ tiếp theo"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Cũng sử dụng từ trước đó để dự đoán"</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_next_key" msgid="362972844525672568">"Tiếp theo"</string> diff --git a/java/res/values-zh-rCN/strings.xml b/java/res/values-zh-rCN/strings.xml index 9f5e4633d..4907f202f 100644 --- a/java/res/values-zh-rCN/strings.xml +++ b/java/res/values-zh-rCN/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"默认"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"联系人姓名建议"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"使用联系人中的姓名提供建议和更正"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"允许再次更正"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"设置建议以用于再次更正"</string> <string name="auto_cap" msgid="1719746674854628252">"自动大写"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"附加词典"</string> <string name="main_dictionary" msgid="4798763781818361168">"主词典"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"小改"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"大改"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"改动极大"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"下一字词建议"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"根据上一个字词提供建议"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"下一字词建议"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"使用上一字词改进建议"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"下一字词预测"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"结合前一个字词进行预测"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>:已保存"</string> <string name="label_go_key" msgid="1635148082137219148">"开始"</string> <string name="label_next_key" msgid="362972844525672568">"下一步"</string> diff --git a/java/res/values-zh-rTW/strings.xml b/java/res/values-zh-rTW/strings.xml index 20592dc44..9179e669b 100644 --- a/java/res/values-zh-rTW/strings.xml +++ b/java/res/values-zh-rTW/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"預設"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"建議聯絡人名稱"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"根據「聯絡人」名稱提供建議與修正"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"啟用重新更正"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"設定建議供重新更正"</string> <string name="auto_cap" msgid="1719746674854628252">"自動大寫"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"外掛字典"</string> <string name="main_dictionary" msgid="4798763781818361168">"主要字典"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"更正範圍小"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"更正範圍大"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"更正範圍極大"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"下一個字詞建議"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"根據先前字詞產生"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"下一個字詞建議"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"根據前一個字詞找出更適合的建議"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"下一個字詞預測"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"同樣使用前一個字詞進行預測"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>:已儲存"</string> <string name="label_go_key" msgid="1635148082137219148">"開始"</string> <string name="label_next_key" msgid="362972844525672568">"繼續"</string> diff --git a/java/res/values-zu/strings.xml b/java/res/values-zu/strings.xml index 35cb99cf8..3f7c96b66 100644 --- a/java/res/values-zu/strings.xml +++ b/java/res/values-zu/strings.xml @@ -46,6 +46,8 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Okuzenzakalelayo"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Sikisela amagama Othintana nabo"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Amagama abasebenzisi kusuka Kothintana nabo bokusikisela nokulungisa"</string> + <string name="enable_span_insert" msgid="7204653105667167620">"Vumela ukulungiswa kabusha"</string> + <string name="enable_span_insert_summary" msgid="2947317657871394467">"Setha iziphakamiso zokulungisa kabusha"</string> <string name="auto_cap" msgid="1719746674854628252">"Ukwenza ofeleba okuzenzakalelayo"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Faka izichazamazwi"</string> <string name="main_dictionary" msgid="4798763781818361168">"Isichazamazwi sakho ngqangi"</string> @@ -60,8 +62,10 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Thobekile"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Bukhali"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Nobudlova kakhulu"</string> - <string name="bigram_prediction" msgid="5809665643352206540">"Iziphakamiso zegama elilandelayo"</string> - <string name="bigram_prediction_summary" msgid="3253961591626441019">"Ngokususela egameni langaphambilini"</string> + <string name="bigram_suggestion" msgid="8169311444438922902">"Iziphakamiso zegama elilandelayo"</string> + <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Sebenzisa igama elandulele ukuthuthukisa iziphakamiso"</string> + <string name="bigram_prediction" msgid="3216364899483135294">"Ukuqagela kwegama elilandelayo"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Sebenzisa igama langaphambilini ukuze uqagele"</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_next_key" msgid="362972844525672568">"Okulandelayo"</string> diff --git a/java/res/values/donottranslate.xml b/java/res/values/donottranslate.xml index 0970aeee0..d6a68d0dc 100644 --- a/java/res/values/donottranslate.xml +++ b/java/res/values/donottranslate.xml @@ -181,52 +181,6 @@ <!-- Description for Bulgarian (BDS) subtype. --> <string name="subtype_bulgarian_bds">%s (BDS)</string> - <!-- Compatibility map from subtypeLocale:subtypeExtraValue to keyboardLayoutSet --> - <string-array name="locale_and_extra_value_to_keyboard_layout_set_map"> - <item>en_US:TrySuppressingImeSwitcher,AsciiCapable,SupportTouchPositionCorrection</item> - <item>qwerty</item> - <item>en_GB:TrySuppressingImeSwitcher,AsciiCapable,SupportTouchPositionCorrection</item> - <item>qwerty</item> - <item>ar:SupportTouchPositionCorrection</item> - <item>arabic</item> - <item>cs:AsciiCapable,SupportTouchPositionCorrection</item> - <item>qwertz</item> - <item>da:AsciiCapable,SupportTouchPositionCorrection</item> - <item>nordic</item> - <item>de:AsciiCapable,SupportTouchPositionCorrection</item> - <item>qwertz</item> - <item>es:AsciiCapable,SupportTouchPositionCorrection</item> - <item>spanish</item> - <item>fi:AsciiCapable,SupportTouchPositionCorrection</item> - <item>nordic</item> - <item>fr:AsciiCapable,SupportTouchPositionCorrection</item> - <item>azerty</item> - <item>fr_CA:AsciiCapable,SupportTouchPositionCorrection</item> - <item>qwerty</item> - <item>hr:AsciiCapable,SupportTouchPositionCorrection</item> - <item>qwertz</item> - <item>hu:AsciiCapable,SupportTouchPositionCorrection</item> - <item>qwertz</item> - <item>it:AsciiCapable,SupportTouchPositionCorrection</item> - <item>qwerty</item> - <item>iw:SupportTouchPositionCorrection</item> - <item>hebrew</item> - <item>nb:AsciiCapable,SupportTouchPositionCorrection</item> - <item>nordic</item> - <item>nl:AsciiCapable,SupportTouchPositionCorrection</item> - <item>qwerty</item> - <item>pl:AsciiCapable,SupportTouchPositionCorrection</item> - <item>qwerty</item> - <item>ru:SupportTouchPositionCorrection</item> - <item>east_slavic</item> - <item>sr:SupportTouchPositionCorrection</item> - <item>south_slavic</item> - <item>sv:AsciiCapable,SupportTouchPositionCorrection</item> - <item>nordic</item> - <item>tr:AsciiCapable,SupportTouchPositionCorrection</item> - <item>qwerty</item> - </string-array> - <!-- dictionary pack package name /settings activity (for shared prefs and settings) --> <string name="dictionary_pack_package_name">com.google.android.inputmethod.latin.dictionarypack</string> <string name="dictionary_pack_settings_activity">com.google.android.inputmethod.latin.dictionarypack.DictionarySettingsActivity</string> diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml index 6c66a4844..0b781af79 100644 --- a/java/res/values/strings.xml +++ b/java/res/values/strings.xml @@ -85,6 +85,11 @@ <!-- Description for option enabling or disabling the use of names of people in Contacts for suggestion and correction [CHAR LIMIT=65] --> <string name="use_contacts_dict_summary">Use names from Contacts for suggestions and corrections</string> + <!-- Option name for enabling insertion of suggestion spans (advanced option) [CHAR LIMIT=25] --> + <string name="enable_span_insert">Enable recorrections</string> + <!-- Option summary for enabling insertion of suggestion spans (advanced option) [CHAR LIMIT=65] --> + <string name="enable_span_insert_summary">Set suggestions for recorrections</string> + <!-- Option to enable auto capitalization of sentences --> <string name="auto_cap">Auto-capitalization</string> @@ -115,10 +120,14 @@ <!-- Option to suggest auto correction suggestions very aggressively. Auto-corrects to a word which has even large edit distance from typed word. [CHAR LIMIT=20] --> <string name="auto_correction_threshold_mode_very_aggeressive">Very aggressive</string> - <!-- Option to enable using next word suggestions. After the user types a space, with this option on, the keyboard will try to predict the next word. --> - <string name="bigram_prediction">Next word suggestions</string> - <!-- 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> + <!-- Option to enable next word correction --> + <string name="bigram_suggestion">Next word suggestions</string> + <!-- Option to enable next word suggestion. This uses the previous word in an attempt to improve the suggestions quality --> + <string name="bigram_suggestion_summary">Use previous word to improve suggestions</string> + <!-- Option to enable using next word prediction --> + <string name="bigram_prediction">Next word prediction</string> + <!-- Description for "next word prediction" option. This displays suggestions even when there is no input, based on the previous word. --> + <string name="bigram_prediction_summary">Use previous word also for prediction</string> <!-- Indicates that a word has been added to the dictionary --> <string name="added_word"><xliff:g id="word">%s</xliff:g> : Saved</string> @@ -296,7 +305,7 @@ <string name="subtype_locale">Language</string> <!-- Title of the spinner for choosing a keyboard layout of custom style in the settings dialog [CHAR LIMIT=15] --> <string name="keyboard_layout_set">Layout</string> - <!-- The message of the dialog to note that a custom input style needs to be enabled. [CHAR LIMIT=130] --> + <!-- The message of the dialog to note that a custom input style needs to be enabled. [CHAR LIMIT=64] --> <string name="custom_input_style_note_message">"Your custom input style needs to be enabled before you start using it. Do you want to enable it now?"</string> <!-- Title of the button to enable a custom input style entry in the settings dialog [CHAR LIMIT=15] --> <string name="enable">Enable</string> diff --git a/java/res/xml/method.xml b/java/res/xml/method.xml index 7f8a23a0e..07bff098b 100644 --- a/java/res/xml/method.xml +++ b/java/res/xml/method.xml @@ -76,19 +76,19 @@ android:label="@string/subtype_en_US" android:imeSubtypeLocale="en_US" android:imeSubtypeMode="keyboard" - android:imeSubtypeExtraValue="TrySuppressingImeSwitcher,AsciiCapable,SupportTouchPositionCorrection" + android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,TrySuppressingImeSwitcher,AsciiCapable" /> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_en_GB" android:imeSubtypeLocale="en_GB" android:imeSubtypeMode="keyboard" - android:imeSubtypeExtraValue="TrySuppressingImeSwitcher,AsciiCapable,SupportTouchPositionCorrection" + android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,TrySuppressingImeSwitcher,AsciiCapable" /> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_generic" android:imeSubtypeLocale="ar" android:imeSubtypeMode="keyboard" - android:imeSubtypeExtraValue="SupportTouchPositionCorrection" + android:imeSubtypeExtraValue="KeyboardLayoutSet=arabic" /> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_generic" @@ -112,19 +112,19 @@ android:label="@string/subtype_generic" android:imeSubtypeLocale="cs" android:imeSubtypeMode="keyboard" - android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection" + android:imeSubtypeExtraValue="KeyboardLayoutSet=qwertz,AsciiCapable" /> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_generic" android:imeSubtypeLocale="da" android:imeSubtypeMode="keyboard" - android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection" + android:imeSubtypeExtraValue="KeyboardLayoutSet=nordic,AsciiCapable" /> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_generic" android:imeSubtypeLocale="de" android:imeSubtypeMode="keyboard" - android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection" + android:imeSubtypeExtraValue="KeyboardLayoutSet=qwertz,AsciiCapable" /> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_generic" @@ -136,7 +136,7 @@ android:label="@string/subtype_generic" android:imeSubtypeLocale="es" android:imeSubtypeMode="keyboard" - android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection" + android:imeSubtypeExtraValue="KeyboardLayoutSet=spanish,AsciiCapable" /> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_generic" @@ -154,19 +154,19 @@ android:label="@string/subtype_generic" android:imeSubtypeLocale="fi" android:imeSubtypeMode="keyboard" - android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection" + android:imeSubtypeExtraValue="KeyboardLayoutSet=nordic,AsciiCapable" /> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_generic" android:imeSubtypeLocale="fr" android:imeSubtypeMode="keyboard" - android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection" + android:imeSubtypeExtraValue="KeyboardLayoutSet=azerty,AsciiCapable" /> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_generic" android:imeSubtypeLocale="fr_CA" android:imeSubtypeMode="keyboard" - android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection" + android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable" /> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_generic" @@ -178,13 +178,13 @@ android:label="@string/subtype_generic" android:imeSubtypeLocale="hr" android:imeSubtypeMode="keyboard" - android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection" + android:imeSubtypeExtraValue="KeyboardLayoutSet=qwertz,AsciiCapable" /> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_generic" android:imeSubtypeLocale="hu" android:imeSubtypeMode="keyboard" - android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection" + android:imeSubtypeExtraValue="KeyboardLayoutSet=qwertz,AsciiCapable" /> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_generic" @@ -196,14 +196,14 @@ android:label="@string/subtype_generic" android:imeSubtypeLocale="it" android:imeSubtypeMode="keyboard" - android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection" + android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable" /> <!-- Java uses the deprecated "iw" code instead of the standard "he" code for Hebrew. --> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_generic" android:imeSubtypeLocale="iw" android:imeSubtypeMode="keyboard" - android:imeSubtypeExtraValue="SupportTouchPositionCorrection" + android:imeSubtypeExtraValue="KeyboardLayoutSet=hebrew" /> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_generic" @@ -239,19 +239,19 @@ android:label="@string/subtype_generic" android:imeSubtypeLocale="nb" android:imeSubtypeMode="keyboard" - android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection" + android:imeSubtypeExtraValue="KeyboardLayoutSet=nordic,AsciiCapable" /> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_generic" android:imeSubtypeLocale="nl" android:imeSubtypeMode="keyboard" - android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection" + android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable" /> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_generic" android:imeSubtypeLocale="pl" android:imeSubtypeMode="keyboard" - android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection" + android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable" /> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_generic" @@ -275,7 +275,7 @@ android:label="@string/subtype_generic" android:imeSubtypeLocale="ru" android:imeSubtypeMode="keyboard" - android:imeSubtypeExtraValue="SupportTouchPositionCorrection" + android:imeSubtypeExtraValue="KeyboardLayoutSet=east_slavic" /> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_generic" @@ -293,13 +293,13 @@ android:label="@string/subtype_generic" android:imeSubtypeLocale="sr" android:imeSubtypeMode="keyboard" - android:imeSubtypeExtraValue="SupportTouchPositionCorrection" + android:imeSubtypeExtraValue="KeyboardLayoutSet=south_slavic" /> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_generic" android:imeSubtypeLocale="sv" android:imeSubtypeMode="keyboard" - android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection" + android:imeSubtypeExtraValue="KeyboardLayoutSet=nordic,AsciiCapable" /> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_generic" @@ -311,7 +311,7 @@ android:label="@string/subtype_generic" android:imeSubtypeLocale="tr" android:imeSubtypeMode="keyboard" - android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection" + android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable" /> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_generic" diff --git a/java/res/xml/prefs.xml b/java/res/xml/prefs.xml index bf8805875..d8bf7847e 100644 --- a/java/res/xml/prefs.xml +++ b/java/res/xml/prefs.xml @@ -81,12 +81,6 @@ android:title="@string/misc_category" android:key="misc_settings"> <CheckBoxPreference - android:key="next_word_prediction" - android:title="@string/bigram_prediction" - android:summary="@string/bigram_prediction_summary" - android:persistent="true" - android:defaultValue="true" /> - <CheckBoxPreference android:key="usability_study_mode" android:title="@string/prefs_usability_study_mode" android:persistent="true" @@ -120,6 +114,12 @@ android:summary="@string/use_contacts_dict_summary" android:persistent="true" android:defaultValue="true" /> + <CheckBoxPreference + android:key="next_word_prediction" + android:title="@string/bigram_prediction" + android:summary="@string/bigram_prediction_summary" + android:persistent="true" + android:defaultValue="true" /> <PreferenceScreen android:key="pref_vibration_duration_settings" android:title="@string/prefs_keypress_vibration_duration_settings"/> diff --git a/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java b/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java index 5ffd94a43..23acb8b74 100644 --- a/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java +++ b/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java @@ -19,7 +19,6 @@ package com.android.inputmethod.accessibility; import android.content.Context; import android.text.TextUtils; import android.util.Log; -import android.util.SparseIntArray; import android.view.inputmethod.EditorInfo; import com.android.inputmethod.keyboard.Key; @@ -40,8 +39,8 @@ public class KeyCodeDescriptionMapper { // Map of key labels to spoken description resource IDs private final HashMap<CharSequence, Integer> mKeyLabelMap; - // Sparse array of spoken description resource IDs indexed by key codes - private final SparseIntArray mKeyCodeMap; + // Map of key codes to spoken description resource IDs + private final HashMap<Integer, Integer> mKeyCodeMap; public static void init() { sInstance.initInternal(); @@ -53,7 +52,7 @@ public class KeyCodeDescriptionMapper { private KeyCodeDescriptionMapper() { mKeyLabelMap = new HashMap<CharSequence, Integer>(); - mKeyCodeMap = new SparseIntArray(); + mKeyCodeMap = new HashMap<Integer, Integer>(); } private void initInternal() { @@ -61,7 +60,7 @@ public class KeyCodeDescriptionMapper { mKeyLabelMap.put(":-)", R.string.spoken_description_smiley); // Symbols that most TTS engines can't speak - mKeyCodeMap.put(' ', R.string.spoken_description_space); + mKeyCodeMap.put((int) ' ', R.string.spoken_description_space); // Special non-character codes defined in Keyboard mKeyCodeMap.put(Keyboard.CODE_DELETE, R.string.spoken_description_delete); @@ -274,8 +273,7 @@ public class KeyCodeDescriptionMapper { return context.getString(OBSCURED_KEY_RES_ID); } - final int resId = mKeyCodeMap.get(code); - if (resId != 0) { + if (mKeyCodeMap.containsKey(code)) { return context.getString(mKeyCodeMap.get(code)); } else if (isDefinedNonCtrl) { return Character.toString((char) code); diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java index 1b4cea2e7..6fc630d05 100644 --- a/java/src/com/android/inputmethod/keyboard/Keyboard.java +++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java @@ -23,8 +23,6 @@ import android.content.res.XmlResourceParser; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.util.Log; -import android.util.SparseArray; -import android.util.SparseIntArray; import android.util.TypedValue; import android.util.Xml; import android.view.InflateException; @@ -46,6 +44,7 @@ import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.HashSet; import java.util.Locale; @@ -135,7 +134,7 @@ public class Keyboard { public final Key[] mAltCodeKeysWhileTyping; public final KeyboardIconsSet mIconsSet; - private final SparseArray<Key> mKeyCache = new SparseArray<Key>(); + private final HashMap<Integer, Key> mKeyCache = new HashMap<Integer, Key>(); private final ProximityInfo mProximityInfo; private final boolean mProximityCharsCorrectionEnabled; @@ -185,23 +184,23 @@ public class Keyboard { if (code == CODE_UNSPECIFIED) { return null; } - final int index = mKeyCache.indexOfKey(code); - if (index >= 0) { - return mKeyCache.valueAt(index); + final Integer keyCode = code; + if (mKeyCache.containsKey(keyCode)) { + return mKeyCache.get(keyCode); } for (final Key key : mKeys) { if (key.mCode == code) { - mKeyCache.put(code, key); + mKeyCache.put(keyCode, key); return key; } } - mKeyCache.put(code, null); + mKeyCache.put(keyCode, null); return null; } public boolean hasKey(Key aKey) { - if (mKeyCache.indexOfValue(aKey) >= 0) { + if (mKeyCache.containsKey(aKey)) { return true; } @@ -345,8 +344,8 @@ public class Keyboard { private int mMaxHeightCount = 0; private int mMaxWidthCount = 0; - private final SparseIntArray mHeightHistogram = new SparseIntArray(); - private final SparseIntArray mWidthHistogram = new SparseIntArray(); + private final HashMap<Integer, Integer> mHeightHistogram = new HashMap<Integer, Integer>(); + private final HashMap<Integer, Integer> mWidthHistogram = new HashMap<Integer, Integer>(); private void clearHistogram() { mMostCommonKeyHeight = 0; @@ -358,22 +357,22 @@ public class Keyboard { mWidthHistogram.clear(); } - private static int updateHistogramCounter(SparseIntArray histogram, int key) { - final int index = histogram.indexOfKey(key); - final int count = (index >= 0 ? histogram.get(key) : 0) + 1; + private static int updateHistogramCounter(HashMap<Integer, Integer> histogram, + Integer key) { + final int count = (histogram.containsKey(key) ? histogram.get(key) : 0) + 1; histogram.put(key, count); return count; } private void updateHistogram(Key key) { - final int height = key.mHeight + key.mVerticalGap; + final Integer height = key.mHeight + key.mVerticalGap; final int heightCount = updateHistogramCounter(mHeightHistogram, height); if (heightCount > mMaxHeightCount) { mMaxHeightCount = heightCount; mMostCommonKeyHeight = height; } - final int width = key.mWidth + key.mHorizontalGap; + final Integer width = key.mWidth + key.mHorizontalGap; final int widthCount = updateHistogramCounter(mWidthHistogram, width); if (widthCount > mMaxWidthCount) { mMaxWidthCount = widthCount; diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java b/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java index aab89a3e5..8c7246855 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java @@ -29,7 +29,6 @@ import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.text.InputType; import android.util.Log; -import android.util.SparseArray; import android.util.Xml; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodSubtype; @@ -117,9 +116,9 @@ public class KeyboardLayoutSet { InputMethodSubtype mSubtype; int mOrientation; int mWidth; - // Sparse array of KeyboardLayoutSet element parameters indexed by element's id. - final SparseArray<ElementParams> mKeyboardLayoutSetElementIdToParamsMap = - new SparseArray<ElementParams>(); + // KeyboardLayoutSet element id to element's parameters map. + final HashMap<Integer, ElementParams> mKeyboardLayoutSetElementIdToParamsMap = + new HashMap<Integer, ElementParams>(); static class ElementParams { int mKeyboardXmlId; diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java index fb98af3e6..18e01fb49 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java @@ -30,7 +30,6 @@ import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.os.Message; import android.util.AttributeSet; -import android.util.SparseArray; import android.util.TypedValue; import android.view.LayoutInflater; import android.view.View; @@ -43,6 +42,7 @@ import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.StaticInnerHandlerWrapper; import com.android.inputmethod.latin.StringUtils; +import java.util.HashMap; import java.util.HashSet; /** @@ -124,10 +124,12 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy { private Canvas mCanvas; private final Paint mPaint = new Paint(); private final Paint.FontMetrics mFontMetrics = new Paint.FontMetrics(); - // 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>(); - // This sparse array caches key label text width in pixel indexed by key label text size. - private static final SparseArray<Float> sTextWidthCache = new SparseArray<Float>(); + // This map caches key label text height in pixel as value and key label text size as map key. + private static final HashMap<Integer, Float> sTextHeightCache = + new HashMap<Integer, Float>(); + // This map caches key label text width in pixel as value and key label text size as map key. + private static final HashMap<Integer, Float> sTextWidthCache = + new HashMap<Integer, Float>(); private static final char[] KEY_LABEL_REFERENCE_CHAR = { 'M' }; private static final char[] KEY_NUMERIC_HINT_LABEL_REFERENCE_CHAR = { '8' }; @@ -764,7 +766,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy { private final Rect mTextBounds = new Rect(); private float getCharHeight(char[] referenceChar, Paint paint) { - final int key = getCharGeometryCacheKey(referenceChar[0], paint); + final Integer key = getCharGeometryCacheKey(referenceChar[0], paint); final Float cachedValue = sTextHeightCache.get(key); if (cachedValue != null) return cachedValue; @@ -776,7 +778,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy { } private float getCharWidth(char[] referenceChar, Paint paint) { - final int key = getCharGeometryCacheKey(referenceChar[0], paint); + final Integer key = getCharGeometryCacheKey(referenceChar[0], paint); final Float cachedValue = sTextWidthCache.get(key); if (cachedValue != null) return cachedValue; diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java index 7714ba892..383298de9 100644 --- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java @@ -127,6 +127,7 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke private static final int MSG_TYPING_STATE_EXPIRED = 4; private final KeyTimerParams mParams; + private boolean mInKeyRepeat; public KeyTimerHandler(LatinKeyboardView outerInstance, KeyTimerParams params) { super(outerInstance); @@ -139,11 +140,8 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke final PointerTracker tracker = (PointerTracker) msg.obj; switch (msg.what) { case MSG_REPEAT_KEY: - final Key currentKey = tracker.getKey(); - if (currentKey != null && currentKey.mCode == msg.arg1) { - tracker.onRegisterKey(currentKey); - startKeyRepeatTimer(tracker, mParams.mKeyRepeatInterval); - } + tracker.onRegisterKey(tracker.getKey()); + startKeyRepeatTimer(tracker, mParams.mKeyRepeatInterval); break; case MSG_LONGPRESS_KEY: if (tracker != null) { @@ -160,23 +158,22 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke } private void startKeyRepeatTimer(PointerTracker tracker, long delay) { - final Key key = tracker.getKey(); - if (key == null) return; - sendMessageDelayed(obtainMessage(MSG_REPEAT_KEY, key.mCode, 0, tracker), delay); + sendMessageDelayed(obtainMessage(MSG_REPEAT_KEY, tracker), delay); } @Override public void startKeyRepeatTimer(PointerTracker tracker) { + mInKeyRepeat = true; startKeyRepeatTimer(tracker, mParams.mKeyRepeatStartTimeout); } public void cancelKeyRepeatTimer() { + mInKeyRepeat = false; removeMessages(MSG_REPEAT_KEY); } - // TODO: Suppress layout changes in key repeat mode public boolean isInKeyRepeat() { - return hasMessages(MSG_REPEAT_KEY); + return mInKeyRepeat; } @Override @@ -454,8 +451,8 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke */ @Override public void setKeyboard(Keyboard keyboard) { - // Remove any pending messages, except dismissing preview and key repeat. - mKeyTimerHandler.cancelLongPressTimer(); + // Remove any pending messages, except dismissing preview + mKeyTimerHandler.cancelKeyTimers(); super.setKeyboard(keyboard); mKeyDetector.setKeyboard( keyboard, -getPaddingLeft(), -getPaddingTop() + mVerticalCorrection); @@ -758,18 +755,15 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke final PointerTracker tracker = PointerTracker.getPointerTracker( pointerId, this); final int px, py; - final MotionEvent motionEvent; if (mMoreKeysPanel != null && tracker.mPointerId == mMoreKeysPanelPointerTrackerId) { px = mMoreKeysPanel.translateX((int)me.getX(i)); py = mMoreKeysPanel.translateY((int)me.getY(i)); - motionEvent = null; } else { px = (int)me.getX(i); py = (int)me.getY(i); - motionEvent = me; } - tracker.onMoveEvent(px, py, eventTime, motionEvent); + tracker.onMoveEvent(px, py, eventTime); if (ENABLE_USABILITY_STUDY_LOG) { final float pointerSize = me.getSize(i); final float pointerPressure = me.getPressure(i); diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java index 32ef408b4..34e428e82 100644 --- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java +++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java @@ -148,6 +148,9 @@ public class PointerTracker { // true if this pointer has been long-pressed and is showing a more keys panel. private boolean mIsShowingMoreKeysPanel; + // true if this pointer is repeatable key + private boolean mIsRepeatableKey; + // true if this pointer is in sliding key input boolean mIsInSlidingKeyInput; @@ -316,13 +319,6 @@ public class PointerTracker { private void setKeyDetectorInner(KeyDetector keyDetector) { mKeyDetector = keyDetector; mKeyboard = keyDetector.getKeyboard(); - final Key newKey = mKeyDetector.detectHitKey(mKeyX, mKeyY); - if (newKey != mCurrentKey) { - if (mDrawingProxy != null) { - setReleasedKeyGraphics(mCurrentKey); - } - mCurrentKey = newKey; - } final int keyQuarterWidth = mKeyboard.mMostCommonKeyWidth / 4; mKeyQuarterWidthSquared = keyQuarterWidth * keyQuarterWidth; } @@ -469,7 +465,7 @@ public class PointerTracker { onUpEvent(x, y, eventTime); break; case MotionEvent.ACTION_MOVE: - onMoveEvent(x, y, eventTime, null); + onMoveEvent(x, y, eventTime); break; case MotionEvent.ACTION_CANCEL: onCancelEvent(x, y, eventTime); @@ -525,6 +521,7 @@ public class PointerTracker { || mKeyDetector.alwaysAllowsSlidingInput(); mKeyboardLayoutHasBeenChanged = false; mKeyAlreadyProcessed = false; + mIsRepeatableKey = false; mIsInSlidingKeyInput = false; mIgnoreModifierKey = false; if (key != null) { @@ -548,7 +545,7 @@ public class PointerTracker { mIsInSlidingKeyInput = true; } - public void onMoveEvent(int x, int y, long eventTime, MotionEvent me) { + public void onMoveEvent(int x, int y, long eventTime) { if (DEBUG_MOVE_EVENT) printTouchEvent("onMoveEvent:", x, y, eventTime); if (mKeyAlreadyProcessed) @@ -671,7 +668,7 @@ public class PointerTracker { } if (mKeyAlreadyProcessed) return; - if (mCurrentKey != null && !mCurrentKey.isRepeatable()) { + if (!mIsRepeatableKey) { detectAndSendKey(mCurrentKey, mKeyX, mKeyY); } } @@ -717,6 +714,9 @@ public class PointerTracker { if (key != null && key.isRepeatable()) { onRegisterKey(key); mTimerProxy.startKeyRepeatTimer(this); + mIsRepeatableKey = true; + } else { + mIsRepeatableKey = false; } } @@ -760,10 +760,14 @@ public class PointerTracker { callListenerOnRelease(key, code, false); } + private long mPreviousEventTime; + private void printTouchEvent(String title, int x, int y, long eventTime) { final Key key = mKeyDetector.detectHitKey(x, y); final String code = KeyDetector.printableCode(key); + final long delta = eventTime - mPreviousEventTime; Log.d(TAG, String.format("%s%s[%d] %4d %4d %5d %s", title, - (mKeyAlreadyProcessed ? "-" : " "), mPointerId, x, y, eventTime, code)); + (mKeyAlreadyProcessed ? "-" : " "), mPointerId, x, y, delta, code)); + mPreviousEventTime = eventTime; } } diff --git a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java index ae123e29a..1bc825479 100644 --- a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java +++ b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java @@ -24,6 +24,7 @@ import com.android.inputmethod.keyboard.Keyboard.Params.TouchPositionCorrection; import com.android.inputmethod.latin.JniUtils; import java.util.Arrays; +import java.util.HashMap; public class ProximityInfo { /** MAX_PROXIMITY_CHARS_SIZE must be the same as MAX_PROXIMITY_CHARS_SIZE_INTERNAL @@ -189,6 +190,10 @@ public class ProximityInfo { private void computeNearestNeighbors() { final int defaultWidth = mMostCommonKeyWidth; final Key[] keys = mKeys; + final HashMap<Integer, Key> keyCodeMap = new HashMap<Integer, Key>(); + for (final Key key : keys) { + keyCodeMap.put(key.mCode, key); + } final int thresholdBase = (int) (defaultWidth * SEARCH_DISTANCE); final int threshold = thresholdBase * thresholdBase; // Round-up so we don't have any pixels outside the grid diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java b/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java index 291b3b943..80f4f259b 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java @@ -18,7 +18,6 @@ package com.android.inputmethod.keyboard.internal; import android.content.res.TypedArray; import android.util.Log; -import android.util.SparseArray; import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.latin.R; @@ -90,7 +89,7 @@ public class KeyStyles { private class DeclaredKeyStyle extends KeyStyle { private final String mParentStyleName; - private final SparseArray<Object> mStyleAttributes = new SparseArray<Object>(); + private final HashMap<Integer, Object> mStyleAttributes = new HashMap<Integer, Object>(); public DeclaredKeyStyle(String parentStyleName) { mParentStyleName = parentStyleName; @@ -101,9 +100,8 @@ public class KeyStyles { if (a.hasValue(index)) { return parseStringArray(a, index); } - final Object value = mStyleAttributes.get(index); - if (value != null) { - return (String[])value; + if (mStyleAttributes.containsKey(index)) { + return (String[])mStyleAttributes.get(index); } final KeyStyle parentStyle = mStyles.get(mParentStyleName); return parentStyle.getStringArray(a, index); @@ -114,9 +112,8 @@ public class KeyStyles { if (a.hasValue(index)) { return parseString(a, index); } - final Object value = mStyleAttributes.get(index); - if (value != null) { - return (String)value; + if (mStyleAttributes.containsKey(index)) { + return (String)mStyleAttributes.get(index); } final KeyStyle parentStyle = mStyles.get(mParentStyleName); return parentStyle.getString(a, index); @@ -127,9 +124,8 @@ public class KeyStyles { if (a.hasValue(index)) { return a.getInt(index, defaultValue); } - final Object value = mStyleAttributes.get(index); - if (value != null) { - return (Integer)value; + if (mStyleAttributes.containsKey(index)) { + return (Integer)mStyleAttributes.get(index); } final KeyStyle parentStyle = mStyles.get(mParentStyleName); return parentStyle.getInt(a, index, defaultValue); @@ -137,13 +133,12 @@ public class KeyStyles { @Override public int getFlag(TypedArray a, int index) { - int flags = a.getInt(index, 0); - final Object value = mStyleAttributes.get(index); - if (value != null) { - flags |= (Integer)value; + int value = a.getInt(index, 0); + if (mStyleAttributes.containsKey(index)) { + value |= (Integer)mStyleAttributes.get(index); } final KeyStyle parentStyle = mStyles.get(mParentStyleName); - return flags | parentStyle.getFlag(a, index); + return value | parentStyle.getFlag(a, index); } void readKeyAttributes(TypedArray keyAttr) { diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java index 5155851fe..540e63b3f 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java @@ -20,7 +20,6 @@ import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.drawable.Drawable; import android.util.Log; -import android.util.SparseIntArray; import com.android.inputmethod.latin.R; @@ -32,7 +31,8 @@ public class KeyboardIconsSet { public static final int ICON_UNDEFINED = 0; private static final int ATTR_UNDEFINED = 0; - private static final SparseIntArray ATTR_ID_TO_ICON_ID = new SparseIntArray(); + private static final HashMap<Integer, Integer> ATTR_ID_TO_ICON_ID + = new HashMap<Integer, Integer>(); // Icon name to icon id map. private static final HashMap<String, Integer> sNameToIdsMap = new HashMap<String, Integer>(); @@ -76,9 +76,7 @@ public class KeyboardIconsSet { } public void loadIcons(final TypedArray keyboardAttrs) { - final int size = ATTR_ID_TO_ICON_ID.size(); - for (int index = 0; index < size; index++) { - final int attrId = ATTR_ID_TO_ICON_ID.keyAt(index); + for (final Integer attrId : ATTR_ID_TO_ICON_ID.keySet()) { try { final Drawable icon = keyboardAttrs.getDrawable(attrId); setDefaultBounds(icon); diff --git a/java/src/com/android/inputmethod/latin/AutoCorrection.java b/java/src/com/android/inputmethod/latin/AutoCorrection.java index c78974dac..e0452483c 100644 --- a/java/src/com/android/inputmethod/latin/AutoCorrection.java +++ b/java/src/com/android/inputmethod/latin/AutoCorrection.java @@ -21,17 +21,34 @@ import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import android.text.TextUtils; import android.util.Log; +import java.util.ArrayList; import java.util.concurrent.ConcurrentHashMap; public class AutoCorrection { private static final boolean DBG = LatinImeLogger.sDBG; private static final String TAG = AutoCorrection.class.getSimpleName(); - private static final int MINIMUM_SAFETY_NET_CHAR_LENGTH = 4; private AutoCorrection() { // Purely static class: can't instantiate. } + public static CharSequence computeAutoCorrectionWord( + final ConcurrentHashMap<String, Dictionary> dictionaries, + final WordComposer wordComposer, final ArrayList<SuggestedWordInfo> suggestions, + final CharSequence consideredWord, final float autoCorrectionThreshold, + final CharSequence whitelistedWord) { + if (hasAutoCorrectionForWhitelistedWord(whitelistedWord)) { + return whitelistedWord; + } else if (hasAutoCorrectionForConsideredWord( + dictionaries, wordComposer, suggestions, consideredWord)) { + return consideredWord; + } else if (hasAutoCorrectionForBinaryDictionary(wordComposer, suggestions, + consideredWord, autoCorrectionThreshold)) { + return suggestions.get(0).mWord; + } + return null; + } + public static boolean isValidWord(final ConcurrentHashMap<String, Dictionary> dictionaries, CharSequence word, boolean ignoreCase) { if (TextUtils.isEmpty(word)) { @@ -39,7 +56,7 @@ public class AutoCorrection { } final CharSequence lowerCasedWord = word.toString().toLowerCase(); for (final String key : dictionaries.keySet()) { - if (key.equals(Dictionary.TYPE_WHITELIST)) continue; + if (key.equals(Suggest.DICT_KEY_WHITELIST)) continue; final Dictionary dictionary = dictionaries.get(key); // It's unclear how realistically 'dictionary' can be null, but the monkey is somehow // managing to get null in here. Presumably the language is changing to a language with @@ -64,7 +81,7 @@ public class AutoCorrection { } int maxFreq = -1; for (final String key : dictionaries.keySet()) { - if (key.equals(Dictionary.TYPE_WHITELIST)) continue; + if (key.equals(Suggest.DICT_KEY_WHITELIST)) continue; final Dictionary dictionary = dictionaries.get(key); if (null == dictionary) continue; final int tempFreq = dictionary.getFrequency(word); @@ -75,12 +92,11 @@ public class AutoCorrection { return maxFreq; } - // Returns true if this is a whitelist entry, or it isn't in any dictionary. - public static boolean isWhitelistedOrNotAWord( + public static boolean allowsToBeAutoCorrected( final ConcurrentHashMap<String, Dictionary> dictionaries, final CharSequence word, final boolean ignoreCase) { final WhitelistDictionary whitelistDictionary = - (WhitelistDictionary)dictionaries.get(Dictionary.TYPE_WHITELIST); + (WhitelistDictionary)dictionaries.get(Suggest.DICT_KEY_WHITELIST); // If "word" is in the whitelist dictionary, it should not be auto corrected. if (whitelistDictionary != null && whitelistDictionary.shouldForciblyAutoCorrectFrom(word)) { @@ -89,18 +105,33 @@ public class AutoCorrection { return !isValidWord(dictionaries, word, ignoreCase); } - public static boolean suggestionExceedsAutoCorrectionThreshold(SuggestedWordInfo suggestion, + private static boolean hasAutoCorrectionForWhitelistedWord(CharSequence whiteListedWord) { + return whiteListedWord != null; + } + + private static boolean hasAutoCorrectionForConsideredWord( + final ConcurrentHashMap<String, Dictionary> dictionaries, + final WordComposer wordComposer, final ArrayList<SuggestedWordInfo> suggestions, + final CharSequence consideredWord) { + if (TextUtils.isEmpty(consideredWord)) return false; + return wordComposer.size() > 1 && suggestions.size() > 0 + && !allowsToBeAutoCorrected(dictionaries, consideredWord, false); + } + + private static boolean hasAutoCorrectionForBinaryDictionary(WordComposer wordComposer, + ArrayList<SuggestedWordInfo> suggestions, CharSequence consideredWord, float autoCorrectionThreshold) { - if (null != suggestion) { + if (wordComposer.size() > 1 && suggestions.size() > 0) { + final SuggestedWordInfo autoCorrectionSuggestion = suggestions.get(0); //final int autoCorrectionSuggestionScore = sortedScores[0]; - final int autoCorrectionSuggestionScore = suggestion.mScore; + final int autoCorrectionSuggestionScore = autoCorrectionSuggestion.mScore; // TODO: when the normalized score of the first suggestion is nearly equals to // the normalized score of the second suggestion, behave less aggressive. final float normalizedScore = BinaryDictionary.calcNormalizedScore( - consideredWord.toString(), suggestion.mWord.toString(), + consideredWord.toString(), autoCorrectionSuggestion.mWord.toString(), autoCorrectionSuggestionScore); if (DBG) { - Log.d(TAG, "Normalized " + consideredWord + "," + suggestion + "," + Log.d(TAG, "Normalized " + consideredWord + "," + autoCorrectionSuggestion + "," + autoCorrectionSuggestionScore + ", " + normalizedScore + "(" + autoCorrectionThreshold + ")"); } @@ -108,43 +139,10 @@ public class AutoCorrection { if (DBG) { Log.d(TAG, "Auto corrected by S-threshold."); } - return !shouldBlockAutoCorrectionBySafetyNet(consideredWord.toString(), - suggestion.mWord); + return true; } } return false; } - // TODO: Resolve the inconsistencies between the native auto correction algorithms and - // this safety net - public static boolean shouldBlockAutoCorrectionBySafetyNet(final String typedWord, - final CharSequence suggestion) { - // Safety net for auto correction. - // Actually if we hit this safety net, it's a bug. - // If user selected aggressive auto correction mode, there is no need to use the safety - // net. - // If the length of typed word is less than MINIMUM_SAFETY_NET_CHAR_LENGTH, - // we should not use net because relatively edit distance can be big. - final int typedWordLength = typedWord.length(); - if (typedWordLength < MINIMUM_SAFETY_NET_CHAR_LENGTH) { - return false; - } - final int maxEditDistanceOfNativeDictionary = - (typedWordLength < 5 ? 2 : typedWordLength / 2) + 1; - final int distance = BinaryDictionary.editDistance(typedWord, suggestion.toString()); - if (DBG) { - Log.d(TAG, "Autocorrected edit distance = " + distance - + ", " + maxEditDistanceOfNativeDictionary); - } - if (distance > maxEditDistanceOfNativeDictionary) { - if (DBG) { - Log.e(TAG, "Safety net: before = " + typedWord + ", after = " + suggestion); - Log.e(TAG, "(Error) The edit distance of this correction exceeds limit. " - + "Turning off auto-correction."); - } - return true; - } else { - return false; - } - } } diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java index ae415d0ab..d0613bd72 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java @@ -20,9 +20,7 @@ import android.content.Context; import android.text.TextUtils; import com.android.inputmethod.keyboard.ProximityInfo; -import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; -import java.util.ArrayList; import java.util.Arrays; import java.util.Locale; @@ -42,18 +40,17 @@ public class BinaryDictionary extends Dictionary { */ public static final int MAX_WORD_LENGTH = 48; public static final int MAX_WORDS = 18; - public static final int MAX_SPACES = 16; private static final String TAG = "BinaryDictionary"; private static final int MAX_BIGRAMS = 60; private static final int TYPED_LETTER_MULTIPLIER = 2; + private int mDicTypeId; private long mNativeDict; private final int[] mInputCodes = new int[MAX_WORD_LENGTH]; private final char[] mOutputChars = new char[MAX_WORD_LENGTH * MAX_WORDS]; private final char[] mOutputChars_bigrams = new char[MAX_WORD_LENGTH * MAX_BIGRAMS]; - private final int[] mSpaceIndices = new int[MAX_SPACES]; private final int[] mScores = new int[MAX_WORDS]; private final int[] mBigramScores = new int[MAX_BIGRAMS]; @@ -68,12 +65,14 @@ public class BinaryDictionary extends Dictionary { * @param offset the offset of the dictionary data within the file. * @param length the length of the binary data. * @param useFullEditDistance whether to use the full edit distance in suggestions - * @param dictType the dictionary type, as a human-readable string */ public BinaryDictionary(final Context context, final String filename, final long offset, final long length, - final boolean useFullEditDistance, final Locale locale, final String dictType) { - super(dictType); + final boolean useFullEditDistance, final Locale locale) { + // Note: at the moment a binary dictionary is always of the "main" type. + // Initializing this here will help transitioning out of the scheme where + // the Suggest class knows everything about every single dictionary. + mDicTypeId = Suggest.DIC_MAIN; mUseFullEditDistance = useFullEditDistance; loadDictionary(filename, offset, length); } @@ -88,10 +87,8 @@ public class BinaryDictionary extends Dictionary { private native int getFrequencyNative(long dict, int[] word, int wordLength); private native boolean isValidBigramNative(long dict, int[] word1, int[] word2); private native int getSuggestionsNative(long dict, long proximityInfo, int[] xCoordinates, - int[] yCoordinates, int[] times, int[] pointerIds, int[] inputCodes, int codesSize, - int commitPoint, boolean isGesture, - int[] prevWordCodePointArray, boolean useFullEditDistance, char[] outputChars, - int[] scores, int[] outputIndices); + int[] yCoordinates, int[] inputCodes, int codesSize, int[] prevWordForBigrams, + boolean useFullEditDistance, char[] outputChars, int[] scores); private native int getBigramsNative(long dict, int[] prevWord, int prevWordLength, int[] inputCodes, int inputCodesLength, char[] outputChars, int[] scores, int maxWordLength, int maxBigrams); @@ -106,9 +103,9 @@ public class BinaryDictionary extends Dictionary { } @Override - public ArrayList<SuggestedWordInfo> getBigrams(final WordComposer codes, - final CharSequence previousWord) { - if (mNativeDict == 0) return null; + public void getBigrams(final WordComposer codes, final CharSequence previousWord, + final WordCallback callback) { + if (mNativeDict == 0) return; int[] codePoints = StringUtils.toCodePointArray(previousWord.toString()); Arrays.fill(mOutputChars_bigrams, (char) 0); @@ -126,7 +123,6 @@ public class BinaryDictionary extends Dictionary { count = MAX_BIGRAMS; } - final ArrayList<SuggestedWordInfo> suggestions = new ArrayList<SuggestedWordInfo>(); for (int j = 0; j < count; ++j) { if (codesSize > 0 && mBigramScores[j] < 1) break; final int start = j * MAX_WORD_LENGTH; @@ -135,22 +131,19 @@ public class BinaryDictionary extends Dictionary { ++len; } if (len > 0) { - suggestions.add(new SuggestedWordInfo( - new String(mOutputChars_bigrams, start, len), - mBigramScores[j], SuggestedWordInfo.KIND_CORRECTION, mDictType)); + callback.addWord(mOutputChars_bigrams, start, len, mBigramScores[j], + mDicTypeId, Dictionary.BIGRAM); } } - return suggestions; } // proximityInfo and/or prevWordForBigrams may not be null. @Override - public ArrayList<SuggestedWordInfo> getWords(final WordComposer codes, - final CharSequence prevWordForBigrams, final ProximityInfo proximityInfo) { + public void getWords(final WordComposer codes, final CharSequence prevWordForBigrams, + final WordCallback callback, final ProximityInfo proximityInfo) { final int count = getSuggestions(codes, prevWordForBigrams, proximityInfo, mOutputChars, - mScores, mSpaceIndices); + mScores); - final ArrayList<SuggestedWordInfo> suggestions = new ArrayList<SuggestedWordInfo>(); for (int j = 0; j < count; ++j) { if (mScores[j] < 1) break; final int start = j * MAX_WORD_LENGTH; @@ -159,13 +152,10 @@ public class BinaryDictionary extends Dictionary { ++len; } if (len > 0) { - // TODO: actually get the kind from native code - suggestions.add(new SuggestedWordInfo( - new String(mOutputChars, start, len), - mScores[j], SuggestedWordInfo.KIND_CORRECTION, mDictType)); + callback.addWord(mOutputChars, start, len, mScores[j], mDicTypeId, + Dictionary.UNIGRAM); } } - return suggestions; } /* package for test */ boolean isValidDictionary() { @@ -175,7 +165,7 @@ public class BinaryDictionary extends Dictionary { // proximityInfo may not be null. /* package for test */ int getSuggestions(final WordComposer codes, final CharSequence prevWordForBigrams, final ProximityInfo proximityInfo, - char[] outputChars, int[] scores, int[] spaceIndices) { + char[] outputChars, int[] scores) { if (!isValidDictionary()) return -1; final int codesSize = codes.size(); @@ -189,22 +179,14 @@ public class BinaryDictionary extends Dictionary { Arrays.fill(outputChars, (char) 0); Arrays.fill(scores, 0); - // TODO: toLowerCase in the native code - final int[] prevWordCodePointArray = (null == prevWordForBigrams) + final int[] prevWordCodePointArray = null == prevWordForBigrams ? null : StringUtils.toCodePointArray(prevWordForBigrams.toString()); - int[] emptyArray = new int[codesSize]; - Arrays.fill(emptyArray, 0); - - //final int commitPoint = codes.getCommitPoint(); - //codes.clearCommitPoint(); - - final InputPointers ips = codes.getInputPointers(); - - return getSuggestionsNative(mNativeDict, proximityInfo.getNativeProximityInfo(), - ips.getXCoordinates(), ips.getYCoordinates(), ips.getTimes(), ips.getPointerIds(), - mInputCodes, codesSize, 0 /* unused */, false, prevWordCodePointArray, - mUseFullEditDistance, outputChars, scores, spaceIndices); + // TODO: pass the previous word to native code + return getSuggestionsNative( + mNativeDict, proximityInfo.getNativeProximityInfo(), + codes.getXCoordinates(), codes.getYCoordinates(), mInputCodes, codesSize, + prevWordCodePointArray, mUseFullEditDistance, outputChars, scores); } public static float calcNormalizedScore(String before, String after, int score) { diff --git a/java/src/com/android/inputmethod/latin/BoundedTreeSet.java b/java/src/com/android/inputmethod/latin/BoundedTreeSet.java deleted file mode 100644 index cf977617d..000000000 --- a/java/src/com/android/inputmethod/latin/BoundedTreeSet.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ - -package com.android.inputmethod.latin; - -import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; - -import java.util.Collection; -import java.util.Comparator; -import java.util.TreeSet; - -/** - * A TreeSet that is bounded in size and throws everything that's smaller than its limit - */ -public class BoundedTreeSet extends TreeSet<SuggestedWordInfo> { - private final int mCapacity; - public BoundedTreeSet(final Comparator<SuggestedWordInfo> comparator, final int capacity) { - super(comparator); - mCapacity = capacity; - } - - @Override - public boolean add(final SuggestedWordInfo e) { - if (size() < mCapacity) return super.add(e); - if (comparator().compare(e, last()) > 0) return false; - super.add(e); - pollLast(); // removes the last element - return true; - } - - @Override - public boolean addAll(final Collection<? extends SuggestedWordInfo> e) { - if (null == e) return false; - return super.addAll(e); - } -} diff --git a/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java index 5edc4314f..10e511eaf 100644 --- a/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java @@ -62,8 +62,8 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary { */ private final boolean mUseFirstLastBigrams; - public ContactsBinaryDictionary(final Context context, Locale locale) { - super(context, getFilenameWithLocale(NAME, locale.toString()), Dictionary.TYPE_CONTACTS); + public ContactsBinaryDictionary(final Context context, final int dicTypeId, Locale locale) { + super(context, getFilenameWithLocale(NAME, locale.toString()), dicTypeId); mLocale = locale; mUseFirstLastBigrams = useFirstLastBigramsForLocale(locale); registerObserver(context); @@ -120,6 +120,12 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary { } } + @Override + public void getBigrams(final WordComposer codes, final CharSequence previousWord, + final WordCallback callback) { + super.getBigrams(codes, previousWord, callback); + } + private boolean useFirstLastBigramsForLocale(Locale locale) { // TODO: Add firstname/lastname bigram rules for other languages. if (locale != null && locale.getLanguage().equals(Locale.ENGLISH.getLanguage())) { @@ -161,7 +167,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary { * bigrams depending on locale. */ private void addName(String name) { - int len = StringUtils.codePointCount(name); + int len = name.codePointCount(0, name.length()); String prevWord = null; // TODO: Better tokenization for non-Latin writing systems for (int i = 0; i < len; i++) { @@ -171,7 +177,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary { i = end - 1; // Don't add single letter words, possibly confuses // capitalization of i. - final int wordLen = StringUtils.codePointCount(word); + final int wordLen = word.codePointCount(0, word.length()); if (wordLen < MAX_WORD_LENGTH && wordLen > 1) { super.addWord(word, null /* shortcut */, FREQUENCY_FOR_CONTACTS); if (!TextUtils.isEmpty(prevWord)) { @@ -260,14 +266,14 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary { * Checks if the words in a name are in the current binary dictionary. */ private boolean isNameInDictionary(String name) { - int len = StringUtils.codePointCount(name); + int len = name.codePointCount(0, name.length()); String prevWord = null; for (int i = 0; i < len; i++) { if (Character.isLetter(name.codePointAt(i))) { int end = getWordEndPosition(name, len, i); String word = name.substring(i, end); i = end - 1; - final int wordLen = StringUtils.codePointCount(word); + final int wordLen = word.codePointCount(0, word.length()); if (wordLen < MAX_WORD_LENGTH && wordLen > 1) { if (!TextUtils.isEmpty(prevWord) && mUseFirstLastBigrams) { if (!super.isValidBigramLocked(prevWord, word)) { diff --git a/java/src/com/android/inputmethod/latin/Dictionary.java b/java/src/com/android/inputmethod/latin/Dictionary.java index 0835450c1..9c3d46e70 100644 --- a/java/src/com/android/inputmethod/latin/Dictionary.java +++ b/java/src/com/android/inputmethod/latin/Dictionary.java @@ -17,9 +17,6 @@ package com.android.inputmethod.latin; import com.android.inputmethod.keyboard.ProximityInfo; -import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; - -import java.util.ArrayList; /** * Abstract base class for a dictionary that can do a fuzzy search for words based on a set of key @@ -31,43 +28,55 @@ public abstract class Dictionary { */ protected static final int FULL_WORD_SCORE_MULTIPLIER = 2; - public static final int NOT_A_PROBABILITY = -1; - - public static final String TYPE_USER_TYPED = "user_typed"; - public static final String TYPE_APPLICATION_DEFINED = "application_defined"; - public static final String TYPE_HARDCODED = "hardcoded"; // punctuation signs and such - public static final String TYPE_MAIN = "main"; - public static final String TYPE_CONTACTS = "contacts"; - // User dictionary, the system-managed one. - public static final String TYPE_USER = "user"; - // User history dictionary internal to LatinIME. - public static final String TYPE_USER_HISTORY = "history"; - public static final String TYPE_WHITELIST ="whitelist"; - protected final String mDictType; + public static final int UNIGRAM = 0; + public static final int BIGRAM = 1; - public Dictionary(final String dictType) { - mDictType = dictType; + public static final int NOT_A_PROBABILITY = -1; + /** + * Interface to be implemented by classes requesting words to be fetched from the dictionary. + * @see #getWords(WordComposer, CharSequence, WordCallback, ProximityInfo) + */ + public interface WordCallback { + /** + * Adds a word to a list of suggestions. The word is expected to be ordered based on + * the provided score. + * @param word the character array containing the word + * @param wordOffset starting offset of the word in the character array + * @param wordLength length of valid characters in the character array + * @param score the score of occurrence. This is normalized between 1 and 255, but + * can exceed those limits + * @param dicTypeId of the dictionary where word was from + * @param dataType tells type of this data, either UNIGRAM or BIGRAM + * @return true if the word was added, false if no more words are required + */ + boolean addWord(char[] word, int wordOffset, int wordLength, int score, int dicTypeId, + int dataType); } /** * Searches for words in the dictionary that match the characters in the composer. Matched - * words are returned as an ArrayList. - * @param composer the key sequence to match with coordinate info, as a WordComposer + * words are added through the callback object. + * @param composer the key sequence to match * @param prevWordForBigrams the previous word, or null if none + * @param callback the callback object to send matched words to as possible candidates * @param proximityInfo the object for key proximity. May be ignored by some implementations. - * @return the list of suggestions + * @see WordCallback#addWord(char[], int, int, int, int, int) */ - abstract public ArrayList<SuggestedWordInfo> getWords(final WordComposer composer, - final CharSequence prevWordForBigrams, final ProximityInfo proximityInfo); + abstract public void getWords(final WordComposer composer, + final CharSequence prevWordForBigrams, final WordCallback callback, + final ProximityInfo proximityInfo); /** - * Searches for pairs in the bigram dictionary that matches the previous word. + * Searches for pairs in the bigram dictionary that matches the previous word and all the + * possible words following are added through the callback object. * @param composer the key sequence to match * @param previousWord the word before - * @return the list of suggestions + * @param callback the callback object to send possible word following previous word */ - public abstract ArrayList<SuggestedWordInfo> getBigrams(final WordComposer composer, - final CharSequence previousWord); + public void getBigrams(final WordComposer composer, final CharSequence previousWord, + final WordCallback callback) { + // empty base implementation + } /** * Checks if the given word occurs in the dictionary diff --git a/java/src/com/android/inputmethod/latin/DictionaryCollection.java b/java/src/com/android/inputmethod/latin/DictionaryCollection.java index dcc53c59f..26c2e637e 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryCollection.java +++ b/java/src/com/android/inputmethod/latin/DictionaryCollection.java @@ -17,11 +17,9 @@ package com.android.inputmethod.latin; import com.android.inputmethod.keyboard.ProximityInfo; -import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import android.util.Log; -import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.concurrent.CopyOnWriteArrayList; @@ -33,13 +31,11 @@ public class DictionaryCollection extends Dictionary { private final String TAG = DictionaryCollection.class.getSimpleName(); protected final CopyOnWriteArrayList<Dictionary> mDictionaries; - public DictionaryCollection(final String dictType) { - super(dictType); + public DictionaryCollection() { mDictionaries = new CopyOnWriteArrayList<Dictionary>(); } - public DictionaryCollection(final String dictType, Dictionary... dictionaries) { - super(dictType); + public DictionaryCollection(Dictionary... dictionaries) { if (null == dictionaries) { mDictionaries = new CopyOnWriteArrayList<Dictionary>(); } else { @@ -48,48 +44,23 @@ public class DictionaryCollection extends Dictionary { } } - public DictionaryCollection(final String dictType, Collection<Dictionary> dictionaries) { - super(dictType); + public DictionaryCollection(Collection<Dictionary> dictionaries) { mDictionaries = new CopyOnWriteArrayList<Dictionary>(dictionaries); mDictionaries.removeAll(Collections.singleton(null)); } @Override - public ArrayList<SuggestedWordInfo> getWords(final WordComposer composer, - final CharSequence prevWordForBigrams, final ProximityInfo proximityInfo) { - final CopyOnWriteArrayList<Dictionary> dictionaries = mDictionaries; - if (dictionaries.isEmpty()) return null; - // To avoid creating unnecessary objects, we get the list out of the first - // dictionary and add the rest to it if not null, hence the get(0) - ArrayList<SuggestedWordInfo> suggestions = dictionaries.get(0).getWords(composer, - prevWordForBigrams, proximityInfo); - if (null == suggestions) suggestions = new ArrayList<SuggestedWordInfo>(); - final int length = dictionaries.size(); - for (int i = 0; i < length; ++ i) { - final ArrayList<SuggestedWordInfo> sugg = dictionaries.get(i).getWords(composer, - prevWordForBigrams, proximityInfo); - if (null != sugg) suggestions.addAll(sugg); - } - return suggestions; + public void getWords(final WordComposer composer, final CharSequence prevWordForBigrams, + final WordCallback callback, final ProximityInfo proximityInfo) { + for (final Dictionary dict : mDictionaries) + dict.getWords(composer, prevWordForBigrams, callback, proximityInfo); } @Override - public ArrayList<SuggestedWordInfo> getBigrams(final WordComposer composer, - final CharSequence previousWord) { - final CopyOnWriteArrayList<Dictionary> dictionaries = mDictionaries; - if (dictionaries.isEmpty()) return null; - // To avoid creating unnecessary objects, we get the list out of the first - // dictionary and add the rest to it if not null, hence the get(0) - ArrayList<SuggestedWordInfo> suggestions = dictionaries.get(0).getBigrams(composer, - previousWord); - if (null == suggestions) suggestions = new ArrayList<SuggestedWordInfo>(); - final int length = dictionaries.size(); - for (int i = 0; i < length; ++ i) { - final ArrayList<SuggestedWordInfo> sugg = - dictionaries.get(i).getBigrams(composer, previousWord); - if (null != sugg) suggestions.addAll(sugg); - } - return suggestions; + public void getBigrams(final WordComposer composer, final CharSequence previousWord, + final WordCallback callback) { + for (final Dictionary dict : mDictionaries) + dict.getBigrams(composer, previousWord, callback); } @Override diff --git a/java/src/com/android/inputmethod/latin/DictionaryFactory.java b/java/src/com/android/inputmethod/latin/DictionaryFactory.java index 06a5f4b72..a22d73af7 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryFactory.java +++ b/java/src/com/android/inputmethod/latin/DictionaryFactory.java @@ -49,8 +49,7 @@ public class DictionaryFactory { final Locale locale, final boolean useFullEditDistance) { if (null == locale) { Log.e(TAG, "No locale defined for dictionary"); - return new DictionaryCollection(Dictionary.TYPE_MAIN, - createBinaryDictionary(context, locale)); + return new DictionaryCollection(createBinaryDictionary(context, locale)); } final LinkedList<Dictionary> dictList = new LinkedList<Dictionary>(); @@ -60,7 +59,7 @@ public class DictionaryFactory { for (final AssetFileAddress f : assetFileList) { final BinaryDictionary binaryDictionary = new BinaryDictionary(context, f.mFilename, f.mOffset, f.mLength, - useFullEditDistance, locale, Dictionary.TYPE_MAIN); + useFullEditDistance, locale); if (binaryDictionary.isValidDictionary()) { dictList.add(binaryDictionary); } @@ -70,7 +69,7 @@ public class DictionaryFactory { // If the list is empty, that means we should not use any dictionary (for example, the user // explicitly disabled the main dictionary), so the following is okay. dictList is never // null, but if for some reason it is, DictionaryCollection handles it gracefully. - return new DictionaryCollection(Dictionary.TYPE_MAIN, dictList); + return new DictionaryCollection(dictList); } /** @@ -113,7 +112,7 @@ public class DictionaryFactory { return null; } return new BinaryDictionary(context, sourceDir, afd.getStartOffset(), afd.getLength(), - false /* useFullEditDistance */, locale, Dictionary.TYPE_MAIN); + false /* useFullEditDistance */, locale); } catch (android.content.res.Resources.NotFoundException e) { Log.e(TAG, "Could not find the resource"); return null; @@ -141,7 +140,7 @@ public class DictionaryFactory { long startOffset, long length, final boolean useFullEditDistance, Locale locale) { if (dictionary.isFile()) { return new BinaryDictionary(context, dictionary.getAbsolutePath(), startOffset, length, - useFullEditDistance, locale, Dictionary.TYPE_MAIN); + useFullEditDistance, locale); } else { Log.e(TAG, "Could not find the file. path=" + dictionary.getAbsolutePath()); return null; diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java index 1cda9f257..c65404cbc 100644 --- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java @@ -19,7 +19,6 @@ import android.os.SystemClock; import android.util.Log; import com.android.inputmethod.keyboard.ProximityInfo; -import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.makedict.BinaryDictInputOutput; import com.android.inputmethod.latin.makedict.FusionDictionary; import com.android.inputmethod.latin.makedict.FusionDictionary.Node; @@ -76,6 +75,9 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { /** The expandable fusion dictionary used to generate the binary dictionary. */ private FusionDictionary mFusionDictionary; + /** The dictionary type id. */ + public final int mDicTypeId; + /** * The name of this dictionary, used as the filename for storing the binary dictionary. Multiple * dictionary instances with the same filename is supported, with access controlled by @@ -121,11 +123,11 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { * @param context The application context of the parent. * @param filename The filename for this binary dictionary. Multiple dictionaries with the same * filename is supported. - * @param dictType the dictionary type, as a human-readable string + * @param dictType The type of this dictionary. */ public ExpandableBinaryDictionary( - final Context context, final String filename, final String dictType) { - super(dictType); + final Context context, final String filename, final int dictType) { + mDicTypeId = dictType; mFilename = filename; mContext = context; mBinaryDictionary = null; @@ -192,47 +194,46 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { } @Override - public ArrayList<SuggestedWordInfo> getWords(final WordComposer codes, - final CharSequence prevWordForBigrams, final ProximityInfo proximityInfo) { + public void getWords(final WordComposer codes, final CharSequence prevWordForBigrams, + final WordCallback callback, final ProximityInfo proximityInfo) { asyncReloadDictionaryIfRequired(); - return getWordsInner(codes, prevWordForBigrams, proximityInfo); + getWordsInner(codes, prevWordForBigrams, callback, proximityInfo); } - protected final ArrayList<SuggestedWordInfo> getWordsInner(final WordComposer codes, - final CharSequence prevWordForBigrams, final ProximityInfo proximityInfo) { + protected final void getWordsInner(final WordComposer codes, + final CharSequence prevWordForBigrams, final WordCallback callback, + final ProximityInfo proximityInfo) { // Ensure that there are no concurrent calls to getWords. If there are, do nothing and // return. if (mLocalDictionaryController.tryLock()) { try { if (mBinaryDictionary != null) { - return mBinaryDictionary.getWords(codes, prevWordForBigrams, proximityInfo); + mBinaryDictionary.getWords(codes, prevWordForBigrams, callback, proximityInfo); } } finally { mLocalDictionaryController.unlock(); } } - return null; } @Override - public ArrayList<SuggestedWordInfo> getBigrams(final WordComposer codes, - final CharSequence previousWord) { + public void getBigrams(final WordComposer codes, final CharSequence previousWord, + final WordCallback callback) { asyncReloadDictionaryIfRequired(); - return getBigramsInner(codes, previousWord); + getBigramsInner(codes, previousWord, callback); } - protected ArrayList<SuggestedWordInfo> getBigramsInner(final WordComposer codes, - final CharSequence previousWord) { + protected void getBigramsInner(final WordComposer codes, final CharSequence previousWord, + final WordCallback callback) { if (mLocalDictionaryController.tryLock()) { try { if (mBinaryDictionary != null) { - return mBinaryDictionary.getBigrams(codes, previousWord); + mBinaryDictionary.getBigrams(codes, previousWord, callback); } } finally { mLocalDictionaryController.unlock(); } } - return null; } @Override @@ -305,7 +306,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { // Build the new binary dictionary final BinaryDictionary newBinaryDictionary = new BinaryDictionary(mContext, filename, 0, length, true /* useFullEditDistance */, - null, mDictType); + null); if (mBinaryDictionary != null) { // Ensure all threads accessing the current dictionary have finished before swapping in diff --git a/java/src/com/android/inputmethod/latin/ExpandableDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java index 76213c0da..f5886aa12 100644 --- a/java/src/com/android/inputmethod/latin/ExpandableDictionary.java +++ b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java @@ -38,6 +38,7 @@ public class ExpandableDictionary extends Dictionary { private Context mContext; private char[] mWordBuilder = new char[BinaryDictionary.MAX_WORD_LENGTH]; + private int mDicTypeId; private int mMaxDepth; private int mInputLength; @@ -151,11 +152,11 @@ public class ExpandableDictionary extends Dictionary { private int[][] mCodes; - public ExpandableDictionary(final Context context, final String dictType) { - super(dictType); + public ExpandableDictionary(Context context, int dicTypeId) { mContext = context; clearDictionary(); mCodes = new int[BinaryDictionary.MAX_WORD_LENGTH][]; + mDicTypeId = dicTypeId; } public void loadDictionary() { @@ -247,20 +248,20 @@ public class ExpandableDictionary extends Dictionary { } @Override - public ArrayList<SuggestedWordInfo> getWords(final WordComposer codes, - final CharSequence prevWordForBigrams, final ProximityInfo proximityInfo) { + public void getWords(final WordComposer codes, final CharSequence prevWordForBigrams, + final WordCallback callback, final ProximityInfo proximityInfo) { synchronized (mUpdatingLock) { // If we need to update, start off a background task if (mRequiresReload) startDictionaryLoadingTaskLocked(); // Currently updating contacts, don't return any results. - if (mUpdatingDictionary) return null; + if (mUpdatingDictionary) return; } if (codes.size() >= BinaryDictionary.MAX_WORD_LENGTH) { - return null; + return; } final ArrayList<SuggestedWordInfo> suggestions = getWordsInner(codes, prevWordForBigrams, proximityInfo); - return suggestions; + Utils.addAllSuggestions(mDicTypeId, Dictionary.UNIGRAM, suggestions, callback); } protected final ArrayList<SuggestedWordInfo> getWordsInner(final WordComposer codes, @@ -268,9 +269,8 @@ public class ExpandableDictionary extends Dictionary { final ArrayList<SuggestedWordInfo> suggestions = new ArrayList<SuggestedWordInfo>(); mInputLength = codes.size(); if (mCodes.length < mInputLength) mCodes = new int[mInputLength][]; - final InputPointers ips = codes.getInputPointers(); - final int[] xCoordinates = ips.getXCoordinates(); - final int[] yCoordinates = ips.getYCoordinates(); + final int[] xCoordinates = codes.getXCoordinates(); + final int[] yCoordinates = codes.getYCoordinates(); // Cache the codes so that we don't have to lookup an array list for (int i = 0; i < mInputLength; i++) { // TODO: Calculate proximity info here. @@ -383,7 +383,7 @@ public class ExpandableDictionary extends Dictionary { // the respective size of the typed word and the suggestion if it matters sometime // in the future. suggestions.add(new SuggestedWordInfo(new String(word, 0, depth + 1), finalFreq, - SuggestedWordInfo.KIND_CORRECTION, mDictType)); + SuggestedWordInfo.KIND_CORRECTION)); if (suggestions.size() >= Suggest.MAX_SUGGESTIONS) return false; } if (null != node.mShortcutTargets) { @@ -391,7 +391,7 @@ public class ExpandableDictionary extends Dictionary { for (int shortcutIndex = 0; shortcutIndex < length; ++shortcutIndex) { final char[] shortcut = node.mShortcutTargets.get(shortcutIndex); suggestions.add(new SuggestedWordInfo(new String(shortcut, 0, shortcut.length), - finalFreq, SuggestedWordInfo.KIND_SHORTCUT, mDictType)); + finalFreq, SuggestedWordInfo.KIND_SHORTCUT)); if (suggestions.size() > Suggest.MAX_SUGGESTIONS) return false; } } @@ -600,25 +600,22 @@ public class ExpandableDictionary extends Dictionary { } private void runBigramReverseLookUp(final CharSequence previousWord, - final ArrayList<SuggestedWordInfo> suggestions) { + final WordCallback callback) { // Search for the lowercase version of the word only, because that's where bigrams // store their sons. Node prevWord = searchNode(mRoots, previousWord.toString().toLowerCase(), 0, previousWord.length()); if (prevWord != null && prevWord.mNGrams != null) { - reverseLookUp(prevWord.mNGrams, suggestions); + reverseLookUp(prevWord.mNGrams, callback); } } @Override - public ArrayList<SuggestedWordInfo> getBigrams(final WordComposer codes, - final CharSequence previousWord) { + public void getBigrams(final WordComposer codes, final CharSequence previousWord, + final WordCallback callback) { if (!reloadDictionaryIfRequired()) { - final ArrayList<SuggestedWordInfo> suggestions = new ArrayList<SuggestedWordInfo>(); - runBigramReverseLookUp(previousWord, suggestions); - return suggestions; + runBigramReverseLookUp(previousWord, callback); } - return null; } /** @@ -645,12 +642,11 @@ public class ExpandableDictionary extends Dictionary { /** * reverseLookUp retrieves the full word given a list of terminal nodes and adds those words - * to the suggestions list passed as an argument. + * through callback. * @param terminalNodes list of terminal nodes we want to add - * @param suggestions the suggestion collection to add the word to */ private void reverseLookUp(LinkedList<NextWord> terminalNodes, - final ArrayList<SuggestedWordInfo> suggestions) { + final WordCallback callback) { Node node; int freq; for (NextWord nextWord : terminalNodes) { @@ -664,9 +660,8 @@ public class ExpandableDictionary extends Dictionary { } while (node != null); if (freq >= 0) { - suggestions.add(new SuggestedWordInfo(new String(mLookedUpString, index, - BinaryDictionary.MAX_WORD_LENGTH - index), - freq, SuggestedWordInfo.KIND_CORRECTION, mDictType)); + callback.addWord(mLookedUpString, index, BinaryDictionary.MAX_WORD_LENGTH - index, + freq, mDicTypeId, Dictionary.BIGRAM); } } } diff --git a/java/src/com/android/inputmethod/latin/InputPointers.java b/java/src/com/android/inputmethod/latin/InputPointers.java deleted file mode 100644 index 218243e9f..000000000 --- a/java/src/com/android/inputmethod/latin/InputPointers.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ - -package com.android.inputmethod.latin; - -import java.util.Arrays; - -public class InputPointers { - private final ScalableIntArray mXCoordinates = new ScalableIntArray(); - private final ScalableIntArray mYCoordinates = new ScalableIntArray(); - private final ScalableIntArray mPointerIds = new ScalableIntArray(); - private final ScalableIntArray mTimes = new ScalableIntArray(); - - public void addPointer(int index, int x, int y, int pointerId, int time) { - mXCoordinates.add(index, x); - mYCoordinates.add(index, y); - mPointerIds.add(index, pointerId); - mTimes.add(index, time); - } - - public void addPointer(int x, int y, int pointerId, int time) { - mXCoordinates.add(x); - mYCoordinates.add(y); - mPointerIds.add(pointerId); - mTimes.add(time); - } - - public void set(InputPointers ip) { - mXCoordinates.set(ip.mXCoordinates); - mYCoordinates.set(ip.mYCoordinates); - mPointerIds.set(ip.mPointerIds); - mTimes.set(ip.mTimes); - } - - public void copy(InputPointers ip) { - mXCoordinates.copy(ip.mXCoordinates); - mYCoordinates.copy(ip.mYCoordinates); - mPointerIds.copy(ip.mPointerIds); - mTimes.copy(ip.mTimes); - } - - public void reset() { - mXCoordinates.reset(); - mYCoordinates.reset(); - mPointerIds.reset(); - mTimes.reset(); - } - - public int getPointerSize() { - return mXCoordinates.getLength(); - } - - public int[] getXCoordinates() { - return mXCoordinates.mArray; - } - - public int[] getYCoordinates() { - return mYCoordinates.mArray; - } - - public int[] getPointerIds() { - return mPointerIds.mArray; - } - - public int[] getTimes() { - return mTimes.mArray; - } - - private static class ScalableIntArray { - private static final int DEFAULT_SIZE = BinaryDictionary.MAX_WORD_LENGTH; - private int[] mArray; - private int mLength; - - public ScalableIntArray() { - reset(); - } - - public void add(int index, int val) { - if (mLength < index + 1) { - mLength = index; - add(val); - } else { - mArray[index] = val; - } - } - - public void add(int val) { - if (mLength >= mArray.length) { - final int[] newArray = new int[mLength * 2]; - System.arraycopy(mArray, 0, newArray, 0, mLength); - } - mArray[mLength] = val; - ++mLength; - } - - public int getLength() { - return mLength; - } - - public void reset() { - mArray = new int[DEFAULT_SIZE]; - mLength = 0; - } - - public int[] getPrimitiveArray() { - return mArray; - } - - public void copy(ScalableIntArray ip) { - mArray = Arrays.copyOf(ip.mArray, ip.mArray.length); - } - - public void set(ScalableIntArray ip) { - mArray = ip.mArray; - mLength = ip.mLength; - } - } -} diff --git a/java/src/com/android/inputmethod/latin/LastComposedWord.java b/java/src/com/android/inputmethod/latin/LastComposedWord.java index 318aecb50..4e1f5fe92 100644 --- a/java/src/com/android/inputmethod/latin/LastComposedWord.java +++ b/java/src/com/android/inputmethod/latin/LastComposedWord.java @@ -41,26 +41,26 @@ public class LastComposedWord { public static final int NOT_A_SEPARATOR = -1; public final int[] mPrimaryKeyCodes; + public final int[] mXCoordinates; + public final int[] mYCoordinates; public final String mTypedWord; public final String mCommittedWord; public final int mSeparatorCode; public final CharSequence mPrevWord; - public final InputPointers mInputPointers = new InputPointers(); private boolean mActive; public static final LastComposedWord NOT_A_COMPOSED_WORD = - new LastComposedWord(null, null, "", "", NOT_A_SEPARATOR, null); + new LastComposedWord(null, null, null, "", "", NOT_A_SEPARATOR, null); // Warning: this is using the passed objects as is and fully expects them to be // immutable. Do not fiddle with their contents after you passed them to this constructor. - public LastComposedWord(final int[] primaryKeyCodes, final InputPointers inputPointers, - final String typedWord, final String committedWord, + public LastComposedWord(final int[] primaryKeyCodes, final int[] xCoordinates, + final int[] yCoordinates, final String typedWord, final String committedWord, final int separatorCode, final CharSequence prevWord) { mPrimaryKeyCodes = primaryKeyCodes; - if (inputPointers != null) { - mInputPointers.copy(inputPointers); - } + mXCoordinates = xCoordinates; + mYCoordinates = yCoordinates; mTypedWord = typedWord; mCommittedWord = committedWord; mSeparatorCode = separatorCode; diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index d4362f79e..8a5fc495e 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -470,7 +470,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // Note that the calling sequence of onCreate() and onCurrentInputMethodSubtypeChanged() // is not guaranteed. It may even be called at the same time on a different thread. if (null == mPrefs) mPrefs = PreferenceManager.getDefaultSharedPreferences(this); - mUserHistoryDictionary = UserHistoryDictionary.getInstance(this, localeStr, mPrefs); + mUserHistoryDictionary = UserHistoryDictionary.getInstance( + this, localeStr, Suggest.DIC_USER_HISTORY, mPrefs); mSuggest.setUserHistoryDictionary(mUserHistoryDictionary); } @@ -498,7 +499,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // If the locale has changed then recreate the contacts dictionary. This // allows locale dependent rules for handling bigram name predictions. oldContactsDictionary.close(); - dictionaryToUse = new ContactsBinaryDictionary(this, locale); + dictionaryToUse = new ContactsBinaryDictionary( + this, Suggest.DIC_CONTACTS, locale); } else { // Make sure the old contacts dictionary is opened. If it is already open, // this is a no-op, so it's safe to call it anyways. @@ -506,7 +508,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen dictionaryToUse = oldContactsDictionary; } } else { - dictionaryToUse = new ContactsBinaryDictionary(this, locale); + dictionaryToUse = new ContactsBinaryDictionary(this, Suggest.DIC_CONTACTS, locale); } } @@ -887,6 +889,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen applicationSuggestedWords, false /* typedWordValid */, false /* hasAutoCorrectionCandidate */, + false /* allowsToBeAutoCorrected */, false /* isPunctuationSuggestions */, false /* isObsoleteSuggestions */, false /* isPrediction */); @@ -1684,9 +1687,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } public void updateSuggestions() { - mHandler.cancelUpdateSuggestions(); - mHandler.cancelUpdateBigramPredictions(); - // Check if we have a suggestion engine attached. if ((mSuggest == null || !mCurrentSettings.isSuggestionsRequested(mDisplayOrientation))) { if (mWordComposer.isComposingWord()) { @@ -1696,8 +1696,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen return; } + mHandler.cancelUpdateSuggestions(); + mHandler.cancelUpdateBigramPredictions(); + if (!mWordComposer.isComposingWord()) { - // This is dead code: we can't come here with an empty word composer. setPunctuationSuggestions(); return; } @@ -1708,7 +1710,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // getSuggestedWords handles gracefully a null value of prevWord final SuggestedWords suggestedWords = mSuggest.getSuggestedWords(mWordComposer, prevWord, mKeyboardSwitcher.getKeyboard().getProximityInfo(), - mCurrentSettings.mCorrectionEnabled, false); + mCurrentSettings.mCorrectionEnabled); // Basically, we update the suggestion strip only when suggestion count > 1. However, // there is an exception: We update the suggestion strip whenever typed word's length @@ -1717,7 +1719,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // need to clear the previous state when the user starts typing a word (i.e. typed word's // length == 1). if (suggestedWords.size() > 1 || typedWord.length() == 1 - || !suggestedWords.mTypedWordValid + || !suggestedWords.mAllowsToBeAutoCorrected || mSuggestionsView.isShowingAddToDictionaryHint()) { showSuggestions(suggestedWords, typedWord); } else { @@ -1732,6 +1734,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen new SuggestedWords(typedWordAndPreviousSuggestions, false /* typedWordValid */, false /* hasAutoCorrectionCandidate */, + false /* allowsToBeAutoCorrected */, false /* isPunctuationSuggestions */, true /* isObsoleteSuggestions */, false /* isPrediction */); @@ -1742,7 +1745,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen public void showSuggestions(final SuggestedWords suggestedWords, final CharSequence typedWord) { final CharSequence autoCorrection; if (suggestedWords.size() > 0) { - if (suggestedWords.mWillAutoCorrect) { + if (suggestedWords.hasAutoCorrectionWord()) { autoCorrection = suggestedWords.getWord(1); } else { autoCorrection = typedWord; @@ -1907,16 +1910,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } public void updateBigramPredictions() { - mHandler.cancelUpdateSuggestions(); - mHandler.cancelUpdateBigramPredictions(); - - if (mSuggest == null || !mCurrentSettings.isSuggestionsRequested(mDisplayOrientation)) { - if (mWordComposer.isComposingWord()) { - Log.w(TAG, "Called updateBigramPredictions but suggestions were not requested!"); - mWordComposer.setAutoCorrection(mWordComposer.getTypedWord()); - } + if (mSuggest == null || !mCurrentSettings.isSuggestionsRequested(mDisplayOrientation)) return; - } if (!mCurrentSettings.mBigramPredictionEnabled) { setPunctuationSuggestions(); @@ -1927,9 +1922,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen if (mCurrentSettings.mCorrectionEnabled) { final CharSequence prevWord = mConnection.getThisWord(mCurrentSettings.mWordSeparators); if (!TextUtils.isEmpty(prevWord)) { - suggestedWords = mSuggest.getSuggestedWords(mWordComposer, - prevWord, mKeyboardSwitcher.getKeyboard().getProximityInfo(), - mCurrentSettings.mCorrectionEnabled, true); + suggestedWords = mSuggest.getBigramPredictions(prevWord); } else { suggestedWords = null; } diff --git a/java/src/com/android/inputmethod/latin/LatinImeLogger.java b/java/src/com/android/inputmethod/latin/LatinImeLogger.java index e843848bc..dc0868e7c 100644 --- a/java/src/com/android/inputmethod/latin/LatinImeLogger.java +++ b/java/src/com/android/inputmethod/latin/LatinImeLogger.java @@ -71,7 +71,7 @@ public class LatinImeLogger implements SharedPreferences.OnSharedPreferenceChang public static void onStartSuggestion(CharSequence previousWords) { } - public static void onAddSuggestedWord(String word, String sourceDictionaryId) { + public static void onAddSuggestedWord(String word, int typeId, int dataType) { } public static void onSetKeyboard(Keyboard kb) { diff --git a/java/src/com/android/inputmethod/latin/ResearchLogger.java b/java/src/com/android/inputmethod/latin/ResearchLogger.java index e83d7c84a..cf3cc7873 100644 --- a/java/src/com/android/inputmethod/latin/ResearchLogger.java +++ b/java/src/com/android/inputmethod/latin/ResearchLogger.java @@ -197,7 +197,6 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang Log.d(TAG, "stop called"); if (mLoggingHandler != null && mLoggingState == LOGGING_STATE_ON) { mLoggingState = LOGGING_STATE_STOPPING; - flushEventQueue(true); // put this in the Handler queue so pending writes are processed first. mLoggingHandler.post(new Runnable() { @Override @@ -380,52 +379,11 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang mCurrentLogUnit.addLogAtom(keys, values, false); } - // Used to track how often words are logged. Too-frequent logging can leak - // semantics, disclosing private data. - /* package for test */ static class LoggingFrequencyState { - private static final int DEFAULT_WORD_LOG_FREQUENCY = 10; - private int mWordsRemainingToSkip; - private final int mFrequency; - - /** - * Tracks how often words may be uploaded. - * - * @param frequency 1=Every word, 2=Every other word, etc. - */ - public LoggingFrequencyState(int frequency) { - mFrequency = frequency; - mWordsRemainingToSkip = mFrequency; - } - - public void onWordLogged() { - mWordsRemainingToSkip = mFrequency; - } - - public void onWordNotLogged() { - if (mWordsRemainingToSkip > 1) { - mWordsRemainingToSkip--; - } - } - - public boolean isSafeToLog() { - return mWordsRemainingToSkip <= 1; - } - } - - /* package for test */ LoggingFrequencyState mLoggingFrequencyState = - new LoggingFrequencyState(LoggingFrequencyState.DEFAULT_WORD_LOG_FREQUENCY); - /* package for test */ boolean isPrivacyThreat(String word) { - // Current checks: - // - Word not in dictionary - // - Word contains numbers - // - Privacy-safe word not logged recently + // currently: word not in dictionary or contains numbers. if (TextUtils.isEmpty(word)) { return false; } - if (!mLoggingFrequencyState.isSafeToLog()) { - return true; - } final int length = word.length(); boolean hasLetter = false; for (int i = 0; i < length; i = word.offsetByCodePoints(i, 1)) { @@ -452,26 +410,15 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang return false; } - private void onWordComplete(String word) { - final boolean isPrivacyThreat = isPrivacyThreat(word); - flushEventQueue(isPrivacyThreat); - if (isPrivacyThreat) { - mLoggingFrequencyState.onWordNotLogged(); - } else { - mLoggingFrequencyState.onWordLogged(); - } - } - /** * Write out enqueued LogEvents to the log, possibly dropping privacy sensitive events. */ - /* package for test */ synchronized void flushEventQueue( - boolean removePotentiallyPrivateEvents) { + /* package for test */ synchronized void flushQueue(boolean removePotentiallyPrivateEvents) { if (isAllowedToLog()) { mCurrentLogUnit.setRemovePotentiallyPrivateEvents(removePotentiallyPrivateEvents); mLoggingHandler.post(mCurrentLogUnit); + mCurrentLogUnit = new LogUnit(); } - mCurrentLogUnit = new LogUnit(); } private synchronized void outputEvent(final String[] keys, final Object[] values) { @@ -532,9 +479,12 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang SuggestedWords words = (SuggestedWords) value; mJsonWriter.beginObject(); mJsonWriter.name("typedWordValid").value(words.mTypedWordValid); - mJsonWriter.name("willAutoCorrect").value(words.mWillAutoCorrect); + mJsonWriter.name("hasAutoCorrectionCandidate") + .value(words.mHasAutoCorrectionCandidate); mJsonWriter.name("isPunctuationSuggestions") .value(words.mIsPunctuationSuggestions); + mJsonWriter.name("allowsToBeAutoCorrected") + .value(words.mAllowsToBeAutoCorrected); mJsonWriter.name("isObsoleteSuggestions") .value(words.mIsObsoleteSuggestions); mJsonWriter.name("isPrediction") @@ -702,6 +652,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang final ResearchLogger researchLogger = getInstance(); researchLogger.enqueuePotentiallyPrivateEvent( EVENTKEYS_LATINIME_COMMITCURRENTAUTOCORRECTION, values); + researchLogger.flushQueue(researchLogger.isPrivacyThreat(autoCorrection)); } private static final String[] EVENTKEYS_LATINIME_COMMITTEXT = { @@ -714,7 +665,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang }; final ResearchLogger researchLogger = getInstance(); researchLogger.enqueuePotentiallyPrivateEvent(EVENTKEYS_LATINIME_COMMITTEXT, values); - researchLogger.onWordComplete(scrubbedWord); + researchLogger.flushQueue(researchLogger.isPrivacyThreat(scrubbedWord)); } private static final String[] EVENTKEYS_LATINIME_DELETESURROUNDINGTEXT = { @@ -792,7 +743,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang } final ResearchLogger researchLogger = getInstance(); researchLogger.enqueueEvent(EVENTKEYS_LATINIME_ONWINDOWHIDDEN, values); - researchLogger.flushEventQueue(true); // Play it safe. Remove privacy-sensitive events. + researchLogger.flushQueue(true); // Play it safe. Remove privacy-sensitive events. } } @@ -873,6 +824,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang final ResearchLogger researchLogger = getInstance(); researchLogger.enqueuePotentiallyPrivateEvent( EVENTKEYS_LATINIME_PICKAPPLICATIONSPECIFIEDCOMPLETION, values); + researchLogger.flushQueue(researchLogger.isPrivacyThreat(cs.toString())); } private static final String[] EVENTKEYS_LATINIME_PICKSUGGESTIONMANUALLY = { @@ -887,6 +839,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang final ResearchLogger researchLogger = getInstance(); researchLogger.enqueuePotentiallyPrivateEvent(EVENTKEYS_LATINIME_PICKSUGGESTIONMANUALLY, values); + researchLogger.flushQueue(researchLogger.isPrivacyThreat(suggestion.toString())); } private static final String[] EVENTKEYS_LATINIME_PUNCTUATIONSUGGESTION = { diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java index 40d327ebb..0c19bed05 100644 --- a/java/src/com/android/inputmethod/latin/RichInputConnection.java +++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java @@ -340,6 +340,13 @@ public class RichInputConnection { * Returns the word before the cursor if the cursor is at the end of a word, null otherwise */ public CharSequence getWordBeforeCursorIfAtEndOfWord(final SettingsValues settings) { + // Bail out if the cursor is not at the end of a word (cursor must be preceded by + // non-whitespace, non-separator, non-start-of-text) + // Example ("|" is the cursor here) : <SOL>"|a" " |a" " | " all get rejected here. + final CharSequence textBeforeCursor = getTextBeforeCursor(1, 0); + if (TextUtils.isEmpty(textBeforeCursor) + || settings.isWordSeparator(textBeforeCursor.charAt(0))) return null; + // Bail out if the cursor is in the middle of a word (cursor must be followed by whitespace, // separator or end of line/text) // Example: "test|"<EOL> "te|st" get rejected here @@ -356,15 +363,6 @@ public class RichInputConnection { word = word.subSequence(1, word.length()); } if (TextUtils.isEmpty(word)) return null; - // Find the last code point of the string - final int lastCodePoint = Character.codePointBefore(word, word.length()); - // If for some reason the text field contains non-unicode binary data, or if the - // charsequence is exactly one char long and the contents is a low surrogate, return null. - if (!Character.isDefined(lastCodePoint)) return null; - // Bail out if the cursor is not at the end of a word (cursor must be preceded by - // non-whitespace, non-separator, non-start-of-text) - // Example ("|" is the cursor here) : <SOL>"|a" " |a" " | " all get rejected here. - if (settings.isWordSeparator(lastCodePoint)) return null; final char firstChar = word.charAt(0); // we just tested that word is not empty if (word.length() == 1 && !Character.isLetter(firstChar)) return null; diff --git a/java/src/com/android/inputmethod/latin/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java index 4c89a6e91..4c67b4957 100644 --- a/java/src/com/android/inputmethod/latin/Settings.java +++ b/java/src/com/android/inputmethod/latin/Settings.java @@ -143,39 +143,19 @@ public class Settings extends InputMethodSettingsFragment generalSettings.removePreference(mVoicePreference); } - final PreferenceGroup advancedSettings = - (PreferenceGroup) findPreference(PREF_ADVANCED_SETTINGS); if (!VibratorUtils.getInstance(context).hasVibrator()) { + final PreferenceGroup advancedSettings = + (PreferenceGroup) findPreference(PREF_ADVANCED_SETTINGS); generalSettings.removePreference(findPreference(PREF_VIBRATE_ON)); if (null != advancedSettings) { // Theoretically advancedSettings cannot be null advancedSettings.removePreference(findPreference(PREF_VIBRATION_DURATION_SETTINGS)); } } - final boolean showKeyPreviewPopupOption = res.getBoolean( + final boolean showPopupOption = res.getBoolean( R.bool.config_enable_show_popup_on_keypress_option); - mKeyPreviewPopupDismissDelay = - (ListPreference) findPreference(PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY); - if (!showKeyPreviewPopupOption) { + if (!showPopupOption) { generalSettings.removePreference(findPreference(PREF_POPUP_ON)); - if (null != advancedSettings) { // Theoretically advancedSettings cannot be null - advancedSettings.removePreference(mKeyPreviewPopupDismissDelay); - } - } else { - final String[] entries = new String[] { - res.getString(R.string.key_preview_popup_dismiss_no_delay), - res.getString(R.string.key_preview_popup_dismiss_default_delay), - }; - final String popupDismissDelayDefaultValue = Integer.toString(res.getInteger( - R.integer.config_key_preview_linger_timeout)); - mKeyPreviewPopupDismissDelay.setEntries(entries); - mKeyPreviewPopupDismissDelay.setEntryValues( - new String[] { "0", popupDismissDelayDefaultValue }); - if (null == mKeyPreviewPopupDismissDelay.getValue()) { - mKeyPreviewPopupDismissDelay.setValue(popupDismissDelayDefaultValue); - } - mKeyPreviewPopupDismissDelay.setEnabled( - SettingsValues.isKeyPreviewPopupEnabled(prefs, res)); } final CheckBoxPreference includeOtherImesInLanguageSwitchList = @@ -183,6 +163,23 @@ public class Settings extends InputMethodSettingsFragment includeOtherImesInLanguageSwitchList.setEnabled( !SettingsValues.isLanguageSwitchKeySupressed(prefs)); + mKeyPreviewPopupDismissDelay = + (ListPreference)findPreference(PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY); + final String[] entries = new String[] { + res.getString(R.string.key_preview_popup_dismiss_no_delay), + res.getString(R.string.key_preview_popup_dismiss_default_delay), + }; + final String popupDismissDelayDefaultValue = Integer.toString(res.getInteger( + R.integer.config_key_preview_linger_timeout)); + mKeyPreviewPopupDismissDelay.setEntries(entries); + mKeyPreviewPopupDismissDelay.setEntryValues( + new String[] { "0", popupDismissDelayDefaultValue }); + if (null == mKeyPreviewPopupDismissDelay.getValue()) { + mKeyPreviewPopupDismissDelay.setValue(popupDismissDelayDefaultValue); + } + mKeyPreviewPopupDismissDelay.setEnabled( + SettingsValues.isKeyPreviewPopupEnabled(prefs, res)); + final PreferenceScreen dictionaryLink = (PreferenceScreen) findPreference(PREF_CONFIGURE_DICTIONARIES_KEY); final Intent intent = dictionaryLink.getIntent(); @@ -308,15 +305,13 @@ public class Settings extends InputMethodSettingsFragment private void updateKeyPreviewPopupDelaySummary() { final ListPreference lp = mKeyPreviewPopupDismissDelay; - final CharSequence[] entries = lp.getEntries(); - if (entries == null || entries.length <= 0) return; - lp.setSummary(entries[lp.findIndexOfValue(lp.getValue())]); + lp.setSummary(lp.getEntries()[lp.findIndexOfValue(lp.getValue())]); } private void updateVoiceModeSummary() { mVoicePreference.setSummary( getResources().getStringArray(R.array.voice_input_modes_summary) - [mVoicePreference.findIndexOfValue(mVoicePreference.getValue())]); + [mVoicePreference.findIndexOfValue(mVoicePreference.getValue())]); } private void refreshEnablingsOfKeypressSoundAndVibrationSettings( diff --git a/java/src/com/android/inputmethod/latin/SettingsValues.java b/java/src/com/android/inputmethod/latin/SettingsValues.java index aab84fccd..ef423f19b 100644 --- a/java/src/com/android/inputmethod/latin/SettingsValues.java +++ b/java/src/com/android/inputmethod/latin/SettingsValues.java @@ -179,13 +179,13 @@ public class SettingsValues { if (puncs != null) { for (final String puncSpec : puncs) { puncList.add(new SuggestedWordInfo(KeySpecParser.getLabel(puncSpec), - SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_HARDCODED, - Dictionary.TYPE_HARDCODED)); + SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_HARDCODED)); } } return new SuggestedWords(puncList, false /* typedWordValid */, false /* hasAutoCorrectionCandidate */, + false /* allowsToBeAutoCorrected */, true /* isPunctuationSuggestions */, false /* isObsoleteSuggestions */, false /* isPrediction */); diff --git a/java/src/com/android/inputmethod/latin/StringUtils.java b/java/src/com/android/inputmethod/latin/StringUtils.java index 6e7d985d6..a43b90525 100644 --- a/java/src/com/android/inputmethod/latin/StringUtils.java +++ b/java/src/com/android/inputmethod/latin/StringUtils.java @@ -184,9 +184,6 @@ public class StringUtils { final char[] characters = string.toCharArray(); final int length = characters.length; final int[] codePoints = new int[Character.codePointCount(characters, 0, length)]; - if (length <= 0) { - return new int[0]; - } int codePoint = Character.codePointAt(characters, 0); int dsti = 0; for (int srci = Character.charCount(codePoint); diff --git a/java/src/com/android/inputmethod/latin/SubtypeLocale.java b/java/src/com/android/inputmethod/latin/SubtypeLocale.java index acc17ef3f..ca293060a 100644 --- a/java/src/com/android/inputmethod/latin/SubtypeLocale.java +++ b/java/src/com/android/inputmethod/latin/SubtypeLocale.java @@ -60,10 +60,6 @@ public class SubtypeLocale { // Exceptional locales to display name map. private static final HashMap<String, String> sExceptionalDisplayNamesMap = new HashMap<String, String>(); - // Keyboard layout set name for the subtypes that don't have a keyboardLayoutSet extra value. - // This is for compatibility to keep the same subtype ids as pre-JellyBean. - private static final HashMap<String,String> sLocaleAndExtraValueToKeyboardLayoutSetMap = - new HashMap<String,String>(); private SubtypeLocale() { // Intentional empty constructor for utility class. @@ -101,14 +97,6 @@ public class SubtypeLocale { final int resId = res.getIdentifier(resourceName, null, RESOURCE_PACKAGE_NAME); sExceptionalLocaleToWithLayoutNameIdsMap.put(localeString, resId); } - - final String[] keyboardLayoutSetMap = res.getStringArray( - R.array.locale_and_extra_value_to_keyboard_layout_set_map); - for (int i = 0; i < keyboardLayoutSetMap.length; i += 2) { - final String key = keyboardLayoutSetMap[i]; - final String keyboardLayoutSet = keyboardLayoutSetMap[i + 1]; - sLocaleAndExtraValueToKeyboardLayoutSetMap.put(key, keyboardLayoutSet); - } } public static String[] getPredefinedKeyboardLayoutSet() { @@ -205,14 +193,7 @@ public class SubtypeLocale { } public static String getKeyboardLayoutSetName(InputMethodSubtype subtype) { - String keyboardLayoutSet = subtype.getExtraValueOf(KEYBOARD_LAYOUT_SET); - if (keyboardLayoutSet == null) { - // This subtype doesn't have a keyboardLayoutSet extra value, so lookup its keyboard - // layout set in sLocaleAndExtraValueToKeyboardLayoutSetMap to keep it compatible with - // pre-JellyBean. - final String key = subtype.getLocale() + ":" + subtype.getExtraValue(); - keyboardLayoutSet = sLocaleAndExtraValueToKeyboardLayoutSetMap.get(key); - } + final String keyboardLayoutSet = subtype.getExtraValueOf(KEYBOARD_LAYOUT_SET); // TODO: Remove this null check when InputMethodManager.getCurrentInputMethodSubtype is // fixed. if (keyboardLayoutSet == null) { diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java index dcfda86ea..892245402 100644 --- a/java/src/com/android/inputmethod/latin/Suggest.java +++ b/java/src/com/android/inputmethod/latin/Suggest.java @@ -18,6 +18,7 @@ package com.android.inputmethod.latin; import android.content.Context; import android.text.TextUtils; +import android.util.Log; import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.keyboard.ProximityInfo; @@ -25,7 +26,6 @@ import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import java.io.File; import java.util.ArrayList; -import java.util.Comparator; import java.util.HashSet; import java.util.Locale; import java.util.concurrent.ConcurrentHashMap; @@ -34,47 +34,80 @@ import java.util.concurrent.ConcurrentHashMap; * This class loads a dictionary and provides a list of suggestions for a given sequence of * characters. This includes corrections and completions. */ -public class Suggest { +public class Suggest implements Dictionary.WordCallback { public static final String TAG = Suggest.class.getSimpleName(); + public static final int APPROX_MAX_WORD_LENGTH = 32; + // TODO: rename this to CORRECTION_OFF public static final int CORRECTION_NONE = 0; // TODO: rename this to CORRECTION_ON public static final int CORRECTION_FULL = 1; + // It seems the following values are only used for logging. + public static final int DIC_USER_TYPED = 0; + public static final int DIC_MAIN = 1; + public static final int DIC_USER = 2; + public static final int DIC_USER_HISTORY = 3; + public static final int DIC_CONTACTS = 4; + public static final int DIC_WHITELIST = 6; + // If you add a type of dictionary, increment DIC_TYPE_LAST_ID + // TODO: this value seems unused. Remove it? + public static final int DIC_TYPE_LAST_ID = 6; + public static final String DICT_KEY_MAIN = "main"; + public static final String DICT_KEY_CONTACTS = "contacts"; + // User dictionary, the system-managed one. + public static final String DICT_KEY_USER = "user"; + // User history dictionary for the unigram map, internal to LatinIME + public static final String DICT_KEY_USER_HISTORY_UNIGRAM = "history_unigram"; + // User history dictionary for the bigram map, internal to LatinIME + public static final String DICT_KEY_USER_HISTORY_BIGRAM = "history_bigram"; + public static final String DICT_KEY_WHITELIST ="whitelist"; + private static final boolean DBG = LatinImeLogger.sDBG; private Dictionary mMainDictionary; private ContactsBinaryDictionary mContactsDict; private WhitelistDictionary mWhiteListDictionary; - private final ConcurrentHashMap<String, Dictionary> mDictionaries = + private final ConcurrentHashMap<String, Dictionary> mUnigramDictionaries = + new ConcurrentHashMap<String, Dictionary>(); + private final ConcurrentHashMap<String, Dictionary> mBigramDictionaries = new ConcurrentHashMap<String, Dictionary>(); public static final int MAX_SUGGESTIONS = 18; + private static final int PREF_MAX_BIGRAMS = 60; + private float mAutoCorrectionThreshold; - // Locale used for upper- and title-casing words - final private Locale mLocale; + private ArrayList<SuggestedWordInfo> mSuggestions = new ArrayList<SuggestedWordInfo>(); + private ArrayList<SuggestedWordInfo> mBigramSuggestions = new ArrayList<SuggestedWordInfo>(); + private CharSequence mConsideredWord; + + // TODO: Remove these member variables by passing more context to addWord() callback method + private boolean mIsFirstCharCapitalized; + private boolean mIsAllUpperCase; + private int mTrailingSingleQuotesCount; + + private static final int MINIMUM_SAFETY_NET_CHAR_LENGTH = 4; public Suggest(final Context context, final Locale locale) { initAsynchronously(context, locale); - mLocale = locale; } /* package for test */ Suggest(final Context context, final File dictionary, final long startOffset, final long length, final Locale locale) { final Dictionary mainDict = DictionaryFactory.createDictionaryForTest(context, dictionary, startOffset, length /* useFullEditDistance */, false, locale); - mLocale = locale; mMainDictionary = mainDict; - addOrReplaceDictionary(mDictionaries, Dictionary.TYPE_MAIN, mainDict); + addOrReplaceDictionary(mUnigramDictionaries, DICT_KEY_MAIN, mainDict); + addOrReplaceDictionary(mBigramDictionaries, DICT_KEY_MAIN, mainDict); initWhitelistAndAutocorrectAndPool(context, locale); } private void initWhitelistAndAutocorrectAndPool(final Context context, final Locale locale) { mWhiteListDictionary = new WhitelistDictionary(context, locale); - addOrReplaceDictionary(mDictionaries, Dictionary.TYPE_WHITELIST, mWhiteListDictionary); + addOrReplaceDictionary(mUnigramDictionaries, DICT_KEY_WHITELIST, mWhiteListDictionary); } private void initAsynchronously(final Context context, final Locale locale) { @@ -103,7 +136,8 @@ public class Suggest { public void run() { final DictionaryCollection newMainDict = DictionaryFactory.createMainDictionaryFromManager(context, locale); - addOrReplaceDictionary(mDictionaries, Dictionary.TYPE_MAIN, newMainDict); + addOrReplaceDictionary(mUnigramDictionaries, DICT_KEY_MAIN, newMainDict); + addOrReplaceDictionary(mBigramDictionaries, DICT_KEY_MAIN, newMainDict); mMainDictionary = newMainDict; } }.start(); @@ -124,7 +158,11 @@ public class Suggest { } public ConcurrentHashMap<String, Dictionary> getUnigramDictionaries() { - return mDictionaries; + return mUnigramDictionaries; + } + + public static int getApproxMaxWordLength() { + return APPROX_MAX_WORD_LENGTH; } /** @@ -132,7 +170,7 @@ public class Suggest { * before the main dictionary, if set. This refers to the system-managed user dictionary. */ public void setUserDictionary(UserBinaryDictionary userDictionary) { - addOrReplaceDictionary(mDictionaries, Dictionary.TYPE_USER, userDictionary); + addOrReplaceDictionary(mUnigramDictionaries, DICT_KEY_USER, userDictionary); } /** @@ -142,157 +180,235 @@ public class Suggest { */ public void setContactsDictionary(ContactsBinaryDictionary contactsDictionary) { mContactsDict = contactsDictionary; - addOrReplaceDictionary(mDictionaries, Dictionary.TYPE_CONTACTS, contactsDictionary); + addOrReplaceDictionary(mUnigramDictionaries, DICT_KEY_CONTACTS, contactsDictionary); + addOrReplaceDictionary(mBigramDictionaries, DICT_KEY_CONTACTS, contactsDictionary); } public void setUserHistoryDictionary(UserHistoryDictionary userHistoryDictionary) { - addOrReplaceDictionary(mDictionaries, Dictionary.TYPE_USER_HISTORY, userHistoryDictionary); + addOrReplaceDictionary(mUnigramDictionaries, DICT_KEY_USER_HISTORY_UNIGRAM, + userHistoryDictionary); + addOrReplaceDictionary(mBigramDictionaries, DICT_KEY_USER_HISTORY_BIGRAM, + userHistoryDictionary); } public void setAutoCorrectionThreshold(float threshold) { mAutoCorrectionThreshold = threshold; } + private static CharSequence capitalizeWord(final boolean all, final boolean first, + final CharSequence word) { + if (TextUtils.isEmpty(word) || !(all || first)) return word; + final int wordLength = word.length(); + final StringBuilder sb = new StringBuilder(getApproxMaxWordLength()); + // TODO: Must pay attention to locale when changing case. + if (all) { + sb.append(word.toString().toUpperCase()); + } else if (first) { + sb.append(Character.toUpperCase(word.charAt(0))); + if (wordLength > 1) { + sb.append(word.subSequence(1, wordLength)); + } + } + return sb; + } + + protected void addBigramToSuggestions(SuggestedWordInfo bigram) { + mSuggestions.add(bigram); + } + + private static final WordComposer sEmptyWordComposer = new WordComposer(); + public SuggestedWords getBigramPredictions(CharSequence prevWordForBigram) { + LatinImeLogger.onStartSuggestion(prevWordForBigram); + mIsFirstCharCapitalized = false; + mIsAllUpperCase = false; + mTrailingSingleQuotesCount = 0; + mSuggestions = new ArrayList<SuggestedWordInfo>(MAX_SUGGESTIONS); + + // Treating USER_TYPED as UNIGRAM suggestion for logging now. + LatinImeLogger.onAddSuggestedWord("", Suggest.DIC_USER_TYPED, Dictionary.UNIGRAM); + mConsideredWord = ""; + + mBigramSuggestions = new ArrayList<SuggestedWordInfo>(PREF_MAX_BIGRAMS); + + getAllBigrams(prevWordForBigram, sEmptyWordComposer); + + // Nothing entered: return all bigrams for the previous word + int insertCount = Math.min(mBigramSuggestions.size(), MAX_SUGGESTIONS); + for (int i = 0; i < insertCount; ++i) { + addBigramToSuggestions(mBigramSuggestions.get(i)); + } + + SuggestedWordInfo.removeDups(mSuggestions); + + return new SuggestedWords(mSuggestions, + false /* typedWordValid */, + false /* hasAutoCorrectionCandidate */, + false /* allowsToBeAutoCorrected */, + false /* isPunctuationSuggestions */, + false /* isObsoleteSuggestions */, + true /* isPrediction */); + } + // TODO: cleanup dictionaries looking up and suggestions building with SuggestedWords.Builder public SuggestedWords getSuggestedWords( final WordComposer wordComposer, CharSequence prevWordForBigram, - final ProximityInfo proximityInfo, final boolean isCorrectionEnabled, - // TODO: remove isPrediction parameter. It effectively means the same thing - // as wordComposer.size() <= 1 - final boolean isPrediction) { + final ProximityInfo proximityInfo, final boolean isCorrectionEnabled) { LatinImeLogger.onStartSuggestion(prevWordForBigram); - final boolean isFirstCharCapitalized = - !isPrediction && wordComposer.isFirstCharCapitalized(); - final boolean isAllUpperCase = !isPrediction && wordComposer.isAllUpperCase(); - final int trailingSingleQuotesCount = wordComposer.trailingSingleQuotesCount(); - final BoundedTreeSet suggestionsSet = new BoundedTreeSet(sSuggestedWordInfoComparator, - MAX_SUGGESTIONS); + mIsFirstCharCapitalized = wordComposer.isFirstCharCapitalized(); + mIsAllUpperCase = wordComposer.isAllUpperCase(); + mTrailingSingleQuotesCount = wordComposer.trailingSingleQuotesCount(); + mSuggestions = new ArrayList<SuggestedWordInfo>(MAX_SUGGESTIONS); final String typedWord = wordComposer.getTypedWord(); - final String consideredWord = trailingSingleQuotesCount > 0 - ? typedWord.substring(0, typedWord.length() - trailingSingleQuotesCount) + final String consideredWord = mTrailingSingleQuotesCount > 0 + ? typedWord.substring(0, typedWord.length() - mTrailingSingleQuotesCount) : typedWord; - LatinImeLogger.onAddSuggestedWord(typedWord, Dictionary.TYPE_USER_TYPED); + // Treating USER_TYPED as UNIGRAM suggestion for logging now. + LatinImeLogger.onAddSuggestedWord(typedWord, Suggest.DIC_USER_TYPED, Dictionary.UNIGRAM); + mConsideredWord = consideredWord; if (wordComposer.size() <= 1 && isCorrectionEnabled) { // At first character typed, search only the bigrams + mBigramSuggestions = new ArrayList<SuggestedWordInfo>(PREF_MAX_BIGRAMS); + if (!TextUtils.isEmpty(prevWordForBigram)) { - final CharSequence lowerPrevWord; - if (StringUtils.hasUpperCase(prevWordForBigram)) { - // TODO: Must pay attention to locale when changing case. - lowerPrevWord = prevWordForBigram.toString().toLowerCase(); + getAllBigrams(prevWordForBigram, wordComposer); + if (TextUtils.isEmpty(consideredWord)) { + // Nothing entered: return all bigrams for the previous word + int insertCount = Math.min(mBigramSuggestions.size(), MAX_SUGGESTIONS); + for (int i = 0; i < insertCount; ++i) { + addBigramToSuggestions(mBigramSuggestions.get(i)); + } } else { - lowerPrevWord = null; - } - for (final String key : mDictionaries.keySet()) { - final Dictionary dictionary = mDictionaries.get(key); - suggestionsSet.addAll(dictionary.getBigrams(wordComposer, prevWordForBigram)); - if (null != lowerPrevWord) { - suggestionsSet.addAll(dictionary.getBigrams(wordComposer, lowerPrevWord)); + // Word entered: return only bigrams that match the first char of the typed word + final char currentChar = consideredWord.charAt(0); + // TODO: Must pay attention to locale when changing case. + // TODO: Use codepoint instead of char + final char currentCharUpper = Character.toUpperCase(currentChar); + int count = 0; + final int bigramSuggestionSize = mBigramSuggestions.size(); + for (int i = 0; i < bigramSuggestionSize; i++) { + final SuggestedWordInfo bigramSuggestion = mBigramSuggestions.get(i); + final char bigramSuggestionFirstChar = + (char)bigramSuggestion.codePointAt(0); + if (bigramSuggestionFirstChar == currentChar + || bigramSuggestionFirstChar == currentCharUpper) { + addBigramToSuggestions(bigramSuggestion); + if (++count > MAX_SUGGESTIONS) break; + } } } } + } else if (wordComposer.size() > 1) { final WordComposer wordComposerForLookup; - if (trailingSingleQuotesCount > 0) { + if (mTrailingSingleQuotesCount > 0) { wordComposerForLookup = new WordComposer(wordComposer); - for (int i = trailingSingleQuotesCount - 1; i >= 0; --i) { + for (int i = mTrailingSingleQuotesCount - 1; i >= 0; --i) { wordComposerForLookup.deleteLast(); } } else { wordComposerForLookup = wordComposer; } // At second character typed, search the unigrams (scores being affected by bigrams) - for (final String key : mDictionaries.keySet()) { + for (final String key : mUnigramDictionaries.keySet()) { // Skip UserUnigramDictionary and WhitelistDictionary to lookup - if (key.equals(Dictionary.TYPE_USER_HISTORY) - || key.equals(Dictionary.TYPE_WHITELIST)) + if (key.equals(DICT_KEY_USER_HISTORY_UNIGRAM) || key.equals(DICT_KEY_WHITELIST)) continue; - final Dictionary dictionary = mDictionaries.get(key); - suggestionsSet.addAll(dictionary.getWords( - wordComposerForLookup, prevWordForBigram, proximityInfo)); + final Dictionary dictionary = mUnigramDictionaries.get(key); + dictionary.getWords(wordComposerForLookup, prevWordForBigram, this, proximityInfo); } } - // TODO: Change this scheme - a boolean is not enough. A whitelisted word may be "valid" - // but still autocorrected from - in the case the whitelist only capitalizes the word. - // The whitelist should be case-insensitive, so it's not possible to be consistent with - // a boolean flag. Right now this is handled with a slight hack in - // WhitelistDictionary#shouldForciblyAutoCorrectFrom. - final boolean allowsToBeAutoCorrected = AutoCorrection.isWhitelistedOrNotAWord( - mDictionaries, consideredWord, wordComposer.isFirstCharCapitalized()); - - final CharSequence whitelistedWord = - mWhiteListDictionary.getWhitelistedWord(consideredWord); + final CharSequence whitelistedWord = capitalizeWord(mIsAllUpperCase, + mIsFirstCharCapitalized, mWhiteListDictionary.getWhitelistedWord(consideredWord)); final boolean hasAutoCorrection; - if (!isCorrectionEnabled || !allowsToBeAutoCorrected || wordComposer.isMostlyCaps() - || wordComposer.isResumed() || !hasMainDictionary()) { - // If we don't have a main dictionary, we never want to auto-correct. The reason for - // this is, the user may have a contact whose name happens to match a valid word in - // their language, and it will unexpectedly auto-correct. For example, if the user - // types in English with no dictionary and has a "Will" in their contact list, "will" - // would always auto-correct to "Will" which is unwanted. Hence, no main dict => no - // auto-correct. - hasAutoCorrection = false; - } else if (null != whitelistedWord) { - hasAutoCorrection = true; - } else if (suggestionsSet.isEmpty()) { - hasAutoCorrection = false; - } else if (AutoCorrection.suggestionExceedsAutoCorrectionThreshold(suggestionsSet.first(), - consideredWord, mAutoCorrectionThreshold)) { - hasAutoCorrection = true; + if (isCorrectionEnabled) { + final CharSequence autoCorrection = + AutoCorrection.computeAutoCorrectionWord(mUnigramDictionaries, wordComposer, + mSuggestions, consideredWord, mAutoCorrectionThreshold, + whitelistedWord); + hasAutoCorrection = (null != autoCorrection); } else { hasAutoCorrection = false; } if (whitelistedWord != null) { - suggestionsSet.add(new SuggestedWordInfo(whitelistedWord, - SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_WHITELIST, - Dictionary.TYPE_WHITELIST)); - } - - final ArrayList<SuggestedWordInfo> suggestionsContainer = - new ArrayList<SuggestedWordInfo>(suggestionsSet); - final int suggestionsCount = suggestionsContainer.size(); - if (isFirstCharCapitalized || isAllUpperCase || 0 != trailingSingleQuotesCount) { - for (int i = 0; i < suggestionsCount; ++i) { - final SuggestedWordInfo wordInfo = suggestionsContainer.get(i); - final SuggestedWordInfo transformedWordInfo = getTransformedSuggestedWordInfo( - wordInfo, mLocale, isAllUpperCase, isFirstCharCapitalized, - trailingSingleQuotesCount); - suggestionsContainer.set(i, transformedWordInfo); + if (mTrailingSingleQuotesCount > 0) { + final StringBuilder sb = new StringBuilder(whitelistedWord); + for (int i = mTrailingSingleQuotesCount - 1; i >= 0; --i) { + sb.appendCodePoint(Keyboard.CODE_SINGLE_QUOTE); + } + mSuggestions.add(0, new SuggestedWordInfo(sb.toString(), + SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_WHITELIST)); + } else { + mSuggestions.add(0, new SuggestedWordInfo(whitelistedWord, + SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_WHITELIST)); } } - for (int i = 0; i < suggestionsCount; ++i) { - final SuggestedWordInfo wordInfo = suggestionsContainer.get(i); - LatinImeLogger.onAddSuggestedWord(wordInfo.mWord.toString(), wordInfo.mSourceDict); - } - - if (!TextUtils.isEmpty(typedWord)) { - suggestionsContainer.add(0, new SuggestedWordInfo(typedWord, - SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_TYPED, - Dictionary.TYPE_USER_TYPED)); - } - SuggestedWordInfo.removeDups(suggestionsContainer); + mSuggestions.add(0, new SuggestedWordInfo(typedWord, SuggestedWordInfo.MAX_SCORE, + SuggestedWordInfo.KIND_TYPED)); + SuggestedWordInfo.removeDups(mSuggestions); final ArrayList<SuggestedWordInfo> suggestionsList; - if (DBG && !suggestionsContainer.isEmpty()) { - suggestionsList = getSuggestionsInfoListWithDebugInfo(typedWord, suggestionsContainer); + if (DBG) { + suggestionsList = getSuggestionsInfoListWithDebugInfo(typedWord, mSuggestions); } else { - suggestionsList = suggestionsContainer; + suggestionsList = mSuggestions; } + // TODO: Change this scheme - a boolean is not enough. A whitelisted word may be "valid" + // but still autocorrected from - in the case the whitelist only capitalizes the word. + // The whitelist should be case-insensitive, so it's not possible to be consistent with + // a boolean flag. Right now this is handled with a slight hack in + // WhitelistDictionary#shouldForciblyAutoCorrectFrom. + final boolean allowsToBeAutoCorrected = AutoCorrection.allowsToBeAutoCorrected( + getUnigramDictionaries(), consideredWord, wordComposer.isFirstCharCapitalized()) + // If we don't have a main dictionary, we never want to auto-correct. The reason for this + // is, the user may have a contact whose name happens to match a valid word in their + // language, and it will unexpectedly auto-correct. For example, if the user types in + // English with no dictionary and has a "Will" in their contact list, "will" would + // always auto-correct to "Will" which is unwanted. Hence, no main dict => no auto-correct. + && hasMainDictionary(); + + boolean autoCorrectionAvailable = hasAutoCorrection; + if (isCorrectionEnabled) { + autoCorrectionAvailable |= !allowsToBeAutoCorrected; + } + // Don't auto-correct words with multiple capital letter + autoCorrectionAvailable &= !wordComposer.isMostlyCaps(); + autoCorrectionAvailable &= !wordComposer.isResumed(); + if (allowsToBeAutoCorrected && suggestionsList.size() > 1 && mAutoCorrectionThreshold > 0 + && Suggest.shouldBlockAutoCorrectionBySafetyNet(typedWord, + suggestionsList.get(1).mWord)) { + autoCorrectionAvailable = false; + } return new SuggestedWords(suggestionsList, - // TODO: this first argument is lying. If this is a whitelisted word which is an - // actual word, it says typedWordValid = false, which looks wrong. We should either - // rename the attribute or change the value. - !isPrediction && !allowsToBeAutoCorrected /* typedWordValid */, - !isPrediction && hasAutoCorrection, /* willAutoCorrect */ + !allowsToBeAutoCorrected /* typedWordValid */, + autoCorrectionAvailable /* hasAutoCorrectionCandidate */, + allowsToBeAutoCorrected /* allowsToBeAutoCorrected */, false /* isPunctuationSuggestions */, false /* isObsoleteSuggestions */, - isPrediction); + false /* isPrediction */); + } + + /** + * Adds all bigram predictions for prevWord. Also checks the lower case version of prevWord if + * it contains any upper case characters. + */ + private void getAllBigrams(final CharSequence prevWord, final WordComposer wordComposer) { + if (StringUtils.hasUpperCase(prevWord)) { + // TODO: Must pay attention to locale when changing case. + final CharSequence lowerPrevWord = prevWord.toString().toLowerCase(); + for (final Dictionary dictionary : mBigramDictionaries.values()) { + dictionary.getBigrams(wordComposer, lowerPrevWord, this); + } + } + for (final Dictionary dictionary : mBigramDictionaries.values()) { + dictionary.getBigrams(wordComposer, prevWord, this); + } } private static ArrayList<SuggestedWordInfo> getSuggestionsInfoListWithDebugInfo( @@ -321,44 +437,120 @@ public class Suggest { return suggestionsList; } - private static class SuggestedWordInfoComparator implements Comparator<SuggestedWordInfo> { - // This comparator ranks the word info with the higher frequency first. That's because - // that's the order we want our elements in. - @Override - public int compare(final SuggestedWordInfo o1, final SuggestedWordInfo o2) { - if (o1.mScore > o2.mScore) return -1; - if (o1.mScore < o2.mScore) return 1; - if (o1.mCodePointCount < o2.mCodePointCount) return -1; - if (o1.mCodePointCount > o2.mCodePointCount) return 1; - return o1.mWord.toString().compareTo(o2.mWord.toString()); + // TODO: Use codepoint instead of char + @Override + public boolean addWord(final char[] word, final int offset, final int length, int score, + final int dicTypeId, final int dataType) { + int dataTypeForLog = dataType; + final ArrayList<SuggestedWordInfo> suggestions; + final int prefMaxSuggestions; + if (dataType == Dictionary.BIGRAM) { + suggestions = mBigramSuggestions; + prefMaxSuggestions = PREF_MAX_BIGRAMS; + } else { + suggestions = mSuggestions; + prefMaxSuggestions = MAX_SUGGESTIONS; } - } - private static final SuggestedWordInfoComparator sSuggestedWordInfoComparator = - new SuggestedWordInfoComparator(); - - private static SuggestedWordInfo getTransformedSuggestedWordInfo( - final SuggestedWordInfo wordInfo, final Locale locale, final boolean isAllUpperCase, - final boolean isFirstCharCapitalized, final int trailingSingleQuotesCount) { - final StringBuilder sb = new StringBuilder(wordInfo.mWord.length()); - if (isAllUpperCase) { - sb.append(wordInfo.mWord.toString().toUpperCase(locale)); - } else if (isFirstCharCapitalized) { - sb.append(StringUtils.toTitleCase(wordInfo.mWord.toString(), locale)); + + int pos = 0; + + // Check if it's the same word, only caps are different + if (StringUtils.equalsIgnoreCase(mConsideredWord, word, offset, length)) { + // TODO: remove this surrounding if clause and move this logic to + // getSuggestedWordBuilder. + if (suggestions.size() > 0) { + final SuggestedWordInfo currentHighestWord = suggestions.get(0); + // If the current highest word is also equal to typed word, we need to compare + // frequency to determine the insertion position. This does not ensure strictly + // correct ordering, but ensures the top score is on top which is enough for + // removing duplicates correctly. + if (StringUtils.equalsIgnoreCase(currentHighestWord.mWord, word, offset, length) + && score <= currentHighestWord.mScore) { + pos = 1; + } + } + } else { + // Check the last one's score and bail + if (suggestions.size() >= prefMaxSuggestions + && suggestions.get(prefMaxSuggestions - 1).mScore >= score) return true; + while (pos < suggestions.size()) { + final int curScore = suggestions.get(pos).mScore; + if (curScore < score + || (curScore == score && length < suggestions.get(pos).codePointCount())) { + break; + } + pos++; + } + } + if (pos >= prefMaxSuggestions) { + return true; + } + + final StringBuilder sb = new StringBuilder(getApproxMaxWordLength()); + // TODO: Must pay attention to locale when changing case. + if (mIsAllUpperCase) { + sb.append(new String(word, offset, length).toUpperCase()); + } else if (mIsFirstCharCapitalized) { + sb.append(Character.toUpperCase(word[offset])); + if (length > 1) { + sb.append(word, offset + 1, length - 1); + } } else { - sb.append(wordInfo.mWord); + sb.append(word, offset, length); } - for (int i = trailingSingleQuotesCount - 1; i >= 0; --i) { + for (int i = mTrailingSingleQuotesCount - 1; i >= 0; --i) { sb.appendCodePoint(Keyboard.CODE_SINGLE_QUOTE); } - return new SuggestedWordInfo(sb, wordInfo.mScore, wordInfo.mKind, wordInfo.mSourceDict); + // TODO: figure out what type of suggestion this is + suggestions.add(pos, new SuggestedWordInfo(sb, score, SuggestedWordInfo.KIND_CORRECTION)); + if (suggestions.size() > prefMaxSuggestions) { + suggestions.remove(prefMaxSuggestions); + } else { + LatinImeLogger.onAddSuggestedWord(sb.toString(), dicTypeId, dataTypeForLog); + } + return true; } public void close() { final HashSet<Dictionary> dictionaries = new HashSet<Dictionary>(); - dictionaries.addAll(mDictionaries.values()); + dictionaries.addAll(mUnigramDictionaries.values()); + dictionaries.addAll(mBigramDictionaries.values()); for (final Dictionary dictionary : dictionaries) { dictionary.close(); } mMainDictionary = null; } + + // TODO: Resolve the inconsistencies between the native auto correction algorithms and + // this safety net + public static boolean shouldBlockAutoCorrectionBySafetyNet(final String typedWord, + final CharSequence suggestion) { + // Safety net for auto correction. + // Actually if we hit this safety net, it's a bug. + // If user selected aggressive auto correction mode, there is no need to use the safety + // net. + // If the length of typed word is less than MINIMUM_SAFETY_NET_CHAR_LENGTH, + // we should not use net because relatively edit distance can be big. + final int typedWordLength = typedWord.length(); + if (typedWordLength < Suggest.MINIMUM_SAFETY_NET_CHAR_LENGTH) { + return false; + } + final int maxEditDistanceOfNativeDictionary = + (typedWordLength < 5 ? 2 : typedWordLength / 2) + 1; + final int distance = BinaryDictionary.editDistance(typedWord, suggestion.toString()); + if (DBG) { + Log.d(TAG, "Autocorrected edit distance = " + distance + + ", " + maxEditDistanceOfNativeDictionary); + } + if (distance > maxEditDistanceOfNativeDictionary) { + if (DBG) { + Log.e(TAG, "Safety net: before = " + typedWord + ", after = " + suggestion); + Log.e(TAG, "(Error) The edit distance of this correction exceeds limit. " + + "Turning off auto-correction."); + } + return true; + } else { + return false; + } + } } diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java index 94af301a2..45ac9ff53 100644 --- a/java/src/com/android/inputmethod/latin/SuggestedWords.java +++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java @@ -25,27 +25,27 @@ import java.util.HashSet; public class SuggestedWords { public static final SuggestedWords EMPTY = new SuggestedWords( - new ArrayList<SuggestedWordInfo>(0), false, false, false, false, false); + new ArrayList<SuggestedWordInfo>(0), false, false, false, false, false, false); public final boolean mTypedWordValid; - // Note: this INCLUDES cases where the word will auto-correct to itself. A good definition - // of what this flag means would be "the top suggestion is strong enough to auto-correct", - // whether this exactly matches the user entry or not. - public final boolean mWillAutoCorrect; + public final boolean mHasAutoCorrectionCandidate; public final boolean mIsPunctuationSuggestions; + public final boolean mAllowsToBeAutoCorrected; public final boolean mIsObsoleteSuggestions; public final boolean mIsPrediction; private final ArrayList<SuggestedWordInfo> mSuggestedWordInfoList; public SuggestedWords(final ArrayList<SuggestedWordInfo> suggestedWordInfoList, final boolean typedWordValid, - final boolean willAutoCorrect, + final boolean hasAutoCorrectionCandidate, + final boolean allowsToBeAutoCorrected, final boolean isPunctuationSuggestions, final boolean isObsoleteSuggestions, final boolean isPrediction) { mSuggestedWordInfoList = suggestedWordInfoList; mTypedWordValid = typedWordValid; - mWillAutoCorrect = willAutoCorrect; + mHasAutoCorrectionCandidate = hasAutoCorrectionCandidate; + mAllowsToBeAutoCorrected = allowsToBeAutoCorrected; mIsPunctuationSuggestions = isPunctuationSuggestions; mIsObsoleteSuggestions = isObsoleteSuggestions; mIsPrediction = isPrediction; @@ -67,8 +67,12 @@ public class SuggestedWords { return mSuggestedWordInfoList.get(pos); } + public boolean hasAutoCorrectionWord() { + return mHasAutoCorrectionCandidate && size() > 1 && !mTypedWordValid; + } + public boolean willAutoCorrect() { - return mWillAutoCorrect; + return !mTypedWordValid && mHasAutoCorrectionCandidate; } @Override @@ -76,7 +80,8 @@ public class SuggestedWords { // Pretty-print method to help debug return "SuggestedWords:" + " mTypedWordValid=" + mTypedWordValid - + " mWillAutoCorrect=" + mWillAutoCorrect + + " mHasAutoCorrectionCandidate=" + mHasAutoCorrectionCandidate + + " mAllowsToBeAutoCorrected=" + mAllowsToBeAutoCorrected + " mIsPunctuationSuggestions=" + mIsPunctuationSuggestions + " words=" + Arrays.toString(mSuggestedWordInfoList.toArray()); } @@ -87,7 +92,7 @@ public class SuggestedWords { for (CompletionInfo info : infos) { if (null != info && info.getText() != null) { result.add(new SuggestedWordInfo(info.getText(), SuggestedWordInfo.MAX_SCORE, - SuggestedWordInfo.KIND_APP_DEFINED, Dictionary.TYPE_APPLICATION_DEFINED)); + SuggestedWordInfo.KIND_APP_DEFINED)); } } return result; @@ -100,7 +105,7 @@ public class SuggestedWords { final ArrayList<SuggestedWordInfo> suggestionsList = new ArrayList<SuggestedWordInfo>(); final HashSet<String> alreadySeen = new HashSet<String>(); suggestionsList.add(new SuggestedWordInfo(typedWord, SuggestedWordInfo.MAX_SCORE, - SuggestedWordInfo.KIND_TYPED, Dictionary.TYPE_USER_TYPED)); + SuggestedWordInfo.KIND_TYPED)); alreadySeen.add(typedWord.toString()); final int previousSize = previousSuggestions.size(); for (int pos = 1; pos < previousSize; pos++) { @@ -130,17 +135,14 @@ public class SuggestedWords { public final int mScore; public final int mKind; // one of the KIND_* constants above public final int mCodePointCount; - public final String mSourceDict; private String mDebugString = ""; - public SuggestedWordInfo(final CharSequence word, final int score, final int kind, - final String sourceDict) { + public SuggestedWordInfo(final CharSequence word, final int score, final int kind) { mWordStr = word.toString(); mWord = word; mScore = score; mKind = kind; - mSourceDict = sourceDict; - mCodePointCount = StringUtils.codePointCount(mWordStr); + mCodePointCount = mWordStr.codePointCount(0, mWordStr.length()); } diff --git a/java/src/com/android/inputmethod/latin/SynchronouslyLoadedContactsBinaryDictionary.java b/java/src/com/android/inputmethod/latin/SynchronouslyLoadedContactsBinaryDictionary.java index 9b20bd690..673b54500 100644 --- a/java/src/com/android/inputmethod/latin/SynchronouslyLoadedContactsBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/SynchronouslyLoadedContactsBinaryDictionary.java @@ -19,23 +19,22 @@ package com.android.inputmethod.latin; import android.content.Context; import com.android.inputmethod.keyboard.ProximityInfo; -import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; -import java.util.ArrayList; import java.util.Locale; public class SynchronouslyLoadedContactsBinaryDictionary extends ContactsBinaryDictionary { private boolean mClosed; public SynchronouslyLoadedContactsBinaryDictionary(final Context context, final Locale locale) { - super(context, locale); + super(context, Suggest.DIC_CONTACTS, locale); } @Override - public synchronized ArrayList<SuggestedWordInfo> getWords(final WordComposer codes, - final CharSequence prevWordForBigrams, final ProximityInfo proximityInfo) { + public synchronized void getWords(final WordComposer codes, + final CharSequence prevWordForBigrams, final WordCallback callback, + final ProximityInfo proximityInfo) { syncReloadDictionaryIfRequired(); - return getWordsInner(codes, prevWordForBigrams, proximityInfo); + getWordsInner(codes, prevWordForBigrams, callback, proximityInfo); } @Override diff --git a/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserBinaryDictionary.java b/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserBinaryDictionary.java index 5b2a6edec..1606a34e0 100644 --- a/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserBinaryDictionary.java @@ -19,9 +19,6 @@ package com.android.inputmethod.latin; import android.content.Context; import com.android.inputmethod.keyboard.ProximityInfo; -import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; - -import java.util.ArrayList; public class SynchronouslyLoadedUserBinaryDictionary extends UserBinaryDictionary { @@ -35,10 +32,11 @@ public class SynchronouslyLoadedUserBinaryDictionary extends UserBinaryDictionar } @Override - public synchronized ArrayList<SuggestedWordInfo> getWords(final WordComposer codes, - final CharSequence prevWordForBigrams, final ProximityInfo proximityInfo) { + public synchronized void getWords(final WordComposer codes, + final CharSequence prevWordForBigrams, final WordCallback callback, + final ProximityInfo proximityInfo) { syncReloadDictionaryIfRequired(); - return getWordsInner(codes, prevWordForBigrams, proximityInfo); + getWordsInner(codes, prevWordForBigrams, callback, proximityInfo); } @Override diff --git a/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java b/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java index 60e6fa127..5bcdb57b5 100644 --- a/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java @@ -34,10 +34,7 @@ import java.util.Arrays; */ public class UserBinaryDictionary extends ExpandableBinaryDictionary { - // The user dictionary provider uses an empty string to mean "all languages". - private static final String USER_DICTIONARY_ALL_LANGUAGES = ""; - - // TODO: use Words.SHORTCUT when we target JellyBean or above + // TODO: use Words.SHORTCUT when it's public in the SDK final static String SHORTCUT = "shortcut"; private static final String[] PROJECTION_QUERY; static { @@ -72,14 +69,9 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary { public UserBinaryDictionary(final Context context, final String locale, final boolean alsoUseMoreRestrictiveLocales) { - super(context, getFilenameWithLocale(NAME, locale), Dictionary.TYPE_USER); + super(context, getFilenameWithLocale(NAME, locale), Suggest.DIC_USER); if (null == locale) throw new NullPointerException(); // Catch the error earlier - if (SubtypeLocale.NO_LANGUAGE.equals(locale)) { - // If we don't have a locale, insert into the "all locales" user dictionary. - mLocale = USER_DICTIONARY_ALL_LANGUAGES; - } else { - mLocale = locale; - } + mLocale = locale; mAlsoUseMoreRestrictiveLocales = alsoUseMoreRestrictiveLocales; // Perform a managed query. The Activity will handle closing and re-querying the cursor // when needed. diff --git a/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java b/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java index 73fa83f9a..5095f6582 100644 --- a/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java +++ b/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java @@ -115,7 +115,8 @@ public class UserHistoryDictionary extends ExpandableDictionary { } public synchronized static UserHistoryDictionary getInstance( - final Context context, final String locale, final SharedPreferences sp) { + final Context context, final String locale, + final int dictTypeId, final SharedPreferences sp) { if (sLangDictCache.containsKey(locale)) { final SoftReference<UserHistoryDictionary> ref = sLangDictCache.get(locale); final UserHistoryDictionary dict = ref == null ? null : ref.get(); @@ -127,14 +128,14 @@ public class UserHistoryDictionary extends ExpandableDictionary { } } final UserHistoryDictionary dict = - new UserHistoryDictionary(context, locale, sp); + new UserHistoryDictionary(context, locale, dictTypeId, sp); sLangDictCache.put(locale, new SoftReference<UserHistoryDictionary>(dict)); return dict; } - private UserHistoryDictionary(final Context context, final String locale, - final SharedPreferences sp) { - super(context, Dictionary.TYPE_USER_HISTORY); + private UserHistoryDictionary(final Context context, final String locale, final int dicTypeId, + SharedPreferences sp) { + super(context, dicTypeId); mLocale = locale; mPrefs = sp; if (sOpenHelper == null) { diff --git a/java/src/com/android/inputmethod/latin/Utils.java b/java/src/com/android/inputmethod/latin/Utils.java index 8f71de0e7..a44b1f9ad 100644 --- a/java/src/com/android/inputmethod/latin/Utils.java +++ b/java/src/com/android/inputmethod/latin/Utils.java @@ -531,4 +531,14 @@ public class Utils { } return builder.toString(); } + + public static void addAllSuggestions(final int dicTypeId, final int dataType, + final ArrayList<SuggestedWords.SuggestedWordInfo> suggestions, + final Dictionary.WordCallback callback) { + for (SuggestedWordInfo suggestion : suggestions) { + final String suggestionStr = suggestion.mWord.toString(); + callback.addWord(suggestionStr.toCharArray(), 0, suggestionStr.length(), + suggestion.mScore, dicTypeId, dataType); + } + } } diff --git a/java/src/com/android/inputmethod/latin/WhitelistDictionary.java b/java/src/com/android/inputmethod/latin/WhitelistDictionary.java index 3af22140e..a0de2f970 100644 --- a/java/src/com/android/inputmethod/latin/WhitelistDictionary.java +++ b/java/src/com/android/inputmethod/latin/WhitelistDictionary.java @@ -37,7 +37,7 @@ public class WhitelistDictionary extends ExpandableDictionary { // TODO: Conform to the async load contact of ExpandableDictionary public WhitelistDictionary(final Context context, final Locale locale) { - super(context, Dictionary.TYPE_WHITELIST); + super(context, Suggest.DIC_WHITELIST); // TODO: Move whitelist dictionary into main dictionary. final RunInLocale<Void> job = new RunInLocale<Void>() { @Override diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java index 98282f970..ca9caa1d3 100644 --- a/java/src/com/android/inputmethod/latin/WordComposer.java +++ b/java/src/com/android/inputmethod/latin/WordComposer.java @@ -34,7 +34,8 @@ public class WordComposer { private static final int N = BinaryDictionary.MAX_WORD_LENGTH; private int[] mPrimaryKeyCodes; - private final InputPointers mInputPointers = new InputPointers(); + private int[] mXCoordinates; + private int[] mYCoordinates; private StringBuilder mTypedWord; private CharSequence mAutoCorrection; private boolean mIsResumed; @@ -53,6 +54,8 @@ public class WordComposer { public WordComposer() { mPrimaryKeyCodes = new int[N]; mTypedWord = new StringBuilder(N); + mXCoordinates = new int[N]; + mYCoordinates = new int[N]; mAutoCorrection = null; mTrailingSingleQuotesCount = 0; mIsResumed = false; @@ -66,7 +69,8 @@ public class WordComposer { public void init(WordComposer source) { mPrimaryKeyCodes = Arrays.copyOf(source.mPrimaryKeyCodes, source.mPrimaryKeyCodes.length); mTypedWord = new StringBuilder(source.mTypedWord); - mInputPointers.copy(source.mInputPointers); + mXCoordinates = Arrays.copyOf(source.mXCoordinates, source.mXCoordinates.length); + mYCoordinates = Arrays.copyOf(source.mYCoordinates, source.mYCoordinates.length); mCapsCount = source.mCapsCount; mIsFirstCharCapitalized = source.mIsFirstCharCapitalized; mAutoCapitalized = source.mAutoCapitalized; @@ -88,7 +92,7 @@ public class WordComposer { refreshSize(); } - private final void refreshSize() { + public final void refreshSize() { mCodePointSize = mTypedWord.codePointCount(0, mTypedWord.length()); } @@ -112,8 +116,12 @@ public class WordComposer { return mPrimaryKeyCodes[index]; } - public InputPointers getInputPointers() { - return mInputPointers; + public int[] getXCoordinates() { + return mXCoordinates; + } + + public int[] getYCoordinates() { + return mYCoordinates; } private static boolean isFirstCharCapitalized(int index, int codePoint, boolean previous) { @@ -149,8 +157,8 @@ public class WordComposer { if (newIndex < BinaryDictionary.MAX_WORD_LENGTH) { mPrimaryKeyCodes[newIndex] = primaryCode >= Keyboard.CODE_SPACE ? Character.toLowerCase(primaryCode) : primaryCode; - // TODO: Set correct pointer id and time - mInputPointers.addPointer(newIndex, keyX, keyY, 0, 0); + mXCoordinates[newIndex] = keyX; + mYCoordinates[newIndex] = keyY; } mIsFirstCharCapitalized = isFirstCharCapitalized( newIndex, primaryCode, mIsFirstCharCapitalized); @@ -310,11 +318,14 @@ public class WordComposer { // or a DECIDED_WORD we may cancel the commit later; otherwise, we should deactivate // the last composed word to ensure this does not happen. final int[] primaryKeyCodes = mPrimaryKeyCodes; + final int[] xCoordinates = mXCoordinates; + final int[] yCoordinates = mYCoordinates; mPrimaryKeyCodes = new int[N]; + mXCoordinates = new int[N]; + mYCoordinates = new int[N]; final LastComposedWord lastComposedWord = new LastComposedWord(primaryKeyCodes, - mInputPointers, mTypedWord.toString(), committedWord, separatorCode, + xCoordinates, yCoordinates, mTypedWord.toString(), committedWord, separatorCode, prevWord); - mInputPointers.reset(); if (type != LastComposedWord.COMMIT_TYPE_DECIDED_WORD && type != LastComposedWord.COMMIT_TYPE_MANUAL_PICK) { lastComposedWord.deactivate(); @@ -328,7 +339,8 @@ public class WordComposer { public void resumeSuggestionOnLastComposedWord(final LastComposedWord lastComposedWord) { mPrimaryKeyCodes = lastComposedWord.mPrimaryKeyCodes; - mInputPointers.set(lastComposedWord.mInputPointers); + mXCoordinates = lastComposedWord.mXCoordinates; + mYCoordinates = lastComposedWord.mYCoordinates; mTypedWord.setLength(0); mTypedWord.append(lastComposedWord.mTypedWord); refreshSize(); diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java index 5f4d66091..7fffc31c0 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java @@ -32,12 +32,12 @@ import com.android.inputmethod.keyboard.ProximityInfo; import com.android.inputmethod.latin.BinaryDictionary; import com.android.inputmethod.latin.ContactsBinaryDictionary; import com.android.inputmethod.latin.Dictionary; +import com.android.inputmethod.latin.Dictionary.WordCallback; import com.android.inputmethod.latin.DictionaryCollection; import com.android.inputmethod.latin.DictionaryFactory; import com.android.inputmethod.latin.LocaleUtils; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.StringUtils; -import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.SynchronouslyLoadedContactsBinaryDictionary; import com.android.inputmethod.latin.SynchronouslyLoadedUserBinaryDictionary; import com.android.inputmethod.latin.UserBinaryDictionary; @@ -203,8 +203,7 @@ public class AndroidSpellCheckerService extends SpellCheckerService EMPTY_STRING_ARRAY); } - // TODO: remove this class and replace it by storage local to the session. - private static class SuggestionsGatherer { + private static class SuggestionsGatherer implements WordCallback { public static class Result { public final String[] mSuggestions; public final boolean mHasRecommendedSuggestions; @@ -238,8 +237,9 @@ public class AndroidSpellCheckerService extends SpellCheckerService mScores = new int[mMaxLength]; } - synchronized public boolean addWord(char[] word, int[] spaceIndices, int wordOffset, - int wordLength, int score) { + @Override + synchronized public boolean addWord(char[] word, int wordOffset, int wordLength, int score, + int dicTypeId, int dataType) { final int positionIndex = Arrays.binarySearch(mScores, 0, mLength, score); // binarySearch returns the index if the element exists, and -<insertion index> - 1 // if it doesn't. See documentation for binarySearch. @@ -780,13 +780,8 @@ public class AndroidSpellCheckerService extends SpellCheckerService try { dictInfo = mDictionaryPool.takeOrGetNull(); if (null == dictInfo) return getNotInDictEmptySuggestions(); - final ArrayList<SuggestedWordInfo> suggestions = dictInfo.mDictionary.getWords( - composer, prevWord, dictInfo.mProximityInfo); - for (final SuggestedWordInfo suggestion : suggestions) { - final String suggestionStr = suggestion.mWord.toString(); - suggestionsGatherer.addWord(suggestionStr.toCharArray(), null, 0, - suggestionStr.length(), suggestion.mScore); - } + dictInfo.mDictionary.getWords(composer, prevWord, suggestionsGatherer, + dictInfo.mProximityInfo); isInDict = dictInfo.mDictionary.isValidWord(text); if (!isInDict && CAPITALIZE_NONE != capitalizeType) { // We want to test the word again if it's all caps or first caps only. diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionsView.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionsView.java index 642a551ce..e86390b11 100644 --- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionsView.java +++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionsView.java @@ -57,11 +57,11 @@ import com.android.inputmethod.keyboard.KeyboardView; import com.android.inputmethod.keyboard.MoreKeysPanel; import com.android.inputmethod.keyboard.PointerTracker; import com.android.inputmethod.keyboard.ViewLayoutUtils; -import com.android.inputmethod.latin.AutoCorrection; import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.ResearchLogger; import com.android.inputmethod.latin.StaticInnerHandlerWrapper; +import com.android.inputmethod.latin.Suggest; import com.android.inputmethod.latin.SuggestedWords; import com.android.inputmethod.latin.Utils; import com.android.inputmethod.latin.define.ProductionFlag; @@ -336,8 +336,8 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener, if (LatinImeLogger.sDBG && suggestedWords.size() > 1) { // If we auto-correct, then the autocorrection is in slot 0 and the typed word // is in slot 1. - if (index == mCenterSuggestionIndex - && AutoCorrection.shouldBlockAutoCorrectionBySafetyNet( + if (index == mCenterSuggestionIndex && suggestedWords.mHasAutoCorrectionCandidate + && Suggest.shouldBlockAutoCorrectionBySafetyNet( suggestedWords.getWord(1).toString(), suggestedWords.getWord(0))) { return 0xFFFF0000; } |