mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Add right-click category search support to the tags browser
This commit is contained in:
parent
03dcd631b4
commit
65e6102e33
@ -186,7 +186,7 @@ class TagsView(QTreeView): # {{{
|
||||
self.clear()
|
||||
|
||||
def context_menu_handler(self, action=None, category=None,
|
||||
key=None, index=None):
|
||||
key=None, index=None, negate=None):
|
||||
if not action:
|
||||
return
|
||||
try:
|
||||
@ -199,6 +199,9 @@ class TagsView(QTreeView): # {{{
|
||||
if action == 'manage_categories':
|
||||
self.user_category_edit.emit(category)
|
||||
return
|
||||
if action == 'search_category':
|
||||
self.tags_marked.emit(category + ':' + str(not negate))
|
||||
return
|
||||
if action == 'manage_searches':
|
||||
self.saved_search_edit.emit(category)
|
||||
return
|
||||
@ -268,6 +271,15 @@ class TagsView(QTreeView): # {{{
|
||||
m.addAction(col,
|
||||
partial(self.context_menu_handler, action='show', category=col))
|
||||
|
||||
# search by category
|
||||
self.context_menu.addAction(
|
||||
_('Search for books in category %s')%category,
|
||||
partial(self.context_menu_handler, action='search_category',
|
||||
category=key, negate=False))
|
||||
self.context_menu.addAction(
|
||||
_('Search for books not in category %s')%category,
|
||||
partial(self.context_menu_handler, action='search_category',
|
||||
category=key, negate=True))
|
||||
# Offer specific editors for tags/series/publishers/saved searches
|
||||
self.context_menu.addSeparator()
|
||||
if key in ['tags', 'publisher', 'series'] or \
|
||||
|
@ -172,8 +172,9 @@ class ResultCache(SearchQueryParser): # {{{
|
||||
'''
|
||||
Stores sorted and filtered metadata in memory.
|
||||
'''
|
||||
def __init__(self, FIELD_MAP, field_metadata):
|
||||
def __init__(self, FIELD_MAP, field_metadata, db_prefs = None):
|
||||
self.FIELD_MAP = FIELD_MAP
|
||||
self.db_prefs = db_prefs
|
||||
self.composites = {}
|
||||
for key in field_metadata:
|
||||
if field_metadata[key]['datatype'] == 'composite':
|
||||
@ -405,6 +406,22 @@ class ResultCache(SearchQueryParser): # {{{
|
||||
matches.add(item[0])
|
||||
return matches
|
||||
|
||||
def get_user_category_matches(self, location, query, candidates):
|
||||
res = set([])
|
||||
if self.db_prefs is None:
|
||||
return res
|
||||
user_cats = self.db_prefs['user_categories']
|
||||
if location not in user_cats:
|
||||
return res
|
||||
c = set(candidates)
|
||||
for (item, category, ign) in user_cats[location]:
|
||||
s = self.get_matches(category, '=' + item, candidates=c)
|
||||
c -= s
|
||||
res |= s
|
||||
if query == 'false':
|
||||
return candidates - res
|
||||
return res
|
||||
|
||||
def get_matches(self, location, query, allow_recursion=True, candidates=None):
|
||||
matches = set([])
|
||||
if candidates is None:
|
||||
@ -443,6 +460,10 @@ class ResultCache(SearchQueryParser): # {{{
|
||||
return self.get_numeric_matches(location, query[1:],
|
||||
candidates, val_func=vf)
|
||||
|
||||
# check for user categories
|
||||
if len(location) >= 2 and location.startswith('@'):
|
||||
return self.get_user_category_matches(location[1:], query.lower(),
|
||||
candidates)
|
||||
# everything else, or 'all' matches
|
||||
matchkind = CONTAINS_MATCH
|
||||
if (len(query) > 1):
|
||||
@ -468,6 +489,8 @@ class ResultCache(SearchQueryParser): # {{{
|
||||
for x in range(len(self.FIELD_MAP)):
|
||||
col_datatype.append('')
|
||||
for x in self.field_metadata:
|
||||
if x.startswith('@'):
|
||||
continue
|
||||
if len(self.field_metadata[x]['search_terms']):
|
||||
db_col[x] = self.field_metadata[x]['rec_index']
|
||||
if self.field_metadata[x]['datatype'] not in \
|
||||
|
@ -332,7 +332,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
||||
traceback.print_exc()
|
||||
|
||||
self.book_on_device_func = None
|
||||
self.data = ResultCache(self.FIELD_MAP, self.field_metadata)
|
||||
self.data = ResultCache(self.FIELD_MAP, self.field_metadata, db_prefs=self.prefs)
|
||||
self.search = self.data.search
|
||||
self.search_getting_ids = self.data.search_getting_ids
|
||||
self.refresh = functools.partial(self.data.refresh, self)
|
||||
|
@ -475,6 +475,8 @@ class FieldMetadata(dict):
|
||||
val = self._tb_cats[key]
|
||||
if val['is_category'] and val['kind'] in ('user', 'search'):
|
||||
del self._tb_cats[key]
|
||||
if key in self._search_term_map:
|
||||
del self._search_term_map[key]
|
||||
|
||||
def cc_series_index_column_for(self, key):
|
||||
return self._tb_cats[key]['rec_index'] + 1
|
||||
@ -482,11 +484,12 @@ class FieldMetadata(dict):
|
||||
def add_user_category(self, label, name):
|
||||
if label in self._tb_cats:
|
||||
raise ValueError('Duplicate user field [%s]'%(label))
|
||||
self._tb_cats[label] = {'table':None, 'column':None,
|
||||
'datatype':None, 'is_multiple':None,
|
||||
'kind':'user', 'name':name,
|
||||
'search_terms':[], 'is_custom':False,
|
||||
self._tb_cats[label] = {'table':None, 'column':None,
|
||||
'datatype':None, 'is_multiple':None,
|
||||
'kind':'user', 'name':name,
|
||||
'search_terms':[label],'is_custom':False,
|
||||
'is_category':True}
|
||||
self._add_search_terms_to_map(label, [label])
|
||||
|
||||
def add_search_category(self, label, name):
|
||||
if label in self._tb_cats:
|
||||
|
Loading…
x
Reference in New Issue
Block a user