diff --git a/src/org/geometerplus/android/fbreader/ControlButtonPanel.java b/src/org/geometerplus/android/fbreader/ControlButtonPanel.java index 4c21e1a7a..5d885c8b9 100644 --- a/src/org/geometerplus/android/fbreader/ControlButtonPanel.java +++ b/src/org/geometerplus/android/fbreader/ControlButtonPanel.java @@ -29,10 +29,14 @@ import android.widget.RelativeLayout; import org.geometerplus.zlibrary.core.application.ZLApplication; +import org.geometerplus.zlibrary.text.view.ZLTextWordCursor; + import org.geometerplus.fbreader.fbreader.FBReaderApp; class ControlButtonPanel implements ZLApplication.ButtonPanel { public final FBReaderApp Reader; + public ZLTextWordCursor StartPosition; + private boolean myVisible; protected ControlPanel myControlPanel; @@ -50,9 +54,6 @@ class ControlButtonPanel implements ZLApplication.ButtonPanel { } public void updateStates() { - if (myControlPanel != null) { - myControlPanel.updateStates(); - } } public final boolean hasControlPanel() { @@ -80,47 +81,49 @@ class ControlButtonPanel implements ZLApplication.ButtonPanel { } } - 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 buffer) { + public static void restoreVisibilitiesFrom(ZLApplication application, List buffer) { Iterator it = buffer.iterator(); - for (ControlButtonPanel panel: ourPanels) { - panel.setVisibility(it.next()); + for (ZLApplication.ButtonPanel panel : application.buttonPanels()) { + ((ControlButtonPanel)panel).setVisibility(it.next()); } } - public static void saveVisibilitiesTo(List buffer) { + public static void saveVisibilitiesTo(ZLApplication application, List buffer) { buffer.clear(); - for (ControlButtonPanel panel: ourPanels) { - buffer.add(panel.getVisibility()); + for (ZLApplication.ButtonPanel panel : application.buttonPanels()) { + buffer.add(((ControlButtonPanel)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; @@ -137,9 +140,9 @@ 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); } } } @@ -153,6 +156,19 @@ class ControlButtonPanel implements ZLApplication.ButtonPanel { } } + 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()) { diff --git a/src/org/geometerplus/android/fbreader/ControlPanel.java b/src/org/geometerplus/android/fbreader/ControlPanel.java index a7f8f8a05..b76be4837 100644 --- a/src/org/geometerplus/android/fbreader/ControlPanel.java +++ b/src/org/geometerplus/android/fbreader/ControlPanel.java @@ -19,8 +19,6 @@ package org.geometerplus.android.fbreader; -import java.util.ArrayList; - import android.os.Handler; import android.os.Message; import android.content.Context; @@ -34,21 +32,7 @@ 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 myButtons = new ArrayList(); - private final LinearLayout myPlateLayout; - +public class ControlPanel extends LinearLayout { public ControlPanel(Context context) { super(context); @@ -57,25 +41,8 @@ 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); } - 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 +88,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); } } diff --git a/src/org/geometerplus/android/fbreader/FBReader.java b/src/org/geometerplus/android/fbreader/FBReader.java index ff7b0c4c9..75bbd61dd 100644 --- a/src/org/geometerplus/android/fbreader/FBReader.java +++ b/src/org/geometerplus/android/fbreader/FBReader.java @@ -64,7 +64,6 @@ public final class FBReader extends ZLAndroidActivity { private static class NavigationButtonPanel extends ControlButtonPanel { public volatile boolean NavigateDragging; - public ZLTextWordCursor StartPosition; NavigationButtonPanel(FBReaderApp fbReader) { super(fbReader); @@ -86,19 +85,6 @@ public final class FBReader extends ZLAndroidActivity { } } - private static class TextSearchButtonPanel extends ControlButtonPanel { - public ZLTextWordCursor StartPosition; - - TextSearchButtonPanel(FBReaderApp fbReader) { - super(fbReader); - } - - @Override - public void onHide() { - Reader.getTextView().clearFindResults(); - } - } - private static TextSearchButtonPanel myTextSearchPanel; private static NavigationButtonPanel myNavigatePanel; @@ -151,12 +137,10 @@ public final class FBReader extends ZLAndroidActivity { @Override protected void onNewIntent(Intent intent) { if (Intent.ACTION_SEARCH.equals(intent.getAction())) { - final FBReaderApp fbReader = (FBReaderApp)FBReaderApp.Instance(); - final ZLTextView textView = fbReader.getTextView(); final String pattern = intent.getStringExtra(SearchManager.QUERY); final Handler successHandler = new Handler() { public void handleMessage(Message message) { - myTextSearchPanel.StartPosition = new ZLTextWordCursor(textView.getStartCursor()); + myTextSearchPanel.initPosition(); myTextSearchPanel.show(true); } }; @@ -167,8 +151,9 @@ public final class FBReader extends ZLAndroidActivity { }; final Runnable runnable = new Runnable() { public void run() { + final FBReaderApp fbReader = (FBReaderApp)FBReaderApp.Instance(); fbReader.TextSearchPatternOption.setValue(pattern); - if (textView.search(pattern, true, false, false, false) != 0) { + if (fbReader.getTextView().search(pattern, true, false, false, false) != 0) { successHandler.sendEmptyMessage(0); } else { failureHandler.sendEmptyMessage(0); @@ -195,19 +180,13 @@ 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); + myTextSearchPanel.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); + panel.addView(layout); myNavigatePanel.setControlPanel(panel, root, true); } } @@ -215,22 +194,22 @@ public final class FBReader extends ZLAndroidActivity { @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(ZLApplication.Instance()); } @Override public void onPause() { - ControlButtonPanel.saveVisibilities(); + ControlButtonPanel.saveVisibilities(ZLApplication.Instance()); super.onPause(); } @Override public void onStop() { - ControlButtonPanel.removeControlPanels(); + ControlButtonPanel.removeControlPanels(ZLApplication.Instance()); super.onStop(); } @@ -244,16 +223,16 @@ public final class FBReader extends ZLAndroidActivity { @Override public boolean onSearchRequested() { final LinkedList visibilities = new LinkedList(); - ControlButtonPanel.saveVisibilitiesTo(visibilities); - ControlButtonPanel.hideAllPendingNotify(); + final FBReaderApp fbreader = (FBReaderApp)ZLApplication.Instance(); + ControlButtonPanel.saveVisibilitiesTo(fbreader, visibilities); + ControlButtonPanel.hideAllPendingNotify(fbreader); final SearchManager manager = (SearchManager)getSystemService(SEARCH_SERVICE); manager.setOnCancelListener(new SearchManager.OnCancelListener() { public void onCancel() { - ControlButtonPanel.restoreVisibilitiesFrom(visibilities); + ControlButtonPanel.restoreVisibilitiesFrom(fbreader, visibilities); manager.setOnCancelListener(null); } }); - final FBReaderApp fbreader = (FBReaderApp)ZLApplication.Instance(); startSearch(fbreader.TextSearchPatternOption.getValue(), true, null, false); return true; } @@ -287,8 +266,7 @@ public final class FBReader extends ZLAndroidActivity { return false; } myNavigatePanel.NavigateDragging = false; - final ZLTextView textView = (ZLTextView)ZLApplication.Instance().getCurrentView(); - myNavigatePanel.StartPosition = new ZLTextWordCursor(textView.getStartCursor()); + myNavigatePanel.initPosition(); myNavigatePanel.show(true); return true; } @@ -332,12 +310,12 @@ public final class FBReader extends ZLAndroidActivity { 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.storePosition(); } + myNavigatePanel.StartPosition = null; myNavigatePanel.hide(true); } }; diff --git a/src/org/geometerplus/android/fbreader/TextSearchButtonPanel.java b/src/org/geometerplus/android/fbreader/TextSearchButtonPanel.java new file mode 100644 index 000000000..2e3169a51 --- /dev/null +++ b/src/org/geometerplus/android/fbreader/TextSearchButtonPanel.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2009-2011 Geometer Plus + * + * 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 myButtons = new ArrayList(); + + TextSearchButtonPanel(FBReaderApp fbReader) { + super(fbReader); + } + + @Override + public void onHide() { + Reader.getTextView().clearFindResults(); + } + + public void createControlPanel(FBReader activity, RelativeLayout root) { + final ControlPanel panel = new ControlPanel(activity); + setControlPanel(panel, 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); + } + } +} diff --git a/src/org/geometerplus/zlibrary/core/application/ZLApplication.java b/src/org/geometerplus/zlibrary/core/application/ZLApplication.java index cdd991ee4..4d769fb2f 100644 --- a/src/org/geometerplus/zlibrary/core/application/ZLApplication.java +++ b/src/org/geometerplus/zlibrary/core/application/ZLApplication.java @@ -199,7 +199,10 @@ public abstract class ZLApplication { void updateStates(); void hide(); } - private final HashSet myPanels = new HashSet(); + private final List myPanels = new LinkedList(); + public final List buttonPanels() { + return Collections.unmodifiableList(myPanels); + } public final void registerButtonPanel(ButtonPanel panel) { myPanels.add(panel); } diff --git a/src/org/geometerplus/zlibrary/text/view/ZLTextWordCursor.java b/src/org/geometerplus/zlibrary/text/view/ZLTextWordCursor.java index 0dc831f39..f0333c0b2 100644 --- a/src/org/geometerplus/zlibrary/text/view/ZLTextWordCursor.java +++ b/src/org/geometerplus/zlibrary/text/view/ZLTextWordCursor.java @@ -208,4 +208,24 @@ public final class ZLTextWordCursor extends ZLTextPosition { public String toString() { return super.toString() + " (" + myParagraphCursor + "," + myElementIndex + "," + myCharIndex + ")"; } + + @Override + public int hashCode() { + return (myElementIndex << 8) + myCharIndex; + } + + @Override + public boolean equals(Object object) { + if (object == this) { + return true; + } + if (!(object instanceof ZLTextWordCursor)) { + return false; + } + final ZLTextWordCursor cursor = (ZLTextWordCursor)object; + return + myParagraphCursor == cursor.myParagraphCursor && + myElementIndex == cursor.myElementIndex && + myCharIndex == cursor.myCharIndex; + } }