mirror of
https://github.com/geometer/FBReaderJ.git
synced 2025-10-06 03:50:19 +02:00
Merge branch 'dict_api' into master-catalogs
This commit is contained in:
commit
43b0f70590
15 changed files with 510 additions and 9176 deletions
|
@ -246,5 +246,6 @@
|
|||
</intent-filter>
|
||||
</receiver>
|
||||
<activity android:name="org.geometerplus.android.fbreader.tips.TipsActivity" android:theme="@style/FBReader.Dialog" android:configChanges="orientation|keyboardHidden|screenSize"/>
|
||||
<activity android:name="com.paragon.dictionary.fbreader.OpenDictionaryActivity" android:theme="@style/FBReader.Transparent" android:configChanges="orientation|keyboardHidden|screenSize"/>
|
||||
</application>
|
||||
</manifest>
|
||||
|
|
|
@ -246,5 +246,6 @@
|
|||
</intent-filter>
|
||||
</receiver>
|
||||
<activity android:name="org.geometerplus.android.fbreader.tips.TipsActivity" android:theme="@style/FBReader.Dialog" android:configChanges="orientation|keyboardHidden|screenSize"/>
|
||||
<activity android:name="com.paragon.dictionary.fbreader.OpenDictionaryActivity" android:theme="@style/FBReader.Transparent" android:configChanges="orientation|keyboardHidden|screenSize"/>
|
||||
</application>
|
||||
</manifest>
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
===== 1.9 (Sep ??, 2013) =====
|
||||
* Dictionary support: added OpenDictionary support (code provided by Paragon Software), better integration with SlovoEd dictionaries
|
||||
* Dictionary support: fixed ColorDict 3 integration
|
||||
* Dictionary support: added Lingvo integration
|
||||
* mobi: added support for <div> & <mbp:pagebreak> tags
|
||||
* ePub: fixed reading of files generated from LibreOffice
|
||||
* ePub: no empty paragraphs before/after the cover
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<dictionaries>
|
||||
<dictionary
|
||||
id="ColorDict"
|
||||
title="ColorDict 3"
|
||||
title="ColorDict 3"
|
||||
package="com.socialnmobile.colordict"
|
||||
class=".activity.Main"
|
||||
action="colordict.intent.action.SEARCH"
|
||||
|
@ -12,7 +12,7 @@
|
|||
/>
|
||||
<dictionary
|
||||
id="ColorDict2"
|
||||
title="ColorDict Old Style"
|
||||
title="ColorDict Old Style"
|
||||
package="com.socialnmobile.colordict"
|
||||
class=".activity.Main"
|
||||
action="android.intent.action.SEARCH"
|
||||
|
@ -31,12 +31,23 @@
|
|||
/>
|
||||
<dictionary
|
||||
id="Free Dictionary . org"
|
||||
title="Free Dictionary . org"
|
||||
package="org.freedictionary"
|
||||
class=".MainActivity"
|
||||
action="android.intent.action.VIEW"
|
||||
pattern="%s"
|
||||
list="always"
|
||||
/>
|
||||
<dictionary
|
||||
id="ABBYY Lingvo"
|
||||
title="ABBYY Lingvo"
|
||||
package="com.abbyy.mobile.lingvo.market"
|
||||
action="com.abbyy.mobile.lingvo.intent.action.TRANSLATE"
|
||||
dataKey="com.abbyy.mobile.lingvo.intent.extra.TEXT"
|
||||
pattern="%s"
|
||||
role="dictionary"
|
||||
supportsTargetLanguage="true"
|
||||
/>
|
||||
<dictionary
|
||||
id="Lingo Quiz Lite"
|
||||
package="mnm.lite.lingoquiz"
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -646,6 +646,7 @@
|
|||
<node name="summary" value="Dictionary settings"/>
|
||||
<node name="dictionary" value="Dictionary"/>
|
||||
<node name="translator" value="Translator"/>
|
||||
<node name="targetLanguage" value="Language to translate to"/>
|
||||
<node name="tappingAction" value="Long tapping action">
|
||||
<node name="doNothing" value="Long tapping does nothing"/>
|
||||
<node name="selectSingleWord" value="Long tapping selects single word"/>
|
||||
|
|
|
@ -45,10 +45,10 @@ void ZLLogger::print(const std::string &className, const std::string &message) c
|
|||
m.replace(index, 1, "%%");
|
||||
}
|
||||
if (className == DEFAULT_CLASS) {
|
||||
__android_log_print(ANDROID_LOG_WARN, "ZLLogger", m.c_str());
|
||||
__android_log_print(ANDROID_LOG_WARN, "ZLLogger", "%s", m.c_str());
|
||||
} else {
|
||||
if (myRegisteredClasses.find(className) != myRegisteredClasses.end()) {
|
||||
__android_log_print(ANDROID_LOG_WARN, className.c_str(), m.c_str());
|
||||
__android_log_print(ANDROID_LOG_WARN, className.c_str(), "%s", m.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
BIN
libs/LingvoIntegration_2.5.2.12.jar
Normal file
BIN
libs/LingvoIntegration_2.5.2.12.jar
Normal file
Binary file not shown.
BIN
libs/open-dictionary-api-1.2.1.jar
Normal file
BIN
libs/open-dictionary-api-1.2.1.jar
Normal file
Binary file not shown.
50
res/layout/opendictionary_flyout.xml
Normal file
50
res/layout/opendictionary_flyout.xml
Normal file
|
@ -0,0 +1,50 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TableLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#00000000" style="@style/FBReader.Dialog" android:alignmentMode="alignMargins"
|
||||
>
|
||||
<TableRow
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="fill_parent" android:id="@+id/top_row"
|
||||
/>
|
||||
<TableRow
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent" android:layout_weight="0" android:background="#3c3f41"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Dicitonary Title"
|
||||
android:id="@+id/opendictionary_title_label" android:layout_row="0" android:layout_column="0" android:layout_gravity="center_vertical|left"
|
||||
android:textSize="18dp" android:textStyle="bold" android:textColor="#d5d5d5"
|
||||
android:layout_marginLeft="8dp" android:ellipsize="end" android:singleLine="true"
|
||||
android:layout_weight="1"
|
||||
/>
|
||||
<ImageButton
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/opendictionary_open_button" android:layout_row="0" android:layout_column="1"
|
||||
android:layout_gravity="center_vertical|right" android:src="@android:drawable/ic_menu_view"
|
||||
android:layout_weight="0"
|
||||
/>
|
||||
</TableRow>
|
||||
<TableRow
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent" android:layout_weight="2" android:background="#3c3f41"
|
||||
>
|
||||
<WebView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/opendictionary_article_view" android:layout_column="0" android:layout_span="2"
|
||||
android:longClickable="false"
|
||||
android:paddingBottom="12dp" android:paddingRight="4dp" android:paddingLeft="4dp"
|
||||
android:background="#3c3f41" android:layout_weight="1"
|
||||
/>
|
||||
</TableRow>
|
||||
<TableRow
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent" android:id="@+id/bottom_row"
|
||||
/>
|
||||
</TableLayout>
|
|
@ -3,4 +3,8 @@
|
|||
</style>
|
||||
<style name="FBReader.Dialog" parent="android:Theme.Dialog">
|
||||
</style>
|
||||
<color name="transparent">#00000000</color>
|
||||
<style name="FBReader.Transparent" parent="android:Theme.Translucent.NoTitleBar">
|
||||
<item name="android:windowBackground">@color/transparent</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
|
185
src/com/paragon/dictionary/fbreader/OpenDictionaryActivity.java
Normal file
185
src/com/paragon/dictionary/fbreader/OpenDictionaryActivity.java
Normal file
|
@ -0,0 +1,185 @@
|
|||
/*
|
||||
* Copyright (C) 2013 Paragon Software Group
|
||||
* Author: Andrey Tumanov <Andrey_Tumanov@penreader.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
package com.paragon.dictionary.fbreader;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Bundle;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.webkit.WebView;
|
||||
import android.widget.*;
|
||||
|
||||
import com.paragon.open.dictionary.api.*;
|
||||
|
||||
import org.geometerplus.zlibrary.ui.android.R;
|
||||
|
||||
public class OpenDictionaryActivity extends Activity {
|
||||
public final static String OPEN_DICTIONARY_QUERY_KEY = "open_dictionary_query";
|
||||
public final static String OPEN_DICTIONARY_HEIGHT_KEY = "open_dictionary_height";
|
||||
public final static String OPEN_DICTIONARY_GRAVITY_KEY = "open_dictionary_gravity";
|
||||
|
||||
private WebView myArticleView = null;
|
||||
private TextView myTitleLabel = null;
|
||||
private ImageButton myOpenDictionaryButton = null;
|
||||
private String myQuery = null;
|
||||
private int myHeight;
|
||||
private int myGravity;
|
||||
private static Dictionary ourDictionary = null;
|
||||
|
||||
static void setDictionary(Dictionary dictionary) {
|
||||
ourDictionary = dictionary;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.opendictionary_flyout);
|
||||
|
||||
myArticleView = (WebView) findViewById(R.id.opendictionary_article_view);
|
||||
myTitleLabel = (TextView) findViewById(R.id.opendictionary_title_label);
|
||||
myOpenDictionaryButton = (ImageButton) findViewById(R.id.opendictionary_open_button);
|
||||
|
||||
myOpenDictionaryButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
finish();
|
||||
openTextInDictionary(myQuery);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
myQuery = getIntent().getStringExtra(OPEN_DICTIONARY_QUERY_KEY);
|
||||
if (myQuery == null)
|
||||
myQuery = "";
|
||||
myHeight = getIntent().getIntExtra(OPEN_DICTIONARY_HEIGHT_KEY, -1);
|
||||
myGravity = getIntent().getIntExtra(OPEN_DICTIONARY_GRAVITY_KEY, android.view.Gravity.BOTTOM);
|
||||
setViewSize(myHeight, myGravity);
|
||||
|
||||
myArticleView.loadData("", "text/text", "UTF-8");
|
||||
if (ourDictionary != null) {
|
||||
myTitleLabel.setText(ourDictionary.getName());
|
||||
Log.d("FBReader", "OpenDictionaryActivity: get translation as text");
|
||||
ourDictionary.getTranslationAsText(myQuery, TranslateMode.SHORT, TranslateFormat.HTML, new Dictionary.TranslateAsTextListener() {
|
||||
@Override
|
||||
public void onComplete(String s, TranslateMode translateMode) {
|
||||
final String url = saveArticle(s.replace("</BODY>", "<br><br></BODY>"), getApplicationContext());
|
||||
if (url == null || url.isEmpty())
|
||||
openTextInDictionary(myQuery);
|
||||
else
|
||||
myArticleView.loadUrl(url);
|
||||
Log.d("FBReader", "OpenDictionaryActivity: translation ready");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWordNotFound(ArrayList<String> similarWords) {
|
||||
finish();
|
||||
openTextInDictionary(myQuery);
|
||||
Log.d("FBReader", "OpenDictionaryActivity: word not found");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(com.paragon.open.dictionary.api.Error error) {
|
||||
finish();
|
||||
Log.e("FBReader", error.getName());
|
||||
Log.e("FBReader", error.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onIPCError(String s) {
|
||||
finish();
|
||||
Log.e("FBReader", s);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
|
||||
setViewSize(myHeight, myGravity);
|
||||
}
|
||||
|
||||
private void setViewSize(int height, int gravity) {
|
||||
final DisplayMetrics metrics = new DisplayMetrics();
|
||||
getWindowManager().getDefaultDisplay().getMetrics(metrics);
|
||||
|
||||
if (height < 0)
|
||||
height = metrics.heightPixels / 3;
|
||||
TableRow bottomRow = (TableRow)findViewById(R.id.bottom_row);
|
||||
TableRow topRow = (TableRow)findViewById(R.id.top_row);
|
||||
|
||||
View.OnTouchListener touchListener = new View.OnTouchListener() {
|
||||
@Override
|
||||
public boolean onTouch(View view, MotionEvent motionEvent) {
|
||||
finish();
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
topRow.setOnTouchListener(touchListener);
|
||||
bottomRow.setOnTouchListener(touchListener);
|
||||
|
||||
switch (gravity) {
|
||||
case android.view.Gravity.TOP:
|
||||
topRow.setMinimumHeight(0);
|
||||
bottomRow.setMinimumHeight(metrics.heightPixels - height);
|
||||
break;
|
||||
case android.view.Gravity.BOTTOM:
|
||||
default:
|
||||
bottomRow.setMinimumHeight(0);
|
||||
topRow.setMinimumHeight(metrics.heightPixels - height);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void openTextInDictionary(String text) {
|
||||
if (ourDictionary != null)
|
||||
ourDictionary.showTranslation(text);
|
||||
}
|
||||
|
||||
private String saveArticle(String data, Context context) {
|
||||
final String filename = "open_dictionary_article.html";
|
||||
final FileOutputStream outputStream;
|
||||
|
||||
try {
|
||||
outputStream = context.openFileOutput(filename, Context.MODE_PRIVATE);
|
||||
outputStream.write(data.getBytes());
|
||||
outputStream.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
|
||||
return "file://" + context.getFilesDir().getAbsolutePath() + "/" + filename;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Copyright (C) 2013 Paragon Software Group
|
||||
* Author: Andrey Tumanov <Andrey_Tumanov@penreader.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
package com.paragon.dictionary.fbreader;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.util.Log;
|
||||
|
||||
import com.paragon.open.dictionary.api.*;
|
||||
|
||||
import org.geometerplus.android.fbreader.DictionaryUtil;
|
||||
|
||||
public class OpenDictionaryFlyout {
|
||||
private final Direction myDirection;
|
||||
private final String myPackageName;
|
||||
|
||||
public OpenDictionaryFlyout(Dictionary dictionary) {
|
||||
myDirection = dictionary.getDirection();
|
||||
myPackageName = dictionary.getApplicationPackageName();
|
||||
}
|
||||
|
||||
private Dictionary getDictionary(final Context context) {
|
||||
if (myPackageName == null) {
|
||||
return null;
|
||||
}
|
||||
final OpenDictionaryAPI api = new OpenDictionaryAPI(context);
|
||||
HashSet<Dictionary> dictionaries = api.getDictionaries(myDirection);
|
||||
for (Dictionary dictionary : dictionaries) {
|
||||
if (myPackageName.equalsIgnoreCase(dictionary.getApplicationPackageName())) {
|
||||
return dictionary;
|
||||
}
|
||||
}
|
||||
Log.e("FBReader", "OpenDictionaryFlyout:getDictionary - Dictionary with direction [" +
|
||||
myDirection.toString() + "] and package name [" + myPackageName + "] not found");
|
||||
return null;
|
||||
}
|
||||
|
||||
public void showTranslation(final Activity activity, final String text, DictionaryUtil.PopupFrameMetric frameMetrics) {
|
||||
Log.d("FBReader", "OpenDictionaryFlyout:showTranslation");
|
||||
final Dictionary dictionary = getDictionary(activity);
|
||||
if (dictionary == null) {
|
||||
Log.e("FBReader", "OpenDictionaryFlyout:showTranslation - null dictionary received");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!dictionary.isTranslationAsTextSupported()) {
|
||||
dictionary.showTranslation(text);
|
||||
} else {
|
||||
OpenDictionaryActivity.setDictionary(dictionary);
|
||||
Intent intent = new Intent(activity, OpenDictionaryActivity.class);
|
||||
intent.putExtra(OpenDictionaryActivity.OPEN_DICTIONARY_QUERY_KEY, text);
|
||||
intent.putExtra(OpenDictionaryActivity.OPEN_DICTIONARY_HEIGHT_KEY, frameMetrics.Height);
|
||||
intent.putExtra(OpenDictionaryActivity.OPEN_DICTIONARY_GRAVITY_KEY, frameMetrics.Gravity);
|
||||
activity.startActivity(intent);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -25,9 +25,14 @@ import android.app.*;
|
|||
import android.content.*;
|
||||
import android.net.Uri;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.Gravity;
|
||||
|
||||
import com.abbyy.mobile.lingvo.api.MinicardContract;
|
||||
import com.paragon.dictionary.fbreader.OpenDictionaryFlyout;
|
||||
import com.paragon.open.dictionary.api.Dictionary;
|
||||
import com.paragon.open.dictionary.api.OpenDictionaryAPI;
|
||||
|
||||
import org.geometerplus.zlibrary.core.filesystem.ZLFile;
|
||||
import org.geometerplus.zlibrary.core.language.Language;
|
||||
import org.geometerplus.zlibrary.core.options.ZLStringOption;
|
||||
import org.geometerplus.zlibrary.core.resources.ZLResource;
|
||||
import org.geometerplus.zlibrary.core.xml.ZLXMLReaderAdapter;
|
||||
|
@ -49,11 +54,14 @@ public abstract class DictionaryUtil {
|
|||
private static ZLStringOption ourSingleWordTranslatorOption;
|
||||
private static ZLStringOption ourMultiWordTranslatorOption;
|
||||
|
||||
// TODO: use StringListOption instead
|
||||
public static final ZLStringOption TargetLanguageOption = new ZLStringOption("Dictionary", "TargetLanguage", Language.ANY_CODE);
|
||||
|
||||
// Map: dictionary info -> mode if package is not installed
|
||||
private static Map<PackageInfo,Integer> ourInfos =
|
||||
Collections.synchronizedMap(new LinkedHashMap<PackageInfo,Integer>());
|
||||
|
||||
public static class PackageInfo {
|
||||
public static abstract class PackageInfo {
|
||||
public final String Id;
|
||||
public final String PackageName;
|
||||
public final String ClassName;
|
||||
|
@ -63,7 +71,9 @@ public abstract class DictionaryUtil {
|
|||
public final String IntentKey;
|
||||
public final String IntentDataPattern;
|
||||
|
||||
PackageInfo(String id, String packageName, String className, String title, String intentAction, String intentKey, String intentDataPattern) {
|
||||
public final boolean SupportsTargetLanguageSetting;
|
||||
|
||||
PackageInfo(String id, String packageName, String className, String title, String intentAction, String intentKey, String intentDataPattern, boolean supportsTargetLanguageSetting) {
|
||||
Id = id;
|
||||
PackageName = packageName;
|
||||
ClassName = className;
|
||||
|
@ -72,9 +82,11 @@ public abstract class DictionaryUtil {
|
|||
IntentAction = intentAction;
|
||||
IntentKey = intentKey;
|
||||
IntentDataPattern = intentDataPattern;
|
||||
|
||||
SupportsTargetLanguageSetting = supportsTargetLanguageSetting;
|
||||
}
|
||||
|
||||
Intent getDictionaryIntent(String text) {
|
||||
final Intent getDictionaryIntent(String text) {
|
||||
final Intent intent = new Intent(IntentAction);
|
||||
if (PackageName != null) {
|
||||
if (ClassName != null) {
|
||||
|
@ -95,6 +107,63 @@ public abstract class DictionaryUtil {
|
|||
return intent.setData(Uri.parse(text));
|
||||
}
|
||||
}
|
||||
|
||||
abstract void open(String text, Activity context, PopupFrameMetric frameMetrics);
|
||||
}
|
||||
|
||||
private static class PlainPackageInfo extends PackageInfo {
|
||||
PlainPackageInfo(String id, String packageName, String className, String title, String intentAction, String intentKey, String intentDataPattern, boolean supportsTargetLanguageSetting) {
|
||||
super(id, packageName, className, title, intentAction, intentKey, intentDataPattern, supportsTargetLanguageSetting);
|
||||
}
|
||||
|
||||
@Override
|
||||
void open(String text, Activity context, PopupFrameMetric frameMetrics) {
|
||||
final Intent intent = getDictionaryIntent(text);
|
||||
try {
|
||||
if ("ABBYY Lingvo".equals(Id)) {
|
||||
intent.putExtra(MinicardContract.EXTRA_GRAVITY, frameMetrics.Gravity);
|
||||
intent.putExtra(MinicardContract.EXTRA_HEIGHT, frameMetrics.Height);
|
||||
intent.putExtra(MinicardContract.EXTRA_FORCE_LEMMATIZATION, true);
|
||||
intent.putExtra(MinicardContract.EXTRA_TRANSLATE_VARIANTS, true);
|
||||
intent.putExtra(MinicardContract.EXTRA_LIGHT_THEME, true);
|
||||
final String targetLanguage = TargetLanguageOption.getValue();
|
||||
if (!Language.ANY_CODE.equals(targetLanguage)) {
|
||||
intent.putExtra(MinicardContract.EXTRA_LANGUAGE_TO, targetLanguage);
|
||||
}
|
||||
} else if ("ColorDict".equals(Id)) {
|
||||
intent.putExtra(ColorDict3.HEIGHT, frameMetrics.Height);
|
||||
intent.putExtra(ColorDict3.GRAVITY, frameMetrics.Gravity);
|
||||
final ZLAndroidLibrary zlibrary = (ZLAndroidLibrary)ZLAndroidLibrary.Instance();
|
||||
intent.putExtra(ColorDict3.FULLSCREEN, !zlibrary.ShowStatusBarOption.getValue());
|
||||
}
|
||||
context.startActivity(intent);
|
||||
} catch (ActivityNotFoundException e) {
|
||||
installDictionaryIfNotInstalled(context, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class OpenDictionaryPackageInfo extends PackageInfo {
|
||||
final OpenDictionaryFlyout Flyout;
|
||||
|
||||
OpenDictionaryPackageInfo(Dictionary dictionary) {
|
||||
super(
|
||||
dictionary.getUID(),
|
||||
dictionary.getApplicationPackageName(),
|
||||
".Start",
|
||||
dictionary.getName(),
|
||||
null,
|
||||
null,
|
||||
"%s",
|
||||
false
|
||||
);
|
||||
Flyout = new OpenDictionaryFlyout(dictionary);
|
||||
}
|
||||
|
||||
@Override
|
||||
void open(String text, Activity context, PopupFrameMetric frameMetrics) {
|
||||
Flyout.showTranslation(context, text, frameMetrics);
|
||||
}
|
||||
}
|
||||
|
||||
private static class InfoReader extends ZLXMLReaderAdapter {
|
||||
|
@ -108,61 +177,33 @@ public abstract class DictionaryUtil {
|
|||
if ("dictionary".equals(tag)) {
|
||||
final String id = attributes.getValue("id");
|
||||
final String title = attributes.getValue("title");
|
||||
|
||||
int flags = FLAG_SHOW_AS_DICTIONARY | FLAG_SHOW_AS_TRANSLATOR;
|
||||
final String role = attributes.getValue("role");
|
||||
int flags;
|
||||
if ("dictionary".equals(role)) {
|
||||
flags = FLAG_SHOW_AS_DICTIONARY;
|
||||
} else if ("translator".equals(role)) {
|
||||
flags = FLAG_SHOW_AS_TRANSLATOR;
|
||||
} else {
|
||||
flags = FLAG_SHOW_AS_DICTIONARY | FLAG_SHOW_AS_TRANSLATOR;
|
||||
}
|
||||
if (!"always".equals(attributes.getValue("list"))) {
|
||||
flags |= FLAG_INSTALLED_ONLY;
|
||||
}
|
||||
ourInfos.put(new PackageInfo(
|
||||
ourInfos.put(new PlainPackageInfo(
|
||||
id,
|
||||
attributes.getValue("package"),
|
||||
attributes.getValue("class"),
|
||||
title != null ? title : id,
|
||||
attributes.getValue("action"),
|
||||
attributes.getValue("dataKey"),
|
||||
attributes.getValue("pattern")
|
||||
attributes.getValue("pattern"),
|
||||
"true".equals(attributes.getValue("supportsTargetLanguage"))
|
||||
), flags);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static class ParagonInfoReader extends ZLXMLReaderAdapter {
|
||||
private final Context myContext;
|
||||
private int myCounter;
|
||||
|
||||
ParagonInfoReader(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, info.getDictionaryIntent("test"), false)) {
|
||||
ourInfos.put(info, FLAG_SHOW_AS_DICTIONARY | FLAG_INSTALLED_ONLY);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static class BitKnightsInfoReader extends ZLXMLReaderAdapter {
|
||||
private final Context myContext;
|
||||
private int myCounter;
|
||||
|
@ -179,14 +220,15 @@ public abstract class DictionaryUtil {
|
|||
@Override
|
||||
public boolean startElementHandler(String tag, ZLStringMap attributes) {
|
||||
if ("dictionary".equals(tag)) {
|
||||
final PackageInfo info = new PackageInfo(
|
||||
final PackageInfo info = new PlainPackageInfo(
|
||||
"BK" + myCounter ++,
|
||||
attributes.getValue("package"),
|
||||
"com.bitknights.dict.ShareTranslateActivity",
|
||||
attributes.getValue("title"),
|
||||
Intent.ACTION_VIEW,
|
||||
null,
|
||||
"%s"
|
||||
"%s",
|
||||
false
|
||||
);
|
||||
if (PackageUtil.canBeStarted(myContext, info.getDictionaryIntent("test"), false)) {
|
||||
ourInfos.put(info, FLAG_SHOW_AS_DICTIONARY | FLAG_INSTALLED_ONLY);
|
||||
|
@ -210,13 +252,32 @@ public abstract class DictionaryUtil {
|
|||
String FULLSCREEN = "EXTRA_FULLSCREEN";
|
||||
}
|
||||
|
||||
private static void collectOpenDictionaries(Context context) {
|
||||
final SortedSet<Dictionary> dictionariesTreeSet =
|
||||
new TreeSet<Dictionary>(new Comparator<Dictionary>() {
|
||||
@Override
|
||||
public int compare(Dictionary lhs, Dictionary rhs) {
|
||||
return lhs.toString().compareTo(rhs.toString());
|
||||
}
|
||||
}
|
||||
);
|
||||
dictionariesTreeSet.addAll(
|
||||
new OpenDictionaryAPI(context).getDictionaries()
|
||||
);
|
||||
|
||||
for (Dictionary dict : dictionariesTreeSet) {
|
||||
final PackageInfo info = new OpenDictionaryPackageInfo(dict);
|
||||
ourInfos.put(info, FLAG_SHOW_AS_DICTIONARY);
|
||||
}
|
||||
}
|
||||
|
||||
public static void init(final Context context) {
|
||||
if (ourInfos.isEmpty()) {
|
||||
final Thread initThread = new Thread(new Runnable() {
|
||||
public void run() {
|
||||
new InfoReader().readQuietly(ZLFile.createFileByPath("dictionaries/main.xml"));
|
||||
new BitKnightsInfoReader(context).readQuietly(ZLFile.createFileByPath("dictionaries/bitknights.xml"));
|
||||
new ParagonInfoReader(context).readQuietly(ZLFile.createFileByPath("dictionaries/paragon.xml"));
|
||||
collectOpenDictionaries(context);
|
||||
}
|
||||
});
|
||||
initThread.setPriority(Thread.MIN_PRIORITY);
|
||||
|
@ -282,7 +343,7 @@ public abstract class DictionaryUtil {
|
|||
return ourMultiWordTranslatorOption;
|
||||
}
|
||||
|
||||
private static PackageInfo getCurrentDictionaryInfo(boolean singleWord) {
|
||||
public static PackageInfo getCurrentDictionaryInfo(boolean singleWord) {
|
||||
final ZLStringOption option = singleWord
|
||||
? singleWordTranslatorOption() : multiWordTranslatorOption();
|
||||
final String id = option.getValue();
|
||||
|
@ -296,6 +357,24 @@ public abstract class DictionaryUtil {
|
|||
return firstInfo();
|
||||
}
|
||||
|
||||
public static class PopupFrameMetric {
|
||||
public final int Height;
|
||||
public final int Gravity;
|
||||
|
||||
PopupFrameMetric(DisplayMetrics metrics, int selectionTop, int selectionBottom) {
|
||||
final int screenHeight = metrics.heightPixels;
|
||||
final int topSpace = selectionTop;
|
||||
final int bottomSpace = metrics.heightPixels - selectionBottom;
|
||||
final boolean showAtBottom = bottomSpace >= topSpace;
|
||||
final int space = (showAtBottom ? bottomSpace : topSpace) - metrics.densityDpi / 12;
|
||||
final int maxHeight = Math.min(metrics.densityDpi * 20 / 12, screenHeight * 2 / 3);
|
||||
final int minHeight = Math.min(metrics.densityDpi * 10 / 12, screenHeight * 2 / 3);
|
||||
|
||||
Height = Math.max(minHeight, Math.min(maxHeight, space));
|
||||
Gravity = showAtBottom ? android.view.Gravity.BOTTOM : android.view.Gravity.TOP;
|
||||
}
|
||||
}
|
||||
|
||||
public static void openTextInDictionary(Activity activity, String text, boolean singleWord, int selectionTop, int selectionBottom) {
|
||||
if (singleWord) {
|
||||
int start = 0;
|
||||
|
@ -308,28 +387,12 @@ public abstract class DictionaryUtil {
|
|||
text = text.substring(start, end);
|
||||
}
|
||||
|
||||
final PackageInfo info = getCurrentDictionaryInfo(singleWord);
|
||||
final Intent intent = info.getDictionaryIntent(text);
|
||||
try {
|
||||
if ("ColorDict".equals(info.Id)) {
|
||||
final DisplayMetrics metrics = new DisplayMetrics();
|
||||
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
|
||||
final int screenHeight = metrics.heightPixels;
|
||||
final int topSpace = selectionTop;
|
||||
final int bottomSpace = metrics.heightPixels - selectionBottom;
|
||||
final boolean showAtBottom = bottomSpace >= topSpace;
|
||||
final int space = (showAtBottom ? bottomSpace : topSpace) - 20;
|
||||
final int maxHeight = Math.min(400, screenHeight * 2 / 3);
|
||||
final int minHeight = Math.min(200, screenHeight * 2 / 3);
|
||||
intent.putExtra(ColorDict3.HEIGHT, Math.max(minHeight, Math.min(maxHeight, space)));
|
||||
intent.putExtra(ColorDict3.GRAVITY, showAtBottom ? Gravity.BOTTOM : Gravity.TOP);
|
||||
final ZLAndroidLibrary zlibrary = (ZLAndroidLibrary)ZLAndroidLibrary.Instance();
|
||||
intent.putExtra(ColorDict3.FULLSCREEN, !zlibrary.ShowStatusBarOption.getValue());
|
||||
}
|
||||
activity.startActivity(intent);
|
||||
} catch (ActivityNotFoundException e) {
|
||||
DictionaryUtil.installDictionaryIfNotInstalled(activity, singleWord);
|
||||
}
|
||||
final DisplayMetrics metrics = new DisplayMetrics();
|
||||
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
|
||||
final PopupFrameMetric frameMetrics =
|
||||
new PopupFrameMetric(metrics, selectionTop, selectionBottom);
|
||||
|
||||
getCurrentDictionaryInfo(singleWord).open(text, activity, frameMetrics);
|
||||
}
|
||||
|
||||
public static void openWordInDictionary(Activity activity, ZLTextWord word, ZLTextRegion region) {
|
||||
|
@ -338,25 +401,23 @@ public abstract class DictionaryUtil {
|
|||
);
|
||||
}
|
||||
|
||||
public static void installDictionaryIfNotInstalled(final Activity activity, boolean singleWord) {
|
||||
final PackageInfo info = getCurrentDictionaryInfo(singleWord);
|
||||
public static void installDictionaryIfNotInstalled(final Activity activity, final PackageInfo info) {
|
||||
if (PackageUtil.canBeStarted(activity, info.getDictionaryIntent("test"), false)) {
|
||||
return;
|
||||
}
|
||||
final PackageInfo dictionaryInfo = getCurrentDictionaryInfo(singleWord);
|
||||
|
||||
final ZLResource dialogResource = ZLResource.resource("dialog");
|
||||
final ZLResource buttonResource = dialogResource.getResource("button");
|
||||
final ZLResource installResource = dialogResource.getResource("installDictionary");
|
||||
new AlertDialog.Builder(activity)
|
||||
.setTitle(installResource.getResource("title").getValue())
|
||||
.setMessage(installResource.getResource("message").getValue().replace("%s", dictionaryInfo.Title))
|
||||
.setMessage(installResource.getResource("message").getValue().replace("%s", info.Title))
|
||||
.setIcon(0)
|
||||
.setPositiveButton(
|
||||
buttonResource.getResource("install").getValue(),
|
||||
new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
installDictionary(activity, dictionaryInfo);
|
||||
installDictionary(activity, info);
|
||||
}
|
||||
}
|
||||
)
|
||||
|
|
|
@ -20,13 +20,14 @@
|
|||
package org.geometerplus.android.fbreader.preferences;
|
||||
|
||||
import java.text.DecimalFormatSymbols;
|
||||
import java.util.Locale;
|
||||
import java.util.*;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.view.KeyEvent;
|
||||
|
||||
import org.geometerplus.zlibrary.core.application.ZLKeyBindings;
|
||||
import org.geometerplus.zlibrary.core.language.Language;
|
||||
import org.geometerplus.zlibrary.core.options.*;
|
||||
import org.geometerplus.zlibrary.core.resources.ZLResource;
|
||||
|
||||
|
@ -468,6 +469,28 @@ public class PreferenceActivity extends ZLPreferenceActivity {
|
|||
scrollingScreen.addOption(pageTurningOptions.Horizontal, "horizontal");
|
||||
|
||||
final Screen dictionaryScreen = createPreferenceScreen("dictionary");
|
||||
|
||||
final List<String> langCodes = ZLResource.languageCodes();
|
||||
final ArrayList<Language> languages = new ArrayList<Language>(langCodes.size() + 1);
|
||||
for (String code : langCodes) {
|
||||
languages.add(new Language(code));
|
||||
}
|
||||
Collections.sort(languages);
|
||||
languages.add(0, new Language(Language.ANY_CODE));
|
||||
final LanguagePreference targetLanguagePreference = new LanguagePreference(
|
||||
this, dictionaryScreen.Resource, "targetLanguage", languages
|
||||
) {
|
||||
@Override
|
||||
protected void init() {
|
||||
setInitialValue(DictionaryUtil.TargetLanguageOption.getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setLanguage(String code) {
|
||||
DictionaryUtil.TargetLanguageOption.setValue(code);
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
dictionaryScreen.addPreference(new DictionaryPreference(
|
||||
this,
|
||||
|
@ -475,7 +498,15 @@ public class PreferenceActivity extends ZLPreferenceActivity {
|
|||
"dictionary",
|
||||
DictionaryUtil.singleWordTranslatorOption(),
|
||||
DictionaryUtil.dictionaryInfos(this, true)
|
||||
));
|
||||
) {
|
||||
@Override
|
||||
protected void onDialogClosed(boolean result) {
|
||||
super.onDialogClosed(result);
|
||||
targetLanguagePreference.setEnabled(
|
||||
DictionaryUtil.getCurrentDictionaryInfo(true).SupportsTargetLanguageSetting
|
||||
);
|
||||
}
|
||||
});
|
||||
dictionaryScreen.addPreference(new DictionaryPreference(
|
||||
this,
|
||||
dictionaryScreen.Resource,
|
||||
|
@ -493,6 +524,10 @@ public class PreferenceActivity extends ZLPreferenceActivity {
|
|||
"navigateOverAllWords"
|
||||
));
|
||||
dictionaryScreen.addOption(fbReader.WordTappingActionOption, "tappingAction");
|
||||
dictionaryScreen.addPreference(targetLanguagePreference);
|
||||
targetLanguagePreference.setEnabled(
|
||||
DictionaryUtil.getCurrentDictionaryInfo(true).SupportsTargetLanguageSetting
|
||||
);
|
||||
|
||||
final Screen imagesScreen = createPreferenceScreen("images");
|
||||
imagesScreen.addOption(fbReader.ImageTappingActionOption, "tappingAction");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue