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 tts

Conflicts:
	assets/default/menubar.xml
	src/org/geometerplus/android/fbreader/FBReader.java
	src/org/geometerplus/fbreader/fbreader/FBReaderApp.java
This commit is contained in:
Nikolay Pultsin 2011-03-26 23:48:20 +00:00
commit 2bab934381
93 changed files with 1147 additions and 752 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="9917" android:versionName="0.99.17" android:installLocation="auto">
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.geometerplus.zlibrary.ui.android" android:versionCode="10000" android:versionName="1.0" 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,4 +1,15 @@
===== 0.99.18 (Mar ??, 2011) =====
===== 1.0 (Mar ??, 2011) =====
* Differnt (and configurable) actions for short and long Back button press (original code by Steffen Siebert)
* SlovoEd dictionaries support has been fixed
* Czech translation has been updated (by Marek Pavelka)
* No OutOfMemoryErrors in image loading
* Float series index parsing has been fixed
* Separate color for visited hyperlinks (original code by Steffen Siebert)
* Removed menubar.xml: menu list is moved into the code
* Proguard obfuscation has been added; package size decreased
===== 0.99.18 (Mar 15, 2011) =====
* Web-free icon
* Epub TOC/cover processing has been fixed
===== 0.99.17 (Mar 13, 2011) =====

View file

@ -2,4 +2,4 @@ DONE hyphenations are not changed after language changing in book info dialog
* scrolling: 4 directions
* scrolling: add 3D animation
DONE 'disable douple tapping' option
* float numbers as series index
DONE float numbers as series index

View file

@ -1 +1 @@
0.99.17
1.0

View file

@ -1,19 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<FictionBook xmlns="http://www.gribuser.ru/xml/fictionbook/2.0" xmlns:l="http://www.w3.org/1999/xlink"><description><title-info><author><last-name>FBReader</last-name></author> <book-title>O aplikaci FBReaderJ</book-title> <lang>cs</lang></title-info></description>
<body>
<title><p>O aplikaci FBReaderJ &FBReaderVersion;</p></title>
<p>FBReaderJ je čtečka e-knih pro <a l:href="http://www.android.com/">platformu Android</a>. Je to klon <a l:href="http://www.fbreader.org/">čtečky knih FBReader</a> napsaný v Java stejnými autory. FBReaderJ podporuje několik formátů e-knih: <code>oeb</code>, <code>epub</code> a <code>fb2</code>. V budoucích vydáních bude seznam rozšířen o podporu stejných formátů jako v originální aplikaci FBReader. Je podporováno přímé čtení z archivů <code>zip</code>, <code>tar</code> a <code>gzip</code>.</p>
<p>FBReaderJ si můžete nastavit tak, abyste mohli číst knihy s potěšením. Barvy, písma a spousta dalších vlastností může být změněna v <code>dialogovém okně předvoleb</code>.</p>
<p>FBReaderJ je šířen podle podmíneek <a l:href="http://www.gnu.org/licenses/gpl.html">GNU GPL</a>.</p>
<empty-line/>
<subtitle><p>Jak začít</p></subtitle>
<p>Jsou dva způsoby jak přidat knihu do knihovny aplikace FBReaderJ.</p>
<p>První je zkopírovat soubor s knihou do vašeho zařízení do adresáře <code>/sdcard/Books</code> (nebo jakéhokoliv jeho podadresáře). FBReader přidá tuto knihu automaticky.</p>
<p>Druhý způsob je klepnout na odkaz na knihu (např. na odkaz na soubor s příponou <code>.epub</code>, <code>.oeb</code>, <code>.fb2</code> nebo <code>.fb2.zip</code>) ve standardním prohlížeči v Androidu. Kniha bude stažena do zařízení a otevřena v aplikaci FBReaderJ. Pokud klepnete znovu na stejný odkaz, kniha se nebude znovu stahovat, ale pro čtení se použije místní kopie.</p>
<title><p>O aplikaci FBReader &FBReaderVersion;</p></title>
<p>FBReader je čtečka elektronických knih. FBReader podporuje formáty souborů <code>ePub</code> a <code>fb2</code>. FBReader bohužel neumí číst soubory chráněné DRM. Pokud máte knihy v podporovaných formátech, jednoduše umístěte vaše soubory do adresáře <code>Books</code> na paměťové kartě. Knihy budou dostupné v <a l:href="fbreader-action://library">knihovně</a>. <a l:href="fbreader-action://networkLibrary">Síťová knihovna</a> obsahuje rozsáhlou sbírku elektronických knih, které si můžete stáhnout nebo zakoupit.</p>
<p>Otáčet stránky můžete vodorovným tahem prstem po displeji nebo pomocí hardwarových tlačítek ovládání hlasitosti.</p>
<p>FBReader je široce nastavitelný. Můžete si nastavit barvy, písma, adresáře, možnosti otáčení stránky atd. v <a l:href="fbreader-action://preferences">dialogovém okně předvoleb</a>.</p>
<p>Pokud na vašem zařízení nemáte žádné hardwarové tlačítko <code>Menu</code>, můžete spustit menu dotykem uprostřed spodní části obrazovky.</p>
<p>Příjemnou zábavu!</p>
<empty-line/>
<subtitle><p>Související stránky</p></subtitle>
<p>Více informací o aplikacích FBReader a FBReaderJ naleznete na <a l:href="http://www.fbreader.org">stránce FBReader</a>.</p>
<p>Pokud chcete být upozorňováni na nové verze, přihlašte se k odběru <a l:href="http://freshmeat.net/projects/fbreaderj">projektu FBReaderJ na freshmeat</a>.</p>
<p>Pokud máte nějaké dotazy nebo návrhy, použijte <a l:href="http://groups.google.com/group/fbreader">skupinu FBReader na googlegroups</a>.</p>
<p>Více informací o aplikaci FBReader naleznete na <a l:href="http://www.fbreader.org/FBReaderJ">naší stránce</a>.</p>
<p>Oznámení vydání a další novinky jsou dostupné na <a l:href="http://twitter.com/fbreader">twitteru</a>.</p>
<p>Pokud máte nějaké dotazy nebo návrhy, použijte <a l:href="http://groups.google.com/group/fbreader">skupinu FBReader v Google skupinách</a>.</p>
<p>Pokud se vám aplikace líbí a chcete podpořit její vývoj, navštivte naši stránku a poskytněte nám <a l:href="http://www.fbreader.org/donation/make.php">dobrovolný dar</a>.</p>
<p>Pokud chcete kontaktovat autory, <a l:href="mailto:contact@geometerplus.com">použijte email</a>.</p>
<p>Do češtiny přeložil <a l:href="http://www.facebook.com/mara.pavelka">Marek Pavelka</a>.</p>
</body>
</FictionBook>

View file

@ -1,19 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<FictionBook xmlns="http://www.gribuser.ru/xml/fictionbook/2.0" xmlns:l="http://www.w3.org/1999/xlink"><description><title-info><author><last-name>FBReader</last-name></author> <book-title>About FBReaderJ</book-title> <lang>en</lang></title-info></description>
<body>
<title><p>About FBReaderJ &FBReaderVersion;</p></title>
<p>FBReaderJ is an e-book reader for the <a l:href="http://www.android.com/">Android platform</a>. It is a clone of the <a l:href="http://www.fbreader.org/">FBReader book reader</a> written in Java by the same authors. FBReaderJ supports several e-book formats: <code>oeb</code>, <code>epub</code>, <code>fb2</code>. In future releases the list will be extended to support the same formats as the original FBReader. Direct reading from <code>zip</code>, <code>tar</code> and <code>gzip</code> archives is supported.</p>
<p>You can configure FBReaderJ to read books with a pleasure. Colors, fonts, key bindings and many other properties can be changed in the <code>Preferences Dialog</code>.</p>
<p>FBReaderJ is distributed under the terms of the <a l:href="http://www.gnu.org/licenses/gpl.html">GNU GPL</a>.</p>
<empty-line/>
<subtitle><p>How To Start</p></subtitle>
<p>There are 2 ways to add book into FBReaderJ library.</p>
<p>The first one is to copy book file to your device into the directory <code>/sdcard/Books</code> (or any its subdirectory). FBReader will add this book automatically.</p>
<p>The second way is to click a book link (i.e. on a link to a file with extension <code>.epub</code>, <code>.oeb</code>, <code>.fb2</code> or <code>.fb2.zip</code>) in the standard Android browser. A book will be downloaded to the device and opened in FBReaderJ. If you'll click the same link again, a book will not be downloaded again, local copy will be used for reading.</p>
<title><p>About FBReader &FBReaderVersion;</p></title>
<p>FBReader is an e-book reader. FBReader supports <code>ePub</code> and <code>fb2</code> file formats. FBReader cannot read DRM-protected files, sorry. If you have any books in supported formats, just put your files into <code>Books</code> catalog on the memory card. The books will be available in <a l:href="fbreader-action://library">the library</a>. <a l:href="fbreader-action://networkLibrary">Network library</a> contains a large set of e-books you can download or buy.</p>
<p>To turn pages swipe screen horizonatally or use hardware volume keys.</p>
<p>FBReader is highly customizable. You can configure colors, fonts, directories, page turning options, etc. in the <a l:href="fbreader-action://preferences">preferences dialog</a>.</p>
<p>If your device has no hardware <code>Menu</code> button, touch bottom-center part of the screen to run menu.</p>
<p>Enjoy!</p>
<empty-line/>
<subtitle><p>Related sites</p></subtitle>
<p>More information about FBReader and FBReaderJ can be found at <a l:href="http://www.fbreader.org">FBReader site</a>.</p>
<p>If you want to be notified about new releases, please subscribe to <a l:href="http://freshmeat.net/projects/fbreaderj">FBReaderJ project at freshmeat</a>.</p>
<p>More information about FBReader can be found at <a l:href="http://www.fbreader.org/FBReaderJ">our site</a>.</p>
<p>Releases announcements and other news are available on <a l:href="http://twitter.com/fbreader">twitter</a>.</p>
<p>If you have any questions or suggestions, please use <a l:href="http://groups.google.com/group/fbreader">FBReader group at googlegroups</a>.</p>
<p>If you like the program and would like to support its development, please visit <a l:href="http://www.fbreader.org/donation/make.php">make donation</a> page.</p>
<p>To contact authors, <a l:href="mailto:contact@geometerplus.com">use an e-mail</a>.</p>
</body>
</FictionBook>

View file

@ -1,19 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<FictionBook xmlns="http://www.gribuser.ru/xml/fictionbook/2.0" xmlns:l="http://www.w3.org/1999/xlink"><description><title-info><author><last-name>FBReader</last-name></author> <book-title>О программе FBReaderJ</book-title> <lang>ru</lang></title-info></description>
<FictionBook xmlns="http://www.gribuser.ru/xml/fictionbook/2.0" xmlns:l="http://www.w3.org/1999/xlink"><description><title-info><author><last-name>FBReader</last-name></author> <book-title>О программе FBReader</book-title> <lang>ru</lang></title-info></description>
<body>
<title><p>О программе FBReaderJ &FBReaderVersion;</p></title>
<p>FBReaderJ &#8211; программа для чтения электронных книг, работающая на платформе <a l:href="http://www.android.com/">Android</a>. Она представляет из себя клон программы <a l:href="http://www.fbreader.org/">FBReader</a>, написанный на Java теми же авторами. FBReaderJ позволяет читать книги в разных форматах: <code>oeb</code>, <code>epub</code>, <code>fb2</code>. В новых версиях будут добавлены остальные форматы, поддерживаемые оригинальным FBReader. Файлы можно читать напрямую из архивов <code>zip</code>, <code>tar</code> и <code>gzip</code>.</p>
<p>Вы можете настроить FBReaderJ, чтобы читать так, как удобнее именно вам. Цвета, шрифты, настройки клавиш и многое другое можно поменять в <code>диалоге настроек</code>.</p>
<p>FBReaderJ распространяется свободно, включая исходные тексты, под лицензией <a l:href="http://www.gnu.org/licenses/gpl.html">GNU GPL</a>.</p>
<empty-line/>
<subtitle><p>С чего начать</p></subtitle>
<p>Есть 2 способа добавить книгу в библиотеку FBReaderJ.</p>
<p>Вы можете положить файл книги в каталог <code>/sdcard/Books</code> на устройстве (или любой его подкаталог). Книга появится в списке при следующем открытии библиотеки.</p>
<p>Если книга доступна на каком-нибудь Интернет-сайте, достаточно просто открыть соответствующую ссылку в браузере прямо на телефоне. Книжка будет скачана и сразу открыта в FBReaderJ. Если вы снова нажмете на ту же ссылку, второй раз книжка скачиваться не будет, откроется сохраненный при первом скачивании файл.</p>
<title><p>О программе FBReader &FBReaderVersion;</p></title>
<p>Эта программа предназначена для чтения электронных книг в форматах ePub и fb2. Если у вас уже есть подходящие книги, положите их на карту памяти в каталог Books. После этого вы найдете свои книги в <a l:href="fbreader-action://library">библиотеке</a>. В FBReader встроена <a l:href="fbreader-action://networkLibrary">сетевaя библиотека</a>, из которой можно бесплатно скачивать и покупать книги.</p>
<p>Для перелистывания страницы коснитесь правой части экрана (или левой, если хотите вернуться на предыдущую страницу). Другие варианты перелистывания &#8211; провести по экрану пальцем справа налево, или воспользоваться кнопками регулировки громкости.</p>
<p>Вы можете настроить FBReader, чтобы читать так, как удобно именно вам. Цвета, шрифты, каталоги, способы листания, и многое другое можно поменять в <a l:href="fbreader-action://preferences">диалоге настроек</a>.</p>
<p>Обычно управление программой происходит с помощью меню. Если на вашем устройстве нет кнопки Menu, просто нажмите на экран в середине его нижней части.</p>
<p>Приятного чтения!</p>
<empty-line/>
<subtitle><p>Ссылки</p></subtitle>
<p>Информацию о программах FBReader и FBReaderJ и их свежие версии можно найти на <a l:href="http://www.fbreader.org">сайте FBReader'а</a>.</p>
<p>Если вы хотите получать сообщения о новых версиях, подпишитесь на <a l:href="http://freshmeat.net/projects/fbreaderj">проект FBReaderJ на freshmeat</a>.</p>
<p>Чтобы связаться с авторами программы, воспользуйтесь <a l:href="http://groups.google.com/group/fbreader">группой FBReader на googlegroups</a>.</p>
<p>Узнать подробнее о программе FBReader, скачать версии для разных устройств и исходные тексты можно на <a l:href="http://www.fbreader.org/FBReaderJ">нашем сайте</a>.</p>
<p>Сообщения о вышедших версиях и другие новости публикуются в <a l:href="http://twitter.com/fbreader">twitter'е</a>.</p>
<p>Если вы хотите связаться с авторами, <a l:href="mailto:contact@geometerplus.com">напишите</a> нам электронное письмо.</p>
</body>
</FictionBook>

View file

@ -2,7 +2,7 @@
<keymap>
<binding key="&lt;VolumeDown&gt;" action="volumeKeyScrollForward"/>
<binding key="&lt;VolumeUp&gt;" action="volumeKeyScrollBackward"/>
<binding key="&lt;Back&gt;" action="cancel"/>
<binding key="&lt;Back&gt;" action="cancelMenu"/>
<binding key="&lt;Enter&gt;" action="processHyperlink"/>
<binding key="&lt;PadCenter&gt;" action="processHyperlink"/>
</keymap>

View file

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<menubar>
<item id="library"/>
<item id="networkLibrary"/>
<item id="toc"/>
<item id="bookmarks"/>
<item id="night"/>
<item id="day"/>
<item id="search"/>
<item id="preferences"/>
<item id="bookInfo"/>
<item id="rotate"/>
<item id="increaseFont"/>
<item id="decreaseFont"/>
<item id="navigate"/>
<item id="speak"/>
</menubar>

View file

@ -53,11 +53,11 @@
<node name="byTitle" value="Podle názvu">
<node name="summary" value="Knihy seřazeny podle názvu"/>
</node>
<node name="byDate" value="By date" toBeTranslated="true">
<node name="summary" value="Books sorted by date of purchasing" toBeTranslated="true"/>
<node name="byDate" value="Podle data">
<node name="summary" value="Knihy seřazeny podle data zakoupení"/>
</node>
<node name="bySeries" value="By series" toBeTranslated="true">
<node name="summary" value="Books sorted by series" toBeTranslated="true"/>
<node name="bySeries" value="Podle série">
<node name="summary" value="Knihy seřazeny podle série"/>
</node>
<node name="openCatalog" value="Otevřít katalog"/>
<node name="showResults" value="Zobrazit výsledky"/>
@ -69,18 +69,22 @@
<node name="deleteDemo" value="Odstranit ukázku"/>
<node name="downloadDemo" value="Stáhnout ukázku"/>
<node name="buy" value="Zakoupit (%s)"/>
<node name="addToBasket" value="Add to basket" toBeTranslated="true"/>
<node name="removeFromBasket" value="Remove from basket" toBeTranslated="true"/>
<node name="addToBasket" value="Přidat do košíku"/>
<node name="removeFromBasket" value="Odebrat z košíku"/>
<node name="openInBrowser" value="Otevřít v prohlížeči" />
<node name="stopLoading" value="Zastavit načítání" />
<node name="stopSearching" value="Zastavit vyhledávání" />
<node name="signIn" value="Přihlásit"/>
<node name="signOut" value="Odhlásit (%s)"/>
<node name="refillAccount" value="Doplnit účet (aktuálně: %s)"/>
<node name="refillTitle" value="Doplnit účet"/>
<node name="refillViaSms" value="Textová zpráva"/>
<node name="refillViaBrowser" value="Otevřít stránku v prohlížeči"/>
<node name="refillSummary" value="Aktuálně: %s"/>
<node name="topup" value="Doplnit účet (aktuálně: %s)"/>
<node name="topupTitle" value="Doplnit účet"/>
<node name="topupViaCreditCard" value="Credit card" toBeTranslated="true"/>
<node name="topupViaSelfServiceKiosk" value="Self-service kiosk" toBeTranslated="true"/>
<node name="topupViaSms" value="Textová zpráva"/>
<node name="topupViaBrowser" value="Otevřít stránku v prohlížeči"/>
<node name="topupSummary" value="Aktuálně: %s"/>
<node name="basket" value="Košík"/>
<node name="basketSummary" value="Knihy, které chci zakoupit"/>
<node name="alreadyDownloading" value="Kniha se stahuje" />
<node name="alreadyDownloadingDemo" value="Ukázka se stahuje" />
<node name="stoppingCatalogLoading" value="Zastavování načítání" />
@ -106,12 +110,14 @@
<node name="networkSearch" value="Prohledávání sítě"/>
<node name="reload" value="Znovu načíst"/>
<node name="signIn" value="Přihlásit"/>
<node name="signOut" value="Odhlásit (%s)"/>
<node name="signUp" value="Přihlásit" />
<node name="refillAccount" value="Doplnit účet"/>
<node name="signOut" value="Odhlásit (%s)"/>
<node name="topup" value="Doplnit účet"/>
<node name="addCustomCatalog" value="Přidat katalog"/>
<node name="refreshCatalogsList" value="Aktualizovat katalogy"/>
<node name="languages" value="Filtr jazyků"/>
<node name="clearBasket" value="Vymazat košík"/>
<node name="buyAllBooks" value="Zakoupit všechny knihy"/>
</node>
</node>
<node name="networkBookView">
@ -123,7 +129,7 @@
<node name="series" value="Série:" />
<node name="indexInSeries" value="Díl v sérii:" />
<node name="tags" value="Štítky:" />
<node name="catalog" value="Catalog:" toBeTranslated="true"/>
<node name="catalog" value="Katalog:"/>
</node>
<node name="bookInfo">
<node name="bookInfo" value="Informace o knize" />
@ -175,6 +181,8 @@
<node name="cancelMenu">
<node name="previousBook" value="Otevřít předchozí knihu"/>
<node name="returnTo" value="Vrátit se na..."/>
<node name="back" value="Back" toBeTranslated="true"/>
<node name="forward" value="Forward" toBeTranslated="true"/>
<node name="close" value="Zavřít FBReader"/>
</node>
<node name="menu">
@ -221,7 +229,7 @@
<node name="openBook" value="Číst" />
<node name="editInfo" value="Upravit" />
<node name="reloadInfo" value="Znovu načíst" />
<node name="refillAccount" value="Doplnit účet"/>
<node name="topup" value="Doplnit účet"/>
</node>
<node name="plugin">
<node name="installTitle" value="Instalovat doplněk" />
@ -422,6 +430,7 @@
<node name="selectionBackground" value="Pozadí výběru"/>
<node name="text" value="Běžný text"/>
<node name="hyperlink" value="Hypertextový odkaz"/>
<node name="hyperlinkVisited" value="Visited hyperlink text" toBeTranslated="true"/>
<node name="highlighting" value="Pozadí výsledků vyhledávání"/>
<node name="footer" value="Patička"/>
</node>
@ -514,6 +523,16 @@
<node name="summaryOff" value="Posouvat stránky svisle"/>
</node>
</node>
<node name="tapZones" value="Oblasti dotyku">
<node name="summary" value="Akce pro dotyk prstem"/>
<node name="tapZonesScheme" value="Schéma oblastí dotyku">
<node name="left_to_right" value="Posouvání stránky zleva doprava"/>
<node name="right_to_left" value="Posouvání stránky zprava doleva"/>
<node name="up" value="Posouvání stránky zdola nahoru"/>
<node name="down" value="Posouvání stránky zhora dolů"/>
<node name="custom" value="Vlastní..."/>
</node>
</node>
<node name="dictionary" value="Slovník">
<node name="summary" value="Nastavení slovníku"/>
<node name="dictionary" value="Slovník"/>
@ -527,15 +546,26 @@
<node name="summaryOff" value="Navigace klávesami prochází pouze hypertextové odkazy"/>
</node>
</node>
<node name="cancelMenu" value="Cancel menu" toBeTranslated="true">
<node name="summary" value="Back button action list" toBeTranslated="true"/>
<node name="previousBook" value="Previous book" toBeTranslated="true">
<node name="summaryOn" value="Show 'return to previous book' item" toBeTranslated="true"/>
<node name="summaryOff" value="Don't show 'return to previous book' item" toBeTranslated="true"/>
<node name="cancelMenu" value="Nabídka Zrušit">
<node name="summary" value="Seznam akcí tlačítka Zpět"/>
<node name="previousBook" value="Předchozí kniha">
<node name="summaryOn" value="Zobrazit položku 'návrat na předchozí knihu'"/>
<node name="summaryOff" value="Nezobrazovat položku 'návrat na předchozí knihu'"/>
</node>
<node name="positions" value="Last 3 positions" toBeTranslated="true">
<node name="summaryOn" value="Show items for last 3 positions in the book" toBeTranslated="true"/>
<node name="summaryOff" value="Don't show items for last 3 positions in the book" toBeTranslated="true"/>
<node name="positions" value="Poslední 3 pozice">
<node name="summaryOn" value="Zobrazit položky pro poslední 3 pozice v knize"/>
<node name="summaryOff" value="Nezobrazovat položky pro poslední 3 pozice v knize"/>
</node>
<node name="backKeyAction" value="Back key action" toBeTranslated="true">
<node name="exit" value="Close FBReader" toBeTranslated="true"/>
<node name="goBack" value="Navigate back" toBeTranslated="true"/>
<node name="cancelMenu" value="Show cancel menu" toBeTranslated="true"/>
</node>
<node name="backKeyLongPressAction" value="Back key long press action" toBeTranslated="true">
<node name="exit" value="Close FBReader" toBeTranslated="true"/>
<node name="goBack" value="Navigate back" toBeTranslated="true"/>
<node name="cancelMenu" value="Show cancel menu" toBeTranslated="true"/>
<node name="none" value="No action" toBeTranslated="true"/>
</node>
</node>
</node>
@ -598,7 +628,7 @@
<node name="register" value="Přihlásit" />
</node>
<node name="CustomCatalogDialog">
<node name="title" value="FBReader: add custom catalog" toBeTranslated="true" />
<node name="title" value="FBReader: přidat vlastní katalog" />
<node name="catalogTitle" value="Název" />
<node name="catalogUrl" value="URL" />
<node name="catalogSummary" value="Stručný obsah" />
@ -632,8 +662,8 @@
<node name="dictionaryIsNotInstalled" value="Slovník není bohužel nainstalován"/>
<node name="permissionDenied" value="Oprávnění bylo bohužel odmítnuto"/>
<node name="noFavorites" value="Seznam oblíbených je bohužel prázdný"/>
<node name="emptyCatalog" value="Katalog je prázdný"/>
<node name="emptyBasket" value="Your basket is empty, sorry" toBeTranslated="true"/>
<node name="emptyCatalog" value="Katalog je bohužel prázdný" />
<node name="emptyBasket" value="Váš košík je bohužel prázdný" />
</node>
<node name="external">
<node name="browser" value="Prohlížeč"/>
@ -642,6 +672,6 @@
<node name="mobipocketPlugin">
<node name="unknown" value="Neznámá chyba"/>
<node name="unsupportedCompressionMethod" value="Nepodporovaná metoda komprese"/>
<node name="encriptedFile" value="Sobor chráněný DRM"/>
<node name="encriptedFile" value="Soubor chráněný DRM"/>
</node>
</resources>

View file

@ -77,11 +77,13 @@
<node name="stopSearching" value="Suchen stoppen" />
<node name="signIn" value="Einloggen"/>
<node name="signOut" value="Ausloggen (%s)"/>
<node name="refillAccount" value="Konto aufladen (derzeit: %s)"/>
<node name="refillTitle" value="Konto aufladen"/>
<node name="refillViaSms" value="Text messages" toBeTranslated="true"/>
<node name="refillViaBrowser" value="Open page in browser" toBeTranslated="true"/>
<node name="refillSummary" value="Derzeit: %s"/>
<node name="topup" value="Konto aufladen (derzeit: %s)"/>
<node name="topupTitle" value="Konto aufladen"/>
<node name="topupViaCreditCard" value="Credit card" toBeTranslated="true"/>
<node name="topupViaSelfServiceKiosk" value="Self-service kiosk" toBeTranslated="true"/>
<node name="topupViaSms" value="Text messages" toBeTranslated="true"/>
<node name="topupViaBrowser" value="Open page in browser" toBeTranslated="true"/>
<node name="topupSummary" value="Derzeit: %s"/>
<node name="alreadyDownloading" value="Buch wird schon geladen" />
<node name="alreadyDownloadingDemo" value="Leseprobe wird schon geladen" />
<node name="stoppingCatalogLoading" value="Herunterladen abbrechen" />
@ -109,7 +111,7 @@
<node name="signIn" value="Einloggen"/>
<node name="signOut" value="Ausloggen (%s)"/>
<node name="signUp" value="Anmelden" />
<node name="refillAccount" value="Konto aufladen"/>
<node name="topup" value="Konto aufladen"/>
<node name="addCustomCatalog" value="Katalog hinzufügen"/>
<node name="refreshCatalogsList" value="Liste der Kataloge aktualisieren"/>
<node name="languages" toBeTranslated="true" value="Language filter"/>
@ -176,6 +178,8 @@
<node name="cancelMenu">
<node name="previousBook" value="Open previous book" toBeTranslated="true"/>
<node name="returnTo" value="Return to ..." toBeTranslated="true"/>
<node name="back" value="Back" toBeTranslated="true"/>
<node name="forward" value="Forward" toBeTranslated="true"/>
<node name="close" value="Close FBReader" toBeTranslated="true"/>
</node>
<node name="menu">
@ -222,7 +226,7 @@
<node name="openBook" value="Read" toBeTranslated="true" />
<node name="editInfo" value="Edit" toBeTranslated="true" />
<node name="reloadInfo" value="Reload" toBeTranslated="true" />
<node name="refillAccount" value="Konto aufladen"/>
<node name="topup" value="Konto aufladen"/>
</node>
<node name="plugin">
<node name="installTitle" value="Install plugin" toBeTranslated="true" />
@ -423,6 +427,7 @@
<node name="selectionBackground" value="Hintergrund von ausgewählten Text"/>
<node name="text" value="Normalen Text"/>
<node name="hyperlink" value="Hyperlinks"/>
<node name="hyperlinkVisited" value="Besuchte Hyperlinks"/>
<node name="highlighting" value="Hintergrund der Suchergebnisse"/>
<node name="footer" value="Footer" toBeTranslated="true"/>
</node>
@ -538,6 +543,17 @@
<node name="summaryOn" value="Show items for last 3 positions in the book" toBeTranslated="true"/>
<node name="summaryOff" value="Don't show items for last 3 positions in the book" toBeTranslated="true"/>
</node>
<node name="backKeyAction" value="Back key action" toBeTranslated="true">
<node name="exit" value="Close FBReader" toBeTranslated="true"/>
<node name="goBack" value="Navigate back" toBeTranslated="true"/>
<node name="cancelMenu" value="Show cancel menu" toBeTranslated="true"/>
</node>
<node name="backKeyLongPressAction" value="Back key long press action" toBeTranslated="true">
<node name="exit" value="Close FBReader" toBeTranslated="true"/>
<node name="goBack" value="Navigate back" toBeTranslated="true"/>
<node name="cancelMenu" value="Show cancel menu" toBeTranslated="true"/>
<node name="none" value="No action" toBeTranslated="true"/>
</node>
</node>
</node>
<node name="OptionsDialog">

View file

@ -75,11 +75,13 @@
<node name="stopSearching" value="Stop searching" />
<node name="signIn" value="Sign in"/>
<node name="signOut" value="Sign out (%s)"/>
<node name="refillAccount" value="Top up account (currently: %s)"/>
<node name="refillTitle" value="Top up account"/>
<node name="refillViaSms" value="Text messages"/>
<node name="refillViaBrowser" value="Open page in browser"/>
<node name="refillSummary" value="Currently: %s"/>
<node name="topup" value="Top up account (currently: %s)"/>
<node name="topupTitle" value="Top up account"/>
<node name="topupViaCreditCard" value="Credit card"/>
<node name="topupViaSelfServiceKiosk" value="Self-service kiosk"/>
<node name="topupViaSms" value="Text messages"/>
<node name="topupViaBrowser" value="Open page in browser"/>
<node name="topupSummary" value="Currently: %s"/>
<node name="basket" value="Basket"/>
<node name="basketSummary" value="Books I want to buy"/>
<node name="alreadyDownloading" value="Book is being downloaded" />
@ -109,7 +111,7 @@
<node name="signIn" value="Sign in"/>
<node name="signUp" value="Sign up"/>
<node name="signOut" value="Sign out (%s)"/>
<node name="refillAccount" value="Top up account"/>
<node name="topup" value="Top up account"/>
<node name="addCustomCatalog" value="Add catalog"/>
<node name="refreshCatalogsList" value="Refresh catalogs"/>
<node name="languages" value="Language filter"/>
@ -178,6 +180,8 @@
<node name="cancelMenu">
<node name="previousBook" value="Open previous book"/>
<node name="returnTo" value="Return to ..."/>
<node name="back" value="Back"/>
<node name="forward" value="Forward"/>
<node name="close" value="Close FBReader"/>
</node>
<node name="menu">
@ -225,7 +229,7 @@
<node name="openBook" value="Read" />
<node name="editInfo" value="Edit" />
<node name="reloadInfo" value="Reload" />
<node name="refillAccount" value="Top up"/>
<node name="topup" value="Top up"/>
</node>
<node name="plugin">
<node name="installTitle" value="Install plugin"/>
@ -426,6 +430,7 @@
<node name="selectionBackground" value="Selection background"/>
<node name="text" value="Regular text"/>
<node name="hyperlink" value="Hyperlink text"/>
<node name="hyperlinkVisited" value="Visited hyperlink text"/>
<node name="highlighting" value="Search results background"/>
<node name="footer" value="Footer" />
</node>
@ -551,6 +556,17 @@
<node name="summaryOn" value="Show items for last 3 positions in the book"/>
<node name="summaryOff" value="Don't show items for last 3 positions in the book"/>
</node>
<node name="backKeyAction" value="Back key action">
<node name="exit" value="Close FBReader"/>
<node name="goBack" value="Navigate back"/>
<node name="cancelMenu" value="Show cancel menu"/>
</node>
<node name="backKeyLongPressAction" value="Back key long press action">
<node name="exit" value="Close FBReader"/>
<node name="goBack" value="Navigate back"/>
<node name="cancelMenu" value="Show cancel menu"/>
<node name="none" value="No action"/>
</node>
</node>
</node>
<node name="OptionsDialog">

View file

@ -79,11 +79,13 @@
<node name="stopSearching" value="Arrêt de la recherche" />
<node name="signIn" value="Connexion"/>
<node name="signOut" value="Déconnexion (%s)"/>
<node name="refillAccount" value="Recréditer le compte (actuellement : %s)"/>
<node name="refillTitle" value="Recréditer le compte"/>
<node name="refillViaSms" value="Messages texte"/>
<node name="refillViaBrowser" value="Ouvrir la page dans le navigateur"/>
<node name="refillSummary" value="Аctuellement : %s"/>
<node name="topup" value="Recréditer le compte (actuellement : %s)"/>
<node name="topupTitle" value="Recréditer le compte"/>
<node name="topupViaCreditCard" value="Credit card" toBeTranslated="true"/>
<node name="topupViaSelfServiceKiosk" value="Self-service kiosk" toBeTranslated="true"/>
<node name="topupViaSms" value="Messages texte"/>
<node name="topupViaBrowser" value="Ouvrir la page dans le navigateur"/>
<node name="topupSummary" value="Аctuellement : %s"/>
<node name="alreadyDownloading" value="Le livre est en cours de téléchargement" />
<node name="alreadyDownloadingDemo" value="L'exemple est en cours de téléchargement" />
<node name="stoppingCatalogLoading" value="Arrêt du chargement" />
@ -111,7 +113,7 @@
<node name="signIn" value="Connexion"/>
<node name="signOut" value="Déconnexion (%s)"/>
<node name="signUp" value="Inscription"/>
<node name="refillAccount" value="Recréditer le compte"/>
<node name="topup" value="Recréditer le compte"/>
<node name="addCustomCatalog" value="Ajouter catalogue"/>
<node name="refreshCatalogsList" value="Rafraîchir"/>
<node name="languages" value="Filtrer par langue"/>
@ -178,6 +180,8 @@
<node name="cancelMenu">
<node name="previousBook" value="Open previous book" toBeTranslated="true"/>
<node name="returnTo" value="Return to ..." toBeTranslated="true"/>
<node name="back" value="Back" toBeTranslated="true"/>
<node name="forward" value="Forward" toBeTranslated="true"/>
<node name="close" value="Close FBReader" toBeTranslated="true"/>
</node>
<node name="menu">
@ -224,7 +228,7 @@
<node name="openBook" value="Lire" />
<node name="editInfo" value="Modifier" />
<node name="reloadInfo" value="Recharger" />
<node name="refillAccount" value="Recréditer"/>
<node name="topup" value="Recréditer"/>
</node>
<node name="plugin">
<node name="installTitle" value="Installer plugin" />
@ -425,6 +429,7 @@
<node name="selectionBackground" value="Arrière-plan de sélection"/>
<node name="text" value="Texte normal"/>
<node name="hyperlink" value="Text d'hyperlien"/>
<node name="hyperlinkVisited" value="Visited hyperlink text" toBeTranslated="true"/>
<node name="highlighting" value="Arrière-plan des résultats de recherche"/>
<node name="footer" value="Pied de page"/>
</node>
@ -540,6 +545,17 @@
<node name="summaryOn" value="Show items for last 3 positions in the book" toBeTranslated="true"/>
<node name="summaryOff" value="Don't show items for last 3 positions in the book" toBeTranslated="true"/>
</node>
<node name="backKeyAction" value="Back key action" toBeTranslated="true">
<node name="exit" value="Close FBReader" toBeTranslated="true"/>
<node name="goBack" value="Navigate back" toBeTranslated="true"/>
<node name="cancelMenu" value="Show cancel menu" toBeTranslated="true"/>
</node>
<node name="backKeyLongPressAction" value="Back key long press action" toBeTranslated="true">
<node name="exit" value="Close FBReader" toBeTranslated="true"/>
<node name="goBack" value="Navigate back" toBeTranslated="true"/>
<node name="cancelMenu" value="Show cancel menu" toBeTranslated="true"/>
<node name="none" value="No action" toBeTranslated="true"/>
</node>
</node>
</node>
<node name="OptionsDialog">

View file

@ -76,11 +76,13 @@
<node name="stopSearching" value="Deter a busca" />
<node name="signIn" value="Acceder"/>
<node name="signOut" value="Saír (%s)"/>
<node name="refillAccount" value="Actualizar a conta (actualmente: %s)"/>
<node name="refillTitle" value="Actualizar a conta"/>
<node name="refillViaSms" value="Mensaxes de texto"/>
<node name="refillViaBrowser" value="Abrir a páxina no navegador"/>
<node name="refillSummary" value="Actualmente: %s"/>
<node name="topup" value="Actualizar a conta (actualmente: %s)"/>
<node name="topupTitle" value="Actualizar a conta"/>
<node name="topupViaCreditCard" value="Credit card" toBeTranslated="true"/>
<node name="topupViaSelfServiceKiosk" value="Self-service kiosk" toBeTranslated="true"/>
<node name="topupViaSms" value="Mensaxes de texto"/>
<node name="topupViaBrowser" value="Abrir a páxina no navegador"/>
<node name="topupSummary" value="Actualmente: %s"/>
<node name="alreadyDownloading" value="O libro está a ser descargado" />
<node name="alreadyDownloadingDemo" value="A mostra está a ser descargada" />
<node name="stoppingCatalogLoading" value="Detendo a carga" />
@ -108,7 +110,7 @@
<node name="signIn" value="Acceder"/>
<node name="signUp" value="Rexistrarse"/>
<node name="signOut" value="Saír (%s)"/>
<node name="refillAccount" value="Recargar a conta"/>
<node name="topup" value="Recargar a conta"/>
<node name="addCustomCatalog" value="Engadir catálogo"/>
<node name="refreshCatalogsList" value="Actualizar catálogos"/>
<node name="languages" value="Filtro de idioma"/>
@ -175,6 +177,8 @@
<node name="cancelMenu">
<node name="previousBook" value="Open previous book"/>
<node name="returnTo" value="Return to ..."/>
<node name="back" value="Back" toBeTranslated="true"/>
<node name="forward" value="Forward" toBeTranslated="true"/>
<node name="close" value="Close FBReader"/>
</node>
<node name="menu">
@ -221,7 +225,7 @@
<node name="openBook" value="Ler" />
<node name="editInfo" value="Editar" />
<node name="reloadInfo" value="Recargar" />
<node name="refillAccount" value="Comletar"/>
<node name="topup" value="Comletar"/>
</node>
<node name="plugin">
<node name="installTitle" value="Instalar complemento"/>
@ -422,6 +426,7 @@
<node name="selectionBackground" value="Selección de fondo"/>
<node name="text" value="Texto normal"/>
<node name="hyperlink" value="Texto de ligazón"/>
<node name="hyperlinkVisited" value="Visited hyperlink text" toBeTranslated="true"/>
<node name="highlighting" value="Resultado da busca de fondos"/>
<node name="footer" value="Rodapé" />
</node>
@ -537,6 +542,17 @@
<node name="summaryOn" value="Show items for last 3 positions in the book" toBeTranslated="true"/>
<node name="summaryOff" value="Don't show items for last 3 positions in the book" toBeTranslated="true"/>
</node>
<node name="backKeyAction" value="Back key action" toBeTranslated="true">
<node name="exit" value="Close FBReader" toBeTranslated="true"/>
<node name="goBack" value="Navigate back" toBeTranslated="true"/>
<node name="cancelMenu" value="Show cancel menu" toBeTranslated="true"/>
</node>
<node name="backKeyLongPressAction" value="Back key long press action" toBeTranslated="true">
<node name="exit" value="Close FBReader" toBeTranslated="true"/>
<node name="goBack" value="Navigate back" toBeTranslated="true"/>
<node name="cancelMenu" value="Show cancel menu" toBeTranslated="true"/>
<node name="none" value="No action" toBeTranslated="true"/>
</node>
</node>
</node>
<node name="OptionsDialog">

View file

@ -76,11 +76,13 @@
<node name="stopSearching" value="Keresés leállítása" />
<node name="signIn" value="Bejelentkezés"/>
<node name="signOut" value="Kijelentkezés (%s)"/>
<node name="refillAccount" value="Számla feltöltése (Jelenleg: %s)"/>
<node name="refillTitle" value="Számla feltöltése"/>
<node name="refillViaSms" value="SMS üzenetek"/>
<node name="refillViaBrowser" value="Oldal megnyitása böngészőben"/>
<node name="refillSummary" value="Jelenleg: %s"/>
<node name="topup" value="Számla feltöltése (Jelenleg: %s)"/>
<node name="topupTitle" value="Számla feltöltése"/>
<node name="topupViaCreditCard" value="Credit card" toBeTranslated="true"/>
<node name="topupViaSelfServiceKiosk" value="Self-service kiosk" toBeTranslated="true"/>
<node name="topupViaSms" value="SMS üzenetek"/>
<node name="topupViaBrowser" value="Oldal megnyitása böngészőben"/>
<node name="topupSummary" value="Jelenleg: %s"/>
<node name="alreadyDownloading" value="Könyv letöltése folyamatban" />
<node name="alreadyDownloadingDemo" value="Minta letöltése folyamatban" />
<node name="stoppingCatalogLoading" value="Letöltés leállítása" />
@ -108,7 +110,7 @@
<node name="signIn" value="Bejelentkezés"/>
<node name="signOut" value="Kijelentkezés (%s)"/>
<node name="signUp" value="Regisztráció" />
<node name="refillAccount" value="Számla feltöltése"/>
<node name="topup" value="Számla feltöltése"/>
<node name="addCustomCatalog" value="Katalógus hozzáadása"/>
<node name="refreshCatalogsList" value="Katalógusok frissítése"/>
<node name="languages" value="Nyelvi szűrő"/>
@ -175,6 +177,8 @@
<node name="cancelMenu">
<node name="previousBook" value="Open previous book" toBeTranslated="true"/>
<node name="returnTo" value="Return to ..." toBeTranslated="true"/>
<node name="back" value="Back" toBeTranslated="true"/>
<node name="forward" value="Forward" toBeTranslated="true"/>
<node name="close" value="Close FBReader" toBeTranslated="true"/>
</node>
<node name="menu">
@ -221,7 +225,7 @@
<node name="openBook" value="Olvasás" />
<node name="editInfo" value="Szerkesztés" />
<node name="reloadInfo" value="Újratölt" />
<node name="refillAccount" value="Számla feltöltése"/>
<node name="topup" value="Számla feltöltése"/>
</node>
<node name="plugin">
<node name="installTitle" value="Plugin telepítése" />
@ -422,6 +426,7 @@
<node name="selectionBackground" value="Kijelölés háttere"/>
<node name="text" value="Szöveg"/>
<node name="hyperlink" value="Hiperhivatkozás"/>
<node name="hyperlinkVisited" value="Visited hyperlink text" toBeTranslated="true"/>
<node name="highlighting" value="Találatok kiemelése"/>
<node name="footer" value="Lábléc"/>
</node>
@ -537,6 +542,17 @@
<node name="summaryOn" value="Show items for last 3 positions in the book" toBeTranslated="true"/>
<node name="summaryOff" value="Don't show items for last 3 positions in the book" toBeTranslated="true"/>
</node>
<node name="backKeyAction" value="Back key action" toBeTranslated="true">
<node name="exit" value="Close FBReader" toBeTranslated="true"/>
<node name="goBack" value="Navigate back" toBeTranslated="true"/>
<node name="cancelMenu" value="Show cancel menu" toBeTranslated="true"/>
</node>
<node name="backKeyLongPressAction" value="Back key long press action" toBeTranslated="true">
<node name="exit" value="Close FBReader" toBeTranslated="true"/>
<node name="goBack" value="Navigate back" toBeTranslated="true"/>
<node name="cancelMenu" value="Show cancel menu" toBeTranslated="true"/>
<node name="none" value="No action" toBeTranslated="true"/>
</node>
</node>
</node>
<node name="OptionsDialog">

View file

@ -76,11 +76,13 @@
<node name="stopSearching" value="Ferma ricerca" />
<node name="signIn" value="Entra"/>
<node name="signOut" value="Esci (%s)"/>
<node name="refillAccount" value="Ricarica account (corrente: %s)"/>
<node name="refillTitle" value="Ricarica account"/>
<node name="refillViaSms" value="Text messages" toBeTranslated="true"/>
<node name="refillViaBrowser" value="Open page in browser" toBeTranslated="true"/>
<node name="refillSummary" value="Corrente: %s"/>
<node name="topup" value="Ricarica account (corrente: %s)"/>
<node name="topupTitle" value="Ricarica account"/>
<node name="topupViaCreditCard" value="Credit card" toBeTranslated="true"/>
<node name="topupViaSelfServiceKiosk" value="Self-service kiosk" toBeTranslated="true"/>
<node name="topupViaSms" value="Text messages" toBeTranslated="true"/>
<node name="topupViaBrowser" value="Open page in browser" toBeTranslated="true"/>
<node name="topupSummary" value="Corrente: %s"/>
<node name="alreadyDownloading" value="Sto scaricando il libro" />
<node name="alreadyDownloadingDemo" value="Sto scaricando il libro d'esempio" />
<node name="stoppingCatalogLoading" value="Sto fermando il caricamento" />
@ -108,7 +110,7 @@
<node name="signIn" value="Entra"/>
<node name="signOut" value="Esci (%s)"/>
<node name="signUp" value="Registrati" />
<node name="refillAccount" value="Ricarica account"/>
<node name="topup" value="Ricarica account"/>
<node name="addCustomCatalog" value="Aggiungi catalogo"/>
<node name="refreshCatalogsList" toBeTranslated="true" value="Refresh catalogs"/>
<node name="languages" toBeTranslated="true" value="Language filter"/>
@ -175,6 +177,8 @@
<node name="cancelMenu">
<node name="previousBook" value="Open previous book" toBeTranslated="true"/>
<node name="returnTo" value="Return to ..." toBeTranslated="true"/>
<node name="back" value="Back" toBeTranslated="true"/>
<node name="forward" value="Forward" toBeTranslated="true"/>
<node name="close" value="Close FBReader" toBeTranslated="true"/>
</node>
<node name="menu">
@ -221,7 +225,7 @@
<node name="openBook" value="Read" toBeTranslated="true" />
<node name="editInfo" value="Edit" toBeTranslated="true" />
<node name="reloadInfo" value="Reload" toBeTranslated="true" />
<node name="refillAccount" value="Ricarica account"/>
<node name="topup" value="Ricarica account"/>
</node>
<node name="plugin">
<node name="installTitle" value="Install plugin" toBeTranslated="true" />
@ -422,6 +426,7 @@
<node name="selectionBackground" value="Seleziona Sfondo"/>
<node name="text" value="Testo Regolare"/>
<node name="hyperlink" value="Testo Hyperlink"/>
<node name="hyperlinkVisited" value="Visited hyperlink text" toBeTranslated="true"/>
<node name="highlighting" value="Risultati Ricerca Sfondo"/>
<node name="footer" value="Footer" toBeTranslated="true"/>
</node>
@ -537,6 +542,17 @@
<node name="summaryOn" value="Show items for last 3 positions in the book" toBeTranslated="true"/>
<node name="summaryOff" value="Don't show items for last 3 positions in the book" toBeTranslated="true"/>
</node>
<node name="backKeyAction" value="Back key action" toBeTranslated="true">
<node name="exit" value="Close FBReader" toBeTranslated="true"/>
<node name="goBack" value="Navigate back" toBeTranslated="true"/>
<node name="cancelMenu" value="Show cancel menu" toBeTranslated="true"/>
</node>
<node name="backKeyLongPressAction" value="Back key long press action" toBeTranslated="true">
<node name="exit" value="Close FBReader" toBeTranslated="true"/>
<node name="goBack" value="Navigate back" toBeTranslated="true"/>
<node name="cancelMenu" value="Show cancel menu" toBeTranslated="true"/>
<node name="none" value="No action" toBeTranslated="true"/>
</node>
</node>
</node>
<node name="OptionsDialog">

View file

@ -76,11 +76,13 @@
<node name="stopSearching" value="Stop searching" toBeTranslated="true" />
<node name="signIn" value="Sign in" toBeTranslated="true"/>
<node name="signOut" value="Sign out (%s)" toBeTranslated="true"/>
<node name="refillAccount" value="Top up account (currently: %s)" toBeTranslated="true"/>
<node name="refillTitle" value="Top up account" toBeTranslated="true"/>
<node name="refillViaSms" value="Text messages" toBeTranslated="true"/>
<node name="refillViaBrowser" value="Open pagina in de browser" />
<node name="refillSummary" value="Currently: %s" toBeTranslated="true"/>
<node name="topup" value="Top up account (currently: %s)" toBeTranslated="true"/>
<node name="topupTitle" value="Top up account" toBeTranslated="true"/>
<node name="topupViaCreditCard" value="Credit card" toBeTranslated="true"/>
<node name="topupViaSelfServiceKiosk" value="Self-service kiosk" toBeTranslated="true"/>
<node name="topupViaSms" value="Text messages" toBeTranslated="true"/>
<node name="topupViaBrowser" value="Open pagina in de browser" />
<node name="topupSummary" value="Currently: %s" toBeTranslated="true"/>
<node name="alreadyDownloading" value="Boek wordt gedownload" />
<node name="alreadyDownloadingDemo" value="Voorbeeld wordt gedownload" />
<node name="stoppingCatalogLoading" value="Stopping loading" toBeTranslated="true" />
@ -108,7 +110,7 @@
<node name="signIn" value="Sign in" toBeTranslated="true"/>
<node name="signUp" value="Sign up" toBeTranslated="true"/>
<node name="signOut" value="Sign out (%s)" toBeTranslated="true"/>
<node name="refillAccount" value="Top up account" toBeTranslated="true"/>
<node name="topup" value="Top up account" toBeTranslated="true"/>
<node name="addCustomCatalog" value="Catalogus toevoegen"/>
<node name="refreshCatalogsList" value="Catalogi vernieuwen"/>
<node name="languages" value="Taalfilter"/>
@ -175,6 +177,8 @@
<node name="cancelMenu">
<node name="previousBook" value="Open previous book" toBeTranslated="true"/>
<node name="returnTo" value="Return to ..." toBeTranslated="true"/>
<node name="back" value="Back" toBeTranslated="true"/>
<node name="forward" value="Forward" toBeTranslated="true"/>
<node name="close" value="Close FBReader" toBeTranslated="true"/>
</node>
<node name="menu">
@ -221,7 +225,7 @@
<node name="openBook" value="Lezen" />
<node name="editInfo" value="Bewerken" />
<node name="reloadInfo" value="Vernieuwen" />
<node name="refillAccount" value="Top up" toBeTranslated="true" />
<node name="topup" value="Top up" toBeTranslated="true" />
</node>
<node name="plugin">
<node name="installTitle" value="Plug-in installeren"/>
@ -422,6 +426,7 @@
<node name="selectionBackground" value="Selectie achtergrond"/>
<node name="text" value="Normale tekst"/>
<node name="hyperlink" value="Hyperlink tekst"/>
<node name="hyperlinkVisited" value="Visited hyperlink text" toBeTranslated="true"/>
<node name="highlighting" value="Achtergrond zoekresultaten"/>
<node name="footer" value="Voettekst" />
</node>
@ -537,6 +542,17 @@
<node name="summaryOn" value="Show items for last 3 positions in the book" toBeTranslated="true"/>
<node name="summaryOff" value="Don't show items for last 3 positions in the book" toBeTranslated="true"/>
</node>
<node name="backKeyAction" value="Back key action" toBeTranslated="true">
<node name="exit" value="Close FBReader" toBeTranslated="true"/>
<node name="goBack" value="Navigate back" toBeTranslated="true"/>
<node name="cancelMenu" value="Show cancel menu" toBeTranslated="true"/>
</node>
<node name="backKeyLongPressAction" value="Back key long press action" toBeTranslated="true">
<node name="exit" value="Close FBReader" toBeTranslated="true"/>
<node name="goBack" value="Navigate back" toBeTranslated="true"/>
<node name="cancelMenu" value="Show cancel menu" toBeTranslated="true"/>
<node name="none" value="No action" toBeTranslated="true"/>
</node>
</node>
</node>
<node name="OptionsDialog">

View file

@ -75,11 +75,13 @@
<node name="stopSearching" value="Остановить поиск" />
<node name="signIn" value="Войти"/>
<node name="signOut" value="Выйти (%s)"/>
<node name="refillAccount" value="Пополнить счёт (текущий счёт: %s)" />
<node name="refillTitle" value="Пополнить счёт"/>
<node name="refillViaSms" value="Варианты SMS"/>
<node name="refillViaBrowser" value="Окно браузера"/>
<node name="refillSummary" value="Текущий счёт: %s"/>
<node name="topup" value="Пополнить счёт (текущий счёт: %s)" />
<node name="topupTitle" value="Пополнить счёт"/>
<node name="topupViaCreditCard" value="Кредитной картой"/>
<node name="topupViaSelfServiceKiosk" value="В платежном терминале"/>
<node name="topupViaSms" value="Платной SMS"/>
<node name="topupViaBrowser" value="В окне браузера"/>
<node name="topupSummary" value="Текущий счёт: %s"/>
<node name="alreadyDownloading" value="Книга загружается" />
<node name="alreadyDownloadingDemo" value="Фрагмент загружается" />
<node name="stoppingCatalogLoading" value="Остановка загрузки" />
@ -107,7 +109,7 @@
<node name="signIn" value="Войти"/>
<node name="signOut" value="Выйти (%s)"/>
<node name="signUp" value="Регистрация"/>
<node name="refillAccount" value="Пополнить счёт"/>
<node name="topup" value="Пополнить счёт"/>
<node name="addCustomCatalog" value="Добавить каталог"/>
<node name="refreshCatalogsList" value="Обновить каталоги"/>
<node name="languages" value="Фильтр по языку"/>
@ -174,6 +176,8 @@
<node name="cancelMenu">
<node name="previousBook" value="Открыть предыдущую книгу"/>
<node name="returnTo" value="Вернуться к ..."/>
<node name="back" value="Back" toBeTranslated="true"/>
<node name="forward" value="Forward" toBeTranslated="true"/>
<node name="close" value="Закрыть FBReader"/>
</node>
<node name="menu">
@ -220,7 +224,7 @@
<node name="openBook" value="Читать" />
<node name="editInfo" value="Изменить" />
<node name="reloadInfo" value="Обновить" />
<node name="refillAccount" value="Пополнить счёт"/>
<node name="topup" value="Пополнить счёт"/>
</node>
<node name="plugin">
<node name="installTitle" value="Установка дополнения"/>
@ -421,6 +425,7 @@
<node name="selectionBackground" value="Фон пометки"/>
<node name="text" value="Обычный текст"/>
<node name="hyperlink" value="Гиперссылка"/>
<node name="hyperlinkVisited" value="Visited hyperlink text" toBeTranslated="true"/>
<node name="highlighting" value="Фон результатов поиска"/>
<node name="footer" value="Подвал"/>
</node>
@ -536,6 +541,17 @@
<node name="summaryOn" value="Показывать пункты меню для последних 3 позиций в книге"/>
<node name="summaryOff" value="Не нужна возможность возврата по ссылкам"/>
</node>
<node name="backKeyAction" value="Действие по кнопке 'Назад'">
<node name="exit" value="Закрыть FBReader"/>
<node name="goBack" value="Вернуться по ссылке"/>
<node name="cancelMenu" value="Показать список действий"/>
</node>
<node name="backKeyLongPressAction" value="Действие по долгому нажатию">
<node name="exit" value="Закрыть FBReader"/>
<node name="goBack" value="Вернуться по ссылке"/>
<node name="cancelMenu" value="Показать список действий"/>
<node name="none" value="Ничего не делать"/>
</node>
</node>
</node>
<node name="OptionsDialog">

View file

@ -76,11 +76,13 @@
<node name="stopSearching" value="หยุดการค้นหา"/>
<node name="signIn" value="ลงชื่อเข้าระบบ"/>
<node name="signOut" value="ออกจากระบบ (%s)"/>
<node name="refillAccount" value="เติมเงินเข้าบัญชีผู้ใช้ (ปัจจุบันคือ: %s)"/>
<node name="refillTitle" value="เติมเงินเข้าบัญชี"/>
<node name="refillViaSms" value="ข้อความ"/>
<node name="refillViaBrowser" value="เปิดในเว็บเบราว์เซอร์"/>
<node name="refillSummary" value="ปัจจุบัน: %s"/>
<node name="topup" value="เติมเงินเข้าบัญชีผู้ใช้ (ปัจจุบันคือ: %s)"/>
<node name="topupTitle" value="เติมเงินเข้าบัญชี"/>
<node name="topupViaCreditCard" value="Credit card" toBeTranslated="true"/>
<node name="topupViaSelfServiceKiosk" value="Self-service kiosk" toBeTranslated="true"/>
<node name="topupViaSms" value="ข้อความ"/>
<node name="topupViaBrowser" value="เปิดในเว็บเบราว์เซอร์"/>
<node name="topupSummary" value="ปัจจุบัน: %s"/>
<node name="alreadyDownloading" value="กำลังดาวน์โหลดหนังสือ"/>
<node name="alreadyDownloadingDemo" value="กำลังดาวน์โหลดหนังสือตัวอย่าง"/>
<node name="stoppingCatalogLoading" value="หยุดการโหลด"/>
@ -108,7 +110,7 @@
<node name="signIn" value="ลงชื่อเข้าระบบ"/>
<node name="signUp" value="ลงทะเบียนเข้าระบบ"/>
<node name="signOut" value="ออกจากระบบ (%s)"/>
<node name="refillAccount" value="เติมเงินเข้าบัญชี"/>
<node name="topup" value="เติมเงินเข้าบัญชี"/>
<node name="addCustomCatalog" value="เพิ่มแคตตาล็อก"/>
<node name="refreshCatalogsList" value="รีเฟรชแคตตาล็อก"/>
<node name="languages" value="ตัวกรองภาษา"/>
@ -175,6 +177,8 @@
<node name="cancelMenu">
<node name="previousBook" value="เปิดหนังสือเล่มก่อนหน้า"/>
<node name="returnTo" value="กลับไป ..."/>
<node name="back" value="Back" toBeTranslated="true"/>
<node name="forward" value="Forward" toBeTranslated="true"/>
<node name="close" value="ปิด FBReader"/>
</node>
<node name="menu">
@ -221,7 +225,7 @@
<node name="openBook" value="อ่าน"/>
<node name="editInfo" value="แก้ไข"/>
<node name="reloadInfo" value="โหลดใหม่"/>
<node name="refillAccount" value="เติมเงิน"/>
<node name="topup" value="เติมเงิน"/>
</node>
<node name="plugin">
<node name="installTitle" value="ติดตั้งปลั๊กอิน"/>
@ -422,6 +426,7 @@
<node name="selectionBackground" value="พื้นหลังที่เลือก"/>
<node name="text" value="ข้อความ"/>
<node name="hyperlink" value="ลิ้งค์ข้อความ"/>
<node name="hyperlinkVisited" value="Visited hyperlink text" toBeTranslated="true"/>
<node name="highlighting" value="สีไฮไลท์ผลการค้นหาคำ"/>
<node name="footer" value="ข้อความท้ายหน้า"/>
</node>
@ -537,6 +542,17 @@
<node name="summaryOn" value="Show items for last 3 positions in the book" toBeTranslated="true"/>
<node name="summaryOff" value="Don't show items for last 3 positions in the book" toBeTranslated="true"/>
</node>
<node name="backKeyAction" value="Back key action" toBeTranslated="true">
<node name="exit" value="Close FBReader" toBeTranslated="true"/>
<node name="goBack" value="Navigate back" toBeTranslated="true"/>
<node name="cancelMenu" value="Show cancel menu" toBeTranslated="true"/>
</node>
<node name="backKeyLongPressAction" value="Back key long press action" toBeTranslated="true">
<node name="exit" value="Close FBReader" toBeTranslated="true"/>
<node name="goBack" value="Navigate back" toBeTranslated="true"/>
<node name="cancelMenu" value="Show cancel menu" toBeTranslated="true"/>
<node name="none" value="No action" toBeTranslated="true"/>
</node>
</node>
</node>
<node name="OptionsDialog">

View file

@ -76,11 +76,13 @@
<node name="stopSearching" value="Припинити пошук" />
<node name="signIn" value="Увійти"/>
<node name="signOut" value="Вийти (%s)"/>
<node name="refillAccount" value="Поповнити рахунок (поточний рахунок: %s)" />
<node name="refillTitle" value="Поповнити рахунок"/>
<node name="refillViaSms" value="Text messages" toBeTranslated="true"/>
<node name="refillViaBrowser" value="Open page in browser" toBeTranslated="true"/>
<node name="refillSummary" value="Поточний рахунок: %s"/>
<node name="topup" value="Поповнити рахунок (поточний рахунок: %s)" />
<node name="topupTitle" value="Поповнити рахунок"/>
<node name="topupViaCreditCard" value="Credit card" toBeTranslated="true"/>
<node name="topupViaSelfServiceKiosk" value="Self-service kiosk" toBeTranslated="true"/>
<node name="topupViaSms" value="Text messages" toBeTranslated="true"/>
<node name="topupViaBrowser" value="Open page in browser" toBeTranslated="true"/>
<node name="topupSummary" value="Поточний рахунок: %s"/>
<node name="alreadyDownloading" value="Книжка завантажується" />
<node name="alreadyDownloadingDemo" value="Уривок завантажається" />
<node name="stoppingCatalogLoading" value="Зупинка завантаження" />
@ -108,7 +110,7 @@
<node name="signIn" value="Увійти"/>
<node name="signOut" value="Вийти (%s)"/>
<node name="signUp" value="Зареєструватися" />
<node name="refillAccount" value="Поповнити рахунок"/>
<node name="topup" value="Поповнити рахунок"/>
<node name="addCustomCatalog" value="Додати каталог"/>
<node name="refreshCatalogsList" value="Оновити каталоги"/>
<node name="languages" toBeTranslated="true" value="Language filter"/>
@ -175,6 +177,8 @@
<node name="cancelMenu">
<node name="previousBook" value="Open previous book" toBeTranslated="true"/>
<node name="returnTo" value="Return to ..." toBeTranslated="true"/>
<node name="back" value="Back" toBeTranslated="true"/>
<node name="forward" value="Forward" toBeTranslated="true"/>
<node name="close" value="Close FBReader" toBeTranslated="true"/>
</node>
<node name="menu">
@ -221,7 +225,7 @@
<node name="openBook" value="Read" toBeTranslated="true" />
<node name="editInfo" value="Edit" toBeTranslated="true" />
<node name="reloadInfo" value="Reload" toBeTranslated="true" />
<node name="refillAccount" value="Поповнити рахунок"/>
<node name="topup" value="Поповнити рахунок"/>
</node>
<node name="plugin">
<node name="installTitle" value="Install plugin" toBeTranslated="true" />
@ -422,6 +426,7 @@
<node name="selectionBackground" value="Фон позначки"/>
<node name="text" value="Звичайний текст"/>
<node name="hyperlink" value="Посилання"/>
<node name="hyperlinkVisited" value="Visited hyperlink text" toBeTranslated="true"/>
<node name="highlighting" value="Фон результатів пошуку"/>
<node name="footer" value="Footer" toBeTranslated="true"/>
</node>
@ -537,6 +542,17 @@
<node name="summaryOn" value="Show items for last 3 positions in the book" toBeTranslated="true"/>
<node name="summaryOff" value="Don't show items for last 3 positions in the book" toBeTranslated="true"/>
</node>
<node name="backKeyAction" value="Back key action" toBeTranslated="true">
<node name="exit" value="Close FBReader" toBeTranslated="true"/>
<node name="goBack" value="Navigate back" toBeTranslated="true"/>
<node name="cancelMenu" value="Show cancel menu" toBeTranslated="true"/>
</node>
<node name="backKeyLongPressAction" value="Back key long press action" toBeTranslated="true">
<node name="exit" value="Close FBReader" toBeTranslated="true"/>
<node name="goBack" value="Navigate back" toBeTranslated="true"/>
<node name="cancelMenu" value="Show cancel menu" toBeTranslated="true"/>
<node name="none" value="No action" toBeTranslated="true"/>
</node>
</node>
</node>
<node name="OptionsDialog">

View file

@ -76,11 +76,13 @@
<node name="stopSearching" value="Dừng tìm kiếm" />
<node name="signIn" value="Đăng nhập"/>
<node name="signOut" value="Đăng xuất (%s)"/>
<node name="refillAccount" value="Làm đầy lại tài khoản (hiện tại: %s)"/>
<node name="refillTitle" value="Làm đầy lại tài khoản"/>
<node name="refillViaSms" value="Tin nhắn"/>
<node name="refillViaBrowser" value="Mở trang trong trình duyệt"/>
<node name="refillSummary" value="Hiện tại: %s"/>
<node name="topup" value="Làm đầy lại tài khoản (hiện tại: %s)"/>
<node name="topupTitle" value="Làm đầy lại tài khoản"/>
<node name="topupViaCreditCard" value="Credit card" toBeTranslated="true"/>
<node name="topupViaSelfServiceKiosk" value="Self-service kiosk" toBeTranslated="true"/>
<node name="topupViaSms" value="Tin nhắn"/>
<node name="topupViaBrowser" value="Mở trang trong trình duyệt"/>
<node name="topupSummary" value="Hiện tại: %s"/>
<node name="alreadyDownloading" value="Sách đang được tải về" />
<node name="alreadyDownloadingDemo" value="Bản thử đang được tải về" />
<node name="stoppingCatalogLoading" value="Dừng tải" />
@ -108,7 +110,7 @@
<node name="signIn" value="Đăng nhập"/>
<node name="signOut" value="Đăng xuất (%s)"/>
<node name="signUp" value="Đăng ký" />
<node name="refillAccount" value="Tái đầy tài khoản "/>
<node name="topup" value="Tái đầy tài khoản "/>
<node name="addCustomCatalog" value="Thêm catalo"/>
<node name="refreshCatalogsList" value="Tải lại các catalo"/>
<node name="languages" value="Bộ lọc ngôn ngữ"/>
@ -175,6 +177,8 @@
<node name="cancelMenu">
<node name="previousBook" value="Open previous book" toBeTranslated="true"/>
<node name="returnTo" value="Return to ..." toBeTranslated="true"/>
<node name="back" value="Back" toBeTranslated="true"/>
<node name="forward" value="Forward" toBeTranslated="true"/>
<node name="close" value="Close FBReader" toBeTranslated="true"/>
</node>
<node name="menu">
@ -221,7 +225,7 @@
<node name="openBook" value="Đọc" />
<node name="editInfo" value="Sửa" />
<node name="reloadInfo" value="Tải lại" />
<node name="refillAccount" value="Tái đầy tài khoản "/>
<node name="topup" value="Tái đầy tài khoản "/>
</node>
<node name="plugin">
<node name="installTitle" value="Cài phần bổ trợ" />
@ -422,6 +426,7 @@
<node name="selectionBackground" value="Nền Phần chọn"/>
<node name="text" value="Văn bản Thường"/>
<node name="hyperlink" value="Siêu liên kết"/>
<node name="hyperlinkVisited" value="Visited hyperlink text" toBeTranslated="true"/>
<node name="highlighting" value="Kết quả Tìm kiếm"/>
<node name="footer" value="Footer"/>
</node>
@ -537,6 +542,17 @@
<node name="summaryOn" value="Show items for last 3 positions in the book" toBeTranslated="true"/>
<node name="summaryOff" value="Don't show items for last 3 positions in the book" toBeTranslated="true"/>
</node>
<node name="backKeyAction" value="Back key action" toBeTranslated="true">
<node name="exit" value="Close FBReader" toBeTranslated="true"/>
<node name="goBack" value="Navigate back" toBeTranslated="true"/>
<node name="cancelMenu" value="Show cancel menu" toBeTranslated="true"/>
</node>
<node name="backKeyLongPressAction" value="Back key long press action" toBeTranslated="true">
<node name="exit" value="Close FBReader" toBeTranslated="true"/>
<node name="goBack" value="Navigate back" toBeTranslated="true"/>
<node name="cancelMenu" value="Show cancel menu" toBeTranslated="true"/>
<node name="none" value="No action" toBeTranslated="true"/>
</node>
</node>
</node>
<node name="OptionsDialog">

View file

@ -76,11 +76,13 @@
<node name="stopSearching" value="停止搜索" />
<node name="signIn" value="登录"/>
<node name="signOut" value="退出 (%s)"/>
<node name="refillAccount" value="重新输入账号(目前: %s)" />
<node name="refillTitle" value="重新输入账号"/>
<node name="refillViaSms" value="短消息"/>
<node name="refillViaBrowser" value="在浏览器中打开页面"/>
<node name="refillSummary" value="当前: %s"/>
<node name="topup" value="重新输入账号(目前: %s)" />
<node name="topupTitle" value="重新输入账号"/>
<node name="topupViaCreditCard" value="Credit card" toBeTranslated="true"/>
<node name="topupViaSelfServiceKiosk" value="Self-service kiosk" toBeTranslated="true"/>
<node name="topupViaSms" value="短消息"/>
<node name="topupViaBrowser" value="在浏览器中打开页面"/>
<node name="topupSummary" value="当前: %s"/>
<node name="alreadyDownloading" value="正在下载" />
<node name="alreadyDownloadingDemo" value="正在下载试读本" />
<node name="stoppingCatalogLoading" value="停止加载" />
@ -108,7 +110,7 @@
<node name="signIn" value="登录"/>
<node name="signOut" value="退出 (%s)"/>
<node name="signUp" value="注册" />
<node name="refillAccount" value="重新输入账号"/>
<node name="topup" value="重新输入账号"/>
<node name="addCustomCatalog" value="添加书库目录"/>
<node name="refreshCatalogsList" value="刷新书库目录"/>
<node name="languages" value="语言过滤"/>
@ -175,6 +177,8 @@
<node name="cancelMenu">
<node name="previousBook" value="Open previous book" toBeTranslated="true"/>
<node name="returnTo" value="Return to ..." toBeTranslated="true"/>
<node name="back" value="Back" toBeTranslated="true"/>
<node name="forward" value="Forward" toBeTranslated="true"/>
<node name="close" value="Close FBReader" toBeTranslated="true"/>
</node>
<node name="menu">
@ -221,7 +225,7 @@
<node name="openBook" value="阅读" />
<node name="editInfo" value="编辑" />
<node name="reloadInfo" value="重新加载" />
<node name="refillAccount" value="重新输入账号"/>
<node name="topup" value="重新输入账号"/>
</node>
<node name="plugin">
<node name="installTitle" value="安装插件" />
@ -422,6 +426,7 @@
<node name="selectionBackground" value="选择背景色" />
<node name="text" value="普通文本" />
<node name="hyperlink" value="超链接文本" />
<node name="hyperlinkVisited" value="Visited hyperlink text" toBeTranslated="true"/>
<node name="highlighting" value="搜索结果背景" />
<node name="footer" value="页脚"/>
</node>
@ -537,6 +542,17 @@
<node name="summaryOn" value="Show items for last 3 positions in the book" toBeTranslated="true"/>
<node name="summaryOff" value="Don't show items for last 3 positions in the book" toBeTranslated="true"/>
</node>
<node name="backKeyAction" value="Back key action" toBeTranslated="true">
<node name="exit" value="Close FBReader" toBeTranslated="true"/>
<node name="goBack" value="Navigate back" toBeTranslated="true"/>
<node name="cancelMenu" value="Show cancel menu" toBeTranslated="true"/>
</node>
<node name="backKeyLongPressAction" value="Back key long press action" toBeTranslated="true">
<node name="exit" value="Close FBReader" toBeTranslated="true"/>
<node name="goBack" value="Navigate back" toBeTranslated="true"/>
<node name="cancelMenu" value="Show cancel menu" toBeTranslated="true"/>
<node name="none" value="No action" toBeTranslated="true"/>
</node>
</node>
</node>
<node name="OptionsDialog">

View file

@ -10,3 +10,4 @@
# Project target.
target=android-8
java.encoding=utf-8
proguard.config=proguard.cfg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Before After
Before After

33
proguard.cfg Executable file
View file

@ -0,0 +1,33 @@
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keepclasseswithmembernames class * {
native <methods>;
}
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}

View file

@ -16,6 +16,9 @@ updateVersion() {
major=`echo $version | cut -d . -f 1`
minor=`echo $version | cut -d . -f 2`
micro=`echo $version | cut -d . -f 3`
if [ "$micro" == "" ]; then
micro=0
fi
intversion=$((10000*$major+100*$minor+$micro))
sed "s/@INTVERSION@/$intversion/" AndroidManifest.xml.pattern | sed "s/@VERSION@/$version/" > AndroidManifest.xml
}

View file

@ -21,8 +21,7 @@ package org.geometerplus.android.fbreader;
import java.io.File;
import java.text.DateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.*;
import android.app.Activity;
import android.content.Intent;
@ -212,11 +211,18 @@ public class BookInfoActivity extends Activity {
}
setupInfoPair(R.id.book_authors, "authors", buffer);
SeriesInfo series = book.getSeriesInfo();
final SeriesInfo series = book.getSeriesInfo();
setupInfoPair(R.id.book_series, "series",
(series == null) ? null : series.Name);
setupInfoPair(R.id.book_series_index, "indexInSeries",
(series == null || series.Index <= 0) ? null : String.valueOf(series.Index));
String seriesIndexString = null;
if (series != null && series.Index > 0) {
if (Math.abs(series.Index - Math.round(series.Index)) < 0.01) {
seriesIndexString = String.valueOf(Math.round(series.Index));
} else {
seriesIndexString = String.format("%.1f", series.Index);
}
}
setupInfoPair(R.id.book_series_index, "indexInSeries", seriesIndexString);
buffer.delete(0, buffer.length());
final HashSet<String> tagNames = new HashSet<String>();

View file

@ -49,22 +49,18 @@ public class CancelActivity extends ListActivity {
myIntent = intent;
}
@Override
public final int getCount() {
return myIntent.getIntExtra(LIST_SIZE, 0);
}
@Override
public final Integer getItem(int position) {
return position;
}
@Override
public final long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, final ViewGroup parent) {
final View view = convertView != null
? convertView

View file

@ -96,7 +96,7 @@ public abstract class DictionaryUtil {
for (Map.Entry<PackageInfo,Boolean> entry : infos().entrySet()) {
final PackageInfo info = entry.getKey();
if (!entry.getValue() ||
PackageUtil.canBeStarted(context, getDictionaryIntent(info, "test"))) {
PackageUtil.canBeStarted(context, getDictionaryIntent(info, "test"), false)) {
list.add(info);
}
}
@ -188,7 +188,7 @@ public abstract class DictionaryUtil {
}
public static void installDictionaryIfNotInstalled(final Activity activity) {
if (PackageUtil.canBeStarted(activity, getDictionaryIntent("test"))) {
if (PackageUtil.canBeStarted(activity, getDictionaryIntent("test"), false)) {
return;
}
final PackageInfo dictionaryInfo = getCurrentDictionaryInfo();

View file

@ -73,7 +73,7 @@ public final class FBReader extends ZLAndroidActivity {
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
final ZLAndroidApplication application = ZLAndroidApplication.Instance();
final ZLAndroidApplication application = (ZLAndroidApplication)getApplication();
myFullScreenFlag =
application.ShowStatusBarOption.getValue() ? 0 : WindowManager.LayoutParams.FLAG_FULLSCREEN;
getWindow().setFlags(
@ -91,7 +91,7 @@ public final class FBReader extends ZLAndroidActivity {
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));
fbReader.addAction(ActionCode.SHOW_CONTENTS, new ShowTOCAction(this, fbReader));
fbReader.addAction(ActionCode.SHOW_TOC, new ShowTOCAction(this, fbReader));
fbReader.addAction(ActionCode.SHOW_BOOKMARKS, new ShowBookmarksAction(this, fbReader));
fbReader.addAction(ActionCode.SHOW_NETWORK_LIBRARY, new ShowNetworkLibraryAction(this, fbReader));
@ -102,12 +102,12 @@ public final class FBReader extends ZLAndroidActivity {
fbReader.addAction(ActionCode.PROCESS_HYPERLINK, new ProcessHyperlinkAction(this, fbReader));
fbReader.addAction(ActionCode.SPEAK, new SpeakAction(this, fbReader));
fbReader.addAction(ActionCode.CANCEL, new CancelAction(this, fbReader));
fbReader.addAction(ActionCode.SHOW_CANCEL_MENU, new ShowCancelMenuAction(this, fbReader));
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
final ZLAndroidApplication application = ZLAndroidApplication.Instance();
final ZLAndroidApplication application = (ZLAndroidApplication)getApplication();
if (!application.ShowStatusBarOption.getValue() &&
application.ShowStatusBarWhenMenuIsActiveOption.getValue()) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
@ -118,7 +118,7 @@ public final class FBReader extends ZLAndroidActivity {
@Override
public void onOptionsMenuClosed(Menu menu) {
super.onOptionsMenuClosed(menu);
final ZLAndroidApplication application = ZLAndroidApplication.Instance();
final ZLAndroidApplication application = (ZLAndroidApplication)getApplication();
if (!application.ShowStatusBarOption.getValue() &&
application.ShowStatusBarWhenMenuIsActiveOption.getValue()) {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
@ -162,7 +162,7 @@ public final class FBReader extends ZLAndroidActivity {
@Override
public void onStart() {
super.onStart();
final ZLAndroidApplication application = ZLAndroidApplication.Instance();
final ZLAndroidApplication application = (ZLAndroidApplication)getApplication();
final int fullScreenFlag =
application.ShowStatusBarOption.getValue() ? 0 : WindowManager.LayoutParams.FLAG_FULLSCREEN;
@ -253,4 +253,36 @@ public final class FBReader extends ZLAndroidActivity {
public void navigate() {
ourNavigatePanel.runNavigation();
}
private void addMenuItem(Menu menu, String actionId, int iconId) {
final ZLAndroidApplication application = (ZLAndroidApplication)getApplication();
application.myMainWindow.addMenuItem(menu, actionId, iconId);
}
private void addMenuItem(Menu menu, String actionId) {
final ZLAndroidApplication application = (ZLAndroidApplication)getApplication();
application.myMainWindow.addMenuItem(menu, actionId, null);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
final ZLAndroidApplication application = (ZLAndroidApplication)getApplication();
addMenuItem(menu, ActionCode.SHOW_LIBRARY, R.drawable.ic_menu_library);
addMenuItem(menu, ActionCode.SHOW_NETWORK_LIBRARY, R.drawable.ic_menu_networklibrary);
addMenuItem(menu, ActionCode.SHOW_TOC, R.drawable.ic_menu_toc);
addMenuItem(menu, ActionCode.SHOW_BOOKMARKS, R.drawable.ic_menu_bookmarks);
addMenuItem(menu, ActionCode.SWITCH_TO_NIGHT_PROFILE, R.drawable.ic_menu_night);
addMenuItem(menu, ActionCode.SWITCH_TO_DAY_PROFILE, R.drawable.ic_menu_day);
addMenuItem(menu, ActionCode.SEARCH, R.drawable.ic_menu_search);
addMenuItem(menu, ActionCode.SHOW_PREFERENCES);
addMenuItem(menu, ActionCode.SHOW_BOOK_INFO);
addMenuItem(menu, ActionCode.ROTATE);
addMenuItem(menu, ActionCode.INCREASE_FONT);
addMenuItem(menu, ActionCode.DECREASE_FONT);
addMenuItem(menu, ActionCode.SHOW_NAVIGATION);
addMenuItem(menu, ActionCode.SPEAK);
return true;
}
}

View file

@ -23,7 +23,6 @@ import android.content.Intent;
import android.content.ActivityNotFoundException;
import android.net.Uri;
import org.geometerplus.zlibrary.core.resources.ZLResource;
import org.geometerplus.zlibrary.core.network.ZLNetworkException;
import org.geometerplus.zlibrary.text.view.*;
@ -38,6 +37,8 @@ import org.geometerplus.android.fbreader.network.BookDownloaderService;
import org.geometerplus.android.fbreader.image.ImageViewActivity;
class ProcessHyperlinkAction extends FBAction {
private static final String ACTION_LINK_PREFIX = "fbreader-action://";
private final FBReader myBaseActivity;
ProcessHyperlinkAction(FBReader baseActivity, FBReaderApp fbreader) {
@ -55,9 +56,14 @@ class ProcessHyperlinkAction extends FBAction {
final ZLTextHyperlink hyperlink = ((ZLTextHyperlinkRegion)region).Hyperlink;
switch (hyperlink.Type) {
case FBHyperlinkType.EXTERNAL:
if (hyperlink.Id.startsWith(ACTION_LINK_PREFIX)) {
Reader.doAction(hyperlink.Id.substring(ACTION_LINK_PREFIX.length()));
} else {
openInBrowser(hyperlink.Id);
}
break;
case FBHyperlinkType.INTERNAL:
Reader.Model.Book.markHyperlinkAsVisited(hyperlink.Id);
Reader.tryOpenFootnote(hyperlink.Id);
break;
}

View file

@ -61,7 +61,7 @@ public final class SQLiteBooksDatabase extends BooksDatabase {
private void migrate(Context context) {
final int version = myDatabase.getVersion();
final int currentVersion = 14;
final int currentVersion = 16;
if (version >= currentVersion) {
return;
}
@ -98,6 +98,10 @@ public final class SQLiteBooksDatabase extends BooksDatabase {
updateTables12();
case 13:
updateTables13();
case 14:
updateTables14();
case 15:
updateTables15();
}
myDatabase.setTransactionSuccessful();
myDatabase.endTransaction();
@ -240,7 +244,7 @@ public final class SQLiteBooksDatabase extends BooksDatabase {
if (book != null) {
String series = seriesById.get(cursor.getLong(1));
if (series != null) {
setSeriesInfo(book, series, cursor.getLong(2));
setSeriesInfo(book, series, cursor.getFloat(2));
}
}
}
@ -461,7 +465,7 @@ public final class SQLiteBooksDatabase extends BooksDatabase {
}
myInsertBookSeriesStatement.bindLong(1, bookId);
myInsertBookSeriesStatement.bindLong(2, seriesId);
myInsertBookSeriesStatement.bindLong(3, seriesInfo.Index);
myInsertBookSeriesStatement.bindDouble(3, seriesInfo.Index);
myInsertBookSeriesStatement.execute();
}
}
@ -470,7 +474,7 @@ public final class SQLiteBooksDatabase extends BooksDatabase {
final Cursor cursor = myDatabase.rawQuery("SELECT Series.name,BookSeries.book_index FROM BookSeries INNER JOIN Series ON Series.series_id = BookSeries.series_id WHERE BookSeries.book_id = ?", new String[] { "" + bookId });
SeriesInfo info = null;
if (cursor.moveToNext()) {
info = new SeriesInfo(cursor.getString(0), cursor.getLong(1));
info = new SeriesInfo(cursor.getString(0), cursor.getFloat(1));
}
cursor.close();
return info;
@ -836,6 +840,7 @@ public final class SQLiteBooksDatabase extends BooksDatabase {
}
myDeleteFromBookListStatement.bindLong(1, bookId);
myDeleteFromBookListStatement.execute();
deleteVisitedHyperlinks(bookId);
return true;
}
@ -850,6 +855,41 @@ public final class SQLiteBooksDatabase extends BooksDatabase {
return myCheckBookListStatement.simpleQueryForLong() > 0;
}
private SQLiteStatement myDeleteVisitedHyperlinksStatement;
private void deleteVisitedHyperlinks(long bookId) {
if (myDeleteVisitedHyperlinksStatement == null) {
myDeleteVisitedHyperlinksStatement = myDatabase.compileStatement(
"DELETE FROM VisitedHyperlinks WHERE book_id = ?"
);
}
myDeleteVisitedHyperlinksStatement.bindLong(1, bookId);
myDeleteVisitedHyperlinksStatement.execute();
}
private SQLiteStatement myStoreVisitedHyperlinksStatement;
protected void addVisitedHyperlink(long bookId, String hyperlinkId) {
if (myStoreVisitedHyperlinksStatement == null) {
myStoreVisitedHyperlinksStatement = myDatabase.compileStatement(
"INSERT OR IGNORE INTO VisitedHyperlinks(book_id,hyperlink_id) VALUES (?,?)"
);
}
myStoreVisitedHyperlinksStatement.bindLong(1, bookId);
myStoreVisitedHyperlinksStatement.bindString(2, hyperlinkId);
myStoreVisitedHyperlinksStatement.execute();
}
protected Collection<String> loadVisitedHyperlinks(long bookId) {
final TreeSet<String> links = new TreeSet<String>();
final Cursor cursor = myDatabase.rawQuery("SELECT hyperlink_id FROM VisitedHyperlinks WHERE book_id = ?", new String[] { "" + bookId });
while (cursor.moveToNext()) {
links.add(cursor.getString(0));
}
cursor.close();
return links;
}
private void createTables() {
myDatabase.execSQL(
@ -1127,4 +1167,23 @@ public final class SQLiteBooksDatabase extends BooksDatabase {
"ALTER TABLE Bookmarks ADD COLUMN visible INTEGER DEFAULT 1"
);
}
private void updateTables14() {
myDatabase.execSQL("ALTER TABLE BookSeries RENAME TO BookSeries_Obsolete");
myDatabase.execSQL(
"CREATE TABLE BookSeries(" +
"series_id INTEGER NOT NULL REFERENCES Series(series_id)," +
"book_id INTEGER NOT NULL UNIQUE REFERENCES Books(book_id)," +
"book_index REAL)");
myDatabase.execSQL("INSERT INTO BookSeries (series_id,book_id,book_index) SELECT series_id,book_id,book_index FROM BookSeries_Obsolete");
myDatabase.execSQL("DROP TABLE BookSeries_Obsolete");
}
private void updateTables15() {
myDatabase.execSQL(
"CREATE TABLE IF NOT EXISTS VisitedHyperlinks(" +
"book_id INTEGER NOT NULL REFERENCES Books(book_id)," +
"hyperlink_id TEXT NOT NULL," +
"CONSTRAINT VisitedHyperlinks_Unique UNIQUE (book_id, hyperlink_id))");
}
}

View file

@ -26,10 +26,10 @@ import android.content.Intent;
import org.geometerplus.fbreader.fbreader.FBAction;
import org.geometerplus.fbreader.fbreader.FBReaderApp;
class CancelAction extends FBAction {
class ShowCancelMenuAction extends FBAction {
private final FBReader myBaseActivity;
CancelAction(FBReader baseActivity, FBReaderApp fbreader) {
ShowCancelMenuAction(FBReader baseActivity, FBReaderApp fbreader) {
super(fbreader);
myBaseActivity = baseActivity;
}

View file

@ -81,9 +81,10 @@ public final class FileManager extends BaseActivity {
}
private void startUpdate() {
new Thread(
new SmartFilter(ZLFile.createFileByPath(myPath))
).start();
final ZLFile file = ZLFile.createFileByPath(myPath);
if (file != null) {
new Thread(new SmartFilter(file)).start();
}
}
@Override

View file

@ -387,10 +387,10 @@ class NetworkBookActions extends NetworkTreeActions {
if (NetworkException.ERROR_PURCHASE_NOT_ENOUGH_MONEY.equals(
exception.getCode())
) {
buttonKey = "refillAccount";
buttonKey = "topup";
action = new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
new RefillAccountActions().runStandalone(activity, book.Link);
new TopupActions().runStandalone(activity, book.Link);
}
};
} else {

View file

@ -126,12 +126,12 @@ public class NetworkBookInfoActivity extends Activity implements NetworkView.Eve
@Override
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) {
NetworkView.Instance().getTopUpActions().buildContextMenu(this, menu, myBook.Link);
NetworkView.Instance().getTopupActions().buildContextMenu(this, menu, myBook.Link);
}
@Override
public boolean onContextItemSelected(MenuItem item) {
RefillAccountActions.runAction(this, myBook.Link, item.getItemId());
TopupActions.runAction(this, myBook.Link, item.getItemId());
return true;
}
@ -185,8 +185,15 @@ public class NetworkBookInfoActivity extends Activity implements NetworkView.Eve
if (myBook.SeriesTitle != null) {
findViewById(R.id.network_book_series_title).setVisibility(View.VISIBLE);
setPairValueText(R.id.network_book_series_title, myBook.SeriesTitle);
if (myBook.IndexInSeries > 0) {
setPairValueText(R.id.network_book_series_index, String.valueOf(myBook.IndexInSeries));
final float indexInSeries = myBook.IndexInSeries;
if (indexInSeries > 0) {
final String seriesIndexString;
if (Math.abs(indexInSeries - Math.round(indexInSeries)) < 0.01) {
seriesIndexString = String.valueOf(Math.round(indexInSeries));
} else {
seriesIndexString = String.format("%.1f", indexInSeries);
}
setPairValueText(R.id.network_book_series_index, seriesIndexString);
findViewById(R.id.network_book_series_index).setVisibility(View.VISIBLE);
} else {
findViewById(R.id.network_book_series_index).setVisibility(View.GONE);

View file

@ -51,7 +51,7 @@ class NetworkCatalogActions extends NetworkTreeActions {
public static final int SIGNUP_ITEM_ID = 3;
public static final int SIGNIN_ITEM_ID = 4;
public static final int SIGNOUT_ITEM_ID = 5;
public static final int REFILL_ACCOUNT_ITEM_ID = 6;
public static final int TOPUP_ITEM_ID = 6;
public static final int CUSTOM_CATALOG_EDIT = 7;
public static final int CUSTOM_CATALOG_REMOVE = 8;
@ -95,10 +95,10 @@ class NetworkCatalogActions extends NetworkTreeActions {
if (mgr != null) {
if (mgr.mayBeAuthorised(false)) {
addMenuItem(menu, SIGNOUT_ITEM_ID, "signOut", mgr.currentUserName());
if (mgr.refillAccountLink() != null) {
if (Util.isTopupSupported(activity, item.Link)) {
final String account = mgr.currentAccount();
if (account != null) {
addMenuItem(menu, REFILL_ACCOUNT_ITEM_ID, "refillAccount", account);
addMenuItem(menu, TOPUP_ITEM_ID, "topup", account);
}
}
} else {
@ -161,7 +161,7 @@ class NetworkCatalogActions extends NetworkTreeActions {
addOptionsItem(menu, SIGNIN_ITEM_ID, "signIn");
addOptionsItem(menu, SIGNUP_ITEM_ID, "signUp");
addOptionsItem(menu, SIGNOUT_ITEM_ID, "signOut", "");
addOptionsItem(menu, REFILL_ACCOUNT_ITEM_ID, "refillAccount");
addOptionsItem(menu, TOPUP_ITEM_ID, "topup");
if (((NetworkCatalogTree)tree).Item instanceof BasketItem) {
addOptionsItem(menu, BASKET_CLEAR, "clearBasket");
addOptionsItem(menu, BASKET_BUY_ALL_BOOKS, "buyAllBooks");
@ -182,7 +182,7 @@ class NetworkCatalogActions extends NetworkTreeActions {
boolean signIn = false;
boolean signOut = false;
boolean refill = false;
boolean topup = false;
String userName = null;
String account = null;
NetworkAuthenticationManager mgr = item.Link.authenticationManager();
@ -191,8 +191,8 @@ class NetworkCatalogActions extends NetworkTreeActions {
userName = mgr.currentUserName();
signOut = true;
account = mgr.currentAccount();
if (mgr.refillAccountLink() != null && account != null) {
refill = true;
if (account != null && Util.isTopupSupported(activity, item.Link)) {
topup = true;
}
} else {
signIn = true;
@ -204,7 +204,7 @@ class NetworkCatalogActions extends NetworkTreeActions {
prepareOptionsItem(menu, SIGNIN_ITEM_ID, signIn);
prepareOptionsItem(menu, SIGNUP_ITEM_ID, signIn & Util.isRegistrationSupported(activity, item.Link));
prepareOptionsItem(menu, SIGNOUT_ITEM_ID, signOut, "signOut", userName);
prepareOptionsItem(menu, REFILL_ACCOUNT_ITEM_ID, refill);
prepareOptionsItem(menu, TOPUP_ITEM_ID, topup);
return true;
}
@ -214,7 +214,7 @@ class NetworkCatalogActions extends NetworkTreeActions {
case B3_TRUE:
return false;
case B3_UNDEFINED:
AuthenticationDialog.show(activity, ((NetworkCatalogTree)tree).Item.Link, new Runnable() {
AuthenticationDialog.show(activity, item.Link, new Runnable() {
public void run() {
if (item.getVisibility() != ZLBoolean3.B3_TRUE) {
return;
@ -231,11 +231,11 @@ class NetworkCatalogActions extends NetworkTreeActions {
@Override
public boolean runAction(NetworkBaseActivity activity, NetworkTree tree, int actionCode) {
if (consumeByVisibility(activity, tree, actionCode)) {
final NetworkCatalogTree catalogTree = (NetworkCatalogTree)tree;
if (consumeByVisibility(activity, catalogTree, actionCode)) {
return true;
}
final NetworkCatalogTree catalogTree = (NetworkCatalogTree)tree;
final NetworkCatalogItem item = catalogTree.Item;
switch (actionCode) {
case OPEN_CATALOG_ITEM_ID:
@ -267,8 +267,8 @@ class NetworkCatalogActions extends NetworkTreeActions {
case SIGNOUT_ITEM_ID:
doSignOut(activity, catalogTree);
return true;
case REFILL_ACCOUNT_ITEM_ID:
new RefillAccountActions().runStandalone(activity, item.Link);
case TOPUP_ITEM_ID:
new TopupActions().runStandalone(activity, item.Link);
return true;
case CUSTOM_CATALOG_EDIT:
{
@ -381,15 +381,15 @@ class NetworkCatalogActions extends NetworkTreeActions {
final INetworkLink link = myTree.Item.Link;
if (myCheckAuthentication && link.authenticationManager() != null) {
final NetworkAuthenticationManager mgr = link.authenticationManager();
if (mgr.isAuthorised(true) && mgr.needsInitialization()) {
try {
if (mgr.isAuthorised(true) && mgr.needsInitialization()) {
mgr.initialize();
}
} catch (ZLNetworkException e) {
mgr.logOut();
}
}
}
}
@Override
public void doLoading(NetworkOperationData.OnNewItemListener doWithListener) throws ZLNetworkException {

View file

@ -66,8 +66,8 @@ public class NetworkCatalogActivity extends NetworkBaseActivity implements UserR
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) {
if (menuInfo == null && myTree instanceof NetworkCatalogTree) {
final INetworkLink link = ((NetworkCatalogTree)myTree).Item.Link;
if (Util.isAccountRefillingSupported(this, link)) {
final RefillAccountActions actions = NetworkView.Instance().getTopUpActions();
if (Util.isTopupSupported(this, link)) {
final TopupActions actions = NetworkView.Instance().getTopupActions();
if (actions != null) {
actions.buildContextMenu(this, menu, link);
return;
@ -81,8 +81,8 @@ public class NetworkCatalogActivity extends NetworkBaseActivity implements UserR
public boolean onContextItemSelected(MenuItem item) {
if ((item == null || item.getMenuInfo() == null) && myTree instanceof NetworkCatalogTree) {
final INetworkLink link = ((NetworkCatalogTree)myTree).Item.Link;
if (Util.isAccountRefillingSupported(this, link)) {
final RefillAccountActions actions = NetworkView.Instance().getTopUpActions();
if (Util.isTopupSupported(this, link)) {
final TopupActions actions = NetworkView.Instance().getTopupActions();
if (actions != null && actions.runAction(this, link, item.getItemId())) {
return true;
}

View file

@ -47,7 +47,7 @@ class NetworkView {
private volatile boolean myInitialized;
private final ArrayList<NetworkTreeActions> myActions = new ArrayList<NetworkTreeActions>();
private RefillAccountActions myTopUpActions;
private TopupActions myTopupActions;
private NetworkView() {
}
@ -66,8 +66,8 @@ class NetworkView {
myActions.add(new NetworkBookActions());
myActions.add(new NetworkCatalogActions());
myActions.add(new SearchItemActions());
myTopUpActions = new RefillAccountActions();
myActions.add(myTopUpActions);
myTopupActions = new TopupActions();
myActions.add(myTopupActions);
myActions.add(new AddCustomCatalogItemActions());
myActions.trimToSize();
@ -91,8 +91,8 @@ class NetworkView {
* NetworkItem's actions
*/
public RefillAccountActions getTopUpActions() {
return myTopUpActions;
public TopupActions getTopupActions() {
return myTopupActions;
}
public NetworkTreeActions getActions(NetworkTree tree) {

View file

@ -29,10 +29,11 @@ import org.geometerplus.fbreader.network.NetworkTree;
import org.geometerplus.fbreader.network.tree.TopUpTree;
import org.geometerplus.fbreader.network.authentication.NetworkAuthenticationManager;
class RefillAccountActions extends NetworkTreeActions {
public static final int REFILL_VIA_SMS_ITEM_ID = 0;
public static final int REFILL_VIA_BROWSER_ITEM_ID = 1;
class TopupActions extends NetworkTreeActions {
public static final int TOPUP_VIA_SMS_ITEM_ID = 0;
public static final int TOPUP_VIA_BROWSER_ITEM_ID = 1;
public static final int TOPUP_VIA_CREDIT_CARD_ITEM_ID = 2;
public static final int TOPUP_VIA_SELF_SERVICE_ITEM_ID = 3;
@Override
public boolean canHandleTree(NetworkTree tree) {
@ -45,13 +46,19 @@ class RefillAccountActions extends NetworkTreeActions {
}
void buildContextMenu(Activity activity, ContextMenu menu, INetworkLink link) {
menu.setHeaderTitle(getTitleValue("refillTitle"));
menu.setHeaderTitle(getTitleValue("topupTitle"));
if (Util.isSmsAccountRefillingSupported(activity, link)) {
addMenuItem(menu, REFILL_VIA_SMS_ITEM_ID, "refillViaSms");
if (Util.isTopupSupported(activity, link, Util.CREDIT_CARD_TOPUP_ACTION)) {
addMenuItem(menu, TOPUP_VIA_CREDIT_CARD_ITEM_ID, "topupViaCreditCard");
}
if (Util.isBrowserAccountRefillingSupported(activity, link)) {
addMenuItem(menu, REFILL_VIA_BROWSER_ITEM_ID, "refillViaBrowser");
if (Util.isTopupSupported(activity, link, Util.SMS_TOPUP_ACTION)) {
addMenuItem(menu, TOPUP_VIA_SMS_ITEM_ID, "topupViaSms");
}
if (Util.isTopupSupported(activity, link, Util.SELF_SERVICE_KIOSK_TOPUP_ACTION)) {
addMenuItem(menu, TOPUP_VIA_SELF_SERVICE_ITEM_ID, "topupViaSelfServiceKiosk");
}
if (Util.isBrowserTopupSupported(activity, link)) {
addMenuItem(menu, TOPUP_VIA_BROWSER_ITEM_ID, "topupViaBrowser");
}
}
@ -60,15 +67,26 @@ class RefillAccountActions extends NetworkTreeActions {
return getDefaultActionCode(activity, ((TopUpTree)tree).Item.Link);
}
private int getDefaultActionCode(Activity activity, INetworkLink link) {
final boolean sms = Util.isSmsAccountRefillingSupported(activity, link);
final boolean browser = Util.isBrowserAccountRefillingSupported(activity, link);
final boolean browser = Util.isBrowserTopupSupported(activity, link);
final boolean sms = Util.isTopupSupported(activity, link, Util.SMS_TOPUP_ACTION);
final boolean creditCard = Util.isTopupSupported(activity, link, Util.CREDIT_CARD_TOPUP_ACTION);
final boolean selfService = Util.isTopupSupported(activity, link, Util.SELF_SERVICE_KIOSK_TOPUP_ACTION);
final int count =
(sms ? 1 : 0) +
(browser ? 1 : 0) +
(creditCard ? 1 : 0) +
(selfService ? 1 : 0);
if (sms && browser) {
if (count > 1) {
return TREE_SHOW_CONTEXT_MENU;
} else if (sms) {
return REFILL_VIA_SMS_ITEM_ID;
return TOPUP_VIA_SMS_ITEM_ID;
} else if (creditCard) {
return TOPUP_VIA_CREDIT_CARD_ITEM_ID;
} else if (selfService) {
return TOPUP_VIA_SELF_SERVICE_ITEM_ID;
} else /* if (browser) */ {
return REFILL_VIA_BROWSER_ITEM_ID;
return TOPUP_VIA_BROWSER_ITEM_ID;
}
}
@ -94,51 +112,57 @@ class RefillAccountActions extends NetworkTreeActions {
}
static boolean runAction(Activity activity, INetworkLink link, int actionCode) {
Runnable refillRunnable = null;
Runnable topupRunnable = null;
switch (actionCode) {
case REFILL_VIA_SMS_ITEM_ID:
refillRunnable = smsRefillRunnable(activity, link);
case TOPUP_VIA_SMS_ITEM_ID:
topupRunnable = topupRunnable(activity, link, Util.SMS_TOPUP_ACTION);
break;
case REFILL_VIA_BROWSER_ITEM_ID:
refillRunnable = browserRefillRunnable(activity, link);
case TOPUP_VIA_BROWSER_ITEM_ID:
topupRunnable = browserTopupRunnable(activity, link);
break;
case TOPUP_VIA_CREDIT_CARD_ITEM_ID:
topupRunnable = topupRunnable(activity, link, Util.CREDIT_CARD_TOPUP_ACTION);
break;
case TOPUP_VIA_SELF_SERVICE_ITEM_ID:
topupRunnable = topupRunnable(activity, link, Util.SELF_SERVICE_KIOSK_TOPUP_ACTION);
break;
}
if (refillRunnable == null) {
if (topupRunnable == null) {
return false;
}
doRefill(activity, link, refillRunnable);
doTopup(activity, link, topupRunnable);
return true;
}
private static Runnable browserRefillRunnable(final Activity activity, final INetworkLink link) {
private static Runnable browserTopupRunnable(final Activity activity, final INetworkLink link) {
return new Runnable() {
public void run() {
Util.openInBrowser(
activity,
link.authenticationManager().refillAccountLink()
link.authenticationManager().topupLink()
);
}
};
}
private static Runnable smsRefillRunnable(final Activity activity, final INetworkLink link) {
private static Runnable topupRunnable(final Activity activity, final INetworkLink link, final String action) {
return new Runnable() {
public void run() {
Util.runSmsDialog(activity, link);
Util.runTopupDialog(activity, link, action);
}
};
}
private static void doRefill(final Activity activity, final INetworkLink link, final Runnable refiller) {
private static void doTopup(final Activity activity, final INetworkLink link, final Runnable action) {
final NetworkAuthenticationManager mgr = link.authenticationManager();
if (mgr.mayBeAuthorised(false)) {
refiller.run();
action.run();
} else {
AuthenticationDialog.show(activity, link, new Runnable() {
public void run() {
if (mgr.mayBeAuthorised(false)) {
refiller.run();
action.run();
}
}
});
@ -146,8 +170,8 @@ class RefillAccountActions extends NetworkTreeActions {
}
public void runStandalone(Activity activity, INetworkLink link) {
final int refillActionCode = getDefaultActionCode(activity, link);
if (refillActionCode == TREE_SHOW_CONTEXT_MENU) {
final int topupActionCode = getDefaultActionCode(activity, link);
if (topupActionCode == TREE_SHOW_CONTEXT_MENU) {
//activity.getListView().showContextMenu();
View view = null;
if (activity instanceof NetworkBaseActivity) {
@ -158,8 +182,8 @@ class RefillAccountActions extends NetworkTreeActions {
if (view != null) {
view.showContextMenu();
}
} else if (refillActionCode >= 0) {
runAction(activity, link, refillActionCode);
} else if (topupActionCode >= 0) {
runAction(activity, link, topupActionCode);
}
}
}

View file

@ -38,11 +38,15 @@ import org.geometerplus.android.util.PackageUtil;
abstract class Util implements UserRegistrationConstants {
private static final String REGISTRATION_ACTION =
"android.fbreader.action.NETWORK_LIBRARY_REGISTER";
private static final String SMS_REFILLING_ACTION =
static final String SMS_TOPUP_ACTION =
"android.fbreader.action.NETWORK_LIBRARY_SMS_REFILLING";
static final String CREDIT_CARD_TOPUP_ACTION =
"android.fbreader.action.NETWORK_LIBRARY_CREDIT_CARD_TOPUP";
static final String SELF_SERVICE_KIOSK_TOPUP_ACTION =
"android.fbreader.action.NETWORK_LIBRARY_SELF_SERVICE_KIOSK_TOPUP";
private static boolean testService(Activity activity, String action, String url) {
return url != null && PackageUtil.canBeStarted(activity, new Intent(action, Uri.parse(url)));
return url != null && PackageUtil.canBeStarted(activity, new Intent(action, Uri.parse(url)), true);
}
static boolean isRegistrationSupported(Activity activity, INetworkLink link) {
@ -59,7 +63,7 @@ abstract class Util implements UserRegistrationConstants {
REGISTRATION_ACTION,
Uri.parse(link.getUrlInfo(INetworkLink.URL_SIGN_UP).URL)
);
if (PackageUtil.canBeStarted(activity, intent)) {
if (PackageUtil.canBeStarted(activity, intent, true)) {
activity.startActivityForResult(new Intent(
REGISTRATION_ACTION,
Uri.parse(link.getUrlInfo(INetworkLink.URL_SIGN_UP).URL)
@ -83,41 +87,43 @@ abstract class Util implements UserRegistrationConstants {
}
}
static boolean isAccountRefillingSupported(Activity activity, INetworkLink link) {
static boolean isTopupSupported(Activity activity, INetworkLink link) {
return
isBrowserAccountRefillingSupported(activity, link) ||
isSmsAccountRefillingSupported(activity, link);
isBrowserTopupSupported(activity, link) ||
isTopupSupported(activity, link, SMS_TOPUP_ACTION) ||
isTopupSupported(activity, link, CREDIT_CARD_TOPUP_ACTION) ||
isTopupSupported(activity, link, SELF_SERVICE_KIOSK_TOPUP_ACTION);
}
static boolean isSmsAccountRefillingSupported(Activity activity, INetworkLink link) {
static boolean isTopupSupported(Activity activity, INetworkLink link, String action) {
return testService(
activity,
SMS_REFILLING_ACTION,
action,
link.getUrlInfo(INetworkLink.URL_MAIN).URL
);
}
static void runSmsDialog(Activity activity, INetworkLink link) {
static void runTopupDialog(Activity activity, INetworkLink link, String action) {
try {
final Intent intent = new Intent(
SMS_REFILLING_ACTION,
action,
Uri.parse(link.getUrlInfo(INetworkLink.URL_MAIN).URL)
);
final NetworkAuthenticationManager mgr = link.authenticationManager();
if (mgr != null) {
for (Map.Entry<String,String> entry : mgr.getSmsRefillingData().entrySet()) {
for (Map.Entry<String,String> entry : mgr.getTopupData().entrySet()) {
intent.putExtra(entry.getKey(), entry.getValue());
}
}
if (PackageUtil.canBeStarted(activity, intent)) {
if (PackageUtil.canBeStarted(activity, intent, true)) {
activity.startActivity(intent);
}
} catch (ActivityNotFoundException e) {
}
}
static boolean isBrowserAccountRefillingSupported(Activity activity, INetworkLink link) {
return link.getUrlInfo(INetworkLink.URL_REFILL_ACCOUNT).URL != null;
static boolean isBrowserTopupSupported(Activity activity, INetworkLink link) {
return link.getUrlInfo(INetworkLink.URL_TOPUP).URL != null;
}
static void openInBrowser(Context context, String url) {

View file

@ -99,6 +99,11 @@ public class EditBookInfoActivity extends ZLPreferenceActivity {
final ZLFile file = ZLFile.createFileByPath(path);
myBook = Book.getByFile(file);
if (myBook == null) {
finish();
return;
}
addPreference(new BookTitlePreference(this, Resource, "title", myBook));
addPreference(new LanguagePreference(this, Resource, "language", myBook));
}
@ -106,6 +111,8 @@ public class EditBookInfoActivity extends ZLPreferenceActivity {
@Override
protected void onPause() {
super.onPause();
if (myBook != null) {
myBook.save();
}
}
}

View file

@ -21,6 +21,7 @@ package org.geometerplus.android.fbreader.preferences;
import android.content.Intent;
import org.geometerplus.zlibrary.core.application.ZLKeyBindings;
import org.geometerplus.zlibrary.core.options.ZLIntegerOption;
import org.geometerplus.zlibrary.core.options.ZLIntegerRangeOption;
@ -239,6 +240,7 @@ public class PreferenceActivity extends ZLPreferenceActivity {
colorsScreen.addOption(profile.HighlightingOption, "highlighting");
colorsScreen.addOption(profile.RegularTextOption, "text");
colorsScreen.addOption(profile.HyperlinkTextOption, "hyperlink");
colorsScreen.addOption(profile.VisitedHyperlinkTextOption, "hyperlinkVisited");
colorsScreen.addOption(profile.FooterFillOption, "footer");
final Screen marginsScreen = createPreferenceScreen("margins");
@ -386,5 +388,20 @@ public class PreferenceActivity extends ZLPreferenceActivity {
final Screen cancelMenuScreen = createPreferenceScreen("cancelMenu");
cancelMenuScreen.addOption(fbReader.ShowPreviousBookInCancelMenuOption, "previousBook");
cancelMenuScreen.addOption(fbReader.ShowPositionsInCancelMenuOption, "positions");
final ZLKeyBindings bindings = fbReader.keyBindings();
final String[] backKeyActions =
//{ ActionCode.EXIT, ActionCode.GO_BACK, ActionCode.SHOW_CANCEL_MENU };
{ ActionCode.EXIT, ActionCode.SHOW_CANCEL_MENU };
cancelMenuScreen.addPreference(new ZLStringChoicePreference(
this, cancelMenuScreen.Resource, "backKeyAction",
bindings.getOption("<Back>", false), backKeyActions
));
final String[] backKeyLongPressActions =
//{ ActionCode.EXIT, ActionCode.GO_BACK, ActionCode.SHOW_CANCEL_MENU, FBReaderApp.NoAction };
{ ActionCode.EXIT, ActionCode.SHOW_CANCEL_MENU, FBReaderApp.NoAction };
cancelMenuScreen.addPreference(new ZLStringChoicePreference(
this, cancelMenuScreen.Resource, "backKeyLongPressAction",
bindings.getOption("<Back>", true), backKeyLongPressActions
));
}
}

View file

@ -0,0 +1,40 @@
/*
* 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.preferences;
import android.content.Context;
import org.geometerplus.zlibrary.core.options.ZLStringOption;
import org.geometerplus.zlibrary.core.resources.ZLResource;
class ZLStringChoicePreference extends ZLStringListPreference {
private final ZLStringOption myOption;
ZLStringChoicePreference(Context context, ZLResource rootResource, String resourceKey, ZLStringOption option, String[] values) {
super(context, rootResource, resourceKey);
setList(values);
setInitialValue(option.getValue());
myOption = option;
}
public void onAccept() {
myOption.setValue(getValue());
}
}

View file

@ -38,7 +38,7 @@ abstract class ZLStringListPreference extends ListPreference implements ZLPrefer
String[] texts = new String[values.length];
for (int i = 0; i < values.length; ++i) {
final ZLResource resource = myResource.getResource(values[i]);
texts[i] = (resource.hasValue()) ? resource.getValue() : values[i];
texts[i] = resource.hasValue() ? resource.getValue() : values[i];
}
setLists(values, texts);
}
@ -50,6 +50,9 @@ abstract class ZLStringListPreference extends ListPreference implements ZLPrefer
}
protected final boolean setInitialValue(String value) {
if (value == null || "".equals(value)) {
return false;
}
final int index = findIndexOfValue(value);
if (index >= 0) {
setValueIndex(index);

View file

@ -54,18 +54,20 @@ public abstract class PackageUtil {
public static boolean isPluginInstalled(Activity activity, String pkg) {
return canBeStarted(
activity,
new Intent("android.fbreader.action.TEST", homeUri(pkg))
new Intent("android.fbreader.action.TEST", homeUri(pkg)),
true
);
}
public static boolean isPluginInstalled(Activity activity, String pkg, String version) {
return canBeStarted(
activity,
new Intent("android.fbreader.action.TEST", homeUri(pkg, version))
new Intent("android.fbreader.action.TEST", homeUri(pkg, version)),
true
);
}
public static boolean canBeStarted(Context context, Intent intent) {
public static boolean canBeStarted(Context context, Intent intent, boolean checkSignature) {
final PackageManager manager = context.getApplicationContext().getPackageManager();
final ResolveInfo info =
manager.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
@ -76,6 +78,9 @@ public abstract class PackageUtil {
if (activityInfo == null) {
return false;
}
if (!checkSignature) {
return true;
}
return
PackageManager.SIGNATURE_MATCH ==
manager.checkSignatures(context.getPackageName(), activityInfo.packageName);

View file

@ -23,7 +23,7 @@ public interface ActionCode {
String SHOW_LIBRARY = "library";
String SHOW_PREFERENCES = "preferences";
String SHOW_BOOK_INFO = "bookInfo";
String SHOW_CONTENTS = "toc";
String SHOW_TOC = "toc";
String SHOW_BOOKMARKS = "bookmarks";
String SHOW_NETWORK_LIBRARY = "networkLibrary";
@ -45,7 +45,11 @@ public interface ActionCode {
String VOLUME_KEY_SCROLL_BACK = "volumeKeyScrollBackward";
String SHOW_MENU = "menu";
String SHOW_NAVIGATION = "navigate";
String CANCEL = "cancel";
String GO_BACK = "goBack";
String EXIT = "exit";
String SHOW_CANCEL_MENU = "cancelMenu";
String ROTATE = "rotate";
String INCREASE_FONT = "increaseFont";
String DECREASE_FONT = "decreaseFont";

View file

@ -59,6 +59,7 @@ public class ColorProfile {
public final ZLColorOption HighlightingOption;
public final ZLColorOption RegularTextOption;
public final ZLColorOption HyperlinkTextOption;
public final ZLColorOption VisitedHyperlinkTextOption;
public final ZLColorOption FooterFillOption;
private ColorProfile(String name, ColorProfile base) {
@ -68,6 +69,7 @@ public class ColorProfile {
HighlightingOption.setValue(base.HighlightingOption.getValue());
RegularTextOption.setValue(base.RegularTextOption.getValue());
HyperlinkTextOption.setValue(base.HyperlinkTextOption.getValue());
VisitedHyperlinkTextOption.setValue(base.VisitedHyperlinkTextOption.getValue());
FooterFillOption.setValue(base.FooterFillOption.getValue());
}
@ -89,6 +91,8 @@ public class ColorProfile {
createOption(name, "Text", 192, 192, 192);
HyperlinkTextOption =
createOption(name, "Hyperlink", 60, 142, 224);
VisitedHyperlinkTextOption =
createOption(name, "VisitedHyperlink", 200, 139, 255);
FooterFillOption =
createOption(name, "FooterFillOption", 85, 85, 85);
} else {
@ -104,6 +108,8 @@ public class ColorProfile {
createOption(name, "Text", 0, 0, 0);
HyperlinkTextOption =
createOption(name, "Hyperlink", 60, 139, 255);
VisitedHyperlinkTextOption =
createOption(name, "VisitedHyperlink", 200, 139, 255);
FooterFillOption =
createOption(name, "FooterFillOption", 170, 170, 170);
}

View file

@ -0,0 +1,34 @@
/*
* 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;
class ExitAction extends FBAction {
ExitAction(FBReaderApp fbreader) {
super(fbreader);
}
public void run() {
if (Reader.getCurrentView() != Reader.BookTextView) {
Reader.showBookTextView();
} else {
Reader.closeWindow();
}
}
}

View file

@ -127,6 +127,8 @@ public final class FBReaderApp extends ZLApplication {
addAction(ActionCode.SWITCH_TO_DAY_PROFILE, new SwitchProfileAction(this, ColorProfile.DAY));
addAction(ActionCode.SWITCH_TO_NIGHT_PROFILE, new SwitchProfileAction(this, ColorProfile.NIGHT));
addAction(ActionCode.EXIT, new ExitAction(this));
BookTextView = new FBView(this);
FootnoteView = new FBView(this);

View file

@ -386,13 +386,16 @@ public final class FBView extends ZLTextView {
}
@Override
public ZLColor getTextColor(byte hyperlinkType) {
public ZLColor getTextColor(ZLTextHyperlink hyperlink) {
final ColorProfile profile = myReader.getColorProfile();
switch (hyperlinkType) {
switch (hyperlink.Type) {
default:
case FBHyperlinkType.NONE:
return profile.RegularTextOption.getValue();
case FBHyperlinkType.INTERNAL:
return myReader.Model.Book.isHyperlinkVisited(hyperlink.Id)
? profile.VisitedHyperlinkTextOption.getValue()
: profile.HyperlinkTextOption.getValue();
case FBHyperlinkType.EXTERNAL:
return profile.HyperlinkTextOption.getValue();
}
@ -461,7 +464,7 @@ public final class FBView extends ZLTextView {
final ZLColor bgColor = getBackgroundColor();
// TODO: separate color option for footer color
final ZLColor fgColor = getTextColor(FBHyperlinkType.NONE);
final ZLColor fgColor = getTextColor(ZLTextHyperlink.NO_LINK);
final ZLColor fillColor = reader.getColorProfile().FooterFillOption.getValue();
final int left = getLeftMargin();

View file

@ -41,7 +41,7 @@ class OEBMetaInfoReader extends ZLXMLReaderAdapter implements XMLNamespaces {
private String myMetaTag = "meta";
private String mySeriesTitle = "";
private int mySeriesIndex = 0;
private float mySeriesIndex = 0;
private final ArrayList<String> myAuthorList = new ArrayList<String>();
private final ArrayList<String> myAuthorList2 = new ArrayList<String>();
@ -138,7 +138,7 @@ class OEBMetaInfoReader extends ZLXMLReaderAdapter implements XMLNamespaces {
} else if (attributes.getValue("name").equals("calibre:series_index")) {
final String strIndex = attributes.getValue("content");
try {
mySeriesIndex = Integer.parseInt(strIndex);
mySeriesIndex = Float.parseFloat(strIndex);
} catch (NumberFormatException e) {
}
}
@ -200,7 +200,7 @@ class OEBMetaInfoReader extends ZLXMLReaderAdapter implements XMLNamespaces {
}
} else {
if (tag.equals(myMetaTag)) {
if (!mySeriesTitle.equals("") && mySeriesIndex > 0) {
if (!"".equals(mySeriesTitle) && mySeriesIndex > 0) {
myBook.setSeriesInfo(mySeriesTitle, mySeriesIndex);
}
}

View file

@ -19,8 +19,7 @@
package org.geometerplus.fbreader.formats.plucker;
import java.io.IOException;
import java.io.InputStream;
import java.io.*;
import org.geometerplus.fbreader.formats.pdb.DocDecompressor;
import org.geometerplus.zlibrary.core.image.ZLSingleImage;
@ -38,29 +37,28 @@ public class DocCompressedFileImage extends ZLSingleImage {
myCompressedSize = compressedSize;
}
@Override
public String getURI() {
// TODO: implement
return null;
}
public byte[] byteData() {
@Override
public InputStream inputStream() {
try {
final InputStream stream = myFile.getInputStream();
if (stream == null) {
return new byte[0];
return null;
}
stream.skip(myOffset);
byte [] targetBuffer = new byte[65535];
final int size = DocDecompressor.decompress(stream, targetBuffer, myCompressedSize);
if (size > 0 && size != 65535) {
byte [] buffer = new byte[size];
System.arraycopy(targetBuffer, 0, buffer, 0, size);
return buffer;
final byte[] buffer = new byte[65535];
final int size = DocDecompressor.decompress(stream, buffer, myCompressedSize);
if (size > 0) {
return new ByteArrayInputStream(buffer, 0, size);
}
return targetBuffer;
} catch (IOException e) {}
return new byte[0];
} catch (IOException e) {
}
return null;
}
}

View file

@ -24,6 +24,7 @@ import java.io.InputStream;
import org.geometerplus.zlibrary.core.image.ZLSingleImage;
import org.geometerplus.zlibrary.core.filesystem.ZLFile;
import org.geometerplus.zlibrary.core.util.SliceInputStream;
public class PluckerFileImage extends ZLSingleImage {
private final ZLFile myFile;
@ -37,24 +38,18 @@ public class PluckerFileImage extends ZLSingleImage {
mySize = size;
}
@Override
public String getURI() {
// TODO: implement
return null;
}
public byte[] byteData() {
@Override
public InputStream inputStream() {
try {
final InputStream stream = myFile.getInputStream();
if (stream == null) {
return new byte[0];
}
stream.skip(myOffset);
byte [] buffer = new byte[mySize];
stream.read(buffer, 0, mySize);
return buffer;
} catch (IOException e) {}
return new byte[0];
return new SliceInputStream(myFile.getInputStream(), myOffset, mySize);
} catch (IOException e) {
return null;
}
}
}

View file

@ -19,8 +19,7 @@
package org.geometerplus.fbreader.formats.plucker;
import java.io.IOException;
import java.io.InputStream;
import java.io.*;
import java.util.ArrayList;
import java.util.zip.DataFormatException;
import java.util.zip.Inflater;
@ -40,16 +39,18 @@ public class ZCompressedFileImage extends ZLSingleImage {
myCompressedSize = compressedSize;
}
@Override
public String getURI() {
// TODO: implement
return null;
}
public byte[] byteData() {
@Override
public InputStream inputStream() {
try {
final InputStream stream = myFile.getInputStream();
if (stream == null) {
return new byte[0];
return null;
}
final ArrayList<byte[]> data = new ArrayList<byte[]>();
@ -73,10 +74,11 @@ public class ZCompressedFileImage extends ZLSingleImage {
System.arraycopy(data.get(i), 0, buffer, i * 4096, 4096);
}
System.arraycopy(data.get(dataSizeMinus1), 0, buffer, dataSizeMinus1 * 4096, sizeOfBufferData);
return buffer;
return new ByteArrayInputStream(buffer);
} catch (IOException e) {
return null;
} catch (DataFormatException e) {
}
return new byte[0];
return null;
}
}
}

View file

@ -30,6 +30,7 @@ class XHTMLTagHyperlinkAction extends XHTMLTagAction {
private static boolean isReference(String text) {
return
text.startsWith("fbreader-action://") ||
text.startsWith("http://") ||
text.startsWith("https://") ||
text.startsWith("mailto:") ||

View file

@ -231,11 +231,11 @@ public class Book {
return mySeriesInfo;
}
void setSeriesInfoWithNoCheck(String name, long index) {
void setSeriesInfoWithNoCheck(String name, float index) {
mySeriesInfo = new SeriesInfo(name, index);
}
public void setSeriesInfo(String name, long index) {
public void setSeriesInfo(String name, float index) {
if (mySeriesInfo == null) {
if (name != null) {
mySeriesInfo = new SeriesInfo(name, index);
@ -244,7 +244,7 @@ public class Book {
} else if (name == null) {
mySeriesInfo = null;
myIsSaved = false;
} else if (!mySeriesInfo.Name.equals(name) || (mySeriesInfo.Index != index)) {
} else if (!name.equals(mySeriesInfo.Name) || mySeriesInfo.Index != index) {
mySeriesInfo = new SeriesInfo(name, index);
myIsSaved = false;
}
@ -335,6 +335,7 @@ public class Book {
database.updateBookInfo(myId, fileInfos.getId(File), myEncoding, myLanguage, myTitle);
} else {
myId = database.insertBookInfo(File, myEncoding, myLanguage, myTitle);
storeAllVisitedHyperinks();
}
long index = 0;
@ -364,6 +365,39 @@ public class Book {
}
}
private Set<String> myVisitedHyperlinks;
private void initHyperlinkSet() {
if (myVisitedHyperlinks == null) {
myVisitedHyperlinks = new TreeSet<String>();
if (myId != -1) {
myVisitedHyperlinks.addAll(BooksDatabase.Instance().loadVisitedHyperlinks(myId));
}
}
}
public boolean isHyperlinkVisited(String linkId) {
initHyperlinkSet();
return myVisitedHyperlinks.contains(linkId);
}
public void markHyperlinkAsVisited(String linkId) {
initHyperlinkSet();
if (!myVisitedHyperlinks.contains(linkId)) {
myVisitedHyperlinks.add(linkId);
if (myId != -1) {
BooksDatabase.Instance().addVisitedHyperlink(myId, linkId);
}
}
}
private void storeAllVisitedHyperinks() {
if (myId != -1 && myVisitedHyperlinks != null) {
for (String linkId : myVisitedHyperlinks) {
BooksDatabase.Instance().addVisitedHyperlink(myId, linkId);
}
}
}
public void insertIntoBookList() {
if (myId != -1) {
BooksDatabase.Instance().insertIntoBookList(myId);

View file

@ -29,10 +29,10 @@ public final class BookInSeriesTree extends BookTree {
@Override
public int compareTo(FBTree tree) {
if (tree instanceof BookInSeriesTree) {
final long difference =
final float difference =
Book.getSeriesInfo().Index - ((BookTree)tree).Book.getSeriesInfo().Index;
if (difference != 0) {
return (int)difference;
return difference > 0 ? 1 : -1;
}
}
return super.compareTo(tree);

View file

@ -49,7 +49,7 @@ public abstract class BooksDatabase {
protected void addTag(Book book, Tag tag) {
book.addTagWithNoCheck(tag);
}
protected void setSeriesInfo(Book book, String series, long index) {
protected void setSeriesInfo(Book book, String series, float index) {
book.setSeriesInfoWithNoCheck(series, index);
}
@ -104,4 +104,7 @@ public abstract class BooksDatabase {
protected abstract boolean insertIntoBookList(long bookId);
protected abstract boolean deleteFromBookList(long bookId);
protected abstract boolean checkBookList(long bookId);
protected abstract Collection<String> loadVisitedHyperlinks(long bookId);
protected abstract void addVisitedHyperlink(long bookId, String hyperlinkId);
}

View file

@ -496,6 +496,9 @@ public final class Library {
private static final WeakReference<ZLImage> NULL_IMAGE = new WeakReference<ZLImage>(null);
public static ZLImage getCover(ZLFile file) {
if (file == null) {
return null;
}
synchronized(ourCoverMap) {
final String path = file.getPath();
final WeakReference<ZLImage> ref = ourCoverMap.get(path);

View file

@ -21,9 +21,9 @@ package org.geometerplus.fbreader.library;
public final class SeriesInfo {
public final String Name;
public final long Index;
public final float Index;
public SeriesInfo(String name, long index) {
public SeriesInfo(String name, float index) {
Name = name;
Index = index;
}

View file

@ -65,7 +65,7 @@ public class BookReference {
URI uri;
try {
uri = new URI(url);
} catch (java.net.URISyntaxException ex) {
} catch (Throwable ex) {
return null;
}

View file

@ -33,7 +33,7 @@ public interface INetworkLink {
String URL_SIGN_IN = "signIn";
String URL_SIGN_OUT = "signOut";
String URL_SIGN_UP = "signUp";
String URL_REFILL_ACCOUNT = "refillAccount";
String URL_TOPUP = "topup";
String URL_RECOVER_PASSWORD = "recoverPassword";
String getSiteName();

View file

@ -75,7 +75,7 @@ public final class NetworkBookItem extends NetworkItem {
public final LinkedList<AuthorData> Authors;
public final LinkedList<String> Tags;
public final String SeriesTitle;
public final int IndexInSeries;
public final float IndexInSeries;
private final LinkedList<BookReference> myReferences;
@ -98,7 +98,7 @@ public final class NetworkBookItem extends NetworkItem {
*/
public NetworkBookItem(INetworkLink link, String id, int index,
String title, String summary, /*String language, String date,*/
List<AuthorData> authors, List<String> tags, String seriesTitle, int indexInSeries,
List<AuthorData> authors, List<String> tags, String seriesTitle, float indexInSeries,
String cover,
List<BookReference> references) {
super(link, title, summary, cover);

View file

@ -68,9 +68,9 @@ public final class NetworkBookItemComparator implements Comparator<NetworkItem>
if (comp != 0) {
return comp;
} else {
final int diff = book0.IndexInSeries - book1.IndexInSeries;
final float diff = book0.IndexInSeries - book1.IndexInSeries;
if (diff != 0) {
return diff;
return diff > 0 ? 1 : -1;
}
}
return book0.Title.compareTo(book1.Title);

View file

@ -205,8 +205,10 @@ public final class NetworkImage extends ZLLoadableImage implements MimeTypes {
}
}
private ZLFileImage myFileImage;
@Override
public byte[] byteData() {
public InputStream inputStream() {
if (myFileImage == null) {
if (!isSynchronized()) {
return null;
}
@ -214,6 +216,8 @@ public final class NetworkImage extends ZLLoadableImage implements MimeTypes {
if (path == null) {
return null;
}
return new ZLFileImage(mimeType(), ZLFile.createFileByPath(path)).byteData();
myFileImage = new ZLFileImage(mimeType(), ZLFile.createFileByPath(path));
}
return myFileImage.inputStream();
}
}

View file

@ -25,8 +25,8 @@ public class TopUpItem extends NetworkItem {
public TopUpItem(INetworkLink link, String cover) {
super(
link,
ZLResource.resource("networkView").getResource("refillTitle").getValue(),
ZLResource.resource("networkView").getResource("refillSummary").getValue(),
ZLResource.resource("networkView").getResource("topupTitle").getValue(),
ZLResource.resource("networkView").getResource("topupSummary").getValue(),
cover
);
}

View file

@ -63,8 +63,6 @@ public abstract class NetworkAuthenticationManager {
public abstract void authorise(String password) throws ZLNetworkException;
public abstract void logOut();
public abstract BookReference downloadReference(NetworkBookItem book);
public abstract Map<String,String> getSmsRefillingData();
public final boolean mayBeAuthorised(boolean useNetwork) {
try {
@ -107,12 +105,15 @@ public abstract class NetworkAuthenticationManager {
//public abstract ZLNetworkSSLCertificate certificate();
/*
* refill account
* topup account
*/
public String refillAccountLink() {
public String topupLink() {
return null;
}
public Map<String,String> getTopupData() {
return Collections.emptyMap();
}
public abstract void initUser(String userName, String sid) throws ZLNetworkException;

View file

@ -233,7 +233,7 @@ public class LitResAuthenticationManager extends NetworkAuthenticationManager {
}
@Override
public String refillAccountLink() {
public String topupLink() {
final String sid;
synchronized (this) {
sid = mySidOption.getValue();
@ -241,7 +241,7 @@ public class LitResAuthenticationManager extends NetworkAuthenticationManager {
if (sid.length() == 0) {
return null;
}
final String url = Link.getUrlInfo(INetworkLink.URL_REFILL_ACCOUNT).URL;
final String url = Link.getUrlInfo(INetworkLink.URL_TOPUP).URL;
if (url == null) {
return null;
}
@ -411,7 +411,7 @@ public class LitResAuthenticationManager extends NetworkAuthenticationManager {
}
@Override
public Map<String,String> getSmsRefillingData() {
public Map<String,String> getTopupData() {
final HashMap<String,String> map = new HashMap<String,String>();
map.put("litres:userId", myUserIdOption.getValue());
map.put("litres:sid", mySidOption.getValue());

View file

@ -135,11 +135,15 @@ class BySeriesCatalogItem extends SortedCatalogItem {
public int compare(NetworkItem item0, NetworkItem item1) {
final NetworkBookItem book0 = (NetworkBookItem)item0;
final NetworkBookItem book1 = (NetworkBookItem)item1;
int diff = book0.SeriesTitle.compareTo(book1.SeriesTitle);
if (diff == 0) {
diff = book0.IndexInSeries - book1.IndexInSeries;
final int diff = book0.SeriesTitle.compareTo(book1.SeriesTitle);
if (diff != 0) {
return diff;
}
return diff != 0 ? diff : book0.Title.compareTo(book1.Title);
final float fdiff = book0.IndexInSeries - book1.IndexInSeries;
if (fdiff != 0) {
return fdiff > 0 ? 1 : -1;
}
return book0.Title.compareTo(book1.Title);
}
};
}

View file

@ -57,7 +57,7 @@ interface OPDSConstants {
String REL_LINK_SIGN_IN = "http://data.fbreader.org/catalog/sign-in";
String REL_LINK_SIGN_OUT = "http://data.fbreader.org/catalog/sign-out";
String REL_LINK_SIGN_UP = "http://data.fbreader.org/catalog/sign-up";
String REL_LINK_REFILL_ACCOUNT = "http://data.fbreader.org/catalog/refill-account";
String REL_LINK_TOPUP = "http://data.fbreader.org/catalog/refill-account";
String REL_LINK_RECOVER_PASSWORD = "http://data.fbreader.org/catalog/recover-password";
// Entry level / OPDS Link Conditions

View file

@ -28,7 +28,7 @@ class OPDSEntry extends ATOMEntry {
public DCDate DCIssued;
public String SeriesTitle;
public int SeriesIndex;
public float SeriesIndex;
@Override
public String toString() {

View file

@ -133,8 +133,8 @@ class OPDSLinkXMLReader extends OPDSXMLReader implements OPDSConstants, MimeType
infos.put(INetworkLink.URL_SIGN_OUT, new UrlInfo(href));
} else if (rel == REL_LINK_SIGN_UP) {
infos.put(INetworkLink.URL_SIGN_UP, new UrlInfo(href));
} else if (rel == REL_LINK_REFILL_ACCOUNT) {
infos.put(INetworkLink.URL_REFILL_ACCOUNT, new UrlInfo(href));
} else if (rel == REL_LINK_TOPUP) {
infos.put(INetworkLink.URL_TOPUP, new UrlInfo(href));
} else if (rel == REL_LINK_RECOVER_PASSWORD) {
infos.put(INetworkLink.URL_RECOVER_PASSWORD, new UrlInfo(href));
} else if (rel == REL_CONDITION_NEVER) {

View file

@ -681,7 +681,7 @@ class OPDSXMLReader extends ZLXMLReaderAdapter {
if (tagPrefix == myCalibreNamespaceId && tag == CALIBRE_TAG_SERIES_INDEX) {
if (bufferContent != null) {
try {
myEntry.SeriesIndex = Integer.parseInt(bufferContent);
myEntry.SeriesIndex = Float.parseFloat(bufferContent);
} catch (NumberFormatException ex) {
}
}

View file

@ -32,7 +32,7 @@ public class NetworkAuthorTree extends NetworkTree {
private int myBooksNumber;
private HashMap<String, Integer> mySeriesMap;
public NetworkAuthorTree(NetworkTree parent, NetworkBookItem.AuthorData author) {
NetworkAuthorTree(NetworkTree parent, NetworkBookItem.AuthorData author) {
super(parent);
Author = author;
}

View file

@ -22,8 +22,6 @@ package org.geometerplus.zlibrary.core.application;
import java.util.*;
import org.geometerplus.zlibrary.core.filesystem.*;
import org.geometerplus.zlibrary.core.options.ZLIntegerRangeOption;
import org.geometerplus.zlibrary.core.resources.ZLResource;
import org.geometerplus.zlibrary.core.view.ZLView;
import org.geometerplus.zlibrary.core.xml.ZLStringMap;
import org.geometerplus.zlibrary.core.xml.ZLXMLReaderAdapter;
@ -39,24 +37,14 @@ public abstract class ZLApplication {
//private static final String MouseScrollDownKey = "<MouseScrollUp>";
public static final String NoAction = "none";
public final ZLIntegerRangeOption KeyDelayOption =
new ZLIntegerRangeOption("Options", "KeyDelay", 0, 5000, 250);
private ZLApplicationWindow myWindow;
private ZLView myView;
private final HashMap<String,ZLAction> myIdToActionMap = new HashMap<String,ZLAction>();
private Menubar myMenubar;
//private ZLTime myLastKeyActionTime;
protected ZLApplication() {
ourInstance = this;
new MenubarCreator().read(ZLResourceFile.createResourceFile("default/menubar.xml"));
}
final Menubar getMenubar() {
return myMenubar;
}
protected final void setView(ZLView view) {
@ -76,7 +64,6 @@ public abstract class ZLApplication {
}
public void initWindow() {
myWindow.init();
setView(myView);
}
@ -135,11 +122,16 @@ public abstract class ZLApplication {
//may be protected
abstract public ZLKeyBindings keyBindings();
public final boolean doActionByKey(String key) {
final String actionId = keyBindings().getBinding(key);
public final boolean hasActionForKey(String key, boolean longPress) {
final String actionId = keyBindings().getBinding(key, longPress);
return actionId != null && !NoAction.equals(actionId);
}
public final boolean doActionByKey(String key, boolean longPress) {
final String actionId = keyBindings().getBinding(key, longPress);
if (actionId != null) {
final ZLAction action = myIdToActionMap.get(keyBindings().getBinding(key));
return (action != null) && action.checkAndRun();
final ZLAction action = myIdToActionMap.get(actionId);
return action != null && action.checkAndRun();
}
return false;
}
@ -188,10 +180,6 @@ public abstract class ZLApplication {
return false;
}
public boolean useKeyDelay() {
return true;
}
abstract protected void run();
}
@ -219,146 +207,6 @@ public abstract class ZLApplication {
return (myWindow != null) ? myWindow.getBatteryLevel() : 0;
}
//Menu
static class Menu {
public interface Item {
}
private final ArrayList<Item> myItems = new ArrayList<Item>();
private final ZLResource myResource;
Menu(ZLResource resource) {
myResource = resource;
}
ZLResource getResource() {
return myResource;
}
void addItem(String actionId) {
myItems.add(new Menubar.PlainItem(myResource.getResource(actionId)));
}
Menubar.Submenu addSubmenu(String key) {
Menubar.Submenu submenu = new Menubar.Submenu(myResource.getResource(key));
myItems.add(submenu);
return submenu;
}
int size() {
return myItems.size();
}
Item getItem(int index) {
return (Item)myItems.get(index);
}
}
//MenuBar
public static final class Menubar extends Menu {
public static final class PlainItem implements Item {
private final ZLResource myResource;
public PlainItem(ZLResource resource) {
myResource = resource;
}
public String getActionId() {
return myResource.Name;
}
public String getTitle() {
return myResource.getValue();
}
};
public static final class Submenu extends Menu implements Item {
public Submenu(ZLResource resource) {
super(resource);
}
public String getMenuName() {
return getResource().getValue();
}
};
public Menubar() {
super(ZLResource.resource("menu"));
}
}
//MenuVisitor
static public abstract class MenuVisitor {
public final void processMenu(ZLApplication application) {
if (application.myMenubar != null) {
processMenu(application.myMenubar);
}
}
private final void processMenu(Menu menu) {
final int size = menu.size();
for (int i = 0; i < size; ++i) {
final Menu.Item item = menu.getItem(i);
if (item instanceof Menubar.PlainItem) {
processItem((Menubar.PlainItem)item);
} else if (item instanceof Menubar.Submenu) {
Menubar.Submenu submenu = (Menubar.Submenu)item;
processSubmenuBeforeItems(submenu);
processMenu(submenu);
processSubmenuAfterItems(submenu);
}
}
}
protected abstract void processSubmenuBeforeItems(Menubar.Submenu submenu);
protected abstract void processSubmenuAfterItems(Menubar.Submenu submenu);
protected abstract void processItem(Menubar.PlainItem item);
}
private class MenubarCreator extends ZLXMLReaderAdapter {
private static final String ITEM = "item";
private static final String SUBMENU = "submenu";
private final ArrayList<Menubar.Submenu> mySubmenuStack = new ArrayList<Menubar.Submenu>();
@Override
public boolean dontCacheAttributeValues() {
return true;
}
@Override
public boolean startElementHandler(String tag, ZLStringMap attributes) {
if (myMenubar == null) {
myMenubar = new Menubar();
}
final ArrayList<Menubar.Submenu> stack = mySubmenuStack;
final Menu menu = stack.isEmpty() ? myMenubar : (Menu)stack.get(stack.size() - 1);
if (ITEM == tag) {
final String id = attributes.getValue("id");
if (id != null) {
menu.addItem(id);
}
} else if (SUBMENU == tag) {
final String id = attributes.getValue("id");
if (id != null) {
stack.add(menu.addSubmenu(id));
}
}
return false;
}
@Override
public boolean endElementHandler(String tag) {
if (SUBMENU == tag) {
final ArrayList<Menubar.Submenu> stack = mySubmenuStack;
if (!stack.isEmpty()) {
stack.remove(stack.size() - 1);
}
}
return false;
}
}
private Timer myTimer;
private final HashMap<Runnable,Long> myTimerTaskPeriods = new HashMap<Runnable,Long>();
private final HashMap<Runnable,TimerTask> myTimerTasks = new HashMap<Runnable,TimerTask>();

View file

@ -31,11 +31,6 @@ abstract public class ZLApplicationWindow {
return myApplication;
}
protected void init() {
initMenu();
}
abstract protected void initMenu();
abstract protected void refreshMenu();
abstract protected void repaintView();

View file

@ -21,74 +21,84 @@ package org.geometerplus.zlibrary.core.application;
import java.util.*;
import org.geometerplus.zlibrary.core.options.ZLIntegerRangeOption;
import org.geometerplus.zlibrary.core.options.ZLStringOption;
import org.geometerplus.zlibrary.core.options.ZLStringListOption;
import org.geometerplus.zlibrary.core.filesystem.ZLResourceFile;
import org.geometerplus.zlibrary.core.xml.ZLStringMap;
import org.geometerplus.zlibrary.core.xml.ZLXMLReaderAdapter;
public final class ZLKeyBindings {
private static final String BINDINGS_NUMBER = "Number";
private static final String BINDED_KEY = "Key";
private static final String BINDED_ACTION = "Action";
private static final String ACTION = "Action";
private static final String LONG_PRESS_ACTION = "LongPressAction";
private final String myName;
private final HashMap<String, String> myBindingsMap = new HashMap<String, String>();
private boolean myIsChanged;
private final ZLStringListOption myKeysOption;
private final TreeMap<String,ZLStringOption> myActionMap = new TreeMap<String,ZLStringOption>();
private final TreeMap<String,ZLStringOption> myLongPressActionMap = new TreeMap<String,ZLStringOption>();
public ZLKeyBindings(String name) {
myName = name;
new ZLKeyBindingsReader(myBindingsMap).readBindings();
loadCustomBindings();
myIsChanged = false;
final List<String> keys = new LinkedList<String>();
new Reader(keys).readBindings();
myKeysOption = new ZLStringListOption(name, "KeyList", keys);
}
public void bindKey(String key, String actionId) {
myBindingsMap.put(key, actionId);
myIsChanged = true;
private ZLStringOption createOption(String key, boolean longPress, String defaultValue) {
final String group = myName + ":" + (longPress ? LONG_PRESS_ACTION : ACTION);
return new ZLStringOption(group, key, defaultValue);
}
public String getBinding(String key) {
return (String)myBindingsMap.get(key);
public ZLStringOption getOption(String key, boolean longPress) {
final TreeMap<String,ZLStringOption> map = longPress ? myLongPressActionMap : myActionMap;
ZLStringOption option = map.get(key);
if (option == null) {
option = createOption(key, longPress, ZLApplication.NoAction);
map.put(key, option);
}
return option;
}
/*
public Set getKeys() {
return myBindingsMap.keySet();
}
*/
private void loadCustomBindings() {
final int size =
new ZLIntegerRangeOption(myName, BINDINGS_NUMBER, 0, 256, 0).getValue();
for (int i = 0; i < size; ++i) {
final String keyValue = new ZLStringOption(myName, BINDED_KEY + i, "").getValue();
if (keyValue.length() != 0) {
final String actionValue =
new ZLStringOption(myName, BINDED_ACTION + i, "").getValue();
if (actionValue.length() != 0) {
bindKey(keyValue, actionValue);
}
}
public void bindKey(String key, boolean longPress, String actionId) {
List<String> keys = myKeysOption.getValue();
if (!keys.contains(key)) {
keys = new ArrayList<String>(keys);
keys.add(key);
myKeysOption.setValue(keys);
}
getOption(key, longPress).setValue(actionId);
}
public void saveCustomBindings() {
if (!myIsChanged) {
return;
public String getBinding(String key, boolean longPress) {
return getOption(key, longPress).getValue();
}
final HashMap<String, String> keymap = new HashMap<String, String>();
new ZLKeyBindingsReader(keymap).readBindings();
private class Reader extends ZLXMLReaderAdapter {
private final List<String> myKeyList;
int counter = 0;
for (Iterator<String> it = myBindingsMap.keySet().iterator(); it.hasNext(); ) {
final String key = it.next();
final String originalValue = keymap.get(key);
final String value = myBindingsMap.get(key);
if (!value.equals(originalValue)) {
new ZLStringOption(myName, BINDED_KEY + counter, "").setValue(key);
new ZLStringOption(myName, BINDED_ACTION + counter, "").setValue(value);
++counter;
Reader(List<String> keyList) {
myKeyList = keyList;
}
@Override
public boolean dontCacheAttributeValues() {
return true;
}
@Override
public boolean startElementHandler(String tag, ZLStringMap attributes) {
if ("binding".equals(tag)) {
final String key = attributes.getValue("key");
final String actionId = attributes.getValue("action");
if (key != null && actionId != null) {
myKeyList.add(key);
myActionMap.put(key, createOption(key, false, actionId));
}
}
new ZLIntegerRangeOption(myName, BINDINGS_NUMBER, 0, 256, 0).setValue(counter);
return false;
}
public void readBindings() {
read(ZLResourceFile.createResourceFile("default/keymap.xml"));
}
}
}

View file

@ -1,55 +0,0 @@
/*
* 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.zlibrary.core.application;
import java.util.*;
import org.geometerplus.zlibrary.core.filesystem.ZLResourceFile;
import org.geometerplus.zlibrary.core.xml.ZLStringMap;
import org.geometerplus.zlibrary.core.xml.ZLXMLReaderAdapter;
class ZLKeyBindingsReader extends ZLXMLReaderAdapter {
private final HashMap<String, String> myKeymap;
@Override
public boolean dontCacheAttributeValues() {
return true;
}
public ZLKeyBindingsReader(HashMap<String, String> keymap) {
myKeymap = keymap;
}
@Override
public boolean startElementHandler(String tag, ZLStringMap attributes) {
if ("binding".equals(tag)) {
final String key = attributes.getValue("key");
final String actionId = attributes.getValue("action");
if ((key != null) && (actionId != null)) {
myKeymap.put(key, actionId);
}
}
return false;
}
public void readBindings() {
read(ZLResourceFile.createResourceFile("default/keymap.xml"));
}
}

View file

@ -19,10 +19,7 @@
package org.geometerplus.zlibrary.core.image;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.*;
public abstract class ZLBase64EncodedImage extends ZLSingleImage {
private boolean myIsDecoded;
@ -129,18 +126,10 @@ public abstract class ZLBase64EncodedImage extends ZLSingleImage {
}
@Override
public final byte[] byteData() {
public final InputStream inputStream() {
try {
decode();
final File file = new File(decodedFileName());
final byte[] data = new byte[(int)file.length()];
final FileInputStream stream = new FileInputStream(file);
try {
stream.read(data);
} finally {
stream.close();
}
return data;
return new FileInputStream(new File(decodedFileName()));
} catch (IOException e) {
return null;
}

View file

@ -22,6 +22,7 @@ package org.geometerplus.zlibrary.core.image;
import java.io.*;
import org.geometerplus.zlibrary.core.filesystem.ZLFile;
import org.geometerplus.zlibrary.core.util.SliceInputStream;
public class ZLFileImage extends ZLSingleImage {
public static final String SCHEME = "imagefile";
@ -46,34 +47,11 @@ public class ZLFileImage extends ZLSingleImage {
}
@Override
public byte[] byteData() {
InputStream stream = null;
public InputStream inputStream() {
try {
stream = myFile.getInputStream();
int toSkip = myOffset - (int)stream.skip(myOffset);
while (--toSkip >= 0) {
stream.read();
}
byte[] buffer = new byte[myLength];
int len = 0;
while (len < myLength) {
final int part = stream.read(buffer);
if (part <= 0) {
return new byte[0];
}
len += part;
}
return buffer;
} catch (IOException e) {
return new byte[0];
} finally {
if (stream != null) {
try {
stream.close();
return new SliceInputStream(myFile.getInputStream(), myOffset, myLength);
} catch (IOException e) {
}
}
return null;
}
}
}

View file

@ -19,6 +19,8 @@
package org.geometerplus.zlibrary.core.image;
import java.io.InputStream;
import org.geometerplus.zlibrary.core.constants.MimeTypes;
public abstract class ZLImageProxy extends ZLLoadableImage {
@ -39,8 +41,8 @@ public abstract class ZLImageProxy extends ZLLoadableImage {
}
@Override
public final byte[] byteData() {
return myImage != null ? myImage.byteData() : null;
public final InputStream inputStream() {
return myImage != null ? myImage.inputStream() : null;
}
@Override

View file

@ -19,6 +19,9 @@
package org.geometerplus.zlibrary.core.image;
import java.io.InputStream;
import java.io.ByteArrayInputStream;
public abstract class ZLSingleImage implements ZLImage {
private final String myMimeType;
@ -26,7 +29,7 @@ public abstract class ZLSingleImage implements ZLImage {
myMimeType = mimeType;
}
public abstract byte[] byteData();
public abstract InputStream inputStream();
public final String mimeType() {
return myMimeType;

View file

@ -0,0 +1,72 @@
/*
* 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.zlibrary.core.util;
import java.io.IOException;
import java.io.InputStream;
public class SliceInputStream extends InputStream {
private final ZLInputStreamWithOffset myBase;
private final int myStart;
private final int myLength;
public SliceInputStream(InputStream base, int start, int length) throws IOException {
myBase = new ZLInputStreamWithOffset(base);
myBase.skip(start);
myStart = start;
myLength = length;
}
@Override
public int available() throws IOException {
return Math.min(myBase.available(), Math.max(myStart + myLength - myBase.offset(), 0));
}
@Override
public long skip(long n) throws IOException {
return myBase.skip(n);
}
@Override
public int read() throws IOException {
return myBase.read();
}
@Override
public void close() throws IOException {
myBase.close();
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
return myBase.read(b, off, len);
}
@Override
public int read(byte[] b) throws IOException {
return myBase.read(b);
}
@Override
public void reset() throws IOException {
myBase.reset();
myBase.skip(myStart);
}
}

View file

@ -24,7 +24,11 @@ import java.util.Map;
public abstract class ZLMiscUtil {
public static <T> boolean equals(T o0, T o1) {
return (o0 == null) ? (o1 == null) : o0.equals(o1);
return o0 == null ? o1 == null : o0.equals(o1);
}
public static boolean isEmptyString(String s) {
return s == null || "".equals(s);
}
public static int hashCode(Object o) {

View file

@ -20,8 +20,8 @@
package org.geometerplus.zlibrary.text.model;
import java.util.*;
import org.geometerplus.zlibrary.core.util.*;
import org.geometerplus.zlibrary.core.util.*;
import org.geometerplus.zlibrary.core.image.ZLImageMap;
public class ZLTextPlainModel implements ZLTextModel {

View file

@ -51,7 +51,7 @@ abstract class ZLTextViewBase extends ZLView {
public abstract ZLFile getWallpaperFile();
public abstract ZLColor getBackgroundColor();
public abstract ZLColor getSelectedBackgroundColor();
public abstract ZLColor getTextColor(byte hyperlinkType);
public abstract ZLColor getTextColor(ZLTextHyperlink hyperlink);
public abstract ZLColor getHighlightingColor();
int getTextAreaHeight() {
@ -185,7 +185,7 @@ abstract class ZLTextViewBase extends ZLView {
final void drawWord(int x, int y, ZLTextWord word, int start, int length, boolean addHyphenationSign) {
final ZLPaintContext context = myContext;
context.setTextColor(getTextColor(myTextStyle.Hyperlink.Type));
context.setTextColor(getTextColor(myTextStyle.Hyperlink));
if ((start == 0) && (length == -1)) {
drawString(x, y, word.Data, word.Offset, word.Length, word.getMark(), 0);
} else {
@ -209,7 +209,6 @@ abstract class ZLTextViewBase extends ZLView {
private final void drawString(int x, int y, char[] str, int offset, int length, ZLTextWord.Mark mark, int shift) {
final ZLPaintContext context = myContext;
context.setTextColor(getTextColor(myTextStyle.Hyperlink.Type));
if (mark == null) {
context.drawString(x, y, str, offset, length);
} else {
@ -240,7 +239,6 @@ abstract class ZLTextViewBase extends ZLView {
context.fillRectangle(x, y - context.getStringHeight(), endX - 1, y + context.getDescent());
context.drawString(x, y, str, offset + markStart, endPos - markStart);
x = endX;
context.setTextColor(getTextColor(myTextStyle.Hyperlink.Type));
}
pos = markStart + markLen;
}

View file

@ -26,6 +26,7 @@ import android.view.MenuItem;
import org.geometerplus.zlibrary.core.application.ZLApplication;
import org.geometerplus.zlibrary.core.application.ZLApplicationWindow;
import org.geometerplus.zlibrary.core.resources.ZLResource;
import org.geometerplus.zlibrary.ui.android.view.ZLAndroidWidget;
import org.geometerplus.zlibrary.ui.android.library.ZLAndroidLibrary;
@ -34,39 +35,12 @@ import org.geometerplus.zlibrary.ui.android.library.ZLAndroidApplication;
import org.geometerplus.zlibrary.ui.android.R;
public final class ZLAndroidApplicationWindow extends ZLApplicationWindow {
private final HashMap<MenuItem,ZLApplication.Menubar.PlainItem> myMenuItemMap =
new HashMap<MenuItem,ZLApplication.Menubar.PlainItem>();
private class MenuBuilder extends ZLApplication.MenuVisitor {
private int myItemCount = Menu.FIRST;
private final Stack<Menu> myMenuStack = new Stack<Menu>();
private MenuBuilder(Menu menu) {
myMenuStack.push(menu);
}
protected void processSubmenuBeforeItems(ZLApplication.Menubar.Submenu submenu) {
myMenuStack.push(myMenuStack.peek().addSubMenu(0, myItemCount++, Menu.NONE, submenu.getMenuName()));
}
protected void processSubmenuAfterItems(ZLApplication.Menubar.Submenu submenu) {
myMenuStack.pop();
}
protected void processItem(ZLApplication.Menubar.PlainItem item) {
MenuItem menuItem = myMenuStack.peek().add(0, myItemCount++, Menu.NONE, item.getTitle());
try {
final String fieldName = "ic_menu_" + item.getActionId().toLowerCase();
menuItem.setIcon(R.drawable.class.getField(fieldName).getInt(null));
} catch (NoSuchFieldException e) {
} catch (IllegalAccessException e) {
}
menuItem.setOnMenuItemClickListener(myMenuListener);
myMenuItemMap.put(menuItem, item);
}
}
private final HashMap<MenuItem,String> myMenuItemMap = new HashMap<MenuItem,String>();
private final MenuItem.OnMenuItemClickListener myMenuListener =
new MenuItem.OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
getApplication().doAction(myMenuItemMap.get(item).getActionId());
getApplication().doAction(myMenuItemMap.get(item));
return true;
}
};
@ -75,24 +49,25 @@ public final class ZLAndroidApplicationWindow extends ZLApplicationWindow {
super(application);
}
public void buildMenu(Menu menu) {
new MenuBuilder(menu).processMenu(getApplication());
refreshMenu();
public void addMenuItem(Menu menu, String actionId, Integer iconId) {
final ZLResource resource = ZLResource.resource("menu");
final MenuItem menuItem = menu.add(resource.getResource(actionId).getValue());
if (iconId != null) {
menuItem.setIcon(iconId);
}
menuItem.setOnMenuItemClickListener(myMenuListener);
myMenuItemMap.put(menuItem, actionId);
}
@Override
protected void refreshMenu() {
for (Map.Entry<MenuItem,ZLApplication.Menubar.PlainItem> entry : myMenuItemMap.entrySet()) {
final String actionId = entry.getValue().getActionId();
for (Map.Entry<MenuItem,String> entry : myMenuItemMap.entrySet()) {
final String actionId = entry.getValue();
final ZLApplication application = getApplication();
entry.getKey().setVisible(application.isActionVisible(actionId) && application.isActionEnabled(actionId));
}
}
public void initMenu() {
// TODO: implement
}
protected void repaintView() {
final ZLAndroidWidget widget =
((ZLAndroidLibrary)ZLAndroidLibrary.Instance()).getWidget();

View file

@ -19,17 +19,22 @@
package org.geometerplus.zlibrary.ui.android.image;
import java.io.InputStream;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
final class ZLAndroidArrayBasedImageData extends ZLAndroidImageData {
private final byte[] myArray;
import org.geometerplus.zlibrary.core.image.ZLSingleImage;
ZLAndroidArrayBasedImageData(byte[] array) {
myArray = array;
final class InputStreamImageData extends ZLAndroidImageData {
private final ZLSingleImage myImage;
InputStreamImageData(ZLSingleImage image) {
myImage = image;
}
protected Bitmap decodeWithOptions(BitmapFactory.Options options) {
return BitmapFactory.decodeByteArray(myArray, 0, myArray.length, options);
final InputStream stream = myImage.inputStream();
return stream != null ? BitmapFactory.decodeStream(stream) : null;
}
}

View file

@ -28,15 +28,11 @@ public final class ZLAndroidImageManager extends ZLImageManager {
if (image instanceof ZLAndroidImageData) {
return (ZLAndroidImageData)image;
} else if (image instanceof ZLSingleImage) {
ZLSingleImage singleImage = (ZLSingleImage)image;
final ZLSingleImage singleImage = (ZLSingleImage)image;
if (MimeTypes.MIME_IMAGE_PALM.equals(singleImage.mimeType())) {
return null;
}
byte[] array = singleImage.byteData();
if (array == null) {
return null;
}
return new ZLAndroidArrayBasedImageData(array);
return new InputStreamImageData(singleImage);
} else {
//TODO
return null;

View file

@ -219,13 +219,6 @@ public abstract class ZLAndroidActivity extends Activity {
return (ZLAndroidLibrary)ZLAndroidLibrary.Instance();
}
@Override
public boolean onCreateOptionsMenu(final Menu menu) {
super.onCreateOptionsMenu(menu);
((ZLAndroidApplication)getApplication()).myMainWindow.buildMenu(menu);
return true;
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
View view = findViewById(R.id.main_view);

View file

@ -56,7 +56,7 @@ public class ZLAndroidApplication extends Application {
"PD_Novel".equals(Build.MODEL);
}
ZLAndroidApplicationWindow myMainWindow;
public ZLAndroidApplicationWindow myMainWindow;
@Override
public void onCreate() {

View file

@ -472,25 +472,46 @@ public class ZLAndroidWidget extends View implements View.OnLongClickListener {
return view.onFingerLongPress(myPressedX, myPressedY);
}
private String myKeyUnderTracking;
private long myTrackingStartTime;
public boolean onKeyDown(int keyCode, KeyEvent event) {
final ZLApplication application = ZLApplication.Instance();
switch (keyCode) {
case KeyEvent.KEYCODE_VOLUME_DOWN:
case KeyEvent.KEYCODE_VOLUME_UP:
case KeyEvent.KEYCODE_BACK:
case KeyEvent.KEYCODE_ENTER:
case KeyEvent.KEYCODE_DPAD_CENTER:
return ZLApplication.Instance().doActionByKey(ZLAndroidKeyUtil.getKeyNameByCode(keyCode));
{
final String keyName = ZLAndroidKeyUtil.getKeyNameByCode(keyCode);
if (myKeyUnderTracking != null) {
if (myKeyUnderTracking.equals(keyName)) {
return true;
} else {
myKeyUnderTracking = null;
}
}
if (application.hasActionForKey(keyName, true)) {
myKeyUnderTracking = keyName;
myTrackingStartTime = System.currentTimeMillis();
return true;
} else {
return application.doActionByKey(keyName, false);
}
}
case KeyEvent.KEYCODE_DPAD_LEFT:
ZLApplication.Instance().getCurrentView().onTrackballRotated(-1, 0);
application.getCurrentView().onTrackballRotated(-1, 0);
return true;
case KeyEvent.KEYCODE_DPAD_RIGHT:
ZLApplication.Instance().getCurrentView().onTrackballRotated(1, 0);
application.getCurrentView().onTrackballRotated(1, 0);
return true;
case KeyEvent.KEYCODE_DPAD_DOWN:
ZLApplication.Instance().getCurrentView().onTrackballRotated(0, 1);
application.getCurrentView().onTrackballRotated(0, 1);
return true;
case KeyEvent.KEYCODE_DPAD_UP:
ZLApplication.Instance().getCurrentView().onTrackballRotated(0, -1);
application.getCurrentView().onTrackballRotated(0, -1);
return true;
default:
return false;
@ -504,6 +525,15 @@ public class ZLAndroidWidget extends View implements View.OnLongClickListener {
case KeyEvent.KEYCODE_BACK:
case KeyEvent.KEYCODE_ENTER:
case KeyEvent.KEYCODE_DPAD_CENTER:
if (myKeyUnderTracking != null) {
final String keyName = ZLAndroidKeyUtil.getKeyNameByCode(keyCode);
if (myKeyUnderTracking.equals(keyName)) {
final boolean longPress = System.currentTimeMillis() >
myTrackingStartTime + ViewConfiguration.getLongPressTimeout();
ZLApplication.Instance().doActionByKey(keyName, longPress);
}
myKeyUnderTracking = null;
}
return true;
default:
return false;