aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRodrigo Moya <rodrigo@ximian.com>2002-08-20 22:04:03 +0800
committerRodrigo Moya <rodrigo@src.gnome.org>2002-08-20 22:04:03 +0800
commit809fdd0e3e313c1143cdc32ead6649afbc5bc7f6 (patch)
tree67589f6637ed51a25f347cdeed2a879c3ec084f5
parent124958ab47828e803faf551e1e93b40647c01bf9 (diff)
downloadgsoc2013-evolution-809fdd0e3e313c1143cdc32ead6649afbc5bc7f6.tar.gz
gsoc2013-evolution-809fdd0e3e313c1143cdc32ead6649afbc5bc7f6.tar.zst
gsoc2013-evolution-809fdd0e3e313c1143cdc32ead6649afbc5bc7f6.zip
new class for config database access and monitoring.
2002-08-16 Rodrigo Moya <rodrigo@ximian.com> * e-config-listener.[ch]: new class for config database access and monitoring. * Makefile.am: added new files. svn path=/trunk/; revision=17816
-rw-r--r--e-util/ChangeLog7
-rw-r--r--e-util/Makefile.am2
-rw-r--r--e-util/e-config-listener.c313
-rw-r--r--e-util/e-config-listener.h53
4 files changed, 375 insertions, 0 deletions
diff --git a/e-util/ChangeLog b/e-util/ChangeLog
index bac53db150..26e78fb47f 100644
--- a/e-util/ChangeLog
+++ b/e-util/ChangeLog
@@ -1,3 +1,10 @@
+2002-08-16 Rodrigo Moya <rodrigo@ximian.com>
+
+ * e-config-listener.[ch]: new class for config database access and
+ monitoring.
+
+ * Makefile.am: added new files.
+
2002-08-14 Rodrigo Moya <rodrigo@ximian.com>
* e-component-listener.[ch]: new class for controlling a component,
diff --git a/e-util/Makefile.am b/e-util/Makefile.am
index f2283b3a0f..75481cdfcf 100644
--- a/e-util/Makefile.am
+++ b/e-util/Makefile.am
@@ -23,6 +23,7 @@ eutilinclude_HEADERS = \
e-categories-master-list-wombat.h \
e-categories-config.h \
e-component-listener.h \
+ e-config-listener.h \
e-corba-utils.h \
e-dialog-utils.h \
e-dialog-widgets.h \
@@ -51,6 +52,7 @@ libeutil_la_SOURCES = \
e-categories-master-list-wombat.c \
e-categories-config.c \
e-component-listener.c \
+ e-config-listener.c \
e-corba-utils.c \
e-dialog-utils.c \
e-dialog-widgets.c \
diff --git a/e-util/e-config-listener.c b/e-util/e-config-listener.c
new file mode 100644
index 0000000000..e6fd8dbb9c
--- /dev/null
+++ b/e-util/e-config-listener.c
@@ -0,0 +1,313 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Configuration component listener
+ *
+ * Author:
+ * Rodrigo Moya <rodrigo@ximian.com>
+ *
+ * Copyright 2002, Ximian, Inc.
+ */
+
+#include <gtk/gtktypeutils.h>
+#include <bonobo/bonobo-exception.h>
+#include <bonobo/bonobo-event-source.h>
+#include <bonobo/bonobo-moniker-util.h>
+#include <bonobo/bonobo-object.h>
+#include "e-config-listener.h"
+
+#define PARENT_TYPE GTK_TYPE_OBJECT
+
+typedef struct {
+ EConfigListener *cl;
+ char *key;
+ GtkFundamentalType type;
+ union {
+ char *v_str;
+ gboolean v_bool;
+ } value;
+ gboolean used_default;
+} KeyData;
+
+struct _EConfigListenerPrivate {
+ Bonobo_ConfigDatabase db;
+ GHashTable *keys;
+};
+
+static void e_config_listener_class_init (EConfigListenerClass *klass);
+static void e_config_listener_init (EConfigListener *cl);
+static void e_config_listener_destroy (GtkObject *object);
+
+static GtkObjectClass *parent_class = NULL;
+
+static void
+e_config_listener_class_init (EConfigListenerClass *klass)
+{
+ GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass);
+
+ parent_class = gtk_type_class (PARENT_TYPE);
+
+ object_class->destroy = e_config_listener_destroy;
+}
+
+static void
+e_config_listener_init (EConfigListener *cl)
+{
+ CORBA_Environment ev;
+
+ /* allocate internal structure */
+ cl->priv = g_new0 (EConfigListenerPrivate, 1);
+
+ cl->priv->keys = g_hash_table_new (g_str_hash, g_str_equal);
+
+ /* activate the configuration database */
+ CORBA_exception_init (&ev);
+ cl->priv->db = bonobo_get_object ("wombat:", "Bonobo/ConfigDatabase", &ev);
+
+ if (BONOBO_EX (&ev) || cl->priv->db == CORBA_OBJECT_NIL) {
+ CORBA_exception_free (&ev);
+ cl->priv->db = CORBA_OBJECT_NIL;
+ }
+}
+
+static void
+free_key_hash (gpointer key, gpointer value, gpointer user_data)
+{
+ KeyData *kd = (KeyData *) value;
+
+ g_return_if_fail (kd != NULL);
+
+ g_free (kd->key);
+ switch (kd->type) {
+ case GTK_TYPE_STRING :
+ g_free (kd->value.v_str);
+ break;
+ default :
+ }
+
+ g_free (kd);
+}
+
+static void
+e_config_listener_destroy (GtkObject *object)
+{
+ EConfigListener *cl = (EConfigListener *) object;
+
+ g_return_if_fail (E_IS_CONFIG_LISTENER (cl));
+
+ if (cl->priv->db != CORBA_OBJECT_NIL) {
+ bonobo_object_release_unref (cl->priv->db, NULL);
+ cl->priv->db = CORBA_OBJECT_NIL;
+ }
+
+ g_hash_table_foreach (cl->priv->keys, (GHFunc) free_key_hash, NULL);
+ g_hash_table_destroy (cl->priv->keys);
+ cl->priv->keys = NULL;
+
+ g_free (cl->priv);
+ cl->priv = NULL;
+
+ if (GTK_OBJECT_CLASS (parent_class)->destroy)
+ (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+GtkType
+e_config_listener_get_type (void)
+{
+ static GtkType type = 0;
+
+ if (!type) {
+ static const GtkTypeInfo info = {
+ "EConfigListener",
+ sizeof (EConfigListener),
+ sizeof (EConfigListenerClass),
+ (GtkClassInitFunc) e_config_listener_class_init,
+ (GtkObjectInitFunc) e_config_listener_init,
+ NULL, /* reserved_1 */
+ NULL, /* reserved_2 */
+ (GtkClassInitFunc) NULL
+ };
+
+ type = gtk_type_unique (PARENT_TYPE, &info);
+ }
+
+ return type;
+}
+
+/**
+ * e_config_listener_new
+ *
+ * Create a new configuration listener, which is an object which
+ * allows to listen for changes in the configuration database. It keeps
+ * an updated copy of all requested configuration entries, so that
+ * access is much quicker and instantaneous.
+ *
+ * Returns: the newly created listener.
+ */
+EConfigListener *
+e_config_listener_new (void)
+{
+ EConfigListener *cl;
+
+ cl = gtk_type_new (E_CONFIG_LISTENER_TYPE);
+ return cl;
+}
+
+static void
+property_change_cb (BonoboListener *listener,
+ char *event_name,
+ CORBA_any *any,
+ CORBA_Environment *ev,
+ gpointer user_data)
+{
+ KeyData *kd = (KeyData *) user_data;
+
+ g_return_if_fail (any != NULL);
+ g_return_if_fail (kd != NULL);
+
+ /* free previous value */
+ if (kd->type == GTK_TYPE_STRING)
+ g_free (kd->value.v_str);
+
+ /* set new value */
+ if (bonobo_arg_type_is_equal (any->_type, BONOBO_ARG_BOOLEAN, NULL)) {
+ kd->type = GTK_TYPE_BOOL;
+ kd->value.v_bool = BONOBO_ARG_GET_BOOLEAN (any);
+ } else if (bonobo_arg_type_is_equal (any->_type, BONOBO_ARG_STRING, NULL)) {
+ kd->type = GTK_TYPE_STRING;
+ kd->value.v_str = g_strdup (BONOBO_ARG_GET_STRING (any));
+ } else
+ return;
+}
+
+static KeyData *
+add_key (EConfigListener *cl, const char *key, GtkFundamentalType type,
+ gpointer value, gboolean used_default)
+{
+ KeyData *kd;
+ char *event_name;
+ CORBA_Environment ev;
+
+ /* add the key to our hash table */
+ kd = g_new0 (KeyData, 1);
+ kd->cl = cl;
+ kd->key = g_strdup (key);
+ kd->type = type;
+ switch (type) {
+ case GTK_TYPE_BOOL :
+ memcpy (&kd->value.v_bool, value, sizeof (gboolean));
+ break;
+ case GTK_TYPE_STRING :
+ kd->value.v_str = (char *) value;
+ break;
+ default :
+ }
+
+ kd->used_default = used_default;
+
+ /* add the listener for changes */
+ event_name = g_strdup_printf ("=Bonobo/ConfigDatabase:change%s",
+ kd->key);
+
+ CORBA_exception_init (&ev);
+ bonobo_event_source_client_add_listener (
+ cl->priv->db,
+ property_change_cb,
+ event_name,
+ &ev, kd);
+ if (BONOBO_EX (&ev)) {
+ CORBA_exception_free (&ev);
+ free_key_hash (kd->key, kd, NULL);
+ return NULL;
+ }
+
+ g_hash_table_insert (cl->priv->keys, kd->key, kd);
+
+ CORBA_exception_free (&ev);
+ g_free (event_name);
+
+ return kd;
+}
+
+char *
+e_config_listener_get_string_with_default (EConfigListener *cl,
+ const char *key,
+ const char *def,
+ gboolean *used_default)
+{
+ char *str;
+ KeyData *kd;
+ gboolean d;
+ gpointer orig_key, orig_value;
+
+ g_return_val_if_fail (E_IS_CONFIG_LISTENER (cl), NULL);
+ g_return_val_if_fail (key != NULL, NULL);
+
+ /* search for the key in our hash table */
+ if (!g_hash_table_lookup_extended (cl->priv->keys, key, &orig_key, &orig_value)) {
+ /* not found, so retrieve it from the configuration database */
+ str = bonobo_config_get_string_with_default (cl->priv->db, key, (char *) def, &d);
+ if (str) {
+ kd = add_key (cl, key, GTK_TYPE_STRING, (gpointer) str, d);
+
+ if (used_default != NULL)
+ *used_default = d;
+ } else
+ return NULL;
+ } else {
+ kd = (KeyData *) orig_value;
+ g_assert (kd != NULL);
+
+ if (kd->type == GTK_TYPE_STRING) {
+ str = g_strdup (kd->value.v_str);
+ if (used_default != NULL)
+ *used_default = kd->used_default;
+ } else
+ return NULL;
+ }
+
+ return str;
+}
+
+gboolean
+e_config_listener_get_boolean_with_default (EConfigListener *cl,
+ const char *key,
+ gboolean def,
+ gboolean *used_default)
+{
+ gboolean value;
+ KeyData *kd;
+ gboolean d;
+ gpointer orig_key, orig_value;
+
+ g_return_val_if_fail (E_IS_CONFIG_LISTENER (cl), FALSE);
+ g_return_val_if_fail (key != NULL, FALSE);
+
+ /* search for the key in our hash table */
+ if (!g_hash_table_lookup_extended (cl->priv->keys, key, &orig_key, &orig_value)) {
+ /* not found, so retrieve it from the configuration database */
+ value = bonobo_config_get_boolean_with_default (cl->priv->db, key, def, &d);
+ kd = add_key (cl, key, GTK_TYPE_BOOL, &value, d);
+
+ if (used_default != NULL)
+ *used_default = d;
+ } else {
+ kd = (KeyData *) orig_value;
+ g_assert (kd != NULL);
+
+ if (kd->type == GTK_TYPE_BOOL) {
+ value = kd->value.v_bool;
+ if (used_default != NULL)
+ *used_default = kd->used_default;
+ } else
+ return FALSE;
+ }
+
+ return value;
+}
+
+Bonobo_ConfigDatabase
+e_config_listener_get_db (EConfigListener *cl)
+{
+ g_return_val_if_fail (E_IS_CONFIG_LISTENER (cl), CORBA_OBJECT_NIL);
+ return cl->priv->db;
+}
diff --git a/e-util/e-config-listener.h b/e-util/e-config-listener.h
new file mode 100644
index 0000000000..b83565d85f
--- /dev/null
+++ b/e-util/e-config-listener.h
@@ -0,0 +1,53 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Configuration component listener
+ *
+ * Author:
+ * Rodrigo Moya <rodrigo@ximian.com>
+ *
+ * Copyright 2002, Ximian, Inc.
+ */
+
+#ifndef __E_CONFIG_LISTENER_H__
+#define __E_CONFIG_LISTENER_H__
+
+#include <gtk/gtkobject.h>
+#include <libgnome/gnome-defs.h>
+#include <bonobo-conf/bonobo-config-database.h>
+
+BEGIN_GNOME_DECLS
+
+#define E_CONFIG_LISTENER_TYPE (e_config_listener_get_type ())
+#define E_CONFIG_LISTENER(o) (GTK_CHECK_CAST ((o), E_CONFIG_LISTENER_TYPE, EConfigListener))
+#define E_CONFIG_LISTENER_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_CONFIG_LISTENER_TYPE, EConfigListenerClass))
+#define E_IS_CONFIG_LISTENER(o) (GTK_CHECK_TYPE ((o), E_CONFIG_LISTENER_TYPE))
+#define E_IS_CONFIG_LISTENER_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_CONFIG_LISTENER_TYPE))
+
+typedef struct _EConfigListenerPrivate EConfigListenerPrivate;
+
+typedef struct {
+ GtkObject object;
+ EConfigListenerPrivate *priv;
+} EConfigListener;
+
+typedef struct {
+ GtkObjectClass parent_class;
+} EConfigListenerClass;
+
+GtkType e_config_listener_get_type (void);
+EConfigListener *e_config_listener_new (void);
+
+char *e_config_listener_get_string_with_default (EConfigListener *cl,
+ const char *key,
+ const char *def,
+ gboolean *used_default);
+gboolean e_config_listener_get_boolean_with_default (EConfigListener *cl,
+ const char *key,
+ gboolean def,
+ gboolean *used_default);
+
+Bonobo_ConfigDatabase e_config_listener_get_db (EConfigListener *cl);
+
+END_GNOME_DECLS
+
+#endif