SF.net SVN: fclient: [577] trunk/fclient/src/fclient/lib/qt4ex/settings.py
Status: Pre-Alpha
Brought to you by:
jurner
|
From: <jU...@us...> - 2008-07-11 16:34:21
|
Revision: 577
http://fclient.svn.sourceforge.net/fclient/?rev=577&view=rev
Author: jUrner
Date: 2008-07-11 09:34:31 -0700 (Fri, 11 Jul 2008)
Log Message:
-----------
deprecate settingsbase use qt4ex.settings instead
Added Paths:
-----------
trunk/fclient/src/fclient/lib/qt4ex/settings.py
Added: trunk/fclient/src/fclient/lib/qt4ex/settings.py
===================================================================
--- trunk/fclient/src/fclient/lib/qt4ex/settings.py (rev 0)
+++ trunk/fclient/src/fclient/lib/qt4ex/settings.py 2008-07-11 16:34:31 UTC (rev 577)
@@ -0,0 +1,368 @@
+"""helpers to work with QSettings
+"""
+from __future__ import absolute_import
+if __name__ == '__main__': # see --> http://bugs.python.org/issue1510172 . works only current dir and below
+ import os; __path__ = [os.path.dirname(__file__)]
+
+
+import operator
+from PyQt4 import QtCore, QtGui
+
+from . import qtools
+#********************************************************************************
+#
+#********************************************************************************
+class Setting(object):
+ __slots__ = ('default', 'type', 'userData', 'value')
+ def __init__(self, type, value, default, userData=None):
+ self.default = default
+ self.type = type
+ self.userData = userData
+ self.value = value
+
+#********************************************************************************
+#
+#********************************************************************************
+class SettingsBase(object):
+ """Base class to deal with reading and writing of settings
+
+ this class tries to take away most of the pain when dealing with QSettings.
+
+ * settings are automatically dumped to disk when they are set
+ * if a setting can not be read from disk or its type is not ok its default value is taken instead
+ * settings are always saved and restored in the specified settings order
+ * any user defined data may be associated to a setting at runtime
+
+ blah more here
+
+
+ you should derrive a class from SettingsBase and implement its L{settingsObject} method.
+ this method is called whenever a settings object is required to read or write a setting.
+ the subclass must define a '_key_' attribute (key to store the settings to) and a tuple
+ _settings_.
+
+ blah more here
+
+
+ sample usage::
+
+ class MySettings(settings.SettingsBase):
+ _key_ = 'MyKey'
+ _settings_ = (
+ ('MySetting-1', 'Bool', True), # name, type, default
+ ('MySetting-1', 'Bool', True, 0), # or.. name, type, default, userData
+ )
+
+ def settingsObject(self):
+ return QtCore.QSettings()
+
+ s = MySettings()
+ s.restore()
+ s.value('MySetting-1')
+ >> True
+
+
+ you may define handlers for custom types as well::
+
+ class MySettings(settings.SettingsBase):
+ _key_ = 'MyKey'
+ _settings_ = (
+ ('MySetting-1', 'MyType', True),
+ )
+
+ def settingsObject(self):
+ return QtCore.QSettings()
+
+ def fromMyType(self, settings, name, value):
+ return QTCore.QVariant(value), True
+
+ def toMyType(self, settings, name, v):
+ return v.toBool(), True
+
+
+ finalisation of the settings object can be handled as well::
+
+ class MySettings(settings.SettingsBase):
+ _key_ = 'MyKey'
+ _settings_ = (
+ ('MySetting-1', 'MyType', True),
+ )
+
+ def settingsObject(self):
+ s = QtCore.QSettings()
+ s.beginGroup('whatever')
+ return s
+
+ def finalizeSettingsObject(self, settingsObject):
+ settingsObject.endGroup()
+
+ """
+ _settings_ = () # (ValueName, type, DefaultValue, (optional)UserData)
+ _key_ = '' #
+
+
+ def __init__(self, parent=None):
+ """
+ @param parent: (QObject) or None
+ """
+
+ self._parent = parent
+ self._settingsDict = None
+ self._settingsOrder = None
+
+ self.updateSettingsDict()
+
+
+ def finalizeSettingsObject(self, settingsObject):
+ """called when done with a settings object as returned from L{settingsObject}
+ @param settingsObject: (QSettings)
+ @note: default implementation does nothing. overwrite to handle
+ """
+
+
+ def settingsObject(self):
+ """should return the QSettings object to store settings to
+ @return: (QSettings)
+ @raise NotImplementedError: overrite to handle
+ """
+ raise NotImplementedError()
+
+ #############################################
+ ##
+ #############################################
+ def default(self, name):
+ """returns the default value of a setting
+ @param name: (str) name of the setting
+ """
+ return self._settingsDict[name].default
+
+
+ def parent(self):
+ """returns the parent of the settings instance"""
+ return self._parent
+
+ def restore(self):
+ """restores settings from disk
+
+ @note: values are restored in settings order
+ @note: the method tries first to find a method to<DesiredType> . if present the method
+ will be called with three arguments (QSettings,settingName, variant). the method should
+ convert the variant to the deired value type and return it along with a boolean flag indicating
+ if the value is ok or not. if it is not ok the settings default value is picked up::
+ dumped to disk or not::
+
+ def toMyType(settings, name, v):
+ if v.isValid():
+ s = v.toString()
+ if not s.isEmpty():
+ return s, True
+ return None, False
+
+ if no such handler is found it is assumed that the value can be converted directly from the QVariant
+ by calling QVariant.to<DesiredType>()
+
+ @note: L{finalizeSettingsObject} is called emidiately after the call to allow for clean ups of the settings object
+ """
+ settings = self.settingsObject()
+ settings.beginGroup(self._key_)
+ try:
+ for name in self._settingsOrder:
+ typeSetting = self.type(name)
+ if typeSetting is not None:
+ v = settings.value(name)
+ # check if we have a conversion method at hand..
+ mthd = getattr(self, 'to' + typeSetting, None)
+ # ..if not definded assert it is a QVariant method
+ if mthd is None:
+ mthd = getattr(v, 'to' + typeSetting, None)
+ if mthd is None:
+ raise ValueError('%s: no conversion method found for type: %r' % (name, typeSetting))
+ obj, ok = qtools.castVariant(v, typeSetting)
+ else:
+ obj, ok = getattr(self, 'to' + typeSetting)(settings, name, v)
+ self._settingsDict[name].value = obj if ok else self.default(name)
+ finally:
+ settings.endGroup()
+ self.finalizeSettingsObject(settings)
+
+
+ def restoreDefaults(self, *names):
+ """restores default values for settings
+ @param names: names to restore defaults for or no name to restore defaults of all settings
+ """
+ names = names if names else self._settingsOrder
+ return self.setValues(**dict([(name, self.default(name)) for name in names]))
+
+
+ def setDefault(self, name, value):
+ """sets the default value of a setting
+ @param name: (str) name of the setting
+ @param value: default value
+ """
+ self._settingsDict[name].default = value
+
+
+ def setType(self, name, value):
+ """sets the type of a setting
+ @param name: (str) name of the setting
+ @param value: desired type
+ @note: the settings value is not adjusted in the call and it is not dumped to disk.
+ use L{updateSettingsDict} followed by L{setValues} to do so
+ """
+ self._settingsDict[name].type = value
+
+
+ def setUserData(self, name, value):
+ """associates (any) user defined data to a setting
+ @param name: (str) name of the setting
+ """
+ self._settingsDict[name].userData = value
+
+
+ def setValues(self, **kws):
+ """sets the value of one or more setting and dumps it to disk
+ @param kws: name --> value to set
+ @note: if no kws are specified all settings are dumped to disk
+
+ @note: values are set in settings order
+ @note: the method tries first to find a method from<DesiredType> . if present the method
+ will be called with three arguments (QSettings,settingName, settingValue). the method should
+ convert the value to a QVariant and return it along with a boolean flag indicating if the value should be
+ dumped to disk or not::
+
+ def fromMyType(settings, name, value):
+ v = QtCore.QVariant(value)
+ if v.isValid():
+ return v, True
+ return None, False
+
+ if no such handler is found it is assumed that the value can be converted directly to a QVariant
+
+ @note: L{finalizeSettingsObject} is called emidiately after the call to allow for clean ups of the settings object
+ """
+ kws = kws if kws else self._settingsDict
+
+ # sort kws by settings order
+ try:
+ L = [(self._settingsOrder.index(i[0]), i[0], i[1]) for i in kws.items()]
+ except ValueError:
+ raise ValueError('No such setting: %s' % [i for i in kws if i not in self._settingsOrder][0])
+ L.sort(key=operator.itemgetter(0))
+
+ settings = self.settingsObject()
+ settings.beginGroup(self._key_)
+ try:
+ for _, name, value in L:
+ typeSetting = self.type(name)
+ self._settingsDict[name].value = value
+ if typeSetting is not None:
+ mthd = getattr(self, 'from' + typeSetting, None)
+ if mthd is None:
+ v = QtCore.QVariant(value)
+ ok = True
+ else:
+ v, ok = mthd(settings, name, value)
+ settings.setValue(name, v) if ok else settings.setValue(name, QtCore.QVariant(self.default(name)))
+ finally:
+ settings.endGroup()
+ self.finalizeSettingsObject(settings)
+
+
+ def toDict(self):
+ """Returns a dict containing the current state of the settings object
+ @return: dict{SettingsName: value}
+ """
+ return dict([(name, setting.value) for (name, setting) in self._settingsDict.items()])
+
+
+ def type(self, name):
+ """returns the type of a setting
+ @param name: (str) name of the setting
+ """
+ return self._settingsDict[name].type
+
+
+ def updateSettingsDict(self):
+ """Updates the internal state of the settings object
+ @note: use this for example if you dynamically add or remove settings
+ """
+ self._settingsDict = {}
+ self._settingsOrder = []
+ for i in self._settings_:
+ if len(i) == 3:
+ setting = Setting(i[1], i[2], i[2])
+ elif len(i) == 4:
+ setting = Setting(i[1], i[2], i[2], userData=i[3])
+ else:
+ raise ValueError('setting data should be 2 or three tuple: %r' % name)
+ name = i[0]
+ if name in self._settingsOrder:
+ raise valueError('setting already exists: %r' % name)
+ self._settingsDict[name] = setting
+ self._settingsOrder.append(name)
+
+
+ def userData(self, name):
+ """returns the user data associated to a setting
+ @param name: (str) name of the setting
+ """
+ return self._settingsDict[name].userData
+
+
+ def value(self, name):
+ """returns the value of a setting
+ @param name: (str) name of the setting
+ """
+ return self._settingsDict[name].value
+
+ #############################################
+ ##
+ #############################################
+ def fromQColor(self, settings, name, value):
+ """default handler to convert a QColor to a QVariant"""
+ if value is not None:
+ return QtCore.QVariant(value.name()), True
+ return QtCore.QVariant(), False
+
+ def toQColor(self, settings, name, v):
+ """default handler to convert a QVariant to a QColor"""
+ if v.isValid():
+ color = QtGui.QColor(v.toString())
+ if color.isValid():
+ return color, True
+ return None, False
+
+ def _fromQPixmap(self, settings, name, value, pixmapFormat):
+ """helper to convert a QPixmap to a QVariant"""
+ if value is not None:
+ arr = QtCore.QByteArray()
+ p = QtCore.QBuffer(arr)
+ p.open(QtCore.QIODevice.WriteOnly)
+ value.save(p, pixmapFormat)
+ return QtCore.QVariant(arr), True
+ return None, False
+
+ def _toPixmap(self, settings, name, v):
+ """helper to convert a QVariant to a QPixmap"""
+ if v.isValid():
+ px = QtGui.QPixmap()
+ if px.loadFromData(v.toByteArray()):
+ return px, True
+ return None, False
+
+ def toQPixmapBmp(self, settings, name, v): return self._toPixmap(settings, name, v)
+ def fromQPixmapBmp(self, settings, name, value): return self._fromPixmap(settings, name, value, 'BMP')
+
+ def toQPixmapJpg(self, settings, name, v): return self._toPixmap(settings, name, v)
+ def fromQPixmapJpg(self, settings, name, value): return self._fromPixmap(settings, name, value, 'JPG')
+
+ def toQPixmapPng(self, settings, name, v): return self._toPixmap(settings, name, v)
+ def fromQPixmapPng(self, settings, name, value): return self._fromPixmap(settings, name, value, 'PNG')
+
+ def toQPixmapXbm(self, settings, name, v): return self._toPixmap(settings, name, v)
+ def fromQPixmapXbm(self, settings, name, value): return self._fromPixmap(settings, name, value, 'XBM')
+
+ def toQPixmapXpm(self, settings, name, v): return self._toPixmap(settings, name, v)
+ def fromQPixmapXpm(self, settings, name, value): return self._fromPixmap(settings, name, value, 'XPM')
+
+
\ No newline at end of file
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|