mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
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:
parent
0d3e4a232a
commit
616290b17e
@ -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:=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`.
|
* ``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*
|
*Search using templates*
|
||||||
|
|
||||||
@ -906,3 +916,6 @@ calibre has several keyboard shortcuts to save you time and mouse movement. Thes
|
|||||||
- Quit calibre
|
- Quit calibre
|
||||||
* - :kbd:`X`
|
* - :kbd:`X`
|
||||||
- Toggle auto scroll of the book list
|
- 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`
|
||||||
|
@ -5,7 +5,7 @@ __license__ = 'GPL v3'
|
|||||||
__copyright__ = '2011, Kovid Goyal <kovid@kovidgoyal.net>'
|
__copyright__ = '2011, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||||
__docformat__ = 'restructuredtext en'
|
__docformat__ = 'restructuredtext en'
|
||||||
|
|
||||||
import weakref, operator, numbers
|
import weakref, operator, numbers, sys
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from polyglot.builtins import iteritems, itervalues
|
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}
|
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):
|
def sort_keys_for_books(self, get_metadata, lang_map):
|
||||||
def key(_id):
|
null = sys.maxsize
|
||||||
return _id if self._ids is not None and _id in self._ids else ''
|
if self._ids is None:
|
||||||
|
def key(_id):
|
||||||
|
return null
|
||||||
|
else:
|
||||||
|
def key(_id):
|
||||||
|
return _id if _id in self._ids else null
|
||||||
return key
|
return key
|
||||||
|
|
||||||
|
|
||||||
@ -95,7 +100,7 @@ class View:
|
|||||||
def __init__(self, cache):
|
def __init__(self, cache):
|
||||||
self.cache = cache
|
self.cache = cache
|
||||||
self.marked_ids = {}
|
self.marked_ids = {}
|
||||||
self.tag_browser_ids = None;
|
self.tag_browser_ids = None
|
||||||
self.marked_listeners = {}
|
self.marked_listeners = {}
|
||||||
self.search_restriction_book_count = 0
|
self.search_restriction_book_count = 0
|
||||||
self.search_restriction = self.base_restriction = ''
|
self.search_restriction = self.base_restriction = ''
|
||||||
|
@ -818,14 +818,13 @@ class TagsModel(QAbstractItemModel): # {{{
|
|||||||
# building the set for a case that will certainly rarely be different
|
# building the set for a case that will certainly rarely be different
|
||||||
# from all books because all books have authors.
|
# from all books because all books have authors.
|
||||||
id_set = set()
|
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():
|
for t in x.child_tags():
|
||||||
id_set |= t.tag.id_set
|
id_set |= t.tag.id_set
|
||||||
changed = self.db.data.get_in_tag_browser() != id_set
|
changed = self.db.data.get_in_tag_browser() != id_set
|
||||||
self.db.data.set_in_tag_browser(id_set)
|
self.db.data.set_in_tag_browser(id_set)
|
||||||
return changed
|
return changed
|
||||||
|
|
||||||
|
|
||||||
def get_category_editor_data(self, category):
|
def get_category_editor_data(self, category):
|
||||||
for cat in self.root_item.children:
|
for cat in self.root_item.children:
|
||||||
if cat.category_key == category:
|
if cat.category_key == category:
|
||||||
|
@ -734,7 +734,7 @@ class TagBrowserWidget(QFrame): # {{{
|
|||||||
mt.m = l.manage_menu = QMenu(l.m)
|
mt.m = l.manage_menu = QMenu(l.m)
|
||||||
mt.setMenu(mt.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
|
# Give it a (complicated) shortcut so people can discover a shortcut
|
||||||
# is possible, I hope without creating collisions.
|
# is possible, I hope without creating collisions.
|
||||||
parent.keyboard.register_shortcut('tag browser filter booklist',
|
parent.keyboard.register_shortcut('tag browser filter booklist',
|
||||||
|
@ -9,6 +9,7 @@ import time, traceback, locale
|
|||||||
from itertools import repeat
|
from itertools import repeat
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
|
from contextlib import suppress
|
||||||
|
|
||||||
from calibre.utils.config import tweaks, prefs
|
from calibre.utils.config import tweaks, prefs
|
||||||
from calibre.utils.date import parse_date, now, UNDEFINED_DATE, clean_date_for_sort
|
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
|
# Set the values in the cache
|
||||||
marked_col = self.FIELD_MAP['marked']
|
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']
|
in_tag_browser_col = self.FIELD_MAP['in_tag_browser']
|
||||||
for r in self.iterall():
|
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):
|
def get_marked(self, idx, index_is_id=True, default_value=None):
|
||||||
id_ = idx if index_is_id else self[idx][0]
|
id_ = idx if index_is_id else self[idx][0]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user