class SearchRestrictionMixin: no_restriction = '<' + _('None') + '>' def __init__(self, *args, **kwargs): pass def init_search_restriction_mixin(self): self.checked = QIcon(I('ok.png')) self.empty = QIcon(I('blank.png')) self.current_search_action = QAction(self.empty, _('*current search'), self) self.current_search_action.triggered.connect(partial(self.apply_virtual_library, library='*')) self.addAction(self.current_search_action) self.keyboard.register_shortcut( 'vl-from-current-search', _('Virtual library from current search'), description=_( 'Create a temporary Virtual library from the current search'), group=pgettext('search restriction group name', 'Miscellaneous'), default_keys=('Ctrl+*',), action=self.current_search_action) self.search_based_vl_name = None self.search_based_vl = None self.virtual_library_menu = QMenu(self.virtual_library) self.virtual_library.setMenu(self.virtual_library_menu) self.virtual_library_menu.aboutToShow.connect(self.virtual_library_menu_about_to_show) self.clear_vl.clicked.connect(lambda x: (self.apply_virtual_library(), self.clear_additional_restriction())) self.virtual_library_tooltip = \ _('Use a "Virtual library" to show only a subset of the books present in this library') self.virtual_library.setToolTip(self.virtual_library_tooltip) self.search_restriction = ComboBoxWithHelp(self) self.search_restriction.setVisible(False) self.clear_vl.setText(_("(all books)")) self.ar_menu = QMenu(_('Additional restriction'), self.virtual_library_menu) self.edit_menu = QMenu(_('Edit Virtual library'), self.virtual_library_menu) self.rm_menu = QMenu(_('Remove Virtual library'), self.virtual_library_menu) self.search_restriction_list_built = False def add_virtual_library(self, db, name, search): virt_libs = db.new_api.pref('virtual_libraries', {}) virt_libs[name] = search db.new_api.set_pref('virtual_libraries', virt_libs) db.new_api.clear_search_caches() self.library_view.model().db.refresh() def do_create_edit(self, name=None): db = self.library_view.model().db virt_libs = db.new_api.pref('virtual_libraries', {}) cd = CreateVirtualLibrary(self, virt_libs.keys(), editing=name) if cd.exec() == QDialog.DialogCode.Accepted: if name: self._remove_vl(name, reapply=False) self.add_virtual_library(db, cd.library_name, cd.library_search) if not name or name == db.data.get_base_restriction_name(): self.apply_virtual_library(cd.library_name) self.rebuild_vl_tabs() def build_virtual_library_menu(self, m, add_tabs_action=True): m.clear() a = m.addAction(QIcon.ic('plus.png'), _('Create Virtual library')) a.triggered.connect(partial(self.do_create_edit, name=None)) db = self.current_db virt_libs = db.new_api.pref('virtual_libraries', {}) a = self.edit_menu self.build_virtual_library_list(a, self.do_create_edit) if virt_libs: m.addMenu(a).setIcon(QIcon.ic('edit_input.png')) a = self.rm_menu self.build_virtual_library_list(a, self.remove_vl_triggered) if virt_libs: m.addMenu(a).setIcon(QIcon.ic('minus.png')) if virt_libs: m.addAction(QIcon.ic('toc.png'), _('Quick select Virtual library'), self.choose_vl_triggerred) if add_tabs_action: if gprefs['show_vl_tabs']: m.addAction(_('Hide Virtual library tabs'), self.vl_tabs.disable_bar) else: m.addAction(_('Show Virtual libraries as tabs'), self.vl_tabs.enable_bar) m.addSeparator() a = self.ar_menu a.clear() a.setIcon(self.checked if db.data.get_search_restriction_name() else self.empty) self.build_search_restriction_list() m.addMenu(a) m.addSeparator() current_lib = db.data.get_base_restriction_name() if not current_lib: a = m.addAction(self.checked, self.no_restriction) else: a = m.addAction(self.empty, self.no_restriction) a.triggered.connect(partial(self.apply_virtual_library, library='')) a = m.addAction(self.current_search_action) if self.search_based_vl_name: a = m.addAction( self.checked if db.data.get_base_restriction_name().startswith('*') else self.empty, self.search_based_vl_name) a.triggered.connect(partial(self.apply_virtual_library, library=self.search_based_vl_name)) m.addSeparator() for vl in sorted(virt_libs.keys(), key=sort_key): is_current = vl == current_lib a = m.addAction(self.checked if is_current else self.empty, vl.replace('&', '&&')) if is_current: a.triggered.connect(self.apply_virtual_library) else: a.triggered.connect(partial(self.apply_virtual_library, library=vl)) def virtual_library_menu_about_to_show(self): self.build_virtual_library_menu(self.virtual_library_menu) def rebuild_vl_tabs(self): self.vl_tabs.rebuild() def apply_virtual_library(self, library=None, update_tabs=True): db = self.library_view.model().db virt_libs = db.new_api.pref('virtual_libraries', {}) if not library: db.data.set_base_restriction('') db.data.set_base_restriction_name('') elif library == '*': if not self.search.current_text: error_dialog(self, _('No search'), _('There is no current search to use'), show=True) return txt = _build_full_search_string(self) try: db.data.search_getting_ids('', txt, use_virtual_library=False) except ParseException as e: error_dialog(self, _('Invalid search'), _('The search in the search box is not valid'), det_msg=e.msg, show=True) return self.search_based_vl = txt db.data.set_base_restriction(txt) self.search_based_vl_name = self._trim_restriction_name('*' + txt) db.data.set_base_restriction_name(self.search_based_vl_name) elif library == self.search_based_vl_name: db.data.set_base_restriction(self.search_based_vl) db.data.set_base_restriction_name(self.search_based_vl_name) elif library in virt_libs: db.data.set_base_restriction(virt_libs[library]) db.data.set_base_restriction_name(library) self.virtual_library.setToolTip(self.virtual_library_tooltip + '\n' + db.data.get_base_restriction()) self._apply_search_restriction(db.data.get_search_restriction(), db.data.get_search_restriction_name()) if update_tabs: self.vl_tabs.update_current() def build_virtual_library_list(self, menu, handler): db = self.library_view.model().db virt_libs = db.new_api.pref('virtual_libraries', {}) menu.clear() menu.setIcon(self.empty) def add_action(name, search): a = menu.addAction(name.replace('&', '&&')) a.triggered.connect(partial(handler, name=name)) a.setIcon(self.empty) libs = sorted(virt_libs.keys(), key=sort_key) if libs: menu.setEnabled(True) for n in libs: add_action(n, virt_libs[n]) else: menu.setEnabled(False) def remove_vl_triggered(self, name=None): if not confirm( _('Are you sure you want to remove the Virtual library <b>{0}</b>?').format(name), 'confirm_vl_removal', parent=self): return self._remove_vl(name, reapply=True) self.library_view.model().db.refresh() def choose_vl_triggerred(self): from calibre.gui2.tweak_book.widgets import QuickOpen, emphasis_style db = self.library_view.model().db virt_libs = db.new_api.pref('virtual_libraries', {}) if not virt_libs: return error_dialog(self, _('No Virtual libraries'), _( 'No Virtual libraries present, create some first'), show=True) example = '<pre>{0}S{1}ome {0}B{1}ook {0}C{1}ollection</pre>'.format( '<span style="%s">' % emphasis_style(), '</span>') chars = '<pre style="%s">sbc</pre>' % emphasis_style() help_text = _('''<p>Quickly choose a Virtual library by typing in just a few characters from the library name into the field above. For example, if want to choose the VL: {example} Simply type in the characters: {chars} and press Enter.''').format(example=example, chars=chars) d = QuickOpen( sorted(virt_libs.keys(), key=sort_key), parent=self, title=_('Choose Virtual library'), name='vl-open', level1=' ', help_text=help_text) if d.exec() == QDialog.DialogCode.Accepted and d.selected_result: self.apply_virtual_library(library=d.selected_result) def _remove_vl(self, name, reapply=True): db = self.library_view.model().db virt_libs = db.new_api.pref('virtual_libraries', {}) virt_libs.pop(name, None) db.new_api.set_pref('virtual_libraries', virt_libs) if reapply and db.data.get_base_restriction_name() == name: self.apply_virtual_library('') self.rebuild_vl_tabs() def _trim_restriction_name(self, name): return name[0:MAX_VIRTUAL_LIBRARY_NAME_LENGTH].strip() def build_search_restriction_list(self): self.search_restriction_list_built = True from calibre.gui2.ui import get_gui m = self.ar_menu m.clear() current_restriction_text = None if self.search_restriction.count() > 1: txt = str(self.search_restriction.itemText(2)) if txt.startswith('*'): current_restriction_text = txt self.search_restriction.clear() current_restriction = self.library_view.model().db.data.get_search_restriction_name() m.setIcon(self.checked if current_restriction else self.empty) def add_action(txt, index): self.search_restriction.addItem(txt) txt = self._trim_restriction_name(txt) if txt == current_restriction: a = m.addAction(self.checked, txt if txt else self.no_restriction) else: a = m.addAction(self.empty, txt if txt else self.no_restriction) a.triggered.connect(partial(self.search_restriction_triggered, action=a, index=index)) add_action('', 0) add_action(_('*current search'), 1) dex = 2 if current_restriction_text: add_action(current_restriction_text, 2) dex += 1 for n in sorted(get_gui().current_db.saved_search_names(), key=sort_key): add_action(n, dex) dex += 1 def search_restriction_triggered(self, action=None, index=None): self.search_restriction.setCurrentIndex(index) self.apply_search_restriction(index) def apply_named_search_restriction(self, name=None): if not self.search_restriction_list_built: self.build_search_restriction_list() if not name: r = 0 else: r = self.search_restriction.findText(name) if r < 0: r = 0 self.search_restriction.setCurrentIndex(r) self.apply_search_restriction(r) def apply_text_search_restriction(self, search): if not self.search_restriction_list_built: self.build_search_restriction_list() search = str(search) if not search: self.search_restriction.setCurrentIndex(0) self._apply_search_restriction('', '') else: s = '*' + search if self.search_restriction.count() > 1: txt = str(self.search_restriction.itemText(2)) if txt.startswith('*'): self.search_restriction.setItemText(2, s) else: self.search_restriction.insertItem(2, s) else: self.search_restriction.insertItem(2, s) self.search_restriction.setCurrentIndex(2) self._apply_search_restriction(search, self._trim_restriction_name(s)) def apply_search_restriction(self, i): if not self.search_restriction_list_built: self.build_search_restriction_list() if i == 1: self.apply_text_search_restriction(str(self.search.currentText())) elif i == 2 and str(self.search_restriction.currentText()).startswith('*'): self.apply_text_search_restriction( str(self.search_restriction.currentText())[1:]) else: r = str(self.search_restriction.currentText()) if r is not None and r != '': restriction = 'search:"%s"'%(r) else: restriction = '' self._apply_search_restriction(restriction, r) def clear_additional_restriction(self): self.search_restriction.setCurrentIndex(0) self._apply_search_restriction('', '') def _apply_search_restriction(self, restriction, name): self.saved_search.clear() # The order below is important. Set the restriction, force a '' search # to apply it, reset the tag browser to take it into account, then set # the book count. self.library_view.model().db.data.set_search_restriction(restriction) self.library_view.model().db.data.set_search_restriction_name(name) self.search.clear(emit_search=True) self.tags_view.recount() self.set_number_of_books_shown() self.current_view().setFocus(Qt.FocusReason.OtherFocusReason) self.set_window_title() v = self.current_view() if not v.currentIndex().isValid(): v.set_current_row() if not v.refresh_book_details(): self.book_details.reset_info() def set_number_of_books_shown(self): db = self.library_view.model().db if self.current_view() == self.library_view and db is not None and \ db.data.search_restriction_applied(): restrictions = [x for x in (db.data.get_base_restriction_name(), db.data.get_search_restriction_name()) if x] t = ' :: '.join(restrictions) if len(t) > 20: t = t[:19] + '…' self.clear_vl.setVisible(True) self.clear_vl.setVisible(not gprefs['show_vl_tabs']) else: # No restriction or not library view t = '' self.clear_vl.setVisible(False) self.clear_vl.setText(t.replace('&', '&&'))
class SearchRestrictionMixin(object): no_restriction = _('<None>') def __init__(self, *args, **kwargs): pass def init_search_restirction_mixin(self): self.checked = QIcon(I('ok.png')) self.empty = QIcon(I('blank.png')) self.current_search_action = QAction(self.empty, _('*current search'), self) self.current_search_action.triggered.connect(partial(self.apply_virtual_library, library='*')) self.addAction(self.current_search_action) self.keyboard.register_shortcut( 'vl-from-current-search', _('Virtual library from current search'), description=_( 'Create a temporary Virtual library from the current search'), group=_('Miscellaneous'), default_keys=('Ctrl+*',), action=self.current_search_action) self.search_based_vl_name = None self.search_based_vl = None self.virtual_library_menu = QMenu() self.virtual_library.clicked.connect(self.virtual_library_clicked) self.clear_vl.clicked.connect(lambda x: (self.apply_virtual_library(), self.clear_additional_restriction())) self.virtual_library_tooltip = \ _('Use a "virtual library" to show only a subset of the books present in this library') self.virtual_library.setToolTip(self.virtual_library_tooltip) self.search_restriction = ComboBoxWithHelp(self) self.search_restriction.setVisible(False) self.search_count.setText(_("(all books)")) self.ar_menu = QMenu(_('Additional restriction')) self.edit_menu = QMenu(_('Edit Virtual Library')) self.rm_menu = QMenu(_('Remove Virtual Library')) self.search_restriction_list_built = False def add_virtual_library(self, db, name, search): virt_libs = db.prefs.get('virtual_libraries', {}) virt_libs[name] = search db.prefs.set('virtual_libraries', virt_libs) def do_create_edit(self, name=None): db = self.library_view.model().db virt_libs = db.prefs.get('virtual_libraries', {}) cd = CreateVirtualLibrary(self, virt_libs.keys(), editing=name) if cd.exec_() == cd.Accepted: if name: self._remove_vl(name, reapply=False) self.add_virtual_library(db, cd.library_name, cd.library_search) if not name or name == db.data.get_base_restriction_name(): self.apply_virtual_library(cd.library_name) self.rebuild_vl_tabs() def virtual_library_clicked(self): m = self.virtual_library_menu m.clear() a = m.addAction(_('Create Virtual Library')) a.triggered.connect(partial(self.do_create_edit, name=None)) a = self.edit_menu self.build_virtual_library_list(a, self.do_create_edit) m.addMenu(a) a = self.rm_menu self.build_virtual_library_list(a, self.remove_vl_triggered) m.addMenu(a) if gprefs['show_vl_tabs']: m.addAction(_('Hide virtual library tabs'), self.vl_tabs.disable_bar) else: m.addAction(_('Show virtual libraries as tabs'), self.vl_tabs.enable_bar) m.addSeparator() db = self.library_view.model().db a = self.ar_menu a.clear() a.setIcon(self.checked if db.data.get_search_restriction_name() else self.empty) self.build_search_restriction_list() m.addMenu(a) m.addSeparator() current_lib = db.data.get_base_restriction_name() if current_lib == '': a = m.addAction(self.checked, self.no_restriction) else: a = m.addAction(self.empty, self.no_restriction) a.triggered.connect(partial(self.apply_virtual_library, library='')) a = m.addAction(self.current_search_action) if self.search_based_vl_name: a = m.addAction( self.checked if db.data.get_base_restriction_name().startswith('*') else self.empty, self.search_based_vl_name) a.triggered.connect(partial(self.apply_virtual_library, library=self.search_based_vl_name)) m.addSeparator() virt_libs = db.prefs.get('virtual_libraries', {}) for vl in sorted(virt_libs.keys(), key=sort_key): a = m.addAction(self.checked if vl == current_lib else self.empty, vl.replace('&', '&&')) a.triggered.connect(partial(self.apply_virtual_library, library=vl)) p = QPoint(0, self.virtual_library.height()) self.virtual_library_menu.popup(self.virtual_library.mapToGlobal(p)) def rebuild_vl_tabs(self): self.vl_tabs.rebuild() def apply_virtual_library(self, library=None, update_tabs=True): db = self.library_view.model().db virt_libs = db.prefs.get('virtual_libraries', {}) if not library: db.data.set_base_restriction('') db.data.set_base_restriction_name('') elif library == '*': if not self.search.current_text: error_dialog(self, _('No search'), _('There is no current search to use'), show=True) return txt = _build_full_search_string(self) try: db.data.search_getting_ids('', txt, use_virtual_library=False) except ParseException as e: error_dialog(self, _('Invalid search'), _('The search in the search box is not valid'), det_msg=e.msg, show=True) return self.search_based_vl = txt db.data.set_base_restriction(txt) self.search_based_vl_name = self._trim_restriction_name('*' + txt) db.data.set_base_restriction_name(self.search_based_vl_name) elif library == self.search_based_vl_name: db.data.set_base_restriction(self.search_based_vl) db.data.set_base_restriction_name(self.search_based_vl_name) elif library in virt_libs: db.data.set_base_restriction(virt_libs[library]) db.data.set_base_restriction_name(library) self.virtual_library.setToolTip(self.virtual_library_tooltip + '\n' + db.data.get_base_restriction()) self._apply_search_restriction(db.data.get_search_restriction(), db.data.get_search_restriction_name()) if update_tabs: self.vl_tabs.update_current() def build_virtual_library_list(self, menu, handler): db = self.library_view.model().db virt_libs = db.prefs.get('virtual_libraries', {}) menu.clear() menu.setIcon(self.empty) def add_action(name, search): a = menu.addAction(name.replace('&', '&&')) a.triggered.connect(partial(handler, name=name)) a.setIcon(self.empty) libs = sorted(virt_libs.keys(), key=sort_key) if libs: menu.setEnabled(True) for n in libs: add_action(n, virt_libs[n]) else: menu.setEnabled(False) def remove_vl_triggered(self, name=None): if not confirm( _('Are you sure you want to remove the virtual library <b>{0}</b>?').format(name), 'confirm_vl_removal', parent=self): return self._remove_vl(name, reapply=True) def _remove_vl(self, name, reapply=True): db = self.library_view.model().db virt_libs = db.prefs.get('virtual_libraries', {}) virt_libs.pop(name, None) db.prefs.set('virtual_libraries', virt_libs) if reapply and db.data.get_base_restriction_name() == name: self.apply_virtual_library('') self.rebuild_vl_tabs() def _trim_restriction_name(self, name): return name[0:MAX_VIRTUAL_LIBRARY_NAME_LENGTH].strip() def build_search_restriction_list(self): self.search_restriction_list_built = True from calibre.gui2.ui import get_gui m = self.ar_menu m.clear() current_restriction_text = None if self.search_restriction.count() > 1: txt = unicode(self.search_restriction.itemText(2)) if txt.startswith('*'): current_restriction_text = txt self.search_restriction.clear() current_restriction = self.library_view.model().db.data.get_search_restriction_name() m.setIcon(self.checked if current_restriction else self.empty) def add_action(txt, index): self.search_restriction.addItem(txt) txt = self._trim_restriction_name(txt) if txt == current_restriction: a = m.addAction(self.checked, txt if txt else self.no_restriction) else: a = m.addAction(self.empty, txt if txt else self.no_restriction) a.triggered.connect(partial(self.search_restriction_triggered, action=a, index=index)) add_action('', 0) add_action(_('*current search'), 1) dex = 2 if current_restriction_text: add_action(current_restriction_text, 2) dex += 1 for n in sorted(get_gui().current_db.saved_search_names(), key=sort_key): add_action(n, dex) dex += 1 def search_restriction_triggered(self, action=None, index=None): self.search_restriction.setCurrentIndex(index) self.apply_search_restriction(index) def apply_named_search_restriction(self, name): if not self.search_restriction_list_built: self.build_search_restriction_list() if not name: r = 0 else: r = self.search_restriction.findText(name) if r < 0: r = 0 self.search_restriction.setCurrentIndex(r) self.apply_search_restriction(r) def apply_text_search_restriction(self, search): if not self.search_restriction_list_built: self.build_search_restriction_list() search = unicode(search) if not search: self.search_restriction.setCurrentIndex(0) self._apply_search_restriction('', '') else: s = '*' + search if self.search_restriction.count() > 1: txt = unicode(self.search_restriction.itemText(2)) if txt.startswith('*'): self.search_restriction.setItemText(2, s) else: self.search_restriction.insertItem(2, s) else: self.search_restriction.insertItem(2, s) self.search_restriction.setCurrentIndex(2) self._apply_search_restriction(search, self._trim_restriction_name(s)) def apply_search_restriction(self, i): if not self.search_restriction_list_built: self.build_search_restriction_list() if i == 1: self.apply_text_search_restriction(unicode(self.search.currentText())) elif i == 2 and unicode(self.search_restriction.currentText()).startswith('*'): self.apply_text_search_restriction( unicode(self.search_restriction.currentText())[1:]) else: r = unicode(self.search_restriction.currentText()) if r is not None and r != '': restriction = 'search:"%s"'%(r) else: restriction = '' self._apply_search_restriction(restriction, r) def clear_additional_restriction(self): self._apply_search_restriction('', '') def _apply_search_restriction(self, restriction, name): self.saved_search.clear() # The order below is important. Set the restriction, force a '' search # to apply it, reset the tag browser to take it into account, then set # the book count. self.library_view.model().db.data.set_search_restriction(restriction) self.library_view.model().db.data.set_search_restriction_name(name) self.search.clear(emit_search=True) self.tags_view.recount() self.set_number_of_books_shown() self.current_view().setFocus(Qt.OtherFocusReason) self.set_window_title() v = self.current_view() if not v.currentIndex().isValid(): v.set_current_row() if not v.refresh_book_details(): self.book_details.reset_info() def set_number_of_books_shown(self): db = self.library_view.model().db if self.current_view() == self.library_view and db is not None and \ db.data.search_restriction_applied(): restrictions = [x for x in (db.data.get_base_restriction_name(), db.data.get_search_restriction_name()) if x] t = ' :: '.join(restrictions) if len(t) > 20: t = t[:19] + u'…' self.search_count.setStyleSheet( 'QLabel { border-radius: 6px; background-color: %s }' % tweaks['highlight_virtual_library']) self.clear_vl.setVisible(True) self.search_count.setVisible(not gprefs['show_vl_tabs']) else: # No restriction or not library view t = '' self.search_count.setStyleSheet( 'QLabel { background-color: transparent; }') self.clear_vl.setVisible(False) self.search_count.setVisible(False) self.search_count.setText(t)
class SearchRestrictionMixin(object): no_restriction = _('<None>') def __init__(self): self.checked = QIcon(I('ok.png')) self.empty = QIcon(I('blank.png')) self.search_based_vl_name = None self.search_based_vl = None self.virtual_library_menu = QMenu() self.virtual_library.clicked.connect(self.virtual_library_clicked) self.virtual_library_tooltip = \ _('Books display will show only those books matching the search') self.virtual_library.setToolTip(self.virtual_library_tooltip) self.search_restriction = ComboBoxWithHelp(self) self.search_restriction.setVisible(False) self.search_count.setText(_("(all books)")) self.ar_menu = QMenu(_('Additional restriction')) self.edit_menu = QMenu(_('Edit Virtual Library')) self.rm_menu = QMenu(_('Remove Virtual Library')) def add_virtual_library(self, db, name, search): virt_libs = db.prefs.get('virtual_libraries', {}) virt_libs[name] = search db.prefs.set('virtual_libraries', virt_libs) def do_create_edit(self, name=None): db = self.library_view.model().db virt_libs = db.prefs.get('virtual_libraries', {}) cd = CreateVirtualLibrary(self, virt_libs.keys(), editing=name) if cd.exec_() == cd.Accepted: if name: self._remove_vl(name, reapply=False) self.add_virtual_library(db, cd.library_name, cd.library_search) if not name or name == db.data.get_base_restriction_name(): self.apply_virtual_library(cd.library_name) def virtual_library_clicked(self): m = self.virtual_library_menu m.clear() a = m.addAction(_('Create Virtual Library')) a.triggered.connect(partial(self.do_create_edit, name=None)) a = self.edit_menu self.build_virtual_library_list(a, self.do_create_edit) m.addMenu(a) a = self.rm_menu self.build_virtual_library_list(a, self.remove_vl_triggered) m.addMenu(a) m.addSeparator() db = self.library_view.model().db a = self.ar_menu a.clear() a.setIcon(self.checked if db.data.get_search_restriction_name() else self.empty) self.build_search_restriction_list() m.addMenu(a) m.addSeparator() current_lib = db.data.get_base_restriction_name() if current_lib == '': a = m.addAction(self.checked, self.no_restriction) else: a = m.addAction(self.empty, self.no_restriction) a.triggered.connect(partial(self.apply_virtual_library, library='')) a = m.addAction(self.empty, _('*current search')) a.triggered.connect(partial(self.apply_virtual_library, library='*')) if self.search_based_vl_name: a = m.addAction( self.checked if db.data.get_base_restriction_name().startswith('*') else self.empty, self.search_based_vl_name) a.triggered.connect(partial(self.apply_virtual_library, library=self.search_based_vl_name)) m.addSeparator() virt_libs = db.prefs.get('virtual_libraries', {}) for vl in sorted(virt_libs.keys(), key=sort_key): a = m.addAction(self.checked if vl == current_lib else self.empty, vl) a.triggered.connect(partial(self.apply_virtual_library, library=vl)) p = QPoint(0, self.virtual_library.height()) self.virtual_library_menu.popup(self.virtual_library.mapToGlobal(p)) def apply_virtual_library(self, library=None): db = self.library_view.model().db virt_libs = db.prefs.get('virtual_libraries', {}) if not library: db.data.set_base_restriction('') db.data.set_base_restriction_name('') elif library == '*': if not self.search.current_text: error_dialog(self, _('No search'), _('There is no current search to use'), show=True) return txt = _build_full_search_string(self) try: db.data.search_getting_ids('', txt, use_virtual_library=False) except ParseException as e: error_dialog(self, _('Invalid search'), _('The search in the search box is not valid'), det_msg=e.msg, show=True) return self.search_based_vl = txt db.data.set_base_restriction(txt) self.search_based_vl_name = self._trim_restriction_name('*' + txt) db.data.set_base_restriction_name(self.search_based_vl_name) elif library == self.search_based_vl_name: db.data.set_base_restriction(self.search_based_vl) db.data.set_base_restriction_name(self.search_based_vl_name) elif library in virt_libs: db.data.set_base_restriction(virt_libs[library]) db.data.set_base_restriction_name(library) self.virtual_library.setToolTip(self.virtual_library_tooltip + '\n' + db.data.get_base_restriction()) self._apply_search_restriction(db.data.get_search_restriction(), db.data.get_search_restriction_name()) def build_virtual_library_list(self, menu, handler): db = self.library_view.model().db virt_libs = db.prefs.get('virtual_libraries', {}) menu.clear() menu.setIcon(self.empty) def add_action(name, search): a = menu.addAction(name) a.triggered.connect(partial(handler, name=name)) a.setIcon(self.empty) libs = sorted(virt_libs.keys(), key=sort_key) if libs: menu.setEnabled(True) for n in libs: add_action(n, virt_libs[n]) else: menu.setEnabled(False) def remove_vl_triggered(self, name=None): if not question_dialog(self, _('Are you sure?'), _('Are you sure you want to remove ' 'the virtual library {0}').format(name), default_yes=False): return self._remove_vl(name, reapply=True) def _remove_vl(self, name, reapply=True): db = self.library_view.model().db virt_libs = db.prefs.get('virtual_libraries', {}) virt_libs.pop(name, None) db.prefs.set('virtual_libraries', virt_libs) if reapply and db.data.get_base_restriction_name() == name: self.apply_virtual_library('') def _trim_restriction_name(self, name): return name[0:MAX_VIRTUAL_LIBRARY_NAME_LENGTH].strip() def build_search_restriction_list(self): m = self.ar_menu m.clear() current_restriction_text = None if self.search_restriction.count() > 1: txt = unicode(self.search_restriction.itemText(2)) if txt.startswith('*'): current_restriction_text = txt self.search_restriction.clear() current_restriction = self.library_view.model().db.data.get_search_restriction_name() m.setIcon(self.checked if current_restriction else self.empty) def add_action(txt, index): self.search_restriction.addItem(txt) txt = self._trim_restriction_name(txt) if txt == current_restriction: a = m.addAction(self.checked, txt if txt else self.no_restriction) else: a = m.addAction(self.empty, txt if txt else self.no_restriction) a.triggered.connect(partial(self.search_restriction_triggered, action=a, index=index)) add_action('', 0) add_action(_('*current search'), 1) dex = 2 if current_restriction_text: add_action(current_restriction_text, 2) dex += 1 for n in sorted(saved_searches().names(), key=sort_key): add_action(n, dex) dex += 1 def search_restriction_triggered(self, action=None, index=None): self.search_restriction.setCurrentIndex(index) self.apply_search_restriction(index) def apply_named_search_restriction(self, name): if not name: r = 0 else: r = self.search_restriction.findText(name) if r < 0: r = 0 self.search_restriction.setCurrentIndex(r) self.apply_search_restriction(r) def apply_text_search_restriction(self, search): search = unicode(search) if not search: self.search_restriction.setCurrentIndex(0) self._apply_search_restriction('', '') else: s = '*' + search if self.search_restriction.count() > 1: txt = unicode(self.search_restriction.itemText(2)) if txt.startswith('*'): self.search_restriction.setItemText(2, s) else: self.search_restriction.insertItem(2, s) else: self.search_restriction.insertItem(2, s) self.search_restriction.setCurrentIndex(2) self._apply_search_restriction(search, self._trim_restriction_name(s)) def apply_search_restriction(self, i): if i == 1: self.apply_text_search_restriction(unicode(self.search.currentText())) elif i == 2 and unicode(self.search_restriction.currentText()).startswith('*'): self.apply_text_search_restriction( unicode(self.search_restriction.currentText())[1:]) else: r = unicode(self.search_restriction.currentText()) if r is not None and r != '': restriction = 'search:"%s"'%(r) else: restriction = '' self._apply_search_restriction(restriction, r) def _apply_search_restriction(self, restriction, name): self.saved_search.clear() # The order below is important. Set the restriction, force a '' search # to apply it, reset the tag browser to take it into account, then set # the book count. self.library_view.model().db.data.set_search_restriction(restriction) self.library_view.model().db.data.set_search_restriction_name(name) self.search.clear(emit_search=True) self.tags_view.recount() self.set_number_of_books_shown() self.current_view().setFocus(Qt.OtherFocusReason) self.set_window_title() def set_number_of_books_shown(self): db = self.library_view.model().db if self.current_view() == self.library_view and db is not None and \ db.data.search_restriction_applied(): rows = self.current_view().row_count() rbc = max(rows, db.data.get_search_restriction_book_count()) t = _("({0} of {1})").format(rows, rbc) self.search_count.setStyleSheet( 'QLabel { border-radius: 8px; background-color: yellow; }') else: # No restriction or not library view if not self.search.in_a_search(): t = _("(all books)") else: t = _("({0} of all)").format(self.current_view().row_count()) self.search_count.setStyleSheet( 'QLabel { background-color: transparent; }') self.search_count.setText(t)
class SearchRestrictionMixin(object): no_restriction = _('<None>') def __init__(self, *args, **kwargs): pass def init_search_restriction_mixin(self): self.checked = QIcon(I('ok.png')) self.empty = QIcon(I('blank.png')) self.current_search_action = QAction(self.empty, _('*current search'), self) self.current_search_action.triggered.connect( partial(self.apply_virtual_library, library='*')) self.addAction(self.current_search_action) self.keyboard.register_shortcut( 'vl-from-current-search', _('Virtual library from current search'), description=_( 'Create a temporary Virtual library from the current search'), group=_('Miscellaneous'), default_keys=('Ctrl+*', ), action=self.current_search_action) self.search_based_vl_name = None self.search_based_vl = None self.virtual_library_menu = QMenu() self.virtual_library.clicked.connect(self.virtual_library_clicked) self.clear_vl.clicked.connect(lambda x: (self.apply_virtual_library( ), self.clear_additional_restriction())) self.virtual_library_tooltip = \ _('Use a "virtual library" to show only a subset of the books present in this library') self.virtual_library.setToolTip(self.virtual_library_tooltip) self.search_restriction = ComboBoxWithHelp(self) self.search_restriction.setVisible(False) self.clear_vl.setText(_("(all books)")) self.ar_menu = QMenu(_('Additional restriction')) self.edit_menu = QMenu(_('Edit Virtual library')) self.rm_menu = QMenu(_('Remove Virtual library')) self.search_restriction_list_built = False def add_virtual_library(self, db, name, search): virt_libs = db.prefs.get('virtual_libraries', {}) virt_libs[name] = search db.new_api.set_pref('virtual_libraries', virt_libs) def do_create_edit(self, name=None): db = self.library_view.model().db virt_libs = db.prefs.get('virtual_libraries', {}) cd = CreateVirtualLibrary(self, virt_libs.keys(), editing=name) if cd.exec_() == cd.Accepted: if name: self._remove_vl(name, reapply=False) self.add_virtual_library(db, cd.library_name, cd.library_search) if not name or name == db.data.get_base_restriction_name(): self.apply_virtual_library(cd.library_name) self.rebuild_vl_tabs() def virtual_library_clicked(self): m = self.virtual_library_menu m.clear() a = m.addAction(_('Create Virtual library')) a.triggered.connect(partial(self.do_create_edit, name=None)) a = self.edit_menu self.build_virtual_library_list(a, self.do_create_edit) m.addMenu(a) a = self.rm_menu self.build_virtual_library_list(a, self.remove_vl_triggered) m.addMenu(a) if gprefs['show_vl_tabs']: m.addAction(_('Hide virtual library tabs'), self.vl_tabs.disable_bar) else: m.addAction(_('Show virtual libraries as tabs'), self.vl_tabs.enable_bar) m.addSeparator() db = self.library_view.model().db a = self.ar_menu a.clear() a.setIcon(self.checked if db.data.get_search_restriction_name( ) else self.empty) self.build_search_restriction_list() m.addMenu(a) m.addSeparator() current_lib = db.data.get_base_restriction_name() if current_lib == '': a = m.addAction(self.checked, self.no_restriction) else: a = m.addAction(self.empty, self.no_restriction) a.triggered.connect(partial(self.apply_virtual_library, library='')) a = m.addAction(self.current_search_action) if self.search_based_vl_name: a = m.addAction( self.checked if db.data.get_base_restriction_name().startswith('*') else self.empty, self.search_based_vl_name) a.triggered.connect( partial(self.apply_virtual_library, library=self.search_based_vl_name)) m.addSeparator() virt_libs = db.prefs.get('virtual_libraries', {}) for vl in sorted(virt_libs.keys(), key=sort_key): a = m.addAction(self.checked if vl == current_lib else self.empty, vl.replace('&', '&&')) a.triggered.connect(partial(self.apply_virtual_library, library=vl)) p = QPoint(0, self.virtual_library.height()) self.virtual_library_menu.popup(self.virtual_library.mapToGlobal(p)) def rebuild_vl_tabs(self): self.vl_tabs.rebuild() def apply_virtual_library(self, library=None, update_tabs=True): db = self.library_view.model().db virt_libs = db.prefs.get('virtual_libraries', {}) if not library: db.data.set_base_restriction('') db.data.set_base_restriction_name('') elif library == '*': if not self.search.current_text: error_dialog(self, _('No search'), _('There is no current search to use'), show=True) return txt = _build_full_search_string(self) try: db.data.search_getting_ids('', txt, use_virtual_library=False) except ParseException as e: error_dialog(self, _('Invalid search'), _('The search in the search box is not valid'), det_msg=e.msg, show=True) return self.search_based_vl = txt db.data.set_base_restriction(txt) self.search_based_vl_name = self._trim_restriction_name('*' + txt) db.data.set_base_restriction_name(self.search_based_vl_name) elif library == self.search_based_vl_name: db.data.set_base_restriction(self.search_based_vl) db.data.set_base_restriction_name(self.search_based_vl_name) elif library in virt_libs: db.data.set_base_restriction(virt_libs[library]) db.data.set_base_restriction_name(library) self.virtual_library.setToolTip(self.virtual_library_tooltip + '\n' + db.data.get_base_restriction()) self._apply_search_restriction(db.data.get_search_restriction(), db.data.get_search_restriction_name()) if update_tabs: self.vl_tabs.update_current() def build_virtual_library_list(self, menu, handler): db = self.library_view.model().db virt_libs = db.prefs.get('virtual_libraries', {}) menu.clear() menu.setIcon(self.empty) def add_action(name, search): a = menu.addAction(name.replace('&', '&&')) a.triggered.connect(partial(handler, name=name)) a.setIcon(self.empty) libs = sorted(virt_libs.keys(), key=sort_key) if libs: menu.setEnabled(True) for n in libs: add_action(n, virt_libs[n]) else: menu.setEnabled(False) def remove_vl_triggered(self, name=None): if not confirm(_( 'Are you sure you want to remove the virtual library <b>{0}</b>?' ).format(name), 'confirm_vl_removal', parent=self): return self._remove_vl(name, reapply=True) def _remove_vl(self, name, reapply=True): db = self.library_view.model().db virt_libs = db.prefs.get('virtual_libraries', {}) virt_libs.pop(name, None) db.new_api.set_pref('virtual_libraries', virt_libs) if reapply and db.data.get_base_restriction_name() == name: self.apply_virtual_library('') self.rebuild_vl_tabs() def _trim_restriction_name(self, name): return name[0:MAX_VIRTUAL_LIBRARY_NAME_LENGTH].strip() def build_search_restriction_list(self): self.search_restriction_list_built = True from calibre.gui2.ui import get_gui m = self.ar_menu m.clear() current_restriction_text = None if self.search_restriction.count() > 1: txt = unicode(self.search_restriction.itemText(2)) if txt.startswith('*'): current_restriction_text = txt self.search_restriction.clear() current_restriction = self.library_view.model( ).db.data.get_search_restriction_name() m.setIcon(self.checked if current_restriction else self.empty) def add_action(txt, index): self.search_restriction.addItem(txt) txt = self._trim_restriction_name(txt) if txt == current_restriction: a = m.addAction(self.checked, txt if txt else self.no_restriction) else: a = m.addAction(self.empty, txt if txt else self.no_restriction) a.triggered.connect( partial(self.search_restriction_triggered, action=a, index=index)) add_action('', 0) add_action(_('*current search'), 1) dex = 2 if current_restriction_text: add_action(current_restriction_text, 2) dex += 1 for n in sorted(get_gui().current_db.saved_search_names(), key=sort_key): add_action(n, dex) dex += 1 def search_restriction_triggered(self, action=None, index=None): self.search_restriction.setCurrentIndex(index) self.apply_search_restriction(index) def apply_named_search_restriction(self, name): if not self.search_restriction_list_built: self.build_search_restriction_list() if not name: r = 0 else: r = self.search_restriction.findText(name) if r < 0: r = 0 self.search_restriction.setCurrentIndex(r) self.apply_search_restriction(r) def apply_text_search_restriction(self, search): if not self.search_restriction_list_built: self.build_search_restriction_list() search = unicode(search) if not search: self.search_restriction.setCurrentIndex(0) self._apply_search_restriction('', '') else: s = '*' + search if self.search_restriction.count() > 1: txt = unicode(self.search_restriction.itemText(2)) if txt.startswith('*'): self.search_restriction.setItemText(2, s) else: self.search_restriction.insertItem(2, s) else: self.search_restriction.insertItem(2, s) self.search_restriction.setCurrentIndex(2) self._apply_search_restriction(search, self._trim_restriction_name(s)) def apply_search_restriction(self, i): if not self.search_restriction_list_built: self.build_search_restriction_list() if i == 1: self.apply_text_search_restriction( unicode(self.search.currentText())) elif i == 2 and unicode( self.search_restriction.currentText()).startswith('*'): self.apply_text_search_restriction( unicode(self.search_restriction.currentText())[1:]) else: r = unicode(self.search_restriction.currentText()) if r is not None and r != '': restriction = 'search:"%s"' % (r) else: restriction = '' self._apply_search_restriction(restriction, r) def clear_additional_restriction(self): self.search_restriction.setCurrentIndex(0) self._apply_search_restriction('', '') def _apply_search_restriction(self, restriction, name): self.saved_search.clear() # The order below is important. Set the restriction, force a '' search # to apply it, reset the tag browser to take it into account, then set # the book count. self.library_view.model().db.data.set_search_restriction(restriction) self.library_view.model().db.data.set_search_restriction_name(name) self.search.clear(emit_search=True) self.tags_view.recount() self.set_number_of_books_shown() self.current_view().setFocus(Qt.OtherFocusReason) self.set_window_title() v = self.current_view() if not v.currentIndex().isValid(): v.set_current_row() if not v.refresh_book_details(): self.book_details.reset_info() def set_number_of_books_shown(self): db = self.library_view.model().db if self.current_view() == self.library_view and db is not None and \ db.data.search_restriction_applied(): restrictions = [ x for x in (db.data.get_base_restriction_name(), db.data.get_search_restriction_name()) if x ] t = ' :: '.join(restrictions) if len(t) > 20: t = t[:19] + u'…' self.clear_vl.setVisible(True) self.clear_vl.setVisible(not gprefs['show_vl_tabs']) else: # No restriction or not library view t = '' self.clear_vl.setVisible(False) self.clear_vl.setText(t.replace('&', '&&'))
class SearchRestrictionMixin(object): no_restriction = _("<None>") def __init__(self): self.checked = QIcon(I("ok.png")) self.empty = QIcon(I("blank.png")) self.search_based_vl_name = None self.search_based_vl = None self.virtual_library_menu = QMenu() self.virtual_library.clicked.connect(self.virtual_library_clicked) self.clear_vl.clicked.connect(lambda x: (self.apply_virtual_library(), self.clear_additional_restriction())) self.virtual_library_tooltip = _( 'Use a "virtual library" to show only a subset of the books present in this library' ) self.virtual_library.setToolTip(self.virtual_library_tooltip) self.search_restriction = ComboBoxWithHelp(self) self.search_restriction.setVisible(False) self.search_count.setText(_("(all books)")) self.ar_menu = QMenu(_("Additional restriction")) self.edit_menu = QMenu(_("Edit Virtual Library")) self.rm_menu = QMenu(_("Remove Virtual Library")) def add_virtual_library(self, db, name, search): virt_libs = db.prefs.get("virtual_libraries", {}) virt_libs[name] = search db.prefs.set("virtual_libraries", virt_libs) def do_create_edit(self, name=None): db = self.library_view.model().db virt_libs = db.prefs.get("virtual_libraries", {}) cd = CreateVirtualLibrary(self, virt_libs.keys(), editing=name) if cd.exec_() == cd.Accepted: if name: self._remove_vl(name, reapply=False) self.add_virtual_library(db, cd.library_name, cd.library_search) if not name or name == db.data.get_base_restriction_name(): self.apply_virtual_library(cd.library_name) def virtual_library_clicked(self): m = self.virtual_library_menu m.clear() a = m.addAction(_("Create Virtual Library")) a.triggered.connect(partial(self.do_create_edit, name=None)) a = self.edit_menu self.build_virtual_library_list(a, self.do_create_edit) m.addMenu(a) a = self.rm_menu self.build_virtual_library_list(a, self.remove_vl_triggered) m.addMenu(a) m.addSeparator() db = self.library_view.model().db a = self.ar_menu a.clear() a.setIcon(self.checked if db.data.get_search_restriction_name() else self.empty) self.build_search_restriction_list() m.addMenu(a) m.addSeparator() current_lib = db.data.get_base_restriction_name() if current_lib == "": a = m.addAction(self.checked, self.no_restriction) else: a = m.addAction(self.empty, self.no_restriction) a.triggered.connect(partial(self.apply_virtual_library, library="")) a = m.addAction(self.empty, _("*current search")) a.triggered.connect(partial(self.apply_virtual_library, library="*")) if self.search_based_vl_name: a = m.addAction( self.checked if db.data.get_base_restriction_name().startswith("*") else self.empty, self.search_based_vl_name, ) a.triggered.connect(partial(self.apply_virtual_library, library=self.search_based_vl_name)) m.addSeparator() virt_libs = db.prefs.get("virtual_libraries", {}) for vl in sorted(virt_libs.keys(), key=sort_key): a = m.addAction(self.checked if vl == current_lib else self.empty, vl) a.triggered.connect(partial(self.apply_virtual_library, library=vl)) p = QPoint(0, self.virtual_library.height()) self.virtual_library_menu.popup(self.virtual_library.mapToGlobal(p)) def apply_virtual_library(self, library=None): db = self.library_view.model().db virt_libs = db.prefs.get("virtual_libraries", {}) if not library: db.data.set_base_restriction("") db.data.set_base_restriction_name("") elif library == "*": if not self.search.current_text: error_dialog(self, _("No search"), _("There is no current search to use"), show=True) return txt = _build_full_search_string(self) try: db.data.search_getting_ids("", txt, use_virtual_library=False) except ParseException as e: error_dialog( self, _("Invalid search"), _("The search in the search box is not valid"), det_msg=e.msg, show=True ) return self.search_based_vl = txt db.data.set_base_restriction(txt) self.search_based_vl_name = self._trim_restriction_name("*" + txt) db.data.set_base_restriction_name(self.search_based_vl_name) elif library == self.search_based_vl_name: db.data.set_base_restriction(self.search_based_vl) db.data.set_base_restriction_name(self.search_based_vl_name) elif library in virt_libs: db.data.set_base_restriction(virt_libs[library]) db.data.set_base_restriction_name(library) self.virtual_library.setToolTip(self.virtual_library_tooltip + "\n" + db.data.get_base_restriction()) self._apply_search_restriction(db.data.get_search_restriction(), db.data.get_search_restriction_name()) def build_virtual_library_list(self, menu, handler): db = self.library_view.model().db virt_libs = db.prefs.get("virtual_libraries", {}) menu.clear() menu.setIcon(self.empty) def add_action(name, search): a = menu.addAction(name) a.triggered.connect(partial(handler, name=name)) a.setIcon(self.empty) libs = sorted(virt_libs.keys(), key=sort_key) if libs: menu.setEnabled(True) for n in libs: add_action(n, virt_libs[n]) else: menu.setEnabled(False) def remove_vl_triggered(self, name=None): if not confirm( _("Are you sure you want to remove the virtual library <b>{0}</b>?").format(name), "confirm_vl_removal", parent=self, ): return self._remove_vl(name, reapply=True) def _remove_vl(self, name, reapply=True): db = self.library_view.model().db virt_libs = db.prefs.get("virtual_libraries", {}) virt_libs.pop(name, None) db.prefs.set("virtual_libraries", virt_libs) if reapply and db.data.get_base_restriction_name() == name: self.apply_virtual_library("") def _trim_restriction_name(self, name): return name[0:MAX_VIRTUAL_LIBRARY_NAME_LENGTH].strip() def build_search_restriction_list(self): from calibre.gui2.ui import get_gui m = self.ar_menu m.clear() current_restriction_text = None if self.search_restriction.count() > 1: txt = unicode(self.search_restriction.itemText(2)) if txt.startswith("*"): current_restriction_text = txt self.search_restriction.clear() current_restriction = self.library_view.model().db.data.get_search_restriction_name() m.setIcon(self.checked if current_restriction else self.empty) def add_action(txt, index): self.search_restriction.addItem(txt) txt = self._trim_restriction_name(txt) if txt == current_restriction: a = m.addAction(self.checked, txt if txt else self.no_restriction) else: a = m.addAction(self.empty, txt if txt else self.no_restriction) a.triggered.connect(partial(self.search_restriction_triggered, action=a, index=index)) add_action("", 0) add_action(_("*current search"), 1) dex = 2 if current_restriction_text: add_action(current_restriction_text, 2) dex += 1 for n in sorted(get_gui().current_db.saved_search_names(), key=sort_key): add_action(n, dex) dex += 1 def search_restriction_triggered(self, action=None, index=None): self.search_restriction.setCurrentIndex(index) self.apply_search_restriction(index) def apply_named_search_restriction(self, name): if not name: r = 0 else: r = self.search_restriction.findText(name) if r < 0: r = 0 self.search_restriction.setCurrentIndex(r) self.apply_search_restriction(r) def apply_text_search_restriction(self, search): search = unicode(search) if not search: self.search_restriction.setCurrentIndex(0) self._apply_search_restriction("", "") else: s = "*" + search if self.search_restriction.count() > 1: txt = unicode(self.search_restriction.itemText(2)) if txt.startswith("*"): self.search_restriction.setItemText(2, s) else: self.search_restriction.insertItem(2, s) else: self.search_restriction.insertItem(2, s) self.search_restriction.setCurrentIndex(2) self._apply_search_restriction(search, self._trim_restriction_name(s)) def apply_search_restriction(self, i): if i == 1: self.apply_text_search_restriction(unicode(self.search.currentText())) elif i == 2 and unicode(self.search_restriction.currentText()).startswith("*"): self.apply_text_search_restriction(unicode(self.search_restriction.currentText())[1:]) else: r = unicode(self.search_restriction.currentText()) if r is not None and r != "": restriction = 'search:"%s"' % (r) else: restriction = "" self._apply_search_restriction(restriction, r) def clear_additional_restriction(self): self._apply_search_restriction("", "") def _apply_search_restriction(self, restriction, name): self.saved_search.clear() # The order below is important. Set the restriction, force a '' search # to apply it, reset the tag browser to take it into account, then set # the book count. self.library_view.model().db.data.set_search_restriction(restriction) self.library_view.model().db.data.set_search_restriction_name(name) self.search.clear(emit_search=True) self.tags_view.recount() self.set_number_of_books_shown() self.current_view().setFocus(Qt.OtherFocusReason) self.set_window_title() v = self.current_view() if not v.currentIndex().isValid(): v.set_current_row() v.refresh_book_details() def set_number_of_books_shown(self): db = self.library_view.model().db if self.current_view() == self.library_view and db is not None and db.data.search_restriction_applied(): restrictions = [ x for x in (db.data.get_base_restriction_name(), db.data.get_search_restriction_name()) if x ] t = " :: ".join(restrictions) if len(t) > 20: t = t[:19] + "…" self.search_count.setStyleSheet( "QLabel { border-radius: 6px; background-color: %s }" % tweaks["highlight_virtual_library"] ) self.clear_vl.setVisible(True) else: # No restriction or not library view t = "" self.search_count.setStyleSheet("QLabel { background-color: transparent; }") self.clear_vl.setVisible(False) self.search_count.setText(t)