Add a button to delete selected annotations in the browse annotations tool

This commit is contained in:
Kovid Goyal 2020-08-05 23:32:03 +05:30
parent 6acd9c1989
commit 93cb98185f
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
3 changed files with 63 additions and 1 deletions

View File

@ -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'

View File

@ -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

View File

@ -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()