Merge branch 'koreader:master' into master

reviewable/pr11542/r1
SomeGuy 3 months ago committed by GitHub
commit dd618a4e42
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -1 +1 @@
Subproject commit 8f5f38d732bba170abdae5df015f9f4b475fac6e Subproject commit 5c7d8bc2b5ca15938880711f75ddc045251e9625

@ -624,6 +624,15 @@ To:
end, end,
}) })
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 --- @note: Currently, only Kobo implements this quirk
if Device:hasEinkScreen() and Device:isKobo() then if Device:hasEinkScreen() and Device:isKobo() then
table.insert(self.menu_items.developer_options.sub_item_table, { table.insert(self.menu_items.developer_options.sub_item_table, {

@ -415,6 +415,7 @@ function ReaderBookmark:gotoBookmark(pn_or_xp, marker_xp)
end end
function ReaderBookmark:onShowBookmark(match_table) function ReaderBookmark:onShowBookmark(match_table)
self.show_edited_only = nil
self.select_mode = false self.select_mode = false
self.filtered_mode = match_table and true or false self.filtered_mode = match_table and true or false
-- build up item_table -- build up item_table
@ -437,9 +438,6 @@ function ReaderBookmark:onShowBookmark(match_table)
if not match_table or self:doesBookmarkMatchTable(item, match_table) then if not match_table or self:doesBookmarkMatchTable(item, match_table) then
item.text_orig = item.text or item.notes item.text_orig = item.text or item.notes
item.text = self.display_prefix[item.type] .. item.text_orig 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) 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 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 item.after_curr_page = true
@ -513,7 +511,7 @@ function ReaderBookmark:onShowBookmark(match_table)
end end
function bm_menu:onMenuHold(item) 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 if item.type == "bookmark" then
bm_view = bm_view .. item.text bm_view = bm_view .. item.text
else else
@ -522,29 +520,46 @@ function ReaderBookmark:onShowBookmark(match_table)
bm_view = bm_view .. "\n\n" .. item.text bm_view = bm_view .. "\n\n" .. item.text
end end
end end
local not_select_mode = not self.select_mode and not bookmark.ui.highlight.select_mode
local textviewer local textviewer
textviewer = TextViewer:new{ textviewer = TextViewer:new{
title = _("Bookmark details"), title = _("Bookmark details"),
text = bm_view, text = bm_view,
text_type = "bookmark", text_type = "bookmark",
buttons_table = { 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.idx)
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"), text = _("Remove bookmark"),
enabled = not self.select_mode and not bookmark.ui.highlight.select_mode, enabled = not_select_mode,
callback = function() callback = function()
UIManager:show(ConfirmBox:new{ UIManager:show(ConfirmBox:new{
text = _("Remove this bookmark?"), text = _("Remove this bookmark?"),
ok_text = _("Remove"), ok_text = _("Remove"),
ok_callback = function() ok_callback = function()
bookmark:removeHighlight(item) bookmark:removeHighlight(item)
-- Also update item_table, so we don't have to rebuilt it in full table.remove(item_table, item.idx)
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
bm_menu:switchItemTable(nil, item_table, -1) bm_menu:switchItemTable(nil, item_table, -1)
UIManager:close(textviewer) UIManager:close(textviewer)
end, end,
@ -592,15 +607,12 @@ function ReaderBookmark:onShowBookmark(match_table)
bm_menu:setTitleBarLeftIcon("check") bm_menu:setTitleBarLeftIcon("check")
else else
for _, v in ipairs(item_table) do for _, v in ipairs(item_table) do
if v.dim then v.dim = nil
v.dim = nil
end
if v.after_curr_page then if v.after_curr_page then
v.mandatory_dim = true v.mandatory_dim = true
end end
end end
bm_menu:switchItemTable(bookmark.filtered_mode and _("Bookmarks (search results)") bm_menu:switchItemTable(nil, item_table, curr_page_index_filtered)
or _("Bookmarks"), item_table, curr_page_index_filtered)
bm_menu:setTitleBarLeftIcon("appbar.menu") bm_menu:setTitleBarLeftIcon("appbar.menu")
end end
end end
@ -654,9 +666,7 @@ function ReaderBookmark:onShowBookmark(match_table)
callback = function() callback = function()
UIManager:close(bm_dialog) UIManager:close(bm_dialog)
for _, v in ipairs(item_table) do for _, v in ipairs(item_table) do
if v.dim then v.dim = nil
v.dim = nil
end
if v.after_curr_page then if v.after_curr_page then
v.mandatory_dim = true v.mandatory_dim = true
end end
@ -711,8 +721,7 @@ function ReaderBookmark:onShowBookmark(match_table)
end end
end end
self.select_mode = false self.select_mode = false
bm_menu:switchItemTable(bookmark.filtered_mode and _("Bookmarks (search results)") bm_menu:switchItemTable(nil, item_table, -1)
or _("Bookmarks"), item_table, -1)
bm_menu:setTitleBarLeftIcon("appbar.menu") bm_menu:setTitleBarLeftIcon("appbar.menu")
end, end,
}) })
@ -778,6 +787,15 @@ function ReaderBookmark:onShowBookmark(match_table)
end, 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, {})
table.insert(buttons, { table.insert(buttons, {
{ {
@ -884,7 +902,7 @@ end
function ReaderBookmark:getBookmarkIndexFullScan(item) function ReaderBookmark:getBookmarkIndexFullScan(item)
for i, v in ipairs(self.bookmarks) do 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 return i
end end
end end
@ -996,6 +1014,10 @@ function ReaderBookmark:updateBookmark(item)
self:onSaveSettings() self:onSaveSettings()
end 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) function ReaderBookmark:setBookmarkNote(item, from_highlight, is_new_note, new_text)
local bookmark local bookmark
if from_highlight then if from_highlight then
@ -1020,7 +1042,7 @@ function ReaderBookmark:setBookmarkNote(item, from_highlight, is_new_note, new_t
end end
self.input = InputDialog:new{ self.input = InputDialog:new{
title = _("Edit note"), title = _("Edit note"),
description = " " .. T(_("Page: %1"), bookmark.mandatory) .. " " .. T(_("Time: %1"), bookmark.datetime), description = " " .. self._getDialogHeader(bookmark),
input = input_text, input = input_text,
allow_newline = true, allow_newline = true,
add_scroll_buttons = true, add_scroll_buttons = true,
@ -1090,6 +1112,73 @@ function ReaderBookmark:setBookmarkNote(item, from_highlight, is_new_note, new_t
self.input:onShowKeyboard() self.input:onShowKeyboard()
end 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) function ReaderBookmark:onSearchBookmark(bm_menu)
local input_dialog local input_dialog
local check_button_case, separator, check_button_bookmark, check_button_highlight, check_button_note 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() input_dialog:onShowKeyboard()
end 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) function ReaderBookmark:filterByHighlightStyle(bm_dialog, bm_menu)
local filter_by_drawer = function(drawer) local filter_by_drawer = function(drawer)
UIManager:close(bm_dialog) UIManager:close(bm_dialog)
@ -1199,7 +1298,8 @@ end
function ReaderBookmark:doesBookmarkMatchTable(item, match_table) function ReaderBookmark:doesBookmarkMatchTable(item, match_table)
if match_table.drawer then -- filter by highlight style 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 end
if match_table[item.type] then if match_table[item.type] then
if match_table.search_str then if match_table.search_str then
@ -1460,14 +1560,4 @@ function ReaderBookmark:getBookmarkForHighlight(item)
return self.bookmarks[self:getBookmarkIndexFullScan(item)] return self.bookmarks[self:getBookmarkIndexFullScan(item)]
end 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 return ReaderBookmark

@ -304,15 +304,7 @@ local footerTextGeneratorMap = {
return prefix .. " " .. left return prefix .. " " .. left
end, end,
chapter_progress = function(footer) chapter_progress = function(footer)
local current = footer.ui.toc:getChapterPagesDone(footer.pageno) return footer:getChapterProgress()
-- 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
end, end,
percentage = function(footer) percentage = function(footer)
local symbol_type = footer.settings.item_prefix local symbol_type = footer.settings.item_prefix
@ -446,6 +438,7 @@ local ReaderFooter = WidgetContainer:extend{
-- which is why it's public. -- which is why it's public.
ReaderFooter.default_settings = { ReaderFooter.default_settings = {
disable_progress_bar = false, -- enable progress bar by default disable_progress_bar = false, -- enable progress bar by default
chapter_progress_bar = false, -- the whole book
disabled = false, disabled = false,
all_at_once = false, all_at_once = false,
reclaim_height = 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) self:refreshFooter(true, true)
end, 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() text_func = function()
local text = _("alongside items") 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) self:refreshFooter(true, true)
end, 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"), text = _("Alongside items"),
checked_func = function() 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) self:refreshFooter(true, true)
end 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"), text = _("Show chapter markers"),
checked_func = function() checked_func = function()
return self.settings.toc_markers == true return self.settings.toc_markers == true and not self.settings.chapter_progress_bar
end, end,
enabled_func = function() 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, end,
callback = function() callback = function()
self.settings.toc_markers = not self.settings.toc_markers 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) return T(_("Chapter marker width (%1)"), markers_width_text)
end, end,
enabled_func = function() 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, end,
sub_item_table = { sub_item_table = {
{ {
@ -2057,7 +2064,7 @@ function ReaderFooter:setTocMarkers(reset)
self.progress_bar.ticks = nil self.progress_bar.ticks = nil
self.pages = self.ui.document:getPageCount() self.pages = self.ui.document:getPageCount()
end 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) self.progress_bar.tick_width = Screen:scaleBySize(self.settings.toc_markers_width)
if self.progress_bar.ticks ~= nil then -- already computed if self.progress_bar.ticks ~= nil then -- already computed
return return
@ -2123,20 +2130,42 @@ end
function ReaderFooter:updateFooterPage(force_repaint, full_repaint) function ReaderFooter:updateFooterPage(force_repaint, full_repaint)
if type(self.pageno) ~= "number" then return end if type(self.pageno) ~= "number" then return end
if self.ui.document:hasHiddenFlows() then if self.settings.chapter_progress_bar then
local flow = self.ui.document:getPageFlow(self.pageno) if self.progress_bar.initial_pos_marker then
local page = self.ui.document:getPageNumberInFlow(self.pageno) if self.ui.toc:getNextChapter(self.pageno) == self.ui.toc:getNextChapter(self.initial_pageno) then
local pages = self.ui.document:getTotalPagesInFlow(flow) self.progress_bar.initial_percentage = self:getChapterProgress(true, self.initial_pageno)
self.progress_bar:setPercentage(page / pages) 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 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 end
self:updateFooterText(force_repaint, full_repaint) self:updateFooterText(force_repaint, full_repaint)
end end
function ReaderFooter:updateFooterPos(force_repaint, full_repaint) function ReaderFooter:updateFooterPos(force_repaint, full_repaint)
if type(self.position) ~= "number" then return end 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) self:updateFooterText(force_repaint, full_repaint)
end end
@ -2267,6 +2296,9 @@ function ReaderFooter:onPageUpdate(pageno)
end end
end end
self.pageno = pageno self.pageno = pageno
if not self.initial_pageno then
self.initial_pageno = pageno
end
self.pages = self.ui.document:getPageCount() self.pages = self.ui.document:getPageCount()
if toc_markers_update then if toc_markers_update then
self:setTocMarkers(true) self:setTocMarkers(true)
@ -2280,6 +2312,9 @@ function ReaderFooter:onPosUpdate(pos, pageno)
self.doc_height = self.ui.document.info.doc_height self.doc_height = self.ui.document.info.doc_height
if pageno then if pageno then
self.pageno = pageno self.pageno = pageno
if not self.initial_pageno then
self.initial_pageno = pageno
end
self.pages = self.ui.document:getPageCount() self.pages = self.ui.document:getPageCount()
self.ui.doc_settings:saveSetting("doc_pages", self.pages) -- for Book information self.ui.doc_settings:saveSetting("doc_pages", self.pages) -- for Book information
end end
@ -2405,6 +2440,31 @@ function ReaderFooter:onToggleFooterMode()
return true return true
end 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) function ReaderFooter:onHoldFooter(ges)
-- We're higher priority than readerhighlight_hold, so, make sure we fall through properly... -- We're higher priority than readerhighlight_hold, so, make sure we fall through properly...
if not self.settings.skim_widget_on_hold then if not self.settings.skim_widget_on_hold then
@ -2443,7 +2503,8 @@ end
function ReaderFooter:onResume() function ReaderFooter:onResume()
-- Reset the initial marker, if any -- Reset the initial marker, if any
if self.progress_bar.initial_pos_marker then 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 end
-- Don't repaint the footer until OutOfScreenSaver if screensaver_delay is enabled... -- Don't repaint the footer until OutOfScreenSaver if screensaver_delay is enabled...

@ -1016,6 +1016,7 @@ function ReaderHighlight:onShowHighlightDialog(page, index, is_auto_text)
} }
if self.ui.rolling then if self.ui.rolling then
local enabled = not self.view.highlight.saved[page][index].edited
local start_prev = "◁▒▒" local start_prev = "◁▒▒"
local start_next = "▷▒▒" local start_next = "▷▒▒"
local end_prev = "▒▒◁" local end_prev = "▒▒◁"
@ -1028,6 +1029,7 @@ function ReaderHighlight:onShowHighlightDialog(page, index, is_auto_text)
table.insert(buttons, { table.insert(buttons, {
{ {
text = start_prev, text = start_prev,
enabled = enabled,
callback = function() callback = function()
self:updateHighlight(page, index, 0, -1, false) self:updateHighlight(page, index, 0, -1, false)
end, end,
@ -1038,6 +1040,7 @@ function ReaderHighlight:onShowHighlightDialog(page, index, is_auto_text)
}, },
{ {
text = start_next, text = start_next,
enabled = enabled,
callback = function() callback = function()
self:updateHighlight(page, index, 0, 1, false) self:updateHighlight(page, index, 0, 1, false)
end, end,
@ -1048,6 +1051,7 @@ function ReaderHighlight:onShowHighlightDialog(page, index, is_auto_text)
}, },
{ {
text = end_prev, text = end_prev,
enabled = enabled,
callback = function() callback = function()
self:updateHighlight(page, index, 1, -1, false) self:updateHighlight(page, index, 1, -1, false)
end, end,
@ -1057,6 +1061,7 @@ function ReaderHighlight:onShowHighlightDialog(page, index, is_auto_text)
}, },
{ {
text = end_next, text = end_next,
enabled = enabled,
callback = function() callback = function()
self:updateHighlight(page, index, 1, 1, false) self:updateHighlight(page, index, 1, 1, false)
end, end,
@ -1812,6 +1817,16 @@ function ReaderHighlight:onUnhighlight(bookmark_item)
end end
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() function ReaderHighlight:getHighlightBookmarkItem()
if self.hold_pos and not self.selected_text then if self.hold_pos and not self.selected_text then
self:highlightFromHoldPos() self:highlightFromHoldPos()
@ -1943,7 +1958,7 @@ function ReaderHighlight:onHighlightSearch()
self:highlightFromHoldPos() self:highlightFromHoldPos()
if self.selected_text then if self.selected_text then
local text = util.stripPunctuation(cleanupSelectedText(self.selected_text.text)) local text = util.stripPunctuation(cleanupSelectedText(self.selected_text.text))
self.ui:handleEvent(Event:new("ShowSearchDialog", text)) self.ui.search:searchText(text)
end end
end end

@ -83,6 +83,16 @@ function ReaderSearch:addToMainMenu(menu_items)
menu_items.fulltext_search_settings = { menu_items.fulltext_search_settings = {
text = _("Fulltext search settings"), text = _("Fulltext search settings"),
sub_item_table = { 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() text_func = function()
return T(_("Words in context: %1"), self.findall_nb_context_words) return T(_("Words in context: %1"), self.findall_nb_context_words)
@ -142,19 +152,36 @@ function ReaderSearch:addToMainMenu(menu_items)
} }
end end
-- if reverse ~= 0 search backwards function ReaderSearch:searchText(text) -- from highlight dialog
function ReaderSearch:searchCallback(reverse) if G_reader_settings:isTrue("fulltext_search_find_all") then
local search_text = self.input_dialog:getInputText() self.ui.highlight:clear()
if search_text == "" then return end self:searchCallback(nil, text)
-- search_text comes from our keyboard, and may contain multiple diacritics ordered else
-- in any order: we'd rather have them normalized, and expect the book content to self:searchCallback(0, text) -- forward
-- be proper and normalized text. 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.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 self.last_search_text = search_text
search_text = Utf8Proc.normalize_NFC(search_text)
self.use_regex = self.check_button_regex.checked local regex_error
self.case_insensitive = not self.check_button_case.checked if text then -- from highlight dialog
local regex_error = self.use_regex and self.ui.document:checkRegex(search_text) 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 if self.use_regex and regex_error ~= 0 then
logger.dbg("ReaderSearch: regex error", regex_error, SRELL_ERROR_CODES[regex_error]) logger.dbg("ReaderSearch: regex error", regex_error, SRELL_ERROR_CODES[regex_error])
local error_message local error_message
@ -167,6 +194,7 @@ function ReaderSearch:searchCallback(reverse)
else else
UIManager:close(self.input_dialog) UIManager:close(self.input_dialog)
if reverse then if reverse then
self.last_search_hash = nil
self:onShowSearchDialog(search_text, reverse, self.use_regex, self.case_insensitive) self:onShowSearchDialog(search_text, reverse, self.use_regex, self.case_insensitive)
else else
local Trapper = require("ui/trapper") 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), icon_height = Screen:scaleBySize(DGENERIC_ICON_SIZE * 0.8),
callback = function() callback = function()
self.search_dialog:onClose() self.search_dialog:onClose()
self.last_search_text = text
self:onShowFulltextSearchInput() self:onShowFulltextSearchInput()
end, end,
}, },
@ -500,7 +527,7 @@ function ReaderSearch:searchNext(pattern, direction, regex, case_insensitive)
end end
function ReaderSearch:findAllText(search_text) 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 local not_cached = self.last_search_hash ~= last_search_hash
if not_cached then if not_cached then
local Trapper = require("ui/trapper") local Trapper = require("ui/trapper")
@ -525,7 +552,7 @@ function ReaderSearch:findAllText(search_text)
end end
function ReaderSearch:onShowFindAllResults(not_cached) 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 -- no cached results, show input dialog
self:onShowFulltextSearchInput() self:onShowFulltextSearchInput()
return return
@ -546,9 +573,15 @@ function ReaderSearch:onShowFindAllResults(not_cached)
local text = TextBoxWidget.PTF_BOLD_START .. word .. TextBoxWidget.PTF_BOLD_END local text = TextBoxWidget.PTF_BOLD_START .. word .. TextBoxWidget.PTF_BOLD_END
-- append context before and after the word -- append context before and after the word
if item.prev_text then if item.prev_text then
if not item.prev_text:find("%s$") then
text = " " .. text
end
text = item.prev_text .. text text = item.prev_text .. text
end end
if item.next_text then if item.next_text then
if not item.next_text:find("^[%s%p]") then
text = text .. " "
end
text = text .. item.next_text text = text .. item.next_text
end end
text = TextBoxWidget.PTF_HEADER .. text -- enable handling of our bold tags text = TextBoxWidget.PTF_HEADER .. text -- enable handling of our bold tags

@ -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 <https://en.wikipedia.org/wiki/CSS> for more information. -- @translators This is style in the sense meant by CSS (cascading style sheets), relating to the layout and presentation of the document. See <https://en.wikipedia.org/wiki/CSS> for more information.
css_menu_title = C_("CSS", "Style"), css_menu_title = C_("CSS", "Style"),
css = nil, css = nil,
internal_css = true,
unscaled_margins = nil, unscaled_margins = nil,
} }
@ -27,8 +26,16 @@ end
function ReaderTypeset:onReadSettings(config) function ReaderTypeset:onReadSettings(config)
self.css = config:readSetting("css") self.css = config:readSetting("css")
or G_reader_settings:readSetting("copt_css") if not self.css then
or self.ui.document.default_css 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() local tweaks_css = self.ui.styletweak:getCssText()
self.ui.document:setStyleSheet(self.css, tweaks_css) self.ui.document:setStyleSheet(self.css, tweaks_css)
@ -93,7 +100,6 @@ function ReaderTypeset:onToggleEmbeddedStyleSheet(toggle)
else else
self.configurable.embedded_css = 0 self.configurable.embedded_css = 0
text = _("Disabled embedded styles.") text = _("Disabled embedded styles.")
self:setStyleSheet(self.ui.document.default_css)
end end
self.ui.document:setEmbeddedStyleSheet(self.configurable.embedded_css) self.ui.document:setEmbeddedStyleSheet(self.configurable.embedded_css)
self.ui:handleEvent(Event:new("UpdatePos")) self.ui:handleEvent(Event:new("UpdatePos"))
@ -165,16 +171,17 @@ local OBSOLETED_CSS = {
} }
function ReaderTypeset:genStyleSheetMenu() function ReaderTypeset:genStyleSheetMenu()
local getStyleMenuItem = function(text, css_file, separator) local getStyleMenuItem = function(text, css_file, description, fb2_compatible, separator)
return { return {
text_func = function() 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, end,
callback = function() callback = function()
self:setStyleSheet(css_file or self.ui.document.default_css) self:setStyleSheet(css_file or self.ui.document.default_css)
end, end,
hold_callback = function(touchmenu_instance) hold_callback = function(touchmenu_instance)
self:makeDefaultStyleSheet(css_file, text, touchmenu_instance) self:makeDefaultStyleSheet(css_file, text, description, touchmenu_instance)
end, end,
checked_func = function() checked_func = function()
if not css_file then -- "Auto" if not css_file then -- "Auto"
@ -182,6 +189,16 @@ function ReaderTypeset:genStyleSheetMenu()
end end
return css_file == self.css return css_file == self.css
end, 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, separator = separator,
} }
end end
@ -189,8 +206,18 @@ function ReaderTypeset:genStyleSheetMenu()
local style_table = {} local style_table = {}
local obsoleted_table = {} local obsoleted_table = {}
table.insert(style_table, getStyleMenuItem(_("None"), "")) table.insert(style_table, getStyleMenuItem(
table.insert(style_table, getStyleMenuItem(_("Auto"), nil, true)) _("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 = {} local css_files = {}
for f in lfs.dir("./data") do for f in lfs.dir("./data") do
@ -200,15 +227,39 @@ function ReaderTypeset:genStyleSheetMenu()
end end
-- Add the 3 main styles -- Add the 3 main styles
if css_files["epub.css"] then 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 css_files["epub.css"] = nil
end end
if css_files["html5.css"] then 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 css_files["html5.css"] = nil
end end
if css_files["fb2.css"] then 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 css_files["fb2.css"] = nil
end end
-- Add the obsoleted ones to the Obsolete sub menu -- Add the obsoleted ones to the Obsolete sub menu
@ -216,7 +267,7 @@ function ReaderTypeset:genStyleSheetMenu()
for __, css in ipairs(OBSOLETED_CSS) do for __, css in ipairs(OBSOLETED_CSS) do
obsoleted_css[css_files[css]] = css obsoleted_css[css_files[css]] = css
if css_files[css] then 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 css_files[css] = nil
end end
end end
@ -227,7 +278,7 @@ function ReaderTypeset:genStyleSheetMenu()
end end
table.sort(user_files) table.sort(user_files)
for __, css in ipairs(user_files) do 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 end
style_table[#style_table].separator = true style_table[#style_table].separator = true
@ -266,6 +317,7 @@ function ReaderTypeset:setStyleSheet(new_css)
end end
end end
-- Not used
function ReaderTypeset:setEmbededStyleSheetOnly() function ReaderTypeset:setEmbededStyleSheetOnly()
if self.css ~= nil then if self.css ~= nil then
-- clear applied css -- clear applied css
@ -355,11 +407,20 @@ function ReaderTypeset:addToMainMenu(menu_items)
} }
end 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{ UIManager:show(ConfirmBox:new{
text = T(_("Set default style to %1?"), BD.filename(text)), text = text,
ok_callback = function() 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 if touchmenu_instance then touchmenu_instance:updateItems() end
end, end,
}) })

@ -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}, 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}, 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}, prev_chapter = {category="none", event="GotoPrevChapter", title=_("Previous chapter"), reader=true},
next_chapter = {category="none", event="GotoNextChapter", title=_("Next 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", "show_config_menu",
"toggle_status_bar", "toggle_status_bar",
"toggle_chapter_progress_bar",
---- ----
"prev_chapter", "prev_chapter",
"next_chapter", "next_chapter",

@ -173,6 +173,7 @@ function CreDocument:init()
self.default_css = "./data/epub.css" self.default_css = "./data/epub.css"
if file_type == "fb2" or file_type == "fb3" then if file_type == "fb2" or file_type == "fb3" then
self.default_css = "./data/fb2.css" self.default_css = "./data/fb2.css"
self.is_fb2 = true -- FB2 won't look good with any html-oriented stylesheet
end end
-- This mode must be the same as the default one set as ReaderView.view_mode -- This mode must be the same as the default one set as ReaderView.view_mode

@ -419,6 +419,13 @@ Further small adjustments can be done with 'Line Spacing' in the bottom menu.]])
}, },
{ {
title = _("Font size and families"), 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 <body> (bgcolor, text…) and <font> (face, size, color…)."),
css = [[body, font { -cr-hint: no-presentational; }]],
separator = true,
},
{ {
id = "font_family_all_inherit", id = "font_family_all_inherit",
title = _("Ignore publisher font families"), 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, links, images"),
{ {
title = _("Tables"), title = _("Tables"),
{
id = "table_no_presentational_hints",
title = _("Ignore tables related HTML presentational hints"),
description = _("Ignore HTML attributes that contribute to styles on the <table> 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", id = "table_full_width",
title = _("Full-width tables"), title = _("Full-width tables"),

@ -96,7 +96,7 @@ function FrameContainer:paintTo(bb, x, y)
if not self.dimen then if not self.dimen then
self.dimen = Geom:new{ self.dimen = Geom:new{
x = x, y = y, x = x, y = y,
w = my_size.w, h = my_size.h w = my_size.w, h = my_size.h,
} }
else else
self.dimen.x = x self.dimen.x = x
@ -110,11 +110,16 @@ function FrameContainer:paintTo(bb, x, y)
shift_x = container_width - my_size.w shift_x = container_width - my_size.w
end end
--- @todo get rid of margin here? 13.03 2013 (houqp)
if self.background then if self.background then
bb:paintRoundedRect(x, y, if not self.radius or not self.bordersize then
container_width, container_height, bb:paintRoundedRect(x, y,
self.background, self.radius) 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 end
if self.stripe_width and self.stripe_color and not self.stripe_over then if self.stripe_width and self.stripe_color and not self.stripe_over then
-- (No support for radius when hatched/stripe) -- (No support for radius when hatched/stripe)
@ -130,10 +135,11 @@ function FrameContainer:paintTo(bb, x, y)
self.inner_bordersize, self.color, self.radius) self.inner_bordersize, self.color, self.radius)
end end
if self.bordersize > 0 then if self.bordersize > 0 then
local anti_alias = G_reader_settings:nilOrTrue("anti_alias_ui")
bb:paintBorder(x + self.margin, y + self.margin, bb:paintBorder(x + self.margin, y + self.margin,
container_width - self.margin * 2, container_width - self.margin * 2,
container_height - self.margin * 2, container_height - self.margin * 2,
self.bordersize, self.color, self.radius) self.bordersize, self.color, self.radius, anti_alias)
end end
if self[1] then if self[1] then
self[1]:paintTo(bb, self[1]:paintTo(bb,

@ -74,7 +74,7 @@ function InputContainer:paintTo(bb, x, y)
local content_size = self[1]:getSize() local content_size = self[1]:getSize()
self.dimen = Geom:new{ self.dimen = Geom:new{
x = x, y = y, x = x, y = y,
w = content_size.w, h = content_size.h w = content_size.w, h = content_size.h,
} }
else else
self.dimen.x = x self.dimen.x = x

@ -1239,6 +1239,19 @@ function DictQuickLookup:onForwardingPan(arg, ges)
end end
function DictQuickLookup:onForwardingPanRelease(arg, ges) 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 -- We can forward onMovablePanRelease() does enough checks
return self.movable:onMovablePanRelease(arg, ges) return self.movable:onMovablePanRelease(arg, ges)
end end

@ -931,6 +931,12 @@ function Menu:init()
} }
} }
end end
self.ges_events.Pan = { -- (for mousewheel scrolling support)
GestureRange:new{
ges = "pan",
range = self.dimen,
}
}
self.ges_events.Close = self.on_close_ges self.ges_events.Close = self.on_close_ges
if not Device:hasKeyboard() then if not Device:hasKeyboard() then
@ -1059,6 +1065,7 @@ function Menu:updateItems(select_number)
-- calculate index in item_table -- calculate index in item_table
local i = (self.page - 1) * self.perpage + c local i = (self.page - 1) * self.perpage + c
if i <= #self.item_table then if i <= #self.item_table then
self.item_table[i].idx = i -- index is valid only for items that have been displayed
local item_shortcut = nil local item_shortcut = nil
local shortcut_style = "square" local shortcut_style = "square"
if self.is_enable_shortcut then if self.is_enable_shortcut then
@ -1386,6 +1393,17 @@ function Menu:onSwipe(arg, ges_ev)
end end
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) function Menu:onMultiSwipe(arg, ges_ev)
-- For consistency with other fullscreen widgets where swipe south can't be -- 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 -- used to close and where we then allow any multiswipe to close, allow any

@ -60,13 +60,13 @@ local ProgressWidget = Widget:extend{
_orig_margin_v = nil, _orig_margin_v = nil,
_orig_bordersize = nil, _orig_bordersize = nil,
initial_pos_marker = false, -- overlay a marker at the initial percentage position initial_pos_marker = false, -- overlay a marker at the initial percentage position
inital_percentage = nil, initial_percentage = nil,
} }
function ProgressWidget:init() function ProgressWidget:init()
if self.initial_pos_marker then if self.initial_pos_marker then
if not self.inital_percentage then if not self.initial_percentage then
self.inital_percentage = self.percentage self.initial_percentage = self.percentage
end end
self:renderMarkerIcon() self:renderMarkerIcon()
@ -182,11 +182,11 @@ function ProgressWidget:paintTo(bb, x, y)
self.fillcolor) self.fillcolor)
-- Overlay the initial position marker on top of that -- 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 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 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 end
end end
@ -212,8 +212,8 @@ end
function ProgressWidget:setPercentage(percentage) function ProgressWidget:setPercentage(percentage)
self.percentage = percentage self.percentage = percentage
if self.initial_pos_marker then if self.initial_pos_marker then
if not self.inital_percentage then if not self.initial_percentage then
self.inital_percentage = self.percentage self.initial_percentage = self.percentage
end end
end end
end end

@ -444,6 +444,15 @@ function TextViewer:onForwardingPan(arg, ges)
end end
function TextViewer:onForwardingPanRelease(arg, ges) 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 -- We can forward onMovablePanRelease() does enough checks
return self.movable:onMovablePanRelease(arg, ges) return self.movable:onMovablePanRelease(arg, ges)
end end

@ -54,6 +54,9 @@ function TrapWidget:init()
SwipeDismiss = { SwipeDismiss = {
GestureRange:new{ ges = "swipe", range = full_screen, } GestureRange:new{ ges = "swipe", range = full_screen, }
}, },
PanReleaseDismiss = { -- emitted on mousewheel event
GestureRange:new{ ges = "pan_release", range = full_screen, }
},
} }
end end
if self.text then if self.text then
@ -139,6 +142,10 @@ function TrapWidget:onSwipeDismiss(_, ev)
return self:_dismissAndResend("Gesture", ev) return self:_dismissAndResend("Gesture", ev)
end end
function TrapWidget:onPanReleaseDismiss(_, ev)
return self:_dismissAndResend("Gesture", ev)
end
function TrapWidget:onShow() function TrapWidget:onShow()
if self.frame then if self.frame then
UIManager:setDirty(self, function() UIManager:setDirty(self, function()

@ -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 -- to look more alike wikipedia web pages (that the user can ignore
-- with "Embedded Style" off) -- with "Embedded Style" off)
epub:add("OEBPS/stylesheet.css", [[ 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 */ /* Make section headers looks left aligned and avoid some page breaks */
h1, h2 { h1, h2 {
page-break-before: always; page-break-before: always;
@ -978,10 +1056,7 @@ a.newwikinonexistent {
/* Don't waste left margin for TOC, notes and other lists */ /* Don't waste left margin for TOC, notes and other lists */
ul, ol { ul, ol {
margin-left: 0; margin: 0;
}
ul:dir(rtl), ol:dir(rtl) {
margin-right: 0;
} }
/* OL in Wikipedia pages may inherit their style-type from a wrapping div, /* OL in Wikipedia pages may inherit their style-type from a wrapping div,
* ensure they fallback to decimal with inheritance */ * ensure they fallback to decimal with inheritance */
@ -1176,6 +1251,11 @@ table {
.citation { .citation {
font-style: italic; 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" */ /* hide some view/edit/discuss short links displayed as "v m d" */
.nv-view, .nv-edit, .nv-talk { .nv-view, .nv-edit, .nv-talk {
display: none; display: none;

@ -1275,6 +1275,11 @@ function util.prettifyCSS(css_text, condensed)
s = s:gsub(";", "\b") s = s:gsub(";", "\b")
return s return s
end) 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 -- Cleanup declarations (the most nested ones only, which may be
-- contained in "@supports (...) {...}" or "@media (...) {...}") -- contained in "@supports (...) {...}" or "@media (...) {...}")
css_text = css_text:gsub(" *{([^{}]*)} *", function(s) css_text = css_text:gsub(" *{([^{}]*)} *", function(s)

@ -265,7 +265,7 @@ function ListMenuItem:update()
local bookinfo = BookInfoManager:getBookInfo(self.filepath, self.do_cover_image) 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.cover_fetched then
if bookinfo.has_cover and not self.menu.no_refresh_covers then if bookinfo.has_cover and not self.menu.no_refresh_covers then
if BookInfoManager.isCachedCoverInvalid(bookinfo, cover_specs) then if BookInfoManager.isCachedCoverInvalid(bookinfo, cover_specs) then

@ -535,7 +535,7 @@ function MosaicMenuItem:update()
local bookinfo = BookInfoManager:getBookInfo(self.filepath, self.do_cover_image) 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.cover_fetched then
if bookinfo.has_cover and not self.menu.no_refresh_covers then if bookinfo.has_cover and not self.menu.no_refresh_covers then
if BookInfoManager.isCachedCoverInvalid(bookinfo, cover_specs) then if BookInfoManager.isCachedCoverInvalid(bookinfo, cover_specs) then

Loading…
Cancel
Save