mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 10:44:09 -04:00
First cut at DB preferences
This commit is contained in:
parent
a3d8ce4850
commit
77ddc1fedf
@ -25,8 +25,8 @@ class SavedSearchEditor(QDialog, Ui_SavedSearchEditor):
|
||||
self.current_search_name = None
|
||||
self.searches = {}
|
||||
self.searches_to_delete = []
|
||||
for name in saved_searches.names():
|
||||
self.searches[name] = saved_searches.lookup(name)
|
||||
for name in saved_searches().names():
|
||||
self.searches[name] = saved_searches().lookup(name)
|
||||
|
||||
self.populate_search_list()
|
||||
if initial_search is not None and initial_search in self.searches:
|
||||
@ -78,7 +78,7 @@ class SavedSearchEditor(QDialog, Ui_SavedSearchEditor):
|
||||
if self.current_search_name:
|
||||
self.searches[self.current_search_name] = unicode(self.search_text.toPlainText())
|
||||
for name in self.searches_to_delete:
|
||||
saved_searches.delete(name)
|
||||
saved_searches().delete(name)
|
||||
for name in self.searches:
|
||||
saved_searches.add(name, self.searches[name])
|
||||
saved_searches().add(name, self.searches[name])
|
||||
QDialog.accept(self)
|
||||
|
@ -7,7 +7,6 @@ from PyQt4.QtCore import SIGNAL, Qt
|
||||
from PyQt4.QtGui import QDialog, QIcon, QListWidgetItem
|
||||
|
||||
from calibre.gui2.dialogs.tag_categories_ui import Ui_TagCategories
|
||||
from calibre.utils.config import prefs
|
||||
from calibre.gui2.dialogs.confirm_delete import confirm
|
||||
from calibre.constants import islinux
|
||||
|
||||
@ -63,7 +62,7 @@ class TagCategories(QDialog, Ui_TagCategories):
|
||||
self.all_items.append(t)
|
||||
self.all_items_dict[label+':'+n] = t
|
||||
|
||||
self.categories = dict.copy(prefs['user_categories'])
|
||||
self.categories = dict.copy(db.prefs['user_categories'])
|
||||
if self.categories is None:
|
||||
self.categories = {}
|
||||
for cat in self.categories:
|
||||
@ -182,7 +181,7 @@ class TagCategories(QDialog, Ui_TagCategories):
|
||||
|
||||
def accept(self):
|
||||
self.save_category()
|
||||
prefs['user_categories'] = self.categories
|
||||
self.db.prefs['user_categories'] = self.categories
|
||||
QDialog.accept(self)
|
||||
|
||||
def save_category(self):
|
||||
|
@ -259,8 +259,7 @@ class SavedSearchBox(QComboBox):
|
||||
self.setMinimumContentsLength(10)
|
||||
self.tool_tip_text = self.toolTip()
|
||||
|
||||
def initialize(self, _saved_searches, _search_box, colorize=False, help_text=_('Search')):
|
||||
self.saved_searches = _saved_searches
|
||||
def initialize(self, _search_box, colorize=False, help_text=_('Search')):
|
||||
self.search_box = _search_box
|
||||
self.help_text = help_text
|
||||
self.colorize = colorize
|
||||
@ -302,11 +301,11 @@ class SavedSearchBox(QComboBox):
|
||||
self.normalize_state()
|
||||
self.search_box.set_search_string(u'search:"%s"' % qname)
|
||||
self.setEditText(qname)
|
||||
self.setToolTip(self.saved_searches.lookup(qname))
|
||||
self.setToolTip(saved_searches().lookup(qname))
|
||||
|
||||
def initialize_saved_search_names(self):
|
||||
self.clear()
|
||||
qnames = self.saved_searches.names()
|
||||
qnames = saved_searches().names()
|
||||
self.addItems(qnames)
|
||||
self.setCurrentIndex(-1)
|
||||
|
||||
@ -319,10 +318,10 @@ class SavedSearchBox(QComboBox):
|
||||
idx = self.currentIndex
|
||||
if idx < 0:
|
||||
return
|
||||
ss = self.saved_searches.lookup(unicode(self.currentText()))
|
||||
ss = saved_searches().lookup(unicode(self.currentText()))
|
||||
if ss is None:
|
||||
return
|
||||
self.saved_searches.delete(unicode(self.currentText()))
|
||||
saved_searches().delete(unicode(self.currentText()))
|
||||
self.clear_to_help()
|
||||
self.search_box.clear_to_help()
|
||||
self.emit(SIGNAL('changed()'))
|
||||
@ -332,8 +331,8 @@ class SavedSearchBox(QComboBox):
|
||||
name = unicode(self.currentText())
|
||||
if self.help_state or not name.strip():
|
||||
name = unicode(self.search_box.text()).replace('"', '')
|
||||
self.saved_searches.delete(name)
|
||||
self.saved_searches.add(name, unicode(self.search_box.text()))
|
||||
saved_searches().delete(name)
|
||||
saved_searches().add(name, unicode(self.search_box.text()))
|
||||
# now go through an initialization cycle to ensure that the combobox has
|
||||
# the new search in it, that it is selected, and that the search box
|
||||
# references the new search instead of the text in the search.
|
||||
@ -348,7 +347,7 @@ class SavedSearchBox(QComboBox):
|
||||
idx = self.currentIndex();
|
||||
if idx < 0:
|
||||
return
|
||||
self.search_box.set_search_string(self.saved_searches.lookup(unicode(self.currentText())))
|
||||
self.search_box.set_search_string(saved_searches().lookup(unicode(self.currentText())))
|
||||
|
||||
class SearchBoxMixin(object):
|
||||
|
||||
@ -390,11 +389,12 @@ class SearchBoxMixin(object):
|
||||
|
||||
class SavedSearchBoxMixin(object):
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self, db):
|
||||
self.db = db
|
||||
self.connect(self.saved_search, SIGNAL('changed()'), self.saved_searches_changed)
|
||||
self.saved_searches_changed()
|
||||
self.connect(self.clear_button, SIGNAL('clicked()'), self.saved_search.clear_to_help)
|
||||
self.saved_search.initialize(saved_searches, self.search, colorize=True,
|
||||
self.saved_search.initialize(self.search, colorize=True,
|
||||
help_text=_('Saved Searches'))
|
||||
self.connect(self.save_search_button, SIGNAL('clicked()'),
|
||||
self.saved_search.save_search_button_clicked)
|
||||
@ -409,9 +409,12 @@ class SavedSearchBoxMixin(object):
|
||||
b = getattr(self, x+'_search_button')
|
||||
b.setStatusTip(b.toolTip())
|
||||
|
||||
def set_database(self, db):
|
||||
self.db = db
|
||||
self.saved_searches_changed()
|
||||
|
||||
def saved_searches_changed(self):
|
||||
p = prefs['saved_searches'].keys()
|
||||
p = saved_searches().names()
|
||||
p.sort()
|
||||
t = unicode(self.search_restriction.currentText())
|
||||
self.search_restriction.clear() # rebuild the restrictions combobox using current saved searches
|
||||
|
@ -224,7 +224,7 @@ class TagsView(QTreeView): # {{{
|
||||
|
||||
# Always show the user categories editor
|
||||
self.context_menu.addSeparator()
|
||||
if category in prefs['user_categories'].keys():
|
||||
if category in self.db.prefs['user_categories'].keys():
|
||||
self.context_menu.addAction(_('Manage User Categories'),
|
||||
partial(self.context_menu_handler, action='manage_categories',
|
||||
category=category))
|
||||
@ -426,10 +426,10 @@ class TagsModel(QAbstractItemModel): # {{{
|
||||
for k in tb_cats.keys():
|
||||
if tb_cats[k]['kind'] in ['user', 'search']:
|
||||
del tb_cats[k]
|
||||
for user_cat in sorted(prefs['user_categories'].keys()):
|
||||
for user_cat in sorted(self.db.prefs['user_categories'].keys()):
|
||||
cat_name = user_cat+':' # add the ':' to avoid name collision
|
||||
tb_cats.add_user_category(label=cat_name, name=user_cat)
|
||||
if len(saved_searches.names()):
|
||||
if len(saved_searches().names()):
|
||||
tb_cats.add_search_category(label='search', name=_('Searches'))
|
||||
|
||||
# Now get the categories
|
||||
@ -507,11 +507,11 @@ class TagsModel(QAbstractItemModel): # {{{
|
||||
if key not in self.db.field_metadata:
|
||||
return
|
||||
if key == 'search':
|
||||
if val in saved_searches.names():
|
||||
if val in saved_searches().names():
|
||||
error_dialog(self.tags_view, _('Duplicate search name'),
|
||||
_('The saved search name %s is already used.')%val).exec_()
|
||||
return False
|
||||
saved_searches.rename(unicode(item.data(role).toString()), val)
|
||||
saved_searches().rename(unicode(item.data(role).toString()), val)
|
||||
self.tags_view.search_item_renamed.emit()
|
||||
else:
|
||||
if key == 'series':
|
||||
|
@ -199,7 +199,7 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, # {{{
|
||||
UpdateMixin.__init__(self, opts)
|
||||
|
||||
####################### Search boxes ########################
|
||||
SavedSearchBoxMixin.__init__(self)
|
||||
SavedSearchBoxMixin.__init__(self, db)
|
||||
SearchBoxMixin.__init__(self)
|
||||
|
||||
####################### Library view ########################
|
||||
@ -392,6 +392,7 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, # {{{
|
||||
self.library_view.model().set_book_on_device_func(self.book_on_device)
|
||||
self.status_bar.clear_message()
|
||||
self.search.clear_to_help()
|
||||
self.saved_search.clear_to_help()
|
||||
self.book_details.reset_info()
|
||||
self.library_view.model().count_changed()
|
||||
self.scheduler.database_changed(db)
|
||||
|
@ -30,7 +30,7 @@ from calibre.customize.ui import run_plugins_on_import
|
||||
from calibre.utils.filenames import ascii_filename
|
||||
from calibre.utils.date import utcnow, now as nowf, utcfromtimestamp
|
||||
from calibre.utils.config import prefs, tweaks
|
||||
from calibre.utils.search_query_parser import saved_searches
|
||||
from calibre.utils.search_query_parser import saved_searches, set_saved_searches
|
||||
from calibre.ebooks import BOOK_EXTENSIONS, check_ebook_format
|
||||
from calibre.utils.magick_draw import save_cover_data_to
|
||||
|
||||
@ -142,6 +142,24 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
||||
|
||||
def initialize_dynamic(self):
|
||||
self.prefs = DBPrefs(self)
|
||||
|
||||
# Migrate saved search and user categories to db preference scheme
|
||||
def migrate_preference(name):
|
||||
ans = self.prefs.get(name, None)
|
||||
if ans is None:
|
||||
ans = prefs[name]
|
||||
try:
|
||||
del prefs[name]
|
||||
except:
|
||||
pass
|
||||
if ans is not None:
|
||||
self.prefs[name] = ans
|
||||
|
||||
migrate_preference('user_categories')
|
||||
migrate_preference('saved_searches')
|
||||
|
||||
set_saved_searches(self, 'saved_searches')
|
||||
|
||||
self.conn.executescript('''
|
||||
DROP TRIGGER IF EXISTS author_insert_trg;
|
||||
CREATE TEMP TRIGGER author_insert_trg
|
||||
@ -270,10 +288,10 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
||||
for k in tb_cats.keys():
|
||||
if tb_cats[k]['kind'] in ['user', 'search']:
|
||||
del tb_cats[k]
|
||||
for user_cat in sorted(prefs['user_categories'].keys()):
|
||||
for user_cat in sorted(self.prefs['user_categories'].keys()):
|
||||
cat_name = user_cat+':' # add the ':' to avoid name collision
|
||||
tb_cats.add_user_category(label=cat_name, name=user_cat)
|
||||
if len(saved_searches.names()):
|
||||
if len(saved_searches().names()):
|
||||
tb_cats.add_search_category(label='search', name=_('Searches'))
|
||||
|
||||
self.book_on_device_func = None
|
||||
@ -845,7 +863,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
||||
categories['formats'].sort(key = lambda x:x.name)
|
||||
|
||||
#### Now do the user-defined categories. ####
|
||||
user_categories = prefs['user_categories']
|
||||
user_categories = self.prefs['user_categories']
|
||||
|
||||
# We want to use same node in the user category as in the source
|
||||
# category. To do that, we need to find the original Tag node. There is
|
||||
@ -882,8 +900,8 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
||||
icon = None
|
||||
if icon_map and 'search' in icon_map:
|
||||
icon = icon_map['search']
|
||||
for srch in saved_searches.names():
|
||||
items.append(Tag(srch, tooltip=saved_searches.lookup(srch), icon=icon))
|
||||
for srch in saved_searches().names():
|
||||
items.append(Tag(srch, tooltip=saved_searches().lookup(srch), icon=icon))
|
||||
if len(items):
|
||||
if icon_map is not None:
|
||||
icon_map['search'] = icon_map['search']
|
||||
|
@ -397,4 +397,3 @@ class SchemaUpgrade(object):
|
||||
UNIQUE(key));
|
||||
'''
|
||||
self.conn.executescript(script)
|
||||
|
||||
|
@ -21,7 +21,6 @@ import sys, string, operator
|
||||
from calibre.utils.pyparsing import Keyword, Group, Forward, CharsNotIn, Suppress, \
|
||||
OneOrMore, oneOf, CaselessLiteral, Optional, NoMatch, ParseException
|
||||
from calibre.constants import preferred_encoding
|
||||
from calibre.utils.config import prefs
|
||||
|
||||
'''
|
||||
This class manages access to the preference holding the saved search queries.
|
||||
@ -32,9 +31,13 @@ class SavedSearchQueries(object):
|
||||
queries = {}
|
||||
opt_name = ''
|
||||
|
||||
def __init__(self, _opt_name):
|
||||
def __init__(self, db, _opt_name):
|
||||
self.opt_name = _opt_name;
|
||||
self.queries = prefs[self.opt_name]
|
||||
self.db = db
|
||||
if db is not None:
|
||||
self.queries = db.prefs[self.opt_name]
|
||||
else:
|
||||
self.queries = {}
|
||||
|
||||
def force_unicode(self, x):
|
||||
if not isinstance(x, unicode):
|
||||
@ -43,20 +46,20 @@ class SavedSearchQueries(object):
|
||||
|
||||
def add(self, name, value):
|
||||
self.queries[self.force_unicode(name)] = self.force_unicode(value).strip()
|
||||
prefs[self.opt_name] = self.queries
|
||||
self.db.prefs[self.opt_name] = self.queries
|
||||
|
||||
def lookup(self, name):
|
||||
return self.queries.get(self.force_unicode(name), None)
|
||||
|
||||
def delete(self, name):
|
||||
self.queries.pop(self.force_unicode(name), False)
|
||||
prefs[self.opt_name] = self.queries
|
||||
self.db.prefs[self.opt_name] = self.queries
|
||||
|
||||
def rename(self, old_name, new_name):
|
||||
self.queries[self.force_unicode(new_name)] = \
|
||||
self.queries.get(self.force_unicode(old_name), None)
|
||||
self.queries.pop(self.force_unicode(old_name), False)
|
||||
prefs[self.opt_name] = self.queries
|
||||
self.db.prefs[self.opt_name] = self.queries
|
||||
|
||||
def names(self):
|
||||
return sorted(self.queries.keys(),
|
||||
@ -66,8 +69,15 @@ class SavedSearchQueries(object):
|
||||
Create a global instance of the saved searches. It is global so that the searches
|
||||
are common across all instances of the parser (devices, library, etc).
|
||||
'''
|
||||
saved_searches = SavedSearchQueries('saved_searches')
|
||||
ss = SavedSearchQueries(None, None)
|
||||
|
||||
def set_saved_searches(db, opt_name):
|
||||
global ss
|
||||
ss = SavedSearchQueries(db, opt_name)
|
||||
|
||||
def saved_searches():
|
||||
global ss
|
||||
return ss
|
||||
|
||||
class SearchQueryParser(object):
|
||||
'''
|
||||
@ -209,7 +219,7 @@ class SearchQueryParser(object):
|
||||
raise ParseException(query, len(query), 'undefined saved search', self)
|
||||
if self.recurse_level > 5:
|
||||
self.searches_seen.add(query)
|
||||
return self._parse(saved_searches.lookup(query))
|
||||
return self._parse(saved_searches().lookup(query))
|
||||
except: # convert all exceptions (e.g., missing key) to a parse error
|
||||
raise ParseException(query, len(query), 'undefined saved search', self)
|
||||
return self.get_matches(location, query)
|
||||
|
Loading…
x
Reference in New Issue
Block a user