* modest-conf-gconf.c => modest-conf.c
[modest] / src / modest-conf-gconf.c
1 /* Copyright (c) 2006, Nokia Corporation
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  *   notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  *   notice, this list of conditions and the following disclaimer in the
12  *   documentation and/or other materials provided with the distribution.
13  * * Neither the name of the Nokia Corporation nor the names of its
14  *   contributors may be used to endorse or promote products derived from
15  *   this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30
31 /* modest-conf-gconf.c */
32 /* GConf implementation of ModestConf */
33
34 #include "modest-conf.h"
35 #include "modest-marshal.h"
36 #include <gconf/gconf-client.h>
37
38
39 /* 'private'/'protected' functions */
40 static void   modest_conf_class_init     (ModestConfClass *klass);
41 static void   modest_conf_init           (ModestConf *obj);
42 static void   modest_conf_finalize       (GObject *obj);
43
44 static void   modest_conf_on_change      (GConfClient *client, guint conn_id,
45                                           GConfEntry *entry, gpointer data);
46 /* list my signals */
47 enum {
48         KEY_CHANGED_SIGNAL,
49         LAST_SIGNAL
50 };
51
52 typedef struct _ModestConfPrivate ModestConfPrivate;
53 struct _ModestConfPrivate {
54         GConfClient *gconf_client;
55 };
56 #define MODEST_CONF_GET_PRIVATE(o)      (G_TYPE_INSTANCE_GET_PRIVATE((o), \
57                                          MODEST_TYPE_CONF, \
58                                          ModestConfPrivate))
59 /* globals */
60 static GObjectClass *parent_class = NULL;
61
62 static guint signals[LAST_SIGNAL] = {0};
63
64 void 
65 modest_conf_key_changed (ModestConf* self, const gchar *key, const gchar *new_value)
66 {
67         g_signal_emit (self, signals[KEY_CHANGED_SIGNAL], 0, key, new_value);
68 }
69
70
71 GType
72 modest_conf_get_type (void)
73 {
74         static GType my_type = 0;
75         if (!my_type) {
76                 static const GTypeInfo my_info = {
77                         sizeof(ModestConfClass),
78                         NULL,           /* base init */
79                         NULL,           /* base finalize */
80                         (GClassInitFunc) modest_conf_class_init,
81                         NULL,           /* class finalize */
82                         NULL,           /* class data */
83                         sizeof(ModestConf),
84                         1,              /* n_preallocs */
85                         (GInstanceInitFunc) modest_conf_init,
86                 };
87                 my_type = g_type_register_static (G_TYPE_OBJECT,
88                                                   "ModestConf",
89                                                   &my_info, 0);
90         }
91         return my_type;
92 }
93
94 static void
95 modest_conf_class_init (ModestConfClass *klass)
96 {
97         GObjectClass *gobject_class;
98         gobject_class = (GObjectClass*) klass;
99         GType paramtypes[2] = {G_TYPE_POINTER, G_TYPE_POINTER};
100
101         parent_class            = g_type_class_peek_parent (klass);
102         gobject_class->finalize = modest_conf_finalize;
103
104         g_type_class_add_private (gobject_class, sizeof(ModestConfPrivate));
105         
106         klass->key_changed = modest_conf_key_changed;
107
108         signals[KEY_CHANGED_SIGNAL] = 
109                 g_signal_newv ("key-changed", 
110                                G_TYPE_FROM_CLASS (gobject_class), G_SIGNAL_RUN_LAST,
111                                NULL, NULL, NULL,
112                                modest_marshal_VOID__POINTER_POINTER,
113                                G_TYPE_NONE, 2, paramtypes);
114 }
115
116 static void
117 modest_conf_init (ModestConf *obj)
118 {
119         GConfClient *conf = NULL;
120         ModestConfPrivate *priv = MODEST_CONF_GET_PRIVATE(obj);
121         GError *err      = NULL;
122         
123         priv->gconf_client = NULL;
124         
125         conf = gconf_client_get_default ();
126         if (!conf) {
127                 g_warning ("could not get gconf client");
128                 return;
129         }
130
131         /* FIXME: is PRELOAD_NONE the most efficient? */
132         gconf_client_add_dir (conf, MODEST_CONF_NAMESPACE,
133                               GCONF_CLIENT_PRELOAD_NONE, &err);
134         if (err) {
135                 g_warning ("error with gconf_client_add_dir: %d:%s",
136                            err->code, err->message);
137                 g_object_unref (conf);
138                 g_error_free (err);
139                 return;
140         }
141
142         gconf_client_notify_add (conf, MODEST_CONF_NAMESPACE,
143                                  modest_conf_on_change,
144                                  obj, NULL, &err);
145         if (err) {
146                 g_warning ("error with gconf_client_notify_add: %d:%s",
147                            err->code, err->message);
148                 g_object_unref (conf);
149                 g_error_free (err);
150                 return;
151         }
152
153         /* all went well! */
154         priv->gconf_client = conf;
155         return;
156 }
157
158 static void
159 modest_conf_finalize (GObject *obj)
160 {
161         ModestConfPrivate *priv = MODEST_CONF_GET_PRIVATE(obj);
162         if (priv->gconf_client) {
163                 gconf_client_suggest_sync (priv->gconf_client, NULL);
164                 g_object_unref (priv->gconf_client);
165         }       
166 }
167
168 GObject*
169 modest_conf_new (void)
170 {
171         ModestConf *conf = MODEST_CONF(g_object_new(MODEST_TYPE_CONF, NULL));
172         if (!conf) {
173                 g_warning ("failed to init ModestConf (GConf)");
174                 return NULL;
175         }
176
177         ModestConfPrivate *priv = MODEST_CONF_GET_PRIVATE(conf);
178         if (!priv->gconf_client) {
179                 g_warning ("failed to init gconf");
180                 g_object_unref (conf);
181                 return NULL;
182         }
183         
184         return G_OBJECT(conf);
185 }
186
187
188 gchar*
189 modest_conf_get_string (ModestConf* self, const gchar* key, GError **err)
190 {
191         ModestConfPrivate *priv;
192         
193         g_return_val_if_fail (self, NULL);
194         g_return_val_if_fail (key,  NULL);
195
196         priv = MODEST_CONF_GET_PRIVATE(self);
197         return gconf_client_get_string (priv->gconf_client, key, err);
198 }
199
200
201 gint
202 modest_conf_get_int (ModestConf* self, const gchar* key, GError **err)
203 {
204         ModestConfPrivate *priv;
205
206         g_return_val_if_fail (self, -1);
207         g_return_val_if_fail (key, -1);
208
209         priv = MODEST_CONF_GET_PRIVATE(self);
210         
211         return gconf_client_get_int (priv->gconf_client, key, err);
212 }
213
214
215 gboolean
216 modest_conf_get_bool (ModestConf* self, const gchar* key, GError **err)
217 {
218         ModestConfPrivate *priv;
219
220         g_return_val_if_fail (self, FALSE);
221         g_return_val_if_fail (key, FALSE);
222
223         priv = MODEST_CONF_GET_PRIVATE(self);
224         
225         return gconf_client_get_bool (priv->gconf_client, key, err);
226 }
227
228
229 gboolean
230 modest_conf_set_string (ModestConf* self, const gchar* key, const gchar* val,
231                         GError **err)
232 {
233         ModestConfPrivate *priv;
234                 
235         g_return_val_if_fail (self,FALSE);
236         g_return_val_if_fail (key, FALSE);
237         
238         priv = MODEST_CONF_GET_PRIVATE(self);
239
240         if (!gconf_client_key_is_writable(priv->gconf_client,key,err)) {
241                 g_warning ("'%s' is not writable", key);
242                 return FALSE;
243         }
244                         
245         return gconf_client_set_string (priv->gconf_client, key, val, err);     
246 }
247
248
249 gboolean
250 modest_conf_set_int  (ModestConf* self, const gchar* key, gint val,
251                       GError **err)
252 {
253         ModestConfPrivate *priv;
254                 
255         g_return_val_if_fail (self,FALSE);
256         g_return_val_if_fail (key, FALSE);
257         
258         priv = MODEST_CONF_GET_PRIVATE(self);
259
260         if (!gconf_client_key_is_writable(priv->gconf_client,key,err)) {
261                 g_warning ("'%s' is not writable", key);
262                 return FALSE;
263         }
264                         
265         return gconf_client_set_int (priv->gconf_client, key, val, err);        
266 }
267
268
269 gboolean
270 modest_conf_set_bool (ModestConf* self, const gchar* key, gboolean val,
271                       GError **err)
272 {
273         ModestConfPrivate *priv;
274                 
275         g_return_val_if_fail (self,FALSE);
276         g_return_val_if_fail (key, FALSE);
277         
278         priv = MODEST_CONF_GET_PRIVATE(self);
279
280         if (!gconf_client_key_is_writable(priv->gconf_client,key, err)) {
281                 g_warning ("'%s' is not writable", key);
282                 return FALSE;
283         }
284                         
285         return gconf_client_set_bool (priv->gconf_client,key,val, err);
286 }
287
288
289
290
291 GSList*
292 modest_conf_list_subkeys (ModestConf* self, const gchar* key, GError **err)
293 {
294         ModestConfPrivate *priv;
295                 
296         g_return_val_if_fail (self,FALSE);
297         g_return_val_if_fail (key, FALSE);
298         
299         priv = MODEST_CONF_GET_PRIVATE(self);
300                         
301         return gconf_client_all_dirs (priv->gconf_client,key,err);
302 }
303
304
305 gboolean
306 modest_conf_remove_key (ModestConf* self, const gchar* key, GError **err)
307 {
308         ModestConfPrivate *priv;
309                 
310         g_return_val_if_fail (self,FALSE);
311         g_return_val_if_fail (key, FALSE);
312         
313         priv = MODEST_CONF_GET_PRIVATE(self);
314                         
315         return gconf_client_recursive_unset (priv->gconf_client,key,0,err);
316 }
317
318
319
320
321 gboolean
322 modest_conf_key_exists (ModestConf* self, const gchar* key, GError **err)
323 {
324         ModestConfPrivate *priv;
325         
326         g_return_val_if_fail (self,FALSE);
327         g_return_val_if_fail (key, FALSE);
328         
329         priv = MODEST_CONF_GET_PRIVATE(self);
330                         
331         return gconf_client_dir_exists (priv->gconf_client,key,err);
332 }
333
334
335
336
337
338 static void
339 modest_conf_on_change (GConfClient *client, guint conn_id, GConfEntry *entry,
340                         gpointer data)
341 {
342         ModestConf *modest_conf = data;
343         
344         if (!entry->value) {
345                 g_print ("modest: key '%s' unset\n",
346                          gconf_entry_get_key (entry));
347                 g_signal_emit (modest_conf, signals[KEY_CHANGED_SIGNAL], 0, 
348                                gconf_entry_get_key (entry), NULL);
349         } else {
350                 gchar *val = gconf_value_to_string (gconf_entry_get_value(entry));
351                 g_print ("modest: key '%s' set to '%s'\n",
352                          gconf_entry_get_key (entry), val);
353                 g_signal_emit (modest_conf, signals[KEY_CHANGED_SIGNAL], 0, 
354                                gconf_entry_get_key (entry), val);
355                 g_free (val);
356         }
357 }