diff --git a/src/calibre/ebooks/metadata/book/base.py b/src/calibre/ebooks/metadata/book/base.py index 77df6b00c2..17f2c6705c 100644 --- a/src/calibre/ebooks/metadata/book/base.py +++ b/src/calibre/ebooks/metadata/book/base.py @@ -16,6 +16,7 @@ from calibre.ebooks.metadata.book import TOP_LEVEL_CLASSIFIERS from calibre.ebooks.metadata.book import ALL_METADATA_FIELDS from calibre.library.field_metadata import FieldMetadata from calibre.utils.date import isoformat, format_date +from calibre.utils.icu import sort_key from calibre.utils.formatter import TemplateFormatter @@ -490,7 +491,7 @@ class Metadata(object): return authors_to_string(self.authors) def format_tags(self): - return u', '.join([unicode(t) for t in self.tags]) + return u', '.join([unicode(t) for t in sorted(self.tags, key=sort_key)]) def format_rating(self): return unicode(self.rating) @@ -530,7 +531,7 @@ class Metadata(object): orig_res = res datatype = cmeta['datatype'] if datatype == 'text' and cmeta['is_multiple']: - res = u', '.join(res) + res = u', '.join(sorted(res, key=sort_key)) elif datatype == 'series' and series_with_index: if self.get_extra(key) is not None: res = res + \ @@ -560,7 +561,7 @@ class Metadata(object): elif key == 'series_index': res = self.format_series_index(res) elif datatype == 'text' and fmeta['is_multiple']: - res = u', '.join(res) + res = u', '.join(sorted(res, key=sort_key)) elif datatype == 'series' and series_with_index: res = res + ' [%s]'%self.format_series_index() elif datatype == 'datetime': diff --git a/src/calibre/library/caches.py b/src/calibre/library/caches.py index 2596b494bf..980c9f1fa9 100644 --- a/src/calibre/library/caches.py +++ b/src/calibre/library/caches.py @@ -691,13 +691,7 @@ class ResultCache(SearchQueryParser): # {{{ fields = [('timestamp', False)] keyg = SortKeyGenerator(fields, self.field_metadata, self._data) - # For efficiency, the key generator returns a plain value if only one - # field is in the sort field list. Because the normal cmp function will - # always assume asc, we must deal with asc/desc here. - if len(fields) == 1: - self._map.sort(key=keyg, reverse=not fields[0][1]) - else: - self._map.sort(key=keyg) + self._map.sort(key=keyg) tmap = list(itertools.repeat(False, len(self._data))) for x in self._map_filtered: @@ -730,8 +724,6 @@ class SortKeyGenerator(object): def __call__(self, record): values = tuple(self.itervals(self.data[record])) - if len(values) == 1: - return values[0] return SortKey(self.orders, values) def itervals(self, record): @@ -754,6 +746,11 @@ class SortKeyGenerator(object): val = (self.string_sort_key(val), sidx) elif dt in ('text', 'comments', 'composite', 'enumeration'): + if val: + sep = fm['is_multiple'] + if sep: + val = sep.join(sorted(val.split(sep), + key=self.string_sort_key)) val = self.string_sort_key(val) elif dt == 'bool':