From 764f8ba647d6cb506983b338fce2bf389e4f83d4 Mon Sep 17 00:00:00 2001 From: zwim <36999612+zwim@users.noreply.github.com> Date: Wed, 6 Mar 2024 16:49:09 +0100 Subject: [PATCH 01/13] bump base: Use Bresenham's algorithm and anti-aliasing for rounded corners --- base | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base b/base index 8f5f38d73..ab2828199 160000 --- a/base +++ b/base @@ -1 +1 @@ -Subproject commit 8f5f38d732bba170abdae5df015f9f4b475fac6e +Subproject commit ab2828199a6811bac3326f013bbb7051a8d1f73a From 58b3367d180dd46c0c9781b6067bf8b7f0cee2d0 Mon Sep 17 00:00:00 2001 From: zwim <36999612+zwim@users.noreply.github.com> Date: Mon, 26 Feb 2024 19:51:01 +0100 Subject: [PATCH 02/13] anti alias rounded corners in UI --- frontend/apps/filemanager/filemanagermenu.lua | 9 +++++++++ .../ui/widget/container/framecontainer.lua | 18 ++++++++++++------ .../ui/widget/container/inputcontainer.lua | 2 +- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/frontend/apps/filemanager/filemanagermenu.lua b/frontend/apps/filemanager/filemanagermenu.lua index 34888217b..329fcf719 100644 --- a/frontend/apps/filemanager/filemanagermenu.lua +++ b/frontend/apps/filemanager/filemanagermenu.lua @@ -624,6 +624,15 @@ To: end, }) end + table.insert(self.menu_items.developer_options.sub_item_table, { + text = _("Anti-alias rounded corners"), + checked_func = function() + return G_reader_settings:nilOrTrue("anti_alias_ui") + end, + callback = function() + G_reader_settings:flipNilOrTrue("anti_alias_ui") + end, + }) --- @note: Currently, only Kobo implements this quirk if Device:hasEinkScreen() and Device:isKobo() then table.insert(self.menu_items.developer_options.sub_item_table, { diff --git a/frontend/ui/widget/container/framecontainer.lua b/frontend/ui/widget/container/framecontainer.lua index 9e0652d1e..855684f6f 100644 --- a/frontend/ui/widget/container/framecontainer.lua +++ b/frontend/ui/widget/container/framecontainer.lua @@ -96,7 +96,7 @@ function FrameContainer:paintTo(bb, x, y) if not self.dimen then self.dimen = Geom:new{ x = x, y = y, - w = my_size.w, h = my_size.h + w = my_size.w, h = my_size.h, } else self.dimen.x = x @@ -110,11 +110,16 @@ function FrameContainer:paintTo(bb, x, y) shift_x = container_width - my_size.w end - --- @todo get rid of margin here? 13.03 2013 (houqp) if self.background then - bb:paintRoundedRect(x, y, - container_width, container_height, - self.background, self.radius) + if not self.radius or not self.bordersize then + bb:paintRoundedRect(x, y, + container_width, container_height, + self.background, self.radius) + else + bb:paintRoundedRect(x, y, + container_width, container_height, + self.background, self.radius + self.bordersize) + end end if self.stripe_width and self.stripe_color and not self.stripe_over then -- (No support for radius when hatched/stripe) @@ -130,10 +135,11 @@ function FrameContainer:paintTo(bb, x, y) self.inner_bordersize, self.color, self.radius) end if self.bordersize > 0 then + local anti_alias = G_reader_settings:nilOrTrue("anti_alias_ui") bb:paintBorder(x + self.margin, y + self.margin, container_width - self.margin * 2, container_height - self.margin * 2, - self.bordersize, self.color, self.radius) + self.bordersize, self.color, self.radius, anti_alias) end if self[1] then self[1]:paintTo(bb, diff --git a/frontend/ui/widget/container/inputcontainer.lua b/frontend/ui/widget/container/inputcontainer.lua index 2f4957335..9ae27e42d 100644 --- a/frontend/ui/widget/container/inputcontainer.lua +++ b/frontend/ui/widget/container/inputcontainer.lua @@ -74,7 +74,7 @@ function InputContainer:paintTo(bb, x, y) local content_size = self[1]:getSize() self.dimen = Geom:new{ x = x, y = y, - w = content_size.w, h = content_size.h + w = content_size.w, h = content_size.h, } else self.dimen.x = x From c65d12803234f149f6e072136a1758312789172a Mon Sep 17 00:00:00 2001 From: poire-z Date: Sat, 9 Mar 2024 09:11:23 +0100 Subject: [PATCH 03/13] Menu, DictQuickLookup, TextViewer: allow mousewheel scrolling (#11525) We also need to catch it in TrapWidget so we can interrupt Wikipedia articles images loading. --- frontend/ui/widget/dictquicklookup.lua | 13 +++++++++++++ frontend/ui/widget/menu.lua | 17 +++++++++++++++++ frontend/ui/widget/textviewer.lua | 9 +++++++++ frontend/ui/widget/trapwidget.lua | 7 +++++++ 4 files changed, 46 insertions(+) diff --git a/frontend/ui/widget/dictquicklookup.lua b/frontend/ui/widget/dictquicklookup.lua index 809f8652c..45722e40c 100644 --- a/frontend/ui/widget/dictquicklookup.lua +++ b/frontend/ui/widget/dictquicklookup.lua @@ -1239,6 +1239,19 @@ function DictQuickLookup:onForwardingPan(arg, ges) end function DictQuickLookup:onForwardingPanRelease(arg, ges) + -- Allow scrolling with the mousewheel + if ges.from_mousewheel and ges.relative and ges.relative.y then + if ges.relative.y < 0 then + if not self.definition_widget[1]:onScrollDown() then + self:onReadNextResult() + end + elseif ges.relative.y > 0 then + if not self.definition_widget[1]:onScrollUp() then + self:onReadPrevResult() + end + end + return true + end -- We can forward onMovablePanRelease() does enough checks return self.movable:onMovablePanRelease(arg, ges) end diff --git a/frontend/ui/widget/menu.lua b/frontend/ui/widget/menu.lua index ffc27a429..368898bbf 100644 --- a/frontend/ui/widget/menu.lua +++ b/frontend/ui/widget/menu.lua @@ -931,6 +931,12 @@ function Menu:init() } } end + self.ges_events.Pan = { -- (for mousewheel scrolling support) + GestureRange:new{ + ges = "pan", + range = self.dimen, + } + } self.ges_events.Close = self.on_close_ges if not Device:hasKeyboard() then @@ -1386,6 +1392,17 @@ function Menu:onSwipe(arg, ges_ev) end end +function Menu:onPan(arg, ges_ev) + if ges_ev.mousewheel_direction then + if ges_ev.direction == "north" then + self:onNextPage() + elseif ges_ev.direction == "south" then + self:onPrevPage() + end + end + return true +end + function Menu:onMultiSwipe(arg, ges_ev) -- For consistency with other fullscreen widgets where swipe south can't be -- used to close and where we then allow any multiswipe to close, allow any diff --git a/frontend/ui/widget/textviewer.lua b/frontend/ui/widget/textviewer.lua index 6a2a91851..cae3ce8e2 100644 --- a/frontend/ui/widget/textviewer.lua +++ b/frontend/ui/widget/textviewer.lua @@ -444,6 +444,15 @@ function TextViewer:onForwardingPan(arg, ges) end function TextViewer:onForwardingPanRelease(arg, ges) + -- Allow scrolling with the mousewheel + if ges.from_mousewheel and ges.relative and ges.relative.y then + if ges.relative.y < 0 then + self.scroll_text_w:scrollText(1) + elseif ges.relative.y > 0 then + self.scroll_text_w:scrollText(-1) + end + return true + end -- We can forward onMovablePanRelease() does enough checks return self.movable:onMovablePanRelease(arg, ges) end diff --git a/frontend/ui/widget/trapwidget.lua b/frontend/ui/widget/trapwidget.lua index bfc708f07..c4b324290 100644 --- a/frontend/ui/widget/trapwidget.lua +++ b/frontend/ui/widget/trapwidget.lua @@ -54,6 +54,9 @@ function TrapWidget:init() SwipeDismiss = { GestureRange:new{ ges = "swipe", range = full_screen, } }, + PanReleaseDismiss = { -- emitted on mousewheel event + GestureRange:new{ ges = "pan_release", range = full_screen, } + }, } end if self.text then @@ -139,6 +142,10 @@ function TrapWidget:onSwipeDismiss(_, ev) return self:_dismissAndResend("Gesture", ev) end +function TrapWidget:onPanReleaseDismiss(_, ev) + return self:_dismissAndResend("Gesture", ev) +end + function TrapWidget:onShow() if self.frame then UIManager:setDirty(self, function() From 66afeebe854148e930c4e5789986d01df3df6cd0 Mon Sep 17 00:00:00 2001 From: hius07 <62179190+hius07@users.noreply.github.com> Date: Sat, 9 Mar 2024 17:02:31 +0200 Subject: [PATCH 04/13] CoverBrowser: show cached cover of deleted file in history (#11523) --- plugins/coverbrowser.koplugin/listmenu.lua | 2 +- plugins/coverbrowser.koplugin/mosaicmenu.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/coverbrowser.koplugin/listmenu.lua b/plugins/coverbrowser.koplugin/listmenu.lua index cf923eead..8d9084f3a 100644 --- a/plugins/coverbrowser.koplugin/listmenu.lua +++ b/plugins/coverbrowser.koplugin/listmenu.lua @@ -265,7 +265,7 @@ function ListMenuItem:update() local bookinfo = BookInfoManager:getBookInfo(self.filepath, self.do_cover_image) - if bookinfo and self.do_cover_image and not bookinfo.ignore_cover then + if bookinfo and self.do_cover_image and not bookinfo.ignore_cover and not self.file_deleted then if bookinfo.cover_fetched then if bookinfo.has_cover and not self.menu.no_refresh_covers then if BookInfoManager.isCachedCoverInvalid(bookinfo, cover_specs) then diff --git a/plugins/coverbrowser.koplugin/mosaicmenu.lua b/plugins/coverbrowser.koplugin/mosaicmenu.lua index 9d33f0c56..1455906a8 100644 --- a/plugins/coverbrowser.koplugin/mosaicmenu.lua +++ b/plugins/coverbrowser.koplugin/mosaicmenu.lua @@ -535,7 +535,7 @@ function MosaicMenuItem:update() local bookinfo = BookInfoManager:getBookInfo(self.filepath, self.do_cover_image) - if bookinfo and self.do_cover_image and not bookinfo.ignore_cover then + if bookinfo and self.do_cover_image and not bookinfo.ignore_cover and not self.file_deleted then if bookinfo.cover_fetched then if bookinfo.has_cover and not self.menu.no_refresh_covers then if BookInfoManager.isCachedCoverInvalid(bookinfo, cover_specs) then From 8df885438c51457ed1e5a6ebbf6441920b4e626f Mon Sep 17 00:00:00 2001 From: hius07 <62179190+hius07@users.noreply.github.com> Date: Sat, 9 Mar 2024 17:03:43 +0200 Subject: [PATCH 05/13] Bookmarks: edit highlighted text (#11484) --- .../apps/reader/modules/readerbookmark.lua | 160 ++++++++++++++---- .../apps/reader/modules/readerhighlight.lua | 15 ++ frontend/ui/widget/menu.lua | 1 + 3 files changed, 141 insertions(+), 35 deletions(-) diff --git a/frontend/apps/reader/modules/readerbookmark.lua b/frontend/apps/reader/modules/readerbookmark.lua index 45f821605..f040adef1 100644 --- a/frontend/apps/reader/modules/readerbookmark.lua +++ b/frontend/apps/reader/modules/readerbookmark.lua @@ -415,6 +415,7 @@ function ReaderBookmark:gotoBookmark(pn_or_xp, marker_xp) end function ReaderBookmark:onShowBookmark(match_table) + self.show_edited_only = nil self.select_mode = false self.filtered_mode = match_table and true or false -- build up item_table @@ -437,9 +438,6 @@ function ReaderBookmark:onShowBookmark(match_table) if not match_table or self:doesBookmarkMatchTable(item, match_table) then item.text_orig = item.text or item.notes item.text = self.display_prefix[item.type] .. item.text_orig - if item.highlighted then - item.drawer = self:getHighlightDrawer(item.datetime) - end item.mandatory = self:getBookmarkPageString(item.page) if (not is_reverse_sorting and i >= curr_page_index) or (is_reverse_sorting and i <= curr_page_index) then item.after_curr_page = true @@ -513,7 +511,7 @@ function ReaderBookmark:onShowBookmark(match_table) end function bm_menu:onMenuHold(item) - local bm_view = T(_("Page: %1"), item.mandatory) .. " " .. T(_("Time: %1"), item.datetime) .. "\n\n" + local bm_view = bookmark._getDialogHeader(item) .. "\n\n" if item.type == "bookmark" then bm_view = bm_view .. item.text else @@ -522,29 +520,46 @@ function ReaderBookmark:onShowBookmark(match_table) bm_view = bm_view .. "\n\n" .. item.text end end + local not_select_mode = not self.select_mode and not bookmark.ui.highlight.select_mode local textviewer textviewer = TextViewer:new{ title = _("Bookmark details"), text = bm_view, text_type = "bookmark", buttons_table = { + { + { + text = _("Reset text"), + enabled = item.highlighted and not_select_mode and item.edited or false, + callback = function() + UIManager:close(textviewer) + bookmark:setHighlightedText(item) + if bookmark.show_edited_only then + table.remove(item_table, item.index) + end + bookmark.refresh() + end, + }, + { + text = _("Edit text"), + enabled = item.highlighted and not_select_mode or false, + callback = function() + UIManager:close(textviewer) + bookmark:editHighlightedText(item) + end, + }, + }, { { text = _("Remove bookmark"), - enabled = not self.select_mode and not bookmark.ui.highlight.select_mode, + enabled = not_select_mode, callback = function() UIManager:show(ConfirmBox:new{ text = _("Remove this bookmark?"), ok_text = _("Remove"), ok_callback = function() bookmark:removeHighlight(item) - -- Also update item_table, so we don't have to rebuilt it in full - for i, v in ipairs(item_table) do - if item.datetime == v.datetime and item.page == v.page then - table.remove(item_table, i) - break - end - end + table.remove(item_table, item.index) bm_menu:switchItemTable(nil, item_table, -1) UIManager:close(textviewer) end, @@ -592,15 +607,12 @@ function ReaderBookmark:onShowBookmark(match_table) bm_menu:setTitleBarLeftIcon("check") else for _, v in ipairs(item_table) do - if v.dim then - v.dim = nil - end + v.dim = nil if v.after_curr_page then v.mandatory_dim = true end end - bm_menu:switchItemTable(bookmark.filtered_mode and _("Bookmarks (search results)") - or _("Bookmarks"), item_table, curr_page_index_filtered) + bm_menu:switchItemTable(nil, item_table, curr_page_index_filtered) bm_menu:setTitleBarLeftIcon("appbar.menu") end end @@ -654,9 +666,7 @@ function ReaderBookmark:onShowBookmark(match_table) callback = function() UIManager:close(bm_dialog) for _, v in ipairs(item_table) do - if v.dim then - v.dim = nil - end + v.dim = nil if v.after_curr_page then v.mandatory_dim = true end @@ -711,8 +721,7 @@ function ReaderBookmark:onShowBookmark(match_table) end end self.select_mode = false - bm_menu:switchItemTable(bookmark.filtered_mode and _("Bookmarks (search results)") - or _("Bookmarks"), item_table, -1) + bm_menu:switchItemTable(nil, item_table, -1) bm_menu:setTitleBarLeftIcon("appbar.menu") end, }) @@ -778,6 +787,15 @@ function ReaderBookmark:onShowBookmark(match_table) end, }, }) + table.insert(buttons, { + { + text = _("Filter by edited highlighted text"), + callback = function() + UIManager:close(bm_dialog) + bookmark:filterByEditedText(bm_menu) + end, + }, + }) table.insert(buttons, {}) table.insert(buttons, { { @@ -884,7 +902,7 @@ end function ReaderBookmark:getBookmarkIndexFullScan(item) for i, v in ipairs(self.bookmarks) do - if item.datetime == v.datetime and item.page == v.page then + if item.datetime == v.datetime then return i end end @@ -996,6 +1014,10 @@ function ReaderBookmark:updateBookmark(item) self:onSaveSettings() end +function ReaderBookmark._getDialogHeader(bookmark) + return T(_("Page: %1"), bookmark.mandatory) .. " " .. T(_("Time: %1"), bookmark.datetime) +end + function ReaderBookmark:setBookmarkNote(item, from_highlight, is_new_note, new_text) local bookmark if from_highlight then @@ -1020,7 +1042,7 @@ function ReaderBookmark:setBookmarkNote(item, from_highlight, is_new_note, new_t end self.input = InputDialog:new{ title = _("Edit note"), - description = " " .. T(_("Page: %1"), bookmark.mandatory) .. " " .. T(_("Time: %1"), bookmark.datetime), + description = " " .. self._getDialogHeader(bookmark), input = input_text, allow_newline = true, add_scroll_buttons = true, @@ -1090,6 +1112,73 @@ function ReaderBookmark:setBookmarkNote(item, from_highlight, is_new_note, new_t self.input:onShowKeyboard() end +function ReaderBookmark:editHighlightedText(item) + local input_dialog + input_dialog = InputDialog:new{ + title = _("Edit highlighted text"), + description = " " .. self._getDialogHeader(item), + input = item.notes, + allow_newline = true, + add_scroll_buttons = true, + use_available_height = true, + buttons = { + { + { + text = _("Cancel"), + id = "close", + callback = function() + UIManager:close(input_dialog) + end, + }, + { + text = _("Save"), + is_enter_default = true, + callback = function() + self:setHighlightedText(item, input_dialog:getInputText()) + UIManager:close(input_dialog) + end, + }, + } + }, + } + UIManager:show(input_dialog) + input_dialog:onShowKeyboard() +end + +function ReaderBookmark:setHighlightedText(item, text) + local edited + if text then + edited = true + else -- reset to selected text + if self.ui.rolling then + text = self.ui.document:getTextFromXPointers(item.pos0, item.pos1) + else + text = self.ui.document:getTextFromPositions(item.pos0, item.pos1).text + end + end + -- highlight + local hl = self.ui.highlight:getHighlightByDatetime(item.datetime) + hl.text = text + hl.edited = edited + -- bookmark + local index = self:getBookmarkIndexBinarySearch(item) or self:getBookmarkIndexFullScan(item) + local bm = self.bookmarks[index] + local is_auto_text_before = self:isBookmarkAutoText(bm) + bm.notes = text + if is_auto_text_before then + bm.text = self:getBookmarkAutoText(bm) + end + bm.edited = edited + -- item table + item.notes = text + item.text_orig = bm.text or text + item.text = self.display_prefix[item.type] .. item.text_orig + item.edited = edited + if edited then + self.refresh() + end +end + function ReaderBookmark:onSearchBookmark(bm_menu) local input_dialog local check_button_case, separator, check_button_bookmark, check_button_highlight, check_button_note @@ -1184,6 +1273,16 @@ function ReaderBookmark:onSearchBookmark(bm_menu) input_dialog:onShowKeyboard() end +function ReaderBookmark:filterByEditedText(bm_menu) + self.show_edited_only = true + for i = #bm_menu.item_table, 1, -1 do + if not bm_menu.item_table[i].edited then + table.remove(bm_menu.item_table, i) + end + end + bm_menu:switchItemTable(_("Bookmarks (edited)"), bm_menu.item_table) +end + function ReaderBookmark:filterByHighlightStyle(bm_dialog, bm_menu) local filter_by_drawer = function(drawer) UIManager:close(bm_dialog) @@ -1199,7 +1298,8 @@ end function ReaderBookmark:doesBookmarkMatchTable(item, match_table) if match_table.drawer then -- filter by highlight style - return item.highlighted and match_table.drawer == item.drawer + return item.highlighted + and match_table.drawer == self.ui.highlight:getHighlightByDatetime(item.datetime).drawer end if match_table[item.type] then if match_table.search_str then @@ -1460,14 +1560,4 @@ function ReaderBookmark:getBookmarkForHighlight(item) return self.bookmarks[self:getBookmarkIndexFullScan(item)] end -function ReaderBookmark:getHighlightDrawer(datetime) - for page, highlights in pairs(self.view.highlight.saved) do - for _, highlight in ipairs(highlights) do - if highlight.datetime == datetime then - return highlight.drawer - end - end - end -end - return ReaderBookmark diff --git a/frontend/apps/reader/modules/readerhighlight.lua b/frontend/apps/reader/modules/readerhighlight.lua index 945f0a4c2..4e3662aa7 100644 --- a/frontend/apps/reader/modules/readerhighlight.lua +++ b/frontend/apps/reader/modules/readerhighlight.lua @@ -1016,6 +1016,7 @@ function ReaderHighlight:onShowHighlightDialog(page, index, is_auto_text) } if self.ui.rolling then + local enabled = not self.view.highlight.saved[page][index].edited local start_prev = "◁▒▒" local start_next = "▷▒▒" local end_prev = "▒▒◁" @@ -1028,6 +1029,7 @@ function ReaderHighlight:onShowHighlightDialog(page, index, is_auto_text) table.insert(buttons, { { text = start_prev, + enabled = enabled, callback = function() self:updateHighlight(page, index, 0, -1, false) end, @@ -1038,6 +1040,7 @@ function ReaderHighlight:onShowHighlightDialog(page, index, is_auto_text) }, { text = start_next, + enabled = enabled, callback = function() self:updateHighlight(page, index, 0, 1, false) end, @@ -1048,6 +1051,7 @@ function ReaderHighlight:onShowHighlightDialog(page, index, is_auto_text) }, { text = end_prev, + enabled = enabled, callback = function() self:updateHighlight(page, index, 1, -1, false) end, @@ -1057,6 +1061,7 @@ function ReaderHighlight:onShowHighlightDialog(page, index, is_auto_text) }, { text = end_next, + enabled = enabled, callback = function() self:updateHighlight(page, index, 1, 1, false) end, @@ -1812,6 +1817,16 @@ function ReaderHighlight:onUnhighlight(bookmark_item) end end +function ReaderHighlight:getHighlightByDatetime(datetime) + for page, highlights in pairs(self.view.highlight.saved) do + for _, highlight in ipairs(highlights) do + if highlight.datetime == datetime then + return highlight + end + end + end +end + function ReaderHighlight:getHighlightBookmarkItem() if self.hold_pos and not self.selected_text then self:highlightFromHoldPos() diff --git a/frontend/ui/widget/menu.lua b/frontend/ui/widget/menu.lua index 368898bbf..f84b03276 100644 --- a/frontend/ui/widget/menu.lua +++ b/frontend/ui/widget/menu.lua @@ -1065,6 +1065,7 @@ function Menu:updateItems(select_number) -- calculate index in item_table local i = (self.page - 1) * self.perpage + c if i <= #self.item_table then + self.item_table[i].index = i -- item.index is valid only for items that have been displayed local item_shortcut = nil local shortcut_style = "square" if self.is_enable_shortcut then From bdb1c3135cc0ca24322456c16f767c712aa387ae Mon Sep 17 00:00:00 2001 From: hius07 <62179190+hius07@users.noreply.github.com> Date: Sun, 10 Mar 2024 07:57:50 +0200 Subject: [PATCH 06/13] Fulltext search: default mode, fixes (#11507) --- .../apps/reader/modules/readerhighlight.lua | 2 +- frontend/apps/reader/modules/readersearch.lua | 63 ++++++++++++++----- 2 files changed, 49 insertions(+), 16 deletions(-) diff --git a/frontend/apps/reader/modules/readerhighlight.lua b/frontend/apps/reader/modules/readerhighlight.lua index 4e3662aa7..d5d7fe0b4 100644 --- a/frontend/apps/reader/modules/readerhighlight.lua +++ b/frontend/apps/reader/modules/readerhighlight.lua @@ -1958,7 +1958,7 @@ function ReaderHighlight:onHighlightSearch() self:highlightFromHoldPos() if self.selected_text then local text = util.stripPunctuation(cleanupSelectedText(self.selected_text.text)) - self.ui:handleEvent(Event:new("ShowSearchDialog", text)) + self.ui.search:searchText(text) end end diff --git a/frontend/apps/reader/modules/readersearch.lua b/frontend/apps/reader/modules/readersearch.lua index 2fc1d1132..acd0a5c9f 100644 --- a/frontend/apps/reader/modules/readersearch.lua +++ b/frontend/apps/reader/modules/readersearch.lua @@ -83,6 +83,16 @@ function ReaderSearch:addToMainMenu(menu_items) menu_items.fulltext_search_settings = { text = _("Fulltext search settings"), sub_item_table = { + { + text = _("Show all results on text selection"), + help_text = _("When invoked after text selection, show a list with all results instead of highlighting matches in book pages."), + checked_func = function() + return G_reader_settings:isTrue("fulltext_search_find_all") + end, + callback = function() + G_reader_settings:flipNilOrFalse("fulltext_search_find_all") + end, + }, { text_func = function() return T(_("Words in context: %1"), self.findall_nb_context_words) @@ -142,19 +152,36 @@ function ReaderSearch:addToMainMenu(menu_items) } end --- if reverse ~= 0 search backwards -function ReaderSearch:searchCallback(reverse) - local search_text = self.input_dialog:getInputText() - if search_text == "" then return end - -- search_text comes from our keyboard, and may contain multiple diacritics ordered - -- in any order: we'd rather have them normalized, and expect the book content to - -- be proper and normalized text. +function ReaderSearch:searchText(text) -- from highlight dialog + if G_reader_settings:isTrue("fulltext_search_find_all") then + self.ui.highlight:clear() + self:searchCallback(nil, text) + else + self:searchCallback(0, text) -- forward + end +end + +-- if reverse == 1 search backwards +function ReaderSearch:searchCallback(reverse, text) + local search_text = text or self.input_dialog:getInputText() + if search_text == nil or search_text == "" then return end self.ui.doc_settings:saveSetting("fulltext_search_last_search_text", search_text) - self.last_search_text = search_text -- if shown again, show it as it has been inputted - search_text = Utf8Proc.normalize_NFC(search_text) - self.use_regex = self.check_button_regex.checked - self.case_insensitive = not self.check_button_case.checked - local regex_error = self.use_regex and self.ui.document:checkRegex(search_text) + self.last_search_text = search_text + + local regex_error + if text then -- from highlight dialog + self.use_regex = false + self.case_insensitive = true + else -- from input dialog + -- search_text comes from our keyboard, and may contain multiple diacritics ordered + -- in any order: we'd rather have them normalized, and expect the book content to + -- be proper and normalized text. + search_text = Utf8Proc.normalize_NFC(search_text) + self.use_regex = self.check_button_regex.checked + self.case_insensitive = not self.check_button_case.checked + regex_error = self.use_regex and self.ui.document:checkRegex(search_text) + end + if self.use_regex and regex_error ~= 0 then logger.dbg("ReaderSearch: regex error", regex_error, SRELL_ERROR_CODES[regex_error]) local error_message @@ -167,6 +194,7 @@ function ReaderSearch:searchCallback(reverse) else UIManager:close(self.input_dialog) if reverse then + self.last_search_hash = nil self:onShowSearchDialog(search_text, reverse, self.use_regex, self.case_insensitive) else local Trapper = require("ui/trapper") @@ -392,7 +420,6 @@ function ReaderSearch:onShowSearchDialog(text, direction, regex, case_insensitiv icon_height = Screen:scaleBySize(DGENERIC_ICON_SIZE * 0.8), callback = function() self.search_dialog:onClose() - self.last_search_text = text self:onShowFulltextSearchInput() end, }, @@ -500,7 +527,7 @@ function ReaderSearch:searchNext(pattern, direction, regex, case_insensitive) end function ReaderSearch:findAllText(search_text) - local last_search_hash = self.last_search_text .. tostring(self.case_insensitive) .. tostring(self.use_regex) + local last_search_hash = (self.last_search_text or "") .. tostring(self.case_insensitive) .. tostring(self.use_regex) local not_cached = self.last_search_hash ~= last_search_hash if not_cached then local Trapper = require("ui/trapper") @@ -525,7 +552,7 @@ function ReaderSearch:findAllText(search_text) end function ReaderSearch:onShowFindAllResults(not_cached) - if not not_cached and self.findall_results == nil then + if not self.last_search_hash or (not not_cached and self.findall_results == nil) then -- no cached results, show input dialog self:onShowFulltextSearchInput() return @@ -546,9 +573,15 @@ function ReaderSearch:onShowFindAllResults(not_cached) local text = TextBoxWidget.PTF_BOLD_START .. word .. TextBoxWidget.PTF_BOLD_END -- append context before and after the word if item.prev_text then + if not item.prev_text:find("%s$") then + text = " " .. text + end text = item.prev_text .. text end if item.next_text then + if not item.next_text:find("^[%s%p]") then + text = text .. " " + end text = text .. item.next_text end text = TextBoxWidget.PTF_HEADER .. text -- enable handling of our bold tags From 6f896e9383008d1e9f07369f39b814aece3ff211 Mon Sep 17 00:00:00 2001 From: hius07 <62179190+hius07@users.noreply.github.com> Date: Sun, 10 Mar 2024 08:05:30 +0200 Subject: [PATCH 07/13] ReaderFooter: chapter progress bar (#11505) --- frontend/apps/reader/modules/readerfooter.lua | 123 +++++++++++++----- frontend/dispatcher.lua | 4 +- frontend/ui/widget/progresswidget.lua | 16 +-- 3 files changed, 103 insertions(+), 40 deletions(-) diff --git a/frontend/apps/reader/modules/readerfooter.lua b/frontend/apps/reader/modules/readerfooter.lua index 3a9ac5cab..0a9fcd5e5 100644 --- a/frontend/apps/reader/modules/readerfooter.lua +++ b/frontend/apps/reader/modules/readerfooter.lua @@ -304,15 +304,7 @@ local footerTextGeneratorMap = { return prefix .. " " .. left end, chapter_progress = function(footer) - local current = footer.ui.toc:getChapterPagesDone(footer.pageno) - -- We want a page number, not a page read count - if current then - current = current + 1 - else - current = footer.pageno - end - local total = footer.ui.toc:getChapterPageCount(footer.pageno) or footer.pages - return current .. " ⁄⁄ " .. total + return footer:getChapterProgress() end, percentage = function(footer) local symbol_type = footer.settings.item_prefix @@ -446,6 +438,7 @@ local ReaderFooter = WidgetContainer:extend{ -- which is why it's public. ReaderFooter.default_settings = { disable_progress_bar = false, -- enable progress bar by default + chapter_progress_bar = false, -- the whole book disabled = false, all_at_once = false, reclaim_height = false, @@ -1643,6 +1636,19 @@ With this enabled, the current page is included, so the count goes from n to 1 i self:refreshFooter(true, true) end, }, + { + text = _("Chapter progress"), + help_text = _("Show progress bar for the current chapter, instead of the whole book."), + enabled_func = function() + return not self.settings.disable_progress_bar + end, + checked_func = function() + return self.settings.chapter_progress_bar + end, + callback = function() + self:onToggleChapterProgressBar() + end, + }, { text_func = function() local text = _("alongside items") @@ -1667,16 +1673,6 @@ With this enabled, the current page is included, so the count goes from n to 1 i self:refreshFooter(true, true) end, }, - { - text = _("Below items"), - checked_func = function() - return self.settings.progress_bar_position == "below" - end, - callback = function() - self.settings.progress_bar_position = "below" - self:refreshFooter(true, true) - end, - }, { text = _("Alongside items"), checked_func = function() @@ -1695,6 +1691,16 @@ With this enabled, the current page is included, so the count goes from n to 1 i self:refreshFooter(true, true) end }, + { + text = _("Below items"), + checked_func = function() + return self.settings.progress_bar_position == "below" + end, + callback = function() + self.settings.progress_bar_position = "below" + self:refreshFooter(true, true) + end, + }, }, }, { @@ -1776,10 +1782,10 @@ With this enabled, the current page is included, so the count goes from n to 1 i { text = _("Show chapter markers"), checked_func = function() - return self.settings.toc_markers == true + return self.settings.toc_markers == true and not self.settings.chapter_progress_bar end, enabled_func = function() - return not self.settings.progress_style_thin + return not self.settings.progress_style_thin and not self.settings.chapter_progress_bar end, callback = function() self.settings.toc_markers = not self.settings.toc_markers @@ -1798,7 +1804,8 @@ With this enabled, the current page is included, so the count goes from n to 1 i return T(_("Chapter marker width (%1)"), markers_width_text) end, enabled_func = function() - return not self.settings.progress_style_thin and self.settings.toc_markers + return not self.settings.progress_style_thin and not self.settings.chapter_progress_bar + and self.settings.toc_markers end, sub_item_table = { { @@ -2057,7 +2064,7 @@ function ReaderFooter:setTocMarkers(reset) self.progress_bar.ticks = nil self.pages = self.ui.document:getPageCount() end - if self.settings.toc_markers then + if self.settings.toc_markers and not self.settings.chapter_progress_bar then self.progress_bar.tick_width = Screen:scaleBySize(self.settings.toc_markers_width) if self.progress_bar.ticks ~= nil then -- already computed return @@ -2123,20 +2130,42 @@ end function ReaderFooter:updateFooterPage(force_repaint, full_repaint) if type(self.pageno) ~= "number" then return end - if self.ui.document:hasHiddenFlows() then - local flow = self.ui.document:getPageFlow(self.pageno) - local page = self.ui.document:getPageNumberInFlow(self.pageno) - local pages = self.ui.document:getTotalPagesInFlow(flow) - self.progress_bar:setPercentage(page / pages) + if self.settings.chapter_progress_bar then + if self.progress_bar.initial_pos_marker then + if self.ui.toc:getNextChapter(self.pageno) == self.ui.toc:getNextChapter(self.initial_pageno) then + self.progress_bar.initial_percentage = self:getChapterProgress(true, self.initial_pageno) + else -- initial position is not in the current chapter + self.progress_bar.initial_percentage = -1 -- do not draw initial position marker + end + end + self.progress_bar:setPercentage(self:getChapterProgress(true)) else - self.progress_bar:setPercentage(self.pageno / self.pages) + if self.ui.document:hasHiddenFlows() then + local flow = self.ui.document:getPageFlow(self.pageno) + local page = self.ui.document:getPageNumberInFlow(self.pageno) + local pages = self.ui.document:getTotalPagesInFlow(flow) + self.progress_bar:setPercentage(page / pages) + else + self.progress_bar:setPercentage(self.pageno / self.pages) + end end self:updateFooterText(force_repaint, full_repaint) end function ReaderFooter:updateFooterPos(force_repaint, full_repaint) if type(self.position) ~= "number" then return end - self.progress_bar:setPercentage(self.position / self.doc_height) + if self.settings.chapter_progress_bar then + if self.progress_bar.initial_pos_marker then + if self.pageno and (self.ui.toc:getNextChapter(self.pageno) == self.ui.toc:getNextChapter(self.initial_pageno)) then + self.progress_bar.initial_percentage = self:getChapterProgress(true, self.initial_pageno) + else + self.progress_bar.initial_percentage = -1 + end + end + self.progress_bar:setPercentage(self:getChapterProgress(true)) + else + self.progress_bar:setPercentage(self.position / self.doc_height) + end self:updateFooterText(force_repaint, full_repaint) end @@ -2267,6 +2296,9 @@ function ReaderFooter:onPageUpdate(pageno) end end self.pageno = pageno + if not self.initial_pageno then + self.initial_pageno = pageno + end self.pages = self.ui.document:getPageCount() if toc_markers_update then self:setTocMarkers(true) @@ -2280,6 +2312,9 @@ function ReaderFooter:onPosUpdate(pos, pageno) self.doc_height = self.ui.document.info.doc_height if pageno then self.pageno = pageno + if not self.initial_pageno then + self.initial_pageno = pageno + end self.pages = self.ui.document:getPageCount() self.ui.doc_settings:saveSetting("doc_pages", self.pages) -- for Book information end @@ -2405,6 +2440,31 @@ function ReaderFooter:onToggleFooterMode() return true end +function ReaderFooter:onToggleChapterProgressBar() + self.settings.chapter_progress_bar = not self.settings.chapter_progress_bar + self:setTocMarkers() + if self.progress_bar.initial_pos_marker and not self.settings.chapter_progress_bar then + self.progress_bar.initial_percentage = self.initial_pageno / self.pages + end + self:refreshFooter(true) +end + +function ReaderFooter:getChapterProgress(get_percentage, pageno) + pageno = pageno or self.pageno + local current = self.ui.toc:getChapterPagesDone(pageno) + -- We want a page number, not a page read count + if current then + current = current + 1 + else + current = pageno + end + local total = self.ui.toc:getChapterPageCount(pageno) or self.pages + if get_percentage then + return current / total + end + return current .. " ⁄⁄ " .. total +end + function ReaderFooter:onHoldFooter(ges) -- We're higher priority than readerhighlight_hold, so, make sure we fall through properly... if not self.settings.skim_widget_on_hold then @@ -2443,7 +2503,8 @@ end function ReaderFooter:onResume() -- Reset the initial marker, if any if self.progress_bar.initial_pos_marker then - self.progress_bar.inital_percentage = self.progress_bar.percentage + self.initial_pageno = self.pageno + self.progress_bar.initial_percentage = self.progress_bar.percentage end -- Don't repaint the footer until OutOfScreenSaver if screensaver_delay is enabled... diff --git a/frontend/dispatcher.lua b/frontend/dispatcher.lua index 24909d4b9..f97b42c18 100644 --- a/frontend/dispatcher.lua +++ b/frontend/dispatcher.lua @@ -133,7 +133,8 @@ local settingsList = { open_next_document_in_folder = {category="none", event="OpenNextDocumentInFolder", title=_("Open next document in folder"), reader=true, separator=true}, ---- show_config_menu = {category="none", event="ShowConfigMenu", title=_("Show bottom menu"), reader=true}, - toggle_status_bar = {category="none", event="ToggleFooterMode", title=_("Toggle status bar"), reader=true, separator=true}, + toggle_status_bar = {category="none", event="ToggleFooterMode", title=_("Toggle status bar"), reader=true}, + toggle_chapter_progress_bar = {category="none", event="ToggleChapterProgressBar", title=_("Toggle chapter progress bar"), reader=true, separator=true}, ---- prev_chapter = {category="none", event="GotoPrevChapter", title=_("Previous chapter"), reader=true}, next_chapter = {category="none", event="GotoNextChapter", title=_("Next chapter"), reader=true}, @@ -352,6 +353,7 @@ local dispatcher_menu_order = { ---- "show_config_menu", "toggle_status_bar", + "toggle_chapter_progress_bar", ---- "prev_chapter", "next_chapter", diff --git a/frontend/ui/widget/progresswidget.lua b/frontend/ui/widget/progresswidget.lua index 3706b6d90..166164565 100644 --- a/frontend/ui/widget/progresswidget.lua +++ b/frontend/ui/widget/progresswidget.lua @@ -60,13 +60,13 @@ local ProgressWidget = Widget:extend{ _orig_margin_v = nil, _orig_bordersize = nil, initial_pos_marker = false, -- overlay a marker at the initial percentage position - inital_percentage = nil, + initial_percentage = nil, } function ProgressWidget:init() if self.initial_pos_marker then - if not self.inital_percentage then - self.inital_percentage = self.percentage + if not self.initial_percentage then + self.initial_percentage = self.percentage end self:renderMarkerIcon() @@ -182,11 +182,11 @@ function ProgressWidget:paintTo(bb, x, y) self.fillcolor) -- Overlay the initial position marker on top of that - if self.initial_pos_marker then + if self.initial_pos_marker and self.initial_percentage >= 0 then if self.height <= INITIAL_MARKER_HEIGHT_THRESHOLD then - self.initial_pos_icon:paintTo(bb, Math.round(fill_x + math.ceil(fill_width * self.inital_percentage) - self.height / 4), y - Math.round(self.height / 6)) + self.initial_pos_icon:paintTo(bb, Math.round(fill_x + math.ceil(fill_width * self.initial_percentage) - self.height / 4), y - Math.round(self.height / 6)) else - self.initial_pos_icon:paintTo(bb, Math.round(fill_x + math.ceil(fill_width * self.inital_percentage) - self.height / 2), y) + self.initial_pos_icon:paintTo(bb, Math.round(fill_x + math.ceil(fill_width * self.initial_percentage) - self.height / 2), y) end end end @@ -212,8 +212,8 @@ end function ProgressWidget:setPercentage(percentage) self.percentage = percentage if self.initial_pos_marker then - if not self.inital_percentage then - self.inital_percentage = self.percentage + if not self.initial_percentage then + self.initial_percentage = self.percentage end end end From 93b3e3504d0e2a771fe9d648dc108146d895138a Mon Sep 17 00:00:00 2001 From: poire-z Date: Sun, 10 Mar 2024 12:21:47 +0100 Subject: [PATCH 08/13] bump crengine: better conformance to the HTML Standard rendering Includes: - Hyphenation: update French.pattern - [CI] Add stylelint to help prevent typos in CSS - In-page footnotes: better handle duplicated ids - lvrend: handle in-page footnotes in table - lvstsheet: fix compiler warnings - LVString: ignore CJK chars in lStr_findWordBounds() - lvtext: AddLine(): handle some CJK + space edge case - EPUB: look for EPUB3 cover even when EPUB2 cover advertized - List items: proper per-specs positionning and sizing - epub.css: add/use "@media (-cr-max-cre-dom-version: 20180527)" - fb2def.h: add more HTML element and attributes names - CSS: generic support for handling presentational hints - CSS: add support for private -cr-apply-func: - ldomDocumentWriterFilter: remove attribute to CSS conversion - lvrend: more proper rendering of block images - lvrend: keep margin_left/right updated when "auto" - CSS: add support for handling HTML's align= attribute - lvrend: fix HR and images positionning when floats involved - epub.css, html5.css: minor updates for easier stylesheet switch - epub.css, html5.css: major updates for better conformance - fb2.css: fix CI stylelint warnings Also update to libunibreak 6.0. --- base | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base b/base index ab2828199..5c7d8bc2b 160000 --- a/base +++ b/base @@ -1 +1 @@ -Subproject commit ab2828199a6811bac3326f013bbb7051a8d1f73a +Subproject commit 5c7d8bc2b5ca15938880711f75ddc045251e9625 From 9467034f3f309b8dc0a10690365669bfdcfca871 Mon Sep 17 00:00:00 2001 From: poire-z Date: Sun, 10 Mar 2024 12:21:49 +0100 Subject: [PATCH 09/13] ReaderTypeset: tweak Style> menu logic and defaults - Reword and document most menu items. - Handle internally two default styles, one applying only to FB2/FB2 books, and the other to all other formats. - Also don't reset the stylesheet to epub.css when toggling Embedded Styles to off. --- .../apps/reader/modules/readertypeset.lua | 95 +++++++++++++++---- frontend/document/credocument.lua | 1 + 2 files changed, 79 insertions(+), 17 deletions(-) diff --git a/frontend/apps/reader/modules/readertypeset.lua b/frontend/apps/reader/modules/readertypeset.lua index 5cb9d24b8..29c1d4f03 100644 --- a/frontend/apps/reader/modules/readertypeset.lua +++ b/frontend/apps/reader/modules/readertypeset.lua @@ -17,7 +17,6 @@ local ReaderTypeset = WidgetContainer:extend{ -- @translators This is style in the sense meant by CSS (cascading style sheets), relating to the layout and presentation of the document. See for more information. css_menu_title = C_("CSS", "Style"), css = nil, - internal_css = true, unscaled_margins = nil, } @@ -27,8 +26,16 @@ end function ReaderTypeset:onReadSettings(config) self.css = config:readSetting("css") - or G_reader_settings:readSetting("copt_css") - or self.ui.document.default_css + if not self.css then + if self.ui.document.is_fb2 then + self.css = G_reader_settings:readSetting("copt_fb2_css") + else + self.css = G_reader_settings:readSetting("copt_css") + end + end + if not self.css then + self.css = self.ui.document.default_css + end local tweaks_css = self.ui.styletweak:getCssText() self.ui.document:setStyleSheet(self.css, tweaks_css) @@ -93,7 +100,6 @@ function ReaderTypeset:onToggleEmbeddedStyleSheet(toggle) else self.configurable.embedded_css = 0 text = _("Disabled embedded styles.") - self:setStyleSheet(self.ui.document.default_css) end self.ui.document:setEmbeddedStyleSheet(self.configurable.embedded_css) self.ui:handleEvent(Event:new("UpdatePos")) @@ -165,16 +171,17 @@ local OBSOLETED_CSS = { } function ReaderTypeset:genStyleSheetMenu() - local getStyleMenuItem = function(text, css_file, separator) + local getStyleMenuItem = function(text, css_file, description, fb2_compatible, separator) return { text_func = function() - return text .. (css_file == G_reader_settings:readSetting("copt_css") and " ★" or "") + local css_opt = self.ui.document.is_fb2 and "copt_fb2_css" or "copt_css" + return text .. (css_file == G_reader_settings:readSetting(css_opt) and " ★" or "") end, callback = function() self:setStyleSheet(css_file or self.ui.document.default_css) end, hold_callback = function(touchmenu_instance) - self:makeDefaultStyleSheet(css_file, text, touchmenu_instance) + self:makeDefaultStyleSheet(css_file, text, description, touchmenu_instance) end, checked_func = function() if not css_file then -- "Auto" @@ -182,6 +189,16 @@ function ReaderTypeset:genStyleSheetMenu() end return css_file == self.css end, + enabled_func = function() + if fb2_compatible == true and not self.ui.document.is_fb2 then + return false + end + if fb2_compatible == false and self.ui.document.is_fb2 then + return false + end + -- if fb2_compatible==nil, we don't know (user css file) + return true + end, separator = separator, } end @@ -189,8 +206,18 @@ function ReaderTypeset:genStyleSheetMenu() local style_table = {} local obsoleted_table = {} - table.insert(style_table, getStyleMenuItem(_("None"), "")) - table.insert(style_table, getStyleMenuItem(_("Auto"), nil, true)) + table.insert(style_table, getStyleMenuItem( + _("None"), + "", + _("This sets an empty User-Agent stylesheet, and expects the document stylesheet to style everything (which publishers probably don't).\nThis is mostly only interesting for testing.") + )) + table.insert(style_table, getStyleMenuItem( + _("Auto"), + nil, + _("This selects the default and preferred stylesheet for the document type."), + nil, + true -- separator + )) local css_files = {} for f in lfs.dir("./data") do @@ -200,15 +227,39 @@ function ReaderTypeset:genStyleSheetMenu() end -- Add the 3 main styles if css_files["epub.css"] then - table.insert(style_table, getStyleMenuItem(_("HTML / EPUB (epub.css)"), css_files["epub.css"])) + table.insert(style_table, getStyleMenuItem( + _("Traditional book look (epub.css)"), + css_files["epub.css"], + _([[ +This is our book look-alike stylesheet: it extends the HTML standard stylesheet with styles aimed at making HTML content look more like a paper book (with justified text and indentation on paragraphs) than like a web page. +It is perfect for unstyled books, and might make styled books more readable. +It may cause some small issues on some books (miscentered titles, headings or separators, or unexpected text indentation), as publishers don't expect to have our added styles at play and need to reset them; try switching to html5.css when you notice such issues.]]), + false -- not fb2_compatible + )) css_files["epub.css"] = nil end if css_files["html5.css"] then - table.insert(style_table, getStyleMenuItem(_("HTML5 (html5.css)"), css_files["html5.css"])) + table.insert(style_table, getStyleMenuItem( + _("HTML Standard rendering (html5.css)"), + css_files["html5.css"], + _([[ +This stylesheet conforms to the HTML Standard rendering suggestions (with a few limitations), similar to what most web browsers use. +As most publishers nowadays make and test their book with tools based on web browser engines, it is the stylesheet to use to see a book as these publishers intended. +On unstyled books though, it may give them the look of a web page (left aligned paragraphs without indentation and with spacing between them); try switching to epub.css when that happens.]]), + false -- not fb2_compatible + )) css_files["html5.css"] = nil end if css_files["fb2.css"] then - table.insert(style_table, getStyleMenuItem(_("FictionBook (fb2.css)"), css_files["fb2.css"], true)) + table.insert(style_table, getStyleMenuItem( + _("FictionBook (fb2.css)"), + css_files["fb2.css"], + _([[ +This stylesheet is to be used only with FB2 and FB3 documents, which are not classic HTML, and need some specific styling. +(FictionBook 2 & 3 are open XML-based e-book formats which originated and gained popularity in Russia.)]]), + true, -- fb2_compatible + true -- separator + )) css_files["fb2.css"] = nil end -- Add the obsoleted ones to the Obsolete sub menu @@ -216,7 +267,7 @@ function ReaderTypeset:genStyleSheetMenu() for __, css in ipairs(OBSOLETED_CSS) do obsoleted_css[css_files[css]] = css if css_files[css] then - table.insert(obsoleted_table, getStyleMenuItem(css, css_files[css])) + table.insert(obsoleted_table, getStyleMenuItem(css, css_files[css], _("This stylesheet is obsolete: don't use it. It is kept solely to be able to open documents last read years ago and to migrate their highlights."))) css_files[css] = nil end end @@ -227,7 +278,7 @@ function ReaderTypeset:genStyleSheetMenu() end table.sort(user_files) for __, css in ipairs(user_files) do - table.insert(style_table, getStyleMenuItem(css, css_files[css])) + table.insert(style_table, getStyleMenuItem(css, css_files[css], _("This is a user added stylesheet."))) end style_table[#style_table].separator = true @@ -266,6 +317,7 @@ function ReaderTypeset:setStyleSheet(new_css) end end +-- Not used function ReaderTypeset:setEmbededStyleSheetOnly() if self.css ~= nil then -- clear applied css @@ -355,11 +407,20 @@ function ReaderTypeset:addToMainMenu(menu_items) } end -function ReaderTypeset:makeDefaultStyleSheet(css, text, touchmenu_instance) +function ReaderTypeset:makeDefaultStyleSheet(css, name, description, touchmenu_instance) + local text = self.ui.document.is_fb2 and T(_("Set default style for FB2 documents to %1?"), BD.filename(name)) + or T(_("Set default style to %1?"), BD.filename(name)) + if description then + text = text .. "\n\n" .. description + end UIManager:show(ConfirmBox:new{ - text = T(_("Set default style to %1?"), BD.filename(text)), + text = text, ok_callback = function() - G_reader_settings:saveSetting("copt_css", css) + if self.ui.document.is_fb2 then + G_reader_settings:saveSetting("copt_fb2_css", css) + else + G_reader_settings:saveSetting("copt_css", css) + end if touchmenu_instance then touchmenu_instance:updateItems() end end, }) diff --git a/frontend/document/credocument.lua b/frontend/document/credocument.lua index 723056584..2748b5a68 100644 --- a/frontend/document/credocument.lua +++ b/frontend/document/credocument.lua @@ -173,6 +173,7 @@ function CreDocument:init() self.default_css = "./data/epub.css" if file_type == "fb2" or file_type == "fb3" then self.default_css = "./data/fb2.css" + self.is_fb2 = true -- FB2 won't look good with any html-oriented stylesheet end -- This mode must be the same as the default one set as ReaderView.view_mode From e3d7669588a258f028182dd40c181d90c8346fb5 Mon Sep 17 00:00:00 2001 From: poire-z Date: Sun, 10 Mar 2024 12:21:51 +0100 Subject: [PATCH 10/13] Style tweaks: add tweak to avoid some presentational hints --- frontend/ui/data/css_tweaks.lua | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/frontend/ui/data/css_tweaks.lua b/frontend/ui/data/css_tweaks.lua index 7aecc3b2b..c81a3fbd3 100644 --- a/frontend/ui/data/css_tweaks.lua +++ b/frontend/ui/data/css_tweaks.lua @@ -419,6 +419,13 @@ Further small adjustments can be done with 'Line Spacing' in the bottom menu.]]) }, { title = _("Font size and families"), + { + id = "font_no_presentational_hints", + title = _("Ignore font related HTML presentational hints"), + description = _("Ignore HTML attributes that contribute to styles on the elements (bgcolor, text…) and (face, size, color…)."), + css = [[body, font { -cr-hint: no-presentational; }]], + separator = true, + }, { id = "font_family_all_inherit", title = _("Ignore publisher font families"), @@ -564,6 +571,13 @@ body, h1, h2, h3, h4, h5, h6, div, li, td, th { text-indent: 0 !important; } title = _("Tables, links, images"), { title = _("Tables"), + { + id = "table_no_presentational_hints", + title = _("Ignore tables related HTML presentational hints"), + description = _("Ignore HTML attributes that contribute to styles on the element and its sub-elements (ie. align, valign, frame, rules, border, cellpading, cellspacing…)."), + css = [[table, caption, colgroup, col, thead, tbody, tfoot, tr, td, th { -cr-hint: no-presentational; }]], + separator = true, + }, { id = "table_full_width", title = _("Full-width tables"), From 70e6f4ce0943c1cb21abf263f4b2d31fa853fc89 Mon Sep 17 00:00:00 2001 From: poire-z Date: Sun, 10 Mar 2024 12:21:53 +0100 Subject: [PATCH 11/13] util.prettifyCSS(): handle better :is() and similar --- frontend/util.lua | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/frontend/util.lua b/frontend/util.lua index ca90b556e..817b0b740 100644 --- a/frontend/util.lua +++ b/frontend/util.lua @@ -1275,6 +1275,11 @@ function util.prettifyCSS(css_text, condensed) s = s:gsub(";", "\b") return s end) + -- Protect ',' inside () (ie. ":is(td, th)") by replacing them with rare control chars + css_text = css_text:gsub("%b()/", function(s) + s = s:gsub(",", "\v") + return s + end) -- Cleanup declarations (the most nested ones only, which may be -- contained in "@supports (...) {...}" or "@media (...) {...}") css_text = css_text:gsub(" *{([^{}]*)} *", function(s) From 0eaa2d82487a9105a4b94e9278f568fe0c3adb35 Mon Sep 17 00:00:00 2001 From: poire-z Date: Sun, 10 Mar 2024 12:21:55 +0100 Subject: [PATCH 12/13] Wikipedia: tweak EPUB css to force epub.css look Include in the EPUB stylesheet most of our epub.css tweaks, so we get our expected styling even when html5.css is used as the default stylesheet. (Users liking the "web page" look can still get it by enabling some of our existing style tweaks.) --- frontend/ui/wikipedia.lua | 88 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 84 insertions(+), 4 deletions(-) diff --git a/frontend/ui/wikipedia.lua b/frontend/ui/wikipedia.lua index 4ff90f416..8372efbf8 100644 --- a/frontend/ui/wikipedia.lua +++ b/frontend/ui/wikipedia.lua @@ -915,6 +915,84 @@ function Wikipedia:createEpub(epub_path, page, lang, with_images) -- to look more alike wikipedia web pages (that the user can ignore -- with "Embedded Style" off) epub:add("OEBPS/stylesheet.css", [[ +/* Generic styling picked from our epub.css (see it for comments), + to give this epub a book look even if used with html5.css */ +body { + text-align: justify; +} +h1, h2, h3, h4, h5, h6 { + margin-top: 0.7em; + margin-bottom: 0.5em; + hyphens: none; +} +h1 { font-size: 150%; } +h2 { font-size: 140%; } +h3 { font-size: 130%; } +h4 { font-size: 120%; } +h5 { font-size: 110%; } +h6 { font-size: 100%; } +p { + text-indent: 1.2em; + margin-top: 0; + margin-bottom: 0; +} +blockquote { + margin-top: 0.5em; + margin-bottom: 0.5em; + margin-left: 2em; + margin-right: 1em; +} +blockquote:dir(rtl) { + margin-left: 1em; + margin-right: 2em; +} +dl { + margin-left: 0; +} +dt { + margin-left: 0; + margin-top: 0.3em; + font-weight: bold; +} +dd { + margin-left: 1.3em; +} +dd:dir(rtl) { + margin-left: unset; + margin-right: 1.3em; +} +pre { + text-align: left; + margin-top: 0.5em; + margin-bottom: 0.5em; +} +hr { + border-style: solid; +} +table { + font-size: 80%; + margin: 3px 0; + border-spacing: 1px; +} +table table { /* stop imbricated tables from getting smaller */ + font-size: 100%; +} +th, td { + padding: 3px; +} +th { + background-color: #DDD; + text-align: center; +} +table caption { + padding: 4px; + background-color: #EEE; +} +sup { font-size: 70%; } +sub { font-size: 70%; } + +/* Specific for our Wikipedia EPUBs */ + /* Make section headers looks left aligned and avoid some page breaks */ h1, h2 { page-break-before: always; @@ -978,10 +1056,7 @@ a.newwikinonexistent { /* Don't waste left margin for TOC, notes and other lists */ ul, ol { - margin-left: 0; -} -ul:dir(rtl), ol:dir(rtl) { - margin-right: 0; + margin: 0; } /* OL in Wikipedia pages may inherit their style-type from a wrapping div, * ensure they fallback to decimal with inheritance */ @@ -1176,6 +1251,11 @@ table { .citation { font-style: italic; } +abbr.abbr { + /* Prevent these from looking like a link */ + text-decoration: inherit; +} + /* hide some view/edit/discuss short links displayed as "v m d" */ .nv-view, .nv-edit, .nv-talk { display: none; From 5414858b74dbe5788d14231b2978b811223efa91 Mon Sep 17 00:00:00 2001 From: hius07 <62179190+hius07@users.noreply.github.com> Date: Tue, 12 Mar 2024 08:51:33 +0200 Subject: [PATCH 13/13] Menu widget: fix item property name (#11534) --- frontend/apps/reader/modules/readerbookmark.lua | 4 ++-- frontend/ui/widget/menu.lua | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/apps/reader/modules/readerbookmark.lua b/frontend/apps/reader/modules/readerbookmark.lua index f040adef1..216537047 100644 --- a/frontend/apps/reader/modules/readerbookmark.lua +++ b/frontend/apps/reader/modules/readerbookmark.lua @@ -535,7 +535,7 @@ function ReaderBookmark:onShowBookmark(match_table) UIManager:close(textviewer) bookmark:setHighlightedText(item) if bookmark.show_edited_only then - table.remove(item_table, item.index) + table.remove(item_table, item.idx) end bookmark.refresh() end, @@ -559,7 +559,7 @@ function ReaderBookmark:onShowBookmark(match_table) ok_text = _("Remove"), ok_callback = function() bookmark:removeHighlight(item) - table.remove(item_table, item.index) + table.remove(item_table, item.idx) bm_menu:switchItemTable(nil, item_table, -1) UIManager:close(textviewer) end, diff --git a/frontend/ui/widget/menu.lua b/frontend/ui/widget/menu.lua index f84b03276..46e3b4386 100644 --- a/frontend/ui/widget/menu.lua +++ b/frontend/ui/widget/menu.lua @@ -1065,7 +1065,7 @@ function Menu:updateItems(select_number) -- calculate index in item_table local i = (self.page - 1) * self.perpage + c if i <= #self.item_table then - self.item_table[i].index = i -- item.index is valid only for items that have been displayed + self.item_table[i].idx = i -- index is valid only for items that have been displayed local item_shortcut = nil local shortcut_style = "square" if self.is_enable_shortcut then