~charlesk/gnome-control-center/make-new-panel

« back to all changes in this revision

Viewing changes to libgnome-control-center/gconf-property-editor.c

  • Committer: Bazaar Package Importer
  • Author(s): Rodrigo Moya
  • Date: 2011-05-17 10:47:27 UTC
  • mfrom: (0.1.11 experimental) (1.1.45 upstream)
  • Revision ID: james.westby@ubuntu.com-20110517104727-lqel6m8vhfw5jby1
Tags: 1:3.0.1.1-1ubuntu1
* Rebase on Debian, remaining Ubuntu changes:
* debian/control:
  - Build-Depend on hardening-wrapper, dpkg-dev and dh-autoreconf
  - Add dependency on ubuntu-system-service
  - Remove dependency on gnome-icon-theme-symbolic
  - Move dependency on apg, gnome-icon-theme-symbolic and accountsservice to
    be a Recommends: until we get them in main
* debian/rules:
  - Use autoreconf
  - Add binary-post-install rule for gnome-control-center-data
  - Run dh-autoreconf
* debian/gnome-control-center.dirs:
* debian/gnome-control-center.links:
  - Add a link to the control center shell for indicators
* debian/patches/00_disable-nm.patch:
  - Temporary patch to disable building with NetworkManager until we get
    the new one in the archive
* debian/patches/01_git_remove_gettext_calls.patch:
  - Remove calls to AM_GNU_GETTEXT, IT_PROG_INTLTOOL should be enough
* debian/patches/01_git_kill_warning.patch:
  - Kill warning
* debian/patches/50_ubuntu_systemwide_prefs.patch:
  - Ubuntu specific proxy preferences
* debian/patches/51_ubuntu_system_keyboard.patch:
  - Implement the global keyboard spec at https://wiki.ubuntu.com/DefaultKeyboardSettings

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- mode: c; style: linux -*- */
 
2
 
 
3
/* gconf-property-editor.c
 
4
 * Copyright (C) 2001 Ximian, Inc.
 
5
 *
 
6
 * Written by Bradford Hovinen <hovinen@ximian.com>
 
7
 *
 
8
 * This program is free software; you can redistribute it and/or modify
 
9
 * it under the terms of the GNU General Public License as published by
 
10
 * the Free Software Foundation; either version 2, or (at your option)
 
11
 * any later version.
 
12
 *
 
13
 * This program is distributed in the hope that it will be useful,
 
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
 * GNU General Public License for more details.
 
17
 *
 
18
 * You should have received a copy of the GNU General Public License
 
19
 * along with this program; if not, write to the Free Software
 
20
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 
21
 * 02111-1307, USA.
 
22
 */
 
23
 
 
24
#ifdef HAVE_CONFIG_H
 
25
# include "config.h"
 
26
#endif
 
27
 
 
28
#include <string.h>
 
29
#include <stdarg.h>
 
30
#include <stdlib.h>
 
31
 
 
32
#include "gconf-property-editor.h"
 
33
#include "cc-marshal.h"
 
34
 
 
35
enum {
 
36
        VALUE_CHANGED,
 
37
        LAST_SIGNAL
 
38
};
 
39
 
 
40
enum {
 
41
        PROP_0,
 
42
        PROP_KEY,
 
43
        PROP_CALLBACK,
 
44
        PROP_CHANGESET,
 
45
        PROP_CONV_TO_WIDGET_CB,
 
46
        PROP_CONV_FROM_WIDGET_CB,
 
47
        PROP_UI_CONTROL,
 
48
        PROP_DATA,
 
49
        PROP_DATA_FREE_CB
 
50
};
 
51
 
 
52
struct _GConfPropertyEditorPrivate
 
53
{
 
54
        gchar                   *key;
 
55
        guint                    handler_id;
 
56
        GConfChangeSet          *changeset;
 
57
        GObject                 *ui_control;
 
58
        GConfPEditorValueConvFn  conv_to_widget_cb;
 
59
        GConfPEditorValueConvFn  conv_from_widget_cb;
 
60
        GConfClientNotifyFunc    callback;
 
61
        gboolean                 inited;
 
62
 
 
63
        gpointer                 data;
 
64
        GFreeFunc                data_free_cb;
 
65
};
 
66
 
 
67
typedef struct
 
68
{
 
69
        GType                    enum_type;
 
70
        GConfPEditorGetValueFn   enum_val_true_fn;
 
71
        gpointer                 enum_val_true_fn_data;
 
72
        guint                    enum_val_false;
 
73
        gboolean                 use_nick;
 
74
} GConfPropertyEditorEnumData;
 
75
 
 
76
static guint peditor_signals[LAST_SIGNAL];
 
77
 
 
78
static void gconf_property_editor_set_prop    (GObject      *object,
 
79
                                               guint         prop_id,
 
80
                                               const GValue *value,
 
81
                                               GParamSpec   *pspec);
 
82
static void gconf_property_editor_get_prop    (GObject      *object,
 
83
                                               guint         prop_id,
 
84
                                               GValue       *value,
 
85
                                               GParamSpec   *pspec);
 
86
 
 
87
static void gconf_property_editor_finalize    (GObject      *object);
 
88
 
 
89
static GObject *gconf_peditor_new             (const gchar           *key,
 
90
                                               GConfClientNotifyFunc  cb,
 
91
                                               GConfChangeSet        *changeset,
 
92
                                               GObject               *ui_control,
 
93
                                               const gchar           *first_prop_name,
 
94
                                               va_list                var_args,
 
95
                                               const gchar           *first_custom,
 
96
                                               ...);
 
97
 
 
98
G_DEFINE_TYPE (GConfPropertyEditor, gconf_property_editor, G_TYPE_OBJECT)
 
99
 
 
100
#define GCONF_PROPERTY_EDITOR_GET_PRIVATE(object) \
 
101
        (G_TYPE_INSTANCE_GET_PRIVATE ((object), gconf_property_editor_get_type (), GConfPropertyEditorPrivate))
 
102
 
 
103
 
 
104
static GConfValue*
 
105
gconf_property_editor_conv_default (GConfPropertyEditor *peditor,
 
106
                                    const GConfValue *value)
 
107
{
 
108
        return gconf_value_copy (value);
 
109
}
 
110
 
 
111
static void
 
112
gconf_property_editor_init (GConfPropertyEditor *gconf_property_editor)
 
113
{
 
114
        gconf_property_editor->p = GCONF_PROPERTY_EDITOR_GET_PRIVATE (gconf_property_editor);
 
115
        gconf_property_editor->p->conv_to_widget_cb = gconf_property_editor_conv_default;
 
116
        gconf_property_editor->p->conv_from_widget_cb = gconf_property_editor_conv_default;
 
117
        gconf_property_editor->p->inited = FALSE;
 
118
}
 
119
 
 
120
static void
 
121
gconf_property_editor_class_init (GConfPropertyEditorClass *class)
 
122
{
 
123
        GObjectClass *object_class;
 
124
 
 
125
        object_class = G_OBJECT_CLASS (class);
 
126
 
 
127
        object_class->finalize = gconf_property_editor_finalize;
 
128
        object_class->set_property = gconf_property_editor_set_prop;
 
129
        object_class->get_property = gconf_property_editor_get_prop;
 
130
 
 
131
        g_object_class_install_property
 
132
                (object_class, PROP_KEY,
 
133
                 g_param_spec_string ("key",
 
134
                                      _("Key"),
 
135
                                      _("GConf key to which this property editor is attached"),
 
136
                                      NULL,
 
137
                                      G_PARAM_READWRITE));
 
138
        g_object_class_install_property
 
139
                (object_class, PROP_CALLBACK,
 
140
                 g_param_spec_pointer ("callback",
 
141
                                       _("Callback"),
 
142
                                       _("Issue this callback when the value associated with key gets changed"),
 
143
                                       G_PARAM_WRITABLE));
 
144
        g_object_class_install_property
 
145
                (object_class, PROP_CHANGESET,
 
146
                 g_param_spec_pointer ("changeset",
 
147
                                       _("Change set"),
 
148
                                       _("GConf change set containing data to be forwarded to the gconf client on apply"),
 
149
                                       G_PARAM_READWRITE));
 
150
        g_object_class_install_property
 
151
                (object_class, PROP_CONV_TO_WIDGET_CB,
 
152
                 g_param_spec_pointer ("conv-to-widget-cb",
 
153
                                       _("Conversion to widget callback"),
 
154
                                       _("Callback to be issued when data are to be converted from GConf to the widget"),
 
155
                                       G_PARAM_WRITABLE));
 
156
        g_object_class_install_property
 
157
                (object_class, PROP_CONV_FROM_WIDGET_CB,
 
158
                 g_param_spec_pointer ("conv-from-widget-cb",
 
159
                                       _("Conversion from widget callback"),
 
160
                                       _("Callback to be issued when data are to be converted to GConf from the widget"),
 
161
                                       G_PARAM_WRITABLE));
 
162
        g_object_class_install_property
 
163
                (object_class, PROP_UI_CONTROL,
 
164
                 g_param_spec_object ("ui-control",
 
165
                                      _("UI Control"),
 
166
                                      _("Object that controls the property (normally a widget)"),
 
167
                                      G_TYPE_OBJECT,
 
168
                                      G_PARAM_WRITABLE));
 
169
 
 
170
        peditor_signals[VALUE_CHANGED] =
 
171
                g_signal_new ("value-changed",
 
172
                              G_TYPE_FROM_CLASS (object_class), 0,
 
173
                              G_STRUCT_OFFSET (GConfPropertyEditorClass, value_changed),
 
174
                              NULL, NULL,
 
175
                              (GSignalCMarshaller) cc_marshal_VOID__STRING_POINTER,
 
176
                              G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_POINTER);
 
177
 
 
178
        g_object_class_install_property
 
179
                (object_class, PROP_DATA,
 
180
                 g_param_spec_pointer ("data",
 
181
                                       _("Property editor object data"),
 
182
                                       _("Custom data required by the specific property editor"),
 
183
                                       G_PARAM_READWRITE));
 
184
 
 
185
        g_object_class_install_property
 
186
                (object_class, PROP_DATA_FREE_CB,
 
187
                 g_param_spec_pointer ("data-free-cb",
 
188
                                       _("Property editor data freeing callback"),
 
189
                                       _("Callback to be issued when property editor object data is to be freed"),
 
190
                                       G_PARAM_WRITABLE));
 
191
 
 
192
        g_type_class_add_private (class, sizeof (GConfPropertyEditorPrivate));
 
193
}
 
194
 
 
195
static void
 
196
gconf_property_editor_set_prop (GObject      *object,
 
197
                                guint         prop_id,
 
198
                                const GValue *value,
 
199
                                GParamSpec   *pspec)
 
200
{
 
201
        GConfPropertyEditor *peditor;
 
202
        GConfClient         *client;
 
203
        GConfNotifyFunc      cb;
 
204
 
 
205
        g_return_if_fail (object != NULL);
 
206
        g_return_if_fail (IS_GCONF_PROPERTY_EDITOR (object));
 
207
 
 
208
        peditor = GCONF_PROPERTY_EDITOR (object);
 
209
 
 
210
        switch (prop_id) {
 
211
        case PROP_KEY:
 
212
                peditor->p->key = g_value_dup_string (value);
 
213
                break;
 
214
 
 
215
        case PROP_CALLBACK:
 
216
                client = gconf_client_get_default ();
 
217
                cb = g_value_get_pointer (value);
 
218
                peditor->p->callback = (GConfClientNotifyFunc) cb;
 
219
                if (peditor->p->handler_id != 0) {
 
220
                        gconf_client_notify_remove (client,
 
221
                                                    peditor->p->handler_id);
 
222
                }
 
223
                peditor->p->handler_id =
 
224
                        gconf_client_notify_add (client, peditor->p->key,
 
225
                                                 peditor->p->callback,
 
226
                                                 peditor, NULL, NULL);
 
227
                g_object_unref (client);
 
228
                break;
 
229
 
 
230
        case PROP_CHANGESET:
 
231
                peditor->p->changeset = g_value_get_pointer (value);
 
232
                break;
 
233
 
 
234
        case PROP_CONV_TO_WIDGET_CB:
 
235
                peditor->p->conv_to_widget_cb = g_value_get_pointer (value);
 
236
                break;
 
237
 
 
238
        case PROP_CONV_FROM_WIDGET_CB:
 
239
                peditor->p->conv_from_widget_cb = g_value_get_pointer (value);
 
240
                break;
 
241
 
 
242
        case PROP_UI_CONTROL:
 
243
                peditor->p->ui_control = g_value_get_object (value);
 
244
                g_object_weak_ref (peditor->p->ui_control, (GWeakNotify) g_object_unref, object);
 
245
                break;
 
246
        case PROP_DATA:
 
247
                peditor->p->data = g_value_get_pointer (value);
 
248
                break;
 
249
        case PROP_DATA_FREE_CB:
 
250
                peditor->p->data_free_cb = g_value_get_pointer (value);
 
251
                break;
 
252
        default:
 
253
                g_warning ("Bad argument set");
 
254
                break;
 
255
        }
 
256
}
 
257
 
 
258
static void
 
259
gconf_property_editor_get_prop (GObject    *object,
 
260
                                guint       prop_id,
 
261
                                GValue     *value,
 
262
                                GParamSpec *pspec)
 
263
{
 
264
        GConfPropertyEditor *peditor;
 
265
 
 
266
        g_return_if_fail (object != NULL);
 
267
        g_return_if_fail (IS_GCONF_PROPERTY_EDITOR (object));
 
268
 
 
269
        peditor = GCONF_PROPERTY_EDITOR (object);
 
270
 
 
271
        switch (prop_id) {
 
272
        case PROP_KEY:
 
273
                g_value_set_string (value, peditor->p->key);
 
274
                break;
 
275
 
 
276
        case PROP_CHANGESET:
 
277
                g_value_set_pointer (value, peditor->p->changeset);
 
278
                break;
 
279
 
 
280
        case PROP_DATA:
 
281
                g_value_set_pointer (value, peditor->p->data);
 
282
                break;
 
283
        default:
 
284
                g_warning ("Bad argument get");
 
285
                break;
 
286
        }
 
287
}
 
288
 
 
289
static void
 
290
gconf_property_editor_finalize (GObject *object)
 
291
{
 
292
        GConfPropertyEditor *gconf_property_editor;
 
293
 
 
294
        g_return_if_fail (object != NULL);
 
295
        g_return_if_fail (IS_GCONF_PROPERTY_EDITOR (object));
 
296
 
 
297
        gconf_property_editor = GCONF_PROPERTY_EDITOR (object);
 
298
 
 
299
        g_free (gconf_property_editor->p->key);
 
300
 
 
301
        if (gconf_property_editor->p->data_free_cb)
 
302
                gconf_property_editor->p->data_free_cb (gconf_property_editor->p->data);
 
303
 
 
304
        if (gconf_property_editor->p->handler_id != 0) {
 
305
                GConfClient *client;
 
306
 
 
307
                client = gconf_client_get_default ();
 
308
                gconf_client_notify_remove (client,
 
309
                                            gconf_property_editor->p->handler_id);
 
310
                g_object_unref (client);
 
311
        }
 
312
 
 
313
        G_OBJECT_CLASS (gconf_property_editor_parent_class)->finalize (object);
 
314
}
 
315
 
 
316
static GObject *
 
317
gconf_peditor_new (const gchar           *key,
 
318
                   GConfClientNotifyFunc  cb,
 
319
                   GConfChangeSet        *changeset,
 
320
                   GObject               *ui_control,
 
321
                   const gchar           *first_prop_name,
 
322
                   va_list                var_args,
 
323
                   const gchar           *first_custom,
 
324
                   ...)
 
325
{
 
326
        GObject     *obj;
 
327
        GConfClient *client;
 
328
        GConfEntry  *gconf_entry;
 
329
 
 
330
        g_return_val_if_fail (key != NULL, NULL);
 
331
        g_return_val_if_fail (cb != NULL, NULL);
 
332
 
 
333
        obj = g_object_new (gconf_property_editor_get_type (),
 
334
                            "key",        key,
 
335
                            "callback",   cb,
 
336
                            "changeset",  changeset,
 
337
                            "ui-control", ui_control,
 
338
                            NULL);
 
339
 
 
340
        g_object_set_valist (obj, first_prop_name, var_args);
 
341
 
 
342
        if (first_custom)
 
343
        {
 
344
                va_list custom_args;
 
345
                va_start (custom_args, first_custom);
 
346
                g_object_set_valist (obj, first_custom, custom_args);
 
347
                va_end (custom_args);
 
348
        }
 
349
 
 
350
        client = gconf_client_get_default ();
 
351
        gconf_entry = gconf_client_get_entry (client, GCONF_PROPERTY_EDITOR (obj)->p->key, NULL, TRUE, NULL);
 
352
        GCONF_PROPERTY_EDITOR (obj)->p->callback (client, 0, gconf_entry, obj);
 
353
        GCONF_PROPERTY_EDITOR (obj)->p->inited = TRUE;
 
354
        if (gconf_entry)
 
355
                gconf_entry_free (gconf_entry);
 
356
        g_object_unref (client);
 
357
 
 
358
        return obj;
 
359
}
 
360
 
 
361
const gchar *
 
362
gconf_property_editor_get_key (GConfPropertyEditor *peditor)
 
363
{
 
364
        return peditor->p->key;
 
365
}
 
366
 
 
367
GObject *
 
368
gconf_property_editor_get_ui_control (GConfPropertyEditor  *peditor)
 
369
{
 
370
        return peditor->p->ui_control;
 
371
}
 
372
 
 
373
static void
 
374
peditor_set_gconf_value (GConfPropertyEditor *peditor,
 
375
                         const gchar         *key,
 
376
                         GConfValue          *value)
 
377
{
 
378
 
 
379
        if (peditor->p->changeset != NULL) {
 
380
                if (value)
 
381
                        gconf_change_set_set (peditor->p->changeset, peditor->p->key, value);
 
382
                else
 
383
                        gconf_change_set_unset (peditor->p->changeset, peditor->p->key);
 
384
        } else {
 
385
                GConfClient *client = gconf_client_get_default();
 
386
 
 
387
                if (value)
 
388
                        gconf_client_set (client, peditor->p->key, value, NULL);
 
389
                else
 
390
                        gconf_client_unset (client, peditor->p->key, NULL);
 
391
 
 
392
                g_object_unref (client);
 
393
        }
 
394
 
 
395
}
 
396
 
 
397
static void
 
398
peditor_boolean_value_changed (GConfClient         *client,
 
399
                               guint                cnxn_id,
 
400
                               GConfEntry          *entry,
 
401
                               GConfPropertyEditor *peditor)
 
402
{
 
403
        GConfValue *value, *value_wid;
 
404
 
 
405
        if (peditor->p->changeset != NULL)
 
406
                gconf_change_set_remove (peditor->p->changeset, peditor->p->key);
 
407
 
 
408
        if (entry && (value = gconf_entry_get_value (entry))) {
 
409
                value_wid = peditor->p->conv_to_widget_cb (peditor, value);
 
410
                gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (peditor->p->ui_control), gconf_value_get_bool (value_wid));
 
411
                gconf_value_free (value_wid);
 
412
        }
 
413
}
 
414
 
 
415
static void
 
416
peditor_switch_value_changed (GConfClient         *client,
 
417
                               guint                cnxn_id,
 
418
                               GConfEntry          *entry,
 
419
                               GConfPropertyEditor *peditor)
 
420
{
 
421
        GConfValue *value, *value_wid;
 
422
 
 
423
        if (peditor->p->changeset != NULL)
 
424
                gconf_change_set_remove (peditor->p->changeset, peditor->p->key);
 
425
 
 
426
        if (entry && (value = gconf_entry_get_value (entry))) {
 
427
                value_wid = peditor->p->conv_to_widget_cb (peditor, value);
 
428
                gtk_switch_set_active (GTK_SWITCH (peditor->p->ui_control), gconf_value_get_bool (value_wid));
 
429
                gconf_value_free (value_wid);
 
430
        }
 
431
}
 
432
 
 
433
static void
 
434
peditor_boolean_widget_changed (GConfPropertyEditor *peditor,
 
435
                                GtkToggleButton     *tb)
 
436
{
 
437
        GConfValue *value, *value_wid;
 
438
 
 
439
        if (!peditor->p->inited) return;
 
440
        value_wid = gconf_value_new (GCONF_VALUE_BOOL);
 
441
        gconf_value_set_bool (value_wid, gtk_toggle_button_get_active (tb));
 
442
        value = peditor->p->conv_from_widget_cb (peditor, value_wid);
 
443
        peditor_set_gconf_value (peditor, peditor->p->key, value);
 
444
        g_signal_emit (peditor, peditor_signals[VALUE_CHANGED], 0, peditor->p->key, value);
 
445
        gconf_value_free (value_wid);
 
446
        gconf_value_free (value);
 
447
}
 
448
 
 
449
static void
 
450
peditor_switch_widget_changed (GtkSwitch *sw,
 
451
                               GParamSpec *pspec,
 
452
                               GConfPropertyEditor *peditor)
 
453
{
 
454
        GConfValue *value, *value_wid;
 
455
 
 
456
        if (!peditor->p->inited) return;
 
457
        value_wid = gconf_value_new (GCONF_VALUE_BOOL);
 
458
        gconf_value_set_bool (value_wid, gtk_switch_get_active (sw));
 
459
        value = peditor->p->conv_from_widget_cb (peditor, value_wid);
 
460
        peditor_set_gconf_value (peditor, peditor->p->key, value);
 
461
        g_signal_emit (peditor, peditor_signals[VALUE_CHANGED], 0, peditor->p->key, value);
 
462
        gconf_value_free (value_wid);
 
463
        gconf_value_free (value);
 
464
}
 
465
 
 
466
GObject *
 
467
gconf_peditor_new_boolean (GConfChangeSet *changeset,
 
468
                           const gchar    *key,
 
469
                           GtkWidget      *checkbox,
 
470
                           const gchar    *first_property_name,
 
471
                           ...)
 
472
{
 
473
        GObject *peditor;
 
474
        va_list var_args;
 
475
 
 
476
        g_return_val_if_fail (key != NULL, NULL);
 
477
        g_return_val_if_fail (checkbox != NULL, NULL);
 
478
        g_return_val_if_fail (GTK_IS_TOGGLE_BUTTON (checkbox), NULL);
 
479
 
 
480
        va_start (var_args, first_property_name);
 
481
 
 
482
        peditor = gconf_peditor_new
 
483
                (key,
 
484
                 (GConfClientNotifyFunc) peditor_boolean_value_changed,
 
485
                 changeset,
 
486
                 G_OBJECT (checkbox),
 
487
                 first_property_name,
 
488
                 var_args,
 
489
                 NULL);
 
490
 
 
491
        va_end (var_args);
 
492
 
 
493
        g_signal_connect_swapped (checkbox, "toggled",
 
494
                                  (GCallback) peditor_boolean_widget_changed, peditor);
 
495
 
 
496
        return peditor;
 
497
}
 
498
 
 
499
GObject *
 
500
gconf_peditor_new_switch (GConfChangeSet *changeset,
 
501
                          const gchar    *key,
 
502
                          GtkWidget      *sw,
 
503
                          const gchar    *first_property_name,
 
504
                          ...)
 
505
{
 
506
        GObject *peditor;
 
507
        va_list var_args;
 
508
 
 
509
        g_return_val_if_fail (key != NULL, NULL);
 
510
        g_return_val_if_fail (sw != NULL, NULL);
 
511
        g_return_val_if_fail (GTK_IS_SWITCH (sw), NULL);
 
512
 
 
513
        va_start (var_args, first_property_name);
 
514
 
 
515
        peditor = gconf_peditor_new
 
516
                (key,
 
517
                 (GConfClientNotifyFunc) peditor_switch_value_changed,
 
518
                 changeset,
 
519
                 G_OBJECT (sw),
 
520
                 first_property_name,
 
521
                 var_args,
 
522
                 NULL);
 
523
 
 
524
        va_end (var_args);
 
525
 
 
526
        g_signal_connect (sw, "notify::active",
 
527
                          (GCallback) peditor_switch_widget_changed, peditor);
 
528
 
 
529
        return peditor;
 
530
}
 
531
 
 
532
static void
 
533
peditor_integer_value_changed (GConfClient         *client,
 
534
                               guint                cnxn_id,
 
535
                               GConfEntry          *entry,
 
536
                               GConfPropertyEditor *peditor)
 
537
{
 
538
        GConfValue *value, *value_wid;
 
539
        const char *entry_current_text;
 
540
        int         entry_current_integer;
 
541
 
 
542
        if (peditor->p->changeset != NULL)
 
543
                gconf_change_set_remove (peditor->p->changeset, peditor->p->key);
 
544
 
 
545
        if (entry && (value = gconf_entry_get_value (entry))) {
 
546
                value_wid = peditor->p->conv_to_widget_cb (peditor, value);
 
547
                entry_current_text = gtk_entry_get_text (GTK_ENTRY (peditor->p->ui_control));
 
548
                entry_current_integer = strtol (entry_current_text, NULL, 10);
 
549
                if (entry_current_integer != gconf_value_get_int (value)) {
 
550
                        char *buf = g_strdup_printf ("%d", gconf_value_get_int (value_wid));
 
551
                        gtk_entry_set_text (GTK_ENTRY (peditor->p->ui_control), buf);
 
552
                        g_free (buf);
 
553
                }
 
554
                gconf_value_free (value_wid);
 
555
        }
 
556
}
 
557
 
 
558
static void
 
559
peditor_integer_widget_changed (GConfPropertyEditor *peditor,
 
560
                                GtkEntry            *entry)
 
561
{
 
562
        GConfValue *value, *value_wid;
 
563
 
 
564
        if (!peditor->p->inited) return;
 
565
 
 
566
        value_wid = gconf_value_new (GCONF_VALUE_INT);
 
567
 
 
568
        gconf_value_set_int (value_wid, strtol (gtk_entry_get_text (entry), NULL, 10));
 
569
        value = peditor->p->conv_from_widget_cb (peditor, value_wid);
 
570
 
 
571
        peditor_set_gconf_value (peditor, peditor->p->key, value);
 
572
 
 
573
        g_signal_emit (peditor, peditor_signals[VALUE_CHANGED], 0, peditor->p->key, value);
 
574
        gconf_value_free (value_wid);
 
575
        gconf_value_free (value);
 
576
}
 
577
 
 
578
static GObject *
 
579
gconf_peditor_new_integer_valist (GConfChangeSet *changeset,
 
580
                                  const gchar    *key,
 
581
                                  GtkWidget      *entry,
 
582
                                  const gchar    *first_property_name,
 
583
                                  va_list         var_args)
 
584
{
 
585
        GObject *peditor;
 
586
 
 
587
        peditor = gconf_peditor_new
 
588
                (key,
 
589
                 (GConfClientNotifyFunc) peditor_integer_value_changed,
 
590
                 changeset,
 
591
                 G_OBJECT (entry),
 
592
                 first_property_name,
 
593
                 var_args, NULL);
 
594
 
 
595
        g_signal_connect_swapped (entry, "changed",
 
596
                                  (GCallback) peditor_integer_widget_changed, peditor);
 
597
 
 
598
        return peditor;
 
599
}
 
600
 
 
601
GObject *
 
602
gconf_peditor_new_integer (GConfChangeSet *changeset,
 
603
                           const gchar    *key,
 
604
                           GtkWidget      *entry,
 
605
                           const gchar    *first_property_name,
 
606
                           ...)
 
607
{
 
608
        GObject *peditor;
 
609
        va_list var_args;
 
610
 
 
611
        g_return_val_if_fail (key != NULL, NULL);
 
612
        g_return_val_if_fail (entry != NULL, NULL);
 
613
        g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL);
 
614
 
 
615
        va_start (var_args, first_property_name);
 
616
 
 
617
        peditor = gconf_peditor_new_integer_valist
 
618
                (changeset, key, entry,
 
619
                 first_property_name, var_args);
 
620
 
 
621
        va_end (var_args);
 
622
 
 
623
        return peditor;
 
624
}
 
625
 
 
626
static void
 
627
peditor_string_value_changed (GConfClient         *client,
 
628
                              guint                cnxn_id,
 
629
                              GConfEntry          *entry,
 
630
                              GConfPropertyEditor *peditor)
 
631
{
 
632
        GConfValue *value, *value_wid;
 
633
 
 
634
        if (peditor->p->changeset != NULL)
 
635
                gconf_change_set_remove (peditor->p->changeset, peditor->p->key);
 
636
 
 
637
        if (entry && (value = gconf_entry_get_value (entry))) {
 
638
                const char *entry_current_text;
 
639
                const char *gconf_text;
 
640
 
 
641
                value_wid = peditor->p->conv_to_widget_cb (peditor, value);
 
642
                gconf_text = gconf_value_get_string (value_wid);
 
643
                entry_current_text = gtk_entry_get_text (GTK_ENTRY (peditor->p->ui_control));
 
644
 
 
645
                if (gconf_text && strcmp (entry_current_text, gconf_text) != 0) {
 
646
                  gtk_entry_set_text (GTK_ENTRY (peditor->p->ui_control), gconf_value_get_string (value_wid));
 
647
                }
 
648
                gconf_value_free (value_wid);
 
649
        }
 
650
}
 
651
 
 
652
static void
 
653
peditor_string_widget_changed (GConfPropertyEditor *peditor,
 
654
                               GtkEntry            *entry)
 
655
{
 
656
        GConfValue *value, *value_wid;
 
657
 
 
658
        if (!peditor->p->inited) return;
 
659
 
 
660
        value_wid = gconf_value_new (GCONF_VALUE_STRING);
 
661
 
 
662
        gconf_value_set_string (value_wid, gtk_entry_get_text (entry));
 
663
        value = peditor->p->conv_from_widget_cb (peditor, value_wid);
 
664
 
 
665
        peditor_set_gconf_value (peditor, peditor->p->key, value);
 
666
 
 
667
        g_signal_emit (peditor, peditor_signals[VALUE_CHANGED], 0, peditor->p->key, value);
 
668
        gconf_value_free (value_wid);
 
669
        gconf_value_free (value);
 
670
}
 
671
 
 
672
static GObject *
 
673
gconf_peditor_new_string_valist (GConfChangeSet *changeset,
 
674
                                 const gchar    *key,
 
675
                                 GtkWidget      *entry,
 
676
                                 const gchar    *first_property_name,
 
677
                                 va_list         var_args)
 
678
{
 
679
        GObject *peditor;
 
680
 
 
681
        peditor = gconf_peditor_new
 
682
                (key,
 
683
                 (GConfClientNotifyFunc) peditor_string_value_changed,
 
684
                 changeset,
 
685
                 G_OBJECT (entry),
 
686
                 first_property_name,
 
687
                 var_args, NULL);
 
688
 
 
689
        g_signal_connect_swapped (entry, "changed",
 
690
                                  (GCallback) peditor_string_widget_changed, peditor);
 
691
 
 
692
        return peditor;
 
693
}
 
694
 
 
695
GObject *
 
696
gconf_peditor_new_string (GConfChangeSet *changeset,
 
697
                          const gchar    *key,
 
698
                          GtkWidget      *entry,
 
699
                          const gchar    *first_property_name,
 
700
                          ...)
 
701
{
 
702
        GObject *peditor;
 
703
        va_list var_args;
 
704
 
 
705
        g_return_val_if_fail (key != NULL, NULL);
 
706
        g_return_val_if_fail (entry != NULL, NULL);
 
707
        g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL);
 
708
 
 
709
        va_start (var_args, first_property_name);
 
710
 
 
711
        peditor = gconf_peditor_new_string_valist
 
712
                (changeset, key, entry,
 
713
                 first_property_name, var_args);
 
714
 
 
715
        va_end (var_args);
 
716
 
 
717
        return peditor;
 
718
}
 
719
 
 
720
static void
 
721
peditor_color_value_changed (GConfClient         *client,
 
722
                             guint                cnxn_id,
 
723
                             GConfEntry          *entry,
 
724
                             GConfPropertyEditor *peditor)
 
725
{
 
726
        GConfValue *value, *value_wid;
 
727
 
 
728
        if (peditor->p->changeset != NULL)
 
729
                gconf_change_set_remove (peditor->p->changeset, peditor->p->key);
 
730
 
 
731
        if (entry && (value = gconf_entry_get_value (entry))) {
 
732
                const gchar *spec;
 
733
 
 
734
                value_wid = peditor->p->conv_to_widget_cb (peditor, value);
 
735
                spec = gconf_value_get_string (value_wid);
 
736
                if (spec) {
 
737
                        GdkColor color;
 
738
                        gdk_color_parse (gconf_value_get_string (value_wid), &color);
 
739
                        gtk_color_button_set_color (
 
740
                            GTK_COLOR_BUTTON (peditor->p->ui_control), &color);
 
741
                }
 
742
                gconf_value_free (value_wid);
 
743
        }
 
744
}
 
745
 
 
746
static void
 
747
peditor_color_widget_changed (GConfPropertyEditor *peditor,
 
748
                              GtkColorButton      *cb)
 
749
{
 
750
        gchar *str;
 
751
        GConfValue *value, *value_wid;
 
752
        GdkColor color;
 
753
 
 
754
        if (!peditor->p->inited) return;
 
755
 
 
756
        value_wid = gconf_value_new (GCONF_VALUE_STRING);
 
757
        gtk_color_button_get_color (cb, &color);
 
758
        str = g_strdup_printf ("#%02x%02x%02x", color.red >> 8,
 
759
                               color.green >> 8, color.blue >> 8);
 
760
        gconf_value_set_string (value_wid, str);
 
761
        g_free (str);
 
762
 
 
763
        value = peditor->p->conv_from_widget_cb (peditor, value_wid);
 
764
 
 
765
        peditor_set_gconf_value (peditor, peditor->p->key, value);
 
766
        g_signal_emit (peditor, peditor_signals[VALUE_CHANGED], 0, peditor->p->key, value);
 
767
 
 
768
        gconf_value_free (value_wid);
 
769
        gconf_value_free (value);
 
770
}
 
771
 
 
772
GObject *
 
773
gconf_peditor_new_color (GConfChangeSet *changeset,
 
774
                         const gchar    *key,
 
775
                         GtkWidget      *cb,
 
776
                         const gchar    *first_property_name,
 
777
                         ...)
 
778
{
 
779
        GObject *peditor;
 
780
        va_list var_args;
 
781
 
 
782
        g_return_val_if_fail (key != NULL, NULL);
 
783
        g_return_val_if_fail (cb != NULL, NULL);
 
784
        g_return_val_if_fail (GTK_IS_COLOR_BUTTON (cb), NULL);
 
785
 
 
786
        va_start (var_args, first_property_name);
 
787
 
 
788
        peditor = gconf_peditor_new
 
789
                (key,
 
790
                 (GConfClientNotifyFunc) peditor_color_value_changed,
 
791
                 changeset,
 
792
                 G_OBJECT (cb),
 
793
                 first_property_name,
 
794
                 var_args, NULL);
 
795
 
 
796
        va_end (var_args);
 
797
 
 
798
        g_signal_connect_swapped (cb, "color_set",
 
799
                                  (GCallback) peditor_color_widget_changed, peditor);
 
800
 
 
801
        return peditor;
 
802
}
 
803
 
 
804
static int
 
805
peditor_enum_int_from_string (GType type, const gchar *str, gboolean use_nick)
 
806
{
 
807
        GEnumClass *klass;
 
808
        GEnumValue *val;
 
809
        int ret = -1;
 
810
 
 
811
        klass = g_type_class_ref (type);
 
812
        if (use_nick)
 
813
                val = g_enum_get_value_by_nick (klass, str);
 
814
        else
 
815
                val = g_enum_get_value_by_name (klass, str);
 
816
 
 
817
        g_type_class_unref (klass);
 
818
 
 
819
        if (val)
 
820
                ret = val->value;
 
821
 
 
822
        return ret;
 
823
}
 
824
 
 
825
static gchar*
 
826
peditor_enum_string_from_int (GType type, const int index, gboolean use_nick)
 
827
{
 
828
        GEnumClass *klass;
 
829
        GEnumValue *val;
 
830
        gchar *ret = NULL;
 
831
 
 
832
        klass = g_type_class_ref (type);
 
833
        val = g_enum_get_value (klass, index);
 
834
        if (val)
 
835
        {
 
836
                if (val->value_nick && use_nick)
 
837
                        ret = g_strdup (val->value_nick);
 
838
                else
 
839
                        ret = g_strdup (val->value_name);
 
840
        }
 
841
 
 
842
        g_type_class_unref (klass);
 
843
 
 
844
        return ret;
 
845
}
 
846
 
 
847
static GConfValue*
 
848
peditor_enum_conv_to_widget (GConfPropertyEditor *peditor,
 
849
                             const GConfValue *value)
 
850
{
 
851
        GConfValue *ret;
 
852
        GConfPropertyEditorEnumData *data = peditor->p->data;
 
853
        int index;
 
854
 
 
855
        if (value->type == GCONF_VALUE_INT)
 
856
                return gconf_value_copy (value);
 
857
 
 
858
        ret = gconf_value_new (GCONF_VALUE_INT);
 
859
 
 
860
        index = peditor_enum_int_from_string (data->enum_type,
 
861
                                              gconf_value_get_string (value),
 
862
                                              data->use_nick);
 
863
 
 
864
        gconf_value_set_int (ret, index);
 
865
 
 
866
        return ret;
 
867
}
 
868
 
 
869
static GConfValue*
 
870
peditor_enum_conv_from_widget (GConfPropertyEditor *peditor,
 
871
                               const GConfValue *value)
 
872
{
 
873
        GConfValue *ret;
 
874
        GConfPropertyEditorEnumData *data = peditor->p->data;
 
875
        gchar *str;
 
876
 
 
877
        if (value->type == GCONF_VALUE_STRING)
 
878
                return gconf_value_copy (value);
 
879
 
 
880
        ret = gconf_value_new (GCONF_VALUE_STRING);
 
881
        str = peditor_enum_string_from_int (data->enum_type,
 
882
                                            gconf_value_get_int (value),
 
883
                                            data->use_nick);
 
884
        gconf_value_set_string (ret, str);
 
885
        g_free (str);
 
886
 
 
887
        return ret;
 
888
}
 
889
 
 
890
static void
 
891
peditor_combo_box_value_changed (GConfClient         *client,
 
892
                                 guint                cnxn_id,
 
893
                                 GConfEntry          *entry,
 
894
                                 GConfPropertyEditor *peditor)
 
895
{
 
896
        GConfValue *value, *value_wid;
 
897
 
 
898
        if (peditor->p->changeset != NULL)
 
899
                gconf_change_set_remove (peditor->p->changeset, peditor->p->key);
 
900
 
 
901
        if (entry && (value = gconf_entry_get_value (entry))) {
 
902
                value_wid = peditor->p->conv_to_widget_cb (peditor, value);
 
903
                gtk_combo_box_set_active (GTK_COMBO_BOX (peditor->p->ui_control), gconf_value_get_int (value_wid));
 
904
                gconf_value_free (value_wid);
 
905
        }
 
906
}
 
907
 
 
908
static void
 
909
peditor_combo_box_widget_changed (GConfPropertyEditor *peditor,
 
910
                                  GtkComboBox         *combo_box)
 
911
{
 
912
        GConfValue *value, *value_wid;
 
913
 
 
914
        if (!peditor->p->inited) return;
 
915
        value_wid = gconf_value_new (GCONF_VALUE_INT);
 
916
        gconf_value_set_int (value_wid, gtk_combo_box_get_active (combo_box));
 
917
        value = peditor->p->conv_from_widget_cb (peditor, value_wid);
 
918
        peditor_set_gconf_value (peditor, peditor->p->key, value);
 
919
        g_signal_emit (peditor, peditor_signals[VALUE_CHANGED], 0, peditor->p->key, value);
 
920
        gconf_value_free (value_wid);
 
921
        if (value)
 
922
                gconf_value_free (value);
 
923
}
 
924
 
 
925
GObject *
 
926
gconf_peditor_new_combo_box (GConfChangeSet *changeset,
 
927
                             const gchar    *key,
 
928
                             GtkWidget      *combo_box,
 
929
                             const gchar    *first_property_name,
 
930
                             ...)
 
931
{
 
932
        GObject *peditor;
 
933
        va_list var_args;
 
934
 
 
935
        g_return_val_if_fail (key != NULL, NULL);
 
936
        g_return_val_if_fail (combo_box != NULL, NULL);
 
937
        g_return_val_if_fail (GTK_IS_COMBO_BOX (combo_box), NULL);
 
938
 
 
939
        va_start (var_args, first_property_name);
 
940
 
 
941
        peditor = gconf_peditor_new
 
942
                (key,
 
943
                 (GConfClientNotifyFunc) peditor_combo_box_value_changed,
 
944
                 changeset,
 
945
                 G_OBJECT (combo_box),
 
946
                 first_property_name,
 
947
                 var_args, NULL);
 
948
 
 
949
        va_end (var_args);
 
950
 
 
951
        g_signal_connect_swapped (combo_box, "changed",
 
952
                                  (GCallback) peditor_combo_box_widget_changed, peditor);
 
953
 
 
954
        return peditor;
 
955
}
 
956
 
 
957
GObject *
 
958
gconf_peditor_new_combo_box_with_enum   (GConfChangeSet *changeset,
 
959
                                         const gchar    *key,
 
960
                                         GtkWidget      *combo_box,
 
961
                                         GType           enum_type,
 
962
                                         gboolean        use_nick,
 
963
                                         const gchar    *first_property_name,
 
964
                                         ...)
 
965
{
 
966
        GObject *peditor;
 
967
        GConfPropertyEditorEnumData *data;
 
968
        va_list var_args;
 
969
 
 
970
        g_return_val_if_fail (key != NULL, NULL);
 
971
        g_return_val_if_fail (combo_box != NULL, NULL);
 
972
        g_return_val_if_fail (GTK_IS_COMBO_BOX (combo_box), NULL);
 
973
        g_return_val_if_fail (enum_type != G_TYPE_NONE, NULL);
 
974
 
 
975
        data = g_new0 (GConfPropertyEditorEnumData, 1);
 
976
        data->enum_type = enum_type;
 
977
        data->use_nick = use_nick;
 
978
 
 
979
        va_start (var_args, first_property_name);
 
980
 
 
981
        peditor = gconf_peditor_new
 
982
                (key,
 
983
                 (GConfClientNotifyFunc) peditor_combo_box_value_changed,
 
984
                 changeset,
 
985
                 G_OBJECT (combo_box),
 
986
                 first_property_name,
 
987
                 var_args,
 
988
                 "conv-to-widget-cb",
 
989
                 peditor_enum_conv_to_widget,
 
990
                 "conv-from-widget-cb",
 
991
                 peditor_enum_conv_from_widget,
 
992
                 "data",
 
993
                 data,
 
994
                 "data-free-cb",
 
995
                 g_free,
 
996
                 NULL
 
997
                 );
 
998
 
 
999
        va_end (var_args);
 
1000
 
 
1001
        g_signal_connect_swapped (combo_box, "changed",
 
1002
                                  (GCallback) peditor_combo_box_widget_changed, peditor);
 
1003
 
 
1004
        return peditor;
 
1005
}
 
1006
 
 
1007
static void
 
1008
peditor_select_radio_value_changed (GConfClient         *client,
 
1009
                                    guint                cnxn_id,
 
1010
                                    GConfEntry          *entry,
 
1011
                                    GConfPropertyEditor *peditor)
 
1012
{
 
1013
        GSList *group, *link;
 
1014
        GConfValue *value, *value_wid;
 
1015
 
 
1016
        if (peditor->p->changeset != NULL)
 
1017
                gconf_change_set_remove (peditor->p->changeset, peditor->p->key);
 
1018
 
 
1019
        if (entry && (value = gconf_entry_get_value (entry))) {
 
1020
                value_wid = peditor->p->conv_to_widget_cb (peditor, value);
 
1021
                group = g_slist_copy (gtk_radio_button_get_group (GTK_RADIO_BUTTON (peditor->p->ui_control)));
 
1022
                group = g_slist_reverse (group);
 
1023
                link = g_slist_nth (group, gconf_value_get_int (value_wid));
 
1024
                if (link && link->data)
 
1025
                        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (link->data), TRUE);
 
1026
                gconf_value_free (value_wid);
 
1027
                g_slist_free (group);
 
1028
        }
 
1029
}
 
1030
 
 
1031
static void
 
1032
peditor_select_radio_widget_changed (GConfPropertyEditor *peditor,
 
1033
                                     GtkToggleButton     *tb)
 
1034
{
 
1035
        GSList *group;
 
1036
        GConfValue *value, *value_wid;
 
1037
 
 
1038
        if (!peditor->p->inited) return;
 
1039
        if (!gtk_toggle_button_get_active (tb)) return;
 
1040
 
 
1041
        value_wid = gconf_value_new (GCONF_VALUE_INT);
 
1042
        group = g_slist_copy (gtk_radio_button_get_group (GTK_RADIO_BUTTON (peditor->p->ui_control)));
 
1043
        group = g_slist_reverse (group);
 
1044
 
 
1045
        gconf_value_set_int (value_wid, g_slist_index (group, tb));
 
1046
        value = peditor->p->conv_from_widget_cb (peditor, value_wid);
 
1047
 
 
1048
        peditor_set_gconf_value (peditor, peditor->p->key, value);
 
1049
        g_signal_emit (peditor, peditor_signals[VALUE_CHANGED], 0, peditor->p->key, value);
 
1050
 
 
1051
        gconf_value_free (value_wid);
 
1052
        gconf_value_free (value);
 
1053
        g_slist_free (group);
 
1054
}
 
1055
 
 
1056
GObject *
 
1057
gconf_peditor_new_select_radio (GConfChangeSet *changeset,
 
1058
                                const gchar    *key,
 
1059
                                GSList         *radio_group,
 
1060
                                const gchar    *first_property_name,
 
1061
                                ...)
 
1062
{
 
1063
        GObject *peditor;
 
1064
        GtkRadioButton *first_button;
 
1065
        GSList *item;
 
1066
        va_list var_args;
 
1067
 
 
1068
        g_return_val_if_fail (key != NULL, NULL);
 
1069
        g_return_val_if_fail (radio_group != NULL, NULL);
 
1070
        g_return_val_if_fail (radio_group->data != NULL, NULL);
 
1071
        g_return_val_if_fail (GTK_IS_RADIO_BUTTON (radio_group->data), NULL);
 
1072
 
 
1073
        first_button = GTK_RADIO_BUTTON (radio_group->data);
 
1074
 
 
1075
        va_start (var_args, first_property_name);
 
1076
 
 
1077
        peditor = gconf_peditor_new
 
1078
                (key,
 
1079
                 (GConfClientNotifyFunc) peditor_select_radio_value_changed,
 
1080
                 changeset,
 
1081
                 G_OBJECT (first_button),
 
1082
                 first_property_name,
 
1083
                 var_args, NULL);
 
1084
 
 
1085
        va_end (var_args);
 
1086
 
 
1087
        for (item = radio_group; item != NULL; item = item->next)
 
1088
                g_signal_connect_swapped (item->data, "toggled",
 
1089
                                          (GCallback) peditor_select_radio_widget_changed, peditor);
 
1090
 
 
1091
        return peditor;
 
1092
}
 
1093
 
 
1094
static void
 
1095
peditor_numeric_range_value_changed (GConfClient         *client,
 
1096
                                     guint                cnxn_id,
 
1097
                                     GConfEntry          *entry,
 
1098
                                     GConfPropertyEditor *peditor)
 
1099
{
 
1100
        GConfValue *value, *value_wid;
 
1101
 
 
1102
        if (peditor->p->changeset != NULL)
 
1103
                gconf_change_set_remove (peditor->p->changeset, peditor->p->key);
 
1104
 
 
1105
        if (entry && (value = gconf_entry_get_value (entry))) {
 
1106
                value_wid = peditor->p->conv_to_widget_cb (peditor, value);
 
1107
 
 
1108
                switch (value_wid->type) {
 
1109
                case GCONF_VALUE_FLOAT:
 
1110
                        gtk_adjustment_set_value (GTK_ADJUSTMENT (peditor->p->ui_control), gconf_value_get_float (value_wid));
 
1111
                        break;
 
1112
                case GCONF_VALUE_INT:
 
1113
                        gtk_adjustment_set_value (GTK_ADJUSTMENT (peditor->p->ui_control), gconf_value_get_int (value_wid));
 
1114
                        break;
 
1115
                default:
 
1116
                        g_warning ("Unknown type in range peditor: %d\n", value_wid->type);
 
1117
                }
 
1118
                gconf_value_free (value_wid);
 
1119
        }
 
1120
}
 
1121
 
 
1122
static void
 
1123
peditor_numeric_range_widget_changed (GConfPropertyEditor *peditor,
 
1124
                                      GtkAdjustment       *adjustment)
 
1125
{
 
1126
        GConfValue *value, *value_wid, *default_value;
 
1127
        GConfClient *client;
 
1128
 
 
1129
        if (!peditor->p->inited) return;
 
1130
 
 
1131
        /* We try to get the default type from the schemas.  if not, we default
 
1132
         * to an int.
 
1133
         */
 
1134
        client = gconf_client_get_default();
 
1135
 
 
1136
        default_value = gconf_client_get_default_from_schema (client,
 
1137
                                                              peditor->p->key,
 
1138
                                                              NULL);
 
1139
        g_object_unref (client);
 
1140
 
 
1141
        if (default_value) {
 
1142
                value_wid = gconf_value_new (default_value->type);
 
1143
                gconf_value_free (default_value);
 
1144
        } else {
 
1145
                g_warning ("Unable to find a default value for key for %s.\n"
 
1146
                           "I'll assume it is an integer, but that may break things.\n"
 
1147
                           "Please be sure that the associated schema is installed",
 
1148
                           peditor->p->key);
 
1149
                value_wid = gconf_value_new (GCONF_VALUE_INT);
 
1150
        }
 
1151
 
 
1152
        g_assert (value_wid);
 
1153
 
 
1154
        if (value_wid->type == GCONF_VALUE_INT)
 
1155
                gconf_value_set_int (value_wid, gtk_adjustment_get_value (adjustment));
 
1156
        else if (value_wid->type == GCONF_VALUE_FLOAT)
 
1157
                gconf_value_set_float (value_wid, gtk_adjustment_get_value (adjustment));
 
1158
        else {
 
1159
                g_warning ("unable to set a gconf key for %s of type %d",
 
1160
                           peditor->p->key,
 
1161
                           value_wid->type);
 
1162
                gconf_value_free (value_wid);
 
1163
                return;
 
1164
        }
 
1165
        value = peditor->p->conv_from_widget_cb (peditor, value_wid);
 
1166
        peditor_set_gconf_value (peditor, peditor->p->key, value);
 
1167
        g_signal_emit (peditor, peditor_signals[VALUE_CHANGED], 0, peditor->p->key, value);
 
1168
        gconf_value_free (value_wid);
 
1169
        gconf_value_free (value);
 
1170
}
 
1171
 
 
1172
GObject *
 
1173
gconf_peditor_new_numeric_range (GConfChangeSet *changeset,
 
1174
                                 const gchar    *key,
 
1175
                                 GtkWidget      *range,
 
1176
                                 const gchar    *first_property_name,
 
1177
                                 ...)
 
1178
{
 
1179
        GObject *peditor;
 
1180
        GObject *adjustment = NULL;
 
1181
        va_list var_args;
 
1182
 
 
1183
        g_return_val_if_fail (key != NULL, NULL);
 
1184
        g_return_val_if_fail (range != NULL, NULL);
 
1185
        g_return_val_if_fail (GTK_IS_RANGE (range)||GTK_IS_SPIN_BUTTON (range), NULL);
 
1186
 
 
1187
        if (GTK_IS_RANGE (range))
 
1188
                adjustment = G_OBJECT (gtk_range_get_adjustment (GTK_RANGE (range)));
 
1189
        else if (GTK_IS_SPIN_BUTTON (range))
 
1190
                adjustment = G_OBJECT (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (range)));
 
1191
        else
 
1192
                g_assert_not_reached ();
 
1193
 
 
1194
        va_start (var_args, first_property_name);
 
1195
 
 
1196
        peditor = gconf_peditor_new
 
1197
                (key,
 
1198
                 (GConfClientNotifyFunc) peditor_numeric_range_value_changed,
 
1199
                 changeset,
 
1200
                 adjustment,
 
1201
                 first_property_name,
 
1202
                 var_args, NULL);
 
1203
 
 
1204
        va_end (var_args);
 
1205
 
 
1206
        g_signal_connect_swapped (adjustment, "value_changed",
 
1207
                                  (GCallback) peditor_numeric_range_widget_changed, peditor);
 
1208
 
 
1209
        return peditor;
 
1210
}
 
1211
 
 
1212
static gboolean
 
1213
guard_get_bool (GConfPropertyEditor *peditor, const GConfValue *value)
 
1214
{
 
1215
        if (value->type == GCONF_VALUE_BOOL)
 
1216
                return gconf_value_get_bool (value);
 
1217
        else
 
1218
        {
 
1219
                GConfPropertyEditorEnumData *data = peditor->p->data;
 
1220
                int index = peditor_enum_int_from_string (data->enum_type, gconf_value_get_string (value), data->use_nick);
 
1221
                return (index != data->enum_val_false);
 
1222
        }
 
1223
}
 
1224
 
 
1225
static void
 
1226
guard_value_changed (GConfPropertyEditor *peditor,
 
1227
                     const gchar         *key,
 
1228
                     const GConfValue    *value,
 
1229
                     GtkWidget           *widget)
 
1230
{
 
1231
        gtk_widget_set_sensitive (widget, guard_get_bool (peditor, value));
 
1232
}
 
1233
 
 
1234
void
 
1235
gconf_peditor_widget_set_guard (GConfPropertyEditor *peditor,
 
1236
                                GtkWidget           *widget)
 
1237
{
 
1238
        GConfClient *client;
 
1239
        GConfValue *value;
 
1240
 
 
1241
        g_return_if_fail (peditor != NULL);
 
1242
        g_return_if_fail (IS_GCONF_PROPERTY_EDITOR (peditor));
 
1243
        g_return_if_fail (widget != NULL);
 
1244
        g_return_if_fail (GTK_IS_WIDGET (widget));
 
1245
 
 
1246
        client = gconf_client_get_default ();
 
1247
        value = gconf_client_get (client, peditor->p->key, NULL);
 
1248
        g_object_unref (client);
 
1249
 
 
1250
        if (value) {
 
1251
                gtk_widget_set_sensitive (widget, guard_get_bool (peditor, value));
 
1252
                gconf_value_free (value);
 
1253
        } else {
 
1254
                g_warning ("NULL GConf value: %s: possibly incomplete setup", peditor->p->key);
 
1255
        }
 
1256
 
 
1257
        g_signal_connect (peditor, "value-changed", (GCallback) guard_value_changed, widget);
 
1258
}
 
1259
 
 
1260
GConfValue *
 
1261
gconf_value_int_to_float (GConfPropertyEditor *ignored, const GConfValue *value)
 
1262
{
 
1263
        GConfValue *new_value;
 
1264
 
 
1265
        new_value = gconf_value_new (GCONF_VALUE_FLOAT);
 
1266
        gconf_value_set_float (new_value, gconf_value_get_int (value));
 
1267
        return new_value;
 
1268
}
 
1269
 
 
1270
GConfValue *
 
1271
gconf_value_float_to_int (GConfPropertyEditor *ignored, const GConfValue *value)
 
1272
{
 
1273
        GConfValue *new_value;
 
1274
 
 
1275
        new_value = gconf_value_new (GCONF_VALUE_INT);
 
1276
        gconf_value_set_int (new_value, gconf_value_get_float (value));
 
1277
        return new_value;
 
1278
}
 
1279
 
 
1280
static void
 
1281
peditor_font_value_changed (GConfClient         *client,
 
1282
                            guint                cnxn_id,
 
1283
                            GConfEntry          *entry,
 
1284
                            GConfPropertyEditor *peditor)
 
1285
{
 
1286
        GConfValue *value, *value_wid;
 
1287
 
 
1288
        if (peditor->p->changeset != NULL)
 
1289
                gconf_change_set_remove (peditor->p->changeset, peditor->p->key);
 
1290
 
 
1291
        if (entry && (value = gconf_entry_get_value (entry))) {
 
1292
                const gchar *font;
 
1293
 
 
1294
                value_wid = peditor->p->conv_to_widget_cb (peditor, value);
 
1295
                font = gconf_value_get_string (value_wid);
 
1296
                gtk_font_button_set_font_name (GTK_FONT_BUTTON (peditor->p->ui_control),
 
1297
                                               font);
 
1298
                gconf_value_free (value_wid);
 
1299
        }
 
1300
}
 
1301
 
 
1302
static void
 
1303
peditor_font_widget_changed (GConfPropertyEditor *peditor,
 
1304
                             GtkFontButton       *font_button)
 
1305
{
 
1306
        const gchar *font_name;
 
1307
        GConfValue *value, *value_wid = NULL;
 
1308
 
 
1309
        if (!peditor->p->inited)
 
1310
                return;
 
1311
 
 
1312
        font_name = gtk_font_button_get_font_name (font_button);
 
1313
 
 
1314
        value_wid = gconf_value_new (GCONF_VALUE_STRING);
 
1315
        gconf_value_set_string (value_wid, font_name);
 
1316
 
 
1317
        value = peditor->p->conv_from_widget_cb (peditor, value_wid);
 
1318
 
 
1319
        peditor_set_gconf_value (peditor, peditor->p->key, value);
 
1320
        g_signal_emit (peditor, peditor_signals[VALUE_CHANGED], 0, peditor->p->key, value);
 
1321
 
 
1322
        gconf_value_free (value_wid);
 
1323
        gconf_value_free (value);
 
1324
}
 
1325
 
 
1326
GObject *
 
1327
gconf_peditor_new_font (GConfChangeSet *changeset,
 
1328
                        const gchar *key,
 
1329
                        GtkWidget *font_button,
 
1330
                        const gchar *first_property_name,
 
1331
                        ...)
 
1332
{
 
1333
        GObject *peditor;
 
1334
        va_list var_args;
 
1335
 
 
1336
        g_return_val_if_fail (key != NULL, NULL);
 
1337
        g_return_val_if_fail (GTK_IS_FONT_BUTTON (font_button), NULL);
 
1338
 
 
1339
        va_start (var_args, first_property_name);
 
1340
 
 
1341
        peditor = gconf_peditor_new (key,
 
1342
                                     (GConfClientNotifyFunc) peditor_font_value_changed,
 
1343
                                     changeset,
 
1344
                                     G_OBJECT (font_button),
 
1345
                                     first_property_name,
 
1346
                                     var_args,
 
1347
                                     NULL);
 
1348
 
 
1349
        va_end (var_args);
 
1350
 
 
1351
        g_signal_connect_swapped (font_button, "font_set",
 
1352
                                  (GCallback) peditor_font_widget_changed, peditor);
 
1353
 
 
1354
        return peditor;
 
1355
}
 
1356
 
 
1357
static GConfValue*
 
1358
peditor_enum_toggle_conv_to_widget (GConfPropertyEditor *peditor,
 
1359
                                    const GConfValue *value)
 
1360
{
 
1361
        GConfValue *ret;
 
1362
        GConfPropertyEditorEnumData *data = peditor->p->data;
 
1363
        int index;
 
1364
 
 
1365
        if (value->type == GCONF_VALUE_BOOL)
 
1366
                return gconf_value_copy (value);
 
1367
 
 
1368
        ret = gconf_value_new (GCONF_VALUE_BOOL);
 
1369
 
 
1370
        index = peditor_enum_int_from_string (data->enum_type,
 
1371
                                              gconf_value_get_string (value),
 
1372
                                              data->use_nick);
 
1373
        gconf_value_set_bool (ret, (index != data->enum_val_false));
 
1374
 
 
1375
        return ret;
 
1376
}
 
1377
 
 
1378
static GConfValue*
 
1379
peditor_enum_toggle_conv_from_widget (GConfPropertyEditor *peditor,
 
1380
                                      const GConfValue *value)
 
1381
{
 
1382
        GConfValue *ret;
 
1383
        GConfPropertyEditorEnumData *data = peditor->p->data;
 
1384
        gchar *str;
 
1385
        int index;
 
1386
 
 
1387
        if (value->type == GCONF_VALUE_STRING)
 
1388
                return gconf_value_copy (value);
 
1389
 
 
1390
        ret = gconf_value_new (GCONF_VALUE_STRING);
 
1391
        if (gconf_value_get_bool (value))
 
1392
                index = data->enum_val_true_fn (peditor, data->enum_val_true_fn_data);
 
1393
        else
 
1394
                index = data->enum_val_false;
 
1395
 
 
1396
        str = peditor_enum_string_from_int (data->enum_type, index, data->use_nick);
 
1397
        gconf_value_set_string (ret, str);
 
1398
        g_free (str);
 
1399
 
 
1400
        return ret;
 
1401
}
 
1402
 
 
1403
GObject *
 
1404
gconf_peditor_new_enum_toggle  (GConfChangeSet          *changeset,
 
1405
                                const gchar             *key,
 
1406
                                GtkWidget               *checkbox,
 
1407
                                GType                    enum_type,
 
1408
                                GConfPEditorGetValueFn   val_true_fn,
 
1409
                                guint                    val_false,
 
1410
                                gboolean                 use_nick,
 
1411
                                gpointer                 data,
 
1412
                                const gchar             *first_property_name,
 
1413
                                ...)
 
1414
{
 
1415
        GObject *peditor;
 
1416
        GConfPropertyEditorEnumData *enum_data;
 
1417
        va_list var_args;
 
1418
 
 
1419
        g_return_val_if_fail (key != NULL, NULL);
 
1420
        g_return_val_if_fail (checkbox != NULL, NULL);
 
1421
        g_return_val_if_fail (GTK_IS_TOGGLE_BUTTON (checkbox), NULL);
 
1422
 
 
1423
        enum_data = g_new0 (GConfPropertyEditorEnumData, 1);
 
1424
        enum_data->enum_type = enum_type;
 
1425
        enum_data->enum_val_true_fn = val_true_fn;
 
1426
        enum_data->enum_val_true_fn_data = data;
 
1427
        enum_data->enum_val_false = val_false;
 
1428
        enum_data->use_nick = use_nick;
 
1429
 
 
1430
        va_start (var_args, first_property_name);
 
1431
 
 
1432
        peditor = gconf_peditor_new
 
1433
                (key,
 
1434
                 (GConfClientNotifyFunc) peditor_boolean_value_changed,
 
1435
                 changeset,
 
1436
                 G_OBJECT (checkbox),
 
1437
                 first_property_name,
 
1438
                 var_args,
 
1439
                 "conv-to-widget-cb",
 
1440
                 peditor_enum_toggle_conv_to_widget,
 
1441
                 "conv-from-widget-cb",
 
1442
                 peditor_enum_toggle_conv_from_widget,
 
1443
                 "data",
 
1444
                 enum_data,
 
1445
                 "data-free-cb",
 
1446
                 g_free,
 
1447
                 NULL);
 
1448
 
 
1449
        va_end (var_args);
 
1450
 
 
1451
        g_signal_connect_swapped (checkbox, "toggled",
 
1452
                                  (GCallback) peditor_boolean_widget_changed, peditor);
 
1453
 
 
1454
        return peditor;
 
1455
}
 
1456
 
 
1457
static gboolean
 
1458
peditor_image_set_filename (GConfPropertyEditor *peditor, const gchar *filename)
 
1459
{
 
1460
        GdkPixbuf *pixbuf = NULL;
 
1461
        GtkImage *image = NULL;
 
1462
        const int scale = 100;
 
1463
        gchar *message = NULL;
 
1464
        GtkWidget *ui_control_child;
 
1465
        GList *l;
 
1466
 
 
1467
        /* NULL is not valid, however "" is, but not an error (it's
 
1468
         * the default) */
 
1469
        g_return_val_if_fail (filename != NULL, FALSE);
 
1470
 
 
1471
 
 
1472
        if (!g_file_test (filename, G_FILE_TEST_EXISTS))
 
1473
        {
 
1474
                message = g_strdup_printf (_("Couldn't find the file '%s'.\n\nPlease make "
 
1475
                                              "sure it exists and try again, "
 
1476
                                              "or choose a different background picture."),
 
1477
                                           filename);
 
1478
 
 
1479
        }
 
1480
        else if (!(pixbuf = gdk_pixbuf_new_from_file_at_size (filename, scale, scale, NULL)))
 
1481
        {
 
1482
                message = g_strdup_printf (_("I don't know how to open the file '%s'.\n"
 
1483
                                             "Perhaps it's "
 
1484
                                             "a kind of picture that is not yet supported.\n\n"
 
1485
                                             "Please select a different picture instead."),
 
1486
                                           filename);
 
1487
        }
 
1488
 
 
1489
        ui_control_child = gtk_bin_get_child (GTK_BIN (peditor->p->ui_control));
 
1490
 
 
1491
        if (GTK_IS_IMAGE (ui_control_child))
 
1492
                image = GTK_IMAGE (ui_control_child);
 
1493
        else
 
1494
        {
 
1495
                for (l = gtk_container_get_children (GTK_CONTAINER (ui_control_child)); l != NULL; l = l->next)
 
1496
                {
 
1497
                        if (GTK_IS_IMAGE (l->data))
 
1498
                                image = GTK_IMAGE (l->data);
 
1499
                        else if (GTK_IS_LABEL (l->data) && message == NULL)
 
1500
                        {
 
1501
                                gchar *base = g_path_get_basename (filename);
 
1502
                                gtk_label_set_text (GTK_LABEL (l->data), base);
 
1503
                                g_free (base);
 
1504
                        }
 
1505
                }
 
1506
        }
 
1507
 
 
1508
        if (message)
 
1509
        {
 
1510
                if (peditor->p->inited)
 
1511
                {
 
1512
                        GtkWidget *box;
 
1513
 
 
1514
                        box = gtk_message_dialog_new (NULL,
 
1515
                                                      GTK_DIALOG_MODAL,
 
1516
                                                      GTK_MESSAGE_ERROR,
 
1517
                                                      GTK_BUTTONS_OK,
 
1518
                                                      "%s",
 
1519
                                                      message);
 
1520
                        gtk_dialog_run (GTK_DIALOG (box));
 
1521
                        gtk_widget_destroy (box);
 
1522
                } else {
 
1523
                        gtk_image_set_from_stock (image, GTK_STOCK_MISSING_IMAGE,
 
1524
                                                  GTK_ICON_SIZE_BUTTON);
 
1525
                }
 
1526
                g_free (message);
 
1527
 
 
1528
                return FALSE;
 
1529
        }
 
1530
 
 
1531
        gtk_image_set_from_pixbuf (image, pixbuf);
 
1532
        g_object_unref (pixbuf);
 
1533
 
 
1534
        return TRUE;
 
1535
}
 
1536
 
 
1537
static void
 
1538
peditor_image_chooser_response_cb (GtkWidget *chooser,
 
1539
                                   gint response,
 
1540
                                   GConfPropertyEditor *peditor)
 
1541
{
 
1542
        GConfValue *value, *value_wid;
 
1543
        gchar *filename;
 
1544
 
 
1545
        if (response == GTK_RESPONSE_CANCEL ||
 
1546
            response == GTK_RESPONSE_DELETE_EVENT)
 
1547
        {
 
1548
                gtk_widget_destroy (chooser);
 
1549
                return;
 
1550
        }
 
1551
 
 
1552
        if (!peditor->p->inited)
 
1553
                return;
 
1554
 
 
1555
        filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser));
 
1556
        if (!(filename && peditor_image_set_filename (peditor, filename)))
 
1557
        {
 
1558
                g_free (filename);
 
1559
                return;
 
1560
        }
 
1561
 
 
1562
        value_wid = gconf_value_new (GCONF_VALUE_STRING);
 
1563
        gconf_value_set_string (value_wid, filename);
 
1564
        value = peditor->p->conv_from_widget_cb (peditor, value_wid);
 
1565
 
 
1566
        peditor_set_gconf_value (peditor, peditor->p->key, value);
 
1567
        g_signal_emit (peditor, peditor_signals[VALUE_CHANGED], 0, peditor->p->key, value);
 
1568
 
 
1569
        gconf_value_free (value_wid);
 
1570
        gconf_value_free (value);
 
1571
        g_free (filename);
 
1572
        gtk_widget_destroy (chooser);
 
1573
}
 
1574
 
 
1575
static void
 
1576
peditor_image_chooser_update_preview_cb (GtkFileChooser *chooser,
 
1577
                                         GtkImage *preview)
 
1578
{
 
1579
        char *filename;
 
1580
        GdkPixbuf *pixbuf = NULL;
 
1581
        const int scale = 100;
 
1582
 
 
1583
        filename = gtk_file_chooser_get_preview_filename (chooser);
 
1584
 
 
1585
        if (filename != NULL && g_file_test (filename, G_FILE_TEST_IS_REGULAR))
 
1586
                pixbuf = gdk_pixbuf_new_from_file_at_size (filename, scale, scale, NULL);
 
1587
 
 
1588
        gtk_image_set_from_pixbuf (preview, pixbuf);
 
1589
 
 
1590
        g_free (filename);
 
1591
 
 
1592
        if (pixbuf != NULL)
 
1593
                g_object_unref (pixbuf);
 
1594
}
 
1595
 
 
1596
static void
 
1597
peditor_image_clicked_cb (GConfPropertyEditor *peditor, GtkButton *button)
 
1598
{
 
1599
        GConfValue *value = NULL, *value_wid;
 
1600
        const gchar *filename;
 
1601
        GtkWidget *chooser, *toplevel, *preview, *preview_box;
 
1602
 
 
1603
        toplevel = gtk_widget_get_toplevel (GTK_WIDGET (button));
 
1604
        chooser = gtk_file_chooser_dialog_new (_("Please select an image."),
 
1605
                                               GTK_IS_WINDOW (toplevel) ? GTK_WINDOW (toplevel)
 
1606
                                                                        : NULL,
 
1607
                                               GTK_FILE_CHOOSER_ACTION_OPEN,
 
1608
                                               GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
 
1609
                                               _("_Select"), GTK_RESPONSE_OK,
 
1610
                                               NULL);
 
1611
 
 
1612
        preview = gtk_image_new ();
 
1613
 
 
1614
        preview_box = gtk_hbox_new (FALSE, 6);
 
1615
        gtk_box_pack_start (GTK_BOX (preview_box), preview, FALSE, TRUE, 0);
 
1616
        gtk_container_set_border_width (GTK_CONTAINER (preview_box), 6);
 
1617
 
 
1618
        gtk_widget_show_all (preview_box);
 
1619
        gtk_file_chooser_set_preview_widget (GTK_FILE_CHOOSER (chooser),
 
1620
                                             preview_box);
 
1621
        gtk_file_chooser_set_preview_widget_active (GTK_FILE_CHOOSER (chooser),
 
1622
                                                    TRUE);
 
1623
 
 
1624
        gtk_dialog_set_default_response (GTK_DIALOG (chooser), GTK_RESPONSE_OK);
 
1625
        gtk_window_set_destroy_with_parent (GTK_WINDOW (chooser), TRUE);
 
1626
        gtk_window_set_modal (GTK_WINDOW (chooser), TRUE);
 
1627
 
 
1628
        /* need the current filename */
 
1629
        if (peditor->p->changeset)
 
1630
                gconf_change_set_check_value (peditor->p->changeset, peditor->p->key, &value);
 
1631
 
 
1632
        if (value)
 
1633
        {
 
1634
                /* the one we got is not a copy */
 
1635
                value = gconf_value_copy (value);
 
1636
        }
 
1637
        else
 
1638
        {
 
1639
                GConfClient *client = gconf_client_get_default ();
 
1640
                value = gconf_client_get (client, peditor->p->key, NULL);
 
1641
                g_object_unref (client);
 
1642
        }
 
1643
 
 
1644
        value_wid = peditor->p->conv_to_widget_cb (peditor, value);
 
1645
        filename = gconf_value_get_string (value_wid);
 
1646
 
 
1647
        if (filename && strcmp (filename, ""))
 
1648
                gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (chooser), filename);
 
1649
 
 
1650
        g_signal_connect (chooser, "update-preview",
 
1651
                          G_CALLBACK (peditor_image_chooser_update_preview_cb),
 
1652
                          preview);
 
1653
        g_signal_connect (chooser, "response",
 
1654
                          G_CALLBACK (peditor_image_chooser_response_cb),
 
1655
                          peditor);
 
1656
 
 
1657
        if (gtk_grab_get_current ())
 
1658
                gtk_grab_add (chooser);
 
1659
 
 
1660
        gtk_widget_show (chooser);
 
1661
 
 
1662
        gconf_value_free (value);
 
1663
        gconf_value_free (value_wid);
 
1664
}
 
1665
 
 
1666
static void
 
1667
peditor_image_value_changed (GConfClient         *client,
 
1668
                             guint                cnxn_id,
 
1669
                             GConfEntry          *entry,
 
1670
                             GConfPropertyEditor *peditor)
 
1671
{
 
1672
        GConfValue *value, *value_wid;
 
1673
 
 
1674
        if (peditor->p->changeset != NULL)
 
1675
                gconf_change_set_remove (peditor->p->changeset, peditor->p->key);
 
1676
 
 
1677
        if (entry && (value = gconf_entry_get_value (entry))) {
 
1678
                const gchar *filename;
 
1679
 
 
1680
                value_wid = peditor->p->conv_to_widget_cb (peditor, value);
 
1681
                filename = gconf_value_get_string (value_wid);
 
1682
                peditor_image_set_filename (peditor, filename);
 
1683
                gconf_value_free (value_wid);
 
1684
        }
 
1685
}
 
1686
 
 
1687
GObject *
 
1688
gconf_peditor_new_image (GConfChangeSet   *changeset,
 
1689
                         const gchar      *key,
 
1690
                         GtkWidget        *button,
 
1691
                         const gchar      *first_property_name,
 
1692
                         ...)
 
1693
{
 
1694
        GObject *peditor;
 
1695
        va_list var_args;
 
1696
 
 
1697
        g_return_val_if_fail (key != NULL, NULL);
 
1698
        g_return_val_if_fail (button != NULL, NULL);
 
1699
        g_return_val_if_fail (GTK_IS_BUTTON (button), NULL);
 
1700
 
 
1701
        va_start (var_args, first_property_name);
 
1702
 
 
1703
        peditor = gconf_peditor_new
 
1704
                (key,
 
1705
                 (GConfClientNotifyFunc) peditor_image_value_changed,
 
1706
                 changeset,
 
1707
                 G_OBJECT (button),
 
1708
                 first_property_name,
 
1709
                 var_args, NULL);
 
1710
 
 
1711
        va_end (var_args);
 
1712
 
 
1713
        g_signal_connect_swapped (button, "clicked",
 
1714
                                  (GCallback) peditor_image_clicked_cb, peditor);
 
1715
 
 
1716
        return peditor;
 
1717
}
 
1718
 
 
1719
GObject *
 
1720
gconf_peditor_new_select_radio_with_enum (GConfChangeSet *changeset,
 
1721
                                          const gchar    *key,
 
1722
                                          GSList         *radio_group,
 
1723
                                          GType          enum_type,
 
1724
                                          gboolean       use_nick,
 
1725
                                          const gchar    *first_property_name,
 
1726
                                          ...)
 
1727
{
 
1728
        GObject *peditor;
 
1729
        GConfPropertyEditorEnumData *enum_data;
 
1730
        GtkRadioButton *first_button;
 
1731
        GSList *item;
 
1732
        va_list var_args;
 
1733
 
 
1734
        g_return_val_if_fail (key != NULL, NULL);
 
1735
        g_return_val_if_fail (radio_group != NULL, NULL);
 
1736
        g_return_val_if_fail (radio_group->data != NULL, NULL);
 
1737
        g_return_val_if_fail (GTK_IS_RADIO_BUTTON (radio_group->data), NULL);
 
1738
 
 
1739
        enum_data = g_new0 (GConfPropertyEditorEnumData, 1);
 
1740
        enum_data->enum_type = enum_type;
 
1741
        enum_data->use_nick = use_nick;
 
1742
 
 
1743
        first_button = GTK_RADIO_BUTTON (radio_group->data);
 
1744
 
 
1745
        va_start (var_args, first_property_name);
 
1746
 
 
1747
        peditor = gconf_peditor_new
 
1748
                (key,
 
1749
                 (GConfClientNotifyFunc) peditor_select_radio_value_changed,
 
1750
                 changeset,
 
1751
                 G_OBJECT (first_button),
 
1752
                 first_property_name,
 
1753
                 var_args,
 
1754
                 "conv-to-widget-cb",
 
1755
                 peditor_enum_conv_to_widget,
 
1756
                 "conv-from-widget-cb",
 
1757
                 peditor_enum_conv_from_widget,
 
1758
                 "data",
 
1759
                 enum_data,
 
1760
                 "data-free-cb",
 
1761
                 g_free,
 
1762
                 NULL);
 
1763
 
 
1764
        va_end (var_args);
 
1765
 
 
1766
        for (item = radio_group; item != NULL; item = item->next)
 
1767
                g_signal_connect_swapped (item->data, "toggled",
 
1768
                                          (GCallback) peditor_select_radio_widget_changed, peditor);
 
1769
 
 
1770
        return peditor;
 
1771
}
 
1772
 
 
1773
static void
 
1774
peditor_tree_view_value_changed (GConfClient         *client,
 
1775
                                 guint                cnxn_id,
 
1776
                                 GConfEntry          *entry,
 
1777
                                 GConfPropertyEditor *peditor)
 
1778
{
 
1779
        GConfValue *value;
 
1780
 
 
1781
        if (peditor->p->changeset != NULL)
 
1782
                gconf_change_set_remove (peditor->p->changeset, peditor->p->key);
 
1783
 
 
1784
        if (entry && (value = gconf_entry_get_value (entry))) {
 
1785
                GtkTreeView *treeview;
 
1786
                GtkTreeSelection *selection;
 
1787
                GConfValue *value_wid;
 
1788
 
 
1789
                treeview = GTK_TREE_VIEW (peditor->p->ui_control);
 
1790
                selection = gtk_tree_view_get_selection (treeview);
 
1791
 
 
1792
                value_wid = peditor->p->conv_to_widget_cb (peditor, value);
 
1793
 
 
1794
                if (value_wid != NULL) {
 
1795
                        GtkTreePath *path = gtk_tree_path_new_from_string (
 
1796
                                gconf_value_get_string (value_wid));
 
1797
                        gtk_tree_selection_select_path (selection, path);
 
1798
                        gtk_tree_view_scroll_to_cell (treeview, path, NULL, FALSE, 0, 0);
 
1799
                        gtk_tree_path_free (path);
 
1800
                        gconf_value_free (value_wid);
 
1801
                } else {
 
1802
                        gtk_tree_selection_unselect_all (selection);
 
1803
                }
 
1804
        }
 
1805
}
 
1806
 
 
1807
static void
 
1808
peditor_tree_view_widget_changed (GConfPropertyEditor *peditor,
 
1809
                                  GtkTreeSelection    *selection)
 
1810
{
 
1811
        GtkTreeModel *model;
 
1812
        GtkTreeIter iter;
 
1813
        GConfValue *value, *value_wid;
 
1814
 
 
1815
        if (!peditor->p->inited) return;
 
1816
 
 
1817
        /* we don't support GTK_SELECTION_MULTIPLE */
 
1818
        if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
 
1819
                gchar *path;
 
1820
 
 
1821
                path = gtk_tree_model_get_string_from_iter (model, &iter);
 
1822
                value_wid = gconf_value_new (GCONF_VALUE_STRING);
 
1823
                gconf_value_set_string (value_wid, path);
 
1824
                g_free (path);
 
1825
        } else
 
1826
                value_wid = NULL;
 
1827
 
 
1828
        value = peditor->p->conv_from_widget_cb (peditor, value_wid);
 
1829
        peditor_set_gconf_value (peditor, peditor->p->key, value);
 
1830
        g_signal_emit (peditor, peditor_signals[VALUE_CHANGED], 0, peditor->p->key, value);
 
1831
 
 
1832
        if (value_wid)
 
1833
                gconf_value_free (value_wid);
 
1834
        if (value)
 
1835
                gconf_value_free (value);
 
1836
}
 
1837
 
 
1838
GObject *
 
1839
gconf_peditor_new_tree_view (GConfChangeSet *changeset,
 
1840
                             const gchar    *key,
 
1841
                             GtkWidget      *tree_view,
 
1842
                             const gchar    *first_property_name,
 
1843
                             ...)
 
1844
{
 
1845
        GObject *peditor;
 
1846
        va_list var_args;
 
1847
 
 
1848
        g_return_val_if_fail (key != NULL, NULL);
 
1849
        g_return_val_if_fail (tree_view != NULL, NULL);
 
1850
        g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), NULL);
 
1851
 
 
1852
        va_start (var_args, first_property_name);
 
1853
 
 
1854
        peditor = gconf_peditor_new
 
1855
                (key,
 
1856
                 (GConfClientNotifyFunc) peditor_tree_view_value_changed,
 
1857
                 changeset,
 
1858
                 G_OBJECT (tree_view),
 
1859
                 first_property_name,
 
1860
                 var_args, NULL);
 
1861
 
 
1862
        va_end (var_args);
 
1863
 
 
1864
        g_signal_connect_swapped (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)),
 
1865
                                  "changed",
 
1866
                                  (GCallback) peditor_tree_view_widget_changed, peditor);
 
1867
 
 
1868
        return peditor;
 
1869
}