1
0
Fork 0

Phew. Changed settings backend. Used more ENUM, fixed some bugs.

* Settings now use the database instead of SharedPreferences (which are
  bad)
  * Changed many constants to now be ENUMs.
  * Changed some character mappings which were too big.
  * Added limit to number of results returned to stop crash.
  * Changed Lang id so can do binary operations on it
  * Removed some old code
This commit is contained in:
Clam 2014-11-03 22:46:02 +11:00
parent 300e9df54b
commit b40db96182
44 changed files with 1043 additions and 483 deletions

View file

@ -3,7 +3,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.13.2'
classpath 'com.android.tools.build:gradle:0.14.0'
}
}
apply plugin: 'android'

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 350 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 894 B

After

Width:  |  Height:  |  Size: 888 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 915 B

After

Width:  |  Height:  |  Size: 817 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 823 B

After

Width:  |  Height:  |  Size: 809 B

Before After
Before After

View file

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- taken from Sharp 007SH -->
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_window_focused="false"
android:state_enabled="true"
android:drawable="@drawable/btn_circle_normal" />
<item
android:state_window_focused="false"
android:state_enabled="false"
android:drawable="@drawable/btn_circle_disable" />
<item
android:state_enabled="false"
android:state_pressed="true"
android:drawable="@drawable/btn_circle_disable" />
<item
android:state_pressed="true"
android:drawable="@drawable/btn_circle_pressed" />
<item
android:state_focused="true"
android:state_enabled="true"
android:drawable="@drawable/btn_circle_selected" />
<item
android:state_enabled="true"
android:drawable="@drawable/btn_circle_normal" />
<item
android:state_focused="true"
android:drawable="@drawable/btn_circle_disable_focused" />
<item android:drawable="@drawable/btn_circle_disable" />
</selector>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- taken from Sharp 007SH -->
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_enabled="false"
android:drawable="@drawable/ic_btn_round_more_disabled" />
<item android:drawable="@drawable/ic_btn_round_more_normal" />
</selector>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 894 B

After

Width:  |  Height:  |  Size: 888 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 915 B

After

Width:  |  Height:  |  Size: 817 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 823 B

After

Width:  |  Height:  |  Size: 809 B

Before After
Before After

View file

@ -34,7 +34,7 @@
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:onClick="cancelButton"
android:text="@string/cancel" />
android:text="@android:string/cancel" />
</RelativeLayout>

26
res/layout/checkbox.xml Normal file
View file

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- taken from android source -->
<!-- Copyright (C) 2006 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- Layout used by CheckBoxPreference for the checkbox style. This is inflated
inside android.R.layout.preference. -->
<CheckBox xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="4dip"
android:layout_gravity="center_vertical"
android:focusable="false"
android:clickable="false" />

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- taken from Sharp 007SH -->
<ImageView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_gravity="center_vertical"
android:background="@drawable/btn_circle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="4.0dip"
android:src="@drawable/ic_btn_round_more"/>

View file

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/* //device/apps/common/assets/res/layout/list_content.xml
**
** Copyright 2006, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
-->
<ListView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:drawSelectorOnTop="false"
android:scrollbarAlwaysDrawVerticalTrack="true"
/>

29
res/layout/setting.xml Normal file
View file

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Modfied from android preference.xml -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:gravity="center_vertical"
android:paddingRight="?android:attr/scrollbarSize"
android:baselineAligned="false">
<RelativeLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="15dip"
android:layout_marginRight="6dip"
android:layout_marginTop="6dip"
android:layout_marginBottom="6dip"
android:layout_weight="1">
<TextView android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceLarge"
android:ellipsize="marquee"
android:fadingEdge="horizontal" />
</RelativeLayout>
</LinearLayout>

View file

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Modfied from android preference.xml -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:gravity="center_vertical"
android:paddingRight="?android:attr/scrollbarSize"
android:baselineAligned="false">
<RelativeLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="15dip"
android:layout_marginRight="6dip"
android:layout_marginTop="6dip"
android:layout_marginBottom="6dip"
android:layout_weight="1">
<TextView android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceLarge"
android:ellipsize="marquee"
android:fadingEdge="horizontal" />
<TextView android:id="@+id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/title"
android:layout_alignLeft="@+id/title"
android:textAppearance="?android:attr/textAppearanceSmall"
android:maxLines="4" />
</RelativeLayout>
</LinearLayout>

View file

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Modfied from android preference.xml -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:gravity="center_vertical"
android:paddingRight="?android:attr/scrollbarSize"
android:baselineAligned="false">
<RelativeLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="15dip"
android:layout_marginRight="6dip"
android:layout_marginTop="6dip"
android:layout_marginBottom="6dip"
android:layout_weight="1">
<TextView android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceLarge"
android:ellipsize="marquee"
android:fadingEdge="horizontal" />
<TextView android:id="@+id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/title"
android:layout_alignLeft="@+id/title"
android:textAppearance="?android:attr/textAppearanceSmall"
android:maxLines="4" />
</RelativeLayout>
<!-- Preference should place its actual preference widget here. -->
<LinearLayout android:id="@+id/widget_frame"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="vertical" />
</LinearLayout>

View file

@ -21,16 +21,15 @@
<string name="symbol_page">Seite: %1$s/%2$s</string>
<string name="add_word">Wort hinzufügen</string>
<string name="ok">OK</string>
<string name="close">Schließen</string>
<string name="add_word_blank">Leeres Wort nicht hinzugefügt.</string>
<string name="add_word_badchar">Wort mit nicht zuordbarem Buchstaben für %1$s (%2$s) kann nicht hinzugefügt werden.</string>
<string name="add_word_exist1">Das Wort (%1$s) ist bereits in der DB.</string>
<string name="add_word_exist2">Das Wort (%1$s) ist bereits für %2$s in der DB.</string>
<string name="cancel">Abbrechen</string>
<string name="title_activity_add_word">Wort hinzufügen</string>
<string name="action_settings">Einstellungen</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">Aktualisiere Wörterbuch-Datenbank. Das könnte einen Moment dauern.</string>

View file

@ -7,7 +7,6 @@
<string name="add_word_exist1">Слово (%1$s) уже есть в словаре.</string>
<string name="add_word_exist2">Слово (%1$s) уже есть в словаре %2$s.</string>
<string name="app_name">Traditional T9</string>
<string name="cancel">Отмена</string>
<string name="hello_world">Hello world!</string>
<string name="ime_name">Клавиатура T9</string>
<string name="ime_number">Цифры</string>
@ -18,7 +17,6 @@
<string name="main_mid_commit">Commit</string>
<string name="main_right_lower">Изменить IME</string>
<string name="main_right_upper">Режим ввода</string>
<string name="ok">OK</string>
<string name="pref_backup_noext">Ошибка: Внешняя память недоступна. Резервное копирование невозможно невозможно.</string>
<string name="pref_backup_title">Резервное копирование базы данных IME</string>
<string name="pref_backup_warn">Предупреждение: Существующая копия базы данных будет перезаписана. Продолжить?</string>
@ -62,6 +60,7 @@
<string name="pref_loaduser_notfound"> Ошибка. \n Словарь %1$s не найден. </string>
<string name="pref_mode_notify_subtitle">Используется для озвучивания изменения режима ввода.</string>
<string name="pref_mode_notify">Режим уведомления</string>
<string name="database_settings_notready">Database unavailable. Using default settings.</string>
<string name="title_activity_add_word">Добавить слово</string>
<string name="traditionalt9_settings">Traditional T9 настройки</string>

View file

@ -1,29 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="pref_inputmode_entries">
<item >Dictionary</item>
<item >Text</item>
<item >Number</item>
</string-array>
<string-array translatable="false" name="pref_inputmode_values">
<item >0</item>
<item >1</item>
<item >2</item>
<item>Dictionary</item>
<item>Text</item>
<item>Number</item>
</string-array>
<integer-array translatable="false" name="pref_inputmode_values">
<item>@integer/INPUT_DICT</item>
<item>@integer/INPUT_TEXT</item>
<item>@integer/INPUT_NUM</item>
</integer-array>
<string-array translatable="false" name="pref_lang_defaults">
<item >0</item>
</string-array>
<string-array name="pref_lang_titles">
<item >English</item>
<item >Russian</item>
<item >German</item>
</string-array>
<string-array translatable="false" name="pref_lang_values">
<item >0</item>
<item >1</item>
<item >2</item>
<item>English</item>
<item>Russian</item>
<item>German</item>
</string-array>
<integer-array translatable="false" name="pref_lang_values">
<item>@integer/LANG_EN</item>
<item>@integer/LANG_RU</item>
<item>@integer/LANG_DE</item>
</integer-array>
<string-array name="capsMode">
<item>Caps off</item>

View file

@ -1,10 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="candidate_normal">#FF000000</color>
<color name="candidate_recommended">#FFE35900</color>
<color name="candidate_other">#ff808080</color>
<color name="candidate_background">#bbffffff</color>
<color name="button_press">#FFFCBE2B</color>
<color name="candidate_recommended">#ffc66ac3</color>
<color name="candidate_other">#ff68f0e9</color>
<color name="candidate_background">#e19185df</color>
<color name="button_focus">#FF2A9AEB</color>
<color name="button_default">#FFA8A8A8</color>
<color name="button_text">#FFFFFFFF</color>

14
res/values/const.xml Normal file
View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- MAKE SURE THESE MATCH WITH LangHelper.java -->
<integer name="LANG_EN">1</integer>
<integer name="LANG_RU">2</integer>
<integer name="LANG_DE">4</integer>
<integer name="INPUT_DICT">0</integer>
<integer name="INPUT_TEXT">1</integer>
<integer name="INPUT_NUM">2</integer>
<integer name="INPUT_DEFAULT">@integer/INPUT_DICT</integer>
<integer name="LANG_DEFAULT">@integer/LANG_EN</integer>
</resources>

View file

@ -22,16 +22,15 @@
<string name="symbol_page">Page: %1$s/%2$s</string>
<string name="add_word">Add word</string>
<string name="ok">OK</string>
<string name="close">Close</string>
<string name="add_word_blank">Blank word not added.</string>
<string name="add_word_badchar">Cannot add word with unmappable character for %1$s (%2$s).</string>
<string name="add_word_exist1">Word (%1$s) already in DB.</string>
<string name="add_word_exist2">Word (%1$s) already in DB for %2$s.</string>
<string name="cancel">Cancel</string>
<string name="title_activity_add_word">Add Word</string>
<string name="action_settings">Settings</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">Updating dictionary database, this might take a while.</string>

View file

@ -17,4 +17,8 @@
<!-- All customizations that are NOT specific to a particular API-level can go here. -->
</style>
<declare-styleable name="PrefItem">
<attr name="title" format="string" />
<attr name="summary" format="string" />
</declare-styleable>
</resources>

View file

@ -1,35 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
android:key="first_preferencescreen">
<Preference android:title="@string/pref_help" android:key="help"/>
<ListPreference
android:key="pref_inputmode"
android:title="@string/pref_inputmode"
android:dialogTitle="@string/pref_inputmode"
android:entries="@array/pref_inputmode_entries"
android:entryValues="@array/pref_inputmode_values"
android:persistent="true"
android:defaultValue="0" android:summary="@string/pref_inputmode_desc"/>
<pl.wavesoftware.widget.MultiSelectListPreference
android:defaultValue="@array/pref_lang_defaults"
android:entries="@array/pref_lang_titles"
android:entryValues="@array/pref_lang_values"
android:key="pref_lang_support"
android:persistent="true"
android:title="@string/pref_lang_title" />
<CheckBoxPreference
android:key="pref_mode_notify"
android:title="@string/pref_mode_notify"
android:summary="@string/pref_mode_notify_subtitle"
android:persistent="true"
android:defaultValue="false"
<!-- WHEN ADDING NEW SETTING KEY THAT STORES VALUE, ADD KEY AND QUERY TO T9DB -->
<Settings>
<Setting title="@string/pref_help" id="help" />
<SettingList
id="pref_inputmode"
title="@string/pref_inputmode"
entries="@array/pref_inputmode_entries"
entryValues="@array/pref_inputmode_values"
defaultValue="@integer/INPUT_DEFAULT"
summary="@string/pref_inputmode_desc"/>
<SettingMultiList
id="pref_lang_support"
defaultValue="@integer/LANG_DEFAULT"
entries="@array/pref_lang_titles"
entryValues="@array/pref_lang_values"
title="@string/pref_lang_title" />
<SettingCheck
id="pref_mode_notify"
title="@string/pref_mode_notify"
summary="@string/pref_mode_notify_subtitle"
defaultValue="false"
/>
<Preference android:title="@string/pref_loaddict" android:key="loaddict"/>
<Preference android:title="@string/pref_loaduserdict" android:summary="@string/pref_loaduserdictdesc" android:key="loaduserdict"/>
<Preference android:title="@string/pref_nukedict" android:key="nukedict"/>
<Preference android:title="@string/pref_backupdict" android:key="backupdict"/>
<Preference android:title="@string/pref_restoredict" android:key="restoredict"/>
<Preference android:title="@string/pref_querytest" android:key="querytest"/>
</PreferenceScreen>
<Setting title="@string/pref_loaddict" id="loaddict"/>
<Setting title="@string/pref_loaduserdict" summary="@string/pref_loaduserdictdesc" id="loaduserdict"/>
<Setting title="@string/pref_nukedict" id="nukedict"/>
<Setting title="@string/pref_backupdict" id="backupdict"/>
<Setting title="@string/pref_restoredict" id="restoredict"/>
</Settings>

View file

@ -3,20 +3,19 @@ package org.nyanya.android.traditionalt9;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.app.Activity;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.EditText;
import org.nyanya.android.traditionalt9.T9DB.DBSettings.SETTING;
public class AddWordAct extends Activity {
View main;
int lang;
SharedPreferences pref;
String origword;
@Override
@ -36,7 +35,6 @@ public class AddWordAct extends Activity {
et.setSelection(origword.length());
setContentView(v);
main = v;
pref = PreferenceManager.getDefaultSharedPreferences(this);
}
public void addWordButton(View v) {
@ -49,13 +47,13 @@ public class AddWordAct extends Activity {
public void doAddWord(String text) {
T9DB db = T9DB.getInstance(this);
try {
db.addWord(text, lang);
db.addWord(text, LangHelper.LANGUAGE.get(lang));
} catch (DBException e) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
String msg = e.getMessage();
//Log.e("AddWord.doAddWord", msg);
builder.setMessage(msg).setTitle(R.string.add_word)
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
@ -64,9 +62,7 @@ public class AddWordAct extends Activity {
AlertDialog dialog = builder.create();
dialog.show();
}
SharedPreferences.Editor prefedit = pref.edit();
prefedit.putString("last_word", text);
prefedit.commit();
db.storeSettingString(SETTING.LAST_WORD, text);
}

View file

@ -8,6 +8,8 @@ import java.util.Map;
import android.util.Log;
import org.nyanya.android.traditionalt9.LangHelper.LANGUAGE;
public class CharMap {
protected static final AbstractList<Map<Character, Integer>> CHARTABLE = new ArrayList<Map<Character, Integer>>(LangHelper.NLANGS);
static {
@ -16,12 +18,10 @@ public class CharMap {
enMap.put('.', 1); enMap.put(',', 1); enMap.put('!', 1); enMap.put('?', 1);
enMap.put('-', 1); enMap.put('"', 1); enMap.put('\'', 1); enMap.put('@', 1);
enMap.put('#', 1); enMap.put('$', 1); enMap.put('%', 1); enMap.put('&', 1);
enMap.put('*', 1); enMap.put('(', 1); enMap.put(')', 1); enMap.put('1', 1);
enMap.put(':', 1); enMap.put(';', 1); enMap.put('/', 1); enMap.put('\\', 1);
enMap.put('+', 1); enMap.put('=', 1); enMap.put('<', 1); enMap.put('>', 1);
enMap.put('[', 1); enMap.put(']', 1); enMap.put('{', 1); enMap.put('}', 1);
enMap.put('^', 1); enMap.put('|', 1); enMap.put('_', 1); enMap.put('~', 1);
enMap.put('`', 1);
enMap.put('*', 1); enMap.put('(', 1); enMap.put(')', 1); enMap.put(':', 1);
enMap.put(';', 1); enMap.put('/', 1); enMap.put('+', 1); enMap.put('=', 1);
enMap.put('<', 1); enMap.put('>', 1); enMap.put('^', 1); enMap.put('_', 1);
enMap.put('~', 1); enMap.put('1', 1);
enMap.put('a', 2); enMap.put('á', 2); enMap.put('ä', 2); enMap.put('â', 2);
enMap.put('à', 2); enMap.put('å', 2); enMap.put('b', 2); enMap.put('c', 2);
enMap.put('ç', 2); enMap.put('2', 2);
@ -48,12 +48,10 @@ public class CharMap {
ruMap.put('.', 1); ruMap.put(',', 1); ruMap.put('!', 1); ruMap.put('?', 1);
ruMap.put('-', 1); ruMap.put('"', 1); ruMap.put('\'', 1); ruMap.put('@', 1);
ruMap.put('#', 1); ruMap.put('$', 1); ruMap.put('%', 1); ruMap.put('&', 1);
ruMap.put('*', 1); ruMap.put('(', 1); ruMap.put(')', 1); ruMap.put('1', 1);
ruMap.put(':', 1); ruMap.put(';', 1); ruMap.put('/', 1); ruMap.put('\\', 1);
ruMap.put('+', 1); ruMap.put('=', 1); ruMap.put('<', 1); ruMap.put('>', 1);
ruMap.put('[', 1); ruMap.put(']', 1); ruMap.put('{', 1); ruMap.put('}', 1);
ruMap.put('^', 1); ruMap.put('|', 1); ruMap.put('_', 1); ruMap.put('~', 1);
ruMap.put('`', 1); ruMap.put('1', 1);
ruMap.put('*', 1); ruMap.put('(', 1); ruMap.put(')', 1); ruMap.put(':', 1);
ruMap.put(';', 1); ruMap.put('/', 1); ruMap.put('+', 1); ruMap.put('=', 1);
ruMap.put('<', 1); ruMap.put('>', 1); ruMap.put('^', 1); ruMap.put('_', 1);
ruMap.put('~', 1); ruMap.put('1', 1);
ruMap.put('а', 2); ruMap.put('б', 2); ruMap.put('в', 2); ruMap.put('г', 2);
ruMap.put('2', 2);
ruMap.put('д', 3); ruMap.put('е', 3); ruMap.put('ё', 3); ruMap.put('ж', 3);
@ -92,33 +90,33 @@ public class CharMap {
{ 'ш', 'щ', 'ъ', 'ы', 'Ш', 'Щ', 'Ъ', 'Ы', '8' }, { 'ь', 'э', 'ю', 'я', 'Ь', 'Э', 'Ю', 'Я', '9' },
{ ' ', '\n' } };
protected static final char[][] DET9TABLE = {
{ '0', '+' },
{ '.', ',', '?', '!', '"', '\'', '-', '@', '€', '$', '%', '&', '*', '(', ')', '_', '1' },
{ 'a', 'á', 'ä', 'â', 'à', 'å', 'b', 'c', 'ç', 'A', 'Á', 'Ä', 'Â', 'À', 'Å', 'B', 'C', 'Ç', '2' },
{ 'd', 'e', 'é','ë','è','ê', 'f', 'D', 'E', 'É', 'Ë', 'È', 'Ê', 'F', '3' },
{ 'g', 'h', 'i', 'í', 'ï', 'G', 'H', 'I', 'Í', 'Ï', '4' },
{ ' ', '+', '0' },
{ '.', ',', '?', '!', ':', ';', '"', '\'', '-', '@', '^', '€', '$', '%', '&', '*', '(', ')', '_', '1' },
{ 'a', 'b', 'c', 'A', 'B', 'C', 'ä', 'Ä','á', 'â', 'à', 'å', 'ç', 'Á', 'Â', 'À', ', 'Ç', '2' },
{ 'd', 'e', 'f', 'D', 'E', 'F', 'é','ë','è',', 'É', 'Ë', 'È', 'Ê', '3' },
{ 'g', 'h', 'i', 'G', 'H', 'I', 'í', 'ï', 'Í', 'Ï', '4' },
{ 'j', 'k', 'l', 'J', 'K', 'L', '5' },
{ 'm', 'n', 'ñ', 'o', 'ó','ö','ô', 'M', 'N', 'Ñ', 'O', 'Ó', ', 'Ô', '6' },
{ 'p', 'q', 'r', 's', 'ß', 'P', 'Q', 'R', 'S', '7' },
{ 't', 'u', 'û','ü', 'v', 'T', 'U', 'Û', 'Ü', 'V', '8' },
{ 'm', 'n', 'o', 'M', 'N', 'O', 'ö', 'Ö', 'ñ','ó','ô', 'Ñ', ', 'Ô', '6' },
{ 'p', 'q', 'r', 's', 'P', 'Q', 'R', 'S', 'ß', '7' },
{ 't', 'u', 'v', 'T', 'U', 'V', 'ü', 'Ü', 'û', ', '8' },
{ 'w', 'x', 'y', 'z', 'W', 'X', 'Y', 'Z', '9' },
{ ' ', '\n' } };
{ '\n' } };
protected static final char[][][] T9TABLE = {ENT9TABLE, RUT9TABLE, DET9TABLE};
protected static final int[] ENT9CAPSTART = { 0, 0, 3, 3, 3, 3, 3, 4, 3, 4, 0 };
protected static final int [] RUT9CAPSTART = {0, 0, 4, 5, 4, 4, 4, 4, 4, 4, 0};
protected static final int[] DET9CAPSTART = { 0, 0, 9, 7, 5, 3, 7, 5, 5, 4, 0 };
protected static final int[] DET9CAPSTART = { 0, 0, 3, 3, 3, 3, 3, 4, 3, 4, 0 };
protected static final int[][] T9CAPSTART = {ENT9CAPSTART, RUT9CAPSTART, DET9CAPSTART};
protected static String getStringSequence(String word, int lang) {
protected static String getStringSequence(String word, LANGUAGE lang) {
StringBuilder seq = new StringBuilder();
String tword = word.toLowerCase(LangHelper.LOCALES[lang]);
String tword = word.toLowerCase(LangHelper.LOCALES[lang.index]);
for (int i = 0; i < word.length(); i++) {
char c = tword.charAt(i);
Integer z = CharMap.CHARTABLE.get(lang).get(c);
Integer z = CharMap.CHARTABLE.get(lang.index).get(c);
if (z == null) {
Log.e("getStringSequence",
"ERROR: " + (int) c + " NOT FOUND FOR [" + lang + "] (" + Integer.toHexString((int) c) + ") Index: " + i);
"ERROR: " + (int) c + " NOT FOUND FOR [" + lang.name() + "] (" + Integer.toHexString((int) c) + ") Index: " + i);
throw new NullPointerException();
}
seq.append(z.toString());

View file

@ -1,21 +1,43 @@
package org.nyanya.android.traditionalt9;
import android.util.Log;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import pl.wavesoftware.widget.MultiSelectListPreference;
public class LangHelper {
protected static final Locale RUSSIAN = new Locale("ru","RU");
protected static final int EN = 0;
protected static final int RU = 1;
protected static final int DE = 1;
protected static final Locale[] LOCALES = {Locale.ENGLISH, RUSSIAN, Locale.GERMAN};
protected static final String[] LANGS = {"EN", "RU", "DE"};
public enum LANGUAGE {
// MAKE SURE THESE MATCH WITH values/const.xml
NONE(-1, -1), EN(0,1), RU(1,2), DE(2,4), ;
public final int id;
public final int index;
// lookup map
private static final Map<Integer, LANGUAGE> lookup = new HashMap<Integer, LANGUAGE>();
private static final LANGUAGE[] ids = LANGUAGE.values();
static { for (LANGUAGE l : ids) lookup.put(l.id, l); }
protected static final int NLANGS = LANGS.length;
private LANGUAGE(int index, int id) { this.index = index; this.id = id; }
public static LANGUAGE get(int i) { return lookup.get(i);}
}
protected static final Locale[] LOCALES = {Locale.ENGLISH, RUSSIAN, Locale.GERMAN};
//protected static final String[] LANGS = {"EN", "RU", "DE"};
public static final int LANG_DEFAULT = LANGUAGE.EN.id;
protected static final int NLANGS = LANGUAGE.lookup.size();
protected static String getString(int lang) {
return LANGS[lang];
return LANGUAGE.get(lang).name();
}
protected static int getIndex(LANGUAGE l) {
return l.index;
}
//[LANG][MODE][CAPSMODE] = iconref
@ -42,31 +64,43 @@ public class LangHelper {
};
protected static int[] buildLangs(CharSequence s) {
int[] ia = MultiSelectListPreference.defaultunpack2Int(s);
public static LANGUAGE[] buildLangs(int i) {
int num = 0;
//calc size of filtered array
for (int i : ia) {
if (i >= 0 && i < LangHelper.NLANGS) {
for (LANGUAGE l : LANGUAGE.ids) {
if ((i & l.id) == l.id) {
num++;
}
}
int[] ian = new int[num];
int iansize = 0;
for (int i : ia) {
if (i >= 0 && i < LangHelper.NLANGS) {
ian[iansize] = i;
iansize++;
LANGUAGE[] la = new LANGUAGE[num];
int lai = 0;
for (LANGUAGE l : LANGUAGE.ids) {
if ((i & l.id) == l.id) {
la[lai] = l;
lai++;
}
}
return ian;
return la;
}
protected static int findIndex(int[] ia, int target) {
public static int shrinkLangs(LANGUAGE[] langs) {
int i = 0;
for (LANGUAGE l : langs)
i = i | l.id;
return i;
}
public static int shrinkLangs(int[] langs) {
int i = 0;
for (int l : langs)
i = i | l;
return i;
}
protected static int findIndex(LANGUAGE[] ia, LANGUAGE target) {
for (int x=0; x<ia.length; x++) {
if (ia[x] == target)
return x;
}
return -1;
return 0;
}
}

View file

@ -1,9 +1,11 @@
package org.nyanya.android.traditionalt9;
import java.util.AbstractList;
import java.util.Collection;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import android.content.ContentValues;
import android.content.Context;
@ -14,17 +16,21 @@ import android.database.sqlite.SQLiteConstraintException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.provider.BaseColumns;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;
import org.nyanya.android.traditionalt9.LangHelper.LANGUAGE;
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 = 2;
protected static final int DATABASE_VERSION = 3;
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;
@ -42,7 +48,12 @@ public class T9DB {
" 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;
@ -53,13 +64,43 @@ public class T9DB {
private Context mContext;
public static class DBSettings {
public enum SETTING {
INPUT_MODE("pref_inputmode", 1),
LANG_SUPPORT("pref_lang_support", 1),
MODE_NOTIFY("pref_mode_notify", 0),
LAST_LANG("set_last_lang", 1),
LAST_WORD("set_last_word", null);
public final String id;
public final Integer defvalue;
// 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) { this.id = id; this.defvalue = defval;}
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);
}
protected static T9DB getInstance(Context caller) {
public static T9DB getInstance(Context caller) {
if (instance == null) {
synchronized (T9DB.class){
if (instance == null) {
@ -91,13 +132,12 @@ public class T9DB {
Intent intent = new Intent(mContext, DBUpdateService.class);
Log.i("T9.init", "Invoking update service...");
mContext.startService(intent);
} else {
db = mOpenHelper.getWritableDatabase();
}
}
protected boolean checkReady() {
public boolean checkReady() {
if (ready) {
if (db == null) {
db = getWritableDatabase();
@ -131,6 +171,7 @@ public class T9DB {
if (db != null) {
db.close();
}
String[] oldSettings = getSettings();
if (!mContext.deleteDatabase(DATABASE_NAME)) {
Log.e("T9DB", "Couldn't delete database.");
}
@ -140,11 +181,118 @@ public class T9DB {
db = null;
ready = true;
init();
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...");
}
protected void addWord(String iword, int lang) throws DBException {
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() {
int len = DBSettings.SETTING.settings.length;
String[] settings = new String[len+1];
StringBuilder sb = new StringBuilder("SELECT ");
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 = db.rawQuery(sb.toString(),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 = 0; x < len; x++) {
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));
@ -154,12 +302,12 @@ public class T9DB {
try {
seq = CharMap.getStringSequence(iword, lang);
} catch (NullPointerException e) {
throw new DBException(r.getString(R.string.add_word_badchar, LangHelper.LANGS[lang], iword));
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);
values.put(COLUMN_LANG, lang.id);
// add word into word
values.put(COLUMN_WORD, iword);
values.put(COLUMN_FREQUENCY, 1);
@ -171,7 +319,7 @@ public class T9DB {
try {
db.insertOrThrow(WORD_TABLE_NAME, null, values);
} catch (SQLiteConstraintException e) {
String msg = r.getString(R.string.add_word_exist2, iword, LangHelper.LANGS[lang]);
String msg = r.getString(R.string.add_word_exist2, iword, lang.name());
Log.w("T9DB.addWord", msg);
throw new DBException(msg);
}
@ -183,58 +331,12 @@ public class T9DB {
Toast.makeText(mContext, R.string.database_notready, Toast.LENGTH_SHORT).show();
return;
}
db.execSQL(
"UPDATE " + WORD_TABLE_NAME +
" SET " + COLUMN_FREQUENCY + " = " + COLUMN_FREQUENCY + "+ 1" +
" WHERE " + COLUMN_ID + " = \"" + id + "\"");
db.execSQL(UPDATEQ + id);
// if id's freq is greater than FREQ_MAX, it gets normalized with trigger
}
protected String getWord(String is, int lang) {
String result = null;
String q =
"SELECT " + COLUMN_WORD + " FROM " + WORD_TABLE_NAME +
" WHERE " + COLUMN_LANG + "=? AND " + COLUMN_SEQ + "=?" +
" ORDER BY " + COLUMN_FREQUENCY + " DESC";
if (!checkReady()) {
Log.e("T9DB.getWord", "not ready");
Toast.makeText(mContext, R.string.database_notready, Toast.LENGTH_SHORT).show();
return "";
}
Cursor cur = db.rawQuery(q, new String[] { is, String.valueOf(lang) });
int hits = 0;
if (cur.moveToFirst()) {
result = cur.getString(0);
}
cur.close();
if (result != null) {
return result;
} else {
int islen = is.length();
if (islen >= 2) {
char c = is.charAt(islen - 1);
c++;
q = "SELECT " + 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)});
if (cur.moveToFirst()) {
result = cur.getString(0);
}
if (result == null) {
result = "";
}
cur.close();
}
}
return result;
}
protected void updateWords(String is, AbstractList<String> stringList, List<Integer> intList,
int capsMode, int lang) {
int capsMode, LANGUAGE lang) {
stringList.clear();
intList.clear();
// String[] sa = packInts(stringToInts(is), true);
@ -245,20 +347,18 @@ public class T9DB {
Toast.makeText(mContext, R.string.database_notready, Toast.LENGTH_SHORT).show();
return;
}
Cursor cur = db.rawQuery(QUERY1, new String[] { String.valueOf(lang), is });
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 >= 15) {
// break;
// }
if (hits >= MAX_MAX_RESULTS) { break; } // to stop index error in candidate view
hits++;
}
cur.close();
if ((hits < MINHITS) && (islen <= 2)) {
if ((hits < MINHITS) && (islen >= 2)) {
char c = is.charAt(islen - 1);
c++;
String q = "SELECT " + COLUMN_ID + ", " + COLUMN_WORD +
@ -267,12 +367,12 @@ public class T9DB {
"' 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) });
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 >= 20) {
if (hits >= MAX_MAX_RESULTS) {
break;
}
hits++;
@ -294,7 +394,7 @@ public class T9DB {
word = iter.next();
switch (capsMode) {
case CAPS_ALL:
wordtemp = word.toUpperCase(LangHelper.LOCALES[lang]);
wordtemp = word.toUpperCase(LangHelper.LOCALES[lang.index]);
if (wordtemp.equals(word)) {
index++;
continue;
@ -308,9 +408,9 @@ public class T9DB {
break;
case CAPS_SINGLE:
if (word.length() > 1) {
wordtemp = word.substring(0, 1).toUpperCase(LangHelper.LOCALES[lang]) + word.substring(1);
wordtemp = word.substring(0, 1).toUpperCase(LangHelper.LOCALES[lang.index]) + word.substring(1);
} else {
wordtemp = word.toUpperCase(LangHelper.LOCALES[lang]);
wordtemp = word.toUpperCase(LangHelper.LOCALES[lang.index]);
}
if (wordtemp.equals(word)) {
index++;
@ -334,58 +434,6 @@ public class T9DB {
//Log.d("T9DB.updateWords", "i:" + is + " words:" + Arrays.toString(stringList.toArray()));
}
protected void updateWordsW(String is, Collection<String> stringList,
Collection<Integer> intList, Collection<Integer> freq, int lang) {
stringList.clear();
intList.clear();
freq.clear();
// String[] sa = packInts(stringToInts(is), true);
int islen = is.length();
String q = "SELECT " + COLUMN_ID + ", " + COLUMN_WORD + ", " + COLUMN_FREQUENCY +
" FROM " + WORD_TABLE_NAME +
" WHERE " + COLUMN_LANG + "=? AND " + COLUMN_SEQ + "=?" +
" ORDER BY " + COLUMN_FREQUENCY + " DESC";
if (!checkReady()) {
Log.e("T9DB.updateWordsW", "not ready");
Toast.makeText(mContext, R.string.database_notready, Toast.LENGTH_SHORT).show();
return;
}
Cursor cur = db.rawQuery(q, new String[] { is, String.valueOf(lang) });
int hits = 0;
for (cur.moveToFirst(); !cur.isAfterLast(); cur.moveToNext()) {
intList.add(cur.getInt(0));
stringList.add(cur.getString(1));
freq.add(cur.getInt(2));
if (hits >= 10) {
break;
}
hits++;
}
cur.close();
if (hits < MINHITS) {
char c = is.charAt(islen - 1);
c++;
q = "SELECT " + COLUMN_ID + ", " + COLUMN_WORD + ", " + COLUMN_FREQUENCY +
" FROM " + WORD_TABLE_NAME +
" WHERE " + COLUMN_LANG + "=? AND " + COLUMN_SEQ + " >= '" + is +
"' 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) });
for (cur.moveToFirst(); !cur.isAfterLast(); cur.moveToNext()) {
intList.add(cur.getInt(0));
stringList.add(cur.getString(1));
freq.add(cur.getInt(2));
if (hits >= 10) {
break;
}
hits++;
}
cur.close();
}
}
private static class DatabaseHelper extends SQLiteOpenHelper {
Context mContext = null;
@ -416,7 +464,7 @@ public class T9DB {
COLUMN_WORD + " TEXT, " +
COLUMN_FREQUENCY + " INTEGER, " +
"UNIQUE(" + COLUMN_LANG + ", " + COLUMN_WORD + ") )");
db.execSQL("CREATE INDEX idx ON " + WORD_TABLE_NAME + "("
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 +
@ -426,19 +474,51 @@ public class T9DB {
+ COLUMN_FREQUENCY + " / " + FREQ_DIV +
" WHERE " + COLUMN_SEQ + " = NEW." + COLUMN_SEQ + ";" +
" END;");
// protected static final String[] setting_keys = {INPUT_MODE, LANG_SUPPORT, MODE_NOTIFY, LAST_LANG};
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, " +
DBSettings.SETTING.LAST_LANG.id + " INTEGER, " +
DBSettings.SETTING.LAST_WORD.id + " TEXT )");
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());
}
@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");
db.execSQL("DROP INDEX IF EXISTS idx");
onCreate(db);
ContentValues updatedata = new ContentValues();
updatedata.put(COLUMN_LANG, 0);
db.update(WORD_TABLE_NAME, updatedata, null, null);
onCreate(db);
oldVersion = 2;
}
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.EN.id +
" WHERE " + COLUMN_LANG + "=0");
db.execSQL("UPDATE " + WORD_TABLE_NAME + " SET " + COLUMN_LANG + "=" + LANGUAGE.RU.id +
" WHERE " + COLUMN_LANG + "=1");
onCreate(db);
}
Log.i("T9DB.onUpgrade", "Done.");
}

View file

@ -6,13 +6,10 @@ import java.util.Arrays;
import java.util.List;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.res.Resources;
import android.inputmethodservice.InputMethodService;
import android.inputmethodservice.KeyboardView;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.text.InputType;
import android.text.TextUtils;
import android.util.Log;
@ -23,7 +20,8 @@ import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.widget.Toast;
import pl.wavesoftware.widget.MultiSelectListPreference;
import org.nyanya.android.traditionalt9.LangHelper.LANGUAGE;
import org.nyanya.android.traditionalt9.T9DB.DBSettings.SETTING;
public class TraditionalT9 extends InputMethodService implements
KeyboardView.OnKeyboardActionListener {
@ -62,10 +60,10 @@ public class TraditionalT9 extends InputMethodService implements
private String mPreviousWord = "";
private int mCapsMode;
private int mLang;
private LANGUAGE mLang;
private int mLangIndex;
private int[] mLangsAvailable = null;
private LANGUAGE[] mLangsAvailable = null;
private static final int CAPS_OFF = 0;
private static final int CAPS_SINGLE = 1;
@ -89,8 +87,6 @@ public class TraditionalT9 extends InputMethodService implements
private static final int[] MODE_CYCLE = { MODE_LANG, MODE_TEXT, MODE_NUM };
private int mKeyMode;
private SharedPreferences pref;
private Toast modeNotification = null;
/**
@ -104,9 +100,6 @@ public class TraditionalT9 extends InputMethodService implements
mCharIndex = 0;
db = T9DB.getInstance(this);
pref = PreferenceManager.getDefaultSharedPreferences(this);
mLangsAvailable = LangHelper.buildLangs(pref.getString("pref_lang_support", null));
if (interfacehandler == null) {
interfacehandler = new InterfaceHandler(getLayoutInflater().inflate(R.layout.mainview,
null), this);
@ -187,7 +180,7 @@ public class TraditionalT9 extends InputMethodService implements
awintent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
awintent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
awintent.putExtra("org.nyanya.android.traditionalt9.word", mComposing.toString());
awintent.putExtra("org.nyanya.android.traditionalt9.lang", mLang);
awintent.putExtra("org.nyanya.android.traditionalt9.lang", mLang.id);
clearState();
InputConnection ic = getCurrentInputConnection();
ic.setComposingText("", 0);
@ -201,23 +194,16 @@ public class TraditionalT9 extends InputMethodService implements
// sanitize lang and set index for cycling lang
// Need to check if last lang is available, if not, set index to -1 and set lang to default to 0
private int sanitizeLang(int lang) {
private LANGUAGE sanitizeLang(LANGUAGE lang) {
mLangIndex = 0;
if (mLangsAvailable.length < 1 || lang == -1) {
if (mLangsAvailable.length < 1 || lang == LANGUAGE.NONE) {
Log.e("T9.sanitizeLang", "This shouldn't happen.");
return 0;
}
if (lang >= LangHelper.NLANGS) {
Log.w("T9.sanitizeLang", "Previous lang not supported: " + lang + " langs: " + Arrays.toString(LangHelper.LANGS));
return mLangsAvailable[0];
} else {
int index = LangHelper.findIndex(mLangsAvailable, lang);
if (index == -1) {
return mLangsAvailable[mLangIndex];
} else {
mLangIndex = index;
return lang;
}
else {
int index = LangHelper.findIndex(mLangsAvailable, lang);
mLangIndex = index;
return mLangsAvailable[index];
}
}
/**
@ -252,8 +238,15 @@ public class TraditionalT9 extends InputMethodService implements
// way.
clearState();
mLangsAvailable = LangHelper.buildLangs(pref.getString("pref_lang_support", null));
mLang = sanitizeLang(pref.getInt("last_lang", 0));
// get settings
Object[] settings = db.getSettings(new SETTING[]
// 0, 1, 2,
{SETTING.LANG_SUPPORT, SETTING.LAST_LANG, SETTING.MODE_NOTIFY,
// 3, 4
SETTING.INPUT_MODE, SETTING.LAST_WORD} );
mLangsAvailable = LangHelper.buildLangs((Integer)settings[0]);
mLang = sanitizeLang(LANGUAGE.get((Integer)settings[1]));
updateCandidates();
@ -261,7 +254,7 @@ public class TraditionalT9 extends InputMethodService implements
mKeyMode = MODE_TEXT;
boolean modenotify = pref.getBoolean("pref_mode_notify", false);
boolean modenotify = settings[2].equals("1");
if (!modenotify && modeNotification != null) {
modeNotification = null;
} else if (modenotify && modeNotification == null){
@ -289,7 +282,7 @@ public class TraditionalT9 extends InputMethodService implements
// normal alphabetic keyboard, and assume that we should
// be doing predictive text (showing candidates as the
// user types).
mKeyMode = Integer.parseInt(pref.getString("pref_inputmode", "0"));
mKeyMode = (Integer)settings[3];
// We now look for a few special variations of text that will
// modify our behavior.
@ -316,7 +309,7 @@ public class TraditionalT9 extends InputMethodService implements
// candidates when in fullscreen mode, otherwise relying
// own it displaying its own UI.
// ????
mKeyMode = Integer.parseInt(pref.getString("pref_inputmode", "0"));
mKeyMode = (Integer)settings[3];
}
// handle filter list cases... do not hijack DPAD center and make
@ -351,20 +344,18 @@ public class TraditionalT9 extends InputMethodService implements
} else {
mAddingWord = false;
// Log.d("onStartInput", "not adding word");
prevword = pref.getString("last_word", null);
prevword = (String)settings[4];
if (prevword != null) {
onText(prevword);
Editor prefedit = pref.edit();
prefedit.remove("last_word");
prefedit.commit();
db.storeSettingString(SETTING.LAST_WORD, null);
}
if (modenotify) {
Resources r = getResources();
if (mKeyMode != MODE_NUM)
modeNotify(String.format("%s %s %s", r.getStringArray(R.array.pref_lang_titles)[mLang],
modeNotify(String.format("%s %s %s", r.getStringArray(R.array.pref_lang_titles)[mLang.index],
r.getStringArray(R.array.keyMode)[mKeyMode], r.getStringArray(R.array.capsMode)[mCapsMode]));
else
modeNotify(String.format("%s %s", r.getStringArray(R.array.pref_lang_titles)[mLang],
modeNotify(String.format("%s %s", r.getStringArray(R.array.pref_lang_titles)[mLang.index],
r.getStringArray(R.array.keyMode)[mKeyMode]));
}
}
@ -393,9 +384,7 @@ public class TraditionalT9 extends InputMethodService implements
public void onFinishInput() {
super.onFinishInput();
// Log.d("onFinishInput", "When is this called?");
Editor prefedit = pref.edit();
prefedit.putInt("last_lang", mLang);
prefedit.commit();
db.storeSettingInt(SETTING.LAST_LANG, mLang.id);
if (mEditing == EDITING) {
commitTyped();
finish();
@ -575,6 +564,7 @@ public class TraditionalT9 extends InputMethodService implements
case KeyEvent.KEYCODE_9:
case KeyEvent.KEYCODE_POUND:
case KeyEvent.KEYCODE_STAR:
case 94:
event.startTracking();
return true;
default:
@ -779,6 +769,7 @@ public class TraditionalT9 extends InputMethodService implements
case KeyEvent.KEYCODE_9:
case KeyEvent.KEYCODE_POUND:
case KeyEvent.KEYCODE_STAR:
case 94:
//case KeyEvent.KEYCODE_FOCUS:
// if (!isInputViewShown()){
// Log.d("onKeyUp", "showing window.");
@ -892,10 +883,6 @@ public class TraditionalT9 extends InputMethodService implements
break;
case KeyEvent.KEYCODE_SOFT_RIGHT:
nextKeyMode();
break;
case KeyEvent.KEYCODE_FOCUS:
// do IME action
break;
default:
if (keyCode >= KeyEvent.KEYCODE_0 && keyCode <= KeyEvent.KEYCODE_9) {
@ -1020,7 +1007,8 @@ public class TraditionalT9 extends InputMethodService implements
} else if (mKeyMode == MODE_TEXT) {
if (mComposing.length() > 0) {
mSuggestionStrings.clear();
char[] ca = CharMap.T9TABLE[mLang][mPrevious];
char[] ca = CharMap.T9TABLE[mLang.index][mPrevious];
for (char c : ca) {
mSuggestionStrings.add(String.valueOf(c));
}
@ -1050,14 +1038,16 @@ public class TraditionalT9 extends InputMethodService implements
}
setCandidatesViewShown(false);
}
Log.d("handleBS", "Stage1: (" + length + "," + length2 + ")");
Log.d("handleBS", "Stage1: (" + mComposingI.toString() + ")");
if (length2 > 1) {
if (mComposingI.charAt(length2-1) == '1' ) {
if (mComposingI.charAt(length2 - 1) == '1') {
// revert previous word
mPreviousWord = mPreviousWord.substring(0, mPreviousWord.length()-1);
mPreviousWord = mPreviousWord.substring(0, mPreviousWord.length() - 1);
}
mComposingI.delete(length2 - 1, length2);
if (length2-1 > 1) {
if (mComposingI.charAt(length2-2) != '1') {
if (length2 - 1 > 1) {
if (mComposingI.charAt(length2 - 2) != '1') {
if (mComposingI.indexOf("1") == -1) {
// no longer contains punctuation so we no longer care
mPreviousWord = "";
@ -1069,6 +1059,7 @@ public class TraditionalT9 extends InputMethodService implements
updateCandidates(true);
getCurrentInputConnection().setComposingText(mComposing, 1);
} else if (length > 0 || length2 > 0) {
Log.d("handleBS", "resetting thing");
mComposing.setLength(0);
mComposingI.setLength(0);
interfacehandler.midButtonUpdate(false);
@ -1129,7 +1120,6 @@ public class TraditionalT9 extends InputMethodService implements
updateCandidates();
getCurrentInputConnection().setComposingText(mComposing, 1);
}
break;
case MODE_TEXT:
@ -1154,20 +1144,19 @@ public class TraditionalT9 extends InputMethodService implements
// start at caps if CapMode
// Log.d("handleChar", "Cm: " + mCapsMode);
if (mCharIndex == 0 && mCapsMode != CAPS_OFF) {
mCharIndex = CharMap.T9CAPSTART[mLang][keyCode];
mCharIndex = CharMap.T9CAPSTART[mLang.index][keyCode];
}
// private int mPrevious;
// private int mCharindex;
mComposing.setLength(0);
mComposingI.setLength(0);
char[] ca = CharMap.T9TABLE[mLang][keyCode];
char[] ca = CharMap.T9TABLE[mLang.index][keyCode];
if (mCharIndex >= ca.length) {
mCharIndex = 0;
}
mComposing.append(ca[mCharIndex]);
mComposingI.append(keyCode);
getCurrentInputConnection().setComposingText(mComposing, 1);
t9releasehandler.postDelayed(mt9release, T9DELAY);
@ -1318,7 +1307,7 @@ public class TraditionalT9 extends InputMethodService implements
mLang = mLangsAvailable[mLangIndex];
updateKeyMode();
if (modeNotification != null) {
modeNotify(getResources().getStringArray(R.array.pref_lang_titles)[mLang]);
modeNotify(getResources().getStringArray(R.array.pref_lang_titles)[mLang.index]);
}
}
@ -1342,7 +1331,7 @@ public class TraditionalT9 extends InputMethodService implements
switch (mKeyMode) {
case MODE_TEXT:
interfacehandler.showHold(false);
icon = LangHelper.ICONMAP[mLang][mKeyMode][mCapsMode];
icon = LangHelper.ICONMAP[mLang.index][mKeyMode][mCapsMode];
break;
case MODE_LANG:
if (!db.ready) {
@ -1364,7 +1353,7 @@ public class TraditionalT9 extends InputMethodService implements
}
//Log.d("T9.updateKeyMode", "lang: " + mLang + " mKeyMode: " + mKeyMode + " mCapsMode"
// + mCapsMode);
icon = LangHelper.ICONMAP[mLang][mKeyMode][mCapsMode];
icon = LangHelper.ICONMAP[mLang.index][mKeyMode][mCapsMode];
break;
case MODE_NUM:
interfacehandler.showHold(false);

View file

@ -21,7 +21,6 @@ import java.io.UnsupportedEncodingException;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@ -29,11 +28,11 @@ import java.util.Properties;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.database.Cursor;
import android.database.DatabaseUtils.InsertHelper;
@ -43,19 +42,23 @@ import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.os.SystemClock;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceManager;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.Toast;
import com.stackoverflow.answer.UnicodeBOMInputStream;
import pl.wavesoftware.widget.MultiSelectListPreference;
import org.nyanya.android.traditionalt9.settings.CustomInflater;
import org.nyanya.android.traditionalt9.settings.Setting;
import org.nyanya.android.traditionalt9.settings.SettingAdapter;
import org.nyanya.android.traditionalt9.LangHelper.LANGUAGE;
import org.nyanya.android.traditionalt9.T9DB.DBSettings.SETTING;
public class TraditionalT9Settings extends PreferenceActivity implements
public class TraditionalT9Settings extends ListActivity implements
DialogInterface.OnCancelListener {
AsyncTask<String, Integer, Reply> task = null;
@ -82,7 +85,7 @@ public class TraditionalT9Settings extends PreferenceActivity implements
protected Reply() {
this.status = true;
this.msgs = new LinkedList<String>();
this.msgs = new ArrayList<String>(4);
}
protected void addMsg(String msg) throws LoadException {
@ -117,7 +120,7 @@ public class TraditionalT9Settings extends PreferenceActivity implements
}
}
private void closeStream(Closeable is, Reply reply) {
private static void closeStream(Closeable is, Reply reply) {
if (is == null) {
return;
}
@ -140,9 +143,9 @@ public class TraditionalT9Settings extends PreferenceActivity implements
boolean internal;
boolean restore;
String[] dicts;
int[] mSupportedLanguages;
LANGUAGE[] mSupportedLanguages;
LoadDictTask(int msgid, boolean intern, boolean restorebackup, int[] supportedLanguages) {
LoadDictTask(int msgid, boolean intern, boolean restorebackup, LANGUAGE[] supportedLanguages) {
internal = intern;
restore = restorebackup;
@ -150,11 +153,9 @@ public class TraditionalT9Settings extends PreferenceActivity implements
dicts = new String[suplanglen];
for (int x=0; x<suplanglen; x++) {
if (intern) {
dicts[x] = String.format(dictname,
LangHelper.LANGS[supportedLanguages[x]].toLowerCase(Locale.ENGLISH));
dicts[x] = String.format(dictname, supportedLanguages[x].name().toLowerCase(Locale.ENGLISH));
} else {
dicts[x] = String.format(userdictname,
LangHelper.LANGS[supportedLanguages[x]].toLowerCase(Locale.ENGLISH));
dicts[x] = String.format(userdictname, supportedLanguages[x].name().toLowerCase(Locale.ENGLISH));
}
}
mSupportedLanguages = supportedLanguages;
@ -241,7 +242,7 @@ public class TraditionalT9Settings extends PreferenceActivity implements
// add characters first, then dictionary:
Log.d("doInBackground", "Adding characters...");
// load characters from supported langs
for (int lang : mSupportedLanguages) {
for (LANGUAGE lang : mSupportedLanguages) {
processChars(db, lang);
}
Log.d("doInBackground", "done.");
@ -255,7 +256,7 @@ public class TraditionalT9Settings extends PreferenceActivity implements
try {
dictstream = new FileInputStream(new File(
new File(Environment.getExternalStorageDirectory(), sddir), backupname));
reply = processFile(dictstream, reply, db, -1, backupname);
reply = processFile(dictstream, reply, db, LANGUAGE.NONE, backupname);
} catch (FileNotFoundException e) {
reply.status = false;
reply.forceMsg("Backup file not found: " + e.getMessage());
@ -319,7 +320,7 @@ public class TraditionalT9Settings extends PreferenceActivity implements
return reply;
}
private void processChars(SQLiteDatabase db, int lang) {
private void processChars(SQLiteDatabase db, LANGUAGE lang) {
InsertHelper wordhelp = new InsertHelper(db, T9DB.WORD_TABLE_NAME);
final int wordColumn = wordhelp.getColumnIndex(T9DB.COLUMN_WORD);
@ -327,34 +328,38 @@ public class TraditionalT9Settings extends PreferenceActivity implements
final int freqColumn = wordhelp.getColumnIndex(T9DB.COLUMN_FREQUENCY);
final int seqColumn = wordhelp.getColumnIndex(T9DB.COLUMN_SEQ);
try {
// load CHARTABLE and then load T9table, just to cover all bases.
for (Map.Entry<Character, Integer> entry : CharMap.CHARTABLE.get(lang).entrySet()) {
for (Map.Entry<Character, Integer> entry : CharMap.CHARTABLE.get(lang.index).entrySet()) {
wordhelp.prepareForReplace();
wordhelp.bind(langColumn, Integer.toString(lang));
wordhelp.bind(langColumn, lang.id);
wordhelp.bind(seqColumn, Integer.toString(entry.getValue()));
wordhelp.bind(wordColumn, Character.toString(entry.getKey()));
wordhelp.bind(freqColumn, 0);
wordhelp.execute();
// upper case
wordhelp.prepareForReplace();
wordhelp.bind(langColumn, Integer.toString(lang));
wordhelp.bind(langColumn, lang.id);
wordhelp.bind(seqColumn, Integer.toString(entry.getValue()));
wordhelp.bind(wordColumn, Character.toString(Character.toUpperCase(entry.getKey())));
wordhelp.bind(freqColumn, 0);
wordhelp.execute();
}
char[][] chartable = CharMap.T9TABLE[lang];
for (int numkey=0; numkey<chartable.length; numkey++) {
char[][] chartable = CharMap.T9TABLE[lang.index];
for (int numkey = 0; numkey < chartable.length; numkey++) {
char[] chars = chartable[numkey];
for (int charindex=0; charindex<chars.length; charindex++) {
for (int charindex = 0; charindex < chars.length; charindex++) {
wordhelp.prepareForReplace();
wordhelp.bind(langColumn, Integer.toString(lang));
wordhelp.bind(langColumn, lang.id);
wordhelp.bind(seqColumn, Integer.toString(numkey));
wordhelp.bind(wordColumn, Character.toString(chars[charindex]));
wordhelp.bind(freqColumn, 0);
wordhelp.execute();
}
}
} finally {
wordhelp.close();
}
}
private String getLine(BufferedReader br, Reply rpl, String fname) throws LoadException {
@ -368,7 +373,7 @@ public class TraditionalT9Settings extends PreferenceActivity implements
return null;
}
private Reply processFile(InputStream is, Reply rpl, SQLiteDatabase db, int lang, String fname)
private Reply processFile(InputStream is, Reply rpl, SQLiteDatabase db, LANGUAGE lang, String fname)
throws LoadException, IOException {
long last = 0;
UnicodeBOMInputStream ubis = new UnicodeBOMInputStream(is);
@ -408,21 +413,21 @@ public class TraditionalT9Settings extends PreferenceActivity implements
rpl.addMsg("Number error ("+fname+") at line " + linecount+". Using 0 for frequency.");
freq = 0;
}
if (lang == -1 && ws.length == 3) {
if (lang == LANGUAGE.NONE && ws.length == 3) {
try {
lang = Integer.parseInt(ws[2]);
lang = LANGUAGE.get(Integer.parseInt(ws[2]));
} catch (NumberFormatException e) {
rpl.status = false;
rpl.addMsg("Number error ("+fname+") at line " + linecount+". Using 0 (en) for language.");
lang = 0;
rpl.addMsg("Number error ("+fname+") at line " + linecount+". Using 1 (en) for language.");
lang = LANGUAGE.EN;
}
if (lang >= LangHelper.LANGS.length) {
if (lang == null) {
rpl.status = false;
rpl.addMsg("Unsupported language ("+fname+") at line " + linecount+". Trying 0 (en) for language.");
lang = 0;
rpl.addMsg("Unsupported language ("+fname+") at line " + linecount+". Trying 1 (en) for language.");
lang = LANGUAGE.EN;
}
} else if (lang == -1) {
lang = 0;
} else if (lang == LANGUAGE.NONE) {
lang = LANGUAGE.EN;
}
} else {
freq = 0;
@ -445,13 +450,13 @@ public class TraditionalT9Settings extends PreferenceActivity implements
rpl.status = false;
rpl.addMsg("Error on word ("+word+") line "+
linecount+" in (" + fname+"): "+
getResources().getString(R.string.add_word_badchar, LangHelper.LANGS[lang], word));
getResources().getString(R.string.add_word_badchar, lang.name(), word));
break;
}
linecount++;
wordhelp.prepareForReplace();
wordhelp.bind(seqColumn, seq);
wordhelp.bind(langColumn, lang);
wordhelp.bind(langColumn, lang.id);
wordhelp.bind(wordColumn, word);
wordhelp.bind(freqColumn, freq);
wordhelp.execute();
@ -597,7 +602,7 @@ public class TraditionalT9Settings extends PreferenceActivity implements
cur.close();
}
} finally {
cur.close();
}
publishProgress(10000);
@ -606,10 +611,6 @@ public class TraditionalT9Settings extends PreferenceActivity implements
Log.d("doInBackground", "entries: " + entries + " last: " + pos);
try {
bw.flush();
} catch (IOException e) {
e.printStackTrace();
}
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
@ -683,86 +684,44 @@ public class TraditionalT9Settings extends PreferenceActivity implements
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.prefs);
Preference button = getPreferenceManager().findPreference("help");
if (button != null) {
button.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference arg0) {
openHelp();
return true;
}
});
}
// maybe need this?
// http://stackoverflow.com/questions/7645880/listview-with-onitemclicklistener-android
button = getPreferenceManager().findPreference("loaddict");
if (button != null) {
button.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference arg0) {
preloader(R.string.pref_loadingdict, true, false);
return true;
// get settings
Object[] settings = T9DB.getInstance(this).getSettings(new SETTING[]
// 0, 1, 2
{SETTING.INPUT_MODE, SETTING.LANG_SUPPORT, SETTING.MODE_NOTIFY});
ListAdapter settingitems;
try {
settingitems = new SettingAdapter(this, CustomInflater.inflate(this, R.xml.prefs, settings));
} catch (Exception e) {
e.printStackTrace();
return;
}
});
}
button = getPreferenceManager().findPreference("loaduserdict");
if (button != null) {
button.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference arg0) {
preloader(R.string.pref_loadinguserdict, false, false);
return true;
}
});
}
button = getPreferenceManager().findPreference("nukedict");
if (button != null) {
button.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference arg0) {
nukeDict();
return true;
}
});
}
button = getPreferenceManager().findPreference("backupdict");
if (button != null) {
button.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference arg0) {
backupDict();
return true;
}
});
}
button = getPreferenceManager().findPreference("restoredict");
if (button != null) {
button.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference arg0) {
restoreDict();
return true;
}
});
}
button = getPreferenceManager().findPreference("querytest");
if (button != null) {
button.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference arg0) {
test();
return true;
}
});
}
setContentView(R.layout.preference_list_content);
setListAdapter(settingitems);
mContext = this;
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
Setting s = (Setting)getListView().getItemAtPosition(position);
if (s.id.equals("help"))
openHelp();
else if (s.id.equals("loaddict"))
preloader(R.string.pref_loadingdict, true, false);
else if (s.id.equals("loaduserdict"))
preloader(R.string.pref_loadinguserdict, false, false);
else if (s.id.equals("nukedict"))
nukeDict();
else if (s.id.equals("backupdict"))
backupDict();
else if (s.id.equals("restoredict"))
restoreDict();
else
s.clicked(mContext);
}
private void openHelp() {
@ -775,7 +734,7 @@ public class TraditionalT9Settings extends PreferenceActivity implements
private void preloader(int msgid, boolean internal, boolean restorebackup) {
task = new LoadDictTask(msgid, internal, restorebackup,
LangHelper.buildLangs(((ListPreference) findPreference("pref_lang_support")).getValue()));
LangHelper.buildLangs(T9DB.getInstance(mContext).getSettingInt(SETTING.LANG_SUPPORT)));
task.execute();
}
@ -787,13 +746,13 @@ public class TraditionalT9Settings extends PreferenceActivity implements
private void nukeDict() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.pref_nuke_warn).setTitle(R.string.pref_nuke_title)
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
.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();
}
}).setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
}).setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
@ -818,12 +777,12 @@ public class TraditionalT9Settings extends PreferenceActivity implements
saveloc = new File(saveloc, backupname);
if (saveloc.exists()) {
builder.setMessage(R.string.pref_backup_warn).setTitle(R.string.pref_backup_title)
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
predumper(R.string.pref_savingbackup);
}
}).setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
}).setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
@ -845,7 +804,7 @@ public class TraditionalT9Settings extends PreferenceActivity implements
private void showErrorDialog(AlertDialog.Builder builder, CharSequence title, CharSequence msg) {
builder.setMessage(msg).setTitle(title)
.setNeutralButton(R.string.ok, new DialogInterface.OnClickListener() {
.setNeutralButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
@ -857,7 +816,7 @@ public class TraditionalT9Settings extends PreferenceActivity implements
private void showErrorDialogID(AlertDialog.Builder builder, int titleid, int msgid) {
builder.setMessage(msgid).setTitle(titleid)
.setNeutralButton(R.string.ok, new DialogInterface.OnClickListener() {
.setNeutralButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
@ -881,12 +840,12 @@ public class TraditionalT9Settings extends PreferenceActivity implements
res.getString(R.string.pref_restore_warn,
res.getString(R.string.pref_nukedict)))
.setTitle(R.string.pref_restore_title)
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
preloader(R.string.pref_loadingbackup, false, true);
}
}).setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
}).setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
@ -913,17 +872,17 @@ public class TraditionalT9Settings extends PreferenceActivity implements
T9DB tdb = T9DB.getInstance(this);
Log.d("queryTestDebug", "Testing...");
tdb.updateWords("123", words, ids, 0, LangHelper.EN);
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.EN);
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.EN);
tdb.updateWords("228", words, ids, 0, LangHelper.LANGUAGE.EN);
i = words.iterator();
while (i.hasNext()) {
Log.d("queryTestDebug", "word: " + i.next());
@ -961,7 +920,7 @@ public class TraditionalT9Settings extends PreferenceActivity implements
T9DB tdb = T9DB.getInstance(this);
tdb.updateWords("222", words, ids, 0, LangHelper.EN);
tdb.updateWords("222", words, ids, 0, LangHelper.LANGUAGE.EN);
size = ids.size();
if (size > 0) {
tdb.incrementWord(ids.get(0));
@ -977,7 +936,7 @@ public class TraditionalT9Settings extends PreferenceActivity implements
Log.d("TIMING", "Execution time: " + (endnow - startnow) + " ms");
List<Integer> freqs = new ArrayList<Integer>(8);
tdb.updateWordsW("222", words, ids, freqs, LangHelper.EN);
//tdb.updateWordsW("222", words, ids, freqs, LangHelper.EN);
Log.d("VALUES", "...");
size = freqs.size();
for (int x = 0; x < size; x++) {
@ -986,13 +945,7 @@ public class TraditionalT9Settings extends PreferenceActivity implements
}
Log.d("queryTestSingle", "done.");
}
private void test() {
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
if ( "".equalsIgnoreCase(pref.getString("pref_lang_support", null)) ) {
Log.d("T9Settings.test", "AAAAAAAAAA blank string");
}
Log.d("T9Settings.test", pref.getString("pref_lang_support", "aaaaaaaaaa"));
}
@Override
public void onCancel(DialogInterface dint) {
task.cancel(false);

View file

@ -0,0 +1,41 @@
package org.nyanya.android.traditionalt9.settings;
// http://stackoverflow.com/a/8488691
import android.content.Context;
import android.content.res.XmlResourceParser;
import android.util.AttributeSet;
import android.util.Log;
import org.nyanya.android.traditionalt9.R;
import org.xmlpull.v1.XmlPullParser;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
public class CustomInflater {
public static ArrayList<Setting> inflate(Context context, int xmlFileResId, Object[] isettings)
throws Exception {
ArrayList<Setting> settings = new ArrayList<Setting>();
XmlResourceParser parser = context.getResources().getXml(xmlFileResId);
int token;
while ((token = parser.next()) != XmlPullParser.END_DOCUMENT) {
if (token == XmlPullParser.START_TAG) {
if (!parser.getName().equals("Settings")) {
//prepend package
Class aClass = Class.forName("org.nyanya.android.traditionalt9.settings."+parser.getName());
Class<?>[] params = new Class[]{Context.class, AttributeSet.class, isettings.getClass()};
Constructor<?> constructor = aClass.getConstructor(params);
try {
settings.add((Setting) constructor.newInstance(context, parser, isettings));
} catch (InstantiationException e) {
e.printStackTrace();
}
}
}
}
return settings;
}
}

View file

@ -0,0 +1,41 @@
package org.nyanya.android.traditionalt9.settings;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import org.nyanya.android.traditionalt9.R;
public class Setting {
String title;
String summary = null;
public String id;
public int widgetID = 0;
public int layout;
protected View view;
public Setting (Context context, AttributeSet attrs, Object[] isettings) {
// http://stackoverflow.com/a/8488691
for (int i = 0; i < attrs.getAttributeCount(); i++) {
String attr = attrs.getAttributeName(i);
if ("title".equals(attr)) {
// load string resource
title = context.getString(attrs.getAttributeResourceValue(i, 0));
} else if ("summary".equals(attr)) {
summary = context.getString(attrs.getAttributeResourceValue(i, 0));
} else if ("id".equals(attr)){
id = attrs.getAttributeValue(i);
}
}
if (summary == null)
layout = R.layout.setting;
else
layout = R.layout.setting_sum;
}
public void clicked(final Context context) {}
public void setView(View view) {
this.view = view;
}
}

View file

@ -0,0 +1,45 @@
package org.nyanya.android.traditionalt9.settings;
// https://github.com/codepath/android_guides/wiki/Using-an-ArrayAdapter-with-ListView
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import org.nyanya.android.traditionalt9.R;
import java.util.ArrayList;
public class SettingAdapter extends ArrayAdapter<Setting> {
public SettingAdapter(Context context, ArrayList<Setting> settings) {
super(context, 0, settings);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get the data item for this position
Setting setting = getItem(position);
final LayoutInflater layoutInflater = LayoutInflater.from(getContext());
// Check if an existing view is being reused, otherwise inflate the view
if (convertView == null) {
convertView = layoutInflater.inflate(setting.layout, parent, false);
}
setting.setView(convertView);
// Lookup view for data population
((TextView) convertView.findViewById(R.id.title)).setText(setting.title);
if (setting.summary != null)
((TextView) convertView.findViewById(R.id.summary)).setText(setting.summary);
if (setting.widgetID != 0) {
final ViewGroup widgetFrame = (ViewGroup) convertView.findViewById(R.id.widget_frame);
layoutInflater.inflate(setting.widgetID, widgetFrame);
}
// Return the completed view to render on screen
return convertView;
}
}

View file

@ -0,0 +1,37 @@
package org.nyanya.android.traditionalt9.settings;
import android.content.Context;
import android.util.AttributeSet;
import org.nyanya.android.traditionalt9.R;
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);
}
}
if (id.equals("pref_mode_notify")){
if (isettings[2] != null)
value = isettings[2].equals(1);
else
value = defaultValue;
}
widgetID = R.layout.checkbox;
}
@Override
public void clicked(Context context) {
}
}

View file

@ -0,0 +1,66 @@
package org.nyanya.android.traditionalt9.settings;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.util.AttributeSet;
import org.nyanya.android.traditionalt9.R;
import org.nyanya.android.traditionalt9.T9DB;
import org.nyanya.android.traditionalt9.T9DB.DBSettings.SETTING;
public class SettingList extends Setting {
String[] entries;
int[] entryValues;
int defaultValue;
int value;
public SettingList (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.getAttributeIntValue(i, -1);
} else if ("entryValues".equals(attr)) {
// load string resource
entryValues = context.getResources().getIntArray(attrs.getAttributeResourceValue(i, 0));
} else if ("entries".equals(attr)) {
entries = context.getResources().getStringArray(attrs.getAttributeResourceValue(i, 0));
}
}
if (id.equals("pref_inputmode")){
if (isettings[0] != null)
value = (Integer)isettings[0];
else
value = defaultValue;
}
widgetID = R.layout.preference_dialog;
layout = R.layout.setting_widget;
}
public void clicked(final Context context) {
AlertDialog.Builder builderSingle = new AlertDialog.Builder(context);
builderSingle.setTitle(title);
builderSingle.setNegativeButton(android.R.string.cancel,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builderSingle.setSingleChoiceItems(entries, value,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
T9DB.getInstance(context).storeSettingInt(SETTING.get(id), entryValues[which]);
value = entryValues[which];
dialog.dismiss();
}
});
builderSingle.show();
}
}

View file

@ -0,0 +1,87 @@
package org.nyanya.android.traditionalt9.settings;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.TextView;
import org.nyanya.android.traditionalt9.LangHelper;
import org.nyanya.android.traditionalt9.R;
import org.nyanya.android.traditionalt9.T9DB;
import org.nyanya.android.traditionalt9.T9DB.DBSettings.SETTING;
public class SettingMultiList extends SettingList {
boolean[] selectedEntries = new boolean[0];
public SettingMultiList (Context context, AttributeSet attrs, Object[] isettings) {
super(context, attrs, isettings);
selectedEntries = new boolean[entries.length];
Log.d("Multi", "len:" + entries.length + " setting:" + isettings[1]);
for (LangHelper.LANGUAGE l : LangHelper.buildLangs((Integer)isettings[1])) {
Log.d("Multi", "index:" + l.index);
selectedEntries[l.index] = true;
}
summary = buildItems();
}
public void clicked(final Context context) {
AlertDialog.Builder builderMulti = new AlertDialog.Builder(context);
builderMulti.setTitle(title);
builderMulti.setNegativeButton(android.R.string.cancel,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builderMulti.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
T9DB.getInstance(context).storeSettingInt(SETTING.get(id), LangHelper.shrinkLangs(buildSelection()));
summary = buildItems();
dialog.dismiss();
((TextView)view.findViewById(R.id.summary)).setText(summary);
}
});
builderMulti.setMultiChoiceItems(entries, selectedEntries,
new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int which, boolean opt) {
selectedEntries[which] = opt;
}
});
builderMulti.show();
}
private int[] buildSelection(){
int count = 0;
for (boolean b: selectedEntries) {if (b) count++;}
int[] selection = new int[count];
count = 0;
for (int x=0;x<selectedEntries.length;x++) {
if (selectedEntries[x]) {
selection[count] = entryValues[x];
count++;
}
}
if (selection.length < 1)
return new int[] {entryValues[0]};
return selection;
}
private String buildItems() {
StringBuilder sb = new StringBuilder();
for (int x=0;x<selectedEntries.length;x++) {
if (selectedEntries[x]) {
sb.append(entries[x]);
sb.append((", "));
}
}
if (sb.length() > 1)
sb.setLength(sb.length()-2);
return sb.toString();
}
}

View file

@ -12,13 +12,14 @@ import android.content.DialogInterface;
import android.content.DialogInterface.OnMultiChoiceClickListener;
import android.content.res.TypedArray;
import android.preference.ListPreference;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
public class MultiSelectListPreference extends ListPreference {
private String separator;
private static final String DEFAULT_SEPARATOR = "\u0001\u0007\u001D\u0007\u0001";
private static final String DEFAULT_SEPARATOR = "|";
private boolean[] entryChecked;
public MultiSelectListPreference(Context context, AttributeSet attributeSet) {
@ -55,7 +56,7 @@ public class MultiSelectListPreference extends ListPreference {
if (val == null || "".equals(val)) {
return new CharSequence[0];
} else {
return ((String) val).split(separator);
return ((String) val).split("\\"+separator);
}
}
@ -65,7 +66,7 @@ public class MultiSelectListPreference extends ListPreference {
//Log.w("MultiSelectPref.defaultunpack", "val is null or empty");
return new int[] {0}; //default pref
} else {
String[] sa = ((String) val).split(DEFAULT_SEPARATOR);
String[] sa = ((String) val).split("\\"+DEFAULT_SEPARATOR);
if (sa.length < 1) {
Log.w("MultiSelectPref.defaultunpack", "split is less than 1");
return new int[] {0}; //default pref
@ -115,7 +116,7 @@ public class MultiSelectListPreference extends ListPreference {
}
}
String value = join(values, separator);
String value = TextUtils.join(separator, values);
setSummary(prepareSummary(values));
setValueAndEvent(value);
}
@ -143,7 +144,7 @@ public class MultiSelectListPreference extends ListPreference {
}
ix += 1;
}
return join(titles, ", ");
return TextUtils.join(", ", titles);
}
@Override
@ -157,12 +158,11 @@ public class MultiSelectListPreference extends ListPreference {
String value = null;
CharSequence[] defaultValue;
if (rawDefaultValue == null) {
defaultValue = new CharSequence[0];
defaultValue = new CharSequence[] {"0"};
} else {
defaultValue = (CharSequence[]) rawDefaultValue;
}
List<CharSequence> joined = Arrays.asList(defaultValue);
String joinedDefaultValue = join(joined, separator);
String joinedDefaultValue = TextUtils.join(separator, defaultValue);
if (restoreValue) {
value = getPersistedString(joinedDefaultValue);
} else {
@ -173,26 +173,4 @@ public class MultiSelectListPreference extends ListPreference {
setValueAndEvent(value);
}
/**
* Joins array of object to single string by separator
*
* Credits to kurellajunior on this post
* http://snippets.dzone.com/posts/show/91
*
* @param iterable
* any kind of iterable ex.: <code>["a", "b", "c"]</code>
* @param separator
* separetes entries ex.: <code>","</code>
* @return joined string ex.: <code>"a,b,c"</code>
*/
protected static String join(Iterable<?> iterable, String separator) {
Iterator<?> oIter;
if (iterable == null || (!(oIter = iterable.iterator()).hasNext()))
return "";
StringBuilder oBuilder = new StringBuilder(String.valueOf(oIter.next()));
while (oIter.hasNext())
oBuilder.append(separator).append(oIter.next());
return oBuilder.toString();
}
}