diff --git a/src/calibre/gui2/preferences/__init__.py b/src/calibre/gui2/preferences/__init__.py index eabb33d03b..04ba9dd225 100644 --- a/src/calibre/gui2/preferences/__init__.py +++ b/src/calibre/gui2/preferences/__init__.py @@ -5,10 +5,10 @@ __license__ = 'GPL v3' __copyright__ = '2010, Kovid Goyal ' __docformat__ = 'restructuredtext en' -from PyQt4.Qt import QWidget, pyqtSignal, QCheckBox +from PyQt4.Qt import QWidget, pyqtSignal, QCheckBox, QAbstractSpinBox, \ + QLineEdit, QComboBox, QVariant from calibre.customize.ui import preferences_plugins -from calibre.utils.config import DynamicConfig, XMLConfig class ConfigWidgetInterface(object): @@ -25,8 +25,11 @@ class ConfigWidgetInterface(object): class Setting(object): - def __init__(self, name, config_obj, widget, gui_name=None): + def __init__(self, name, config_obj, widget, gui_name=None, + empty_string_is_None=True, choices=None): self.name, self.gui_name = name, gui_name + self.empty_string_is_None = empty_string_is_None + self.choices = choices if gui_name is None: self.gui_name = 'opt_'+name self.config_obj = config_obj @@ -36,37 +39,76 @@ class Setting(object): self.datatype = 'bool' self.gui_obj.stateChanged.connect(lambda x: widget.changed_signal.emit()) + elif isinstance(self.gui_obj, QAbstractSpinBox): + self.datatype = 'number' + self.gui_obj.valueChanged.connect(lambda x: + widget.changed_signal.emit()) + elif isinstance(self.gui_obj, QLineEdit): + self.datatype = 'string' + self.gui_obj.textChanged.connect(lambda x: + widget.changed_signal.emit()) + elif isinstance(self.gui_obj, QComboBox): + self.datatype = 'choice' + self.gui_obj.editTextChanged.connect(lambda x: + widget.changed_signal.emit()) + self.gui_obj.currentIndexChanged.connect(lambda x: + widget.changed_signal.emit()) else: raise ValueError('Unknown data type') - if isinstance(config_obj, (DynamicConfig, XMLConfig)): - self.config_type = 'dict' - else: - raise ValueError('Unknown config type') - def initialize(self): - self.set_gui_val() + self.gui_obj.blockSignals(True) + if self.datatype == 'choices': + self.gui_obj.clear() + for x in self.choices: + if isinstance(x, basestring): + x = (x, x) + self.gui_obj.addItem(x[0], QVariant(x[1])) + self.set_gui_val(self.get_config_val(default=False)) + self.gui_obj.blockSignals(False) def commit(self): - self.set_config_val() + self.set_config_val(self.get_gui_val()) def restore_defaults(self): - self.set_gui_val(to_default=True) + self.set_gui_val(self.get_config_val(default=True)) - def set_gui_val(self, to_default=False): - if self.config_type == 'dict': - if to_default: - val = self.config_obj.defaults[self.name] - else: - val = self.config_obj[self.name] + def get_config_val(self, default=False): + if default: + val = self.config_obj.defaults[self.name] + else: + val = self.config_obj[self.name] + return val + + def set_config_val(self, val): + self.config_obj[self.name] = val + + def set_gui_val(self, val): if self.datatype == 'bool': self.gui_obj.setChecked(bool(val)) + elif self.datatype == 'number': + self.gui_obj.setValue(val) + elif self.datatype == 'string': + self.gui_obj.setText(val if val else '') + elif self.datatype == 'choices': + idx = self.gui_obj.findData(QVariant(val)) + if idx == -1: + idx = 0 + self.gui_obj.setCurrentIndex(idx) - def set_config_val(self): + def get_gui_val(self): if self.datatype == 'bool': val = bool(self.gui_obj.isChecked()) - if self.config_type == 'dict': - self.config_obj[self.name] = val + elif self.datatype == 'number': + val = self.gui_obj.value(val) + elif self.datatype == 'string': + val = unicode(self.gui_name.text()).strip() + if self.empty_string_is_None and not val: + val = None + elif self.datatype == 'choices': + idx = self.gui_obj.currentIndex() + val = unicode(self.gui_obj.itemData(idx).toString()) + return val class ConfigWidgetBase(QWidget, ConfigWidgetInterface): @@ -77,6 +119,29 @@ class ConfigWidgetBase(QWidget, ConfigWidgetInterface): QWidget.__init__(self, parent) if hasattr(self, 'setupUi'): self.setupUi(self) + self.settings = {} + + def register(self, name, config_obj, widget, gui_name=None): + setting = Setting(name, config_obj, widget, gui_name=gui_name) + self.register_setting(setting) + + def register_setting(self, setting): + self.settings[setting.name] = setting + return setting + + def initialize(self): + for setting in self.settings.values(): + setting.initialize() + + def commit(self): + for setting in self.settings.values(): + setting.commit() + + def restore_defaults(self, *args): + for setting in self.settings.values(): + setting.restore_defaults() + + def get_plugin(category, name): for plugin in preferences_plugins(): diff --git a/src/calibre/library/prefs.py b/src/calibre/library/prefs.py index ff9733aaa3..b125fe9067 100644 --- a/src/calibre/library/prefs.py +++ b/src/calibre/library/prefs.py @@ -15,6 +15,7 @@ class DBPrefs(dict): def __init__(self, db): dict.__init__(self) self.db = db + self.defaults = {} for key, val in self.db.conn.get('SELECT key,val FROM preferences'): val = self.raw_to_object(val) dict.__setitem__(self, key, val) @@ -28,7 +29,10 @@ class DBPrefs(dict): return json.dumps(val, indent=2, default=to_json) def __getitem__(self, key): - return dict.__getitem__(self, key) + try: + return dict.__getitem__(self, key) + except KeyError: + return self.defaults[key] def __delitem__(self, key): dict.__delitem__(self, key) diff --git a/src/calibre/utils/config.py b/src/calibre/utils/config.py index 9fd1315caa..c001b6da36 100644 --- a/src/calibre/utils/config.py +++ b/src/calibre/utils/config.py @@ -194,6 +194,7 @@ class OptionSet(object): def __init__(self, description=''): self.description = description + self.defaults = {} self.preferences = [] self.group_list = [] self.groups = {} @@ -274,6 +275,7 @@ class OptionSet(object): if pref in self.preferences: raise ValueError('An option with the name %s already exists in this set.'%name) self.preferences.append(pref) + self.defaults[name] = default def option_parser(self, user_defaults=None, usage='', gui_mode=False): parser = OptionParser(usage, gui_mode=gui_mode) @@ -466,6 +468,10 @@ class ConfigProxy(object): self.__config = config self.__opts = None + @property + def defaults(self): + return self.__config.option_set.defaults + def refresh(self): self.__opts = self.__config.parse()