From a52f03fa5cb340447ba3a7085ca3b86362f853e0 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 27 Aug 2023 11:36:19 +0530 Subject: [PATCH] More work on note editing UI --- src/calibre/db/backend.py | 7 +- src/calibre/db/cache.py | 4 +- src/calibre/gui2/comments_editor.py | 12 +++- .../gui2/dialogs/edit_category_notes.py | 64 +++++++++++++++++++ 4 files changed, 80 insertions(+), 7 deletions(-) diff --git a/src/calibre/db/backend.py b/src/calibre/db/backend.py index 1a02031c87..365b7c4222 100644 --- a/src/calibre/db/backend.py +++ b/src/calibre/db/backend.py @@ -972,9 +972,12 @@ class DB: def notes_for(self, field_name, item_id): return self.notes.get_note(self.conn, field_name, item_id) or '' - def set_notes_for(self, field, item_id, doc: str, searchable_text: str, resource_hashes) -> int: + def set_notes_for(self, field, item_id, doc: str, searchable_text: str, resource_hashes, remove_unused_resources) -> int: id_val = self.tables[field].id_map[item_id] - return self.notes.set_note(self.conn, field, item_id, id_val, doc, resource_hashes, searchable_text) + note_id = self.notes.set_note(self.conn, field, item_id, id_val, doc, resource_hashes, searchable_text) + if remove_unused_resources: + self.notes.remove_unreferenced_resources(self.conn) + return note_id def unretire_note_for(self, field, item_id) -> int: id_val = self.tables[field].id_map[item_id] diff --git a/src/calibre/db/cache.py b/src/calibre/db/cache.py index 5e4c0883f8..7263924f63 100644 --- a/src/calibre/db/cache.py +++ b/src/calibre/db/cache.py @@ -681,8 +681,8 @@ class Cache: return self.backend.notes_for(field, item_id) @write_api - def set_notes_for(self, field, item_id, doc: str, searchable_text: str = copy_marked_up_text, resource_hashes=()) -> int: - return self.backend.set_notes_for(field, item_id, doc, searchable_text, resource_hashes) + def set_notes_for(self, field, item_id, doc: str, searchable_text: str = copy_marked_up_text, resource_hashes=(), remove_unused_resources=False) -> int: + return self.backend.set_notes_for(field, item_id, doc, searchable_text, resource_hashes, remove_unused_resources) @write_api def add_notes_resource(self, path_or_stream_or_data, name: str) -> int: diff --git a/src/calibre/gui2/comments_editor.py b/src/calibre/gui2/comments_editor.py index a3988eb9be..710bf3a0a0 100644 --- a/src/calibre/gui2/comments_editor.py +++ b/src/calibre/gui2/comments_editor.py @@ -226,7 +226,7 @@ def cleanup_qt_markup(root): # }}} -def fix_html(original_html, original_txt, remove_comments=True): +def fix_html(original_html, original_txt, remove_comments=True, callback=None): raw = original_html raw = xml_to_unicode(raw, strip_encoding_pats=True, resolve_entities=True)[0] if remove_comments: @@ -248,6 +248,8 @@ def fix_html(original_html, original_txt, remove_comments=True): except Exception: import traceback traceback.print_exc() + if callback is not None: + callback(root) elems = [] for body in root.xpath('//body'): if body.text: @@ -808,7 +810,10 @@ class EditorWidget(QTextEdit, LineEditECM): # {{{ @property def html(self): - return fix_html(self.toHtml(), self.toPlainText().strip()) + return fix_html(self.toHtml(), self.toPlainText().strip(), callback=self.get_html_callback) + + def get_html_callback(self, root): + pass @html.setter def html(self, val): @@ -1137,12 +1142,13 @@ class Editor(QWidget): # {{{ toolbar_prefs_name = None data_changed = pyqtSignal() + editor_class = EditorWidget def __init__(self, parent=None, one_line_toolbar=False, toolbar_prefs_name=None): QWidget.__init__(self, parent) self.toolbar_prefs_name = toolbar_prefs_name or self.toolbar_prefs_name self.toolbar = create_flow_toolbar(self, restrict_to_single_line=one_line_toolbar, icon_size=18) - self.editor = EditorWidget(self) + self.editor = self.editor_class(self) self.editor.data_changed.connect(self.data_changed) self.set_base_url = self.editor.set_base_url self.set_html = self.editor.set_html diff --git a/src/calibre/gui2/dialogs/edit_category_notes.py b/src/calibre/gui2/dialogs/edit_category_notes.py index ece8b7a7a2..a13003562c 100644 --- a/src/calibre/gui2/dialogs/edit_category_notes.py +++ b/src/calibre/gui2/dialogs/edit_category_notes.py @@ -1,11 +1,75 @@ #!/usr/bin/env python # License: GPLv3 Copyright: 2023, Kovid Goyal +from qt.core import QIcon, QSize, QVBoxLayout, QWidget, pyqtSlot +from calibre.gui2.comments_editor import Editor, EditorWidget from calibre.gui2.widgets2 import Dialog +class NoteEditorWidget(EditorWidget): + + load_resource = None + + @pyqtSlot(int, 'QUrl', result='QVariant') + def loadResource(self, rtype, qurl): + if self.load_resource is not None: + return self.load_resource(rtype, qurl) + + def get_html_callback(self, root): + self.searchable_text = '' + self.referenced_resources = set() + + + +class NoteEditor(Editor): + editor_class = NoteEditorWidget + + def get_doc(self): + html = self.editor.html + return html, self.editor.searchable_text, self.editor.referenced_resources + + + +class EditNoteWidget(QWidget): + + def __init__(self, db, field, item_id, item_val, parent=None): + super().__init__(parent) + self.db, self.field, self.item_id, self.item_val = db, field, item_id, item_val + self.l = l = QVBoxLayout(self) + l.setContentsMargins(0, 0, 0, 0) + self.editor = e = NoteEditor(self, toolbar_prefs_name='edit-notes-for-category-ce') + e.editor.load_resource = self.load_resource + l.addWidget(e) + e.html = self.db.notes_for(field, item_id) or '' + + def load_resource(self, resource_type, qurl): + pass + + def sizeHint(self): + return QSize(800, 600) + + def commit(self): + doc, searchable_text, resources = self.editor.get_doc() + self.db.set_notes_for(self.field, self.item_id, doc, searchable_text, resources, remove_unused_resources=True) + return True + + class EditNoteDialog(Dialog): def __init__(self, field, item_id, db, parent=None): self.db = db.new_api + self.field, self.item_id = field, item_id + self.item_val = self.db.get_item_name(field, item_id) + super().__init__(_('Edit notes for {}').format(self.item_val), 'edit-notes-for-category', parent=parent) + self.setWindowIcon(QIcon.ic('edit_input.png')) + + def setup_ui(self): + self.l = l = QVBoxLayout(self) + self.edit_note_widget = EditNoteWidget(self.db, self.field, self.item_id, self.item_val, self) + l.addWidget(self.edit_note_widget) + l.addWidget(self.bb) + + def accept(self): + if self.edit_note_widget.commit(): + super().accept()