Cleanup previous PR

Tag browser: When searching the Tag browser allow also filtering the book list to show only books that match one of the categories currently shown in the Tag browser. To use enable the two Preferences: Preferences->Look & feel->Tag browser->Hide empty categories and Find shows all items that match. Then when searching the Tag browser, press Ctrl+Alt+Shift+F to restrict the displayed books.

Fixes #1989813
This commit is contained in:
Kovid Goyal 2022-09-20 07:25:58 +05:30
parent 0d3e4a232a
commit 616290b17e
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
5 changed files with 32 additions and 19 deletions

View File

@ -526,9 +526,19 @@ Identifiers (e.g., ISBN, DOI, LCCN, etc.) use an extended syntax. An identifier
* ``identifiers:=isbn:=123456789`` will find books with a type equal to ISBN having a value equal to `123456789`.
* ``identifiers:i:1`` will find books with a type containing an `i` having a value containing a `1`.
*Categories in the Tag browser*
*Categories visible in the Tag browser*
The search ``in_tag_browser:true`` finds all books with items (values in categories) currently shown in the :guilabel:`Tag browser`. This is useful if you set the preferences :guilabel:`Preferences . Look & feel . Tag browser . Hide empty categories` and :guilabel:`. Find shows all items that match`. With those two preferences set, doing a ``find`` in the :guilabel:`Tag browser` shows only categories containing items matched by the ``find``. The search ``in_tag_browser:true`` finds books with these categories / items.
The search ``in_tag_browser:true`` finds all books that are in categories
(tags, authors, etc.) currently shown in the :guilabel:`Tag browser`. This is
useful if you set the two preferences :guilabel:`Preferences->Look & feel->Tag
browser->Hide empty categories` and :guilabel:`Find shows all items that
match`. With those two preferences set, doing a :guilabel:`Find` in the
:guilabel:`Tag browser` shows only categories containing items matched by the
:guilabel:`Find`. Then, the search ``in_tag_browser:true`` additionally finds books
with these categories / items. You can easily run this search by pressing the
key :kbd:`Ctrl+Alt+Shift+F` or clicking the configure button in the
:guilabel:`Tag browser` and choosing the :guilabel:`Show only books that have
visible categories` entry.
*Search using templates*
@ -906,3 +916,6 @@ calibre has several keyboard shortcuts to save you time and mouse movement. Thes
- Quit calibre
* - :kbd:`X`
- Toggle auto scroll of the book list
* - :kbd:`Ctrl+Alt+Shift+F`
- Restrict the displayed books to only those books that are in a category
currently displayed in the :guilabel:`Tag browser`

View File

@ -5,7 +5,7 @@ __license__ = 'GPL v3'
__copyright__ = '2011, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en'
import weakref, operator, numbers
import weakref, operator, numbers, sys
from functools import partial
from polyglot.builtins import iteritems, itervalues
@ -45,8 +45,13 @@ class InTagBrowserVirtualField:
yield str(book_id) if self._ids is None or book_id in self._ids else default_value, {book_id}
def sort_keys_for_books(self, get_metadata, lang_map):
null = sys.maxsize
if self._ids is None:
def key(_id):
return _id if self._ids is not None and _id in self._ids else ''
return null
else:
def key(_id):
return _id if _id in self._ids else null
return key
@ -95,7 +100,7 @@ class View:
def __init__(self, cache):
self.cache = cache
self.marked_ids = {}
self.tag_browser_ids = None;
self.tag_browser_ids = None
self.marked_listeners = {}
self.search_restriction_book_count = 0
self.search_restriction = self.base_restriction = ''

View File

@ -818,14 +818,13 @@ class TagsModel(QAbstractItemModel): # {{{
# building the set for a case that will certainly rarely be different
# from all books because all books have authors.
id_set = set()
for x in [a for a in self.root_item.children if a.category_key != 'search' and not a.is_gst]:
for x in (a for a in self.root_item.children if a.category_key != 'search' and not a.is_gst):
for t in x.child_tags():
id_set |= t.tag.id_set
changed = self.db.data.get_in_tag_browser() != id_set
self.db.data.set_in_tag_browser(id_set)
return changed
def get_category_editor_data(self, category):
for cat in self.root_item.children:
if cat.category_key == category:

View File

@ -734,7 +734,7 @@ class TagBrowserWidget(QFrame): # {{{
mt.m = l.manage_menu = QMenu(l.m)
mt.setMenu(mt.m)
l.m.filter_action = ac = l.m.addAction(QIcon.ic('filter.png'), _('Filter book list (search %s)') % 'in_tag_browser:true')
l.m.filter_action = ac = l.m.addAction(QIcon.ic('filter.png'), _('Show only books that have visible categories'))
# Give it a (complicated) shortcut so people can discover a shortcut
# is possible, I hope without creating collisions.
parent.keyboard.register_shortcut('tag browser filter booklist',

View File

@ -9,6 +9,7 @@ import time, traceback, locale
from itertools import repeat
from datetime import timedelta
from threading import Thread
from contextlib import suppress
from calibre.utils.config import tweaks, prefs
from calibre.utils.date import parse_date, now, UNDEFINED_DATE, clean_date_for_sort
@ -929,18 +930,13 @@ class ResultCache(SearchQueryParser): # {{{
# Set the values in the cache
marked_col = self.FIELD_MAP['marked']
for r in self.iterall():
r[marked_col] = None
for id_, val in iteritems(self.marked_ids_dict):
try:
self._data[id_][marked_col] = val
except:
pass
in_tag_browser_col = self.FIELD_MAP['in_tag_browser']
for r in self.iterall():
r[in_tag_browser_col] = None
r[marked_col] = r[in_tag_browser_col] = None
for id_, val in self.marked_ids_dict.items():
with suppress(Exception):
self._data[id_][marked_col] = val
def get_marked(self, idx, index_is_id=True, default_value=None):
id_ = idx if index_is_id else self[idx][0]