/* * Copyright (C) 2007-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.fbreader; import java.util.*; import org.geometerplus.zlibrary.core.resources.ZLResource; import org.geometerplus.zlibrary.core.filesystem.*; import org.geometerplus.zlibrary.core.application.*; import org.geometerplus.zlibrary.core.dialogs.ZLDialogManager; import org.geometerplus.zlibrary.core.options.*; import org.geometerplus.zlibrary.text.hyphenation.ZLTextHyphenator; import org.geometerplus.zlibrary.text.view.ZLTextWordCursor; import org.geometerplus.android.fbreader.library.LibraryTopLevelActivity; import org.geometerplus.fbreader.bookmodel.BookModel; import org.geometerplus.fbreader.library.Library; import org.geometerplus.fbreader.library.Book; import org.geometerplus.fbreader.library.Bookmark; import android.content.Intent; public final class FBReaderApp extends ZLApplication { public static boolean pass=false; public final ZLBooleanOption AllowPasswdAdjustmentOption = new ZLBooleanOption("Options", "AllowPasswdAdjustment", false); public final ZLStringOption PasswdOption = new ZLStringOption("Options", "PasswdOption", ""); public final ZLBooleanOption AllowScreenBrightnessAdjustmentOption = new ZLBooleanOption("LookNFeel", "AllowScreenBrightnessAdjustment", true); public final ZLStringOption TextSearchPatternOption = new ZLStringOption("TextSearch", "Pattern", ""); public final ZLBooleanOption UseSeparateBindingsOption = new ZLBooleanOption("KeysOptions", "UseSeparateBindings", false); public final ZLBooleanOption EnableDoubleTapOption = new ZLBooleanOption("Options", "EnableDoubleTap", false); public final ZLBooleanOption NavigateAllWordsOption = new ZLBooleanOption("Options", "NavigateAllWords", false); public enum DictionaryTappingAction { doNothing, selectWord, openDictionary } public final ZLEnumOption<DictionaryTappingAction> DictionaryTappingActionOption = new ZLEnumOption<DictionaryTappingAction>("Options", "DictionaryTappingAction", DictionaryTappingAction.selectWord); public final ZLIntegerRangeOption LeftMarginOption = new ZLIntegerRangeOption("Options", "LeftMargin", 0, 30, 4); public final ZLIntegerRangeOption RightMarginOption = new ZLIntegerRangeOption("Options", "RightMargin", 0, 30, 4); public final ZLIntegerRangeOption TopMarginOption = new ZLIntegerRangeOption("Options", "TopMargin", 0, 30, 0); public final ZLIntegerRangeOption BottomMarginOption = new ZLIntegerRangeOption("Options", "BottomMargin", 0, 30, 4); public final ZLIntegerRangeOption ScrollbarTypeOption = new ZLIntegerRangeOption("Options", "ScrollbarType", 0, 3, FBView.SCROLLBAR_SHOW_AS_FOOTER); public final ZLIntegerRangeOption FooterHeightOption = new ZLIntegerRangeOption("Options", "FooterHeight", 8, 20, 9); public final ZLBooleanOption FooterShowTOCMarksOption = new ZLBooleanOption("Options", "FooterShowTOCMarks", true); public final ZLIntegerRangeOption FooterLongTapOption = new ZLIntegerRangeOption("Options", "FooterLongTap", 0, 1, 0/*revert*/); public final ZLBooleanOption FooterShowClockOption = new ZLBooleanOption("Options", "ShowClockInFooter", true); public final ZLBooleanOption FooterShowBatteryOption = new ZLBooleanOption("Options", "ShowBatteryInFooter", true); public final ZLBooleanOption FooterShowProgressOption = new ZLBooleanOption("Options", "ShowProgressInFooter", true); public final ZLBooleanOption FooterIsSensitiveOption = new ZLBooleanOption("Options", "FooterIsSensitive", false); public final ZLStringOption FooterFontOption = new ZLStringOption("Options", "FooterFont", "Droid Sans"); final ZLBooleanOption SelectionEnabledOption = new ZLBooleanOption("Options", "IsSelectionEnabled", true); final ZLStringOption ColorProfileOption = new ZLStringOption("Options", "ColorProfile", ColorProfile.DAY); public final ZLBooleanOption ShowPreviousBookInCancelMenuOption = new ZLBooleanOption("CancelMenu", "previousBook", false); public final ZLBooleanOption ShowPositionsInCancelMenuOption = new ZLBooleanOption("CancelMenu", "positions", true); public final ZLBooleanOption ShowGotoLibInCancelMenuOption = //hym 返回的本地藏书 new ZLBooleanOption("CancelMenu", "positions", true); private final ZLKeyBindings myBindings = new ZLKeyBindings("Keys"); public final FBView BookTextView; public final FBView FootnoteView; public BookModel Model; private final String myArg0; public FBReaderApp(String arg) { myArg0 = arg; //按键事件 addAction(ActionCode.INCREASE_FONT, new ChangeFontSizeAction(this, +2)); addAction(ActionCode.DECREASE_FONT, new ChangeFontSizeAction(this, -2)); addAction(ActionCode.ROTATE, new RotateAction(this)); addAction(ActionCode.FIND_NEXT, new FindNextAction(this)); addAction(ActionCode.FIND_PREVIOUS, new FindPreviousAction(this)); addAction(ActionCode.CLEAR_FIND_RESULTS, new ClearFindResultsAction(this)); addAction(ActionCode.TURN_PAGE_FORWARD, new TurnPageAction(this, true)); addAction(ActionCode.TURN_PAGE_BACK, new TurnPageAction(this, false)); addAction(ActionCode.VOLUME_KEY_SCROLL_FORWARD, new VolumeKeyTurnPageAction(this, true)); addAction(ActionCode.VOLUME_KEY_SCROLL_BACK, new VolumeKeyTurnPageAction(this, false)); //addAction(ActionCode.COPY_SELECTED_TEXT_TO_CLIPBOARD, new DummyAction(this)); //addAction(ActionCode.OPEN_SELECTED_TEXT_IN_DICTIONARY, new DummyAction(this)); //addAction(ActionCode.CLEAR_SELECTION, new DummyAction(this)); addAction(ActionCode.SWITCH_TO_DAY_PROFILE, new SwitchProfileAction(this, ColorProfile.DAY)); addAction(ActionCode.SWITCH_TO_NIGHT_PROFILE, new SwitchProfileAction(this, ColorProfile.NIGHT)); BookTextView = new FBView(this); FootnoteView = new FBView(this); setView(BookTextView); } public void initWindow() { super.initWindow(); ZLDialogManager.Instance().wait("loadingBook", new Runnable() { public void run() { Book book = createBookForFile(ZLFile.createFileByPath(myArg0)); if (book == null) { book = Library.getRecentBook(); } if ((book == null) || !book.File.exists()) { book = Book.getByFile(Library.getHelpFile()); } openBookInternal(book, null); } }); } public void gotoLib(){ // Model.Book=null; // doAction(ActionCode.SHOW_MENU); doAction(ActionCode.SHOW_LIBRARY); //// final BookModel model = Reader.Model; // Intent intent = new Intent(myWindow.getApplicationContext(), LibraryTopLevelActivity.class); // if (Model != null && Model.Book != null) { // intent.putExtra(LibraryTopLevelActivity.SELECTED_BOOK_PATH_KEY, Model.Book.File.getPath()); // } // myWindow.startActivity(intent); } public void openBook(final Book book, final Bookmark bookmark) { if (book == null) { return; } if (Model != null) { if (bookmark == null & book.File.getPath().equals(Model.Book.File.getPath())) { return; } } ZLDialogManager.Instance().wait("loadingBook", new Runnable() { public void run() { openBookInternal(book, bookmark); } }); } private ColorProfile myColorProfile; public ColorProfile getColorProfile() { if (myColorProfile == null) { myColorProfile = ColorProfile.get(getColorProfileName()); } return myColorProfile; } public String getColorProfileName() { return ColorProfileOption.getValue(); } public void setColorProfileName(String name) { ColorProfileOption.setValue(name); myColorProfile = null; } public ZLKeyBindings keyBindings() { return myBindings; } public FBView getTextView() { return (FBView)getCurrentView(); } public void tryOpenFootnote(String id) { if (Model != null) { BookModel.Label label = Model.getLabel(id); if (label != null) { addInvisibleBookmark(); if (label.ModelId == null) { BookTextView.gotoPosition(label.ParagraphIndex, 0, 0); } else { FootnoteView.setModel(Model.getFootnoteModel(label.ModelId)); setView(FootnoteView); FootnoteView.gotoPosition(label.ParagraphIndex, 0, 0); } repaintView(); } } } public void clearTextCaches() { BookTextView.clearCaches(); FootnoteView.clearCaches(); } void openBookInternal(Book book, Bookmark bookmark) { if (book != null) { onViewChanged(); if (Model != null) { Model.Book.storePosition(BookTextView.getStartCursor()); } BookTextView.setModel(null); FootnoteView.setModel(null); clearTextCaches(); Model = null; System.gc(); System.gc(); Model = BookModel.createModel(book); if (Model != null) { ZLTextHyphenator.Instance().load(book.getLanguage()); BookTextView.setModel(Model.BookTextModel); BookTextView.gotoPosition(book.getStoredPosition()); if (bookmark == null) { setView(BookTextView); } else { gotoBookmark(bookmark); } Library.addBookToRecentList(book); } } repaintView(); } public void gotoBookmark(Bookmark bookmark) { addInvisibleBookmark(); final String modelId = bookmark.ModelId; if (modelId == null) { BookTextView.gotoPosition(bookmark); setView(BookTextView); } else { FootnoteView.setModel(Model.getFootnoteModel(modelId)); FootnoteView.gotoPosition(bookmark); setView(FootnoteView); } repaintView(); } public void showBookTextView() { setView(BookTextView); } private Book createBookForFile(ZLFile file) { if (file == null) { return null; } Book book = Book.getByFile(file); if (book != null) { book.insertIntoBookList(); return book; } if (file.isArchive()) { for (ZLFile child : file.children()) { book = Book.getByFile(child); if (book != null) { book.insertIntoBookList(); return book; } } } return null; } @Override public void openFile(ZLFile file) { final Book book = createBookForFile(file); if (book != null) { openBook(book, null); } } public void onWindowClosing() { if (Model != null && BookTextView != null) { Model.Book.storePosition(BookTextView.getStartCursor()); } } public static enum CancelActionType { gotoLib, previousBook, returnTo, close } public boolean isGotoLib(CancelActionDescription description ){ switch (description.Type) { case gotoLib: return true; } return false; } public static class CancelActionDescription { public final CancelActionType Type; public final String Title; public final String Summary; CancelActionDescription(CancelActionType type, String summary) { final ZLResource resource = ZLResource.resource("cancelMenu"); Type = type; Title = resource.getResource(type.toString()).getValue(); Summary = summary; } } private static class BookmarkDescription extends CancelActionDescription { final Bookmark Bookmark; BookmarkDescription(Bookmark b) { super(CancelActionType.returnTo, b.getText()); Bookmark = b; } } private final ArrayList<CancelActionDescription> myCancelActionsList = new ArrayList<CancelActionDescription>(); public List<CancelActionDescription> getCancelActionsList() { myCancelActionsList.clear(); if (ShowPreviousBookInCancelMenuOption.getValue()) { final Book previousBook = Library.getPreviousBook(); if (previousBook != null) { myCancelActionsList.add(new CancelActionDescription( CancelActionType.previousBook, previousBook.getTitle() )); } } if (ShowPositionsInCancelMenuOption.getValue()) { if (Model != null && Model.Book != null) { for (Bookmark bookmark : Bookmark.invisibleBookmarks(Model.Book)) { myCancelActionsList.add(new BookmarkDescription(bookmark)); } } } if (ShowGotoLibInCancelMenuOption.getValue()) { myCancelActionsList.add(new CancelActionDescription( CancelActionType.gotoLib, null )); } myCancelActionsList.add(new CancelActionDescription( CancelActionType.close, null )); return myCancelActionsList; } public void runCancelAction(int index) { if (index < 0 || index >= myCancelActionsList.size()) { return; } final CancelActionDescription description = myCancelActionsList.get(index); switch (description.Type) { case gotoLib: gotoLib(); break; case previousBook: openBook(Library.getPreviousBook(), null); break; case returnTo: { final Bookmark b = ((BookmarkDescription)description).Bookmark; b.delete(); // addInvisibleBookmark(); gotoBookmark(b); break; } case close: closeWindow(); break; } } 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) { bookmarks.get(i).delete(); } } } //也是添加返回书签,在书签中不显示的。导航中跳转用。 public void addInvisibleBookmark(ZLTextWordCursor cursor) { if (cursor != null && Model != null && Model.Book != null && getTextView() == BookTextView) { updateInvisibleBookmarksList(new Bookmark( Model.Book, getTextView().getModel().getId(), cursor, 10, false )); } } //怎么添加 这个 返回菜单中的 书签???;返回书签 由 6-10 public void addInvisibleBookmark() { if (Model.Book != null && getTextView() == BookTextView) { updateInvisibleBookmarksList(addBookmark(10, false)); } } public Bookmark addBookmark(int maxLength, boolean visible) { final FBView view = getTextView(); final ZLTextWordCursor cursor = view.getStartCursor(); if (cursor.isNull()) { return null; } return new Bookmark( Model.Book, view.getModel().getId(), cursor, maxLength, visible ); } }