source: trunk/third/libgnome/monikers/bonobo-config-bag.c @ 18580

Revision 18580, 13.5 KB checked in by ghudson, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18579, which included commits to RCS files with non-trunk default branches.
Line 
1/**
2 * bonobo-config-bag.c: config bag object implementation.
3 *
4 * Author:
5 *   Dietmar Maurer (dietmar@ximian.com)
6 *   Rodrigo Moya   (rodrigo@ximian.com)
7 *
8 * Copyright 2000 Ximian, Inc.
9 */
10#include <config.h>
11#include <bonobo/Bonobo.h>
12#include <bonobo/bonobo-arg.h>
13#include <bonobo/bonobo-i18n.h>
14#include <bonobo/bonobo-main.h>
15#include <bonobo/bonobo-exception.h>
16#include <string.h>
17
18#include "bonobo-config-bag.h"
19
20#define PARENT_TYPE (BONOBO_TYPE_OBJECT)
21
22#define GET_BAG_FROM_SERVANT(servant) BONOBO_CONFIG_BAG (bonobo_object (servant))
23
24static GObjectClass *parent_class = NULL;
25
26#define CLASS(o) BONOBO_CONFIG_BAG_CLASS (G_OBJECT_GET_CLASS (o))
27
28static void
29bonobo_config_bag_finalize (GObject *object)
30{
31        BonoboConfigBag *cb = BONOBO_CONFIG_BAG (object);
32
33        g_free (cb->path);
34        g_object_unref (G_OBJECT (cb->conf_client));
35
36        parent_class->finalize (object);
37}
38
39static Bonobo_KeyList *
40impl_Bonobo_PropertyBag_getKeys (PortableServer_Servant  servant,
41                                 const CORBA_char       *filter,
42                                 CORBA_Environment      *ev)
43{
44        BonoboConfigBag *cb = GET_BAG_FROM_SERVANT (servant);
45        char            *path;
46        Bonobo_KeyList  *retval;
47        GSList          *slist, *sl;
48        GError          *err = NULL;
49        int              length;
50        int              n;
51
52        if (strchr (filter, '/')) {
53                bonobo_exception_set (ev, ex_Bonobo_PropertyBag_NotFound);
54                return NULL;
55        }
56
57        path = g_strconcat (cb->path, "/", filter, NULL);
58
59        /* get keys from GConf */
60        slist = gconf_client_all_entries (cb->conf_client, path, &err);
61        g_free (path);
62        if (err) {
63                bonobo_exception_general_error_set (ev, NULL, err->message);
64                g_error_free (err);
65                return CORBA_OBJECT_NIL;
66        }
67
68        /* create CORBA sequence */
69        length = g_slist_length (slist);
70        retval = Bonobo_KeyList__alloc ();
71        retval->_length = length;
72        CORBA_sequence_set_release (retval, TRUE);
73        retval->_buffer = Bonobo_KeyList_allocbuf (length);
74
75        for (sl = slist, n = 0; n < length; sl = sl->next, n++) {
76                GConfEntry *entry = (GConfEntry *) sl->data;
77                const char *entry_name;
78
79                entry_name = gconf_entry_get_key (entry);
80                retval->_buffer[n] = CORBA_string_dup (entry_name);
81        }
82
83        g_slist_free (slist);
84
85        return retval;
86}
87
88static CORBA_TypeCode
89impl_Bonobo_PropertyBag_getType (PortableServer_Servant  servant,
90                                 const CORBA_char       *key,
91                                 CORBA_Environment      *ev)
92{
93        BonoboConfigBag *cb = GET_BAG_FROM_SERVANT (servant);
94        char            *path;
95        GConfValue      *value;
96        GError          *err = NULL;
97
98        if (strchr (key, '/')) {
99                bonobo_exception_set (ev, ex_Bonobo_PropertyBag_NotFound);
100                return CORBA_OBJECT_NIL;
101        }
102
103        path = g_strconcat (cb->path, "/", key, NULL);
104
105        /* get type for the given key */
106        value = gconf_client_get (cb->conf_client, path, &err);
107        g_free (path);
108        if (err) {
109                bonobo_exception_general_error_set (ev, NULL, err->message);
110                g_error_free (err);
111                return CORBA_OBJECT_NIL;
112        }
113
114        switch (value->type) {
115        case GCONF_VALUE_STRING :
116                return (CORBA_TypeCode)
117                        CORBA_Object_duplicate ((CORBA_Object) BONOBO_ARG_STRING, ev);
118        case GCONF_VALUE_INT :
119                return (CORBA_TypeCode)
120                        CORBA_Object_duplicate ((CORBA_Object) BONOBO_ARG_LONG, ev);
121        case GCONF_VALUE_FLOAT :
122                return (CORBA_TypeCode)
123                        CORBA_Object_duplicate ((CORBA_Object) BONOBO_ARG_DOUBLE, ev);
124        case GCONF_VALUE_BOOL :
125                return (CORBA_TypeCode)
126                        CORBA_Object_duplicate ((CORBA_Object) BONOBO_ARG_BOOLEAN, ev);
127        default :
128                /* FIXME */
129                break;
130        }
131
132        return CORBA_OBJECT_NIL;
133}
134
135static BonoboArg*
136bonobo_arg_new_from_gconf_value (GConfValue *value)
137{
138        if (value == NULL)
139                return bonobo_arg_new (BONOBO_ARG_NULL);
140       
141        switch (value->type) {
142        case GCONF_VALUE_STRING :
143                return bonobo_arg_new_from (BONOBO_ARG_STRING,
144                                            gconf_value_get_string (value));
145        case GCONF_VALUE_INT : {
146                long v = gconf_value_get_int (value);
147                return bonobo_arg_new_from (BONOBO_ARG_LONG, &v);
148        }
149        case GCONF_VALUE_FLOAT : {
150                double v = gconf_value_get_float (value);
151                return bonobo_arg_new_from (BONOBO_ARG_DOUBLE, &v);
152        }
153        case GCONF_VALUE_BOOL : {
154                gboolean v = gconf_value_get_bool (value);
155                return bonobo_arg_new_from (BONOBO_ARG_BOOLEAN, &v);
156        }
157        default :
158                return bonobo_arg_new (BONOBO_ARG_NULL);
159        }
160}
161
162static CORBA_any *
163impl_Bonobo_PropertyBag_getValue (PortableServer_Servant  servant,
164                                  const CORBA_char       *key,
165                                  CORBA_Environment      *ev)
166{
167        BonoboConfigBag *cb = GET_BAG_FROM_SERVANT (servant);
168        char            *path;
169        GConfValue      *value;
170        GError          *err = NULL;
171 
172        if (strchr (key, '/')) {
173                bonobo_exception_set (ev, ex_Bonobo_PropertyBag_NotFound);
174                return NULL;
175        }
176
177        path = g_strconcat (cb->path, "/", key, NULL);
178
179        value = gconf_client_get (cb->conf_client, path, &err);
180        g_free (path);
181        if (err) {
182                bonobo_exception_general_error_set (ev, NULL, err->message);
183                g_error_free (err);
184                return CORBA_OBJECT_NIL;
185        }
186
187        /* FIXME The original code here returned BonoboArg*
188         * as a CORBA_any*, is that OK?
189         */
190        return bonobo_arg_new_from_gconf_value (value);
191}
192
193static void
194impl_Bonobo_PropertyBag_setValue (PortableServer_Servant  servant,
195                                  const CORBA_char       *key,
196                                  const CORBA_any        *value,
197                                  CORBA_Environment      *ev)
198{
199        BonoboConfigBag *cb = GET_BAG_FROM_SERVANT (servant);
200        char            *path;
201        GError          *err = NULL;
202       
203        if (strchr (key, '/')) {
204                bonobo_exception_set (ev, ex_Bonobo_PropertyBag_NotFound);
205                return;
206        }
207
208        path = g_strconcat (cb->path, "/", key, NULL);
209
210        if (bonobo_arg_type_is_equal (value->_type, BONOBO_ARG_STRING, ev)) {
211                gconf_client_set_string (cb->conf_client, path,
212                                         BONOBO_ARG_GET_STRING (value), &err);
213        }
214        else if (bonobo_arg_type_is_equal (value->_type, BONOBO_ARG_LONG, ev)) {
215                gconf_client_set_int (cb->conf_client, path,
216                                      BONOBO_ARG_GET_LONG (value), &err);
217        }
218        else if (bonobo_arg_type_is_equal (value->_type, BONOBO_ARG_DOUBLE, ev)) {
219                gconf_client_set_float (cb->conf_client, path,
220                                        BONOBO_ARG_GET_DOUBLE (value), &err);
221        }
222        else if (bonobo_arg_type_is_equal (value->_type, BONOBO_ARG_BOOLEAN, ev)) {
223                gconf_client_set_bool (cb->conf_client, path,
224                                       BONOBO_ARG_GET_BOOLEAN (value), &err);
225        }
226        else if (bonobo_arg_type_is_equal (value->_type, BONOBO_ARG_NULL, ev)) {
227                gconf_client_unset (cb->conf_client, path, &err);
228        }
229        else {
230                g_free (path);
231                bonobo_exception_general_error_set (ev, NULL, _("Unknown type"));
232                return;
233        }
234
235        g_free (path);
236
237        if (err) {
238                bonobo_exception_general_error_set (ev, NULL, err->message);
239                g_error_free (err);
240        }
241}
242
243static Bonobo_PropertySet *
244impl_Bonobo_PropertyBag_getValues (PortableServer_Servant servant,
245                                   const CORBA_char       *filter,
246                                   CORBA_Environment      *ev)
247{
248        BonoboConfigBag *cb = GET_BAG_FROM_SERVANT (servant);
249        char *path;
250        Bonobo_PropertySet *retval;
251        GSList *slist, *sl;
252        GError *err = NULL;
253        int length;
254        int n;
255
256        if (strchr (filter, '/')) {
257                bonobo_exception_set (ev, ex_Bonobo_PropertyBag_NotFound);
258                return NULL;
259        }
260
261        path = g_strconcat (cb->path, "/", filter, NULL);
262
263        /* get keys from GConf */
264        slist = gconf_client_all_entries (cb->conf_client, path, &err);
265        g_free (path);
266        if (err) {
267                bonobo_exception_general_error_set (ev, NULL, err->message);
268                g_error_free (err);
269                return CORBA_OBJECT_NIL;
270        }
271
272        /* create CORBA sequence */
273        length = g_slist_length (slist);
274        retval = Bonobo_PropertySet__alloc ();
275        retval->_length = length;
276        CORBA_sequence_set_release (retval, TRUE);
277        retval->_buffer = CORBA_sequence_Bonobo_Pair_allocbuf (length);
278
279        for (sl = slist, n = 0; n < length; sl = sl->next, n++) {
280                GConfEntry *entry = (GConfEntry *) sl->data;
281                BonoboArg *arg;
282                GConfValue *value;
283
284                retval->_buffer[n].name = CORBA_string_dup (gconf_entry_get_key (entry));
285                value = gconf_entry_get_value (entry);
286
287                arg = bonobo_arg_new_from_gconf_value (value);
288               
289                retval->_buffer[n].value = *arg;
290        }
291
292        g_slist_free (slist);
293
294        return retval;
295}
296
297static void                 
298impl_Bonobo_PropertyBag_setValues (PortableServer_Servant servant,
299                                   const Bonobo_PropertySet *set,
300                                   CORBA_Environment *ev)
301{
302        int i;
303
304        for (i = 0; i < set->_length; i++) {
305                impl_Bonobo_PropertyBag_setValue (servant,
306                                                  set->_buffer [i].name,
307                                                  &set->_buffer [i].value,
308                                                  ev);
309                if (BONOBO_EX (ev))
310                        return;
311        }
312}
313
314static CORBA_any *
315impl_Bonobo_PropertyBag_getDefault (PortableServer_Servant  servant,
316                                    const CORBA_char       *key,
317                                    CORBA_Environment      *ev)
318{
319        BonoboConfigBag *cb = GET_BAG_FROM_SERVANT (servant);
320        char            *path;
321        GConfValue      *value;
322        GError          *err = NULL;
323
324        if (strchr (key, '/')) {
325                bonobo_exception_set (ev, ex_Bonobo_PropertyBag_NotFound);
326                return NULL;
327        }
328
329        path = g_strconcat (cb->path, "/", key, NULL);
330
331        value = gconf_client_get_default_from_schema (cb->conf_client, path, &err);
332        g_free (path);
333        if (err) {
334                bonobo_exception_general_error_set (ev, NULL, err->message);
335                g_error_free (err);
336                return CORBA_OBJECT_NIL;
337        }
338
339        return bonobo_arg_new_from_gconf_value (value);
340}
341
342static CORBA_char *
343impl_Bonobo_PropertyBag_getDocTitle (PortableServer_Servant  servant,
344                                     const CORBA_char       *key,
345                                     CORBA_Environment      *ev)
346{
347        BonoboConfigBag *cb = GET_BAG_FROM_SERVANT (servant);
348        char            *path;
349        CORBA_char      *retval;
350        GConfSchema     *schema;
351        GError          *err = NULL;
352
353        if (strchr (key, '/')) {
354                bonobo_exception_set (ev, ex_Bonobo_PropertyBag_NotFound);
355                return NULL;
356        }
357
358        path = g_strconcat (cb->path, "/", key, NULL);
359        schema = gconf_client_get_schema (cb->conf_client, path, &err);
360        g_free (path);
361        if (err) {
362                bonobo_exception_general_error_set (ev, NULL, err->message);
363                g_error_free (err);
364                return NULL;
365        }
366
367        retval = CORBA_string_dup (gconf_schema_get_short_desc (schema));
368
369        gconf_schema_free (schema);
370
371        return retval;
372}
373
374static CORBA_char *
375impl_Bonobo_PropertyBag_getDoc (PortableServer_Servant  servant,
376                                const CORBA_char       *key,
377                                CORBA_Environment      *ev)
378{
379        BonoboConfigBag *cb = GET_BAG_FROM_SERVANT (servant);
380        char            *path;
381        CORBA_char      *retval;
382        GConfSchema     *schema;
383        GError          *err = NULL;
384
385        if (strchr (key, '/')) {
386                bonobo_exception_set (ev, ex_Bonobo_PropertyBag_NotFound);
387                return NULL;
388        }
389
390        path = g_strconcat (cb->path, "/", key, NULL);
391
392        schema = gconf_client_get_schema (cb->conf_client, path, &err);
393        g_free (path);
394        if (err) {
395                bonobo_exception_general_error_set (ev, NULL, err->message);
396                g_error_free (err);
397                return NULL;
398        }
399
400        retval = CORBA_string_dup (gconf_schema_get_long_desc (schema));
401
402        gconf_schema_free (schema);
403
404        return retval;
405}
406
407static Bonobo_PropertyFlags
408impl_Bonobo_PropertyBag_getFlags (PortableServer_Servant  servant,
409                                  const CORBA_char       *key,
410                                  CORBA_Environment      *ev)
411{
412        BonoboConfigBag      *cb = GET_BAG_FROM_SERVANT (servant);
413        char                 *path;
414        Bonobo_PropertyFlags  retval = 0;
415        GConfEntry           *entry;
416        GError               *err = NULL;
417
418        if (strchr (key, '/')) {
419                bonobo_exception_set (ev, ex_Bonobo_PropertyBag_NotFound);
420                return 0;
421        }
422
423        path = g_strconcat (cb->path, "/", key, NULL);
424        entry = gconf_client_get_entry (cb->conf_client, path, NULL, TRUE, &err);
425        g_free (path);
426        if (err) {
427                bonobo_exception_general_error_set (ev, NULL, err->message);
428                g_error_free (err);
429                return 0;
430        }
431
432        retval |= Bonobo_PROPERTY_READABLE;
433        if (gconf_entry_get_is_writable (entry))
434                retval |= Bonobo_PROPERTY_WRITEABLE;
435
436        gconf_entry_free (entry);
437
438        return retval;
439}
440
441
442void
443notify_cb (BonoboListener    *listener,
444           const char        *event_name,
445           const CORBA_any   *any,
446           CORBA_Environment *ev,
447           gpointer           user_data)
448{
449        BonoboConfigBag *cb = BONOBO_CONFIG_BAG (user_data);
450        char *tmp, *ename;
451
452        tmp = bonobo_event_subtype (event_name);
453        ename = g_strconcat ("Bonobo/Property:change:", tmp, NULL);
454        g_free (tmp);
455
456        bonobo_event_source_notify_listeners (cb->es, ename, any, NULL);
457
458        g_free (ename);
459}
460
461BonoboConfigBag *
462bonobo_config_bag_new (const gchar *path)
463{
464        BonoboConfigBag *cb;
465        char *m;
466        int l;
467
468        g_return_val_if_fail (path != NULL, NULL);
469
470        cb = g_object_new (BONOBO_TYPE_CONFIG_BAG, NULL);
471
472        if (path[0] == '/')
473                cb->path = g_strdup (path);
474        else
475                cb->path = g_strconcat ("/", path, NULL);
476
477        while ((l = strlen (cb->path)) > 1 && path [l - 1] == '/')
478                cb->path [l] = '\0';
479       
480        cb->es = bonobo_event_source_new ();
481
482        bonobo_object_add_interface (BONOBO_OBJECT (cb),
483                                     BONOBO_OBJECT (cb->es));
484
485        m = g_strconcat ("Bonobo/ConfigDatabase:change", cb->path, ":", NULL);
486
487        /* bonobo_event_source_client_add_listener (db, notify_cb, m, NULL, cb); */
488
489        g_free (m);
490
491        /* initialize GConf client */
492        if (!gconf_is_initialized ())
493                gconf_init (0, NULL, NULL);
494        cb->conf_client = gconf_client_get_default ();
495
496        return cb;
497}
498
499static void
500bonobo_config_bag_class_init (BonoboConfigBagClass *class)
501{
502        GObjectClass *object_class = (GObjectClass *) class;
503        POA_Bonobo_PropertyBag__epv *epv= &class->epv;
504       
505        parent_class = g_type_class_peek_parent (class);
506
507        object_class->finalize = bonobo_config_bag_finalize;
508
509        epv->getKeys       = impl_Bonobo_PropertyBag_getKeys;
510        epv->getType       = impl_Bonobo_PropertyBag_getType;
511        epv->getValue      = impl_Bonobo_PropertyBag_getValue;
512        epv->setValue      = impl_Bonobo_PropertyBag_setValue;
513        epv->getValues     = impl_Bonobo_PropertyBag_getValues;
514        epv->setValues     = impl_Bonobo_PropertyBag_setValues;
515        epv->getDefault    = impl_Bonobo_PropertyBag_getDefault;
516        epv->getDocTitle   = impl_Bonobo_PropertyBag_getDocTitle;
517        epv->getDoc        = impl_Bonobo_PropertyBag_getDoc;
518        epv->getFlags      = impl_Bonobo_PropertyBag_getFlags;
519}
520
521static void
522bonobo_config_bag_init (BonoboConfigBag *cb)
523{
524        /* nothing to do */
525}
526
527BONOBO_TYPE_FUNC_FULL (BonoboConfigBag,
528                       Bonobo_PropertyBag,
529                       PARENT_TYPE,
530                       bonobo_config_bag);
531
Note: See TracBrowser for help on using the repository browser.