Bookmarks: fix sort within one page (#8616)

Accurate sorting of bookmarks located in one page depending on their positions in text.
This commit is contained in:
hius07
2022-01-06 21:54:33 +02:00
committed by GitHub
parent 7163a392a8
commit 00b08d7b54
5 changed files with 90 additions and 20 deletions

View File

@@ -195,6 +195,55 @@ function ReaderBookmark:isBookmarkInTimeOrder(a, b)
return a.datetime > b.datetime
end
function ReaderBookmark:isBookmarkInPositionOrder(a, b)
if self.ui.paging then
if a.page == b.page then -- both bookmarks in the same page
if a.highlighted and b.highlighted then -- both are highlights, compare positions
local is_reflow = self.ui.document.configurable.text_wrap -- save reflow mode
-- reflow mode doesn't set page in positions
a.pos0.page = a.page
a.pos1.page = a.page
b.pos0.page = b.page
b.pos1.page = b.page
self.ui.document.configurable.text_wrap = 0 -- native positions
-- sort start and end positions of each highlight
local compare_pos, a_start, a_end, b_start, b_end, result
compare_pos = self.ui.document:comparePositions(a.pos0, a.pos1) > 0
a_start = compare_pos and a.pos0 or a.pos1
a_end = compare_pos and a.pos1 or a.pos0
compare_pos = self.ui.document:comparePositions(b.pos0, b.pos1) > 0
b_start = compare_pos and b.pos0 or b.pos1
b_end = compare_pos and b.pos1 or b.pos0
-- compare start positions
compare_pos = self.ui.document:comparePositions(a_start, b_start)
if compare_pos == 0 then -- both highlights with the same start, compare ends
result = self.ui.document:comparePositions(a_end, b_end) < 0
else
result = compare_pos < 0
end
self.ui.document.configurable.text_wrap = is_reflow -- restore reflow mode
return result
end
return a.highlighted -- have page bookmarks before highlights
end
return a.page > b.page
else
local a_page = self.ui.document:getPageFromXPointer(a.page)
local b_page = self.ui.document:getPageFromXPointer(b.page)
if a_page == b_page then -- both bookmarks in the same page
local compare_xp = self.ui.document:compareXPointers(a.page, b.page)
if compare_xp == 0 then -- both bookmarks with the same start
if a.highlighted and b.highlighted then -- both are highlights, compare ends
return self.ui.document:compareXPointers(a.pos1, b.pos1) < 0
end
return a.highlighted -- have page bookmarks before highlights
end
return compare_xp < 0
end
return a_page > b_page
end
end
function ReaderBookmark:isBookmarkInPageOrder(a, b)
if self.ui.document.info.has_pages then
if a.page == b.page then -- have bookmarks before highlights
@@ -244,9 +293,10 @@ end
function ReaderBookmark:fixBookmarkSort(config)
-- for backward compatibility, since previously bookmarks for credocuments
-- are not well sorted. We need to do a whole sorting for at least once.
if config:hasNot("bookmarks_sorted") then
-- 20220106: accurate sorting with isBookmarkInPositionOrder
if config:hasNot("bookmarks_sorted_20220106") then
table.sort(self.bookmarks, function(a, b)
return self:isBookmarkInPageOrder(a, b)
return self:isBookmarkInPositionOrder(a, b)
end)
end
end
@@ -311,6 +361,7 @@ end
function ReaderBookmark:onSaveSettings()
self.ui.doc_settings:saveSetting("bookmarks", self.bookmarks)
self.ui.doc_settings:makeTrue("bookmarks_sorted")
self.ui.doc_settings:makeTrue("bookmarks_sorted_20220106")
self.ui.doc_settings:makeTrue("highlights_imported")
end
@@ -833,7 +884,7 @@ function ReaderBookmark:addBookmark(item)
logger.warn("skip adding duplicated bookmark")
return
end
if self:isBookmarkInPageOrder(item, self.bookmarks[_middle]) then
if self:isBookmarkInPositionOrder(item, self.bookmarks[_middle]) then
_end, direction = _middle - 1, 0
else
_start, direction = _middle + 1, 1
@@ -894,7 +945,7 @@ function ReaderBookmark:removeBookmark(item, reset_auto_text_only)
self.view.footer:onUpdateFooter(self.view.footer_visible)
end
return
elseif self:isBookmarkInPageOrder(item, v) then
elseif self:isBookmarkInPositionOrder(item, v) then
_end = _middle - 1
else
_start = _middle + 1