diff --git a/src/calibre/db/cache.py b/src/calibre/db/cache.py index a49b86af16..aeceafbb8b 100644 --- a/src/calibre/db/cache.py +++ b/src/calibre/db/cache.py @@ -2208,13 +2208,13 @@ class Cache(object): self._restore_annotations(book_id, annotations) @read_api - def virtual_libraries_for_books(self, book_ids): + def virtual_libraries_for_books(self, book_ids, virtual_fields=None): if self.vls_for_books_cache is None: # Using a list is slightly faster than a set. c = defaultdict(list) libraries = self._pref('virtual_libraries', {}) for lib, expr in libraries.items(): - for book in self._search(expr): + for book in self._search(expr, virtual_fields=virtual_fields): c[book].append(lib) self.vls_for_books_cache = {b:tuple(sorted(libs, key=sort_key)) for b, libs in c.items()} if not book_ids: diff --git a/src/calibre/db/lazy.py b/src/calibre/db/lazy.py index 9ad3aba57d..d2b7398f24 100644 --- a/src/calibre/db/lazy.py +++ b/src/calibre/db/lazy.py @@ -258,6 +258,11 @@ def composite_getter(mi, field, dbref, book_id, cache, formatter, template_cache def virtual_libraries_getter(dbref, book_id, cache): + ''' + This method is deprecated because it doesn't (and can't) return virtual + library names when the VL search references marked books. It is replaced + by db.view.get_virtual_libraries_for_books() + ''' try: return cache['virtual_libraries'] except KeyError: diff --git a/src/calibre/db/view.py b/src/calibre/db/view.py index 1a9a5ef33d..fa4e297156 100644 --- a/src/calibre/db/view.py +++ b/src/calibre/db/view.py @@ -232,6 +232,10 @@ class View(object): ans = [':::'.join((adata[aid]['name'], adata[aid]['sort'], adata[aid]['link'])) for aid in ids if aid in adata] return ':#:'.join(ans) if ans else default_value + def get_virtual_libraries_for_books(self, ids): + return self.cache.virtual_libraries_for_books( + ids, virtual_fields={'marked':MarkedVirtualField(self.marked_ids)}) + def _do_sort(self, ids_to_sort, fields=(), subsort=False): fields = [(sanitize_sort_field_name(self.field_metadata, x), bool(y)) for x, y in fields] keys = self.field_metadata.sortable_field_keys() @@ -377,7 +381,9 @@ class View(object): # This invalidates all searches in the cache even though the cache may # be shared by multiple views. This is not ideal, but... cmids = set(self.marked_ids) - self.cache.clear_search_caches(old_marked_ids | cmids) + changed_ids = old_marked_ids | cmids + self.cache.clear_search_caches(changed_ids) + self.refresh_ids(changed_ids) if old_marked_ids != cmids: for funcref in itervalues(self.marked_listeners): func = funcref() diff --git a/src/calibre/utils/formatter_functions.py b/src/calibre/utils/formatter_functions.py index 61af39c00c..275763af53 100644 --- a/src/calibre/utils/formatter_functions.py +++ b/src/calibre/utils/formatter_functions.py @@ -1714,7 +1714,9 @@ class BuiltinVirtualLibraries(BuiltinFormatterFunction): def evaluate(self, formatter, kwargs, mi, locals_): if hasattr(mi, '_proxy_metadata'): - return mi._proxy_metadata.virtual_libraries + from calibre.gui2.ui import get_gui + a = get_gui().current_db.data.get_virtual_libraries_for_books((mi.id,)) + return ', '.join(a[mi.id]) return _('This function can be used only in the GUI')