From: Thad Hughes Date: Fri, 5 Nov 2010 19:25:08 +0000 (-0700) Subject: go X-Git-Url: https://gitweb.fperrin.net/?a=commitdiff_plain;h=4b031e28dc75b564ae405ea4ce6d323dff75898c;p=Dictionary.git go --- diff --git a/americanFlag.jpg b/americanFlag.jpg deleted file mode 100755 index 8d85b25..0000000 Binary files a/americanFlag.jpg and /dev/null differ diff --git a/flags.xcf b/flags.xcf deleted file mode 100755 index b322c28..0000000 Binary files a/flags.xcf and /dev/null differ diff --git a/germanFlag.jpg b/germanFlag.jpg deleted file mode 100755 index b796c87..0000000 Binary files a/germanFlag.jpg and /dev/null differ diff --git a/res/drawable/icon.png b/res/drawable/icon.png index 17ccb38..99ae67f 100644 Binary files a/res/drawable/icon.png and b/res/drawable/icon.png differ diff --git a/res/layout/about_activity.xml b/res/layout/about_activity.xml index bf7759c..47b8d62 100755 --- a/res/layout/about_activity.xml +++ b/res/layout/about_activity.xml @@ -63,6 +63,23 @@ android:clickable="true" android:layout_gravity="left" android:paddingBottom="10dip"/> + + + + + diff --git a/res/layout/edit_activity.xml b/res/layout/edit_activity.xml index d2d6e06..8c42824 100755 --- a/res/layout/edit_activity.xml +++ b/res/layout/edit_activity.xml @@ -35,18 +35,6 @@ android:layout_width="fill_parent" android:layout_height="wrap_content" /> - - - - QuickDic\nby Thad Hughes + Dictionary list Add dictionary @@ -12,8 +13,25 @@ Delete dictionary Move up New Dictionary + + + + Thanks for updating QuickDic. +

New features: +

    +
  • Easily work with multiple dictionaries. +
  • Wiktionary-based dictionaries for French, Italian, German, Spanish, Swedish. +
  • Create your own dictionaries. Look in Menu...About for details. +
+

The new version requires you to re-download any dictionaries you want.
+ + +]]> + + Edit dictionary config Dictionary name Dictionary download URL Dictionary info: @@ -24,6 +42,7 @@ Entries: %d Tokens: %d Rows: %d + Search Text @@ -39,7 +58,9 @@ Thad Hughes If you\'re using QuickDic, I\'d love to hear from you. Please send comments, suggestions, bug reports, or just a quick hello to: thad.hughes\+quickdic@gmail.com - + For more information, including how to make your own QuickDic dictionaries, see: + http://sites.google.com/site/quickdic/home + Downloading, %d of %d bytes. Download finished, %d bytes downloaded. @@ -54,7 +75,7 @@ wordListFile Word list file The local file where the word list will be appended. - /sdcard/wordList.txt + /sdcard/quickDic/wordList.txt saveOnlyFirstSubentry Save only first sub-entry @@ -64,16 +85,6 @@ Show \'clear search text\' button Show the button to clear the search text. You can also just move focus away from search text and start typing. - dictFile - Dictionary file - The local filename where the dictionary is stored (and downloaded to). - /sdcard/de-en.dict - - dictFetchUrl - Dictionary fetch URL - URL to use to download the dictionary from the Internet. - http://www.stanford.edu/~egirard/dict/de-en.dict - vibrateOnFailedSearch Vibrate on failed search. Vibrate the phone when invalid search text is entered. diff --git a/src/com/hughes/android/dictionary/C.java b/src/com/hughes/android/dictionary/C.java index 21fbfed..ce929a1 100644 --- a/src/com/hughes/android/dictionary/C.java +++ b/src/com/hughes/android/dictionary/C.java @@ -8,5 +8,7 @@ public class C { static final String INDEX_INDEX = "indexIndex"; static final String SEARCH_TOKEN = "searchToken"; + public static final String INTRO_MESSAGE_SHOWN = "introMessageShown"; + } diff --git a/src/com/hughes/android/dictionary/DictionaryActivity.java b/src/com/hughes/android/dictionary/DictionaryActivity.java index c8850ff..afca2b5 100644 --- a/src/com/hughes/android/dictionary/DictionaryActivity.java +++ b/src/com/hughes/android/dictionary/DictionaryActivity.java @@ -1,7 +1,12 @@ package com.hughes.android.dictionary; import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; import java.io.RandomAccessFile; +import java.text.SimpleDateFormat; +import java.util.Date; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicBoolean; @@ -15,22 +20,33 @@ import android.os.Bundle; import android.os.Handler; import android.os.Vibrator; import android.preference.PreferenceManager; +import android.text.ClipboardManager; import android.text.Editable; import android.text.Spannable; import android.text.TextWatcher; import android.text.style.StyleSpan; import android.util.Log; +import android.view.ContextMenu; +import android.view.KeyEvent; +import android.view.Menu; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; +import android.view.ContextMenu.ContextMenuInfo; +import android.view.MenuItem.OnMenuItemClickListener; import android.view.View.OnClickListener; import android.view.inputmethod.InputMethodManager; +import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.EditText; import android.widget.ListAdapter; +import android.widget.ListView; import android.widget.TableLayout; import android.widget.TableRow; import android.widget.TextView; +import android.widget.Toast; +import android.widget.AdapterView.AdapterContextMenuInfo; import com.hughes.android.dictionary.engine.Dictionary; import com.hughes.android.dictionary.engine.Index; @@ -45,6 +61,7 @@ public class DictionaryActivity extends ListActivity { static final int VIBRATE_MILLIS = 100; + int dictIndex = 0; RandomAccessFile dictRaf = null; Dictionary dictionary = null; int indexIndex = 0; @@ -70,35 +87,49 @@ public class DictionaryActivity extends ListActivity { public DictionaryActivity() { } - public static Intent getIntent(final int dictIndex, final int indexIndex, final String searchToken) { + 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()); - intent.putExtra(C.DICT_INDEX, dictIndex); - intent.putExtra(C.INDEX_INDEX, indexIndex); - intent.putExtra(C.SEARCH_TOKEN, searchToken); return intent; } + public static void setDictionaryPrefs(final Context context, + final int dictIndex, final int indexIndex, final String searchToken) { + final SharedPreferences.Editor prefs = PreferenceManager.getDefaultSharedPreferences(context).edit(); + prefs.putInt(C.DICT_INDEX, dictIndex); + prefs.putInt(C.INDEX_INDEX, indexIndex); + prefs.putString(C.SEARCH_TOKEN, searchToken); + prefs.commit(); + } + + public static void clearDictionaryPrefs(final Context context) { + final SharedPreferences.Editor prefs = PreferenceManager.getDefaultSharedPreferences(context).edit(); + prefs.remove(C.DICT_INDEX); + prefs.remove(C.INDEX_INDEX); + prefs.remove(C.SEARCH_TOKEN); + prefs.commit(); + } + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); - PersistentObjectCache.init(this); - QuickDicConfig quickDicConfig = PersistentObjectCache.init( - this).read(C.DICTIONARY_CONFIGS, QuickDicConfig.class); - - final Intent intent = getIntent(); - - final int dictIndex = intent.getIntExtra(C.DICT_INDEX, 0); try { + PersistentObjectCache.init(this); + 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); dictRaf = new RandomAccessFile(dictionaryConfig.localFile, "r"); dictionary = new Dictionary(dictRaf); } catch (Exception e) { Log.e(LOG, "Unable to load dictionary.", e); - DictionaryEditActivity.getIntent(dictIndex); + Toast.makeText(this, getString(R.string.invalidDictionary, "", e.getMessage()), Toast.LENGTH_LONG); + startActivity(DictionaryEditActivity.getIntent(dictIndex)); finish(); return; } @@ -121,7 +152,7 @@ public class DictionaryActivity extends ListActivity { } }); - indexIndex = intent.getIntExtra(C.INDEX_INDEX, 0) % dictionary.indices.size(); + indexIndex = prefs.getInt(C.INDEX_INDEX, 0) % dictionary.indices.size(); index = dictionary.indices.get(indexIndex); setListAdapter(new IndexAdapter(index)); @@ -129,8 +160,10 @@ public class DictionaryActivity extends ListActivity { searchText = (EditText) findViewById(R.id.SearchText); langButton = (Button) findViewById(R.id.LangButton); + searchText.requestFocus(); searchText.addTextChangedListener(new SearchTextWatcher()); - + searchText.setText(prefs.getString(C.SEARCH_TOKEN, "")); + Log.d(LOG, "Trying to restore searchText=" + searchText.getText()); final Button clearSearchTextButton = (Button) findViewById(R.id.ClearSearchTextButton); clearSearchTextButton.setOnClickListener(new OnClickListener() { @@ -148,6 +181,7 @@ public class DictionaryActivity extends ListActivity { onLanguageButton(); } }); + updateLangButton(); final Button upButton = (Button) findViewById(R.id.UpButton); upButton.setOnClickListener(new OnClickListener() { @@ -162,15 +196,56 @@ public class DictionaryActivity extends ListActivity { } }); + getListView().setOnItemSelectedListener(new ListView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView adapterView, View arg1, final int position, + long id) { + if (!searchText.isFocused()) { + // TODO: don't do this if multi words are entered. + final RowBase row = (RowBase) getListAdapter().getItem(position); + final TokenRow tokenRow = row.getTokenRow(true); + searchText.setText(tokenRow.getToken()); + } + } + + @Override + public void onNothingSelected(AdapterView arg0) { + } + }); + // ContextMenu. registerForContextMenu(getListView()); - + + // Prefs. + wordList = new File(prefs.getString(getString(R.string.wordListFileKey), + getString(R.string.wordListFileDefault))); + saveOnlyFirstSubentry = prefs.getBoolean(getString(R.string.saveOnlyFirstSubentryKey), false); if (prefs.getBoolean(getString(R.string.vibrateOnFailedSearchKey), true)) { vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); } + Log.d(LOG, "wordList=" + wordList + ", saveOnlyFirstSubentry=" + saveOnlyFirstSubentry); + } + + + @Override + protected void onResume() { + super.onResume(); + } - updateLangButton(); + @Override + protected void onPause() { + super.onPause(); + } + @Override + protected void onDestroy() { + super.onDestroy(); + setDictionaryPrefs(this, dictIndex, indexIndex, searchText.getText().toString()); + try { + dictRaf.close(); + } catch (IOException e) { + Log.e(LOG, "Failed to close dictionary", e); + } } // -------------------------------------------------------------------------- @@ -221,25 +296,150 @@ public class DictionaryActivity extends ListActivity { destIndexEntry = Math.min(tokenRow.referenceIndex + 1, index.sortedIndexEntries.size()); } - Log.d(LOG, "onUpDownButton, destIndexEntry=" + destIndexEntry); - jumpToRow(index.sortedIndexEntries.get(destIndexEntry).startRow); + final Index.IndexEntry dest = index.sortedIndexEntries.get(destIndexEntry); + searchText.setText(dest.token); + Log.d(LOG, "onUpDownButton, destIndexEntry=" + dest.token); + //jumpToRow(index.sortedIndexEntries.get(destIndexEntry).startRow); } // -------------------------------------------------------------------------- - // Menu + // Options Menu // -------------------------------------------------------------------------- + + @Override + public boolean onCreateOptionsMenu(final Menu menu) { + + { + final MenuItem preferences = menu.add(getString(R.string.preferences)); + preferences.setOnMenuItemClickListener(new OnMenuItemClickListener() { + public boolean onMenuItemClick(final MenuItem menuItem) { + startActivity(new Intent(DictionaryActivity.this, + PreferenceActivity.class)); + return false; + } + }); + } + + { + 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(DictionaryListActivity.getIntent(DictionaryActivity.this)); + return false; + } + }); + } + + { + final MenuItem dictionaryList = menu.add(getString(R.string.editDictionary)); + dictionaryList.setOnMenuItemClickListener(new OnMenuItemClickListener() { + public boolean onMenuItemClick(final MenuItem menuItem) { + final Intent intent = DictionaryEditActivity.getIntent(dictIndex); + startActivity(intent); + return false; + } + }); + } + + return true; + } + + + // -------------------------------------------------------------------------- + // Context Menu + clicks + // -------------------------------------------------------------------------- + + @Override + public void onCreateContextMenu(ContextMenu menu, View v, + ContextMenuInfo menuInfo) { + AdapterContextMenuInfo adapterContextMenuInfo = (AdapterContextMenuInfo) menuInfo; + final RowBase row = (RowBase) getListAdapter().getItem(adapterContextMenuInfo.position); + + final MenuItem addToWordlist = menu.add(getString(R.string.addToWordList, wordList.getName())); + addToWordlist.setOnMenuItemClickListener(new OnMenuItemClickListener() { + public boolean onMenuItemClick(MenuItem item) { + onAppendToWordList(row); + return false; + } + }); + + final MenuItem copy = menu.add(android.R.string.copy); + copy.setOnMenuItemClickListener(new OnMenuItemClickListener() { + public boolean onMenuItemClick(MenuItem item) { + onCopy(row); + return false; + } + }); + + } + + @Override + protected void onListItemClick(ListView l, View v, int row, long id) { + openContextMenu(v); + } + + void onAppendToWordList(final RowBase row) { + final StringBuilder rawText = new StringBuilder(); + rawText.append( + new SimpleDateFormat("yyyy.MM.dd HH:mm:ss").format(new Date())) + .append("\t"); + rawText.append(index.longName).append("\t"); + rawText.append(row.getTokenRow(true).getToken()).append("\t"); + rawText.append(row.getRawText(saveOnlyFirstSubentry)); + Log.d(LOG, "Writing : " + rawText); + try { + wordList.getParentFile().mkdirs(); + final PrintWriter out = new PrintWriter( + new FileWriter(wordList, true)); + out.println(rawText.toString()); + out.close(); + } catch (IOException e) { + Log.e(LOG, "Unable to append to " + wordList.getAbsolutePath(), e); + Toast.makeText(this, getString(R.string.failedAddingToWordList, wordList.getAbsolutePath()), Toast.LENGTH_LONG); + } + return; + } + + void onCopy(final RowBase row) { + Log.d(LOG, "Copy, row=" + row); + final StringBuilder result = new StringBuilder(); + result.append(row.getRawText(false)); + final ClipboardManager clipboardManager = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); + clipboardManager.setText(result.toString()); + Log.d(LOG, "Copied: " + result); + } + + @Override + public boolean onKeyDown(final int keyCode, final KeyEvent event) { + if (event.getUnicodeChar() != 0) { + if (!searchText.hasFocus()) { + searchText.setText("" + (char) event.getUnicodeChar()); + onSearchTextChange(searchText.getText().toString()); + searchText.requestFocus(); + } + return true; + } + return super.onKeyDown(keyCode, event); + } + // -------------------------------------------------------------------------- // SearchOperation // -------------------------------------------------------------------------- private void searchFinished(final SearchOperation searchOperation) { + if (searchOperation.interrupted.get()) { + Log.d(LOG, "Search operation was interrupted: " + searchOperation); + return; + } if (searchOperation != this.currentSearchOperation) { + Log.d(LOG, "Stale searchOperation finished: " + searchOperation); return; } final Index.SearchResult searchResult = searchOperation.searchResult; - Log.d(LOG, "searchFinished, " + searchResult.longestPrefixString + ", success=" + searchResult.success); + Log.d(LOG, "searchFinished: " + searchOperation + ", searchResult=" + searchResult); jumpToRow(searchResult.longestPrefix.startRow); @@ -272,6 +472,10 @@ public class DictionaryActivity extends ListActivity { this.searchText = searchText.trim(); this.index = index; } + + public String toString() { + return String.format("SearchOperation(%s,%s)", searchText, interrupted.toString()); + } @Override public void run() { @@ -310,13 +514,13 @@ public class DictionaryActivity extends ListActivity { } @Override - public Object getItem(int position) { + public RowBase getItem(int position) { return index.rows.get(position); } @Override public long getItemId(int position) { - return position; + return getItem(position).index(); } @Override @@ -394,19 +598,23 @@ public class DictionaryActivity extends ListActivity { // SearchText // -------------------------------------------------------------------------- - void onSearchTextChange(final String searchText) { - Log.d(LOG, "onSearchTextChange: " + searchText); + void onSearchTextChange(final String text) { + if (!searchText.isFocused()) { + return; + } + Log.d(LOG, "onSearchTextChange: " + text); if (currentSearchOperation != null) { + Log.d(LOG, "Interrupting currentSearchOperation."); currentSearchOperation.interrupted.set(true); } - currentSearchOperation = new SearchOperation(searchText, index); + currentSearchOperation = new SearchOperation(text, index); searchExecutor.execute(currentSearchOperation); } private class SearchTextWatcher implements TextWatcher { public void afterTextChanged(final Editable searchTextEditable) { - Log.d(LOG, "Search text changed: " + searchText.getText()); if (searchText.hasFocus()) { + Log.d(LOG, "Search text changed with focus: " + searchText.getText()); // If they were typing to cause the change, update the UI. onSearchTextChange(searchText.getText().toString()); } diff --git a/src/com/hughes/android/dictionary/DictionaryConfig.java b/src/com/hughes/android/dictionary/DictionaryConfig.java index 1c2458b..3ef6333 100644 --- a/src/com/hughes/android/dictionary/DictionaryConfig.java +++ b/src/com/hughes/android/dictionary/DictionaryConfig.java @@ -8,7 +8,6 @@ public class DictionaryConfig implements Serializable { String name = ""; String localFile = "/sdcard/quickDic/"; - String wordList = "/sdcard/quickDic/"; String downloadUrl = "http://"; int openIndex = 0; @@ -19,7 +18,6 @@ public class DictionaryConfig implements Serializable { result.name = "DE<->EN"; result.downloadUrl = "http://www.stanford.edu/~egirard/dict/de-en.2.dict"; result.localFile = "/sdcard/quickDic/de-en.dict"; - result.wordList = "/sdcard/quickDict/wordlist_de-en.txt"; return result; } diff --git a/src/com/hughes/android/dictionary/DictionaryEditActivity.java b/src/com/hughes/android/dictionary/DictionaryEditActivity.java index 1e36156..cc21132 100644 --- a/src/com/hughes/android/dictionary/DictionaryEditActivity.java +++ b/src/com/hughes/android/dictionary/DictionaryEditActivity.java @@ -10,6 +10,7 @@ import android.content.Intent; import android.os.Bundle; import android.text.Editable; import android.text.TextWatcher; +import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.MenuItem.OnMenuItemClickListener; @@ -22,13 +23,15 @@ import com.hughes.android.util.PersistentObjectCache; public class DictionaryEditActivity extends Activity { + static final String LOG = "QuickDic"; + QuickDicConfig quickDicConfig; private DictionaryConfig dictionaryConfig; - public static Intent getIntent(final int dictIndex) { final Intent intent = new Intent(); - intent.setClassName(DictionaryEditActivity.class.getPackage().getName(), DictionaryEditActivity.class.getName()); + intent.setClassName(DictionaryEditActivity.class.getPackage().getName(), + DictionaryEditActivity.class.getName()); intent.putExtra(C.DICT_INDEX, dictIndex); return intent; } @@ -39,92 +42,118 @@ public class DictionaryEditActivity extends Activity { super.onCreate(savedInstanceState); setContentView(R.layout.edit_activity); - PersistentObjectCache.init(this); - quickDicConfig = PersistentObjectCache.init( - this).read(C.DICTIONARY_CONFIGS, QuickDicConfig.class); - final Intent intent = getIntent(); - dictionaryConfig = quickDicConfig.dictionaryConfigs.get(intent.getIntExtra(C.DICT_INDEX, 0)); - // Write stuff from object into fields. - - ((EditText) findViewById(R.id.dictionaryName)).setText(dictionaryConfig.name); - ((EditText) findViewById(R.id.localFile)).setText(dictionaryConfig.localFile); - ((EditText) findViewById(R.id.wordListFile)).setText(dictionaryConfig.wordList); - ((EditText) findViewById(R.id.downloadUrl)).setText(dictionaryConfig.downloadUrl); + PersistentObjectCache.init(this); + try { + quickDicConfig = PersistentObjectCache.init(this).read( + C.DICTIONARY_CONFIGS, QuickDicConfig.class); + dictionaryConfig = quickDicConfig.dictionaryConfigs.get(intent + .getIntExtra(C.DICT_INDEX, 0)); + } catch (Exception e) { + Log.e(LOG, "Failed to read QuickDicConfig.", e); + quickDicConfig = new QuickDicConfig(); + dictionaryConfig = quickDicConfig.dictionaryConfigs.get(0); + } + // Write stuff from object into fields. + + ((EditText) findViewById(R.id.dictionaryName)) + .setText(dictionaryConfig.name); + ((EditText) findViewById(R.id.localFile)) + .setText(dictionaryConfig.localFile); + ((EditText) findViewById(R.id.downloadUrl)) + .setText(dictionaryConfig.downloadUrl); + updateDictInfo(); - ((EditText) findViewById(R.id.localFile)).addTextChangedListener(new TextWatcher() { - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - } - - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - } - - @Override - public void afterTextChanged(Editable s) { - updateDictInfo(); - } - }); - + ((EditText) findViewById(R.id.localFile)) + .addTextChangedListener(new TextWatcher() { + @Override + public void onTextChanged(CharSequence s, int start, int before, + int count) { + } + + @Override + public void beforeTextChanged(CharSequence s, int start, int count, + int after) { + } + + @Override + public void afterTextChanged(Editable s) { + updateDictInfo(); + } + }); + } @Override protected void onPause() { super.onPause(); - + // Read stuff from fields into object. - dictionaryConfig.name = ((EditText) findViewById(R.id.dictionaryName)).getText().toString(); - dictionaryConfig.localFile = ((EditText) findViewById(R.id.localFile)).getText().toString(); - dictionaryConfig.wordList = ((EditText) findViewById(R.id.wordListFile)).getText().toString(); - dictionaryConfig.downloadUrl = ((EditText) findViewById(R.id.downloadUrl)).getText().toString(); - - PersistentObjectCache.getInstance().write(C.DICTIONARY_CONFIGS, quickDicConfig); + dictionaryConfig.name = ((EditText) findViewById(R.id.dictionaryName)) + .getText().toString(); + dictionaryConfig.localFile = ((EditText) findViewById(R.id.localFile)) + .getText().toString(); + dictionaryConfig.downloadUrl = ((EditText) findViewById(R.id.downloadUrl)) + .getText().toString(); + + PersistentObjectCache.getInstance().write(C.DICTIONARY_CONFIGS, + quickDicConfig); } - + public boolean onCreateOptionsMenu(final Menu menu) { - final MenuItem newDictionaryMenuItem = menu.add(R.string.downloadDictionary); - newDictionaryMenuItem.setOnMenuItemClickListener(new OnMenuItemClickListener() { + final MenuItem newDictionaryMenuItem = menu + .add(R.string.downloadDictionary); + newDictionaryMenuItem + .setOnMenuItemClickListener(new OnMenuItemClickListener() { public boolean onMenuItemClick(final MenuItem menuItem) { - startDownloadDictActivity(DictionaryEditActivity.this, dictionaryConfig); + startDownloadDictActivity(DictionaryEditActivity.this, + dictionaryConfig); return false; } }); - + return true; } - + void updateDictInfo() { final TextView dictInfo = (TextView) findViewById(R.id.dictionaryInfo); - final String localFile = ((EditText) findViewById(R.id.localFile)).getText().toString(); - + final String localFile = ((EditText) findViewById(R.id.localFile)) + .getText().toString(); + if (!new File(localFile).canRead()) { dictInfo.setText(getString(R.string.fileNotFound, localFile)); return; } - + try { final RandomAccessFile raf = new RandomAccessFile(localFile, "r"); final Dictionary dict = new Dictionary(raf); final StringBuilder builder = new StringBuilder(); builder.append(dict.dictInfo).append("\n"); - builder.append(getString(R.string.numPairEntries, dict.pairEntries.size())).append("\n"); + builder.append( + getString(R.string.numPairEntries, dict.pairEntries.size())).append( + "\n"); for (final Index index : dict.indices) { builder.append("\n"); builder.append(index.longName).append("\n"); - builder.append(" ").append(getString(R.string.numTokens, index.sortedIndexEntries.size())).append("\n"); - builder.append(" ").append(getString(R.string.numRows, index.rows.size())).append("\n"); + builder.append(" ").append( + getString(R.string.numTokens, index.sortedIndexEntries.size())) + .append("\n"); + builder.append(" ").append( + getString(R.string.numRows, index.rows.size())).append("\n"); } raf.close(); dictInfo.setText(builder.toString()); } catch (IOException e) { - dictInfo.setText(getString(R.string.invalidDictionary, localFile, e.toString())); + dictInfo.setText(getString(R.string.invalidDictionary, localFile, e + .toString())); } } - static void startDownloadDictActivity(final Context context, final DictionaryConfig dictionaryConfig) { + static void startDownloadDictActivity(final Context context, + final DictionaryConfig dictionaryConfig) { final Intent intent = new Intent(context, DownloadActivity.class); intent.putExtra(DownloadActivity.SOURCE, dictionaryConfig.downloadUrl); intent.putExtra(DownloadActivity.DEST, dictionaryConfig.localFile); diff --git a/src/com/hughes/android/dictionary/DictionaryListActivity.java b/src/com/hughes/android/dictionary/DictionaryListActivity.java index 26f7075..29ec4b8 100644 --- a/src/com/hughes/android/dictionary/DictionaryListActivity.java +++ b/src/com/hughes/android/dictionary/DictionaryListActivity.java @@ -1,8 +1,13 @@ package com.hughes.android.dictionary; +import android.app.AlertDialog; import android.app.ListActivity; +import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; +import android.content.SharedPreferences; import android.os.Bundle; +import android.preference.PreferenceManager; import android.util.Log; import android.view.ContextMenu; import android.view.Menu; @@ -11,6 +16,7 @@ import android.view.View; import android.view.ViewGroup; import android.view.ContextMenu.ContextMenuInfo; import android.view.MenuItem.OnMenuItemClickListener; +import android.webkit.WebView; import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.TableLayout; @@ -34,15 +40,6 @@ public class DictionaryListActivity extends ListActivity { // UI init. setContentView(R.layout.list_activity); - /* - getListView().setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { - public boolean onItemLongClick(AdapterView arg0, View arg1, int row, - long arg3) { - return false; - } - }); - */ - getListView().setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView arg0, View arg1, int index, @@ -53,17 +50,41 @@ public class DictionaryListActivity extends ListActivity { // ContextMenu. registerForContextMenu(getListView()); - + + final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + final int introMessageId = 0; + if (prefs.getInt(C.INTRO_MESSAGE_SHOWN, 0) < introMessageId) { + final AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setCancelable(false); + final WebView webView = new WebView(getApplicationContext()); + webView.loadData(getString(R.string.thanksForUpdating), "text/html", "utf-8"); + builder.setView(webView); + builder.setNegativeButton(android.R.string.ok, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + dialog.cancel(); + } + }); + final AlertDialog alert = builder.create(); + alert.show(); + prefs.edit().putInt(C.INTRO_MESSAGE_SHOWN, introMessageId).commit(); + } } private void onClick(int dictIndex) { - final Intent intent = DictionaryActivity.getIntent(dictIndex, 0, ""); + final Intent intent = DictionaryActivity.getIntent(this, dictIndex, 0, ""); startActivity(intent); } @Override protected void onResume() { super.onResume(); + + final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + if (prefs.contains(C.DICT_INDEX) && prefs.contains(C.INDEX_INDEX)) { + startActivity(DictionaryActivity.getIntent(this, prefs.getInt(C.DICT_INDEX, 0), prefs.getInt(C.INDEX_INDEX, 0), prefs.getString(C.SEARCH_TOKEN, ""))); + finish(); + return; + } quickDicConfig = PersistentObjectCache.init(this).read(C.DICTIONARY_CONFIGS, QuickDicConfig.class); if (quickDicConfig == null) { @@ -72,6 +93,7 @@ public class DictionaryListActivity extends ListActivity { } setListAdapter(new Adapter()); + } public boolean onCreateOptionsMenu(final Menu menu) { @@ -168,5 +190,12 @@ 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()); + return intent; + } } diff --git a/src/com/hughes/android/dictionary/engine/Dictionary.java b/src/com/hughes/android/dictionary/engine/Dictionary.java index cbe76fb..f85af81 100644 --- a/src/com/hughes/android/dictionary/engine/Dictionary.java +++ b/src/com/hughes/android/dictionary/engine/Dictionary.java @@ -20,6 +20,7 @@ public class Dictionary implements RAFSerializable { // persisted final int dictFileVersion; + final long creationMillis; public final String dictInfo; public final List pairEntries; public final List textEntries; @@ -28,6 +29,7 @@ public class Dictionary implements RAFSerializable { public Dictionary(final String dictInfo) { this.dictFileVersion = 0; + this.creationMillis = System.currentTimeMillis(); this.dictInfo = dictInfo; pairEntries = new ArrayList(); textEntries = new ArrayList(); @@ -40,6 +42,7 @@ public class Dictionary implements RAFSerializable { if (dictFileVersion != 0) { throw new IOException("Invalid dictionary version: " + dictFileVersion); } + creationMillis = raf.readLong(); dictInfo = raf.readUTF(); sources = CachingList.createFullyCached(RAFList.create(raf, EntrySource.SERIALIZER, raf.getFilePointer())); pairEntries = CachingList.create(RAFList.create(raf, PairEntry.SERIALIZER, raf.getFilePointer()), CACHE_SIZE); @@ -54,6 +57,7 @@ public class Dictionary implements RAFSerializable { @Override public void write(RandomAccessFile raf) throws IOException { raf.writeInt(dictFileVersion); + raf.writeLong(creationMillis); raf.writeUTF(dictInfo); RAFList.write(raf, sources, EntrySource.SERIALIZER); RAFList.write(raf, pairEntries, PairEntry.SERIALIZER); diff --git a/src/com/hughes/android/dictionary/engine/Index.java b/src/com/hughes/android/dictionary/engine/Index.java index e15c1b7..2d3d42f 100644 --- a/src/com/hughes/android/dictionary/engine/Index.java +++ b/src/com/hughes/android/dictionary/engine/Index.java @@ -85,6 +85,7 @@ public final class Index implements RAFSerializable { public static final class IndexEntry implements RAFSerializable { public final String token; public final int startRow; + public final int numRows; static final RAFSerializer SERIALIZER = new RAFSerializer () { @Override @@ -96,25 +97,28 @@ public final class Index implements RAFSerializable { t.write(raf); }}; - public IndexEntry(final String token, final int startRow) { + public IndexEntry(final String token, final int startRow, final int numRows) { assert token.equals(token.trim()); assert token.length() > 0; this.token = token; this.startRow = startRow; + this.numRows = numRows; } public IndexEntry(final RandomAccessFile raf) throws IOException { token = raf.readUTF(); startRow = raf.readInt(); + numRows = raf.readInt(); } public void write(RandomAccessFile raf) throws IOException { raf.writeUTF(token); raf.writeInt(startRow); + raf.writeInt(numRows); } public String toString() { - return token + "@" + startRow; + return String.format("%s@%d(%d)", token, startRow, numRows); } } @@ -164,6 +168,11 @@ public final class Index implements RAFSerializable { 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) { diff --git a/src/com/hughes/android/dictionary/engine/PairEntry.java b/src/com/hughes/android/dictionary/engine/PairEntry.java index 4f7c6a5..7d30310 100644 --- a/src/com/hughes/android/dictionary/engine/PairEntry.java +++ b/src/com/hughes/android/dictionary/engine/PairEntry.java @@ -22,6 +22,11 @@ public class PairEntry extends Entry implements RAFSerializable { public String toString() { return lang1 + " :: " + lang2; } + + public String toStringTab() { + return lang1 + "\t" + lang2; + } + } public final Pair[] pairs; @@ -83,6 +88,29 @@ public class PairEntry extends Entry implements RAFSerializable { out.println(); } } + + @Override + public String getRawText(boolean compact) { + final PairEntry pairEntry = getEntry(); + if (compact) { + return pairEntry.pairs[0].toStringTab(); + } + final StringBuilder builder = new StringBuilder(); + for (int i = 0; i < pairEntry.pairs.length; ++i) { + if (i > 0) { + builder.append(" | "); + } + builder.append(pairEntry.pairs[i].lang1); + } + builder.append("\t"); + for (int i = 0; i < pairEntry.pairs.length; ++i) { + if (i > 0) { + builder.append(" | "); + } + builder.append(pairEntry.pairs[i].lang2); + } + return builder.toString(); + } } diff --git a/src/com/hughes/android/dictionary/engine/RowBase.java b/src/com/hughes/android/dictionary/engine/RowBase.java index 6450058..5491b4e 100644 --- a/src/com/hughes/android/dictionary/engine/RowBase.java +++ b/src/com/hughes/android/dictionary/engine/RowBase.java @@ -64,7 +64,9 @@ public abstract class RowBase extends IndexedObject { } public abstract void print(PrintStream out); - + + public abstract String getRawText(final boolean compact); + // RowBase must manage "disk-based" polymorphism. All other polymorphism is // dealt with in the normal manner. static class Serializer implements RAFListSerializer { diff --git a/src/com/hughes/android/dictionary/engine/TextEntry.java b/src/com/hughes/android/dictionary/engine/TextEntry.java index 4aba121..dd71092 100644 --- a/src/com/hughes/android/dictionary/engine/TextEntry.java +++ b/src/com/hughes/android/dictionary/engine/TextEntry.java @@ -47,6 +47,11 @@ public class TextEntry extends Entry implements RAFSerializable { public void print(PrintStream out) { out.println(" " + getEntry().text); } + + @Override + public String getRawText(boolean compact) { + return getEntry().text; + } } diff --git a/src/com/hughes/android/dictionary/engine/TokenRow.java b/src/com/hughes/android/dictionary/engine/TokenRow.java index 3cfce02..e40d124 100644 --- a/src/com/hughes/android/dictionary/engine/TokenRow.java +++ b/src/com/hughes/android/dictionary/engine/TokenRow.java @@ -37,5 +37,10 @@ public class TokenRow extends RowBase { out.println(getToken()); } + @Override + public String getRawText(boolean compact) { + return getToken(); + } + }