meld r1220 - trunk



Author: kaiw
Date: Sat Mar  7 16:31:56 2009
New Revision: 1220
URL: http://svn.gnome.org/viewvc/meld?rev=1220&view=rev

Log:
Add a ConfigParser-based preferences backend for non-gconf platforms

For platforms where gconf is not installed or is unavailable, we provide a
ConfigParser-based fallback for Meld's preference handling. This is required
for letting Meld run on other platforms, as part of bug 556404.

Patch provided by Greg Bowyer.


Modified:
   trunk/meldapp.py
   trunk/prefs.py

Modified: trunk/meldapp.py
==============================================================================
--- trunk/meldapp.py	(original)
+++ trunk/meldapp.py	Sat Mar  7 16:31:56 2009
@@ -440,9 +440,13 @@
         if self.use_custom_font:
             return self.custom_font
         else:
+            if not hasattr(self, "_gconf"):
+                return "Monospace 10"
             return self._gconf.get_string('/desktop/gnome/interface/monospace_font_name') or "Monospace 10"
 
     def get_toolbar_style(self):
+        if not hasattr(self, "_gconf"):
+            return gtk.TOOLBAR_BOTH
         style = self._gconf.get_string('/desktop/gnome/interface/toolbar_style') or "both"
         style = {"both":gtk.TOOLBAR_BOTH, "text":gtk.TOOLBAR_TEXT,
                  "icon":gtk.TOOLBAR_ICONS, "icons":gtk.TOOLBAR_ICONS,
@@ -452,6 +456,8 @@
         return style
 
     def get_gnome_editor_command(self, files):
+        if not hasattr(self, "_gconf"):
+            return []
         argv = []
         editor = self._gconf.get_string('/desktop/gnome/applications/editor/exec') or "gedit"
         if self._gconf.get_bool("/desktop/gnome/applications/editor/needs_term"):

Modified: trunk/prefs.py
==============================================================================
--- trunk/prefs.py	(original)
+++ trunk/prefs.py	Sat Mar  7 16:31:56 2009
@@ -27,11 +27,15 @@
 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)
+# settings are persistent
 p.color = "blue"
 
 """
 
+import os
+import sys
+
+
 class Value(object):
     """Represents a settable preference.
     """
@@ -48,9 +52,6 @@
         self.default = d
         self.current = d
 
-# maybe fall back to ConfigParser if gconf is unavailable.
-import gconf
-
 # types of values allowed
 BOOL = "bool"
 INT = "int"
@@ -61,8 +62,8 @@
 
 ##
 
-class Preferences(object):
-    """Persistent preferences object.
+class GConfPreferences(object):
+    """Persistent preferences object that handles preferences via gconf.
 
     Example:
     import prefs
@@ -140,3 +141,104 @@
         for k,v in self._prefs.items():
             print k, v.type, v.current
 
+
+class ConfigParserPreferences(object):
+    """Persistent preferences object that handles preferences via ConfigParser.
+
+    This preferences implementation is provided as a fallback for gconf-less
+    platforms. The ConfigParser library is included in Python and should be
+    available everywhere. The biggest drawbacks to this backend are lack of
+    access to desktop-wide settings, and lack of external change notification.
+    """
+
+    def __init__(self, rootkey, initial):
+        """Create a preferences object.
+
+        Settings are initialised with 'initial' and then overriden
+        from values in the ConfigParser database if available.
+
+        rootkey : unused (retained for compatibility with existing gconf API)
+        initial : a dictionary of string to Value objects.
+        """
+        self.__dict__["_parser"] = ConfigParser.SafeConfigParser()
+        self.__dict__["_listeners"] = []
+        self.__dict__["_prefs"] = initial
+        self.__dict__["_type_mappings"] = {
+            BOOL   : self._parser.getboolean,
+            INT    : self._parser.getint,
+            STRING : self._parser.get,
+            FLOAT  : self._parser.getfloat
+        }
+
+        if sys.platform == "win32":
+            pref_dir = os.path.join(os.getenv("APPDATA"), "Meld")
+        else:
+            pref_dir = os.path.join(os.path.expanduser("~"), ".meld")
+
+        if not os.path.exists(pref_dir):
+            os.makedirs(pref_dir)
+
+        self.__dict__["_file_path"] = os.path.join(pref_dir, "meldrc.ini")
+
+        try:
+            config_file = open(self._file_path, "r")
+            try:
+                self._parser.readfp(config_file)
+            finally:
+                config_file.close()
+        except IOError:
+            pass
+
+        for key, value in self._prefs.items():
+            if self._parser.has_option("DEFAULT", key):
+                value.current = self._type_mappings[value.type]("DEFAULT", 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
+            self._parser.set(None, attr, str(val))
+
+            try:
+                fp = open(self._file_path, "w")
+                try:
+                    self._parser.write(fp)
+                finally:
+                    fp.close()
+            except IOError:
+                pass
+
+            try:
+                for l in self._listeners:
+                    l(attr, val)
+            except StopIteration:
+                pass
+
+    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
+
+# Prefer gconf, falling back to ConfigParser
+try:
+    import gconf
+    Preferences = GConfPreferences
+except ImportError:
+    import ConfigParser
+    Preferences = ConfigParserPreferences
+



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]