diff --git a/src/calibre/gui2/tag_browser/model.py b/src/calibre/gui2/tag_browser/model.py index e759783d7b..0324fd8622 100644 --- a/src/calibre/gui2/tag_browser/model.py +++ b/src/calibre/gui2/tag_browser/model.py @@ -21,6 +21,7 @@ from calibre.utils.icu import sort_key, lower, strcmp from calibre.library.field_metadata import TagsIcons, category_icon_map from calibre.gui2.dialogs.confirm_delete import confirm from calibre.utils.formatter import EvalFormatter +from calibre.utils.ordered_dict import OrderedDict from calibre.utils.search_query_parser import saved_searches TAG_SEARCH_STATES = {'clear': 0, 'mark_plus': 1, 'mark_plusplus': 2, @@ -315,9 +316,11 @@ class TagsModel(QAbstractItemModel): # {{{ for i,p in enumerate(path_parts): path += p if path not in category_node_map: + icon = self.category_icon_map['gst'] if is_gst else \ + self.category_icon_map[key] node = self.create_node(parent=last_category_node, data=p[1:] if i == 0 else p, - category_icon=self.category_icon_map[key], + category_icon=icon, tooltip=tt if path == key else path, category_key=path, icon_map=self.icon_state_map) @@ -375,6 +378,7 @@ class TagsModel(QAbstractItemModel): # {{{ collapse_letter = None category_node = category key = category_node.category_key + is_gst = category_node.is_gst if key not in data: return cat_len = len(data[key]) @@ -455,6 +459,7 @@ class TagsModel(QAbstractItemModel): # {{{ tooltip = None, temporary=True, category_key=category_node.category_key, icon_map=self.icon_state_map) + sub_cat.is_gst = is_gst node_parent = sub_cat else: node_parent = category @@ -1161,7 +1166,10 @@ class TagsModel(QAbstractItemModel): # {{{ prefix = ' not ' else: prefix = '' - category = tag.category if key != 'news' else 'tag' + if node.is_gst: + category = key + else: + category = tag.category if key != 'news' else 'tag' add_colon = False if self.db.field_metadata[tag.category]['is_csp']: add_colon = True diff --git a/src/calibre/library/database2.py b/src/calibre/library/database2.py index 9d8a27d1fb..9fe9d3dabb 100644 --- a/src/calibre/library/database2.py +++ b/src/calibre/library/database2.py @@ -7,7 +7,7 @@ __docformat__ = 'restructuredtext en' The database used to store ebook metadata ''' import os, sys, shutil, cStringIO, glob, time, functools, traceback, re, \ - json, uuid, tempfile, hashlib + json, uuid, tempfile, hashlib, copy from collections import defaultdict import threading, random from itertools import repeat @@ -1794,10 +1794,22 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): for user_cat in sorted(user_categories.keys(), key=sort_key): items = [] + names_seen = {} for (name,label,ign) in user_categories[user_cat]: n = icu_lower(name) if label in taglist and n in taglist[label]: - items.append(taglist[label][n]) + if user_cat in gst: + # for gst items, make copy and consolidate the tags by name. + if n in names_seen: + names_seen[n].id_set |= taglist[label][n].id_set + names_seen[n].count += taglist[label][n].count + else: + t = copy.copy(taglist[label][n]) + t.icon = icon_map['gst'] + names_seen[t.name] = t + items.append(t) + else: + items.append(taglist[label][n]) # else: do nothing, to not include nodes w zero counts cat_name = '@' + user_cat # add the '@' to avoid name collision # Not a problem if we accumulate entries in the icon map diff --git a/src/calibre/library/field_metadata.py b/src/calibre/library/field_metadata.py index 231af23038..51511e26d9 100644 --- a/src/calibre/library/field_metadata.py +++ b/src/calibre/library/field_metadata.py @@ -17,7 +17,7 @@ class TagsIcons(dict): category_icons = ['authors', 'series', 'formats', 'publisher', 'rating', 'news', 'tags', 'custom:', 'user:', 'search', - 'identifiers'] + 'identifiers', 'gst'] def __init__(self, icon_dict): for a in self.category_icons: if a not in icon_dict: @@ -35,7 +35,8 @@ category_icon_map = { 'custom:' : 'column.png', 'user:' : 'tb_folder.png', 'search' : 'search.png', - 'identifiers': 'identifiers.png' + 'identifiers': 'identifiers.png', + 'gst' : 'catalog.png', }