From 98518a3277e3083a4bef9888042571f2dbe22b15 Mon Sep 17 00:00:00 2001 From: Thad Hughes Date: Sun, 15 Jan 2012 16:07:26 -0800 Subject: [PATCH] UI changes, (experiments), Arabic rendering changes, changing the way dictionaries are indexed (listed), new type of TokenRow (to distinguish major from minor entries). --- AndroidManifest.xml | 2 +- res/drawable/token_row_drawable.xml | 6 + res/raw/dictionary_info.txt | 62 +++++++ res/values/languages.xml | 67 +++++++ res/values/strings.xml | 9 +- res/values/themeLight.xml | 6 + .../dictionary/DictionaryActivity.java | 52 ++++-- .../dictionary/DictionaryEditActivity.java | 19 +- ...tionaryConfig.java => DictionaryInfo.java} | 27 ++- ...ty.java => DictionaryManagerActivity.java} | 25 ++- .../dictionary/PreferenceActivity.java | 3 + .../android/dictionary/QuickDicConfig.java | 19 +- .../android/dictionary/engine/Index.java | 62 +------ .../android/dictionary/engine/Language.java | 171 ++++++++++-------- .../android/dictionary/engine/RowBase.java | 7 +- .../android/dictionary/engine/TokenRow.java | 8 +- 16 files changed, 341 insertions(+), 204 deletions(-) create mode 100644 res/drawable/token_row_drawable.xml create mode 100644 res/raw/dictionary_info.txt create mode 100644 res/values/languages.xml rename src/com/hughes/android/dictionary/{DictionaryConfig.java => DictionaryInfo.java} (51%) rename src/com/hughes/android/dictionary/{DictionaryListActivity.java => DictionaryManagerActivity.java} (91%) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 871f3b5..5496c76 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -43,7 +43,7 @@ - diff --git a/res/drawable/token_row_drawable.xml b/res/drawable/token_row_drawable.xml new file mode 100644 index 0000000..fc581cb --- /dev/null +++ b/res/drawable/token_row_drawable.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/res/raw/dictionary_info.txt b/res/raw/dictionary_info.txt new file mode 100644 index 0000000..9d32762 --- /dev/null +++ b/res/raw/dictionary_info.txt @@ -0,0 +1,62 @@ +# LANG_1 %LANG_2 FILENAME FILESIZE NUM_MAIN_WORDS_1 NUM_MAIN_WORDS_2 NUM_ALL_WORDS_1 NUM_ALL_WORDS_2 +DE EN DE-EN_chemnitz_enwiktionary.quickdic 50207808 262726 119111 262726 119111 +EN af EN-AF_enwiktionary.quickdic 524028 4864 2757 4864 2757 +EN ar EN-AR_enwiktionary.quickdic 4012835 16522 23357 16522 23357 +EN be EN-BE_enwiktionary.quickdic 711212 4481 5325 4481 5325 +EN bg EN-BG_enwiktionary.quickdic 12913407 19530 54724 19530 54724 +EN bn EN-BN_enwiktionary.quickdic 709473 4479 1867 4479 1867 +EN bo EN-BO_enwiktionary.quickdic 82371 767 424 767 424 +EN bs EN-BS_enwiktionary.quickdic 532886 5031 2947 5031 2947 +EN ca EN-CA_enwiktionary.quickdic 8983841 16662 50054 16662 50054 +EN ci EN-CI_enwiktionary.quickdic 749721 5884 3779 5884 3779 +EN cs EN-CS_enwiktionary.quickdic 5819580 24351 23142 24351 23142 +EN da EN-DA_enwiktionary.quickdic 5279379 17460 30597 17460 30597 +EN el EN-EL_enwiktionary.quickdic 12106155 24424 48789 24424 48789 +EN eo EN-EO_enwiktionary.quickdic 11600016 16907 100765 16907 100765 +EN es EN-ES_enwiktionary.quickdic 66315884 37676 240847 37676 240847 +EN et EN-ET_enwiktionary.quickdic 1447664 9818 7697 9818 7697 +EN fa EN-FA_enwiktionary.quickdic 2266032 11292 11565 11292 11565 +EN fi EN-FI_enwiktionary.quickdic 24362077 51150 126697 51150 126697 +EN FR EN-FR_enwiktionary.quickdic 37999114 44540 208469 44540 208469 +EN ga EN-GA_enwiktionary.quickdic 2146063 11870 8649 11870 8649 +EN iw EN-HE_enwiktionary.quickdic 3655803 15703 18853 15703 18853 +EN hi EN-HI_enwiktionary.quickdic 1578419 8494 5673 8494 5673 +EN hr EN-HR_enwiktionary.quickdic 11994054 21291 45181 21291 45181 +EN hu EN-HU_enwiktionary.quickdic 6648136 22700 36369 22700 36369 +EN hy EN-HY_enwiktionary.quickdic 4635747 16697 20671 16697 20671 +EN in EN-ID_enwiktionary.quickdic 855320 6919 4384 6919 4384 +EN is EN-IS_enwiktionary.quickdic 3539828 16781 16584 16781 16584 +EN IT EN-IT_enwiktionary.quickdic 66258996 82955 458534 82955 458534 +EN ja EN-JA_enwiktionary.quickdic 14160233 32116 74666 32116 74666 +EN ko EN-KO_enwiktionary.quickdic 3798948 18780 24154 18780 24154 +EN ku EN-KU_enwiktionary.quickdic 950213 5853 5266 5853 5266 +EN la EN-LA_enwiktionary.quickdic 97577095 22517 515727 22517 515727 +EN lt EN-LT_enwiktionary.quickdic 2947045 7970 18146 7970 18146 +EN lv EN-LV_enwiktionary.quickdic 895714 6533 4709 6533 4709 +EN mi EN-MI_enwiktionary.quickdic 122547 1316 637 1316 637 +EN mn EN-MN_enwiktionary.quickdic 299861 2238 2295 2238 2295 +EN ms EN-MS_enwiktionary.quickdic 664757 5026 3483 5026 3483 +EN ne EN-NE_enwiktionary.quickdic 55115 494 305 494 305 +EN nl EN-NL_enwiktionary.quickdic 12882227 32296 65344 32296 65344 +EN no EN-NO_enwiktionary.quickdic 3793263 16740 19398 16740 19398 +EN pa EN-PA_enwiktionary.quickdic 79473 721 418 721 418 +EN pl EN-PL_enwiktionary.quickdic 8265972 22429 42112 22429 42112 +EN pt EN-PT_enwiktionary.quickdic 10595199 21951 49188 21951 49188 +EN ro EN-RO_enwiktionary.quickdic 4100603 17827 18709 17827 18709 +EN ru EN-RU_enwiktionary.quickdic 13197074 37230 70018 37230 70018 +EN sa EN-SA_enwiktionary.quickdic 1514085 7958 3667 7958 3667 +EN sk EN-SK_enwiktionary.quickdic 1022589 7895 5040 7895 5040 +EN so EN-SO_enwiktionary.quickdic 29794 326 169 326 169 +EN sq EN-SQ_enwiktionary.quickdic 820891 6153 4112 6153 4112 +EN sr EN-SR_enwiktionary.quickdic 1363176 8002 9261 8002 9261 +EN sv EN-SV_enwiktionary.quickdic 15275508 26455 98329 26455 98329 +EN sw EN-SW_enwiktionary.quickdic 1192717 7864 3526 7864 3526 +EN tg EN-TG_enwiktionary.quickdic 326521 2034 1788 2034 1788 +EN th EN-TH_enwiktionary.quickdic 1394582 7647 8766 7647 8766 +EN tr EN-TR_enwiktionary.quickdic 3420079 15760 17996 15760 17996 +EN uk EN-UK_enwiktionary.quickdic 1332001 7512 9448 7512 9448 +EN vi EN-VI_enwiktionary.quickdic 1225627 9074 4767 9074 4767 +EN ji EN-YI_enwiktionary.quickdic 421569 2955 2807 2955 2807 +EN zh EN-ZH_enwiktionary.quickdic 13270167 28253 73329 28253 73329 +EN zu EN-ZU_enwiktionary.quickdic 41213 484 224 484 224 +EN haw EN-haw_enwiktionary.quickdic 228760 1791 961 1791 961 diff --git a/res/values/languages.xml b/res/values/languages.xml new file mode 100644 index 0000000..80b2fcb --- /dev/null +++ b/res/values/languages.xml @@ -0,0 +1,67 @@ + + + + Afrikaans + Albanian + Arabic + Armenian + Belarusian + Bengali + Bosnian + Bulgarian + Catalan + Croatian + Czech + Chinese|Mandarin|Cantonese + Danish + Dutch + English + Esperanto + Estonian + Finnish + French + German + Greek + Hawaiian + Hebrew + Hindi + Hungarian + Icelandic + Indonesian + Irish + Italian + Latin + Latvian + Lithuanian + Japanese + Korean + Kurdish + Malay + Maori + Mongolian + Nepali + Norwegian + Persian + Polish + Portuguese + Punjabi + Romanian + Russian + Sanskrit + Serbian + Slovak + Somali + Spanish + Swahili + Swedish + Tajik + Thai + Tibetan + Turkish + Ukrainian + Vietnamese + Welsh + Yiddish + Zulu + + \ No newline at end of file diff --git a/res/values/strings.xml b/res/values/strings.xml index eded208..3a90f6b 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -4,16 +4,11 @@ QuickDic - Dictionary list + Dictionary manager - Add dictionary - Add default dictionaries - Remove all dictionaries - Edit dictionary config - Delete dictionary + Dictionary config Move to top - New dictionary %s (not on device) 3.0.1h diff --git a/res/values/themeLight.xml b/res/values/themeLight.xml index 59f3d41..2b75000 100644 --- a/res/values/themeLight.xml +++ b/res/values/themeLight.xml @@ -9,7 +9,13 @@ #FFFFFF #000000 + --> + + + diff --git a/src/com/hughes/android/dictionary/DictionaryActivity.java b/src/com/hughes/android/dictionary/DictionaryActivity.java index d217c81..a3cc390 100644 --- a/src/com/hughes/android/dictionary/DictionaryActivity.java +++ b/src/com/hughes/android/dictionary/DictionaryActivity.java @@ -66,6 +66,7 @@ import android.widget.Toast; import com.hughes.android.dictionary.engine.Dictionary; import com.hughes.android.dictionary.engine.Index; +import com.hughes.android.dictionary.engine.Language; import com.hughes.android.dictionary.engine.PairEntry; import com.hughes.android.dictionary.engine.PairEntry.Pair; import com.hughes.android.dictionary.engine.RowBase; @@ -116,11 +117,19 @@ public class DictionaryActivity extends ListActivity { public static Intent getIntent(final Context context, final int dictIndex, final int indexIndex, final String searchToken) { setDictionaryPrefs(context, dictIndex, indexIndex, searchToken); - final Intent intent = new Intent(); intent.setClassName(DictionaryActivity.class.getPackage().getName(), DictionaryActivity.class.getName()); return intent; } + + // TODO: Can we trigger an App restart when the preferences activity gets opened? + // TODO: fix these... + + @Override + protected void onSaveInstanceState(final Bundle outState) { + super.onSaveInstanceState(outState); + setDictionaryPrefs(this, dictIndex, indexIndex, searchText.getText().toString()); + } public static void setDictionaryPrefs(final Context context, final int dictIndex, final int indexIndex, final String searchToken) { @@ -130,9 +139,10 @@ public class DictionaryActivity extends ListActivity { prefs.putString(C.SEARCH_TOKEN, searchToken); prefs.commit(); } - + public static void clearDictionaryPrefs(final Context context) { - final SharedPreferences.Editor prefs = PreferenceManager.getDefaultSharedPreferences(context).edit(); + final SharedPreferences.Editor prefs = PreferenceManager + .getDefaultSharedPreferences(context).edit(); prefs.remove(C.DICT_INDEX); prefs.remove(C.INDEX_INDEX); prefs.remove(C.SEARCH_TOKEN); @@ -153,7 +163,7 @@ public class DictionaryActivity extends ListActivity { QuickDicConfig quickDicConfig = PersistentObjectCache.init( this).read(C.DICTIONARY_CONFIGS, QuickDicConfig.class); dictIndex = prefs.getInt(C.DICT_INDEX, 0) ; - final DictionaryConfig dictionaryConfig = quickDicConfig.dictionaryConfigs.get(dictIndex); + final DictionaryInfo dictionaryConfig = quickDicConfig.dictionaryConfigs.get(dictIndex); this.setTitle("QuickDic: " + dictionaryConfig.name); dictRaf = new RandomAccessFile(dictionaryConfig.localFile, "r"); dictionary = new Dictionary(dictRaf); @@ -168,7 +178,7 @@ public class DictionaryActivity extends ListActivity { dictRaf = null; } Toast.makeText(this, getString(R.string.invalidDictionary, "", e.getMessage()), Toast.LENGTH_LONG); - startActivity(DictionaryEditActivity.getIntent(dictIndex)); + startActivity(DictionaryManagerActivity.getIntent(this)); finish(); return; } @@ -196,7 +206,7 @@ public class DictionaryActivity extends ListActivity { }); for (final Index index : dictionary.indices) { - Log.d(LOG, "Starting collator load for lang=" + index.sortLanguage.getSymbol()); + Log.d(LOG, "Starting collator load for lang=" + index.sortLanguage.getIsoCode()); final com.ibm.icu.text.Collator c = index.sortLanguage.getCollator(); if (c.compare("pre-print", "preppy") >= 0) { @@ -295,6 +305,11 @@ public class DictionaryActivity extends ListActivity { @Override protected void onResume() { super.onResume(); + if (PreferenceActivity.prefsMightHaveChanged) { + PreferenceActivity.prefsMightHaveChanged = false; + finish(); + startActivity(getIntent()); + } } @Override @@ -402,6 +417,7 @@ public class DictionaryActivity extends ListActivity { final MenuItem preferences = menu.add(getString(R.string.preferences)); preferences.setOnMenuItemClickListener(new OnMenuItemClickListener() { public boolean onMenuItemClick(final MenuItem menuItem) { + PreferenceActivity.prefsMightHaveChanged = true; startActivity(new Intent(DictionaryActivity.this, PreferenceActivity.class)); return false; @@ -413,7 +429,7 @@ public class DictionaryActivity extends ListActivity { final MenuItem dictionaryList = menu.add(getString(R.string.dictionaryList)); dictionaryList.setOnMenuItemClickListener(new OnMenuItemClickListener() { public boolean onMenuItemClick(final MenuItem menuItem) { - startActivity(DictionaryListActivity.getIntent(DictionaryActivity.this)); + startActivity(DictionaryManagerActivity.getIntent(DictionaryActivity.this)); finish(); return false; } @@ -545,14 +561,12 @@ public class DictionaryActivity extends ListActivity { return true; } if (keyCode == KeyEvent.KEYCODE_BACK) { - Log.d(LOG, "Clearing dictionary prefs."); - DictionaryActivity.clearDictionaryPrefs(this); } if (keyCode == KeyEvent.KEYCODE_ENTER) { -// Log.d(LOG, "Trying to hide soft keyboard."); -// final InputMethodManager manager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); -// manager.hideSoftInputFromWindow(searchText, InputMethodManager.SHOW_FORCED); - + Log.d(LOG, "Trying to hide soft keyboard."); + final InputMethodManager inputManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + inputManager.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); + return true; } return super.onKeyDown(keyCode, event); } @@ -720,7 +734,7 @@ public class DictionaryActivity extends ListActivity { // TODO: color words by gender final Pair pair = entry.pairs.get(r); - final String col1Text = index.swapPairEntries ? pair.lang2 : pair.lang1; + final String col1Text = Language.fixBidiText(index.swapPairEntries ? pair.lang2 : pair.lang1); column1.setText(col1Text, TextView.BufferType.SPANNABLE); final Spannable col1Spannable = (Spannable) column1.getText(); @@ -732,7 +746,8 @@ public class DictionaryActivity extends ListActivity { startPos += token.length(); } - final String col2Text = index.swapPairEntries ? pair.lang1 : pair.lang2; + String col2Text = index.swapPairEntries ? pair.lang1 : pair.lang2; + col2Text = Language.fixBidiText(col2Text); column2.setText(col2Text, TextView.BufferType.NORMAL); column1.setTextSize(TypedValue.COMPLEX_UNIT_SP, fontSizeSp); @@ -745,8 +760,13 @@ public class DictionaryActivity extends ListActivity { } private View getView(TokenRow row, ViewGroup parent) { - final TextView textView = new TextView(parent.getContext()); + final Context context = parent.getContext(); + final TextView textView = new TextView(context); textView.setText(row.getToken()); + textView.setBackgroundResource(R.drawable.token_row_drawable); + // Doesn't work: + //textView.setTextColor(android.R.color.secondary_text_light); + textView.setTextAppearance(context, R.style.Theme_Light_Token); textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 5 * fontSizeSp / 4); return textView; } diff --git a/src/com/hughes/android/dictionary/DictionaryEditActivity.java b/src/com/hughes/android/dictionary/DictionaryEditActivity.java index 12d3ae2..7d8e1a8 100644 --- a/src/com/hughes/android/dictionary/DictionaryEditActivity.java +++ b/src/com/hughes/android/dictionary/DictionaryEditActivity.java @@ -32,6 +32,7 @@ import android.view.MenuItem; import android.view.View; import android.view.MenuItem.OnMenuItemClickListener; import android.view.View.OnClickListener; +import android.view.WindowManager; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; @@ -45,7 +46,7 @@ public class DictionaryEditActivity extends Activity { static final String LOG = "QuickDic"; QuickDicConfig quickDicConfig; - private DictionaryConfig dictionaryConfig; + private DictionaryInfo dictionaryConfig; final Handler uiHandler = new Handler(); @@ -127,6 +128,9 @@ public class DictionaryEditActivity extends Activity { startActivity(intent); } }); + + // Don't show the keyboard when this opens up: + getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); } @@ -170,7 +174,7 @@ public class DictionaryEditActivity extends Activity { final MenuItem dictionaryList = menu.add(getString(R.string.dictionaryList)); dictionaryList.setOnMenuItemClickListener(new OnMenuItemClickListener() { public boolean onMenuItemClick(final MenuItem menuItem) { - startActivity(DictionaryListActivity.getIntent(DictionaryEditActivity.this)); + startActivity(DictionaryManagerActivity.getIntent(DictionaryEditActivity.this)); return false; } }); @@ -225,20 +229,11 @@ public class DictionaryEditActivity extends Activity { } static void startDownloadDictActivity(final Context context, - final DictionaryConfig dictionaryConfig) { + final DictionaryInfo dictionaryConfig) { final Intent intent = new Intent(context, DownloadActivity.class); intent.putExtra(DownloadActivity.SOURCE, dictionaryConfig.downloadUrl); intent.putExtra(DownloadActivity.DEST, dictionaryConfig.localFile + ".zip"); context.startActivity(intent); } - @Override - public boolean onKeyDown(final int keyCode, final KeyEvent event) { - if (keyCode == KeyEvent.KEYCODE_BACK) { - Log.d(LOG, "Clearing dictionary prefs."); - DictionaryActivity.clearDictionaryPrefs(this); - } - return super.onKeyDown(keyCode, event); - } - } diff --git a/src/com/hughes/android/dictionary/DictionaryConfig.java b/src/com/hughes/android/dictionary/DictionaryInfo.java similarity index 51% rename from src/com/hughes/android/dictionary/DictionaryConfig.java rename to src/com/hughes/android/dictionary/DictionaryInfo.java index 5dcd03d..088dcf6 100644 --- a/src/com/hughes/android/dictionary/DictionaryConfig.java +++ b/src/com/hughes/android/dictionary/DictionaryInfo.java @@ -16,21 +16,32 @@ package com.hughes.android.dictionary; import java.io.Serializable; -public class DictionaryConfig implements Serializable { +public class DictionaryInfo implements Serializable { - private static final long serialVersionUID = -6850863377577700387L; - - String name = ""; - String localFile = "/sdcard/quickDic/"; - String downloadUrl = "http://"; + private static final long serialVersionUID = -6850863377577700388L; - int openIndex = 0; - String openWord = ""; + // Stuff populated from the text file. + public final String[] langIsos = new String[2]; + public String uncompressedFilename; + public long uncompressedSize; + public final int[] allTokenCounts = new int[2]; + public final int[] mainTokenCounts = new int[2]; + + String name; // Determined at runtime based on locale on device--user editable. + String localFile; // Determined based on device's Environment. + String downloadUrl; @Override public String toString() { return name; } + + public String toTabSeparatedString() { + return String.format("%s\t%s\t%s\t%d\t%d\t%d\t%d\t%d", langIsos[0], + langIsos[1], uncompressedFilename, uncompressedSize, + mainTokenCounts[0], mainTokenCounts[1], allTokenCounts[0], + allTokenCounts[1]); + } } diff --git a/src/com/hughes/android/dictionary/DictionaryListActivity.java b/src/com/hughes/android/dictionary/DictionaryManagerActivity.java similarity index 91% rename from src/com/hughes/android/dictionary/DictionaryListActivity.java rename to src/com/hughes/android/dictionary/DictionaryManagerActivity.java index 1c4015e..b1d2398 100644 --- a/src/com/hughes/android/dictionary/DictionaryListActivity.java +++ b/src/com/hughes/android/dictionary/DictionaryManagerActivity.java @@ -44,7 +44,7 @@ import android.widget.AdapterView.OnItemClickListener; import com.hughes.android.util.PersistentObjectCache; -public class DictionaryListActivity extends ListActivity { +public class DictionaryManagerActivity extends ListActivity { static final String LOG = "QuickDic"; @@ -104,6 +104,12 @@ public class DictionaryListActivity extends ListActivity { protected void onResume() { super.onResume(); + if (PreferenceActivity.prefsMightHaveChanged) { + PreferenceActivity.prefsMightHaveChanged = false; + finish(); + startActivity(getIntent()); + } + final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); if (prefs.contains(C.DICT_INDEX) && prefs.contains(C.INDEX_INDEX)) { Log.d(LOG, "Skipping Dictionary List, going straight to dictionary."); @@ -122,7 +128,7 @@ public class DictionaryListActivity extends ListActivity { // Replace <-> with - if (quickDicConfig.currentVersion < 5) { - for (final DictionaryConfig config : quickDicConfig.dictionaryConfigs) { + for (final DictionaryInfo config : quickDicConfig.dictionaryConfigs) { config.name = config.name.replace("<->", "-"); } } @@ -140,7 +146,7 @@ public class DictionaryListActivity extends ListActivity { final MenuItem newDictionaryMenuItem = menu.add(R.string.addDictionary); newDictionaryMenuItem.setOnMenuItemClickListener(new OnMenuItemClickListener() { public boolean onMenuItemClick(final MenuItem menuItem) { - final DictionaryConfig dictionaryConfig = new DictionaryConfig(); + final DictionaryInfo dictionaryConfig = new DictionaryInfo(); dictionaryConfig.name = getString(R.string.newDictionary); quickDicConfig.dictionaryConfigs.add(0, dictionaryConfig); dictionaryConfigsChanged(); @@ -179,7 +185,8 @@ public class DictionaryListActivity extends ListActivity { final MenuItem preferences = menu.add(getString(R.string.preferences)); preferences.setOnMenuItemClickListener(new OnMenuItemClickListener() { public boolean onMenuItemClick(final MenuItem menuItem) { - startActivity(new Intent(DictionaryListActivity.this, + PreferenceActivity.prefsMightHaveChanged = true; + startActivity(new Intent(DictionaryManagerActivity.this, PreferenceActivity.class)); return false; } @@ -210,7 +217,7 @@ public class DictionaryListActivity extends ListActivity { moveToTopMenuItem.setOnMenuItemClickListener(new OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { - final DictionaryConfig dictionaryConfig = quickDicConfig.dictionaryConfigs.remove(adapterContextMenuInfo.position); + final DictionaryInfo dictionaryConfig = quickDicConfig.dictionaryConfigs.remove(adapterContextMenuInfo.position); quickDicConfig.dictionaryConfigs.add(0, dictionaryConfig); dictionaryConfigsChanged(); return true; @@ -243,7 +250,7 @@ public class DictionaryListActivity extends ListActivity { } @Override - public DictionaryConfig getItem(int position) { + public DictionaryInfo getItem(int position) { return quickDicConfig.dictionaryConfigs.get(position); } @@ -254,7 +261,7 @@ public class DictionaryListActivity extends ListActivity { @Override public View getView(int position, View convertView, ViewGroup parent) { - final DictionaryConfig dictionaryConfig = getItem(position); + final DictionaryInfo dictionaryConfig = getItem(position); final TableLayout tableLayout = new TableLayout(parent.getContext()); final TextView view = new TextView(parent.getContext()); @@ -275,8 +282,8 @@ public class DictionaryListActivity extends ListActivity { public static Intent getIntent(final Context context) { DictionaryActivity.clearDictionaryPrefs(context); final Intent intent = new Intent(); - intent.setClassName(DictionaryListActivity.class.getPackage().getName(), - DictionaryListActivity.class.getName()); + intent.setClassName(DictionaryManagerActivity.class.getPackage().getName(), + DictionaryManagerActivity.class.getName()); return intent; } diff --git a/src/com/hughes/android/dictionary/PreferenceActivity.java b/src/com/hughes/android/dictionary/PreferenceActivity.java index 858be19..2ac2118 100644 --- a/src/com/hughes/android/dictionary/PreferenceActivity.java +++ b/src/com/hughes/android/dictionary/PreferenceActivity.java @@ -17,6 +17,9 @@ package com.hughes.android.dictionary; import android.os.Bundle; public class PreferenceActivity extends android.preference.PreferenceActivity { + + static boolean prefsMightHaveChanged = false; + @Override public void onCreate(Bundle savedInstanceState) { ((DictionaryApplication)getApplication()).applyTheme(this); diff --git a/src/com/hughes/android/dictionary/QuickDicConfig.java b/src/com/hughes/android/dictionary/QuickDicConfig.java index 1923ccc..414ae2d 100644 --- a/src/com/hughes/android/dictionary/QuickDicConfig.java +++ b/src/com/hughes/android/dictionary/QuickDicConfig.java @@ -18,6 +18,8 @@ import java.io.Serializable; import java.util.ArrayList; import java.util.List; +import android.os.Environment; + import com.hughes.android.dictionary.engine.Language; public final class QuickDicConfig implements Serializable { @@ -27,7 +29,7 @@ public final class QuickDicConfig implements Serializable { // Just increment this to have them all update... static final int LATEST_VERSION = 6; - final List dictionaryConfigs = new ArrayList(); + final List dictionaryConfigs = new ArrayList(); int currentVersion = LATEST_VERSION; public QuickDicConfig() { @@ -35,30 +37,31 @@ public final class QuickDicConfig implements Serializable { } static final String BASE_URL = "http://quickdic-dictionary.googlecode.com/files/"; - static final String VERSION_SUFFIX = "v002"; + // TODO: read this from a resource file.... + public void addDefaultDictionaries() { { - final DictionaryConfig config = new DictionaryConfig(); + final DictionaryInfo config = new DictionaryInfo(); config.name = "German-English"; config.downloadUrl = String.format("%sDE-EN_chemnitz_enwiktionary.quickdic.%s.zip", BASE_URL, VERSION_SUFFIX); - config.localFile = "/sdcard/quickDic/DE-EN_chemnitz_enwiktionary.quickdic"; + config.localFile = String.format("%s/quickDic/DE-EN_chemnitz_enwiktionary.quickdic", Environment.getExternalStorageDirectory()); addOrReplace(config); } - for (final String iso : Language.isoCodeToWikiName.keySet()) { + for (final String iso : Language.isoCodeToResourceName.keySet()) { if (iso.equals("EN") || iso.equals("DE")) { continue; } - final DictionaryConfig config = new DictionaryConfig(); + final DictionaryInfo config = new DictionaryInfo(); config.name = String.format("English-%s", Language.isoCodeToWikiName.get(iso)); config.downloadUrl = String.format("%sEN-%s_enwiktionary.quickdic.%s.zip", BASE_URL, iso, VERSION_SUFFIX); - config.localFile = String.format("/sdcard/quickDic/EN-%s_enwiktionary.quickdic", iso); + config.localFile = String.format("%s/quickDic/EN-%s_enwiktionary.quickdic", Environment.getExternalStorageDirectory(), iso); addOrReplace(config); } } - private void addOrReplace(final DictionaryConfig dictionaryConfig) { + private void addOrReplace(final DictionaryInfo dictionaryConfig) { for (int i = 0; i < dictionaryConfigs.size(); ++i) { if (dictionaryConfigs.get(i).name.equals(dictionaryConfig.name)) { dictionaryConfigs.set(i, dictionaryConfig); diff --git a/src/com/hughes/android/dictionary/engine/Index.java b/src/com/hughes/android/dictionary/engine/Index.java index 8e9ca96..39fcab5 100644 --- a/src/com/hughes/android/dictionary/engine/Index.java +++ b/src/com/hughes/android/dictionary/engine/Index.java @@ -100,7 +100,7 @@ public final class Index implements RAFSerializable { public void write(final RandomAccessFile raf) throws IOException { raf.writeUTF(shortName); raf.writeUTF(longName); - raf.writeUTF(sortLanguage.getSymbol()); + raf.writeUTF(sortLanguage.getIsoCode()); raf.writeUTF(normalizerRules); raf.writeBoolean(swapPairEntries); RAFList.write(raf, sortedIndexEntries, IndexEntry.SERIALIZER); @@ -205,52 +205,7 @@ public final class Index implements RAFSerializable { result = windBackCase(sortedIndexEntries.get(result).normalizedToken(), result, interrupted); return sortedIndexEntries.get(result); } - - public static final class SearchResult { - public final IndexEntry insertionPoint; - public final IndexEntry longestPrefix; - public final String longestPrefixString; - public final boolean success; - - public SearchResult(IndexEntry insertionPoint, IndexEntry longestPrefix, - String longestPrefixString, boolean success) { - this.insertionPoint = insertionPoint; - this.longestPrefix = longestPrefix; - this.longestPrefixString = longestPrefixString; - this.success = success; - } - @Override - public String toString() { - return String.format("inerstionPoint=%s,longestPrefix=%s,longestPrefixString=%s,success=%b", insertionPoint.toString(), longestPrefix.toString(), longestPrefixString, success); - } - } - -// public SearchResult findLongestSubstring(String token, final AtomicBoolean interrupted) { -// token = normalizer.transliterate(token); -// if (token.length() == 0) { -// return new SearchResult(sortedIndexEntries.get(0), sortedIndexEntries.get(0), "", true); -// } -// IndexEntry insertionPoint = null; -// IndexEntry result = null; -// boolean unmodified = true; -// while (!interrupted.get() && token.length() > 0) { -// result = findInsertionPoint(token, interrupted); -// if (result == null) { -// return null; -// } -// if (unmodified) { -// insertionPoint = result; -// } -// if (result.normalizedToken(normalizer).startsWith(token)) { -// return new SearchResult(insertionPoint, result, token, unmodified); -// } -// unmodified = false; -// token = token.substring(0, token.length() - 1); -// } -// return new SearchResult(insertionPoint, sortedIndexEntries.get(0), "", false); -// } - private final int windBackCase(final String token, int result, final AtomicBoolean interrupted) { while (result > 0 && sortedIndexEntries.get(result - 1).normalizedToken().equals(token)) { --result; @@ -261,19 +216,4 @@ public final class Index implements RAFSerializable { return result; } - /* - public int tokenRowBinarySearch(final int rowIndex) { - int start = 0; - int end = sortedIndexEntries.size(); - while (start < end) { - final int mid = (start + end) / 2; - final int midRowIndex = sortedIndexEntries.get(mid).startRow; - if (midRowIndex == rowIndex) { - return mid; - } - if () - } - } - */ - } \ No newline at end of file diff --git a/src/com/hughes/android/dictionary/engine/Language.java b/src/com/hughes/android/dictionary/engine/Language.java index 84a625a..fcf74f1 100644 --- a/src/com/hughes/android/dictionary/engine/Language.java +++ b/src/com/hughes/android/dictionary/engine/Language.java @@ -17,89 +17,92 @@ package com.hughes.android.dictionary.engine; import java.util.LinkedHashMap; import java.util.Locale; import java.util.Map; +import java.util.regex.Pattern; +import com.hughes.android.dictionary.R; import com.ibm.icu.text.Collator; public class Language { - public static final Map isoCodeToWikiName = new LinkedHashMap(); + public static final Map isoCodeToResourceId = new LinkedHashMap(); static { - isoCodeToWikiName.put("AF", "Afrikaans"); - isoCodeToWikiName.put("SQ", "Albanian"); - isoCodeToWikiName.put("AR", "Arabic"); - isoCodeToWikiName.put("HY", "Armenian"); - isoCodeToWikiName.put("BE", "Belarusian"); - isoCodeToWikiName.put("BN", "Bengali"); - isoCodeToWikiName.put("BS", "Bosnian"); - isoCodeToWikiName.put("BG", "Bulgarian"); - isoCodeToWikiName.put("CA", "Catalan"); - isoCodeToWikiName.put("HR", "Croatian"); - isoCodeToWikiName.put("CS", "Czech"); - isoCodeToWikiName.put("ZH", "Chinese|Mandarin|Cantonese"); - isoCodeToWikiName.put("DA", "Danish"); - isoCodeToWikiName.put("NL", "Dutch"); - isoCodeToWikiName.put("EN", "English"); - isoCodeToWikiName.put("EO", "Esperanto"); - isoCodeToWikiName.put("ET", "Estonian"); - isoCodeToWikiName.put("FI", "Finnish"); - isoCodeToWikiName.put("FR", "French"); - isoCodeToWikiName.put("DE", "German"); - isoCodeToWikiName.put("EL", "Greek"); - isoCodeToWikiName.put("haw", "Hawaiian"); - isoCodeToWikiName.put("HE", "Hebrew"); - isoCodeToWikiName.put("HI", "Hindi"); - isoCodeToWikiName.put("HU", "Hungarian"); - isoCodeToWikiName.put("IS", "Icelandic"); - isoCodeToWikiName.put("ID", "Indonesian"); - isoCodeToWikiName.put("GA", "Irish"); - isoCodeToWikiName.put("IT", "Italian"); - isoCodeToWikiName.put("LA", "Latin"); - isoCodeToWikiName.put("LV", "Latvian"); - isoCodeToWikiName.put("LT", "Lithuanian"); - isoCodeToWikiName.put("JA", "Japanese"); - isoCodeToWikiName.put("KO", "Korean"); - isoCodeToWikiName.put("KU", "Kurdish"); - isoCodeToWikiName.put("MS", "Malay"); - isoCodeToWikiName.put("MI", "Maori"); - isoCodeToWikiName.put("MN", "Mongolian"); - isoCodeToWikiName.put("NE", "Nepali"); - isoCodeToWikiName.put("NO", "Norwegian"); - isoCodeToWikiName.put("FA", "Persian"); - isoCodeToWikiName.put("PL", "Polish"); - isoCodeToWikiName.put("PT", "Portuguese"); - isoCodeToWikiName.put("PA", "Punjabi"); - isoCodeToWikiName.put("RO", "Romanian"); - isoCodeToWikiName.put("RU", "Russian"); - isoCodeToWikiName.put("SA", "Sanskrit"); - isoCodeToWikiName.put("SR", "Serbian"); - isoCodeToWikiName.put("SK", "Slovak"); - isoCodeToWikiName.put("SO", "Somali"); - isoCodeToWikiName.put("ES", "Spanish"); - isoCodeToWikiName.put("SW", "Swahili"); - isoCodeToWikiName.put("SV", "Swedish"); - isoCodeToWikiName.put("TG", "Tajik"); - isoCodeToWikiName.put("TH", "Thai"); - isoCodeToWikiName.put("BO", "Tibetan"); - isoCodeToWikiName.put("TR", "Turkish"); - isoCodeToWikiName.put("UK", "Ukrainian"); - isoCodeToWikiName.put("VI", "Vietnamese"); - isoCodeToWikiName.put("CI", "Welsh"); - isoCodeToWikiName.put("YI", "Yiddish"); - isoCodeToWikiName.put("ZU", "Zulu"); + isoCodeToResourceId.put("AF", R.string.AF); + isoCodeToResourceId.put("SQ", R.string.SQ); + isoCodeToResourceId.put("AR", R.string.AR); + isoCodeToResourceId.put("HY", R.string.HY); + isoCodeToResourceId.put("BE", R.string.BE); + isoCodeToResourceId.put("BN", R.string.BN); + isoCodeToResourceId.put("BS", R.string.BS); + isoCodeToResourceId.put("BG", R.string.BG); + isoCodeToResourceId.put("CA", R.string.CA); + isoCodeToResourceId.put("HR", R.string.HR); + isoCodeToResourceId.put("CS", R.string.CS); + isoCodeToResourceId.put("ZH", R.string.ZH); + isoCodeToResourceId.put("DA", R.string.DA); + isoCodeToResourceId.put("NL", R.string.NL); + isoCodeToResourceId.put("EN", R.string.EN); + isoCodeToResourceId.put("EO", R.string.EO); + isoCodeToResourceId.put("ET", R.string.ET); + isoCodeToResourceId.put("FI", R.string.FI); + isoCodeToResourceId.put("FR", R.string.FR); + isoCodeToResourceId.put("DE", R.string.DE); + isoCodeToResourceId.put("EL", R.string.EL); + isoCodeToResourceId.put("haw", R.string.haw); + isoCodeToResourceId.put("HE", R.string.HE); + isoCodeToResourceId.put("HI", R.string.HI); + isoCodeToResourceId.put("HU", R.string.HU); + isoCodeToResourceId.put("IS", R.string.IS); + isoCodeToResourceId.put("ID", R.string.ID); + isoCodeToResourceId.put("GA", R.string.GA); + isoCodeToResourceId.put("IT", R.string.IT); + isoCodeToResourceId.put("LA", R.string.LA); + isoCodeToResourceId.put("LV", R.string.LV); + isoCodeToResourceId.put("LT", R.string.LT); + isoCodeToResourceId.put("JA", R.string.JA); + isoCodeToResourceId.put("KO", R.string.KO); + isoCodeToResourceId.put("KU", R.string.KU); + isoCodeToResourceId.put("MS", R.string.MS); + isoCodeToResourceId.put("MI", R.string.MI); + isoCodeToResourceId.put("MN", R.string.MN); + isoCodeToResourceId.put("NE", R.string.NE); + isoCodeToResourceId.put("NO", R.string.NO); + isoCodeToResourceId.put("FA", R.string.FA); + isoCodeToResourceId.put("PL", R.string.PL); + isoCodeToResourceId.put("PT", R.string.PT); + isoCodeToResourceId.put("PA", R.string.PA); + isoCodeToResourceId.put("RO", R.string.RO); + isoCodeToResourceId.put("RU", R.string.RU); + isoCodeToResourceId.put("SA", R.string.SA); + isoCodeToResourceId.put("SR", R.string.SR); + isoCodeToResourceId.put("SK", R.string.SK); + isoCodeToResourceId.put("SO", R.string.SO); + isoCodeToResourceId.put("ES", R.string.ES); + isoCodeToResourceId.put("SW", R.string.SW); + isoCodeToResourceId.put("SV", R.string.SV); + isoCodeToResourceId.put("TG", R.string.TG); + isoCodeToResourceId.put("TH", R.string.TH); + isoCodeToResourceId.put("BO", R.string.BO); + isoCodeToResourceId.put("TR", R.string.TR); + isoCodeToResourceId.put("UK", R.string.UK); + isoCodeToResourceId.put("VI", R.string.VI); + isoCodeToResourceId.put("CI", R.string.CI); + isoCodeToResourceId.put("YI", R.string.YI); + isoCodeToResourceId.put("ZU", R.string.ZU); } - static final Map symbolToLangauge = new LinkedHashMap(); - final String symbol; + private static final Map registry = new LinkedHashMap(); + + final String isoCode; final Locale locale; private Collator collator; - public Language(final Locale locale) { - this.symbol = locale.getLanguage(); + private Language(final Locale locale, final String isoCode) { this.locale = locale; + this.isoCode = isoCode; - symbolToLangauge.put(symbol.toLowerCase(), this); + registry.put(isoCode.toLowerCase(), this); } @Override @@ -107,8 +110,8 @@ public class Language { return locale.toString(); } - public String getSymbol() { - return symbol; + public String getIsoCode() { + return isoCode; } public synchronized Collator getCollator() { @@ -122,13 +125,27 @@ public class Language { public String getDefaultNormalizerRules() { return ":: Any-Latin; ' ' > ; :: Lower; :: NFD; :: [:Nonspacing Mark:] Remove; :: NFC ;"; } + + /** + * A practical pattern to identify strong RTL characters. This pattern is not + * completely correct according to the Unicode standard. It is simplified for + * performance and small code size. + */ + private static final String rtlChars = + "\u0591-\u07FF\uFB1D-\uFDFD\uFE70-\uFEFC"; + private static final Pattern RTL_TOKEN = Pattern.compile("[" + rtlChars + "]+"); + + public static String fixBidiText(final String text) { + return RTL_TOKEN.matcher(text).replaceAll("\u200e $0 \u200e"); + } + // ---------------------------------------------------------------- - public static final Language en = new Language(Locale.ENGLISH); - public static final Language fr = new Language(Locale.FRENCH); - public static final Language it = new Language(Locale.ITALIAN); + public static final Language en = new Language(Locale.ENGLISH, "EN"); + public static final Language fr = new Language(Locale.FRENCH, "FR"); + public static final Language it = new Language(Locale.ITALIAN, "IT"); - public static final Language de = new Language(Locale.GERMAN) { + public static final Language de = new Language(Locale.GERMAN, "DE") { @Override public String getDefaultNormalizerRules() { return ":: Lower; 'ae' > 'ä'; 'oe' > 'ö'; 'ue' > 'ü'; 'ß' > 'ss'; "; @@ -137,10 +154,10 @@ public class Language { // ---------------------------------------------------------------- - public static synchronized Language lookup(final String symbol) { - Language lang = symbolToLangauge.get(symbol.toLowerCase()); + public static synchronized Language lookup(final String isoCode) { + Language lang = registry.get(isoCode.toLowerCase()); if (lang == null) { - lang = new Language(new Locale(symbol)); + lang = new Language(new Locale(isoCode), isoCode); } return lang; } diff --git a/src/com/hughes/android/dictionary/engine/RowBase.java b/src/com/hughes/android/dictionary/engine/RowBase.java index 0914174..569fc00 100644 --- a/src/com/hughes/android/dictionary/engine/RowBase.java +++ b/src/com/hughes/android/dictionary/engine/RowBase.java @@ -113,8 +113,8 @@ public abstract class RowBase extends IndexedObject { final byte rowType = raf.readByte(); if (rowType == 0) { return new PairEntry.Row(raf, listIndex, index); - } else if (rowType == 1) { - return new TokenRow(raf, listIndex, index); + } else if (rowType == 1 || rowType == 3) { + return new TokenRow(raf, listIndex, index, rowType == 1); } else if (rowType == 2) { return new TextEntry.Row(raf, listIndex, index); } @@ -126,7 +126,8 @@ public abstract class RowBase extends IndexedObject { if (t instanceof PairEntry.Row) { raf.writeByte(0); } else if (t instanceof TokenRow) { - raf.writeByte(1); + final TokenRow tokenRow = (TokenRow) t; + raf.writeByte(tokenRow.hasMainEntry ? 1 : 3); } else if (t instanceof TextEntry.Row) { raf.writeByte(2); } diff --git a/src/com/hughes/android/dictionary/engine/TokenRow.java b/src/com/hughes/android/dictionary/engine/TokenRow.java index 247436b..8579761 100644 --- a/src/com/hughes/android/dictionary/engine/TokenRow.java +++ b/src/com/hughes/android/dictionary/engine/TokenRow.java @@ -20,12 +20,16 @@ import java.io.RandomAccessFile; public class TokenRow extends RowBase { - TokenRow(final RandomAccessFile raf, final int thisRowIndex, final Index index) throws IOException { + final boolean hasMainEntry; + + TokenRow(final RandomAccessFile raf, final int thisRowIndex, final Index index, final boolean hasMainEntry) throws IOException { super(raf, thisRowIndex, index); + this.hasMainEntry = hasMainEntry; } - TokenRow(final int referenceIndex, final int thisRowIndex, final Index index) { + TokenRow(final int referenceIndex, final int thisRowIndex, final Index index, final boolean hasMainEntry) { super(referenceIndex, thisRowIndex, index); + this.hasMainEntry = hasMainEntry; } public String toString() { -- 2.43.0