diff --git a/src/calibre/db/categories.py b/src/calibre/db/categories.py index 3f7bbb9e61..df6c1402d2 100644 --- a/src/calibre/db/categories.py +++ b/src/calibre/db/categories.py @@ -16,7 +16,6 @@ from calibre.ebooks.metadata import author_to_author_sort from calibre.library.field_metadata import TagsIcons from calibre.utils.config_base import tweaks from calibre.utils.icu import sort_key -from calibre.utils.search_query_parser import saved_searches CATEGORY_SORTS = ('name', 'popularity', 'rating') # This has to be a tuple not a set @@ -229,7 +228,7 @@ def get_categories(dbcache, sort='name', book_ids=None, icon_map=None): icon = None if icon_map and 'search' in icon_map: icon = icon_map['search'] - ss = saved_searches() + ss = dbcache._search_api.get_saved_searches() for srch in ss.names(): items.append(Tag(srch, tooltip=ss.lookup(srch), sort=srch, icon=icon, category='search', diff --git a/src/calibre/db/legacy.py b/src/calibre/db/legacy.py index b938e7dddf..838ccdfe21 100644 --- a/src/calibre/db/legacy.py +++ b/src/calibre/db/legacy.py @@ -120,6 +120,9 @@ class LibraryDatabase(object): self.new_api.reload_from_db() self.last_update_check = utcnow() + def get_saved_searches(self): + return self.new_api._search_api.get_saved_searches() + @property def custom_column_num_map(self): return self.backend.custom_column_num_map diff --git a/src/calibre/gui2/dialogs/saved_search_editor.py b/src/calibre/gui2/dialogs/saved_search_editor.py index c9f843109a..669771e46e 100644 --- a/src/calibre/gui2/dialogs/saved_search_editor.py +++ b/src/calibre/gui2/dialogs/saved_search_editor.py @@ -7,7 +7,6 @@ from PyQt4.QtCore import SIGNAL from PyQt4.QtGui import QDialog from calibre.gui2.dialogs.saved_search_editor_ui import Ui_SavedSearchEditor -from calibre.utils.search_query_parser import saved_searches from calibre.utils.icu import sort_key from calibre.gui2 import error_dialog from calibre.gui2.dialogs.confirm_delete import confirm @@ -15,6 +14,7 @@ from calibre.gui2.dialogs.confirm_delete import confirm class SavedSearchEditor(QDialog, Ui_SavedSearchEditor): def __init__(self, parent, initial_search=None): + from calibre.gui2.ui import saved_searches QDialog.__init__(self, parent) Ui_SavedSearchEditor.__init__(self) self.setupUi(self) @@ -98,6 +98,7 @@ class SavedSearchEditor(QDialog, Ui_SavedSearchEditor): self.search_text.setPlainText('') def accept(self): + from calibre.gui2.ui import saved_searches if self.current_search_name: self.searches[self.current_search_name] = unicode(self.search_text.toPlainText()) for name in saved_searches().names(): diff --git a/src/calibre/gui2/search_box.py b/src/calibre/gui2/search_box.py index 85ddf533c4..b10fdd40ef 100644 --- a/src/calibre/gui2/search_box.py +++ b/src/calibre/gui2/search_box.py @@ -18,7 +18,6 @@ from calibre.gui2 import config, error_dialog from calibre.gui2.dialogs.confirm_delete import confirm from calibre.gui2.dialogs.saved_search_editor import SavedSearchEditor from calibre.gui2.dialogs.search import SearchDialog -from calibre.utils.search_query_parser import saved_searches class SearchLineEdit(QLineEdit): # {{{ key_pressed = pyqtSignal(object) @@ -309,6 +308,7 @@ class SavedSearchBox(QComboBox): # {{{ self.saved_search_selected(self.currentText()) def saved_search_selected(self, qname): + from calibre.gui2.ui import saved_searches qname = unicode(qname) if qname is None or not qname.strip(): self.search_box.clear() @@ -322,12 +322,14 @@ class SavedSearchBox(QComboBox): # {{{ self.setToolTip(saved_searches().lookup(qname)) def initialize_saved_search_names(self): + from calibre.gui2.ui import saved_searches qnames = saved_searches().names() self.addItems(qnames) self.setCurrentIndex(-1) # SIGNALed from the main UI def save_search_button_clicked(self): + from calibre.gui2.ui import saved_searches name = unicode(self.currentText()) if not name.strip(): name = unicode(self.search_box.text()).replace('"', '') @@ -346,6 +348,7 @@ class SavedSearchBox(QComboBox): # {{{ self.changed.emit() def delete_current_search(self): + from calibre.gui2.ui import saved_searches idx = self.currentIndex() if idx <= 0: error_dialog(self, _('Delete current search'), @@ -365,6 +368,7 @@ class SavedSearchBox(QComboBox): # {{{ # SIGNALed from the main UI def copy_search_button_clicked(self): + from calibre.gui2.ui import saved_searches idx = self.currentIndex() if idx < 0: return diff --git a/src/calibre/gui2/search_restriction_mixin.py b/src/calibre/gui2/search_restriction_mixin.py index b986a2a78e..71e0f2f392 100644 --- a/src/calibre/gui2/search_restriction_mixin.py +++ b/src/calibre/gui2/search_restriction_mixin.py @@ -17,7 +17,6 @@ from calibre.gui2.widgets import ComboBoxWithHelp from calibre.utils.config_base import tweaks from calibre.utils.icu import sort_key from calibre.utils.search_query_parser import ParseException -from calibre.utils.search_query_parser import saved_searches class SelectNames(QDialog): # {{{ @@ -179,6 +178,7 @@ class CreateVirtualLibrary(QDialog): # {{{ self.resize(self.sizeHint()+QSize(150, 25)) def search_text_changed(self, txt): + from calibre.gui2.ui import saved_searches searches = [_('Saved searches recognized in the expression:')] txt = unicode(txt) while txt: @@ -234,6 +234,7 @@ class CreateVirtualLibrary(QDialog): # {{{ self.vl_text.setText(self.original_search) def link_activated(self, url): + from calibre.gui2.ui import saved_searches db = self.gui.current_db f, txt = unicode(url).partition('.')[0::2] if f == 'search': @@ -475,6 +476,7 @@ class SearchRestrictionMixin(object): return name[0:MAX_VIRTUAL_LIBRARY_NAME_LENGTH].strip() def build_search_restriction_list(self): + from calibre.gui2.ui import saved_searches m = self.ar_menu m.clear() diff --git a/src/calibre/gui2/tag_browser/model.py b/src/calibre/gui2/tag_browser/model.py index 33d1235f8b..7dba7cfe7d 100644 --- a/src/calibre/gui2/tag_browser/model.py +++ b/src/calibre/gui2/tag_browser/model.py @@ -21,7 +21,6 @@ from calibre.utils.icu import sort_key, lower, strcmp, collation_order from calibre.library.field_metadata import TagsIcons, category_icon_map from calibre.gui2.dialogs.confirm_delete import confirm from calibre.utils.formatter import EvalFormatter -from calibre.utils.search_query_parser import saved_searches TAG_SEARCH_STATES = {'clear': 0, 'mark_plus': 1, 'mark_plusplus': 2, 'mark_minus': 3, 'mark_minusminus': 4} @@ -879,7 +878,7 @@ class TagsModel(QAbstractItemModel): # {{{ traceback.print_exc() self.db.data.change_search_locations(self.db.field_metadata.get_search_terms()) - if len(saved_searches().names()): + if len(self.db.get_saved_searches().names()): tb_cats.add_search_category(label='search', name=_('Searches')) if self.filter_categories_by: @@ -1005,11 +1004,11 @@ class TagsModel(QAbstractItemModel): # {{{ _('Author names cannot contain & characters.')).exec_() return False if key == 'search': - if val in saved_searches().names(): + if val in self.db.get_saved_searches().names(): error_dialog(self.gui_parent, _('Duplicate search name'), _('The saved search name %s is already used.')%val).exec_() return False - saved_searches().rename(unicode(item.data(role).toString()), val) + self.db.get_saved_searches().rename(unicode(item.data(role).toString()), val) item.tag.name = val self.search_item_renamed.emit() # Does a refresh else: diff --git a/src/calibre/gui2/tag_browser/view.py b/src/calibre/gui2/tag_browser/view.py index cefa0f8975..d28b7ca848 100644 --- a/src/calibre/gui2/tag_browser/view.py +++ b/src/calibre/gui2/tag_browser/view.py @@ -20,7 +20,6 @@ from calibre.constants import config_dir from calibre.gui2.tag_browser.model import (TagTreeItem, TAG_SEARCH_STATES, TagsModel) from calibre.gui2 import config, gprefs, choose_files, pixmap_to_data -from calibre.utils.search_query_parser import saved_searches from calibre.utils.icu import sort_key class TagDelegate(QStyledItemDelegate): # {{{ @@ -355,6 +354,7 @@ class TagsView(QTreeView): # {{{ self.delete_user_category.emit(key) return if action == 'delete_search': + from calibre.gui2.ui import saved_searches saved_searches().delete(key) self.rebuild_saved_searches.emit() return diff --git a/src/calibre/gui2/ui.py b/src/calibre/gui2/ui.py index 229ed0933d..e54d06e671 100644 --- a/src/calibre/gui2/ui.py +++ b/src/calibre/gui2/ui.py @@ -98,6 +98,16 @@ _gui = None def get_gui(): return _gui +def saved_searches(): + 'Return the saved searches defined in the currently open library' + try: + return _gui.library_view.model().db.get_saved_searches() + except AttributeError: + # Happens during initialization of the gui + from calibre.utils.search_query_parser import saved_searches + return saved_searches() + + class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{ TagBrowserMixin, CoverFlowMixin, LibraryViewMixin, SearchBoxMixin, SavedSearchBoxMixin, SearchRestrictionMixin, LayoutMixin, UpdateMixin, diff --git a/src/calibre/library/cli.py b/src/calibre/library/cli.py index 547cc5bc08..7e7a234724 100644 --- a/src/calibre/library/cli.py +++ b/src/calibre/library/cli.py @@ -1028,10 +1028,8 @@ def command_saved_searches(args, dbpath): print prints(_('Error: You must specify an action (add|remove|list)'), file=sys.stderr) return 1 - from calibre.utils.search_query_parser import saved_searches db = get_db(dbpath, opts) - db - ss = saved_searches() + ss = db.get_saved_searches() if args[0] == 'list': for name in ss.names(): prints(_('Name:'), name) diff --git a/src/calibre/library/database2.py b/src/calibre/library/database2.py index 9022605024..8ea7e75b59 100644 --- a/src/calibre/library/database2.py +++ b/src/calibre/library/database2.py @@ -537,6 +537,9 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): if self.user_version == 0: self.user_version = 1 + def get_saved_searches(self): + return saved_searches() + def last_modified(self): ''' Return last modified time as a UTC datetime object''' return utcfromtimestamp(os.stat(self.dbpath).st_mtime) diff --git a/src/calibre/library/server/base.py b/src/calibre/library/server/base.py index bbd5239b42..a677b991f9 100644 --- a/src/calibre/library/server/base.py +++ b/src/calibre/library/server/base.py @@ -25,7 +25,6 @@ from calibre.library.server.opds import OPDSServer from calibre.library.server.cache import Cache from calibre.library.server.browse import BrowseServer from calibre.library.server.ajax import AjaxServer -from calibre.utils.search_query_parser import saved_searches from calibre import prints, as_unicode @@ -210,7 +209,7 @@ class LibraryServer(ContentServer, MobileServer, XMLServer, OPDSServer, Cache, if sr: if sr in virt_libs: sr = virt_libs[sr] - elif sr not in saved_searches().names(): + elif sr not in self.db.get_saved_searches().names(): prints('WARNING: Content server: search restriction ', sr, ' does not exist') sr = ''