diff --git a/src/calibre/db/cache.py b/src/calibre/db/cache.py index 0be9f9f9ef..6bd7c1a3cf 100644 --- a/src/calibre/db/cache.py +++ b/src/calibre/db/cache.py @@ -781,7 +781,7 @@ class Cache(object): return ret @read_api - def multisort(self, fields, ids_to_sort=None): + def multisort(self, fields, ids_to_sort=None, virtual_fields=None): ''' Return a list of sorted book ids. If ids_to_sort is None, all book ids are returned. @@ -794,6 +794,7 @@ class Cache(object): else ids_to_sort) get_metadata = self._get_proxy_metadata lang_map = self.fields['languages'].book_value_map + virtual_fields = virtual_fields or {} fm = {'title':'sort', 'authors':'author_sort'} @@ -801,8 +802,12 @@ class Cache(object): 'Handle series type fields' idx = field + '_index' is_series = idx in self.fields - ans = self.fields[fm.get(field, field)].sort_keys_for_books( - get_metadata, lang_map, all_book_ids,) + try: + ans = self.fields[fm.get(field, field)].sort_keys_for_books( + get_metadata, lang_map, all_book_ids) + except KeyError: + ans = virtual_fields[fm.get(field, field)].sort_keys_for_books( + get_metadata, lang_map, all_book_ids) if is_series: idx_ans = self.fields[idx].sort_keys_for_books( get_metadata, lang_map, all_book_ids) diff --git a/src/calibre/db/tests/reading.py b/src/calibre/db/tests/reading.py index 2006348862..66b1dacec4 100644 --- a/src/calibre/db/tests/reading.py +++ b/src/calibre/db/tests/reading.py @@ -511,3 +511,14 @@ class ReadingTest(BaseTest): # }}} + def test_marked_field(self): # {{{ + ' Test the marked field ' + db = self.init_legacy() + db.set_marked_ids({3:1, 2:3}) + ids = [1,2,3] + db.multisort([('marked', True)], only_ids=ids) + self.assertListEqual([1, 3, 2], ids) + db.multisort([('marked', False)], only_ids=ids) + self.assertListEqual([2, 3, 1], ids) + # }}} + diff --git a/src/calibre/db/view.py b/src/calibre/db/view.py index 7468ec11b2..0e8d4081e5 100644 --- a/src/calibre/db/view.py +++ b/src/calibre/db/view.py @@ -30,6 +30,9 @@ class MarkedVirtualField(object): for book_id in candidates: yield self.marked_ids.get(book_id, default_value), {book_id} + def sort_keys_for_books(self, get_metadata, lang_map, all_book_ids): + return {bid:self.marked_ids.get(bid, None) for bid in all_book_ids} + class TableRow(object): def __init__(self, book_id, view): @@ -219,7 +222,7 @@ class View(object): if not fields: fields = [('timestamp', False)] - sorted_book_ids = self.cache.multisort(fields, ids_to_sort=only_ids) + sorted_book_ids = self.cache.multisort(fields, ids_to_sort=only_ids, virtual_fields={'marked':MarkedVirtualField(self.marked_ids)}) if only_ids is None: self._map = tuple(sorted_book_ids) if len(self._map_filtered) == len(self._map):