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