From 73f7d860cdee63fec75bb8b3b8a7c8d6f5ff8a62 Mon Sep 17 00:00:00 2001 From: frankyifei Date: Wed, 20 Apr 2016 01:16:27 +0930 Subject: [PATCH 01/35] imagewidget fix bring back the old behavior: when width and height are set and all the zooming options are false, zoom the image to that size. The last commit to Imagewidget.lua caused it ignores the set width and height and use the image's original size instead when no zoom option is set. This caused #1979. Although #1979 can be fixed by setting autostretch=true, but I think it's good to fix here. --- frontend/ui/widget/imagewidget.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/ui/widget/imagewidget.lua b/frontend/ui/widget/imagewidget.lua index d17511d46..9ed5540dd 100644 --- a/frontend/ui/widget/imagewidget.lua +++ b/frontend/ui/widget/imagewidget.lua @@ -87,7 +87,7 @@ function ImageWidget:_render() error("cannot render image") end local native_w, native_h = self._bb:getWidth(), self._bb:getHeight() - local w, h + local w, h = self.width, self.height if self.autoscale then local dpi_scale = Screen:getDPI() / 167 -- rounding off to power of 2 to avoid alias with pow(2, floor(log(x)/log(2)) From f33f78cf089608d63cd84d9a4b8be89bc58407cf Mon Sep 17 00:00:00 2001 From: Zijie He Date: Tue, 19 Apr 2016 15:48:35 -0700 Subject: [PATCH 02/35] Add an ignore_power_sleepcover setting to ignore Kobo power_sleepcover keycode --- frontend/device/kobo/device.lua | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/frontend/device/kobo/device.lua b/frontend/device/kobo/device.lua index bf8f5b580..18c598bd6 100644 --- a/frontend/device/kobo/device.lua +++ b/frontend/device/kobo/device.lua @@ -86,13 +86,16 @@ function Kobo:init() self.input = require("device/input"):new{ device = self, event_map = { - [59] = "Power_SleepCover", [90] = "Light", [102] = "Home", [116] = "Power", } } + if not G_reader_settings:readSetting("ignore_power_sleepcover") then + self.input.event_map[59] = "Power_SleepCover" + end + Generic.init(self) self.input.open("/dev/input/event0") -- Light button and sleep slider From 667e8834ad686d4e9dd394951a5d4cfe97f09d15 Mon Sep 17 00:00:00 2001 From: Zijie He Date: Mon, 18 Apr 2016 15:38:14 -0700 Subject: [PATCH 03/35] Migrate history folder, FileManagerHistory uses own history.lua file and ReadHistory component --- .../apps/filemanager/filemanagerhistory.lua | 31 +---- frontend/apps/reader/readerui.lua | 1 + frontend/docsettings.lua | 35 +++--- frontend/readhistory.lua | 112 ++++++++++++++++++ 4 files changed, 133 insertions(+), 46 deletions(-) create mode 100644 frontend/readhistory.lua diff --git a/frontend/apps/filemanager/filemanagerhistory.lua b/frontend/apps/filemanager/filemanagerhistory.lua index 7dfe9c076..5ab81ef5b 100644 --- a/frontend/apps/filemanager/filemanagerhistory.lua +++ b/frontend/apps/filemanager/filemanagerhistory.lua @@ -1,17 +1,11 @@ local InputContainer = require("ui/widget/container/inputcontainer") local CenterContainer = require("ui/widget/container/centercontainer") local ButtonDialog = require("ui/widget/buttondialog") -local lfs = require("libs/libkoreader-lfs") -local DataStorage = require("datastorage") local UIManager = require("ui/uimanager") -local DocSettings = require("docsettings") local Menu = require("ui/widget/menu") -local joinPath = require("ffi/util").joinPath local Screen = require("device").screen local _ = require("gettext") -local history_dir = DataStorage:getHistoryDir() - local FileManagerHistory = InputContainer:extend{ hist_menu_title = _("History"), } @@ -31,27 +25,8 @@ function FileManagerHistory:addToMainMenu(tab_item_table) end function FileManagerHistory:updateItemTable() - local ReaderUI = require("apps/reader/readerui") - self.hist = {} - - for f in lfs.dir(history_dir) do - local path = joinPath(history_dir, f) - if lfs.attributes(path, "mode") == "file" then - local name = DocSettings:getNameFromHistory(f) - table.insert(self.hist, { - date = lfs.attributes(path, "modification"), - text = name, - histfile = f, - callback = function() - ReaderUI:showReader( - DocSettings:getPathFromHistory(f).. "/" .. name) - end - }) - end - end - table.sort(self.hist, function(v1, v2) return v1.date > v2.date end) - - self.hist_menu:swithItemTable(self.hist_menu_title, self.hist) + self.hist_menu:swithItemTable(self.hist_menu_title, + require("readhistory").hist) end function FileManagerHistory:onSetDimensions(dimen) @@ -65,7 +40,7 @@ function FileManagerHistory:onMenuHold(item) { text = _("Remove this item from history"), callback = function() - os.remove(joinPath(history_dir, item.histfile)) + require("readhistory"):removeItem(item) self._manager:updateItemTable() UIManager:close(self.histfile_dialog) end, diff --git a/frontend/apps/reader/readerui.lua b/frontend/apps/reader/readerui.lua index 1ddeaee52..d3e1f3612 100644 --- a/frontend/apps/reader/readerui.lua +++ b/frontend/apps/reader/readerui.lua @@ -329,6 +329,7 @@ end function ReaderUI:showReader(file) DEBUG("show reader ui") + require("readhistory"):addItem(file) if lfs.attributes(file, "mode") ~= "file" then UIManager:show(InfoMessage:new{ text = T( _("File '%1' does not exist."), file) diff --git a/frontend/docsettings.lua b/frontend/docsettings.lua index da67aa158..9032078c4 100644 --- a/frontend/docsettings.lua +++ b/frontend/docsettings.lua @@ -36,38 +36,37 @@ function DocSettings:purgeDocSettings(doc_path) end function DocSettings:open(docfile) - local history_path - local sidecar_path + -- TODO(zijiehe): Remove history_path, use only sidecar. + local new = { data = {} } + local ok, stored if docfile == ".reader" then -- we handle reader setting as special case - history_path = DataStorage:getDataDir() .. "/settings.reader.lua" + new.history_file = DataStorage:getDataDir() .. "/settings.reader.lua" + + ok, stored = pcall(dofile, new.history_file) else - history_path = self:getHistoryPath(docfile) + new.history_file = self:getHistoryPath(docfile) local sidecar = self:getSidecarDir(docfile) if lfs.attributes(sidecar, "mode") ~= "directory" then lfs.mkdir(sidecar) end - sidecar_path = sidecar.."/"..docfile:match(".*%/(.*)")..".lua" - end - -- construct settings obj - local new = { - history_file = history_path, - sidecar_file = sidecar_path, - data = {} - } - local ok, stored = pcall(dofile, new.sidecar_file or "") - if not ok then - ok, stored = pcall(dofile, new.history_file or "") + new.sidecar_file = sidecar.."/"..docfile:match(".*%/(.*)")..".lua" + + ok, stored = pcall(dofile, new.sidecar_file or "") if not ok then - -- try legacy conf path, for backward compatibility. this also - -- takes care of reader legacy setting - ok, stored = pcall(dofile, docfile..".kpdfview.lua") + ok, stored = pcall(dofile, new.history_file or "") + if not ok then + -- try legacy conf path, for backward compatibility. this also + -- takes care of reader legacy setting + ok, stored = pcall(dofile, docfile..".kpdfview.lua") + end end end if ok and stored then new.data = stored end + return setmetatable(new, { __index = DocSettings}) end diff --git a/frontend/readhistory.lua b/frontend/readhistory.lua new file mode 100644 index 000000000..dd5eb4791 --- /dev/null +++ b/frontend/readhistory.lua @@ -0,0 +1,112 @@ +local lfs = require("libs/libkoreader-lfs") +local DataStorage = require("datastorage") +local DocSettings = require("docsettings") +local joinPath = require("ffi/util").joinPath +local dump = require("dump") + +local history_file = joinPath(DataStorage:getDataDir(), "history.lua") + +local ReadHistory = { + hist = {}, +} + +local function buildEntry(input_time, input_file) + return { + time = input_time, + text = input_file:gsub(".*/", ""), + file = input_file, + callback = function() + local ReaderUI = require("apps/reader/readerui") + ReaderUI:showReader(input_file) + end + } +end + +function ReadHistory:_sort() + table.sort(self.hist, function(l, r) return l.file < r.file end) + -- TODO(zijiehe): Use binary insert instead of a loop to deduplicate. + for i = #self.hist, 2, -1 do + if self.hist[i].file == self.hist[i - 1].file then + table.remove(self.hist, i) + end + end + table.sort(self.hist, function(v1, v2) return v1.time > v2.time end) + -- TODO(zijiehe): Use binary search to find an item when deleting it. + for i = 1, #self.hist, 1 do + self.hist[i].index = i + end +end + +-- Reduces total count in hist list to a reasonable number by removing last +-- several items. +function ReadHistory:_reduce() + while #self.hist > 500 do + table.remove(self.hist, #self.hist) + end +end + +-- Flushes current history table into file. +function ReadHistory:_flush() + local content = {} + for k, v in pairs(self.hist) do + content[k] = { + time = v.time, + file = v.file + } + end + local f = io.open(history_file, "w") + f:write("return " .. dump(content) .. "\n") + f:close() +end + +-- Reads history table from file +function ReadHistory:_read() + local ok, data = pcall(dofile, history_file) + if ok then + for k, v in pairs(data) do + table.insert(self.hist, buildEntry(v.time, v.file)) + end + end +end + +-- Reads history from legacy history folder +function ReadHistory:_readLegacyHistory() + local history_dir = DataStorage:getHistoryDir() + for f in lfs.dir(history_dir) do + local path = joinPath(history_dir, f) + if lfs.attributes(path, "mode") == "file" then + local file = joinPath(DocSettings:getPathFromHistory(f), + DocSettings:getNameFromHistory(f)) + table.insert(self.hist, + buildEntry(lfs.attributes(path, "modification"), file)) + end + end +end + +function ReadHistory:_init() + self:_read() + self:_readLegacyHistory() + self:_sort() + self:_reduce() +end + +function ReadHistory:removeItem(item) + table.remove(self.hist, item.index) + os.remove(DocSettings:getHistoryPath(item.file)) + self:_flush() +end + +function ReadHistory:addItem(file) + if file ~= nil and lfs.attributes(file, "mode") == "file" then + table.insert(self.hist, 1, buildEntry(os.time(), file)) + -- TODO(zijiehe): We do not need to sort if we can use binary insert and + -- binary search. + self:_sort() + self:_reduce() + self:_flush() + end +end + +ReadHistory:_init() + +return ReadHistory From 26ecc6035a029e3338ea05ce49794b0a0457267a Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Wed, 20 Apr 2016 20:48:50 -0700 Subject: [PATCH 04/35] bookstatus: cache total pages --- frontend/ui/widget/bookstatuswidget.lua | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/frontend/ui/widget/bookstatuswidget.lua b/frontend/ui/widget/bookstatuswidget.lua index a727143f9..9ad75146f 100644 --- a/frontend/ui/widget/bookstatuswidget.lua +++ b/frontend/ui/widget/bookstatuswidget.lua @@ -57,7 +57,7 @@ function BookStatusWidget:init() self.stats = { total_time_in_sec = 0, performance_in_pages = {}, - pages = self.document:getPageCount(), + total_pages = self.document:getPageCount(), } self:getStatisticsSettings() if self.settings then @@ -123,8 +123,8 @@ function BookStatusWidget:getStatHours(stats) end function BookStatusWidget:getReadPages(stats) - if stats and stats.performance_in_pages and stats.pages then - return util.tableSize(stats.performance_in_pages) .. "/" .. stats.pages + if stats and stats.performance_in_pages and stats.total_pages then + return util.tableSize(stats.performance_in_pages) .. "/" .. stats.total_pages end return "none" end @@ -253,12 +253,14 @@ function BookStatusWidget:genBookInfoGroup() } ) -- progress bar - local total_pages = self.document:getPageCount() + local total_pages = self.stats.total_pages local read_percentage = self.view.state.page / total_pages local progress_bar = ProgressWidget:new{ width = width * 0.7, height = Screen:scaleBySize(10), percentage = read_percentage, + ticks = nil, + last = nil, } table.insert(book_meta_info_group, CenterContainer:new{ From 572412b1f6686117352020c0eac75e85f2c7604f Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Wed, 20 Apr 2016 21:41:34 -0700 Subject: [PATCH 05/35] readerrolling(fix): detect end of book properly --- .../apps/reader/modules/readerrolling.lua | 16 +++---- spec/unit/readerrolling_spec.lua | 44 ++++++++++++++++++- 2 files changed, 50 insertions(+), 10 deletions(-) diff --git a/frontend/apps/reader/modules/readerrolling.lua b/frontend/apps/reader/modules/readerrolling.lua index b4a08c0c1..271f1624e 100644 --- a/frontend/apps/reader/modules/readerrolling.lua +++ b/frontend/apps/reader/modules/readerrolling.lua @@ -357,11 +357,6 @@ end function ReaderRolling:onGotoViewRel(diff) DEBUG("goto relative screen:", diff, ", in mode: ", self.view.view_mode) - local prev_xp - -- save xpointer to check whether we reach the end of the book - if diff > 0 then - prev_xp = self.xpointer - end if self.view.view_mode == "scroll" then local pan_diff = diff * self.ui.dimen.h if self.show_overlap_enable then @@ -371,15 +366,20 @@ function ReaderRolling:onGotoViewRel(diff) pan_diff = pan_diff + self.overlap end end + local old_pos = self.current_pos self:_gotoPos(self.current_pos + pan_diff) + if diff > 0 and old_pos == self.current_pos then + self.ui:handleEvent(Event:new("EndOfBook")) + end elseif self.view.view_mode == "page" then local page_count = self.ui.document:getVisiblePageCount() + local old_page = self.current_page self:_gotoPage(self.current_page + diff*page_count) + if diff > 0 and old_page == self.current_page then + self.ui:handleEvent(Event:new("EndOfBook")) + end end self.xpointer = self.ui.document:getXPointer() - if self.xpointer == prev_xp then - self.ui:handleEvent(Event:new("EndOfBook")) - end return true end diff --git a/spec/unit/readerrolling_spec.lua b/spec/unit/readerrolling_spec.lua index d9d2a444a..5d95bb623 100644 --- a/spec/unit/readerrolling_spec.lua +++ b/spec/unit/readerrolling_spec.lua @@ -51,18 +51,57 @@ describe("Readerrolling module", function() assert.are.same(toc:getPreviousChapter(i, 0), rolling.current_page) end end) - it("should emit EndOfBook event at the end", function() - rolling:onGotoPage(readerui.document:getPageCount()) + it("should emit EndOfBook event at the end of sample epub", function() local called = false readerui.onEndOfBook = function() called = true end + -- check beginning of the book + rolling:onGotoPage(1) + assert.is.falsy(called) + rolling:onGotoViewRel(-1) + rolling:onGotoViewRel(-1) + assert.is.falsy(called) + -- check end of the book + rolling:onGotoPage(readerui.document:getPageCount()) + assert.is.falsy(called) rolling:onGotoViewRel(1) + assert.is.truthy(called) rolling:onGotoViewRel(1) assert.is.truthy(called) readerui.onEndOfBook = nil end) + + it("should emit EndOfBook event at the end sample txt", function() + local sample_txt = "spec/front/unit/data/sample.txt" + local txt_readerui = ReaderUI:new{ + document = DocumentRegistry:openDocument(sample_txt), + } + local called = false + txt_readerui.onEndOfBook = function() + called = true + end + local txt_rolling = txt_readerui.rolling + -- check beginning of the book + txt_rolling:onGotoPage(1) + assert.is.falsy(called) + txt_rolling:onGotoViewRel(-1) + txt_rolling:onGotoViewRel(-1) + assert.is.falsy(called) + -- not at the end of the book + txt_rolling:onGotoPage(3) + assert.is.falsy(called) + txt_rolling:onGotoViewRel(1) + assert.is.falsy(called) + -- at the end of the book + txt_rolling:onGotoPage(txt_readerui.document:getPageCount()) + assert.is.falsy(called) + txt_rolling:onGotoViewRel(1) + assert.is.truthy(called) + readerui.onEndOfBook = nil + end) end) + describe("test in landscape screen mode", function() it("should go to landscape screen mode", function() readerui:handleEvent(Event:new("ChangeScreenMode", "landscape")) @@ -110,6 +149,7 @@ describe("Readerrolling module", function() readerui.onEndOfBook = nil end) end) + describe("switching screen mode should not change current page number", function() it("for portrait-landscape-portrait switching", function() for i = 80, 100, 10 do From 0226efc4cd3041113e69563ac9cf93d7e8e00a4e Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Wed, 20 Apr 2016 21:49:33 -0700 Subject: [PATCH 06/35] readerfooter(minor): just incase self.pages is nil --- base | 2 +- frontend/apps/reader/modules/readerfooter.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/base b/base index b5c82144e..02c4e24e7 160000 --- a/base +++ b/base @@ -1 +1 @@ -Subproject commit b5c82144e253844849ab66e55bdff363d4991c66 +Subproject commit 02c4e24e732f4d7009b71c763dbaa503c40365a1 diff --git a/frontend/apps/reader/modules/readerfooter.lua b/frontend/apps/reader/modules/readerfooter.lua index 9333b1df3..ff9717d42 100644 --- a/frontend/apps/reader/modules/readerfooter.lua +++ b/frontend/apps/reader/modules/readerfooter.lua @@ -295,7 +295,7 @@ function ReaderFooter:updateFooterText() if #ticks_candidates > 0 then self.progress_bar.ticks = ticks_candidates[1] - self.progress_bar.last = self.pages + self.progress_bar.last = self.pages or self.view.document:getPageCount() else -- we still set ticks here so self.progress_bar.ticks will not be -- initialized again if ticks_candidates is empty From 984c9941929ac27740eb1b2069d09cde7ac6ca45 Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Wed, 20 Apr 2016 23:06:32 -0700 Subject: [PATCH 07/35] test(fix): add missing sample txt file --- test/sample.txt | 94 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 test/sample.txt diff --git a/test/sample.txt b/test/sample.txt new file mode 100644 index 000000000..15d7805fe --- /dev/null +++ b/test/sample.txt @@ -0,0 +1,94 @@ + Lorem ipsum + Dolor sit amet, foo@bar.com + v0.1, 99 September 7999 + + Lorem ipsum dolor sit amet, pri id laudem vulputate disputando, ad mea + pericula consetetur. Nusquam detraxit ad sed, tritani mandamus aliquando et + has, porro graeco at pri. Sale denique ut sit, mel suas erroribus repudiare + ea. Vim probo dicit consequuntur te. + ______________________________________________________________________ + + Table of Contents + + + 1. Eos ex eius iusto delicata + + 2. Illum argumentum sed a + + 3. In eum magna iusto integre + + + + ______________________________________________________________________ + + 1. Eos ex eius iusto delicata + + + Eos ex eius iusto delicata, ius ne facer invenire electram, cu mel assum + novum efficiendi. Duo enim eleifend te. Elitr nihil vivendo vix ex, ex homero + salutatus sed, ea nec posse commune consetetur. Ea iusto labore docendi his, + at per mollis mentitum. Ex esse recteque eos, ex iudicabit gloriatur mei. + + Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue: + + 1. Maecenas nec odio et ante tincidunt tempus. + + 2. Donec sodales sagittis magna. + + 3. Phasellus viverra nulla ut metus varius laoreet. + + Li Europan lingues es membres del sam familie. Lor separat existentie es un + myth. + + It va esser tam simplic quam Occidental in fact, it va esser Occidental. A un + Angleso it va semblar un simplificat Angles, quam un skeptic Cambridge amico + dit me que Occidental es.Li Europan lingues es membres del sam familie. Lor + separat existentie es un myth. Por scientie, musica, sport etc, litot Europa + usa li sam vocabular. Li lingues differe solmen in li grammatica, li + pronunciation e li plu commun vocabules. Omnicos directe al desirabilite de + un nov lingua franca: On refusa continuar payar custosi traductores. At + solmen va esser necessi far uniform grammatica, pronunciation e plu sommun + paroles. + + + 2. Illum argumentum sed a + + Illum argumentum sed ad, vel accumsan noluisse eu. Nam ne minimum consulatu, + vim nullam quidam ut. Ea pro temporibus ullamcorper, at case aeque vix. Est + id consetetur intellegam. Eu cum oratio gubergren, aeque tritani feugiat vel + te. + + · Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium + doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore + veritatis et quasi architecto beatae vitae dicta sunt explicabo. + + · Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam + nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas + nulla pariatur? + + cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod + maxime placeat facere. + + To install the tar.gz source, use the commands: + + ______________________________________________________________________ + ./configure + make + make install + ______________________________________________________________________ + + + Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed + quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. + Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, + adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore + et dolore magnam aliquam quaerat voluptatem. + + + 3. In eum magna iusto integre + + In eum magna iusto integre, cu solet commodo constituto pro. Te nec tota + altera, diam periculis ius eu, eum te velit partiendo conclusionemque. Diam + mnesarchum at usu, agam nonumes at nec. Vix aliquip liberavisse ex, nam at + quis choro accusam. Eu his zril graecis, latine legendos inimicus eum at, qui + te adolescens adipiscing. From d7b1b403c13bd35919a3dd45a6806e6316443aa3 Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Wed, 20 Apr 2016 23:16:40 -0700 Subject: [PATCH 08/35] progresswidget(fix): ignore nil self.last --- frontend/ui/widget/progresswidget.lua | 4 ++-- spec/unit/readerrolling_spec.lua | 5 +++++ spec/unit/widget_menu_spec.lua | 11 +++++++---- spec/unit/widget_progresswidget_spec.lua | 18 ++++++++++++++++++ 4 files changed, 32 insertions(+), 6 deletions(-) create mode 100644 spec/unit/widget_progresswidget_spec.lua diff --git a/frontend/ui/widget/progresswidget.lua b/frontend/ui/widget/progresswidget.lua index 7500622f1..ba347f869 100644 --- a/frontend/ui/widget/progresswidget.lua +++ b/frontend/ui/widget/progresswidget.lua @@ -14,7 +14,7 @@ Configurable attributes: * rectcolor -- infill color * ticks (list) -- default to nil, use this if you want to insert markers * tick_width - * last -- maximum tick + * last -- maximum tick, used with ticks Example: @@ -68,7 +68,7 @@ function ProgressWidget:paintTo(bb, x, y) bb:paintRect(x+self.margin_h, math.ceil(y+self.margin_v+self.bordersize), math.ceil((my_size.w-2*self.margin_h)*self.percentage), my_size.h-2*(self.margin_v+self.bordersize), self.rectcolor) - if self.ticks then + if self.ticks and self.last then for i=1, #self.ticks do bb:paintRect( x + (my_size.w-2*self.margin_h)*(self.ticks[i]/self.last), diff --git a/spec/unit/readerrolling_spec.lua b/spec/unit/readerrolling_spec.lua index 5d95bb623..9572997ce 100644 --- a/spec/unit/readerrolling_spec.lua +++ b/spec/unit/readerrolling_spec.lua @@ -20,12 +20,14 @@ describe("Readerrolling module", function() it("should goto portrait screen mode", function() readerui:handleEvent(Event:new("ChangeScreenMode", "portrait")) end) + it("should goto certain page", function() for i = 1, 10, 5 do rolling:onGotoPage(i) assert.are.same(i, rolling.current_page) end end) + it("should goto relative page", function() for i = 20, 40, 5 do rolling:onGotoPage(i) @@ -35,6 +37,7 @@ describe("Readerrolling module", function() assert.are.same(i, rolling.current_page) end end) + it("should goto next chapter", function() local toc = readerui.toc for i = 30, 50, 5 do @@ -43,6 +46,7 @@ describe("Readerrolling module", function() assert.are.same(toc:getNextChapter(i, 0), rolling.current_page) end end) + it("should goto previous chapter", function() local toc = readerui.toc for i = 60, 80, 5 do @@ -51,6 +55,7 @@ describe("Readerrolling module", function() assert.are.same(toc:getPreviousChapter(i, 0), rolling.current_page) end end) + it("should emit EndOfBook event at the end of sample epub", function() local called = false readerui.onEndOfBook = function() diff --git a/spec/unit/widget_menu_spec.lua b/spec/unit/widget_menu_spec.lua index 0ac1c7926..1fa9f2e38 100644 --- a/spec/unit/widget_menu_spec.lua +++ b/spec/unit/widget_menu_spec.lua @@ -1,8 +1,11 @@ -require("commonrequire") -local Menu = require("ui/widget/menu") -local DEBUG = require("dbg") - describe("Menu widget", function() + local Menu, dbg + setup(function() + require("commonrequire") + Menu = require("ui/widget/menu") + dbg = require("dbg") + end) + it("should convert item table from touch menu properly", function() local cb1 = function() end local cb2 = function() end diff --git a/spec/unit/widget_progresswidget_spec.lua b/spec/unit/widget_progresswidget_spec.lua new file mode 100644 index 000000000..f5085b657 --- /dev/null +++ b/spec/unit/widget_progresswidget_spec.lua @@ -0,0 +1,18 @@ +describe("ProgressWidget widget", function() + local ProgressWidget, Screen + setup(function() + require("commonrequire") + ProgressWidget = require("ui/widget/progresswidget") + Screen = require("device").screen + end) + + it("should not crash with nil self.last #ok", function() + local progress = ProgressWidget:new{ + width = 100, + height = 50, + percentage = 5/100, + ticks = {1}, + } + progress:paintTo(Screen.bb, 0, 0) + end) +end) From 31206cb80fdf4bfb0a7fe48de13605175c0fab39 Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Wed, 20 Apr 2016 23:56:38 -0700 Subject: [PATCH 09/35] ci: fix coverage report --- .ci/after_success.sh | 2 +- Makefile | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.ci/after_success.sh b/.ci/after_success.sh index e655228ba..011b8d1be 100755 --- a/.ci/after_success.sh +++ b/.ci/after_success.sh @@ -5,7 +5,7 @@ source "${CI_DIR}/common.sh" set +e -make coverage +travis_retry make coverage pushd koreader-*/koreader luajit $(which luacov-coveralls) -v popd diff --git a/Makefile b/Makefile index 0435dc7cc..e24910c12 100644 --- a/Makefile +++ b/Makefile @@ -107,7 +107,10 @@ test: $(MAKE) testfront coverage: $(INSTALL_DIR)/koreader/.luacov - cd $(INSTALL_DIR)/koreader && ./luajit $(shell which busted) -o verbose_print --coverage --exclude-tags=nocov + cd $(INSTALL_DIR)/koreader && \ + ./luajit $(shell which busted) -o verbose_print \ + --no-auto-insulate \ + --coverage --exclude-tags=nocov # coverage report summary cd $(INSTALL_DIR)/koreader && tail -n \ +$$(($$(grep -nm1 Summary luacov.report.out|cut -d: -f1)-1)) \ From 51327911f2fbea00258717d7b284e061ad31832e Mon Sep 17 00:00:00 2001 From: Hzj_jie Date: Thu, 21 Apr 2016 20:37:16 -0700 Subject: [PATCH 10/35] Won't track missing files in history, and always keep latest timestamp --- frontend/readhistory.lua | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/frontend/readhistory.lua b/frontend/readhistory.lua index dd5eb4791..e0c2c837e 100644 --- a/frontend/readhistory.lua +++ b/frontend/readhistory.lua @@ -23,11 +23,20 @@ local function buildEntry(input_time, input_file) end function ReadHistory:_sort() + for i = #self.hist, 1, -1 do + if lfs.attributes(self.hist[i].file, "mode") ~= "file" then + table.remove(self.hist, i) + end + end table.sort(self.hist, function(l, r) return l.file < r.file end) -- TODO(zijiehe): Use binary insert instead of a loop to deduplicate. for i = #self.hist, 2, -1 do if self.hist[i].file == self.hist[i - 1].file then - table.remove(self.hist, i) + if self.hist[i].time < self.hist[i - 1].time then + table.remove(self.hist, i) + else + table.remove(self.hist,i - 1) + end end end table.sort(self.hist, function(v1, v2) return v1.time > v2.time end) From df65d2972a45c0b9ed597f1aa76eab33078ebebe Mon Sep 17 00:00:00 2001 From: chrox Date: Fri, 15 Apr 2016 01:18:19 +0800 Subject: [PATCH 11/35] experimental port to Mac OSX Currently it can open cre-based docs and Djvu docs It still has some problems with PDF docs and the touch input. --- .editorconfig | 4 ++++ .gitignore | 1 + Makefile | 6 +++--- README.md | 14 ++++++++++---- base | 2 +- 5 files changed, 19 insertions(+), 8 deletions(-) diff --git a/.editorconfig b/.editorconfig index 904eab0e8..3db0a7dde 100644 --- a/.editorconfig +++ b/.editorconfig @@ -18,6 +18,10 @@ trim_trailing_whitespace = false indent_style = tab indent_size = 8 +[Makefile.def] +indent_style = tab +indent_size = 4 + [*.{js,css,scss,sass,html,handlebars,tpl}] indent_style = space indent_size = 2 diff --git a/.gitignore b/.gitignore index 8eeaa94e4..9bd3f9bea 100644 --- a/.gitignore +++ b/.gitignore @@ -37,5 +37,6 @@ koreader-kobo-arm-linux-gnueabihf* koreader-emulator-i686-w64-mingw32 koreader-emulator-x86_64-linux-gnu koreader-emulator-x86_64-pc-linux-gnu +koreader-emulator-x86_64-apple-darwin* koreader-pocketbook-arm-obreey-linux-gnueabi koreader-ubuntu-touch-arm-linux-gnueabihf diff --git a/Makefile b/Makefile index e24910c12..c94379363 100644 --- a/Makefile +++ b/Makefile @@ -63,7 +63,7 @@ ifneq ($(or $(EMULATE_READER),$(WIN32)),) cd $(INSTALL_DIR)/koreader/spec/front/unit && test -e data || \ ln -sf ../../test ./data else - cp -rfL $(KOR_BASE)/$(OUTPUT_DIR)/* $(INSTALL_DIR)/koreader/ + $(RCP) -fL $(KOR_BASE)/$(OUTPUT_DIR)/* $(INSTALL_DIR)/koreader/ endif for f in $(INSTALL_FILES); do \ ln -sf ../../$$f $(INSTALL_DIR)/koreader/; \ @@ -77,9 +77,9 @@ ifdef WIN32 cd $(INSTALL_DIR)/koreader && cp ../../$(WIN32_DIR)/*.dll . endif @echo "[*] Install plugins" - cp -r plugins/* $(INSTALL_DIR)/koreader/plugins/ + $(RCP) plugins/* $(INSTALL_DIR)/koreader/plugins/ @echo "[*] Installresources" - cp -rpL resources/fonts/* $(INSTALL_DIR)/koreader/fonts/ + $(RCP) -pL resources/fonts/* $(INSTALL_DIR)/koreader/fonts/ install -d $(INSTALL_DIR)/koreader/{screenshots,data/{dict,tessdata},fonts/host,ota} ifeq ($(or $(EMULATE_READER),$(WIN32)),) @echo "[*] Clean up, remove unused files for releases" diff --git a/README.md b/README.md index 540b4fc94..08108ee48 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,9 @@ KOReader KOReader is a document viewer application, originally created for Kindle e-ink readers. It currently runs on Kindle, Kobo, PocketBook, Ubuntu Touch -and Android (2.3+) devices. Developers can also run Koreader emulator -for development purpose on desktop PC with Linux and Windows operating system. +and Android (2.3+) devices. Developers can also run KOReader emulator +for development purpose on desktop PC with Linux and Windows and +Mac OSX (experimental for now). Main features for users ----------------------- @@ -91,6 +92,11 @@ sudo apt-get install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf sudo apt-get install gcc-mingw-w64-i686 g++-mingw-w64-i686 ``` +Mac OSX users may need to install these tools: +``` +brew install gcc48 nasm binutils libtool autoconf automake sdl2 +``` + A recent version of Android SDK/NDK and `ant` are needed in order to build Koreader for Android devices. ``` @@ -155,10 +161,10 @@ Then, run this command to build installable package for Android: ./kodev release android ``` -For emulating KOReader on Linux and Windows +For emulating KOReader on Linux, Windows and Mac OSX ------------- -To build an emulator on current Linux machine just run: +To build an emulator on current Linux or OSX machine: ``` ./kodev build ``` diff --git a/base b/base index 02c4e24e7..afaf36bc7 160000 --- a/base +++ b/base @@ -1 +1 @@ -Subproject commit 02c4e24e732f4d7009b71c763dbaa503c40365a1 +Subproject commit afaf36bc7aba673a6c4ec8159f79ed8f5d9996ec From 25b70007d4ea1dffd12142041fc0cbbca98e1c8d Mon Sep 17 00:00:00 2001 From: chrox Date: Fri, 22 Apr 2016 20:10:04 +0800 Subject: [PATCH 12/35] update to latest koreader base --- .gitignore | 6 ++++-- README.md | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 9bd3f9bea..bcf7e344c 100644 --- a/.gitignore +++ b/.gitignore @@ -8,13 +8,15 @@ lua-* .vimrc *.o tags -test/*.sdr +test/* *.tar *.log spec/unit/data doc/html - +git-rev emu +luacov.stats.out +trace-out.txt koreader-*.zip koreader-*.apk diff --git a/README.md b/README.md index 08108ee48..83959578c 100644 --- a/README.md +++ b/README.md @@ -94,7 +94,7 @@ sudo apt-get install gcc-mingw-w64-i686 g++-mingw-w64-i686 Mac OSX users may need to install these tools: ``` -brew install gcc48 nasm binutils libtool autoconf automake sdl2 +brew install nasm binutils libtool autoconf automake sdl2 ``` A recent version of Android SDK/NDK and `ant` are needed in order to build From 7071ae2b6eb90a5a099a8ff12290340b27f3999e Mon Sep 17 00:00:00 2001 From: chrox Date: Sat, 23 Apr 2016 21:50:21 +0800 Subject: [PATCH 13/35] fix unit test of occurrences search --- spec/unit/readersearch_spec.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/unit/readersearch_spec.lua b/spec/unit/readersearch_spec.lua index 3766e0d47..41c216850 100644 --- a/spec/unit/readersearch_spec.lua +++ b/spec/unit/readersearch_spec.lua @@ -87,7 +87,7 @@ describe("Readersearch module", function() for _, word in ipairs(words) do --dbg("found word", word.start) end - doc:gotoXPointer(words[1].start) + doc:gotoXPointer(words[#words].start) words = search:searchNext("Verona", 0) end assert.are.equal(13, count) From 92184f0199246992cd83ac01e644c9d17375eb74 Mon Sep 17 00:00:00 2001 From: chrox Date: Sat, 23 Apr 2016 22:56:56 +0800 Subject: [PATCH 14/35] fix #1985 by always return to the parent dir of current doc in the FileManager --- frontend/apps/filemanager/filemanager.lua | 6 +++--- frontend/apps/reader/modules/readermenu.lua | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/frontend/apps/filemanager/filemanager.lua b/frontend/apps/filemanager/filemanager.lua index 87436b9b8..c670774a0 100644 --- a/frontend/apps/filemanager/filemanager.lua +++ b/frontend/apps/filemanager/filemanager.lua @@ -229,10 +229,10 @@ function FileManager:init() self:handleEvent(Event:new("SetDimensions", self.dimen)) end -function FileManager:resetDimen(dimen) - self.dimen = dimen +function FileManager:reinit(path) + self.dimen = Screen:getSize() -- backup the root path and path items - self.root_path = self.file_chooser.path + self.root_path = path or self.file_chooser.path local path_items_backup = {} for k, v in pairs(self.file_chooser.path_items) do path_items_backup[k] = v diff --git a/frontend/apps/reader/modules/readermenu.lua b/frontend/apps/reader/modules/readermenu.lua index 0d4724290..ffed21153 100644 --- a/frontend/apps/reader/modules/readermenu.lua +++ b/frontend/apps/reader/modules/readermenu.lua @@ -38,14 +38,14 @@ function ReaderMenu:init() self:onTapCloseMenu() self.ui:onClose() local FileManager = require("apps/filemanager/filemanager") + local lastdir = nil + local last_file = G_reader_settings:readSetting("lastfile") + if last_file then + lastdir = last_file:match("(.*)/") + end if FileManager.instance then - FileManager.instance:resetDimen(Screen:getSize()) + FileManager.instance:reinit(lastdir) else - local lastdir = nil - local last_file = G_reader_settings:readSetting("lastfile") - if last_file then - lastdir = last_file:match("(.*)/") - end FileManager:showFiles(lastdir) end end, From 6e723237ba97c9137461915276c4d1fdc998d9a3 Mon Sep 17 00:00:00 2001 From: chrox Date: Sat, 23 Apr 2016 23:09:31 +0800 Subject: [PATCH 15/35] fix 'opening file' dialog not centered in landscape by setting the timeout to 0.0 seconds so that when the screen is turned to landscape the dialog is already closed. --- frontend/apps/reader/readerui.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/apps/reader/readerui.lua b/frontend/apps/reader/readerui.lua index d3e1f3612..8d8a663df 100644 --- a/frontend/apps/reader/readerui.lua +++ b/frontend/apps/reader/readerui.lua @@ -338,7 +338,7 @@ function ReaderUI:showReader(file) end UIManager:show(InfoMessage:new{ text = T( _("Opening file '%1'."), file), - timeout = 0.1, + timeout = 0.0, }) UIManager:nextTick(function() DEBUG("creating coroutine for showing reader") From 0166ff8add7df3800ea1e3ae8c68964dac260d28 Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Sat, 23 Apr 2016 21:09:50 -0700 Subject: [PATCH 16/35] reader(fix): force draw info message before loading document Since the doShowReader will run in nextTick, it will get picked up by checkTask, which is in the beginning of next UI loop and blocks UIManager from redrawing the screen for the info popup. --- frontend/apps/reader/readerui.lua | 26 ++++++++++++++------------ frontend/ui/uimanager.lua | 4 ++++ 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/frontend/apps/reader/readerui.lua b/frontend/apps/reader/readerui.lua index 8d8a663df..74c986bb5 100644 --- a/frontend/apps/reader/readerui.lua +++ b/frontend/apps/reader/readerui.lua @@ -12,7 +12,7 @@ local Device = require("device") local Screen = require("device").screen local Event = require("ui/event") local Cache = require("cache") -local DEBUG = require("dbg") +local dbg = require("dbg") local T = require("ffi/util").template local _ = require("gettext") @@ -304,7 +304,7 @@ function ReaderUI:init() }) -- koreader plugins for _,plugin_module in ipairs(PluginLoader:loadPlugins()) do - DEBUG("Loaded plugin", plugin_module.name, "at", plugin_module.path) + dbg("Loaded plugin", plugin_module.name, "at", plugin_module.path) self:registerModule(plugin_module.name, plugin_module:new{ dialog = self.dialog, view = self.view, @@ -313,7 +313,7 @@ function ReaderUI:init() }) end - --DEBUG(self.doc_settings) + --dbg(self.doc_settings) -- we only read settings after all the widgets are initialized self:handleEvent(Event:new("ReadSettings", self.doc_settings)) @@ -328,20 +328,22 @@ function ReaderUI:init() end function ReaderUI:showReader(file) - DEBUG("show reader ui") + dbg("show reader ui") require("readhistory"):addItem(file) if lfs.attributes(file, "mode") ~= "file" then UIManager:show(InfoMessage:new{ - text = T( _("File '%1' does not exist."), file) + text = T(_("File '%1' does not exist."), file) }) return end UIManager:show(InfoMessage:new{ - text = T( _("Opening file '%1'."), file), + text = T(_("Opening file '%1'."), file), timeout = 0.0, }) + -- doShowReader might block for a long time, so force repaint here + UIManager:forceRePaint() UIManager:nextTick(function() - DEBUG("creating coroutine for showing reader") + dbg("creating coroutine for showing reader") local co = coroutine.create(function() self:doShowReader(file) end) @@ -356,7 +358,7 @@ end local running_instance = nil function ReaderUI:doShowReader(file) - DEBUG("opening file", file) + dbg("opening file", file) -- keep only one instance running if running_instance then running_instance:onClose() @@ -369,7 +371,7 @@ function ReaderUI:doShowReader(file) return end if document.is_locked then - DEBUG("document is locked") + dbg("document is locked") self._coroutine = coroutine.running() or self._coroutine self:unlockDocumentWithPassword(document) if coroutine.running() then @@ -394,7 +396,7 @@ function ReaderUI:_getRunningInstance() end function ReaderUI:unlockDocumentWithPassword(document, try_again) - DEBUG("show input password dialog") + dbg("show input password dialog") self.password_dialog = InputDialog:new{ title = try_again and _("Password is incorrect, try again?") or _("Input document password"), @@ -482,10 +484,10 @@ function ReaderUI:notifyCloseDocument() end function ReaderUI:onClose() - DEBUG("closing reader") + dbg("closing reader") self:saveSettings() if self.document ~= nil then - DEBUG("closing document") + dbg("closing document") self:notifyCloseDocument() end UIManager:close(self.dialog, "full") diff --git a/frontend/ui/uimanager.lua b/frontend/ui/uimanager.lua index af850fec9..3e113efb6 100644 --- a/frontend/ui/uimanager.lua +++ b/frontend/ui/uimanager.lua @@ -521,6 +521,10 @@ function UIManager:_repaint() self.refresh_counted = false end +function UIManager:forceRePaint() + self:_repaint() +end + function UIManager:setInputTimeout(timeout) self.INPUT_TIMEOUT = timeout or 200*1000 end From eb71d29716cb1298bc2bc57b4a62fb75f7c33e5e Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Sat, 23 Apr 2016 21:16:37 -0700 Subject: [PATCH 17/35] kodev(minor): fix arg test --- frontend/ui/uimanager.lua | 4 ++-- kodev | 2 +- spec/unit/readersearch_spec.lua | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/frontend/ui/uimanager.lua b/frontend/ui/uimanager.lua index 3e113efb6..11520b30e 100644 --- a/frontend/ui/uimanager.lua +++ b/frontend/ui/uimanager.lua @@ -198,8 +198,8 @@ function UIManager:schedule(time, action) break end else - -- for fairness, it's better to make p+1 is strictly less than p - -- might want to revisit here in the future + -- for fairness, it's better to make p+1 is strictly less than + -- p might want to revisit here in the future break end until e < s diff --git a/kodev b/kodev index bddd743b2..cf131c332 100755 --- a/kodev +++ b/kodev @@ -4,7 +4,7 @@ CURDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" function assert_ret_zero { if [ $1 -ne 0 ]; then - if [ ! -z $2 ]; then + if [ ! -z "$2" ]; then echo $2 fi exit 1 diff --git a/spec/unit/readersearch_spec.lua b/spec/unit/readersearch_spec.lua index 41c216850..64ad2cd26 100644 --- a/spec/unit/readersearch_spec.lua +++ b/spec/unit/readersearch_spec.lua @@ -93,6 +93,7 @@ describe("Readersearch module", function() assert.are.equal(13, count) end) end) + describe("search API for PDF documents", function() local doc, search, paging setup(function() From 0f3eeb24c9f89553ae8f053b3320167c0c754498 Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Thu, 28 Apr 2016 00:02:15 -0700 Subject: [PATCH 18/35] progressbar(fix): persist progressbar visibility --- frontend/apps/reader/modules/readerfooter.lua | 94 ++++++++++--------- frontend/apps/reader/modules/readerview.lua | 5 +- spec/unit/readerfooter_spec.lua | 35 +++++++ spec/unit/widget_progresswidget_spec.lua | 2 +- 4 files changed, 89 insertions(+), 47 deletions(-) diff --git a/frontend/apps/reader/modules/readerfooter.lua b/frontend/apps/reader/modules/readerfooter.lua index ff9717d42..a10d85dcf 100644 --- a/frontend/apps/reader/modules/readerfooter.lua +++ b/frontend/apps/reader/modules/readerfooter.lua @@ -18,9 +18,23 @@ local _ = require("gettext") local util = require("util") +local MODE = { + off = 0, + page_progress = 1, + time = 2, + pages_left = 3, + battery = 4, + percentage = 5, + book_time_to_read = 6, + chapter_time_to_read = 7, +} +local MODE_INDEX = {} +for k,v in pairs(MODE) do + MODE_INDEX[v] = k +end + local ReaderFooter = InputContainer:new{ - mode = 1, - visible = true, + mode = MODE.page_progress, pageno = nil, pages = nil, toc_level = 0, @@ -67,7 +81,6 @@ function ReaderFooter:init() face = Font:getFace(self.text_font_face, self.text_font_size), } self.text_width = self.progress_text:getSize().w + self.text_left_margin - self:applyFooterMode() self.progress_bar = ProgressWidget:new{ width = nil, -- width will be updated in self:resetLayout() height = self.bar_height, @@ -101,7 +114,8 @@ function ReaderFooter:init() } } - self.mode = G_reader_settings:readSetting("reader_footer_mode") or self.mode + self:applyFooterMode( + G_reader_settings:readSetting("reader_footer_mode") or self.mode) self:resetLayout() if self.settings.auto_refresh_time then @@ -328,21 +342,23 @@ function ReaderFooter:updateFooterText() end self.progress_text:setText(table.concat(info, " | ")) else - local info = "" - if self.mode == 1 then + local info + if self.mode == MODE.page_progress then info = self:getProgressInfo() - elseif self.mode == 2 then + elseif self.mode == MODE.time then info = self:getTimeInfo() - elseif self.mode == 3 then + elseif self.mode == MODE.pages_left then info = self:getNextChapterInfo() - elseif self.mode == 4 then + elseif self.mode == MODE.battery then info = self:getBatteryInfo() - elseif self.mode == 5 then + elseif self.mode == MODE.percentage then info = self:getProgressPercentage() - elseif self.mode == 6 then + elseif self.mode == MODE.book_time_to_read then info = self:getBookTimeToRead() - elseif self.mode == 7 then + elseif self.mode == MODE.chapter_time_to_read then info = self:getChapterTimeToRead() + else + info = "" end self.progress_text:setText(info) end @@ -384,16 +400,12 @@ function ReaderFooter:applyFooterMode(mode) -- 6 for from statistics book time to read -- 7 for from statistics chapter time to read if mode ~= nil then self.mode = mode end - if self.mode == 0 then - self.view.footer_visible = false - else - self.view.footer_visible = true - end + self.view.footer_visible = (self.mode ~= MODE.off) end function ReaderFooter:onEnterFlippingMode() self.orig_mode = self.mode - self:applyFooterMode(1) + self:applyFooterMode(MODE.page_progress) end function ReaderFooter:onExitFlippingMode() @@ -410,30 +422,24 @@ function ReaderFooter:onTapFooter(arg, ges) self.ui:handleEvent(Event:new("GotoPercentage", percentage)) end else - self.mode = (self.mode + 1) % 8 - if self.settings.all_at_once and (self.mode > 1) then - self.mode = 0 - end - if (self.mode == 1) and not self.settings.page_progress then - self.mode = 2 - end - if (self.mode == 2) and not self.settings.time then - self.mode = 3 - end - if (self.mode == 3) and not self.settings.pages_left then - self.mode = 4 - end - if (self.mode == 4) and not self.settings.battery then - self.mode = 5 - end - if (self.mode == 5) and not self.settings.percentage then - self.mode = 6 - end - if (self.mode == 6) and not self.settings.book_time_to_read then - self.mode = 7 - end - if (self.mode == 7) and not self.settings.chapter_time_to_read then - self.mode = 0 + if self.settings.all_at_once then + if self.mode >= 1 then + self.mode = MODE.off + else + self.mode = MODE.page_progress + end + else + self.mode = (self.mode + 1) % 8 + for i, m in ipairs(MODE_INDEX) do + if self.mode == MODE.off then break end + if self.mode == i then + if self.settings[m] then + break + else + self.mode = (self.mode + 1) % 8 + end + end + end end self:applyFooterMode() G_reader_settings:saveSetting("reader_footer_mode", self.mode) @@ -443,13 +449,13 @@ function ReaderFooter:onTapFooter(arg, ges) end function ReaderFooter:onHoldFooter(arg, ges) - if self.mode == 0 then return end + if self.mode == MODE.off then return end self.ui:handleEvent(Event:new("ShowGotoDialog")) return true end function ReaderFooter:onSetStatusLine(status_line) - self.view.footer_visible = status_line == 1 and true or false + self.view.footer_visible = (status_line == 1) self.ui.document:setStatusLineProp(status_line) self.ui:handleEvent(Event:new("UpdatePos")) end diff --git a/frontend/apps/reader/modules/readerview.lua b/frontend/apps/reader/modules/readerview.lua index 225ea21d7..16fe52a07 100644 --- a/frontend/apps/reader/modules/readerview.lua +++ b/frontend/apps/reader/modules/readerview.lua @@ -94,7 +94,6 @@ function ReaderView:addWidgets() self.footer = ReaderFooter:new{ view = self, ui = self.ui, - visible = self.footer_visible, } self.flipping = ReaderFlipping:new{ view = self, @@ -644,7 +643,9 @@ function ReaderView:onReadSettings(config) self.state.gamma = config:readSetting("gamma") or DGLOBALGAMMA local full_screen = config:readSetting("kopt_full_screen") or self.document.configurable.full_screen local status_line = config:readSetting("copt_status_line") or self.document.configurable.status_line - self.footer_visible = (full_screen == 0 or status_line == 1) and true or false + if full_screen == 0 or status_line == 0 then + self.footer_visible = false + end self:resetLayout() local page_scroll = config:readSetting("kopt_page_scroll") or self.document.configurable.page_scroll self.page_scroll = page_scroll == 1 and true or false diff --git a/spec/unit/readerfooter_spec.lua b/spec/unit/readerfooter_spec.lua index f95b62bfd..e7f1c9095 100644 --- a/spec/unit/readerfooter_spec.lua +++ b/spec/unit/readerfooter_spec.lua @@ -100,6 +100,41 @@ describe("Readerfooter module", function() assert.are.same('TC: na', footer.progress_text.text) end) + it("should rotate through different modes", function() + local sample_pdf = "spec/front/unit/data/2col.pdf" + local readerui = ReaderUI:new{ + document = DocumentRegistry:openDocument(sample_pdf), + } + local footer = readerui.view.footer + footer.settings.all_at_once = false + footer.mode = 0 + footer:onTapFooter() + assert.is.same(1, footer.mode) + footer:onTapFooter() + assert.is.same(2, footer.mode) + footer:onTapFooter() + assert.is.same(3, footer.mode) + footer:onTapFooter() + assert.is.same(4, footer.mode) + footer:onTapFooter() + assert.is.same(5, footer.mode) + footer:onTapFooter() + assert.is.same(6, footer.mode) + footer:onTapFooter() + assert.is.same(7, footer.mode) + footer:onTapFooter() + assert.is.same(0, footer.mode) + + footer.settings.all_at_once = true + footer.mode = 5 + footer:onTapFooter() + assert.is.same(0, footer.mode) + footer:onTapFooter() + assert.is.same(1, footer.mode) + footer:onTapFooter() + assert.is.same(0, footer.mode) + end) + it("should pick up screen resize in resetLayout", function() local sample_pdf = "spec/front/unit/data/2col.pdf" purgeDir(DocSettings:getSidecarDir(sample_pdf)) diff --git a/spec/unit/widget_progresswidget_spec.lua b/spec/unit/widget_progresswidget_spec.lua index f5085b657..0f3dd0f0e 100644 --- a/spec/unit/widget_progresswidget_spec.lua +++ b/spec/unit/widget_progresswidget_spec.lua @@ -6,7 +6,7 @@ describe("ProgressWidget widget", function() Screen = require("device").screen end) - it("should not crash with nil self.last #ok", function() + it("should not crash with nil self.last", function() local progress = ProgressWidget:new{ width = 100, height = 50, From 7c380121ea73d541e1bf8b7e428bdf9f4bb8e972 Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Thu, 28 Apr 2016 01:26:10 -0700 Subject: [PATCH 19/35] test: more readerfooter progressbar tests --- spec/unit/readerfooter_spec.lua | 61 +++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/spec/unit/readerfooter_spec.lua b/spec/unit/readerfooter_spec.lua index e7f1c9095..c9736a239 100644 --- a/spec/unit/readerfooter_spec.lua +++ b/spec/unit/readerfooter_spec.lua @@ -29,6 +29,67 @@ describe("Readerfooter module", function() }) end) + it("should setup footer as visible", function() + G_reader_settings:saveSetting("reader_footer_mode", 1) + local sample_pdf = "spec/front/unit/data/2col.pdf" + purgeDir(DocSettings:getSidecarDir(sample_pdf)) + os.remove(DocSettings:getHistoryPath(sample_pdf)) + + local readerui = ReaderUI:new{ + document = DocumentRegistry:openDocument(sample_pdf), + } + assert.is.same(true, readerui.view.footer_visible) + G_reader_settings:delSetting("reader_footer_mode") + end) + + it("should setup footer as invisible in full screen mode", function() + G_reader_settings:saveSetting("reader_footer_mode", 1) + local sample_pdf = "spec/front/unit/data/2col.pdf" + purgeDir(DocSettings:getSidecarDir(sample_pdf)) + os.remove(DocSettings:getHistoryPath(sample_pdf)) + local cfg = DocSettings:open(sample_pdf) + cfg:saveSetting("kopt_full_screen", 0) + cfg:flush() + + local readerui = ReaderUI:new{ + document = DocumentRegistry:openDocument(sample_pdf), + } + assert.is.same(false, readerui.view.footer_visible) + G_reader_settings:delSetting("reader_footer_mode") + end) + + it("should setup footer as visible in mini progress bar mode", function() + G_reader_settings:saveSetting("reader_footer_mode", 1) + local sample_pdf = "spec/front/unit/data/2col.pdf" + purgeDir(DocSettings:getSidecarDir(sample_pdf)) + os.remove(DocSettings:getHistoryPath(sample_pdf)) + local cfg = DocSettings:open(sample_pdf) + cfg:saveSetting("kopt_full_screen", 0) + cfg:flush() + + local readerui = ReaderUI:new{ + document = DocumentRegistry:openDocument(sample_pdf), + } + assert.is.same(false, readerui.view.footer_visible) + G_reader_settings:delSetting("reader_footer_mode") + end) + + it("should setup footer as invisible", function() + G_reader_settings:saveSetting("reader_footer_mode", 1) + local sample_epub = "spec/front/unit/data/juliet.epub" + purgeDir(DocSettings:getSidecarDir(sample_epub)) + os.remove(DocSettings:getHistoryPath(sample_epub)) + local cfg = DocSettings:open(sample_epub) + cfg:saveSetting("copt_status_line", 1) + cfg:flush() + + local readerui = ReaderUI:new{ + document = DocumentRegistry:openDocument(sample_epub), + } + assert.is.same(true, readerui.view.footer_visible) + G_reader_settings:delSetting("reader_footer_mode") + end) + it("should setup footer for epub without error", function() local sample_epub = "spec/front/unit/data/juliet.epub" purgeDir(DocSettings:getSidecarDir(sample_epub)) From ef4004e72bffef6af85659a44144fd3629aa58f3 Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Thu, 28 Apr 2016 20:31:17 -0700 Subject: [PATCH 20/35] test(fix): disable footer in readerlink_spec --- kodev | 1 + spec/unit/readerlink_spec.lua | 2 ++ 2 files changed, 3 insertions(+) diff --git a/kodev b/kodev index cf131c332..fc472e2dc 100755 --- a/kodev +++ b/kodev @@ -13,6 +13,7 @@ function assert_ret_zero { function setup_env { files=`ls -d ./koreader-emulator-*/koreader` + assert_ret_zero $? "Emulator not found, please build it first." export EMU_DIR=${files[0]} } diff --git a/spec/unit/readerlink_spec.lua b/spec/unit/readerlink_spec.lua index e950ab04e..beb7fafdf 100644 --- a/spec/unit/readerlink_spec.lua +++ b/spec/unit/readerlink_spec.lua @@ -88,6 +88,8 @@ describe("ReaderLink module", function() zoom = 0.9501187648456056456, }, } + -- disable footer + G_reader_settings:saveSetting("reader_footer_mode", 0) local readerui = ReaderUI:new{ document = DocumentRegistry:openDocument(sample_pdf), } From 259bd72cf2d6f9317ef441a529c0f6321a48245a Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Thu, 28 Apr 2016 20:34:43 -0700 Subject: [PATCH 21/35] bump base for fixes --- base | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base b/base index afaf36bc7..88aa05b66 160000 --- a/base +++ b/base @@ -1 +1 @@ -Subproject commit afaf36bc7aba673a6c4ec8159f79ed8f5d9996ec +Subproject commit 88aa05b664b8b5c276e13976905b8126c15486d2 From b406e3591ffa4344c905bd5ce30a44eda8761229 Mon Sep 17 00:00:00 2001 From: NiLuJe Date: Sun, 1 May 2016 05:59:50 +0200 Subject: [PATCH 22/35] Update Kobo startup script for KFMon Takes care of some potentially critical stuff ;p --- platform/kobo/koreader.sh | 40 +++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/platform/kobo/koreader.sh b/platform/kobo/koreader.sh index 8c7016ecd..73b301bec 100755 --- a/platform/kobo/koreader.sh +++ b/platform/kobo/koreader.sh @@ -36,14 +36,36 @@ if pkill -0 nickel ; then fi if [ "${FROM_NICKEL}" == "true" ] ; then - # Siphon a few things from nickel's env... - eval "$(xargs -n 1 -0 < /proc/$(pidof nickel)/environ | grep -e DBUS_SESSION_BUS_ADDRESS -e WIFI_MODULE -e PLATFORM -e WIFI_MODULE_PATH -e INTERFACE -e PRODUCT 2>/dev/null)" - export DBUS_SESSION_BUS_ADDRESS WIFI_MODULE PLATFORM WIFI_MODULE_PATH INTERFACE PRODUCT + # Detect if we were started from KFMon + if pkill -0 kfmon ; then + FROM_KFMON="true" + else + FROM_KFMON="false" + fi + + if [ "${FROM_KFMON}" == "true" ] ; then + # Siphon nickel's full environment, since KFMon inherits such a minimal one... + for env in $(xargs -n 1 -0 < /proc/$(pidof nickel)/environ) ; do + export ${env} + done + else + # Siphon a few things from nickel's env... + eval "$(xargs -n 1 -0 < /proc/$(pidof nickel)/environ | grep -e DBUS_SESSION_BUS_ADDRESS -e WIFI_MODULE -e PLATFORM -e WIFI_MODULE_PATH -e INTERFACE -e PRODUCT 2>/dev/null)" + export DBUS_SESSION_BUS_ADDRESS WIFI_MODULE PLATFORM WIFI_MODULE_PATH INTERFACE PRODUCT + fi # flush disks, might help avoid trashing nickel's DB... sync + # Double the fun! + sleep 1 + sync # stop kobo software because it's running - killall nickel hindenburg fmon 2>/dev/null + killall nickel hindenburg sickel fickel fmon 2>/dev/null + + # NOTE: Not particularly critical, we should be safe leaving it up, but since we reboot on exit anyway... + #if [ "${FROM_KFMON}" == "true" ] ; then + # killall kfmon 2>/dev/null + #fi fi # fallback for old fmon (and advboot) users (-> if no args were passed to the sript, start the FM) @@ -89,8 +111,14 @@ fi ./reader.lua "${args}" > crash.log 2>&1 if [ "${FROM_NICKEL}" == "true" ] ; then - # start kobo software because it was running before koreader - ./nickel.sh & + if [ "${FROM_KFMON}" != "true" ] ; then + # start kobo software because it was running before koreader + ./nickel.sh & + else + # If we were called from KFMon, just reboot, because depending on how the user triggered it, Nickel can get its panties in a serious twist on restore... + # And at best, we'd still restart with broken suspend behavior anyway... + reboot + fi else # if we were called from advboot then we must reboot to go to the menu # NOTE: This is actually achieved by checking if KSM or a KSM-related script is running: From f01b26118874d444d3ac82e3705067c9edc57a38 Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Tue, 26 Apr 2016 00:16:27 -0700 Subject: [PATCH 23/35] test: add kindle init and fl tests --- spec/unit/device_spec.lua | 64 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/spec/unit/device_spec.lua b/spec/unit/device_spec.lua index ac26c3228..3a2f84532 100644 --- a/spec/unit/device_spec.lua +++ b/spec/unit/device_spec.lua @@ -95,4 +95,68 @@ describe("device module", function() mock_input.open:revert() end) end) + + describe("kindle", function() + it("should initialize voyager without error", function() + package.loaded['ffi/framebuffer_mxcfb'] = mock_fb + stub(io, "open") + io.open.returns({ + read = function() + return "XX13XX" + end, + close = function() end + }) + mock_input = require('device/input') + stub(mock_input, "open") + + local kindle_dev = require("device/kindle/device") + assert.is.same(kindle_dev.model, "KindleVoyage") + kindle_dev:init() + assert.is.same(kindle_dev.input.event_map[104], "LPgBack") + assert.is.same(kindle_dev.input.event_map[109], "LPgFwd") + assert.is.same(kindle_dev.powerd.fl_min, 0) + assert.is.same(kindle_dev.powerd.fl_max, 24) + + io.open:revert() + package.loaded['ffi/framebuffer_mxcfb'] = nil + mock_input.open:revert() + end) + + it("should toggle frontlight", function() + package.loaded['ffi/framebuffer_mxcfb'] = mock_fb + stub(io, "open") + io.open.returns({ + read = function() + return "12" + end, + close = function() end + }) + mock_input = require('device/input') + stub(mock_input, "open") + stub(os, "execute") + + local kindle_dev = require("device/kindle/device") + kindle_dev:init() + + assert.is.same(kindle_dev.powerd.fl_intensity, 12) + kindle_dev.powerd:setIntensity(5) + assert.stub(os.execute).was_called_with( + "echo -n 5 > /sys/class/backlight/max77696-bl/brightness") + assert.is.same(kindle_dev.powerd.fl_intensity, 5) + + kindle_dev.powerd:toggleFrontlight() + assert.stub(os.execute).was_called_with( + "echo -n 0 > /sys/class/backlight/max77696-bl/brightness") + assert.is.same(kindle_dev.powerd.fl_intensity, 5) + + kindle_dev.powerd:toggleFrontlight() + assert.stub(os.execute).was_called_with( + "echo -n 5 > /sys/class/backlight/max77696-bl/brightness") + + io.open:revert() + package.loaded['ffi/framebuffer_mxcfb'] = nil + mock_input.open:revert() + os.execute:revert() + end) + end) end) From 2bcc3671c58b730f60f56881a707b1450a0f0d5f Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Sun, 1 May 2016 00:51:50 -0700 Subject: [PATCH 24/35] scrolltextwideget(fix): listen to page fwd/bck events --- frontend/ui/widget/scrolltextwidget.lua | 40 ++++++++++++++++++++----- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/frontend/ui/widget/scrolltextwidget.lua b/frontend/ui/widget/scrolltextwidget.lua index 28a86ee00..85018f248 100644 --- a/frontend/ui/widget/scrolltextwidget.lua +++ b/frontend/ui/widget/scrolltextwidget.lua @@ -4,10 +4,11 @@ local VerticalScrollBar = require("ui/widget/verticalscrollbar") local Geom = require("ui/geometry") local GestureRange = require("ui/gesturerange") local UIManager = require("ui/uimanager") -local Screen = require("device").screen +local Device = require("device") +local Screen = Device.screen +local Input = Device.input local HorizontalGroup = require("ui/widget/horizontalgroup") local HorizontalSpan = require("ui/widget/horizontalspan") -local Device = require("device") local Blitbuffer = require("ffi/blitbuffer") --[[ @@ -57,6 +58,12 @@ function ScrollTextWidget:init() }, } end + if Device:hasKeyboard() or Device:hasKeys() then + self.key_events = { + ScrollDown = {{Input.group.PgFwd}, doc = "scroll down"}, + ScrollUp = {{Input.group.PgBack}, doc = "scroll up"}, + } + end end function ScrollTextWidget:updateScrollBar(text) @@ -69,17 +76,36 @@ function ScrollTextWidget:updateScrollBar(text) ) end -function ScrollTextWidget:onScrollText(arg, ges) - if ges.direction == "north" then +function ScrollTextWidget:scrollText(direction) + if direction == 0 then return end + if direction > 0 then self.text_widget:scrollDown() - self:updateScrollBar(self.text_widget) - elseif ges.direction == "south" then + else self.text_widget:scrollUp() - self:updateScrollBar(self.text_widget) end + self:updateScrollBar(self.text_widget) UIManager:setDirty(self.dialog, function() return "partial", self.dimen end) end +function ScrollTextWidget:onScrollText(arg, ges) + if ges.direction == "north" then + self:scrollText(1) + elseif ges.direction == "south" then + self:scrollText(-1) + end + return true +end + +function ScrollTextWidget:onScrollDown() + self:scrollText(1) + return true +end + +function ScrollTextWidget:onScrollUp() + self:scrollText(-1) + return true +end + return ScrollTextWidget From 18c0cee18fc6eca5e1397b54023179c09459df61 Mon Sep 17 00:00:00 2001 From: Cosmin Gorgovan Date: Sun, 1 May 2016 13:46:17 +0100 Subject: [PATCH 25/35] UIManager: add method for broadcasting an event to all widgets --- frontend/ui/uimanager.lua | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/frontend/ui/uimanager.lua b/frontend/ui/uimanager.lua index 11520b30e..8b38bfa54 100644 --- a/frontend/ui/uimanager.lua +++ b/frontend/ui/uimanager.lua @@ -347,7 +347,7 @@ function UIManager:quit() end end --- transmit an event to registered widgets +-- transmit an event to an active widget function UIManager:sendEvent(event) if #self._window_stack == 0 then return end -- top level widget has first access to the event @@ -368,6 +368,20 @@ function UIManager:sendEvent(event) end end +-- transmit an event to all registered widgets +function UIManager:broadcastEvent(event) + -- the widget's event handler might close widgets in which case + -- a simple iterator like ipairs would skip over some entries + local i = 1 + while (i <= #self._window_stack) do + local prev_widget = self._window_stack[i].widget + self._window_stack[i].widget:handleEvent(event) + if (self._window_stack[i].widget == prev_widget) then + i = i + 1 + end + end +end + function UIManager:_checkTasks() local now = { util.gettime() } local now_us = now[1] * MILLION + now[2] From 19338cb439175c53cc1b69a598707e2fffe35b01 Mon Sep 17 00:00:00 2001 From: Cosmin Gorgovan Date: Tue, 26 Apr 2016 23:30:52 +0100 Subject: [PATCH 26/35] Kobo: Offer to power off if the power button is held for at least 3 seconds --- frontend/device/generic/device.lua | 3 +++ frontend/device/input.lua | 24 ++++++++++++++--------- frontend/device/kobo/device.lua | 4 ++++ frontend/ui/uimanager.lua | 31 ++++++++++++++++++++++++++++++ 4 files changed, 53 insertions(+), 9 deletions(-) diff --git a/frontend/device/generic/device.lua b/frontend/device/generic/device.lua index 07f452c10..e8f671c6c 100644 --- a/frontend/device/generic/device.lua +++ b/frontend/device/generic/device.lua @@ -153,6 +153,9 @@ function Device:suspend() end -- Hardware specific method to resume the device function Device:resume() end +-- Hardware specific method to power off the device +function Device:powerOff() end + function Device:usbPlugIn() if self.charging_mode == false and self.screen_saver_mode == false then self.screen:saveCurrentBB() diff --git a/frontend/device/input.lua b/frontend/device/input.lua index e4f8ef878..016be3b90 100644 --- a/frontend/device/input.lua +++ b/frontend/device/input.lua @@ -258,20 +258,26 @@ function Input:handleKeyBoardEv(ev) end end - if ev.value == EVENT_VALUE_KEY_RELEASE then - if keycode == "Light" then - return keycode - elseif keycode == "Power" then - -- Kobo generates Power keycode only, we need to decide whether it's - -- power-on or power-off ourselves. - if self.device.screen_saver_mode then + if keycode == "Power" then + -- Kobo generates Power keycode only, we need to decide whether it's + -- power-on or power-off ourselves. + if self.device.screen_saver_mode then + if ev.value == EVENT_VALUE_KEY_RELEASE then return "Resume" - else - return "Suspend" + end + else + if ev.value == EVENT_VALUE_KEY_PRESS then + return "PowerPress" + elseif ev.value == EVENT_VALUE_KEY_RELEASE then + return "PowerRelease" end end end + if ev.value == EVENT_VALUE_KEY_RELEASE and keycode == "Light" then + return keycode + end + -- handle modifier keys if self.modifiers[keycode] ~= nil then if ev.value == EVENT_VALUE_KEY_PRESS then diff --git a/frontend/device/kobo/device.lua b/frontend/device/kobo/device.lua index 18c598bd6..8f96561ef 100644 --- a/frontend/device/kobo/device.lua +++ b/frontend/device/kobo/device.lua @@ -189,6 +189,10 @@ function Kobo:resume() end end +function Kobo:powerOff() + os.execute("poweroff") +end + -------------- device probe ------------ local codename = Kobo:getCodeName() diff --git a/frontend/ui/uimanager.lua b/frontend/ui/uimanager.lua index 8b38bfa54..f00b842e8 100644 --- a/frontend/ui/uimanager.lua +++ b/frontend/ui/uimanager.lua @@ -27,6 +27,7 @@ local UIManager = { _zeromqs = {}, _refresh_stack = {}, _refresh_func_stack = {}, + _power_ev_handled = false, } function UIManager:init() @@ -55,6 +56,36 @@ function UIManager:init() self:sendEvent(Event:new("Resume")) self:_startAutoSuspend() end + self.event_handlers["PowerPress"] = function(input_event) + self._power_ev_handled = false + local showPowerOffDialog = function() + if self._power_ev_handled then return end + self._power_ev_handled = true + local ConfirmBox = require("ui/widget/confirmbox") + UIManager:show(ConfirmBox:new{ + text = _("Power off?"), + ok_callback = function() + local InfoMessage = require("ui/widget/infomessage") + + UIManager:show(InfoMessage:new{ + text = _("Powered off."), + }) + -- The message can fail to render if this is executed directly + UIManager:scheduleIn(0.1, function() + self:broadcastEvent(Event:new("Close")) + Device:powerOff() + end) + end, + }) + end + UIManager:scheduleIn(3, showPowerOffDialog) + end + self.event_handlers["PowerRelease"] = function(input_event) + if not self._power_ev_handled then + self._power_ev_handled = true + self.event_handlers["Suspend"]("Suspend") + end + end self.event_handlers["Light"] = function() Device:getPowerDevice():toggleFrontlight() end From e90f1018db01f65253a7b41bbf82b78afb5373ce Mon Sep 17 00:00:00 2001 From: NiLuJe Date: Sun, 1 May 2016 15:11:47 +0200 Subject: [PATCH 27/35] Make the KFMon chekc actually accurate... Sleep does wonder for your brain! --- platform/kobo/koreader.sh | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/platform/kobo/koreader.sh b/platform/kobo/koreader.sh index 73b301bec..5000f7554 100755 --- a/platform/kobo/koreader.sh +++ b/platform/kobo/koreader.sh @@ -37,14 +37,16 @@ fi if [ "${FROM_NICKEL}" == "true" ] ; then # Detect if we were started from KFMon + FROM_KFMON="false" if pkill -0 kfmon ; then - FROM_KFMON="true" - else - FROM_KFMON="false" + # That's a start, now check if KFMon truly is our parent... + if [ "$(pidof kfmon)" -eq "${PPID}" ] ; then + FROM_KFMON="true" + fi fi if [ "${FROM_KFMON}" == "true" ] ; then - # Siphon nickel's full environment, since KFMon inherits such a minimal one... + # Siphon nickel's full environment, since KFMon inherits such a minimal one, and that apparently confuses the hell out of Nickel for some reason if we decide to restart it without a reboot... for env in $(xargs -n 1 -0 < /proc/$(pidof nickel)/environ) ; do export ${env} done @@ -63,6 +65,7 @@ if [ "${FROM_NICKEL}" == "true" ] ; then killall nickel hindenburg sickel fickel fmon 2>/dev/null # NOTE: Not particularly critical, we should be safe leaving it up, but since we reboot on exit anyway... + # Keep KFMon up for now to make sure it's not doing anything overly stupid we might have overlooked ;). #if [ "${FROM_KFMON}" == "true" ] ; then # killall kfmon 2>/dev/null #fi @@ -115,7 +118,7 @@ if [ "${FROM_NICKEL}" == "true" ] ; then # start kobo software because it was running before koreader ./nickel.sh & else - # If we were called from KFMon, just reboot, because depending on how the user triggered it, Nickel can get its panties in a serious twist on restore... + # If we were called from KFMon, just reboot, because there's always a (hopefully slim to nonexistent, now) chance Nickel will get its panties in a serious twist on restore for one reason or another... # And at best, we'd still restart with broken suspend behavior anyway... reboot fi From 42dde82c4347ce8b45506d7def19b6bd57861e62 Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Mon, 2 May 2016 00:51:58 -0700 Subject: [PATCH 28/35] uimanager(minor): simplify suspend event handler's signature --- frontend/ui/uimanager.lua | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/frontend/ui/uimanager.lua b/frontend/ui/uimanager.lua index f00b842e8..0509f54ac 100644 --- a/frontend/ui/uimanager.lua +++ b/frontend/ui/uimanager.lua @@ -47,16 +47,16 @@ function UIManager:init() -- suspend. So let's unschedule it when suspending, and restart it after -- resume. self:_initAutoSuspend() - self.event_handlers["Suspend"] = function(input_event) + self.event_handlers["Suspend"] = function() self:_stopAutoSuspend() - Device:onPowerEvent(input_event) + Device:onPowerEvent("Suspend") end - self.event_handlers["Resume"] = function(input_event) - Device:onPowerEvent(input_event) + self.event_handlers["Resume"] = function() + Device:onPowerEvent("Resume") self:sendEvent(Event:new("Resume")) self:_startAutoSuspend() end - self.event_handlers["PowerPress"] = function(input_event) + self.event_handlers["PowerPress"] = function() self._power_ev_handled = false local showPowerOffDialog = function() if self._power_ev_handled then return end @@ -80,10 +80,10 @@ function UIManager:init() end UIManager:scheduleIn(3, showPowerOffDialog) end - self.event_handlers["PowerRelease"] = function(input_event) + self.event_handlers["PowerRelease"] = function() if not self._power_ev_handled then self._power_ev_handled = true - self.event_handlers["Suspend"]("Suspend") + self.event_handlers["Suspend"]() end end self.event_handlers["Light"] = function() From 068cefe8fcb3289e40cd7f8e855c542367e70991 Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Mon, 2 May 2016 01:35:06 -0700 Subject: [PATCH 29/35] test: flush book settings before suspend --- spec/unit/device_spec.lua | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/spec/unit/device_spec.lua b/spec/unit/device_spec.lua index 3a2f84532..bfdc4b0ba 100644 --- a/spec/unit/device_spec.lua +++ b/spec/unit/device_spec.lua @@ -94,6 +94,44 @@ describe("device module", function() os.getenv:revert() mock_input.open:revert() end) + + it("should flush book settings before suspend", function() + local sample_pdf = "spec/front/unit/data/tall.pdf" + local ReaderUI = require("apps/reader/readerui") + local Device = require("device") + local NickelConf = require("device/kobo/nickel_conf") + + stub(NickelConf.frontLightLevel, "get") + stub(NickelConf.frontLightState, "get") + NickelConf.frontLightLevel.get.returns(1) + NickelConf.frontLightState.get.returns(0) + + local UIManager = require("ui/uimanager") + stub(Device, "suspend") + stub(Device.powerd, "beforeSuspend") + stub(Device, "isKobo") + + Device.isKobo.returns(true) + local saved_noop = UIManager._resetAutoSuspendTimer + UIManager:init() + + ReaderUI:doShowReader(sample_pdf) + local readerui = ReaderUI._getRunningInstance() + stub(readerui, "onFlushSettings") + UIManager.event_handlers["PowerPress"]() + UIManager.event_handlers["PowerRelease"]() + assert.stub(readerui.onFlushSettings).was_called() + + Device.suspend:revert() + Device.powerd.beforeSuspend:revert() + Device.isKobo:revert() + NickelConf.frontLightLevel.get:revert() + NickelConf.frontLightState.get:revert() + UIManager._startAutoSuspend = nil + UIManager._stopAutoSuspend = nil + UIManager._resetAutoSuspendTimer = saved_noop + readerui:onClose() + end) end) describe("kindle", function() From 2cf4e77ae506d58fa7e4e2eac825944cd42b49bc Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Mon, 2 May 2016 22:35:18 -0700 Subject: [PATCH 30/35] readerui(chore): rename _running_instance --- frontend/apps/reader/readerui.lua | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/frontend/apps/reader/readerui.lua b/frontend/apps/reader/readerui.lua index 74c986bb5..d98664342 100644 --- a/frontend/apps/reader/readerui.lua +++ b/frontend/apps/reader/readerui.lua @@ -356,12 +356,12 @@ function ReaderUI:showReader(file) end) end -local running_instance = nil +local _running_instance = nil function ReaderUI:doShowReader(file) dbg("opening file", file) -- keep only one instance running - if running_instance then - running_instance:onClose() + if _running_instance then + _running_instance:onClose() end local document = DocumentRegistry:openDocument(file) if not document then @@ -388,11 +388,11 @@ function ReaderUI:doShowReader(file) document = document, } UIManager:show(reader) - running_instance = reader + _running_instance = reader end function ReaderUI:_getRunningInstance() - return running_instance + return _running_instance end function ReaderUI:unlockDocumentWithPassword(document, try_again) @@ -493,8 +493,8 @@ function ReaderUI:onClose() UIManager:close(self.dialog, "full") -- serialize last used items for later launch Cache:serialize() - if running_instance == self then - running_instance = nil + if _running_instance == self then + _running_instance = nil end return true end From 6e9208ac500a4972c65ed41d1429e6075ece48f8 Mon Sep 17 00:00:00 2001 From: Frans de Jonge Date: Fri, 6 May 2016 14:06:48 +0200 Subject: [PATCH 31/35] kodev code quality --- kodev | 64 +++++++++++++++++++++++++++++------------------------------ 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/kodev b/kodev index fc472e2dc..09e689d4b 100755 --- a/kodev +++ b/kodev @@ -3,16 +3,16 @@ CURDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" function assert_ret_zero { - if [ $1 -ne 0 ]; then + if [ "$1" -ne 0 ]; then if [ ! -z "$2" ]; then - echo $2 + echo "$2" fi exit 1 fi } function setup_env { - files=`ls -d ./koreader-emulator-*/koreader` + files=$(ls -d ./koreader-emulator-*/koreader) assert_ret_zero $? "Emulator not found, please build it first." export EMU_DIR=${files[0]} } @@ -44,8 +44,8 @@ TARGET: ${SUPPORTED_TARGETS}" while [[ $1 == '-'* ]]; do - PARAM=`echo $1 | awk -F= '{print $1}'` - VALUE=`echo $1 | awk -F= '{print $2}'` + PARAM=$(echo "$1" | awk -F= '{print $1}') + VALUE=$(echo "$1" | awk -F= '{print $2}') case $PARAM in -v | --verbose) export VERBOSE=1 @@ -77,7 +77,7 @@ ${SUPPORTED_TARGETS}" assert_ret_zero $? ;; android) - if [ ! -d ${CURDIR}/base/toolchain/android-toolchain ]; then + if [ ! -d "${CURDIR}/base/toolchain/android-toolchain" ]; then make android-toolchain assert_ret_zero $? fi @@ -85,7 +85,7 @@ ${SUPPORTED_TARGETS}" assert_ret_zero $? ;; pocketbook) - if [ ! -d ${CURDIR}/base/toolchain/pocketbook-toolchain ]; then + if [ ! -d "${CURDIR}/base/toolchain/pocketbook-toolchain" ]; then make pocketbook-toolchain assert_ret_zero $? fi @@ -131,7 +131,7 @@ ${SUPPORTED_TARGETS}" ;; android) make TARGET=android clean - rm -f *.apk + rm -f ./*.apk ;; pocketbook) make TARGET=pocketbook clean @@ -203,7 +203,7 @@ ${SUPPORTED_RELEASE_TARGETS}" function kodev-wbuilder { kodev-build echo "[*] Running wbuilder.lua..." - pushd ${EMU_DIR} + pushd "${EMU_DIR}" EMULATE_READER_W=540 EMULATE_READER_H=720 ./luajit ./utils/wbuilder.lua popd } @@ -222,8 +222,8 @@ OPTIONS: screen_width=540 screen_height=720 while [[ $1 == '-'* ]]; do - PARAM=`echo $1 | awk -F= '{print $1}'` - VALUE=`echo $1 | awk -F= '{print $2}'` + PARAM=$(echo "$1" | awk -F= '{print $1}') + VALUE=$(echo "$1" | awk -F= '{print $2}') case $PARAM in --disable-touch) export DISABLE_TOUCH=1 @@ -257,18 +257,18 @@ OPTIONS: setup_env fi - if [ ! -d ${EMU_DIR} ]; then + if [ ! -d "${EMU_DIR}" ]; then echo "Failed to find emulator directory! Please try build command first." exit 1 fi - echo "[*] Running KOReader with arguments: $@..." - pushd ${EMU_DIR} + echo "[*] Running KOReader with arguments: $*..." + pushd "${EMU_DIR}" if [ $# -lt 1 ]; then args=${CURDIR}/test else - args="$@" + args="$*" [[ $args != /* ]] && args="${CURDIR}/${args}" fi @@ -288,8 +288,8 @@ OPTIONS: --tags=TAGS only run tests with given tags " while [[ $1 == '-'* ]]; do - PARAM=`echo $1 | awk -F= '{print $1}'` - VALUE=`echo $1 | awk -F= '{print $2}'` + PARAM=$(echo "$1" | awk -F= '{print $1}') + VALUE=$(echo "$1" | awk -F= '{print $2}') case $PARAM in --tags) opts="--tags=${VALUE}" @@ -313,19 +313,19 @@ OPTIONS: fi setup_env - make ${EMU_DIR}/.busted - pushd ${EMU_DIR} + make "${EMU_DIR}/.busted" + pushd "${EMU_DIR}" - test_path=./spec/$1/unit + test_path="./spec/$1/unit" - if [ ! -z $2 ]; then + if [ ! -z "$2" ]; then test_path="${test_path}/$2" fi - busted --lua=./luajit ${opts} \ + busted --lua="./luajit ${opts}" \ --no-auto-insulate \ --lazy \ - -o ./spec/$1/unit/verbose_print \ - --exclude-tags=notest ${test_path} + -o "./spec/$1/unit/verbose_print" \ + --exclude-tags=notest "${test_path}" popd } @@ -388,38 +388,38 @@ case $1 in activate) echo "adding ${CURDIR} to \$PATH..." export PATH="${PATH}:${CURDIR}" - eval $(luarocks path bin) - exec ${SHELL} + eval "$(luarocks path bin)" + exec "${SHELL}" ;; fetch-thirdparty) kodev-fetch-thirdparty ;; clean) shift 1 - kodev-clean $@ + kodev-clean "$@" ;; build) shift 1 - kodev-build $@ + kodev-build "$@" ;; release) shift 1 - kodev-release $@ + kodev-release "$@" ;; wbuilder) kodev-wbuilder ;; run) shift 1 - kodev-run $@ + kodev-run "$@" ;; test) shift 1 - kodev-test $@ + kodev-test "$@" ;; log) shift 1 - kodev-log $@ + kodev-log "$@" ;; --help | -h) echo "${HELP_MSG}" From 8643d38a681df3ea01e920a8773ddfd7bf7df0fa Mon Sep 17 00:00:00 2001 From: Frans de Jonge Date: Fri, 6 May 2016 18:51:10 +0200 Subject: [PATCH 32/35] Removed some bashisms --- platform/kobo/koreader.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/platform/kobo/koreader.sh b/platform/kobo/koreader.sh index 5000f7554..9647f3dc8 100755 --- a/platform/kobo/koreader.sh +++ b/platform/kobo/koreader.sh @@ -35,7 +35,7 @@ if pkill -0 nickel ; then FROM_NICKEL="true" fi -if [ "${FROM_NICKEL}" == "true" ] ; then +if [ "${FROM_NICKEL}" = "true" ] ; then # Detect if we were started from KFMon FROM_KFMON="false" if pkill -0 kfmon ; then @@ -45,7 +45,7 @@ if [ "${FROM_NICKEL}" == "true" ] ; then fi fi - if [ "${FROM_KFMON}" == "true" ] ; then + if [ "${FROM_KFMON}" = "true" ] ; then # Siphon nickel's full environment, since KFMon inherits such a minimal one, and that apparently confuses the hell out of Nickel for some reason if we decide to restart it without a reboot... for env in $(xargs -n 1 -0 < /proc/$(pidof nickel)/environ) ; do export ${env} @@ -75,7 +75,7 @@ fi if [ "$#" -eq 0 ] ; then args="/mnt/onboard" else - args="$@" + args="$*" fi # check whether PLATFORM & PRODUCT have a value assigned by rcS @@ -93,7 +93,7 @@ if [ ! -n "${PLATFORM}" ] ; then PLATFORM="${CPU}-ntx" fi - if [ "${PLATFORM}" == "freescale" ] ; then + if [ "${PLATFORM}" = "freescale" ] ; then if [ ! -s "/lib/firmware/imx/epdc_E60_V220.fw" ] ; then mkdir -p "/lib/firmware/imx" dd if="/dev/mmcblk0" bs=512K skip=10 count=1 | zcat > "/lib/firmware/imx/epdc_E60_V220.fw" @@ -113,7 +113,7 @@ fi ./reader.lua "${args}" > crash.log 2>&1 -if [ "${FROM_NICKEL}" == "true" ] ; then +if [ "${FROM_NICKEL}" = "true" ] ; then if [ "${FROM_KFMON}" != "true" ] ; then # start kobo software because it was running before koreader ./nickel.sh & From 1aa0c4192aaab6915cd0dc5ddb7b503f5534356d Mon Sep 17 00:00:00 2001 From: Zijie He Date: Mon, 25 Apr 2016 19:45:55 -0700 Subject: [PATCH 33/35] Multi-line toggle switch & add instruction to resolve sdcv build error. --- README.md | 5 ++ .../apps/reader/modules/readercropping.lua | 12 +++- frontend/ui/data/creoptions.lua | 1 - frontend/ui/data/koptoptions.lua | 1 - frontend/ui/widget/configdialog.lua | 8 ++- frontend/ui/widget/toggleswitch.lua | 57 ++++++++++++------- 6 files changed, 58 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 83959578c..c7e1f6883 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,11 @@ sudo apt-get install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf sudo apt-get install gcc-mingw-w64-i686 g++-mingw-w64-i686 ``` +Packages pkg-config-arm-linux-gnueabihf and pkg-config-arm-linux-gnueabi may +block you to build for Kobo or Kindle, remove them if you got ld error, +`/usr/lib/gcc-cross/arm-linux-gnueabihf/4.8/../../../../arm-linux-gnueabihf/bin/ +ld: cannot find -lglib-2.0` + Mac OSX users may need to install these tools: ``` brew install nasm binutils libtool autoconf automake sdl2 diff --git a/frontend/apps/reader/modules/readercropping.lua b/frontend/apps/reader/modules/readercropping.lua index 32f5648b2..c5a75b490 100644 --- a/frontend/apps/reader/modules/readercropping.lua +++ b/frontend/apps/reader/modules/readercropping.lua @@ -168,14 +168,20 @@ end function ReaderCropping:setCropZoomMode(confirmed) if confirmed then -- if original zoom mode is not "content", set zoom mode to "contentwidth" - self.ui:handleEvent(Event:new("SetZoomMode", - self.orig_zoom_mode:find("content") and self.orig_zoom_mode or "contentwidth")) + self:setZoomMode( + self.orig_zoom_mode:find("content") + and self.orig_zoom_mode + or "contentwidth") self.ui:handleEvent(Event:new("InitScrollPageStates")) else - self.ui:handleEvent(Event:new("SetZoomMode", self.orig_zoom_mode)) + self:setZoomMode(self.orig_zoom_mode) end end +function ReaderCropping:setZoomMode(mode) + self.ui:handleEvent(Event:new("SetZoomMode", mode)) +end + function ReaderCropping:onReadSettings(config) self.document.bbox = config:readSetting("bbox") end diff --git a/frontend/ui/data/creoptions.lua b/frontend/ui/data/creoptions.lua index a18717f4d..aed602129 100644 --- a/frontend/ui/data/creoptions.lua +++ b/frontend/ui/data/creoptions.lua @@ -91,7 +91,6 @@ local CreOptions = { event = "ChangeSize", args = {"decrease", "increase"}, alternate = false, - height = 60, } } }, diff --git a/frontend/ui/data/koptoptions.lua b/frontend/ui/data/koptoptions.lua index beb2c7004..4aa4efe8d 100644 --- a/frontend/ui/data/koptoptions.lua +++ b/frontend/ui/data/koptoptions.lua @@ -144,7 +144,6 @@ local KoptOptions = { event = "FineTuningFontSize", args = {-0.05, 0.05}, alternate = false, - height = 60, enabled_func = function(configurable) return enable_if_equals(configurable, "text_wrap", 1) end, diff --git a/frontend/ui/widget/configdialog.lua b/frontend/ui/widget/configdialog.lua index 786ec8a22..4ccfd5e2e 100644 --- a/frontend/ui/widget/configdialog.lua +++ b/frontend/ui/widget/configdialog.lua @@ -353,9 +353,14 @@ function ConfigOption:init() if self.options[c].toggle then local max_toggle_width = Screen:getWidth() / 2 - local toggle_width = Screen:scaleBySize(self.options[c].width or 216) + local toggle_width = Screen:scaleBySize(self.options[c].width + or 216) + local row_count = self.options[c].row_count or 1 + local toggle_height = Screen:scaleBySize(self.options[c].height + or 30 * row_count) local switch = ToggleSwitch:new{ width = math.min(max_toggle_width, toggle_width), + height = toggle_height, font_face = item_font_face, font_size = item_font_size, name = self.options[c].name, @@ -368,6 +373,7 @@ function ConfigOption:init() events = self.options[c].events, config = self.config, enabled = enabled, + row_count = row_count, } local position = current_item switch:setPosition(position) diff --git a/frontend/ui/widget/toggleswitch.lua b/frontend/ui/widget/toggleswitch.lua index 8d6dcad4b..79419f20d 100644 --- a/frontend/ui/widget/toggleswitch.lua +++ b/frontend/ui/widget/toggleswitch.lua @@ -3,6 +3,7 @@ local InputContainer = require("ui/widget/container/inputcontainer") local FrameContainer = require("ui/widget/container/framecontainer") local CenterContainer = require("ui/widget/container/centercontainer") local HorizontalGroup = require("ui/widget/horizontalgroup") +local VerticalGroup = require("ui/widget/verticalgroup") local Font = require("ui/font") local Geom = require("ui/geometry") local RenderText = require("ui/rendertext") @@ -31,10 +32,12 @@ local ToggleSwitch = InputContainer:new{ font_face = "cfont", font_size = 16, enabled = true, + row_count = 1, } function ToggleSwitch:init() - self.n_pos = #self.toggle + -- Item count per row + self.n_pos = math.ceil(#self.toggle / self.row_count) self.position = nil self.toggle_frame = FrameContainer:new{ @@ -45,16 +48,24 @@ function ToggleSwitch:init() padding = 2, dim = not self.enabled, } - self.toggle_content = HorizontalGroup:new{} - for i=1,#self.toggle do + self.toggle_content = VerticalGroup:new{} + for i = 1, self.row_count do + table.insert(self.toggle_content, HorizontalGroup:new{}) + end + + local center_dimen = Geom:new{ + w = self.width / self.n_pos, + h = self.height / self.row_count, + } + for i = 1, #self.toggle do local label = ToggleLabel:new{ align = "center", text = self.toggle[i], face = Font:getFace(self.font_face, self.font_size), } local content = CenterContainer:new{ - dimen = Geom:new{w = self.width/self.n_pos, h = self.height}, + dimen = center_dimen, label, } local button = FrameContainer:new{ @@ -66,7 +77,7 @@ function ToggleSwitch:init() padding = 0, content, } - table.insert(self.toggle_content, button) + table.insert(self.toggle_content[math.ceil(i / self.n_pos)], button) end self.toggle_frame[1] = self.toggle_content @@ -94,15 +105,19 @@ end function ToggleSwitch:update() local pos = self.position - for i=1,#self.toggle_content do - if pos == i then - self.toggle_content[i].color = self.fgcolor - self.toggle_content[i].background = self.fgcolor - self.toggle_content[i][1][1].fgcolor = Blitbuffer.COLOR_WHITE - else - self.toggle_content[i].color = self.bgcolor - self.toggle_content[i].background = self.bgcolor - self.toggle_content[i][1][1].fgcolor = Blitbuffer.COLOR_BLACK + for i = 1, #self.toggle_content do + local row = self.toggle_content[i] + for j = 1, #row do + local cell = row[j] + if pos == (i - 1) * self.n_pos + j then + cell.color = self.fgcolor + cell.background = self.fgcolor + cell[1][1].fgcolor = Blitbuffer.COLOR_WHITE + else + cell.color = self.bgcolor + cell.background = self.bgcolor + cell[1][1].fgcolor = Blitbuffer.COLOR_BLACK + end end end end @@ -124,11 +139,15 @@ function ToggleSwitch:togglePosition(position) self:update() end +function ToggleSwitch:calculatePosition(gev) + local x = (gev.pos.x - self.dimen.x) / self.dimen.w * self.n_pos + local y = (gev.pos.y - self.dimen.y) / self.dimen.h * self.row_count + return math.ceil(x) + math.floor(y) * self.n_pos +end + function ToggleSwitch:onTapSelect(arg, gev) if not self.enabled then return true end - local position = math.ceil( - (gev.pos.x - self.dimen.x) / self.dimen.w * self.n_pos - ) + local position = self:calculatePosition(gev) self:togglePosition(position) --[[ if self.values then @@ -152,9 +171,7 @@ function ToggleSwitch:onTapSelect(arg, gev) end function ToggleSwitch:onHoldSelect(arg, gev) - local position = math.ceil( - (gev.pos.x - self.dimen.x) / self.dimen.w * self.n_pos - ) + local position = self:calculatePosition(gev) self.config:onMakeDefault(self.name, self.name_text, self.values or self.args, self.toggle, position) return true From 5e8c045fcb216c3dcff3918544ddc5d8e6eb830a Mon Sep 17 00:00:00 2001 From: chrox Date: Fri, 13 May 2016 00:46:03 +0800 Subject: [PATCH 34/35] Bump k2pdfopt to v2.34, tesseract-ocr to 3.04 and leptonica to v1.72 --- base | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base b/base index 88aa05b66..edfd1239c 160000 --- a/base +++ b/base @@ -1 +1 @@ -Subproject commit 88aa05b664b8b5c276e13976905b8126c15486d2 +Subproject commit edfd1239c685e930fd0918bab6eb80267555aead From 4c491b5ee2d7bdcd8614712f22d358cde9ca4fe7 Mon Sep 17 00:00:00 2001 From: chrox Date: Sat, 14 May 2016 12:19:24 +0800 Subject: [PATCH 35/35] rename 'Highlight' to 'Highlight options' in menu This should fix #2023. --- .../apps/reader/modules/readerhighlight.lua | 2 +- frontend/ui/data/creoptions.lua | 20 +++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/frontend/apps/reader/modules/readerhighlight.lua b/frontend/apps/reader/modules/readerhighlight.lua index 9fbc4a5f0..cfbbebde7 100644 --- a/frontend/apps/reader/modules/readerhighlight.lua +++ b/frontend/apps/reader/modules/readerhighlight.lua @@ -66,7 +66,7 @@ end function ReaderHighlight:addToMainMenu(tab_item_table) -- insert table to main reader menu table.insert(tab_item_table.typeset, { - text = _("Highlight"), + text = _("Highlight options"), sub_item_table = self:genHighlightDrawerMenu(), }) end diff --git a/frontend/ui/data/creoptions.lua b/frontend/ui/data/creoptions.lua index aed602129..05f1addbc 100644 --- a/frontend/ui/data/creoptions.lua +++ b/frontend/ui/data/creoptions.lua @@ -34,6 +34,16 @@ local CreOptions = { { icon = "resources/icons/appbar.column.two.large.png", options = { + { + name = "view_mode", + name_text = S.VIEW_MODE, + toggle = {S.VIEW_SCROLL, S.VIEW_PAGE}, + values = {1, 0}, + default_value = 0, + args = {"scroll", "page"}, + default_arg = "page", + event = "SetViewMode", + }, { name = "line_spacing", name_text = S.LINE_SPACING, @@ -128,16 +138,6 @@ local CreOptions = { { icon = "resources/icons/appbar.settings.large.png", options = { - { - name = "view_mode", - name_text = S.VIEW_MODE, - toggle = {S.VIEW_SCROLL, S.VIEW_PAGE}, - values = {1, 0}, - default_value = 0, - args = {"scroll", "page"}, - default_arg = "page", - event = "SetViewMode", - }, { name = "status_line", name_text = S.PROGRESS_BAR,