From 95abe9d07296499bdf2d10deaffbcb82c4dbe3d1 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 19 Oct 2020 17:54:37 +0530 Subject: [PATCH] Viewer: handle editing of missing highlights more gracefully Fixes #1900358 [ebook-viewer Reapplying missing annotation highlight after modifying ePub](https://bugs.launchpad.net/calibre/+bug/1900358) --- src/pyj/read_book/iframe.pyj | 2 ++ src/pyj/read_book/selection_bar.pyj | 36 ++++++++++++++++++++++++++++- src/pyj/read_book/view.pyj | 2 ++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/pyj/read_book/iframe.pyj b/src/pyj/read_book/iframe.pyj index a78132cc9b..6819e1b0d9 100644 --- a/src/pyj/read_book/iframe.pyj +++ b/src/pyj/read_book/iframe.pyj @@ -780,6 +780,8 @@ class IframeBoss: window.setTimeout(def(): self.send_message('annotations', type='edit-highlight') , 50) + else: + self.send_message('annotations', type='edit-highlight-failed', uuid=data.uuid) elif dtype is 'notes-edited': cls = 'crw-has-dot' crw_ = {v: k for k, v in Object.entries(annot_id_uuid_map)}[data.uuid] diff --git a/src/pyj/read_book/selection_bar.pyj b/src/pyj/read_book/selection_bar.pyj index b5158ce750..4277eb9a17 100644 --- a/src/pyj/read_book/selection_bar.pyj +++ b/src/pyj/read_book/selection_bar.pyj @@ -9,11 +9,12 @@ from uuid import short_uuid from book_list.globals import get_session_data from book_list.theme import get_color from dom import change_icon_image, clear, svgicon, unique_id -from modals import error_dialog, question_dialog +from modals import error_dialog, question_dialog, create_custom_dialog from read_book.globals import runtime, ui_operations from read_book.highlights import ( ICON_SIZE, EditNotesAndColors, HighlightStyle, all_styles, render_notes ) +from widgets import create_button from read_book.shortcuts import shortcut_for_key_event from read_book.toc import get_toc_nodes_bordering_spine_item, family_for_toc_node @@ -573,6 +574,37 @@ class SelectionBar: self.new_bookmark() elif sc_name is 'toggle_highlights': self.view.on_handle_shortcut({'name': sc_name}) + + def report_failed_edit_highlight(self, annot_id): + notes = self.annotations_manager.notes_for_highlight(annot_id) + has_notes = bool(notes) + title = _('Highlight text missing') + text = _( + 'The text associated with this highlight could not be found in the book.' + ' This can happen if the book was modified. This highlight will be automatically removed.' + ) + if runtime.is_standalone_viewer or not has_notes: + if has_notes: + ui_operations.copy_selection(notes) + text += ' ' + _('The notes for this highlight have been copied to the clipboard.') + error_dialog(title, text) + else: + create_custom_dialog(title, def (parent, close_modal): + parent.appendChild(E.div( + E.div(text), + E.div( + class_='button-box', + create_button( + _('Copy notes to clipboard'), None, def(): + ui_operations.copy_selection(notes) + close_modal() + , highlight=True), + '\xa0', + create_button(_('OK'), None, close_modal), + ) + )) + ) + self.remove_highlight_with_id(annot_id) # }}} # drag scroll {{{ @@ -992,6 +1024,8 @@ class SelectionBar: elif msg.type is 'edit-highlight': if self.state is WAITING: self.create_highlight() + elif msg.type is 'edit-highlight-failed': + self.report_failed_edit_highlight(msg.uuid) elif msg.type is 'double-click': self.last_double_click_at = window.performance.now() else: diff --git a/src/pyj/read_book/view.pyj b/src/pyj/read_book/view.pyj index 67ab61ab6c..a64615cfd3 100644 --- a/src/pyj/read_book/view.pyj +++ b/src/pyj/read_book/view.pyj @@ -1320,6 +1320,8 @@ class View: spine = self.book.manifest.spine spine_index = self.annotations_manager.spine_index_for_highlight(uuid, spine) if spine_index < 0 or spine_index >= spine.length: + if which is 'edit': + self.selection_bar.report_failed_edit_highlight(uuid) return if which is 'edit': if self.currently_showing.spine_index is spine_index: