mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Add a button to delete selected annotations in the browse annotations tool
This commit is contained in:
parent
6acd9c1989
commit
93cb98185f
@ -1834,6 +1834,31 @@ class DB(object):
|
||||
if not ignore_removed or not annot.get('removed'):
|
||||
yield {'format': fmt, 'user_type': user_type, 'user': user, 'annotation': annot}
|
||||
|
||||
def delete_annotations(self, annot_ids):
|
||||
from calibre.utils.date import utcnow
|
||||
replacements = []
|
||||
removals = []
|
||||
for annot_id in annot_ids:
|
||||
for (raw_annot_data, annot_type) in self.execute(
|
||||
'SELECT annot_data, annot_type FROM annotations WHERE id=?', (annot_id,)
|
||||
):
|
||||
try:
|
||||
annot_data = json.loads(raw_annot_data)
|
||||
except Exception:
|
||||
removals.append((annot_id,))
|
||||
continue
|
||||
new_annot = {'removed': True, 'timestamp': utcnow().isoformat(), 'type': annot_type}
|
||||
uuid = annot_data.get('uuid')
|
||||
if uuid is not None:
|
||||
new_annot['uuid'] = uuid
|
||||
else:
|
||||
new_annot['title'] = annot_data['title']
|
||||
replacements.append((json.dumps(new_annot), annot_id))
|
||||
if replacements:
|
||||
self.executemany('UPDATE annotations SET annot_data=?, searchable_text="" WHERE id=?', replacements)
|
||||
if removals:
|
||||
self.executemany('DELETE FROM annotations WHERE id=?', removals)
|
||||
|
||||
def all_annotations(self, restrict_to_user=None, limit=None, annotation_type=None, ignore_removed=False):
|
||||
ls = json.loads
|
||||
q = 'SELECT id, book, format, user_type, user, annot_data FROM annotations'
|
||||
|
@ -2333,6 +2333,10 @@ class Cache(object):
|
||||
ignore_removed
|
||||
))
|
||||
|
||||
@write_api
|
||||
def delete_annotations(self, annot_ids):
|
||||
self.backend.delete_annotations(annot_ids)
|
||||
|
||||
@write_api
|
||||
def restore_annotations(self, book_id, annotations):
|
||||
from calibre.utils.iso8601 import parse_iso8601
|
||||
|
@ -13,7 +13,7 @@ from PyQt5.Qt import (
|
||||
|
||||
from calibre import prepare_string_for_xml
|
||||
from calibre.ebooks.metadata import authors_to_string, fmt_sidx
|
||||
from calibre.gui2 import Application, config, gprefs
|
||||
from calibre.gui2 import Application, config, error_dialog, gprefs, question_dialog
|
||||
from calibre.gui2.viewer.widgets import ResultsDelegate, SearchBox
|
||||
from calibre.gui2.widgets2 import Dialog
|
||||
|
||||
@ -76,6 +76,7 @@ class ResultsList(QTreeWidget):
|
||||
def __init__(self, parent):
|
||||
QTreeWidget.__init__(self, parent)
|
||||
self.setHeaderHidden(True)
|
||||
self.setSelectionMode(self.ExtendedSelection)
|
||||
self.delegate = AnnotsResultsDelegate(self)
|
||||
self.setItemDelegate(self.delegate)
|
||||
self.section_font = QFont(self.font())
|
||||
@ -145,6 +146,11 @@ class ResultsList(QTreeWidget):
|
||||
return
|
||||
return QTreeWidget.keyPressEvent(self, ev)
|
||||
|
||||
@property
|
||||
def selected_annot_ids(self):
|
||||
for item in self.selectedItems():
|
||||
yield item.data(0, Qt.UserRole)['id']
|
||||
|
||||
|
||||
class Restrictions(QWidget):
|
||||
|
||||
@ -310,12 +316,20 @@ class BrowsePanel(QWidget):
|
||||
def effective_query_changed(self):
|
||||
self.do_find()
|
||||
|
||||
def refresh(self):
|
||||
self.current_query = None
|
||||
self.do_find()
|
||||
|
||||
def show_next(self):
|
||||
self.do_find()
|
||||
|
||||
def show_previous(self):
|
||||
self.do_find(backwards=True)
|
||||
|
||||
@property
|
||||
def selected_annot_ids(self):
|
||||
return self.results_list.selected_annot_ids
|
||||
|
||||
|
||||
class Details(QTextBrowser):
|
||||
|
||||
@ -486,9 +500,28 @@ class AnnotationsBrowser(Dialog):
|
||||
h = QHBoxLayout()
|
||||
l.addLayout(h)
|
||||
h.addWidget(us), h.addStretch(10), h.addWidget(self.bb)
|
||||
self.delete_button = b = self.bb.addButton(_('Delete selected'), self.bb.ActionRole)
|
||||
b.setToolTip(_('Delete the selected annotations'))
|
||||
b.setIcon(QIcon(I('trash.png')))
|
||||
b.clicked.connect(self.delete_selected)
|
||||
|
||||
def delete_selected(self):
|
||||
ids = frozenset(self.browse_panel.selected_annot_ids)
|
||||
if not ids:
|
||||
return error_dialog(self, _('No selected annotations'), _(
|
||||
'No annotations have been selected'), show=True)
|
||||
if question_dialog(self, _('Are you sure?'), ngettext(
|
||||
'Are you sure you want to <b>permanently</b> delete this annotation?',
|
||||
'Are you sure you want to <b>permanently</b> delete these {} annotations?',
|
||||
len(ids)).format(len(ids))
|
||||
):
|
||||
db = current_db()
|
||||
db.delete_annotations(ids)
|
||||
self.browse_panel.refresh()
|
||||
|
||||
def show_dialog(self):
|
||||
if self.parent() is None:
|
||||
self.browse_panel.effective_query_changed()
|
||||
self.exec_()
|
||||
else:
|
||||
self.reinitialize()
|
||||
|
Loading…
x
Reference in New Issue
Block a user