More work on note editing UI

This commit is contained in:
Kovid Goyal 2023-08-27 11:36:19 +05:30
parent bf723cd34d
commit a52f03fa5c
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
4 changed files with 80 additions and 7 deletions

View File

@ -972,9 +972,12 @@ class DB:
def notes_for(self, field_name, item_id): def notes_for(self, field_name, item_id):
return self.notes.get_note(self.conn, field_name, item_id) or '' 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] 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: def unretire_note_for(self, field, item_id) -> int:
id_val = self.tables[field].id_map[item_id] id_val = self.tables[field].id_map[item_id]

View File

@ -681,8 +681,8 @@ class Cache:
return self.backend.notes_for(field, item_id) return self.backend.notes_for(field, item_id)
@write_api @write_api
def set_notes_for(self, field, item_id, doc: str, searchable_text: str = copy_marked_up_text, resource_hashes=()) -> int: 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) return self.backend.set_notes_for(field, item_id, doc, searchable_text, resource_hashes, remove_unused_resources)
@write_api @write_api
def add_notes_resource(self, path_or_stream_or_data, name: str) -> int: def add_notes_resource(self, path_or_stream_or_data, name: str) -> int:

View File

@ -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 = original_html
raw = xml_to_unicode(raw, strip_encoding_pats=True, resolve_entities=True)[0] raw = xml_to_unicode(raw, strip_encoding_pats=True, resolve_entities=True)[0]
if remove_comments: if remove_comments:
@ -248,6 +248,8 @@ def fix_html(original_html, original_txt, remove_comments=True):
except Exception: except Exception:
import traceback import traceback
traceback.print_exc() traceback.print_exc()
if callback is not None:
callback(root)
elems = [] elems = []
for body in root.xpath('//body'): for body in root.xpath('//body'):
if body.text: if body.text:
@ -808,7 +810,10 @@ class EditorWidget(QTextEdit, LineEditECM): # {{{
@property @property
def html(self): 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 @html.setter
def html(self, val): def html(self, val):
@ -1137,12 +1142,13 @@ class Editor(QWidget): # {{{
toolbar_prefs_name = None toolbar_prefs_name = None
data_changed = pyqtSignal() data_changed = pyqtSignal()
editor_class = EditorWidget
def __init__(self, parent=None, one_line_toolbar=False, toolbar_prefs_name=None): def __init__(self, parent=None, one_line_toolbar=False, toolbar_prefs_name=None):
QWidget.__init__(self, parent) QWidget.__init__(self, parent)
self.toolbar_prefs_name = toolbar_prefs_name or self.toolbar_prefs_name 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.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.editor.data_changed.connect(self.data_changed)
self.set_base_url = self.editor.set_base_url self.set_base_url = self.editor.set_base_url
self.set_html = self.editor.set_html self.set_html = self.editor.set_html

View File

@ -1,11 +1,75 @@
#!/usr/bin/env python #!/usr/bin/env python
# License: GPLv3 Copyright: 2023, Kovid Goyal <kovid at kovidgoyal.net> # License: GPLv3 Copyright: 2023, Kovid Goyal <kovid at kovidgoyal.net>
from qt.core import QIcon, QSize, QVBoxLayout, QWidget, pyqtSlot
from calibre.gui2.comments_editor import Editor, EditorWidget
from calibre.gui2.widgets2 import Dialog 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): class EditNoteDialog(Dialog):
def __init__(self, field, item_id, db, parent=None): def __init__(self, field, item_id, db, parent=None):
self.db = db.new_api 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()