* A lot of changes in the documentation, now it's generated correctly
[modest] / src / modest-conf.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 #include <gconf/gconf-client.h>
31 #include <string.h>
32 #include "modest-conf.h"
33 #include "modest-marshal.h"
34
35 static void   modest_conf_class_init     (ModestConfClass *klass);
36 static void   modest_conf_init           (ModestConf *obj);
37 static void   modest_conf_finalize       (GObject *obj);
38 static void   modest_conf_on_change      (GConfClient *client, guint conn_id,
39                                           GConfEntry *entry, gpointer data);
40 /* list my signals */
41 enum {
42         KEY_CHANGED_SIGNAL,
43         LAST_SIGNAL
44 };
45 static guint signals[LAST_SIGNAL] = {0}; 
46
47
48 typedef struct _ModestConfPrivate ModestConfPrivate;
49 struct _ModestConfPrivate {
50         GConfClient *gconf_client;
51 };
52 #define MODEST_CONF_GET_PRIVATE(o)      (G_TYPE_INSTANCE_GET_PRIVATE((o), \
53                                          MODEST_TYPE_CONF, \
54                                          ModestConfPrivate))
55 /* globals */
56 static GObjectClass *parent_class = NULL;
57
58 GType
59 modest_conf_get_type (void)
60 {
61         static GType my_type = 0;
62         if (!my_type) {
63                 static const GTypeInfo my_info = {
64                         sizeof(ModestConfClass),
65                         NULL,           /* base init */
66                         NULL,           /* base finalize */
67                         (GClassInitFunc) modest_conf_class_init,
68                         NULL,           /* class finalize */
69                         NULL,           /* class data */
70                         sizeof(ModestConf),
71                         1,              /* n_preallocs */
72                         (GInstanceInitFunc) modest_conf_init,
73                         NULL
74                 };
75                 my_type = g_type_register_static (G_TYPE_OBJECT,
76                                                   "ModestConf",
77                                                   &my_info, 0);
78         }
79         return my_type;
80 }
81
82 static void
83 modest_conf_class_init (ModestConfClass *klass)
84 {
85         GObjectClass *gobject_class;
86         gobject_class = (GObjectClass*) klass;
87
88         parent_class            = g_type_class_peek_parent (klass);
89         gobject_class->finalize = modest_conf_finalize;
90
91         g_type_class_add_private (gobject_class, sizeof(ModestConfPrivate));
92         
93         signals[KEY_CHANGED_SIGNAL] =
94                 g_signal_new ("key_changed",
95                               G_TYPE_FROM_CLASS (gobject_class),
96                               G_SIGNAL_RUN_FIRST,
97                               G_STRUCT_OFFSET (ModestConfClass,key_changed),
98                               NULL, NULL,
99                               modest_marshal_VOID__STRING_INT,
100                               G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_INT); 
101 }
102
103 static void
104 modest_conf_init (ModestConf *obj)
105 {
106         GConfClient *conf = NULL;
107         ModestConfPrivate *priv = MODEST_CONF_GET_PRIVATE(obj);
108         GError *err      = NULL;
109         
110         priv->gconf_client = NULL;
111         
112         conf = gconf_client_get_default ();
113         if (!conf) {
114                 g_printerr ("modest: could not get gconf client\n");
115                 return;
116         }
117
118         gconf_client_add_dir (conf,MODEST_CONF_NAMESPACE,
119                               GCONF_CLIENT_PRELOAD_NONE,
120                               &err);
121         if (err) {
122                 g_printerr ("modest: error %d with gconf_client_add_dir: '%s'\n",
123                             err->code, err->message);
124                 g_object_unref (conf);
125                 g_error_free (err);
126                 return;
127         }
128         
129         gconf_client_notify_add (conf, MODEST_CONF_NAMESPACE,
130                                  modest_conf_on_change,
131                                  obj, NULL, &err);
132         if (err) {
133                 g_printerr ("modest: gconf_client_notify_add error %d: '%s'\n",
134                             err->code, err->message);
135                 g_object_unref (conf);
136                 g_error_free (err);
137                 return;
138         }
139         
140         priv->gconf_client = conf;      /* all went well! */
141 }
142
143 static void
144 modest_conf_finalize (GObject *obj)
145 {
146         ModestConfPrivate *priv = MODEST_CONF_GET_PRIVATE(obj);
147         if (priv->gconf_client) {
148
149                 gconf_client_suggest_sync (priv->gconf_client, NULL);
150
151                 g_object_unref (priv->gconf_client);
152                 priv->gconf_client = NULL;
153         }       
154 }
155
156 ModestConf*
157 modest_conf_new (void)
158 {
159         ModestConf *conf;
160         ModestConfPrivate *priv;
161         
162         conf = MODEST_CONF(g_object_new(MODEST_TYPE_CONF, NULL));
163         if (!conf) {
164                 g_printerr ("modest: failed to init ModestConf (GConf)\n");
165                 return NULL;
166         }
167
168         priv = MODEST_CONF_GET_PRIVATE(conf);
169         if (!priv->gconf_client) {
170                 g_printerr ("modest: failed to init gconf\n");
171                 g_object_unref (conf);
172                 return NULL;
173         }
174         
175         return conf;
176 }
177
178
179 gchar*
180 modest_conf_get_string (ModestConf* self, const gchar* key, GError **err)
181 {
182         ModestConfPrivate *priv;
183         
184         g_return_val_if_fail (self, NULL);
185         g_return_val_if_fail (key,  NULL);
186
187         priv = MODEST_CONF_GET_PRIVATE(self);
188         return gconf_client_get_string (priv->gconf_client, key, err);
189 }
190
191
192 gint
193 modest_conf_get_int (ModestConf* self, const gchar* key, GError **err)
194 {
195         ModestConfPrivate *priv;
196
197         g_return_val_if_fail (self, -1);
198         g_return_val_if_fail (key, -1);
199
200         priv = MODEST_CONF_GET_PRIVATE(self);
201         
202         return gconf_client_get_int (priv->gconf_client, key, err);
203 }
204
205
206 gboolean
207 modest_conf_get_bool (ModestConf* self, const gchar* key, GError **err)
208 {
209         ModestConfPrivate *priv;
210
211         g_return_val_if_fail (self, FALSE);
212         g_return_val_if_fail (key, FALSE);
213
214         priv = MODEST_CONF_GET_PRIVATE(self);
215         
216         return gconf_client_get_bool (priv->gconf_client, key, err);
217 }
218
219
220
221 gchar*
222 modest_conf_get_string_or_default (ModestConf* self, const gchar* key,
223                                    const gchar *defaultval)
224 {
225         ModestConfPrivate *priv;
226         GConfValue *val;
227         const gchar *str;
228
229         g_return_val_if_fail (self, g_strdup(defaultval));
230         g_return_val_if_fail (key,  g_strdup(defaultval));
231
232         priv = MODEST_CONF_GET_PRIVATE(self);
233         val = gconf_client_get (priv->gconf_client, key, NULL);
234
235         if (!val)
236                 str = defaultval;
237         else {
238                 str = gconf_value_get_string (val);
239                 gconf_value_free (val);
240         }
241         
242         return g_strdup (str);
243 }
244
245
246 gint
247 modest_conf_get_int_or_default (ModestConf* self, const gchar* key,
248                                 gint defaultval)
249 {
250         ModestConfPrivate *priv;
251         GConfValue *val;
252         gint retval;
253         
254         g_return_val_if_fail (self, defaultval);
255         g_return_val_if_fail (key,  defaultval);
256
257         priv = MODEST_CONF_GET_PRIVATE(self);
258         val = gconf_client_get (priv->gconf_client, key, NULL);
259
260         if (!val)
261                 retval = defaultval;
262         else {
263                 retval = gconf_value_get_int (val);
264                 gconf_value_free (val);
265         }       
266
267         return retval;
268 }
269
270
271
272
273 gboolean
274 modest_conf_set_string (ModestConf* self, const gchar* key, const gchar* val,
275                         GError **err)
276 {
277         ModestConfPrivate *priv;
278                 
279         g_return_val_if_fail (self,FALSE);
280         g_return_val_if_fail (key, FALSE);
281         
282         priv = MODEST_CONF_GET_PRIVATE(self);
283
284         if (!gconf_client_key_is_writable(priv->gconf_client,key,err)) {
285                 g_printerr ("modest: '%s' is not writable\n", key);
286                 return FALSE;
287         }
288                         
289         return gconf_client_set_string (priv->gconf_client, key, val, err);     
290 }
291
292
293 gboolean
294 modest_conf_set_int  (ModestConf* self, const gchar* key, gint val,
295                       GError **err)
296 {
297         ModestConfPrivate *priv;
298                 
299         g_return_val_if_fail (self,FALSE);
300         g_return_val_if_fail (key, FALSE);
301         
302         priv = MODEST_CONF_GET_PRIVATE(self);
303
304         if (!gconf_client_key_is_writable(priv->gconf_client,key,err)) {
305                 g_printerr ("modest: '%s' is not writable\n", key);
306                 return FALSE;
307         }
308                         
309         return gconf_client_set_int (priv->gconf_client, key, val, err);        
310 }
311
312
313 gboolean
314 modest_conf_set_bool (ModestConf* self, const gchar* key, gboolean val,
315                       GError **err)
316 {
317         ModestConfPrivate *priv;
318                 
319         g_return_val_if_fail (self,FALSE);
320         g_return_val_if_fail (key, FALSE);
321         
322         priv = MODEST_CONF_GET_PRIVATE(self);
323
324         if (!gconf_client_key_is_writable(priv->gconf_client,key, err)) {
325                 g_warning ("modest: '%s' is not writable\n", key);
326                 return FALSE;
327         }
328                         
329         return gconf_client_set_bool (priv->gconf_client,key,val, err);
330 }
331
332
333
334
335 GSList*
336 modest_conf_list_subkeys (ModestConf* self, const gchar* key, GError **err)
337 {
338         ModestConfPrivate *priv;
339                 
340         g_return_val_if_fail (self,FALSE);
341         g_return_val_if_fail (key, FALSE);
342         
343         priv = MODEST_CONF_GET_PRIVATE(self);
344                         
345         return gconf_client_all_dirs (priv->gconf_client,key,err);
346 }
347
348
349 gboolean
350 modest_conf_remove_key (ModestConf* self, const gchar* key, GError **err)
351 {
352         ModestConfPrivate *priv;
353                 
354         g_return_val_if_fail (self,FALSE);
355         g_return_val_if_fail (key, FALSE);
356         
357         priv = MODEST_CONF_GET_PRIVATE(self);
358                         
359         return gconf_client_recursive_unset (priv->gconf_client,key,0,err);
360 }
361
362
363 gboolean
364 modest_conf_key_exists (ModestConf* self, const gchar* key, GError **err)
365 {
366         ModestConfPrivate *priv;
367         GConfValue *val;
368
369         g_return_val_if_fail (self,FALSE);
370         g_return_val_if_fail (key, FALSE);
371         
372         priv = MODEST_CONF_GET_PRIVATE(self);
373
374         /* the fast way... */
375         if (gconf_client_dir_exists (priv->gconf_client,key,err))
376                 return TRUE;
377         
378         val = gconf_client_get (priv->gconf_client, key, NULL);
379         if (!val)
380                 return FALSE;
381         else {
382                 gconf_value_free (val);
383                 return TRUE;
384         }       
385 }
386
387
388 gchar*
389 modest_conf_key_escape (ModestConf *self, const gchar* key)
390 {
391         g_return_val_if_fail (key, NULL);
392
393         return gconf_escape_key (key, strlen(key));
394 }
395
396
397 gchar*
398 modest_conf_key_unescape (ModestConf *self, const gchar* key)
399 {
400         g_return_val_if_fail (key, NULL);
401
402         return gconf_unescape_key (key, strlen(key));
403 }
404
405
406
407 static void
408 modest_conf_on_change (GConfClient *client, guint conn_id, GConfEntry *entry,
409                        gpointer data)
410 {
411         ModestConfEvent event;
412         const gchar* key;
413
414         event = (entry->value) ? MODEST_CONF_EVENT_KEY_CHANGED : MODEST_CONF_EVENT_KEY_UNSET;
415         key    = gconf_entry_get_key (entry);
416
417         g_signal_emit (G_OBJECT(data),
418                        signals[KEY_CHANGED_SIGNAL], 0,
419                        key, event);
420 }
421
422 GSList * 
423 modest_conf_get_list (ModestConf* self, const gchar* key, ModestConfValueType list_type, GError **err)
424 {
425         ModestConfPrivate *priv;
426         GConfValueType gconf_type;
427         
428         g_return_val_if_fail (self, NULL);
429         g_return_val_if_fail (key,  NULL);
430
431         priv = MODEST_CONF_GET_PRIVATE(self);
432
433         switch (list_type) {
434         case MODEST_CONF_VALUE_INT:
435                 gconf_type = GCONF_VALUE_INT;
436                 break;
437         case MODEST_CONF_VALUE_BOOL:
438                 gconf_type = GCONF_VALUE_BOOL;
439                 break;
440         case MODEST_CONF_VALUE_FLOAT:
441                 gconf_type = GCONF_VALUE_FLOAT;
442                 break;
443         case MODEST_CONF_VALUE_STRING:
444                 gconf_type = GCONF_VALUE_STRING;
445                 break;
446         default:
447                 return NULL;
448         }
449
450         return gconf_client_get_list (priv->gconf_client, key, gconf_type, err);
451 }