* modest-conf-gconf.c => modest-conf.c
[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 "modest-conf.h"
32 #include "modest-marshal.h"
33
34 static void   modest_conf_class_init     (ModestConfClass *klass);
35 static void   modest_conf_init           (ModestConf *obj);
36 static void   modest_conf_finalize       (GObject *obj);
37 static void   modest_conf_on_change      (GConfClient *client, guint conn_id,
38                                           GConfEntry *entry, gpointer data);
39 /* list my signals */
40 enum {
41         KEY_CHANGED_SIGNAL,
42         LAST_SIGNAL
43 };
44 static guint signals[LAST_SIGNAL] = {0}; 
45
46
47 typedef struct _ModestConfPrivate ModestConfPrivate;
48 struct _ModestConfPrivate {
49         GConfClient *gconf_client;
50 };
51 #define MODEST_CONF_GET_PRIVATE(o)      (G_TYPE_INSTANCE_GET_PRIVATE((o), \
52                                          MODEST_TYPE_CONF, \
53                                          ModestConfPrivate))
54 /* globals */
55 static GObjectClass *parent_class = NULL;
56
57 GType
58 modest_conf_get_type (void)
59 {
60         static GType my_type = 0;
61         if (!my_type) {
62                 static const GTypeInfo my_info = {
63                         sizeof(ModestConfClass),
64                         NULL,           /* base init */
65                         NULL,           /* base finalize */
66                         (GClassInitFunc) modest_conf_class_init,
67                         NULL,           /* class finalize */
68                         NULL,           /* class data */
69                         sizeof(ModestConf),
70                         1,              /* n_preallocs */
71                         (GInstanceInitFunc) modest_conf_init,
72                 };
73                 my_type = g_type_register_static (G_TYPE_OBJECT,
74                                                   "ModestConf",
75                                                   &my_info, 0);
76         }
77         return my_type;
78 }
79
80 static void
81 modest_conf_class_init (ModestConfClass *klass)
82 {
83         GObjectClass *gobject_class;
84         gobject_class = (GObjectClass*) klass;
85
86         parent_class            = g_type_class_peek_parent (klass);
87         gobject_class->finalize = modest_conf_finalize;
88
89         g_type_class_add_private (gobject_class, sizeof(ModestConfPrivate));
90         
91         signals[KEY_CHANGED_SIGNAL] =
92                 g_signal_new ("key_changed",
93                               G_TYPE_FROM_CLASS (gobject_class),
94                               G_SIGNAL_RUN_FIRST,
95                               G_STRUCT_OFFSET (ModestConfClass,key_changed),
96                               NULL, NULL,
97                               modest_marshal_VOID__STRING_INT,
98                               G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_INT); 
99 }
100
101 static void
102 modest_conf_init (ModestConf *obj)
103 {
104         GConfClient *conf = NULL;
105         ModestConfPrivate *priv = MODEST_CONF_GET_PRIVATE(obj);
106         GError *err      = NULL;
107         
108         priv->gconf_client = NULL;
109         
110         conf = gconf_client_get_default ();
111         if (!conf) {
112                 g_printerr ("modest: could not get gconf client\n");
113                 return;
114         }
115
116         gconf_client_add_dir (conf,MODEST_CONF_NAMESPACE,
117                               GCONF_CLIENT_PRELOAD_NONE,
118                               &err);
119         if (err) {
120                 g_printerr ("modest: error %d with gconf_client_add_dir: '%s'\n",
121                             err->code, err->message);
122                 g_object_unref (conf);
123                 g_error_free (err);
124                 return;
125         }
126         
127         gconf_client_notify_add (conf, MODEST_CONF_NAMESPACE,
128                                  modest_conf_on_change,
129                                  obj, NULL, &err);
130         if (err) {
131                 g_printerr ("modest: gconf_client_notify_add error %d: '%s'\n",
132                             err->code, err->message);
133                 g_object_unref (conf);
134                 g_error_free (err);
135                 return;
136         }
137         
138         priv->gconf_client = conf;      /* all went well! */
139 }
140
141 static void
142 modest_conf_finalize (GObject *obj)
143 {
144         ModestConfPrivate *priv = MODEST_CONF_GET_PRIVATE(obj);
145         if (priv->gconf_client) {
146
147                 gconf_client_suggest_sync (priv->gconf_client, NULL);
148
149                 g_object_unref (priv->gconf_client);
150                 priv->gconf_client = NULL;
151         }       
152 }
153
154 GObject*
155 modest_conf_new (void)
156 {
157         ModestConf *conf = MODEST_CONF(g_object_new(MODEST_TYPE_CONF, NULL));
158         if (!conf) {
159                 g_printerr ("modest: failed to init ModestConf (GConf)\n");
160                 return NULL;
161         }
162
163         ModestConfPrivate *priv = MODEST_CONF_GET_PRIVATE(conf);
164         if (!priv->gconf_client) {
165                 g_printerr ("modest: failed to init gconf\n");
166                 g_object_unref (conf);
167                 return NULL;
168         }
169         
170         return G_OBJECT(conf);
171 }
172
173
174 gchar*
175 modest_conf_get_string (ModestConf* self, const gchar* key, GError **err)
176 {
177         ModestConfPrivate *priv;
178         
179         g_return_val_if_fail (self, NULL);
180         g_return_val_if_fail (key,  NULL);
181
182         priv = MODEST_CONF_GET_PRIVATE(self);
183         return gconf_client_get_string (priv->gconf_client, key, err);
184 }
185
186
187 gint
188 modest_conf_get_int (ModestConf* self, const gchar* key, GError **err)
189 {
190         ModestConfPrivate *priv;
191
192         g_return_val_if_fail (self, -1);
193         g_return_val_if_fail (key, -1);
194
195         priv = MODEST_CONF_GET_PRIVATE(self);
196         
197         return gconf_client_get_int (priv->gconf_client, key, err);
198 }
199
200
201 gboolean
202 modest_conf_get_bool (ModestConf* self, const gchar* key, GError **err)
203 {
204         ModestConfPrivate *priv;
205
206         g_return_val_if_fail (self, FALSE);
207         g_return_val_if_fail (key, FALSE);
208
209         priv = MODEST_CONF_GET_PRIVATE(self);
210         
211         return gconf_client_get_bool (priv->gconf_client, key, err);
212 }
213
214
215 gboolean
216 modest_conf_set_string (ModestConf* self, const gchar* key, const gchar* val,
217                         GError **err)
218 {
219         ModestConfPrivate *priv;
220                 
221         g_return_val_if_fail (self,FALSE);
222         g_return_val_if_fail (key, FALSE);
223         
224         priv = MODEST_CONF_GET_PRIVATE(self);
225
226         if (!gconf_client_key_is_writable(priv->gconf_client,key,err)) {
227                 g_printerr ("modest: '%s' is not writable\n", key);
228                 return FALSE;
229         }
230                         
231         return gconf_client_set_string (priv->gconf_client, key, val, err);     
232 }
233
234
235 gboolean
236 modest_conf_set_int  (ModestConf* self, const gchar* key, gint val,
237                       GError **err)
238 {
239         ModestConfPrivate *priv;
240                 
241         g_return_val_if_fail (self,FALSE);
242         g_return_val_if_fail (key, FALSE);
243         
244         priv = MODEST_CONF_GET_PRIVATE(self);
245
246         if (!gconf_client_key_is_writable(priv->gconf_client,key,err)) {
247                 g_printerr ("modest: '%s' is not writable\n", key);
248                 return FALSE;
249         }
250                         
251         return gconf_client_set_int (priv->gconf_client, key, val, err);        
252 }
253
254
255 gboolean
256 modest_conf_set_bool (ModestConf* self, const gchar* key, gboolean val,
257                       GError **err)
258 {
259         ModestConfPrivate *priv;
260                 
261         g_return_val_if_fail (self,FALSE);
262         g_return_val_if_fail (key, FALSE);
263         
264         priv = MODEST_CONF_GET_PRIVATE(self);
265
266         if (!gconf_client_key_is_writable(priv->gconf_client,key, err)) {
267                 g_warning ("modest: '%s' is not writable\n", key);
268                 return FALSE;
269         }
270                         
271         return gconf_client_set_bool (priv->gconf_client,key,val, err);
272 }
273
274
275
276
277 GSList*
278 modest_conf_list_subkeys (ModestConf* self, const gchar* key, GError **err)
279 {
280         ModestConfPrivate *priv;
281                 
282         g_return_val_if_fail (self,FALSE);
283         g_return_val_if_fail (key, FALSE);
284         
285         priv = MODEST_CONF_GET_PRIVATE(self);
286                         
287         return gconf_client_all_dirs (priv->gconf_client,key,err);
288 }
289
290
291 gboolean
292 modest_conf_remove_key (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_recursive_unset (priv->gconf_client,key,0,err);
302 }
303
304
305
306
307 gboolean
308 modest_conf_key_exists (ModestConf* self, const gchar* key, GError **err)
309 {
310         ModestConfPrivate *priv;
311         
312         g_return_val_if_fail (self,FALSE);
313         g_return_val_if_fail (key, FALSE);
314         
315         priv = MODEST_CONF_GET_PRIVATE(self);
316                         
317         return gconf_client_dir_exists (priv->gconf_client,key,err);
318 }
319
320
321
322
323
324 static void
325 modest_conf_on_change (GConfClient *client, guint conn_id, GConfEntry *entry,
326                        gpointer data)
327 {
328         ModestConfEvent event;
329         const gchar* key;
330
331         event = (entry->value) ? MODEST_CONF_EVENT_KEY_CHANGED : MODEST_CONF_EVENT_KEY_UNSET;
332         key    = gconf_entry_get_key (entry);
333
334         g_signal_emit (G_OBJECT(data),
335                        signals[KEY_CHANGED_SIGNAL], 0,
336                        key, event);
337 }