Add right-click category search support to the tags browser

This commit is contained in:
Charles Haley 2011-01-24 09:15:05 +00:00
parent 03dcd631b4
commit 65e6102e33
4 changed files with 45 additions and 7 deletions

View File

@ -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 \

View File

@ -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 \

View File

@ -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)

View File

@ -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
@ -485,8 +487,9 @@ class FieldMetadata(dict):
self._tb_cats[label] = {'table':None, 'column':None,
'datatype':None, 'is_multiple':None,
'kind':'user', 'name':name,
'search_terms':[], 'is_custom':False,
'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: