diff --git a/README.md b/README.md index 44b2bd50f..df0667c1e 100644 --- a/README.md +++ b/README.md @@ -24,16 +24,17 @@ Main features for users * built-in multi-lingual hyphenation dictionaries * supports adding custom online OPDS catalogs * calibre integration - * send ebooks from calibre library to koreader wirelessly + * search calibre metadata on your koreader device + * send ebooks from calibre library to your koreader device wirelessly * browser calibre library and download ebooks via calibre OPDS server -* can share ebooks to other koreader devices wirelessly +* can share ebooks with other koreader devices wirelessly * various optimizations for e-ink devices * paginated menus without animation * adjustable text contrast * multi-lingual user interface * online Over-The-Air software update -Highlights for developlers +Highlights for developers -------------------------- * frontend written in Lua scripting language diff --git a/frontend/apps/reader/modules/readerhighlight.lua b/frontend/apps/reader/modules/readerhighlight.lua index c17362161..9c6892a24 100644 --- a/frontend/apps/reader/modules/readerhighlight.lua +++ b/frontend/apps/reader/modules/readerhighlight.lua @@ -12,7 +12,9 @@ local _ = require("gettext") local ReaderHighlight = InputContainer:new{} function ReaderHighlight:init() - self.ui.menu:registerToMainMenu(self) + self.ui:registerPostInitCallback(function() + self.ui.menu:registerToMainMenu(self) + end) end function ReaderHighlight:initGesListener() diff --git a/frontend/apps/reader/modules/readerlink.lua b/frontend/apps/reader/modules/readerlink.lua index a586334f0..0b5ef933a 100644 --- a/frontend/apps/reader/modules/readerlink.lua +++ b/frontend/apps/reader/modules/readerlink.lua @@ -17,7 +17,9 @@ function ReaderLink:init() if Device:isTouchDevice() then self:initGesListener() end - self.ui.menu:registerToMainMenu(self) + self.ui:registerPostInitCallback(function() + self.ui.menu:registerToMainMenu(self) + end) end function ReaderLink:onReadSettings(config) diff --git a/frontend/apps/reader/modules/readerrolling.lua b/frontend/apps/reader/modules/readerrolling.lua index 23b958187..547375c2a 100644 --- a/frontend/apps/reader/modules/readerrolling.lua +++ b/frontend/apps/reader/modules/readerrolling.lua @@ -247,12 +247,14 @@ function ReaderRolling:onResume() end function ReaderRolling:onDoubleTapForward() - self:onGotoPage(self.ui.toc:getNextChapter(self.current_page)) + local pageno = self.current_page + self.ui.document:getVisiblePageCount() + self:onGotoPage(self.ui.toc:getNextChapter(pageno, 0)) return true end function ReaderRolling:onDoubleTapBackward() - self:onGotoPage(self.ui.toc:getPreviousChapter(self.current_page)) + local pageno = self.current_page + self:onGotoPage(self.ui.toc:getPreviousChapter(pageno, 0)) return true end diff --git a/frontend/apps/reader/pluginloader.lua b/frontend/apps/reader/pluginloader.lua index 788964f9e..b94fd03c7 100644 --- a/frontend/apps/reader/pluginloader.lua +++ b/frontend/apps/reader/pluginloader.lua @@ -27,6 +27,7 @@ function PluginLoader:loadPlugins() package.cpath = package_cpath if ok then module.path = path + module.name = module.name or path:match("/(.-)%.koplugin") table.insert(self.plugins, module) end end diff --git a/frontend/apps/reader/readerui.lua b/frontend/apps/reader/readerui.lua index 15214547e..cb9356a53 100644 --- a/frontend/apps/reader/readerui.lua +++ b/frontend/apps/reader/readerui.lua @@ -67,6 +67,15 @@ local ReaderUI = InputContainer:new{ postInitCallback = nil, } +function ReaderUI:registerModule(name, module, always_active) + if name then self[name] = module end + table.insert(always_active and self.active_widgets or self, module) +end + +function ReaderUI:registerPostInitCallback(callback) + table.insert(self.postInitCallback, callback) +end + function ReaderUI:init() self.postInitCallback = {} -- if we are not the top level dialog ourselves, it must be given in the table @@ -83,204 +92,194 @@ function ReaderUI:init() self.doc_settings = DocSettings:open(self.document.file) -- a view container (so it must be child #1!) - self[1] = ReaderView:new{ + self:registerModule("view", ReaderView:new{ dialog = self.dialog, dimen = self.dimen, ui = self, document = self.document, - } - -- reader menu controller - -- hold reference to menu widget - self.menu = ReaderMenu:new{ - view = self[1], - ui = self - } - -- link - table.insert(self, ReaderLink:new{ + }) + -- goto link controller + self:registerModule("link", ReaderLink:new{ dialog = self.dialog, - view = self[1], + view = self.view, ui = self, document = self.document, }) -- text highlight - table.insert(self, ReaderHighlight:new{ + self:registerModule("highlight", ReaderHighlight:new{ dialog = self.dialog, - view = self[1], + view = self.view, ui = self, document = self.document, }) -- menu widget should be registered after link widget and highlight widget -- so that taps on link and highlight areas won't popup reader menu - table.insert(self, self.menu) + -- reader menu controller + self:registerModule("menu", ReaderMenu:new{ + view = self.view, + ui = self + }) -- rotation controller - table.insert(self, ReaderRotation:new{ + self:registerModule("rotation", ReaderRotation:new{ dialog = self.dialog, - view = self[1], + view = self.view, ui = self }) -- Table of content controller - -- hold reference to bm widget - self.toc = ReaderToc:new{ + self:registerModule("toc", ReaderToc:new{ dialog = self.dialog, - view = self[1], + view = self.view, ui = self - } - table.insert(self, self.toc) + }) -- bookmark controller - table.insert(self, ReaderBookmark:new{ + self:registerModule("bookmark", ReaderBookmark:new{ dialog = self.dialog, - view = self[1], + view = self.view, ui = self }) -- reader goto controller - table.insert(self, ReaderGoto:new{ + -- "goto" being a dirty keyword in Lua? + self:registerModule("gotopage", ReaderGoto:new{ dialog = self.dialog, - view = self[1], + view = self.view, ui = self, document = self.document, }) -- dictionary - table.insert(self, ReaderDictionary:new{ + self:registerModule("dictionary", ReaderDictionary:new{ dialog = self.dialog, - view = self[1], + view = self.view, ui = self, document = self.document, }) -- wikipedia - table.insert(self, ReaderWikipedia:new{ + self:registerModule("wikipedia", ReaderWikipedia:new{ dialog = self.dialog, - view = self[1], + view = self.view, ui = self, document = self.document, }) -- screenshot controller - table.insert(self.active_widgets, ReaderScreenshot:new{ + self:registerModule("screenshot", ReaderScreenshot:new{ dialog = self.dialog, - view = self[1], + view = self.view, ui = self - }) + }, true) -- frontlight controller if Device:hasFrontlight() then - table.insert(self, ReaderFrontLight:new{ + self:registerModule("frontlight", ReaderFrontLight:new{ dialog = self.dialog, - view = self[1], + view = self.view, ui = self }) end -- configuable controller if self.document.info.configurable then -- config panel controller - table.insert(self, ReaderConfig:new{ + self:registerModule("config", ReaderConfig:new{ configurable = self.document.configurable, options = self.document.options, dialog = self.dialog, - view = self[1], + view = self.view, ui = self }) - if not self.document.info.has_pages then + if self.document.info.has_pages then + -- kopt option controller + self:registerModule("koptlistener", ReaderKoptListener:new{ + dialog = self.dialog, + view = self.view, + ui = self, + document = self.document, + }) + else -- cre option controller - table.insert(self, ReaderCoptListener:new{ + self:registerModule("crelistener", ReaderCoptListener:new{ dialog = self.dialog, - view = self[1], + view = self.view, ui = self, document = self.document, }) end + -- activity indicator when some configurations take long take to affect + self:registerModule("activityindicator", ReaderActivityIndicator:new{ + dialog = self.dialog, + view = self.view, + ui = self, + document = self.document, + }) end -- for page specific controller if self.document.info.has_pages then -- cropping controller - table.insert(self, ReaderCropping:new{ + self:registerModule("cropping", ReaderCropping:new{ dialog = self.dialog, - view = self[1], + view = self.view, ui = self, document = self.document, }) -- paging controller - table.insert(self, ReaderPaging:new{ + self:registerModule("paging", ReaderPaging:new{ dialog = self.dialog, - view = self[1], + view = self.view, ui = self }) -- zooming controller - local zoom = ReaderZooming:new{ + self:registerModule("zooming", ReaderZooming:new{ dialog = self.dialog, - view = self[1], + view = self.view, ui = self - } - table.insert(self, zoom) + }) -- panning controller - table.insert(self, ReaderPanning:new{ + self:registerModule("panning", ReaderPanning:new{ dialog = self.dialog, - view = self[1], + view = self.view, ui = self }) -- hinting controller - table.insert(self, ReaderHinting:new{ + self:registerModule("hinting", ReaderHinting:new{ dialog = self.dialog, - zoom = zoom, - view = self[1], + zoom = self.zooming, + view = self.view, ui = self, document = self.document, }) else -- make sure we render document first before calling any callback - table.insert(self.postInitCallback, function() + self:registerPostInitCallback(function() self.document:render() end) -- typeset controller - table.insert(self, ReaderTypeset:new{ + self:registerModule("typeset", ReaderTypeset:new{ dialog = self.dialog, - view = self[1], + view = self.view, ui = self }) -- font menu - self.font = ReaderFont:new{ + self:registerModule("font", ReaderFont:new{ dialog = self.dialog, - view = self[1], + view = self.view, ui = self - } - table.insert(self, self.font) -- hold reference to font menu + }) -- hyphenation menu - self.hyphenation = ReaderHyphenation:new{ + self:registerModule("hyphenation", ReaderHyphenation:new{ dialog = self.dialog, - view = self[1], + view = self.view, ui = self - } - table.insert(self, self.hyphenation) -- hold reference to hyphenation menu + }) -- rolling controller - table.insert(self, ReaderRolling:new{ + self:registerModule("rolling", ReaderRolling:new{ dialog = self.dialog, - view = self[1], + view = self.view, ui = self }) end - -- configuable controller - if self.document.info.configurable then - if self.document.info.has_pages then - -- kopt option controller - table.insert(self, ReaderKoptListener:new{ - dialog = self.dialog, - view = self[1], - ui = self, - document = self.document, - }) - end - -- activity indicator - table.insert(self, ReaderActivityIndicator:new{ - dialog = self.dialog, - view = self[1], - ui = self, - document = self.document, - }) - end -- koreader plugins for _,module in ipairs(PluginLoader:loadPlugins()) do - DEBUG("Loaded plugin", module.path) - table.insert(self, module:new{ + DEBUG("Loaded plugin", module.name, "at", module.path) + self:registerModule(module.name, module:new{ dialog = self.dialog, - view = self[1], + view = self.view, ui = self, document = self.document, }) diff --git a/plugins/calibrecompanion.koplugin/main.lua b/plugins/calibrecompanion.koplugin/main.lua index 440c079e8..65eb8d7e4 100644 --- a/plugins/calibrecompanion.koplugin/main.lua +++ b/plugins/calibrecompanion.koplugin/main.lua @@ -22,6 +22,7 @@ local dummy = require("ffi/zeromq_h") More details can be found at calibre/devices/smart_device_app/driver.py. --]] local CalibreCompanion = InputContainer:new{ + name = "calibrecompanion", -- calibre companion local port port = 8134, -- calibre broadcast ports used to find calibre server diff --git a/plugins/evernote.koplugin/main.lua b/plugins/evernote.koplugin/main.lua index 344d53cd5..ed95e2bf1 100644 --- a/plugins/evernote.koplugin/main.lua +++ b/plugins/evernote.koplugin/main.lua @@ -13,6 +13,7 @@ local slt2 = require('slt2') local MyClipping = require("clip") local EvernoteExporter = InputContainer:new{ + name = "evernote", login_title = _("Login to Evernote"), notebook_name = _("Koreader Notes"), evernote_domain = nil, diff --git a/plugins/zsync.koplugin/main.lua b/plugins/zsync.koplugin/main.lua index f815b1456..dd2597e30 100644 --- a/plugins/zsync.koplugin/main.lua +++ b/plugins/zsync.koplugin/main.lua @@ -28,6 +28,7 @@ int rmdir(const char *); local dummy = require("ffi/zeromq_h") local ZSync = InputContainer:new{ + name = "zsync", } function ZSync:init()