mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Some refactoring and improvements:
1) Add a context menu to the notes widget. Remove the keyboard handler as it isn't needed. 2) Allow passing an item string value instead of an item_id to __init__ 3) Make the notes widget self contained, making the signal advisory instead of mandatory 4) Add a delete note button to the widget.
This commit is contained in:
parent
8e8f038896
commit
36f65e9187
@ -230,9 +230,7 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog):
|
|||||||
self.table.setItem(row, 1, sort_item)
|
self.table.setItem(row, 1, sort_item)
|
||||||
self.table.setItem(row, 2, link_item)
|
self.table.setItem(row, 2, link_item)
|
||||||
|
|
||||||
item_id = db.get_item_id('authors', name)
|
nw = NotesItemWidget(get_gui().current_db, 'authors', name)
|
||||||
nw = NotesItemWidget(get_gui().current_db.new_api, 'authors', item_id, row)
|
|
||||||
nw.clicked.connect(self.notes_button_clicked)
|
|
||||||
self.table.setCellWidget(row, 3, nw)
|
self.table.setCellWidget(row, 3, nw)
|
||||||
|
|
||||||
self.set_icon(name_item, id_)
|
self.set_icon(name_item, id_)
|
||||||
@ -285,10 +283,6 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog):
|
|||||||
self.start_find_pos = -1
|
self.start_find_pos = -1
|
||||||
self.table.blockSignals(False)
|
self.table.blockSignals(False)
|
||||||
|
|
||||||
def notes_button_clicked(self, w, field, item_id, db):
|
|
||||||
EditNoteDialog(field, item_id, db).exec()
|
|
||||||
w.set_checked()
|
|
||||||
|
|
||||||
def row_height_changed(self, row, old, new):
|
def row_height_changed(self, row, old, new):
|
||||||
self.table.verticalHeader().blockSignals(True)
|
self.table.verticalHeader().blockSignals(True)
|
||||||
self.table.verticalHeader().setDefaultSectionSize(new)
|
self.table.verticalHeader().setDefaultSectionSize(new)
|
||||||
|
@ -146,16 +146,40 @@ class EditColumnDelegate(QItemDelegate):
|
|||||||
|
|
||||||
|
|
||||||
class NotesItemWidget(QWidget):
|
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.
|
||||||
|
'''
|
||||||
|
|
||||||
clicked = pyqtSignal(object, object, object, object)
|
'''
|
||||||
icon = QIcon.ic('edit_input.png')
|
This signal is emitted when a note is edited, after the notes editor
|
||||||
|
returns, or deleted. It is provided in case the using class wants to know if
|
||||||
|
a note has possibly changed. If not then using this signal isn't required.
|
||||||
|
Parameters: self (this widget), field, item_id, note, db (new_api)
|
||||||
|
'''
|
||||||
|
note_edited = pyqtSignal(object, object, object, object, object)
|
||||||
|
|
||||||
def __init__(self, db, field, item_id, row):
|
edit_icon = QIcon.ic('edit_input.png')
|
||||||
|
delete_icon = QIcon.ic('trash.png')
|
||||||
|
|
||||||
|
def __init__(self, db, field, item_id):
|
||||||
|
'''
|
||||||
|
:param db: A database instance, either old or new api
|
||||||
|
:param field: the lookup name of a field
|
||||||
|
:param item_id: Either the numeric item_id of an item in the field or
|
||||||
|
the item's string value
|
||||||
|
'''
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.row = row
|
self.db = db = db.new_api
|
||||||
self.field = field
|
self.field = field
|
||||||
self.item_id = item_id
|
if isinstance(item_id, str):
|
||||||
self.db = db
|
self.item_id = db.get_item_id(field, item_id)
|
||||||
|
if self.item_id is None:
|
||||||
|
raise ValueError(f"The item {item_id} doesn't exist")
|
||||||
|
else:
|
||||||
|
self.item_id = item_id
|
||||||
|
|
||||||
l = QHBoxLayout()
|
l = QHBoxLayout()
|
||||||
l.setContentsMargins(2, 0, 0, 0)
|
l.setContentsMargins(2, 0, 0, 0)
|
||||||
@ -163,28 +187,62 @@ class NotesItemWidget(QWidget):
|
|||||||
cb = self.cb = QCheckBox()
|
cb = self.cb = QCheckBox()
|
||||||
cb.setEnabled(False)
|
cb.setEnabled(False)
|
||||||
l.addWidget(cb)
|
l.addWidget(cb)
|
||||||
tb = self.tb = QToolButton()
|
|
||||||
tb.setIcon(self.icon)
|
editb = self.edit_button = QToolButton()
|
||||||
tb.clicked.connect(self.tb_clicked)
|
editb.setIcon(self.edit_icon)
|
||||||
l.addWidget(tb)
|
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)
|
||||||
|
|
||||||
l.addStretch(3)
|
l.addStretch(3)
|
||||||
self.setFocusPolicy(Qt.FocusPolicy.StrongFocus)
|
self.setFocusPolicy(Qt.FocusPolicy.StrongFocus)
|
||||||
self.set_checked()
|
self.set_checked()
|
||||||
|
self.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
|
||||||
|
self.customContextMenuRequested.connect(self.show_context_menu)
|
||||||
|
|
||||||
def keyPressEvent(self, ev):
|
@classmethod
|
||||||
# Use this instead of focusProxy() because fp() changes selection behavior
|
def get_item_id(cls, db, field: str, value: str):
|
||||||
if ev.key() in (Qt.Key.Key_Enter, Qt.Key.Key_Return, Qt.Key.Key_Space):
|
return db.new_api.get_item_id(field, value)
|
||||||
ev.accept()
|
|
||||||
self.tb_clicked()
|
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 = m.addAction(self.delete_icon, _('Delete note'))
|
||||||
|
ac.setEnabled(self.cb.isChecked())
|
||||||
|
ac.triggered.connect(self.delete_button_clicked)
|
||||||
|
|
||||||
|
m.exec(self.mapToGlobal(point))
|
||||||
|
|
||||||
|
def edit_note(self):
|
||||||
|
EditNoteDialog(self.field, self.item_id, self.db).exec()
|
||||||
|
self.set_checked()
|
||||||
|
|
||||||
|
def delete_note(self):
|
||||||
|
if not question_dialog(self, _('Delete note?'),
|
||||||
|
'<p>'+_('The note will be immediately deleted. There is no undo. '
|
||||||
|
'Do you want to do this?')+'<br>'):
|
||||||
return
|
return
|
||||||
return super().keyPressEvent(ev)
|
self.db.set_notes_for(self.field, self.item_id, '')
|
||||||
|
self.set_checked()
|
||||||
def tb_clicked(self):
|
|
||||||
self.clicked.emit(self, self.field, self.item_id, self.db)
|
|
||||||
|
|
||||||
def set_checked(self):
|
def set_checked(self):
|
||||||
t = self.db.notes_for(self.field, self.item_id)
|
notes = self.db.notes_for(self.field, self.item_id)
|
||||||
self.cb.setChecked(bool(t))
|
t = bool(notes)
|
||||||
|
self.cb.setChecked(t)
|
||||||
|
self.delete_button.setEnabled(t)
|
||||||
|
self.note_edited.emit(self, self.field, self.item_id, notes, self.db)
|
||||||
|
|
||||||
|
def is_checked(self):
|
||||||
|
# returns True if the checkbox is checked, meaning the note contains text
|
||||||
|
return self.cb.isChecked()
|
||||||
|
|
||||||
|
|
||||||
class TagListEditor(QDialog, Ui_TagListEditor):
|
class TagListEditor(QDialog, Ui_TagListEditor):
|
||||||
@ -559,8 +617,7 @@ class TagListEditor(QDialog, Ui_TagListEditor):
|
|||||||
|
|
||||||
if self.category is not None:
|
if self.category is not None:
|
||||||
from calibre.gui2.ui import get_gui
|
from calibre.gui2.ui import get_gui
|
||||||
nw = NotesItemWidget(get_gui().current_db.new_api, self.category, _id, row)
|
nw = NotesItemWidget(get_gui().current_db, self.category, _id)
|
||||||
nw.clicked.connect(self.notes_button_clicked)
|
|
||||||
self.table.setCellWidget(row, 4, nw)
|
self.table.setCellWidget(row, 4, nw)
|
||||||
|
|
||||||
# re-sort the table
|
# re-sort the table
|
||||||
@ -578,10 +635,6 @@ class TagListEditor(QDialog, Ui_TagListEditor):
|
|||||||
self.start_find_pos = -1
|
self.start_find_pos = -1
|
||||||
self.table.blockSignals(False)
|
self.table.blockSignals(False)
|
||||||
|
|
||||||
def notes_button_clicked(self, w, field, item_id, db):
|
|
||||||
EditNoteDialog(field, item_id, db).exec()
|
|
||||||
w.set_checked()
|
|
||||||
|
|
||||||
def not_found_label_timer_event(self):
|
def not_found_label_timer_event(self):
|
||||||
self.not_found_label.setVisible(False)
|
self.not_found_label.setVisible(False)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user