diff --git a/java/res/values-ar/strings.xml b/java/res/values-ar/strings.xml
index 4c04fce9a..fecb97fae 100644
--- a/java/res/values-ar/strings.xml
+++ b/java/res/values-ar/strings.xml
@@ -27,7 +27,12 @@
"صوت عند الضغط على مفتاح"
"انبثاق عند الضغط على المفاتيح"
"عام"
- "تصحيح النص"
+
+
+
+
+
+
"استخدام الأحرف الكبيرة تلقائيًا"
"إصلاحات سريعة"
"تصحيح الأخطاء المكتوبة الشائعة"
@@ -36,6 +41,8 @@
"عرض دومًا"
"عرض في وضع رأسي"
"إخفاء دومًا"
+
+
"عرض مفتاح الإعدادات"
"تلقائي"
"إظهار بشكل دائم"
@@ -45,8 +52,12 @@
"إيقاف"
"معتدل"
"حاد"
- "اقتراحات ثنائية"
+ "اقتراحات ثنائية"
"استخدام الكلمة السابقة لتحسين الاقتراح"
+
+
+
+
"%s : تم الحفظ"
"تنفيذ"
"التالي"
diff --git a/java/res/values-bg/strings.xml b/java/res/values-bg/strings.xml
index de00621ae..1c30fb6e7 100644
--- a/java/res/values-bg/strings.xml
+++ b/java/res/values-bg/strings.xml
@@ -27,7 +27,12 @@
"Звук при натискане на клавиш"
"Изскачащ прозорец при натискане на клавиш"
"Общи"
- "Корекция на текста"
+
+
+
+
+
+
"Автоматично поставяне на главни букви"
"Бързи корекции"
"Коригира най-честите грешки при въвеждане"
@@ -36,6 +41,8 @@
"Винаги да се показва"
"Показване с вертикална ориентация"
"Винаги да се скрива"
+
+
"Показване на клавиша за настройки"
"Автоматично"
"Да се показва винаги"
@@ -45,8 +52,12 @@
"Изкл."
"Умерено"
"Агресивно"
- "Предложения за биграми"
+ "Предложения за биграми"
"Използване на предишната дума за подобряване на предложението"
+
+
+
+
"%s : Запазено"
"Старт"
"Напред"
diff --git a/java/res/values-ca/strings.xml b/java/res/values-ca/strings.xml
index 2923d1347..b569520ad 100644
--- a/java/res/values-ca/strings.xml
+++ b/java/res/values-ca/strings.xml
@@ -27,7 +27,12 @@
"So en prémer una tecla"
"Finestra emergent en prémer un botó"
"General"
- "Correcció de text"
+
+
+
+
+
+
"Majúscules automàtiques"
"Correccions ràpides"
"Corregeix els errors d\'ortografia habituals"
@@ -36,6 +41,8 @@
"Mostra sempre"
"Mostra en mode vertical"
"Amaga sempre"
+
+
"Mostra la tecla de configuració"
"Automàtic"
"Mostra sempre"
@@ -45,8 +52,12 @@
"Desactiva"
"Moderada"
"Total"
- "Suggeriments Bigram"
+ "Suggeriments Bigram"
"Utilitza la paraula anterior per millorar el suggeriment"
+
+
+
+
"%s: desada"
"Vés"
"Següent"
diff --git a/java/res/values-cs/strings.xml b/java/res/values-cs/strings.xml
index 09e68725c..bfe309eb7 100644
--- a/java/res/values-cs/strings.xml
+++ b/java/res/values-cs/strings.xml
@@ -27,7 +27,12 @@
"Zvuk při stisku klávesy"
"Zobrazit znaky při stisku klávesy"
"Obecné"
- "Oprava textu"
+
+
+
+
+
+
"Velká písmena automaticky"
"Rychlé opravy"
"Opravuje nejčastější chyby při psaní"
@@ -36,6 +41,8 @@
"Vždy zobrazovat"
"Zobrazit v režimu na výšku"
"Vždy skrývat"
+
+
"Zobrazit klávesu Nastavení"
"Automaticky"
"Vždy zobrazovat"
@@ -45,8 +52,12 @@
"Vypnuto"
"Mírné"
"Agresivní"
- "Návrh Bigram"
+ "Návrh Bigram"
"Použít předchozí slovo ke zlepšení návrhu"
+
+
+
+
"%s: Uloženo"
"Přejít"
"Další"
diff --git a/java/res/values-da/strings.xml b/java/res/values-da/strings.xml
index d9d1b43c5..381eaaab9 100644
--- a/java/res/values-da/strings.xml
+++ b/java/res/values-da/strings.xml
@@ -27,7 +27,12 @@
"Lyd ved tastetryk"
"Popup ved tastetryk"
"Generelt"
- "Tekstkorrigering"
+
+
+
+
+
+
"Skriv aut. med stort"
"Hurtige løsninger"
"Retter almindelige stavefejl"
@@ -36,6 +41,8 @@
"Vis altid"
"Vis i portrættilstand"
"Skjul altid"
+
+
"Vis indstillingsnøgle"
"Automatisk"
"Vis altid"
@@ -45,8 +52,12 @@
"Fra"
"Beskeden"
"Aggressiv"
- "Bigram-forslag"
+ "Bigram-forslag"
"Brug forrige ord for at forbedre forslag"
+
+
+
+
"%s: Gemt"
"Gå"
"Næste"
diff --git a/java/res/values-de/strings.xml b/java/res/values-de/strings.xml
index 74c1041a0..55766eb74 100644
--- a/java/res/values-de/strings.xml
+++ b/java/res/values-de/strings.xml
@@ -27,7 +27,12 @@
"Ton bei Tastendruck"
"Pop-up bei Tastendruck"
"Allgemein"
- "Textkorrektur"
+
+
+
+
+
+
"Autom. Groß-/Kleinschr."
"Quick Fixes"
"Korrigiert gängige Tippfehler"
@@ -36,6 +41,8 @@
"Immer anzeigen"
"Im Hochformat anzeigen"
"Immer ausblenden"
+
+
"Einstellungstaste anz."
"Automatisch"
"Immer anzeigen"
@@ -45,8 +52,12 @@
"Aus"
"Mäßig"
"Stark"
- "Bigramm-Vorschläge"
+ "Bigramm-Vorschläge"
"Zur Verbesserung des Vorschlags vorheriges Wort verwenden"
+
+
+
+
"%s: gespeichert"
"Los"
"Weiter"
diff --git a/java/res/values-el/strings.xml b/java/res/values-el/strings.xml
index 305bb4fe2..019d7e943 100644
--- a/java/res/values-el/strings.xml
+++ b/java/res/values-el/strings.xml
@@ -27,7 +27,12 @@
"Ήχος κατά το πάτημα πλήκτρων"
"Εμφάνιση με το πάτημα πλήκτρου"
"Γενικά"
- "Διόρθωση κειμένου"
+
+
+
+
+
+
"Αυτόματη χρήση κεφαλαίων"
"Γρήγορες διορθώσεις"
"Διορθώνει συνηθισμένα λάθη πληκτρολόγησης"
@@ -36,6 +41,8 @@
"Να εμφανίζεται πάντα"
"Εμφάνιση σε λειτουργία κατακόρυφης προβολής"
"Πάντα απόκρυψη"
+
+
"Εμφάνιση πλήκτρου ρυθμίσεων"
"Αυτόματο"
"Να εμφανίζεται πάντα"
@@ -45,8 +52,12 @@
"Απενεργοποίηση"
"Μέτρια"
"Υψηλή"
- "Προτάσεις bigram"
+ "Προτάσεις bigram"
"Χρήση προηγούμενης λέξης για τη βελτίωση πρότασης"
+
+
+
+
"%s : Αποθηκεύτηκε"
"Μετ."
"Επόμενο"
diff --git a/java/res/values-en-rGB/strings.xml b/java/res/values-en-rGB/strings.xml
index 64006345a..30d20b2df 100644
--- a/java/res/values-en-rGB/strings.xml
+++ b/java/res/values-en-rGB/strings.xml
@@ -27,7 +27,12 @@
"Sound on key-press"
"Pop-up on key press"
"General"
- "Text correction"
+
+
+
+
+
+
"Auto-capitalisation"
"Quick fixes"
"Corrects commonly typed mistakes"
@@ -36,6 +41,8 @@
"Always show"
"Show on portrait mode"
"Always hide"
+
+
"Show settings key"
"Automatic"
"Always show"
@@ -45,8 +52,12 @@
"Off"
"Modest"
"Aggressive"
- "Bigram Suggestions"
+ "Bigram Suggestions"
"Use previous word to improve suggestion"
+
+
+
+
"%s : Saved"
"Go"
"Next"
diff --git a/java/res/values-es-rUS/strings.xml b/java/res/values-es-rUS/strings.xml
index a00005098..aae15d5c8 100644
--- a/java/res/values-es-rUS/strings.xml
+++ b/java/res/values-es-rUS/strings.xml
@@ -27,7 +27,12 @@
"Sonar al pulsar las teclas"
"Aviso emergente al pulsar tecla"
"General"
- "Corrección de texto"
+
+
+
+
+
+
"Mayúsculas automáticas"
"Arreglos rápidos"
"Corrige errores de escritura comunes"
@@ -36,6 +41,8 @@
"Mostrar siempre"
"Mostrar en modo retrato"
"Ocultar siempre"
+
+
"Mostrar tecla de configuración"
"Automático"
"Mostrar siempre"
@@ -45,8 +52,12 @@
"Desactivado"
"Moderado"
"Total"
- "Sugerencias de Vigoran"
+ "Sugerencias de bigramas"
"Utiliza la palabra anterior para mejorar la sugerencia"
+
+
+
+
"%s: guardada"
"Ir"
"Siguiente"
diff --git a/java/res/values-es/strings.xml b/java/res/values-es/strings.xml
index b5439d453..89435f596 100644
--- a/java/res/values-es/strings.xml
+++ b/java/res/values-es/strings.xml
@@ -27,7 +27,12 @@
"Sonido al pulsar tecla"
"Popup al pulsar tecla"
"General"
- "Corrección ortográfica"
+
+
+
+
+
+
"Mayúsculas automáticas"
"Correcciones rápidas"
"Corrige los errores tipográficos que se cometen con más frecuencia."
@@ -36,6 +41,8 @@
"Mostrar siempre"
"Mostrar en modo vertical"
"Ocultar siempre"
+
+
"Mostrar tecla de ajustes"
"Automáticamente"
"Mostrar siempre"
@@ -45,8 +52,12 @@
"Desactivada"
"Parcial"
"Total"
- "Sugerencias de bigramas"
+ "Sugerencias de bigramas"
"Usar palabra anterior para mejorar sugerencias"
+
+
+
+
"%s: guardada"
"Ir"
"Sig."
diff --git a/java/res/values-fa/strings.xml b/java/res/values-fa/strings.xml
index ca7c1412d..87af40406 100644
--- a/java/res/values-fa/strings.xml
+++ b/java/res/values-fa/strings.xml
@@ -27,7 +27,12 @@
"صدا با فشار کلید"
"بازشو با فشار کلید"
"کلی"
- "تصحیح متن"
+
+
+
+
+
+
"نوشتن با حروف بزرگ خودکار"
"راه حل های سریع"
"تصحیح خطاهای تایپی رایج"
@@ -36,6 +41,8 @@
"همیشه نمایش داده شود"
"نمایش در حالت عمودی"
"همیشه پنهان شود"
+
+
"نمایش کلید تنظیمات"
"خودکار"
"همیشه نمایش"
@@ -45,8 +52,12 @@
"خاموش"
"متوسط"
"فعال"
- "توضیحات بیگرام"
+ "پیشنهادات بیگرام"
"برای بهبود پیشنهاد از کلمه قبلی استفاده شود"
+
+
+
+
"%s : ذخیره شد"
"برو"
"بعدی"
diff --git a/java/res/values-fi/strings.xml b/java/res/values-fi/strings.xml
index 56d2df721..4fb3aa87e 100644
--- a/java/res/values-fi/strings.xml
+++ b/java/res/values-fi/strings.xml
@@ -27,7 +27,12 @@
"Toista ääni näppäimiä painettaessa"
"Ponnahdusikkuna painalluksella"
"Yleinen"
- "Tekstin korjaus"
+
+
+
+
+
+
"Automaattiset isot kirjaimet"
"Pikakorjaukset"
"Korjaa yleiset kirjoitusvirheet"
@@ -36,6 +41,8 @@
"Näytä aina"
"Näytä pystysuunnassa"
"Piilota aina"
+
+
"Näytä asetukset-näppäin"
"Automaattinen"
"Näytä aina"
@@ -45,8 +52,12 @@
"Älä käytä"
"Osittainen"
"Täysi"
- "Bigram-ehdotukset"
+ "Bigram-ehdotukset"
"Paranna ehdotusta aiemman sanan avulla"
+
+
+
+
"%s : Tallennettu"
"Siirry"
"Seuraava"
diff --git a/java/res/values-fr/strings.xml b/java/res/values-fr/strings.xml
index 86e37b32d..0b03b6a16 100644
--- a/java/res/values-fr/strings.xml
+++ b/java/res/values-fr/strings.xml
@@ -27,7 +27,12 @@
"Son à chaque touche"
"Agrandir les caractères"
"Général"
- "Correction du texte"
+
+
+
+
+
+
"Majuscules auto"
"Corrections rapides"
"Corrige les fautes de frappe courantes"
@@ -36,6 +41,8 @@
"Toujours afficher"
"Afficher en mode Portrait"
"Toujours masquer"
+
+
"Afficher touche param."
"Automatique"
"Toujours afficher"
@@ -45,8 +52,12 @@
"Désactiver"
"Simple"
"Proactive"
- "Suggestions de type bigramme"
+ "Suggestions de type bigramme"
"Améliorer la suggestion en fonction du mot précédent"
+
+
+
+
"%s : enregistré"
"OK"
"Suivant"
diff --git a/java/res/values-hr/strings.xml b/java/res/values-hr/strings.xml
index 24e70cf8e..e1da48e14 100644
--- a/java/res/values-hr/strings.xml
+++ b/java/res/values-hr/strings.xml
@@ -27,7 +27,12 @@
"Zvuk pri pritisku tipke"
"Povećanja na pritisak tipke"
"Općenito"
- "Ispravak teksta"
+
+
+
+
+
+
"Automatsko pisanje velikih slova"
"Brzi popravci"
"Ispravlja uobičajene pogreške u pisanju"
@@ -36,6 +41,8 @@
"Uvijek prikaži"
"Prikaži u portretnom načinu"
"Uvijek sakrij"
+
+
"Prikaži tipku postavki"
"Automatski"
"Uvijek prikaži"
@@ -45,8 +52,12 @@
"Isključeno"
"Skromno"
"Agresivno"
- "Bigram prijedlozi"
+ "Bigram prijedlozi"
"Upotrijebi prethodnu riječ radi poboljšanja prijedloga"
+
+
+
+
"%s : Spremljeno"
"Idi"
"Dalje"
diff --git a/java/res/values-hu/strings.xml b/java/res/values-hu/strings.xml
index cfcdf45ad..cf4f9f5da 100644
--- a/java/res/values-hu/strings.xml
+++ b/java/res/values-hu/strings.xml
@@ -27,7 +27,12 @@
"Hangjelzés billentyű megnyomása esetén"
"Legyen nagyobb billentyű lenyomásakor"
"Általános"
- "Szövegjavítás"
+
+
+
+
+
+
"Automatikusan nagy kezdőbetű"
"Gyorsjavítások"
"Kijavítja a gyakori gépelési hibákat"
@@ -36,6 +41,8 @@
"Mindig látszik"
"Megjelenítés álló tájolásban"
"Mindig rejtve"
+
+
"Beállítások billentyű megjelenítése"
"Automatikus"
"Mindig látszik"
@@ -45,8 +52,12 @@
"Ki"
"Mérsékelt"
"Agresszív"
- "Bigram javaslatok"
+ "Bigram javaslatok"
"Előző szó használata a javaslatok javításához"
+
+
+
+
"%s : mentve"
"Ugrás"
"Tovább"
diff --git a/java/res/values-in/strings.xml b/java/res/values-in/strings.xml
index 5dfcbf0ff..1b62b6c30 100644
--- a/java/res/values-in/strings.xml
+++ b/java/res/values-in/strings.xml
@@ -27,7 +27,12 @@
"Berbunyi jika tombol ditekan"
"Muncul saat tombol ditekan"
"Umum"
- "Koreksi teks"
+
+
+
+
+
+
"Kapitalisasi otomatis"
"Perbaikan cepat"
"Memperbaiki kesalahan ketik umum"
@@ -36,6 +41,8 @@
"Selalu tampilkan"
"Tampilkan pada mode potret"
"Selalu sembunyikan"
+
+
"Lihat tombol setelan"
"Otomatis"
"Selalu tampilkan"
@@ -45,8 +52,12 @@
"Mati"
"Sederhana"
"Agresif"
- "Saran Bigram"
+ "Saran Bigram"
"Gunakan kata sebelumnya untuk meningkatkan sara"
+
+
+
+
"%s : Telah disimpan"
"Buka"
"Berikutnya"
diff --git a/java/res/values-it/strings.xml b/java/res/values-it/strings.xml
index 64bbf654b..0d0f8db3b 100644
--- a/java/res/values-it/strings.xml
+++ b/java/res/values-it/strings.xml
@@ -27,7 +27,12 @@
"Suono tasti"
"Popup sui tasti"
"Generali"
- "Correzione testo"
+
+
+
+
+
+
"Maiuscole automatiche"
"Correzioni veloci"
"Corregge gli errori di digitazione più comuni"
@@ -36,6 +41,8 @@
"Mostra sempre"
"Mostra in modalità verticale"
"Nascondi sempre"
+
+
"Mostra tasto impostaz."
"Automatico"
"Mostra sempre"
@@ -45,8 +52,12 @@
"Off"
"Media"
"Massima"
- "Suggerimenti sui bigrammi"
+ "Suggerimenti sui bigrammi"
"Utilizza parola precedente per migliorare il suggerimento"
+
+
+
+
"%s : parola salvata"
"Vai"
"Avanti"
diff --git a/java/res/values-iw/strings.xml b/java/res/values-iw/strings.xml
index 2ad86c910..dfbfb659f 100644
--- a/java/res/values-iw/strings.xml
+++ b/java/res/values-iw/strings.xml
@@ -27,7 +27,12 @@
"צלילים עם לחיצה על מקשים"
"חלון קופץ עם לחיצה על מקשים"
"כללי"
- "תיקון טקסט"
+
+
+
+
+
+
"הפיכה אוטומטית של אותיות לרישיות"
"תיקונים מהירים"
"מתקן שגיאות הקלדה נפוצות"
@@ -36,6 +41,8 @@
"הצג תמיד"
"הצג בפריסה לאורך"
"הסתר תמיד"
+
+
"הצג מקש הגדרות"
"אוטומטי"
"הצג תמיד"
@@ -45,8 +52,12 @@
"כבוי"
"מצומצם"
"מחמיר"
- "הצעות של צמדי אותיות (Bigram)"
+ "הצעות של צמדי אותיות (Bigram)"
"השתמש במילה הקודמת כדי לשפר את ההצעה"
+
+
+
+
"%s : נשמרה"
"בצע"
"הבא"
diff --git a/java/res/values-ja/strings.xml b/java/res/values-ja/strings.xml
index 768122c60..01619e00c 100644
--- a/java/res/values-ja/strings.xml
+++ b/java/res/values-ja/strings.xml
@@ -27,7 +27,12 @@
"キー操作音"
"キー押下時ポップアップ"
"全般"
- "テキストの修正"
+
+
+
+
+
+
"自動大文字変換"
"クイックフィックス"
"よくある誤字・脱字を修正します"
@@ -36,6 +41,8 @@
"常に表示"
"縦向きで表示"
"常に非表示"
+
+
"設定キーを表示"
"自動"
"常に表示"
@@ -45,8 +52,12 @@
"OFF"
"中"
"強"
- "バイグラム入力候補表示"
+ "バイグラム入力候補表示"
"直前の単語から入力候補を予測します"
+
+
+
+
"%s:保存しました"
"実行"
"次へ"
diff --git a/java/res/values-ko/strings.xml b/java/res/values-ko/strings.xml
index 850981cca..9d442dd0a 100644
--- a/java/res/values-ko/strings.xml
+++ b/java/res/values-ko/strings.xml
@@ -27,7 +27,12 @@
"키를 누를 때 소리 발생"
"키를 누를 때 팝업"
"일반"
- "텍스트 수정"
+
+
+
+
+
+
"자동 대문자화"
"빠른 수정"
"자주 발생하는 오타를 수정합니다."
@@ -36,6 +41,8 @@
"항상 표시"
"세로 모드로 표시"
"항상 숨기기"
+
+
"설정 키 표시"
"자동"
"항상 표시"
@@ -45,8 +52,12 @@
"사용 안함"
"보통"
"적극적"
- "Bigram 추천"
+ "Bigram 추천"
"이전 단어를 사용하여 추천 기능 개선"
+
+
+
+
"%s: 저장됨"
"이동"
"다음"
diff --git a/java/res/values-lt/strings.xml b/java/res/values-lt/strings.xml
index 247e201fb..fb288430f 100644
--- a/java/res/values-lt/strings.xml
+++ b/java/res/values-lt/strings.xml
@@ -27,7 +27,12 @@
"Klavišo paspaudimo garsas"
"Iššoka paspaudus klavišą"
"Bendra"
- "Teksto taisymas"
+
+
+
+
+
+
"Automatinis didžiųjų raidžių rašymas"
"Greiti pataisymai"
"Taiso dažnai padarytas rašybos klaidas"
@@ -36,6 +41,8 @@
"Visada rodyti"
"Rodyti stačiuoju režimu"
"Visada slėpti"
+
+
"Rodyti nustatymų raktą"
"Automatinis"
"Visada rodyti"
@@ -45,8 +52,12 @@
"Išjungta"
"Vidutinis"
"Atkaklus"
- "Digramų pasiūlymai"
+ "Bigramų pasiūlymai"
"Naudoti ankstesnį žodį pasiūlymui patobulinti"
+
+
+
+
"%s: išsaugota"
"Pradėti"
"Kitas"
diff --git a/java/res/values-lv/strings.xml b/java/res/values-lv/strings.xml
index 5d0c0ae7e..ff31bf8d4 100644
--- a/java/res/values-lv/strings.xml
+++ b/java/res/values-lv/strings.xml
@@ -27,7 +27,12 @@
"Skaņa, nospiežot taustiņu"
"Nospiežot taustiņu, parādīt uznirstošo izvēlni"
"Vispārīgi"
- "Teksta korekcija"
+
+
+
+
+
+
"Automātiska lielo burtu lietošana"
"Ātrie labojumi"
"Nodrošina izplatītu drukas kļūdu labošanu."
@@ -36,6 +41,8 @@
"Vienmēr rādīt"
"Rādīt portreta režīmā"
"Vienmēr slēpt"
+
+
"Rādīt iestatījumu taustiņu"
"Automātiski"
"Vienmēr rādīt"
@@ -45,8 +52,12 @@
"Izslēgta"
"Mērena"
"Agresīva"
- "Bigram ieteikumi"
+ "Bigram ieteikumi"
"Ieteikuma uzlabošanai izmantot iepriekšējo vārdu"
+
+
+
+
"%s: saglabāts"
"Sākt"
"Tālāk"
diff --git a/java/res/values-nb/strings.xml b/java/res/values-nb/strings.xml
index 944e8dd5a..cd70aadc0 100644
--- a/java/res/values-nb/strings.xml
+++ b/java/res/values-nb/strings.xml
@@ -27,7 +27,12 @@
"Lyd ved tastetrykk"
"Hurtigvindu ved tastetrykk"
"Generelt"
- "Tekstkorrigering"
+
+
+
+
+
+
"Stor forbokstav"
"Autokorrektur"
"Retter vanlige stavefeil"
@@ -36,6 +41,8 @@
"Vis alltid"
"Vis i stående modus"
"Skjul alltid"
+
+
"Vis innstillingsnøkkel"
"Automatisk"
"Vis alltid"
@@ -45,8 +52,12 @@
"Av"
"Moderat"
"Omfattende"
- "Bigram-forslag"
+ "Bigram-forslag"
"Bruk forrige ord til å forbedre forslaget"
+
+
+
+
"%s: Lagret"
"Gå"
"Neste"
diff --git a/java/res/values-nl/strings.xml b/java/res/values-nl/strings.xml
index 0efb45b7b..868deae42 100644
--- a/java/res/values-nl/strings.xml
+++ b/java/res/values-nl/strings.xml
@@ -27,7 +27,12 @@
"Geluid bij toetsaanslag"
"Pop-up bij toetsaanslag"
"Algemeen"
- "Tekstcorrectie"
+
+
+
+
+
+
"Auto-hoofdlettergebruik"
"Snelle oplossingen"
"Hiermee worden veelvoorkomende typefouten gecorrigeerd"
@@ -36,6 +41,8 @@
"Altijd weergeven"
"Weergeven in staande modus"
"Altijd verbergen"
+
+
"Instellingscode weergeven"
"Automatisch"
"Altijd weergeven"
@@ -45,8 +52,12 @@
"Uitgeschakeld"
"Normaal"
"Agressief"
- "Digram-suggesties"
+ "Digram-suggesties"
"Vorig woord gebruiken om suggestie te verbeteren"
+
+
+
+
"%s: opgeslagen"
"Start"
"Volgende"
diff --git a/java/res/values-pl/strings.xml b/java/res/values-pl/strings.xml
index b0c707f35..14380588d 100644
--- a/java/res/values-pl/strings.xml
+++ b/java/res/values-pl/strings.xml
@@ -27,7 +27,12 @@
"Dźwięk przy naciśnięciu"
"Powiększ po naciśnięciu"
"Ogólne"
- "Korekta tekstu"
+
+
+
+
+
+
"Wstawiaj wielkie litery"
"Szybkie poprawki"
"Poprawia częste błędy wpisywania"
@@ -36,6 +41,8 @@
"Zawsze pokazuj"
"Pokaż w trybie pionowym"
"Zawsze ukrywaj"
+
+
"Pokaż klawisz ustawień"
"Automatycznie"
"Zawsze pokazuj"
@@ -45,8 +52,12 @@
"Wyłącz"
"Umiarkowana"
"Agresywna"
- "Sugestie dla bigramów"
+ "Sugestie dla bigramów"
"Używaj poprzedniego wyrazu, aby polepszyć sugestię"
+
+
+
+
"%s : Zapisano"
"OK"
"Dalej"
diff --git a/java/res/values-pt-rPT/strings.xml b/java/res/values-pt-rPT/strings.xml
index 83686662b..258a488db 100644
--- a/java/res/values-pt-rPT/strings.xml
+++ b/java/res/values-pt-rPT/strings.xml
@@ -27,7 +27,12 @@
"Som ao premir as teclas"
"Mostrar popup ao premir tecla"
"Geral"
- "Correcção de texto"
+
+
+
+
+
+
"Letras maiúsculas automáticas"
"Correcções rápidas"
"Corrige os erros de escrita comuns"
@@ -36,6 +41,8 @@
"Mostrar sempre"
"Mostrar no modo de retrato"
"Ocultar sempre"
+
+
"Mostrar tecla das definições"
"Automático"
"Mostrar sempre"
@@ -45,8 +52,12 @@
"Desligar"
"Moderada"
"Agressiva"
- "Sugestões Bigram"
+ "Sugestões Bigram"
"Utilizar a palavra anterior para melhorar a sugestão"
+
+
+
+
"%s: guardada"
"Ir"
"Seguinte"
diff --git a/java/res/values-pt/strings.xml b/java/res/values-pt/strings.xml
index 0d09b1119..72c59fbfd 100644
--- a/java/res/values-pt/strings.xml
+++ b/java/res/values-pt/strings.xml
@@ -27,7 +27,12 @@
"Som ao tocar a tecla"
"Exibir pop-up ao digitar"
"Geral"
- "Correção de texto"
+
+
+
+
+
+
"Capitaliz. automática"
"Reparos rápidos"
"Corrige erros comuns de digitação"
@@ -36,6 +41,8 @@
"Mostrar sempre"
"Mostrar em modo retrato"
"Sempre ocultar"
+
+
"Mostrar tecla de config."
"Automático"
"Mostrar sempre"
@@ -45,8 +52,12 @@
"Desativado"
"Moderado"
"Agressivo"
- "Sugestões de bigrama"
+ "Sugestões de bigrama"
"Usar palavra anterior para melhorar a sugestão"
+
+
+
+
"%s : Salvo"
"Ir"
"Avançar"
diff --git a/java/res/values-rm/strings.xml b/java/res/values-rm/strings.xml
index c788597d6..8328fc9e8 100644
--- a/java/res/values-rm/strings.xml
+++ b/java/res/values-rm/strings.xml
@@ -29,7 +29,12 @@
"Pop-up cun smatgar ina tasta"
- "Parameters da las propostas per pleds"
+
+
+
+
+
+
"Maiusclas automaticas"
"Correcturas sveltas"
"Curregia sbagls da tippar currents"
@@ -43,6 +48,8 @@
+
+
@@ -59,8 +66,12 @@
- "Propostas da tip bigram"
+ "Propostas da tip bigram"
"Meglierar la proposta cun agid dal pled precedent"
+
+
+
+
"%s : Memorisà"
"Dai"
"Vinavant"
diff --git a/java/res/values-ro/strings.xml b/java/res/values-ro/strings.xml
index c9639a807..9f256d668 100644
--- a/java/res/values-ro/strings.xml
+++ b/java/res/values-ro/strings.xml
@@ -27,7 +27,12 @@
"Sunet la apăsarea tastei"
"Fereastră pop-up la apăsarea tastei"
"General"
- "Corectare text"
+
+
+
+
+
+
"Auto-capitalizare"
"Remedieri rapide"
"Corectează greşelile introduse frecvent"
@@ -36,6 +41,8 @@
"Afişaţi întotdeauna"
"Afişaţi în modul Portret"
"Ascundeţi întotdeauna"
+
+
"Afişaţi tasta setări"
"Automat"
"Afişaţi întotdeauna"
@@ -45,8 +52,12 @@
"Dezactivată"
"Moderată"
"Agresivă"
- "Sugestii pentru cuvinte de două litere"
+ "Sugestii pentru cuvinte de două litere"
"Utilizaţi cuvântul anterior pentru a îmbunătăţi sugestia"
+
+
+
+
"%s: salvat"
"OK"
"Înainte"
diff --git a/java/res/values-ru/strings.xml b/java/res/values-ru/strings.xml
index c1e379dd9..26e9e2d39 100644
--- a/java/res/values-ru/strings.xml
+++ b/java/res/values-ru/strings.xml
@@ -27,7 +27,12 @@
"Звук клавиш"
"Увеличение нажатых"
"Общие"
- "Коррекция текста"
+
+
+
+
+
+
"Заглавные автоматически"
"Быстрое исправление"
"Исправлять распространенные опечатки"
@@ -36,6 +41,8 @@
"Всегда показывать"
"Показать вертикально"
"Всегда скрывать"
+
+
"Кнопка настроек"
"Автоматически"
"Всегда показывать"
@@ -45,8 +52,12 @@
"Откл."
"Умеренное"
"Активное"
- "Биграммные подсказки"
+ "Биграммные подсказки"
"Используйте предыдущее слово, чтобы исправить подсказку"
+
+
+
+
"%s: сохранено"
"Поиск"
"Далее"
diff --git a/java/res/values-sk/strings.xml b/java/res/values-sk/strings.xml
index 20e29764a..5097615ff 100644
--- a/java/res/values-sk/strings.xml
+++ b/java/res/values-sk/strings.xml
@@ -27,7 +27,12 @@
"Zvuk pri stlačení klávesu"
"Zobraziť znaky pri stlačení klávesu"
"Všeobecné"
- "Oprava textu"
+
+
+
+
+
+
"Veľké písmená automaticky"
"Rýchle opravy"
"Opravuje najčastejšie chyby pri písaní"
@@ -36,6 +41,8 @@
"Vždy zobrazovať"
"Zobraziť v režime na výšku"
"Vždy skrývať"
+
+
"Zobraziť kláves Nastavenia"
"Automaticky"
"Vždy zobrazovať"
@@ -45,8 +52,12 @@
"Vypnuté"
"Mierne"
"Agresívne"
- "Návrh Bigram"
+ "Návrhy Bigram"
"Na zlepšenie návrhu použiť predchádzajúce slovo"
+
+
+
+
"%s : Uložené"
"Hľadať"
"Ďalej"
diff --git a/java/res/values-sl/strings.xml b/java/res/values-sl/strings.xml
index 12df259da..965b2b61d 100644
--- a/java/res/values-sl/strings.xml
+++ b/java/res/values-sl/strings.xml
@@ -27,7 +27,12 @@
"Zvok ob pritisku tipke"
"Pojavno okno ob pritisku tipke"
"Splošno"
- "Popravek besedila"
+
+
+
+
+
+
"Samodejne velike začetnice"
"Hitri popravki"
"Popravi pogoste tipkarske napake"
@@ -36,6 +41,8 @@
"Vedno pokaži"
"Pokaži v pokončnem načinu"
"Vedno skrij"
+
+
"Pokaži tipko za nastavitve"
"Samodejno"
"Vedno pokaži"
@@ -45,8 +52,12 @@
"Izklopljeno"
"Zmerno"
"Agresivno"
- "Bigramni predlogi"
+ "Bigramni predlogi"
"Predlog izboljšaj s prejšnjo besedo"
+
+
+
+
"%s: shranjeno"
"Pojdi"
"Naprej"
diff --git a/java/res/values-sr/strings.xml b/java/res/values-sr/strings.xml
index 1e637fd01..26234038d 100644
--- a/java/res/values-sr/strings.xml
+++ b/java/res/values-sr/strings.xml
@@ -27,7 +27,12 @@
"Звук на притисак тастера"
"Искачући прозор приликом притиска тастера"
"Опште"
- "Исправљање текста"
+
+
+
+
+
+
"Аутоматски унос великих слова"
"Брзе исправке"
"Исправља честе грешке у куцању"
@@ -36,6 +41,8 @@
"Увек прикажи"
"Прикажи у усправном режиму"
"Увек сакриј"
+
+
"Прикажи тастер за подешавања"
"Аутоматски"
"Увек прикажи"
@@ -45,8 +52,12 @@
"Искључи"
"Умерено"
"Агресивно"
- "Bigram предлози"
+ "Bigram предлози"
"Користи претходну реч за побољшање предлога"
+
+
+
+
"%s : Сачувано"
"Иди"
"Следеће"
diff --git a/java/res/values-sv/strings.xml b/java/res/values-sv/strings.xml
index fc311e7ff..cf1b998aa 100644
--- a/java/res/values-sv/strings.xml
+++ b/java/res/values-sv/strings.xml
@@ -27,7 +27,12 @@
"Knappljud"
"Popup vid knapptryck"
"Allmänt"
- "Textkorrigering"
+
+
+
+
+
+
"Automatiska versaler"
"Snabba lösningar"
"Åtgärdar automatiskt vanliga misstag"
@@ -36,6 +41,8 @@
"Visa alltid"
"Visa stående"
"Dölj alltid"
+
+
"Visa inställningsknapp"
"Automatiskt"
"Visa alltid"
@@ -45,8 +52,12 @@
"Av"
"Måttlig"
"Aggressiv"
- "Bigramförslag"
+ "Bigramförslag"
"Förbättra förslaget med föregående ord"
+
+
+
+
"%s: sparat"
"Kör"
"Nästa"
diff --git a/java/res/values-th/strings.xml b/java/res/values-th/strings.xml
index c19b7d538..4dc0eb637 100644
--- a/java/res/values-th/strings.xml
+++ b/java/res/values-th/strings.xml
@@ -27,7 +27,12 @@
"ส่งเสียงเมื่อกดปุ่ม"
"ป๊อปอัปเมื่อกดแป้น"
"ทั่วไป"
- "การแก้ไขข้อความ"
+
+
+
+
+
+
"ปรับเป็นตัวพิมพ์ใหญ่อัตโนมัติ"
"แก้ไขด่วน"
"แก้ไขข้อผิดพลาดในการพิมพ์ที่พบบ่อย"
@@ -36,6 +41,8 @@
"แสดงทุกครั้ง"
"แสดงในโหมดแนวตั้ง"
"ซ่อนทุกครั้ง"
+
+
"แสดงแป้นการตั้งค่า"
"อัตโนมัติ"
"แสดงตลอดเวลา"
@@ -45,8 +52,12 @@
"ปิด"
"ปานกลาง"
"เข้มงวด"
- "คำแนะนำ Bigram"
+ "คำแนะนำ Bigram"
"ใช้คำก่อนหน้านี้เพื่อปรับปรุงคำแนะนำ"
+
+
+
+
"%s : บันทึกแล้ว"
"ไป"
"ถัดไป"
diff --git a/java/res/values-tl/strings.xml b/java/res/values-tl/strings.xml
index 5906b5874..daf2f944e 100644
--- a/java/res/values-tl/strings.xml
+++ b/java/res/values-tl/strings.xml
@@ -27,7 +27,12 @@
"Tunog sa keypress"
"Popup sa keypress"
"Pangkalahatan"
- "Pagwawasto ng teksto"
+
+
+
+
+
+
"Auto-capitalization"
"Mga mabilisang pagsasaayos"
"Itinatama ang mga karaniwang na-type na mali"
@@ -36,6 +41,8 @@
"Palaging ipakita"
"Ipakita sa portrait mode"
"Palaging itago"
+
+
"Ipakita ang key ng mga setting"
"Awtomatiko"
"Palaging ipakita"
@@ -45,8 +52,12 @@
"Naka-off"
"Modest"
"Agresibo"
- "Mga Suhestiyon na Bigram"
+ "Mga Suhestiyon na Bigram"
"Gamitin ang nakaraang salita upang pahusayin ang suhestiyon"
+
+
+
+
"%s : Na-save"
"Punta"
"Susunod"
diff --git a/java/res/values-tr/strings.xml b/java/res/values-tr/strings.xml
index da8b287d3..1e168f4c8 100644
--- a/java/res/values-tr/strings.xml
+++ b/java/res/values-tr/strings.xml
@@ -27,7 +27,12 @@
"Tuşa basıldığında ses çıkar"
"Tuşa basıldığında pop-up aç"
"Genel"
- "Metin düzeltme"
+
+
+
+
+
+
"Otomatik olarak büyük harf yap"
"Hızlı onarımlar"
"Yaygın olarak yapılan yazım hatalarını düzeltir"
@@ -36,6 +41,8 @@
"Her zaman göster"
"Dikey modda göster"
"Her zaman gizle"
+
+
"Ayarları göster tuşu"
"Otomatik"
"Her zaman göster"
@@ -45,8 +52,12 @@
"Kapalı"
"Ölçülü"
"Agresif"
- "Bigram Önerileri"
+ "Bigram Önerileri"
"Öneriyi geliştirmek için önceki kelimeyi kullanın"
+
+
+
+
"%s : Kaydedildi"
"Git"
"İleri"
diff --git a/java/res/values-uk/strings.xml b/java/res/values-uk/strings.xml
index 53063393a..c46c99d28 100644
--- a/java/res/values-uk/strings.xml
+++ b/java/res/values-uk/strings.xml
@@ -27,7 +27,12 @@
"Звук при натиску клав."
"Сплив. при нат.клав."
"Загальні"
- "Виправлення тексту"
+
+
+
+
+
+
"Авто викор. вел. літер"
"Шв. виправлення"
"Виправляє поширені помилки"
@@ -36,6 +41,8 @@
"Завжди показувати"
"Показувати в книжковому режимі"
"Завжди ховати"
+
+
"Показ. клав. налашт."
"Автоматично"
"Завжди показ."
@@ -45,8 +52,12 @@
"Вимк."
"Середнє"
"Повне"
- "Двобуквені пропозиції"
+ "Двобуквені пропозиції"
"Викор. попер. слово для покращ. пропозиції"
+
+
+
+
"%s : збережено"
"Іти"
"Далі"
diff --git a/java/res/values-vi/strings.xml b/java/res/values-vi/strings.xml
index 0473464b5..f02d12e2f 100644
--- a/java/res/values-vi/strings.xml
+++ b/java/res/values-vi/strings.xml
@@ -27,7 +27,12 @@
"Âm thanh khi nhấn phím"
"Cửa sổ bật lên khi nhấn phím"
"Chung"
- "Sửa văn bản"
+
+
+
+
+
+
"Tự động viết hoa"
"Sửa nhanh"
"Sửa lỗi nhập thông thường"
@@ -36,6 +41,8 @@
"Luôn hiển thị"
"Hiển thị trên chế độ khổ đứng"
"Luôn ẩn"
+
+
"Hiển thị phím cài đặt"
"Tự động"
"Luôn hiển thị"
@@ -45,8 +52,12 @@
"Tắt"
"Đơn giản"
"Linh hoạt"
- "Đề xuất Bigram"
+ "Đề xuất Bigram"
"Sử dụng từ trước đó để cải tiến đề xuất"
+
+
+
+
"%s : Đã lưu"
"Đến"
"Tiếp theo"
diff --git a/java/res/values-zh-rCN/strings.xml b/java/res/values-zh-rCN/strings.xml
index 5578566a2..95c06ed55 100644
--- a/java/res/values-zh-rCN/strings.xml
+++ b/java/res/values-zh-rCN/strings.xml
@@ -27,7 +27,12 @@
"按键时播放音效"
"按键时显示弹出窗口"
"常规"
- "文本更正"
+
+
+
+
+
+
"自动大写"
"快速纠正"
"纠正常见的输入错误"
@@ -36,6 +41,8 @@
"始终显示"
"以纵向模式显示"
"始终隐藏"
+
+
"显示设置键"
"自动"
"始终显示"
@@ -45,8 +52,12 @@
"关闭"
"部分"
"全部"
- "双连词建议"
+ "双连词建议"
"使用以前的字词改进建议"
+
+
+
+
"%s:已保存"
"开始"
"下一步"
diff --git a/java/res/values-zh-rTW/strings.xml b/java/res/values-zh-rTW/strings.xml
index ea143f2d8..e2381b426 100644
--- a/java/res/values-zh-rTW/strings.xml
+++ b/java/res/values-zh-rTW/strings.xml
@@ -27,7 +27,12 @@
"按鍵時播放音效"
"按鍵時顯示彈出式視窗"
"一般設定"
- "文字修正"
+
+
+
+
+
+
"自動大寫"
"快速修正"
"修正一般打字錯誤"
@@ -36,6 +41,8 @@
"一律顯示"
"以垂直模式顯示"
"永遠隱藏"
+
+
"顯示設定金鑰"
"自動"
"一律顯示"
@@ -45,8 +52,12 @@
"關閉"
"部分"
"全部"
- "雙連詞建議"
+ "雙連詞建議"
"根據前一個字詞自動找出更適合的建議"
+
+
+
+
"%s:已儲存"
"開始"
"繼續"
diff --git a/java/res/xml-xlarge/kbd_symbols.xml b/java/res/xml-xlarge/kbd_symbols.xml
index 1061178e0..f1deae0f9 100644
--- a/java/res/xml-xlarge/kbd_symbols.xml
+++ b/java/res/xml-xlarge/kbd_symbols.xml
@@ -211,9 +211,10 @@
latin:keyLabel="-" />
+
+ latin:popupCharacters="“,”,„,‟,«,»,‘,’,‚,‛" />
diff --git a/java/res/xml-xlarge/kbd_symbols_shift.xml b/java/res/xml-xlarge/kbd_symbols_shift.xml
index 8359b7571..cc23358a5 100644
--- a/java/res/xml-xlarge/kbd_symbols_shift.xml
+++ b/java/res/xml-xlarge/kbd_symbols_shift.xml
@@ -99,7 +99,8 @@
latin:popupCharacters="↑,↓,←,→" />
+ latin:keyLabel="°"
+ latin:popupCharacters="′,″" />
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/java/res/xml/kbd_symbols.xml b/java/res/xml/kbd_symbols.xml
index 0b8b89969..9748bce8b 100644
--- a/java/res/xml/kbd_symbols.xml
+++ b/java/res/xml/kbd_symbols.xml
@@ -105,12 +105,14 @@
+
+ latin:popupCharacters="“,”,„,‟,«,»"
+ latin:maxPopupKeyboardColumn="6" />
+ latin:popupCharacters="‘,’,‚,‛,´" />
@@ -64,13 +69,18 @@
latin:keyStyle="nonSpecialBackgroundTabKeyStyle"
latin:keyEdgeFlags="left" />
+ latin:keyStyle="nonPasswordSymbolKeyStyle"
+ latin:keyLabel="°"
+ latin:popupCharacters="′,″" />
@@ -92,12 +102,16 @@
latin:visualInsetsRight="1%p"
latin:keyEdgeFlags="left" />
+ latin:popupCharacters="“,”,„,‟,«,»,‘,’,‚,‛"
+ latin:keyStyle="nonPasswordFunctionalKeyStyle" />
+ latin:keyStyle="nonPasswordFunctionalKeyStyle" />
+ latin:popupCharacters="“,”,„,‟,«,»,‘,’,‚,‛"
+ latin:keyStyle="nonPasswordFunctionalKeyStyle" />
+ latin:keyStyle="nonPasswordFunctionalKeyStyle" />
)retval).isEmpty()) {
+ if (retval == null || !(retval instanceof List>) || ((List>)retval).isEmpty()) {
if (!FORCE_ENABLE_VOICE_EVEN_WITH_NO_VOICE_SUBTYPES) {
// Returns an empty list
return Collections.emptyList();
@@ -137,7 +137,7 @@ public class InputMethodManagerCompatWrapper {
}
return subtypeList;
}
- return CompatUtils.copyInputMethodSubtypeListToWrapper((List>)retval);
+ return CompatUtils.copyInputMethodSubtypeListToWrapper(retval);
}
private InputMethodInfoCompatWrapper getLatinImeInputMethodInfo() {
@@ -159,7 +159,7 @@ public class InputMethodManagerCompatWrapper {
public Map>
getShortcutInputMethodsAndSubtypes() {
Object retval = CompatUtils.invoke(mImm, null, METHOD_getShortcutInputMethodsAndSubtypes);
- if (retval == null || !(retval instanceof Map) || ((Map, ?>)retval).isEmpty()) {
+ if (retval == null || !(retval instanceof Map, ?>) || ((Map, ?>)retval).isEmpty()) {
if (!FORCE_ENABLE_VOICE_EVEN_WITH_NO_VOICE_SUBTYPES) {
// Returns an empty map
return Collections.emptyMap();
diff --git a/java/src/com/android/inputmethod/deprecated/VoiceProxy.java b/java/src/com/android/inputmethod/deprecated/VoiceProxy.java
index 0d0591bd0..753dceead 100644
--- a/java/src/com/android/inputmethod/deprecated/VoiceProxy.java
+++ b/java/src/com/android/inputmethod/deprecated/VoiceProxy.java
@@ -754,15 +754,15 @@ public class VoiceProxy implements VoiceInput.UiListener {
}
public static class VoiceLoggerWrapper {
- private static final VoiceLoggerWrapper sInstance = new VoiceLoggerWrapper();
+ private static final VoiceLoggerWrapper sLoggerWrapperInstance = new VoiceLoggerWrapper();
private VoiceInputLogger mLogger;
public static VoiceLoggerWrapper getInstance(Context context) {
- if (sInstance.mLogger == null) {
+ if (sLoggerWrapperInstance.mLogger == null) {
// Not thread safe, but it's ok.
- sInstance.mLogger = VoiceInputLogger.getLogger(context);
+ sLoggerWrapperInstance.mLogger = VoiceInputLogger.getLogger(context);
}
- return sInstance;
+ return sLoggerWrapperInstance;
}
// private for the singleton
@@ -795,10 +795,10 @@ public class VoiceProxy implements VoiceInput.UiListener {
}
public static class VoiceInputWrapper {
- private static final VoiceInputWrapper sInstance = new VoiceInputWrapper();
+ private static final VoiceInputWrapper sInputWrapperInstance = new VoiceInputWrapper();
private VoiceInput mVoiceInput;
public static VoiceInputWrapper getInstance() {
- return sInstance;
+ return sInputWrapperInstance;
}
public void setVoiceInput(VoiceInput voiceInput, SubtypeSwitcher switcher) {
if (mVoiceInput == null && voiceInput != null) {
diff --git a/java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java b/java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java
index ce576d0cc..a1b49b475 100644
--- a/java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java
+++ b/java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java
@@ -17,19 +17,17 @@
package com.android.inputmethod.deprecated.languageswitcher;
import com.android.inputmethod.keyboard.KeyboardParser;
-import com.android.inputmethod.latin.BinaryDictionary;
+import com.android.inputmethod.latin.DictionaryFactory;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.Settings;
import com.android.inputmethod.latin.SharedPreferencesCompat;
import com.android.inputmethod.latin.SubtypeSwitcher;
-import com.android.inputmethod.latin.Suggest;
import com.android.inputmethod.latin.Utils;
import org.xmlpull.v1.XmlPullParserException;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
-import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
@@ -123,24 +121,11 @@ public class InputLanguageSelection extends PreferenceActivity {
private Pair hasDictionaryOrLayout(Locale locale) {
if (locale == null) return new Pair(false, false);
final Resources res = getResources();
- final Configuration conf = res.getConfiguration();
- final Locale saveLocale = conf.locale;
- conf.locale = locale;
- res.updateConfiguration(conf, res.getDisplayMetrics());
- boolean hasDictionary = false;
+ final Locale saveLocale = Utils.setSystemLocale(res, locale);
+ final boolean hasDictionary = DictionaryFactory.isDictionaryAvailable(this, locale);
boolean hasLayout = false;
try {
- BinaryDictionary bd = BinaryDictionary.initDictionaryFromManager(this, Suggest.DIC_MAIN,
- locale, Utils.getMainDictionaryResourceId(res));
-
- // Is the dictionary larger than a placeholder? Arbitrarily chose a lower limit of
- // 4000-5000 words, whereas the LARGE_DICTIONARY is about 20000+ words.
- if (bd.getSize() > Suggest.LARGE_DICTIONARY_THRESHOLD / 4) {
- hasDictionary = true;
- }
- bd.close();
-
final String localeStr = locale.toString();
final String[] layoutCountryCodes = KeyboardParser.parseKeyboardLocale(
this, R.xml.kbd_qwerty).split(",", -1);
@@ -155,8 +140,7 @@ public class InputLanguageSelection extends PreferenceActivity {
} catch (XmlPullParserException e) {
} catch (IOException e) {
}
- conf.locale = saveLocale;
- res.updateConfiguration(conf, res.getDisplayMetrics());
+ Utils.setSystemLocale(res, saveLocale);
return new Pair(hasDictionary, hasLayout);
}
diff --git a/java/src/com/android/inputmethod/deprecated/languageswitcher/LanguageSwitcher.java b/java/src/com/android/inputmethod/deprecated/languageswitcher/LanguageSwitcher.java
index 1a606eaaf..5ef236e31 100644
--- a/java/src/com/android/inputmethod/deprecated/languageswitcher/LanguageSwitcher.java
+++ b/java/src/com/android/inputmethod/deprecated/languageswitcher/LanguageSwitcher.java
@@ -16,7 +16,6 @@
package com.android.inputmethod.deprecated.languageswitcher;
-import com.android.inputmethod.compat.InputMethodSubtypeCompatWrapper;
import com.android.inputmethod.latin.LatinIME;
import com.android.inputmethod.latin.LatinImeLogger;
import com.android.inputmethod.latin.Settings;
@@ -38,6 +37,7 @@ import java.util.Locale;
public class LanguageSwitcher {
private static final String TAG = LanguageSwitcher.class.getSimpleName();
+ @SuppressWarnings("unused")
private static final String KEYBOARD_MODE = "keyboard";
private static final String[] EMPTY_STIRNG_ARRAY = new String[0];
@@ -154,7 +154,6 @@ public class LanguageSwitcher {
/**
* Returns the currently selected input locale, or the display locale if no specific
* locale was selected for input.
- * @return
*/
public Locale getInputLocale() {
if (getLocaleCount() == 0) return mDefaultInputLocale;
@@ -175,7 +174,6 @@ public class LanguageSwitcher {
/**
* Returns the next input locale in the list. Wraps around to the beginning of the
* list if we're at the end of the list.
- * @return
*/
public Locale getNextInputLocale() {
if (getLocaleCount() == 0) return mDefaultInputLocale;
@@ -201,7 +199,6 @@ public class LanguageSwitcher {
/**
* Returns the previous input locale in the list. Wraps around to the end of the
* list if we're at the beginning of the list.
- * @return
*/
public Locale getPrevInputLocale() {
if (getLocaleCount() == 0) return mDefaultInputLocale;
diff --git a/java/src/com/android/inputmethod/deprecated/voice/VoiceInputLogger.java b/java/src/com/android/inputmethod/deprecated/voice/VoiceInputLogger.java
index dcd124f70..87b943426 100644
--- a/java/src/com/android/inputmethod/deprecated/voice/VoiceInputLogger.java
+++ b/java/src/com/android/inputmethod/deprecated/voice/VoiceInputLogger.java
@@ -17,7 +17,6 @@
package com.android.inputmethod.deprecated.voice;
import com.android.common.speech.LoggingEvents;
-import com.android.common.userhappiness.UserHappinessSignals;
import com.android.inputmethod.deprecated.compat.VoiceInputLoggerCompatUtils;
import android.content.Context;
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index e163457d8..55041154d 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -57,6 +57,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
private LatinKeyboardView mInputView;
private LatinIME mInputMethodService;
+ // TODO: Combine these key state objects with auto mode switch state.
private ShiftKeyState mShiftKeyState = new ShiftKeyState("Shift");
private ModifierKeyState mSymbolKeyState = new ModifierKeyState("Symbol");
@@ -75,13 +76,17 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
private boolean mVoiceKeyEnabled;
private boolean mVoiceButtonOnPrimary;
- private static final int AUTO_MODE_SWITCH_STATE_ALPHA = 0;
- private static final int AUTO_MODE_SWITCH_STATE_SYMBOL_BEGIN = 1;
- private static final int AUTO_MODE_SWITCH_STATE_SYMBOL = 2;
+ // TODO: Encapsulate these state handling to separate class and combine with ShiftKeyState
+ // and ModifierKeyState.
+ private static final int SWITCH_STATE_ALPHA = 0;
+ private static final int SWITCH_STATE_SYMBOL_BEGIN = 1;
+ private static final int SWITCH_STATE_SYMBOL = 2;
// The following states are used only on the distinct multi-touch panel devices.
- private static final int AUTO_MODE_SWITCH_STATE_MOMENTARY = 3;
- private static final int AUTO_MODE_SWITCH_STATE_CHORDING = 4;
- private int mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_ALPHA;
+ private static final int SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL = 3;
+ private static final int SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE = 4;
+ private static final int SWITCH_STATE_CHORDING_ALPHA = 5;
+ private static final int SWITCH_STATE_CHORDING_SYMBOL = 6;
+ private int mSwitchState = SWITCH_STATE_ALPHA;
// Indicates whether or not we have the settings key in option of settings
private boolean mSettingsKeyEnabledInSettings;
@@ -124,7 +129,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
public void loadKeyboard(EditorInfo attribute, boolean voiceKeyEnabled,
boolean voiceButtonOnPrimary) {
- mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_ALPHA;
+ mSwitchState = SWITCH_STATE_ALPHA;
try {
loadKeyboardInternal(attribute, voiceKeyEnabled, voiceButtonOnPrimary, false);
} catch (RuntimeException e) {
@@ -164,7 +169,8 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
final SoftReference ref = mKeyboardCache.get(id);
LatinKeyboard keyboard = (ref == null) ? null : ref.get();
if (keyboard == null) {
- final Locale savedLocale = mSubtypeSwitcher.changeSystemLocale(
+ final Resources res = mInputMethodService.getResources();
+ final Locale savedLocale = Utils.setSystemLocale(res,
mSubtypeSwitcher.getInputLocale());
keyboard = new LatinKeyboard(mInputMethodService, id);
@@ -178,7 +184,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
Log.d(TAG, "keyboard cache size=" + mKeyboardCache.size() + ": "
+ ((ref == null) ? "LOAD" : "GCed") + " id=" + id);
- mSubtypeSwitcher.changeSystemLocale(savedLocale);
+ Utils.setSystemLocale(res, savedLocale);
} else if (DEBUG) {
Log.d(TAG, "keyboard cache size=" + mKeyboardCache.size() + ": HIT id=" + id);
}
@@ -465,6 +471,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
// In symbol mode, just toggle symbol and symbol more keyboard.
shiftKeyState.onPress();
toggleShift();
+ mSwitchState = SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE;
}
}
@@ -486,6 +493,10 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
} else if (isShiftLocked() && !shiftKeyState.isIgnoring() && !withSliding) {
// Shift has been pressed without chording while caps lock state.
toggleCapsLock();
+ // To be able to turn off caps lock by "double tap" on shift key, we should ignore
+ // the second tap of the "double tap" from now for a while because we just have
+ // already turned off caps lock above.
+ mInputView.startIgnoringDoubleTap();
} else if (isShiftedOrShiftLocked() && shiftKeyState.isPressingOnShifted()
&& !withSliding) {
// Shift has been pressed without chording while shifted state.
@@ -496,6 +507,12 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
// transited from automatic temporary upper case.
toggleShift();
}
+ } else {
+ // In symbol mode, snap back to the previous keyboard mode if the user chords the shift
+ // key and another key, then releases the shift key.
+ if (mSwitchState == SWITCH_STATE_CHORDING_SYMBOL) {
+ toggleShift();
+ }
}
shiftKeyState.onRelease();
}
@@ -510,7 +527,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
+ " symbolKeyState=" + mSymbolKeyState);
changeKeyboardMode();
mSymbolKeyState.onPress();
- mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_MOMENTARY;
+ mSwitchState = SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL;
}
public void onReleaseSymbol() {
@@ -522,9 +539,10 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
+ " keyboard=" + getLatinKeyboard().getKeyboardShiftState()
+ " symbolKeyState=" + mSymbolKeyState);
// Snap back to the previous keyboard mode if the user chords the mode change key and
- // other key, then released the mode change key.
- if (mAutoModeSwitchState == AUTO_MODE_SWITCH_STATE_CHORDING)
+ // another key, then releases the mode change key.
+ if (mSwitchState == SWITCH_STATE_CHORDING_ALPHA) {
changeKeyboardMode();
+ }
mSymbolKeyState.onRelease();
}
@@ -543,8 +561,13 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
public void onCancelInput() {
// Snap back to the previous keyboard mode if the user cancels sliding input.
- if (mAutoModeSwitchState == AUTO_MODE_SWITCH_STATE_MOMENTARY && getPointerCount() == 1)
- changeKeyboardMode();
+ if (getPointerCount() == 1) {
+ if (mSwitchState == SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL) {
+ changeKeyboardMode();
+ } else if (mSwitchState == SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE) {
+ toggleShift();
+ }
+ }
}
private void toggleShiftInSymbol() {
@@ -567,8 +590,9 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
setKeyboard(keyboard);
}
- public boolean isInMomentaryAutoModeSwitchState() {
- return mAutoModeSwitchState == AUTO_MODE_SWITCH_STATE_MOMENTARY;
+ public boolean isInMomentarySwitchState() {
+ return mSwitchState == SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL
+ || mSwitchState == SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE;
}
public boolean isVibrateAndSoundFeedbackRequired() {
@@ -582,9 +606,9 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
private void toggleKeyboardMode() {
loadKeyboardInternal(mAttribute, mVoiceKeyEnabled, mVoiceButtonOnPrimary, !mIsSymbols);
if (mIsSymbols) {
- mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_SYMBOL_BEGIN;
+ mSwitchState = SWITCH_STATE_SYMBOL_BEGIN;
} else {
- mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_ALPHA;
+ mSwitchState = SWITCH_STATE_ALPHA;
}
}
@@ -596,28 +620,52 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
return mInputView != null && mInputView.hasDistinctMultitouch();
}
+ private static boolean isSpaceCharacter(int c) {
+ return c == Keyboard.CODE_SPACE || c == Keyboard.CODE_ENTER;
+ }
+
+ private static boolean isQuoteCharacter(int c) {
+ // Apostrophe, quotation mark.
+ if (c == '\'' || c == '"')
+ return true;
+ // \u2018: Left single quotation mark
+ // \u2019: Right single quotation mark
+ // \u201a: Single low-9 quotation mark
+ // \u201b: Single high-reversed-9 quotation mark
+ // \u201c: Left double quotation mark
+ // \u201d: Right double quotation mark
+ // \u201e: Double low-9 quotation mark
+ // \u201f: Double high-reversed-9 quotation mark
+ if (c >= '\u2018' && c <= '\u201f')
+ return true;
+ // \u00ab: Left-pointing double angle quotation mark
+ // \u00bb: Right-pointing double angle quotation mark
+ if (c == '\u00ab' || c == '\u00bb')
+ return true;
+ return false;
+ }
+
/**
* Updates state machine to figure out when to automatically snap back to the previous mode.
*/
- public void onKey(int key) {
+ public void onKey(int code) {
if (DEBUG_STATE)
- Log.d(TAG, "onKey: code=" + key + " autoModeSwitchState=" + mAutoModeSwitchState
+ Log.d(TAG, "onKey: code=" + code + " switchState=" + mSwitchState
+ " pointers=" + getPointerCount());
- switch (mAutoModeSwitchState) {
- case AUTO_MODE_SWITCH_STATE_MOMENTARY:
+ switch (mSwitchState) {
+ case SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL:
// Only distinct multi touch devices can be in this state.
// On non-distinct multi touch devices, mode change key is handled by
// {@link LatinIME#onCodeInput}, not by {@link LatinIME#onPress} and
- // {@link LatinIME#onRelease}. So, on such devices, {@link #mAutoModeSwitchState} starts
- // from {@link #AUTO_MODE_SWITCH_STATE_SYMBOL_BEGIN}, or
- // {@link #AUTO_MODE_SWITCH_STATE_ALPHA}, not from
- // {@link #AUTO_MODE_SWITCH_STATE_MOMENTARY}.
- if (key == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) {
+ // {@link LatinIME#onRelease}. So, on such devices, {@link #mSwitchState} starts
+ // from {@link #SWITCH_STATE_SYMBOL_BEGIN}, or {@link #SWITCH_STATE_ALPHA}, not from
+ // {@link #SWITCH_STATE_MOMENTARY}.
+ if (code == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) {
// Detected only the mode change key has been pressed, and then released.
if (mIsSymbols) {
- mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_SYMBOL_BEGIN;
+ mSwitchState = SWITCH_STATE_SYMBOL_BEGIN;
} else {
- mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_ALPHA;
+ mSwitchState = SWITCH_STATE_ALPHA;
}
} else if (getPointerCount() == 1) {
// Snap back to the previous keyboard mode if the user pressed the mode change key
@@ -628,18 +676,34 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
} else {
// Chording input is being started. The keyboard mode will be snapped back to the
// previous mode in {@link onReleaseSymbol} when the mode change key is released.
- mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_CHORDING;
+ mSwitchState = SWITCH_STATE_CHORDING_ALPHA;
}
break;
- case AUTO_MODE_SWITCH_STATE_SYMBOL_BEGIN:
- if (key != Keyboard.CODE_SPACE && key != Keyboard.CODE_ENTER && key >= 0) {
- mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_SYMBOL;
+ case SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE:
+ if (code == Keyboard.CODE_SHIFT) {
+ // Detected only the shift key has been pressed on symbol layout, and then released.
+ mSwitchState = SWITCH_STATE_SYMBOL_BEGIN;
+ } else if (getPointerCount() == 1) {
+ // Snap back to the previous keyboard mode if the user pressed the shift key on
+ // symbol mode and slid to other key, then released the finger.
+ toggleShift();
+ mSwitchState = SWITCH_STATE_SYMBOL;
+ } else {
+ // Chording input is being started. The keyboard mode will be snapped back to the
+ // previous mode in {@link onReleaseShift} when the shift key is released.
+ mSwitchState = SWITCH_STATE_CHORDING_SYMBOL;
}
break;
- case AUTO_MODE_SWITCH_STATE_SYMBOL:
+ case SWITCH_STATE_SYMBOL_BEGIN:
+ if (!isSpaceCharacter(code) && code >= 0) {
+ mSwitchState = SWITCH_STATE_SYMBOL;
+ }
+ break;
+ case SWITCH_STATE_SYMBOL:
+ case SWITCH_STATE_CHORDING_SYMBOL:
// Snap back to alpha keyboard mode if user types one or more non-space/enter
- // characters followed by a space/enter.
- if (key == Keyboard.CODE_ENTER || key == Keyboard.CODE_SPACE) {
+ // characters followed by a space/enter or quotation mark.
+ if (isSpaceCharacter(code) || isQuoteCharacter(code)) {
changeKeyboardMode();
}
break;
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
index c36895258..11476e069 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
@@ -44,6 +44,7 @@ import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
+import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
@@ -73,7 +74,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
private static final boolean DEBUG_SHOW_ALIGN = false;
private static final boolean DEBUG_KEYBOARD_GRID = false;
- private static final boolean ENABLE_CAPSLOCK_BY_LONGPRESS = false;
+ private static final boolean ENABLE_CAPSLOCK_BY_LONGPRESS = true;
private static final boolean ENABLE_CAPSLOCK_BY_DOUBLETAP = true;
public static final int COLOR_SCHEME_WHITE = 0;
@@ -189,6 +190,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
private static final int MSG_REPEAT_KEY = 3;
private static final int MSG_LONGPRESS_KEY = 4;
private static final int MSG_LONGPRESS_SHIFT_KEY = 5;
+ private static final int MSG_IGNORE_DOUBLE_TAP = 6;
private boolean mInKeyRepeat;
@@ -286,6 +288,16 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
public void cancelKeyTimers() {
cancelKeyRepeatTimer();
cancelLongPressTimers();
+ removeMessages(MSG_IGNORE_DOUBLE_TAP);
+ }
+
+ public void startIgnoringDoubleTap() {
+ sendMessageDelayed(obtainMessage(MSG_IGNORE_DOUBLE_TAP),
+ ViewConfiguration.getDoubleTapTimeout());
+ }
+
+ public boolean isIgnoringDoubleTap() {
+ return hasMessages(MSG_IGNORE_DOUBLE_TAP);
}
public void cancelAllMessages() {
@@ -449,7 +461,12 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
final PointerTracker tracker = getPointerTracker(id);
// If the second down event is also on shift key.
if (tracker.isOnShiftKey((int)secondDown.getX(), (int)secondDown.getY())) {
- onDoubleTapShiftKey(tracker);
+ // Detected a double tap on shift key. If we are in the ignoring double tap
+ // mode, it means we have already turned off caps lock in
+ // {@link KeyboardSwitcher#onReleaseShift} .
+ final boolean ignoringDoubleTap = mHandler.isIgnoringDoubleTap();
+ if (!ignoringDoubleTap)
+ onDoubleTapShiftKey(tracker);
return true;
}
// Otherwise these events should not be handled as double tap.
@@ -468,6 +485,11 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
mKeyRepeatInterval = res.getInteger(R.integer.config_key_repeat_interval);
}
+ public void startIgnoringDoubleTap() {
+ if (ENABLE_CAPSLOCK_BY_DOUBLETAP)
+ mHandler.startIgnoringDoubleTap();
+ }
+
public void setOnKeyboardActionListener(KeyboardActionListener listener) {
mKeyboardActionListener = listener;
for (PointerTracker tracker : mPointerTrackers) {
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index e3161f610..abd1ef286 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -662,7 +662,7 @@ public class PointerTracker {
// We need not start long press timer on the key which has manual temporary upper case
// code defined and the keyboard is in manual temporary upper case mode.
return;
- } else if (mKeyboardSwitcher.isInMomentaryAutoModeSwitchState()) {
+ } else if (mKeyboardSwitcher.isInMomentarySwitchState()) {
// We use longer timeout for sliding finger input started from the symbols mode key.
mHandler.startLongPressTimer(mLongPressKeyTimeout * 3, keyIndex, this);
} else {
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index 7e63aacdf..d95fb9638 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -21,12 +21,8 @@ import com.android.inputmethod.keyboard.KeyboardSwitcher;
import com.android.inputmethod.keyboard.ProximityInfo;
import android.content.Context;
-import android.content.res.AssetFileDescriptor;
-import android.util.Log;
-import java.io.File;
import java.util.Arrays;
-import java.util.Locale;
/**
* Implements a static, compacted, binary dictionary of standard words.
@@ -45,16 +41,15 @@ public class BinaryDictionary extends Dictionary {
public static final int MAX_WORD_LENGTH = 48;
public static final int MAX_WORDS = 18;
+ @SuppressWarnings("unused")
private static final String TAG = "BinaryDictionary";
private static final int MAX_PROXIMITY_CHARS_SIZE = ProximityInfo.MAX_PROXIMITY_CHARS_SIZE;
private static final int MAX_BIGRAMS = 60;
private static final int TYPED_LETTER_MULTIPLIER = 2;
- private static final BinaryDictionary sInstance = new BinaryDictionary();
private int mDicTypeId;
private int mNativeDict;
- private long mDictLength;
private final int[] mInputCodes = new int[MAX_WORD_LENGTH * MAX_PROXIMITY_CHARS_SIZE];
private final char[] mOutputChars = new char[MAX_WORD_LENGTH * MAX_WORDS];
private final char[] mOutputChars_bigrams = new char[MAX_WORD_LENGTH * MAX_BIGRAMS];
@@ -79,95 +74,32 @@ public class BinaryDictionary extends Dictionary {
private int mFlags = 0;
- private BinaryDictionary() {
- }
-
/**
- * Initializes a dictionary from a raw resource file
- * @param context application context for reading resources
- * @param resId the resource containing the raw binary dictionary
- * @param dicTypeId the type of the dictionary being created, out of the list in Suggest.DIC_*
- * @return an initialized instance of BinaryDictionary
+ * Constructor for the binary dictionary. This is supposed to be called from the
+ * dictionary factory.
+ * All implementations should pass null into flagArray, except for testing purposes.
+ * @param context the context to access the environment from.
+ * @param filename the name of the file to read through native code.
+ * @param offset the offset of the dictionary data within the file.
+ * @param length the length of the binary data.
+ * @param flagArray the flags to limit the dictionary to, or null for default.
*/
- public static BinaryDictionary initDictionary(Context context, int resId, int dicTypeId) {
- synchronized (sInstance) {
- sInstance.closeInternal();
- try {
- final AssetFileDescriptor afd = context.getResources().openRawResourceFd(resId);
- if (afd == null) {
- Log.e(TAG, "Found the resource but it is compressed. resId=" + resId);
- return null;
- }
- final String sourceDir = context.getApplicationInfo().sourceDir;
- final File packagePath = new File(sourceDir);
- // TODO: Come up with a way to handle a directory.
- if (!packagePath.isFile()) {
- Log.e(TAG, "sourceDir is not a file: " + sourceDir);
- return null;
- }
- sInstance.loadDictionary(sourceDir, afd.getStartOffset(), afd.getLength());
- sInstance.mDicTypeId = dicTypeId;
- } catch (android.content.res.Resources.NotFoundException e) {
- Log.e(TAG, "Could not find the resource. resId=" + resId);
- return null;
- }
- }
- sInstance.mFlags = Flag.initFlags(ALL_FLAGS, context, SubtypeSwitcher.getInstance());
- return sInstance;
- }
-
- /* package for test */ static BinaryDictionary initDictionary(Context context, File dictionary,
- long startOffset, long length, int dicTypeId, Flag[] flagArray) {
- synchronized (sInstance) {
- sInstance.closeInternal();
- if (dictionary.isFile()) {
- sInstance.loadDictionary(dictionary.getAbsolutePath(), startOffset, length);
- sInstance.mDicTypeId = dicTypeId;
- } else {
- Log.e(TAG, "Could not find the file. path=" + dictionary.getAbsolutePath());
- return null;
- }
- }
- sInstance.mFlags = Flag.initFlags(flagArray, context, null);
- return sInstance;
+ public BinaryDictionary(final Context context,
+ final String filename, final long offset, final long length, Flag[] flagArray) {
+ // 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;
+ // TODO: Stop relying on the state of SubtypeSwitcher, get it as a parameter
+ mFlags = Flag.initFlags(null == flagArray ? ALL_FLAGS : flagArray, context,
+ SubtypeSwitcher.getInstance());
+ loadDictionary(filename, offset, length);
}
static {
Utils.loadNativeLibrary();
}
- /**
- * Initializes a dictionary from a dictionary pack.
- *
- * This searches for a content provider providing a dictionary pack for the specified
- * locale. If none is found, it falls back to using the resource passed as fallBackResId
- * as a dictionary.
- * @param context application context for reading resources
- * @param dicTypeId the type of the dictionary being created, out of the list in Suggest.DIC_*
- * @param locale the locale for which to create the dictionary
- * @param fallBackResId the id of the resource to use as a fallback if no pack is found
- * @return an initialized instance of BinaryDictionary
- */
- public static BinaryDictionary initDictionaryFromManager(Context context, int dicTypeId,
- Locale locale, int fallbackResId) {
- if (null == locale) {
- Log.e(TAG, "No locale defined for dictionary");
- return initDictionary(context, fallbackResId, dicTypeId);
- }
- synchronized (sInstance) {
- sInstance.closeInternal();
-
- final AssetFileAddress dictFile = BinaryDictionaryGetter.getDictionaryFile(locale,
- context, fallbackResId);
- if (null != dictFile) {
- sInstance.loadDictionary(dictFile.mFilename, dictFile.mOffset, dictFile.mLength);
- sInstance.mDicTypeId = dicTypeId;
- }
- }
- sInstance.mFlags = Flag.initFlags(ALL_FLAGS, context, SubtypeSwitcher.getInstance());
- return sInstance;
- }
-
private native int openNative(String sourceDir, long dictOffset, long dictSize,
int typedLetterMultiplier, int fullWordMultiplier, int maxWordLength,
int maxWords, int maxAlternatives);
@@ -184,7 +116,6 @@ public class BinaryDictionary extends Dictionary {
mNativeDict = openNative(path, startOffset, length,
TYPED_LETTER_MULTIPLIER, FULL_WORD_SCORE_MULTIPLIER,
MAX_WORD_LENGTH, MAX_WORDS, MAX_PROXIMITY_CHARS_SIZE);
- mDictLength = length;
}
@Override
@@ -278,10 +209,6 @@ public class BinaryDictionary extends Dictionary {
return isValidWordNative(mNativeDict, chars, chars.length);
}
- public long getSize() {
- return mDictLength; // This value is initialized in loadDictionary()
- }
-
@Override
public synchronized void close() {
closeInternal();
@@ -291,7 +218,6 @@ public class BinaryDictionary extends Dictionary {
if (mNativeDict != 0) {
closeNative(mNativeDict);
mNativeDict = 0;
- mDictLength = 0;
}
}
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
index 72512c7e1..c4e098a0c 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
@@ -65,9 +65,6 @@ class BinaryDictionaryGetter {
* If that fails:
* - Returns null.
* @return The address of a valid file, or null.
- * @throws FileNotFoundException if a dictionary provider returned a file name, but the
- * file cannot be found.
- * @throws IOException if there was an I/O problem reading or copying a file.
*/
public static AssetFileAddress getDictionaryFile(Locale locale, Context context,
int fallbackResId) {
diff --git a/java/src/com/android/inputmethod/latin/ContactsDictionary.java b/java/src/com/android/inputmethod/latin/ContactsDictionary.java
index 048f72dc5..bdb68cac7 100644
--- a/java/src/com/android/inputmethod/latin/ContactsDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ContactsDictionary.java
@@ -95,6 +95,14 @@ public class ContactsDictionary extends ExpandableDictionary {
mLastLoadedContacts = SystemClock.uptimeMillis();
}
+ @Override
+ public void getBigrams(final WordComposer codes, final CharSequence previousWord,
+ final WordCallback callback) {
+ // Do not return bigrams from Contacts when nothing was typed.
+ if (codes.size() <= 0) return;
+ super.getBigrams(codes, previousWord, callback);
+ }
+
private void addWords(Cursor cursor) {
clearDictionary();
diff --git a/java/src/com/android/inputmethod/latin/Dictionary.java b/java/src/com/android/inputmethod/latin/Dictionary.java
index ac43d6477..c7737b9a2 100644
--- a/java/src/com/android/inputmethod/latin/Dictionary.java
+++ b/java/src/com/android/inputmethod/latin/Dictionary.java
@@ -61,7 +61,7 @@ public abstract class Dictionary {
* words are added through the callback object.
* @param composer the key sequence to match
* @param callback the callback object to send matched words to as possible candidates
- * @see WordCallback#addWord(char[], int, int)
+ * @see WordCallback#addWord(char[], int, int, int, int, DataType)
*/
abstract public void getWords(final WordComposer composer, final WordCallback callback);
diff --git a/java/src/com/android/inputmethod/latin/DictionaryCollection.java b/java/src/com/android/inputmethod/latin/DictionaryCollection.java
new file mode 100644
index 000000000..4b64e5344
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/DictionaryCollection.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.android.inputmethod.latin;
+
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * Class for a collection of dictionaries that behave like one dictionary.
+ */
+public class DictionaryCollection extends Dictionary {
+
+ protected final List mDictionaries;
+
+ public DictionaryCollection() {
+ mDictionaries = new CopyOnWriteArrayList();
+ }
+
+ public DictionaryCollection(Dictionary... dictionaries) {
+ mDictionaries = new CopyOnWriteArrayList(dictionaries);
+ }
+
+ @Override
+ public void getWords(final WordComposer composer, final WordCallback callback) {
+ for (final Dictionary dict : mDictionaries)
+ dict.getWords(composer, callback);
+ }
+
+ @Override
+ public void getBigrams(final WordComposer composer, final CharSequence previousWord,
+ final WordCallback callback) {
+ for (final Dictionary dict : mDictionaries)
+ dict.getBigrams(composer, previousWord, callback);
+ }
+
+ @Override
+ public boolean isValidWord(CharSequence word) {
+ for (final Dictionary dict : mDictionaries)
+ if (dict.isValidWord(word)) return true;
+ return false;
+ }
+
+ @Override
+ public void close() {
+ for (final Dictionary dict : mDictionaries)
+ dict.close();
+ }
+
+ public void addDictionary(Dictionary newDict) {
+ mDictionaries.add(newDict);
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFactory.java b/java/src/com/android/inputmethod/latin/DictionaryFactory.java
new file mode 100644
index 000000000..2dbd582f3
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/DictionaryFactory.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.android.inputmethod.latin;
+
+import android.content.Context;
+import android.content.res.AssetFileDescriptor;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.util.Log;
+
+import java.io.File;
+import java.util.Locale;
+
+/**
+ * Factory for dictionary instances.
+ */
+public class DictionaryFactory {
+
+ private static String TAG = DictionaryFactory.class.getSimpleName();
+
+ /**
+ * Initializes a dictionary from a dictionary pack.
+ *
+ * This searches for a content provider providing a dictionary pack for the specified
+ * locale. If none is found, it falls back to using the resource passed as fallBackResId
+ * as a dictionary.
+ * @param context application context for reading resources
+ * @param locale the locale for which to create the dictionary
+ * @param fallbackResId the id of the resource to use as a fallback if no pack is found
+ * @return an initialized instance of Dictionary
+ */
+ public static Dictionary createDictionaryFromManager(Context context, Locale locale,
+ int fallbackResId) {
+ if (null == locale) {
+ Log.e(TAG, "No locale defined for dictionary");
+ return new DictionaryCollection(createBinaryDictionary(context, fallbackResId));
+ }
+
+ final AssetFileAddress dictFile = BinaryDictionaryGetter.getDictionaryFile(locale,
+ context, fallbackResId);
+ if (null == dictFile) return null;
+ return new DictionaryCollection(new BinaryDictionary(context,
+ dictFile.mFilename, dictFile.mOffset, dictFile.mLength, null));
+ }
+
+ /**
+ * Initializes a dictionary from a raw resource file
+ * @param context application context for reading resources
+ * @param resId the resource containing the raw binary dictionary
+ * @return an initialized instance of BinaryDictionary
+ */
+ protected static BinaryDictionary createBinaryDictionary(Context context, int resId) {
+ AssetFileDescriptor afd = null;
+ try {
+ // TODO: IMPORTANT: Do not create a dictionary from a placeholder.
+ afd = context.getResources().openRawResourceFd(resId);
+ if (afd == null) {
+ Log.e(TAG, "Found the resource but it is compressed. resId=" + resId);
+ return null;
+ }
+ if (!isFullDictionary(afd)) return null;
+ final String sourceDir = context.getApplicationInfo().sourceDir;
+ final File packagePath = new File(sourceDir);
+ // TODO: Come up with a way to handle a directory.
+ if (!packagePath.isFile()) {
+ Log.e(TAG, "sourceDir is not a file: " + sourceDir);
+ return null;
+ }
+ return new BinaryDictionary(context,
+ sourceDir, afd.getStartOffset(), afd.getLength(), null);
+ } catch (android.content.res.Resources.NotFoundException e) {
+ Log.e(TAG, "Could not find the resource. resId=" + resId);
+ return null;
+ } finally {
+ if (null != afd) {
+ try {
+ afd.close();
+ } catch (java.io.IOException e) {
+ /* IOException on close ? What am I supposed to do ? */
+ }
+ }
+ }
+ }
+
+ /**
+ * Create a dictionary from passed data. This is intended for unit tests only.
+ * @param context the test context to create this data from.
+ * @param dictionary the file to read
+ * @param startOffset the offset in the file where the data starts
+ * @param length the length of the data
+ * @param flagArray the flags to use with this data for testing
+ * @return the created dictionary, or null.
+ */
+ public static Dictionary createDictionaryForTest(Context context, File dictionary,
+ long startOffset, long length, Flag[] flagArray) {
+ if (dictionary.isFile()) {
+ return new BinaryDictionary(context, dictionary.getAbsolutePath(), startOffset, length,
+ flagArray);
+ } else {
+ Log.e(TAG, "Could not find the file. path=" + dictionary.getAbsolutePath());
+ return null;
+ }
+ }
+
+ /**
+ * Find out whether a dictionary is available for this locale.
+ * @param context the context on which to check resources.
+ * @param locale the locale to check for.
+ * @return whether a (non-placeholder) dictionary is available or not.
+ */
+ public static boolean isDictionaryAvailable(Context context, Locale locale) {
+ final Resources res = context.getResources();
+ final Locale saveLocale = Utils.setSystemLocale(res, locale);
+
+ final int resourceId = Utils.getMainDictionaryResourceId(res);
+ final AssetFileDescriptor afd = res.openRawResourceFd(resourceId);
+ final boolean hasDictionary = isFullDictionary(afd);
+ try {
+ if (null != afd) afd.close();
+ } catch (java.io.IOException e) {
+ /* Um, what can we do here exactly? */
+ }
+
+ Utils.setSystemLocale(res, saveLocale);
+ return hasDictionary;
+ }
+
+ // TODO: Find the Right Way to find out whether the resource is a placeholder or not.
+ // Suggestion : strip the locale, open the placeholder file and store its offset.
+ // Upon opening the file, if it's the same offset, then it's the placeholder.
+ private static final long PLACEHOLDER_LENGTH = 34;
+ /**
+ * Finds out whether the data pointed out by an AssetFileDescriptor is a full
+ * dictionary (as opposed to null, or to a place holder).
+ * @param afd the file descriptor to test, or null
+ * @return true if the dictionary is a real full dictionary, false if it's null or a placeholder
+ */
+ protected static boolean isFullDictionary(final AssetFileDescriptor afd) {
+ return (afd != null && afd.getLength() > PLACEHOLDER_LENGTH);
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/EditingUtils.java b/java/src/com/android/inputmethod/latin/EditingUtils.java
index ea281f5b8..39e7e402f 100644
--- a/java/src/com/android/inputmethod/latin/EditingUtils.java
+++ b/java/src/com/android/inputmethod/latin/EditingUtils.java
@@ -73,7 +73,7 @@ public class EditingUtils {
/**
* @param connection connection to the current text field.
- * @param sep characters which may separate words
+ * @param separators characters which may separate words
* @return the word that surrounds the cursor, including up to one trailing
* separator. For example, if the field contains "he|llo world", where |
* represents the cursor, then "hello " will be returned.
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 28fd6aad7..39bc78e20 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -112,7 +112,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
private static final int DELAY_UPDATE_SUGGESTIONS = 180;
private static final int DELAY_UPDATE_OLD_SUGGESTIONS = 300;
- private static final int DELAY_UPDATE_SHIFT_STATE = 300;
+ private static final int DELAY_UPDATE_SHIFT_STATE = 100;
private static final int EXTENDED_TOUCHABLE_REGION_HEIGHT = 100;
// How many continuous deletes at which to start deleting at a higher speed.
@@ -470,14 +470,14 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
final String localeStr = mSubtypeSwitcher.getInputLocaleStr();
final Locale keyboardLocale = new Locale(localeStr);
- final Locale savedLocale = mSubtypeSwitcher.changeSystemLocale(keyboardLocale);
+ final Resources res = mResources;
+ final Locale savedLocale = Utils.setSystemLocale(res, keyboardLocale);
if (mSuggest != null) {
mSuggest.close();
}
final SharedPreferences prefs = mPrefs;
mQuickFixes = isQuickFixesEnabled(prefs);
- final Resources res = mResources;
int mainDicResId = Utils.getMainDictionaryResourceId(res);
mSuggest = new Suggest(this, mainDicResId, keyboardLocale);
loadAndSetAutoCorrectionThreshold(prefs);
@@ -499,7 +499,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
mWordSeparators = res.getString(R.string.word_separators);
mSentenceSeparators = res.getString(R.string.sentence_separators);
- mSubtypeSwitcher.changeSystemLocale(savedLocale);
+ Utils.setSystemLocale(res, savedLocale);
}
/* package private */ void resetSuggestMainDict() {
diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
index 158977927..d8012087b 100644
--- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
+++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
@@ -475,19 +475,6 @@ public class SubtypeSwitcher {
}
}
- /**
- * Change system locale for this application
- * @param newLocale
- * @return oldLocale
- */
- public Locale changeSystemLocale(Locale newLocale) {
- Configuration conf = mResources.getConfiguration();
- Locale oldLocale = conf.locale;
- conf.locale = newLocale;
- mResources.updateConfiguration(conf, mResources.getDisplayMetrics());
- return oldLocale;
- }
-
public boolean isKeyboardMode() {
return KEYBOARD_MODE.equals(getCurrentSubtypeMode());
}
@@ -608,7 +595,7 @@ public class SubtypeSwitcher {
}
public static String getMiddleDisplayLanguage(Locale locale) {
- return toTitleCase(locale.getDisplayLanguage(new Locale(locale.getLanguage())));
+ return toTitleCase((new Locale(locale.getLanguage()).getDisplayLanguage(locale)));
}
public static String getShortDisplayLanguage(Locale locale) {
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index 15743ee2d..ca75866c0 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -56,7 +56,7 @@ public class Suggest implements Dictionary.WordCallback {
/**
* Maximum possible bigram frequency. Will depend on how many bits are being used in data
- * structure. Maximum bigram freqeuncy will get the BIGRAM_MULTIPLIER_MAX as the multiplier.
+ * structure. Maximum bigram frequency will get the BIGRAM_MULTIPLIER_MAX as the multiplier.
*/
public static final int MAXIMUM_BIGRAM_FREQUENCY = 127;
@@ -75,13 +75,11 @@ public class Suggest implements Dictionary.WordCallback {
public static final String DICT_KEY_USER_BIGRAM = "user_bigram";
public static final String DICT_KEY_WHITELIST ="whitelist";
- public static final int LARGE_DICTIONARY_THRESHOLD = 200 * 1000;
-
private static final boolean DBG = LatinImeLogger.sDBG;
private AutoCorrection mAutoCorrection;
- private BinaryDictionary mMainDict;
+ private Dictionary mMainDict;
private WhitelistDictionary mWhiteListDictionary;
private final Map mUnigramDictionaries = new HashMap();
private final Map mBigramDictionaries = new HashMap();
@@ -108,17 +106,17 @@ public class Suggest implements Dictionary.WordCallback {
private int mCorrectionMode = CORRECTION_BASIC;
public Suggest(Context context, int dictionaryResId, Locale locale) {
- init(context, BinaryDictionary.initDictionaryFromManager(context, DIC_MAIN, locale,
+ init(context, DictionaryFactory.createDictionaryFromManager(context, locale,
dictionaryResId));
}
/* package for test */ Suggest(Context context, File dictionary, long startOffset, long length,
Flag[] flagArray) {
- init(null, BinaryDictionary.initDictionary(context, dictionary, startOffset, length,
- DIC_MAIN, flagArray));
+ init(null, DictionaryFactory.createDictionaryForTest(context, dictionary, startOffset,
+ length, flagArray));
}
- private void init(Context context, BinaryDictionary mainDict) {
+ private void init(Context context, Dictionary mainDict) {
if (mainDict != null) {
mMainDict = mainDict;
mUnigramDictionaries.put(DICT_KEY_MAIN, mainDict);
@@ -133,8 +131,8 @@ public class Suggest implements Dictionary.WordCallback {
}
public void resetMainDict(Context context, int dictionaryResId, Locale locale) {
- final BinaryDictionary newMainDict = BinaryDictionary.initDictionaryFromManager(context,
- DIC_MAIN, locale, dictionaryResId);
+ final Dictionary newMainDict = DictionaryFactory.createDictionaryFromManager(
+ context, locale, dictionaryResId);
mMainDict = newMainDict;
if (null == newMainDict) {
mUnigramDictionaries.remove(DICT_KEY_MAIN);
@@ -165,7 +163,7 @@ public class Suggest implements Dictionary.WordCallback {
}
public boolean hasMainDictionary() {
- return mMainDict != null && mMainDict.getSize() > LARGE_DICTIONARY_THRESHOLD;
+ return mMainDict != null;
}
public Map getUnigramDictionaries() {
diff --git a/java/src/com/android/inputmethod/latin/Utils.java b/java/src/com/android/inputmethod/latin/Utils.java
index 9244e4560..47890e643 100644
--- a/java/src/com/android/inputmethod/latin/Utils.java
+++ b/java/src/com/android/inputmethod/latin/Utils.java
@@ -23,6 +23,7 @@ import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.keyboard.KeyboardId;
import android.content.Context;
+import android.content.res.Configuration;
import android.content.res.Resources;
import android.inputmethodservice.InputMethodService;
import android.os.AsyncTask;
@@ -43,11 +44,13 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
+import java.util.Locale;
public class Utils {
private static final String TAG = Utils.class.getSimpleName();
private static final int MINIMUM_SAFETY_NET_CHAR_LENGTH = 4;
private static boolean DBG = LatinImeLogger.sDBG;
+ private static boolean DBG_EDIT_DISTANCE = false;
private Utils() {
// Intentional empty constructor for utility class.
@@ -289,7 +292,7 @@ public class Utils {
}
}
}
- if (LatinImeLogger.sDBG) {
+ if (DBG_EDIT_DISTANCE) {
Log.d(TAG, "editDistance:" + s + "," + t);
for (int i = 0; i < dp.length; ++i) {
StringBuffer sb = new StringBuffer();
@@ -338,6 +341,7 @@ public class Utils {
private static final int MAX_INITIAL_SCORE = 255;
private static final int TYPED_LETTER_MULTIPLIER = 2;
private static final int FULL_WORD_MULTIPLIER = 2;
+ private static final int S_INT_MAX = 2147483647;
public static double calcNormalizedScore(CharSequence before, CharSequence after, int score) {
final int beforeLength = before.length();
final int afterLength = after.length();
@@ -352,7 +356,7 @@ public class Utils {
}
}
if (spaceCount == afterLength) return 0;
- final double maximumScore = MAX_INITIAL_SCORE
+ final double maximumScore = score == S_INT_MAX ? S_INT_MAX : MAX_INITIAL_SCORE
* Math.pow(
TYPED_LETTER_MULTIPLIER, Math.min(beforeLength, afterLength - spaceCount))
* FULL_WORD_MULTIPLIER;
@@ -648,6 +652,14 @@ public class Utils {
/** Convert pixel to DIP */
public static int dipToPixel(float scale, int dip) {
- return (int) ((float) dip * scale + 0.5);
+ return (int) (dip * scale + 0.5);
+ }
+
+ public static Locale setSystemLocale(Resources res, Locale newLocale) {
+ final Configuration conf = res.getConfiguration();
+ final Locale saveLocale = conf.locale;
+ conf.locale = newLocale;
+ res.updateConfiguration(conf, res.getDisplayMetrics());
+ return saveLocale;
}
}
diff --git a/native/src/unigram_dictionary.cpp b/native/src/unigram_dictionary.cpp
index b9f4b961d..20a185219 100644
--- a/native/src/unigram_dictionary.cpp
+++ b/native/src/unigram_dictionary.cpp
@@ -300,7 +300,7 @@ bool UnigramDictionary::addWord(unsigned short *word, int length, int frequency)
if (DEBUG_DICT) {
char s[length + 1];
for (int i = 0; i <= length; i++) s[i] = word[i];
- LOGI("Added word = %s, freq = %d", s, frequency);
+ LOGI("Added word = %s, freq = %d, %d", s, frequency, S_INT_MAX);
}
memmove((char*) mFrequencies + (insertAt + 1) * sizeof(mFrequencies[0]),
(char*) mFrequencies + insertAt * sizeof(mFrequencies[0]),
@@ -409,11 +409,44 @@ void UnigramDictionary::getSuggestionCandidates(const int skipPos,
}
}
-inline static void multiplyRate(const int rate, int *freq) {
- if (rate > 1000000) {
- *freq = (*freq / 100) * rate;
+static const int TWO_31ST_DIV_255 = S_INT_MAX / 255;
+static inline int capped255MultForFullMatchAccentsOrCapitalizationDifference(const int num) {
+ return (num < TWO_31ST_DIV_255 ? 255 * num : S_INT_MAX);
+}
+
+static const int TWO_31ST_DIV_2 = S_INT_MAX / 2;
+inline static void multiplyIntCapped(const int multiplier, int *base) {
+ const int temp = *base;
+ if (temp != S_INT_MAX) {
+ // Branch if multiplier == 2 for the optimization
+ if (multiplier == 2) {
+ *base = TWO_31ST_DIV_2 >= temp ? temp << 1 : S_INT_MAX;
+ } else {
+ const int tempRetval = temp * multiplier;
+ *base = tempRetval >= temp ? tempRetval : S_INT_MAX;
+ }
+ }
+}
+
+inline static int powerIntCapped(const int base, const int n) {
+ if (base == 2) {
+ return n < 31 ? 1 << n : S_INT_MAX;
} else {
- *freq = *freq * rate / 100;
+ int ret = base;
+ for (int i = 1; i < n; ++i) multiplyIntCapped(base, &ret);
+ return ret;
+ }
+}
+
+inline static void multiplyRate(const int rate, int *freq) {
+ if (*freq != S_INT_MAX) {
+ if (*freq > 1000000) {
+ *freq /= 100;
+ multiplyIntCapped(rate, freq);
+ } else {
+ multiplyIntCapped(rate, freq);
+ *freq /= 100;
+ }
}
}
@@ -449,9 +482,7 @@ inline static int calcFreqForSplitTwoWords(
// (firstFreq * (1 - 1 / (firstWordLength + 1)) + secondFreq * (1 - 1 / (secondWordLength + 1)))
// * (1 - 1 / totalLength) / (1 - 1 / (totalLength + 1))
- for (int i = 0; i < totalLength; ++i) {
- totalFreq *= typedLetterMultiplier;
- }
+ multiplyIntCapped(powerIntCapped(typedLetterMultiplier, totalLength), &totalFreq);
// This is another workaround to offset the demotion which will be done in
// calcNormalizedScore in Utils.java.
@@ -499,7 +530,7 @@ bool UnigramDictionary::getSplitTwoWordsSuggestion(const int inputLength,
int pairFreq = calcFreqForSplitTwoWords(
TYPED_LETTER_MULTIPLIER, firstWordLength, secondWordLength, firstFreq, secondFreq);
if (DEBUG_DICT) {
- LOGI("Missing space: %d, %d, %d, %d, %d", firstFreq, secondFreq, pairFreq, inputLength,
+ LOGI("Split two words: %d, %d, %d, %d, %d", firstFreq, secondFreq, pairFreq, inputLength,
TYPED_LETTER_MULTIPLIER);
}
addWord(word, newWordLength, pairFreq);
@@ -559,10 +590,6 @@ void UnigramDictionary::getWordsRec(const int childrenCount, const int pos, cons
}
}
-static const int TWO_31ST_DIV_255 = S_INT_MAX / 255;
-static inline int capped255MultForFullMatchAccentsOrCapitalizationDifference(const int num) {
- return (num < TWO_31ST_DIV_255 ? 255 * num : S_INT_MAX);
-}
inline int UnigramDictionary::calculateFinalFreq(const int inputIndex, const int depth,
const int matchWeight, const int skipPos, const int excessivePos, const int transposedPos,
const int freq, const bool sameLength) const {
@@ -591,7 +618,7 @@ inline int UnigramDictionary::calculateFinalFreq(const int inputIndex, const int
}
}
int lengthFreq = TYPED_LETTER_MULTIPLIER;
- for (int i = 0; i < depth; ++i) lengthFreq *= TYPED_LETTER_MULTIPLIER;
+ multiplyIntCapped(powerIntCapped(TYPED_LETTER_MULTIPLIER, depth), &lengthFreq);
if (lengthFreq == matchWeight) {
// Full exact match
if (depth > 1) {
@@ -608,13 +635,13 @@ inline int UnigramDictionary::calculateFinalFreq(const int inputIndex, const int
if (DEBUG_DICT) {
LOGI("Found one proximity correction.");
}
- finalFreq *= 2;
+ multiplyIntCapped(TYPED_LETTER_MULTIPLIER, &finalFreq);
multiplyRate(WORDS_WITH_PROXIMITY_CHARACTER_DEMOTION_RATE, &finalFreq);
}
if (DEBUG_DICT) {
LOGI("calc: %d, %d", depth, sameLength);
}
- if (sameLength) finalFreq *= FULL_WORD_MULTIPLIER;
+ if (sameLength) multiplyIntCapped(FULL_WORD_MULTIPLIER, &finalFreq);
return finalFreq;
}
@@ -767,7 +794,7 @@ inline bool UnigramDictionary::processCurrentNode(const int pos, const int depth
// If inputIndex is greater than mInputLength, that means there is no
// proximity chars. So, we don't need to check proximity.
if (SAME_OR_ACCENTED_OR_CAPITALIZED_CHAR == matchedProximityCharId) {
- matchWeight = matchWeight * TYPED_LETTER_MULTIPLIER;
+ multiplyIntCapped(TYPED_LETTER_MULTIPLIER, &matchWeight);
}
bool isSameAsUserTypedLength = mInputLength == inputIndex + 1
|| (excessivePos == mInputLength - 1 && inputIndex == mInputLength - 2);