android:max="100" android:progress="50"
android:layout_width="fill_parent" android:layout_height="wrap_content" android:indeterminate="false"/>
+ <TextView android:id="@+id/downloadMessage" android:layout_width="wrap_content"
+ android:layout_height="wrap_content" android:visibility="visible" android:text="Download message."/>
+
<TextView android:id="@+id/downloadStatus" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:visibility="visible" android:text="Download status."/>
<string name="BO">Tibetan</string>
<string name="TR">Turkish</string>
<string name="UK">Ukrainian</string>
+ <string name="UR">Urdu</string>
<string name="VI">Vietnamese</string>
<string name="CI">Welsh</string>
<string name="YI">Yiddish</string>
<string name="downloadButton">Download</string>
<string name="openButton">Open</string>
<string name="dictionaryInfo">Dictionary info:</string>
+ <string name="indexInfo">Index %1$s, %2$d words</string>
<string name="localFile">Dictionary file</string>
<string name="wordListFile">Word list file</string>
<string name="fileNotFound">File not found: \'%s\'</string>
<string name="invalidDictionary">Invalid dictionary: file=%1$s, error=%2$s</string>
<string name="numPairEntries">Entries: %,d</string>
- <string name="numTokens">Tokens: %,d</string>
- <string name="numRows">Rows: %,d</string>
<!-- Main -->
import java.io.PrintWriter;\r
import java.io.RandomAccessFile;\r
import java.text.SimpleDateFormat;\r
-import java.util.ArrayList;\r
import java.util.Date;\r
import java.util.List;\r
import java.util.concurrent.Executor;\r
import com.hughes.android.dictionary.engine.RowBase;\r
import com.hughes.android.dictionary.engine.TokenRow;\r
import com.hughes.android.dictionary.engine.TransliteratorManager;\r
-import com.hughes.android.util.PersistentObjectCache;\r
\r
public class DictionaryActivity extends ListActivity {\r
\r
return intent;\r
}\r
\r
- // TODO: fix these...\r
-\r
@Override\r
protected void onSaveInstanceState(final Bundle outState) {\r
super.onSaveInstanceState(outState);\r
outState.putString(C.SEARCH_TOKEN, searchText.getText().toString());\r
}\r
+\r
+ @Override\r
+ protected void onRestoreInstanceState(final Bundle outState) {\r
+ super.onRestoreInstanceState(outState);\r
+ setSearchText(outState.getString(C.SEARCH_TOKEN));\r
+ }\r
+\r
+ public DictionaryApplication getDictionaryApplication() {\r
+ return (DictionaryApplication) super.getApplication();\r
+ }\r
\r
@Override\r
public void onCreate(Bundle savedInstanceState) {\r
+ // Clear them so that if something goes wrong, we won't relaunch.\r
clearDictionaryPrefs(this);\r
\r
Log.d(LOG, "onCreate:" + this);\r
dictFile = intent.getStringExtra(C.DICT_FILE);\r
\r
try {\r
- PersistentObjectCache.init(this);\r
- QuickDicConfig quickDicConfig = PersistentObjectCache.init(\r
- this).read(C.DICTIONARY_CONFIGS, QuickDicConfig.class);\r
- final DictionaryInfo dictionaryConfig = quickDicConfig.getDictionaryInfoByFile(dictFile);\r
- this.setTitle("QuickDic: " + dictionaryConfig.name);\r
- dictRaf = new RandomAccessFile(dictionaryConfig.localFile, "r");\r
+ final String name = getDictionaryApplication().getDictionaryName(dictFile);\r
+ this.setTitle("QuickDic: " + name);\r
+ dictRaf = new RandomAccessFile(dictFile, "r");\r
dictionary = new Dictionary(dictRaf); \r
} catch (Exception e) {\r
Log.e(LOG, "Unable to load dictionary.", e);\r
dictRaf = null;\r
}\r
Toast.makeText(this, getString(R.string.invalidDictionary, "", e.getMessage()), Toast.LENGTH_LONG);\r
- startActivity(DictionaryEditActivity.getLaunchIntent(dictFile));\r
+ startActivity(DictionaryManagerActivity.getLaunchIntent());\r
finish();\r
return;\r
}\r
dialog.setTitle(R.string.selectADictionary);\r
\r
ListView listView = (ListView) dialog.findViewById(android.R.id.list);\r
+ \r
+ final List<DictionaryInfo> installedDicts = ((DictionaryApplication)getApplication()).getUsableDicts();\r
\r
- QuickDicConfig quickDicConfig = PersistentObjectCache.init(\r
- this).read(C.DICTIONARY_CONFIGS, QuickDicConfig.class);\r
- final List<DictionaryInfo> dictionaryInfos = new ArrayList<DictionaryInfo>();\r
- for (final DictionaryInfo dictionaryInfo : quickDicConfig.dictionaryInfos) {\r
- if (new File(dictionaryInfo.localFile).canRead()) {\r
- dictionaryInfos.add(dictionaryInfo);\r
- }\r
- }\r
listView.setAdapter(new BaseAdapter() {\r
\r
@Override\r
public View getView(int position, View convertView, ViewGroup parent) {\r
final LinearLayout result = new LinearLayout(parent.getContext());\r
//result.addView(new Butt)\r
+ // TODO: me\r
return result;\r
}\r
\r
}\r
\r
@Override\r
- public Object getItem(int position) {\r
- return dictionaryInfos.get(position);\r
+ public DictionaryInfo getItem(int position) {\r
+ return installedDicts.get(position);\r
}\r
\r
@Override\r
public int getCount() {\r
- return dictionaryInfos.size();\r
+ return installedDicts.size();\r
}\r
});\r
}\r
package com.hughes.android.dictionary;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
import android.app.Application;
+import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.os.Environment;
import android.preference.PreferenceManager;
import android.util.Log;
+import com.hughes.android.dictionary.engine.Dictionary;
+import com.hughes.android.dictionary.engine.Language;
import com.hughes.android.dictionary.engine.TransliteratorManager;
+import com.hughes.android.util.PersistentObjectCache;
+import com.ibm.icu.text.Collator;
public class DictionaryApplication extends Application {
+ static final String LOG = "QuickDicApp";
+
+ private static final File DICT_DIR = new File(Environment.getExternalStorageDirectory().getName(), "quickdic");
+
+ // Static, determined by resources (and locale).
+ // Unordered.
+ static Map<String,DictionaryInfo> DOWNLOADABLE_NAME_TO_INFO = null;
+
+ static final class DictionaryConfig implements Serializable {
+ private static final long serialVersionUID = -1444177164708201260L;
+ // User-ordered list, persisted, just the ones that are/have been present.
+ final List<String> dictionaryFiles = new ArrayList<String>();
+ }
+ DictionaryConfig dictionaryConfig = null;
+
@Override
public void onCreate() {
super.onCreate();
Log.d("QuickDic", "Application: onCreate");
TransliteratorManager.init(null);
+ staticInit(getApplicationContext());
- setTheme(getSelectedTheme().themeId);
-
+ // Load the dictionaries we know about.
+ dictionaryConfig = PersistentObjectCache.init(getApplicationContext()).read(C.DICTIONARY_CONFIGS, DictionaryConfig.class);
+ if (dictionaryConfig == null) {
+ dictionaryConfig = new DictionaryConfig();
+ }
+
+ // Theme stuff.
+ setTheme(getSelectedTheme().themeId);
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
prefs.registerOnSharedPreferenceChangeListener(new OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key) {
Log.d("THAD", "prefs changed: " + key);
-
if (key.equals(getString(R.string.themeKey))) {
setTheme(getSelectedTheme().themeId);
}
return C.Theme.DEFAULT;
}
}
+
+ static synchronized void staticInit(final Context context) {
+ if (DOWNLOADABLE_NAME_TO_INFO != null) {
+ return;
+ }
+ DOWNLOADABLE_NAME_TO_INFO = new LinkedHashMap<String,DictionaryInfo>();
+ final BufferedReader reader = new BufferedReader(new InputStreamReader(context.getResources().openRawResource(R.raw.dictionary_info)));
+ try {
+ String line;
+ while ((line = reader.readLine()) != null) {
+ if (line.startsWith("#") || line.length() == 0) {
+ continue;
+ }
+ final DictionaryInfo dictionaryInfo = new DictionaryInfo(line);
+ DOWNLOADABLE_NAME_TO_INFO.put(dictionaryInfo.uncompressedFilename, dictionaryInfo);
+ }
+ reader.close();
+ } catch (IOException e) {
+ Log.e(LOG, "Failed to load downloadable dictionary lists.", e);
+ }
+ }
+
+ private File getPath(String uncompressedFilename) {
+ return new File(DICT_DIR, uncompressedFilename);
+ }
+
+
+ public List<DictionaryInfo> getUsableDicts() {
+ final List<DictionaryInfo> result = new ArrayList<DictionaryInfo>(dictionaryConfig.dictionaryFiles.size());
+ for (final String uncompressedFilename : dictionaryConfig.dictionaryFiles) {
+ final DictionaryInfo dictionaryInfo = Dictionary.getDictionaryInfo(getPath(uncompressedFilename));
+ if (dictionaryInfo != null) {
+ result.add(dictionaryInfo);
+ }
+ }
+ return result;
+ }
+
+ final Map<String, String> fileToNameCache = new LinkedHashMap<String, String>();
+ public synchronized String getDictionaryName(final String uncompressedFilename) {
+ String name = fileToNameCache.get(uncompressedFilename);
+ if (name != null) {
+ return name;
+ }
+
+ final DictionaryInfo dictionaryInfo = DOWNLOADABLE_NAME_TO_INFO.get(uncompressedFilename);
+ final Context context = getApplicationContext();
+ if (dictionaryInfo != null) {
+ final StringBuilder nameBuilder = new StringBuilder();
+ for (int i = 0; i < dictionaryInfo.indexInfos.size(); ++i) {
+ final Integer langCode = Language.isoCodeToResourceId.get(dictionaryInfo.indexInfos.get(i).shortName);
+ final String lang = langCode != null ? context.getString(langCode) : dictionaryInfo.indexInfos.get(i).shortName;
+ if (i > 0) {
+ nameBuilder.append("-");
+ }
+ nameBuilder.append(lang);
+ }
+ name = nameBuilder.toString();
+ } else {
+ name = uncompressedFilename.replace(".quickdic", "");
+ }
+ fileToNameCache.put(uncompressedFilename, name);
+ return name;
+ }
+
+ public void moveDictionaryToTop(final String canonicalPath) {
+ dictionaryConfig.dictionaryFiles.remove(canonicalPath);
+ dictionaryConfig.dictionaryFiles.add(0, canonicalPath);
+ PersistentObjectCache.getInstance().write(C.DICTIONARY_CONFIGS, dictionaryConfig);
+ }
+
+ public void deleteDictionary(String canonicalPath) {
+ while (dictionaryConfig.dictionaryFiles.remove(canonicalPath)) {};
+ PersistentObjectCache.getInstance().write(C.DICTIONARY_CONFIGS, dictionaryConfig);
+ }
+
+ public List<DictionaryInfo> getAllDictionaries() {
+ final List<DictionaryInfo> result = getUsableDicts();
+
+ // The ones we knew about...
+ final Set<String> known = new LinkedHashSet<String>();
+ for (final DictionaryInfo usable : result) {
+ known.add(usable.uncompressedFilename);
+ }
+
+ // Are there dictionaries on the device that we didn't know about already?
+ // Pick them up and put them at the end of the list.
+ boolean foundNew = false;
+ final File[] dictDirFiles = DICT_DIR.listFiles();
+ for (final File file : dictDirFiles) {
+ if (!file.getName().endsWith(".quickdic")) {
+ continue;
+ }
+ if (known.contains(file.getName())) {
+ // We have it in our list already.
+ continue;
+ }
+ final DictionaryInfo dictionaryInfo = Dictionary.getDictionaryInfo(file);
+ if (dictionaryInfo == null) {
+ Log.e(LOG, "Unable to parse dictionary: " + file.getPath());
+ continue;
+ }
+ known.add(file.getName());
+ foundNew = true;
+ dictionaryConfig.dictionaryFiles.add(file.getName());
+ result.add(dictionaryInfo);
+ }
+ if (foundNew) {
+ PersistentObjectCache.getInstance().write(C.DICTIONARY_CONFIGS, dictionaryConfig);
+ }
+
+ // The downloadable ones.
+ final Map<String,DictionaryInfo> remaining = new LinkedHashMap<String, DictionaryInfo>(DOWNLOADABLE_NAME_TO_INFO);
+ remaining.keySet().removeAll(known);
+ final List<DictionaryInfo> remainingSorted = new ArrayList<DictionaryInfo>(remaining.values());
+ final Collator collator = Collator.getInstance();
+ Collections.sort(remainingSorted, new Comparator<DictionaryInfo>() {
+ @Override
+ public int compare(DictionaryInfo object1, DictionaryInfo object2) {
+ return collator.compare(getDictionaryName(object1.uncompressedFilename), getDictionaryName(object2.uncompressedFilename));
+ }
+ });
+
+ result.addAll(remainingSorted);
+ return result;
+ }
+
+ public boolean isDictionaryOnDevice(String uncompressedFilename) {
+ return getPath(uncompressedFilename).canRead();
+ }
+
+
}
+++ /dev/null
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.hughes.android.dictionary;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.Handler;
-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;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.WindowManager;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.TextView;
-
-import com.hughes.android.dictionary.engine.Dictionary;
-import com.hughes.android.dictionary.engine.Index;
-import com.hughes.android.util.PersistentObjectCache;
-
-public class DictionaryEditActivity extends Activity {
-
- static final String LOG = "QuickDic";
-
- QuickDicConfig quickDicConfig;
- private DictionaryInfo dictionaryInfo;
-
- final Handler uiHandler = new Handler();
-
- public static Intent getLaunchIntent(final String dictFile) {
- final Intent intent = new Intent();
- intent.setClassName(DictionaryEditActivity.class.getPackage().getName(),
- DictionaryEditActivity.class.getName());
- intent.putExtra(C.DICT_FILE, dictFile);
- return intent;
- }
-
- /** Called when the activity is first created. */
- @Override
- public void onCreate(final Bundle savedInstanceState) {
- //((DictionaryApplication)getApplication()).applyTheme(this);
-
- super.onCreate(savedInstanceState);
- setContentView(R.layout.edit_activity);
-
- final Intent intent = getIntent();
- final String dictFile = intent.getStringExtra(C.DICT_FILE);
-
- PersistentObjectCache.init(this);
- try {
- quickDicConfig = PersistentObjectCache.init(this).read(
- C.DICTIONARY_CONFIGS, QuickDicConfig.class);
- dictionaryInfo = quickDicConfig.getDictionaryInfoByFile(dictFile);
- } catch (Exception e) {
- Log.e(LOG, "Failed to read QuickDicConfig.", e);
- finish();
- startActivity(DictionaryManagerActivity.getLaunchIntent());
- return;
- }
-
- // Write stuff from object into fields.
-
- ((EditText) findViewById(R.id.dictionaryName))
- .setText(dictionaryInfo.name);
- ((EditText) findViewById(R.id.localFile))
- .setText(dictionaryInfo.localFile);
-
- final TextWatcher textWatcher = 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(textWatcher);
-
- final EditText downloadUrl = (EditText) findViewById(R.id.downloadUrl);
- downloadUrl.setText(dictionaryInfo.downloadUrl);
- downloadUrl.addTextChangedListener(textWatcher);
-
- final Button downloadButton = (Button) findViewById(R.id.downloadButton);
- downloadButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- startDownloadDictActivity(DictionaryEditActivity.this,
- dictionaryInfo);
- }
- });
-
- final Button openButton = (Button) findViewById(R.id.openButton);
- openButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- final Intent intent = DictionaryActivity.getLaunchIntent(dictFile, 0, "");
- startActivity(intent);
- }
- });
-
- // Don't show the keyboard when this opens up:
- getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
-
- }
-
- protected void onResume() {
- super.onResume();
-
- updateDictInfo();
-
- // Focus the download button so the keyboard doesn't pop up.
- final Button downloadButton = (Button) findViewById(R.id.downloadButton);
- downloadButton.requestFocus();
- }
-
- @Override
- protected void onPause() {
- super.onPause();
-
- // Read stuff from fields into object.
- dictionaryInfo.name = ((EditText) findViewById(R.id.dictionaryName))
- .getText().toString();
- dictionaryInfo.localFile = ((EditText) findViewById(R.id.localFile))
- .getText().toString();
- dictionaryInfo.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() {
- public boolean onMenuItemClick(final MenuItem menuItem) {
- startDownloadDictActivity(DictionaryEditActivity.this,
- dictionaryInfo);
- return false;
- }
- });
-
- final MenuItem dictionaryList = menu.add(getString(R.string.dictionaryManager));
- dictionaryList.setOnMenuItemClickListener(new OnMenuItemClickListener() {
- public boolean onMenuItemClick(final MenuItem menuItem) {
- startActivity(DictionaryManagerActivity.getLaunchIntent());
- return false;
- }
- });
-
-
- return true;
- }
-
- void updateDictInfo() {
- final String downloadUrl = ((EditText) findViewById(R.id.downloadUrl))
- .getText().toString();
- final String localFile = ((EditText) findViewById(R.id.localFile))
- .getText().toString();
-
- final Button downloadButton = (Button) findViewById(R.id.downloadButton);
- downloadButton.setEnabled(downloadUrl.length() > 0 && localFile.length() > 0);
-
- final Button openButton = (Button) findViewById(R.id.openButton);
- openButton.setEnabled(false);
-
- final TextView dictInfo = (TextView) findViewById(R.id.dictionaryInfo);
- 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");
- 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");
- }
- raf.close();
- dictInfo.setText(builder.toString());
- openButton.setEnabled(true);
-
- } catch (IOException e) {
- dictInfo.setText(getString(R.string.invalidDictionary, localFile, e
- .toString()));
- }
- }
-
- static void startDownloadDictActivity(final Context context,
- 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);
- }
-
-}
public static final class IndexInfo implements Serializable {
private static final long serialVersionUID = 6524751236198309438L;
- public IndexInfo(String langIso, int allTokenCount, int mainTokenCount) {
- this.langIso = langIso;
+ public IndexInfo(String shortName, int allTokenCount, int mainTokenCount) {
+ this.shortName = shortName;
this.allTokenCount = allTokenCount;
this.mainTokenCount = mainTokenCount;
}
- public final String langIso;
+ public final String shortName; // Often LangISO.
public final int allTokenCount;
public final int mainTokenCount;
public static final int SIZE = 3;
public StringBuilder append(StringBuilder result) {
- result.append(langIso);
+ result.append(shortName);
result.append("\t").append(allTokenCount);
result.append("\t").append(mainTokenCount);
return result;
}
public IndexInfo(final String[] fields, int i) {
- langIso = fields[i++];
+ shortName = fields[i++];
allTokenCount = Integer.parseInt(fields[i++]);
mainTokenCount = Integer.parseInt(fields[i++]);
}
}
// Stuff populated from the text file.
- public String uncompressedFilename;
+ public String uncompressedFilename; // used as a key throughout the program.
public String downloadUrl;
public long uncompressedSize;
public long creationMillis;
public final List<IndexInfo> indexInfos = new ArrayList<DictionaryInfo.IndexInfo>();
public String dictInfo;
-
- String name; // Determined at runtime based on locale on device--user editable?
- String localFile; // Determined based on device's Environment.
public StringBuilder append(final StringBuilder result) {
result.append(uncompressedFilename);
@Override
public String toString() {
- return name;
+ return uncompressedFilename;
}
package com.hughes.android.dictionary;
-import java.io.File;
+import java.util.List;
import android.app.AlertDialog;
import android.app.ListActivity;
import android.widget.TableLayout;
import android.widget.TextView;
-import com.hughes.android.util.PersistentObjectCache;
-
public class DictionaryManagerActivity extends ListActivity {
static final String LOG = "QuickDic";
static boolean canAutoLaunch = true;
+ final DictionaryApplication application = (DictionaryApplication) getApplication();
public void onCreate(Bundle savedInstanceState) {
//((DictionaryApplication)getApplication()).applyTheme(this);
}
}
- private void onClick(int dictIndex) {
- final DictionaryInfo dictionaryInfo = quickDicConfig.dictionaryInfos.get(dictIndex);
- final Intent intent = DictionaryActivity.getLaunchIntent(dictionaryInfo.localFile, 0, "");
+ private void onClick(int index) {
+ final DictionaryInfo dictionaryInfo = adapter.getItem(index);
+ final Intent intent = DictionaryActivity.getLaunchIntent(dictionaryInfo.uncompressedFilename, 0, "");
startActivity(intent);
}
return;
}
- quickDicConfig = PersistentObjectCache.init(this).read(C.DICTIONARY_CONFIGS, QuickDicConfig.class);
- if (quickDicConfig == null) {
- quickDicConfig = new QuickDicConfig(this);
- } else {
- quickDicConfig.addDefaultDictionaries(this);
- }
- PersistentObjectCache.getInstance().write(C.DICTIONARY_CONFIGS, quickDicConfig);
-
- Log.d(LOG, "DictionaryList: " + quickDicConfig.dictionaryInfos);
- setListAdapter(new Adapter());
+ setListAdapter(adapter);
}
public boolean onCreateOptionsMenu(final Menu menu) {
super.onCreateContextMenu(menu, view, menuInfo);
final AdapterContextMenuInfo adapterContextMenuInfo = (AdapterContextMenuInfo) menuInfo;
+ final int position = adapterContextMenuInfo.position;
+ final DictionaryInfo dictionaryInfo = adapter.getItem(position);
- if (adapterContextMenuInfo.position > 0) {
+ if (position > 0) {
final MenuItem moveToTopMenuItem = menu.add(R.string.moveToTop);
moveToTopMenuItem.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
- final DictionaryInfo dictionaryConfig = quickDicConfig.dictionaryInfos.remove(adapterContextMenuInfo.position);
- quickDicConfig.dictionaryInfos.add(0, dictionaryConfig);
- dictionaryConfigsChanged();
+ application.moveDictionaryToTop(dictionaryInfo.uncompressedFilename);
+ setListAdapter(adapter = new Adapter());
return true;
}
});
deleteMenuItem.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
- quickDicConfig.dictionaryInfos.remove(adapterContextMenuInfo.position);
- dictionaryConfigsChanged();
+ application.deleteDictionary(dictionaryInfo.uncompressedFilename);
+ setListAdapter(adapter = new Adapter());
return true;
}
});
}
- private void dictionaryConfigsChanged() {
- PersistentObjectCache.getInstance().write(C.DICTIONARY_CONFIGS, quickDicConfig);
- setListAdapter(getListAdapter());
- }
-
class Adapter extends BaseAdapter {
+
+ final List<DictionaryInfo> dictionaryInfos = application.getAllDictionaries();
@Override
public int getCount() {
- return quickDicConfig.dictionaryInfos.size();
+ return dictionaryInfos.size();
}
@Override
public DictionaryInfo getItem(int position) {
- return quickDicConfig.dictionaryInfos.get(position);
+ return dictionaryInfos.get(position);
}
@Override
@Override
public View getView(int position, View convertView, ViewGroup parent) {
- final DictionaryInfo dictionaryConfig = getItem(position);
+ final DictionaryInfo dictionaryInfo = getItem(position);
final TableLayout tableLayout = new TableLayout(parent.getContext());
final TextView view = new TextView(parent.getContext());
- String name = dictionaryConfig.name;
- if (!new File(dictionaryConfig.localFile).canRead()) {
- name = getString(R.string.notOnDevice, dictionaryConfig.name);
+ String name = application.getDictionaryName(dictionaryInfo.uncompressedFilename);
+ if (!application.isDictionaryOnDevice(dictionaryInfo.uncompressedFilename)) {
+ name = getString(R.string.notOnDevice, name);
}
view.setText(name);
return tableLayout;
}
-
}
+ Adapter adapter = new Adapter();
public static Intent getLaunchIntent() {
final Intent intent = new Intent();
\r
public static final String SOURCE = "source";\r
public static final String DEST = "dest";\r
+ public static final String MESSAGE = "message";\r
\r
String source;\r
String dest;\r
+ String message;\r
long bytesProcessed = 0;\r
long contentLength = -1;\r
\r
private final Handler uiHandler = new Handler();\r
\r
final AtomicBoolean stop = new AtomicBoolean(false);\r
+ \r
+ public static Intent getLaunchIntent(final String dictFile, final String source, final String dest, final String message) {\r
+ final Intent intent = new Intent();\r
+ intent.setClassName(DownloadActivity.class.getPackage().getName(), DownloadActivity.class.getName());\r
+ intent.putExtra(SOURCE, source);\r
+ intent.putExtra(DEST, dest);\r
+ intent.putExtra(MESSAGE, message);\r
+ return intent;\r
+ }\r
\r
/** Called when the activity is first created. */\r
@Override\r
final Intent intent = getIntent();\r
source = intent.getStringExtra(SOURCE);\r
dest = intent.getStringExtra(DEST);\r
+ message = intent.getStringExtra(MESSAGE);\r
if (source == null || dest == null) {\r
throw new RuntimeException("null source or dest.");\r
}\r
package com.hughes.android.dictionary;
import java.io.BufferedReader;
+import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
+import java.io.RandomAccessFile;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import android.content.Context;
import android.os.Environment;
+import android.util.Log;
+import com.hughes.android.dictionary.engine.Dictionary;
import com.hughes.android.dictionary.engine.Language;
public final class QuickDicConfig implements Serializable {
- private static final long serialVersionUID = 6711617368780900979L;
+ private static final String LOG = "QuickDicConfig";
- final List<DictionaryInfo> dictionaryInfos = new ArrayList<DictionaryInfo>();
-
- public QuickDicConfig(final Context context) {
- addDefaultDictionaries(context);
- }
-
- public void addDefaultDictionaries(final Context context) {
- for (final DictionaryInfo dictionaryInfo : getDefaultDictionaries(context).values()) {
- addOrReplace(dictionaryInfo);
- }
- }
+ private static final long serialVersionUID = 6711617368780900979L;
- private static Map<String,DictionaryInfo> defaultDictionaries = null;
- public synchronized static Map<String,DictionaryInfo> getDefaultDictionaries(final Context context) {
- if (defaultDictionaries != null) {
- return defaultDictionaries;
- }
-
- defaultDictionaries = new LinkedHashMap<String, DictionaryInfo>();
-
- final BufferedReader reader = new BufferedReader(new InputStreamReader(context.getResources().openRawResource(R.raw.dictionary_info)));
- String line;
- try {
- while ((line = reader.readLine()) != null) {
- if (line.startsWith("#") || line.length() == 0) {
- continue;
- }
- final DictionaryInfo dictionaryInfo = new DictionaryInfo(line);
- String name = "";
- for (int i = 0; i < dictionaryInfo.indexInfos.size(); ++i) {
- final Integer langCode = Language.isoCodeToResourceId.get(dictionaryInfo.indexInfos.get(i).langIso);
- final String lang = langCode != null ? context.getString(langCode) : dictionaryInfo.indexInfos.get(i).langIso;
- if (i > 0) {
- name += "-";
- }
- name += lang;
- }
- dictionaryInfo.name = name;
- dictionaryInfo.localFile = Environment.getExternalStorageDirectory().getName() + "/quickdic/" + dictionaryInfo.uncompressedFilename;
- defaultDictionaries.put(dictionaryInfo.localFile, dictionaryInfo);
- }
- } catch (IOException e) {
- defaultDictionaries = null;
- return new LinkedHashMap<String, DictionaryInfo>();
- }
-
- return defaultDictionaries;
- }
-
- private void addOrReplace(final DictionaryInfo dictionaryConfig) {
- for (int i = 0; i < dictionaryInfos.size(); ++i) {
- if (dictionaryInfos.get(i).uncompressedFilename.equals(dictionaryConfig.uncompressedFilename)) {
- dictionaryInfos.set(i, dictionaryConfig);
- return;
- }
- }
- dictionaryInfos.add(dictionaryConfig);
- }
- DictionaryInfo getDictionaryInfoByFile(final String dictFile) throws Exception {
- for (int i = 0; i < dictionaryInfos.size(); ++i) {
- if (dictionaryInfos.get(i).localFile.equals(dictFile)) {
- return dictionaryInfos.get(i);
- }
- }
- throw new Exception("Not found: " + dictFile);
- }
}
package com.hughes.android.dictionary.engine;
+import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.io.RandomAccessFile;
static final int CACHE_SIZE = 5000;
- static final int CURRENT_DICT_VERSION = 2;
+ static final int CURRENT_DICT_VERSION = 3;
static final String END_OF_DICTIONARY = "END OF DICTIONARY";
// persisted
dictInfo = raf.readUTF();
// Load the sources, then seek past them, because reading them later disrupts the offset.
- final RAFList<EntrySource> rafSources = RAFList.create(raf, EntrySource.SERIALIZER, raf.getFilePointer());
+ final RAFList<EntrySource> rafSources = RAFList.create(raf, new EntrySource.Serializer(this), raf.getFilePointer());
sources = new ArrayList<EntrySource>(rafSources);
raf.seek(rafSources.getEndOffset());
raf.writeInt(dictFileVersion);
raf.writeLong(creationMillis);
raf.writeUTF(dictInfo);
- RAFList.write(raf, sources, EntrySource.SERIALIZER);
+ RAFList.write(raf, sources, new EntrySource.Serializer(this));
RAFList.write(raf, pairEntries, new PairEntry.Serializer(this));
RAFList.write(raf, textEntries, new TextEntry.Serializer(this));
RAFList.write(raf, indices, indexSerializer);
public void print(final PrintStream out) {
out.println("dictInfo=" + dictInfo);
+ for (final EntrySource entrySource : sources) {
+ out.printf("EntrySource: %s %d\n", entrySource.name, entrySource.numEntries);
+ }
+ out.println();
for (final Index index : indices) {
out.printf("Index: %s %s\n", index.shortName, index.longName);
index.print(out);
}
return result;
}
-
+
+ public static DictionaryInfo getDictionaryInfo(final File file) {
+ RandomAccessFile raf = null;
+ try {
+ raf = new RandomAccessFile(file, "r");
+ final Dictionary dict = new Dictionary(raf);
+ final DictionaryInfo dictionaryInfo = dict.getDictionaryInfo();
+ raf.close();
+ return dictionaryInfo;
+ } catch (IOException e) {
+ return null;
+ } finally {
+ if (raf != null) {
+ try {
+ raf.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
}
\ No newline at end of file
private static final long serialVersionUID = -1323165134846120269L;
final String name;
+ int numEntries;
- public EntrySource(final int index, final String name) {
+ public EntrySource(final int index, final String name, int numEntries) {
super(index);
this.name = name;
+ this.numEntries = numEntries;
}
@Override
}
- public static RAFListSerializer<EntrySource> SERIALIZER = new RAFListSerializer<EntrySource>() {
+ public static final class Serializer implements RAFListSerializer<EntrySource> {
+
+ final Dictionary dictionary;
+
+ Serializer(Dictionary dictionary) {
+ this.dictionary = dictionary;
+ }
@Override
public EntrySource read(RandomAccessFile raf, int readIndex)
throws IOException {
final String name = raf.readUTF();
- return new EntrySource(readIndex, name);
+ final int numEntries = dictionary.dictFileVersion >= 3 ? raf.readInt() : 0;
+ return new EntrySource(readIndex, name, numEntries);
}
@Override
public void write(RandomAccessFile raf, EntrySource t) throws IOException {
raf.writeUTF(t.name);
+ raf.writeInt(t.numEntries);
}
};
isoCodeToResourceId.put("BO", R.string.BO);\r
isoCodeToResourceId.put("TR", R.string.TR);\r
isoCodeToResourceId.put("UK", R.string.UK);\r
+ isoCodeToResourceId.put("UR", R.string.UR);\r
isoCodeToResourceId.put("VI", R.string.VI);\r
isoCodeToResourceId.put("CI", R.string.CI);\r
isoCodeToResourceId.put("YI", R.string.YI);\r
private static boolean starting = false;
private static boolean ready = false;
+ // Whom to notify when we're all set up and ready to go.
private static List<Callback> callbacks = new ArrayList<TransliteratorManager.Callback>();
public static synchronized boolean init(final Callback callback) {
--- /dev/null
+package com.hughes.android.util;
+
+import android.app.Activity;
+import android.content.Intent;
+
+public class IntentLauncher {
+
+ final Intent intent;
+ final Activity activity;
+
+ private IntentLauncher(final Intent intent, final Activity activity) {
+ this.intent = intent;
+ this.activity = activity;
+ }
+
+ private void go() {
+ if (activity != null) {
+ activity.finish();
+ }
+ activity.startActivity(intent);
+ }
+
+
+
+}