diff --git a/base b/base index 959f8c216..3260f0494 160000 --- a/base +++ b/base @@ -1 +1 @@ -Subproject commit 959f8c2160abee41b846158b2b06820617427b38 +Subproject commit 3260f0494f7558f234806e68adb92606af391f8f diff --git a/frontend/apps/reader/modules/readerdictionary.lua b/frontend/apps/reader/modules/readerdictionary.lua index e1ee8d2f7..398df95e5 100644 --- a/frontend/apps/reader/modules/readerdictionary.lua +++ b/frontend/apps/reader/modules/readerdictionary.lua @@ -32,21 +32,24 @@ function ReaderDictionary:onLookupWord(word, box, highlight) return true end -local function tidyCDATA(results) +local function tidy_markup(results) local cdata_tag = "" local format_escape = "&[29Ib%+]{(.-)}" for _, result in ipairs(results) do + local def = result.definition + -- preserve the
tag for line break + def = def:gsub("<[bB][rR] ?/?>", "\n") -- parse CDATA text in XML - if result.definition:find(cdata_tag) then - local def = result.definition:gsub(cdata_tag, "%1") - -- ignore all tags - def = def:gsub("%b<>", "") + if def:find(cdata_tag) then + def = def:gsub(cdata_tag, "%1") -- ignore format strings while def:find(format_escape) do def = def:gsub(format_escape, "%1") end - result.definition = def end + -- ignore all markup tags + def = def:gsub("%b<>", "") + result.definition = def end return results end @@ -66,7 +69,7 @@ function ReaderDictionary:stardictLookup(word, box) local ok, results = pcall(JSON.decode, JSON, results_str) if ok and results then DEBUG("lookup result table:", word, results) - self:showDict(word, tidyCDATA(results), box) + self:showDict(word, tidy_markup(results), box) else -- dummy results results = { diff --git a/frontend/apps/reader/modules/readermenu.lua b/frontend/apps/reader/modules/readermenu.lua index 8c79c3c90..da688f5bf 100644 --- a/frontend/apps/reader/modules/readermenu.lua +++ b/frontend/apps/reader/modules/readermenu.lua @@ -46,7 +46,6 @@ function ReaderMenu:init() local FileManager = require("apps/filemanager/filemanager") FileManager:restoreScreenMode() if not FileManager.is_running then - UIManager:quit() FileManager:showFiles() end end, @@ -91,8 +90,6 @@ function ReaderMenu:setUpdateItemTable() end -- setting tab - -- FIXME: it's curious that if this 'Screen' menu is placed after the Language - -- menu submenu in 'Screen' won't be shown. Probably a bug in the touchmenu module. table.insert(self.tab_item_table.setting, { text = _("Screen settings"), sub_item_table = { @@ -143,27 +140,33 @@ function ReaderMenu:setUpdateItemTable() end }) - --typeset tab if KOBO_SCREEN_SAVER_LAST_BOOK then - local exclude = self.ui.doc_settings:readSetting("exclude_screensaver") or false + local excluded = function() + return self.ui.doc_settings:readSetting("exclude_screensaver") or false + end + local proportional = function() + return self.ui.doc_settings:readSetting("proportional_screensaver") or false + end table.insert(self.tab_item_table.typeset, { - text = _("Use this book's cover as screensaver"), - checked_func = function() return not (self.ui.doc_settings:readSetting("exclude_screensaver") or false) end, - callback = function() - local exclude = self.ui.doc_settings:readSetting("exclude_screensaver") or false - self.ui.doc_settings:saveSetting("exclude_screensaver", not exclude) - self.ui:saveSettings() - end - }) - local proportional = self.ui.doc_settings:readSetting("proportional_screensaver") or false - table.insert(self.tab_item_table.typeset, { - text = _("Display proportional cover image in screensaver"), - checked_func = function() return (self.ui.doc_settings:readSetting("proportional_screensaver") or false) end, - callback = function() - local proportional = self.ui.doc_settings:readSetting("proportional_screensaver") or false - self.ui.doc_settings:saveSetting("proportional_screensaver", not proportional) - self.ui:saveSettings() - end + text = "Screensaver", + sub_item_table = { + { + text = _("Use this book's cover as screensaver"), + checked_func = function() return not excluded() end, + callback = function() + self.ui.doc_settings:saveSetting("exclude_screensaver", not excluded()) + self.ui:saveSettings() + end + }, + { + text = _("Display proportional cover image in screensaver"), + checked_func = function() return proportional() end, + callback = function() + self.ui.doc_settings:saveSetting("proportional_screensaver", not proportional()) + self.ui:saveSettings() + end + } + } }) end end diff --git a/frontend/cache.lua b/frontend/cache.lua index a7306a619..a2455148e 100644 --- a/frontend/cache.lua +++ b/frontend/cache.lua @@ -136,8 +136,11 @@ function Cache:serialize() -- serialize the most recently used cache local cache_size = 0 for _, key in ipairs(self.cache_order) do - if self.cache[key].dump then - cache_size = self.cache[key]:dump(cache_path..md5(key)) or 0 + local cache_item = self.cache[key] + -- only dump cache item that requests serialization explicitly + if cache_item.persistent and cache_item.dump then + DEBUG("dump cache item", key) + cache_size = cache_item:dump(cache_path..md5(key)) or 0 if cache_size > 0 then break end end end diff --git a/frontend/document/document.lua b/frontend/document/document.lua index 535e09893..f274b6dda 100644 --- a/frontend/document/document.lua +++ b/frontend/document/document.lua @@ -1,11 +1,12 @@ -local DrawContext = require("ffi/drawcontext") -local Blitbuffer = require("ffi/blitbuffer") -local Cache = require("cache") -local CacheItem = require("cacheitem") local TileCacheItem = require("document/tilecacheitem") -local Geom = require("ui/geometry") +local DrawContext = require("ffi/drawcontext") local Configurable = require("configurable") +local Blitbuffer = require("ffi/blitbuffer") +local lfs = require("libs/libkoreader-lfs") +local CacheItem = require("cacheitem") +local Geom = require("ui/geometry") local Math = require("optmath") +local Cache = require("cache") local DEBUG = require("dbg") --[[ @@ -114,6 +115,7 @@ function Document:getNativePageDimensions(pageno) end function Document:_readMetadata() + self.mod_time = lfs.attributes(self.file, "modification") self.info.number_of_pages = self._document:getPages() return true end @@ -215,8 +217,13 @@ function Document:getCoverPageImage() return nil end +function Document:getFullPageHash(pageno, zoom, rotation, gamma, render_mode) + return "renderpg|"..self.file.."|"..self.mod_time.."|"..pageno.."|" + ..zoom.."|"..rotation.."|"..gamma.."|"..render_mode +end + function Document:renderPage(pageno, rect, zoom, rotation, gamma, render_mode) - local hash = "renderpg|"..self.file.."|"..pageno.."|"..zoom.."|"..rotation.."|"..gamma.."|"..render_mode + local hash = self:getFullPageHash(pageno, zoom, rotation, gamma, render_mode) local page_size = self:getPageDimensions(pageno, zoom, rotation) -- this will be the size we actually render local size = page_size @@ -231,12 +238,13 @@ function Document:renderPage(pageno, rect, zoom, rotation, gamma, render_mode) return end -- only render required part - hash = "renderpg|"..self.file.."|"..pageno.."|"..zoom.."|"..rotation.."|"..gamma.."|"..render_mode.."|"..tostring(rect) + hash = self:getFullPageHash(pageno, zoom, rotation, gamma, render_mode).."|"..tostring(rect) size = rect end -- prepare cache item with contained blitbuffer local tile = TileCacheItem:new{ + persistent = true, size = size.w * size.h + 64, -- estimation excerpt = size, pageno = pageno, @@ -274,7 +282,7 @@ end -- a hint for the cache engine to paint a full page to the cache -- TODO: this should trigger a background operation function Document:hintPage(pageno, zoom, rotation, gamma, render_mode) - local hash_full_page = "renderpg|"..self.file.."|"..pageno.."|"..zoom.."|"..rotation.."|"..gamma.."|"..render_mode + local hash_full_page = self:getFullPageHash(pageno, zoom, rotation, gamma, render_mode) if not Cache:check(hash_full_page, TileCacheItem) then DEBUG("hinting page", pageno) self:renderPage(pageno, nil, zoom, rotation, gamma, render_mode) @@ -290,7 +298,7 @@ Draw page content to blitbuffer. @rect: visible_area inside document page --]] function Document:drawPage(target, x, y, rect, pageno, zoom, rotation, gamma, render_mode) - local hash_full_page = "renderpg|"..self.file.."|"..pageno.."|"..zoom.."|"..rotation.."|"..gamma.."|"..render_mode + local hash_full_page = self:getFullPageHash(pageno, zoom, rotation, gamma, render_mode) local hash_excerpt = hash_full_page.."|"..tostring(rect) local tile = Cache:check(hash_full_page, TileCacheItem) if not tile then diff --git a/frontend/document/koptinterface.lua b/frontend/document/koptinterface.lua index 2193f5e29..368a78e37 100644 --- a/frontend/document/koptinterface.lua +++ b/frontend/document/koptinterface.lua @@ -107,7 +107,8 @@ function KoptInterface:getContextHash(doc, pageno, bbox) local screen_size = Screen:getSize() local screen_size_hash = screen_size.w.."|"..screen_size.h local bbox_hash = bbox.x0.."|"..bbox.y0.."|"..bbox.x1.."|"..bbox.y1 - return doc.file.."|"..pageno.."|"..doc.configurable:hash("|").."|"..bbox_hash.."|"..screen_size_hash + return doc.file.."|"..doc.mod_time.."|"..pageno.."|" + ..doc.configurable:hash("|").."|"..bbox_hash.."|"..screen_size_hash end function KoptInterface:getPageBBox(doc, pageno) @@ -215,6 +216,7 @@ function KoptInterface:getCachedContext(doc, pageno) DEBUG("reflowed page", pageno, "fullwidth:", fullwidth, "fullheight:", fullheight) self.last_context_size = fullwidth * fullheight + 128 -- estimation Cache:insert(kctx_hash, ContextCacheItem:new{ + persistent = true, size = self.last_context_size, kctx = kc }) @@ -289,7 +291,7 @@ function KoptInterface:renderReflowedPage(doc, pageno, rect, zoom, rotation, ren end -- prepare cache item with contained blitbuffer local tile = TileCacheItem:new{ - size = fullwidth * fullheight / 2 + 64, -- estimation + size = fullwidth * fullheight + 64, -- estimation excerpt = Geom:new{ w = fullwidth, h = fullheight }, pageno = pageno, } @@ -311,7 +313,7 @@ function KoptInterface:renderOptimizedPage(doc, pageno, rect, zoom, rotation, re local context_hash = self:getContextHash(doc, pageno, bbox) local renderpg_hash = "renderoptpg|"..context_hash..zoom - local cached = Cache:check(renderpg_hash) + local cached = Cache:check(renderpg_hash, TileCacheItem) if not cached then local page_size = Document.getNativePageDimensions(doc, pageno) local bbox = { @@ -329,7 +331,8 @@ function KoptInterface:renderOptimizedPage(doc, pageno, rect, zoom, rotation, re local fullwidth, fullheight = kc:getPageDim() -- prepare cache item with contained blitbuffer local tile = TileCacheItem:new{ - size = fullwidth * fullheight / 2 + 64, -- estimation + persistent = true, + size = fullwidth * fullheight + 64, -- estimation excerpt = Geom:new{ x = 0, y = 0, w = fullwidth, diff --git a/frontend/ui/uimanager.lua b/frontend/ui/uimanager.lua index de9beb7d8..72a5d234a 100644 --- a/frontend/ui/uimanager.lua +++ b/frontend/ui/uimanager.lua @@ -132,10 +132,20 @@ function UIManager:init() end -- register & show a widget +-- modal widget should be always on the top function UIManager:show(widget, x, y) + DEBUG("show widget", widget.id) self._running = true - -- put widget on top of stack - table.insert(self._window_stack, {x = x or 0, y = y or 0, widget = widget}) + local window = {x = x or 0, y = y or 0, widget = widget} + -- put this window on top of the toppest non-modal window + for i = #self._window_stack, 0, -1 do + local top_window = self._window_stack[i] + -- skip modal window + if not top_window or not top_window.widget.modal then + table.insert(self._window_stack, i + 1, window) + break + end + end -- and schedule it to be painted self:setDirty(widget) -- tell the widget that it is shown now @@ -148,6 +158,7 @@ end -- unregister a widget function UIManager:close(widget) + DEBUG("close widget", widget.id) Input.disable_double_tap = DGESDETECT_DISABLE_DOUBLE_TAP local dirty = false for i = #self._window_stack, 1, -1 do @@ -226,6 +237,7 @@ end -- signal to quit function UIManager:quit() + DEBUG("quit uimanager") self._running = false for i = #self._window_stack, 1, -1 do table.remove(self._window_stack, i) diff --git a/frontend/ui/widget/confirmbox.lua b/frontend/ui/widget/confirmbox.lua index f21240d9b..fd7a02427 100644 --- a/frontend/ui/widget/confirmbox.lua +++ b/frontend/ui/widget/confirmbox.lua @@ -24,6 +24,7 @@ local Blitbuffer = require("ffi/blitbuffer") Widget that shows a message and OK/Cancel buttons ]] local ConfirmBox = InputContainer:new{ + modal = true, text = _("no text"), face = Font:getFace("infofont", 25), ok_text = _("OK"), diff --git a/frontend/ui/widget/infomessage.lua b/frontend/ui/widget/infomessage.lua index cc006c586..adb8f4731 100644 --- a/frontend/ui/widget/infomessage.lua +++ b/frontend/ui/widget/infomessage.lua @@ -21,6 +21,7 @@ Widget that displays an informational message it vanishes on key press or after a given timeout ]] local InfoMessage = InputContainer:new{ + modal = true, face = Font:getFace("infofont", 25), text = "", timeout = nil, -- in seconds diff --git a/frontend/ui/widget/touchmenu.lua b/frontend/ui/widget/touchmenu.lua index b0ea0883b..080dcec8b 100644 --- a/frontend/ui/widget/touchmenu.lua +++ b/frontend/ui/widget/touchmenu.lua @@ -103,6 +103,7 @@ function TouchMenuItem:onTapSelect(arg, ges) UIManager:setDirty(self.show_parent, "partial") end) self.menu:onMenuSelect(self.item) + return true end function TouchMenuItem:onHoldSelect(arg, ges) @@ -119,6 +120,7 @@ function TouchMenuItem:onHoldSelect(arg, ges) UIManager:setDirty(self.show_parent, "partial") end) self.menu:onMenuHold(self.item) + return true end --[[ @@ -331,11 +333,11 @@ function TouchMenu:init() self.device_info = HorizontalGroup:new{ self.time_info, self.net_info, - } - else + } + else self.device_info = HorizontalGroup:new{ self.time_info, - } + } end local footer_width = self.width - self.padding*2 - self.bordersize*2 self.footer = HorizontalGroup:new{