diff --git a/frontend/apps/reader/modules/readerbookmark.lua b/frontend/apps/reader/modules/readerbookmark.lua index 4b3ff2b2f..1be3df045 100644 --- a/frontend/apps/reader/modules/readerbookmark.lua +++ b/frontend/apps/reader/modules/readerbookmark.lua @@ -443,6 +443,24 @@ function ReaderBookmark:removeBookmark(item) logger.warn("removeBookmark: full scan search didn't find bookmark") end +function ReaderBookmark:updateBookmark(item) + for i=1, #self.bookmarks do + 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 new_text = item.updated_highlight.text + self.bookmarks[i].page = item.updated_highlight.pos0 + self.bookmarks[i].pos0 = item.updated_highlight.pos0 + self.bookmarks[i].pos1 = item.updated_highlight.pos1 + 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:onSaveSettings() + end + end +end + function ReaderBookmark:renameBookmark(item, from_highlight) if from_highlight then -- Called by ReaderHighlight:editHighlight, we need to find the bookmark diff --git a/frontend/apps/reader/modules/readerhighlight.lua b/frontend/apps/reader/modules/readerhighlight.lua index 10871421b..bb38314af 100644 --- a/frontend/apps/reader/modules/readerhighlight.lua +++ b/frontend/apps/reader/modules/readerhighlight.lua @@ -248,27 +248,139 @@ function ReaderHighlight:onTapXPointerSavedHighlight(ges) end end +function ReaderHighlight:updateHighlight(page, index, side, direction, move_by_char) + if self.ui.document.info.has_pages then -- we do this only if it's epub file + return + end + + local highlight = self.view.highlight.saved[page][index] + local highlight_time = highlight.datetime + local highlight_beginning = highlight.pos0 + local highlight_end = highlight.pos1 + if side == 0 then -- we move pos0 + if direction == 1 then -- move highlight to the right + local updated_highlight_beginning + if move_by_char then + updated_highlight_beginning = self.ui.document:getNextVisibleChar(highlight_beginning) + else + updated_highlight_beginning = self.ui.document:getNextVisibleWordStart(highlight_beginning) + end + if updated_highlight_beginning then -- in theory crengine could return nil + self.view.highlight.saved[page][index].pos0 = updated_highlight_beginning + end + else -- move highlight to the left + local updated_highlight_beginning + if move_by_char then + updated_highlight_beginning = self.ui.document:getPrevVisibleChar(highlight_beginning) + else + updated_highlight_beginning = self.ui.document:getPrevVisibleWordStart(highlight_beginning) + end + if updated_highlight_beginning then + self.view.highlight.saved[page][index].pos0 = updated_highlight_beginning + end + end + else -- we move pos1 + if direction == 1 then -- move highlight to the right + local updated_highlight_end + if move_by_char then + updated_highlight_end = self.ui.document:getNextVisibleChar(highlight_end) + else + updated_highlight_end = self.ui.document:getNextVisibleWordEnd(highlight_end) + end + if updated_highlight_end then + self.view.highlight.saved[page][index].pos1 = updated_highlight_end + end + else -- move highlight to the left + local updated_highlight_end + if move_by_char then + updated_highlight_end = self.ui.document:getPrevVisibleChar(highlight_end) + else + updated_highlight_end = self.ui.document:getPrevVisibleWordEnd(highlight_end) + end + if updated_highlight_end then + self.view.highlight.saved[page][index].pos1 = updated_highlight_end + end + end + end + + local new_beginning = self.view.highlight.saved[page][index].pos0 + local new_end = self.view.highlight.saved[page][index].pos1 + local new_text = self.ui.document:getTextFromXPointers(new_beginning, new_end) + self.view.highlight.saved[page][index].text = new_text + local new_highlight = self.view.highlight.saved[page][index] + self.ui.bookmark:updateBookmark({ + page = highlight_beginning, + datetime = highlight_time, + updated_highlight = new_highlight + }, true) + UIManager:setDirty(self.dialog, "ui") +end + function ReaderHighlight:onShowHighlightDialog(page, index) - self.edit_highlight_dialog = ButtonDialog:new{ - buttons = { + local buttons = { + { { - { - text = _("Delete"), - callback = function() - self:deleteHighlight(page, index) - -- other part outside of the dialog may be dirty - UIManager:close(self.edit_highlight_dialog, "ui") - end, - }, - { - text = _("Edit"), - callback = function() - self:editHighlight(page, index) - UIManager:close(self.edit_highlight_dialog) - end, - }, + text = _("Delete"), + callback = function() + self:deleteHighlight(page, index) + -- other part outside of the dialog may be dirty + UIManager:close(self.edit_highlight_dialog, "ui") + end, }, - }, + { + text = _("Edit"), + callback = function() + self:editHighlight(page, index) + UIManager:close(self.edit_highlight_dialog) + end, + }, + } + } + + if not self.ui.document.info.has_pages then + table.insert(buttons, { + { + text = _("◁⇱"), + callback = function() + self:updateHighlight(page, index, 0, -1, false) + end, + hold_callback = function() + self:updateHighlight(page, index, 0, -1, true) + return true + end + }, + { + text = _("⇱▷"), + callback = function() + self:updateHighlight(page, index, 0, 1, false) + end, + hold_callback = function() + self:updateHighlight(page, index, 0, 1, true) + return true + end + }, + { + text = _("◁⇲"), + callback = function() + self:updateHighlight(page, index, 1, -1, false) + end, + hold_callback = function() + self:updateHighlight(page, index, 1, -1, true) + end + }, + { + text = _("⇲▷"), + callback = function() + self:updateHighlight(page, index, 1, 1, false) + end, + hold_callback = function() + self:updateHighlight(page, index, 1, 1, true) + end + } + }) + end + self.edit_highlight_dialog = ButtonDialog:new{ + buttons = buttons } UIManager:show(self.edit_highlight_dialog) return true @@ -900,7 +1012,6 @@ function ReaderHighlight:deleteHighlight(page, i, bookmark_item) end function ReaderHighlight:editHighlight(page, i) - logger.info("edit highlight", page, i) local item = self.view.highlight.saved[page][i] self.ui.bookmark:renameBookmark({ page = self.ui.document.info.has_pages and page or item.pos0, diff --git a/frontend/document/credocument.lua b/frontend/document/credocument.lua index b44877631..b367ce19c 100644 --- a/frontend/document/credocument.lua +++ b/frontend/document/credocument.lua @@ -306,6 +306,30 @@ function CreDocument:getScreenBoxesFromPositions(pos0, pos1, get_segments) return line_boxes end +function CreDocument:getNextVisibleWordStart(xp) + return self._document:getNextVisibleWordStart(xp) +end + +function CreDocument:getNextVisibleWordEnd(xp) + return self._document:getNextVisibleWordEnd(xp) +end + +function CreDocument:getPrevVisibleWordStart(xp) + return self._document:getPrevVisibleWordStart(xp) +end + +function CreDocument:getPrevVisibleWordEnd(xp) + return self._document:getPrevVisibleWordEnd(xp) +end + +function CreDocument:getPrevVisibleChar(xp) + return self._document:getPrevVisibleChar(xp) +end + +function CreDocument:getNextVisibleChar(xp) + return self._document:getNextVisibleChar(xp) +end + function CreDocument:drawCurrentView(target, x, y, rect, pos) if self.buffer and (self.buffer.w ~= rect.w or self.buffer.h ~= rect.h) then self.buffer:free() @@ -428,6 +452,10 @@ function CreDocument:getTextFromXPointer(xp) end end +function CreDocument:getTextFromXPointers(pos0, pos1) + return self._document:getTextFromXPointers(pos0, pos1) +end + function CreDocument:getHTMLFromXPointer(xp, flags, from_final_parent) if xp then return self._document:getHTMLFromXPointer(xp, flags, from_final_parent) diff --git a/frontend/ui/widget/button.lua b/frontend/ui/widget/button.lua index 90e47f23d..c006e7160 100644 --- a/frontend/ui/widget/button.lua +++ b/frontend/ui/widget/button.lua @@ -102,6 +102,13 @@ function Button:init() range = self.dimen, }, doc = "Hold Button", + }, + -- Safe-guard for when used inside a MovableContainer + HoldReleaseSelectButton = { + GestureRange:new{ + ges = "hold_release", + range = self.dimen, + }, } } end @@ -240,4 +247,16 @@ function Button:onHoldSelectButton() return true end +function Button:onHoldReleaseSelectButton() + -- Safe-guard for when used inside a MovableContainer, + -- which would handle HoldRelease and process it like + -- a Hold if we wouldn't return true here + if self.enabled and self.hold_callback then + return true + elseif self.hold_input or type(self.hold_input_func) == "function" then + return true + end + return false +end + return Button diff --git a/frontend/ui/widget/buttontable.lua b/frontend/ui/widget/buttontable.lua index f2fac48e2..22fdda267 100644 --- a/frontend/ui/widget/buttontable.lua +++ b/frontend/ui/widget/buttontable.lua @@ -53,6 +53,7 @@ function ButtonTable:init() text = btn_entry.text, enabled = btn_entry.enabled, callback = btn_entry.callback, + hold_callback = btn_entry.hold_callback, width = (self.width - sizer_space)/column_cnt, max_width = (self.width - sizer_space)/column_cnt - 2*self.sep_width - 2*self.padding, bordersize = 0,