mirror of
https://github.com/koreader/koreader.git
synced 2025-08-10 00:52:38 +00:00
ReaderHighlight: manage overlapped highlights (#10492)
This commit is contained in:
@@ -24,16 +24,15 @@ local N_ = _.ngettext
|
||||
local Screen = require("device").screen
|
||||
local T = require("ffi/util").template
|
||||
|
||||
-- mark the type of a bookmark with a symbol + non-expandable space
|
||||
local DISPLAY_PREFIX = {
|
||||
highlight = "\u{2592}\u{2002}", -- "medium shade"
|
||||
note = "\u{F040}\u{2002}", -- "pencil"
|
||||
bookmark = "\u{F097}\u{2002}", -- "empty bookmark"
|
||||
}
|
||||
|
||||
local ReaderBookmark = InputContainer:extend{
|
||||
bookmarks_items_per_page_default = 14,
|
||||
bookmarks = nil,
|
||||
-- mark the type of a bookmark with a symbol + non-expandable space
|
||||
display_prefix = {
|
||||
highlight = "\u{2592}\u{2002}", -- "medium shade"
|
||||
note = "\u{F040}\u{2002}", -- "pencil"
|
||||
bookmark = "\u{F097}\u{2002}", -- "empty bookmark"
|
||||
},
|
||||
}
|
||||
|
||||
function ReaderBookmark:init()
|
||||
@@ -437,7 +436,7 @@ function ReaderBookmark:onShowBookmark(match_table)
|
||||
item.type = self:getBookmarkType(item)
|
||||
if not match_table or self:doesBookmarkMatchTable(item, match_table) then
|
||||
item.text_orig = item.text or item.notes
|
||||
item.text = DISPLAY_PREFIX[item.type] .. item.text_orig
|
||||
item.text = self.display_prefix[item.type] .. item.text_orig
|
||||
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
|
||||
@@ -517,7 +516,7 @@ function ReaderBookmark:onShowBookmark(match_table)
|
||||
if item.type == "bookmark" then
|
||||
bm_view = bm_view .. item.text
|
||||
else
|
||||
bm_view = bm_view .. DISPLAY_PREFIX["highlight"] .. item.notes
|
||||
bm_view = bm_view .. bookmark.display_prefix["highlight"] .. item.notes
|
||||
if item.type == "note" then
|
||||
bm_view = bm_view .. "\n\n" .. item.text
|
||||
end
|
||||
@@ -733,12 +732,12 @@ function ReaderBookmark:onShowBookmark(match_table)
|
||||
bm_count = bm_count + 1
|
||||
end
|
||||
end
|
||||
dialog_title = T(DISPLAY_PREFIX["highlight"] .. "%1" .. " " ..
|
||||
DISPLAY_PREFIX["note"] .. "%2" .. " " ..
|
||||
DISPLAY_PREFIX["bookmark"] .. "%3", hl_count, nt_count, bm_count)
|
||||
dialog_title = T(bookmark.display_prefix["highlight"] .. "%1" .. " " ..
|
||||
bookmark.display_prefix["note"] .. "%2" .. " " ..
|
||||
bookmark.display_prefix["bookmark"] .. "%3", hl_count, nt_count, bm_count)
|
||||
table.insert(buttons, {
|
||||
{
|
||||
text = DISPLAY_PREFIX["highlight"] .. _("highlights"),
|
||||
text = bookmark.display_prefix["highlight"] .. _("highlights"),
|
||||
callback = function()
|
||||
UIManager:close(bm_dialog)
|
||||
bm_menu:onClose()
|
||||
@@ -746,7 +745,7 @@ function ReaderBookmark:onShowBookmark(match_table)
|
||||
end,
|
||||
},
|
||||
{
|
||||
text = DISPLAY_PREFIX["bookmark"] .. _("page bookmarks"),
|
||||
text = bookmark.display_prefix["bookmark"] .. _("page bookmarks"),
|
||||
callback = function()
|
||||
UIManager:close(bm_dialog)
|
||||
bm_menu:onClose()
|
||||
@@ -756,7 +755,7 @@ function ReaderBookmark:onShowBookmark(match_table)
|
||||
})
|
||||
table.insert(buttons, {
|
||||
{
|
||||
text = DISPLAY_PREFIX["note"] .. _("notes"),
|
||||
text = bookmark.display_prefix["note"] .. _("notes"),
|
||||
callback = function()
|
||||
UIManager:close(bm_dialog)
|
||||
bm_menu:onClose()
|
||||
@@ -1072,7 +1071,7 @@ function ReaderBookmark:setBookmarkNote(item, from_highlight, is_new_note, new_t
|
||||
end
|
||||
else
|
||||
bookmark.text_orig = bookmark.text
|
||||
bookmark.text = DISPLAY_PREFIX[bookmark.type] .. bookmark.text
|
||||
bookmark.text = self.display_prefix[bookmark.type] .. bookmark.text
|
||||
self.refresh()
|
||||
end
|
||||
end,
|
||||
@@ -1152,19 +1151,19 @@ function ReaderBookmark:onSearchBookmark(bm_menu)
|
||||
}
|
||||
input_dialog:addWidget(separator)
|
||||
check_button_highlight = CheckButton:new{
|
||||
text = " " .. DISPLAY_PREFIX["highlight"] .. _("highlights"),
|
||||
text = " " .. self.display_prefix["highlight"] .. _("highlights"),
|
||||
checked = true,
|
||||
parent = input_dialog,
|
||||
}
|
||||
input_dialog:addWidget(check_button_highlight)
|
||||
check_button_note = CheckButton:new{
|
||||
text = " " .. DISPLAY_PREFIX["note"] .. _("notes"),
|
||||
text = " " .. self.display_prefix["note"] .. _("notes"),
|
||||
checked = true,
|
||||
parent = input_dialog,
|
||||
}
|
||||
input_dialog:addWidget(check_button_note)
|
||||
check_button_bookmark = CheckButton:new{
|
||||
text = " " .. DISPLAY_PREFIX["bookmark"] .. _("page bookmarks"),
|
||||
text = " " .. self.display_prefix["bookmark"] .. _("page bookmarks"),
|
||||
checked = true,
|
||||
parent = input_dialog,
|
||||
}
|
||||
|
||||
@@ -659,6 +659,7 @@ end
|
||||
function ReaderHighlight:onTapPageSavedHighlight(ges)
|
||||
local pages = self.view:getCurrentPageList()
|
||||
local pos = self.view:screenToPageTransform(ges.pos)
|
||||
local highlights_tapped = {}
|
||||
for _, page in ipairs(pages) do
|
||||
local items = self.view:getPageSavedHighlights(page)
|
||||
if items then
|
||||
@@ -674,13 +675,26 @@ function ReaderHighlight:onTapPageSavedHighlight(ges)
|
||||
else
|
||||
hl_page, hl_i = page, i
|
||||
end
|
||||
return self:onShowHighlightNoteOrDialog(hl_page, hl_i)
|
||||
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
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if #highlights_tapped > 0 then
|
||||
return self:showChooseHighlightDialog(highlights_tapped)
|
||||
end
|
||||
end
|
||||
|
||||
function ReaderHighlight:onTapXPointerSavedHighlight(ges)
|
||||
@@ -697,6 +711,7 @@ function ReaderHighlight:onTapXPointerSavedHighlight(ges)
|
||||
-- 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,
|
||||
-- i.e., often a bit earlier)...
|
||||
local highlights_tapped = {}
|
||||
for page, items in pairs(self.view.highlight.saved) do
|
||||
if items then
|
||||
for i = 1, #items do
|
||||
@@ -725,7 +740,17 @@ function ReaderHighlight:onTapXPointerSavedHighlight(ges)
|
||||
for index, box in pairs(boxes) do
|
||||
if inside_box(pos, box) then
|
||||
logger.dbg("Tap on highlight")
|
||||
return self:onShowHighlightNoteOrDialog(page, i)
|
||||
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
|
||||
end
|
||||
end
|
||||
@@ -733,6 +758,9 @@ function ReaderHighlight:onTapXPointerSavedHighlight(ges)
|
||||
end
|
||||
end
|
||||
end
|
||||
if #highlights_tapped > 0 then
|
||||
return self:showChooseHighlightDialog(highlights_tapped)
|
||||
end
|
||||
end
|
||||
|
||||
function ReaderHighlight:updateHighlight(page, index, side, direction, move_by_char)
|
||||
@@ -820,16 +848,42 @@ function ReaderHighlight:updateHighlight(page, index, side, direction, move_by_c
|
||||
UIManager:setDirty(self.dialog, "ui")
|
||||
end
|
||||
|
||||
function ReaderHighlight:onShowHighlightNoteOrDialog(page, index)
|
||||
if self.select_mode then
|
||||
if page ~= self.highlight_page or index ~= self.highlight_idx then return end
|
||||
-- tap on the first fragment: abort select mode, clear highlight
|
||||
self.select_mode = false
|
||||
self:deleteHighlight(page, index)
|
||||
return true
|
||||
function ReaderHighlight:showChooseHighlightDialog(highlights)
|
||||
if #highlights == 1 then
|
||||
local page, index = unpack(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
|
||||
local dialog
|
||||
local buttons = {}
|
||||
for i, v in ipairs(highlights) do
|
||||
local page, index = unpack(v)
|
||||
local item = self.view.highlight.saved[page][index]
|
||||
local bookmark_note = self.ui.bookmark:getBookmarkNote({datetime = item.datetime})
|
||||
buttons[i] = {{
|
||||
text = (bookmark_note and self.ui.bookmark.display_prefix["note"]
|
||||
or self.ui.bookmark.display_prefix["highlight"]) .. item.text,
|
||||
align = "left",
|
||||
avoid_text_truncation = false,
|
||||
font_face = "smallinfofont",
|
||||
font_size = 22,
|
||||
font_bold = false,
|
||||
callback = function()
|
||||
UIManager:close(dialog)
|
||||
self:showHighlightNoteOrDialog(page, index, bookmark_note)
|
||||
end,
|
||||
}}
|
||||
end
|
||||
dialog = ButtonDialog:new{
|
||||
buttons = buttons,
|
||||
}
|
||||
UIManager:show(dialog)
|
||||
end
|
||||
local item = self.view.highlight.saved[page][index]
|
||||
local bookmark_note = self.ui.bookmark:getBookmarkNote({datetime = item.datetime})
|
||||
return true
|
||||
end
|
||||
|
||||
function ReaderHighlight:showHighlightNoteOrDialog(page, index, bookmark_note)
|
||||
if bookmark_note then
|
||||
local textviewer
|
||||
textviewer = TextViewer:new{
|
||||
@@ -860,7 +914,6 @@ function ReaderHighlight:onShowHighlightNoteOrDialog(page, index)
|
||||
else
|
||||
self:onShowHighlightDialog(page, index, true)
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function ReaderHighlight:onShowHighlightDialog(page, index, is_auto_text)
|
||||
|
||||
@@ -159,7 +159,7 @@ describe("Readerhighlight module", function()
|
||||
Screen:shot("screenshots/reader_highlight_single_word_pdf.png")
|
||||
end)
|
||||
it("should highlight text", function()
|
||||
highlight_text(readerui, Geom:new{ x = 260, y = 70 }, Geom:new{ x = 260, y = 150 })
|
||||
highlight_text(readerui, Geom:new{ x = 260, y = 170 }, Geom:new{ x = 260, y = 250 })
|
||||
Screen:shot("screenshots/reader_highlight_text_pdf.png")
|
||||
end)
|
||||
it("should response on tap gesture", function()
|
||||
@@ -250,7 +250,7 @@ describe("Readerhighlight module", function()
|
||||
Screen:shot("screenshots/reader_highlight_single_word_pdf_scroll.png")
|
||||
end)
|
||||
it("should highlight text", function()
|
||||
highlight_text(readerui, Geom:new{ x = 260, y = 70 }, Geom:new{ x = 260, y = 150 })
|
||||
highlight_text(readerui, Geom:new{ x = 260, y = 170 }, Geom:new{ x = 260, y = 250 })
|
||||
Screen:shot("screenshots/reader_highlight_text_pdf_scroll.png")
|
||||
end)
|
||||
it("should response on tap gesture", function()
|
||||
|
||||
Reference in New Issue
Block a user