diff --git a/ChangeLog b/ChangeLog index 1a0a9e859..05fdf727d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,6 @@ ===== 1.3.4 (??? ??, 2012) ===== * About section in the preferences dialog +* Better SlovoEd dictionary integration (780 dictionaries are supported) * CHANGE_WIFI_STATE permission is not required more * getBookFileName() API method has been implemented diff --git a/assets/dictionaries.xml b/assets/dictionaries.xml deleted file mode 100644 index 46558358e..000000000 --- a/assets/dictionaries.xml +++ /dev/null @@ -1,138 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/assets/dictionaries/main.xml b/assets/dictionaries/main.xml new file mode 100644 index 000000000..f2768a7cc --- /dev/null +++ b/assets/dictionaries/main.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + diff --git a/assets/dictionaries/slovoEd.xml b/assets/dictionaries/slovoEd.xml new file mode 100644 index 000000000..475c00cd8 --- /dev/null +++ b/assets/dictionaries/slovoEd.xml @@ -0,0 +1,3903 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/org/geometerplus/android/fbreader/DictionaryUtil.java b/src/org/geometerplus/android/fbreader/DictionaryUtil.java index 47648b7be..020a358db 100644 --- a/src/org/geometerplus/android/fbreader/DictionaryUtil.java +++ b/src/org/geometerplus/android/fbreader/DictionaryUtil.java @@ -42,12 +42,17 @@ import org.geometerplus.android.util.UIUtil; import org.geometerplus.android.util.PackageUtil; public abstract class DictionaryUtil { - // Map: dictionary info -> hide if package is not installed - private static LinkedHashMap ourDictionaryInfos = - new LinkedHashMap(); + private static int FLAG_INSTALLED_ONLY = 1; + private static int FLAG_SHOW_AS_DICTIONARY = 2; + private static int FLAG_SHOW_AS_TRANSLATOR = 4; + private static ZLStringOption ourSingleWordTranslatorOption; private static ZLStringOption ourMultiWordTranslatorOption; + // Map: dictionary info -> mode if package is not installed + private static Map ourInfos = + Collections.synchronizedMap(new LinkedHashMap()); + private static class InfoReader extends ZLXMLReaderAdapter { @Override public boolean dontCacheAttributeValues() { @@ -59,7 +64,12 @@ public abstract class DictionaryUtil { if ("dictionary".equals(tag)) { final String id = attributes.getValue("id"); final String title = attributes.getValue("title"); - ourDictionaryInfos.put(new PackageInfo( + + int flags = FLAG_SHOW_AS_DICTIONARY | FLAG_SHOW_AS_TRANSLATOR; + if (!"always".equals(attributes.getValue("list"))) { + flags |= FLAG_INSTALLED_ONLY; + } + ourInfos.put(new PackageInfo( id, attributes.getValue("package"), attributes.getValue("class"), @@ -67,7 +77,43 @@ public abstract class DictionaryUtil { attributes.getValue("action"), attributes.getValue("dataKey"), attributes.getValue("pattern") - ), !"always".equals(attributes.getValue("list"))); + ), flags); + } + return false; + } + } + + private static class SlovoEdInfoReader extends ZLXMLReaderAdapter { + private final Context myContext; + private int myCounter; + + SlovoEdInfoReader(Context context) { + myContext = context; + } + + @Override + public boolean dontCacheAttributeValues() { + return true; + } + + @Override + public boolean startElementHandler(String tag, ZLStringMap attributes) { + if ("dictionary".equals(tag)) { + final String id = attributes.getValue("id"); + final String title = attributes.getValue("title"); + + final PackageInfo info = new PackageInfo( + String.valueOf(++myCounter), + attributes.getValue("package"), + ".Start", + attributes.getValue("title"), + Intent.ACTION_VIEW, + null, + attributes.getValue("pattern") + ); + if (PackageUtil.canBeStarted(myContext, getDictionaryIntent(info, "test"), false)) { + ourInfos.put(info, FLAG_SHOW_AS_DICTIONARY | FLAG_INSTALLED_ONLY); + } } return false; } @@ -86,29 +132,58 @@ public abstract class DictionaryUtil { String FULLSCREEN = "EXTRA_FULLSCREEN"; } - private static Map infos() { - if (ourDictionaryInfos.isEmpty()) { - new InfoReader().read(ZLFile.createFileByPath("dictionaries.xml")); + public static void init(final Context context) { + if (ourInfos.isEmpty()) { + final Thread initThread = new Thread(new Runnable() { + public void run() { + new InfoReader().read(ZLFile.createFileByPath("dictionaries/main.xml")); + new SlovoEdInfoReader(context).read(ZLFile.createFileByPath("dictionaries/slovoEd.xml")); + } + }); + initThread.setPriority(Thread.MIN_PRIORITY); + initThread.start(); } - return ourDictionaryInfos; } - public static List dictionaryInfos(Context context) { + public static List dictionaryInfos(Context context, boolean dictionaryNotTranslator) { final LinkedList list = new LinkedList(); - for (Map.Entry entry : infos().entrySet()) { - final PackageInfo info = entry.getKey(); - if (!entry.getValue() || - PackageUtil.canBeStarted(context, getDictionaryIntent(info, "test"), false)) { - list.add(info); + final HashSet installedPackages = new HashSet(); + final HashSet notInstalledPackages = new HashSet(); + synchronized (ourInfos) { + for (Map.Entry entry : ourInfos.entrySet()) { + final PackageInfo info = entry.getKey(); + final int flags = entry.getValue(); + if (dictionaryNotTranslator) { + if ((flags & FLAG_SHOW_AS_DICTIONARY) == 0) { + continue; + } + } else { + if ((flags & FLAG_SHOW_AS_TRANSLATOR) == 0) { + continue; + } + } + if (((flags & FLAG_INSTALLED_ONLY) == 0) || + installedPackages.contains(info.PackageName)) { + list.add(info); + } else if (!notInstalledPackages.contains(info.PackageName)) { + if (PackageUtil.canBeStarted(context, getDictionaryIntent(info, "test"), false)) { + list.add(info); + installedPackages.add(info.PackageName); + } else { + notInstalledPackages.add(info.PackageName); + } + } } } return list; } private static PackageInfo firstInfo() { - for (Map.Entry entry : infos().entrySet()) { - if (!entry.getValue()) { - return entry.getKey(); + synchronized (ourInfos) { + for (Map.Entry entry : ourInfos.entrySet()) { + if ((entry.getValue() & FLAG_INSTALLED_ONLY) == 0) { + return entry.getKey(); + } } } throw new RuntimeException("There are no available dictionary infos"); @@ -132,9 +207,11 @@ public abstract class DictionaryUtil { final ZLStringOption option = singleWord ? singleWordTranslatorOption() : multiWordTranslatorOption(); final String id = option.getValue(); - for (PackageInfo info : infos().keySet()) { - if (info.Id.equals(id)) { - return info; + synchronized (ourInfos) { + for (PackageInfo info : ourInfos.keySet()) { + if (info.Id.equals(id)) { + return info; + } } } return firstInfo(); diff --git a/src/org/geometerplus/android/fbreader/FBReader.java b/src/org/geometerplus/android/fbreader/FBReader.java index b55615f9d..d7df13f4e 100644 --- a/src/org/geometerplus/android/fbreader/FBReader.java +++ b/src/org/geometerplus/android/fbreader/FBReader.java @@ -102,6 +102,10 @@ public final class FBReader extends ZLAndroidActivity { @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); + + DictionaryUtil.init(this); + + final FBReaderApp fbReader = (FBReaderApp)FBReaderApp.Instance(); final ZLAndroidLibrary zlibrary = (ZLAndroidLibrary)ZLibrary.Instance(); myFullScreenFlag = zlibrary.ShowStatusBarOption.getValue() ? 0 : WindowManager.LayoutParams.FLAG_FULLSCREEN; @@ -109,7 +113,6 @@ public final class FBReader extends ZLAndroidActivity { WindowManager.LayoutParams.FLAG_FULLSCREEN, myFullScreenFlag ); - final FBReaderApp fbReader = (FBReaderApp)FBReaderApp.Instance(); if (fbReader.getPopupById(TextSearchPopup.ID) == null) { new TextSearchPopup(fbReader); } diff --git a/src/org/geometerplus/android/fbreader/preferences/DictionaryPreference.java b/src/org/geometerplus/android/fbreader/preferences/DictionaryPreference.java index 93f8f2eb5..dd355389f 100644 --- a/src/org/geometerplus/android/fbreader/preferences/DictionaryPreference.java +++ b/src/org/geometerplus/android/fbreader/preferences/DictionaryPreference.java @@ -26,17 +26,15 @@ import android.content.Context; import org.geometerplus.zlibrary.core.options.ZLStringOption; import org.geometerplus.zlibrary.core.resources.ZLResource; -import org.geometerplus.android.fbreader.DictionaryUtil; import org.geometerplus.android.fbreader.PackageInfo; class DictionaryPreference extends ZLStringListPreference { private final ZLStringOption myOption; - DictionaryPreference(Context context, ZLResource resource, String resourceKey, ZLStringOption dictionaryOption) { + DictionaryPreference(Context context, ZLResource resource, String resourceKey, ZLStringOption dictionaryOption, List infos) { super(context, resource, resourceKey); myOption = dictionaryOption; - final List infos = DictionaryUtil.dictionaryInfos(context); final String[] values = new String[infos.size()]; final String[] texts = new String[infos.size()]; diff --git a/src/org/geometerplus/android/fbreader/preferences/PreferenceActivity.java b/src/org/geometerplus/android/fbreader/preferences/PreferenceActivity.java index b3c11a163..ee096cc35 100644 --- a/src/org/geometerplus/android/fbreader/preferences/PreferenceActivity.java +++ b/src/org/geometerplus/android/fbreader/preferences/PreferenceActivity.java @@ -391,13 +391,15 @@ public class PreferenceActivity extends ZLPreferenceActivity { this, dictionaryScreen.Resource, "dictionary", - DictionaryUtil.singleWordTranslatorOption() + DictionaryUtil.singleWordTranslatorOption(), + DictionaryUtil.dictionaryInfos(this, true) )); dictionaryScreen.addPreference(new DictionaryPreference( this, dictionaryScreen.Resource, "translator", - DictionaryUtil.multiWordTranslatorOption() + DictionaryUtil.multiWordTranslatorOption(), + DictionaryUtil.dictionaryInfos(this, false) )); dictionaryScreen.addPreference(new ZLBooleanPreference( this, diff --git a/src/org/geometerplus/android/fbreader/preferences/ZLStringListPreference.java b/src/org/geometerplus/android/fbreader/preferences/ZLStringListPreference.java index d3a2935a9..83e391cc8 100644 --- a/src/org/geometerplus/android/fbreader/preferences/ZLStringListPreference.java +++ b/src/org/geometerplus/android/fbreader/preferences/ZLStringListPreference.java @@ -50,25 +50,21 @@ abstract class ZLStringListPreference extends ListPreference { } protected final boolean setInitialValue(String value) { - if (value == null) { - return false; - } - // throws NPE in some cases (?) - //final int index = findIndexOfValue(value); - int index = -1; + int index = 0; + boolean found = false;; final CharSequence[] entryValues = getEntryValues(); - for (int i = 0; i < entryValues.length; ++i) { - if (value.equals(entryValues[i])) { - index = i; - break; + if (value != null) { + for (int i = 0; i < entryValues.length; ++i) { + if (value.equals(entryValues[i])) { + index = i; + found = true; + break; + } } } - if (index >= 0) { - setValueIndex(index); - setSummary(getEntry()); - return true; - } - return false; + setValueIndex(index); + setSummary(getEntry()); + return found; } @Override