1
0
Fork 0

Settings in SharedPreferences (#36)

* moved all settings from SQLite to SharedPreferences. The database now contains only dictionaries.

* removed key remapping, dictionary backup and nuke functions along with a bunch of unused code and translations
This commit is contained in:
Dimo Karaivanov 2022-08-05 14:18:53 +03:00 committed by GitHub
parent 8a025297c3
commit 5d3894e403
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 645 additions and 1460 deletions

View file

@ -46,7 +46,6 @@ To support a new language one needs to:
- Add translations for arrays.xml and strings.xml in to new files in the appropriate locale folder (e.g. res/values-de/arrays.xml.) AndroidStudio has a cute/nice Translation Editor which might be handy. - Add translations for arrays.xml and strings.xml in to new files in the appropriate locale folder (e.g. res/values-de/arrays.xml.) AndroidStudio has a cute/nice Translation Editor which might be handy.
- Edit the base arrays.xml file to add the new language. (pref_lang_titles, pref_lang_values) - Edit the base arrays.xml file to add the new language. (pref_lang_titles, pref_lang_values)
- Exclude translatable="false" items from the new locale arrays.xml file. - Exclude translatable="false" items from the new locale arrays.xml file.
- Also make sure the new language is added to pref_loaduserdictdesc (base non-locale strings.xml)
- Find a suitable dictionary and add it to assets - Find a suitable dictionary and add it to assets
That should be it? I hope. That should be it? I hope.

View file

@ -11,6 +11,7 @@ apply plugin: 'com.android.application'
dependencies { dependencies {
implementation "androidx.core:core:1.6.0" implementation "androidx.core:core:1.6.0"
implementation 'androidx.preference:preference:1.1.1'
} }
repositories { repositories {

View file

@ -41,9 +41,6 @@ Insert symbol or Add word depending on state and context. Add word only availabl
## Configuration Options ## Configuration Options
TODO... TODO...
### Key Remapping
See [the original manual](https://github.com/Clam-/TraditionalT9/wiki/Key-remapping).
## License ## License
- The source code, the logo image and the icons are licensed under [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0). - The source code, the logo image and the icons are licensed under [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0).
- The word lists / dictionaries are licensed under the licenses provided in the respective readme files found in the source code, where applicable. - The word lists / dictionaries are licensed under the licenses provided in the respective readme files found in the source code, where applicable.

View file

@ -27,7 +27,6 @@
<string name="title_activity_add_word">Добавяне на дума</string> <string name="title_activity_add_word">Добавяне на дума</string>
<string name="action_settings">Настройки</string> <string name="action_settings">Настройки</string>
<string name="database_notready">Базата данни е недостъпна.</string> <string name="database_notready">Базата данни е недостъпна.</string>
<string name="database_settings_notready">Базата данни е недостъпна. Зареждане на стандартни настройки.</string>
<string name="updating_database_title">Обновяване на речника…</string> <string name="updating_database_title">Обновяване на речника…</string>
<string name="updating_database">Речникът се обновява, моля изчакайте…</string> <string name="updating_database">Речникът се обновява, моля изчакайте…</string>
@ -38,35 +37,10 @@
<string name="pref_help">Помощ</string> <string name="pref_help">Помощ</string>
<string name="pref_loaddict">Зареди заводски речник</string> <string name="pref_loaddict">Зареди заводски речник</string>
<string name="pref_loaduserdict">Зареди собствен речник</string> <string name="pref_loaduserdict">Зареди собствен речник</string>
<string name="pref_nukedict">Изтрий собствен речник</string>
<string name="pref_backupdict">Резервно копие на речник</string>
<string name="pref_restoredict">Възстанови копие</string>
<string name="pref_querytest">Query test</string>
<string name="pref_testfunc">Test func</string>
<string name="pref_loadingdict">Зареждане на речник…</string> <string name="pref_loadingdict">Зареждане на речник…</string>
<string name="pref_loadinguserdict">Зареждане на вашия речник…</string> <string name="pref_loadinguserdict">Зареждане на вашия речник…</string>
<string name="pref_load_title">Зареди речник</string> <string name="pref_load_title">Зареди речник</string>
<string name="pref_loadingbackup">Възстановяване на речник…</string>
<string name="pref_savingbackup">Създаване на резервно копие…</string>
<string name="pref_nukingdict">Изтриване на речник…</string>
<string name="pref_loaduser_notfound">Няма речник за %1$s. Не може да се зареди такъв.</string> <string name="pref_loaduser_notfound">Няма речник за %1$s. Не може да се зареди такъв.</string>
<string name="pref_backup_warn">Внимание! Вече съществува резервно копие на речника. Моля потвърдете презаписването му</string>
<string name="pref_backup_title">Създаване на резервно копие</string>
<string name="pref_backup_noext">Грешка! Няма външна памет, за да се запише резервното копие.</string>
<string name="pref_restore_warn">Ако имате думи в речника на телефона, те ще бъдат заменени със същите от резервното копие. Ако не желаете това, моля изберете \"%1$s\" преди възстановяването..</string>
<string name="pref_restore_title">Възстановяване на резервно копие</string>
<string name="pref_restore_noext">Грешка! Няма външна памет, от която да се възстанови резервното копие на речника.</string>
<string name="pref_restore_nofile">Грешка! Не е открито резервно копие.</string>
<string name="pref_nuke_warn">Внимание! Всички думи от Вашия речник ще бъдат изтрити. Потвърждавате ли?</string>
<string name="pref_nuke_title">Изтрий собствения речник</string>
<string name="pref_reloadKeys">Зареди keymap.txt</string>
<string name="pref_reloadKeysSum">Зарежда повторно файла с разменени клавиши</string>
<string name="pref_reloadKeysDone">Упешно зареждане.</string>
<string name="pref_reloadKeysDoneWE">Имаше грешки при зареждане (виж logcat.)</string>
<string name="pref_reloadKeysNoFile">Няма файл keymap.txt.</string>
<string name="hello_world">Работи!</string>
</resources> </resources>

View file

@ -27,7 +27,6 @@
<string name="title_activity_add_word">Wort hinzufügen</string> <string name="title_activity_add_word">Wort hinzufügen</string>
<string name="action_settings">Einstellungen</string> <string name="action_settings">Einstellungen</string>
<string name="database_notready">Datenbank nicht verfügbar.</string> <string name="database_notready">Datenbank nicht verfügbar.</string>
<string name="database_settings_notready">Database unavailable. Using default settings.</string>
<string name="updating_database_title">Wörterbuch-Datenbank wird aktualisiert…</string> <string name="updating_database_title">Wörterbuch-Datenbank wird aktualisiert…</string>
<string name="updating_database">Aktualisiere Wörterbuch-Datenbank. Das könnte einen Moment dauern.</string> <string name="updating_database">Aktualisiere Wörterbuch-Datenbank. Das könnte einen Moment dauern.</string>
@ -38,31 +37,10 @@
<string name="pref_help">"Hilfe anzeigen</string> <string name="pref_help">"Hilfe anzeigen</string>
<string name="pref_loaddict">Wörterbuch laden</string> <string name="pref_loaddict">Wörterbuch laden</string>
<string name="pref_loaduserdict">Benutzerwörterbuch laden</string> <string name="pref_loaduserdict">Benutzerwörterbuch laden</string>
<string name="pref_nukedict">Wörterbuch löschen</string>
<string name="pref_backupdict">Wörterbuch sichern</string>
<string name="pref_restoredict">Wörterbuch wiederherstellen</string>
<string name="pref_querytest">Query test</string>
<string name="pref_testfunc">Test func</string>
<string name="pref_loadingdict">Lade Wörterbuch…</string> <string name="pref_loadingdict">Lade Wörterbuch…</string>
<string name="pref_loadinguserdict">Lade Benutzerwörterbuch…</string> <string name="pref_loadinguserdict">Lade Benutzerwörterbuch…</string>
<string name="pref_load_title">IME-Wörterbuch laden</string> <string name="pref_load_title">IME-Wörterbuch laden</string>
<string name="pref_loadingbackup">Stelle Wörterbuch wiederher…</string>
<string name="pref_savingbackup">Sichere Wörterbuch…</string>
<string name="pref_nukingdict">Lösche Wörterbuch… Bitte warten…</string>
<string name="pref_loaduser_notfound">Wörterbuch für %1$s nicht gefunden. Wird nicht geladen.</string> <string name="pref_loaduser_notfound">Wörterbuch für %1$s nicht gefunden. Wird nicht geladen.</string>
<string name="pref_backup_warn">Warnung: Es existiert bereits ein Datenbank-Backup. Soll es überschrieben werden?</string>
<string name="pref_backup_title">IME-Datenbank sichern</string>
<string name="pref_backup_noext">Fehler: Für das Backup ist kein externer Speicher verfügbar. Sicherung kann nicht fortfahren.</string>
<string name="pref_restore_warn">Einträge aus der Sicherungsdatenbank werden existierende Datenbankeinträge überschreiben. Einträge, die nicht in der Sicherung sind, bleiben erhalten. Falls dies nicht gewünscht ist, bitte \"%1$s\" wählen, bevor diese Option gewählt wird.</string>
<string name="pref_restore_title">IME-Datenbank wiederherstellen</string>
<string name="pref_restore_noext">Fehler: Für die Wiederherstellung ist kein externer Speicher verfügbar. Wiederherstellung kann nicht fortfahren.</string>
<string name="pref_restore_nofile">Fehler: Sicherungsdatei nicht gefunden.</string>
<string name="pref_nuke_warn">Warnung: Dies wird das gesamte Wörterbuch löschen. Fortfahren?</string>
<string name="pref_nuke_title">IME-Wörterbuch löschen</string>
<string name="pref_reloadKeys">Force reload of key overrides</string>
<string name="hello_world">Hallo Welt!</string>
</resources> </resources>

View file

@ -27,7 +27,6 @@
<string name="title_activity_add_word">Aj. mot</string> <string name="title_activity_add_word">Aj. mot</string>
<string name="action_settings">Paramètres</string> <string name="action_settings">Paramètres</string>
<string name="database_notready">Base de données indisponible</string> <string name="database_notready">Base de données indisponible</string>
<string name="database_settings_notready">Base de données indisponible. Options par défaut utilisées.</string>
<string name="updating_database_title">Mise à jour de la base de données du dictionnaire…</string> <string name="updating_database_title">Mise à jour de la base de données du dictionnaire…</string>
<string name="updating_database">Mise à jour de la base de données du dictionnaire, cela peut prendre un certain temps.</string> <string name="updating_database">Mise à jour de la base de données du dictionnaire, cela peut prendre un certain temps.</string>
@ -38,31 +37,10 @@
<string name="pref_help">"Afficher l\'aide</string> <string name="pref_help">"Afficher l\'aide</string>
<string name="pref_loaddict">Charger le dictionnaire</string> <string name="pref_loaddict">Charger le dictionnaire</string>
<string name="pref_loaduserdict">Charger le dictionnaire utilisateur</string> <string name="pref_loaduserdict">Charger le dictionnaire utilisateur</string>
<string name="pref_nukedict">Détruire le dictionnaire</string>
<string name="pref_backupdict">Sauvegarder le dictionnaire</string>
<string name="pref_restoredict">Restaurer le dictionnaire</string>
<string name="pref_querytest">Tester le clavier</string>
<string name="pref_testfunc">Teste fonc</string>
<string name="pref_loadingdict">Chargement du dictionnaire…</string> <string name="pref_loadingdict">Chargement du dictionnaire…</string>
<string name="pref_loadinguserdict">Chargement du dictionnaire utilisateur…</string> <string name="pref_loadinguserdict">Chargement du dictionnaire utilisateur…</string>
<string name="pref_load_title">Charger le dictionnaire IME</string> <string name="pref_load_title">Charger le dictionnaire IME</string>
<string name="pref_loadingbackup">Restauration du dictionnaire…</string>
<string name="pref_savingbackup">Sauvegarde du dictionnaire…</string>
<string name="pref_nukingdict">Destruction du dictionary… Attendez s\'il vous plaît…</string>
<string name="pref_loaduser_notfound">Dictionnaire %1$s introuvable. Chargement annulé.</string> <string name="pref_loaduser_notfound">Dictionnaire %1$s introuvable. Chargement annulé.</string>
<string name="pref_backup_warn">Attention: Une sauvegarde de la base de données est déjà présente. Souhaitez-vous la réécrire ?</string>
<string name="pref_backup_title">Sauvegarde de la base de données IME</string>
<string name="pref_backup_noext">Erreur: Pas de stockage externe disponible pour la sauvegarde. Sauvegarde annulée.</string>
<string name="pref_restore_warn">Les entrée de la sauvegarde vont réécrire les entrées existantes. Les entrées qui ne sont pas présentes dans la sauvegarde seront conservées. Si ce n\'est pas ce que vous souhaitez, selectionnez \"%1$s\" avant de selectionner cette option.</string>
<string name="pref_restore_title">Restaurer la base de données IME</string>
<string name="pref_restore_noext">Erreur: Pas de stockage externe pour la restauration. Restauration annulée</string>
<string name="pref_restore_nofile">Erreur: Fichier de sauvegarde introuvable.</string>
<string name="pref_nuke_warn">Attention: Votre ditionnaire sera entièrement effacé. Voulez-vous continuer ?</string>
<string name="pref_nuke_title">Détruire le dictionnaire IME</string>
<string name="pref_reloadKeys">Forcer le rechargement de la surcharge des touches</string>
<string name="hello_world">Bonjour monde !</string>
</resources> </resources>

View file

@ -27,7 +27,6 @@
<string name="title_activity_add_word">Aggiungi parola</string> <string name="title_activity_add_word">Aggiungi parola</string>
<string name="action_settings">Impostazioni</string> <string name="action_settings">Impostazioni</string>
<string name="database_notready">Database non disponibile.</string> <string name="database_notready">Database non disponibile.</string>
<string name="database_settings_notready">Database non disponibile. Utilizzo impostazioni di base.</string>
<string name="updating_database_title">Aggiornamento database dizionario…</string> <string name="updating_database_title">Aggiornamento database dizionario…</string>
<string name="updating_database">Aggiornamento database dizionario, potrebbe volerci un po\'.</string> <string name="updating_database">Aggiornamento database dizionario, potrebbe volerci un po\'.</string>
@ -38,32 +37,11 @@
<string name="pref_help">"Mostra aiuto</string> <string name="pref_help">"Mostra aiuto</string>
<string name="pref_loaddict">Carica dizionario</string> <string name="pref_loaddict">Carica dizionario</string>
<string name="pref_loaduserdict">Carica dizionario utente</string> <string name="pref_loaduserdict">Carica dizionario utente</string>
<string name="pref_nukedict">Elimina dizionario</string>
<string name="pref_backupdict">Salvataggio dizionario</string>
<string name="pref_restoredict">Ripristina dizionario</string>
<string name="pref_querytest">Test ricerca</string>
<string name="pref_testfunc">Test func</string>
<string name="pref_loadingdict">Caricamento dizionario…</string> <string name="pref_loadingdict">Caricamento dizionario…</string>
<string name="pref_loadinguserdict">Caricamento dizionario utente…</string> <string name="pref_loadinguserdict">Caricamento dizionario utente…</string>
<string name="pref_load_title">Caricamento dizionario IME</string> <string name="pref_load_title">Caricamento dizionario IME</string>
<string name="pref_loadingbackup">Ripristino dizionario…</string>
<string name="pref_savingbackup">Salvataggio dizionario…</string>
<string name="pref_nukingdict">Eliminazione dizionario… Attendere prego…</string>
<string name="pref_loaduser_notfound">Dizionario per %1$s non trovato. Impossibile caricare.</string> <string name="pref_loaduser_notfound">Dizionario per %1$s non trovato. Impossibile caricare.</string>
<string name="pref_backup_warn">Attenzione: salvataggio già esistente. Sovrascrivere ?</string>
<string name="pref_backup_title">Salvataggio database IME </string>
<string name="pref_backup_noext">Errore: Nessuna unità esterna disponibile per il salvataggio. Il salvataggio verrà interrotto.</string>
<string name="pref_restore_warn">I dati presenti nel salvataggio sostituiranno i dati esistenti. I dati non presenti nel salvataggio verranno mantenuti. In alternativa utilizzare \"%1$s\" prima di effettuare il ripristino.</string>
<string name="pref_restore_title">Ripristino database IME </string>
<string name="pref_restore_noext">Errore: Nessuna unità esterna disponibile per il ripristino. Il ripristino verrà interrotto.</string>
<string name="pref_restore_nofile">Errore: File di salvataggio non trovato.</string>
<string name="pref_nuke_warn">Attenzione: L\'intero dizionario sarà cancellato. Continuare ?</string>
<string name="pref_nuke_title">Elimina dizionario IME </string>
<string name="pref_reloadKeys">Ricaricamento KeyMap</string>
<string name="hello_world">Ciao mondo!</string>
</resources> </resources>

View file

@ -7,7 +7,6 @@
<string name="add_word_exist1">Слово (%1$s) уже есть в словаре.</string> <string name="add_word_exist1">Слово (%1$s) уже есть в словаре.</string>
<string name="add_word_exist2">Слово (%1$s) уже есть в словаре %2$s.</string> <string name="add_word_exist2">Слово (%1$s) уже есть в словаре %2$s.</string>
<string name="app_name">Traditional T9</string> <string name="app_name">Traditional T9</string>
<string name="hello_world">Hello world!</string>
<string name="ime_name">Клавиатура T9</string> <string name="ime_name">Клавиатура T9</string>
<string name="ime_number">Цифры</string> <string name="ime_number">Цифры</string>
<string name="main_left_addword">Добавить слово</string> <string name="main_left_addword">Добавить слово</string>
@ -15,31 +14,14 @@
<string name="main_left_notfound">Добавить слово?</string> <string name="main_left_notfound">Добавить слово?</string>
<string name="main_right_lower">Изменить IME</string> <string name="main_right_lower">Изменить IME</string>
<string name="main_right_upper">Режим ввода</string> <string name="main_right_upper">Режим ввода</string>
<string name="pref_backup_noext">Ошибка: Внешняя память недоступна. Резервное копирование невозможно невозможно.</string>
<string name="pref_backup_title">Резервное копирование базы данных IME</string>
<string name="pref_backup_warn">Предупреждение: Существующая копия базы данных будет перезаписана. Продолжить?</string>
<string name="pref_backupdict">Бэкап словаря</string>
<string name="pref_inputmode">Режим ввода по умолчанию</string> <string name="pref_inputmode">Режим ввода по умолчанию</string>
<string name="pref_inputmode_desc">Режим ввода по умолчанию</string> <string name="pref_inputmode_desc">Режим ввода по умолчанию</string>
<string name="pref_load_title">Загрузить словарь IME</string> <string name="pref_load_title">Загрузить словарь IME</string>
<string name="pref_loaddict">Загрузить словарь</string> <string name="pref_loaddict">Загрузить словарь</string>
<string name="pref_loadingbackup">Восстановление словаря…</string>
<string name="pref_loadingdict">Загрузка словаря</string> <string name="pref_loadingdict">Загрузка словаря</string>
<string name="pref_loadinguserdict">Загрузка пользовательского словаря…</string> <string name="pref_loadinguserdict">Загрузка пользовательского словаря…</string>
<string name="pref_loaduserdict">Загрузить свой словарь</string> <string name="pref_loaduserdict">Загрузить свой словарь</string>
<string name="pref_lang_title">Мультиязычная поддержка</string> <string name="pref_lang_title">Мультиязычная поддержка</string>
<string name="pref_nuke_title">Очистить IME словарь</string>
<string name="pref_nuke_warn">Предупреждение: Будет выполнена очстка словаря. Продолжить?</string>
<string name="pref_nukedict">Очистить словарь</string>
<string name="pref_nukingdict">Очистка словаря… Пожалуйста, подождите…</string>
<string name="pref_querytest">Query test</string>
<string name="pref_restore_noext">Ошибка: Внешняя память недоступна. Восстановление невозможно.</string>
<string name="pref_restore_nofile">Ошибка: Файл встановления не найден.</string>
<string name="pref_restore_title">Восстановить базу данных IME</string>
<string name="pref_restore_warn">При восстановлении существующая база данных будет очищена. Если это нежелательно, то сначала выберите \"%1$s\" перед использованием этой опции.</string>
<string name="pref_restoredict">Сохранить словарь</string>
<string name="pref_savingbackup">Сохранение словаря…</string>
<string name="pref_testfunc">Test func</string>
<string name="ricon_desc">Hold Icon</string> <string name="ricon_desc">Hold Icon</string>
<string name="pref_help">О программе</string> <string name="pref_help">О программе</string>
<string name="symbol_next">Следущая страница</string> <string name="symbol_next">Следущая страница</string>
@ -56,8 +38,6 @@
<string name="updating_database_done">Обновление базы данных словаря выполнено успешно.</string> <string name="updating_database_done">Обновление базы данных словаря выполнено успешно.</string>
<string name="updating_database_unavailable">Обновление базы данных словаря недоступно.</string> <string name="updating_database_unavailable">Обновление базы данных словаря недоступно.</string>
<string name="pref_loaduser_notfound"> Ошибка. \n Словарь %1$s не найден. </string> <string name="pref_loaduser_notfound"> Ошибка. \n Словарь %1$s не найден. </string>
<string name="database_settings_notready">База данных недоступна. Используем значения по умолчанию.</string>
<string name="pref_reloadKeys">>Перезагрузить кеймап</string>
<string name="title_activity_add_word">Добавить слово</string> <string name="title_activity_add_word">Добавить слово</string>
<string name="traditionalt9_settings">Traditional T9 настройки</string> <string name="traditionalt9_settings">Traditional T9 настройки</string>

View file

@ -7,7 +7,6 @@
<string name="add_word_exist1">Слово (%1$s) вже є в словнику.</string> <string name="add_word_exist1">Слово (%1$s) вже є в словнику.</string>
<string name="add_word_exist2">Слово (%1$s) вже є в словнику %2$s.</string> <string name="add_word_exist2">Слово (%1$s) вже є в словнику %2$s.</string>
<string name="app_name">Traditional T9</string> <string name="app_name">Traditional T9</string>
<string name="hello_world">Hello world!</string>
<string name="ime_name">Клавіатура T9</string> <string name="ime_name">Клавіатура T9</string>
<string name="ime_number">Цифри</string> <string name="ime_number">Цифри</string>
<string name="main_left_addword">Додати слово</string> <string name="main_left_addword">Додати слово</string>
@ -15,31 +14,14 @@
<string name="main_left_notfound">Додати слово?</string> <string name="main_left_notfound">Додати слово?</string>
<string name="main_right_lower">Змінити IME</string> <string name="main_right_lower">Змінити IME</string>
<string name="main_right_upper">Режим введення</string> <string name="main_right_upper">Режим введення</string>
<string name="pref_backup_noext">Помилка: Зовнішня пам\'ять недоступна. Резервне копіювання неможливе.</string>
<string name="pref_backup_title">Резервне копіювання бази даних IME</string>
<string name="pref_backup_warn">Попередження: Існуюча копія бази даних буде перезаписана. Продовжити?</string>
<string name="pref_backupdict">Бекап словника</string>
<string name="pref_inputmode">Режим введення за замовчуванням</string> <string name="pref_inputmode">Режим введення за замовчуванням</string>
<string name="pref_inputmode_desc">Режим введення за замовчуванням</string> <string name="pref_inputmode_desc">Режим введення за замовчуванням</string>
<string name="pref_load_title">Завантажити словник IME</string> <string name="pref_load_title">Завантажити словник IME</string>
<string name="pref_loaddict">Завантажити словник</string> <string name="pref_loaddict">Завантажити словник</string>
<string name="pref_loadingbackup">Відновлення словника…</string>
<string name="pref_loadingdict">Завантаження словника</string> <string name="pref_loadingdict">Завантаження словника</string>
<string name="pref_loadinguserdict">Завантаження словника користувача…</string> <string name="pref_loadinguserdict">Завантаження словника користувача…</string>
<string name="pref_loaduserdict">Завантажити свій словник</string> <string name="pref_loaduserdict">Завантажити свій словник</string>
<string name="pref_lang_title">Багатомовна підтримка</string> <string name="pref_lang_title">Багатомовна підтримка</string>
<string name="pref_nuke_title">Очистити IME словник</string>
<string name="pref_nuke_warn">Попередження: Буде виконана очистка словника. Продовжити?</string>
<string name="pref_nukedict">Очистка словника</string>
<string name="pref_nukingdict">Очистка словника… Будь-ласка, зачекайте…</string>
<string name="pref_querytest">Тестовий запит</string>
<string name="pref_restore_noext">Помилка: Зовнішня память недоступна. Відновлення неможливе.</string>
<string name="pref_restore_nofile">Помилка: Файл відновлення не знайдений.</string>
<string name="pref_restore_title">Відновити базу даних IME</string>
<string name="pref_restore_warn">При відновленні існуюча база даних буде витерта. Если это нежелательно, то сначала выберите \"%1$s\" перед использованием этой опции.</string>
<string name="pref_restoredict">Зберегти словник</string>
<string name="pref_savingbackup">Збереження словника…</string>
<string name="pref_testfunc">Test func</string>
<string name="ricon_desc">Hold Icon</string> <string name="ricon_desc">Hold Icon</string>
<string name="pref_help">Про програму</string> <string name="pref_help">Про програму</string>
<string name="symbol_next">Наступне</string> <string name="symbol_next">Наступне</string>
@ -56,8 +38,6 @@
<string name="updating_database_done">Оновлення бази даних словника виконано успішно.</string> <string name="updating_database_done">Оновлення бази даних словника виконано успішно.</string>
<string name="updating_database_unavailable">Оновлення бізи даних словника недоступне.</string> <string name="updating_database_unavailable">Оновлення бізи даних словника недоступне.</string>
<string name="pref_loaduser_notfound"> Помилка. \n Словник %1$s не знайдено. </string> <string name="pref_loaduser_notfound"> Помилка. \n Словник %1$s не знайдено. </string>
<string name="database_settings_notready">База даних недоступна. Використовуюься значення за замовчуванням.</string>
<string name="pref_reloadKeys">Перезавантажити значення клавіш</string>
<string name="title_activity_add_word">Додати слово</string> <string name="title_activity_add_word">Додати слово</string>
<string name="traditionalt9_settings">Налаштування Traditional T9</string> <string name="traditionalt9_settings">Налаштування Traditional T9</string>

View file

@ -29,7 +29,6 @@
<string name="title_activity_add_word">Add Word</string> <string name="title_activity_add_word">Add Word</string>
<string name="action_settings">Settings</string> <string name="action_settings">Settings</string>
<string name="database_notready">Database unavailable.</string> <string name="database_notready">Database unavailable.</string>
<string name="database_settings_notready">Database unavailable. Using default settings.</string>
<string name="updating_database_title">Updating dictionary database…</string> <string name="updating_database_title">Updating dictionary database…</string>
<string name="updating_database">Updating dictionary database, this might take a while.</string> <string name="updating_database">Updating dictionary database, this might take a while.</string>
@ -41,35 +40,10 @@
<string name="pref_loaddict">Load dictionary</string> <string name="pref_loaddict">Load dictionary</string>
<string name="pref_loaduserdict">Load user dictionary</string> <string name="pref_loaduserdict">Load user dictionary</string>
<string translatable="false" name="pref_loaduserdictdesc">SDcard/traditionalt9/user.lang.dict (lang: en/ru/de/fr)</string> <string translatable="false" name="pref_loaduserdictdesc">SDcard/traditionalt9/user.lang.dict (lang: en/ru/de/fr)</string>
<string name="pref_nukedict">Nuke dictionary</string>
<string name="pref_backupdict">Backup dictionary</string>
<string name="pref_restoredict">Restore dictionary</string>
<string name="pref_querytest">Query test</string>
<string name="pref_testfunc">Test func</string>
<string name="pref_loadingdict">Loading dictionary…</string> <string name="pref_loadingdict">Loading dictionary…</string>
<string name="pref_loadinguserdict">Loading user dictionary…</string> <string name="pref_loadinguserdict">Loading user dictionary…</string>
<string name="pref_load_title">Load IME dictionary</string> <string name="pref_load_title">Load IME dictionary</string>
<string name="pref_loadingbackup">Restoring dictionary…</string>
<string name="pref_savingbackup">Backing up dictionary…</string>
<string name="pref_nukingdict">Nuking dictionary… Please wait…</string>
<string name="pref_loaduser_notfound">Dictionary for %1$s not found. Not loading.</string> <string name="pref_loaduser_notfound">Dictionary for %1$s not found. Not loading.</string>
<string name="pref_backup_warn">Warning: An existing database backup exists. Do you wish to overwrite?</string>
<string name="pref_backup_title">Backup IME database</string>
<string name="pref_backup_noext">Error: No external storage available for backup. Backup will not continue.</string>
<string name="pref_restore_warn">Backup database entries will overwrite existing database entries. Entries not in the backup will be retained. If that is not desired behaviour select \"%1$s\" before selecting this option.</string>
<string name="pref_restore_title">Restore IME database</string>
<string name="pref_restore_noext">Error: No external storage available for restoring. Restore will not continue.</string>
<string name="pref_restore_nofile">Error: Backup file not found.</string>
<string name="pref_nuke_warn">Warning: This will delete your entire dictionary. Do you wish to continue?</string>
<string name="pref_nuke_title">Nuke IME dictionary</string>
<string name="pref_reloadKeys">Reload KeyMap</string>
<string name="pref_reloadKeysSum" translatable="false">Force reload of key mapping overrides</string>
<string name="pref_reloadKeysDone" translatable="false">Reload complete.</string>
<string name="pref_reloadKeysDoneWE" translatable="false">Reload complete with errors (check logcat.)</string>
<string name="pref_reloadKeysNoFile" translatable="false">No keymap.txt file found.</string>
<string name="hello_world">Hello world!</string>
</resources> </resources>

View file

@ -15,9 +15,6 @@
entryValues="@array/pref_lang_values" entryValues="@array/pref_lang_values"
title="@string/pref_lang_title" /> title="@string/pref_lang_title" />
<Setting title="@string/pref_loaddict" id="loaddict"/> <Setting title="@string/pref_loaddict" id="loaddict"/>
<Setting title="@string/pref_loaduserdict" summary="@string/pref_loaduserdictdesc" id="loaduserdict"/> <!-- Take care of dictionary loading in #26 -->
<Setting title="@string/pref_nukedict" id="nukedict"/> <!-- <Setting title="@string/pref_loaduserdict" summary="@string/pref_loaduserdictdesc" id="loaduserdict"/> -->
<Setting title="@string/pref_backupdict" id="backupdict"/>
<Setting title="@string/pref_restoredict" id="restoredict"/>
<Setting title="@string/pref_reloadKeys" summary="@string/pref_reloadKeysSum" id="reloadKeys"/>
</Settings> </Settings>

View file

@ -10,7 +10,9 @@ import android.view.Menu;
import android.view.View; import android.view.View;
import android.widget.EditText; import android.widget.EditText;
import io.github.sspanak.tt9.T9DB.DBSettings.SETTING; import io.github.sspanak.tt9.db.DBException;
import io.github.sspanak.tt9.db.T9DB;
import io.github.sspanak.tt9.preferences.T9Preferences;
public class AddWordAct extends Activity { public class AddWordAct extends Activity {
@ -45,9 +47,8 @@ public class AddWordAct extends Activity {
} }
public void doAddWord(String text) { public void doAddWord(String text) {
T9DB db = T9DB.getInstance(this);
try { try {
db.addWord(text, LangHelper.LANGUAGE.get(lang)); T9DB.getInstance(this).addWord(text, LangHelper.LANGUAGE.get(lang));
} catch (DBException e) { } catch (DBException e) {
AlertDialog.Builder builder = new AlertDialog.Builder(this); AlertDialog.Builder builder = new AlertDialog.Builder(this);
String msg = e.getMessage(); String msg = e.getMessage();
@ -62,7 +63,7 @@ public class AddWordAct extends Activity {
AlertDialog dialog = builder.create(); AlertDialog dialog = builder.create();
dialog.show(); dialog.show();
} }
db.storeSettingString(SETTING.LAST_WORD, text); T9Preferences.getInstance(this).setLastWord(text);
} }

View file

@ -163,7 +163,7 @@ public class CharMap {
protected static final int[] BGT9CAPSTART = { 0, 0, 4, 4, 4, 4, 4, 4, 3, 3, 0, 0, 0 }; protected static final int[] BGT9CAPSTART = { 0, 0, 4, 4, 4, 4, 4, 4, 3, 3, 0, 0, 0 };
protected static final int[][] T9CAPSTART = {ENT9CAPSTART, RUT9CAPSTART, DET9CAPSTART, FRT9CAPSTART, ITT9CAPSTART, UKT9CAPSTART, BGT9CAPSTART}; protected static final int[][] T9CAPSTART = {ENT9CAPSTART, RUT9CAPSTART, DET9CAPSTART, FRT9CAPSTART, ITT9CAPSTART, UKT9CAPSTART, BGT9CAPSTART};
protected static String getStringSequence(String word, LANGUAGE lang) { public static String getStringSequence(String word, LANGUAGE lang) {
StringBuilder seq = new StringBuilder(); StringBuilder seq = new StringBuilder();
String tword = word.toLowerCase(LangHelper.LOCALES[lang.index]); String tword = word.toLowerCase(LangHelper.LOCALES[lang.index]);
for (int i = 0; i < word.length(); i++) { for (int i = 0; i < word.length(); i++) {

View file

@ -1,60 +0,0 @@
package io.github.sspanak.tt9;
import android.os.Environment;
import android.util.Log;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class KeyMap {
public static final String keymapfname = "keymap.txt";
public static Map<Integer, Integer> keyMapping = new HashMap<Integer, Integer>();
static {
setKeys();
}
public static int setKeys() {
int msg = 0;
keyMapping = new HashMap<Integer, Integer>();
// check storage
if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(Environment.getExternalStorageState())
|| Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
// check for file
if ((new File(new File(Environment.getExternalStorageDirectory(), TraditionalT9Settings.sddir),
keymapfname)).exists()) {
BufferedReader br = null;
Log.d("T9.KeyMap", "Attemping to load keys");
try {
br = new BufferedReader(new FileReader(new File(
new File(Environment.getExternalStorageDirectory(), TraditionalT9Settings.sddir), keymapfname)));
String line;
try {
while ((line = br.readLine()) != null) {
String[] ws = line.split(" ");
if (ws.length != 2) {continue;}
else if (line.startsWith("#")) {continue;}
try {
keyMapping.put(Integer.parseInt(ws[0]), Integer.parseInt(ws[1]));
} catch (NumberFormatException _ignore) {
Log.w("T9.KeyMap", "Invalid number found");
msg = R.string.pref_reloadKeysDoneWE;
}
}
Log.d("T9.KeyMap", "Done.");
} catch (IOException _ignore) {
Log.e("T9.KeyMap", "Error while reading line.");
try { br.close(); }
catch (IOException ignored) {}
}
} catch (FileNotFoundException ignored) { msg = R.string.pref_reloadKeysDone; }
} else { msg = R.string.pref_reloadKeysNoFile; }
} else { msg = R.string.pref_reloadKeysNoFile; }
return msg;
}
}

View file

@ -29,7 +29,7 @@ public class LangHelper {
public static LANGUAGE get(int i) { return lookup.get(i);} public static LANGUAGE get(int i) { return lookup.get(i);}
} }
protected static final Locale[] LOCALES = {Locale.ENGLISH, RUSSIAN, Locale.GERMAN, Locale.FRENCH, Locale.ITALIAN, UKRAINIAN, BULGARIAN}; public static final Locale[] LOCALES = {Locale.ENGLISH, RUSSIAN, Locale.GERMAN, Locale.FRENCH, Locale.ITALIAN, UKRAINIAN, BULGARIAN};
public static final int LANG_DEFAULT = LANGUAGE.EN.id; public static final int LANG_DEFAULT = LANGUAGE.EN.id;

View file

@ -1,561 +0,0 @@
package io.github.sspanak.tt9;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.database.Cursor;
import android.database.sqlite.SQLiteConstraintException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.provider.BaseColumns;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;
import io.github.sspanak.tt9.LangHelper.LANGUAGE;
import java.util.AbstractList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class T9DB {
private static volatile T9DB instance = null;
protected boolean ready = true;
protected static final String DATABASE_NAME = "t9dict.db";
protected static final int DATABASE_VERSION = 4;
protected static final String WORD_TABLE_NAME = "word";
protected static final String SETTING_TABLE_NAME = "setting";
protected static final String FREQ_TRIGGER_NAME = "freqtrigger";
// 50k, 10k
private static final int FREQ_MAX = 50000;
private static final int FREQ_DIV = 10000;
// This seems to be pretty fast on my phone. 10 is pretty slow (Might be because > MAX_RESULTS (8).)
private static final int MINHITS = 4;
protected static final String COLUMN_ID = BaseColumns._ID;
protected static final String COLUMN_LANG = "lang";
protected static final String COLUMN_SEQ = "seq";
protected static final String COLUMN_WORD = "word";
protected static final String COLUMN_FREQUENCY = "freq";
private static final String QUERY1 = "SELECT " + COLUMN_ID + ", " + COLUMN_WORD + " FROM " + WORD_TABLE_NAME +
" WHERE " + COLUMN_LANG + "=? AND " + COLUMN_SEQ + "=?" +
" ORDER BY " + COLUMN_FREQUENCY + " DESC";
private static final String UPDATEQ = "UPDATE " + WORD_TABLE_NAME +
" SET " + COLUMN_FREQUENCY + " = " + COLUMN_FREQUENCY + "+1" +
" WHERE " + COLUMN_ID + "=";
private static final int MAX_RESULTS = 8;
private static final int MAX_MAX_RESULTS = 30; // to make sure we don't exceed candidate view array.
private static final int CAPS_OFF = 0;
private static final int CAPS_SINGLE = 1;
private static final int CAPS_ALL = 2;
private DatabaseHelper mOpenHelper;
private SQLiteDatabase db;
private Context mContext;
public static class DBSettings {
public enum SETTING {
INPUT_MODE("pref_inputmode", 0, 0),
LANG_SUPPORT("pref_lang_support", 1, 1),
MODE_NOTIFY("pref_mode_notify", 0, 2), // no longer in use; delete in #7
LAST_LANG("set_last_lang", 1, 5),
LAST_WORD("set_last_word", null, 6),
SPACE_ZERO("pref_spaceOnZero", 0, 4), // no longer in use; delete in #7
KEY_REMAP("pref_keyMap", 0, 3); // no longer in use; delete in #7
public final String id;
public final Integer defvalue;
public final int sqOrder; // used for building SettingsUI
// lookup map
private static final Map<String, SETTING> lookup = new HashMap<String, SETTING>();
private static final SETTING[] settings = SETTING.values();
static { for (SETTING l : settings) lookup.put(l.id, l); }
private SETTING(String id, Integer defval, int sqOrder) {
this.id = id; this.defvalue = defval; this.sqOrder = sqOrder;
}
public static SETTING get(String i) { return lookup.get(i);}
public static StringBuilder join(SETTING[] settings, StringBuilder sb) {
for (int x=0; x<settings.length; x++) {
sb.append(settings[x].id);
if (x < settings.length-1)
sb.append(", ");
}
return sb;
}
}
protected static final String SETTINGQUERY = " FROM " + SETTING_TABLE_NAME +
" WHERE " + COLUMN_ID + "=1";
}
public T9DB(Context caller) {
// create db
mContext = caller;
mOpenHelper = new DatabaseHelper(caller);
}
public static T9DB getInstance(Context caller) {
if (instance == null) {
synchronized (T9DB.class){
if (instance == null) {
instance = new T9DB (caller);
instance.init();
}
}
}
return instance;
}
protected static SQLiteDatabase getSQLDB(Context caller) {
T9DB t9dbhelper = getInstance(caller);
//Log.d("T9DB.getSQLDB", "db:" + t9dbhelper.db.isOpen());
return t9dbhelper.db;
}
private void init() {
if (mOpenHelper.needsUpgrading() ) {
ready = false;
Log.i("T9.init", "needsUpgrading");
// start updating service
if (db != null) {
try {
db.close();
} catch (NullPointerException ignored) { }
db = null;
}
Intent intent = new Intent(mContext, DBUpdateService.class);
Log.i("T9.init", "Invoking update service...");
mContext.startService(intent);
} else {
db = mOpenHelper.getWritableDatabase();
}
}
public boolean checkReady() {
if (ready) {
if (db == null) {
db = getWritableDatabase();
}
return true;
} else {
return false;
}
}
protected SQLiteDatabase getWritableDatabase() {
return mOpenHelper.getWritableDatabase();
}
protected void setSQLDB(SQLiteDatabase tdb) {
synchronized (T9DB.class){
db = tdb;
ready = true;
}
}
protected void close() {
try { db.close(); }
catch (NullPointerException ignored) { }
db = null;
}
protected void nuke() {
Log.i("T9DB.nuke", "Deleting database...");
synchronized (T9DB.class){
String[] oldSettings = getSettings();
if (oldSettings == null) { Log.e("T9DB", "Couldn't get old settings"); }
if (db != null) { db.close(); }
if (!mContext.deleteDatabase(DATABASE_NAME)) { Log.e("T9DB", "Couldn't delete database."); }
Log.i("T9DB.nuke", "Preparing database...");
getWritableDatabase().close();
db = null;
ready = true;
init();
if (oldSettings != null) {
StringBuilder sb = new StringBuilder("INSERT OR REPLACE INTO ");
sb.append(SETTING_TABLE_NAME); sb.append(" ("); sb.append(COLUMN_ID); sb.append(",");
sb = DBSettings.SETTING.join(DBSettings.SETTING.settings, sb);
sb.append(") VALUES ("); sb.append(TextUtils.join(",", oldSettings)); sb.append(")");
db.execSQL(sb.toString());
}
}
Log.i("T9DB.nuke", "Done...");
}
public void showDBaccessError() {
Toast.makeText(mContext, R.string.database_notready, Toast.LENGTH_SHORT).show();
}
public boolean storeSettingString(DBSettings.SETTING key, String value) {
ContentValues updatedata = new ContentValues();
updatedata.put(key.id, value);
return storeSetting(updatedata);
}
public boolean storeSettingInt(DBSettings.SETTING key, int value) {
ContentValues updatedata = new ContentValues();
updatedata.put(key.id, value);
return storeSetting(updatedata);
}
public boolean storeSetting(ContentValues updatedata) {
if (!checkReady()) {
Log.e("T9DB.storeSetting", "not ready");
return false;
}
db.update(SETTING_TABLE_NAME, updatedata, null, null);
return true;
}
// CHECK READY BEFORE CALLING THIS SO CAN SHOW USER MESSAGE IF NOT READY
public int getSettingInt(DBSettings.SETTING key) {
Cursor cur = db.rawQuery((new StringBuilder("SELECT ")).append(key.id)
.append(DBSettings.SETTINGQUERY).toString(), null);
if (cur.moveToFirst()) {
int value = cur.getInt(0);
cur.close();
return value;
}
return key.defvalue;
}
public String getSettingString(DBSettings.SETTING key) {
if (!checkReady()) {
return null;
}
Cursor cur = db.rawQuery((new StringBuilder("SELECT ")).append(key.id)
.append(DBSettings.SETTINGQUERY).toString(), null);
if (cur.moveToFirst()) {
String value = cur.getString(0);
cur.close();
return value;
}
return null;
}
public Object[] getSettings(DBSettings.SETTING[] keys) {
if (checkReady()) {
StringBuilder sb = new StringBuilder("SELECT ");
sb = DBSettings.SETTING.join(keys, sb);
Cursor cur = db.rawQuery(sb.append(DBSettings.SETTINGQUERY).toString(), null);
if (cur.moveToFirst()) {
Object[] values = new Object[keys.length];
for (int x=0;x<keys.length;x++){
if (keys[x] == DBSettings.SETTING.LAST_WORD)
values[x] = cur.getString(x);
else
values[x] = cur.getInt(x);
}
cur.close();
return values;
}
} else {
Log.e("T9DB.getSettings", "not ready");
Toast.makeText(mContext, R.string.database_settings_notready, Toast.LENGTH_SHORT).show();
}
Object[] values = new Object[keys.length];
for (int x=0;x<keys.length;x++) {
values[x] = keys[x].defvalue;
}
return values;
}
private String[] getSettings() {
if (!checkReady()) {
Log.e("T9DB.getSetting", "not ready");
return null;
}
int len = DBSettings.SETTING.settings.length+1;
String[] settings = new String[len];
StringBuilder sb = new StringBuilder("SELECT "); sb.append(COLUMN_ID); sb.append(",");
sb = DBSettings.SETTING.join(DBSettings.SETTING.settings, sb);
sb.append(" FROM "); sb.append(SETTING_TABLE_NAME); sb.append(" WHERE "); sb.append(COLUMN_ID);
sb.append("=1");
Cursor cur = null;
cur = db.rawQuery(sb.toString(),null);
try { cur = db.rawQuery(sb.toString(),null); }
catch (SQLiteException e) {
if (cur != null) { cur.close(); }
return null;
}
if (cur.moveToFirst()) {
for (int x = 0; x < len; x++)
settings[x] = cur.getString(x);
} else {
Log.w("T9DB.getSettings", "COULDN'T RETRIEVE SETTINGS?");
for (int x = 1; x < len; x++) {
settings[0] = "1"; // COLUMN_ID
if (DBSettings.SETTING.settings[x].defvalue == null)
settings[x] = null;
else
settings[x] = DBSettings.SETTING.settings[x].defvalue.toString();
}
}
cur.close();
return settings;
}
protected void addWord(String iword, LANGUAGE lang) throws DBException {
Resources r = mContext.getResources();
if (iword.equals("")) {
throw new DBException(r.getString(R.string.add_word_blank));
}
// get int sequence
String seq;
try {
seq = CharMap.getStringSequence(iword, lang);
} catch (NullPointerException e) {
throw new DBException(r.getString(R.string.add_word_badchar, lang.name(), iword));
}
// add int sequence into num table
ContentValues values = new ContentValues();
values.put(COLUMN_SEQ, seq);
values.put(COLUMN_LANG, lang.id);
// add word into word
values.put(COLUMN_WORD, iword);
values.put(COLUMN_FREQUENCY, 1);
if (!checkReady()) {
Log.e("T9DB.addWord", "not ready");
Toast.makeText(mContext, R.string.database_notready, Toast.LENGTH_SHORT).show();
return;
}
try {
db.insertOrThrow(WORD_TABLE_NAME, null, values);
} catch (SQLiteConstraintException e) {
String msg = r.getString(R.string.add_word_exist2, iword, lang.name());
Log.w("T9DB.addWord", msg);
throw new DBException(msg);
}
}
protected void incrementWord(int id) {
if (!checkReady()) {
Log.e("T9DB.incrementWord", "not ready");
Toast.makeText(mContext, R.string.database_notready, Toast.LENGTH_SHORT).show();
return;
}
db.execSQL(UPDATEQ + id);
// if id's freq is greater than FREQ_MAX, it gets normalized with trigger
}
protected void updateWords(String is, AbstractList<String> stringList, List<Integer> intList,
int capsMode, LANGUAGE lang) {
stringList.clear();
intList.clear();
// String[] sa = packInts(stringToInts(is), true);
int islen = is.length();
if (!checkReady()) {
Log.e("T9DB.updateWords", "not ready");
Toast.makeText(mContext, R.string.database_notready, Toast.LENGTH_SHORT).show();
return;
}
Cursor cur = db.rawQuery(QUERY1, new String[] { String.valueOf(lang.id), is });
int hits = 0;
for (cur.moveToFirst(); !cur.isAfterLast(); cur.moveToNext()) {
intList.add(cur.getInt(0));
stringList.add(cur.getString(1));
if (hits >= MAX_MAX_RESULTS) { break; } // to stop index error in candidate view
hits++;
}
cur.close();
if ((hits < MINHITS) && (islen >= 2)) {
char c = is.charAt(islen - 1);
c++;
String q = "SELECT " + COLUMN_ID + ", " + COLUMN_WORD +
" FROM " + WORD_TABLE_NAME +
" WHERE " + COLUMN_LANG + "=? AND " + COLUMN_SEQ + " >= '" + is + "1" +
"' AND " + COLUMN_SEQ + " < '" + is.substring(0, islen - 1) + c + "'" +
" ORDER BY " + COLUMN_FREQUENCY + " DESC, " + COLUMN_SEQ + " ASC" +
" LIMIT " + (MAX_RESULTS - hits);
cur = db.rawQuery(q, new String[] { String.valueOf(lang.id) });
for (cur.moveToFirst(); !cur.isAfterLast(); cur.moveToNext()) {
intList.add(cur.getInt(0));
stringList.add(cur.getString(1));
if (hits >= MAX_MAX_RESULTS) {
break;
}
hits++;
}
cur.close();
}
// Log.d("T9DB.updateWords", "pre: " + stringList);
if (capsMode == CAPS_OFF) {
return;
}
// Log.d("T9DB.updateWords", "filtering...");
// filter list
Iterator<String> iter = stringList.iterator();
String word;
String wordtemp;
int index = 0;
boolean removed = false;
while (iter.hasNext()) {
word = iter.next();
switch (capsMode) {
case CAPS_ALL:
wordtemp = word.toUpperCase(LangHelper.LOCALES[lang.index]);
if (wordtemp.equals(word)) {
index++;
continue;
} else if (stringList.contains(wordtemp)) {
// remove this entry
iter.remove();
removed = true;
} else {
stringList.set(index, wordtemp);
}
break;
case CAPS_SINGLE:
if (word.length() > 1) {
wordtemp = word.substring(0, 1).toUpperCase(LangHelper.LOCALES[lang.index]) + word.substring(1);
} else {
wordtemp = word.toUpperCase(LangHelper.LOCALES[lang.index]);
}
if (wordtemp.equals(word)) {
index++;
continue;
} else if (stringList.contains(wordtemp)) {
// remove this entry
iter.remove();
removed = true;
} else {
stringList.set(index, wordtemp);
}
break;
}
if (removed) {
intList.remove(index);
removed = false;
} else {
index++;
}
}
//Log.d("T9DB.updateWords", "i:" + is + " words:" + Arrays.toString(stringList.toArray()));
}
private static class DatabaseHelper extends SQLiteOpenHelper {
Context mContext = null;
DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
mContext = context;
}
// partial code from parent class SQLiteOpenHelper
protected boolean needsUpgrading() {
//quick and dirty check to see if an existing database exists.
if (mContext.databaseList().length > 0) {
SQLiteDatabase db = mContext.openOrCreateDatabase(DATABASE_NAME, 0, null);
int version = db.getVersion();
db.close();
return version < DATABASE_VERSION;
} else {
return false;
}
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE IF NOT EXISTS " + WORD_TABLE_NAME + " (" +
COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
COLUMN_LANG + " INTEGER, " +
COLUMN_SEQ + " TEXT, " +
COLUMN_WORD + " TEXT, " +
COLUMN_FREQUENCY + " INTEGER, " +
"UNIQUE(" + COLUMN_LANG + ", " + COLUMN_WORD + ") )");
db.execSQL("CREATE INDEX IF NOT EXISTS idx ON " + WORD_TABLE_NAME + "("
+ COLUMN_LANG + ", " + COLUMN_SEQ + " ASC, " + COLUMN_FREQUENCY + " DESC )");
db.execSQL("CREATE TRIGGER IF NOT EXISTS " + FREQ_TRIGGER_NAME +
" AFTER UPDATE ON " + WORD_TABLE_NAME +
" WHEN NEW." + COLUMN_FREQUENCY + " > " + FREQ_MAX +
" BEGIN" +
" UPDATE " + WORD_TABLE_NAME + " SET " + COLUMN_FREQUENCY + " = "
+ COLUMN_FREQUENCY + " / " + FREQ_DIV +
" WHERE " + COLUMN_SEQ + " = NEW." + COLUMN_SEQ + ";" +
" END;");
createSettingsTable(db);
StringBuilder sb = new StringBuilder("INSERT OR IGNORE INTO "); sb.append(SETTING_TABLE_NAME);
sb.append(" ("); sb.append(COLUMN_ID); sb.append(", ");
sb = DBSettings.SETTING.join(DBSettings.SETTING.settings, sb);
sb.append(") VALUES (1,");
for (int x=0;x<DBSettings.SETTING.settings.length; x++) {
if (DBSettings.SETTING.settings[x].defvalue == null)
sb.append("NULL");
else
sb.append(DBSettings.SETTING.settings[x].defvalue);
if (x<DBSettings.SETTING.settings.length-1) sb.append(",");
}
sb.append(")");
db.execSQL(sb.toString());
}
private void createSettingsTable(SQLiteDatabase db) {
db.execSQL("CREATE TABLE IF NOT EXISTS " + SETTING_TABLE_NAME + " (" +
COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
DBSettings.SETTING.INPUT_MODE.id + " INTEGER, " +
DBSettings.SETTING.LANG_SUPPORT.id + " INTEGER, " +
DBSettings.SETTING.MODE_NOTIFY.id + " INTEGER, " + // no longer in use; delete in #7
DBSettings.SETTING.LAST_LANG.id + " INTEGER, " +
DBSettings.SETTING.KEY_REMAP.id + " INTEGER, " + // no longer in use; delete in #7
DBSettings.SETTING.SPACE_ZERO.id + " INTEGER, " + // no longer in use; delete in #7
DBSettings.SETTING.LAST_WORD.id + " TEXT )");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.i("T9DB.onUpgrade", "Upgrading database from version " + oldVersion + " to " + newVersion);
if (oldVersion <= 1) {
// ADDED LANG
db.execSQL("DROP INDEX IF EXISTS idx");
db.execSQL("ALTER TABLE " + WORD_TABLE_NAME + " ADD COLUMN " +
COLUMN_LANG + " INTEGER");
ContentValues updatedata = new ContentValues();
updatedata.put(COLUMN_LANG, 0);
db.update(WORD_TABLE_NAME, updatedata, null, null);
}
if (oldVersion <= 2) {
// ADDED SETTINGS, CHANGED LANG VALUE
db.execSQL("DROP INDEX IF EXISTS idx");
db.execSQL("UPDATE " + WORD_TABLE_NAME + " SET " + COLUMN_LANG + "=" + LANGUAGE.RU.id +
" WHERE " + COLUMN_LANG + "=1");
db.execSQL("UPDATE " + WORD_TABLE_NAME + " SET " + COLUMN_LANG + "=" + LANGUAGE.EN.id +
" WHERE " + COLUMN_LANG + "=0");
createSettingsTable(db);
}
if (oldVersion == 3) {
// ADDED REMAP OPTION and SPACEONZERO
db.execSQL("ALTER TABLE " + SETTING_TABLE_NAME + " ADD COLUMN " +
DBSettings.SETTING.KEY_REMAP.id + " INTEGER");
db.execSQL("ALTER TABLE " + SETTING_TABLE_NAME + " ADD COLUMN " +
DBSettings.SETTING.SPACE_ZERO.id + " INTEGER");
ContentValues updatedata = new ContentValues();
updatedata.put(DBSettings.SETTING.KEY_REMAP.id, 0);
updatedata.put(DBSettings.SETTING.SPACE_ZERO.id, 0);
db.update(SETTING_TABLE_NAME, updatedata, null, null);
}
onCreate(db);
Log.i("T9DB.onUpgrade", "Done.");
}
}
}

View file

@ -18,16 +18,15 @@ import android.view.inputmethod.InputConnection;
import android.widget.Toast; import android.widget.Toast;
import io.github.sspanak.tt9.LangHelper.LANGUAGE; import io.github.sspanak.tt9.LangHelper.LANGUAGE;
import io.github.sspanak.tt9.T9DB.DBSettings.SETTING;
import io.github.sspanak.tt9.Utils.SpecialInputType; import io.github.sspanak.tt9.Utils.SpecialInputType;
import io.github.sspanak.tt9.db.T9DB;
import io.github.sspanak.tt9.preferences.T9Preferences;
import java.util.AbstractList; import java.util.AbstractList;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class TraditionalT9 extends InputMethodService implements public class TraditionalT9 extends InputMethodService implements KeyboardView.OnKeyboardActionListener {
KeyboardView.OnKeyboardActionListener {
private CandidateView mCandidateView; private CandidateView mCandidateView;
private InterfaceHandler interfacehandler = null; private InterfaceHandler interfacehandler = null;
@ -67,10 +66,7 @@ public class TraditionalT9 extends InputMethodService implements
private LANGUAGE[] mLangsAvailable = null; private LANGUAGE[] mLangsAvailable = null;
private static final int CAPS_OFF = 0; private final static int[] CAPS_CYCLE = { T9Preferences.CASE_LOWER, T9Preferences.CASE_CAPITALIZE, T9Preferences.CASE_UPPER };
private static final int CAPS_SINGLE = 1;
private static final int CAPS_ALL = 2;
private final static int[] CAPS_CYCLE = { CAPS_OFF, CAPS_SINGLE, CAPS_ALL };
private final static int T9DELAY = 900; private final static int T9DELAY = 900;
final Handler t9releasehandler = new Handler(); final Handler t9releasehandler = new Handler();
@ -82,11 +78,9 @@ public class TraditionalT9 extends InputMethodService implements
}; };
private T9DB db; private T9DB db;
private T9Preferences prefs;
public static final int MODE_LANG = 0; private static final int[] MODE_CYCLE = { T9Preferences.MODE_PREDICTIVE, T9Preferences.MODE_ABC, T9Preferences.MODE_123 };
public static final int MODE_TEXT = 1;
public static final int MODE_NUM = 2;
private static final int[] MODE_CYCLE = { MODE_LANG, MODE_TEXT, MODE_NUM };
private int mKeyMode; private int mKeyMode;
private InputConnection currentInputConnection = null; private InputConnection currentInputConnection = null;
@ -101,6 +95,7 @@ public class TraditionalT9 extends InputMethodService implements
mPrevious = -1; mPrevious = -1;
mCharIndex = 0; mCharIndex = 0;
db = T9DB.getInstance(this); db = T9DB.getInstance(this);
prefs = new T9Preferences(this);
if (interfacehandler == null) { if (interfacehandler == null) {
interfacehandler = new InterfaceHandler(getLayoutInflater().inflate(R.layout.mainview, interfacehandler = new InterfaceHandler(getLayoutInflater().inflate(R.layout.mainview,
@ -133,7 +128,7 @@ public class TraditionalT9 extends InputMethodService implements
//updateKeyMode(); //updateKeyMode();
View v = getLayoutInflater().inflate(R.layout.mainview, null); View v = getLayoutInflater().inflate(R.layout.mainview, null);
interfacehandler.changeView(v); interfacehandler.changeView(v);
if (mKeyMode == MODE_LANG) { if (mKeyMode == T9Preferences.MODE_PREDICTIVE) {
interfacehandler.showHold(true); interfacehandler.showHold(true);
} else { } else {
interfacehandler.showHold(false); interfacehandler.showHold(false);
@ -199,7 +194,7 @@ public class TraditionalT9 extends InputMethodService implements
} }
protected void showAddWord() { protected void showAddWord() {
if (mKeyMode == MODE_LANG) { if (mKeyMode == T9Preferences.MODE_PREDICTIVE) {
// decide if we are going to look for work to base on // decide if we are going to look for work to base on
String template = mComposing.toString(); String template = mComposing.toString();
if (template.length() == 0) { if (template.length() == 0) {
@ -245,6 +240,7 @@ public class TraditionalT9 extends InputMethodService implements
@Override @Override
public void onStartInput(EditorInfo inputField, boolean restarting) { public void onStartInput(EditorInfo inputField, boolean restarting) {
super.onStartInput(inputField, restarting); super.onStartInput(inputField, restarting);
currentInputConnection = getCurrentInputConnection(); currentInputConnection = getCurrentInputConnection();
//Log.d("T9.onStartInput", "INPUTTYPE: " + inputField.inputType + " FIELDID: " + inputField.fieldId + //Log.d("T9.onStartInput", "INPUTTYPE: " + inputField.inputType + " FIELDID: " + inputField.fieldId +
// " FIELDNAME: " + inputField.fieldName + " PACKAGE NAME: " + inputField.packageName); // " FIELDNAME: " + inputField.fieldName + " PACKAGE NAME: " + inputField.packageName);
@ -272,24 +268,14 @@ public class TraditionalT9 extends InputMethodService implements
// way. // way.
clearState(); clearState();
// get settings mLangsAvailable = LangHelper.buildLangs(prefs.getEnabledLanguages());
Object[] settings = db.getSettings(new SETTING[] { mLang = sanitizeLang(LANGUAGE.get(prefs.getInputLanguage()));
// 0, 1, 2,
// "2" is no longer in use; delete in #7
SETTING.LANG_SUPPORT, SETTING.LAST_LANG, SETTING.MODE_NOTIFY,
// 3, 4, 5
// "5" is no longer in use; delete in #7
SETTING.INPUT_MODE, SETTING.LAST_WORD, SETTING.SPACE_ZERO
});
mLangsAvailable = LangHelper.buildLangs((Integer)settings[0]);
mLang = sanitizeLang(LANGUAGE.get((Integer)settings[1]));
updateCandidates(); updateCandidates();
//TODO: Check if "restarting" variable will make things faster/more effecient //TODO: Check if "restarting" variable will make things faster/more effecient
mKeyMode = MODE_TEXT; mKeyMode = T9Preferences.MODE_ABC;
// We are now going to initialize our state based on the type of // We are now going to initialize our state based on the type of
// text being edited. // text being edited.
@ -298,13 +284,13 @@ public class TraditionalT9 extends InputMethodService implements
case InputType.TYPE_CLASS_DATETIME: case InputType.TYPE_CLASS_DATETIME:
// Numbers and dates default to the symbols keyboard, with // Numbers and dates default to the symbols keyboard, with
// no extra features. // no extra features.
mKeyMode = MODE_NUM; mKeyMode = T9Preferences.MODE_123;
break; break;
case InputType.TYPE_CLASS_PHONE: case InputType.TYPE_CLASS_PHONE:
// Phones will also default to the symbols keyboard, though // Phones will also default to the symbols keyboard, though
// often you will want to have a dedicated phone keyboard. // often you will want to have a dedicated phone keyboard.
mKeyMode = MODE_NUM; mKeyMode = T9Preferences.MODE_123;
break; break;
case InputType.TYPE_CLASS_TEXT: case InputType.TYPE_CLASS_TEXT:
@ -312,7 +298,7 @@ public class TraditionalT9 extends InputMethodService implements
// normal alphabetic keyboard, and assume that we should // normal alphabetic keyboard, and assume that we should
// be doing predictive text (showing candidates as the // be doing predictive text (showing candidates as the
// user types). // user types).
mKeyMode = (Integer)settings[3]; mKeyMode = prefs.getInputMode();
// We now look for a few special variations of text that will // We now look for a few special variations of text that will
// modify our behavior. // modify our behavior.
@ -321,7 +307,7 @@ public class TraditionalT9 extends InputMethodService implements
|| variation == InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD) { || variation == InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD) {
// Do not display predictions / what the user is typing // Do not display predictions / what the user is typing
// when they are entering a password. // when they are entering a password.
mKeyMode = MODE_TEXT; mKeyMode = T9Preferences.MODE_ABC;
} }
if (variation == InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS if (variation == InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS
@ -329,7 +315,7 @@ public class TraditionalT9 extends InputMethodService implements
|| variation == InputType.TYPE_TEXT_VARIATION_FILTER) { || variation == InputType.TYPE_TEXT_VARIATION_FILTER) {
// Our predictions are not useful for e-mail addresses // Our predictions are not useful for e-mail addresses
// or URIs. // or URIs.
mKeyMode = MODE_TEXT; mKeyMode = T9Preferences.MODE_ABC;
} }
if ((inputField.inputType & InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE) != 0) { if ((inputField.inputType & InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE) != 0) {
@ -339,7 +325,7 @@ public class TraditionalT9 extends InputMethodService implements
// candidates when in fullscreen mode, otherwise relying // candidates when in fullscreen mode, otherwise relying
// own it displaying its own UI. // own it displaying its own UI.
// ???? // ????
mKeyMode = (Integer)settings[3]; mKeyMode = prefs.getInputMode();
} }
// handle filter list cases... do not hijack DPAD center and make // handle filter list cases... do not hijack DPAD center and make
@ -361,22 +347,23 @@ public class TraditionalT9 extends InputMethodService implements
updateShiftKeyState(inputField); updateShiftKeyState(inputField);
} }
if (inputField.inputType == SpecialInputType.TYPE_SHARP_007H_PHONE_BOOK) { if (inputField.inputType == SpecialInputType.TYPE_SHARP_007H_PHONE_BOOK) {
mKeyMode = MODE_TEXT; mKeyMode = T9Preferences.MODE_ABC;
} }
String prevword = null; if (
if (inputField.privateImeOptions != null inputField.privateImeOptions != null
&& inputField.privateImeOptions.equals("io.github.sspanak.tt9.addword=true")) { && inputField.privateImeOptions.equals("io.github.sspanak.tt9.addword=true")
) {
mAddingWord = true; mAddingWord = true;
// mAddingSkipInput = true; // mAddingSkipInput = true;
// Log.d("onStartInput", "ADDING WORD"); // Log.d("onStartInput", "ADDING WORD");
mKeyMode = MODE_TEXT; mKeyMode = T9Preferences.MODE_ABC;
} else { } else {
mAddingWord = false; mAddingWord = false;
// Log.d("onStartInput", "not adding word"); // Log.d("onStartInput", "not adding word");
prevword = (String)settings[4]; String prevword = prefs.getLastWord();
if (prevword != null) { if (prevword != "") {
onText(prevword); onText(prevword);
db.storeSettingString(SETTING.LAST_WORD, null); prefs.setLastWord("");
} }
} }
@ -402,7 +389,7 @@ public class TraditionalT9 extends InputMethodService implements
super.onFinishInput(); super.onFinishInput();
// Log.d("onFinishInput", "When is this called?"); // Log.d("onFinishInput", "When is this called?");
if (mEditing == EDITING || mEditing == EDITING_NOSHOW) { if (mEditing == EDITING || mEditing == EDITING_NOSHOW) {
db.storeSettingInt(SETTING.LAST_LANG, mLang.id); prefs.setInputLanguage(mLang.id);
commitTyped(); commitTyped();
finish(); finish();
} }
@ -452,7 +439,7 @@ public class TraditionalT9 extends InputMethodService implements
int candidatesStart, int candidatesEnd) { int candidatesStart, int candidatesEnd) {
super.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd, candidatesStart, super.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd, candidatesStart,
candidatesEnd); candidatesEnd);
if (mKeyMode == MODE_TEXT) { return; } // stops the ghost fast-type commit if (mKeyMode == T9Preferences.MODE_ABC) { return; } // stops the ghost fast-type commit
// If the current selection in the text view changes, we should // If the current selection in the text view changes, we should
// clear whatever candidate text we have. // clear whatever candidate text we have.
if ((mComposing.length() > 0 || mComposingI.length() > 0) if ((mComposing.length() > 0 || mComposingI.length() > 0)
@ -477,17 +464,13 @@ public class TraditionalT9 extends InputMethodService implements
// ?????????????? // ??????????????
} }
private KeyEvent TranslateKey(int keyCode, KeyEvent event) { /**
KeyEvent key = event; * Use this to monitor key events being delivered to the application. We get
if (KeyMap.keyMapping.containsKey(keyCode)) { * first crack at them, and can either resume them or let them continue to
key = new KeyEvent(event.getDownTime(), event.getEventTime(), event.getAction(), * the app.
KeyMap.keyMapping.get(keyCode), event.getRepeatCount(), event.getMetaState(), */
event.getDeviceId(), 0, event.getFlags()); @Override
} public boolean onKeyDown(int keyCode, KeyEvent event) {
return key;
}
private boolean onKeyDown_(int keyCode, KeyEvent event) {
// Log.d("onKeyDown", "Key: " + event + " repeat?: " + // Log.d("onKeyDown", "Key: " + event + " repeat?: " +
// event.getRepeatCount() + " long-time: " + event.isLongPress()); // event.getRepeatCount() + " long-time: " + event.isLongPress());
if (mEditing == NON_EDIT) { if (mEditing == NON_EDIT) {
@ -516,7 +499,7 @@ public class TraditionalT9 extends InputMethodService implements
return super.onKeyDown(keyCode, event); return super.onKeyDown(keyCode, event);
} }
} else if (keyCode == KeyEvent.KEYCODE_DEL) {// Special handling of the delete key: if we currently are } else if (keyCode == prefs.getKeyBackspace()) {// Special handling of the delete key: if we currently are
// composing text for the user, we want to modify that instead // composing text for the user, we want to modify that instead
// of let the application do the delete itself. // of let the application do the delete itself.
// if (mComposing.length() > 0) { // if (mComposing.length() > 0) {
@ -530,7 +513,7 @@ public class TraditionalT9 extends InputMethodService implements
if (event.getRepeatCount() != 0) { if (event.getRepeatCount() != 0) {
return true; return true;
} }
if (mKeyMode == MODE_TEXT) { if (mKeyMode == T9Preferences.MODE_ABC) {
t9releasehandler.removeCallbacks(mt9release); t9releasehandler.removeCallbacks(mt9release);
} }
if (keyCode == KeyEvent.KEYCODE_BACK) { if (keyCode == KeyEvent.KEYCODE_BACK) {
@ -564,20 +547,6 @@ public class TraditionalT9 extends InputMethodService implements
commitReset(); commitReset();
return super.onKeyDown(keyCode, event); return super.onKeyDown(keyCode, event);
} }
/**
* Use this to monitor key events being delivered to the application. We get
* first crack at them, and can either resume them or let them continue to
* the app.
*/
@Override
public boolean onKeyDown(int inputKeyCode, KeyEvent inputEvent) {
KeyEvent event = TranslateKey(inputKeyCode, inputEvent);
if (event != null) {
return onKeyDown_(event.getKeyCode(), event);
}
return onKeyDown_(inputKeyCode, inputEvent);
}
protected void launchOptions() { protected void launchOptions() {
Intent awintent = new Intent(this, TraditionalT9Settings.class); Intent awintent = new Intent(this, TraditionalT9Settings.class);
@ -607,7 +576,7 @@ public class TraditionalT9 extends InputMethodService implements
} }
return true; return true;
} else if (keyCode == KeyEvent.KEYCODE_STAR) { } else if (keyCode == KeyEvent.KEYCODE_STAR) {
if (mKeyMode != MODE_NUM) { if (mKeyMode != T9Preferences.MODE_123) {
if (mLangsAvailable.length > 1) { if (mLangsAvailable.length > 1) {
nextLang(); nextLang();
} else { } else {
@ -620,7 +589,7 @@ public class TraditionalT9 extends InputMethodService implements
if (interfacehandler != null) { if (interfacehandler != null) {
interfacehandler.setPressed(keyCode, false); interfacehandler.setPressed(keyCode, false);
} }
if (mKeyMode == MODE_LANG) { if (mKeyMode == T9Preferences.MODE_PREDICTIVE) {
if (mWordFound) { if (mWordFound) {
showAddWord(); showAddWord();
} else { } else {
@ -637,13 +606,13 @@ public class TraditionalT9 extends InputMethodService implements
return true; return true;
} }
if (keyCode >= KeyEvent.KEYCODE_0 && keyCode <= KeyEvent.KEYCODE_9) { if (keyCode >= KeyEvent.KEYCODE_0 && keyCode <= KeyEvent.KEYCODE_9) {
if (mKeyMode == MODE_LANG) { if (mKeyMode == T9Preferences.MODE_PREDICTIVE) {
commitTyped(); commitTyped();
onText(String.valueOf(keyCode - KeyEvent.KEYCODE_0)); onText(String.valueOf(keyCode - KeyEvent.KEYCODE_0));
} else if (mKeyMode == MODE_TEXT) { } else if (mKeyMode == T9Preferences.MODE_ABC) {
commitReset(); commitReset();
onText(String.valueOf(keyCode - KeyEvent.KEYCODE_0)); onText(String.valueOf(keyCode - KeyEvent.KEYCODE_0));
} else if (mKeyMode == MODE_NUM) { } else if (mKeyMode == T9Preferences.MODE_123) {
if (keyCode == KeyEvent.KEYCODE_0) { if (keyCode == KeyEvent.KEYCODE_0) {
onText("+"); onText("+");
} }
@ -651,8 +620,13 @@ public class TraditionalT9 extends InputMethodService implements
} }
return true; return true;
} }
/**
private boolean onKeyUp_(int keyCode, KeyEvent event) { * Use this to monitor key events being delivered to the application. We get
* first crack at them, and can either resume them or let them continue to
* the app.
*/
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
// Log.d("onKeyUp", "Key: " + keyCode + " repeat?: " + // Log.d("onKeyUp", "Key: " + keyCode + " repeat?: " +
// event.getRepeatCount()); // event.getRepeatCount());
if (mEditing == NON_EDIT) { if (mEditing == NON_EDIT) {
@ -700,7 +674,7 @@ public class TraditionalT9 extends InputMethodService implements
} }
return false; return false;
} else if (keyCode == KeyEvent.KEYCODE_DEL) { } else if (keyCode == prefs.getKeyBackspace()) {
return true; return true;
} else if (keyCode == KeyEvent.KEYCODE_ENTER) { } else if (keyCode == KeyEvent.KEYCODE_ENTER) {
return false; return false;
@ -743,20 +717,6 @@ public class TraditionalT9 extends InputMethodService implements
commitReset(); commitReset();
return super.onKeyUp(keyCode, event); return super.onKeyUp(keyCode, event);
} }
/**
* Use this to monitor key events being delivered to the application. We get
* first crack at them, and can either resume them or let them continue to
* the app.
*/
@Override
public boolean onKeyUp(int inputKeyCode, KeyEvent inputEvent) {
KeyEvent event = TranslateKey(inputKeyCode, inputEvent);
if (event != null) {
return onKeyUp_(event.getKeyCode(), event);
}
return onKeyUp_(inputKeyCode, inputEvent);
}
/** /**
* Helper function to commit any text being composed in to the editor. * Helper function to commit any text being composed in to the editor.
@ -780,7 +740,7 @@ public class TraditionalT9 extends InputMethodService implements
*/ */
private void updateShiftKeyState(EditorInfo attr) { private void updateShiftKeyState(EditorInfo attr) {
// Log.d("updateShift", "CM start: " + mCapsMode); // Log.d("updateShift", "CM start: " + mCapsMode);
if (attr != null && mCapsMode != CAPS_ALL) { if (attr != null && mCapsMode != T9Preferences.CASE_UPPER) {
int caps = 0; int caps = 0;
if (attr.inputType != InputType.TYPE_NULL) { if (attr.inputType != InputType.TYPE_NULL) {
caps = currentInputConnection.getCursorCapsMode(attr.inputType); caps = currentInputConnection.getCursorCapsMode(attr.inputType);
@ -788,13 +748,13 @@ public class TraditionalT9 extends InputMethodService implements
// mInputView.setShifted(mCapsLock || caps != 0); // mInputView.setShifted(mCapsLock || caps != 0);
// Log.d("updateShift", "caps: " + caps); // Log.d("updateShift", "caps: " + caps);
if ((caps & TextUtils.CAP_MODE_CHARACTERS) == TextUtils.CAP_MODE_CHARACTERS) { if ((caps & TextUtils.CAP_MODE_CHARACTERS) == TextUtils.CAP_MODE_CHARACTERS) {
mCapsMode = CAPS_ALL; mCapsMode = T9Preferences.CASE_UPPER;
} else if ((caps & TextUtils.CAP_MODE_SENTENCES) == TextUtils.CAP_MODE_SENTENCES) { } else if ((caps & TextUtils.CAP_MODE_SENTENCES) == TextUtils.CAP_MODE_SENTENCES) {
mCapsMode = CAPS_SINGLE; mCapsMode = T9Preferences.CASE_CAPITALIZE;
} else if ((caps & TextUtils.CAP_MODE_WORDS) == TextUtils.CAP_MODE_WORDS) { } else if ((caps & TextUtils.CAP_MODE_WORDS) == TextUtils.CAP_MODE_WORDS) {
mCapsMode = CAPS_SINGLE; mCapsMode = T9Preferences.CASE_CAPITALIZE;
} else { } else {
mCapsMode = CAPS_OFF; mCapsMode = T9Preferences.CASE_LOWER;
} }
updateKeyMode(); updateKeyMode();
} }
@ -820,11 +780,11 @@ public class TraditionalT9 extends InputMethodService implements
// Log.d("OnKey", "pri: " + keyCode); // Log.d("OnKey", "pri: " + keyCode);
// Log.d("onKey", "START Cm: " + mCapsMode); // Log.d("onKey", "START Cm: " + mCapsMode);
// HANDLE SPECIAL KEYS // HANDLE SPECIAL KEYS
if (keyCode == KeyEvent.KEYCODE_DEL) { if (keyCode == prefs.getKeyBackspace()) {
handleBackspace(); handleBackspace();
} else if (keyCode == KeyEvent.KEYCODE_STAR) { } else if (keyCode == KeyEvent.KEYCODE_STAR) {
// change case // change case
if (mKeyMode == MODE_NUM) { if (mKeyMode == T9Preferences.MODE_123) {
handleCharacter(KeyEvent.KEYCODE_STAR); handleCharacter(KeyEvent.KEYCODE_STAR);
} else { } else {
handleShift(); handleShift();
@ -878,14 +838,14 @@ public class TraditionalT9 extends InputMethodService implements
} }
if (mComposing.length() > 0) { if (mComposing.length() > 0) {
switch (mKeyMode) { switch (mKeyMode) {
case MODE_LANG: case T9Preferences.MODE_PREDICTIVE:
commitTyped(); commitTyped();
break; break;
case MODE_TEXT: case T9Preferences.MODE_ABC:
commitTyped(); commitTyped();
charReset(); charReset();
break; break;
case MODE_NUM: case T9Preferences.MODE_123:
// shouldn't happen // shouldn't happen
break; break;
} }
@ -902,7 +862,7 @@ public class TraditionalT9 extends InputMethodService implements
updateCandidates(false); updateCandidates(false);
} }
private void updateCandidates(boolean backspace) { private void updateCandidates(boolean backspace) {
if (mKeyMode == MODE_LANG) { if (mKeyMode == T9Preferences.MODE_PREDICTIVE) {
int len = mComposingI.length(); int len = mComposingI.length();
if (len > 0) { if (len > 0) {
if (mComposingI.charAt(len - 1) == '1') { if (mComposingI.charAt(len - 1) == '1') {
@ -964,7 +924,7 @@ public class TraditionalT9 extends InputMethodService implements
interfacehandler.showNotFound(false); interfacehandler.showNotFound(false);
} }
} }
} else if (mKeyMode == MODE_TEXT) { } else if (mKeyMode == T9Preferences.MODE_ABC) {
if (mComposing.length() > 0) { if (mComposing.length() > 0) {
//Log.d("updateCandidates", "Previous: " + mComposing.toString()); //Log.d("updateCandidates", "Previous: " + mComposing.toString());
mSuggestionStrings.clear(); mSuggestionStrings.clear();
@ -993,7 +953,7 @@ public class TraditionalT9 extends InputMethodService implements
private void handleBackspace() { private void handleBackspace() {
final int length = mComposing.length(); final int length = mComposing.length();
final int length2 = mComposingI.length(); final int length2 = mComposingI.length();
if (mKeyMode == MODE_TEXT) { if (mKeyMode == T9Preferences.MODE_ABC) {
charReset(); charReset();
setCandidatesViewShown(false); setCandidatesViewShown(false);
} }
@ -1028,7 +988,7 @@ public class TraditionalT9 extends InputMethodService implements
updateCandidates(); updateCandidates();
} else { } else {
mPreviousWord = ""; mPreviousWord = "";
keyDownUp(KeyEvent.KEYCODE_DEL); keyDownUp(prefs.getKeyBackspace());
} }
updateShiftKeyState(getCurrentInputEditorInfo()); updateShiftKeyState(getCurrentInputEditorInfo());
// Log.d("handleBS", "Cm: " + mCapsMode); // Log.d("handleBS", "Cm: " + mCapsMode);
@ -1044,7 +1004,7 @@ public class TraditionalT9 extends InputMethodService implements
mCapsMode++; mCapsMode++;
} }
if (mKeyMode == MODE_LANG && mComposing.length() > 0) { if (mKeyMode == T9Preferences.MODE_PREDICTIVE && mComposing.length() > 0) {
updateCandidates(); updateCandidates();
currentInputConnection.setComposingText(mComposing, 1); currentInputConnection.setComposingText(mComposing, 1);
} }
@ -1058,7 +1018,7 @@ public class TraditionalT9 extends InputMethodService implements
*/ */
private void handleCharacter(int keyCode) { private void handleCharacter(int keyCode) {
switch (mKeyMode) { switch (mKeyMode) {
case MODE_LANG: case T9Preferences.MODE_PREDICTIVE:
// it begins // it begins
if (keyCode == KeyEvent.KEYCODE_POUND || keyCode == KeyEvent.KEYCODE_0) { if (keyCode == KeyEvent.KEYCODE_POUND || keyCode == KeyEvent.KEYCODE_0) {
if (mComposing.length() > 0) { if (mComposing.length() > 0) {
@ -1074,7 +1034,7 @@ public class TraditionalT9 extends InputMethodService implements
} }
break; break;
case MODE_TEXT: case T9Preferences.MODE_ABC:
t9releasehandler.removeCallbacks(mt9release); t9releasehandler.removeCallbacks(mt9release);
if (keyCode == KeyEvent.KEYCODE_POUND) { if (keyCode == KeyEvent.KEYCODE_POUND) {
keyCode = 10; keyCode = 10;
@ -1102,7 +1062,7 @@ public class TraditionalT9 extends InputMethodService implements
// start at caps if CapMode // start at caps if CapMode
// Log.d("handleChar", "Cm: " + mCapsMode); // Log.d("handleChar", "Cm: " + mCapsMode);
if (mCharIndex == 0 && mCapsMode != CAPS_OFF) { if (mCharIndex == 0 && mCapsMode != T9Preferences.CASE_LOWER) {
mCharIndex = CharMap.T9CAPSTART[mLang.index][keyCode]; mCharIndex = CharMap.T9CAPSTART[mLang.index][keyCode];
} }
@ -1120,15 +1080,15 @@ public class TraditionalT9 extends InputMethodService implements
t9releasehandler.postDelayed(mt9release, T9DELAY); t9releasehandler.postDelayed(mt9release, T9DELAY);
if (newChar) { if (newChar) {
// consume single caps // consume single caps
if (mCapsMode == CAPS_SINGLE) { if (mCapsMode == T9Preferences.CASE_CAPITALIZE) {
mCapsMode = CAPS_OFF; mCapsMode = T9Preferences.CASE_LOWER;
} }
} }
updateCandidates(); updateCandidates();
updateShiftKeyState(getCurrentInputEditorInfo()); updateShiftKeyState(getCurrentInputEditorInfo());
break; break;
case MODE_NUM: case T9Preferences.MODE_123:
if (keyCode == KeyEvent.KEYCODE_POUND) { if (keyCode == KeyEvent.KEYCODE_POUND) {
onText("#"); onText("#");
} else if (keyCode == KeyEvent.KEYCODE_STAR) { } else if (keyCode == KeyEvent.KEYCODE_STAR) {
@ -1173,7 +1133,7 @@ public class TraditionalT9 extends InputMethodService implements
mIgnoreDPADKeyUp = false; mIgnoreDPADKeyUp = false;
return super.onKeyUp(keyCode, event); return super.onKeyUp(keyCode, event);
} else { } else {
if (mKeyMode != MODE_NUM && mComposing.length() > 0) { if (mKeyMode != T9Preferences.MODE_123 && mComposing.length() > 0) {
if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) { if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
mCandidateView.scrollToSuggestion(1); mCandidateView.scrollToSuggestion(1);
if (mSuggestionStrings.size() > mCandidateView.mSelectedIndex) if (mSuggestionStrings.size() > mCandidateView.mSelectedIndex)
@ -1185,9 +1145,9 @@ public class TraditionalT9 extends InputMethodService implements
currentInputConnection.setComposingText(mSuggestionStrings.get(mCandidateView.mSelectedIndex), 1); currentInputConnection.setComposingText(mSuggestionStrings.get(mCandidateView.mSelectedIndex), 1);
return true; return true;
} else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) { } else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
if (mKeyMode == MODE_LANG) { if (mKeyMode == T9Preferences.MODE_PREDICTIVE) {
commitTyped(); commitTyped();
} else if (mKeyMode == MODE_TEXT) { } else if (mKeyMode == T9Preferences.MODE_ABC) {
commitReset(); commitReset();
} }
// getCurrentInputConnection().sendKeyEvent(mDPADkeyEvent); // getCurrentInputConnection().sendKeyEvent(mDPADkeyEvent);
@ -1219,8 +1179,8 @@ public class TraditionalT9 extends InputMethodService implements
private void commitReset() { private void commitReset() {
commitTyped(); commitTyped();
charReset(); charReset();
if (mCapsMode == CAPS_SINGLE) { if (mCapsMode == T9Preferences.CASE_CAPITALIZE) {
mCapsMode = CAPS_OFF; mCapsMode = T9Preferences.CASE_LOWER;
} }
// Log.d("commitReset", "CM pre: " + mCapsMode); // Log.d("commitReset", "CM pre: " + mCapsMode);
updateShiftKeyState(getCurrentInputEditorInfo()); updateShiftKeyState(getCurrentInputEditorInfo());
@ -1260,7 +1220,7 @@ public class TraditionalT9 extends InputMethodService implements
private void resetKeyMode() { private void resetKeyMode() {
charReset(); charReset();
if (mKeyMode != MODE_NUM) { if (mKeyMode != T9Preferences.MODE_123) {
commitTyped(); commitTyped();
} }
mComposing.setLength(0); mComposing.setLength(0);
@ -1276,12 +1236,12 @@ public class TraditionalT9 extends InputMethodService implements
int icon = 0; int icon = 0;
switch (mKeyMode) { switch (mKeyMode) {
case MODE_TEXT: case T9Preferences.MODE_ABC:
interfacehandler.showHold(false); interfacehandler.showHold(false);
icon = LangHelper.ICONMAP[mLang.index][mKeyMode][mCapsMode]; icon = LangHelper.ICONMAP[mLang.index][mKeyMode][mCapsMode];
break; break;
case MODE_LANG: case T9Preferences.MODE_PREDICTIVE:
if (!db.ready) { if (!db.isReady()) {
if (!mGaveUpdateWarn) { if (!mGaveUpdateWarn) {
Toast.makeText(this, getText(R.string.updating_database_unavailable), Toast.LENGTH_LONG).show(); Toast.makeText(this, getText(R.string.updating_database_unavailable), Toast.LENGTH_LONG).show();
mGaveUpdateWarn = true; mGaveUpdateWarn = true;
@ -1302,7 +1262,7 @@ public class TraditionalT9 extends InputMethodService implements
// + mCapsMode); // + mCapsMode);
icon = LangHelper.ICONMAP[mLang.index][mKeyMode][mCapsMode]; icon = LangHelper.ICONMAP[mLang.index][mKeyMode][mCapsMode];
break; break;
case MODE_NUM: case T9Preferences.MODE_123:
interfacehandler.showHold(false); interfacehandler.showHold(false);
icon = R.drawable.ime_number; icon = R.drawable.ime_number;
break; break;
@ -1329,14 +1289,14 @@ public class TraditionalT9 extends InputMethodService implements
// mSuggestionStrings.get(mCandidateView.mSelectedIndex)); // mSuggestionStrings.get(mCandidateView.mSelectedIndex));
// get and commit selected suggestion // get and commit selected suggestion
ic.commitText(mSuggestionStrings.get(mCandidateView.mSelectedIndex), 1); ic.commitText(mSuggestionStrings.get(mCandidateView.mSelectedIndex), 1);
if (mKeyMode == MODE_LANG) { if (mKeyMode == T9Preferences.MODE_PREDICTIVE) {
// update freq // update freq
db.incrementWord(mSuggestionInts.get(mCandidateView.mSelectedIndex)); db.incrementWord(mSuggestionInts.get(mCandidateView.mSelectedIndex));
} }
} else { } else {
// commit suggestion index // commit suggestion index
ic.commitText(mSuggestionStrings.get(index), 1); ic.commitText(mSuggestionStrings.get(index), 1);
if (mKeyMode == MODE_LANG) { if (mKeyMode == T9Preferences.MODE_PREDICTIVE) {
db.incrementWord(mSuggestionInts.get(index)); db.incrementWord(mSuggestionInts.get(index));
} }
} }

View file

@ -7,15 +7,12 @@ import android.app.ProgressDialog;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.res.Resources;
import android.database.Cursor;
import android.database.DatabaseUtils.InsertHelper; import android.database.DatabaseUtils.InsertHelper;
import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase;
import android.net.Uri; import android.net.Uri;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.os.Environment; import android.os.Environment;
import android.os.Handler;
import android.os.SystemClock; import android.os.SystemClock;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
@ -27,39 +24,32 @@ import android.widget.Toast;
import com.stackoverflow.answer.UnicodeBOMInputStream; import com.stackoverflow.answer.UnicodeBOMInputStream;
import io.github.sspanak.tt9.LangHelper.LANGUAGE; import io.github.sspanak.tt9.LangHelper.LANGUAGE;
import io.github.sspanak.tt9.T9DB.DBSettings.SETTING; import io.github.sspanak.tt9.db.T9DB;
import io.github.sspanak.tt9.preferences.T9Preferences;
import io.github.sspanak.tt9.settings.CustomInflater; import io.github.sspanak.tt9.settings.CustomInflater;
import io.github.sspanak.tt9.settings.Setting; import io.github.sspanak.tt9.settings.Setting;
import io.github.sspanak.tt9.settings.SettingAdapter; import io.github.sspanak.tt9.settings.SettingAdapter;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.Closeable; import java.io.Closeable;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.util.AbstractList;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
public class TraditionalT9Settings extends ListActivity implements public class TraditionalT9Settings extends ListActivity implements DialogInterface.OnCancelListener {
DialogInterface.OnCancelListener {
AsyncTask<String, Integer, Reply> task = null; AsyncTask<String, Integer, Reply> task = null;
final static String dictname = "%s-utf8.txt"; final static String dictname = "%s-utf8.txt";
final static String userdictname = "user.%s.dict"; final static String userdictname = "user.%s.dict";
final static String backupname = "t9backup.txt";
final static String sddir = "tt9"; final static String sddir = "tt9";
final int BACKUP_Q_LIMIT = 1000; final int BACKUP_Q_LIMIT = 1000;
@ -136,13 +126,11 @@ public class TraditionalT9Settings extends ListActivity implements
long size; long size;
long pos; long pos;
boolean internal; boolean internal;
boolean restore;
String[] dicts; String[] dicts;
LANGUAGE[] mSupportedLanguages; LANGUAGE[] mSupportedLanguages;
LoadDictTask(int msgid, boolean intern, boolean restorebackup, LANGUAGE[] supportedLanguages) { LoadDictTask(int msgid, boolean intern, LANGUAGE[] supportedLanguages) {
internal = intern; internal = intern;
restore = restorebackup;
int suplanglen = supportedLanguages.length; int suplanglen = supportedLanguages.length;
dicts = new String[suplanglen]; dicts = new String[suplanglen];
@ -160,7 +148,7 @@ public class TraditionalT9Settings extends ListActivity implements
pd.setOnCancelListener(TraditionalT9Settings.this); pd.setOnCancelListener(TraditionalT9Settings.this);
} }
private long getDictSizes(boolean internal, boolean restore, String[] dicts) { private long getDictSizes(boolean internal, String[] dicts) {
if (internal) { if (internal) {
InputStream input; InputStream input;
Properties props = new Properties(); Properties props = new Properties();
@ -183,32 +171,22 @@ public class TraditionalT9Settings extends ListActivity implements
} }
} else { } else {
File backupfile = new File(Environment.getExternalStorageDirectory(), sddir); File backupfile = new File(Environment.getExternalStorageDirectory(), sddir);
if (restore) { long total = 0;
// using external backup File f;
backupfile = new File(backupfile, backupname); for (String dict : dicts) {
if (backupfile.exists() && backupfile.isFile()) { f = new File(backupfile, dict);
return backupfile.length(); if (f.exists() && f.isFile()) {
total = total + f.length();
} else { } else {
return -1; total = total + 0;
} }
} else {
long total = 0;
File f;
for (String dict : dicts) {
f = new File(backupfile, dict);
if (f.exists() && f.isFile()) {
total = total + f.length();
} else {
total = total + 0;
}
}
return total;
} }
return total;
} }
} }
@Override protected void onPreExecute() { @Override protected void onPreExecute() {
size = getDictSizes(internal, restore, dicts); size = getDictSizes(internal, dicts);
pos = 0; pos = 0;
if ( size >= 0 ) { if ( size >= 0 ) {
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
@ -247,64 +225,45 @@ public class TraditionalT9Settings extends ListActivity implements
InputStream dictstream = null; InputStream dictstream = null;
try { try {
if (restore) { for (int x=0; x<dicts.length; x++) {
try { if (internal) {
dictstream = new FileInputStream(new File( try {
new File(Environment.getExternalStorageDirectory(), sddir), backupname)); dictstream = getAssets().open(dicts[x]);
reply = processFile(dictstream, reply, db, LANGUAGE.NONE, backupname); reply = processFile(dictstream, reply, db, mSupportedLanguages[x], dicts[x]);
} catch (FileNotFoundException e) { } catch (IOException e) {
reply.status = false; e.printStackTrace();
reply.forceMsg("Backup file not found: " + e.getMessage()); reply.status = false;
closeStream(dictstream, reply); // this is silly but it reply.forceMsg("IO Error: " + e.getMessage());
return reply; // stops IDE nagging at me. }
} catch (IOException e) { } else {
reply.status = false; try {
reply.forceMsg("IO Error: " + e.getMessage()); dictstream = new FileInputStream(new File(
closeStream(dictstream, reply); // this is silly but it new File(Environment.getExternalStorageDirectory(), sddir), dicts[x]));
return reply; // stops IDE nagging at me. reply = processFile(dictstream, reply, db, mSupportedLanguages[x], dicts[x]);
} catch (FileNotFoundException e) {
reply.status = false;
reply.forceMsg("File not found: " + e.getMessage());
final String msg = mContext.getString(R.string.pref_loaduser_notfound, dicts[x]);
//Log.d("T9Setting.load", "Built string. Calling Toast.");
((Activity) mContext).runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(mContext,
msg,
Toast.LENGTH_SHORT).show();
}
});
closeStream(dictstream, reply); // this is silly but it
// stops IDE nagging at me.
} catch (IOException e) {
reply.status = false;
reply.forceMsg("IO Error: " + e.getMessage());
closeStream(dictstream, reply); // this is silly but it
return reply; // stops IDE nagging at me.
}
} }
closeStream(dictstream, reply); closeStream(dictstream, reply);
} else {
for (int x=0; x<dicts.length; x++) {
if (internal) {
try {
dictstream = getAssets().open(dicts[x]);
reply = processFile(dictstream, reply, db, mSupportedLanguages[x], dicts[x]);
} catch (IOException e) {
e.printStackTrace();
reply.status = false;
reply.forceMsg("IO Error: " + e.getMessage());
}
} else {
try {
dictstream = new FileInputStream(new File(
new File(Environment.getExternalStorageDirectory(), sddir), dicts[x]));
reply = processFile(dictstream, reply, db, mSupportedLanguages[x], dicts[x]);
} catch (FileNotFoundException e) {
reply.status = false;
reply.forceMsg("File not found: " + e.getMessage());
final String msg = mContext.getString(R.string.pref_loaduser_notfound, dicts[x]);
//Log.d("T9Setting.load", "Built string. Calling Toast.");
((Activity) mContext).runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(mContext,
msg,
Toast.LENGTH_SHORT).show();
}
});
closeStream(dictstream, reply); // this is silly but it
// stops IDE nagging at me.
} catch (IOException e) {
reply.status = false;
reply.forceMsg("IO Error: " + e.getMessage());
closeStream(dictstream, reply); // this is silly but it
return reply; // stops IDE nagging at me.
}
}
closeStream(dictstream, reply);
}
} }
} catch (LoadException e) { } catch (LoadException e) {
// too many errors, bail // too many errors, bail
@ -489,190 +448,7 @@ public class TraditionalT9Settings extends ListActivity implements
@Override @Override
protected void onPostExecute(Reply result) { protected void onPostExecute(Reply result) {
if (restore) { finishAndShowError(pd, result, R.string.pref_load_title);
finishAndShowError(pd, result, R.string.pref_restore_title);
} else {
finishAndShowError(pd, result, R.string.pref_load_title);
}
}
}
private class DumpDictTask extends AsyncTask<String, Integer, Reply> {
ProgressDialog pd;
DumpDictTask(int msgid) {
pd = new ProgressDialog(TraditionalT9Settings.this);
pd.setMessage(getResources().getString(msgid));
pd.setOnCancelListener(TraditionalT9Settings.this);
}
@Override protected void onPreExecute() {
pd.show();
}
@Override
protected Reply doInBackground(String... ignore) {
Reply reply = new Reply();
SQLiteDatabase db;
db = T9DB.getSQLDB(mContext);
if (db == null) {
reply.forceMsg("Database unavailable at this time. (May be updating)");
reply.status = false;
return reply;
}
long entries;
int current = 0;
int pos = 0;
int last = 0;
File backupfile = new File(new File(Environment.getExternalStorageDirectory(),
sddir), backupname);
db.setLockingEnabled(false);
Log.d("doInBackground", "Dumping dict...");
BufferedWriter bw;
OutputStream dictstream = null;
try {
dictstream = new FileOutputStream(backupfile);
} catch (FileNotFoundException e) {
reply.status = false;
reply.forceMsg("Backup file error: " + e.getMessage());
return reply;
}
try {
bw = new BufferedWriter(new OutputStreamWriter(dictstream, "UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
reply.status = false;
reply.forceMsg("Encoding Error (backupfile): " + e.getMessage());
closeStream(dictstream, reply);
return reply;
}
long startnow, endnow;
startnow = SystemClock.uptimeMillis();
String q = "SELECT count(*) FROM " + T9DB.WORD_TABLE_NAME;
Cursor cur = db.rawQuery(q, null);
cur.moveToFirst();
entries = cur.getInt(0);
// pd.setMax((int)entries);
cur.close();
try {
while (pos < entries) {
q = "SELECT " + T9DB.COLUMN_ID + ", " + T9DB.COLUMN_LANG + ", " +
T9DB.COLUMN_WORD + ", " + T9DB.COLUMN_FREQUENCY +
" FROM " + T9DB.WORD_TABLE_NAME +
" WHERE " + T9DB.COLUMN_ID + ">" + current +
" ORDER BY " + T9DB.COLUMN_ID + " LIMIT " + BACKUP_Q_LIMIT;
cur = db.rawQuery(q, null);
for (cur.moveToFirst(); !cur.isAfterLast(); cur.moveToNext()) {
if (isCancelled()) {
reply.status = false;
reply.forceMsg("User cancelled.");
break;
}
current = cur.getInt(0);
pos++;
try {
bw.write(cur.getString(2)); // write word
bw.write(" ");
bw.write(Integer.toString(cur.getInt(3))); // then freq
bw.write(" ");
bw.write(Integer.toString(cur.getInt(1))); // then lang
bw.newLine();
} catch (Exception e) {
e.printStackTrace();
reply.status = false;
reply.forceMsg("Error: " + e.getMessage());
closeStream(dictstream, reply);
}
if ((pos - last) > 80) {
publishProgress((int) ((float) pos / entries * 10000));
last = pos;
}
}
cur.close();
}
} finally {
cur.close();
}
publishProgress(10000);
endnow = SystemClock.uptimeMillis();
Log.d("TIMING", "Execution time: " + (endnow - startnow) + " ms");
Log.d("doInBackground", "entries: " + entries + " last: " + pos);
try {
bw.flush();
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
closeStream(dictstream, reply);
return reply;
}
@Override
protected void onProgressUpdate(Integer... progress) {
if (pd.isShowing()) {
pd.setProgress(progress[0]);
}
}
/**
* The system calls this to perform work in the UI thread and delivers
* the result from doInBackground()
*/
@Override
protected void onPostExecute(Reply result) {
finishAndShowError(pd, result, R.string.pref_backup_title);
}
}
private class NukeDictTask extends AsyncTask<String, Integer, Reply> {
ProgressDialog pd;
NukeDictTask(int msgid) {
pd = new ProgressDialog(TraditionalT9Settings.this);
pd.setMessage(getResources().getString(msgid));
pd.setCancelable(false);
pd.setProgressStyle(ProgressDialog.STYLE_SPINNER);
}
@Override protected void onPreExecute() {
pd.show();
}
@Override
protected Reply doInBackground(String... ignore) {
Reply reply = new Reply();
Log.d("doInBackground", "Nuking dict...");
long startnow, endnow;
startnow = SystemClock.uptimeMillis();
T9DB t9db = T9DB.getInstance(mContext);
t9db.nuke();
endnow = SystemClock.uptimeMillis();
Log.d("TIMING", "Execution time: " + (endnow - startnow) + " ms");
return reply;
}
@Override
protected void onCancelled() {
// Pointless callback. Thanks android.
}
/**
* The system calls this to perform work in the UI thread and delivers
* the result from doInBackground()
*/
@Override
protected void onPostExecute(Reply result) {
finishAndShowError(pd, result, R.string.pref_nuke_title);
} }
} }
@ -684,10 +460,14 @@ public class TraditionalT9Settings extends ListActivity implements
// http://stackoverflow.com/questions/7645880/listview-with-onitemclicklistener-android // http://stackoverflow.com/questions/7645880/listview-with-onitemclicklistener-android
// get settings // get settings
Object[] settings = T9DB.getInstance(this).getSettings(new SETTING[] T9Preferences prefs = new T9Preferences(this);
// Order should be based on SETTING.sqOrder Object[] settings = {
// "MODE_NOTIFY", "SPACE_ZERO" and "KEY_REMAP" are no longer in use; delete in #7 prefs.getInputMode(),
{SETTING.INPUT_MODE, SETTING.LANG_SUPPORT, SETTING.MODE_NOTIFY, SETTING.KEY_REMAP, SETTING.SPACE_ZERO}); prefs.getEnabledLanguages(),
null, // MODE_NOTIFY; not used, remove in #29
false, // KEY_REMAP; not used, remove in #29
true, // SPACE_ZERO; not used, remove in #29
};
ListAdapter settingitems; ListAdapter settingitems;
try { try {
settingitems = new SettingAdapter(this, CustomInflater.inflate(this, R.xml.prefs, settings)); settingitems = new SettingAdapter(this, CustomInflater.inflate(this, R.xml.prefs, settings));
@ -707,21 +487,9 @@ public class TraditionalT9Settings extends ListActivity implements
if (s.id.equals("help")) if (s.id.equals("help"))
openHelp(); openHelp();
else if (s.id.equals("loaddict")) else if (s.id.equals("loaddict"))
preloader(R.string.pref_loadingdict, true, false); preloader(R.string.pref_loadingdict, true);
else if (s.id.equals("loaduserdict")) else if (s.id.equals("loaduserdict"))
preloader(R.string.pref_loadinguserdict, false, false); preloader(R.string.pref_loadinguserdict, false);
else if (s.id.equals("nukedict"))
nukeDict();
else if (s.id.equals("backupdict"))
backupDict();
else if (s.id.equals("restoredict"))
restoreDict();
else if (s.id.equals("reloadKeys")) {
int msg = KeyMap.setKeys();
if (msg != 0) {
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
}
}
else else
s.clicked(mContext); s.clicked(mContext);
} }
@ -732,81 +500,17 @@ public class TraditionalT9Settings extends ListActivity implements
startActivity(i); startActivity(i);
} }
// LoadDictTask(int msgid, boolean intern, boolean restorebackup, CheckBoxPreference setting) private void preloader(int msgid, boolean internal) {
private void preloader(int msgid, boolean internal, boolean restorebackup) {
task = new LoadDictTask(msgid, internal, restorebackup,
LangHelper.buildLangs(T9DB.getInstance(mContext).getSettingInt(SETTING.LANG_SUPPORT))); task = new LoadDictTask(
msgid,
internal,
LangHelper.buildLangs(T9Preferences.getInstance(mContext).getEnabledLanguages())
);
task.execute(); task.execute();
} }
private void predumper(int msgid) {
task = new DumpDictTask(msgid);
task.execute();
}
private void nukeDict() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.pref_nuke_warn).setTitle(R.string.pref_nuke_title)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
task = new NukeDictTask(R.string.pref_nukingdict);
task.execute();
// restart settings to get fresh settings.
TraditionalT9Settings.this.finish();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
startActivity(new Intent(TraditionalT9Settings.this, TraditionalT9Settings.class));
}}, 1000);
}
}).setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
AlertDialog dialog = builder.create();
dialog.show();
}
private void backupDict() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
File saveloc = new File(Environment.getExternalStorageDirectory(), sddir);
saveloc.mkdirs();
if (!saveloc.canWrite()) {
Log.e("backupDict", "can't write : " + saveloc.getAbsolutePath());
showErrorDialogID(builder, R.string.pref_backup_title, R.string.pref_backup_noext);
return;
}
saveloc = new File(saveloc, backupname);
if (saveloc.exists()) {
builder.setMessage(R.string.pref_backup_warn).setTitle(R.string.pref_backup_title)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
predumper(R.string.pref_savingbackup);
}
}).setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
AlertDialog dialog = builder.create();
dialog.show();
} else {
predumper(R.string.pref_savingbackup);
}
} else {
showErrorDialogID(builder, R.string.pref_backup_title, R.string.pref_backup_noext);
}
}
private void showErrorDialog(CharSequence title, CharSequence msg) { private void showErrorDialog(CharSequence title, CharSequence msg) {
showErrorDialog(new AlertDialog.Builder(this), title, msg); showErrorDialog(new AlertDialog.Builder(this), title, msg);
@ -836,125 +540,6 @@ public class TraditionalT9Settings extends ListActivity implements
dialog.show(); dialog.show();
} }
private void restoreDict() {
// Environment.MEDIA_MOUNTED_READ_ONLY;
// Environment.MEDIA_MOUNTED;
AlertDialog.Builder builder = new AlertDialog.Builder(this);
if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(Environment.getExternalStorageState())
|| Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
if ((new File(new File(Environment.getExternalStorageDirectory(), sddir),
backupname)).exists()) {
Resources res = getResources();
builder
.setMessage(
res.getString(R.string.pref_restore_warn,
res.getString(R.string.pref_nukedict)))
.setTitle(R.string.pref_restore_title)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
preloader(R.string.pref_loadingbackup, false, true);
}
}).setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
AlertDialog dialog = builder.create();
dialog.show();
} else {
showErrorDialogID(builder, R.string.pref_restore_title,
R.string.pref_restore_nofile);
}
} else {
showErrorDialogID(builder, R.string.pref_restore_title, R.string.pref_restore_noext);
}
}
@SuppressWarnings("unused")
private void queryTestDebug() {
long startnow, endnow;
AbstractList<String> words = new ArrayList<String>();
List<Integer> ids = new ArrayList<Integer>();
startnow = SystemClock.uptimeMillis();
T9DB tdb = T9DB.getInstance(this);
Log.d("queryTestDebug", "Testing...");
tdb.updateWords("123", words, ids, 0, LangHelper.LANGUAGE.EN);
Log.d("queryTestDebug", "123->" + words.toString());
Log.d("queryTestDebug", "269->");
tdb.updateWords("269", words, ids, 0, LangHelper.LANGUAGE.EN);
Iterator<String> i = words.iterator();
while (i.hasNext()) {
Log.d("queryTestDebug", "word: " + i.next());
}
Log.d("queryTestDebug", "228->");
tdb.updateWords("228", words, ids, 0, LangHelper.LANGUAGE.EN);
i = words.iterator();
while (i.hasNext()) {
Log.d("queryTestDebug", "word: " + i.next());
}
endnow = SystemClock.uptimeMillis();
Log.d("TIMING", "Execution time: " + (endnow - startnow) + " ms");
}
@SuppressWarnings("unused")
private void queryTest() {
long startnow, endnow;
startnow = SystemClock.uptimeMillis();
T9DB tdb = T9DB.getInstance(this);
// tdb.getWords("123").iterator();
// tdb.getWords("269").iterator();
// tdb.getWords("228").iterator();
// tdb.getWords("24371").iterator();
// tdb.getWords("22376284").iterator();
// tdb.getWords("68372667367283").iterator();
// tdb.getWords("22637").iterator();
endnow = SystemClock.uptimeMillis();
Log.d("TIMING", "Execution time: " + (endnow - startnow) + " ms");
}
@SuppressWarnings("unused")
private void queryTestSingle() {
long startnow, endnow;
int size;
AbstractList<String> words = new ArrayList<String>(8);
ArrayList<Integer> ids = new ArrayList<Integer>(8);
startnow = SystemClock.uptimeMillis();
T9DB tdb = T9DB.getInstance(this);
tdb.updateWords("222", words, ids, 0, LangHelper.LANGUAGE.EN);
size = ids.size();
if (size > 0) {
tdb.incrementWord(ids.get(0));
tdb.incrementWord(ids.get(0));
tdb.incrementWord(ids.get(0));
}
for (int x = 0; x < size; x++) {
tdb.incrementWord(ids.get(x));
}
endnow = SystemClock.uptimeMillis();
Log.d("TIMING", "Execution time: " + (endnow - startnow) + " ms");
List<Integer> freqs = new ArrayList<Integer>(8);
//tdb.updateWordsW("222", words, ids, freqs, LangHelper.EN);
Log.d("VALUES", "...");
size = freqs.size();
for (int x = 0; x < size; x++) {
Log.d("VALUES",
"Word: " + words.get(x) + " id: " + ids.get(x) + " freq: " + freqs.get(x));
}
Log.d("queryTestSingle", "done.");
}
@Override @Override
public void onCancel(DialogInterface dint) { public void onCancel(DialogInterface dint) {

View file

@ -1,4 +1,4 @@
package io.github.sspanak.tt9; package io.github.sspanak.tt9.db;
public class DBException extends Exception { public class DBException extends Exception {
private static final long serialVersionUID = 376752656441823823L; private static final long serialVersionUID = 376752656441823823L;

View file

@ -1,4 +1,4 @@
package io.github.sspanak.tt9; package io.github.sspanak.tt9.db;
import android.app.IntentService; import android.app.IntentService;
import android.app.Notification; import android.app.Notification;
@ -11,6 +11,8 @@ import android.os.Handler;
import android.util.Log; import android.util.Log;
import android.widget.Toast; import android.widget.Toast;
import io.github.sspanak.tt9.R;
public class DBUpdateService extends IntentService { public class DBUpdateService extends IntentService {
private static final int UPDATING_NOTIFICATION_ID = 9640142; private static final int UPDATING_NOTIFICATION_ID = 9640142;

View file

@ -0,0 +1,56 @@
package io.github.sspanak.tt9.db;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class DatabaseHelper extends SQLiteOpenHelper {
Context mContext = null;
DatabaseHelper(Context context) {
super(context, T9DB.DATABASE_NAME, null, T9DB.DATABASE_VERSION);
mContext = context;
}
// partial code from parent class SQLiteOpenHelper
protected boolean needsUpgrading() {
//quick and dirty check to see if an existing database exists.
if (mContext.databaseList().length > 0) {
SQLiteDatabase db = mContext.openOrCreateDatabase(T9DB.DATABASE_NAME, 0, null);
int version = db.getVersion();
db.close();
return version < T9DB.DATABASE_VERSION;
} else {
return false;
}
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE IF NOT EXISTS " + T9DB.WORD_TABLE_NAME + " (" +
T9DB.COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
T9DB.COLUMN_LANG + " INTEGER, " +
T9DB.COLUMN_SEQ + " TEXT, " +
T9DB.COLUMN_WORD + " TEXT, " +
T9DB.COLUMN_FREQUENCY + " INTEGER, " +
"UNIQUE(" + T9DB.COLUMN_LANG + ", " + T9DB.COLUMN_WORD + ") )");
db.execSQL("CREATE INDEX IF NOT EXISTS idx ON " + T9DB.WORD_TABLE_NAME + "("
+ T9DB.COLUMN_LANG + ", " + T9DB.COLUMN_SEQ + " ASC, " + T9DB.COLUMN_FREQUENCY + " DESC )");
db.execSQL("CREATE TRIGGER IF NOT EXISTS " + T9DB.FREQ_TRIGGER_NAME +
" AFTER UPDATE ON " + T9DB.WORD_TABLE_NAME +
" WHEN NEW." + T9DB.COLUMN_FREQUENCY + " > " + T9DB.FREQ_MAX +
" BEGIN" +
" UPDATE " + T9DB.WORD_TABLE_NAME + " SET " + T9DB.COLUMN_FREQUENCY + " = "
+ T9DB.COLUMN_FREQUENCY + " / " + T9DB.FREQ_DIV +
" WHERE " + T9DB.COLUMN_SEQ + " = NEW." + T9DB.COLUMN_SEQ + ";" +
" END;");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.i("T9DB.onUpgrade", "Upgrading database from version " + oldVersion + " to " + newVersion);
onCreate(db);
// subsequent database migrations go here
Log.i("T9DB.onUpgrade", "Done.");
}
}

View file

@ -0,0 +1,299 @@
package io.github.sspanak.tt9.db;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.database.Cursor;
import android.database.sqlite.SQLiteConstraintException;
import android.database.sqlite.SQLiteDatabase;
import android.provider.BaseColumns;
import android.util.Log;
import android.widget.Toast;
import io.github.sspanak.tt9.CharMap;
import io.github.sspanak.tt9.LangHelper;
import io.github.sspanak.tt9.LangHelper.LANGUAGE;
import io.github.sspanak.tt9.R;
import io.github.sspanak.tt9.preferences.T9Preferences;
import java.util.AbstractList;
import java.util.Iterator;
import java.util.List;
public class T9DB {
private static volatile T9DB instance = null;
protected boolean ready = true;
public static final String DATABASE_NAME = "t9dict.db";
public static final int DATABASE_VERSION = 5; // Versions < 5 belong to the original project. We don't care about
// them and we don't migrate them, because the APP ID used to be
// different. This means the TT9 must be installed as a new application
// since version 5, which eliminates the possibility of reusing any
// legacy data.
public static final String WORD_TABLE_NAME = "word";
public static final String FREQ_TRIGGER_NAME = "freqtrigger";
// 50k, 10k
public static final int FREQ_MAX = 50000;
public static final int FREQ_DIV = 10000;
// This seems to be pretty fast on my phone. 10 is pretty slow (Might be because > MAX_RESULTS (8).)
private static final int MINHITS = 4;
public static final String COLUMN_ID = BaseColumns._ID;
public static final String COLUMN_LANG = "lang";
public static final String COLUMN_SEQ = "seq";
public static final String COLUMN_WORD = "word";
public static final String COLUMN_FREQUENCY = "freq";
private static final String QUERY1 =
"SELECT " + COLUMN_ID + ", " + COLUMN_WORD +
" FROM " + WORD_TABLE_NAME +
" WHERE " + COLUMN_LANG + "=? AND " + COLUMN_SEQ + "=?" +
" ORDER BY " + COLUMN_FREQUENCY + " DESC";
private static final String UPDATEQ =
"UPDATE " + WORD_TABLE_NAME +
" SET " + COLUMN_FREQUENCY + " = " + COLUMN_FREQUENCY + "+1" +
" WHERE " + COLUMN_ID + "=";
private static final int MAX_RESULTS = 8;
private static final int MAX_MAX_RESULTS = 30; // to make sure we don't exceed candidate view array.
private DatabaseHelper mOpenHelper;
private SQLiteDatabase db;
private Context mContext;
public T9DB(Context caller) {
// create db
mContext = caller;
mOpenHelper = new DatabaseHelper(caller);
}
public static T9DB getInstance(Context caller) {
if (instance == null) {
synchronized (T9DB.class){
if (instance == null) {
instance = new T9DB (caller);
instance.init();
}
}
}
return instance;
}
public static SQLiteDatabase getSQLDB(Context caller) {
T9DB t9dbhelper = getInstance(caller);
//Log.d("T9DB.getSQLDB", "db:" + t9dbhelper.db.isOpen());
return t9dbhelper.db;
}
private void init() {
if (mOpenHelper.needsUpgrading() ) {
ready = false;
Log.i("T9.init", "needsUpgrading");
// start updating service
if (db != null) {
try {
db.close();
} catch (NullPointerException ignored) { }
db = null;
}
Intent intent = new Intent(mContext, DBUpdateService.class);
Log.i("T9.init", "Invoking update service...");
mContext.startService(intent);
} else {
db = mOpenHelper.getWritableDatabase();
}
}
private boolean ensureDb() {
if (ready) {
if (db == null) {
db = getWritableDatabase();
}
return true;
} else {
return false;
}
}
protected SQLiteDatabase getWritableDatabase() {
return mOpenHelper.getWritableDatabase();
}
protected void setSQLDB(SQLiteDatabase tdb) {
synchronized (T9DB.class){
db = tdb;
ready = true;
}
}
public boolean isReady() {
return this.ready;
}
public void close() {
try { db.close(); }
catch (NullPointerException ignored) { }
db = null;
}
public void truncate() {
Log.i("T9DB.truncate", "Truncating words table...");
synchronized (T9DB.class) {
ready = false;
db = getWritableDatabase();
db.delete(WORD_TABLE_NAME, null, null);
ready = true;
}
Log.i("T9DB.truncate", "Done...");
}
public void showDBaccessError() {
Toast.makeText(mContext, R.string.database_notready, Toast.LENGTH_SHORT).show();
}
public void addWord(String iword, LANGUAGE lang) throws DBException {
Resources r = mContext.getResources();
if (iword.equals("")) {
throw new DBException(r.getString(R.string.add_word_blank));
}
// get int sequence
String seq;
try {
seq = CharMap.getStringSequence(iword, lang);
} catch (NullPointerException e) {
throw new DBException(r.getString(R.string.add_word_badchar, lang.name(), iword));
}
// add int sequence into num table
ContentValues values = new ContentValues();
values.put(COLUMN_SEQ, seq);
values.put(COLUMN_LANG, lang.id);
// add word into word
values.put(COLUMN_WORD, iword);
values.put(COLUMN_FREQUENCY, 1);
if (!ensureDb()) {
Log.e("T9DB.addWord", "not ready");
this.showDBaccessError();
return;
}
try {
db.insertOrThrow(WORD_TABLE_NAME, null, values);
} catch (SQLiteConstraintException e) {
String msg = r.getString(R.string.add_word_exist2, iword, lang.name());
Log.w("T9DB.addWord", msg);
throw new DBException(msg);
}
}
public void incrementWord(int id) {
if (!ensureDb()) {
Log.e("T9DB.incrementWord", "not ready");
this.showDBaccessError();
return;
}
db.execSQL(UPDATEQ + id);
// if id's freq is greater than FREQ_MAX, it gets normalized with trigger
}
public void updateWords(String is, AbstractList<String> stringList, List<Integer> intList,
int capsMode, LANGUAGE lang) {
stringList.clear();
intList.clear();
// String[] sa = packInts(stringToInts(is), true);
int islen = is.length();
if (!ensureDb()) {
Log.e("T9DB.updateWords", "not ready");
this.showDBaccessError();
return;
}
Cursor cur = db.rawQuery(QUERY1, new String[] { String.valueOf(lang.id), is });
int hits = 0;
for (cur.moveToFirst(); !cur.isAfterLast(); cur.moveToNext()) {
intList.add(cur.getInt(0));
stringList.add(cur.getString(1));
if (hits >= MAX_MAX_RESULTS) { break; } // to stop index error in candidate view
hits++;
}
cur.close();
if ((hits < MINHITS) && (islen >= 2)) {
char c = is.charAt(islen - 1);
c++;
String q = "SELECT " + COLUMN_ID + ", " + COLUMN_WORD +
" FROM " + WORD_TABLE_NAME +
" WHERE " + COLUMN_LANG + "=? AND " + COLUMN_SEQ + " >= '" + is + "1" +
"' AND " + COLUMN_SEQ + " < '" + is.substring(0, islen - 1) + c + "'" +
" ORDER BY " + COLUMN_FREQUENCY + " DESC, " + COLUMN_SEQ + " ASC" +
" LIMIT " + (MAX_RESULTS - hits);
cur = db.rawQuery(q, new String[] { String.valueOf(lang.id) });
for (cur.moveToFirst(); !cur.isAfterLast(); cur.moveToNext()) {
intList.add(cur.getInt(0));
stringList.add(cur.getString(1));
if (hits >= MAX_MAX_RESULTS) {
break;
}
hits++;
}
cur.close();
}
// Log.d("T9DB.updateWords", "pre: " + stringList);
if (capsMode == T9Preferences.CASE_LOWER) {
return;
}
// Log.d("T9DB.updateWords", "filtering...");
// filter list
Iterator<String> iter = stringList.iterator();
String word;
String wordtemp;
int index = 0;
boolean removed = false;
while (iter.hasNext()) {
word = iter.next();
switch (capsMode) {
case T9Preferences.CASE_UPPER:
wordtemp = word.toUpperCase(LangHelper.LOCALES[lang.index]);
if (wordtemp.equals(word)) {
index++;
continue;
} else if (stringList.contains(wordtemp)) {
// remove this entry
iter.remove();
removed = true;
} else {
stringList.set(index, wordtemp);
}
break;
case T9Preferences.CASE_CAPITALIZE:
if (word.length() > 1) {
wordtemp = word.substring(0, 1).toUpperCase(LangHelper.LOCALES[lang.index]) + word.substring(1);
} else {
wordtemp = word.toUpperCase(LangHelper.LOCALES[lang.index]);
}
if (wordtemp.equals(word)) {
index++;
continue;
} else if (stringList.contains(wordtemp)) {
// remove this entry
iter.remove();
removed = true;
} else {
stringList.set(index, wordtemp);
}
break;
}
if (removed) {
intList.remove(index);
removed = false;
} else {
index++;
}
}
//Log.d("T9DB.updateWords", "i:" + is + " words:" + Arrays.toString(stringList.toArray()));
}
}

View file

@ -0,0 +1,109 @@
package io.github.sspanak.tt9.preferences;
import android.content.Context;
import android.content.SharedPreferences;
import androidx.preference.PreferenceManager;
import android.view.KeyEvent;
public class T9Preferences {
private static T9Preferences self;
private SharedPreferences prefs;
private SharedPreferences.Editor prefsEditor;
public static final int CASE_LOWER = 0;
public static final int CASE_CAPITALIZE = 1;
public static final int CASE_UPPER = 2;
public static final int MODE_PREDICTIVE = 0;
public static final int MODE_ABC = 1;
public static final int MODE_123 = 2;
public T9Preferences (Context context) {
prefs = PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext());
prefsEditor = prefs.edit();
}
public static T9Preferences getInstance(Context context) {
if (self == null) {
self = new T9Preferences(context);
}
return self;
}
public int getEnabledLanguages() {
return prefs.getInt("pref_enabled_languages", 1);
}
public T9Preferences setEnabledLanguages(int languageMask) {
prefsEditor.putInt("pref_enabled_languages", languageMask);
prefsEditor.apply();
return this;
}
// public int getInputCase() {
// return prefs.getInt("pref_input_case", CASE_CAPITALIZE);
// }
public int getInputLanguage() {
return prefs.getInt("pref_input_language", 1);
}
public T9Preferences setInputLanguage(int language) {
prefsEditor.putInt("pref_input_language", language);
prefsEditor.apply();
return this;
}
public int getInputMode() {
return prefs.getInt("pref_input_mode", MODE_PREDICTIVE);
}
public T9Preferences setInputMode(int mode) throws Exception {
if (mode != MODE_PREDICTIVE && mode != MODE_ABC && mode != MODE_123) {
throw new Exception("Invalid input mode: '" + mode + "'");
}
prefsEditor.putInt("pref_input_mode", mode);
prefsEditor.apply();
return this;
}
public int getKeyBackspace() {
return prefs.getInt("pref_key_backspace", KeyEvent.KEYCODE_DEL);
}
// public int getKeyInputMode() {
// return prefs.getInt("pref_key_inputmode", KeyEvent.KEYCODE_POUND);
// }
// public int getKeyOtherActions() {
// return prefs.getInt("pref_key_other_actions", KeyEvent.KEYCODE_CALL);
// }
// public boolean getSoftBackspaceEnabled() {
// return prefs.getBoolean("pref_softkey_backspace", true);
// }
// public boolean getSoftPrefsEnabled() {
// return prefs.getBoolean("pref_softkey_prefs", true);
// }
public String getLastWord() {
return prefs.getString("last_word", "");
}
public T9Preferences setLastWord(String lastWord) {
// "last_word" was part of the original Preferences implementation.
// It is weird, but it is simple and it works, so I decided to keep it.
prefsEditor.putString("last_word", lastWord);
prefsEditor.apply();
return this;
}
}

View file

@ -1,49 +0,0 @@
package io.github.sspanak.tt9.settings;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.CheckBox;
import io.github.sspanak.tt9.R;
import io.github.sspanak.tt9.T9DB;
import io.github.sspanak.tt9.T9DB.DBSettings.SETTING;
public class SettingCheck extends Setting {
boolean value;
boolean defaultValue;
public SettingCheck (Context context, AttributeSet attrs, Object[] isettings) {
super(context, attrs, isettings);
// http://stackoverflow.com/a/8488691
for (int i = 0; i < attrs.getAttributeCount(); i++) {
String attr = attrs.getAttributeName(i);
if ("defaultValue".equals(attr)) {
defaultValue = attrs.getAttributeBooleanValue(i, false);
}
}
SETTING s = SETTING.get(id);
if (s != null) {
Object o = isettings[s.sqOrder];
if (o == null)
value = defaultValue;
else
value = o.equals(1);
}
widgetID = R.layout.checkbox;
layout = R.layout.setting_widget;
}
@Override
public void clicked(Context context) {
value = !value;
T9DB.getInstance(context).storeSettingInt(SETTING.get(id), value ? 1 : 0);
((CheckBox)view.findViewById(R.id.checkbox)).setChecked(value);
}
@Override
public void init(){
((CheckBox)view.findViewById(R.id.checkbox)).setChecked(value);
}
}

View file

@ -4,10 +4,10 @@ import android.app.AlertDialog;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.Log;
import io.github.sspanak.tt9.R; import io.github.sspanak.tt9.R;
import io.github.sspanak.tt9.T9DB; import io.github.sspanak.tt9.preferences.T9Preferences;
import io.github.sspanak.tt9.T9DB.DBSettings.SETTING;
public class SettingList extends Setting { public class SettingList extends Setting {
String[] entries; String[] entries;
@ -56,7 +56,13 @@ public class SettingList extends Setting {
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
T9DB.getInstance(context).storeSettingInt(SETTING.get(id), entryValues[which]); if (id.equals("pref_inputmode")) {
try {
T9Preferences.getInstance(context).setInputMode(entryValues[which]);
} catch (Exception e) {
Log.e("SettingsList", e.getMessage());
}
}
value = entryValues[which]; value = entryValues[which];
dialog.dismiss(); dialog.dismiss();
} }

View file

@ -8,8 +8,7 @@ import android.widget.TextView;
import io.github.sspanak.tt9.LangHelper; import io.github.sspanak.tt9.LangHelper;
import io.github.sspanak.tt9.R; import io.github.sspanak.tt9.R;
import io.github.sspanak.tt9.T9DB; import io.github.sspanak.tt9.preferences.T9Preferences;
import io.github.sspanak.tt9.T9DB.DBSettings.SETTING;
public class SettingMultiList extends SettingList { public class SettingMultiList extends SettingList {
boolean[] selectedEntries = new boolean[0]; boolean[] selectedEntries = new boolean[0];
@ -38,7 +37,9 @@ public class SettingMultiList extends SettingList {
new DialogInterface.OnClickListener() { new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
T9DB.getInstance(context).storeSettingInt(SETTING.get(id), LangHelper.shrinkLangs(buildSelection())); if (id.equals("pref_lang_support")) {
T9Preferences.getInstance(context).setEnabledLanguages(LangHelper.shrinkLangs(buildSelection()));
}
summary = buildItems(); summary = buildItems();
dialog.dismiss(); dialog.dismiss();
((TextView)view.findViewById(R.id.summary)).setText(summary); ((TextView)view.findViewById(R.id.summary)).setText(summary);