From ded835f7358b8f41bce3e1d4ea2ef1d43e84cd2f Mon Sep 17 00:00:00 2001 From: poire-z Date: Wed, 13 Mar 2024 17:06:19 +0100 Subject: [PATCH] ReaderToc: add option to show chapter lengths --- frontend/apps/reader/modules/readertoc.lua | 62 +++++++++++++++++++++- frontend/ui/elements/reader_menu_order.lua | 1 + 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/frontend/apps/reader/modules/readertoc.lua b/frontend/apps/reader/modules/readertoc.lua index a70ced5d1..b5058196c 100644 --- a/frontend/apps/reader/modules/readertoc.lua +++ b/frontend/apps/reader/modules/readertoc.lua @@ -104,6 +104,7 @@ end function ReaderToc:resetToc() self.toc = nil + self.toc_menu_items_built = false self.toc_depth = nil self.ticks = nil self.ticks_flattened = nil @@ -191,6 +192,7 @@ function ReaderToc:validateAndFixToc() local cur_page = 0 local max_depth = 0 local cur_seq_by_level = {} + local prev_item_by_level = {} for i = first, last do local item = toc[i] local page = item.page @@ -210,6 +212,24 @@ function ReaderToc:validateAndFixToc() local seq = (cur_seq_by_level[depth] or 0) + 1 item.seq_in_level = seq cur_seq_by_level[depth] = seq + -- Also use this loop to compute chapter lengths + for j=#prev_item_by_level, depth, -1 do + local prev_item = prev_item_by_level[j] + if prev_item then + prev_item.length = page - prev_item.page + end + prev_item_by_level[j] = nil + end + prev_item_by_level[depth] = item + if i == last then -- set the length of the last ones + local page = self.ui.document:getPageCount() + for j=#prev_item_by_level, 0, -1 do + local prev_item = prev_item_by_level[j] + if prev_item then + prev_item.length = page - prev_item.page + end + end + end end if not has_bogus then -- no TOC items, or all are valid logger.dbg("validateAndFixToc(): TOC is fine") @@ -312,6 +332,30 @@ function ReaderToc:validateAndFixToc() end logger.info(string.format("TOC had %d bogus page numbers: fixed %d items to keep them ordered.", nb_bogus, nb_fixed_pages)) self.toc_depth = max_depth + -- Recompute chapter lengths now that pages are fixed + local prev_item_by_level = {} + for i = first, last do + local item = toc[i] + local page = item.page + local depth = item.depth + for j=#prev_item_by_level, depth, -1 do + local prev_item = prev_item_by_level[j] + if prev_item then + prev_item.length = page - prev_item.page + end + prev_item_by_level[j] = nil + end + prev_item_by_level[depth] = item + if i == last then -- set the length of the last ones + local page = self.ui.document:getPageCount() + for j=#prev_item_by_level, 0, -1 do + local prev_item = prev_item_by_level[j] + if prev_item then + prev_item.length = page - prev_item.page + end + end + end + end end function ReaderToc:getTocIndexByPage(pn_or_xp, skip_ignored_ticks) @@ -661,11 +705,13 @@ function ReaderToc:onShowToc() local items_per_page = G_reader_settings:readSetting("toc_items_per_page") or self.toc_items_per_page_default local items_font_size = G_reader_settings:readSetting("toc_items_font_size") or Menu.getItemFontSize(items_per_page) + local items_show_chapter_length = G_reader_settings:isTrue("toc_items_show_chapter_length") local items_with_dots = G_reader_settings:nilOrTrue("toc_items_with_dots") self:fillToc() -- build menu items - if #self.toc > 0 and not self.toc[1].text then + if #self.toc > 0 and not self.toc_menu_items_built then + self.toc_menu_items_built = true -- Have the width of 4 spaces be the unit of indentation local tmp = TextWidget:new{ text = " ", @@ -679,6 +725,9 @@ function ReaderToc:onShowToc() v.index = k v.indent = toc_indent * (v.depth-1) v.text = self:cleanUpTocTitle(v.title, true) + if items_show_chapter_length then + v.text = v.text .. T(" (%1)", v.length) + end v.bidi_wrap_func = BD.auto v.mandatory = v.page if has_hidden_flows then @@ -1147,6 +1196,17 @@ Enabling this option will restrict display to the chapter titles of progress bar UIManager:show(items_font) end, } + menu_items.toc_items_show_chapter_length = { + text = _("Append chapter length"), + keep_menu_open = true, + checked_func = function() + return not G_reader_settings:nilOrFalse("toc_items_show_chapter_length") + end, + callback = function() + G_reader_settings:flipNilOrFalse("toc_items_show_chapter_length") + self.toc_menu_items_built = false + end + } menu_items.toc_items_with_dots = { text = _("With dots"), keep_menu_open = true, diff --git a/frontend/ui/elements/reader_menu_order.lua b/frontend/ui/elements/reader_menu_order.lua index ca48996bf..d64d5f0e6 100644 --- a/frontend/ui/elements/reader_menu_order.lua +++ b/frontend/ui/elements/reader_menu_order.lua @@ -35,6 +35,7 @@ local order = { "----------------------------", "toc_items_per_page", "toc_items_font_size", + "toc_items_show_chapter_length", "toc_items_with_dots", "----------------------------", "toc_alt_toc",