Merge branch 'koreader:master' into master

reviewable/pr11542/r1
SomeGuy 2 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
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, {

@ -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.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"),
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.idx)
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

@ -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...

@ -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()
@ -1943,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

@ -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

@ -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.
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,
})

@ -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",

@ -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

@ -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 <body> (bgcolor, text…) and <font> (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 <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",
title = _("Full-width tables"),

@ -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,

@ -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

@ -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

@ -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
@ -1059,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].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
@ -1386,6 +1393,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

@ -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

@ -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

@ -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()

@ -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;

@ -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)

@ -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

@ -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

Loading…
Cancel
Save