Browse annotations: Add a check box to restrict the displayed annotations to only the books currently selected in the calibre library. Fixes #1897354 [Enhancement Request: Annotation browser and VLs](https://bugs.launchpad.net/calibre/+bug/1897354)

This commit is contained in:
Kovid Goyal 2020-10-06 12:42:23 +05:30
parent 0f4b491083
commit 45f9e9318c
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
3 changed files with 75 additions and 16 deletions

View File

@ -25,18 +25,23 @@ class BrowseAnnotationsAction(InterfaceAction):
def browser(self):
if self._browser is None:
from calibre.gui2.library.annotations import AnnotationsBrowser
self.gui.library_view.selection_changed.connect(self.selection_changed)
self._browser = AnnotationsBrowser(self.gui)
self._browser.show_book.connect(self.open_book, type=Qt.QueuedConnection)
self._browser.open_annotation.connect(self.open_annotation, type=Qt.QueuedConnection)
return self._browser
def show_browser(self):
self.browser.show_dialog()
self.browser.show_dialog(self.gui.library_view.get_selected_ids(as_set=True))
def library_changed(self, db):
if self._browser is not None:
self._browser.reinitialize()
def selection_changed(self):
if self._browser is not None:
self._browser.selection_changed()
def open_book(self, book_id, fmt):
self.gui.library_view.select_rows({book_id})

View File

@ -286,10 +286,15 @@ class Restrictions(QWidget):
restrictions_changed = pyqtSignal()
def __init__(self, parent):
self.restrict_to_book_ids = frozenset()
QWidget.__init__(self, parent)
h = QHBoxLayout(self)
v = QVBoxLayout(self)
v.setContentsMargins(0, 0, 0, 0)
h = QHBoxLayout()
h.setContentsMargins(0, 0, 0, 0)
h.addWidget(QLabel(_('Restrict to') + ': '))
v.addLayout(h)
self.rla = QLabel(_('Restrict to') + ': ')
h.addWidget(self.rla)
la = QLabel(_('Types:'))
h.addWidget(la)
self.types_box = tb = QComboBox(self)
@ -309,8 +314,42 @@ class Restrictions(QWidget):
ub.setToolTip(_('Show only annotations created by the specified user'))
h.addWidget(ub)
h.addStretch(10)
h = QHBoxLayout()
self.restrict_to_books_cb = cb = QCheckBox('')
self.update_book_restrictions_text()
cb.setToolTip(_('Only show annotations from books that have been selected in the calibre library'))
cb.setChecked(bool(gprefs.get('show_annots_from_selected_books_only', False)))
cb.stateChanged.connect(self.show_only_selected_changed)
h.addWidget(cb)
v.addLayout(h)
def re_initialize(self, db):
def update_book_restrictions_text(self):
if not self.restrict_to_book_ids:
t = _('Show results from only selected books')
else:
t = ngettext(
'Show results from only the selected book',
'Show results from only the {} selected books',
len(self.restrict_to_book_ids)).format(len(self.restrict_to_book_ids))
self.restrict_to_books_cb.setText(t)
def show_only_selected_changed(self):
self.restrictions_changed.emit()
gprefs['show_annots_from_selected_books_only'] = bool(self.restrict_to_books_cb.isChecked())
def selection_changed(self, restrict_to_book_ids):
self.restrict_to_book_ids = frozenset(restrict_to_book_ids or set())
self.update_book_restrictions_text()
if self.restrict_to_books_cb.isChecked():
self.restrictions_changed.emit()
@property
def effective_restrict_to_book_ids(self):
return (self.restrict_to_book_ids or None) if self.restrict_to_books_cb.isChecked() else None
def re_initialize(self, db, restrict_to_book_ids=None):
self.restrict_to_book_ids = frozenset(restrict_to_book_ids or set())
self.update_book_restrictions_text()
tb = self.types_box
before = tb.currentData()
if not before:
@ -344,7 +383,8 @@ class Restrictions(QWidget):
tb.blockSignals(False)
ub_is_visible = tb.count() > 2
tb.setVisible(ub_is_visible), tb.la.setVisible(ub_is_visible)
self.setVisible(tb_is_visible or ub_is_visible)
self.rla.setVisible(tb_is_visible or ub_is_visible)
self.setVisible(True)
class BrowsePanel(QWidget):
@ -393,13 +433,16 @@ class BrowsePanel(QWidget):
rl.delete_requested.connect(self.delete_requested)
l.addWidget(rl)
def re_initialize(self):
def re_initialize(self, restrict_to_book_ids=None):
db = current_db()
self.search_box.setFocus(Qt.OtherFocusReason)
self.restrictions.re_initialize(db)
self.restrictions.re_initialize(db, restrict_to_book_ids or set())
self.current_query = None
self.results_list.clear()
def selection_changed(self, restrict_to_book_ids):
self.restrictions.selection_changed(restrict_to_book_ids)
def sizeHint(self):
return QSize(450, 600)
@ -418,6 +461,7 @@ class BrowsePanel(QWidget):
'annotation_type': (atype or '').strip(),
'restrict_to_user': self.restrict_to_user,
'use_stemming': bool(self.use_stemmer.isChecked()),
'restrict_to_book_ids': self.restrictions.effective_restrict_to_book_ids,
}
def cleared(self):
@ -434,12 +478,13 @@ class BrowsePanel(QWidget):
if not q['fts_engine_query']:
results = db.all_annotations(
restrict_to_user=q['restrict_to_user'], limit=4096, annotation_type=q['annotation_type'],
ignore_removed=True
ignore_removed=True, restrict_to_book_ids=q['restrict_to_book_ids'] or None
)
else:
results = db.search_annotations(
highlight_start='\x1d', highlight_end='\x1d', snippet_size=64,
ignore_removed=True, **q
ignore_removed=True, restrict_to_book_ids=q['restrict_to_book_ids'] or None,
**q
)
self.results_list.set_results(results, bool(q['fts_engine_query']))
self.current_query = q
@ -729,18 +774,23 @@ class AnnotationsBrowser(Dialog):
db.update_annotations({annot_id: annot})
self.details_panel.update_notes(annot)
def show_dialog(self):
def show_dialog(self, restrict_to_book_ids=None):
if self.parent() is None:
self.browse_panel.effective_query_changed()
self.exec_()
else:
self.reinitialize()
self.reinitialize(restrict_to_book_ids)
self.show()
self.raise_()
QTimer.singleShot(80, self.browse_panel.effective_query_changed)
def reinitialize(self):
self.browse_panel.re_initialize()
def selection_changed(self):
if self.isVisible() and self.parent():
gui = self.parent()
self.browse_panel.selection_changed(gui.library_view.get_selected_ids(as_set=True))
def reinitialize(self, restrict_to_book_ids=None):
self.browse_panel.re_initialize(restrict_to_book_ids or set())
if __name__ == '__main__':

View File

@ -206,6 +206,7 @@ class BooksView(QTableView): # {{{
files_dropped = pyqtSignal(object)
books_dropped = pyqtSignal(object)
selection_changed = pyqtSignal()
add_column_signal = pyqtSignal()
is_library_view = True
@ -288,6 +289,7 @@ class BooksView(QTableView): # {{{
wv.setSelectionBehavior(QAbstractItemView.SelectRows)
wv.setSortingEnabled(True)
self.selectionModel().currentRowChanged.connect(self._model.current_changed)
self.selectionModel().selectionChanged.connect(self.selection_changed.emit)
self.preserve_state = partial(PreserveViewState, self)
self.marked_changed_listener = FunctionDispatcher(self.marked_changed)
@ -1235,15 +1237,17 @@ class BooksView(QTableView): # {{{
m.index(max(group), max_col)), sm.Select)
sm.select(sel, sm.ClearAndSelect)
def get_selected_ids(self):
def get_selected_ids(self, as_set=False):
ans = []
seen = set()
m = self.model()
for idx in self.selectedIndexes():
r = idx.row()
i = m.id(r)
if i not in ans:
if i not in seen:
ans.append(i)
return ans
seen.add(i)
return seen if as_set else ans
@property
def current_id(self):