summaryrefslogtreecommitdiff
path: root/rapid/prefs.py
diff options
context:
space:
mode:
Diffstat (limited to 'rapid/prefs.py')
-rw-r--r--rapid/prefs.py182
1 files changed, 182 insertions, 0 deletions
diff --git a/rapid/prefs.py b/rapid/prefs.py
new file mode 100644
index 0000000..6912138
--- /dev/null
+++ b/rapid/prefs.py
@@ -0,0 +1,182 @@
+### Copyright (C) 2002-2006 Stephen Kennedy <stevek@gnome.org>
+
+### This program is free software; you can redistribute it and/or modify
+### it under the terms of the GNU General Public License as published by
+### the Free Software Foundation; either version 2 of the License, or
+### (at your option) any later version.
+
+### This program is distributed in the hope that it will be useful,
+### but WITHOUT ANY WARRANTY; without even the implied warranty of
+### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+### GNU General Public License for more details.
+
+### You should have received a copy of the GNU General Public License
+### along with this program; if not, write to the Free Software
+### Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+### Modified August 2007 by Damon Lynch to allow use of list value preferences
+
+"""Module to help implement 'instant-apply' preferences.
+
+Usage:
+
+import prefs
+defaults = {
+ "colour" : prefs.Value(prefs.STRING, "red")
+ "size" : prefs.Value(prefs.INT, 10)
+}
+
+p = prefs.Preferences("/apps/myapp", defaults)
+# use variables as if they were normal attributes.
+draw(p.colour, p.size)
+# settings are persistent. (saved in gconf)
+p.color = "blue"
+
+"""
+
+class Value(object):
+ """Represents a settable preference.
+ """
+
+ __slots__ = ["type", "default", "current"]
+
+ def __init__(self, t, d):
+ """Create a value.
+
+ t : a string : one of ("bool", "int", "string", "list")
+ d : the default value, also the initial value
+ """
+ self.type = t
+ self.default = d
+ self.current = d
+
+ def setfunc(self, gconf, rootkey, attr):
+ setfunc = getattr(gconf, "set_%s" % self.type)
+ setfunc("%s/%s" % (rootkey, attr), self.current)
+
+ def getfunc(self, gconf, rootkey, attr):
+ getfunc = getattr(gconf, "get_%s" % self.type)
+ return getfunc("%s/%s" % (rootkey, attr))
+
+
+class ListValue(Value):
+ """
+ Represents a list type settable preference.
+ """
+
+ __slots__ = Value.__slots__ + ["list_type"]
+ def __init__(self, list_type, d):
+ """
+ Create a list value.
+
+ d : the default value, also the initial value
+ list_type: the type of elements the list contains
+ """
+ Value.__init__(self, LIST, d)
+ self.list_type = list_type
+
+ def setfunc(self, gconf, rootkey, attr):
+ setfunc = getattr(gconf, "set_list")
+ setfunc("%s/%s" % (rootkey, attr), self.list_type, self.current)
+
+ def getfunc(self, gconf, rootkey, attr):
+ getfunc = getattr(gconf, "get_list")
+ return getfunc("%s/%s" % (rootkey, attr), self.list_type)
+
+
+# maybe fall back to ConfigParser if gconf is unavailable.
+import gconf
+
+# types of values allowed
+BOOL = "bool"
+INT = "int"
+STRING = "string"
+FLOAT = "float"
+LIST = "list"
+# PAIR = "pair"
+STRING_LIST = gconf.VALUE_STRING
+INT_LIST = gconf.VALUE_INT
+BOOL_LIST = gconf.VALUE_BOOL
+FLOAT_LIST = gconf.VALUE_FLOAT
+##
+
+class Preferences(object):
+ """Persistent preferences object.
+
+ Example:
+ import prefs
+ defaults = {"spacing": prefs.Value(prefs.INT, 4),
+ "font": prefs.Value(prefs.STRING, "monospace") }
+ p = prefs.Prefs("myapp", defaults)
+ print p.font
+ p.font = "sans" # written to gconf too
+ p2 = prefs.Prefs("myapp", defaults)
+ print p.font # prints "sans"
+ """
+
+ def __init__(self, rootkey, initial):
+ """Create a preferences object.
+
+ Settings are initialised with 'initial' and then overriden
+ from values in the gconf database if available.
+
+ rootkey : the root gconf key where the values will be stored
+ initial : a dictionary of string to Value objects.
+ """
+ self.__dict__["_gconf"] = gconf.client_get_default()
+ self.__dict__["_listeners"] = []
+ self.__dict__["_rootkey"] = rootkey
+ self.__dict__["_prefs"] = initial
+ self._gconf.add_dir(rootkey, gconf.CLIENT_PRELOAD_NONE)
+ self._gconf.notify_add(rootkey, self._on_preference_changed)
+ for key, value in self._prefs.items():
+ gval = self._gconf.get_without_default("%s/%s" % (rootkey, key) )
+ if gval != None:
+ value.current = value.getfunc(self._gconf, rootkey, key)
+
+ def __getattr__(self, attr):
+ return self._prefs[attr].current
+
+ def get_default(self, attr):
+ return self._prefs[attr].default
+
+ def __setattr__(self, attr, val):
+ value = self._prefs[attr]
+
+ if value.current != val:
+ value.current = val
+ value.setfunc(self._gconf, self._rootkey, attr)
+
+ try:
+ for l in self._listeners:
+ l(attr,val)
+ except StopIteration:
+ pass
+
+ def _on_preference_changed(self, client, timestamp, entry, extra):
+ attr = entry.key[ entry.key.rindex("/")+1 : ]
+ try:
+ valuestruct = self._prefs[attr]
+ except KeyError: # unknown key, we don't care about it
+ pass
+ else:
+ if entry.value != None: # value has changed
+ newval = valuestruct.getfunc(self._gconf, self._rootkey, attr)
+ setattr( self, attr, newval)
+ else: # value has been deleted
+ setattr( self, attr, valuestruct.default )
+
+ def notify_add(self, callback):
+ """Register a callback to be called when a preference changes.
+
+ callback : a callable object which take two parameters, 'attr' the
+ name of the attribute changed and 'val' the new value.
+ """
+ self._listeners.append(callback)
+
+ def dump(self):
+ """Print all preferences.
+ """
+ for k,v in self._prefs.items():
+ print k, v.type, v.current
+