A new 'authors type' custom column

This commit is contained in:
Kovid Goyal 2011-03-22 10:58:06 -06:00
commit ca2d9875bd
14 changed files with 133 additions and 60 deletions

View File

@ -575,7 +575,10 @@ class Metadata(object):
orig_res = res orig_res = res
datatype = cmeta['datatype'] datatype = cmeta['datatype']
if datatype == 'text' and cmeta['is_multiple']: if datatype == 'text' and cmeta['is_multiple']:
res = u', '.join(sorted(res, key=sort_key)) if cmeta['display'].get('is_names', False):
res = u' & '.join(res)
else:
res = u', '.join(sorted(res, key=sort_key))
elif datatype == 'series' and series_with_index: elif datatype == 'series' and series_with_index:
if self.get_extra(key) is not None: if self.get_extra(key) is not None:
res = res + \ res = res + \

View File

@ -226,10 +226,18 @@ class Comments(Base):
class Text(Base): class Text(Base):
def setup_ui(self, parent): def setup_ui(self, parent):
if self.col_metadata['display'].get('is_names', False):
self.sep = u' & '
else:
self.sep = u', '
values = self.all_values = list(self.db.all_custom(num=self.col_id)) values = self.all_values = list(self.db.all_custom(num=self.col_id))
values.sort(key=sort_key) values.sort(key=sort_key)
if self.col_metadata['is_multiple']: if self.col_metadata['is_multiple']:
w = MultiCompleteLineEdit(parent) w = MultiCompleteLineEdit(parent)
w.set_separator(self.sep.strip())
if self.sep == u' & ':
w.set_space_before_sep(True)
w.set_add_separator(tweaks['authors_completer_append_separator'])
w.update_items_cache(values) w.update_items_cache(values)
w.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred) w.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred)
else: else:
@ -261,12 +269,12 @@ class Text(Base):
if self.col_metadata['is_multiple']: if self.col_metadata['is_multiple']:
if not val: if not val:
val = [] val = []
self.widgets[1].setText(u', '.join(val)) self.widgets[1].setText(self.sep.join(val))
def getter(self): def getter(self):
if self.col_metadata['is_multiple']: if self.col_metadata['is_multiple']:
val = unicode(self.widgets[1].text()).strip() val = unicode(self.widgets[1].text()).strip()
ans = [x.strip() for x in val.split(',') if x.strip()] ans = [x.strip() for x in val.split(self.sep.strip()) if x.strip()]
if not ans: if not ans:
ans = None ans = None
return ans return ans
@ -847,13 +855,20 @@ class BulkText(BulkBase):
self.main_widget.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred) self.main_widget.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred)
self.adding_widget = self.main_widget self.adding_widget = self.main_widget
w = RemoveTags(parent, values) if not self.col_metadata['display'].get('is_names', False):
self.widgets.append(QLabel('&'+self.col_metadata['name']+': ' + w = RemoveTags(parent, values)
_('tags to remove'), parent)) self.widgets.append(QLabel('&'+self.col_metadata['name']+': ' +
self.widgets.append(w) _('tags to remove'), parent))
self.removing_widget = w self.widgets.append(w)
w.tags_box.textChanged.connect(self.a_c_checkbox_changed) self.removing_widget = w
w.checkbox.stateChanged.connect(self.a_c_checkbox_changed) self.main_widget.set_separator(',')
w.tags_box.textChanged.connect(self.a_c_checkbox_changed)
w.checkbox.stateChanged.connect(self.a_c_checkbox_changed)
else:
self.main_widget.set_separator('&')
self.main_widget.set_space_before_sep(True)
self.main_widget.set_add_separator(
tweaks['authors_completer_append_separator'])
else: else:
self.make_widgets(parent, MultiCompleteComboBox) self.make_widgets(parent, MultiCompleteComboBox)
self.main_widget.set_separator(None) self.main_widget.set_separator(None)
@ -882,21 +897,26 @@ class BulkText(BulkBase):
if not self.a_c_checkbox.isChecked(): if not self.a_c_checkbox.isChecked():
return return
if self.col_metadata['is_multiple']: if self.col_metadata['is_multiple']:
remove_all, adding, rtext = self.gui_val if self.col_metadata['display'].get('is_names', False):
remove = set() val = self.gui_val
if remove_all: add = [v.strip() for v in val.split('&') if v.strip()]
remove = set(self.db.all_custom(num=self.col_id)) self.db.set_custom_bulk(book_ids, add, num=self.col_id)
else: else:
txt = rtext remove_all, adding, rtext = self.gui_val
remove = set()
if remove_all:
remove = set(self.db.all_custom(num=self.col_id))
else:
txt = rtext
if txt:
remove = set([v.strip() for v in txt.split(',')])
txt = adding
if txt: if txt:
remove = set([v.strip() for v in txt.split(',')]) add = set([v.strip() for v in txt.split(',')])
txt = adding else:
if txt: add = set()
add = set([v.strip() for v in txt.split(',')]) self.db.set_custom_bulk_multiple(book_ids, add=add,
else: remove=remove, num=self.col_id)
add = set()
self.db.set_custom_bulk_multiple(book_ids, add=add, remove=remove,
num=self.col_id)
else: else:
val = self.gui_val val = self.gui_val
val = self.normalize_ui_val(val) val = self.normalize_ui_val(val)
@ -905,10 +925,11 @@ class BulkText(BulkBase):
def getter(self): def getter(self):
if self.col_metadata['is_multiple']: if self.col_metadata['is_multiple']:
return self.removing_widget.checkbox.isChecked(), \ if not self.col_metadata['display'].get('is_names', False):
unicode(self.adding_widget.text()), \ return self.removing_widget.checkbox.isChecked(), \
unicode(self.removing_widget.tags_box.text()) unicode(self.adding_widget.text()), \
unicode(self.removing_widget.tags_box.text())
return unicode(self.adding_widget.text())
val = unicode(self.main_widget.currentText()).strip() val = unicode(self.main_widget.currentText()).strip()
if not val: if not val:
val = None val = None

View File

@ -653,7 +653,10 @@ class MetadataBulkDialog(ResizableDialog, Ui_MetadataBulkDialog):
if self.destination_field_fm['is_multiple']: if self.destination_field_fm['is_multiple']:
if self.comma_separated.isChecked(): if self.comma_separated.isChecked():
if dest == 'authors': if dest == 'authors' or \
(self.destination_field_fm['is_custom'] and
self.destination_field_fm['datatype'] == 'text' and
self.destination_field_fm['display'].get('is_names', False)):
splitter = ' & ' splitter = ' & '
else: else:
splitter = ',' splitter = ','

View File

@ -640,18 +640,18 @@ class BooksModel(QAbstractTableModel): # {{{
return self.bool_yes_icon return self.bool_yes_icon
return self.bool_blank_icon return self.bool_blank_icon
def text_type(r, mult=False, idx=-1): def text_type(r, mult=None, idx=-1):
text = self.db.data[r][idx] text = self.db.data[r][idx]
if text and mult: if text and mult is not None:
return QVariant(', '.join(sorted(text.split('|'),key=sort_key))) if mult:
return QVariant(u' & '.join(text.split('|')))
return QVariant(u', '.join(sorted(text.split('|'),key=sort_key)))
return QVariant(text) return QVariant(text)
def decorated_text_type(r, mult=False, idx=-1): def decorated_text_type(r, idx=-1):
text = self.db.data[r][idx] text = self.db.data[r][idx]
if force_to_bool(text) is not None: if force_to_bool(text) is not None:
return None return None
if text and mult:
return QVariant(', '.join(sorted(text.split('|'),key=sort_key)))
return QVariant(text) return QVariant(text)
def number_type(r, idx=-1): def number_type(r, idx=-1):
@ -659,7 +659,7 @@ class BooksModel(QAbstractTableModel): # {{{
self.dc = { self.dc = {
'title' : functools.partial(text_type, 'title' : functools.partial(text_type,
idx=self.db.field_metadata['title']['rec_index'], mult=False), idx=self.db.field_metadata['title']['rec_index'], mult=None),
'authors' : functools.partial(authors, 'authors' : functools.partial(authors,
idx=self.db.field_metadata['authors']['rec_index']), idx=self.db.field_metadata['authors']['rec_index']),
'size' : functools.partial(size, 'size' : functools.partial(size,
@ -671,14 +671,14 @@ class BooksModel(QAbstractTableModel): # {{{
'rating' : functools.partial(rating_type, 'rating' : functools.partial(rating_type,
idx=self.db.field_metadata['rating']['rec_index']), idx=self.db.field_metadata['rating']['rec_index']),
'publisher': functools.partial(text_type, 'publisher': functools.partial(text_type,
idx=self.db.field_metadata['publisher']['rec_index'], mult=False), idx=self.db.field_metadata['publisher']['rec_index'], mult=None),
'tags' : functools.partial(tags, 'tags' : functools.partial(tags,
idx=self.db.field_metadata['tags']['rec_index']), idx=self.db.field_metadata['tags']['rec_index']),
'series' : functools.partial(series_type, 'series' : functools.partial(series_type,
idx=self.db.field_metadata['series']['rec_index'], idx=self.db.field_metadata['series']['rec_index'],
siix=self.db.field_metadata['series_index']['rec_index']), siix=self.db.field_metadata['series_index']['rec_index']),
'ondevice' : functools.partial(text_type, 'ondevice' : functools.partial(text_type,
idx=self.db.field_metadata['ondevice']['rec_index'], mult=False), idx=self.db.field_metadata['ondevice']['rec_index'], mult=None),
} }
self.dc_decorator = { self.dc_decorator = {
@ -692,11 +692,12 @@ class BooksModel(QAbstractTableModel): # {{{
datatype = self.custom_columns[col]['datatype'] datatype = self.custom_columns[col]['datatype']
if datatype in ('text', 'comments', 'composite', 'enumeration'): if datatype in ('text', 'comments', 'composite', 'enumeration'):
mult=self.custom_columns[col]['is_multiple'] mult=self.custom_columns[col]['is_multiple']
if mult is not None:
mult = self.custom_columns[col]['display'].get('is_names', False)
self.dc[col] = functools.partial(text_type, idx=idx, mult=mult) self.dc[col] = functools.partial(text_type, idx=idx, mult=mult)
if datatype in ['text', 'composite', 'enumeration'] and not mult: if datatype in ['text', 'composite', 'enumeration'] and not mult:
if self.custom_columns[col]['display'].get('use_decorations', False): if self.custom_columns[col]['display'].get('use_decorations', False):
self.dc[col] = functools.partial(decorated_text_type, self.dc[col] = functools.partial(decorated_text_type, idx=idx)
idx=idx, mult=mult)
self.dc_decorator[col] = functools.partial( self.dc_decorator[col] = functools.partial(
bool_type_decorator, idx=idx, bool_type_decorator, idx=idx,
bool_cols_are_tristate= bool_cols_are_tristate=

View File

@ -78,6 +78,7 @@ class BooksView(QTableView): # {{{
self.pubdate_delegate = PubDateDelegate(self) self.pubdate_delegate = PubDateDelegate(self)
self.tags_delegate = CompleteDelegate(self, ',', 'all_tags') self.tags_delegate = CompleteDelegate(self, ',', 'all_tags')
self.authors_delegate = CompleteDelegate(self, '&', 'all_author_names', True) self.authors_delegate = CompleteDelegate(self, '&', 'all_author_names', True)
self.cc_names_delegate = CompleteDelegate(self, '&', 'all_custom', True)
self.series_delegate = TextDelegate(self) self.series_delegate = TextDelegate(self)
self.publisher_delegate = TextDelegate(self) self.publisher_delegate = TextDelegate(self)
self.text_delegate = TextDelegate(self) self.text_delegate = TextDelegate(self)
@ -410,6 +411,7 @@ class BooksView(QTableView): # {{{
self.save_state() self.save_state()
self._model.set_database(db) self._model.set_database(db)
self.tags_delegate.set_database(db) self.tags_delegate.set_database(db)
self.cc_names_delegate.set_database(db)
self.authors_delegate.set_database(db) self.authors_delegate.set_database(db)
self.series_delegate.set_auto_complete_function(db.all_series) self.series_delegate.set_auto_complete_function(db.all_series)
self.publisher_delegate.set_auto_complete_function(db.all_publishers) self.publisher_delegate.set_auto_complete_function(db.all_publishers)
@ -431,12 +433,17 @@ class BooksView(QTableView): # {{{
self.setItemDelegateForColumn(cm.index(colhead), delegate) self.setItemDelegateForColumn(cm.index(colhead), delegate)
elif cc['datatype'] == 'comments': elif cc['datatype'] == 'comments':
self.setItemDelegateForColumn(cm.index(colhead), self.cc_comments_delegate) self.setItemDelegateForColumn(cm.index(colhead), self.cc_comments_delegate)
elif cc['datatype'] in ('text', 'series'): elif cc['datatype'] == 'text':
if cc['is_multiple']: if cc['is_multiple']:
self.setItemDelegateForColumn(cm.index(colhead), self.tags_delegate) if cc['display'].get('is_names', False):
self.setItemDelegateForColumn(cm.index(colhead),
self.cc_names_delegate)
else:
self.setItemDelegateForColumn(cm.index(colhead),
self.tags_delegate)
else: else:
self.setItemDelegateForColumn(cm.index(colhead), self.cc_text_delegate) self.setItemDelegateForColumn(cm.index(colhead), self.cc_text_delegate)
elif cc['datatype'] in ('int', 'float'): elif cc['datatype'] in ('series', 'int', 'float'):
self.setItemDelegateForColumn(cm.index(colhead), self.cc_text_delegate) self.setItemDelegateForColumn(cm.index(colhead), self.cc_text_delegate)
elif cc['datatype'] == 'bool': elif cc['datatype'] == 'bool':
self.setItemDelegateForColumn(cm.index(colhead), self.cc_bool_delegate) self.setItemDelegateForColumn(cm.index(colhead), self.cc_bool_delegate)

View File

@ -125,6 +125,8 @@ class CreateCustomColumn(QDialog, Ui_QCreateCustomColumn):
self.datatype_changed() self.datatype_changed()
if ct in ['text', 'composite', 'enumeration']: if ct in ['text', 'composite', 'enumeration']:
self.use_decorations.setChecked(c['display'].get('use_decorations', False)) self.use_decorations.setChecked(c['display'].get('use_decorations', False))
elif ct == '*text':
self.is_names.setChecked(c['display'].get('is_names', False))
self.exec_() self.exec_()
def shortcut_activated(self, url): def shortcut_activated(self, url):
@ -167,6 +169,7 @@ class CreateCustomColumn(QDialog, Ui_QCreateCustomColumn):
for x in ('box', 'default_label', 'label'): for x in ('box', 'default_label', 'label'):
getattr(self, 'enum_'+x).setVisible(col_type == 'enumeration') getattr(self, 'enum_'+x).setVisible(col_type == 'enumeration')
self.use_decorations.setVisible(col_type in ['text', 'composite', 'enumeration']) self.use_decorations.setVisible(col_type in ['text', 'composite', 'enumeration'])
self.is_names.setVisible(col_type == '*text')
def accept(self): def accept(self):
col = unicode(self.column_name_box.text()).strip() col = unicode(self.column_name_box.text()).strip()
@ -241,6 +244,8 @@ class CreateCustomColumn(QDialog, Ui_QCreateCustomColumn):
return self.simple_error('', _('The value "{0}" is in the ' return self.simple_error('', _('The value "{0}" is in the '
'list more than once').format(l[i])) 'list more than once').format(l[i]))
display_dict = {'enum_values': l} display_dict = {'enum_values': l}
elif col_type == 'text' and is_multiple:
display_dict = {'is_names': self.is_names.isChecked()}
if col_type in ['text', 'composite', 'enumeration']: if col_type in ['text', 'composite', 'enumeration']:
display_dict['use_decorations'] = self.use_decorations.checkState() display_dict['use_decorations'] = self.use_decorations.checkState()

View File

@ -120,6 +120,16 @@ Everything else will show nothing.</string>
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QCheckBox" name="is_names">
<property name="text">
<string>Contains names</string>
</property>
<property name="toolTip">
<string>Check this box if this column contains names, like the authors column.</string>
</property>
</widget>
</item>
<item> <item>
<spacer name="horizontalSpacer_27"> <spacer name="horizontalSpacer_27">
<property name="orientation"> <property name="orientation">

View File

@ -64,8 +64,9 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
r('tags_browser_collapse_at', gprefs) r('tags_browser_collapse_at', gprefs)
choices = set([k for k in db.field_metadata.all_field_keys() choices = set([k for k in db.field_metadata.all_field_keys()
if db.field_metadata[k]['is_category'] and if db.field_metadata[k]['is_category'] and
db.field_metadata[k]['datatype'] in ['text', 'series', 'enumeration']]) (db.field_metadata[k]['datatype'] in ['text', 'series', 'enumeration']) and
not db.field_metadata[k]['display'].get('is_names', False)])
choices -= set(['authors', 'publisher', 'formats', 'news', 'identifiers']) choices -= set(['authors', 'publisher', 'formats', 'news', 'identifiers'])
choices |= set(['search']) choices |= set(['search'])
self.opt_categories_using_hierarchy.update_items_cache(choices) self.opt_categories_using_hierarchy.update_items_cache(choices)

View File

@ -658,8 +658,7 @@ class TagTreeItem(object): # {{{
def tag_data(self, role): def tag_data(self, role):
tag = self.tag tag = self.tag
if tag.category == 'authors' and \ if tag.use_sort_as_name:
tweaks['categories_use_field_for_author_name'] == 'author_sort':
name = tag.sort name = tag.sort
tt_author = True tt_author = True
else: else:
@ -1275,6 +1274,7 @@ class TagsModel(QAbstractItemModel): # {{{
if len(components) == 0 or '.'.join(components) != tag.original_name: if len(components) == 0 or '.'.join(components) != tag.original_name:
components = [tag.original_name] components = [tag.original_name]
if (not tag.is_hierarchical) and (in_uc or if (not tag.is_hierarchical) and (in_uc or
(fm['is_custom'] and fm['display'].get('is_names', False)) or
key in ['authors', 'publisher', 'news', 'formats', 'rating'] or key in ['authors', 'publisher', 'news', 'formats', 'rating'] or
key not in self.db.prefs.get('categories_using_hierarchy', []) or key not in self.db.prefs.get('categories_using_hierarchy', []) or
len(components) == 1): len(components) == 1):

View File

@ -15,7 +15,7 @@ from calibre.utils.config import tweaks, prefs
from calibre.utils.date import parse_date, now, UNDEFINED_DATE from calibre.utils.date import parse_date, now, UNDEFINED_DATE
from calibre.utils.search_query_parser import SearchQueryParser from calibre.utils.search_query_parser import SearchQueryParser
from calibre.utils.pyparsing import ParseException from calibre.utils.pyparsing import ParseException
from calibre.ebooks.metadata import title_sort from calibre.ebooks.metadata import title_sort, author_to_author_sort
from calibre.ebooks.metadata.opf2 import metadata_to_opf from calibre.ebooks.metadata.opf2 import metadata_to_opf
from calibre import prints from calibre import prints
@ -1023,7 +1023,11 @@ class SortKeyGenerator(object):
if val: if val:
sep = fm['is_multiple'] sep = fm['is_multiple']
if sep: if sep:
val = sep.join(sorted(val.split(sep), if fm['display'].get('is_names', False):
val = sep.join(
[author_to_author_sort(v) for v in val.split(sep)])
else:
val = sep.join(sorted(val.split(sep),
key=self.string_sort_key)) key=self.string_sort_key))
val = self.string_sort_key(val) val = self.string_sort_key(val)

View File

@ -117,7 +117,7 @@ class CustomColumns(object):
if x is None: if x is None:
return [] return []
if isinstance(x, (str, unicode, bytes)): if isinstance(x, (str, unicode, bytes)):
x = x.split(',') x = x.split('&' if d['display'].get('is_names', False) else',')
x = [y.strip() for y in x if y.strip()] x = [y.strip() for y in x if y.strip()]
x = [y.decode(preferred_encoding, 'replace') if not isinstance(y, x = [y.decode(preferred_encoding, 'replace') if not isinstance(y,
unicode) else y for y in x] unicode) else y for y in x]
@ -482,8 +482,11 @@ class CustomColumns(object):
set_val = val if data['is_multiple'] else [val] set_val = val if data['is_multiple'] else [val]
existing = getter() existing = getter()
if not existing: if not existing:
existing = [] existing = set([])
for x in set(set_val) - set(existing): else:
existing = set(existing)
# preserve the order in set_val
for x in [v for v in set_val if v not in existing]:
# normalized types are text and ratings, so we can do this check # normalized types are text and ratings, so we can do this check
# to see if we need to re-add the value # to see if we need to re-add the value
if not x: if not x:

View File

@ -48,7 +48,7 @@ class Tag(object):
def __init__(self, name, id=None, count=0, state=0, avg=0, sort=None, def __init__(self, name, id=None, count=0, state=0, avg=0, sort=None,
tooltip=None, icon=None, category=None, id_set=None, tooltip=None, icon=None, category=None, id_set=None,
is_editable = True, is_searchable=True): is_editable = True, is_searchable=True, use_sort_as_name=False):
self.name = self.original_name = name self.name = self.original_name = name
self.id = id self.id = id
self.count = count self.count = count
@ -59,6 +59,7 @@ class Tag(object):
self.id_set = id_set if id_set is not None else set([]) self.id_set = id_set if id_set is not None else set([])
self.avg_rating = avg/2.0 if avg is not None else 0 self.avg_rating = avg/2.0 if avg is not None else 0
self.sort = sort self.sort = sort
self.use_sort_as_name = use_sort_as_name
if self.avg_rating > 0: if self.avg_rating > 0:
if tooltip: if tooltip:
tooltip = tooltip + ': ' tooltip = tooltip + ': '
@ -1323,6 +1324,11 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
for l in list: for l in list:
(id, val) = (l[0], l[1]) (id, val) = (l[0], l[1])
tids[category][val] = (id, '{0:05.2f}'.format(val)) tids[category][val] = (id, '{0:05.2f}'.format(val))
elif cat['datatype'] == 'text' and cat['is_multiple'] and \
cat['display'].get('is_names', False):
for l in list:
(id, val) = (l[0], l[1])
tids[category][val] = (id, author_to_author_sort(val))
else: else:
for l in list: for l in list:
(id, val) = (l[0], l[1]) (id, val) = (l[0], l[1])
@ -1480,11 +1486,20 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
reverse=True reverse=True
items.sort(key=kf, reverse=reverse) items.sort(key=kf, reverse=reverse)
if tweaks['categories_use_field_for_author_name'] == 'author_sort' and\
(category == 'authors' or
(cat['display'].get('is_names', False) and
cat['is_custom'] and cat['is_multiple'] and
cat['datatype'] == 'text')):
use_sort_as_name = True
else:
use_sort_as_name = False
is_editable = category not in ['news', 'rating'] is_editable = category not in ['news', 'rating']
categories[category] = [tag_class(formatter(r.n), count=r.c, id=r.id, categories[category] = [tag_class(formatter(r.n), count=r.c, id=r.id,
avg=avgr(r), sort=r.s, icon=icon, avg=avgr(r), sort=r.s, icon=icon,
tooltip=tooltip, category=category, tooltip=tooltip, category=category,
id_set=r.id_set, is_editable=is_editable) id_set=r.id_set, is_editable=is_editable,
use_sort_as_name=use_sort_as_name)
for r in items] for r in items]
#print 'end phase "tags list":', time.clock() - last, 'seconds' #print 'end phase "tags list":', time.clock() - last, 'seconds'

View File

@ -15,7 +15,7 @@ from calibre import isbytestring, force_unicode, fit_image, \
prepare_string_for_xml prepare_string_for_xml
from calibre.utils.ordered_dict import OrderedDict from calibre.utils.ordered_dict import OrderedDict
from calibre.utils.filenames import ascii_filename from calibre.utils.filenames import ascii_filename
from calibre.utils.config import prefs, tweaks from calibre.utils.config import prefs
from calibre.utils.icu import sort_key from calibre.utils.icu import sort_key
from calibre.utils.magick import Image from calibre.utils.magick import Image
from calibre.library.comments import comments_to_html from calibre.library.comments import comments_to_html
@ -155,8 +155,7 @@ def get_category_items(category, items, restriction, datatype, prefix): # {{{
'<div>{1}</div>' '<div>{1}</div>'
'<div>{2}</div></div>') '<div>{2}</div></div>')
rating, rstring = render_rating(i.avg_rating, prefix) rating, rstring = render_rating(i.avg_rating, prefix)
if i.category == 'authors' and \ if i.use_sort_as_name:
tweaks['categories_use_field_for_author_name'] == 'author_sort':
name = xml(i.sort) name = xml(i.sort)
else: else:
name = xml(i.name) name = xml(i.name)
@ -696,7 +695,10 @@ class BrowseServer(object):
xml(href, True), xml(href, True),
xml(val if len(dbtags) == 1 else tag.name), xml(val if len(dbtags) == 1 else tag.name),
xml(key, True))) xml(key, True)))
join = ' &amp; ' if key == 'authors' else ', ' join = ' &amp; ' if key == 'authors' or \
(fm['is_custom'] and
fm['display'].get('is_names', False)) \
else ', '
args[key] = join.join(vals) args[key] = join.join(vals)
added_key = True added_key = True
if not added_key: if not added_key:

View File

@ -22,7 +22,6 @@ from calibre.library.server.utils import format_tag_string, Offsets
from calibre import guess_type, prepare_string_for_xml as xml from calibre import guess_type, prepare_string_for_xml as xml
from calibre.utils.icu import sort_key from calibre.utils.icu import sort_key
from calibre.utils.ordered_dict import OrderedDict from calibre.utils.ordered_dict import OrderedDict
from calibre.utils.config import tweaks
BASE_HREFS = { BASE_HREFS = {
0 : '/stanza', 0 : '/stanza',
@ -126,8 +125,7 @@ def CATALOG_ENTRY(item, item_kind, base_href, version, updated,
count = (_('%d books') if item.count > 1 else _('%d book'))%item.count count = (_('%d books') if item.count > 1 else _('%d book'))%item.count
if ignore_count: if ignore_count:
count = '' count = ''
if item.category == 'authors' and \ if item.use_sort_as_name:
tweaks['categories_use_field_for_author_name'] == 'author_sort':
name = item.sort name = item.sort
else: else:
name = item.name name = item.name