Update readerhighlight.lua

reviewable/pr11563/r5
hius07 2 months ago committed by GitHub
parent 7943e0c0ba
commit 24eba8549c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -7,6 +7,7 @@ local Geom = require("ui/geometry")
local InfoMessage = require("ui/widget/infomessage") local InfoMessage = require("ui/widget/infomessage")
local InputContainer = require("ui/widget/container/inputcontainer") local InputContainer = require("ui/widget/container/inputcontainer")
local Notification = require("ui/widget/notification") local Notification = require("ui/widget/notification")
local RadioButtonWidget = require("ui/widget/radiobuttonwidget")
local TextViewer = require("ui/widget/textviewer") local TextViewer = require("ui/widget/textviewer")
local Translator = require("ui/translator") local Translator = require("ui/translator")
local UIManager = require("ui/uimanager") local UIManager = require("ui/uimanager")
@ -127,11 +128,11 @@ function ReaderHighlight:init()
end, end,
} }
end, end,
["07_translate"] = function(this, page, index) ["07_translate"] = function(this, index)
return { return {
text = _("Translate"), text = _("Translate"),
callback = function() callback = function()
this:translate(this.selected_text, page, index) this:translate(this.selected_text, index)
-- We don't call this:onClose(), so one can still see -- We don't call this:onClose(), so one can still see
-- the highlighted text when moving the translated -- the highlighted text when moving the translated
-- text window, and also if NetworkMgr:promptWifiOn() -- text window, and also if NetworkMgr:promptWifiOn()
@ -455,7 +456,7 @@ function ReaderHighlight:addToMainMenu(menu_items)
}, },
}) })
end end
UIManager:show(require("ui/widget/radiobuttonwidget"):new{ UIManager:show(RadioButtonWidget:new{
title_text = _("Note marker"), title_text = _("Note marker"),
width_factor = 0.5, width_factor = 0.5,
keep_shown_on_apply = true, keep_shown_on_apply = true,
@ -475,7 +476,7 @@ function ReaderHighlight:addToMainMenu(menu_items)
}) })
end, end,
}) })
if self.document.info.has_pages then if self.ui.paging then
menu_items.panel_zoom_options = { menu_items.panel_zoom_options = {
text = _("Panel zoom (manga/comic)"), text = _("Panel zoom (manga/comic)"),
sub_item_table = self:genPanelZoomMenu(), sub_item_table = self:genPanelZoomMenu(),
@ -671,6 +672,7 @@ function ReaderHighlight:clear(clear_id)
end end
self.is_word_selection = false self.is_word_selection = false
self.selected_text_start_xpointer = nil self.selected_text_start_xpointer = nil
self.gest_pos = nil
if self.hold_pos then if self.hold_pos then
self.hold_pos = nil self.hold_pos = nil
self.selected_text = nil self.selected_text = nil
@ -693,7 +695,7 @@ function ReaderHighlight:onTapSelectModeIcon()
cancel_text = _("Close"), cancel_text = _("Close"),
ok_callback = function() ok_callback = function()
self.select_mode = false self.select_mode = false
self:deleteHighlight(self.highlight_page, self.highlight_idx) self:deleteHighlight(self.highlight_idx)
end end
}) })
return true return true
@ -707,6 +709,7 @@ function ReaderHighlight:onTap(_, ges)
local cleared = self.hold_pos and self:clear() local cleared = self.hold_pos and self:clear()
-- We only care about potential taps on existing highlights, not on taps that closed a highlight menu. -- We only care about potential taps on existing highlights, not on taps that closed a highlight menu.
if not cleared and ges then if not cleared and ges then
if #self.ui.annotation.annotations == 0 then return end
if self.ui.paging then if self.ui.paging then
return self:onTapPageSavedHighlight(ges) return self:onTapPageSavedHighlight(ges)
else else
@ -720,31 +723,24 @@ function ReaderHighlight:onTapPageSavedHighlight(ges)
local pos = self.view:screenToPageTransform(ges.pos) local pos = self.view:screenToPageTransform(ges.pos)
local highlights_tapped = {} local highlights_tapped = {}
for _, page in ipairs(pages) do for _, page in ipairs(pages) do
local items = self.view:getPageSavedHighlights(page) local items = self:getPageSavedHighlights(page)
if items then for i, item in ipairs(items) do
for i, item in ipairs(items) do local boxes = self.ui.document:getPageBoxesFromPositions(page, item.pos0, item.pos1)
local boxes = self.ui.document:getPageBoxesFromPositions(page, item.pos0, item.pos1) if boxes then
if boxes then for __, box in ipairs(boxes) do
for _, box in ipairs(boxes) do if inside_box(pos, box) then
if inside_box(pos, box) then logger.dbg("Tap on highlight")
logger.dbg("Tap on highlight") local hl_i = item.parent or i -- parent exists in multi-page highlight only
local hl_page, hl_i if self.select_mode then
if item.parent then -- multi-page highlight if hl_i == self.highlight_idx then
hl_page, hl_i = unpack(item.parent) -- tap on the first fragment: abort select mode, clear highlight
else self.select_mode = false
hl_page, hl_i = page, i self:deleteHighlight(hl_i)
end return true
if self.select_mode then
if hl_page == self.highlight_page and hl_i == self.highlight_idx then
-- tap on the first fragment: abort select mode, clear highlight
self.select_mode = false
self:deleteHighlight(hl_page, hl_i)
return true
end
else
table.insert(highlights_tapped, {hl_page, hl_i})
break
end end
else
table.insert(highlights_tapped, hl_i)
break
end end
end end
end end
@ -761,7 +757,6 @@ function ReaderHighlight:onTapXPointerSavedHighlight(ges)
-- showing menu...). We might want to cache these boxes per page (and -- showing menu...). We might want to cache these boxes per page (and
-- clear that cache when page layout change or highlights are added -- clear that cache when page layout change or highlights are added
-- or removed). -- or removed).
local cur_view_top, cur_view_bottom
local pos = self.view:screenToPageTransform(ges.pos) local pos = self.view:screenToPageTransform(ges.pos)
-- NOTE: By now, pos.page is set, but if a highlight spans across multiple pages, -- NOTE: By now, pos.page is set, but if a highlight spans across multiple pages,
-- it's stored under the hash of its *starting* point, -- it's stored under the hash of its *starting* point,
@ -770,46 +765,39 @@ function ReaderHighlight:onTapXPointerSavedHighlight(ges)
-- because pos.page isn't super accurate in continuous mode -- because pos.page isn't super accurate in continuous mode
-- (it's the page number for what's it the topleft corner of the screen, -- (it's the page number for what's it the topleft corner of the screen,
-- i.e., often a bit earlier)... -- i.e., often a bit earlier)...
-- Even in page mode, it's safer to use pos and ui.dimen.h
-- than pages' xpointers pos, even if ui.dimen.h is a bit
-- larger than pages' heights
local cur_view_top = self.document:getCurrentPos()
local cur_view_bottom
if self.view.view_mode == "page" and self.document:getVisiblePageCount() > 1 then
cur_view_bottom = cur_view_top + 2 * self.ui.dimen.h
else
cur_view_bottom = cur_view_top + self.ui.dimen.h
end
local highlights_tapped = {} local highlights_tapped = {}
for page, items in pairs(self.view.highlight.saved) do for hl_i, item in ipairs(self.ui.annotation.annotations) do
if items then if item.drawer then
for i = 1, #items do -- document:getScreenBoxesFromPositions() is expensive, so we
local item = items[i] -- first check this item is on current page
local pos0, pos1 = item.pos0, item.pos1 local start_pos = self.document:getPosFromXPointer(item.pos0)
-- document:getScreenBoxesFromPositions() is expensive, so we local end_pos = self.document:getPosFromXPointer(item.pos1)
-- first check this item is on current page if start_pos <= cur_view_bottom and end_pos >= cur_view_top then
if not cur_view_top then local boxes = self.ui.document:getScreenBoxesFromPositions(item.pos0, item.pos1, true) -- get_segments=true
-- Even in page mode, it's safer to use pos and ui.dimen.h if boxes then
-- than pages' xpointers pos, even if ui.dimen.h is a bit for _, box in ipairs(boxes) do
-- larger than pages' heights if inside_box(pos, box) then
cur_view_top = self.ui.document:getCurrentPos() logger.dbg("Tap on highlight")
if self.view.view_mode == "page" and self.ui.document:getVisiblePageCount() > 1 then if self.select_mode then
cur_view_bottom = cur_view_top + 2 * self.ui.dimen.h if hl_i == self.highlight_idx then
else -- tap on the first fragment: abort select mode, clear highlight
cur_view_bottom = cur_view_top + self.ui.dimen.h self.select_mode = false
end self:deleteHighlight(hl_i)
end return true
local spos0 = self.ui.document:getPosFromXPointer(pos0)
local spos1 = self.ui.document:getPosFromXPointer(pos1)
local start_pos = math.min(spos0, spos1)
local end_pos = math.max(spos0, spos1)
if start_pos <= cur_view_bottom and end_pos >= cur_view_top then
local boxes = self.ui.document:getScreenBoxesFromPositions(pos0, pos1, true) -- get_segments=true
if boxes then
for index, box in pairs(boxes) do
if inside_box(pos, box) then
logger.dbg("Tap on highlight")
if self.select_mode then
if page == self.highlight_page and i == self.highlight_idx then
-- tap on the first fragment: abort select mode, clear highlight
self.select_mode = false
self:deleteHighlight(page, i)
return true
end
else
table.insert(highlights_tapped, {page, i})
break
end end
else
table.insert(highlights_tapped, hl_i)
break
end end
end end
end end
@ -822,9 +810,9 @@ function ReaderHighlight:onTapXPointerSavedHighlight(ges)
end end
end end
function ReaderHighlight:updateHighlight(page, index, side, direction, move_by_char) function ReaderHighlight:updateHighlight(index, side, direction, move_by_char)
if self.ui.paging then return end local highlight = self.ui.annotation.annotations[index]
local highlight = self.view.highlight.saved[page][index] local bookmark_before = util.tableDeepCopy(highlight)
local highlight_time = highlight.datetime local highlight_time = highlight.datetime
local highlight_beginning = highlight.pos0 local highlight_beginning = highlight.pos0
local highlight_end = highlight.pos1 local highlight_end = highlight.pos1
@ -846,7 +834,10 @@ function ReaderHighlight:updateHighlight(page, index, side, direction, move_by_c
if updated_highlight_beginning then if updated_highlight_beginning then
local order = self.ui.document:compareXPointers(updated_highlight_beginning, highlight_end) local order = self.ui.document:compareXPointers(updated_highlight_beginning, highlight_end)
if order and order > 0 then -- only if beginning did not go past end if order and order > 0 then -- only if beginning did not go past end
self.view.highlight.saved[page][index].pos0 = updated_highlight_beginning highlight.pos0 = updated_highlight_beginning
highlight.page = updated_highlight_beginning
highlight.pageno = self.document:getPageFromXPointer(updated_highlight_beginning)
highlight.chapter = self.ui.toc:getTocTitleByPage(updated_highlight_beginning)
end end
end end
else -- we move pos1 else -- we move pos1
@ -867,23 +858,16 @@ function ReaderHighlight:updateHighlight(page, index, side, direction, move_by_c
if updated_highlight_end then if updated_highlight_end then
local order = self.ui.document:compareXPointers(highlight_beginning, updated_highlight_end) local order = self.ui.document:compareXPointers(highlight_beginning, updated_highlight_end)
if order and order > 0 then -- only if end did not go back past beginning if order and order > 0 then -- only if end did not go back past beginning
self.view.highlight.saved[page][index].pos1 = updated_highlight_end highlight.pos1 = updated_highlight_end
end end
end end
end end
local new_beginning = self.view.highlight.saved[page][index].pos0 local new_beginning = highlight.pos0
local new_end = self.view.highlight.saved[page][index].pos1 local new_end = highlight.pos1
local new_text = self.ui.document:getTextFromXPointers(new_beginning, new_end) local new_text = self.ui.document:getTextFromXPointers(new_beginning, new_end)
local new_chapter = self.ui.toc:getTocTitleByPage(new_beginning) highlight.text = cleanupSelectedText(new_text)
self.view.highlight.saved[page][index].text = cleanupSelectedText(new_text) self.ui:handleEvent(Event:new("BookmarkUpdated", highlight, bookmark_before))
self.view.highlight.saved[page][index].chapter = new_chapter
local new_highlight = self.view.highlight.saved[page][index]
self.ui.bookmark:updateBookmark({
page = highlight_beginning,
datetime = highlight_time,
updated_highlight = new_highlight
})
if side == 0 then if side == 0 then
-- Ensure we show the page with the new beginning of highlight -- Ensure we show the page with the new beginning of highlight
if not self.ui.document:isXPointerInCurrentPage(new_beginning) then if not self.ui.document:isXPointerInCurrentPage(new_beginning) then
@ -909,20 +893,15 @@ end
function ReaderHighlight:showChooseHighlightDialog(highlights) function ReaderHighlight:showChooseHighlightDialog(highlights)
if #highlights == 1 then if #highlights == 1 then
local page, index = unpack(highlights[1]) self:showHighlightNoteOrDialog(highlights[1])
local item = self.view.highlight.saved[page][index]
local bookmark_note = self.ui.bookmark:getBookmarkNote({datetime = item.datetime})
self:showHighlightNoteOrDialog(page, index, bookmark_note)
else -- overlapped highlights else -- overlapped highlights
local dialog local dialog
local buttons = {} local buttons = {}
for i, v in ipairs(highlights) do for i, index in ipairs(highlights) do
local page, index = unpack(v) local item = self.ui.annotation.annotations[index]
local item = self.view.highlight.saved[page][index]
local bookmark_note = self.ui.bookmark:getBookmarkNote({datetime = item.datetime})
buttons[i] = {{ buttons[i] = {{
text = (bookmark_note and self.ui.bookmark.display_prefix["note"] text = (item.note and self.ui.bookmark.display_prefix["note"]
or self.ui.bookmark.display_prefix["highlight"]) .. item.text, or self.ui.bookmark.display_prefix["highlight"]) .. item.text,
align = "left", align = "left",
avoid_text_truncation = false, avoid_text_truncation = false,
font_face = "smallinfofont", font_face = "smallinfofont",
@ -930,7 +909,7 @@ function ReaderHighlight:showChooseHighlightDialog(highlights)
font_bold = false, font_bold = false,
callback = function() callback = function()
UIManager:close(dialog) UIManager:close(dialog)
self:showHighlightNoteOrDialog(page, index, bookmark_note) self:showHighlightNoteOrDialog(index)
end, end,
}} }}
end end
@ -942,7 +921,8 @@ function ReaderHighlight:showChooseHighlightDialog(highlights)
return true return true
end end
function ReaderHighlight:showHighlightNoteOrDialog(page, index, bookmark_note) function ReaderHighlight:showHighlightNoteOrDialog(index)
local bookmark_note = self.ui.annotation.annotations[index].note
if bookmark_note then if bookmark_note then
local textviewer local textviewer
textviewer = TextViewer:new{ textviewer = TextViewer:new{
@ -957,14 +937,14 @@ function ReaderHighlight:showHighlightNoteOrDialog(page, index, bookmark_note)
text = _("Delete highlight"), text = _("Delete highlight"),
callback = function() callback = function()
UIManager:close(textviewer) UIManager:close(textviewer)
self:deleteHighlight(page, index) self:deleteHighlight(index)
end, end,
}, },
{ {
text = _("Edit highlight"), text = _("Edit highlight"),
callback = function() callback = function()
UIManager:close(textviewer) UIManager:close(textviewer)
self:onShowHighlightDialog(page, index, false) self:onShowHighlightDialog(index)
end, end,
}, },
}, },
@ -972,17 +952,18 @@ function ReaderHighlight:showHighlightNoteOrDialog(page, index, bookmark_note)
} }
UIManager:show(textviewer) UIManager:show(textviewer)
else else
self:onShowHighlightDialog(page, index, true) self:onShowHighlightDialog(index)
end end
end end
function ReaderHighlight:onShowHighlightDialog(page, index, is_auto_text) function ReaderHighlight:onShowHighlightDialog(index)
local item = self.ui.annotation.annotations[index]
local buttons = { local buttons = {
{ {
{ {
text = _("Delete"), text = _("Delete"),
callback = function() callback = function()
self:deleteHighlight(page, index) self:deleteHighlight(index)
UIManager:close(self.edit_highlight_dialog) UIManager:close(self.edit_highlight_dialog)
self.edit_highlight_dialog = nil self.edit_highlight_dialog = nil
end, end,
@ -990,15 +971,15 @@ function ReaderHighlight:onShowHighlightDialog(page, index, is_auto_text)
{ {
text = C_("Highlight", "Style"), text = C_("Highlight", "Style"),
callback = function() callback = function()
self:editHighlightStyle(page, index) self:editHighlightStyle(index)
UIManager:close(self.edit_highlight_dialog) UIManager:close(self.edit_highlight_dialog)
self.edit_highlight_dialog = nil self.edit_highlight_dialog = nil
end, end,
}, },
{ {
text = is_auto_text and _("Add note") or _("Edit note"), text = item.note and _("Edit note") or _("Add note"),
callback = function() callback = function()
self:editHighlight(page, index) self:editHighlight(index)
UIManager:close(self.edit_highlight_dialog) UIManager:close(self.edit_highlight_dialog)
self.edit_highlight_dialog = nil self.edit_highlight_dialog = nil
end, end,
@ -1006,8 +987,8 @@ function ReaderHighlight:onShowHighlightDialog(page, index, is_auto_text)
{ {
text = "", text = "",
callback = function() callback = function()
self.selected_text = self.view.highlight.saved[page][index] self.selected_text = util.tableDeepCopy(item)
self:onShowHighlightMenu(page, index) self:onShowHighlightMenu(index)
UIManager:close(self.edit_highlight_dialog) UIManager:close(self.edit_highlight_dialog)
self.edit_highlight_dialog = nil self.edit_highlight_dialog = nil
end, end,
@ -1016,7 +997,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 enabled = not item.text_edited
local start_prev = "◁▒▒" local start_prev = "◁▒▒"
local start_next = "▷▒▒" local start_next = "▷▒▒"
local end_prev = "▒▒◁" local end_prev = "▒▒◁"
@ -1031,10 +1012,10 @@ function ReaderHighlight:onShowHighlightDialog(page, index, is_auto_text)
text = start_prev, text = start_prev,
enabled = enabled, enabled = enabled,
callback = function() callback = function()
self:updateHighlight(page, index, 0, -1, false) self:updateHighlight(index, 0, -1, false)
end, end,
hold_callback = function() hold_callback = function()
self:updateHighlight(page, index, 0, -1, true) self:updateHighlight(index, 0, -1, true)
return true return true
end end
}, },
@ -1042,10 +1023,10 @@ function ReaderHighlight:onShowHighlightDialog(page, index, is_auto_text)
text = start_next, text = start_next,
enabled = enabled, enabled = enabled,
callback = function() callback = function()
self:updateHighlight(page, index, 0, 1, false) self:updateHighlight(index, 0, 1, false)
end, end,
hold_callback = function() hold_callback = function()
self:updateHighlight(page, index, 0, 1, true) self:updateHighlight(index, 0, 1, true)
return true return true
end end
}, },
@ -1053,20 +1034,20 @@ function ReaderHighlight:onShowHighlightDialog(page, index, is_auto_text)
text = end_prev, text = end_prev,
enabled = enabled, enabled = enabled,
callback = function() callback = function()
self:updateHighlight(page, index, 1, -1, false) self:updateHighlight(index, 1, -1, false)
end, end,
hold_callback = function() hold_callback = function()
self:updateHighlight(page, index, 1, -1, true) self:updateHighlight(index, 1, -1, true)
end end
}, },
{ {
text = end_next, text = end_next,
enabled = enabled, enabled = enabled,
callback = function() callback = function()
self:updateHighlight(page, index, 1, 1, false) self:updateHighlight(index, 1, 1, false)
end, end,
hold_callback = function() hold_callback = function()
self:updateHighlight(page, index, 1, 1, true) self:updateHighlight(index, 1, 1, true)
end end
} }
}) })
@ -1090,7 +1071,7 @@ function ReaderHighlight:removeFromHighlightDialog(idx)
return button return button
end end
function ReaderHighlight:onShowHighlightMenu(page, index) function ReaderHighlight:onShowHighlightMenu(index)
if not self.selected_text then if not self.selected_text then
return return
end end
@ -1099,7 +1080,7 @@ function ReaderHighlight:onShowHighlightMenu(page, index)
local columns = 2 local columns = 2
for idx, fn_button in ffiUtil.orderedPairs(self._highlight_buttons) do for idx, fn_button in ffiUtil.orderedPairs(self._highlight_buttons) do
local button = fn_button(self, page, index) local button = fn_button(self, index)
if not button.show_in_highlight_dialog_func or button.show_in_highlight_dialog_func() then if not button.show_in_highlight_dialog_func or button.show_in_highlight_dialog_func() then
if #highlight_buttons[#highlight_buttons] >= columns then if #highlight_buttons[#highlight_buttons] >= columns then
table.insert(highlight_buttons, {}) table.insert(highlight_buttons, {})
@ -1198,12 +1179,12 @@ function ReaderHighlight:_resetHoldTimer(clear)
end end
function ReaderHighlight:onTogglePanelZoomSetting(arg, ges) function ReaderHighlight:onTogglePanelZoomSetting(arg, ges)
if not self.document.info.has_pages then return end if self.ui.rolling then return end
self.panel_zoom_enabled = not self.panel_zoom_enabled self.panel_zoom_enabled = not self.panel_zoom_enabled
end end
function ReaderHighlight:onToggleFallbackTextSelection(arg, ges) function ReaderHighlight:onToggleFallbackTextSelection(arg, ges)
if not self.document.info.has_pages then return end if self.ui.rolling then return end
self.panel_zoom_fallback_to_text_selection = not self.panel_zoom_fallback_to_text_selection self.panel_zoom_fallback_to_text_selection = not self.panel_zoom_fallback_to_text_selection
end end
@ -1229,7 +1210,7 @@ function ReaderHighlight:onPanelZoom(arg, ges)
end end
function ReaderHighlight:onHold(arg, ges) function ReaderHighlight:onHold(arg, ges)
if self.document.info.has_pages and self.panel_zoom_enabled then if self.ui.paging and self.panel_zoom_enabled then
local res = self:onPanelZoom(arg, ges) local res = self:onPanelZoom(arg, ges)
if res or not self.panel_zoom_fallback_to_text_selection then if res or not self.panel_zoom_fallback_to_text_selection then
return res return res
@ -1548,7 +1529,7 @@ function ReaderHighlight:viewSelectionHTML(debug_view, no_css_files_buttons)
end end
end end
function ReaderHighlight:translate(selected_text, page, index) function ReaderHighlight:translate(selected_text, index)
if self.ui.rolling then if self.ui.rolling then
-- Extend the selected text to include any punctuation at start or end, -- Extend the selected text to include any punctuation at start or end,
-- which may give a better translation with the added context. -- which may give a better translation with the added context.
@ -1558,7 +1539,7 @@ function ReaderHighlight:translate(selected_text, page, index)
end end
end end
if #selected_text.text > 0 then if #selected_text.text > 0 then
self:onTranslateText(selected_text.text, page, index) self:onTranslateText(selected_text.text, index)
-- or we will do OCR -- or we will do OCR
elseif self.hold_pos then elseif self.hold_pos then
local text = self.ui.document:getOCRText(self.hold_pos.page, selected_text) local text = self.ui.document:getOCRText(self.hold_pos.page, selected_text)
@ -1578,8 +1559,8 @@ dbg:guard(ReaderHighlight, "translate",
"translate must not be called with nil selected_text!") "translate must not be called with nil selected_text!")
end) end)
function ReaderHighlight:onTranslateText(text, page, index) function ReaderHighlight:onTranslateText(text, index)
Translator:showTranslation(text, true, nil, nil, true, page, index) Translator:showTranslation(text, true, nil, nil, true, index)
end end
function ReaderHighlight:onTranslateCurrentPage() function ReaderHighlight:onTranslateCurrentPage()
@ -1751,133 +1732,43 @@ function ReaderHighlight:highlightFromHoldPos()
end end
end end
function ReaderHighlight:onHighlight() function ReaderHighlight:saveHighlight(extend_to_sentence)
self:saveHighlight() logger.dbg("save highlight")
end
function ReaderHighlight:onUnhighlight(bookmark_item)
local page
local sel_text
local sel_pos0
local datetime
local idx
if bookmark_item then -- called from Bookmarks menu onHold
page = bookmark_item.page
sel_text = bookmark_item.notes
sel_pos0 = bookmark_item.pos0
datetime = bookmark_item.datetime
else -- called from DictQuickLookup Unhighlight button
--- @fixme: is this self.hold_pos access safe?
page = self.hold_pos.page
sel_text = cleanupSelectedText(self.selected_text.text)
sel_pos0 = self.selected_text.pos0
end
if self.ui.paging then -- We can safely use page
-- As we may have changed spaces and hyphens handling in the extracted
-- text over the years, check text identities with them removed
local sel_text_cleaned = sel_text:gsub("[ -]", ""):gsub("\u{00AD}", "")
for index = 1, #self.view.highlight.saved[page] do
local highlight = self.view.highlight.saved[page][index]
-- pos0 are tables and can't be compared directly, except when from
-- DictQuickLookup where these are the same object.
-- If bookmark_item provided, just check datetime
if ( (datetime == nil and highlight.pos0 == sel_pos0) or
(datetime ~= nil and highlight.datetime == datetime) ) then
if highlight.text:gsub("[ -]", ""):gsub("\u{00AD}", "") == sel_text_cleaned then
idx = index
break
end
end
end
else -- page is a xpointer
-- The original page could be found in bookmark_item.text, but
-- no more if it has been renamed: we need to loop through all
-- highlights on all page slots
for p, highlights in pairs(self.view.highlight.saved) do
for index = 1, #highlights do
local highlight = highlights[index]
-- pos0 are strings and can be compared directly
if highlight.text == sel_text and (
(datetime == nil and highlight.pos0 == sel_pos0) or
(datetime ~= nil and highlight.datetime == datetime)) then
page = p -- this is the original page slot
idx = index
break
end
end
if idx then
break
end
end
end
if idx then
logger.dbg("found highlight to delete on page", page, idx)
self:deleteHighlight(page, idx, bookmark_item)
return true
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 if self.hold_pos and not self.selected_text then
self:highlightFromHoldPos() self:highlightFromHoldPos()
end end
if self.selected_text and self.selected_text.pos0 and self.selected_text.pos1 then if self.selected_text and self.selected_text.pos0 and self.selected_text.pos1 then
return { self.ui:handleEvent(Event:new("AddHighlight"))
page = self.ui.paging and self.selected_text.pos0.page or self.selected_text.pos0, local pg_or_xp, page
pos0 = self.selected_text.pos0, if self.ui.rolling then
pos1 = self.selected_text.pos1, if extend_to_sentence then
notes = cleanupSelectedText(self.selected_text.text), local extended_text = self.ui.document:extendXPointersToSentenceSegment(self.selected_text.pos0, self.selected_text.pos1)
highlighted = true, if extended_text then
} self.selected_text = extended_text
end end
end
function ReaderHighlight:saveHighlight(extend_to_sentence)
self.ui:handleEvent(Event:new("AddHighlight"))
logger.dbg("save highlight")
if self.selected_text and self.selected_text.pos0 and self.selected_text.pos1 then
if extend_to_sentence and self.ui.rolling then
local extended_text = self.ui.document:extendXPointersToSentenceSegment(self.selected_text.pos0, self.selected_text.pos1)
if extended_text then
self.selected_text = extended_text
end end
pg_or_xp = self.selected_text.pos0
page = self.ui.document:getPageFromXPointer(pg_or_xp)
else
pg_or_xp = self.selected_text.pos0.page
page = pg_or_xp
end end
local page = self.ui.paging and self.selected_text.pos0.page or self.ui.document:getPageFromXPointer(self.selected_text.pos0) local item = {
if not self.view.highlight.saved[page] then page = self.ui.paging and self.selected_text.pos0.page or self.selected_text.pos0,
self.view.highlight.saved[page] = {}
end
local datetime = os.date("%Y-%m-%d %H:%M:%S")
local pg_or_xp = self.ui.paging and page or self.selected_text.pos0
local chapter_name = self.ui.toc:getTocTitleByPage(pg_or_xp)
local hl_item = {
datetime = datetime,
text = cleanupSelectedText(self.selected_text.text),
pos0 = self.selected_text.pos0, pos0 = self.selected_text.pos0,
pos1 = self.selected_text.pos1, pos1 = self.selected_text.pos1,
pboxes = self.selected_text.pboxes, text = cleanupSelectedText(self.selected_text.text),
ext = self.selected_text.ext,
drawer = self.view.highlight.saved_drawer, drawer = self.view.highlight.saved_drawer,
chapter = chapter_name, datetime = os.date("%Y-%m-%d %H:%M:%S"),
chapter = self.ui.toc:getTocTitleByPage(pg_or_xp),
pageno = page,
} }
table.insert(self.view.highlight.saved[page], hl_item) if self.ui.paging then
local bookmark_item = self:getHighlightBookmarkItem() item.pboxes = self.selected_text.pboxes
if bookmark_item then item.ext = self.selected_text.ext
bookmark_item.datetime = datetime self:writePdfAnnotation("save", page, item)
bookmark_item.chapter = chapter_name
self.ui.bookmark:addBookmark(bookmark_item)
end end
self:writePdfAnnotation("save", page, hl_item) return self.ui.bookmark:addItem(item) -- index
return page, #self.view.highlight.saved[page]
end end
end end
@ -1897,24 +1788,10 @@ function ReaderHighlight:writePdfAnnotation(action, page, item, content)
end end
local can_write local can_write
if item.pos0.page == item.pos1.page then -- single-page highlight if item.pos0.page == item.pos1.page then -- single-page highlight
local item_ can_write = doAction(action, page, item, content)
if item.pboxes then
item_ = item
else -- called from bookmarks to write bookmark note to annotation
for _, hl in ipairs(self.view.highlight.saved[page]) do
if hl.datetime == item.datetime then
item_ = {pboxes = hl.pboxes}
break
end
end
end
can_write = doAction(action, page, item_, content)
else -- multi-page highlight else -- multi-page highlight
local is_reflow = self.ui.document.configurable.text_wrap
for hl_page = item.pos0.page, item.pos1.page do for hl_page = item.pos0.page, item.pos1.page do
self.ui.document.configurable.text_wrap = 0
local hl_part = self:getSavedExtendedHighlightPage(item, hl_page) local hl_part = self:getSavedExtendedHighlightPage(item, hl_page)
self.ui.document.configurable.text_wrap = is_reflow
can_write = doAction(action, hl_page, hl_part, content) can_write = doAction(action, hl_page, hl_part, content)
if can_write == false then break end if can_write == false then break end
if action == "save" then -- update pboxes from quadpoints if action == "save" then -- update pboxes from quadpoints
@ -1934,14 +1811,6 @@ If you wish your highlights to be saved in the document, just move it to a writa
end end
end end
function ReaderHighlight:addNote(text)
local page, index = self:saveHighlight(true)
if text then self:clear() end
self:editHighlight(page, index, true, text)
UIManager:close(self.edit_highlight_dialog)
self.edit_highlight_dialog = nil
end
function ReaderHighlight:lookupWikipedia() function ReaderHighlight:lookupWikipedia()
if self.selected_text then if self.selected_text then
self.ui:handleEvent(Event:new("LookupWikipedia", cleanupSelectedText(self.selected_text.text))) self.ui:handleEvent(Event:new("LookupWikipedia", cleanupSelectedText(self.selected_text.text)))
@ -1970,59 +1839,48 @@ function ReaderHighlight:onHighlightDictLookup()
end end
end end
function ReaderHighlight:deleteHighlight(page, i, bookmark_item) function ReaderHighlight:deleteHighlight(index)
logger.dbg("delete highlight", page, i) logger.dbg("delete highlight", index)
-- The per-page table is a pure array local item = self.ui.annotation.annotations[index]
local removed = table.remove(self.view.highlight.saved[page], i) self:writePdfAnnotation("delete", item.page, item)
-- But the main, outer table is a hash, so clear the table for this page if there are no longer any highlights on it self.ui.bookmark:removeItemByIndex(index)
if #self.view.highlight.saved[page] == 0 then
self.view.highlight.saved[page] = nil
end
if bookmark_item then
self.ui.bookmark:removeBookmark(bookmark_item)
else
self.ui.bookmark:removeBookmark({
page = self.ui.paging and page or removed.pos0,
datetime = removed.datetime,
})
end
self:writePdfAnnotation("delete", page, removed)
UIManager:setDirty(self.dialog, "ui") UIManager:setDirty(self.dialog, "ui")
end end
function ReaderHighlight:editHighlight(page, i, is_new_note, text) function ReaderHighlight:addNote(text)
local item = self.view.highlight.saved[page][i] local index = self:saveHighlight(true)
self.ui.bookmark:setBookmarkNote({ if text then -- called from Translator to save translation to note
page = self.ui.paging and page or item.pos0, self:clear()
datetime = item.datetime, end
}, true, is_new_note, text) self:editHighlight(index, true, text)
UIManager:close(self.edit_highlight_dialog)
self.edit_highlight_dialog = nil
end
function ReaderHighlight:editHighlight(index, is_new_note, text)
self.ui.bookmark:setBookmarkNote(index, is_new_note, text)
end end
function ReaderHighlight:editHighlightStyle(page, i) function ReaderHighlight:editHighlightStyle(index)
local item = self.view.highlight.saved[page][i] local item = self.ui.annotation.annotations[index]
local apply_drawer = function(drawer) local apply_drawer = function(drawer)
self:writePdfAnnotation("delete", page, item) self:writePdfAnnotation("delete", item.page, item)
item.drawer = drawer item.drawer = drawer
if self.ui.paging then if self.ui.paging then
self:writePdfAnnotation("save", page, item) self:writePdfAnnotation("save", item.page, item)
local bm_note = self.ui.bookmark:getBookmarkNote(item) if item.note then
if bm_note then self:writePdfAnnotation("content", item.page, item, item.note)
self:writePdfAnnotation("content", page, item, bm_note)
end end
end end
UIManager:setDirty(self.dialog, "ui") UIManager:setDirty(self.dialog, "ui")
self.ui:handleEvent(Event:new("BookmarkUpdated", self.ui:handleEvent(Event:new("BookmarkUpdated", item))
self.ui.bookmark:getBookmarkForHighlight({
page = self.ui.paging and page or item.pos0,
datetime = item.datetime,
})))
end end
self:showHighlightStyleDialog(apply_drawer, item.drawer) self:showHighlightStyleDialog(apply_drawer, item.drawer)
end end
function ReaderHighlight:showHighlightStyleDialog(caller_callback, item_drawer) function ReaderHighlight:showHighlightStyleDialog(caller_callback, item_drawer)
local default_drawer, keep_shown_on_apply local default_drawer, keep_shown_on_apply
if item_drawer then -- called from editHighlightStyle if item_drawer then -- called from ReaderHighlight:editHighlightStyle()
default_drawer = self.view.highlight.saved_drawer or default_drawer = self.view.highlight.saved_drawer or
G_reader_settings:readSetting("highlight_drawing_style", "lighten") G_reader_settings:readSetting("highlight_drawing_style", "lighten")
keep_shown_on_apply = true keep_shown_on_apply = true
@ -2037,7 +1895,6 @@ function ReaderHighlight:showHighlightStyleDialog(caller_callback, item_drawer)
}, },
}) })
end end
local RadioButtonWidget = require("ui/widget/radiobuttonwidget")
UIManager:show(RadioButtonWidget:new{ UIManager:show(RadioButtonWidget:new{
title_text = _("Highlight style"), title_text = _("Highlight style"),
width_factor = 0.5, width_factor = 0.5,
@ -2051,14 +1908,14 @@ function ReaderHighlight:showHighlightStyleDialog(caller_callback, item_drawer)
end end
function ReaderHighlight:startSelection() function ReaderHighlight:startSelection()
self.highlight_page, self.highlight_idx = self:saveHighlight() self.highlight_idx = self:saveHighlight()
self.select_mode = true self.select_mode = true
end end
function ReaderHighlight:extendSelection() function ReaderHighlight:extendSelection()
-- item1 - starting fragment (saved), item2 - ending fragment (currently selected) -- item1 - starting fragment (saved), item2 - ending fragment (currently selected)
-- new extended highlight includes item1, item2 and the text between them -- new extended highlight includes item1, item2 and the text between them
local item1 = self.view.highlight.saved[self.highlight_page][self.highlight_idx] local item1 = self.ui.annotation.annotations[self.highlight_idx]
local item2_pos0, item2_pos1 = self.selected_text.pos0, self.selected_text.pos1 local item2_pos0, item2_pos1 = self.selected_text.pos0, self.selected_text.pos1
-- getting starting and ending positions, text and pboxes of extended highlight -- getting starting and ending positions, text and pboxes of extended highlight
local new_pos0, new_pos1, new_text, new_pboxes, ext local new_pos0, new_pos1, new_text, new_pboxes, ext
@ -2106,7 +1963,7 @@ function ReaderHighlight:extendSelection()
-- true to draw -- true to draw
new_text = self.ui.document:getTextFromXPointers(new_pos0, new_pos1, true) new_text = self.ui.document:getTextFromXPointers(new_pos0, new_pos1, true)
end end
self:deleteHighlight(self.highlight_page, self.highlight_idx) -- starting fragment self:deleteHighlight(self.highlight_idx) -- starting fragment
self.selected_text = { self.selected_text = {
text = new_text, text = new_text,
pos0 = new_pos0, pos0 = new_pos0,
@ -2165,20 +2022,27 @@ function ReaderHighlight:getExtendedHighlightPage(pos0, pos1, cur_page)
return item return item
end end
-- Returns one page of saved multi-page highlight -- Returns the list of highlights in page.
-- The list includes full single-page highlights and parts of multi-page highlights.
-- (For pdf documents only) -- (For pdf documents only)
function ReaderHighlight:getSavedExtendedHighlightPage(hl_or_bm, page, index) function ReaderHighlight:getPageSavedHighlights(page)
local highlight local highlights = {}
if hl_or_bm.ext then for index, highlight in ipairs(self.ui.annotation.annotations) do
highlight = hl_or_bm if highlight.drawer and highlight.pos0.page <= page and page <= highlight.pos1.page then
else -- called from bookmark, need to find the corresponding highlight if highlight.ext then -- multi-page highlight
for _, hl in ipairs(self.view.highlight.saved[hl_or_bm.page]) do local item = self:getSavedExtendedHighlightPage(highlight, page, index)
if hl.datetime == hl_or_bm.datetime then table.insert(highlights, item)
highlight = hl else
break table.insert(highlights, highlight)
end end
end end
end end
return highlights
end
-- Returns one page of saved multi-page highlight
-- (For pdf documents only)
function ReaderHighlight:getSavedExtendedHighlightPage(highlight, page, index)
local item = { local item = {
datetime = highlight.datetime, datetime = highlight.datetime,
drawer = highlight.drawer, drawer = highlight.drawer,
@ -2199,13 +2063,12 @@ end
function ReaderHighlight:onReadSettings(config) function ReaderHighlight:onReadSettings(config)
self.view.highlight.saved_drawer = config:readSetting("highlight_drawer") self.view.highlight.saved_drawer = config:readSetting("highlight_drawer")
or G_reader_settings:readSetting("highlight_drawing_style") or self.view.highlight.saved_drawer or G_reader_settings:readSetting("highlight_drawing_style") or self.view.highlight.saved_drawer
self.view.highlight.disabled = G_reader_settings:has("default_highlight_action") self.view.highlight.disabled = G_reader_settings:readSetting("default_highlight_action") == "nothing"
and G_reader_settings:readSetting("default_highlight_action") == "nothing"
self.allow_corner_scroll = G_reader_settings:nilOrTrue("highlight_corner_scroll") self.allow_corner_scroll = G_reader_settings:nilOrTrue("highlight_corner_scroll")
-- panel zoom settings isn't supported in EPUB -- panel zoom settings isn't supported in EPUB
if self.document.info.has_pages then if self.ui.paging then
local ext = util.getFileNameSuffix(self.ui.document.file) local ext = util.getFileNameSuffix(self.ui.document.file)
G_reader_settings:initializeExtSettings("panel_zoom_enabled", {cbz = true, cbt = true}) G_reader_settings:initializeExtSettings("panel_zoom_enabled", {cbz = true, cbt = true})
G_reader_settings:initializeExtSettings("panel_zoom_fallback_to_text_selection", {pdf = true}) G_reader_settings:initializeExtSettings("panel_zoom_fallback_to_text_selection", {pdf = true})

Loading…
Cancel
Save