From 8a0b3c1ffc69bc710eedcf4d7b6e1be996e33963 Mon Sep 17 00:00:00 2001
From: Charles Haley <>
Date: Fri, 18 Mar 2011 09:39:44 +0000
Subject: [PATCH] Add option to show composite columns in the tag browser
---
.../gui2/preferences/create_custom_column.py | 8 +++--
.../gui2/preferences/create_custom_column.ui | 32 +++++++++++------
src/calibre/library/database2.py | 35 ++++++++++++++++---
src/calibre/library/server/browse.py | 2 ++
4 files changed, 59 insertions(+), 18 deletions(-)
diff --git a/src/calibre/gui2/preferences/create_custom_column.py b/src/calibre/gui2/preferences/create_custom_column.py
index 8909bc7b3d..cee34f150e 100644
--- a/src/calibre/gui2/preferences/create_custom_column.py
+++ b/src/calibre/gui2/preferences/create_custom_column.py
@@ -118,6 +118,8 @@ class CreateCustomColumn(QDialog, Ui_QCreateCustomColumn):
else:
sb = 0
self.composite_sort_by.setCurrentIndex(sb)
+ self.composite_make_category.setChecked(
+ c['display'].get('make_category', False))
elif ct == 'enumeration':
self.enum_box.setText(','.join(c['display'].get('enum_values', [])))
self.datatype_changed()
@@ -159,7 +161,8 @@ class CreateCustomColumn(QDialog, Ui_QCreateCustomColumn):
col_type = None
for x in ('box', 'default_label', 'label'):
getattr(self, 'date_format_'+x).setVisible(col_type == 'datetime')
- for x in ('box', 'default_label', 'label', 'sort_by', 'sort_by_label'):
+ for x in ('box', 'default_label', 'label', 'sort_by', 'sort_by_label',
+ 'make_category'):
getattr(self, 'composite_'+x).setVisible(col_type == 'composite')
for x in ('box', 'default_label', 'label'):
getattr(self, 'enum_'+x).setVisible(col_type == 'enumeration')
@@ -222,7 +225,8 @@ class CreateCustomColumn(QDialog, Ui_QCreateCustomColumn):
' composite columns'))
display_dict = {'composite_template':unicode(self.composite_box.text()).strip(),
'composite_sort': ['text', 'number', 'date', 'bool']
- [self.composite_sort_by.currentIndex()]
+ [self.composite_sort_by.currentIndex()],
+ 'make_category': self.composite_make_category.isChecked(),
}
elif col_type == 'enumeration':
if not unicode(self.enum_box.text()).strip():
diff --git a/src/calibre/gui2/preferences/create_custom_column.ui b/src/calibre/gui2/preferences/create_custom_column.ui
index aaa69f5e4b..3290d3c846 100644
--- a/src/calibre/gui2/preferences/create_custom_column.ui
+++ b/src/calibre/gui2/preferences/create_custom_column.ui
@@ -220,18 +220,18 @@ Everything else will show nothing.
- -
-
-
- &Sort/search column by
-
-
- composite_sort_by
-
-
-
-
-
+
+
-
+
+
+ &Sort/search column by
+
+
+ composite_sort_by
+
+
+
-
@@ -239,6 +239,16 @@ Everything else will show nothing.
+ -
+
+
+ Show in tags browser
+
+
+ If checked, this column will appear in the tags browser as a category
+
+
+
-
diff --git a/src/calibre/library/database2.py b/src/calibre/library/database2.py
index ec766c72f3..50a0ba98dd 100644
--- a/src/calibre/library/database2.py
+++ b/src/calibre/library/database2.py
@@ -1210,6 +1210,13 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
return ans
field = self.field_metadata[category]
+ if field['datatype'] == 'composite':
+ dex = field['rec_index']
+ for book in self.data.iterall():
+ if book[dex] == id_:
+ ans.add(book[0])
+ return ans
+
ans = self.conn.get(
'SELECT book FROM books_{tn}_link WHERE {col}=?'.format(
tn=field['table'], col=field['link_column']), (id_,))
@@ -1281,7 +1288,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
# First, build the maps. We need a category->items map and an
# item -> (item_id, sort_val) map to use in the books loop
- for category in tb_cats.keys():
+ for category in tb_cats.iterkeys():
cat = tb_cats[category]
if not cat['is_category'] or cat['kind'] in ['user', 'search'] \
or category in ['news', 'formats'] or cat.get('is_csp',
@@ -1324,8 +1331,15 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
tcategories[category] = {}
# create a list of category/field_index for the books scan to use.
# This saves iterating through field_metadata for each book
- md.append((category, cat['rec_index'], cat['is_multiple']))
+ md.append((category, cat['rec_index'], cat['is_multiple'], False))
+ for category in tb_cats.iterkeys():
+ cat = tb_cats[category]
+ if cat['datatype'] == 'composite' and \
+ cat['display'].get('make_category', False):
+ tcategories[category] = {}
+ md.append((category, cat['rec_index'], cat['is_multiple'],
+ cat['datatype'] == 'composite'))
#print 'end phase "collection":', time.clock() - last, 'seconds'
#last = time.clock()
@@ -1339,11 +1353,22 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
continue
rating = book[rating_dex]
# We kept track of all possible category field_map positions above
- for (cat, dex, mult) in md:
- if book[dex] is None:
+ for (cat, dex, mult, is_comp) in md:
+ if not book[dex]:
continue
if not mult:
val = book[dex]
+ if is_comp:
+ item = tcategories[cat].get(val, None)
+ if not item:
+ item = tag_class(val, val)
+ tcategories[cat][val] = item
+ item.c += 1
+ item.id = val
+ if rating > 0:
+ item.rt += rating
+ item.rc += 1
+ continue
try:
(item_id, sort_val) = tids[cat][val] # let exceptions fly
item = tcategories[cat].get(val, None)
@@ -1405,7 +1430,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
# and building the Tag instances.
categories = {}
tag_class = Tag
- for category in tb_cats.keys():
+ for category in tb_cats.iterkeys():
if category not in tcategories:
continue
cat = tb_cats[category]
diff --git a/src/calibre/library/server/browse.py b/src/calibre/library/server/browse.py
index fd015f5848..c3843840b8 100644
--- a/src/calibre/library/server/browse.py
+++ b/src/calibre/library/server/browse.py
@@ -623,6 +623,8 @@ class BrowseServer(object):
except:
raise cherrypy.HTTPError(404, 'Search: %r not understood'%which)
else:
+ if fm[category]['datatype'] == 'composite':
+ cid = cid.decode('utf-8')
all_ids = self.search_cache('')
if category == 'newest':
ids = all_ids