1
0
Fork 0
mirror of https://github.com/geometer/FBReaderJ.git synced 2025-10-06 03:50:19 +02:00

Merge branch 'master' into basket

This commit is contained in:
Nikolay Pultsin 2011-02-12 02:41:10 +00:00
commit 0271f24bf4
43 changed files with 551 additions and 300 deletions

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.geometerplus.zlibrary.ui.android" android:versionCode="9911" android:versionName="0.99.11" android:installLocation="auto">
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.geometerplus.zlibrary.ui.android" android:versionCode="9912" android:versionName="0.99.12" android:installLocation="auto">
<uses-sdk android:minSdkVersion="4" />
<supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:anyDensity="true" />
<uses-permission android:name="android.permission.INTERNET" />

View file

@ -1,3 +1,13 @@
===== 0.99.13 (??? ??, 2011) =====
* Color channel values in color dialog
* Fixed categories processing in feedbooks feed
===== 0.99.12 (Feb 09, 2011) =====
* Added support for more dictionaries (by Steffen Siebert)
* Option 'show status bar when menu becomes visible' (by Steffen Siebert)
* Litres: series list has been added
* Litres: recommendation list has been added
===== 0.99.11 (Feb 01, 2011) =====
* Galician translation has been added (by Miguel Anxo Bouzada)
* Czech translation has been updated (by Marek Pavelka)

View file

@ -1 +1 @@
0.99.11
0.99.12

102
assets/dictionaries.xml Normal file
View file

@ -0,0 +1,102 @@
<?xml version="1.0" encoding="utf-8"?>
<dictionaries>
<dictionary
id="ColorDict"
title="ColorDict 3"
action="colordict.intent.action.SEARCH"
dataKey="EXTRA_QUERY"
pattern="%s"
list="always"
/>
<dictionary
id="ColorDict2"
title="ColorDict Old Style"
package="com.socialnmobile.colordict"
class=".activity.Main"
action="android.intent.action.SEARCH"
dataKey="query"
pattern="%s"
list="always"
/>
<dictionary
id="Fora Dictionary"
package="com.ngc.fora"
class=".ForaDictionary"
action="android.intent.action.SEARCH"
dataKey="query"
pattern="%s"
list="always"
/>
<dictionary
id="Free Dictionary . org"
package="org.freedictionary"
class=".MainActivity"
action="android.intent.action.VIEW"
pattern="%s"
list="always"
/>
<dictionary
id="SlovoEd Deluxe German->English"
package="com.slovoed.noreg.english_german.deluxe"
class=".Start"
action="android.intent.action.VIEW"
pattern="%s/808464950"
list="installed"
/>
<dictionary
id="SlovoEd Deluxe English->German"
package="com.slovoed.noreg.english_german.deluxe"
class=".Start"
action="android.intent.action.VIEW"
pattern="%s/808464949"
list="installed"
/>
<dictionary
id="Langenscheidt Professional German->English"
package="com.slovoed.noreg.langenscheidt.professional.german_english"
class=".Start"
action="android.intent.action.VIEW"
pattern="%s/808661296"
list="installed"
/>
<dictionary
id="Langenscheidt Professional English->German"
package="com.slovoed.noreg.langenscheidt.professional.german_english"
class=".Start"
action="android.intent.action.VIEW"
pattern="%s/808661297"
list="installed"
/>
<dictionary
id="Duden - Deutsches Universalwoerterbuch"
package="com.slovoed.noreg.duden.duden_german_explanatory_dictionary"
class=".Start"
action="android.intent.action.VIEW"
pattern="%s/808596281"
list="installed"
/>
<dictionary
id="Merriam-Webster's Unabridged"
package="com.slovoed.noreg.merriam_webster.english_english_unabridged"
class=".Start"
action="android.intent.action.VIEW"
pattern="%s/808595524"
list="installed"
/>
<dictionary
id="SlovoEd Deluxe French->Russian"
package="com.slovoed.french_russian.deluxe"
class=".Start"
action="android.intent.action.VIEW"
pattern="%s/808532019"
list="installed"
/>
<dictionary
id="SlovoEd Deluxe Russian->French"
package="com.slovoed.french_russian.deluxe"
class=".Start"
action="android.intent.action.VIEW"
pattern="%s/808532018"
list="installed"
/>
</dictionaries>

View file

@ -240,6 +240,10 @@
<node name="summaryOn" value="Zobrazit stavový řádek v režimu čtení"/>
<node name="summaryOff" value="Skrýt stavový řádek v režimu čtení"/>
</node>
<node name="showStatusBarWhenMenuIsActive" value="Show status bar when menu is active" toBeTranslated="true">
<node name="summaryOn" value="Show status bar when menu becomes active" toBeTranslated="true"/>
<node name="summaryOff" value="Don't show status bar when menu becomes active" toBeTranslated="true"/>
</node>
</node>
<node name="text" value="Text">
<node name="summary" value="Písmo, dělení slov atd."/>

View file

@ -241,6 +241,10 @@
<node name="summaryOn" value="Statusbar im Lesemodus anzeigen."/>
<node name="summaryOff" value="Statusbar im Lesemodus verstecken."/>
</node>
<node name="showStatusBarWhenMenuIsActive" value="Show status bar when menu is active" toBeTranslated="true">
<node name="summaryOn" value="Show status bar when menu becomes active" toBeTranslated="true"/>
<node name="summaryOff" value="Don't show status bar when menu becomes active" toBeTranslated="true"/>
</node>
</node>
<node name="text" value="Text Darstellung">
<node name="summary" value="Zeichensatz, Silbentrennung, etc."/>

View file

@ -243,6 +243,10 @@
<node name="summaryOn" value="Show status bar in reading mode"/>
<node name="summaryOff" value="Hide status bar in reading mode"/>
</node>
<node name="showStatusBarWhenMenuIsActive" value="Show status bar when menu is active">
<node name="summaryOn" value="Show status bar when menu becomes active"/>
<node name="summaryOff" value="Don't show status bar when menu becomes active"/>
</node>
</node>
<node name="text" value="Text">
<node name="summary" value="Font, hyphenations, etc."/>

View file

@ -243,6 +243,10 @@
<node name="summaryOn" value="Afficher la barre de statut en mode lecture"/>
<node name="summaryOff" value="Cacher la barre de statut en mode lecture"/>
</node>
<node name="showStatusBarWhenMenuIsActive" value="Show status bar when menu is active" toBeTranslated="true">
<node name="summaryOn" value="Show status bar when menu becomes active" toBeTranslated="true"/>
<node name="summaryOff" value="Don't show status bar when menu becomes active" toBeTranslated="true"/>
</node>
</node>
<node name="text" value="Texte">
<node name="summary" value="Polices, césures, etc."/>

View file

@ -240,6 +240,10 @@
<node name="summaryOn" value="Mostrar a barra de estado en modo de lectura"/>
<node name="summaryOff" value="Agochar a barra de estado en modo de lectura"/>
</node>
<node name="showStatusBarWhenMenuIsActive" value="Show status bar when menu is active" toBeTranslated="true">
<node name="summaryOn" value="Show status bar when menu becomes active" toBeTranslated="true"/>
<node name="summaryOff" value="Don't show status bar when menu becomes active" toBeTranslated="true"/>
</node>
</node>
<node name="text" value="Texto">
<node name="summary" value="Tipo de letra, guionizado, etc."/>

View file

@ -240,6 +240,10 @@
<node name="summaryOn" value="Az állapotsor látszik olvasás közben"/>
<node name="summaryOff" value="Az állapotsor nem látszik olvasás közben"/>
</node>
<node name="showStatusBarWhenMenuIsActive" value="Show status bar when menu is active" toBeTranslated="true">
<node name="summaryOn" value="Show status bar when menu becomes active" toBeTranslated="true"/>
<node name="summaryOff" value="Don't show status bar when menu becomes active" toBeTranslated="true"/>
</node>
</node>
<node name="text" value="Szöveg">
<node name="summary" value="Betűtípus, elválasztás stb."/>

View file

@ -240,6 +240,10 @@
<node name="summaryOn" value="Mostra barra di stato in modalità lettura"/>
<node name="summaryOff" value="Nascondi barra di stato in modalità lettura"/>
</node>
<node name="showStatusBarWhenMenuIsActive" value="Show status bar when menu is active" toBeTranslated="true">
<node name="summaryOn" value="Show status bar when menu becomes active" toBeTranslated="true"/>
<node name="summaryOff" value="Don't show status bar when menu becomes active" toBeTranslated="true"/>
</node>
</node>
<node name="text" value="Text" toBeTranslated="true">
<node name="summary" value="Font, hyphenations, etc." toBeTranslated="true"/>

View file

@ -240,6 +240,10 @@
<node name="summaryOn" value="Toon statusbalk tijdens lezen"/>
<node name="summaryOff" value="Verberg statusbalk tijdens lezen"/>
</node>
<node name="showStatusBarWhenMenuIsActive" value="Show status bar when menu is active" toBeTranslated="true">
<node name="summaryOn" value="Show status bar when menu becomes active" toBeTranslated="true"/>
<node name="summaryOff" value="Don't show status bar when menu becomes active" toBeTranslated="true"/>
</node>
</node>
<node name="text" value="Tekst">
<node name="summary" value="Lettertype, Afbreken, etc."/>

View file

@ -239,6 +239,10 @@
<node name="summaryOn" value="Строка состояния видна во время чтения"/>
<node name="summaryOff" value="Строка состояния не видна во время чтения"/>
</node>
<node name="showStatusBarWhenMenuIsActive" value="Показывать строку состояния при активации меню">
<node name="summaryOn" value="Показывать строку состояния, когда меню появляется на экране"/>
<node name="summaryOff" value="Не показывать строку состояния, когда меню появляется на экране"/>
</node>
</node>
<node name="text" value="Текст">
<node name="summary" value="Шрифты, переносы, и т.д."/>

View file

@ -240,6 +240,10 @@
<node name="summaryOn" value="Рядок стану видно під час читання"/>
<node name="summaryOff" value="Рядок стану не видно під час читання"/>
</node>
<node name="showStatusBarWhenMenuIsActive" value="Show status bar when menu is active" toBeTranslated="true">
<node name="summaryOn" value="Show status bar when menu becomes active" toBeTranslated="true"/>
<node name="summaryOff" value="Don't show status bar when menu becomes active" toBeTranslated="true"/>
</node>
</node>
<node name="text" value="Text" toBeTranslated="true">
<node name="summary" value="Font, hyphenations, etc." toBeTranslated="true"/>

View file

@ -240,6 +240,10 @@
<node name="summaryOn" value="Hiện thanh trạng thái khi đọc"/>
<node name="summaryOff" value=" Ẩn thanh trạng thía khi đọc"/>
</node>
<node name="showStatusBarWhenMenuIsActive" value="Show status bar when menu is active" toBeTranslated="true">
<node name="summaryOn" value="Show status bar when menu becomes active" toBeTranslated="true"/>
<node name="summaryOff" value="Don't show status bar when menu becomes active" toBeTranslated="true"/>
</node>
</node>
<node name="text" value="Văn bản">
<node name="summary" value="Phông, tách chữ, v..v."/>

View file

@ -240,6 +240,10 @@
<node name="summaryOn" value="阅读模式下显示状态栏" />
<node name="summaryOff" value="阅读模式下隐藏状态栏" />
</node>
<node name="showStatusBarWhenMenuIsActive" value="Show status bar when menu is active" toBeTranslated="true">
<node name="summaryOn" value="Show status bar when menu becomes active" toBeTranslated="true"/>
<node name="summaryOff" value="Don't show status bar when menu becomes active" toBeTranslated="true"/>
</node>
</node>
<node name="text" value="文字">
<node name="summary" value="字体, 断字等等。"/>

View file

@ -27,8 +27,11 @@ import android.net.Uri;
import android.util.DisplayMetrics;
import android.view.Gravity;
import org.geometerplus.zlibrary.core.filesystem.ZLFile;
import org.geometerplus.zlibrary.core.options.ZLStringOption;
import org.geometerplus.zlibrary.core.resources.ZLResource;
import org.geometerplus.zlibrary.core.xml.ZLXMLReaderAdapter;
import org.geometerplus.zlibrary.core.xml.ZLStringMap;
import org.geometerplus.zlibrary.text.view.ZLTextWordRegion;
@ -43,6 +46,31 @@ public abstract class DictionaryUtil {
new LinkedHashMap<PackageInfo,Boolean>();
private static ZLStringOption ourDictionaryOption;
private static class InfoReader extends ZLXMLReaderAdapter {
@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");
ourDictionaryInfos.put(new PackageInfo(
id,
attributes.getValue("package"),
attributes.getValue("class"),
title != null ? title : id,
attributes.getValue("action"),
attributes.getValue("dataKey"),
attributes.getValue("pattern")
), !"always".equals(attributes.getValue("list")));
}
return false;
}
}
private interface ColorDict3 {
String ACTION = "colordict.intent.action.SEARCH";
String QUERY = "EXTRA_QUERY";
@ -58,60 +86,7 @@ public abstract class DictionaryUtil {
private static Map<PackageInfo,Boolean> infos() {
if (ourDictionaryInfos.isEmpty()) {
ourDictionaryInfos.put(new PackageInfo(
"ColorDict", // Id
null, // Package
null, // Class
"ColorDict 3", // Title
ColorDict3.ACTION,
ColorDict3.QUERY,
"%s"
), false);
ourDictionaryInfos.put(new PackageInfo(
"ColorDict2", // Id
"com.socialnmobile.colordict", // Package
"com.socialnmobile.colordict.activity.Main", // Class
"ColorDict Old Style", // Title
Intent.ACTION_SEARCH,
SearchManager.QUERY,
"%s"
), false);
ourDictionaryInfos.put(new PackageInfo(
"Fora Dictionary", // Id
"com.ngc.fora", // Package
"com.ngc.fora.ForaDictionary", // Class
"Fora Dictionary", // Title
Intent.ACTION_SEARCH,
SearchManager.QUERY,
"%s"
), false);
ourDictionaryInfos.put(new PackageInfo(
"Free Dictionary . org", // Id
"org.freedictionary", // Package
"org.freedictionary.MainActivity", // Class
"Free Dictionary . org", // Title
Intent.ACTION_VIEW,
null,
"%s"
), false);
ourDictionaryInfos.put(new PackageInfo(
"SlovoEd Deluxe German->English", // Id
"com.slovoed.noreg.english_german.deluxe", // Package
"com.slovoed.noreg.english_german.deluxe.Start", // Class
"SlovoEd Deluxe German->English", // Title
Intent.ACTION_VIEW,
null,
"%s/808464950"
), true);
ourDictionaryInfos.put(new PackageInfo(
"SlovoEd Deluxe English->German", // Id
"com.slovoed.noreg.english_german.deluxe", // Package
"com.slovoed.noreg.english_german.deluxe.Start", // Class
"SlovoEd Deluxe English->German", // Title
Intent.ACTION_VIEW,
null,
"%s/808464949"
), true);
new InfoReader().read(ZLFile.createFileByPath("dictionaries.xml"));
}
return ourDictionaryInfos;
}
@ -161,8 +136,12 @@ public abstract class DictionaryUtil {
public static Intent getDictionaryIntent(PackageInfo dictionaryInfo, String text) {
final Intent intent = new Intent(dictionaryInfo.IntentAction);
if (dictionaryInfo.PackageName != null) {
String cls = dictionaryInfo.ClassName;
if (cls != null && cls.startsWith(".")) {
cls = dictionaryInfo.PackageName + cls;
}
intent.setComponent(new ComponentName(
dictionaryInfo.PackageName, dictionaryInfo.ClassName
dictionaryInfo.PackageName, cls
));
}
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

View file

@ -26,7 +26,9 @@ import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;
import android.view.WindowManager;
import android.view.Window;
import android.widget.RelativeLayout;
import org.geometerplus.zlibrary.core.filesystem.ZLFile;
@ -103,10 +105,30 @@ public final class FBReader extends ZLAndroidActivity {
fbReader.addAction(ActionCode.CANCEL, new CancelAction(this, fbReader));
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
final ZLAndroidApplication application = ZLAndroidApplication.Instance();
if (!application.ShowStatusBarOption.getValue() &&
application.ShowStatusBarWhenMenuIsActiveOption.getValue()) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
}
return super.onPrepareOptionsMenu(menu);
}
@Override
public void onOptionsMenuClosed(Menu menu) {
super.onOptionsMenuClosed(menu);
final ZLAndroidApplication application = ZLAndroidApplication.Instance();
if (!application.ShowStatusBarOption.getValue() &&
application.ShowStatusBarWhenMenuIsActiveOption.getValue()) {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
}
}
@Override
protected void onNewIntent(Intent intent) {
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
final String pattern = intent.getStringExtra(SearchManager.QUERY);
final String pattern = intent.getStringExtra(SearchManager.QUERY);
final Handler successHandler = new Handler() {
public void handleMessage(Message message) {
ourTextSearchPanel.show(true);

View file

@ -74,7 +74,6 @@ class NetworkCatalogActions extends NetworkTreeActions {
final NetworkCatalogItem item = catalogTree.Item;
menu.setHeaderTitle(tree.getName());
final boolean isVisible = item.getVisibility() == ZLBoolean3.B3_TRUE;
boolean hasItems = false;
final String catalogUrl = item.URLByType.get(NetworkCatalogItem.URL_CATALOG);
@ -84,7 +83,7 @@ class NetworkCatalogActions extends NetworkTreeActions {
}
if (tree instanceof NetworkCatalogRootTree) {
if (isVisible) {
if (item.getVisibility() == ZLBoolean3.B3_TRUE) {
final NetworkAuthenticationManager mgr = item.Link.authenticationManager();
if (mgr != null) {
if (mgr.mayBeAuthorised(false)) {
@ -115,14 +114,9 @@ class NetworkCatalogActions extends NetworkTreeActions {
}
}
if (!isVisible && !hasItems) {
switch (item.Visibility) {
case NetworkCatalogItem.VISIBLE_LOGGED_USER:
if (item.Link.authenticationManager() != null) {
addMenuItem(menu, SIGNIN_ITEM_ID, "signIn");
}
break;
}
if (item.getVisibility() == ZLBoolean3.B3_UNDEFINED &&
!hasItems && item.Link.authenticationManager() != null) {
addMenuItem(menu, SIGNIN_ITEM_ID, "signIn");
}
}
@ -136,15 +130,9 @@ class NetworkCatalogActions extends NetworkTreeActions {
if (item.URLByType.get(NetworkCatalogItem.URL_HTML_PAGE) != null) {
return OPEN_IN_BROWSER_ITEM_ID;
}
if (item.getVisibility() != ZLBoolean3.B3_TRUE) {
switch (item.Visibility) {
case NetworkCatalogItem.VISIBLE_LOGGED_USER:
if (item.Link.authenticationManager() != null) {
return SIGNIN_ITEM_ID;
}
break;
}
return TREE_NO_ACTION;
if (item.getVisibility() == ZLBoolean3.B3_UNDEFINED &&
item.Link.authenticationManager() != null) {
return SIGNIN_ITEM_ID;
}
return TREE_NO_ACTION;
}
@ -208,22 +196,21 @@ class NetworkCatalogActions extends NetworkTreeActions {
private boolean consumeByVisibility(final NetworkBaseActivity activity, final NetworkTree tree, final int actionCode) {
final NetworkCatalogTree catalogTree = (NetworkCatalogTree) tree;
if (catalogTree.Item.getVisibility() == ZLBoolean3.B3_TRUE) {
return false;
}
switch (catalogTree.Item.Visibility) {
case NetworkCatalogItem.VISIBLE_LOGGED_USER:
NetworkDialog.show(activity, NetworkDialog.DIALOG_AUTHENTICATION, ((NetworkCatalogTree)tree).Item.Link, new Runnable() {
public void run() {
if (catalogTree.Item.getVisibility() != ZLBoolean3.B3_TRUE) {
return;
switch (catalogTree.Item.getVisibility()) {
case B3_TRUE:
return false;
case B3_UNDEFINED:
NetworkDialog.show(activity, NetworkDialog.DIALOG_AUTHENTICATION, ((NetworkCatalogTree)tree).Item.Link, new Runnable() {
public void run() {
if (catalogTree.Item.getVisibility() != ZLBoolean3.B3_TRUE) {
return;
}
if (actionCode != SIGNIN_ITEM_ID) {
runAction(activity, tree, actionCode);
}
}
if (actionCode != SIGNIN_ITEM_ID) {
runAction(activity, tree, actionCode);
}
}
});
break;
});
break;
}
return true;
}

View file

@ -51,9 +51,27 @@ public class PreferenceActivity extends ZLPreferenceActivity {
}
directoriesScreen.addOption(Paths.WallpapersDirectoryOption(), "wallpapers");
final ZLPreferenceSet statusBarPreferences = new ZLPreferenceSet();
final Screen appearanceScreen = createPreferenceScreen("appearance");
appearanceScreen.addOption(androidApp.AutoOrientationOption, "autoOrientation");
appearanceScreen.addOption(androidApp.ShowStatusBarOption, "showStatusBar");
appearanceScreen.addPreference(
new ZLBooleanPreference(
this, androidApp.ShowStatusBarOption, appearanceScreen.Resource, "showStatusBar"
) {
@Override
public void onClick() {
super.onClick();
statusBarPreferences.setEnabled(!isChecked());
}
}
);
statusBarPreferences.add(
appearanceScreen.addOption(
androidApp.ShowStatusBarWhenMenuIsActiveOption,
"showStatusBarWhenMenuIsActive"
)
);
statusBarPreferences.setEnabled(!androidApp.ShowStatusBarOption.getValue());
final Screen textScreen = createPreferenceScreen("text");
final ZLTextStyleCollection collection = ZLTextStyleCollection.Instance();

View file

@ -39,13 +39,13 @@ class ZLBoolean3Preference extends ZLStringListPreference {
setList(new String[] { ON, OFF, UNCHANGED });
switch (option.getValue()) {
case ZLBoolean3.B3_TRUE:
case B3_TRUE:
setInitialValue(ON);
break;
case ZLBoolean3.B3_FALSE:
case B3_FALSE:
setInitialValue(OFF);
break;
case ZLBoolean3.B3_UNDEFINED:
case B3_UNDEFINED:
setInitialValue(UNCHANGED);
break;
}

View file

@ -61,7 +61,7 @@ class ZLColorPreference extends DialogPreference implements ZLPreference {
slider.setProgressDrawable(new SeekBarDrawable(
slider.getProgressDrawable(),
ZLResource.resource("color").getResource(resourceKey).getValue(),
value < 128
slider
));
return slider;
}
@ -135,13 +135,15 @@ class ZLColorPreference extends DialogPreference implements ZLPreference {
}
static class SeekBarDrawable extends Drawable {
private final SeekBar mySlider;
private final Drawable myBase;
private final String myText;
private final Paint myPaint;
private final Paint myOutlinePaint;
private boolean myLabelOnRight;
public SeekBarDrawable(Drawable base, String text, boolean labelOnRight) {
public SeekBarDrawable(Drawable base, String text, SeekBar slider) {
mySlider = slider;
myBase = base;
myText = text;
@ -155,7 +157,7 @@ class ZLColorPreference extends DialogPreference implements ZLPreference {
myOutlinePaint.setStrokeWidth(3);
myOutlinePaint.setColor(0xFFAAAAAA);
myLabelOnRight = labelOnRight;
myLabelOnRight = mySlider.getProgress() < 128;
}
@Override
@ -194,11 +196,12 @@ class ZLColorPreference extends DialogPreference implements ZLPreference {
myOutlinePaint.setTextSize(textSize);
final Rect textBounds = new Rect();
myPaint.getTextBounds("a", 0, 1, textBounds);
final float textWidth = myOutlinePaint.measureText(myText);
final String text = myText + ": " + mySlider.getProgress();
final float textWidth = myOutlinePaint.measureText(text);
final float x = myLabelOnRight ? bounds.width() - textWidth - 6 : 6;
final float y = bounds.height() / 2 + textBounds.height();
canvas.drawText(myText, x, y, myOutlinePaint);
canvas.drawText(myText, x, y, myPaint);
canvas.drawText(text, x, y, myOutlinePaint);
canvas.drawText(text, x, y, myPaint);
}
@Override

View file

@ -24,27 +24,36 @@ import java.util.*;
import org.geometerplus.zlibrary.core.util.ZLBoolean3;
import org.geometerplus.zlibrary.core.network.ZLNetworkException;
import org.geometerplus.fbreader.network.authentication.NetworkAuthenticationManager;
public abstract class NetworkCatalogItem extends NetworkLibraryItem {
// catalog types:
public static final int CATALOG_OTHER = 0;
public static final int CATALOG_BY_AUTHORS = 1;
public static enum CatalogType {
OTHER,
BY_AUTHOR,
BY_SERIES
}
// catalog visibility types:
public static final int VISIBLE_ALWAYS = 1;
public static final int VISIBLE_LOGGED_USER = 2;
// catalog accessibility types:
public static enum Accessibility {
NEVER,
ALWAYS,
SIGNED_IN,
HAS_BOOKS
}
// URL type values:
public static final int URL_NONE = 0;
public static final int URL_CATALOG = 1;
public static final int URL_HTML_PAGE = 2;
public final int Visibility;
public final int CatalogType;
private final Accessibility myAccessibility;
private final CatalogType myCatalogType;
public final TreeMap<Integer, String> URLByType;
/**
* Creates new NetworkCatalogItem instance with <code>VISIBLE_ALWAYS</code> visibility and <code>CATALOG_OTHER</code> type.
* Creates new NetworkCatalogItem instance with <code>Accessibility.ALWAYS</code> accessibility and <code>CatalogType.OTHER</code> type.
*
* @param link corresponding NetworkLink object. Must be not <code>null</code>.
* @param title title of this library item. Must be not <code>null</code>.
@ -53,40 +62,40 @@ public abstract class NetworkCatalogItem extends NetworkLibraryItem {
* @param urlByType map contains URLs and their types. Must be not <code>null</code>.
*/
public NetworkCatalogItem(INetworkLink link, String title, String summary, String cover, Map<Integer,String> urlByType) {
this(link, title, summary, cover, urlByType, VISIBLE_ALWAYS, CATALOG_OTHER);
this(link, title, summary, cover, urlByType, Accessibility.ALWAYS, CatalogType.OTHER);
}
/**
* Creates new NetworkCatalogItem instance with specified visibility and <code>CATALOG_OTHER</code> type.
* Creates new NetworkCatalogItem instance with specified accessibility and <code>CatalogType.OTHER</code> type.
*
* @param link corresponding NetworkLink object. Must be not <code>null</code>.
* @param title title of this library item. Must be not <code>null</code>.
* @param summary description of this library item. Can be <code>null</code>.
* @param cover cover url. Can be <code>null</code>.
* @param urlByType map contains URLs and their types. Must be not <code>null</code>.
* @param visibility value defines when this library item will be shown in the network library.
* Can be one of the VISIBLE_* values.
* @param link corresponding NetworkLink object. Must be not <code>null</code>.
* @param title title of this library item. Must be not <code>null</code>.
* @param summary description of this library item. Can be <code>null</code>.
* @param cover cover url. Can be <code>null</code>.
* @param urlByType map contains URLs and their types. Must be not <code>null</code>.
* @param accessibility value defines when this library item will be accessible
* in the network library view.
*/
public NetworkCatalogItem(INetworkLink link, String title, String summary, String cover, Map<Integer, String> urlByType, int visibility) {
this(link, title, summary, cover, urlByType, visibility, CATALOG_OTHER);
public NetworkCatalogItem(INetworkLink link, String title, String summary, String cover, Map<Integer, String> urlByType, Accessibility accessibility) {
this(link, title, summary, cover, urlByType, accessibility, CatalogType.OTHER);
}
/**
* Creates new NetworkCatalogItem instance with specified visibility and type.
* Creates new NetworkCatalogItem instance with specified accessibility and type.
*
* @param link corresponding NetworkLink object. Must be not <code>null</code>.
* @param title title of this library item. Must be not <code>null</code>.
* @param summary description of this library item. Can be <code>null</code>.
* @param cover cover url. Can be <code>null</code>.
* @param urlByType map contains URLs and their types. Must be not <code>null</code>.
* @param visibility value defines when this library item will be shown in the network library.
* Can be one of the VISIBLE_* values.
* @param catalogType value defines type of this catalog. Can be one of the CATALOG_* values.
* @param link corresponding NetworkLink object. Must be not <code>null</code>.
* @param title title of this library item. Must be not <code>null</code>.
* @param summary description of this library item. Can be <code>null</code>.
* @param cover cover url. Can be <code>null</code>.
* @param urlByType map contains URLs and their types. Must be not <code>null</code>.
* @param accessibility value defines when this library item will be accessible
* in the network library view.
* @param catalogType value defines type of this catalog.
*/
public NetworkCatalogItem(INetworkLink link, String title, String summary, String cover, Map<Integer, String> urlByType, int visibility, int catalogType) {
public NetworkCatalogItem(INetworkLink link, String title, String summary, String cover, Map<Integer, String> urlByType, Accessibility accessibility, CatalogType catalogType) {
super(link, title, summary, cover);
Visibility = visibility;
CatalogType = catalogType;
myAccessibility = accessibility;
myCatalogType = catalogType;
URLByType = new TreeMap<Integer, String>(urlByType);
}
@ -113,21 +122,33 @@ public abstract class NetworkCatalogItem extends NetworkLibraryItem {
public void onDisplayItem() {
}
public int getVisibility() {
if (Visibility == VISIBLE_ALWAYS) {
return ZLBoolean3.B3_TRUE;
}
if (Visibility == VISIBLE_LOGGED_USER) {
if (Link.authenticationManager() == null) {
public final CatalogType getCatalogType() {
return myCatalogType;
}
public ZLBoolean3 getVisibility() {
final NetworkAuthenticationManager mgr = Link.authenticationManager();
switch (myAccessibility) {
default:
return ZLBoolean3.B3_FALSE;
}
try {
return Link.authenticationManager().isAuthorised(false) ?
ZLBoolean3.B3_TRUE : ZLBoolean3.B3_UNDEFINED;
} catch (ZLNetworkException e) {
return ZLBoolean3.B3_UNDEFINED;
}
case ALWAYS:
return ZLBoolean3.B3_TRUE;
case SIGNED_IN:
if (mgr == null) {
return ZLBoolean3.B3_FALSE;
}
try {
return mgr.isAuthorised(false) ?
ZLBoolean3.B3_TRUE : ZLBoolean3.B3_UNDEFINED;
} catch (ZLNetworkException e) {
return ZLBoolean3.B3_UNDEFINED;
}
case HAS_BOOKS:
if (mgr != null && mgr.purchasedBooks().size() > 0) {
return ZLBoolean3.B3_TRUE;
} else {
return ZLBoolean3.B3_FALSE;
}
}
return ZLBoolean3.B3_FALSE;
}
}

View file

@ -19,8 +19,7 @@
package org.geometerplus.fbreader.network.authentication;
import java.util.Map;
import java.util.HashMap;
import java.util.*;
import org.geometerplus.zlibrary.core.options.ZLStringOption;
import org.geometerplus.zlibrary.core.network.ZLNetworkException;
@ -97,6 +96,10 @@ public abstract class NetworkAuthenticationManager {
throw new ZLNetworkException(NetworkException.ERROR_UNSUPPORTED_OPERATION);
}
public List<NetworkBookItem> purchasedBooks() {
return Collections.emptyList();
}
public String currentAccount() {
return null;
}

View file

@ -286,11 +286,11 @@ public class LitResAuthenticationManager extends NetworkAuthenticationManager {
}
}
synchronized void collectPurchasedBooks(List<NetworkLibraryItem> list) {
list.addAll(myPurchasedBooks.values());
@Override
public synchronized List<NetworkBookItem> purchasedBooks() {
return new ArrayList(myPurchasedBooks.values());
}
@Override
public synchronized boolean needsInitialization() {
final String sid = mySidOption.getValue();
@ -361,11 +361,11 @@ public class LitResAuthenticationManager extends NetworkAuthenticationManager {
}
private void loadPurchasedBooksOnSuccess(LitResNetworkRequest purchasedBooksRequest) {
LitResXMLReader reader = (LitResXMLReader) purchasedBooksRequest.Reader;
LitResXMLReader reader = (LitResXMLReader)purchasedBooksRequest.Reader;
myPurchasedBooks.clear();
for (NetworkLibraryItem item: reader.Books) {
if (item instanceof NetworkBookItem) {
NetworkBookItem book = (NetworkBookItem) item;
NetworkBookItem book = (NetworkBookItem)item;
myPurchasedBooks.put(book.Id, book);
}
}
@ -390,7 +390,7 @@ public class LitResAuthenticationManager extends NetworkAuthenticationManager {
}
private void loadAccountOnSuccess(LitResNetworkRequest accountRequest) {
LitResPurchaseXMLReader reader = (LitResPurchaseXMLReader) accountRequest.Reader;
LitResPurchaseXMLReader reader = (LitResPurchaseXMLReader)accountRequest.Reader;
myAccount = BuyBookReference.price(reader.Account, "RUB");
}

View file

@ -26,20 +26,10 @@ import org.geometerplus.zlibrary.core.network.ZLNetworkException;
import org.geometerplus.fbreader.network.*;
public class LitResBookshelfItem extends NetworkCatalogItem {
private boolean myForceReload;
public LitResBookshelfItem(INetworkLink link, String title, String summary, String cover, Map<Integer, String> urlByType) {
super(link, title, summary, cover, urlByType);
}
public LitResBookshelfItem(INetworkLink link, String title, String summary, String cover, Map<Integer, String> urlByType, int visibility) {
super(link, title, summary, cover, urlByType, visibility);
}
public LitResBookshelfItem(INetworkLink link, String title, String summary, String cover, Map<Integer, String> urlByType, int visibility, int catalogType) {
super(link, title, summary, cover, urlByType, visibility, catalogType);
public LitResBookshelfItem(INetworkLink link, String title, String summary, String cover, Map<Integer, String> urlByType, Accessibility accessibility) {
super(link, title, summary, cover, urlByType, accessibility);
}
@Override
@ -49,7 +39,8 @@ public class LitResBookshelfItem extends NetworkCatalogItem {
@Override
public void loadChildren(NetworkOperationData.OnNewItemListener listener) throws ZLNetworkException {
LitResAuthenticationManager mgr = (LitResAuthenticationManager) Link.authenticationManager();
final LitResAuthenticationManager mgr =
(LitResAuthenticationManager)Link.authenticationManager();
// TODO: Maybe it's better to call isAuthorised(true) directly
// and let exception fly through???
@ -63,10 +54,10 @@ public class LitResBookshelfItem extends NetworkCatalogItem {
} finally {
myForceReload = true;
// TODO: implement asynchronous loading
LinkedList<NetworkLibraryItem> children = new LinkedList<NetworkLibraryItem>();
mgr.collectPurchasedBooks(children);
ArrayList<NetworkBookItem> children =
new ArrayList<NetworkBookItem>(mgr.purchasedBooks());
Collections.sort(children, new NetworkBookItemComparator());
for (NetworkLibraryItem item: children) {
for (NetworkLibraryItem item : children) {
listener.onNewItem(Link, item);
}
listener.commitItems(Link);

View file

@ -0,0 +1,52 @@
/*
* Copyright (C) 2010-2011 Geometer Plus <contact@geometerplus.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 org.geometerplus.fbreader.network.authentication.litres;
import java.util.Map;
import org.geometerplus.zlibrary.core.util.ZLNetworkUtil;
import org.geometerplus.fbreader.network.INetworkLink;
import org.geometerplus.fbreader.network.NetworkBookItem;
import org.geometerplus.fbreader.network.opds.OPDSCatalogItem;
public class LitResRecommendationsItem extends OPDSCatalogItem {
public LitResRecommendationsItem(INetworkLink link, String title, String summary, String cover, Map<Integer,String> urlByType, Accessibility accessibility) {
super(link, title, summary, cover, urlByType, accessibility, CatalogType.BY_SERIES);
}
@Override
protected String getUrl() {
final LitResAuthenticationManager mgr =
(LitResAuthenticationManager)Link.authenticationManager();
final StringBuilder builder = new StringBuilder();
boolean flag = false;
for (NetworkBookItem book : mgr.purchasedBooks()) {
if (flag) {
builder.append(',');
} else {
flag = true;
}
builder.append(book.Id);
}
return ZLNetworkUtil.appendParameter(URLByType.get(URL_CATALOG), "ids", builder.toString());
}
}

View file

@ -27,6 +27,7 @@ import org.geometerplus.zlibrary.core.util.ZLNetworkUtil;
import org.geometerplus.fbreader.network.*;
import org.geometerplus.fbreader.network.atom.*;
import org.geometerplus.fbreader.network.authentication.litres.LitResBookshelfItem;
import org.geometerplus.fbreader.network.authentication.litres.LitResRecommendationsItem;
class NetworkOPDSFeedReader implements OPDSFeedReader, OPDSConstants, MimeTypes {
private final String myBaseURL;
@ -73,7 +74,7 @@ class NetworkOPDSFeedReader implements OPDSFeedReader, OPDSConstants, MimeTypes
}
return false;
}
final OPDSNetworkLink opdsLink = (OPDSNetworkLink) myData.Link;
final OPDSNetworkLink opdsLink = (OPDSNetworkLink)myData.Link;
for (ATOMLink link: feed.Links) {
final String type = ZLNetworkUtil.filterMimeType(link.getType());
final String rel = opdsLink.relation(link.getRel(), type);
@ -139,7 +140,7 @@ class NetworkOPDSFeedReader implements OPDSFeedReader, OPDSConstants, MimeTypes
String id = null;
int idType = 0;
final OPDSNetworkLink opdsLink = (OPDSNetworkLink) myData.Link;
final OPDSNetworkLink opdsLink = (OPDSNetworkLink)myData.Link;
for (ATOMLink link: entry.Links) {
final String type = ZLNetworkUtil.filterMimeType(link.getType());
final String rel = opdsLink.relation(link.getRel(), type);
@ -188,10 +189,7 @@ class NetworkOPDSFeedReader implements OPDSFeedReader, OPDSConstants, MimeTypes
}
myData.LoadedIds.add(entry.Id.Uri);
final OPDSNetworkLink opdsLink = (OPDSNetworkLink) myData.Link;
if (opdsLink.getCondition(entry.Id.Uri) == OPDSNetworkLink.FeedCondition.NEVER) {
return tryInterrupt();
}
final OPDSNetworkLink opdsLink = (OPDSNetworkLink)myData.Link;
boolean hasBookLink = false;
for (ATOMLink link: entry.Links) {
final String type = ZLNetworkUtil.filterMimeType(link.getType());
@ -221,7 +219,7 @@ class NetworkOPDSFeedReader implements OPDSFeedReader, OPDSConstants, MimeTypes
private static final String AuthorsPrefix = "authors:";
private NetworkLibraryItem readBookItem(OPDSEntry entry) {
final OPDSNetworkLink opdsNetworkLink = (OPDSNetworkLink) myData.Link;
final OPDSNetworkLink opdsNetworkLink = (OPDSNetworkLink)myData.Link;
/*final String date;
if (entry.DCIssued != null) {
date = entry.DCIssued.getDateTime(true);
@ -231,9 +229,12 @@ class NetworkOPDSFeedReader implements OPDSFeedReader, OPDSConstants, MimeTypes
final LinkedList<String> tags = new LinkedList<String>();
for (ATOMCategory category: entry.Categories) {
String term = category.getTerm();
if (term != null) {
tags.add(term);
String label = category.getLabel();
if (label == null) {
label = category.getTerm();
}
if (label != null) {
tags.add(label);
}
}
@ -254,7 +255,7 @@ class NetworkOPDSFeedReader implements OPDSFeedReader, OPDSConstants, MimeTypes
cover = href;
}
} else if (BookReference.Type.BUY == referenceType) {
final OPDSLink opdsLink = (OPDSLink) link;
final OPDSLink opdsLink = (OPDSLink)link;
String price = null;
final OPDSPrice opdsPrice = opdsLink.selectBestPrice();
if (opdsPrice != null) {
@ -368,14 +369,14 @@ class NetworkOPDSFeedReader implements OPDSFeedReader, OPDSConstants, MimeTypes
}
private NetworkLibraryItem readCatalogItem(OPDSEntry entry) {
final OPDSNetworkLink opdsLink = (OPDSNetworkLink) myData.Link;
final OPDSNetworkLink opdsLink = (OPDSNetworkLink)myData.Link;
String coverURL = null;
String url = null;
boolean urlIsAlternate = false;
String htmlURL = null;
boolean litresCatalogue = false;
int catalogType = NetworkCatalogItem.CATALOG_OTHER;
for (ATOMLink link: entry.Links) {
String litresRel = null;
NetworkCatalogItem.CatalogType catalogType = NetworkCatalogItem.CatalogType.OTHER;
for (ATOMLink link : entry.Links) {
final String href = ZLNetworkUtil.url(myBaseURL, link.getHref());
final String type = ZLNetworkUtil.filterMimeType(link.getType());
final String rel = opdsLink.relation(link.getRel(), type);
@ -391,12 +392,13 @@ class NetworkOPDSFeedReader implements OPDSFeedReader, OPDSConstants, MimeTypes
url = href;
urlIsAlternate = true;
}
} else if (url == null
|| rel == null || rel.equals(REL_SUBSECTION)) {
} else if (url == null || rel == null || rel.equals(REL_SUBSECTION)) {
url = href;
urlIsAlternate = false;
if (REL_CATALOG_AUTHOR.equals(rel)) {
catalogType = NetworkCatalogItem.CATALOG_BY_AUTHORS;
catalogType = NetworkCatalogItem.CatalogType.BY_AUTHOR;
} else if (REL_CATALOG_SERIES.equals(rel)) {
catalogType = NetworkCatalogItem.CatalogType.BY_SERIES;
}
}
} else if (MIME_TEXT_HTML.equals(type)) {
@ -407,10 +409,8 @@ class NetworkOPDSFeedReader implements OPDSFeedReader, OPDSConstants, MimeTypes
htmlURL = href;
}
} else if (MIME_APP_LITRES.equals(type)) {
if (REL_BOOKSHELF.equals(rel)) {
litresCatalogue = true;
url = href; // FIXME: mimeType ???
}
litresRel = rel;
url = href;
}
}
@ -422,9 +422,6 @@ class NetworkOPDSFeedReader implements OPDSFeedReader, OPDSConstants, MimeTypes
htmlURL = null;
}
final boolean dependsOnAccount =
OPDSNetworkLink.FeedCondition.SIGNED_IN == opdsLink.getCondition(entry.Id.Uri);
final String annotation;
if (entry.Summary != null) {
annotation = entry.Summary.replace("\n", "");
@ -441,15 +438,28 @@ class NetworkOPDSFeedReader implements OPDSFeedReader, OPDSConstants, MimeTypes
if (htmlURL != null) {
urlMap.put(NetworkCatalogItem.URL_HTML_PAGE, htmlURL);
}
if (litresCatalogue) {
return new LitResBookshelfItem(
opdsLink,
entry.Title,
annotation,
coverURL,
urlMap,
dependsOnAccount ? NetworkCatalogItem.VISIBLE_LOGGED_USER : NetworkCatalogItem.VISIBLE_ALWAYS
);
if (litresRel != null) {
if (REL_BOOKSHELF.equals(litresRel)) {
return new LitResBookshelfItem(
opdsLink,
entry.Title,
annotation,
coverURL,
urlMap,
opdsLink.getCondition(entry.Id.Uri)
);
} else if (REL_RECOMMENDATIONS.equals(litresRel)) {
return new LitResRecommendationsItem(
opdsLink,
entry.Title,
annotation,
coverURL,
urlMap,
opdsLink.getCondition(entry.Id.Uri)
);
} else {
return null;
}
} else {
return new OPDSCatalogItem(
opdsLink,
@ -457,7 +467,7 @@ class NetworkOPDSFeedReader implements OPDSFeedReader, OPDSConstants, MimeTypes
annotation,
coverURL,
urlMap,
dependsOnAccount ? NetworkCatalogItem.VISIBLE_LOGGED_USER : NetworkCatalogItem.VISIBLE_ALWAYS,
opdsLink.getCondition(entry.Id.Uri),
catalogType
);
}

View file

@ -27,7 +27,7 @@ import org.geometerplus.zlibrary.core.network.ZLNetworkRequest;
import org.geometerplus.fbreader.network.*;
class OPDSCatalogItem extends NetworkCatalogItem {
public class OPDSCatalogItem extends NetworkCatalogItem {
static class State extends NetworkOperationData {
public String LastLoadedId;
public final HashSet<String> LoadedIds = new HashSet<String>();
@ -44,8 +44,8 @@ class OPDSCatalogItem extends NetworkCatalogItem {
myExtraData = extraData;
}
OPDSCatalogItem(INetworkLink link, String title, String summary, String cover, Map<Integer, String> urlByType, int visibility, int catalogType) {
super(link, title, summary, cover, urlByType, visibility, catalogType);
public OPDSCatalogItem(INetworkLink link, String title, String summary, String cover, Map<Integer, String> urlByType, Accessibility accessibility, CatalogType catalogType) {
super(link, title, summary, cover, urlByType, accessibility, catalogType);
myExtraData = null;
}
@ -70,6 +70,10 @@ class OPDSCatalogItem extends NetworkCatalogItem {
return myExtraData;
}
protected String getUrl() {
return URLByType.get(URL_CATALOG);
}
@Override
public final void loadChildren(NetworkOperationData.OnNewItemListener listener) throws ZLNetworkException {
OPDSNetworkLink opdsLink = (OPDSNetworkLink) Link;
@ -77,7 +81,7 @@ class OPDSCatalogItem extends NetworkCatalogItem {
myLoadingState = opdsLink.createOperationData(Link, listener);
ZLNetworkRequest networkRequest =
opdsLink.createNetworkData(URLByType.get(URL_CATALOG), myLoadingState);
opdsLink.createNetworkData(getUrl(), myLoadingState);
doLoadChildren(listener, networkRequest);
}

View file

@ -21,13 +21,14 @@ package org.geometerplus.fbreader.network.opds;
interface OPDSConstants {
// Feed level
String REL_BOOKSHELF = "http://opds-spec.org/bookshelf";
String REL_BOOKSHELF = "http://data.fbreader.org/rel/bookshelf";
String REL_RECOMMENDATIONS = "http://data.fbreader.org/rel/recommendations";
//String REL_SUBSCRIPTIONS = "http://opds-spec.org/subscriptions";
// Entry level / catalog types
String REL_CATALOG_AUTHOR = "http://data.fbreader.org/catalog/author";
String REL_CATALOG_SERIES = "http://data.fbreader.org/catalog/series";
String REL_SUBSECTION = "subsection";
// Entry level / acquisition links
@ -60,4 +61,5 @@ interface OPDSConstants {
// Entry level / OPDS Link Conditions
String REL_CONDITION_NEVER = "http://data.fbreader.org/condition/never";
String REL_CONDITION_SIGNED_IN = "http://data.fbreader.org/condition/signed-in";
String REL_CONDITION_HAS_BOOKS = "http://data.fbreader.org/condition/has-books";
}

View file

@ -36,10 +36,8 @@ import org.geometerplus.fbreader.Paths;
import org.geometerplus.fbreader.network.*;
import org.geometerplus.fbreader.network.atom.ATOMUpdated;
public class OPDSLinkReader {
static final String CATALOGS_URL = "http://data.fbreader.org/catalogs/generic-1.1.xml";
static final String CATALOGS_URL = "http://data.fbreader.org/catalogs/generic-1.2.xml";
public static ICustomNetworkLink createCustomLink(int id, String siteName, String title, String summary, String icon, Map<String, String> links) {
if (siteName == null || title == null || links.get(INetworkLink.URL_MAIN) == null) {

View file

@ -29,6 +29,7 @@ import org.geometerplus.zlibrary.core.xml.ZLStringMap;
import org.geometerplus.fbreader.network.INetworkLink;
import org.geometerplus.fbreader.network.NetworkLibrary;
import org.geometerplus.fbreader.network.NetworkCatalogItem;
import org.geometerplus.fbreader.network.atom.ATOMLink;
import org.geometerplus.fbreader.network.atom.ATOMUpdated;
import org.geometerplus.fbreader.network.authentication.NetworkAuthenticationManager;
@ -98,8 +99,9 @@ class OPDSLinkXMLReader extends OPDSXMLReader implements OPDSConstants, MimeType
final String language = entry.DCLanguage;
String icon = null;
final HashMap<String, String> links = new HashMap<String, String>();
final HashMap<String, Integer> urlConditions = new HashMap<String, Integer>();
final HashMap<String,String> links = new HashMap<String,String>();
final HashMap<String,NetworkCatalogItem.Accessibility> urlConditions =
new HashMap<String,NetworkCatalogItem.Accessibility>();
for (ATOMLink link: entry.Links) {
final String href = link.getHref();
final String type = ZLNetworkUtil.filterMimeType(link.getType());
@ -135,9 +137,11 @@ class OPDSLinkXMLReader extends OPDSXMLReader implements OPDSConstants, MimeType
} else if (rel == REL_LINK_RECOVER_PASSWORD) {
links.put(INetworkLink.URL_RECOVER_PASSWORD, href);
} else if (rel == REL_CONDITION_NEVER) {
urlConditions.put(href, OPDSNetworkLink.FeedCondition.NEVER);
urlConditions.put(href, NetworkCatalogItem.Accessibility.NEVER);
} else if (rel == REL_CONDITION_SIGNED_IN) {
urlConditions.put(href, OPDSNetworkLink.FeedCondition.SIGNED_IN);
urlConditions.put(href, NetworkCatalogItem.Accessibility.SIGNED_IN);
} else if (rel == REL_CONDITION_HAS_BOOKS) {
urlConditions.put(href, NetworkCatalogItem.Accessibility.HAS_BOOKS);
}
}
@ -156,8 +160,16 @@ class OPDSLinkXMLReader extends OPDSXMLReader implements OPDSConstants, MimeType
return false;
}
private INetworkLink link(String siteName, String title, String summary, String icon, String language,
Map<String, String> links, HashMap<String, Integer> urlConditions, String sslCertificate) {
private INetworkLink link(
String siteName,
String title,
String summary,
String icon,
String language,
Map<String,String> links,
HashMap<String,NetworkCatalogItem.Accessibility> urlConditions,
String sslCertificate
) {
if (siteName == null || title == null || links.get(INetworkLink.URL_MAIN) == null) {
return null;
}

View file

@ -34,18 +34,10 @@ import org.geometerplus.zlibrary.core.network.ZLNetworkRequest;
import org.geometerplus.fbreader.network.*;
import org.geometerplus.fbreader.network.authentication.NetworkAuthenticationManager;
class OPDSNetworkLink extends AbstractNetworkLink {
public interface FeedCondition {
int REGULAR = 0;
int NEVER = 1;
int SIGNED_IN = 2;
}
private TreeMap<RelationAlias, String> myRelationAliases;
private TreeMap<String, Integer> myUrlConditions;
private TreeMap<String,NetworkCatalogItem.Accessibility> myUrlConditions;
private final LinkedList<URLRewritingRule> myUrlRewritingRules = new LinkedList<URLRewritingRule>();
private final Map<String,String> myExtraData = new HashMap<String,String>();
private NetworkAuthenticationManager myAuthenticationManager;
@ -66,9 +58,9 @@ class OPDSNetworkLink extends AbstractNetworkLink {
}
}
final void setUrlConditions(Map<String, Integer> conditions) {
final void setUrlConditions(Map<String,NetworkCatalogItem.Accessibility> conditions) {
if (conditions != null && conditions.size() > 0) {
myUrlConditions = new TreeMap<String, Integer>(conditions);
myUrlConditions = new TreeMap<String,NetworkCatalogItem.Accessibility>(conditions);
} else {
myUrlConditions = null;
}
@ -169,15 +161,12 @@ class OPDSNetworkLink extends AbstractNetworkLink {
return url;
}
int getCondition(String url) {
NetworkCatalogItem.Accessibility getCondition(String url) {
if (myUrlConditions == null) {
return FeedCondition.REGULAR;
return NetworkCatalogItem.Accessibility.ALWAYS;
}
Integer cond = myUrlConditions.get(url);
if (cond == null) {
return FeedCondition.REGULAR;
}
return cond.intValue();
NetworkCatalogItem.Accessibility cond = myUrlConditions.get(url);
return cond != null ? cond : NetworkCatalogItem.Accessibility.ALWAYS;
}
// rel and type must be either null or interned String objects.

View file

@ -105,14 +105,17 @@ public class NetworkCatalogTree extends NetworkTree {
}
NetworkCatalogTree child = (NetworkCatalogTree) currentNode;
if (child.Item == currentItem) {
final int visibility = child.Item.getVisibility();
if (visibility == ZLBoolean3.B3_TRUE) {
child.updateVisibility();
} else if (visibility == ZLBoolean3.B3_FALSE) {
toRemove.add(child);
} else {
child.clear();
child.ChildrenItems.clear();
switch (child.Item.getVisibility()) {
case B3_TRUE:
child.updateVisibility();
break;
case B3_FALSE:
toRemove.add(child);
break;
case B3_UNDEFINED:
child.clear();
child.ChildrenItems.clear();
break;
}
currentNode = null;
++nodeCount;

View file

@ -50,11 +50,12 @@ public class NetworkTreeFactory {
throw new RuntimeException("Unable to insert NetworkBookItem to the middle of the catalog");
}
final boolean showAuthors = parent.Item.CatalogType != NetworkCatalogItem.CATALOG_BY_AUTHORS;
final NetworkCatalogItem.CatalogType catalogType = parent.Item.getCatalogType();
final boolean showAuthors = catalogType != NetworkCatalogItem.CatalogType.BY_AUTHOR;
NetworkBookItem book = (NetworkBookItem) item;
String seriesTitle = book.SeriesTitle;
if (seriesTitle == null) {
if (seriesTitle == null || catalogType == NetworkCatalogItem.CatalogType.BY_SERIES) {
return new NetworkBookTree(parent, (NetworkBookItem) item, position, showAuthors);
}

View file

@ -22,27 +22,27 @@ package org.geometerplus.zlibrary.core.options;
import org.geometerplus.zlibrary.core.util.ZLBoolean3;
public final class ZLBoolean3Option extends ZLOption {
private int myValue;
private final int myDefaultValue;
private ZLBoolean3 myValue;
private final ZLBoolean3 myDefaultValue;
public ZLBoolean3Option(String group, String optionName, int defaultValue) {
public ZLBoolean3Option(String group, String optionName, ZLBoolean3 defaultValue) {
super(group, optionName);
myDefaultValue = defaultValue;
myValue = myDefaultValue;
}
public int getValue() {
public ZLBoolean3 getValue() {
if (!myIsSynchronized) {
String value = getConfigValue(null);
if (value != null) {
myValue = ZLBoolean3.getByString(value);
myValue = ZLBoolean3.getByName(value);
}
myIsSynchronized = true;
}
return myValue;
}
public void setValue(int value) {
public void setValue(ZLBoolean3 value) {
if (myIsSynchronized && (myValue == value)) {
return;
}
@ -52,7 +52,7 @@ public final class ZLBoolean3Option extends ZLOption {
if (myValue == myDefaultValue) {
unsetConfigValue();
} else {
setConfigValue(ZLBoolean3.getName(myValue));
setConfigValue(myValue.Name);
}
}
}

View file

@ -19,36 +19,23 @@
package org.geometerplus.zlibrary.core.util;
public final class ZLBoolean3 {
public static final int B3_FALSE = 0;
public static final int B3_TRUE = 1;
public static final int B3_UNDEFINED = 2;
public enum ZLBoolean3 {
B3_FALSE("false"),
B3_TRUE("true"),
B3_UNDEFINED("undefined");
private static final String STRING_FALSE = "false";
private static final String STRING_TRUE = "true";
private static final String STRING_UNDEFINED = "undefined";
public final String Name;
public static int getByString(String name) {
if (STRING_TRUE.equals(name)) {
return B3_TRUE;
}
if (STRING_FALSE.equals(name)) {
return B3_FALSE;
private ZLBoolean3(String name) {
Name = name;
}
public static ZLBoolean3 getByName(String name) {
for (ZLBoolean3 b3 : values()) {
if (b3.Name.equals(name)) {
return b3;
}
}
return B3_UNDEFINED;
}
public static String getName(int value) {
switch (value) {
case B3_FALSE:
return STRING_FALSE;
case B3_TRUE:
return STRING_TRUE;
default:
return STRING_UNDEFINED;
}
}
private ZLBoolean3() {
}
}

View file

@ -24,7 +24,7 @@ import java.io.InputStream;
import org.geometerplus.zlibrary.core.filesystem.ZLFile;
public class ZLXMLReaderAdapter implements ZLXMLReader {
public abstract class ZLXMLReaderAdapter implements ZLXMLReader {
private Map<String,String> myNamespaceMap = Collections.emptyMap();
public boolean read(ZLFile file) {

View file

@ -19,6 +19,7 @@
package org.geometerplus.zlibrary.text.view.style;
import org.geometerplus.zlibrary.core.util.ZLBoolean3;
import org.geometerplus.zlibrary.core.options.*;
import org.geometerplus.zlibrary.text.view.ZLTextStyle;
@ -36,7 +37,7 @@ public class ZLTextFullStyleDecoration extends ZLTextStyleDecoration {
public final ZLIntegerOption LineSpacePercentOption;
public ZLTextFullStyleDecoration(String name, int fontSizeDelta, int bold, int italic, int underline, int spaceBefore, int spaceAfter, int leftIndent,int rightIndent, int firstLineIndentDelta, int verticalShift, byte alignment, int lineSpace, int allowHyphenations) {
public ZLTextFullStyleDecoration(String name, int fontSizeDelta, ZLBoolean3 bold, ZLBoolean3 italic, ZLBoolean3 underline, int spaceBefore, int spaceAfter, int leftIndent,int rightIndent, int firstLineIndentDelta, int verticalShift, byte alignment, int lineSpace, ZLBoolean3 allowHyphenations) {
super(name, fontSizeDelta, bold, italic, underline, verticalShift, allowHyphenations);
SpaceBeforeOption = new ZLIntegerRangeOption(STYLE, name + ":spaceBefore", -10, 100, spaceBefore);
SpaceAfterOption = new ZLIntegerRangeOption(STYLE, name + ":spaceAfter", -10, 100, spaceAfter);

View file

@ -46,9 +46,9 @@ class ZLTextPartialDecoratedStyle extends ZLTextDecoratedStyle {
@Override
protected boolean isBoldInternal() {
switch (myDecoration.BoldOption.getValue()) {
case ZLBoolean3.B3_TRUE:
case B3_TRUE:
return true;
case ZLBoolean3.B3_FALSE:
case B3_FALSE:
return false;
default:
return Base.isBold();
@ -58,9 +58,9 @@ class ZLTextPartialDecoratedStyle extends ZLTextDecoratedStyle {
@Override
protected boolean isItalicInternal() {
switch (myDecoration.ItalicOption.getValue()) {
case ZLBoolean3.B3_TRUE:
case B3_TRUE:
return true;
case ZLBoolean3.B3_FALSE:
case B3_FALSE:
return false;
default:
return Base.isItalic();
@ -70,9 +70,9 @@ class ZLTextPartialDecoratedStyle extends ZLTextDecoratedStyle {
@Override
protected boolean isUnderlineInternal() {
switch (myDecoration.UnderlineOption.getValue()) {
case ZLBoolean3.B3_TRUE:
case B3_TRUE:
return true;
case ZLBoolean3.B3_FALSE:
case B3_FALSE:
return false;
default:
return Base.isUnderline();
@ -121,7 +121,13 @@ class ZLTextPartialDecoratedStyle extends ZLTextDecoratedStyle {
@Override
public boolean allowHyphenations() {
int a = myDecoration.AllowHyphenationsOption.getValue();
return (a == ZLBoolean3.B3_UNDEFINED) ? Base.allowHyphenations() : (a == ZLBoolean3.B3_TRUE);
switch (myDecoration.AllowHyphenationsOption.getValue()) {
case B3_FALSE:
return false;
case B3_TRUE:
return true;
default:
return Base.allowHyphenations();
}
}
}

View file

@ -76,8 +76,8 @@ public class ZLTextStyleCollection {
return "true".equals(attributes.getValue(name));
}
private static int b3Value(ZLStringMap attributes, String name) {
return ZLBoolean3.getByString(attributes.getValue(name));
private static ZLBoolean3 b3Value(ZLStringMap attributes, String name) {
return ZLBoolean3.getByName(attributes.getValue(name));
}
public TextStyleReader(ZLTextStyleCollection collection) {
@ -98,11 +98,11 @@ public class ZLTextStyleCollection {
ZLTextStyleDecoration decoration;
int fontSizeDelta = intValue(attributes, "fontSizeDelta", 0);
int bold = b3Value(attributes, "bold");
int italic = b3Value(attributes, "italic");
int underline = b3Value(attributes, "underline");
ZLBoolean3 bold = b3Value(attributes, "bold");
ZLBoolean3 italic = b3Value(attributes, "italic");
ZLBoolean3 underline = b3Value(attributes, "underline");
int verticalShift = intValue(attributes, "vShift", 0);
int allowHyphenations = b3Value(attributes, "allowHyphenations");
ZLBoolean3 allowHyphenations = b3Value(attributes, "allowHyphenations");
if (booleanValue(attributes, "partial")) {
decoration = new ZLTextStyleDecoration(name, fontSizeDelta, bold, italic, underline, verticalShift, allowHyphenations);

View file

@ -19,6 +19,7 @@
package org.geometerplus.zlibrary.text.view.style;
import org.geometerplus.zlibrary.core.util.ZLBoolean3;
import org.geometerplus.zlibrary.core.options.*;
import org.geometerplus.zlibrary.text.view.ZLTextStyle;
@ -37,7 +38,7 @@ public class ZLTextStyleDecoration {
private final String myName;
public ZLTextStyleDecoration(String name, int fontSizeDelta, int bold, int italic, int underline, int verticalShift, int allowHyphenations) {
public ZLTextStyleDecoration(String name, int fontSizeDelta, ZLBoolean3 bold, ZLBoolean3 italic, ZLBoolean3 underline, int verticalShift, ZLBoolean3 allowHyphenations) {
myName = name;
FontFamilyOption = new ZLStringOption(STYLE, name + ":fontFamily", "");
FontSizeDeltaOption = new ZLIntegerRangeOption(STYLE, name + ":fontSize", -16, 16, fontSizeDelta);

View file

@ -35,6 +35,7 @@ public class ZLAndroidApplication extends Application {
public final ZLBooleanOption AutoOrientationOption = new ZLBooleanOption("LookNFeel", "AutoOrientation", false);
public final ZLBooleanOption ShowStatusBarOption = new ZLBooleanOption("LookNFeel", "ShowStatusBar", hasNoHardwareMenuButton());
public final ZLBooleanOption ShowStatusBarWhenMenuIsActiveOption = new ZLBooleanOption("LookNFeel", "ShowStatusBarWithMenu", true);
public final ZLIntegerRangeOption BatteryLevelToTurnScreenOffOption = new ZLIntegerRangeOption("LookNFeel", "BatteryLevelToTurnScreenOff", 0, 100, 50);
public final ZLBooleanOption DontTurnScreenOffDuringChargingOption = new ZLBooleanOption("LookNFeel", "DontTurnScreenOffDuringCharging", true);
public final ZLIntegerRangeOption ScreenBrightnessLevelOption = new ZLIntegerRangeOption("LookNFeel", "ScreenBrightnessLevel", 0, 100, 0);