mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
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:
parent
0f4b491083
commit
45f9e9318c
@ -25,18 +25,23 @@ class BrowseAnnotationsAction(InterfaceAction):
|
|||||||
def browser(self):
|
def browser(self):
|
||||||
if self._browser is None:
|
if self._browser is None:
|
||||||
from calibre.gui2.library.annotations import AnnotationsBrowser
|
from calibre.gui2.library.annotations import AnnotationsBrowser
|
||||||
|
self.gui.library_view.selection_changed.connect(self.selection_changed)
|
||||||
self._browser = AnnotationsBrowser(self.gui)
|
self._browser = AnnotationsBrowser(self.gui)
|
||||||
self._browser.show_book.connect(self.open_book, type=Qt.QueuedConnection)
|
self._browser.show_book.connect(self.open_book, type=Qt.QueuedConnection)
|
||||||
self._browser.open_annotation.connect(self.open_annotation, type=Qt.QueuedConnection)
|
self._browser.open_annotation.connect(self.open_annotation, type=Qt.QueuedConnection)
|
||||||
return self._browser
|
return self._browser
|
||||||
|
|
||||||
def show_browser(self):
|
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):
|
def library_changed(self, db):
|
||||||
if self._browser is not None:
|
if self._browser is not None:
|
||||||
self._browser.reinitialize()
|
self._browser.reinitialize()
|
||||||
|
|
||||||
|
def selection_changed(self):
|
||||||
|
if self._browser is not None:
|
||||||
|
self._browser.selection_changed()
|
||||||
|
|
||||||
def open_book(self, book_id, fmt):
|
def open_book(self, book_id, fmt):
|
||||||
self.gui.library_view.select_rows({book_id})
|
self.gui.library_view.select_rows({book_id})
|
||||||
|
|
||||||
|
@ -286,10 +286,15 @@ class Restrictions(QWidget):
|
|||||||
restrictions_changed = pyqtSignal()
|
restrictions_changed = pyqtSignal()
|
||||||
|
|
||||||
def __init__(self, parent):
|
def __init__(self, parent):
|
||||||
|
self.restrict_to_book_ids = frozenset()
|
||||||
QWidget.__init__(self, parent)
|
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.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:'))
|
la = QLabel(_('Types:'))
|
||||||
h.addWidget(la)
|
h.addWidget(la)
|
||||||
self.types_box = tb = QComboBox(self)
|
self.types_box = tb = QComboBox(self)
|
||||||
@ -309,8 +314,42 @@ class Restrictions(QWidget):
|
|||||||
ub.setToolTip(_('Show only annotations created by the specified user'))
|
ub.setToolTip(_('Show only annotations created by the specified user'))
|
||||||
h.addWidget(ub)
|
h.addWidget(ub)
|
||||||
h.addStretch(10)
|
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
|
tb = self.types_box
|
||||||
before = tb.currentData()
|
before = tb.currentData()
|
||||||
if not before:
|
if not before:
|
||||||
@ -344,7 +383,8 @@ class Restrictions(QWidget):
|
|||||||
tb.blockSignals(False)
|
tb.blockSignals(False)
|
||||||
ub_is_visible = tb.count() > 2
|
ub_is_visible = tb.count() > 2
|
||||||
tb.setVisible(ub_is_visible), tb.la.setVisible(ub_is_visible)
|
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):
|
class BrowsePanel(QWidget):
|
||||||
@ -393,13 +433,16 @@ class BrowsePanel(QWidget):
|
|||||||
rl.delete_requested.connect(self.delete_requested)
|
rl.delete_requested.connect(self.delete_requested)
|
||||||
l.addWidget(rl)
|
l.addWidget(rl)
|
||||||
|
|
||||||
def re_initialize(self):
|
def re_initialize(self, restrict_to_book_ids=None):
|
||||||
db = current_db()
|
db = current_db()
|
||||||
self.search_box.setFocus(Qt.OtherFocusReason)
|
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.current_query = None
|
||||||
self.results_list.clear()
|
self.results_list.clear()
|
||||||
|
|
||||||
|
def selection_changed(self, restrict_to_book_ids):
|
||||||
|
self.restrictions.selection_changed(restrict_to_book_ids)
|
||||||
|
|
||||||
def sizeHint(self):
|
def sizeHint(self):
|
||||||
return QSize(450, 600)
|
return QSize(450, 600)
|
||||||
|
|
||||||
@ -418,6 +461,7 @@ class BrowsePanel(QWidget):
|
|||||||
'annotation_type': (atype or '').strip(),
|
'annotation_type': (atype or '').strip(),
|
||||||
'restrict_to_user': self.restrict_to_user,
|
'restrict_to_user': self.restrict_to_user,
|
||||||
'use_stemming': bool(self.use_stemmer.isChecked()),
|
'use_stemming': bool(self.use_stemmer.isChecked()),
|
||||||
|
'restrict_to_book_ids': self.restrictions.effective_restrict_to_book_ids,
|
||||||
}
|
}
|
||||||
|
|
||||||
def cleared(self):
|
def cleared(self):
|
||||||
@ -434,12 +478,13 @@ class BrowsePanel(QWidget):
|
|||||||
if not q['fts_engine_query']:
|
if not q['fts_engine_query']:
|
||||||
results = db.all_annotations(
|
results = db.all_annotations(
|
||||||
restrict_to_user=q['restrict_to_user'], limit=4096, annotation_type=q['annotation_type'],
|
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:
|
else:
|
||||||
results = db.search_annotations(
|
results = db.search_annotations(
|
||||||
highlight_start='\x1d', highlight_end='\x1d', snippet_size=64,
|
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.results_list.set_results(results, bool(q['fts_engine_query']))
|
||||||
self.current_query = q
|
self.current_query = q
|
||||||
@ -729,18 +774,23 @@ class AnnotationsBrowser(Dialog):
|
|||||||
db.update_annotations({annot_id: annot})
|
db.update_annotations({annot_id: annot})
|
||||||
self.details_panel.update_notes(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:
|
if self.parent() is None:
|
||||||
self.browse_panel.effective_query_changed()
|
self.browse_panel.effective_query_changed()
|
||||||
self.exec_()
|
self.exec_()
|
||||||
else:
|
else:
|
||||||
self.reinitialize()
|
self.reinitialize(restrict_to_book_ids)
|
||||||
self.show()
|
self.show()
|
||||||
self.raise_()
|
self.raise_()
|
||||||
QTimer.singleShot(80, self.browse_panel.effective_query_changed)
|
QTimer.singleShot(80, self.browse_panel.effective_query_changed)
|
||||||
|
|
||||||
def reinitialize(self):
|
def selection_changed(self):
|
||||||
self.browse_panel.re_initialize()
|
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__':
|
if __name__ == '__main__':
|
||||||
|
@ -206,6 +206,7 @@ class BooksView(QTableView): # {{{
|
|||||||
|
|
||||||
files_dropped = pyqtSignal(object)
|
files_dropped = pyqtSignal(object)
|
||||||
books_dropped = pyqtSignal(object)
|
books_dropped = pyqtSignal(object)
|
||||||
|
selection_changed = pyqtSignal()
|
||||||
add_column_signal = pyqtSignal()
|
add_column_signal = pyqtSignal()
|
||||||
is_library_view = True
|
is_library_view = True
|
||||||
|
|
||||||
@ -288,6 +289,7 @@ class BooksView(QTableView): # {{{
|
|||||||
wv.setSelectionBehavior(QAbstractItemView.SelectRows)
|
wv.setSelectionBehavior(QAbstractItemView.SelectRows)
|
||||||
wv.setSortingEnabled(True)
|
wv.setSortingEnabled(True)
|
||||||
self.selectionModel().currentRowChanged.connect(self._model.current_changed)
|
self.selectionModel().currentRowChanged.connect(self._model.current_changed)
|
||||||
|
self.selectionModel().selectionChanged.connect(self.selection_changed.emit)
|
||||||
self.preserve_state = partial(PreserveViewState, self)
|
self.preserve_state = partial(PreserveViewState, self)
|
||||||
self.marked_changed_listener = FunctionDispatcher(self.marked_changed)
|
self.marked_changed_listener = FunctionDispatcher(self.marked_changed)
|
||||||
|
|
||||||
@ -1235,15 +1237,17 @@ class BooksView(QTableView): # {{{
|
|||||||
m.index(max(group), max_col)), sm.Select)
|
m.index(max(group), max_col)), sm.Select)
|
||||||
sm.select(sel, sm.ClearAndSelect)
|
sm.select(sel, sm.ClearAndSelect)
|
||||||
|
|
||||||
def get_selected_ids(self):
|
def get_selected_ids(self, as_set=False):
|
||||||
ans = []
|
ans = []
|
||||||
|
seen = set()
|
||||||
m = self.model()
|
m = self.model()
|
||||||
for idx in self.selectedIndexes():
|
for idx in self.selectedIndexes():
|
||||||
r = idx.row()
|
r = idx.row()
|
||||||
i = m.id(r)
|
i = m.id(r)
|
||||||
if i not in ans:
|
if i not in seen:
|
||||||
ans.append(i)
|
ans.append(i)
|
||||||
return ans
|
seen.add(i)
|
||||||
|
return seen if as_set else ans
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def current_id(self):
|
def current_id(self):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user