From 3554bdd2c4e31c38040381436175318ab32b641f Mon Sep 17 00:00:00 2001 From: chrox Date: Tue, 14 Oct 2014 13:02:48 +0800 Subject: [PATCH 1/4] fix firewall block of calibre companion on Kindle --- platform/kindle/koreader.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/platform/kindle/koreader.sh b/platform/kindle/koreader.sh index bd3e7b1d9..7ad2bce0a 100755 --- a/platform/kindle/koreader.sh +++ b/platform/kindle/koreader.sh @@ -114,10 +114,12 @@ export TESSDATA_PREFIX="data" # export dict directory export STARDICT_DATA_DIR="data/dict" -# accept input ports for zsync plugin logmsg "Setting up IPTables rules . . ." +# accept input ports for zsync plugin iptables -A INPUT -i wlan0 -p udp --dport 5670 -j ACCEPT iptables -A INPUT -i wlan0 -p tcp --dport 49152:49162 -j ACCEPT +# accept input ports for calibre companion +iptables -A INPUT -i wlan0 -p udp --dport 8134 -j ACCEPT # bind-mount system fonts if ! grep ${KOREADER_DIR}/fonts/host /proc/mounts > /dev/null 2>&1 ; then @@ -251,8 +253,9 @@ if [ "${STOP_FRAMEWORK}" == "no" -a "${INIT_TYPE}" == "upstart" ] ; then fi fi -# restore firewall rules logmsg "Restoring IPTables rules . . ." +# restore firewall rules +iptables -D INPUT -i wlan0 -p udp --dport 8134 -j ACCEPT iptables -D INPUT -i wlan0 -p udp --dport 5670 -j ACCEPT iptables -D INPUT -i wlan0 -p tcp --dport 49152:49162 -j ACCEPT From 46963df0bb451e6acc5d4470c13bdd58187ebb4a Mon Sep 17 00:00:00 2001 From: chrox Date: Tue, 14 Oct 2014 13:04:49 +0800 Subject: [PATCH 2/4] don't need to rebuild ota installed package if it's detected --- frontend/ui/otamanager.lua | 6 ++++++ platform/kindle/koreader.sh | 3 ++- platform/kobo/koreader.sh | 5 +++-- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/frontend/ui/otamanager.lua b/frontend/ui/otamanager.lua index 514b44b1a..4f01f901e 100644 --- a/frontend/ui/otamanager.lua +++ b/frontend/ui/otamanager.lua @@ -1,6 +1,7 @@ local InfoMessage = require("ui/widget/infomessage") local ConfirmBox = require("ui/widget/confirmbox") local NetworkMgr = require("ui/networkmgr") +local lfs = require("libs/libkoreader-lfs") local UIManager = require("ui/uimanager") local Device = require("ui/device") local DEBUG = require("dbg") @@ -128,6 +129,11 @@ function OTAManager:fetchAndProcessUpdate() end function OTAManager:_buildLocalPackage() + -- TODO: validate the installed package? + local installed_package = lfs.currentdir() .. "/" .. self.installed_package + if lfs.attributes(installed_package, "mode") == "file" then + return 0 + end return os.execute(string.format( "./tar cvf %s -C .. -T %s --no-recursion", self.installed_package, self.package_indexfile)) diff --git a/platform/kindle/koreader.sh b/platform/kindle/koreader.sh index 7ad2bce0a..e80a1bbf6 100755 --- a/platform/kindle/koreader.sh +++ b/platform/kindle/koreader.sh @@ -83,6 +83,7 @@ cd "${KOREADER_DIR}" # Handle pending OTA update NEWUPDATE="${KOREADER_DIR}/ota/koreader.updated.tar" +INSTALLED="${KOREADER_DIR}/ota/koreader.installed.tar" if [ -f "${NEWUPDATE}" ] ; then logmsg "Updating koreader . . ." # Look for our own GNU tar build to do a fancy progress tracking... @@ -98,7 +99,7 @@ if [ -f "${NEWUPDATE}" ] ; then fi # Cleanup behind us... if [ $? -eq 0 ] ; then - rm "${NEWUPDATE}" + mv "${NEWUPDATE}" "${INSTALLED}" logmsg "Update sucessful :)" eips_print_bottom_centered "Update successful :)" 1 else diff --git a/platform/kobo/koreader.sh b/platform/kobo/koreader.sh index bc4c6aa17..b9f49d34f 100755 --- a/platform/kobo/koreader.sh +++ b/platform/kobo/koreader.sh @@ -5,10 +5,11 @@ export LC_ALL="en_US.UTF-8" KOREADER_DIR=/mnt/onboard/.kobo/koreader # update to new version from OTA directory -NEWUPDATE=${KOREADER_DIR}/ota/koreader.updated.tar +NEWUPDATE="${KOREADER_DIR}/ota/koreader.updated.tar" +INSTALLED="${KOREADER_DIR}/ota/koreader.installed.tar" if [ -f $NEWUPDATE ]; then # TODO: any graphic indication for the updating progress? - cd /mnt/onboard/.kobo && tar xf $NEWUPDATE && rm $NEWUPDATE + cd /mnt/onboard/.kobo && tar xf $NEWUPDATE && mv $NEWUPDATE $INSTALLED fi # we're always starting from our working directory From 7c9130744c1fabdce22078b1f5b91e2bf6fffc5d Mon Sep 17 00:00:00 2001 From: chrox Date: Tue, 14 Oct 2014 21:33:13 +0800 Subject: [PATCH 3/4] add collapsable TOC menu --- frontend/apps/reader/modules/readertoc.lua | 138 ++++++++++++++++-- frontend/ui/widget/menu.lua | 51 +++++-- resources/icons/appbar.control.collapse.png | Bin 0 -> 246 bytes resources/icons/appbar.control.expand.png | Bin 0 -> 213 bytes .../icons/src/appbar.control.collapse.svg | 49 +++++++ resources/icons/src/appbar.control.expand.svg | 49 +++++++ spec/unit/readertoc_spec.lua | 24 ++- 7 files changed, 282 insertions(+), 29 deletions(-) create mode 100644 resources/icons/appbar.control.collapse.png create mode 100644 resources/icons/appbar.control.expand.png create mode 100644 resources/icons/src/appbar.control.collapse.svg create mode 100644 resources/icons/src/appbar.control.expand.svg diff --git a/frontend/apps/reader/modules/readertoc.lua b/frontend/apps/reader/modules/readertoc.lua index 499cde266..9d98a57c5 100644 --- a/frontend/apps/reader/modules/readertoc.lua +++ b/frontend/apps/reader/modules/readertoc.lua @@ -1,11 +1,12 @@ local InputContainer = require("ui/widget/container/inputcontainer") local CenterContainer = require("ui/widget/container/centercontainer") local GestureRange = require("ui/gesturerange") +local Button = require("ui/widget/button") +local UIManager = require("ui/uimanager") local Menu = require("ui/widget/menu") local Geom = require("ui/geometry") local Screen = require("ui/screen") local Device = require("ui/device") -local UIManager = require("ui/uimanager") local Event = require("ui/event") local Font = require("ui/font") local DEBUG = require("dbg") @@ -14,6 +15,10 @@ local _ = require("gettext") local ReaderToc = InputContainer:new{ toc = nil, ticks = {}, + toc_indent = " ", + collapsed_toc = {}, + collapse_depth = 2, + expanded_nodes = {}, toc_menu_title = _("Table of contents"), } @@ -54,6 +59,7 @@ end function ReaderToc:onUpdateToc() self.toc = nil self.ticks = {} + self.collapsed_toc = {} return true end @@ -208,29 +214,66 @@ function ReaderToc:getChapterPagesDone(pageno, level) return previous_chapter end -function ReaderToc:onShowToc() - self:fillToc() - -- build menu items - if #self.toc > 0 and not self.toc[1].text then - for _,v in ipairs(self.toc) do - v.text = (" "):rep(v.depth-1)..self:cleanUpTocTitle(v.title) - v.mandatory = v.page - end - end - -- update current entry - if #self.toc > 0 then - for i=1, #self.toc do - v = self.toc[i] +function ReaderToc:updateCurrentNode() + if #self.collapsed_toc > 0 then + for i, v in ipairs(self.collapsed_toc) do if v.page > self.pageno then - self.toc.current = i > 1 and i - 1 or 1 + self.collapsed_toc.current = i > 1 and i - 1 or 1 break end end end +end +function ReaderToc:onShowToc() + self:fillToc() + local max_depth = self:getMaxDepth() + -- build menu items + if #self.toc > 0 and not self.toc[1].text then + for _,v in ipairs(self.toc) do + v.text = self.toc_indent:rep(v.depth-1)..self:cleanUpTocTitle(v.title) + v.mandatory = v.page + end + end + + -- update collapsible state + self.expand_button = Button:new{ + icon = "resources/icons/appbar.control.expand.png", + bordersize = 0, + show_parent = self, + } + + self.collapse_button = Button:new{ + icon = "resources/icons/appbar.control.collapse.png", + bordersize = 0, + show_parent = self, + } + + if #self.toc > 0 and #self.collapsed_toc == 0 then + local depth = 0 + for i = #self.toc, 1, -1 do + local v = self.toc[i] + -- node v has child node(s) + if v.depth < depth then + v.state = self.expand_button:new{ + callback = function() self:expandToc(i) end, + indent = self.toc_indent:rep(v.depth-1), + } + end + if v.depth < self.collapse_depth then + table.insert(self.collapsed_toc, 1, v) + end + depth = v.depth + end + end + + self:updateCurrentNode() + + local button_size = self.expand_button:getSize() local toc_menu = Menu:new{ title = _("Table of Contents"), - item_table = self.toc, + item_table = self.collapsed_toc, + state_size = button_size, ui = self.ui, is_borderless = true, width = Screen:getWidth(), @@ -264,11 +307,74 @@ function ReaderToc:onShowToc() toc_menu.show_parent = menu_container + self.toc_menu = toc_menu + UIManager:show(menu_container) return true end +-- expand TOC node of index in raw toc table +function ReaderToc:expandToc(index) + table.insert(self.expanded_nodes, index) + local cur_node = self.toc[index] + local cur_depth = cur_node.depth + local collapsed_index = nil + for i, v in ipairs(self.collapsed_toc) do + if v.page == cur_node.page and v.depth == cur_depth + and v.text == cur_node.text then + collapsed_index = i + break + end + end + for i = index + 1, #self.toc do + local v = self.toc[i] + if v.depth == cur_depth + 1 then + collapsed_index = collapsed_index + 1 + table.insert(self.collapsed_toc, collapsed_index, v) + elseif v.depth <= cur_depth then + break + end + end + -- change state of current node to expanded + cur_node.state = self.collapse_button:new{ + callback = function() self:collapseToc(index) end, + indent = self.toc_indent:rep(cur_depth-1), + } + self:updateCurrentNode() + self.toc_menu:swithItemTable(nil, self.collapsed_toc, -1) +end + +-- collapse TOC node of index in raw toc table +function ReaderToc:collapseToc(index) + local cur_node = self.toc[index] + local cur_depth = cur_node.depth + local i = 1 + local is_child_node = false + while i <= #self.collapsed_toc do + local v = self.collapsed_toc[i] + if v.page > cur_node.page and v.depth <= cur_depth then + is_child_node = false + end + if is_child_node then + table.remove(self.collapsed_toc, i) + else + i = i + 1 + end + if v.page == cur_node.page and v.depth == cur_depth + and v.text == cur_node.text then + is_child_node = true + end + end + -- change state of current node to collapsed + cur_node.state = self.expand_button:new{ + callback = function() self:expandToc(index) end, + indent = self.toc_indent:rep(cur_depth-1), + } + self:updateCurrentNode() + self.toc_menu:swithItemTable(nil, self.collapsed_toc, -1) +end + function ReaderToc:addToMainMenu(tab_item_table) -- insert table to main reader menu table.insert(tab_item_table.navi, 1, { diff --git a/frontend/ui/widget/menu.lua b/frontend/ui/widget/menu.lua index 724a94b22..65fc7b0ab 100644 --- a/frontend/ui/widget/menu.lua +++ b/frontend/ui/widget/menu.lua @@ -160,28 +160,51 @@ function MenuItem:init() end local mandatory = self.mandatory and ""..self.mandatory.." " or "" - local mandatory_w = RenderText:sizeUtf8Text(0, self.dimen.w, self.info_face, ""..mandatory, true).x + local mandatory_w = RenderText:sizeUtf8Text(0, self.dimen.w, self.info_face, + ""..mandatory, true, self.bold).x - w = RenderText:sizeUtf8Text(0, self.dimen.w, self.face, self.text, true).x - if w + mandatory_w >= self.content_width then - if Device:isTouchDevice() then - else + local state_button_width = self.state_size.w or 0 + w = RenderText:sizeUtf8Text(0, self.dimen.w, self.face, + self.text, true, self.bold).x + if w + mandatory_w + state_button_width >= self.content_width then + if Device:hasKeyboard() then self.active_key_events.ShowItemDetail = { {"Right"}, doc = "show item detail" } end local indicator = " >> " - local indicator_w = RenderText:sizeUtf8Text(0, self.dimen.w, self.face, indicator, true).x + local indicator_w = RenderText:sizeUtf8Text(0, self.dimen.w, self.face, + indicator, true, self.bold).x self.text = RenderText:getSubTextByWidth(self.text, self.face, - self.content_width - indicator_w - mandatory_w, true) .. indicator + self.content_width - indicator_w - mandatory_w - state_button_width, + true, self.bold) .. indicator end + local state_button = self.state or HorizontalSpan:new{ + width = state_button_width, + } + local state_indent = self.state and self.state.indent or "" + local state_container = LeftContainer:new{ + dimen = Geom:new{w = self.content_width/2, h = self.dimen.h}, + HorizontalGroup:new{ + HorizontalSpan:new{ + width = RenderText:sizeUtf8Text(0, self.dimen.w, self.face, + state_indent, true, self.bold).x, + }, + state_button + } + } local text_container = LeftContainer:new{ dimen = Geom:new{w = self.content_width, h = self.dimen.h}, - TextWidget:new{ - text = self.text, - face = self.face, - bold = self.bold, + HorizontalGroup:new{ + HorizontalSpan:new{ + width = self.state_size.w, + }, + TextWidget:new{ + text = self.text, + face = self.face, + bold = self.bold, + } } } @@ -195,6 +218,7 @@ function MenuItem:init() } self._underline_container = UnderlineContainer:new{ + vertical_align = "center", dimen = Geom:new{ w = self.content_width, h = self.dimen.h @@ -203,16 +227,17 @@ function MenuItem:init() align = "center", OverlapGroup:new{ dimen = Geom:new{w = self.content_width, h = self.dimen.h}, + state_container, text_container, mandatory_container, }, } } - self[1] = FrameContainer:new{ bordersize = 0, padding = 0, HorizontalGroup:new{ + align = "center", HorizontalSpan:new{ width = 5 }, ItemShortCutIcon:new{ dimen = shortcut_icon_dimen, @@ -569,6 +594,8 @@ function Menu:updateItems(select_number) end local item_tmp = MenuItem:new{ show_parent = self.show_parent, + state = self.item_table[i].state, + state_size = self.state_size or {}, text = self.item_table[i].text, mandatory = self.item_table[i].mandatory, bold = self.item_table.current == i, diff --git a/resources/icons/appbar.control.collapse.png b/resources/icons/appbar.control.collapse.png new file mode 100644 index 0000000000000000000000000000000000000000..b87cad71f1d0f0be8078d0acaec799c5e91ac18d GIT binary patch literal 246 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|Y)RhkE)4%caKYZ?lYt_f1s;*b zKpodXn9)gNb_Gz7y~NYkmHi$UACHPo%hEGGK%r(&7sn8d^Jgb*6l6B!V428VwLnB_ zk$Q;0(hJNNEq};IZi}}Md)8gvY@NZ7q0WEn%r=L#ZS3JwSN(HZofRtBa7JWeb(D*d zFasllfZ&-ui)LCX@qH3u*zwz|;Ctg<7KZ7}Gj5*Q!+D=s#&!Ck;|z;m%r#(}(S0s+ l`u;1`@prfUz5m&kG5Y)2<-XF~HbCbvc)I$ztaD0e0sx`BRKoxO literal 0 HcmV?d00001 diff --git a/resources/icons/appbar.control.expand.png b/resources/icons/appbar.control.expand.png new file mode 100644 index 0000000000000000000000000000000000000000..284407b2d44a06c71ac5fac00f880bc205908109 GIT binary patch literal 213 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|Y)RhkE)4%caKYZ?lYt_f1s;*b zKpodXn9)gNb_Gz7y~NYkmHi$UACD^Ijl_i@p(IZi#}JM4YbR~wZ3y6S(HDDjKttz< zU%jGRBKxZR#Gcki--XsMs^sM7``oiT{AvvAb(R^CX+jJPp}jx{C@3ZKFj-vE-0HCW z3!9CWZo}?NY-aWAj(7^EKb1Qk+N^#5c-8w^?Z3=xt%TfxwlR3R`njxgN@xNAMhim~ literal 0 HcmV?d00001 diff --git a/resources/icons/src/appbar.control.collapse.svg b/resources/icons/src/appbar.control.collapse.svg new file mode 100644 index 000000000..101eed96d --- /dev/null +++ b/resources/icons/src/appbar.control.collapse.svg @@ -0,0 +1,49 @@ + +image/svg+xml \ No newline at end of file diff --git a/resources/icons/src/appbar.control.expand.svg b/resources/icons/src/appbar.control.expand.svg new file mode 100644 index 000000000..311087080 --- /dev/null +++ b/resources/icons/src/appbar.control.expand.svg @@ -0,0 +1,49 @@ + +image/svg+xml \ No newline at end of file diff --git a/spec/unit/readertoc_spec.lua b/spec/unit/readertoc_spec.lua index 1b62d8cd1..a4c93098e 100644 --- a/spec/unit/readertoc_spec.lua +++ b/spec/unit/readertoc_spec.lua @@ -24,7 +24,7 @@ describe("Readertoc module", function() local ticks_level_0 = nil it("should get ticks of level 0", function() ticks_level_0 = toc:getTocTicks(0) - DEBUG("ticks", ticks_level_0) + --DEBUG("ticks", ticks_level_0) assert.are.same(28, #ticks_level_0) end) local ticks_level_1 = nil @@ -68,4 +68,26 @@ describe("Readertoc module", function() assert.are.same(0, toc:getChapterPagesDone(100, 0)) assert.are.same(10, toc:getChapterPagesDone(200, 0)) end) + describe("collasible TOC", function() + it("should collapse the secondary toc nodes by default", function() + toc:onShowToc() + assert.are.same(7, #toc.collapsed_toc) + end) + it("should not expand toc nodes that have no child nodes", function() + toc:expandToc(2) + assert.are.same(7, #toc.collapsed_toc) + end) + it("should expand toc nodes that have child nodes", function() + toc:expandToc(3) + assert.are.same(13, #toc.collapsed_toc) + toc:expandToc(18) + assert.are.same(18, #toc.collapsed_toc) + end) + it("should collapse toc nodes that have been expanded", function() + toc:collapseToc(3) + assert.are.same(12, #toc.collapsed_toc) + toc:collapseToc(18) + assert.are.same(7, #toc.collapsed_toc) + end) + end) end) From 96960cd5543714921e6f0aeeea68a02d3c2c0be2 Mon Sep 17 00:00:00 2001 From: chrox Date: Tue, 14 Oct 2014 21:34:09 +0800 Subject: [PATCH 4/4] don't dim icon button by default --- frontend/ui/widget/button.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/ui/widget/button.lua b/frontend/ui/widget/button.lua index fbc5abc33..bafeb87d2 100644 --- a/frontend/ui/widget/button.lua +++ b/frontend/ui/widget/button.lua @@ -41,7 +41,7 @@ function Button:init() else self.label_widget = ImageWidget:new{ file = self.icon, - dim = self.enabled, + dim = not self.enabled, } end local widget_size = self.label_widget:getSize()