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:
parent
8a025297c3
commit
5d3894e403
26 changed files with 645 additions and 1460 deletions
|
|
@ -10,7 +10,9 @@ import android.view.Menu;
|
|||
import android.view.View;
|
||||
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 {
|
||||
|
||||
|
|
@ -45,9 +47,8 @@ public class AddWordAct extends Activity {
|
|||
}
|
||||
|
||||
public void doAddWord(String text) {
|
||||
T9DB db = T9DB.getInstance(this);
|
||||
try {
|
||||
db.addWord(text, LangHelper.LANGUAGE.get(lang));
|
||||
T9DB.getInstance(this).addWord(text, LangHelper.LANGUAGE.get(lang));
|
||||
} catch (DBException e) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
String msg = e.getMessage();
|
||||
|
|
@ -62,7 +63,7 @@ public class AddWordAct extends Activity {
|
|||
AlertDialog dialog = builder.create();
|
||||
dialog.show();
|
||||
}
|
||||
db.storeSettingString(SETTING.LAST_WORD, text);
|
||||
T9Preferences.getInstance(this).setLastWord(text);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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[][] 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();
|
||||
String tword = word.toLowerCase(LangHelper.LOCALES[lang.index]);
|
||||
for (int i = 0; i < word.length(); i++) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -29,7 +29,7 @@ public class LangHelper {
|
|||
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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -18,16 +18,15 @@ import android.view.inputmethod.InputConnection;
|
|||
import android.widget.Toast;
|
||||
|
||||
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.db.T9DB;
|
||||
import io.github.sspanak.tt9.preferences.T9Preferences;
|
||||
|
||||
import java.util.AbstractList;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class TraditionalT9 extends InputMethodService implements
|
||||
KeyboardView.OnKeyboardActionListener {
|
||||
|
||||
public class TraditionalT9 extends InputMethodService implements KeyboardView.OnKeyboardActionListener {
|
||||
private CandidateView mCandidateView;
|
||||
private InterfaceHandler interfacehandler = null;
|
||||
|
||||
|
|
@ -67,10 +66,7 @@ public class TraditionalT9 extends InputMethodService implements
|
|||
|
||||
private LANGUAGE[] mLangsAvailable = null;
|
||||
|
||||
private static final int CAPS_OFF = 0;
|
||||
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[] CAPS_CYCLE = { T9Preferences.CASE_LOWER, T9Preferences.CASE_CAPITALIZE, T9Preferences.CASE_UPPER };
|
||||
|
||||
private final static int T9DELAY = 900;
|
||||
final Handler t9releasehandler = new Handler();
|
||||
|
|
@ -82,11 +78,9 @@ public class TraditionalT9 extends InputMethodService implements
|
|||
};
|
||||
|
||||
private T9DB db;
|
||||
private T9Preferences prefs;
|
||||
|
||||
public static final int MODE_LANG = 0;
|
||||
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 static final int[] MODE_CYCLE = { T9Preferences.MODE_PREDICTIVE, T9Preferences.MODE_ABC, T9Preferences.MODE_123 };
|
||||
private int mKeyMode;
|
||||
|
||||
private InputConnection currentInputConnection = null;
|
||||
|
|
@ -101,6 +95,7 @@ public class TraditionalT9 extends InputMethodService implements
|
|||
mPrevious = -1;
|
||||
mCharIndex = 0;
|
||||
db = T9DB.getInstance(this);
|
||||
prefs = new T9Preferences(this);
|
||||
|
||||
if (interfacehandler == null) {
|
||||
interfacehandler = new InterfaceHandler(getLayoutInflater().inflate(R.layout.mainview,
|
||||
|
|
@ -133,7 +128,7 @@ public class TraditionalT9 extends InputMethodService implements
|
|||
//updateKeyMode();
|
||||
View v = getLayoutInflater().inflate(R.layout.mainview, null);
|
||||
interfacehandler.changeView(v);
|
||||
if (mKeyMode == MODE_LANG) {
|
||||
if (mKeyMode == T9Preferences.MODE_PREDICTIVE) {
|
||||
interfacehandler.showHold(true);
|
||||
} else {
|
||||
interfacehandler.showHold(false);
|
||||
|
|
@ -199,7 +194,7 @@ public class TraditionalT9 extends InputMethodService implements
|
|||
}
|
||||
|
||||
protected void showAddWord() {
|
||||
if (mKeyMode == MODE_LANG) {
|
||||
if (mKeyMode == T9Preferences.MODE_PREDICTIVE) {
|
||||
// decide if we are going to look for work to base on
|
||||
String template = mComposing.toString();
|
||||
if (template.length() == 0) {
|
||||
|
|
@ -245,6 +240,7 @@ public class TraditionalT9 extends InputMethodService implements
|
|||
@Override
|
||||
public void onStartInput(EditorInfo inputField, boolean restarting) {
|
||||
super.onStartInput(inputField, restarting);
|
||||
|
||||
currentInputConnection = getCurrentInputConnection();
|
||||
//Log.d("T9.onStartInput", "INPUTTYPE: " + inputField.inputType + " FIELDID: " + inputField.fieldId +
|
||||
// " FIELDNAME: " + inputField.fieldName + " PACKAGE NAME: " + inputField.packageName);
|
||||
|
|
@ -272,24 +268,14 @@ public class TraditionalT9 extends InputMethodService implements
|
|||
// way.
|
||||
clearState();
|
||||
|
||||
// get settings
|
||||
Object[] settings = db.getSettings(new SETTING[] {
|
||||
// 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]));
|
||||
mLangsAvailable = LangHelper.buildLangs(prefs.getEnabledLanguages());
|
||||
mLang = sanitizeLang(LANGUAGE.get(prefs.getInputLanguage()));
|
||||
|
||||
updateCandidates();
|
||||
|
||||
//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
|
||||
// text being edited.
|
||||
|
|
@ -298,13 +284,13 @@ public class TraditionalT9 extends InputMethodService implements
|
|||
case InputType.TYPE_CLASS_DATETIME:
|
||||
// Numbers and dates default to the symbols keyboard, with
|
||||
// no extra features.
|
||||
mKeyMode = MODE_NUM;
|
||||
mKeyMode = T9Preferences.MODE_123;
|
||||
break;
|
||||
|
||||
case InputType.TYPE_CLASS_PHONE:
|
||||
// Phones will also default to the symbols keyboard, though
|
||||
// often you will want to have a dedicated phone keyboard.
|
||||
mKeyMode = MODE_NUM;
|
||||
mKeyMode = T9Preferences.MODE_123;
|
||||
break;
|
||||
|
||||
case InputType.TYPE_CLASS_TEXT:
|
||||
|
|
@ -312,7 +298,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)settings[3];
|
||||
mKeyMode = prefs.getInputMode();
|
||||
|
||||
// We now look for a few special variations of text that will
|
||||
// modify our behavior.
|
||||
|
|
@ -321,7 +307,7 @@ public class TraditionalT9 extends InputMethodService implements
|
|||
|| variation == InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD) {
|
||||
// Do not display predictions / what the user is typing
|
||||
// when they are entering a password.
|
||||
mKeyMode = MODE_TEXT;
|
||||
mKeyMode = T9Preferences.MODE_ABC;
|
||||
}
|
||||
|
||||
if (variation == InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS
|
||||
|
|
@ -329,7 +315,7 @@ public class TraditionalT9 extends InputMethodService implements
|
|||
|| variation == InputType.TYPE_TEXT_VARIATION_FILTER) {
|
||||
// Our predictions are not useful for e-mail addresses
|
||||
// or URIs.
|
||||
mKeyMode = MODE_TEXT;
|
||||
mKeyMode = T9Preferences.MODE_ABC;
|
||||
}
|
||||
|
||||
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
|
||||
// own it displaying its own UI.
|
||||
// ????
|
||||
mKeyMode = (Integer)settings[3];
|
||||
mKeyMode = prefs.getInputMode();
|
||||
}
|
||||
|
||||
// handle filter list cases... do not hijack DPAD center and make
|
||||
|
|
@ -361,22 +347,23 @@ public class TraditionalT9 extends InputMethodService implements
|
|||
updateShiftKeyState(inputField);
|
||||
}
|
||||
if (inputField.inputType == SpecialInputType.TYPE_SHARP_007H_PHONE_BOOK) {
|
||||
mKeyMode = MODE_TEXT;
|
||||
mKeyMode = T9Preferences.MODE_ABC;
|
||||
}
|
||||
String prevword = null;
|
||||
if (inputField.privateImeOptions != null
|
||||
&& inputField.privateImeOptions.equals("io.github.sspanak.tt9.addword=true")) {
|
||||
if (
|
||||
inputField.privateImeOptions != null
|
||||
&& inputField.privateImeOptions.equals("io.github.sspanak.tt9.addword=true")
|
||||
) {
|
||||
mAddingWord = true;
|
||||
// mAddingSkipInput = true;
|
||||
// Log.d("onStartInput", "ADDING WORD");
|
||||
mKeyMode = MODE_TEXT;
|
||||
mKeyMode = T9Preferences.MODE_ABC;
|
||||
} else {
|
||||
mAddingWord = false;
|
||||
// Log.d("onStartInput", "not adding word");
|
||||
prevword = (String)settings[4];
|
||||
if (prevword != null) {
|
||||
String prevword = prefs.getLastWord();
|
||||
if (prevword != "") {
|
||||
onText(prevword);
|
||||
db.storeSettingString(SETTING.LAST_WORD, null);
|
||||
prefs.setLastWord("");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -402,7 +389,7 @@ public class TraditionalT9 extends InputMethodService implements
|
|||
super.onFinishInput();
|
||||
// Log.d("onFinishInput", "When is this called?");
|
||||
if (mEditing == EDITING || mEditing == EDITING_NOSHOW) {
|
||||
db.storeSettingInt(SETTING.LAST_LANG, mLang.id);
|
||||
prefs.setInputLanguage(mLang.id);
|
||||
commitTyped();
|
||||
finish();
|
||||
}
|
||||
|
|
@ -452,7 +439,7 @@ public class TraditionalT9 extends InputMethodService implements
|
|||
int candidatesStart, int candidatesEnd) {
|
||||
super.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd, candidatesStart,
|
||||
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
|
||||
// clear whatever candidate text we have.
|
||||
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;
|
||||
if (KeyMap.keyMapping.containsKey(keyCode)) {
|
||||
key = new KeyEvent(event.getDownTime(), event.getEventTime(), event.getAction(),
|
||||
KeyMap.keyMapping.get(keyCode), event.getRepeatCount(), event.getMetaState(),
|
||||
event.getDeviceId(), 0, event.getFlags());
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
private boolean onKeyDown_(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 onKeyDown(int keyCode, KeyEvent event) {
|
||||
// Log.d("onKeyDown", "Key: " + event + " repeat?: " +
|
||||
// event.getRepeatCount() + " long-time: " + event.isLongPress());
|
||||
if (mEditing == NON_EDIT) {
|
||||
|
|
@ -516,7 +499,7 @@ public class TraditionalT9 extends InputMethodService implements
|
|||
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
|
||||
// of let the application do the delete itself.
|
||||
// if (mComposing.length() > 0) {
|
||||
|
|
@ -530,7 +513,7 @@ public class TraditionalT9 extends InputMethodService implements
|
|||
if (event.getRepeatCount() != 0) {
|
||||
return true;
|
||||
}
|
||||
if (mKeyMode == MODE_TEXT) {
|
||||
if (mKeyMode == T9Preferences.MODE_ABC) {
|
||||
t9releasehandler.removeCallbacks(mt9release);
|
||||
}
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK) {
|
||||
|
|
@ -564,20 +547,6 @@ public class TraditionalT9 extends InputMethodService implements
|
|||
commitReset();
|
||||
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() {
|
||||
Intent awintent = new Intent(this, TraditionalT9Settings.class);
|
||||
|
|
@ -607,7 +576,7 @@ public class TraditionalT9 extends InputMethodService implements
|
|||
}
|
||||
return true;
|
||||
} else if (keyCode == KeyEvent.KEYCODE_STAR) {
|
||||
if (mKeyMode != MODE_NUM) {
|
||||
if (mKeyMode != T9Preferences.MODE_123) {
|
||||
if (mLangsAvailable.length > 1) {
|
||||
nextLang();
|
||||
} else {
|
||||
|
|
@ -620,7 +589,7 @@ public class TraditionalT9 extends InputMethodService implements
|
|||
if (interfacehandler != null) {
|
||||
interfacehandler.setPressed(keyCode, false);
|
||||
}
|
||||
if (mKeyMode == MODE_LANG) {
|
||||
if (mKeyMode == T9Preferences.MODE_PREDICTIVE) {
|
||||
if (mWordFound) {
|
||||
showAddWord();
|
||||
} else {
|
||||
|
|
@ -637,13 +606,13 @@ public class TraditionalT9 extends InputMethodService implements
|
|||
return true;
|
||||
}
|
||||
if (keyCode >= KeyEvent.KEYCODE_0 && keyCode <= KeyEvent.KEYCODE_9) {
|
||||
if (mKeyMode == MODE_LANG) {
|
||||
if (mKeyMode == T9Preferences.MODE_PREDICTIVE) {
|
||||
commitTyped();
|
||||
onText(String.valueOf(keyCode - KeyEvent.KEYCODE_0));
|
||||
} else if (mKeyMode == MODE_TEXT) {
|
||||
} else if (mKeyMode == T9Preferences.MODE_ABC) {
|
||||
commitReset();
|
||||
onText(String.valueOf(keyCode - KeyEvent.KEYCODE_0));
|
||||
} else if (mKeyMode == MODE_NUM) {
|
||||
} else if (mKeyMode == T9Preferences.MODE_123) {
|
||||
if (keyCode == KeyEvent.KEYCODE_0) {
|
||||
onText("+");
|
||||
}
|
||||
|
|
@ -651,8 +620,13 @@ public class TraditionalT9 extends InputMethodService implements
|
|||
}
|
||||
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?: " +
|
||||
// event.getRepeatCount());
|
||||
if (mEditing == NON_EDIT) {
|
||||
|
|
@ -700,7 +674,7 @@ public class TraditionalT9 extends InputMethodService implements
|
|||
}
|
||||
|
||||
return false;
|
||||
} else if (keyCode == KeyEvent.KEYCODE_DEL) {
|
||||
} else if (keyCode == prefs.getKeyBackspace()) {
|
||||
return true;
|
||||
} else if (keyCode == KeyEvent.KEYCODE_ENTER) {
|
||||
return false;
|
||||
|
|
@ -743,20 +717,6 @@ public class TraditionalT9 extends InputMethodService implements
|
|||
commitReset();
|
||||
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.
|
||||
|
|
@ -780,7 +740,7 @@ public class TraditionalT9 extends InputMethodService implements
|
|||
*/
|
||||
private void updateShiftKeyState(EditorInfo attr) {
|
||||
// Log.d("updateShift", "CM start: " + mCapsMode);
|
||||
if (attr != null && mCapsMode != CAPS_ALL) {
|
||||
if (attr != null && mCapsMode != T9Preferences.CASE_UPPER) {
|
||||
int caps = 0;
|
||||
if (attr.inputType != InputType.TYPE_NULL) {
|
||||
caps = currentInputConnection.getCursorCapsMode(attr.inputType);
|
||||
|
|
@ -788,13 +748,13 @@ public class TraditionalT9 extends InputMethodService implements
|
|||
// mInputView.setShifted(mCapsLock || caps != 0);
|
||||
// Log.d("updateShift", "caps: " + caps);
|
||||
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) {
|
||||
mCapsMode = CAPS_SINGLE;
|
||||
mCapsMode = T9Preferences.CASE_CAPITALIZE;
|
||||
} else if ((caps & TextUtils.CAP_MODE_WORDS) == TextUtils.CAP_MODE_WORDS) {
|
||||
mCapsMode = CAPS_SINGLE;
|
||||
mCapsMode = T9Preferences.CASE_CAPITALIZE;
|
||||
} else {
|
||||
mCapsMode = CAPS_OFF;
|
||||
mCapsMode = T9Preferences.CASE_LOWER;
|
||||
}
|
||||
updateKeyMode();
|
||||
}
|
||||
|
|
@ -820,11 +780,11 @@ public class TraditionalT9 extends InputMethodService implements
|
|||
// Log.d("OnKey", "pri: " + keyCode);
|
||||
// Log.d("onKey", "START Cm: " + mCapsMode);
|
||||
// HANDLE SPECIAL KEYS
|
||||
if (keyCode == KeyEvent.KEYCODE_DEL) {
|
||||
if (keyCode == prefs.getKeyBackspace()) {
|
||||
handleBackspace();
|
||||
} else if (keyCode == KeyEvent.KEYCODE_STAR) {
|
||||
// change case
|
||||
if (mKeyMode == MODE_NUM) {
|
||||
if (mKeyMode == T9Preferences.MODE_123) {
|
||||
handleCharacter(KeyEvent.KEYCODE_STAR);
|
||||
} else {
|
||||
handleShift();
|
||||
|
|
@ -878,14 +838,14 @@ public class TraditionalT9 extends InputMethodService implements
|
|||
}
|
||||
if (mComposing.length() > 0) {
|
||||
switch (mKeyMode) {
|
||||
case MODE_LANG:
|
||||
case T9Preferences.MODE_PREDICTIVE:
|
||||
commitTyped();
|
||||
break;
|
||||
case MODE_TEXT:
|
||||
case T9Preferences.MODE_ABC:
|
||||
commitTyped();
|
||||
charReset();
|
||||
break;
|
||||
case MODE_NUM:
|
||||
case T9Preferences.MODE_123:
|
||||
// shouldn't happen
|
||||
break;
|
||||
}
|
||||
|
|
@ -902,7 +862,7 @@ public class TraditionalT9 extends InputMethodService implements
|
|||
updateCandidates(false);
|
||||
}
|
||||
private void updateCandidates(boolean backspace) {
|
||||
if (mKeyMode == MODE_LANG) {
|
||||
if (mKeyMode == T9Preferences.MODE_PREDICTIVE) {
|
||||
int len = mComposingI.length();
|
||||
if (len > 0) {
|
||||
if (mComposingI.charAt(len - 1) == '1') {
|
||||
|
|
@ -964,7 +924,7 @@ public class TraditionalT9 extends InputMethodService implements
|
|||
interfacehandler.showNotFound(false);
|
||||
}
|
||||
}
|
||||
} else if (mKeyMode == MODE_TEXT) {
|
||||
} else if (mKeyMode == T9Preferences.MODE_ABC) {
|
||||
if (mComposing.length() > 0) {
|
||||
//Log.d("updateCandidates", "Previous: " + mComposing.toString());
|
||||
mSuggestionStrings.clear();
|
||||
|
|
@ -993,7 +953,7 @@ public class TraditionalT9 extends InputMethodService implements
|
|||
private void handleBackspace() {
|
||||
final int length = mComposing.length();
|
||||
final int length2 = mComposingI.length();
|
||||
if (mKeyMode == MODE_TEXT) {
|
||||
if (mKeyMode == T9Preferences.MODE_ABC) {
|
||||
charReset();
|
||||
setCandidatesViewShown(false);
|
||||
}
|
||||
|
|
@ -1028,7 +988,7 @@ public class TraditionalT9 extends InputMethodService implements
|
|||
updateCandidates();
|
||||
} else {
|
||||
mPreviousWord = "";
|
||||
keyDownUp(KeyEvent.KEYCODE_DEL);
|
||||
keyDownUp(prefs.getKeyBackspace());
|
||||
}
|
||||
updateShiftKeyState(getCurrentInputEditorInfo());
|
||||
// Log.d("handleBS", "Cm: " + mCapsMode);
|
||||
|
|
@ -1044,7 +1004,7 @@ public class TraditionalT9 extends InputMethodService implements
|
|||
mCapsMode++;
|
||||
}
|
||||
|
||||
if (mKeyMode == MODE_LANG && mComposing.length() > 0) {
|
||||
if (mKeyMode == T9Preferences.MODE_PREDICTIVE && mComposing.length() > 0) {
|
||||
updateCandidates();
|
||||
currentInputConnection.setComposingText(mComposing, 1);
|
||||
}
|
||||
|
|
@ -1058,7 +1018,7 @@ public class TraditionalT9 extends InputMethodService implements
|
|||
*/
|
||||
private void handleCharacter(int keyCode) {
|
||||
switch (mKeyMode) {
|
||||
case MODE_LANG:
|
||||
case T9Preferences.MODE_PREDICTIVE:
|
||||
// it begins
|
||||
if (keyCode == KeyEvent.KEYCODE_POUND || keyCode == KeyEvent.KEYCODE_0) {
|
||||
if (mComposing.length() > 0) {
|
||||
|
|
@ -1074,7 +1034,7 @@ public class TraditionalT9 extends InputMethodService implements
|
|||
}
|
||||
break;
|
||||
|
||||
case MODE_TEXT:
|
||||
case T9Preferences.MODE_ABC:
|
||||
t9releasehandler.removeCallbacks(mt9release);
|
||||
if (keyCode == KeyEvent.KEYCODE_POUND) {
|
||||
keyCode = 10;
|
||||
|
|
@ -1102,7 +1062,7 @@ public class TraditionalT9 extends InputMethodService implements
|
|||
|
||||
// start at caps if CapMode
|
||||
// Log.d("handleChar", "Cm: " + mCapsMode);
|
||||
if (mCharIndex == 0 && mCapsMode != CAPS_OFF) {
|
||||
if (mCharIndex == 0 && mCapsMode != T9Preferences.CASE_LOWER) {
|
||||
mCharIndex = CharMap.T9CAPSTART[mLang.index][keyCode];
|
||||
}
|
||||
|
||||
|
|
@ -1120,15 +1080,15 @@ public class TraditionalT9 extends InputMethodService implements
|
|||
t9releasehandler.postDelayed(mt9release, T9DELAY);
|
||||
if (newChar) {
|
||||
// consume single caps
|
||||
if (mCapsMode == CAPS_SINGLE) {
|
||||
mCapsMode = CAPS_OFF;
|
||||
if (mCapsMode == T9Preferences.CASE_CAPITALIZE) {
|
||||
mCapsMode = T9Preferences.CASE_LOWER;
|
||||
}
|
||||
}
|
||||
updateCandidates();
|
||||
updateShiftKeyState(getCurrentInputEditorInfo());
|
||||
break;
|
||||
|
||||
case MODE_NUM:
|
||||
case T9Preferences.MODE_123:
|
||||
if (keyCode == KeyEvent.KEYCODE_POUND) {
|
||||
onText("#");
|
||||
} else if (keyCode == KeyEvent.KEYCODE_STAR) {
|
||||
|
|
@ -1173,7 +1133,7 @@ public class TraditionalT9 extends InputMethodService implements
|
|||
mIgnoreDPADKeyUp = false;
|
||||
return super.onKeyUp(keyCode, event);
|
||||
} else {
|
||||
if (mKeyMode != MODE_NUM && mComposing.length() > 0) {
|
||||
if (mKeyMode != T9Preferences.MODE_123 && mComposing.length() > 0) {
|
||||
if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
|
||||
mCandidateView.scrollToSuggestion(1);
|
||||
if (mSuggestionStrings.size() > mCandidateView.mSelectedIndex)
|
||||
|
|
@ -1185,9 +1145,9 @@ public class TraditionalT9 extends InputMethodService implements
|
|||
currentInputConnection.setComposingText(mSuggestionStrings.get(mCandidateView.mSelectedIndex), 1);
|
||||
return true;
|
||||
} else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
|
||||
if (mKeyMode == MODE_LANG) {
|
||||
if (mKeyMode == T9Preferences.MODE_PREDICTIVE) {
|
||||
commitTyped();
|
||||
} else if (mKeyMode == MODE_TEXT) {
|
||||
} else if (mKeyMode == T9Preferences.MODE_ABC) {
|
||||
commitReset();
|
||||
}
|
||||
// getCurrentInputConnection().sendKeyEvent(mDPADkeyEvent);
|
||||
|
|
@ -1219,8 +1179,8 @@ public class TraditionalT9 extends InputMethodService implements
|
|||
private void commitReset() {
|
||||
commitTyped();
|
||||
charReset();
|
||||
if (mCapsMode == CAPS_SINGLE) {
|
||||
mCapsMode = CAPS_OFF;
|
||||
if (mCapsMode == T9Preferences.CASE_CAPITALIZE) {
|
||||
mCapsMode = T9Preferences.CASE_LOWER;
|
||||
}
|
||||
// Log.d("commitReset", "CM pre: " + mCapsMode);
|
||||
updateShiftKeyState(getCurrentInputEditorInfo());
|
||||
|
|
@ -1260,7 +1220,7 @@ public class TraditionalT9 extends InputMethodService implements
|
|||
|
||||
private void resetKeyMode() {
|
||||
charReset();
|
||||
if (mKeyMode != MODE_NUM) {
|
||||
if (mKeyMode != T9Preferences.MODE_123) {
|
||||
commitTyped();
|
||||
}
|
||||
mComposing.setLength(0);
|
||||
|
|
@ -1276,12 +1236,12 @@ public class TraditionalT9 extends InputMethodService implements
|
|||
int icon = 0;
|
||||
|
||||
switch (mKeyMode) {
|
||||
case MODE_TEXT:
|
||||
case T9Preferences.MODE_ABC:
|
||||
interfacehandler.showHold(false);
|
||||
icon = LangHelper.ICONMAP[mLang.index][mKeyMode][mCapsMode];
|
||||
break;
|
||||
case MODE_LANG:
|
||||
if (!db.ready) {
|
||||
case T9Preferences.MODE_PREDICTIVE:
|
||||
if (!db.isReady()) {
|
||||
if (!mGaveUpdateWarn) {
|
||||
Toast.makeText(this, getText(R.string.updating_database_unavailable), Toast.LENGTH_LONG).show();
|
||||
mGaveUpdateWarn = true;
|
||||
|
|
@ -1302,7 +1262,7 @@ public class TraditionalT9 extends InputMethodService implements
|
|||
// + mCapsMode);
|
||||
icon = LangHelper.ICONMAP[mLang.index][mKeyMode][mCapsMode];
|
||||
break;
|
||||
case MODE_NUM:
|
||||
case T9Preferences.MODE_123:
|
||||
interfacehandler.showHold(false);
|
||||
icon = R.drawable.ime_number;
|
||||
break;
|
||||
|
|
@ -1329,14 +1289,14 @@ public class TraditionalT9 extends InputMethodService implements
|
|||
// mSuggestionStrings.get(mCandidateView.mSelectedIndex));
|
||||
// get and commit selected suggestion
|
||||
ic.commitText(mSuggestionStrings.get(mCandidateView.mSelectedIndex), 1);
|
||||
if (mKeyMode == MODE_LANG) {
|
||||
if (mKeyMode == T9Preferences.MODE_PREDICTIVE) {
|
||||
// update freq
|
||||
db.incrementWord(mSuggestionInts.get(mCandidateView.mSelectedIndex));
|
||||
}
|
||||
} else {
|
||||
// commit suggestion index
|
||||
ic.commitText(mSuggestionStrings.get(index), 1);
|
||||
if (mKeyMode == MODE_LANG) {
|
||||
if (mKeyMode == T9Preferences.MODE_PREDICTIVE) {
|
||||
db.incrementWord(mSuggestionInts.get(index));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,15 +7,12 @@ import android.app.ProgressDialog;
|
|||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.database.Cursor;
|
||||
import android.database.DatabaseUtils.InsertHelper;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.os.Handler;
|
||||
import android.os.SystemClock;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
|
@ -27,39 +24,32 @@ import android.widget.Toast;
|
|||
import com.stackoverflow.answer.UnicodeBOMInputStream;
|
||||
|
||||
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.Setting;
|
||||
import io.github.sspanak.tt9.settings.SettingAdapter;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.Closeable;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.AbstractList;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
public class TraditionalT9Settings extends ListActivity implements
|
||||
DialogInterface.OnCancelListener {
|
||||
public class TraditionalT9Settings extends ListActivity implements DialogInterface.OnCancelListener {
|
||||
|
||||
AsyncTask<String, Integer, Reply> task = null;
|
||||
final static String dictname = "%s-utf8.txt";
|
||||
final static String userdictname = "user.%s.dict";
|
||||
final static String backupname = "t9backup.txt";
|
||||
final static String sddir = "tt9";
|
||||
|
||||
final int BACKUP_Q_LIMIT = 1000;
|
||||
|
|
@ -136,13 +126,11 @@ public class TraditionalT9Settings extends ListActivity implements
|
|||
long size;
|
||||
long pos;
|
||||
boolean internal;
|
||||
boolean restore;
|
||||
String[] dicts;
|
||||
LANGUAGE[] mSupportedLanguages;
|
||||
|
||||
LoadDictTask(int msgid, boolean intern, boolean restorebackup, LANGUAGE[] supportedLanguages) {
|
||||
LoadDictTask(int msgid, boolean intern, LANGUAGE[] supportedLanguages) {
|
||||
internal = intern;
|
||||
restore = restorebackup;
|
||||
|
||||
int suplanglen = supportedLanguages.length;
|
||||
dicts = new String[suplanglen];
|
||||
|
|
@ -160,7 +148,7 @@ public class TraditionalT9Settings extends ListActivity implements
|
|||
pd.setOnCancelListener(TraditionalT9Settings.this);
|
||||
}
|
||||
|
||||
private long getDictSizes(boolean internal, boolean restore, String[] dicts) {
|
||||
private long getDictSizes(boolean internal, String[] dicts) {
|
||||
if (internal) {
|
||||
InputStream input;
|
||||
Properties props = new Properties();
|
||||
|
|
@ -183,32 +171,22 @@ public class TraditionalT9Settings extends ListActivity implements
|
|||
}
|
||||
} else {
|
||||
File backupfile = new File(Environment.getExternalStorageDirectory(), sddir);
|
||||
if (restore) {
|
||||
// using external backup
|
||||
backupfile = new File(backupfile, backupname);
|
||||
if (backupfile.exists() && backupfile.isFile()) {
|
||||
return backupfile.length();
|
||||
long total = 0;
|
||||
File f;
|
||||
for (String dict : dicts) {
|
||||
f = new File(backupfile, dict);
|
||||
if (f.exists() && f.isFile()) {
|
||||
total = total + f.length();
|
||||
} 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() {
|
||||
size = getDictSizes(internal, restore, dicts);
|
||||
size = getDictSizes(internal, dicts);
|
||||
pos = 0;
|
||||
if ( size >= 0 ) {
|
||||
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
|
||||
|
|
@ -247,64 +225,45 @@ public class TraditionalT9Settings extends ListActivity implements
|
|||
InputStream dictstream = null;
|
||||
|
||||
try {
|
||||
if (restore) {
|
||||
try {
|
||||
dictstream = new FileInputStream(new File(
|
||||
new File(Environment.getExternalStorageDirectory(), sddir), backupname));
|
||||
reply = processFile(dictstream, reply, db, LANGUAGE.NONE, backupname);
|
||||
} catch (FileNotFoundException e) {
|
||||
reply.status = false;
|
||||
reply.forceMsg("Backup file not found: " + e.getMessage());
|
||||
closeStream(dictstream, reply); // this is silly but it
|
||||
return reply; // 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.
|
||||
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);
|
||||
} 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) {
|
||||
// too many errors, bail
|
||||
|
|
@ -489,190 +448,7 @@ public class TraditionalT9Settings extends ListActivity implements
|
|||
|
||||
@Override
|
||||
protected void onPostExecute(Reply result) {
|
||||
if (restore) {
|
||||
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);
|
||||
finishAndShowError(pd, result, R.string.pref_load_title);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -684,10 +460,14 @@ public class TraditionalT9Settings extends ListActivity implements
|
|||
// http://stackoverflow.com/questions/7645880/listview-with-onitemclicklistener-android
|
||||
|
||||
// get settings
|
||||
Object[] settings = T9DB.getInstance(this).getSettings(new SETTING[]
|
||||
// Order should be based on SETTING.sqOrder
|
||||
// "MODE_NOTIFY", "SPACE_ZERO" and "KEY_REMAP" are no longer in use; delete in #7
|
||||
{SETTING.INPUT_MODE, SETTING.LANG_SUPPORT, SETTING.MODE_NOTIFY, SETTING.KEY_REMAP, SETTING.SPACE_ZERO});
|
||||
T9Preferences prefs = new T9Preferences(this);
|
||||
Object[] settings = {
|
||||
prefs.getInputMode(),
|
||||
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;
|
||||
try {
|
||||
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"))
|
||||
openHelp();
|
||||
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"))
|
||||
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 if (s.id.equals("reloadKeys")) {
|
||||
int msg = KeyMap.setKeys();
|
||||
if (msg != 0) {
|
||||
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
preloader(R.string.pref_loadinguserdict, false);
|
||||
else
|
||||
s.clicked(mContext);
|
||||
}
|
||||
|
|
@ -732,81 +500,17 @@ public class TraditionalT9Settings extends ListActivity implements
|
|||
startActivity(i);
|
||||
}
|
||||
|
||||
// LoadDictTask(int msgid, boolean intern, boolean restorebackup, CheckBoxPreference setting)
|
||||
private void preloader(int msgid, boolean internal, boolean restorebackup) {
|
||||
private void preloader(int msgid, boolean internal) {
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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) {
|
||||
showErrorDialog(new AlertDialog.Builder(this), title, msg);
|
||||
|
|
@ -836,125 +540,6 @@ public class TraditionalT9Settings extends ListActivity implements
|
|||
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
|
||||
public void onCancel(DialogInterface dint) {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
package io.github.sspanak.tt9;
|
||||
package io.github.sspanak.tt9.db;
|
||||
|
||||
public class DBException extends Exception {
|
||||
private static final long serialVersionUID = 376752656441823823L;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package io.github.sspanak.tt9;
|
||||
package io.github.sspanak.tt9.db;
|
||||
|
||||
import android.app.IntentService;
|
||||
import android.app.Notification;
|
||||
|
|
@ -11,6 +11,8 @@ import android.os.Handler;
|
|||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import io.github.sspanak.tt9.R;
|
||||
|
||||
public class DBUpdateService extends IntentService {
|
||||
private static final int UPDATING_NOTIFICATION_ID = 9640142;
|
||||
|
||||
56
src/io/github/sspanak/tt9/db/DatabaseHelper.java
Normal file
56
src/io/github/sspanak/tt9/db/DatabaseHelper.java
Normal 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.");
|
||||
}
|
||||
}
|
||||
299
src/io/github/sspanak/tt9/db/T9DB.java
Normal file
299
src/io/github/sspanak/tt9/db/T9DB.java
Normal 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()));
|
||||
}
|
||||
}
|
||||
109
src/io/github/sspanak/tt9/preferences/T9Preferences.java
Normal file
109
src/io/github/sspanak/tt9/preferences/T9Preferences.java
Normal 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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -4,10 +4,10 @@ import android.app.AlertDialog;
|
|||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
|
||||
import io.github.sspanak.tt9.R;
|
||||
import io.github.sspanak.tt9.T9DB;
|
||||
import io.github.sspanak.tt9.T9DB.DBSettings.SETTING;
|
||||
import io.github.sspanak.tt9.preferences.T9Preferences;
|
||||
|
||||
public class SettingList extends Setting {
|
||||
String[] entries;
|
||||
|
|
@ -56,7 +56,13 @@ public class SettingList extends Setting {
|
|||
@Override
|
||||
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];
|
||||
dialog.dismiss();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,8 +8,7 @@ import android.widget.TextView;
|
|||
|
||||
import io.github.sspanak.tt9.LangHelper;
|
||||
import io.github.sspanak.tt9.R;
|
||||
import io.github.sspanak.tt9.T9DB;
|
||||
import io.github.sspanak.tt9.T9DB.DBSettings.SETTING;
|
||||
import io.github.sspanak.tt9.preferences.T9Preferences;
|
||||
|
||||
public class SettingMultiList extends SettingList {
|
||||
boolean[] selectedEntries = new boolean[0];
|
||||
|
|
@ -38,7 +37,9 @@ public class SettingMultiList extends SettingList {
|
|||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
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();
|
||||
dialog.dismiss();
|
||||
((TextView)view.findViewById(R.id.summary)).setText(summary);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue