devhelp r1195 - in trunk: . src



Author: rhult
Date: Fri Oct 10 17:48:26 2008
New Revision: 1195
URL: http://svn.gnome.org/viewvc/devhelp?rev=1195&view=rev

Log:
2008-10-10  Richard Hult  <richard imendio com>

	* src/Makefile.am:
	* src/ige-conf.h:
	* src/ige-conf-private.h:
	* src/ige-conf.c: New file with code to read the installed
	defaults file.

	* src/ige-conf-mac.m: Use the defaults from above here to setup
	defaults for NSUserDefaults.

	* src/ige-conf-gconf.c: Get the highest level dir from the
	defaults instead of hard coding it.


Added:
   trunk/src/ige-conf-private.h
   trunk/src/ige-conf.c
Modified:
   trunk/ChangeLog
   trunk/src/ige-conf-gconf.c
   trunk/src/ige-conf-mac.m
   trunk/src/ige-conf.h

Modified: trunk/src/ige-conf-gconf.c
==============================================================================
--- trunk/src/ige-conf-gconf.c	(original)
+++ trunk/src/ige-conf-gconf.c	Fri Oct 10 17:48:26 2008
@@ -38,8 +38,6 @@
 #define GET_PRIVATE(instance) G_TYPE_INSTANCE_GET_PRIVATE \
   (instance, IGE_TYPE_CONF, IgeConfPriv);
 
-#define CONF_PATH "/apps/devhelp"
-
 static IgeConf *global_conf = NULL;
 
 static void
@@ -49,9 +47,11 @@
 
         priv = GET_PRIVATE (object);
 
+        /* FIXME: Remove added dirs.
         gconf_client_remove_dir (priv->gconf_client,
                                  CONF_PATH,
                                  NULL);
+        */
 
         g_object_unref (priv->gconf_client);
 
@@ -74,15 +74,12 @@
 ige_conf_init (IgeConf *conf)
 {
         IgeConfPriv *priv;
+        GList       *defaults;
+        gchar       *root;
 
         priv = GET_PRIVATE (conf);
 
         priv->gconf_client = gconf_client_get_default ();
-
-        gconf_client_add_dir (priv->gconf_client,
-                              CONF_PATH,
-                              GCONF_CLIENT_PRELOAD_ONELEVEL,
-                              NULL);
 }
 
 IgeConf *
@@ -95,6 +92,25 @@
         return global_conf;
 }
 
+void
+ige_conf_add_defaults (IgeConf     *conf,
+                       const gchar *path)
+{
+        GList *defaults;
+        gchar *root;
+
+        defaults = _ige_conf_defaults_read_file (path, NULL);
+        root = _ige_conf_defaults_get_root (defaults);
+
+        gconf_client_add_dir (priv->gconf_client,
+                              root,
+                              GCONF_CLIENT_PRELOAD_ONELEVEL,
+                              NULL);
+
+        g_free (root);
+        _ige_conf_defaults_free_list (defaults);
+}
+
 gboolean
 ige_conf_set_int (IgeConf     *conf,
                   const gchar *key,

Modified: trunk/src/ige-conf-mac.m
==============================================================================
--- trunk/src/ige-conf-mac.m	(original)
+++ trunk/src/ige-conf-mac.m	Fri Oct 10 17:48:26 2008
@@ -21,7 +21,7 @@
 #include "config.h"
 #import <Cocoa/Cocoa.h>
 #include <string.h>
-#include "ige-conf.h"
+#include "ige-conf-private.h"
 
 typedef struct {
         NSUserDefaults *defaults;
@@ -33,9 +33,6 @@
         gpointer           user_data;
 } IgeConfNotifyData;
 
-#define POOL_ALLOC   NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]
-#define POOL_RELEASE [pool release]
-
 G_DEFINE_TYPE (IgeConf, ige_conf, G_TYPE_OBJECT);
 
 #define GET_PRIVATE(instance) G_TYPE_INSTANCE_GET_PRIVATE \
@@ -50,6 +47,10 @@
 
         [priv->defaults synchronize];
 
+        if (IGE_CONF (object) == global_conf) {
+                global_conf = NULL;
+        }
+
         G_OBJECT_CLASS (ige_conf_parent_class)->finalize (object);
 }
 
@@ -68,24 +69,16 @@
 static void
 ige_conf_init (IgeConf *conf)
 {
-        IgeConfPriv  *priv = GET_PRIVATE (conf);
-        NSDictionary *dict;
-
-        priv->defaults = [NSUserDefaults standardUserDefaults];
-
-        POOL_ALLOC;
-
-#define CONF_PATH                     "/apps/devhelp"
-#define CONF_UI_MAIN_WINDOW_MAXIMIZED CONF_PATH "/ui/main_window_maximized"
-
-        dict = [NSDictionary dictionaryWithObjectsAndKeys:
-                @"NO", @CONF_UI_MAIN_WINDOW_MAXIMIZED,
-                nil];
+}
 
-        /* Setup defaults. FIXME: Can we do this only when needed? */
-        [priv->defaults registerDefaults: dict];
+static void
+conf_atexit (void)
+{
+        if (global_conf) {
+                IgeConfPriv *priv = GET_PRIVATE (global_conf);
 
-        POOL_RELEASE;
+                [priv->defaults synchronize];
+        }
 }
 
 IgeConf *
@@ -93,11 +86,40 @@
 {
         if (!global_conf) {
                 global_conf = g_object_new (IGE_TYPE_CONF, NULL);
+                g_atexit (conf_atexit);
         }
 
         return global_conf;
 }
 
+void
+ige_conf_add_defaults (IgeConf     *conf,
+                       const gchar *path)
+{
+        IgeConfPriv  *priv = GET_PRIVATE (conf);
+        NSDictionary *dict;
+        GList        *defaults, *l;
+
+        priv->defaults = [NSUserDefaults standardUserDefaults];
+
+        dict = [NSMutableDictionary dictionaryWithCapacity: 10];
+
+        defaults = _ige_conf_defaults_read_file (path, NULL);
+        for (l = defaults; l; l = l->next) {
+                IgeConfDefaultItem *item = l->data;
+                NSString           *key;
+                NSString           *value;
+
+                key = [NSString stringWithUTF8String: item->key];
+                value = [NSString stringWithUTF8String: item->value];
+                [dict setValue:value forKey:key];
+        }
+
+        _ige_conf_defaults_free_list (defaults);
+
+        [priv->defaults registerDefaults: dict];
+}
+
 gboolean
 ige_conf_set_int (IgeConf     *conf,
                   const gchar *key,
@@ -110,13 +132,9 @@
 
         priv = GET_PRIVATE (conf);
 
-        POOL_ALLOC;
-
         string = [NSString stringWithUTF8String: key];
         [priv->defaults setInteger: value forKey: string];
 
-        POOL_RELEASE;
-
         return TRUE;
 }
 
@@ -132,15 +150,9 @@
 
         priv = GET_PRIVATE (conf);
 
-        POOL_ALLOC;
-
         string = [NSString stringWithUTF8String: key];
         *value = [priv->defaults integerForKey: string];
 
-        [priv->defaults synchronize];
-
-        POOL_RELEASE;
-
         return TRUE;
 }
 
@@ -156,15 +168,9 @@
 
         priv = GET_PRIVATE (conf);
 
-        POOL_ALLOC;
-
         string = [NSString stringWithUTF8String: key];
         [priv->defaults setBool: value forKey: string];
 
-        [priv->defaults synchronize];
-
-        POOL_RELEASE;
-
         return TRUE;
 }
 
@@ -180,13 +186,9 @@
 
         priv = GET_PRIVATE (conf);
 
-        POOL_ALLOC;
-
         string = [NSString stringWithUTF8String: key];
         *value = [priv->defaults boolForKey: string];
 
-        POOL_RELEASE;
-
         return TRUE;
 }
 
@@ -202,15 +204,10 @@
 
         priv = GET_PRIVATE (conf);
 
-        POOL_ALLOC;
-
         string = [NSString stringWithUTF8String: key];
         nsvalue = [NSString stringWithUTF8String: value];
-        [priv->defaults setObject: nsvalue forKey: string];
 
-        [priv->defaults synchronize];
-
-        POOL_RELEASE;
+        [priv->defaults setObject: nsvalue forKey: string];
 
         return TRUE;
 }
@@ -227,15 +224,16 @@
 
         priv = GET_PRIVATE (conf);
 
-        POOL_ALLOC;
+        *value = NULL;
 
         string = [NSString stringWithUTF8String: key];
         nsvalue = [priv->defaults stringForKey: string];
+        if (nsvalue == NULL) {
+                return FALSE;
+        }
 
         *value = g_strdup ([nsvalue UTF8String]);
 
-        POOL_RELEASE;
-
         return TRUE;
 }
 

Added: trunk/src/ige-conf-private.h
==============================================================================
--- (empty file)
+++ trunk/src/ige-conf-private.h	Fri Oct 10 17:48:26 2008
@@ -0,0 +1,49 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2008 Imendio AB
+ *
+ * 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.
+ */
+
+#ifndef __IGE_CONF_PRIVATE_H__
+#define __IGE_CONF_PRIVATE_H__
+
+#include <glib.h>
+#include "ige-conf.h"
+
+G_BEGIN_DECLS
+
+typedef enum {
+        IGE_CONF_TYPE_INT,
+        IGE_CONF_TYPE_BOOLEAN,
+        IGE_CONF_TYPE_STRING
+} IgeConfType;
+
+typedef struct {
+        IgeConfType  type;
+        gchar       *key;
+        gchar       *value;
+} IgeConfDefaultItem;
+
+GList *_ige_conf_defaults_read_file (const gchar  *path,
+                                     GError      **error);
+void   _ige_conf_defaults_free_list (GList        *defaults);
+
+const gchar *_ige_conf_defaults_get_root (GList *defaults);
+
+G_END_DECLS
+
+#endif /* __IGE_CONF_PRIVATE_H__ */

Added: trunk/src/ige-conf.c
==============================================================================
--- (empty file)
+++ trunk/src/ige-conf.c	Fri Oct 10 17:48:26 2008
@@ -0,0 +1,269 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2008 Imendio AB
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include <string.h>
+#include "ige-conf-private.h"
+
+typedef struct {
+        GString      *text;
+
+        gchar        *current_key;
+        gchar        *current_value;
+        IgeConfType   current_type;
+
+        GList        *defaults;
+} DefaultData;
+
+#define BYTES_PER_READ 4096
+
+static void
+parser_start_cb (GMarkupParseContext  *context,
+                 const gchar          *node_name,
+                 const gchar         **attribute_names,
+                 const gchar         **attribute_values,
+                 gpointer              user_data,
+                 GError              **error)
+{
+	DefaultData *data = user_data;
+
+        if (g_ascii_strcasecmp (node_name, "applyto") == 0) {
+                data->text = g_string_new (NULL);
+        }
+        else if (g_ascii_strcasecmp (node_name, "type") == 0) {
+                data->text = g_string_new (NULL);
+        }
+        else if (g_ascii_strcasecmp (node_name, "default") == 0) {
+                data->text = g_string_new (NULL);
+        }
+}
+
+static void
+parser_end_cb (GMarkupParseContext  *context,
+               const gchar          *node_name,
+               gpointer              user_data,
+               GError              **error)
+{
+	DefaultData *data = user_data;
+
+        if (g_ascii_strcasecmp (node_name, "schema") == 0) {
+                IgeConfDefaultItem *item;
+
+                item = g_slice_new0 (IgeConfDefaultItem);
+                item->key = data->current_key;
+                item->type = data->current_type;
+
+                switch (item->type) {
+                case IGE_CONF_TYPE_INT:
+                case IGE_CONF_TYPE_STRING:
+                        item->value = g_strdup (data->current_value);
+                        break;
+                case IGE_CONF_TYPE_BOOLEAN:
+                        if (strcmp (data->current_value, "true") == 0) {
+                                item->value = g_strdup ("YES");
+                        } else {
+                                item->value = g_strdup ("NO");
+                        }
+                        break;
+                }
+
+                data->defaults = g_list_prepend (data->defaults, item);
+
+                data->current_key = NULL;
+
+                g_free (data->current_value);
+                data->current_value = NULL;
+        }
+        else if (g_ascii_strcasecmp (node_name, "applyto") == 0) {
+                data->current_key = g_string_free (data->text, FALSE);
+                data->text = NULL;
+        }
+        else if (g_ascii_strcasecmp (node_name, "type") == 0) {
+                gchar *str;
+
+                str = g_string_free (data->text, FALSE);
+                if (strcmp (str, "int") == 0) {
+                        data->current_type = IGE_CONF_TYPE_INT;
+                }
+                else if (strcmp (str, "bool") == 0) {
+                        data->current_type = IGE_CONF_TYPE_BOOLEAN;
+                }
+                else if (strcmp (str, "string") == 0) {
+                        data->current_type = IGE_CONF_TYPE_STRING;
+                }
+
+                g_free (str);
+                data->text = NULL;
+        }
+        else if (g_ascii_strcasecmp (node_name, "default") == 0) {
+                data->current_value = g_string_free (data->text, FALSE);
+                data->text = NULL;
+        }
+}
+
+static void
+parser_text_cb (GMarkupParseContext  *context,
+                const gchar          *text,
+                gsize                 text_len,
+                gpointer              user_data,
+                GError              **error)
+{
+        DefaultData *data = user_data;
+
+        if (data->text) {
+                g_string_append_len (data->text, text, text_len);
+        }
+}
+
+static void
+parser_error_cb (GMarkupParseContext *context,
+		 GError              *error,
+		 gpointer             user_data)
+{
+	g_warning ("Error: %s\n", error->message);
+}
+
+GList *
+_ige_conf_defaults_read_file (const gchar  *path,
+                              GError      **error)
+{
+        DefaultData          data;
+	GMarkupParser       *parser;
+	GMarkupParseContext *context;
+	GIOChannel          *io = NULL;
+	gchar                buf[BYTES_PER_READ];
+
+        io = g_io_channel_new_file (path, "r", error);
+        if (!io) {
+                return NULL;
+        }
+
+	parser = g_new0 (GMarkupParser, 1);
+
+	parser->start_element = parser_start_cb;
+	parser->end_element = parser_end_cb;
+	parser->text = parser_text_cb;
+	parser->error = parser_error_cb;
+
+        memset (&data, 0, sizeof (DefaultData));
+
+	context = g_markup_parse_context_new (parser,
+                                              0,
+                                              &data,
+                                              NULL);
+
+        while (TRUE) {
+                GIOStatus io_status;
+                gsize     bytes_read;
+
+                io_status = g_io_channel_read_chars (io, buf, BYTES_PER_READ,
+                                                     &bytes_read, error);
+                if (io_status == G_IO_STATUS_ERROR) {
+                        goto exit;
+                }
+                if (io_status != G_IO_STATUS_NORMAL) {
+                        break;
+                }
+
+                g_markup_parse_context_parse (context, buf, bytes_read, error);
+                if (error != NULL && *error != NULL) {
+                        goto exit;
+                }
+
+                if (bytes_read < BYTES_PER_READ) {
+                        break;
+                }
+        }
+
+ exit:
+        g_io_channel_unref (io);
+	g_markup_parse_context_free (context);
+	g_free (parser);
+
+	return data.defaults;
+}
+
+void
+_ige_conf_defaults_free_list (GList *defaults)
+{
+        GList *l;
+
+        for (l = defaults; l; l = l->next) {
+                IgeConfDefaultItem *item = l->data;
+
+                g_free (item->value);
+                g_slice_free (IgeConfDefaultItem, item);
+        }
+
+        g_list_free (defaults);
+}
+
+const gchar *
+_ige_conf_defaults_get_root (GList *defaults)
+{
+        GList        *l;
+        const gchar  *root;
+        gchar       **strv_prev = NULL;
+        gint          i;
+        gint          last_common = G_MAXINT;
+
+        for (l = defaults; l; l = l->next) {
+                IgeConfDefaultItem  *item = l->data;
+                gchar              **strv;
+
+                strv = g_strsplit (item->key, "/", 0);
+                if (strv_prev == NULL) {
+                        strv_prev = strv;
+                        continue;
+                }
+
+                i = 0;
+                while (strv[i] && strv_prev[i] && i < last_common) {
+                        if (strcmp (strv[i], strv_prev[i]) != 0) {
+                                last_common = i;
+                                break;
+                        }
+                        i++;
+                }
+
+                g_strfreev (strv_prev);
+                strv_prev = strv;
+        }
+
+        if (strv_prev) {
+                GString *str;
+
+                str = g_string_new (NULL);
+                i = 0;
+                while (strv_prev[i] && i < last_common) {
+                        if (strv_prev[i][0] != '\0') {
+                                g_string_append_c (str, '/');
+                                g_string_append (str, strv_prev[i]);
+                        }
+                        i++;
+                }
+                root = g_string_free (str, FALSE);
+                g_strfreev (strv_prev);
+        } else {
+                root = g_strdup ("/");
+        }
+
+        return root;
+}

Modified: trunk/src/ige-conf.h
==============================================================================
--- trunk/src/ige-conf.h	(original)
+++ trunk/src/ige-conf.h	Fri Oct 10 17:48:26 2008
@@ -36,7 +36,7 @@
 typedef struct _IgeConfClass IgeConfClass;
 
 struct _IgeConf  {
-        GObject parent;
+        GObject parent_instance;
 };
 
 struct _IgeConfClass {
@@ -49,6 +49,8 @@
 
 GType       ige_conf_get_type        (void);
 IgeConf    *ige_conf_get             (void);
+void        ige_conf_add_defaults    (IgeConf            *conf,
+				      const gchar        *path);
 guint       ige_conf_notify_add      (IgeConf            *conf,
                                       const gchar        *key,
                                       IgeConfNotifyFunc   func,



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