From f176c4ac36b94c4c932c691250c061e80b2f0752 Mon Sep 17 00:00:00 2001 From: Charles Haley Date: Sun, 5 Nov 2023 15:32:51 +0000 Subject: [PATCH] Add a "Show items in selected books" choice to manage tags and manage authors. Radio buttons are more visually intuitive than checkboxes, but it is a little strange not having a "Use all" radio button. You click the radio button again to turn it off. Adding the third button takes up more vertical space than it is worth. Switching back to checkboxes is trivial. --- .../gui2/dialogs/edit_authors_dialog.py | 22 +++++++++++++--- .../gui2/dialogs/edit_authors_dialog.ui | 26 ++++++++++++++++--- src/calibre/gui2/dialogs/tag_list_editor.py | 22 ++++++++++++++-- src/calibre/gui2/dialogs/tag_list_editor.ui | 18 ++++++++++++- src/calibre/gui2/tag_browser/ui.py | 23 ++++++++++++---- 5 files changed, 97 insertions(+), 14 deletions(-) diff --git a/src/calibre/gui2/dialogs/edit_authors_dialog.py b/src/calibre/gui2/dialogs/edit_authors_dialog.py index 57ee1a6788..f0e5104987 100644 --- a/src/calibre/gui2/dialogs/edit_authors_dialog.py +++ b/src/calibre/gui2/dialogs/edit_authors_dialog.py @@ -108,7 +108,10 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog): self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setText(_('&Cancel')) self.buttonBox.accepted.connect(self.accepted) self.buttonBox.rejected.connect(self.rejected) - self.apply_vl_checkbox.stateChanged.connect(self.use_vl_changed) + self.apply_vl_checkbox.setAutoExclusive(False) + self.apply_vl_checkbox.toggled.connect(self.use_vl_changed) + self.apply_selection_checkbox.setAutoExclusive(False) + self.apply_selection_checkbox.toggled.connect(self.apply_selection_box_changed) self.table.setAlternatingRowColors(True) self.table.setSelectionMode(QAbstractItemView.SelectionMode.SingleSelection) @@ -211,8 +214,22 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog): self.ignore_cell_changed = orig def use_vl_changed(self, x): + if self.apply_vl_checkbox.isChecked(): + self.apply_selection_checkbox.setChecked(False) self.show_table(None, None, None, False) + def apply_selection_box_changed(self, x): + if self.apply_selection_checkbox.isChecked(): + self.apply_vl_checkbox.setChecked(False) + self.show_table(None, None, None, False) + + def selection_to_apply(self): + if self.apply_selection_checkbox.isChecked(): + return 'selection' + if self.apply_vl_checkbox.isChecked(): + return 'virtual_library' + return None + def clear_filter(self): self.filter_box.setText('') self.show_table(None, None, None, False) @@ -221,8 +238,7 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog): self.show_table(None, None, None, False) def show_table(self, id_to_select, select_sort, select_link, is_first_letter): - auts_to_show = {t[0] for t in - self.find_aut_func(use_virtual_library=self.apply_vl_checkbox.isChecked())} + auts_to_show = {t[0] for t in self.find_aut_func(self.selection_to_apply())} filter_text = icu_lower(str(self.filter_box.text())) if filter_text: auts_to_show = {id_ for id_ in auts_to_show diff --git a/src/calibre/gui2/dialogs/edit_authors_dialog.ui b/src/calibre/gui2/dialogs/edit_authors_dialog.ui index ec5c17fd88..6427e171ef 100644 --- a/src/calibre/gui2/dialogs/edit_authors_dialog.ui +++ b/src/calibre/gui2/dialogs/edit_authors_dialog.ui @@ -66,17 +66,37 @@ - + - <p>Only show authors in the + <p>Show authors only if they appear in the current Virtual library. Edits already done may be hidden but will - not be forgotten.</p> + not be forgotten. + </p><p> + Note that this box affects only what is displayed. Changes + will affect all books in your library even if this box + is checked.</p>< Only show authors in the current &Virtual library + + + + <p>Show items only if they appear in the + currently selected books. Edits already done may be hidden but will + not be forgotten. + </p><p> + Note that this box affects only what is displayed. Changes + will affect all books in your library even if this box + is checked.</p>< + + + O&nly show authors in the currently selected books + + + diff --git a/src/calibre/gui2/dialogs/tag_list_editor.py b/src/calibre/gui2/dialogs/tag_list_editor.py index 19a0379e5f..983d05ce61 100644 --- a/src/calibre/gui2/dialogs/tag_list_editor.py +++ b/src/calibre/gui2/dialogs/tag_list_editor.py @@ -372,7 +372,10 @@ class TagListEditor(QDialog, Ui_TagListEditor): ac.triggered.connect(self.clear_filter) le.returnPressed.connect(self.do_filter) self.filter_button.clicked.connect(self.do_filter) - self.apply_vl_checkbox.clicked.connect(self.vl_box_changed) + self.apply_vl_checkbox.setAutoExclusive(False) + self.apply_vl_checkbox.toggled.connect(self.vl_box_changed) + self.apply_selection_checkbox.setAutoExclusive(False) + self.apply_selection_checkbox.toggled.connect(self.apply_selection_box_changed) self.is_enumerated = False if fm: @@ -537,9 +540,24 @@ class TagListEditor(QDialog, Ui_TagListEditor): return txt.swapcase() def vl_box_changed(self): + if self.apply_vl_checkbox.isChecked(): + self.apply_selection_checkbox.setChecked(False) self.search_item_row = -1 self.fill_in_table(None, None, False) + def apply_selection_box_changed(self): + if self.apply_selection_checkbox.isChecked(): + self.apply_vl_checkbox.setChecked(False) + self.search_item_row = -1 + self.fill_in_table(None, None, False) + + def selection_to_apply(self): + if self.apply_selection_checkbox.isChecked(): + return 'selection' + if self.apply_vl_checkbox.isChecked(): + return 'virtual_library' + return None + def do_search(self): self.not_found_label.setVisible(False) find_text = str(self.search_box.currentText()) @@ -653,7 +671,7 @@ class TagListEditor(QDialog, Ui_TagListEditor): def fill_in_table(self, tags, tag_to_match, ttm_is_first_letter): self.create_table() - data = self.get_book_ids(self.apply_vl_checkbox.isChecked()) + data = self.get_book_ids(self.selection_to_apply()) self.all_tags = {} filter_text = icu_lower(str(self.filter_box.text())) for k,v,count in data: diff --git a/src/calibre/gui2/dialogs/tag_list_editor.ui b/src/calibre/gui2/dialogs/tag_list_editor.ui index 789940df40..5589613ef2 100644 --- a/src/calibre/gui2/dialogs/tag_list_editor.ui +++ b/src/calibre/gui2/dialogs/tag_list_editor.ui @@ -72,7 +72,7 @@ - + <p>Show items only if they appear in the current Virtual library. Edits already done may be hidden but will @@ -87,6 +87,22 @@ + + + + <p>Show items only if they appear in the + currently selected books. Edits already done may be hidden but will + not be forgotten. + </p><p> + Note that this box affects only what is displayed. Changes + will affect all books in your library even if this box + is checked.</p> + + + O&nly show items in the currently selected books + + + diff --git a/src/calibre/gui2/tag_browser/ui.py b/src/calibre/gui2/tag_browser/ui.py index 7f2e5d5cf8..f99204f912 100644 --- a/src/calibre/gui2/tag_browser/ui.py +++ b/src/calibre/gui2/tag_browser/ui.py @@ -15,7 +15,7 @@ from qt.core import ( ) from calibre.ebooks.metadata import title_sort -from calibre.gui2 import config, error_dialog, gprefs, question_dialog +from calibre.gui2 import config, error_dialog, gprefs, question_dialog, warning_dialog from calibre.gui2.dialogs.edit_authors_dialog import EditAuthorsDialog from calibre.gui2.dialogs.tag_categories import TagCategories from calibre.gui2.dialogs.tag_list_editor import TagListEditor @@ -157,7 +157,6 @@ class TagBrowserMixin: # {{{ self.library_view.model().research(reset=False) self.library_view.current_id = current_row_id # the setter checks for None - def do_restriction_error(self, e): error_dialog(self.tags_view, _('Invalid search restriction'), _('The current search restriction is invalid'), @@ -312,8 +311,22 @@ class TagBrowserMixin: # {{{ db.new_api.clear_search_caches() self.user_categories_edited() + # Keep this for compatibility. It isn't used here but could be used in a plugin def get_book_ids(self, use_virtual_library, db, category): - book_ids = None if not use_virtual_library else self.tags_view.model().get_book_ids_to_use() + return self.get_book_ids_in_vl_or_selection( + ('virtual_library' if use_virtual_library else None), db, category) + + def get_book_ids_in_vl_or_selection(self, use_what, db, category): + if use_what is None: + book_ids = None + elif use_what == 'virtual_library': + book_ids = self.tags_view.model().get_book_ids_to_use() + else: + book_ids = self.library_view.get_selected_ids() + if not book_ids: + warning_dialog(self.tags_view, _('No books selected'), + _('No books are selected. Showing all items.'), show=True) + book_ids = None data = db.new_api.get_categories(book_ids=book_ids) if category in data: result = [(t.id, t.original_name, t.count) for t in data[category] if t.count > 0] @@ -337,7 +350,7 @@ class TagBrowserMixin: # {{{ d = TagListEditor(self, category=category, cat_name=db.field_metadata[category]['name'], tag_to_match=tag, - get_book_ids=partial(self.get_book_ids, db=db, category=category), + get_book_ids=partial(self.get_book_ids_in_vl_or_selection, db=db, category=category), sorter=key, ttm_is_first_letter=is_first_letter, fm=db.field_metadata[category], link_map=db.new_api.get_link_map(category)) @@ -514,7 +527,7 @@ class TagBrowserMixin: # {{{ Open the manage authors dialog ''' db = self.library_view.model().db - get_authors_func = partial(self.get_book_ids, db=db, category='authors') + get_authors_func = partial(self.get_book_ids_in_vl_or_selection, db=db, category='authors') if lookup_author: for t in get_authors_func(use_virtual_library=False): if t[1] == id_: