Unify defaults interface across all config types

This commit is contained in:
Kovid Goyal 2010-08-25 08:16:50 -06:00
parent b6e17824e3
commit 440e34d1b8
3 changed files with 96 additions and 21 deletions

View File

@ -5,10 +5,10 @@ __license__ = 'GPL v3'
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
__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():

View File

@ -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)

View File

@ -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()