Bookmarks: new settings and tweaks (#8301)

Bookmarks list:
- page numbers are displayed
- page bookmarks are marked with a star
- new setting: Sort by largest page number (default: checked)
New bookmark setting: Add page number / timestamp to bookmark
- If enabled (default), bookmark name is 'Page # notes @ time'.
- If disabled, bookmark name is equal to the notes field.
Rename bookmark dialog:
- page number and timestamp are displayed in the input
  dialog description
- blank input renames bookmark to the default name in
  accordance with the new setting
Also fix: changing boundaries of the highlight: the name of the
highlight is not changed if it was previously edited by the user.
pull/8323/head^2
hius07 3 years ago committed by GitHub
parent fd697f3c77
commit f0b992d425
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -3,7 +3,6 @@ local CenterContainer = require("ui/widget/container/centercontainer")
local ConfirmBox = require("ui/widget/confirmbox") local ConfirmBox = require("ui/widget/confirmbox")
local Device = require("device") local Device = require("device")
local Event = require("ui/event") local Event = require("ui/event")
local Font = require("ui/font")
local Geom = require("ui/geometry") local Geom = require("ui/geometry")
local GestureRange = require("ui/gesturerange") local GestureRange = require("ui/gesturerange")
local InputContainer = require("ui/widget/container/inputcontainer") local InputContainer = require("ui/widget/container/inputcontainer")
@ -12,10 +11,13 @@ local Menu = require("ui/widget/menu")
local TextViewer = require("ui/widget/textviewer") local TextViewer = require("ui/widget/textviewer")
local UIManager = require("ui/uimanager") local UIManager = require("ui/uimanager")
local logger = require("logger") local logger = require("logger")
local util = require("util")
local _ = require("gettext") local _ = require("gettext")
local Screen = require("device").screen local Screen = require("device").screen
local T = require("ffi/util").template local T = require("ffi/util").template
local PAGE_BOOKMARK_DISPLAY_PREFIX = "" -- distinguish page bookmarks from highlights and notes
local ReaderBookmark = InputContainer:new{ local ReaderBookmark = InputContainer:new{
bm_menu_title = _("Bookmarks"), bm_menu_title = _("Bookmarks"),
bbm_menu_title = _("Bookmark browsing mode"), bbm_menu_title = _("Bookmark browsing mode"),
@ -75,55 +77,87 @@ function ReaderBookmark:addToMainMenu(menu_items)
end, end,
} }
end end
menu_items.bookmarks_items_per_page = { menu_items.bookmarks_settings = {
text = _("Bookmarks per page"), text = _("Bookmarks"),
keep_menu_open = true, sub_item_table = {
callback = function() {
local SpinWidget = require("ui/widget/spinwidget") text_func = function()
local curr_perpage = G_reader_settings:readSetting("bookmarks_items_per_page") or self.bookmarks_items_per_page_default local curr_perpage = G_reader_settings:readSetting("bookmarks_items_per_page")
local items = SpinWidget:new{ return T(_("Bookmarks per page: %1"), curr_perpage)
value = curr_perpage, end,
value_min = 6, keep_menu_open = true,
value_max = 24, callback = function(touchmenu_instance)
default_value = self.bookmarks_items_per_page_default, local SpinWidget = require("ui/widget/spinwidget")
title_text = _("Bookmarks per page"), local curr_perpage = G_reader_settings:readSetting("bookmarks_items_per_page")
callback = function(spin) local items = SpinWidget:new{
G_reader_settings:saveSetting("bookmarks_items_per_page", spin.value) value = curr_perpage,
value_min = 6,
value_max = 24,
default_value = self.bookmarks_items_per_page_default,
title_text = _("Bookmarks per page"),
callback = function(spin)
G_reader_settings:saveSetting("bookmarks_items_per_page", spin.value)
if touchmenu_instance then touchmenu_instance:updateItems() end
end
}
UIManager:show(items)
end end
} },
UIManager:show(items) {
end text_func = function()
} local curr_perpage = G_reader_settings:readSetting("bookmarks_items_per_page")
menu_items.bookmarks_items_font_size = { local default_font_size = Menu.getItemFontSize(curr_perpage)
text = _("Bookmark font size"), local curr_font_size = G_reader_settings:readSetting("bookmarks_items_font_size", default_font_size)
keep_menu_open = true, return T(_("Bookmark font size: %1"), curr_font_size)
callback = function() end,
local SpinWidget = require("ui/widget/spinwidget") keep_menu_open = true,
local curr_perpage = G_reader_settings:readSetting("bookmarks_items_per_page") or self.bookmarks_items_per_page_default callback = function(touchmenu_instance)
local default_font_size = Menu.getItemFontSize(curr_perpage) local SpinWidget = require("ui/widget/spinwidget")
local curr_font_size = G_reader_settings:readSetting("bookmarks_items_font_size") or default_font_size local curr_perpage = G_reader_settings:readSetting("bookmarks_items_per_page")
local items_font = SpinWidget:new{ local default_font_size = Menu.getItemFontSize(curr_perpage)
value = curr_font_size, local curr_font_size = G_reader_settings:readSetting("bookmarks_items_font_size", default_font_size)
value_min = 10, local items_font = SpinWidget:new{
value_max = 72, value = curr_font_size,
default_value = default_font_size, value_min = 10,
title_text = _("Bookmark font size"), value_max = 72,
callback = function(spin) default_value = default_font_size,
G_reader_settings:saveSetting("bookmarks_items_font_size", spin.value) title_text = _("Bookmark font size"),
callback = function(spin)
G_reader_settings:saveSetting("bookmarks_items_font_size", spin.value)
if touchmenu_instance then touchmenu_instance:updateItems() end
end
}
UIManager:show(items_font)
end,
},
{
text = _("Shrink bookmark font size to fit more text"),
checked_func = function()
return G_reader_settings:isTrue("bookmarks_items_multilines_show_more_text")
end,
callback = function()
G_reader_settings:flipNilOrFalse("bookmarks_items_multilines_show_more_text")
end end
} },
UIManager:show(items_font) {
end, text = _("Add page number / timestamp to bookmark"),
} checked_func = function()
menu_items.bookmarks_items_show_more_text = { return G_reader_settings:nilOrTrue("bookmarks_items_auto_text")
text = _("Shrink bookmark font size to fit more text"), end,
keep_menu_open = true, callback = function()
checked_func = function() G_reader_settings:flipNilOrTrue("bookmarks_items_auto_text")
return G_reader_settings:isTrue("bookmarks_items_multilines_show_more_text") end
end, },
callback = function() {
G_reader_settings:flipNilOrFalse("bookmarks_items_multilines_show_more_text") text = _("Sort by largest page number"),
end checked_func = function()
return G_reader_settings:nilOrTrue("bookmarks_items_reverse_sorting")
end,
callback = function()
G_reader_settings:flipNilOrTrue("bookmarks_items_reverse_sorting")
end
},
},
} }
end end
@ -315,40 +349,35 @@ end
function ReaderBookmark:onShowBookmark() function ReaderBookmark:onShowBookmark()
self:updateHighlightsIfNeeded() self:updateHighlightsIfNeeded()
-- build up item_table -- build up item_table
for k, v in ipairs(self.bookmarks) do local item_table = {}
local page = v.page local is_reverse_sorting = G_reader_settings:nilOrTrue("bookmarks_items_reverse_sorting")
-- for CREngine, bookmark page is xpointer local num = #self.bookmarks + 1
if not self.ui.document.info.has_pages then for i, v in ipairs(self.bookmarks) do
if self.ui.pagemap and self.ui.pagemap:wantsPageLabels() then
page = self.ui.pagemap:getXPointerPageLabel(page, true)
else
page = self.ui.document:getPageFromXPointer(page)
if self.ui.document:hasHiddenFlows() then
local flow = self.ui.document:getPageFlow(page)
page = self.ui.document:getPageNumberInFlow(page)
if flow > 0 then
page = T("[%1]%2", page, flow)
end
end
end
end
if v.text == nil or v.text == "" then if v.text == nil or v.text == "" then
v.text = T(_("Page %1 %2 @ %3"), page, v.notes, v.datetime) v.text = self:getBookmarkAutoText(v)
end
-- bookmarks are internally sorted by descending page numbers
local k = is_reverse_sorting and i or num - i
item_table[k] = util.tableDeepCopy(v)
item_table[k].text_orig = v.text or v.notes
item_table[k].text = item_table[k].text_orig
if not v.highlighted then -- page bookmark
item_table[k].text = PAGE_BOOKMARK_DISPLAY_PREFIX .. item_table[k].text
end end
item_table[k].mandatory = self:getBookmarkPageString(v.page)
end end
local items_per_page = G_reader_settings:readSetting("bookmarks_items_per_page") or self.bookmarks_items_per_page_default local items_per_page = G_reader_settings:readSetting("bookmarks_items_per_page")
local items_font_size = G_reader_settings:readSetting("bookmarks_items_font_size") or Menu.getItemFontSize(items_per_page) local items_font_size = G_reader_settings:readSetting("bookmarks_items_font_size", Menu.getItemFontSize(items_per_page))
local multilines_show_more_text = G_reader_settings:isTrue("bookmarks_items_multilines_show_more_text") local multilines_show_more_text = G_reader_settings:isTrue("bookmarks_items_multilines_show_more_text")
local bm_menu = Menu:new{ local bm_menu = Menu:new{
title = _("Bookmarks"), title = _("Bookmarks"),
item_table = self.bookmarks, item_table = item_table,
is_borderless = true, is_borderless = true,
is_popout = false, is_popout = false,
width = Screen:getWidth(), width = Screen:getWidth(),
height = Screen:getHeight(), height = Screen:getHeight(),
cface = Font:getFace("x_smallinfofont"),
items_per_page = items_per_page, items_per_page = items_per_page,
items_font_size = items_font_size, items_font_size = items_font_size,
multilines_show_more_text = multilines_show_more_text, multilines_show_more_text = multilines_show_more_text,
@ -406,7 +435,14 @@ function ReaderBookmark:onShowBookmark()
ok_text = _("Remove"), ok_text = _("Remove"),
ok_callback = function() ok_callback = function()
bookmark:removeHighlight(item) bookmark:removeHighlight(item)
bm_menu:switchItemTable(nil, bookmark.bookmarks, -1) -- Also update item_table, so we don't have to rebuilt it in full
for k, v in pairs(item_table) do
if v == item then
table.remove(item_table, k)
break
end
end
bm_menu:switchItemTable(nil, item_table, -1)
UIManager:close(self.textviewer) UIManager:close(self.textviewer)
end, end,
}) })
@ -569,25 +605,18 @@ end
function ReaderBookmark:updateBookmark(item) function ReaderBookmark:updateBookmark(item)
for i=1, #self.bookmarks do for i=1, #self.bookmarks do
if item.datetime == self.bookmarks[i].datetime and item.page == self.bookmarks[i].page then if item.datetime == self.bookmarks[i].datetime and item.page == self.bookmarks[i].page then
local page = self.ui.document:getPageFromXPointer(item.updated_highlight.pos0) local is_auto_text = self:isBookmarkAutoText(self.bookmarks[i])
if self.ui.document:hasHiddenFlows() then
local flow = self.ui.document:getPageFlow(page)
page = self.ui.document:getPageNumberInFlow(page)
if flow > 0 then
page = T("[%1]%2", page, flow)
end
end
local new_text = item.updated_highlight.text
self.bookmarks[i].page = item.updated_highlight.pos0 self.bookmarks[i].page = item.updated_highlight.pos0
self.bookmarks[i].pos0 = item.updated_highlight.pos0 self.bookmarks[i].pos0 = item.updated_highlight.pos0
self.bookmarks[i].pos1 = item.updated_highlight.pos1 self.bookmarks[i].pos1 = item.updated_highlight.pos1
self.bookmarks[i].notes = item.updated_highlight.text self.bookmarks[i].notes = item.updated_highlight.text
self.bookmarks[i].text = T(_("Page %1 %2 @ %3"), page,
new_text,
item.updated_highlight.datetime)
self.bookmarks[i].datetime = item.updated_highlight.datetime self.bookmarks[i].datetime = item.updated_highlight.datetime
self.bookmarks[i].chapter = item.updated_highlight.chapter self.bookmarks[i].chapter = item.updated_highlight.chapter
if is_auto_text then
self.bookmarks[i].text = self:getBookmarkAutoText(self.bookmarks[i])
end
self:onSaveSettings() self:onSaveSettings()
break
end end
end end
end end
@ -599,27 +628,17 @@ function ReaderBookmark:renameBookmark(item, from_highlight)
local pboxes = item.pboxes local pboxes = item.pboxes
for __, bm in ipairs(self.bookmarks) do for __, bm in ipairs(self.bookmarks) do
if item.datetime == bm.datetime and item.page == bm.page then if item.datetime == bm.datetime and item.page == bm.page then
bookmark = bm bm.pboxes = pboxes
bookmark.pboxes = pboxes if bm.text == nil or bm.text == "" then
if bookmark.text == nil or bookmark.text == "" then bm.text = self:getBookmarkAutoText(bm)
-- Make up bookmark text as done in onShowBookmark
local page = bookmark.page
if not self.ui.document.info.has_pages then
page = self.ui.document:getPageFromXPointer(page)
if self.ui.document:hasHiddenFlows() then
local flow = self.ui.document:getPageFlow(page)
page = self.ui.document:getPageNumberInFlow(page)
if flow > 0 then
page = T("[%1]%2", page, flow)
end
end
end
bookmark.text = T(_("Page %1 %2 @ %3"), page, bookmark.notes, bookmark.datetime)
end end
bookmark = util.tableDeepCopy(bm)
bookmark.text_orig = bm.text or bm.notes
bookmark.mandatory = self:getBookmarkPageString(bm.page)
break break
end end
end end
if not bookmark or bookmark.text == nil then -- bookmark not found if not bookmark or bookmark.text_orig == nil then -- bookmark not found
return return
end end
else else
@ -627,8 +646,8 @@ function ReaderBookmark:renameBookmark(item, from_highlight)
end end
self.input = InputDialog:new{ self.input = InputDialog:new{
title = _("Rename bookmark"), title = _("Rename bookmark"),
input = bookmark.text, description = T(" " .. _("Page: %1") .. " " .. _("Time: %2"), bookmark.mandatory, bookmark.datetime),
input_type = "text", input = bookmark.text_orig,
allow_newline = true, allow_newline = true,
cursor_at_end = false, cursor_at_end = false,
add_scroll_buttons = true, add_scroll_buttons = true,
@ -636,33 +655,38 @@ function ReaderBookmark:renameBookmark(item, from_highlight)
{ {
{ {
text = _("Cancel"), text = _("Cancel"),
is_enter_default = true,
callback = function() callback = function()
UIManager:close(self.input) UIManager:close(self.input)
end, end,
}, },
{ {
text = _("Rename"), text = _("Rename"),
is_enter_default = true,
callback = function() callback = function()
local value = self.input:getInputValue() local value = self.input:getInputValue()
if value ~= "" then if value == "" then -- blank input resets the 'text' field to auto-text
for __, bm in ipairs(self.bookmarks) do value = self:getBookmarkAutoText(bookmark)
if bookmark.text == bm.text and bookmark.pos0 == bm.pos0 and end
bookmark.pos1 == bm.pos1 and bookmark.page == bm.page then for __, bm in ipairs(self.bookmarks) do
bm.text = value if bookmark.datetime == bm.datetime and bookmark.page == bm.page then
-- A bookmark isn't necessarily a highlight (it doesn't have pboxes) bm.text = value
if bookmark.pboxes then bookmark.text_orig = value or bookmark.notes
local setting = G_reader_settings:readSetting("save_document") bookmark.text = bookmark.text_orig
if setting ~= "disable" then -- A bookmark isn't necessarily a highlight (it doesn't have pboxes)
self.ui.document:updateHighlightContents(bookmark.page, bookmark, value) if bookmark.pboxes then
end local setting = G_reader_settings:readSetting("save_document")
if setting ~= "disable" then
self.ui.document:updateHighlightContents(bookmark.page, bookmark, value or bookmark.notes)
end end
UIManager:close(self.input) end
if not from_highlight then UIManager:close(self.input)
self.refresh() if not from_highlight then
if not bookmark.highlighted then
bookmark.text = PAGE_BOOKMARK_DISPLAY_PREFIX .. bookmark.text
end end
break self.refresh()
end end
break
end end
end end
UIManager:close(self.input) UIManager:close(self.input)
@ -814,4 +838,45 @@ function ReaderBookmark:getNumberOfHighlightsAndNotes()
return highlights, notes return highlights, notes
end end
function ReaderBookmark:getBookmarkPageString(page)
if not self.ui.document.info.has_pages then
if self.ui.pagemap and self.ui.pagemap:wantsPageLabels() then
page = self.ui.pagemap:getXPointerPageLabel(page, true)
else
page = self.ui.document:getPageFromXPointer(page)
if self.ui.document:hasHiddenFlows() then
local flow = self.ui.document:getPageFlow(page)
page = self.ui.document:getPageNumberInFlow(page)
if flow > 0 then
page = T("[%1]%2", page, flow)
end
end
end
end
return tostring(page)
end
function ReaderBookmark:getBookmarkAutoText(bookmark, force_auto_text)
if G_reader_settings:nilOrTrue("bookmarks_items_auto_text") or force_auto_text then
local page = self:getBookmarkPageString(bookmark.page)
return T(_("Page %1 %2 @ %3"), page, bookmark.notes, bookmark.datetime)
else
-- When not auto_text, and 'text' would be identical to 'notes', leave 'text' be nil
return nil
end
end
--- Check if the 'text' field has not been edited manually
function ReaderBookmark:isBookmarkAutoText(bookmark)
return (bookmark.text == nil) or (bookmark.text == self:getBookmarkAutoText(bookmark, true))
end
function ReaderBookmark:isHighlightAutoText(item)
for i=1, #self.bookmarks do
if item.datetime == self.bookmarks[i].datetime and item.page == self.bookmarks[i].page then
return self:isBookmarkAutoText(self.bookmarks[i])
end
end
end
return ReaderBookmark return ReaderBookmark

@ -35,9 +35,7 @@ local order = {
"toc_items_font_size", "toc_items_font_size",
"toc_items_with_dots", "toc_items_with_dots",
"----------------------------", "----------------------------",
"bookmarks_items_per_page", "bookmarks_settings",
"bookmarks_items_font_size",
"bookmarks_items_show_more_text",
}, },
typeset = { typeset = {
"set_render_style", "set_render_style",

Loading…
Cancel
Save