1
0
Fork 0
mirror of https://github.com/geometer/FBReaderJ.git synced 2025-10-05 19:42:17 +02:00

Merge branch 'master' into basket

This commit is contained in:
Nikolay Pultsin 2011-02-05 07:34:41 +00:00
commit 38c6d0a700
25 changed files with 420 additions and 329 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="9910" android:versionName="0.99.10" android:installLocation="auto">
<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">
<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" />
@ -75,7 +75,7 @@
</intent-filter>
<meta-data android:name="android.app.searchable" android:resource="@xml/searchable" />
</activity>
<activity android:name="org.geometerplus.android.fbreader.library.FileManager" android:process=":library"/>
<activity android:name="org.geometerplus.android.fbreader.library.FileManager" android:process=":library" android:configChanges="orientation|keyboardHidden"/>
<activity android:name="org.geometerplus.android.fbreader.TOCActivity" android:configChanges="orientation|keyboardHidden" />
<activity android:name="org.geometerplus.android.fbreader.BookmarksActivity" android:launchMode="singleTask" android:configChanges="orientation|keyboardHidden">
<intent-filter>

View file

@ -75,7 +75,7 @@
</intent-filter>
<meta-data android:name="android.app.searchable" android:resource="@xml/searchable" />
</activity>
<activity android:name="org.geometerplus.android.fbreader.library.FileManager" android:process=":library"/>
<activity android:name="org.geometerplus.android.fbreader.library.FileManager" android:process=":library" android:configChanges="orientation|keyboardHidden"/>
<activity android:name="org.geometerplus.android.fbreader.TOCActivity" android:configChanges="orientation|keyboardHidden" />
<activity android:name="org.geometerplus.android.fbreader.BookmarksActivity" android:launchMode="singleTask" android:configChanges="orientation|keyboardHidden">
<intent-filter>

View file

@ -1,5 +1,8 @@
===== 0.99.11 (??? ??, 2011) =====
===== 0.99.11 (Feb 01, 2011) =====
* Galician translation has been added (by Miguel Anxo Bouzada)
* Czech translation has been updated (by Marek Pavelka)
* Mobipocket images/cover/links support has been added (by Steffen Siebert)
* Small fixes
===== 0.99.10 (Jan 30, 2011) =====
* Full-size image view

View file

@ -1 +1 @@
0.99.10
0.99.11

View file

@ -137,8 +137,8 @@
<node name="contentError" value="Stahování selhalo" />
<node name="downloadingStarted" value="Stahování knihy bylo zahájeno" />
<node name="alreadyDownloading" value="Kniha se již stahuje" />
<node name="cannotCreateDirectory" value="Unable to create directory %s" toBeTranslated="true"/>
<node name="cannotCreateFile" value="Unable to create file %s" toBeTranslated="true"/>
<node name="cannotCreateDirectory" value="Nelze vytvořit adresář %s"/>
<node name="cannotCreateFile" value="Nelze vytvořit soubor %s"/>
</node>
<node name="tocView">
<node name="expandTree" value="Rozbalit strom"/>
@ -158,9 +158,9 @@
</node>
</node>
<node name="cancelMenu">
<node name="previousBook" value="Open previous book" toBeTranslated="true"/>
<node name="returnTo" value="Return to ..." toBeTranslated="true"/>
<node name="close" value="Close FBReader" toBeTranslated="true"/>
<node name="previousBook" value="Otevřít předchozí knihu"/>
<node name="returnTo" value="Vrátit se na..."/>
<node name="close" value="Zavřít FBReader"/>
</node>
<node name="menu">
<node name="preferences" value="Nastavení"/>

View file

@ -13,7 +13,7 @@
<node name="title" value="Chyba sítě" />
<node name="unknownErrorMessage" value="Neznámá chyba" />
<node name="operationTimedOutMessage" value="Vypršel časový limit operace" />
<node name="somethingWrongMessage" value="Něco se pokazilo s&#10;%s" />
<node name="somethingWrongMessage" value="Něco není v pořádku s&#10;%s" />
<node name="couldntCreateDirectoryMessage" value="Nelze vytvořit adresář&#10;%s" />
<node name="couldntCreateFileMessage" value="Nelze vytvořit soubor&#10;%s" />
<node name="couldntConnectToNetworkMessage" value="Nelze se připojit k síti" />

View file

@ -59,8 +59,8 @@ public class BookInfoActivity extends Activity {
private boolean myHideOpenButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
Thread.setDefaultUncaughtExceptionHandler(
new org.geometerplus.zlibrary.ui.android.library.UncaughtExceptionHandler(this)
);

View file

@ -33,8 +33,8 @@ public class CancelActivity extends ListActivity {
static final String ITEM_SUMMARY = "summary";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
requestWindowFeature(Window.FEATURE_NO_TITLE);
final ActionListAdapter adapter = new ActionListAdapter(getIntent());
setListAdapter(adapter);

View file

@ -19,104 +19,78 @@
package org.geometerplus.android.fbreader;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import org.geometerplus.zlibrary.core.application.ZLApplication;
class ControlButtonPanel implements ZLApplication.ButtonPanel {
import org.geometerplus.zlibrary.text.view.ZLTextWordCursor;
import org.geometerplus.fbreader.fbreader.FBReaderApp;
abstract class ControlButtonPanel implements ZLApplication.ButtonPanel {
public final FBReaderApp Reader;
public ZLTextWordCursor StartPosition;
private boolean myVisible;
protected ControlPanel myControlPanel;
private static LinkedList<ControlButtonPanel> ourPanels = new LinkedList<ControlButtonPanel>();
ControlButtonPanel(FBReaderApp fbReader) {
Reader = fbReader;
fbReader.registerButtonPanel(this);
}
public final void hide() {
hide(false);
}
public void updateStates() {
if (myControlPanel != null) {
myControlPanel.updateStates();
}
}
public final void register() {
ZLApplication.Instance().registerButtonPanel(this);
ourPanels.add(this);
}
public final boolean hasControlPanel() {
return myControlPanel != null;
}
public final void setControlPanel(ControlPanel panel, RelativeLayout root, boolean fillWidth) {
myControlPanel = panel;
RelativeLayout.LayoutParams p = new RelativeLayout.LayoutParams(
fillWidth ? ViewGroup.LayoutParams.FILL_PARENT : ViewGroup.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT
);
p.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
p.addRule(RelativeLayout.CENTER_HORIZONTAL);
myControlPanel.setVisibility(View.GONE);
root.addView(myControlPanel, p);
}
private final void removeControlPanel() {
if (myControlPanel != null) {
ViewGroup root = (ViewGroup) myControlPanel.getParent();
ViewGroup root = (ViewGroup)myControlPanel.getParent();
myControlPanel.hide(false);
root.removeView(myControlPanel);
myControlPanel = null;
}
}
public static void removeControlPanels() {
for (ControlButtonPanel panel: ourPanels) {
panel.removeControlPanel();
public static void removeControlPanels(ZLApplication application) {
for (ZLApplication.ButtonPanel panel : application.buttonPanels()) {
((ControlButtonPanel)panel).removeControlPanel();
}
}
public static void restoreVisibilities() {
for (ControlButtonPanel panel: ourPanels) {
panel.setVisibility(panel.myVisible);
public static void restoreVisibilities(ZLApplication application) {
for (ZLApplication.ButtonPanel panel : application.buttonPanels()) {
final ControlButtonPanel p = (ControlButtonPanel)panel;
p.setVisibility(p.myVisible);
}
}
public static void saveVisibilities() {
for (ControlButtonPanel panel: ourPanels) {
panel.myVisible = panel.getVisibility();
public static void saveVisibilities(ZLApplication application) {
for (ZLApplication.ButtonPanel panel : application.buttonPanels()) {
final ControlButtonPanel p = (ControlButtonPanel)panel;
p.myVisible = p.getVisibility();
}
}
public static void restoreVisibilitiesFrom(List<Boolean> buffer) {
Iterator<Boolean> it = buffer.iterator();
for (ControlButtonPanel panel: ourPanels) {
panel.setVisibility(it.next());
}
}
public static void saveVisibilitiesTo(List<Boolean> buffer) {
buffer.clear();
for (ControlButtonPanel panel: ourPanels) {
buffer.add(panel.getVisibility());
}
}
public static void hideAllPendingNotify() {
for (ControlButtonPanel panel: ourPanels) {
if (panel.myControlPanel != null && panel.getVisibility()) {
panel.myControlPanel.hide(false);
public static void hideAllPendingNotify(ZLApplication application) {
for (ZLApplication.ButtonPanel panel : application.buttonPanels()) {
final ControlButtonPanel p = (ControlButtonPanel)panel;
if (p.myControlPanel != null && p.getVisibility()) {
p.myControlPanel.hide(false);
}
}
}
public final boolean getVisibility() {
if (myControlPanel != null) {
return myControlPanel.getVisibility() == View.VISIBLE;
@ -124,7 +98,7 @@ class ControlButtonPanel implements ZLApplication.ButtonPanel {
return false;
}
public final void setVisibility(boolean visible) {
private void setVisibility(boolean visible) {
if (visible) {
show(false);
} else {
@ -133,30 +107,42 @@ class ControlButtonPanel implements ZLApplication.ButtonPanel {
}
private void hideOthers() {
for (ControlButtonPanel panel: ourPanels) {
for (ZLApplication.ButtonPanel panel : Reader.buttonPanels()) {
if (panel != this) {
panel.hide(false);
((ControlButtonPanel)panel).hide(false);
}
}
}
public final void show(boolean animate) {
if (myControlPanel != null && !getVisibility()) {
myVisible = true;
hideOthers();
onShow();
myControlPanel.show(animate);
}
}
public final void initPosition() {
if (StartPosition == null) {
StartPosition = new ZLTextWordCursor(Reader.getTextView().getStartCursor());
}
}
public final void storePosition() {
if (StartPosition != null &&
!StartPosition.equals(Reader.getTextView().getStartCursor())) {
Reader.addInvisibleBookmark(StartPosition);
}
}
public final void hide(boolean animate) {
myVisible = false;
if (myControlPanel != null && getVisibility()) {
onHide();
myControlPanel.hide(animate);
}
}
public abstract void createControlPanel(FBReader activity, RelativeLayout root);
// callback methods
public void onShow() {}

View file

@ -19,14 +19,10 @@
package org.geometerplus.android.fbreader;
import java.util.ArrayList;
import android.os.Handler;
import android.os.Message;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.*;
import android.view.animation.AlphaAnimation;
import android.widget.*;
@ -34,22 +30,8 @@ import org.geometerplus.zlibrary.ui.android.R;
import org.geometerplus.zlibrary.core.application.ZLApplication;
class ActionButton extends ZoomButton {
final String ActionId;
final boolean IsCloseButton;
ActionButton(Context context, String actionId, boolean isCloseButton) {
super(context);
ActionId = actionId;
IsCloseButton = isCloseButton;
}
}
public class ControlPanel extends LinearLayout implements View.OnClickListener {
private final ArrayList<ActionButton> myButtons = new ArrayList<ActionButton>();
private final LinearLayout myPlateLayout;
public ControlPanel(Context context) {
public class ControlPanel extends LinearLayout {
public ControlPanel(Context context, RelativeLayout root, boolean fillWidth) {
super(context);
setFocusable(false);
@ -57,25 +39,18 @@ public class ControlPanel extends LinearLayout implements View.OnClickListener {
final LayoutInflater inflater =
(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.control_panel, this, true);
myPlateLayout = (LinearLayout)findViewById(R.id.tools_plate);
RelativeLayout.LayoutParams p = new RelativeLayout.LayoutParams(
fillWidth ? ViewGroup.LayoutParams.FILL_PARENT : ViewGroup.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT
);
p.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
p.addRule(RelativeLayout.CENTER_HORIZONTAL);
root.addView(this, p);
setVisibility(View.GONE);
}
public void addButton(String actionId, boolean isCloseButton, int imageId) {
final ActionButton button = new ActionButton(getContext(), actionId, isCloseButton);
button.setImageResource(imageId);
button.setOnClickListener(this);
myPlateLayout.addView(button);
myButtons.add(button);
}
public void onClick(View view) {
final ActionButton button = (ActionButton)view;
ZLApplication.Instance().doAction(button.ActionId);
if (button.IsCloseButton) {
hide(true);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return true;
@ -121,28 +96,8 @@ public class ControlPanel extends LinearLayout implements View.OnClickListener {
startAnimation(animation);
setVisibility(visibility);
}
public void updateStates() {
final ZLApplication application = ZLApplication.Instance();
for (ActionButton button : myButtons) {
button.setEnabled(application.isActionEnabled(button.ActionId));
}
}
@Override
public boolean hasFocus() {
for (ActionButton button : myButtons) {
if (button.hasFocus()) {
return true;
}
}
return false;
}
public void setExtension(View view) {
if (view != null) {
myPlateLayout.removeAllViews();
myPlateLayout.addView(view);
}
public void addView(View view) {
((LinearLayout)findViewById(R.id.tools_plate)).addView(view);
}
}

View file

@ -19,8 +19,6 @@
package org.geometerplus.android.fbreader;
import java.util.LinkedList;
import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
@ -28,16 +26,11 @@ import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.*;
import android.widget.*;
import android.view.WindowManager;
import android.widget.RelativeLayout;
import org.geometerplus.zlibrary.core.application.ZLApplication;
import org.geometerplus.zlibrary.core.filesystem.ZLFile;
import org.geometerplus.zlibrary.core.resources.ZLResource;
import org.geometerplus.zlibrary.core.view.ZLView;
import org.geometerplus.zlibrary.text.view.ZLTextWordCursor;
import org.geometerplus.zlibrary.text.view.ZLTextView;
import org.geometerplus.zlibrary.text.hyphenation.ZLTextHyphenator;
import org.geometerplus.zlibrary.ui.android.R;
@ -46,7 +39,6 @@ import org.geometerplus.zlibrary.ui.android.library.ZLAndroidApplication;
import org.geometerplus.fbreader.fbreader.ActionCode;
import org.geometerplus.fbreader.fbreader.FBReaderApp;
import org.geometerplus.fbreader.fbreader.FBView;
import org.geometerplus.fbreader.bookmodel.BookModel;
import org.geometerplus.fbreader.library.Book;
@ -62,36 +54,8 @@ public final class FBReader extends ZLAndroidActivity {
private int myFullScreenFlag;
private class NavigationButtonPanel extends ControlButtonPanel {
public volatile boolean NavigateDragging;
public ZLTextWordCursor StartPosition;
@Override
public void onShow() {
if (myControlPanel != null) {
setupNavigation(myControlPanel);
}
}
@Override
public void updateStates() {
super.updateStates();
if (!NavigateDragging && myControlPanel != null) {
setupNavigation(myControlPanel);
}
}
}
private static class TextSearchButtonPanel extends ControlButtonPanel {
@Override
public void onHide() {
final ZLTextView textView = (ZLTextView)ZLApplication.Instance().getCurrentView();
textView.clearFindResults();
}
}
private static TextSearchButtonPanel myTextSearchPanel;
private static NavigationButtonPanel myNavigatePanel;
private static TextSearchButtonPanel ourTextSearchPanel;
private static NavigationButtonPanel ourNavigatePanel;
@Override
protected ZLFile fileFromIntent(Intent intent) {
@ -114,16 +78,15 @@ public final class FBReader extends ZLAndroidActivity {
getWindow().setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN, myFullScreenFlag
);
if (myTextSearchPanel == null) {
myTextSearchPanel = new TextSearchButtonPanel();
myTextSearchPanel.register();
final FBReaderApp fbReader = (FBReaderApp)FBReaderApp.Instance();
if (ourTextSearchPanel == null) {
ourTextSearchPanel = new TextSearchButtonPanel(fbReader);
}
if (myNavigatePanel == null) {
myNavigatePanel = new NavigationButtonPanel();
myNavigatePanel.register();
if (ourNavigatePanel == null) {
ourNavigatePanel = new NavigationButtonPanel(fbReader);
}
final FBReaderApp fbReader = (FBReaderApp)ZLApplication.Instance();
fbReader.addAction(ActionCode.SHOW_LIBRARY, new ShowLibraryAction(this, fbReader));
fbReader.addAction(ActionCode.SHOW_PREFERENCES, new ShowPreferencesAction(this, fbReader));
fbReader.addAction(ActionCode.SHOW_BOOK_INFO, new ShowBookInfoAction(this, fbReader));
@ -146,16 +109,18 @@ public final class FBReader extends ZLAndroidActivity {
final String pattern = intent.getStringExtra(SearchManager.QUERY);
final Handler successHandler = new Handler() {
public void handleMessage(Message message) {
showTextSearchControls(true);
ourTextSearchPanel.show(true);
}
};
final Handler failureHandler = new Handler() {
public void handleMessage(Message message) {
UIUtil.showErrorMessage(FBReader.this, "textNotFound");
ourTextSearchPanel.StartPosition = null;
}
};
final Runnable runnable = new Runnable() {
public void run() {
ourTextSearchPanel.initPosition();
final FBReaderApp fbReader = (FBReaderApp)FBReaderApp.Instance();
fbReader.TextSearchPatternOption.setValue(pattern);
if (fbReader.getTextView().search(pattern, true, false, false, false) != 0) {
@ -184,55 +149,38 @@ public final class FBReader extends ZLAndroidActivity {
}
final RelativeLayout root = (RelativeLayout)findViewById(R.id.root_view);
if (!myTextSearchPanel.hasControlPanel()) {
final ControlPanel panel = new ControlPanel(this);
panel.addButton(ActionCode.FIND_PREVIOUS, false, R.drawable.text_search_previous);
panel.addButton(ActionCode.CLEAR_FIND_RESULTS, true, R.drawable.text_search_close);
panel.addButton(ActionCode.FIND_NEXT, false, R.drawable.text_search_next);
myTextSearchPanel.setControlPanel(panel, root, false);
if (!ourTextSearchPanel.hasControlPanel()) {
ourTextSearchPanel.createControlPanel(this, root);
}
if (!myNavigatePanel.hasControlPanel()) {
final ControlPanel panel = new ControlPanel(this);
final View layout = getLayoutInflater().inflate(R.layout.navigate, panel, false);
createNavigation(layout);
panel.setExtension(layout);
myNavigatePanel.setControlPanel(panel, root, true);
if (!ourNavigatePanel.hasControlPanel()) {
ourNavigatePanel.createControlPanel(this, root);
}
}
@Override
public void onResume() {
super.onResume();
final Context context = getApplicationContext();
if (context != null) {
sendBroadcast(new Intent(context, KillerCallback.class));
try {
sendBroadcast(new Intent(getApplicationContext(), KillerCallback.class));
} catch (Throwable t) {
}
ControlButtonPanel.restoreVisibilities();
ControlButtonPanel.restoreVisibilities(FBReaderApp.Instance());
}
@Override
public void onPause() {
ControlButtonPanel.saveVisibilities();
ControlButtonPanel.saveVisibilities(FBReaderApp.Instance());
super.onPause();
}
@Override
public void onStop() {
ControlButtonPanel.removeControlPanels();
ControlButtonPanel.removeControlPanels(FBReaderApp.Instance());
super.onStop();
}
void showTextSearchControls(boolean show) {
if (show) {
myTextSearchPanel.show(true);
} else {
myTextSearchPanel.hide(false);
}
}
protected ZLApplication createApplication(ZLFile file) {
@Override
protected FBReaderApp createApplication(ZLFile file) {
if (SQLiteBooksDatabase.Instance() == null) {
new SQLiteBooksDatabase(this, "READER");
}
@ -241,24 +189,23 @@ public final class FBReader extends ZLAndroidActivity {
@Override
public boolean onSearchRequested() {
final LinkedList<Boolean> visibilities = new LinkedList<Boolean>();
ControlButtonPanel.saveVisibilitiesTo(visibilities);
ControlButtonPanel.hideAllPendingNotify();
final FBReaderApp fbreader = (FBReaderApp)FBReaderApp.Instance();
ControlButtonPanel.saveVisibilities(fbreader);
ControlButtonPanel.hideAllPendingNotify(fbreader);
final SearchManager manager = (SearchManager)getSystemService(SEARCH_SERVICE);
manager.setOnCancelListener(new SearchManager.OnCancelListener() {
public void onCancel() {
ControlButtonPanel.restoreVisibilitiesFrom(visibilities);
ControlButtonPanel.restoreVisibilities(fbreader);
manager.setOnCancelListener(null);
}
});
final FBReaderApp fbreader = (FBReaderApp)ZLApplication.Instance();
startSearch(fbreader.TextSearchPatternOption.getValue(), true, null, false);
return true;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
final FBReaderApp fbreader = (FBReaderApp)ZLApplication.Instance();
final FBReaderApp fbreader = (FBReaderApp)FBReaderApp.Instance();
switch (requestCode) {
case REPAINT_CODE:
{
@ -280,88 +227,7 @@ public final class FBReader extends ZLAndroidActivity {
}
}
public boolean navigate() {
if (myNavigatePanel.getVisibility()) {
return false;
}
final ZLTextView textView = (ZLTextView)ZLApplication.Instance().getCurrentView();
myNavigatePanel.NavigateDragging = false;
myNavigatePanel.StartPosition = new ZLTextWordCursor(textView.getStartCursor());
myNavigatePanel.show(true);
return true;
}
private final void createNavigation(View layout) {
final FBReaderApp fbreader = (FBReaderApp)ZLApplication.Instance();
final SeekBar slider = (SeekBar)layout.findViewById(R.id.book_position_slider);
final TextView text = (TextView)layout.findViewById(R.id.book_position_text);
slider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
private void gotoPage(int page) {
final ZLTextView view = fbreader.getTextView();
if (page == 1) {
view.gotoHome();
} else {
view.gotoPage(page);
}
fbreader.repaintView();
}
public void onStopTrackingTouch(SeekBar seekBar) {
myNavigatePanel.NavigateDragging = false;
}
public void onStartTrackingTouch(SeekBar seekBar) {
myNavigatePanel.NavigateDragging = true;
}
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser) {
final int page = progress + 1;
final int pagesNumber = seekBar.getMax() + 1;
text.setText(makeProgressText(page, pagesNumber));
gotoPage(page);
}
}
});
final Button btnOk = (Button)layout.findViewById(android.R.id.button1);
final Button btnCancel = (Button)layout.findViewById(android.R.id.button3);
View.OnClickListener listener = new View.OnClickListener() {
public void onClick(View v) {
final ZLTextWordCursor position = myNavigatePanel.StartPosition;
myNavigatePanel.StartPosition = null;
if (v == btnCancel && position != null) {
fbreader.getTextView().gotoPosition(position);
} else if (v == btnOk) {
fbreader.addInvisibleBookmark(position);
}
myNavigatePanel.hide(true);
}
};
btnOk.setOnClickListener(listener);
btnCancel.setOnClickListener(listener);
final ZLResource buttonResource = ZLResource.resource("dialog").getResource("button");
btnOk.setText(buttonResource.getResource("ok").getValue());
btnCancel.setText(buttonResource.getResource("cancel").getValue());
}
private final void setupNavigation(ControlPanel panel) {
final SeekBar slider = (SeekBar)panel.findViewById(R.id.book_position_slider);
final TextView text = (TextView)panel.findViewById(R.id.book_position_text);
final ZLTextView textView = (ZLTextView)ZLApplication.Instance().getCurrentView();
final int page = textView.computeCurrentPage();
final int pagesNumber = textView.computePageNumber();
if (slider.getMax() != pagesNumber - 1 || slider.getProgress() != page - 1) {
slider.setMax(pagesNumber - 1);
slider.setProgress(page - 1);
text.setText(makeProgressText(page, pagesNumber));
}
}
private static String makeProgressText(int page, int pagesNumber) {
return "" + page + " / " + pagesNumber;
public void navigate() {
ourNavigatePanel.runNavigation();
}
}

View file

@ -0,0 +1,146 @@
/*
* Copyright (C) 2009-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.android.fbreader;
import android.view.View;
import android.widget.Button;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import org.geometerplus.zlibrary.core.resources.ZLResource;
import org.geometerplus.zlibrary.text.view.ZLTextView;
import org.geometerplus.zlibrary.text.view.ZLTextWordCursor;
import org.geometerplus.zlibrary.ui.android.R;
import org.geometerplus.fbreader.fbreader.FBReaderApp;
final class NavigationButtonPanel extends ControlButtonPanel {
private volatile boolean myIsInProgress;
NavigationButtonPanel(FBReaderApp fbReader) {
super(fbReader);
}
public void runNavigation() {
if (!getVisibility()) {
myIsInProgress = false;
initPosition();
show(true);
}
}
@Override
public void onShow() {
if (myControlPanel != null) {
setupNavigation(myControlPanel);
}
}
@Override
public void updateStates() {
super.updateStates();
if (!myIsInProgress && myControlPanel != null) {
setupNavigation(myControlPanel);
}
}
@Override
public void createControlPanel(FBReader activity, RelativeLayout root) {
myControlPanel = new ControlPanel(activity, root, true);
final View layout = activity.getLayoutInflater().inflate(R.layout.navigate, myControlPanel, false);
final SeekBar slider = (SeekBar)layout.findViewById(R.id.book_position_slider);
final TextView text = (TextView)layout.findViewById(R.id.book_position_text);
slider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
private void gotoPage(int page) {
final ZLTextView view = Reader.getTextView();
if (page == 1) {
view.gotoHome();
} else {
view.gotoPage(page);
}
Reader.repaintView();
}
public void onStopTrackingTouch(SeekBar seekBar) {
myIsInProgress = false;
}
public void onStartTrackingTouch(SeekBar seekBar) {
myIsInProgress = true;
}
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser) {
final int page = progress + 1;
final int pagesNumber = seekBar.getMax() + 1;
text.setText(makeProgressText(page, pagesNumber));
gotoPage(page);
}
}
});
final Button btnOk = (Button)layout.findViewById(android.R.id.button1);
final Button btnCancel = (Button)layout.findViewById(android.R.id.button3);
View.OnClickListener listener = new View.OnClickListener() {
public void onClick(View v) {
final ZLTextWordCursor position = StartPosition;
if (v == btnCancel && position != null) {
Reader.getTextView().gotoPosition(position);
} else if (v == btnOk) {
storePosition();
}
StartPosition = null;
hide(true);
}
};
btnOk.setOnClickListener(listener);
btnCancel.setOnClickListener(listener);
final ZLResource buttonResource = ZLResource.resource("dialog").getResource("button");
btnOk.setText(buttonResource.getResource("ok").getValue());
btnCancel.setText(buttonResource.getResource("cancel").getValue());
myControlPanel.addView(layout);
}
private void setupNavigation(ControlPanel panel) {
final SeekBar slider = (SeekBar)panel.findViewById(R.id.book_position_slider);
final TextView text = (TextView)panel.findViewById(R.id.book_position_text);
final ZLTextView textView = Reader.getTextView();
final int page = textView.computeCurrentPage();
final int pagesNumber = textView.computePageNumber();
if (slider.getMax() != pagesNumber - 1 || slider.getProgress() != page - 1) {
slider.setMax(pagesNumber - 1);
slider.setProgress(page - 1);
text.setText(makeProgressText(page, pagesNumber));
}
}
private static String makeProgressText(int page, int pagesNumber) {
return page + " / " + pagesNumber;
}
}

View file

@ -0,0 +1,90 @@
/*
* Copyright (C) 2009-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.android.fbreader;
import java.util.ArrayList;
import android.content.Context;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.ZoomButton;
import org.geometerplus.zlibrary.ui.android.R;
import org.geometerplus.fbreader.fbreader.ActionCode;
import org.geometerplus.fbreader.fbreader.FBReaderApp;
class ActionButton extends ZoomButton {
final String ActionId;
final boolean IsCloseButton;
ActionButton(Context context, String actionId, boolean isCloseButton) {
super(context);
ActionId = actionId;
IsCloseButton = isCloseButton;
}
}
final class TextSearchButtonPanel extends ControlButtonPanel implements View.OnClickListener {
private final ArrayList<ActionButton> myButtons = new ArrayList<ActionButton>();
TextSearchButtonPanel(FBReaderApp fbReader) {
super(fbReader);
}
@Override
public void onHide() {
Reader.getTextView().clearFindResults();
}
@Override
public void createControlPanel(FBReader activity, RelativeLayout root) {
myControlPanel = new ControlPanel(activity, root, false);
addButton(ActionCode.FIND_PREVIOUS, false, R.drawable.text_search_previous);
addButton(ActionCode.CLEAR_FIND_RESULTS, true, R.drawable.text_search_close);
addButton(ActionCode.FIND_NEXT, false, R.drawable.text_search_next);
}
private void addButton(String actionId, boolean isCloseButton, int imageId) {
final ActionButton button = new ActionButton(myControlPanel.getContext(), actionId, isCloseButton);
button.setImageResource(imageId);
myControlPanel.addView(button);
button.setOnClickListener(this);
myButtons.add(button);
}
@Override
public void updateStates() {
for (ActionButton button : myButtons) {
button.setEnabled(Reader.isActionEnabled(button.ActionId));
}
}
public void onClick(View view) {
final ActionButton button = (ActionButton)view;
Reader.doAction(button.ActionId);
if (button.IsCloseButton && myControlPanel != null) {
storePosition();
StartPosition = null;
myControlPanel.hide(true);
}
}
}

View file

@ -35,8 +35,8 @@ public class ImageViewActivity extends Activity {
Bitmap myBitmap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
requestWindowFeature(Window.FEATURE_NO_TITLE);
final ZLAndroidApplication application = ZLAndroidApplication.Instance();

View file

@ -47,8 +47,8 @@ public final class FileManager extends BaseActivity {
private String myPath;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
if (DatabaseInstance == null || LibraryInstance == null) {
finish();

View file

@ -52,8 +52,8 @@ public class NetworkBookInfoActivity extends Activity implements NetworkView.Eve
private BookDownloaderServiceConnection myConnection;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
if (!NetworkView.Instance().isInitialized()) {
finish();

View file

@ -239,6 +239,7 @@ public final class FBReaderApp extends ZLApplication {
}
public void gotoBookmark(Bookmark bookmark) {
addInvisibleBookmark();
final String modelId = bookmark.ModelId;
if (modelId == null) {
BookTextView.gotoPosition(bookmark);
@ -354,7 +355,6 @@ public final class FBReaderApp extends ZLApplication {
{
final Bookmark b = ((BookmarkDescription)description).Bookmark;
b.delete();
addInvisibleBookmark();
gotoBookmark(b);
break;
}
@ -366,6 +366,11 @@ public final class FBReaderApp extends ZLApplication {
private void updateInvisibleBookmarksList(Bookmark b) {
if (Model.Book != null && b != null) {
for (Bookmark bm : Bookmark.invisibleBookmarks(Model.Book)) {
if (b.equals(bm)) {
bm.delete();
}
}
b.save();
final List<Bookmark> bookmarks = Bookmark.invisibleBookmarks(Model.Book);
for (int i = 3; i < bookmarks.size(); ++i) {

View file

@ -259,6 +259,9 @@ public class HtmlReader extends BookReader implements ZLHtmlReader {
if (ref.charAt(0) == '#') {
myHyperlinkType = FBTextKind.FOOTNOTE;
ref = ref.substring(1);
} else if (ref.charAt(0) == '&') {
myHyperlinkType = FBTextKind.INTERNAL_HYPERLINK;
ref = ref.substring(1);
} else {
myHyperlinkType = FBTextKind.EXTERNAL_HYPERLINK;
}

View file

@ -122,7 +122,7 @@ public class MobipocketHtmlBookReader extends HtmlReader {
}
}
myFileposReferences.add(filePosition);
// TODO: add hyperlink control
attributes.put(new ZLByteBuffer("href"), new ZLByteBuffer("&filepos" + filePosition));
} catch (NumberFormatException e) {
}
}
@ -182,12 +182,21 @@ public class MobipocketHtmlBookReader extends HtmlReader {
if (length <= 0) {
break;
}
addImage("" + index, new ZLFileImage(MimeTypes.MIME_IMAGE_AUTO, Model.Book.File, offset, length));
addImage("" + (index + 1), new ZLFileImage(MimeTypes.MIME_IMAGE_AUTO, Model.Book.File, offset, length));
}
}
@Override
public void endDocumentHandler() {
for (Integer entry: myFileposReferences) {
final SortedMap<Integer,Integer> subMap =
myPositionToParagraph.tailMap(entry);
if (subMap.isEmpty()) {
break;
}
addHyperlinkLabel("filepos" + entry, subMap.get(subMap.firstKey()));
}
for (Map.Entry<Integer,String> entry : myTocEntries.entrySet()) {
final SortedMap<Integer,Integer> subMap =
myPositionToParagraph.tailMap(entry.getKey());

View file

@ -22,7 +22,9 @@ package org.geometerplus.fbreader.formats.pdb;
import java.io.*;
import org.geometerplus.zlibrary.core.filesystem.ZLFile;
import org.geometerplus.zlibrary.core.image.ZLFileImage;
import org.geometerplus.zlibrary.core.image.ZLImage;
import org.geometerplus.zlibrary.core.constants.MimeTypes;
import org.geometerplus.zlibrary.core.encoding.ZLEncodingCollection;
import org.geometerplus.zlibrary.core.language.ZLLanguageUtil;
@ -202,20 +204,14 @@ public class MobipocketPlugin extends PdbPlugin {
coverIndex = thumbIndex;
}
// TODO: implement
/*final MobipocketStream mpStream = new MobipocketStream(file);
int index = pbStream.firstImageLocationIndex(file.path());
if (index >= 0) {
std::pair<int,int> imageLocation = pbStream.imageLocation(pbStream.header(), index + coverIndex);
if ((imageLocation.first > 0) && (imageLocation.second > 0)) {
return new ZLFileImage(
file,
imageLocation.first,
imageLocation.second
);
MobipocketStream myMobipocketStream = new MobipocketStream(file);
int start = myMobipocketStream.getImageOffset(coverIndex);
if (start >= 0) {
int len = myMobipocketStream.getImageLength(coverIndex);
if (len > 0) {
return new ZLFileImage(MimeTypes.MIME_IMAGE_AUTO, file, start, len);
}
}*/
}
return null;
} catch (IOException e) {
return null;

View file

@ -25,6 +25,7 @@ import org.geometerplus.zlibrary.core.filesystem.ZLFile;
class MobipocketStream extends PalmDocLikeStream {
private final int myFileSize;
private final int myImageStartIndex;
MobipocketStream(ZLFile file) throws IOException {
super(file);
@ -39,11 +40,14 @@ class MobipocketStream extends PalmDocLikeStream {
}
myBuffer = new byte[maxRecordSize];
myRecordIndex = 0;
PdbUtil.skip(myBase, 96);
myImageStartIndex = (int)PdbUtil.readInt(myBase);
}
int getImageOffset(int index) {
try {
return myHeader.Offsets[index + myMaxRecordIndex + 1];
return myHeader.Offsets[index + myImageStartIndex];
} catch (ArrayIndexOutOfBoundsException e) {
return -1;
}
@ -51,7 +55,7 @@ class MobipocketStream extends PalmDocLikeStream {
int getImageLength(int index) {
try {
final int i = index + myMaxRecordIndex + 1;
final int i = index + myImageStartIndex;
final int start = myHeader.Offsets[i];
final int end = (i == myHeader.Offsets.length) ? myFileSize : myHeader.Offsets[i + 1];
return end - start;

View file

@ -199,7 +199,10 @@ public abstract class ZLApplication {
void updateStates();
void hide();
}
private final HashSet<ButtonPanel> myPanels = new HashSet<ButtonPanel>();
private final List<ButtonPanel> myPanels = new LinkedList<ButtonPanel>();
public final List<ButtonPanel> buttonPanels() {
return Collections.unmodifiableList(myPanels);
}
public final void registerButtonPanel(ButtonPanel panel) {
myPanels.add(panel);
}

View file

@ -37,6 +37,11 @@ public final class ZLByteBuffer {
this(20);
}
public ZLByteBuffer(String value) {
myLength = value.length();
myData = value.getBytes();
}
ZLByteBuffer(ZLByteBuffer container) {
final int len = container.myLength;
myData = ZLArrayUtils.createCopy(container.myData, len, len);

View file

@ -44,4 +44,24 @@ public abstract class ZLTextPosition implements Comparable<ZLTextPosition> {
return getCharIndex() - position.getCharIndex();
}
@Override
public int hashCode() {
return (getParagraphIndex() << 16) + (getElementIndex() << 8) + getCharIndex();
}
@Override
public boolean equals(Object object) {
if (object == this) {
return true;
}
if (!(object instanceof ZLTextPosition)) {
return false;
}
final ZLTextPosition position = (ZLTextPosition)object;
return
getParagraphIndex() == position.getParagraphIndex() &&
getElementIndex() == position.getElementIndex() &&
getCharIndex() == position.getCharIndex();
}
}

View file

@ -39,8 +39,8 @@ public class BugReportActivity extends Activity {
}
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.bug_report_view);
final String stackTrace = getIntent().getStringExtra(STACKTRACE);
final TextView reportTextView = (TextView)findViewById(R.id.report_text);