X-Git-Url: http://git.maemo.org/git/?a=blobdiff_plain;f=src%2Fmodest-conf.c;h=9b2d95f73f96e48016e1487abb93b5d4e97b2685;hb=38c9c20c5e0fbe81dcb67e4cda31f7bb4ed597b1;hp=5e7f8947ff327a5a116b1b60457d345f647a1743;hpb=d95c7041b38e519a34fb756fe4483f2a731839d6;p=modest diff --git a/src/modest-conf.c b/src/modest-conf.c index 5e7f894..9b2d95f 100644 --- a/src/modest-conf.c +++ b/src/modest-conf.c @@ -28,15 +28,25 @@ */ #include +#include #include +#include #include "modest-conf.h" #include "modest-marshal.h" +#include static void modest_conf_class_init (ModestConfClass *klass); static void modest_conf_init (ModestConf *obj); static void modest_conf_finalize (GObject *obj); static void modest_conf_on_change (GConfClient *client, guint conn_id, GConfEntry *entry, gpointer data); +static GConfValueType modest_conf_type_to_gconf_type (ModestConfValueType value_type, + GError **err); + + +static void +modest_conf_maemo_fake_on_change (ModestConf *conf, const gchar* key, ModestConfEvent event); + /* list my signals */ enum { KEY_CHANGED_SIGNAL, @@ -50,8 +60,8 @@ struct _ModestConfPrivate { GConfClient *gconf_client; }; #define MODEST_CONF_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \ - MODEST_TYPE_CONF, \ - ModestConfPrivate)) + MODEST_TYPE_CONF, \ + ModestConfPrivate)) /* globals */ static GObjectClass *parent_class = NULL; @@ -70,6 +80,7 @@ modest_conf_get_type (void) sizeof(ModestConf), 1, /* n_preallocs */ (GInstanceInitFunc) modest_conf_init, + NULL }; my_type = g_type_register_static (G_TYPE_OBJECT, "ModestConf", @@ -105,6 +116,7 @@ modest_conf_init (ModestConf *obj) GConfClient *conf = NULL; ModestConfPrivate *priv = MODEST_CONF_GET_PRIVATE(obj); GError *err = NULL; + priv->gconf_client = NULL; @@ -113,7 +125,6 @@ modest_conf_init (ModestConf *obj) g_printerr ("modest: could not get gconf client\n"); return; } - gconf_client_add_dir (conf,MODEST_CONF_NAMESPACE, GCONF_CLIENT_PRELOAD_NONE, &err); @@ -135,7 +146,6 @@ modest_conf_init (ModestConf *obj) g_error_free (err); return; } - priv->gconf_client = conf; /* all went well! */ } @@ -150,25 +160,30 @@ modest_conf_finalize (GObject *obj) g_object_unref (priv->gconf_client); priv->gconf_client = NULL; } + + G_OBJECT_CLASS(parent_class)->finalize (obj); } -GObject* +ModestConf* modest_conf_new (void) { - ModestConf *conf = MODEST_CONF(g_object_new(MODEST_TYPE_CONF, NULL)); + ModestConf *conf; + ModestConfPrivate *priv; + + conf = MODEST_CONF(g_object_new(MODEST_TYPE_CONF, NULL)); if (!conf) { g_printerr ("modest: failed to init ModestConf (GConf)\n"); return NULL; } - ModestConfPrivate *priv = MODEST_CONF_GET_PRIVATE(conf); + priv = MODEST_CONF_GET_PRIVATE(conf); if (!priv->gconf_client) { g_printerr ("modest: failed to init gconf\n"); g_object_unref (conf); return NULL; } - return G_OBJECT(conf); + return conf; } @@ -213,6 +228,26 @@ modest_conf_get_bool (ModestConf* self, const gchar* key, GError **err) } +GSList * +modest_conf_get_list (ModestConf* self, const gchar* key, ModestConfValueType list_type, + GError **err) +{ + ModestConfPrivate *priv; + GConfValueType gconf_type; + + g_return_val_if_fail (self, NULL); + g_return_val_if_fail (key, NULL); + + priv = MODEST_CONF_GET_PRIVATE(self); + + gconf_type = modest_conf_type_to_gconf_type (list_type, err); + + return gconf_client_get_list (priv->gconf_client, key, gconf_type, err); +} + + + + gboolean modest_conf_set_string (ModestConf* self, const gchar* key, const gchar* val, GError **err) @@ -221,6 +256,7 @@ modest_conf_set_string (ModestConf* self, const gchar* key, const gchar* val, g_return_val_if_fail (self,FALSE); g_return_val_if_fail (key, FALSE); + g_return_val_if_fail (val, FALSE); priv = MODEST_CONF_GET_PRIVATE(self); @@ -229,7 +265,11 @@ modest_conf_set_string (ModestConf* self, const gchar* key, const gchar* val, return FALSE; } - return gconf_client_set_string (priv->gconf_client, key, val, err); + if (gconf_client_set_string (priv->gconf_client, key, val, err)) { + modest_conf_maemo_fake_on_change (self, key, MODEST_CONF_EVENT_KEY_CHANGED); + return TRUE; + } else + return FALSE; } @@ -249,7 +289,11 @@ modest_conf_set_int (ModestConf* self, const gchar* key, gint val, return FALSE; } - return gconf_client_set_int (priv->gconf_client, key, val, err); + if (gconf_client_set_int (priv->gconf_client, key, val, err)) { + modest_conf_maemo_fake_on_change (self, key, MODEST_CONF_EVENT_KEY_CHANGED); + return TRUE; + } else + return FALSE; } @@ -268,11 +312,59 @@ modest_conf_set_bool (ModestConf* self, const gchar* key, gboolean val, g_warning ("modest: '%s' is not writable\n", key); return FALSE; } - - return gconf_client_set_bool (priv->gconf_client,key,val, err); + + if (gconf_client_set_bool (priv->gconf_client, key, val, err)) { + modest_conf_maemo_fake_on_change (self, key, MODEST_CONF_EVENT_KEY_CHANGED); + return TRUE; + } else + return FALSE; } +gboolean +modest_conf_set_list (ModestConf* self, const gchar* key, + GSList *val, ModestConfValueType list_type, + GError **err) +{ + ModestConfPrivate *priv; + GConfValueType gconf_type; + gboolean result; + + g_return_val_if_fail (self, FALSE); + g_return_val_if_fail (key, FALSE); + + priv = MODEST_CONF_GET_PRIVATE(self); + + gconf_type = modest_conf_type_to_gconf_type (list_type, err); + if (*err) + return FALSE; + + result = gconf_client_set_list (priv->gconf_client, key, gconf_type, val, err); + if(*err) { + g_warning("gconf_client_set_list() failed with key=%s. error=%s", key, + (*err)->message); + result = FALSE; + } + + /* TODO: Remove this, when we fix the problem: */ + /* This shows that sometimes set_list fails, while saying that it succeeded: */ + if (result) { + const gint debug_list_length_start = g_slist_length(val); + GSList* debug_list = gconf_client_get_list(priv->gconf_client, key, gconf_type, err); + const gint debug_list_length_after = g_slist_length(debug_list); + + if(debug_list_length_start != debug_list_length_after) + g_warning("modest_conf_set_list(): The list length after setting is " + "not the same as the specified list. key=%s. " + "We think that we fixed this, so tell us if you see this.", key); + g_slist_free(debug_list); + } + + if (result) + modest_conf_maemo_fake_on_change (self, key, MODEST_CONF_EVENT_KEY_CHANGED); + + return result; +} GSList* @@ -293,51 +385,74 @@ gboolean modest_conf_remove_key (ModestConf* self, const gchar* key, GError **err) { ModestConfPrivate *priv; - + gboolean retval; + g_return_val_if_fail (self,FALSE); g_return_val_if_fail (key, FALSE); priv = MODEST_CONF_GET_PRIVATE(self); - return gconf_client_recursive_unset (priv->gconf_client,key,0,err); -} - + retval = gconf_client_recursive_unset (priv->gconf_client,key,0,err); + gconf_client_suggest_sync (priv->gconf_client, NULL); + if (retval) { + modest_conf_maemo_fake_on_change (self, key, MODEST_CONF_EVENT_KEY_UNSET); + return TRUE; + } else + return FALSE; +} gboolean modest_conf_key_exists (ModestConf* self, const gchar* key, GError **err) { ModestConfPrivate *priv; - + GConfValue *val; + g_return_val_if_fail (self,FALSE); g_return_val_if_fail (key, FALSE); priv = MODEST_CONF_GET_PRIVATE(self); - - return gconf_client_dir_exists (priv->gconf_client,key,err); + + /* the fast way... */ + if (gconf_client_dir_exists (priv->gconf_client,key,err)) + return TRUE; + + val = gconf_client_get (priv->gconf_client, key, NULL); + if (!val) + return FALSE; + else { + gconf_value_free (val); + return TRUE; + } } gchar* -modest_conf_key_escape (ModestConf *self, const gchar* key) +modest_conf_key_escape (const gchar* key) { g_return_val_if_fail (key, NULL); - + g_return_val_if_fail (strlen (key) > 0, g_strdup (key)); + return gconf_escape_key (key, strlen(key)); } gchar* -modest_conf_key_unescape (ModestConf *self, const gchar* key) +modest_conf_key_unescape (const gchar* key) { g_return_val_if_fail (key, NULL); return gconf_unescape_key (key, strlen(key)); } +gboolean +modest_conf_key_is_valid (const gchar* key) +{ + return gconf_valid_key (key, NULL); +} - +/* hmmm... might need to make specific callback for specific keys */ static void modest_conf_on_change (GConfClient *client, guint conn_id, GConfEntry *entry, gpointer data) @@ -352,3 +467,106 @@ modest_conf_on_change (GConfClient *client, guint conn_id, GConfEntry *entry, signals[KEY_CHANGED_SIGNAL], 0, key, event); } + + +static GConfValueType +modest_conf_type_to_gconf_type (ModestConfValueType value_type, GError **err) +{ + GConfValueType gconf_type; + + switch (value_type) { + case MODEST_CONF_VALUE_INT: + gconf_type = GCONF_VALUE_INT; + break; + case MODEST_CONF_VALUE_BOOL: + gconf_type = GCONF_VALUE_BOOL; + break; + case MODEST_CONF_VALUE_FLOAT: + gconf_type = GCONF_VALUE_FLOAT; + break; + case MODEST_CONF_VALUE_STRING: + gconf_type = GCONF_VALUE_STRING; + break; + default: + /* FIXME: use MODEST_ERROR, and error code */ + gconf_type = GCONF_VALUE_INVALID; + g_printerr ("modest: invalid list value type %d\n", value_type); + *err = g_error_new_literal (0, 0, "invalid list value type"); + } + return gconf_type; +} + + + +//////////////////////////////////////////////////////////////////////////////// +/* workaround for the b0rked dbus-gconf on maemo */ +/* fires a fake change notification after 0.3 secs. + * Might not be necessary anymore. */ +#if 0 +#ifdef MODEST_PLATFORM_MAEMO +typedef struct { + GObject *obj; + gchar *key; +} ChangeHelper; + +ChangeHelper* +change_helper_new (ModestConf *conf, const gchar *key) +{ + ChangeHelper *helper = g_slice_alloc (sizeof(ChangeHelper)); + helper->obj = g_object_ref(G_OBJECT(conf)); + helper->key = g_strdup (key); + return helper; +} + +static void +change_helper_free (ChangeHelper *helper) +{ + g_object_unref (helper->obj); + g_free (helper->key); + helper->key = NULL; + helper->obj = NULL; + g_slice_free (ChangeHelper,helper); +} + +static gboolean +emit_change_cb (ChangeHelper *helper) +{ + if (!helper) + return FALSE; + g_signal_emit (G_OBJECT(helper->obj),signals[KEY_CHANGED_SIGNAL], 0, + helper->key, MODEST_CONF_EVENT_KEY_CHANGED); + change_helper_free (helper); + + return FALSE; +} + +static gboolean +emit_remove_cb (ChangeHelper *helper) +{ + if (!helper) + return FALSE; + g_signal_emit (G_OBJECT(helper->obj),signals[KEY_CHANGED_SIGNAL], 0, + helper->key, MODEST_CONF_EVENT_KEY_UNSET); + change_helper_free (helper); + + return FALSE; +} +#endif /* MODEST_PLATFORM_MAEMO */ +#endif + +static void +modest_conf_maemo_fake_on_change (ModestConf *conf, const gchar* key, ModestConfEvent event) +{ +/* hack for faster notification, might not be necessary anymore: */ +#if 0 +#ifdef MODEST_PLATFORM_MAEMO + + ChangeHelper *helper = change_helper_new (conf,key); + g_timeout_add (100, /* after 100 ms */ + (event == MODEST_CONF_EVENT_KEY_CHANGED) + ? (GSourceFunc)emit_change_cb : (GSourceFunc)emit_remove_cb, + (gpointer)helper); +#endif /* MODEST_PLATFORM_MAEMO */ +#endif +} +//////////////////////////////////////////////////////////////////////////////////