From b9dcc6ee85b892311fc17ef275511732614176cf Mon Sep 17 00:00:00 2001 From: Charles Haley Date: Tue, 12 Sep 2023 15:40:22 +0100 Subject: [PATCH] Add the undo button. Clean up some code. --- src/calibre/gui2/dialogs/tag_list_editor.py | 59 +++++++++++++-------- src/calibre/gui2/dialogs/tag_list_editor.ui | 11 ---- 2 files changed, 36 insertions(+), 34 deletions(-) diff --git a/src/calibre/gui2/dialogs/tag_list_editor.py b/src/calibre/gui2/dialogs/tag_list_editor.py index 0ff614447d..7be7e134fe 100644 --- a/src/calibre/gui2/dialogs/tag_list_editor.py +++ b/src/calibre/gui2/dialogs/tag_list_editor.py @@ -150,7 +150,7 @@ class NotesItemWidget(QWidget): This is a self-contained widget for manipulating notes. It can be used in a table (as a cellWidget) or in a layout. It currently contains a check box indicating that the item has a note, and buttons to edit/create or delete a - note. + note, or undo a deletion. ''' ''' @@ -163,6 +163,7 @@ class NotesItemWidget(QWidget): edit_icon = QIcon.ic('edit_input.png') delete_icon = QIcon.ic('trash.png') + undo_delete_icon = QIcon.ic('edit-undo.png') def __init__(self, db, field, item_id): ''' @@ -180,6 +181,7 @@ class NotesItemWidget(QWidget): raise ValueError(f"The item {item_id} doesn't exist") else: self.item_id = item_id + self.can_undo = False l = QHBoxLayout() l.setContentsMargins(2, 0, 0, 0) @@ -188,19 +190,20 @@ class NotesItemWidget(QWidget): cb.setEnabled(False) l.addWidget(cb) - editb = self.edit_button = QToolButton() - editb.setIcon(self.edit_icon) - editb.clicked.connect(self.edit_note) - editb.setContentsMargins(0, 0, 0, 0) - l.addWidget(editb) - - delb = self.delete_button = QToolButton() - delb.setIcon(self.delete_icon) - delb.clicked.connect(self.delete_note) - delb.setContentsMargins(0, 0, 0, 0) - l.addWidget(delb) - + self.buttons = {} + for button_data in (('edit', 'Edit or create the note. Changes cannot be undone or cancelled'), + ('delete', 'Delete the note'), + ('undo_delete', 'Undo the deletion')): + button_name = button_data[0] + tool_tip = button_data[1] + b = self.buttons[button_name] = QToolButton() + b.setIcon(getattr(self, button_name + '_icon')) + b.setToolTip(tool_tip) + b.clicked.connect(getattr(self, 'do_' + button_name)) + b.setContentsMargins(0, 0, 0, 0) + l.addWidget(b) l.addStretch(3) + self.setFocusPolicy(Qt.FocusPolicy.StrongFocus) self.set_checked() self.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu) @@ -213,31 +216,41 @@ class NotesItemWidget(QWidget): def show_context_menu(self, point): m = QMenu() ac = m.addAction(self.edit_icon, _('Edit note') if self.cb.isChecked() else _('Create note')) - ac.triggered.connect(self.edit_button_clicked) + ac.triggered.connect(self.do_edit) ac = m.addAction(self.delete_icon, _('Delete note')) ac.setEnabled(self.cb.isChecked()) - ac.triggered.connect(self.delete_button_clicked) + ac.triggered.connect(self.do_delete) + + ac = m.addAction(self.delete_icon, _('Undo delete')) + ac.setEnabled(self.can_undo) + ac.triggered.connect(self.do_undo_delete) m.exec(self.mapToGlobal(point)) - def edit_note(self): - EditNoteDialog(self.field, self.item_id, self.db).exec() + def do_edit(self): + accepted = EditNoteDialog(self.field, self.item_id, self.db).exec() + # Continue to allow an undo if it was allowed before and the dialog was cancelled. + self.can_undo = not accepted and self.can_undo self.set_checked() - def delete_note(self): - if not question_dialog(self, _('Delete note?'), - '

'+_('The note will be immediately deleted. There is no undo. ' - 'Do you want to do this?')+'
'): - return + def do_delete(self): self.db.set_notes_for(self.field, self.item_id, '') + self.can_undo = True self.set_checked() + def do_undo_delete(self): + if self.can_undo: + self.db.unretire_note_for(self.field, self.item_id) + self.can_undo = False + self.set_checked() + def set_checked(self): notes = self.db.notes_for(self.field, self.item_id) t = bool(notes) self.cb.setChecked(t) - self.delete_button.setEnabled(t) + self.buttons['delete'].setEnabled(t) + self.buttons['undo_delete'].setEnabled(self.can_undo) self.note_edited.emit(self, self.field, self.item_id, notes, self.db) def is_checked(self): diff --git a/src/calibre/gui2/dialogs/tag_list_editor.ui b/src/calibre/gui2/dialogs/tag_list_editor.ui index 9a309030be..789940df40 100644 --- a/src/calibre/gui2/dialogs/tag_list_editor.ui +++ b/src/calibre/gui2/dialogs/tag_list_editor.ui @@ -127,17 +127,6 @@ - - - - Notes changes are immediate - - - Creating or changing a note has immediate effect. They are not -reverted by undo or canceling this dialog - - -