mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Tag Browser: Add API for locating categories
This commit is contained in:
commit
269e58b0df
@ -515,8 +515,8 @@ class TagsModel(QAbstractItemModel): # {{{
|
|||||||
QAbstractItemModel.__init__(self, parent)
|
QAbstractItemModel.__init__(self, parent)
|
||||||
|
|
||||||
# must do this here because 'QPixmap: Must construct a QApplication
|
# must do this here because 'QPixmap: Must construct a QApplication
|
||||||
# before a QPaintDevice'. The ':' in front avoids polluting either the
|
# before a QPaintDevice'. The ':' at the end avoids polluting either the
|
||||||
# user-defined categories (':' at end) or columns namespaces (no ':').
|
# user-defined categories (':' at front) or columns namespaces (no ':').
|
||||||
iconmap = {}
|
iconmap = {}
|
||||||
for key in category_icon_map:
|
for key in category_icon_map:
|
||||||
iconmap[key] = QIcon(I(category_icon_map[key]))
|
iconmap[key] = QIcon(I(category_icon_map[key]))
|
||||||
@ -690,7 +690,7 @@ class TagsModel(QAbstractItemModel): # {{{
|
|||||||
tb_cats = self.db.field_metadata
|
tb_cats = self.db.field_metadata
|
||||||
for user_cat in sorted(self.db.prefs.get('user_categories', {}).keys(),
|
for user_cat in sorted(self.db.prefs.get('user_categories', {}).keys(),
|
||||||
key=sort_key):
|
key=sort_key):
|
||||||
cat_name = user_cat+':' # add the ':' to avoid name collision
|
cat_name = ':' + user_cat # add the ':' to avoid name collision
|
||||||
tb_cats.add_user_category(label=cat_name, name=user_cat)
|
tb_cats.add_user_category(label=cat_name, name=user_cat)
|
||||||
if len(saved_searches().names()):
|
if len(saved_searches().names()):
|
||||||
tb_cats.add_search_category(label='search', name=_('Searches'))
|
tb_cats.add_search_category(label='search', name=_('Searches'))
|
||||||
@ -997,7 +997,7 @@ class TagsModel(QAbstractItemModel): # {{{
|
|||||||
if self.hidden_categories and self.categories[i] in self.hidden_categories:
|
if self.hidden_categories and self.categories[i] in self.hidden_categories:
|
||||||
continue
|
continue
|
||||||
row_index += 1
|
row_index += 1
|
||||||
if key.endswith(':'):
|
if key.startswith(':'):
|
||||||
# User category, so skip it. The tag will be marked in its real category
|
# User category, so skip it. The tag will be marked in its real category
|
||||||
continue
|
continue
|
||||||
category_item = self.root_item.children[row_index]
|
category_item = self.root_item.children[row_index]
|
||||||
@ -1016,7 +1016,7 @@ class TagsModel(QAbstractItemModel): # {{{
|
|||||||
ans.append('%s%s:"=%s"'%(prefix, category, tag.name))
|
ans.append('%s%s:"=%s"'%(prefix, category, tag.name))
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
def find_node(self, key, txt, start_path):
|
def find_item_node(self, key, txt, start_path):
|
||||||
'''
|
'''
|
||||||
Search for an item (a node) in the tags browser list that matches both
|
Search for an item (a node) in the tags browser list that matches both
|
||||||
the key (exact case-insensitive match) and txt (contains case-
|
the key (exact case-insensitive match) and txt (contains case-
|
||||||
@ -1070,6 +1070,22 @@ class TagsModel(QAbstractItemModel): # {{{
|
|||||||
break
|
break
|
||||||
return self.path_found
|
return self.path_found
|
||||||
|
|
||||||
|
def find_category_node(self, key):
|
||||||
|
'''
|
||||||
|
Search for an category node (a top-level node) in the tags browser list
|
||||||
|
that matches the key (exact case-insensitive match). Returns the path to
|
||||||
|
the node. Paths are as in find_item_node.
|
||||||
|
'''
|
||||||
|
if not key:
|
||||||
|
return None
|
||||||
|
|
||||||
|
for i in xrange(self.rowCount(QModelIndex())):
|
||||||
|
idx = self.index(i, 0, QModelIndex())
|
||||||
|
ckey = idx.internalPointer().category_key
|
||||||
|
if strcmp(ckey, key) == 0:
|
||||||
|
return self.path_for_index(idx)
|
||||||
|
return None
|
||||||
|
|
||||||
def show_item_at_path(self, path, box=False):
|
def show_item_at_path(self, path, box=False):
|
||||||
'''
|
'''
|
||||||
Scroll the browser and open categories to show the item referenced by
|
Scroll the browser and open categories to show the item referenced by
|
||||||
@ -1355,15 +1371,15 @@ class TagBrowserWidget(QWidget): # {{{
|
|||||||
self.search_button.setFocus(True)
|
self.search_button.setFocus(True)
|
||||||
self.item_search.lineEdit().blockSignals(False)
|
self.item_search.lineEdit().blockSignals(False)
|
||||||
|
|
||||||
colon = txt.find(':')
|
|
||||||
key = None
|
key = None
|
||||||
|
colon = txt.rfind(':') if len(txt) > 2 else 0
|
||||||
if colon > 0:
|
if colon > 0:
|
||||||
key = self.parent.library_view.model().db.\
|
key = self.parent.library_view.model().db.\
|
||||||
field_metadata.search_term_to_field_key(txt[:colon])
|
field_metadata.search_term_to_field_key(txt[:colon])
|
||||||
txt = txt[colon+1:]
|
txt = txt[colon+1:]
|
||||||
|
|
||||||
self.current_find_position = model.find_node(key, txt,
|
self.current_find_position = \
|
||||||
self.current_find_position)
|
model.find_item_node(key, txt, self.current_find_position)
|
||||||
if self.current_find_position:
|
if self.current_find_position:
|
||||||
model.show_item_at_path(self.current_find_position, box=True)
|
model.show_item_at_path(self.current_find_position, box=True)
|
||||||
elif self.item_search.text():
|
elif self.item_search.text():
|
||||||
|
@ -319,7 +319,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
self.field_metadata.remove_dynamic_categories()
|
self.field_metadata.remove_dynamic_categories()
|
||||||
tb_cats = self.field_metadata
|
tb_cats = self.field_metadata
|
||||||
for user_cat in sorted(self.prefs.get('user_categories', {}).keys(), key=sort_key):
|
for user_cat in sorted(self.prefs.get('user_categories', {}).keys(), key=sort_key):
|
||||||
cat_name = user_cat+':' # add the ':' to avoid name collision
|
cat_name = ':' + user_cat # add the ':' to avoid name collision
|
||||||
tb_cats.add_user_category(label=cat_name, name=user_cat)
|
tb_cats.add_user_category(label=cat_name, name=user_cat)
|
||||||
if len(saved_searches().names()):
|
if len(saved_searches().names()):
|
||||||
tb_cats.add_search_category(label='search', name=_('Searches'))
|
tb_cats.add_search_category(label='search', name=_('Searches'))
|
||||||
@ -1243,7 +1243,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
if category in icon_map:
|
if category in icon_map:
|
||||||
icon = icon_map[label]
|
icon = icon_map[label]
|
||||||
else:
|
else:
|
||||||
icon = icon_map[':custom']
|
icon = icon_map['custom:']
|
||||||
icon_map[category] = icon
|
icon_map[category] = icon
|
||||||
|
|
||||||
datatype = cat['datatype']
|
datatype = cat['datatype']
|
||||||
@ -1339,20 +1339,19 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
if label in taglist and name in taglist[label]:
|
if label in taglist and name in taglist[label]:
|
||||||
items.append(taglist[label][name])
|
items.append(taglist[label][name])
|
||||||
# else: do nothing, to not include nodes w zero counts
|
# else: do nothing, to not include nodes w zero counts
|
||||||
if len(items):
|
cat_name = ':' + user_cat # add the ':' to avoid name collision
|
||||||
cat_name = user_cat+':' # add the ':' to avoid name collision
|
# Not a problem if we accumulate entries in the icon map
|
||||||
# Not a problem if we accumulate entries in the icon map
|
if icon_map is not None:
|
||||||
if icon_map is not None:
|
icon_map[cat_name] = icon_map['user:']
|
||||||
icon_map[cat_name] = icon_map[':user']
|
if sort == 'popularity':
|
||||||
if sort == 'popularity':
|
categories[cat_name] = \
|
||||||
categories[cat_name] = \
|
sorted(items, key=lambda x: x.count, reverse=True)
|
||||||
sorted(items, key=lambda x: x.count, reverse=True)
|
elif sort == 'name':
|
||||||
elif sort == 'name':
|
categories[cat_name] = \
|
||||||
categories[cat_name] = \
|
sorted(items, key=lambda x: sort_key(x.sort))
|
||||||
sorted(items, key=lambda x: sort_key(x.sort))
|
else:
|
||||||
else:
|
categories[cat_name] = \
|
||||||
categories[cat_name] = \
|
sorted(items, key=lambda x:x.avg_rating, reverse=True)
|
||||||
sorted(items, key=lambda x:x.avg_rating, reverse=True)
|
|
||||||
|
|
||||||
#### Finally, the saved searches category ####
|
#### Finally, the saved searches category ####
|
||||||
items = []
|
items = []
|
||||||
|
@ -16,7 +16,7 @@ class TagsIcons(dict):
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
category_icons = ['authors', 'series', 'formats', 'publisher', 'rating',
|
category_icons = ['authors', 'series', 'formats', 'publisher', 'rating',
|
||||||
'news', 'tags', ':custom', ':user', 'search',]
|
'news', 'tags', 'custom:', 'user:', 'search',]
|
||||||
def __init__(self, icon_dict):
|
def __init__(self, icon_dict):
|
||||||
for a in self.category_icons:
|
for a in self.category_icons:
|
||||||
if a not in icon_dict:
|
if a not in icon_dict:
|
||||||
@ -31,8 +31,8 @@ category_icon_map = {
|
|||||||
'rating' : 'rating.png',
|
'rating' : 'rating.png',
|
||||||
'news' : 'news.png',
|
'news' : 'news.png',
|
||||||
'tags' : 'tags.png',
|
'tags' : 'tags.png',
|
||||||
':custom' : 'column.png',
|
'custom:' : 'column.png',
|
||||||
':user' : 'drawer.png',
|
'user:' : 'drawer.png',
|
||||||
'search' : 'search.png'
|
'search' : 'search.png'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user