From 5174e5ca747a5e970268dc28e6b7d87459284a6f Mon Sep 17 00:00:00 2001 From: Charles Haley <> Date: Fri, 8 Jul 2011 07:39:44 +0100 Subject: [PATCH 1/4] Fix 807256: TypeError:list of indices must be integers, not unicode --- src/calibre/gui2/actions/edit_metadata.py | 5 ++--- src/calibre/gui2/tag_browser/ui.py | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/calibre/gui2/actions/edit_metadata.py b/src/calibre/gui2/actions/edit_metadata.py index 718ece46d2..0a56286593 100644 --- a/src/calibre/gui2/actions/edit_metadata.py +++ b/src/calibre/gui2/actions/edit_metadata.py @@ -446,9 +446,8 @@ class EditMetadataAction(InterfaceAction): if d.result() == d.Accepted: to_rename = d.to_rename # dict of new text to old ids to_delete = d.to_delete # list of ids - for text in to_rename: - for old_id in to_rename[text]: - model.rename_collection(old_id, new_name=unicode(text)) + for old_id, new_name in to_rename.iteritems(): + model.rename_collection(old_id, new_name=unicode(new_name)) for item in to_delete: model.delete_collection_using_id(item) self.gui.upload_collections(model.db, view=view, oncard=oncard) diff --git a/src/calibre/gui2/tag_browser/ui.py b/src/calibre/gui2/tag_browser/ui.py index d7e504b3e9..390273e5b2 100644 --- a/src/calibre/gui2/tag_browser/ui.py +++ b/src/calibre/gui2/tag_browser/ui.py @@ -218,7 +218,7 @@ class TagBrowserMixin(object): # {{{ d = TagListEditor(self, tag_to_match=tag, data=result, key=key) d.exec_() if d.result() == d.Accepted: - to_rename = d.to_rename # dict of new text to old id + to_rename = d.to_rename # dict of old id to new name to_delete = d.to_delete # list of ids orig_name = d.original_names # dict of id: name From 231c0a4bbfddfb097d9cc97c9c010b0f9d000e5d Mon Sep 17 00:00:00 2001 From: Charles Haley <> Date: Fri, 8 Jul 2011 07:50:51 +0100 Subject: [PATCH 2/4] Fix 807262: true/false searches don't work on device views. --- src/calibre/gui2/library/models.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/calibre/gui2/library/models.py b/src/calibre/gui2/library/models.py index 8cbc2e1979..0937f0bb12 100644 --- a/src/calibre/gui2/library/models.py +++ b/src/calibre/gui2/library/models.py @@ -950,11 +950,11 @@ class OnDeviceSearch(SearchQueryParser): # {{{ for locvalue in locations: accessor = q[locvalue] if query == 'true': - if accessor(row) is not None: + if accessor(row): matches.add(index) continue if query == 'false': - if accessor(row) is None: + if not accessor(row): matches.add(index) continue if locvalue == 'inlibrary': From cf02b7c2b554d6e52b996669348437e29cbc5806 Mon Sep 17 00:00:00 2001 From: Charles Haley <> Date: Fri, 8 Jul 2011 13:56:42 +0100 Subject: [PATCH 3/4] Improvements in display of grouped search terms in the tag browser. Consolodate tags and use the category name. Use the catalog icon for grouped search terms. Searching from the tag browser uses the GST name instead of the underlying category. --- src/calibre/gui2/tag_browser/model.py | 12 ++++++++++-- src/calibre/library/database2.py | 16 ++++++++++++++-- src/calibre/library/field_metadata.py | 5 +++-- 3 files changed, 27 insertions(+), 6 deletions(-) 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', } From eea7a690f6966bd9e99dcea29e65cb2f6572bd81 Mon Sep 17 00:00:00 2001 From: Charles Haley <> Date: Fri, 8 Jul 2011 14:02:39 +0100 Subject: [PATCH 4/4] Remove unused import --- src/calibre/gui2/tag_browser/model.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/calibre/gui2/tag_browser/model.py b/src/calibre/gui2/tag_browser/model.py index 0324fd8622..6ac1366446 100644 --- a/src/calibre/gui2/tag_browser/model.py +++ b/src/calibre/gui2/tag_browser/model.py @@ -21,7 +21,6 @@ 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,