X-Git-Url: http://gitweb.fperrin.net/?a=blobdiff_plain;f=src%2Fcom%2Fhughes%2Fandroid%2Fdictionary%2FDictionaryApplication.java;h=a16ad0e163dafa3112ce9c8740af40a97f373461;hb=6d31b7b124787ac07ba682879fd47229765b6ee0;hp=d7109a062cc39d8376c155ce939e9f8439ecd839;hpb=c56b5d8ce1721eabc8283558acce1d00b6b358e2;p=Dictionary.git diff --git a/src/com/hughes/android/dictionary/DictionaryApplication.java b/src/com/hughes/android/dictionary/DictionaryApplication.java index d7109a0..a16ad0e 100644 --- a/src/com/hughes/android/dictionary/DictionaryApplication.java +++ b/src/com/hughes/android/dictionary/DictionaryApplication.java @@ -14,32 +14,73 @@ 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 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 dictionaryFiles = new ArrayList(); + } + 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); } @@ -56,4 +97,136 @@ public class DictionaryApplication extends Application { return C.Theme.DEFAULT; } } + + static synchronized void staticInit(final Context context) { + if (DOWNLOADABLE_NAME_TO_INFO != null) { + return; + } + DOWNLOADABLE_NAME_TO_INFO = new LinkedHashMap(); + 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 getUsableDicts() { + final List result = new ArrayList(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 fileToNameCache = new LinkedHashMap(); + 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 getAllDictionaries() { + final List result = getUsableDicts(); + + // The ones we knew about... + final Set known = new LinkedHashSet(); + 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 remaining = new LinkedHashMap(DOWNLOADABLE_NAME_TO_INFO); + remaining.keySet().removeAll(known); + final List remainingSorted = new ArrayList(remaining.values()); + final Collator collator = Collator.getInstance(); + Collections.sort(remainingSorted, new Comparator() { + @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(); + } + + }