~ubuntu-branches/ubuntu/oneiric/gnome-panel/oneiric

« back to all changes in this revision

Viewing changes to gnome-panel/panel-profile.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher, Sebastien Bacher, Jeremy Bicha
  • Date: 2011-05-30 11:04:49 UTC
  • mfrom: (1.13.10 upstream) (2.2.5 experimental)
  • Revision ID: james.westby@ubuntu.com-20110530110449-hinl17kxkcefjw6x
Tags: 1:3.0.2-0ubuntu1
[ Sebastien Bacher ]
* New upstream version
* debian/control.in:
  - the new libgweather version is in oneiric, use it
  - drop the python and python-gconf depends, 
    they were added for gnome-panel-add which is still using gconf and buggy
* debian/gnome-panel-data.install:
  - don't install the apport hook, it's only getting gconf datas which 
    doesn't work since gnome-panel uses gsettings
* debian/patches/90_build_fixes.patch:
  - restore build fix from git not applied in the new serie
* debian/patches/01_panel_submenus.patch:
  - don't take that Debian diff, the .menus use the upstream naming in Ubuntu
* debian/patches/06_no_resize_grip.patch:
  - dropped, the issue is fixed in the new version
* debian/patches/50_fix-potfiles.patch:
  - dropped, the issue is fixed in the new version
* debian/watch:
  - track unstable series as well

Drop those delta, since gnome-panel is not the default Ubuntu session now we
can go back to an experience closer to the upstream one: 
* debian/control.in:
  - drop the indicators recommends, unity-2d is the ubuntu fallback session
    so we can get back to use an upstream config for gnome-panel and reduce
    the delta we carry
* debian/patches/04_default_panel_config.patch:
  - don't modify the upstream layout
* debian/patches/05_no_session_delay.patch:
  - no need to tweak the upstream session to optimize it
* debian/patches/16_compiz_workspace_switcher.patch:
  - go back to the upstream switcher behaviour    
* debian/patches/25_dynamic_fusa_detection.patch:
  - not needed since we use the upstream layout, could be ported if someone
    is wanting to do the work though
* debian/patches/30_disable-initial-animation.patch, debian/rules:
  - drop the --disable-initial-animation, that was some login optimization
    but since it's not the default desktop you should go back to the 
    upstream behaviour

[ Jeremy Bicha ]   
* New upstream version
* Merge from Debian experimental, remaining Ubuntu changes:
* debian/control:
  - Recommends gnome-settings-daemon which has the timezone polkit service
* debian/rules:
  - Update translations template.
* debian/gnome-panel-data.install:
  - Install apport hook
  - Install the "About Ubuntu" menu item.
* debian/patches/01_layout.patch:
  - Disabled, Help & About Ubuntu don't fit as well in Gnome Panel 3
* debian/patches/01_panel_submenus.patch.
  - Dropped
* debian/patches/03_dnd_places_link.patch:
  - Disabled, when using Drag'n'Drop from Places menu, install a link launcher
    (.desktop file) instead of copying the entire directory.
* debian/patches/17_about-ubuntu-translation.patch:
  - List ubuntu-about.desktop for translation.
* debian/patches/40_unset_menuproxy.patch:
  - Make sure gnome-panel and the applets don't pick up menu proxies.
* debian/patches/50_fix-potfiles.patch
  - Fix i18n
* debian/patches/85_disable_shutdown_on_ltsp.patch:
  - Suppress the shutdown option in the panel if LTSP_CLIENT is set.
* debian/patches/71_change_bookmark_submenu_limit_value.patch
  - Dropped, picked up by Debian
* debian/patches/18_lockdown_lock_editor.patch:
* debian/patches/90_git_wnck_show_realize.patch:
* debian/patches/90_fix_linking_DSO_link.patch:
* debian/patches/91_gir_annotations.patch
* debian/patches/92_git_calendar_day.patch
* debian/patches/92_git_fix_applets_in_multiscreen.patch:
  - Dropped, applied upstream
* debian/watch:
  - watch unstable versions

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * panel-profile.c:
3
 
 *
4
 
 * Copyright (C) 2003 Sun Microsystems, Inc.
5
 
 *
6
 
 * This program is free software; you can redistribute it and/or
7
 
 * modify it under the terms of the GNU General Public License as
8
 
 * published by the Free Software Foundation; either version 2 of the
9
 
 * License, or (at your option) any later version.
10
 
 *
11
 
 * This program is distributed in the hope that it will be useful, but
12
 
 * WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 
 * General Public License for more details.
15
 
 *
16
 
 * You should have received a copy of the GNU General Public License
17
 
 * along with this program; if not, write to the Free Software
18
 
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19
 
 * 02111-1307, USA.
20
 
 *
21
 
 * Authors:
22
 
 *      Mark McLoughlin <mark@skynet.ie>
23
 
 */
24
 
 
25
 
#include <config.h>
26
 
 
27
 
#include "panel-profile.h"
28
 
 
29
 
#include <string.h>
30
 
#include <glib/gi18n.h>
31
 
 
32
 
#include <libpanel-util/panel-list.h>
33
 
 
34
 
#include "applet.h"
35
 
#include "panel-compatibility.h"
36
 
#include "panel-gconf.h"
37
 
#include "panel.h"
38
 
#include "panel-widget.h"
39
 
#include "panel-util.h"
40
 
#include "panel-multiscreen.h"
41
 
#include "panel-toplevel.h"
42
 
#include "panel-lockdown.h"
43
 
 
44
 
typedef struct {
45
 
        GdkScreen       *screen;
46
 
        int              monitor;
47
 
        int              size;
48
 
        int              x;
49
 
        int              x_right;
50
 
        gboolean         x_centered;
51
 
        int              y;
52
 
        int              y_bottom;
53
 
        gboolean         y_centered;
54
 
        PanelOrientation orientation;
55
 
 
56
 
        guint screen_changed : 1;
57
 
        guint monitor_changed : 1;
58
 
        guint size_changed : 1;
59
 
        guint x_changed : 1;
60
 
        guint x_right_changed : 1;
61
 
        guint x_centered_changed : 1;
62
 
        guint y_changed : 1;
63
 
        guint y_bottom_changed : 1;
64
 
        guint y_centered_changed : 1;
65
 
        guint orientation_changed : 1;
66
 
} ToplevelLocationChange;
67
 
 
68
 
typedef const char *(*PanelProfileGetIdFunc)   (gpointer           object);
69
 
typedef gboolean    (*PanelProfileOnLoadQueue) (const char        *id);
70
 
typedef void        (*PanelProfileLoadFunc)    (GConfClient       *client,
71
 
                                                const char        *profile_dir, 
72
 
                                                PanelGConfKeyType  type,
73
 
                                                const char        *id);
74
 
typedef void        (*PanelProfileDestroyFunc) (const char        *id);
75
 
 
76
 
static GConfEnumStringPair panel_orientation_map [] = {
77
 
        { PANEL_ORIENTATION_TOP,    "top"    },
78
 
        { PANEL_ORIENTATION_BOTTOM, "bottom" },
79
 
        { PANEL_ORIENTATION_LEFT,   "left"   },
80
 
        { PANEL_ORIENTATION_RIGHT,  "right"  },
81
 
        { 0,                        NULL     }
82
 
};
83
 
 
84
 
static GConfEnumStringPair panel_animation_speed_map [] = {
85
 
        { PANEL_ANIMATION_SLOW,   "slow"   },
86
 
        { PANEL_ANIMATION_MEDIUM, "medium" },
87
 
        { PANEL_ANIMATION_FAST,   "fast"   },
88
 
        { 0,                      NULL     }
89
 
};
90
 
 
91
 
static GConfEnumStringPair panel_background_type_map [] = {
92
 
        { PANEL_BACK_NONE,  "gtk"   },
93
 
        { PANEL_BACK_COLOR, "color" },
94
 
        { PANEL_BACK_IMAGE, "image" },
95
 
        { 0,                NULL    }
96
 
};
97
 
 
98
 
static GConfEnumStringPair panel_object_type_map [] = {
99
 
        { PANEL_OBJECT_DRAWER,    "drawer-object" },
100
 
        { PANEL_OBJECT_MENU,      "menu-object" },
101
 
        { PANEL_OBJECT_LAUNCHER,  "launcher-object" },
102
 
        { PANEL_OBJECT_APPLET,    "bonobo-applet" },
103
 
        { PANEL_OBJECT_ACTION,    "action-applet" },
104
 
        { PANEL_OBJECT_MENU_BAR,  "menu-bar" },
105
 
        { PANEL_OBJECT_SEPARATOR, "separator" },
106
 
        /* The following two are for backwards compatibility with 2.0.x */
107
 
        { PANEL_OBJECT_LOCK,      "lock-object" },
108
 
        { PANEL_OBJECT_LOGOUT,    "logout-object" },
109
 
        { 0,                      NULL }
110
 
};
111
 
 
112
 
static GQuark toplevel_id_quark = 0;
113
 
static GQuark queued_changes_quark = 0;
114
 
static GQuark commit_timeout_quark = 0;
115
 
 
116
 
static void panel_profile_object_id_list_update (GConfClient       *client,
117
 
                                                 GConfValue        *value,
118
 
                                                 PanelGConfKeyType  type);
119
 
 
120
 
gboolean
121
 
panel_profile_map_orientation_string (const char       *str,
122
 
                                      PanelOrientation *orientation)
123
 
{
124
 
        int mapped;
125
 
 
126
 
        g_return_val_if_fail (orientation != NULL, FALSE);
127
 
 
128
 
        if (!str)
129
 
                return FALSE;
130
 
 
131
 
        if (!gconf_string_to_enum (panel_orientation_map, str, &mapped))
132
 
                return FALSE;
133
 
 
134
 
        *orientation = mapped;
135
 
 
136
 
        return TRUE;
137
 
}
138
 
 
139
 
const char *
140
 
panel_profile_map_orientation (PanelOrientation orientation)
141
 
{
142
 
        return gconf_enum_to_string (panel_orientation_map, orientation);
143
 
}
144
 
 
145
 
gboolean
146
 
panel_profile_map_speed_string (const char          *str,
147
 
                                PanelAnimationSpeed *speed)
148
 
{
149
 
        int mapped;
150
 
 
151
 
        g_return_val_if_fail (speed != NULL, FALSE);
152
 
 
153
 
        if (!str)
154
 
                return FALSE;
155
 
 
156
 
        if (!gconf_string_to_enum (panel_animation_speed_map, str, &mapped))
157
 
                return FALSE;
158
 
 
159
 
        *speed = mapped;
160
 
 
161
 
        return TRUE;
162
 
}
163
 
 
164
 
gboolean
165
 
panel_profile_map_background_type_string (const char          *str,
166
 
                                          PanelBackgroundType *background_type)
167
 
{
168
 
        int mapped;
169
 
 
170
 
        g_return_val_if_fail (background_type != NULL, FALSE);
171
 
 
172
 
        if (!str)
173
 
                return FALSE;
174
 
 
175
 
        if (!gconf_string_to_enum (panel_background_type_map, str, &mapped))
176
 
                return FALSE;
177
 
 
178
 
        *background_type = mapped;
179
 
 
180
 
        return TRUE;
181
 
}
182
 
 
183
 
const char *
184
 
panel_profile_map_background_type (PanelBackgroundType  background_type)
185
 
{
186
 
        return gconf_enum_to_string (panel_background_type_map, background_type);
187
 
}
188
 
 
189
 
gboolean
190
 
panel_profile_map_object_type_string (const char       *str,
191
 
                                      PanelObjectType  *object_type)
192
 
{
193
 
        int mapped;
194
 
 
195
 
        g_return_val_if_fail (object_type != NULL, FALSE);
196
 
 
197
 
        if (!str)
198
 
                return FALSE;
199
 
 
200
 
        if (!gconf_string_to_enum (panel_object_type_map, str, &mapped))
201
 
                return FALSE;
202
 
 
203
 
        *object_type = mapped;
204
 
 
205
 
        return TRUE;
206
 
}
207
 
 
208
 
static void
209
 
panel_profile_set_toplevel_id (PanelToplevel *toplevel,
210
 
                               const char    *id)
211
 
{
212
 
        if (!toplevel_id_quark)
213
 
                toplevel_id_quark = g_quark_from_static_string ("panel-toplevel-id");
214
 
 
215
 
        g_object_set_qdata_full (G_OBJECT (toplevel),
216
 
                                 toplevel_id_quark,
217
 
                                 g_strdup (id),
218
 
                                 g_free);
219
 
}
220
 
 
221
 
const char *
222
 
panel_profile_get_toplevel_id (PanelToplevel *toplevel)
223
 
{
224
 
        if (!toplevel_id_quark)
225
 
                return NULL;
226
 
 
227
 
        return g_object_get_qdata (G_OBJECT (toplevel), toplevel_id_quark);
228
 
}
229
 
 
230
 
PanelToplevel *
231
 
panel_profile_get_toplevel_by_id (const char *toplevel_id)
232
 
{
233
 
        GSList *toplevels, *l;
234
 
 
235
 
        if (!toplevel_id || !toplevel_id [0])
236
 
                return NULL;
237
 
 
238
 
        toplevels = panel_toplevel_list_toplevels ();
239
 
        for (l = toplevels; l; l = l->next)
240
 
                if (!strcmp (panel_profile_get_toplevel_id (l->data), toplevel_id))
241
 
                        return l->data;
242
 
 
243
 
        return NULL;
244
 
}
245
 
 
246
 
char *
247
 
panel_profile_find_new_id (PanelGConfKeyType type)
248
 
{
249
 
        GConfClient *client;
250
 
        GSList      *l, *existing_ids;
251
 
        const char  *key;
252
 
        char        *retval = NULL;
253
 
        char        *prefix;
254
 
        char        *dir;
255
 
        int          i;
256
 
 
257
 
        client  = panel_gconf_get_client ();
258
 
 
259
 
        switch (type) {
260
 
        case PANEL_GCONF_TOPLEVELS:
261
 
                prefix = "panel";
262
 
                dir = "toplevels";
263
 
                break;
264
 
        case PANEL_GCONF_OBJECTS:
265
 
                prefix = "object";
266
 
                dir = "objects";
267
 
                break;
268
 
        case PANEL_GCONF_APPLETS:
269
 
                prefix = "applet";
270
 
                dir = "applets";
271
 
                break;
272
 
        default:
273
 
                prefix = dir = NULL;
274
 
                g_assert_not_reached ();
275
 
                break;
276
 
        }
277
 
 
278
 
        key = panel_gconf_sprintf (PANEL_CONFIG_DIR "/%s", dir);
279
 
        existing_ids = gconf_client_all_dirs (client, key, NULL);
280
 
 
281
 
        for (i = 0; !retval; i++) {
282
 
                retval = g_strdup_printf ("%s_%d", prefix, i);
283
 
 
284
 
                for (l = existing_ids; l; l = l->next)
285
 
                        if (!strcmp (panel_gconf_basename (l->data), retval)) {
286
 
                                g_free (retval);
287
 
                                retval = NULL;
288
 
                                break;
289
 
                        }
290
 
        }
291
 
 
292
 
        g_assert (retval != NULL);
293
 
 
294
 
        for (l = existing_ids; l; l = l->next)
295
 
                g_free (l->data);
296
 
        g_slist_free (existing_ids);
297
 
 
298
 
        return retval;
299
 
}
300
 
 
301
 
static void
302
 
panel_profile_set_queued_changes (PanelToplevel  *toplevel,
303
 
                                  GConfChangeSet *changes)
304
 
{
305
 
        if (!queued_changes_quark)
306
 
                queued_changes_quark = g_quark_from_static_string ("panel-queued-changes");
307
 
 
308
 
        g_object_set_qdata_full (G_OBJECT (toplevel),
309
 
                                 queued_changes_quark,
310
 
                                 changes,
311
 
                                 (GDestroyNotify) gconf_change_set_unref);
312
 
}
313
 
 
314
 
static GConfChangeSet *
315
 
panel_profile_get_queued_changes (GObject *object)
316
 
{
317
 
        if (!queued_changes_quark)
318
 
                return NULL;
319
 
 
320
 
        return g_object_get_qdata (object, queued_changes_quark);
321
 
}
322
 
 
323
 
static void
324
 
panel_profile_remove_commit_timeout (guint timeout)
325
 
{
326
 
        g_source_remove (timeout);
327
 
}
328
 
 
329
 
static void
330
 
panel_profile_set_commit_timeout (PanelToplevel *toplevel,
331
 
                                  guint          timeout)
332
 
{
333
 
        GDestroyNotify destroy_notify;
334
 
 
335
 
        if (!commit_timeout_quark)
336
 
                commit_timeout_quark = g_quark_from_static_string ("panel-queued-timeout");
337
 
 
338
 
        if (timeout)
339
 
                destroy_notify = (GDestroyNotify) panel_profile_remove_commit_timeout;
340
 
        else
341
 
                destroy_notify = NULL;
342
 
 
343
 
        g_object_set_qdata_full (G_OBJECT (toplevel),
344
 
                                 commit_timeout_quark,
345
 
                                 GUINT_TO_POINTER (timeout),
346
 
                                 destroy_notify);
347
 
}
348
 
 
349
 
static guint
350
 
panel_profile_get_commit_timeout (GObject *object)
351
 
{
352
 
        if (!commit_timeout_quark)
353
 
                return 0;
354
 
 
355
 
        return GPOINTER_TO_UINT (g_object_get_qdata (object, commit_timeout_quark));
356
 
}
357
 
 
358
 
static const char *
359
 
panel_profile_get_toplevel_key (PanelToplevel *toplevel,
360
 
                                const char    *key)
361
 
{
362
 
        const char *id;
363
 
 
364
 
        id = panel_profile_get_toplevel_id (toplevel);
365
 
 
366
 
        return panel_gconf_full_key (PANEL_GCONF_TOPLEVELS, id, key);
367
 
}
368
 
 
369
 
#define TOPLEVEL_IS_WRITABLE_FUNC(k, p, s)                            \
370
 
        gboolean                                                      \
371
 
        panel_profile_is_writable_##p##_##s (PanelToplevel *toplevel) \
372
 
        {                                                             \
373
 
                GConfClient *client;                                  \
374
 
                const char  *key;                                     \
375
 
                client = panel_gconf_get_client ();                   \
376
 
                key = panel_profile_get_toplevel_key (toplevel, k);   \
377
 
                return gconf_client_key_is_writable (client, key, NULL); \
378
 
        }
379
 
 
380
 
void
381
 
panel_profile_set_background_type (PanelToplevel       *toplevel,
382
 
                                   PanelBackgroundType  background_type)
383
 
{
384
 
        GConfClient *client;
385
 
        const char  *key;
386
 
 
387
 
        client = panel_gconf_get_client ();
388
 
 
389
 
        key = panel_profile_get_toplevel_key (toplevel, "background/type");
390
 
        gconf_client_set_string (client,
391
 
                                 key,
392
 
                                 panel_profile_map_background_type (background_type),
393
 
                                 NULL);
394
 
}
395
 
 
396
 
PanelBackgroundType
397
 
panel_profile_get_background_type (PanelToplevel *toplevel)
398
 
{
399
 
        PanelBackgroundType  background_type;
400
 
        GConfClient         *client;
401
 
        const char          *key;
402
 
        char                *str;
403
 
 
404
 
        client = panel_gconf_get_client ();
405
 
 
406
 
        key = panel_profile_get_toplevel_key (toplevel, "background/type");
407
 
        str = gconf_client_get_string (client, key, NULL);
408
 
 
409
 
        if (!str || !panel_profile_map_background_type_string (str, &background_type))
410
 
                background_type = PANEL_BACK_NONE;
411
 
 
412
 
        g_free (str);
413
 
 
414
 
        return background_type;
415
 
}
416
 
 
417
 
TOPLEVEL_IS_WRITABLE_FUNC ("background/type", background, type)
418
 
 
419
 
void
420
 
panel_profile_set_background_color (PanelToplevel *toplevel,
421
 
                                    PanelColor    *color)
422
 
{
423
 
        panel_profile_set_background_gdk_color (toplevel, &color->gdk);
424
 
        panel_profile_set_background_opacity (toplevel, color->alpha);
425
 
}
426
 
 
427
 
void
428
 
panel_profile_get_background_color (PanelToplevel *toplevel,
429
 
                                    PanelColor    *color)
430
 
{
431
 
        panel_profile_get_background_gdk_color (toplevel, &(color->gdk));
432
 
        color->alpha = panel_profile_get_background_opacity (toplevel);
433
 
}
434
 
 
435
 
TOPLEVEL_IS_WRITABLE_FUNC ("background/color", background, color)
436
 
 
437
 
void
438
 
panel_profile_set_background_gdk_color (PanelToplevel *toplevel,
439
 
                                        GdkColor      *gdk_color)
440
 
{
441
 
        GConfClient *client;
442
 
        const char  *key;
443
 
        char        *color_str;
444
 
 
445
 
        client = panel_gconf_get_client ();
446
 
 
447
 
        color_str = g_strdup_printf ("#%02x%02x%02x",
448
 
                                     gdk_color->red   / 256,
449
 
                                     gdk_color->green / 256,
450
 
                                     gdk_color->blue  / 256);
451
 
 
452
 
        key = panel_profile_get_toplevel_key (toplevel, "background/color");
453
 
        gconf_client_set_string (client, key, color_str, NULL);
454
 
 
455
 
        g_free (color_str);
456
 
}
457
 
 
458
 
void
459
 
panel_profile_get_background_gdk_color (PanelToplevel *toplevel,
460
 
                                        GdkColor      *gdk_color)
461
 
{
462
 
        GConfClient *client;
463
 
        const char  *key;
464
 
        char        *color_str;
465
 
 
466
 
        client = panel_gconf_get_client ();
467
 
 
468
 
        key = panel_profile_get_toplevel_key (toplevel, "background/color");
469
 
        color_str = gconf_client_get_string (client, key, NULL);
470
 
        if (!color_str || !gdk_color_parse (color_str, gdk_color)) {
471
 
                gdk_color->red   = 0;
472
 
                gdk_color->green = 0;
473
 
                gdk_color->blue  = 0;
474
 
        }
475
 
 
476
 
        g_free (color_str);
477
 
}
478
 
 
479
 
void
480
 
panel_profile_set_background_opacity (PanelToplevel *toplevel,
481
 
                                      guint16        opacity)
482
 
{
483
 
        GConfClient *client;
484
 
        const char  *key;
485
 
 
486
 
        client = panel_gconf_get_client ();
487
 
 
488
 
        key = panel_profile_get_toplevel_key (toplevel, "background/opacity");
489
 
        gconf_client_set_int (client, key, opacity, NULL);
490
 
}
491
 
 
492
 
guint16
493
 
panel_profile_get_background_opacity (PanelToplevel *toplevel)
494
 
{
495
 
        GConfClient *client;
496
 
        const char  *key;
497
 
        guint16      opacity;
498
 
 
499
 
        client = panel_gconf_get_client ();
500
 
 
501
 
        key = panel_profile_get_toplevel_key (toplevel, "background/opacity");
502
 
        opacity = gconf_client_get_int (client, key, NULL);
503
 
 
504
 
        return opacity;
505
 
}
506
 
 
507
 
TOPLEVEL_IS_WRITABLE_FUNC ("background/opacity", background, opacity)
508
 
 
509
 
void
510
 
panel_profile_set_background_image (PanelToplevel *toplevel,
511
 
                                    const char    *image)
512
 
{
513
 
        GConfClient *client;
514
 
        const char  *key;
515
 
 
516
 
        client = panel_gconf_get_client ();
517
 
 
518
 
        key = panel_profile_get_toplevel_key (toplevel, "background/image");
519
 
 
520
 
        if (image && image [0])
521
 
                gconf_client_set_string (client, key, image, NULL);
522
 
        else
523
 
                gconf_client_unset (client, key, NULL);
524
 
}
525
 
 
526
 
char *
527
 
panel_profile_get_background_image (PanelToplevel *toplevel)
528
 
{
529
 
        GConfClient *client;
530
 
        const char  *key;
531
 
        char        *retval;
532
 
 
533
 
        client = panel_gconf_get_client ();
534
 
 
535
 
        key = panel_profile_get_toplevel_key (toplevel, "background/image");
536
 
        retval = gconf_client_get_string (client, key, NULL);
537
 
 
538
 
        return retval;
539
 
}
540
 
 
541
 
TOPLEVEL_IS_WRITABLE_FUNC ("background/image", background, image)
542
 
 
543
 
void
544
 
panel_profile_set_toplevel_name (PanelToplevel *toplevel,
545
 
                                 const char    *name)
546
 
{
547
 
        GConfClient *client;
548
 
        const char  *key;
549
 
 
550
 
        client = panel_gconf_get_client ();
551
 
 
552
 
        key = panel_profile_get_toplevel_key (toplevel, "name");
553
 
 
554
 
        if (name && name [0])
555
 
                gconf_client_set_string (client, key, name, NULL);
556
 
        else
557
 
                gconf_client_unset (client, key, NULL);
558
 
}
559
 
 
560
 
char *
561
 
panel_profile_get_toplevel_name (PanelToplevel *toplevel)
562
 
{
563
 
        GConfClient *client;
564
 
        const char  *key;
565
 
        char        *retval;
566
 
 
567
 
        client = panel_gconf_get_client ();
568
 
 
569
 
        key = panel_profile_get_toplevel_key (toplevel, "name");
570
 
        retval = gconf_client_get_string (client, key, NULL);
571
 
 
572
 
        return retval;
573
 
}
574
 
 
575
 
TOPLEVEL_IS_WRITABLE_FUNC ("name", toplevel, name)
576
 
 
577
 
void
578
 
panel_profile_set_toplevel_orientation (PanelToplevel    *toplevel,
579
 
                                        PanelOrientation  orientation)
580
 
{
581
 
        GConfClient *client;
582
 
        const char  *key;
583
 
 
584
 
        client = panel_gconf_get_client ();
585
 
 
586
 
        key = panel_profile_get_toplevel_key (toplevel, "orientation");
587
 
        gconf_client_set_string (client,
588
 
                                 key,
589
 
                                 panel_profile_map_orientation (orientation),
590
 
                                 NULL);
591
 
}
592
 
 
593
 
PanelOrientation
594
 
panel_profile_get_toplevel_orientation (PanelToplevel *toplevel)
595
 
{
596
 
        PanelOrientation  orientation;
597
 
        GConfClient      *client;
598
 
        const char       *key;
599
 
        char             *str;
600
 
 
601
 
        client = panel_gconf_get_client ();
602
 
 
603
 
        key = panel_profile_get_toplevel_key (toplevel, "orientation");
604
 
        str = gconf_client_get_string (client, key, NULL);
605
 
 
606
 
        if (!panel_profile_map_orientation_string (str, &orientation))
607
 
            orientation = panel_toplevel_get_orientation (toplevel);
608
 
 
609
 
        g_free (str);
610
 
 
611
 
        return orientation;
612
 
}
613
 
 
614
 
TOPLEVEL_IS_WRITABLE_FUNC ("orientation", toplevel, orientation)
615
 
 
616
 
#define TOPLEVEL_GET_SET_FUNCS(k, p, t, s, a)                         \
617
 
        void                                                          \
618
 
        panel_profile_set_##p##_##s (PanelToplevel *toplevel, a s)    \
619
 
        {                                                             \
620
 
                GConfClient *client;                                  \
621
 
                const char  *key;                                     \
622
 
                client = panel_gconf_get_client ();                   \
623
 
                key = panel_profile_get_toplevel_key (toplevel, k);   \
624
 
                gconf_client_set_##t (client, key, s, NULL);          \
625
 
        }                                                             \
626
 
        a                                                             \
627
 
        panel_profile_get_##p##_##s (PanelToplevel *toplevel)         \
628
 
        {                                                             \
629
 
                GConfClient *client;                                  \
630
 
                const char  *key;                                     \
631
 
                a retval;                                             \
632
 
                client = panel_gconf_get_client ();                   \
633
 
                key = panel_profile_get_toplevel_key (toplevel, k);   \
634
 
                retval = gconf_client_get_##t (client, key, NULL);    \
635
 
                return retval;                                        \
636
 
        }                                                             \
637
 
        TOPLEVEL_IS_WRITABLE_FUNC(k, p, s)
638
 
 
639
 
TOPLEVEL_GET_SET_FUNCS ("size",               toplevel,   int,  size,           int)
640
 
TOPLEVEL_GET_SET_FUNCS ("expand",             toplevel,   bool, expand,         gboolean)
641
 
TOPLEVEL_GET_SET_FUNCS ("auto_hide",          toplevel,   bool, auto_hide,      gboolean)
642
 
TOPLEVEL_GET_SET_FUNCS ("enable_buttons",     toplevel,   bool, enable_buttons, gboolean)
643
 
TOPLEVEL_GET_SET_FUNCS ("enable_arrows",      toplevel,   bool, enable_arrows,  gboolean)
644
 
TOPLEVEL_GET_SET_FUNCS ("background/fit",     background, bool, fit,            gboolean)
645
 
TOPLEVEL_GET_SET_FUNCS ("background/stretch", background, bool, stretch,        gboolean)
646
 
TOPLEVEL_GET_SET_FUNCS ("background/rotate",  background, bool, rotate,         gboolean)
647
 
 
648
 
static const char *
649
 
panel_profile_get_attached_object_key (PanelToplevel *toplevel,
650
 
                                       const char    *key)
651
 
{
652
 
        GtkWidget  *attach_widget;
653
 
        const char *id;
654
 
 
655
 
        attach_widget = panel_toplevel_get_attach_widget (toplevel);
656
 
 
657
 
        id = panel_applet_get_id_by_widget (attach_widget);
658
 
 
659
 
        if (!id)
660
 
                return NULL;
661
 
 
662
 
        return panel_gconf_full_key (PANEL_GCONF_OBJECTS, id, key);
663
 
}
664
 
 
665
 
void
666
 
panel_profile_set_attached_custom_icon (PanelToplevel *toplevel,
667
 
                                        const char    *custom_icon)
668
 
{
669
 
        GConfClient *client;
670
 
        const char  *key;
671
 
 
672
 
        client = panel_gconf_get_client ();
673
 
 
674
 
        key = panel_profile_get_attached_object_key (toplevel, "use_custom_icon");
675
 
        if (key)
676
 
                gconf_client_set_bool (client, key, custom_icon != NULL, NULL);
677
 
 
678
 
        key = panel_profile_get_attached_object_key (toplevel, "custom_icon");
679
 
        if (key)
680
 
                gconf_client_set_string (client, key, sure_string (custom_icon), NULL);
681
 
}
682
 
 
683
 
char *
684
 
panel_profile_get_attached_custom_icon (PanelToplevel *toplevel)
685
 
{
686
 
        GConfClient *client;
687
 
        const char  *key;
688
 
 
689
 
        client = panel_gconf_get_client ();
690
 
 
691
 
        key = panel_profile_get_attached_object_key (toplevel, "use_custom_icon");
692
 
        if (!key || !gconf_client_get_bool (client, key, NULL))
693
 
                return NULL;
694
 
 
695
 
        key = panel_profile_get_attached_object_key (toplevel, "custom_icon");
696
 
 
697
 
        return key ? gconf_client_get_string (client, key, NULL) : NULL;
698
 
}
699
 
 
700
 
gboolean
701
 
panel_profile_is_writable_attached_custom_icon (PanelToplevel *toplevel)
702
 
{
703
 
        GConfClient *client;
704
 
        const char  *key;
705
 
 
706
 
        client = panel_gconf_get_client ();
707
 
 
708
 
        key = panel_profile_get_attached_object_key (toplevel, "use_custom_icon");
709
 
        if (!key)
710
 
                return TRUE;
711
 
 
712
 
        if (!gconf_client_key_is_writable (client, key, NULL))
713
 
                return FALSE;
714
 
 
715
 
        key = panel_profile_get_attached_object_key (toplevel, "custom_icon");
716
 
 
717
 
        return key ? gconf_client_key_is_writable (client, key, NULL) : TRUE;
718
 
}
719
 
 
720
 
void
721
 
panel_profile_set_attached_tooltip (PanelToplevel *toplevel,
722
 
                                    const char    *tooltip)
723
 
{
724
 
        GConfClient *client;
725
 
        const char  *key;
726
 
 
727
 
        client = panel_gconf_get_client ();
728
 
 
729
 
        key = panel_profile_get_attached_object_key (toplevel, "tooltip");
730
 
        if (key)
731
 
                gconf_client_set_string (client, key, tooltip, NULL);
732
 
}
733
 
 
734
 
char *
735
 
panel_profile_get_attached_tooltip (PanelToplevel *toplevel)
736
 
{
737
 
        GConfClient *client;
738
 
        const char  *key;
739
 
 
740
 
        client = panel_gconf_get_client ();
741
 
 
742
 
        key = panel_profile_get_attached_object_key (toplevel, "tooltip");
743
 
 
744
 
        return key ? gconf_client_get_string (client, key, NULL) : NULL;
745
 
}
746
 
 
747
 
gboolean
748
 
panel_profile_is_writable_attached_tooltip (PanelToplevel *toplevel)
749
 
{
750
 
        GConfClient *client;
751
 
        const char  *key;
752
 
 
753
 
        client = panel_gconf_get_client ();
754
 
 
755
 
        key = panel_profile_get_attached_object_key (toplevel, "tooltip");
756
 
 
757
 
        return key ? gconf_client_key_is_writable (client, key, NULL) : TRUE;
758
 
}
759
 
 
760
 
static PanelBackgroundType
761
 
get_background_type (GConfClient *client,
762
 
                     const char  *toplevel_dir)
763
 
{
764
 
        PanelBackgroundType  background_type;
765
 
        GError              *error = NULL;
766
 
        const char          *key;
767
 
        char                *type_str;
768
 
 
769
 
        key = panel_gconf_sprintf ("%s/background/type", toplevel_dir);
770
 
        type_str = gconf_client_get_string (client, key, &error);
771
 
        if (error) {
772
 
                g_warning (_("Error reading GConf string value '%s': %s"),
773
 
                           key, error->message);
774
 
                g_error_free (error);
775
 
                return PANEL_BACK_NONE;
776
 
        }
777
 
 
778
 
        if (!type_str || !panel_profile_map_background_type_string (type_str, &background_type))
779
 
                background_type = PANEL_BACK_NONE;
780
 
 
781
 
        g_free (type_str);
782
 
        
783
 
        return background_type;
784
 
}
785
 
 
786
 
static void
787
 
get_background_color (GConfClient *client,
788
 
                      const char  *toplevel_dir,
789
 
                      PanelColor  *color)
790
 
{
791
 
        GError     *error;
792
 
        const char *key;
793
 
        char       *color_str;
794
 
 
795
 
        error = NULL;
796
 
        key = panel_gconf_sprintf ("%s/background/color", toplevel_dir);
797
 
        color_str = gconf_client_get_string (client, key, &error);
798
 
        if (error) {
799
 
                g_warning (_("Error reading GConf string value '%s': %s"),
800
 
                           key, error->message);
801
 
                g_error_free (error);
802
 
        } else if (!color_str || !gdk_color_parse (color_str, &(color->gdk))) {
803
 
                color->gdk.red   = 0;
804
 
                color->gdk.green = 0;
805
 
                color->gdk.blue  = 0;
806
 
        }
807
 
 
808
 
        g_free (color_str);
809
 
 
810
 
        error = NULL;
811
 
        key = panel_gconf_sprintf ("%s/background/opacity", toplevel_dir);
812
 
        color->alpha = gconf_client_get_int (client, key, &error);
813
 
        if (error) {
814
 
                g_warning (_("Error reading GConf integer value '%s': %s"),
815
 
                           key, error->message);
816
 
                g_error_free (error);
817
 
                color->alpha = 65535; /* fallback to fully opaque */
818
 
        }
819
 
}
820
 
 
821
 
static char *
822
 
get_background_image (GConfClient  *client,
823
 
                      const char   *toplevel_dir,
824
 
                      gboolean     *fit,
825
 
                      gboolean     *stretch,
826
 
                      gboolean     *rotate)
827
 
{
828
 
        const char *key;
829
 
        GError     *error = NULL;
830
 
        char       *image;
831
 
 
832
 
        key = panel_gconf_sprintf ("%s/background/image", toplevel_dir);
833
 
        image = gconf_client_get_string (client, key, &error);
834
 
        if (error) {
835
 
                g_warning (_("Error reading GConf string value '%s': %s"),
836
 
                           key, error->message);
837
 
                g_error_free (error);
838
 
        }
839
 
 
840
 
        key = panel_gconf_sprintf ("%s/background/fit", toplevel_dir);
841
 
        *fit = gconf_client_get_bool (client, key, NULL);
842
 
 
843
 
        key = panel_gconf_sprintf ("%s/background/stretch", toplevel_dir);
844
 
        *stretch = gconf_client_get_bool (client, key, NULL);
845
 
 
846
 
        key = panel_gconf_sprintf ("%s/background/rotate", toplevel_dir);
847
 
        *rotate = gconf_client_get_bool (client, key, NULL);
848
 
 
849
 
        return image;
850
 
}
851
 
 
852
 
static void
853
 
panel_profile_load_background (PanelToplevel *toplevel,
854
 
                               GConfClient   *client,
855
 
                               const char    *toplevel_dir)
856
 
{
857
 
        PanelWidget         *panel_widget;
858
 
        PanelBackground     *background;
859
 
        PanelBackgroundType  background_type;
860
 
        PanelColor           color;
861
 
        char                *image;
862
 
        gboolean             fit;
863
 
        gboolean             stretch;
864
 
        gboolean             rotate;
865
 
 
866
 
        panel_widget = panel_toplevel_get_panel_widget (toplevel);
867
 
        background = &panel_widget->background;
868
 
 
869
 
        background_type = get_background_type (client, toplevel_dir);
870
 
 
871
 
        get_background_color (client, toplevel_dir, &color);
872
 
 
873
 
        image = get_background_image (client, toplevel_dir, &fit, &stretch, &rotate);
874
 
 
875
 
        panel_background_set (background,
876
 
                              background_type,
877
 
                              &color,
878
 
                              image,
879
 
                              fit,
880
 
                              stretch,
881
 
                              rotate);
882
 
 
883
 
        g_free (image);
884
 
}
885
 
 
886
 
static gboolean
887
 
panel_profile_commit_toplevel_changes (PanelToplevel *toplevel)
888
 
{
889
 
        GConfChangeSet *queued_changes;
890
 
 
891
 
        queued_changes = panel_profile_get_queued_changes (G_OBJECT (toplevel));
892
 
        if (queued_changes)
893
 
                gconf_client_commit_change_set (
894
 
                                panel_gconf_get_client (),
895
 
                                queued_changes, FALSE, NULL);
896
 
 
897
 
        panel_profile_set_queued_changes (toplevel, NULL);
898
 
        panel_profile_set_commit_timeout (toplevel, 0);
899
 
 
900
 
        return FALSE;
901
 
}
902
 
 
903
 
static void
904
 
panel_profile_queue_toplevel_location_change (PanelToplevel          *toplevel,
905
 
                                              ToplevelLocationChange *change)
906
 
{
907
 
        GConfChangeSet *queued_changes;
908
 
        guint           commit_timeout;
909
 
 
910
 
        queued_changes = panel_profile_get_queued_changes (G_OBJECT (toplevel));
911
 
        if (!queued_changes) {
912
 
                queued_changes = gconf_change_set_new ();
913
 
                panel_profile_set_queued_changes (toplevel, queued_changes);
914
 
        }
915
 
 
916
 
        if (change->screen_changed)
917
 
                gconf_change_set_set_int (
918
 
                        queued_changes,
919
 
                        panel_profile_get_toplevel_key (toplevel, "screen"),
920
 
                        gdk_screen_get_number (change->screen));
921
 
 
922
 
        if (change->monitor_changed)
923
 
                gconf_change_set_set_int (
924
 
                        queued_changes,
925
 
                        panel_profile_get_toplevel_key (toplevel, "monitor"),
926
 
                        change->monitor);
927
 
 
928
 
        if (change->size_changed)
929
 
                gconf_change_set_set_int (
930
 
                        queued_changes,
931
 
                        panel_profile_get_toplevel_key (toplevel, "size"),
932
 
                        change->size);
933
 
 
934
 
        if (change->orientation_changed)
935
 
                gconf_change_set_set_string (
936
 
                        queued_changes,
937
 
                        panel_profile_get_toplevel_key (toplevel, "orientation"),
938
 
                        gconf_enum_to_string (panel_orientation_map, change->orientation));
939
 
 
940
 
        if (!panel_toplevel_get_expand (toplevel)) {
941
 
                if (change->x_changed)
942
 
                        gconf_change_set_set_int (
943
 
                                queued_changes,
944
 
                                panel_profile_get_toplevel_key (toplevel, "x"),
945
 
                                change->x);
946
 
 
947
 
                if (change->x_right_changed)
948
 
                        gconf_change_set_set_int (
949
 
                                queued_changes,
950
 
                                panel_profile_get_toplevel_key (toplevel, "x_right"),
951
 
                                change->x_right);
952
 
 
953
 
                if (change->x_centered_changed)
954
 
                        gconf_change_set_set_bool (
955
 
                                queued_changes,
956
 
                                panel_profile_get_toplevel_key (toplevel, "x_centered"),
957
 
                                change->x_centered);
958
 
 
959
 
                if (change->y_changed)
960
 
                        gconf_change_set_set_int (
961
 
                                queued_changes,
962
 
                                panel_profile_get_toplevel_key (toplevel, "y"),
963
 
                                change->y);
964
 
 
965
 
                if (change->y_bottom_changed)
966
 
                        gconf_change_set_set_int (
967
 
                                queued_changes,
968
 
                                panel_profile_get_toplevel_key (toplevel, "y_bottom"),
969
 
                                change->y_bottom);
970
 
 
971
 
                if (change->y_centered_changed)
972
 
                        gconf_change_set_set_bool (
973
 
                                queued_changes,
974
 
                                panel_profile_get_toplevel_key (toplevel, "y_centered"),
975
 
                                change->y_centered);
976
 
        }
977
 
 
978
 
        commit_timeout = panel_profile_get_commit_timeout (G_OBJECT (toplevel));
979
 
        if (!commit_timeout) {
980
 
                commit_timeout =
981
 
                        g_timeout_add (500,
982
 
                                       (GSourceFunc) panel_profile_commit_toplevel_changes,
983
 
                                       toplevel);
984
 
                panel_profile_set_commit_timeout (toplevel, commit_timeout);
985
 
        }
986
 
}
987
 
 
988
 
#define TOPLEVEL_LOCATION_CHANGED_HANDLER(c)                                      \
989
 
        static void                                                               \
990
 
        panel_profile_toplevel_##c##_changed (PanelToplevel *toplevel)            \
991
 
        {                                                                         \
992
 
                ToplevelLocationChange change = { NULL };                           \
993
 
                change.c##_changed = TRUE;                                        \
994
 
                change.c = panel_toplevel_get_##c (toplevel);                     \
995
 
                panel_profile_queue_toplevel_location_change (toplevel, &change); \
996
 
        }
997
 
 
998
 
TOPLEVEL_LOCATION_CHANGED_HANDLER(monitor)
999
 
TOPLEVEL_LOCATION_CHANGED_HANDLER(size)
1000
 
TOPLEVEL_LOCATION_CHANGED_HANDLER(orientation)
1001
 
TOPLEVEL_LOCATION_CHANGED_HANDLER(x_centered)
1002
 
TOPLEVEL_LOCATION_CHANGED_HANDLER(y_centered)
1003
 
 
1004
 
#define TOPLEVEL_POSITION_CHANGED_HANDLER(c)                                      \
1005
 
        static void                                                               \
1006
 
        panel_profile_toplevel_##c##_changed (PanelToplevel *toplevel)            \
1007
 
        {                                                                         \
1008
 
                ToplevelLocationChange change = { NULL };                           \
1009
 
                int                    x, y, x_right, y_bottom;                   \
1010
 
                change.c##_changed = TRUE;                                        \
1011
 
                panel_toplevel_get_position (toplevel,                            \
1012
 
                                             &x, &x_right,                        \
1013
 
                                             &y, &y_bottom);                      \
1014
 
                change.c = c;                                                     \
1015
 
                panel_profile_queue_toplevel_location_change (toplevel, &change); \
1016
 
        }
1017
 
 
1018
 
TOPLEVEL_POSITION_CHANGED_HANDLER(x)
1019
 
TOPLEVEL_POSITION_CHANGED_HANDLER(x_right)
1020
 
TOPLEVEL_POSITION_CHANGED_HANDLER(y)
1021
 
TOPLEVEL_POSITION_CHANGED_HANDLER(y_bottom)
1022
 
 
1023
 
static void
1024
 
panel_profile_toplevel_screen_changed (PanelToplevel *toplevel)
1025
 
{
1026
 
        ToplevelLocationChange change = { NULL };
1027
 
 
1028
 
        change.screen_changed = TRUE;
1029
 
        change.screen = gtk_window_get_screen (GTK_WINDOW (toplevel));
1030
 
 
1031
 
        panel_profile_queue_toplevel_location_change (toplevel, &change);
1032
 
}
1033
 
 
1034
 
static void
1035
 
panel_profile_connect_to_toplevel (PanelToplevel *toplevel)
1036
 
{
1037
 
        g_signal_connect (toplevel, "notify::screen",
1038
 
                          G_CALLBACK (panel_profile_toplevel_screen_changed), NULL);
1039
 
        g_signal_connect (toplevel, "notify::monitor",
1040
 
                          G_CALLBACK (panel_profile_toplevel_monitor_changed), NULL);
1041
 
        g_signal_connect (toplevel, "notify::size",
1042
 
                          G_CALLBACK (panel_profile_toplevel_size_changed), NULL);
1043
 
        g_signal_connect (toplevel, "notify::x",
1044
 
                          G_CALLBACK (panel_profile_toplevel_x_changed), NULL);
1045
 
        g_signal_connect (toplevel, "notify::x-right",
1046
 
                          G_CALLBACK (panel_profile_toplevel_x_right_changed), NULL);
1047
 
        g_signal_connect (toplevel, "notify::x-centered",
1048
 
                          G_CALLBACK (panel_profile_toplevel_x_centered_changed), NULL);
1049
 
        g_signal_connect (toplevel, "notify::y",
1050
 
                          G_CALLBACK (panel_profile_toplevel_y_changed), NULL);
1051
 
        g_signal_connect (toplevel, "notify::y-bottom",
1052
 
                          G_CALLBACK (panel_profile_toplevel_y_bottom_changed), NULL);
1053
 
        g_signal_connect (toplevel, "notify::y-centered",
1054
 
                          G_CALLBACK (panel_profile_toplevel_y_centered_changed), NULL);
1055
 
        g_signal_connect (toplevel, "notify::orientation",
1056
 
                          G_CALLBACK (panel_profile_toplevel_orientation_changed), NULL);
1057
 
}
1058
 
 
1059
 
static void
1060
 
set_name_from_string (PanelToplevel *toplevel,
1061
 
                      const char    *str)
1062
 
{
1063
 
        if (!str)
1064
 
                return;
1065
 
 
1066
 
        panel_toplevel_set_name (toplevel, str);
1067
 
}
1068
 
 
1069
 
static void
1070
 
set_orientation_from_string (PanelToplevel *toplevel,
1071
 
                             const char    *str)
1072
 
{
1073
 
        PanelOrientation orientation;
1074
 
 
1075
 
        if (!str || !panel_profile_map_orientation_string (str, &orientation))
1076
 
                return;
1077
 
 
1078
 
        panel_toplevel_set_orientation (toplevel, orientation);
1079
 
}
1080
 
 
1081
 
static void
1082
 
set_animation_speed_from_string (PanelToplevel *toplevel,
1083
 
                                 const char    *str)
1084
 
{
1085
 
        PanelAnimationSpeed animation_speed;
1086
 
 
1087
 
        if (!str || !panel_profile_map_speed_string (str, &animation_speed))
1088
 
                return;
1089
 
 
1090
 
        panel_toplevel_set_animation_speed (toplevel, animation_speed);
1091
 
}
1092
 
 
1093
 
static void
1094
 
panel_profile_toplevel_change_notify (GConfClient   *client,
1095
 
                                      guint          cnxn_id,
1096
 
                                      GConfEntry    *entry,
1097
 
                                      PanelToplevel *toplevel)
1098
 
{
1099
 
        GConfValue *value;
1100
 
        const char *key;
1101
 
 
1102
 
        key = panel_gconf_basename (gconf_entry_get_key (entry));
1103
 
 
1104
 
        if (!(value = gconf_entry_get_value (entry)))
1105
 
                return;
1106
 
 
1107
 
#define UPDATE_STRING(k, n)                                                             \
1108
 
                if (!strcmp (key, k)) {                                                 \
1109
 
                        if (value->type == GCONF_VALUE_STRING)                          \
1110
 
                                set_##n##_from_string (toplevel,                        \
1111
 
                                                       gconf_value_get_string (value)); \
1112
 
                }
1113
 
 
1114
 
#define UPDATE_INT(k, n)                                                                \
1115
 
                if (!strcmp (key, k)) {                                                 \
1116
 
                        if (value->type == GCONF_VALUE_INT)                             \
1117
 
                                panel_toplevel_set_##n (toplevel,                       \
1118
 
                                                        gconf_value_get_int (value));   \
1119
 
                }
1120
 
 
1121
 
#define UPDATE_BOOL(k, n)                                                               \
1122
 
                if (!strcmp (key, k)) {                                                 \
1123
 
                        if (value->type == GCONF_VALUE_BOOL)                            \
1124
 
                                panel_toplevel_set_##n (toplevel,                       \
1125
 
                                                        gconf_value_get_bool (value));  \
1126
 
                }
1127
 
 
1128
 
#define UPDATE_POS(k, n, n2)                                                            \
1129
 
                if (!strcmp (key, k)) {                                                 \
1130
 
                        if (value->type == GCONF_VALUE_INT) {                           \
1131
 
                                int x, x_right, y, y_bottom;                            \
1132
 
                                panel_toplevel_get_position (toplevel, &x, &x_right,    \
1133
 
                                                             &y, &y_bottom);            \
1134
 
                                panel_toplevel_set_##n (                                \
1135
 
                                        toplevel,                                       \
1136
 
                                        gconf_value_get_int (value),                    \
1137
 
                                        n2,                                             \
1138
 
                                        panel_toplevel_get_##n##_centered (toplevel));  \
1139
 
                        }                                                               \
1140
 
                }
1141
 
 
1142
 
#define UPDATE_POS2(k, n, n2)                                                           \
1143
 
                if (!strcmp (key, k)) {                                                 \
1144
 
                        if (value->type == GCONF_VALUE_INT) {                           \
1145
 
                                int x, x_right, y, y_bottom;                            \
1146
 
                                panel_toplevel_get_position (toplevel, &x, &x_right,    \
1147
 
                                                             &y, &y_bottom);            \
1148
 
                                panel_toplevel_set_##n (                                \
1149
 
                                        toplevel,                                       \
1150
 
                                        n,                                              \
1151
 
                                        gconf_value_get_int (value),                    \
1152
 
                                        panel_toplevel_get_##n##_centered (toplevel));  \
1153
 
                        }                                                               \
1154
 
                }
1155
 
 
1156
 
#define UPDATE_CENTERED(k, n, n2)                                                       \
1157
 
                if (!strcmp (key, k)) {                                                 \
1158
 
                        if (value->type == GCONF_VALUE_BOOL) {                          \
1159
 
                                int x, x_right, y, y_bottom;                            \
1160
 
                                panel_toplevel_get_position (toplevel, &x, &x_right,    \
1161
 
                                                             &y, &y_bottom);            \
1162
 
                                panel_toplevel_set_##n (                                \
1163
 
                                        toplevel, n, n2, gconf_value_get_bool (value)); \
1164
 
                        }                                                               \
1165
 
                }
1166
 
 
1167
 
        if (!strcmp (key, "screen")) {
1168
 
                if (value->type == GCONF_VALUE_INT) {
1169
 
                        GdkScreen *screen;
1170
 
 
1171
 
                        screen = gdk_display_get_screen (
1172
 
                                        gdk_display_get_default (), 
1173
 
                                        gconf_value_get_int (value));
1174
 
                        if (screen)
1175
 
                                gtk_window_set_screen (GTK_WINDOW (toplevel), screen);
1176
 
                        else
1177
 
                                /* Make sure to set the key back to an actual
1178
 
                                 * available screen so it will get loaded on
1179
 
                                 * next startup.
1180
 
                                 */
1181
 
                                panel_profile_toplevel_screen_changed (toplevel);
1182
 
                }
1183
 
                        
1184
 
        }
1185
 
        else UPDATE_INT ("monitor", monitor)
1186
 
        else UPDATE_STRING ("name", name)
1187
 
        else UPDATE_BOOL ("expand", expand)
1188
 
        else UPDATE_STRING ("orientation", orientation)
1189
 
        else UPDATE_INT ("size", size)
1190
 
        else UPDATE_POS ("x", x, x_right)
1191
 
        else UPDATE_POS ("y", y, y_bottom)
1192
 
        else UPDATE_POS2 ("x_right", x, x_right)
1193
 
        else UPDATE_POS2 ("y_bottom", y, y_bottom)
1194
 
        else UPDATE_CENTERED ("x_centered", x, x_right)
1195
 
        else UPDATE_CENTERED ("y_centered", y, y_bottom)
1196
 
        else UPDATE_BOOL ("auto_hide", auto_hide)
1197
 
        else UPDATE_BOOL ("enable_animations", animate)
1198
 
        else UPDATE_BOOL ("enable_buttons", enable_buttons)
1199
 
        else UPDATE_BOOL ("enable_arrows", enable_arrows)
1200
 
        else UPDATE_INT ("hide_delay", hide_delay)
1201
 
        else UPDATE_INT ("unhide_delay", unhide_delay)
1202
 
        else UPDATE_INT ("auto_hide_size", auto_hide_size)
1203
 
        else UPDATE_STRING ("animation_speed", animation_speed)
1204
 
}
1205
 
 
1206
 
static void
1207
 
panel_profile_background_change_notify (GConfClient   *client,
1208
 
                                        guint          cnxn_id,
1209
 
                                        GConfEntry    *entry,
1210
 
                                        PanelToplevel *toplevel)
1211
 
{
1212
 
        PanelWidget     *panel_widget;
1213
 
        PanelBackground *background;
1214
 
        GConfValue      *value;
1215
 
        const char      *key;
1216
 
 
1217
 
        key = panel_gconf_basename (gconf_entry_get_key (entry));
1218
 
 
1219
 
        if (!(value = gconf_entry_get_value (entry)))
1220
 
                return;
1221
 
 
1222
 
        panel_widget = panel_toplevel_get_panel_widget (toplevel);
1223
 
        background = &panel_widget->background;
1224
 
 
1225
 
        if (!strcmp (key, "type")) {
1226
 
                if (value->type == GCONF_VALUE_STRING) {
1227
 
                        PanelBackgroundType  background_type;
1228
 
 
1229
 
                        if (panel_profile_map_background_type_string (
1230
 
                                                gconf_value_get_string (value),
1231
 
                                                &background_type)) {
1232
 
                                panel_background_set_type (background, background_type);
1233
 
                                panel_toplevel_update_edges (toplevel);
1234
 
                        }
1235
 
                }
1236
 
        } else if (!strcmp (key, "color")) {
1237
 
                if (value->type == GCONF_VALUE_STRING) {
1238
 
                        GdkColor    gdk_color;
1239
 
                        const char *str;
1240
 
 
1241
 
                        str = gconf_value_get_string (value);
1242
 
 
1243
 
                        if (gdk_color_parse (str, &gdk_color))
1244
 
                                panel_background_set_gdk_color (background, &gdk_color);
1245
 
                }
1246
 
        } else if (!strcmp (key, "opacity")) {
1247
 
                if (value->type == GCONF_VALUE_INT)
1248
 
                        panel_background_set_opacity (background,
1249
 
                                                      gconf_value_get_int (value));
1250
 
        } else if (!strcmp (key, "image")) {
1251
 
                if (value->type == GCONF_VALUE_STRING)
1252
 
                        panel_background_set_image (background,
1253
 
                                                    gconf_value_get_string (value));
1254
 
        } else if (!strcmp (key, "fit")) {
1255
 
                if (value->type == GCONF_VALUE_BOOL)
1256
 
                        panel_background_set_fit (background,
1257
 
                                                  gconf_value_get_bool (value));
1258
 
        } else if (!strcmp (key, "stretch")) {
1259
 
                if (value->type == GCONF_VALUE_BOOL)
1260
 
                        panel_background_set_stretch (background,
1261
 
                                                      gconf_value_get_bool (value));
1262
 
        } else if (!strcmp (key, "rotate")) {
1263
 
                if (value->type == GCONF_VALUE_BOOL)
1264
 
                        panel_background_set_rotate (background,
1265
 
                                                     gconf_value_get_bool (value));
1266
 
        }
1267
 
}
1268
 
 
1269
 
static void
1270
 
panel_profile_disconnect_toplevel (PanelToplevel *toplevel,
1271
 
                                   gpointer       data)
1272
 
{
1273
 
        GConfClient *client;
1274
 
        guint        notify_id = GPOINTER_TO_UINT (data);
1275
 
 
1276
 
        client = panel_gconf_get_client ();
1277
 
 
1278
 
        gconf_client_notify_remove (client, notify_id);
1279
 
}
1280
 
 
1281
 
guint
1282
 
panel_profile_toplevel_notify_add (PanelToplevel         *toplevel,
1283
 
                                   const char            *key,
1284
 
                                   GConfClientNotifyFunc  func,
1285
 
                                   gpointer               data)
1286
 
{
1287
 
        GConfClient *client;
1288
 
        const char  *tmp;
1289
 
        guint        retval;
1290
 
 
1291
 
        client = panel_gconf_get_client ();
1292
 
 
1293
 
        if (!key)
1294
 
                tmp = panel_gconf_sprintf (PANEL_CONFIG_DIR "/toplevels/%s",
1295
 
                                           panel_profile_get_toplevel_id (toplevel));
1296
 
        else
1297
 
                tmp = panel_gconf_sprintf (PANEL_CONFIG_DIR "/toplevels/%s/%s",
1298
 
                                           panel_profile_get_toplevel_id (toplevel),
1299
 
                                           key);
1300
 
 
1301
 
        retval = gconf_client_notify_add (client, tmp, func, data, NULL, NULL);
1302
 
 
1303
 
        return retval;
1304
 
}
1305
 
 
1306
 
static void
1307
 
panel_profile_save_id_list (PanelGConfKeyType  type,
1308
 
                            GSList            *list,
1309
 
                            gboolean           resave)
1310
 
{
1311
 
        GConfClient *client;
1312
 
        const char  *key;
1313
 
        const char  *id_list;
1314
 
 
1315
 
        g_assert (!(resave && list != NULL));
1316
 
 
1317
 
        client = panel_gconf_get_client ();
1318
 
 
1319
 
        id_list = panel_gconf_key_type_to_id_list (type);
1320
 
 
1321
 
        key = panel_gconf_general_key (id_list);
1322
 
        if (resave)
1323
 
                list = gconf_client_get_list (client, key, GCONF_VALUE_STRING, NULL);
1324
 
        else {
1325
 
                /* Make sure the elements in the list appear only once. We only
1326
 
                 * do it when we save a list with new elements. */
1327
 
                list = panel_g_slist_make_unique (list,
1328
 
                                                  (GCompareFunc) strcmp,
1329
 
                                                  TRUE);
1330
 
        }
1331
 
 
1332
 
        gconf_client_set_list (client, key, GCONF_VALUE_STRING, list, NULL);
1333
 
 
1334
 
        g_slist_foreach (list, (GFunc) g_free, NULL);
1335
 
        g_slist_free (list);
1336
 
}
1337
 
 
1338
 
static inline void
1339
 
panel_profile_save_other_id_lists (PanelGConfKeyType type)
1340
 
{
1341
 
        if (type != PANEL_GCONF_TOPLEVELS)
1342
 
                panel_profile_save_id_list (PANEL_GCONF_TOPLEVELS, NULL, TRUE);
1343
 
 
1344
 
        if (type != PANEL_GCONF_OBJECTS)
1345
 
                panel_profile_save_id_list (PANEL_GCONF_OBJECTS, NULL, TRUE);
1346
 
 
1347
 
        if (type != PANEL_GCONF_APPLETS)
1348
 
                panel_profile_save_id_list (PANEL_GCONF_APPLETS, NULL, TRUE);
1349
 
}
1350
 
 
1351
 
void
1352
 
panel_profile_add_to_list (PanelGConfKeyType  type,
1353
 
                           const char        *id)
1354
 
{
1355
 
        GConfClient *client;
1356
 
        GSList      *list;
1357
 
        const char  *key;
1358
 
        const char  *id_list;
1359
 
        char        *new_id;
1360
 
 
1361
 
        client = panel_gconf_get_client ();
1362
 
 
1363
 
        id_list = panel_gconf_key_type_to_id_list (type);
1364
 
 
1365
 
        key = panel_gconf_general_key (id_list);
1366
 
        list = gconf_client_get_list (client, key, GCONF_VALUE_STRING, NULL);
1367
 
 
1368
 
        new_id = id ? g_strdup (id) : panel_profile_find_new_id (type);
1369
 
 
1370
 
        list = g_slist_append (list, new_id);
1371
 
 
1372
 
        panel_profile_save_id_list (type, list, FALSE);
1373
 
        panel_profile_save_other_id_lists (type);
1374
 
}
1375
 
 
1376
 
void
1377
 
panel_profile_remove_from_list (PanelGConfKeyType  type,
1378
 
                                const char        *id)
1379
 
{
1380
 
        GConfClient *client;
1381
 
        GSList      *list, *l;
1382
 
        const char  *key;
1383
 
        const char  *id_list;
1384
 
 
1385
 
        client = panel_gconf_get_client ();
1386
 
 
1387
 
        id_list = panel_gconf_key_type_to_id_list (type);
1388
 
 
1389
 
        key = panel_gconf_general_key (id_list);
1390
 
        list = gconf_client_get_list (client, key, GCONF_VALUE_STRING, NULL);
1391
 
 
1392
 
        /* Remove all occurrence of id and not just the first. We're more solid
1393
 
         * this way (see bug #137308 for example). */
1394
 
        l = list;
1395
 
        while (l) {
1396
 
                GSList *next;
1397
 
 
1398
 
                next = l->next;
1399
 
 
1400
 
                if (!strcmp (id, l->data)) {
1401
 
                        g_free (l->data);
1402
 
                        list = g_slist_delete_link (list, l);
1403
 
                }
1404
 
 
1405
 
                l = next;
1406
 
        }
1407
 
 
1408
 
        panel_profile_save_id_list (type, list, FALSE);
1409
 
        panel_profile_save_other_id_lists (type);
1410
 
}
1411
 
 
1412
 
static gboolean
1413
 
panel_profile_id_list_is_writable (PanelGConfKeyType type)
1414
 
{
1415
 
        GConfClient *client;
1416
 
        const char  *key;
1417
 
        const char  *id_list;
1418
 
 
1419
 
        client = panel_gconf_get_client ();
1420
 
 
1421
 
        id_list = panel_gconf_key_type_to_id_list (type);
1422
 
 
1423
 
        key = panel_gconf_general_key (id_list);
1424
 
        return gconf_client_key_is_writable (client, key, NULL);
1425
 
}
1426
 
 
1427
 
gboolean
1428
 
panel_profile_id_lists_are_writable (void)
1429
 
{
1430
 
  return
1431
 
    panel_profile_id_list_is_writable (PANEL_GCONF_TOPLEVELS) &&
1432
 
    panel_profile_id_list_is_writable (PANEL_GCONF_APPLETS)   &&
1433
 
    panel_profile_id_list_is_writable (PANEL_GCONF_OBJECTS);
1434
 
}
1435
 
 
1436
 
static gboolean
1437
 
panel_profile_find_empty_spot (GdkScreen *screen,
1438
 
                               PanelOrientation *orientation,
1439
 
                               int *monitor)
1440
 
{
1441
 
        GSList *li;
1442
 
        int i;
1443
 
        int *filled_spots;
1444
 
        gboolean found_a_spot = FALSE;
1445
 
 
1446
 
        *monitor = 0;
1447
 
        *orientation = PANEL_ORIENTATION_TOP;
1448
 
 
1449
 
        filled_spots = g_new0 (int, panel_multiscreen_monitors (screen));
1450
 
 
1451
 
        for (li = panel_toplevel_list_toplevels (); li != NULL; li = li->next) {
1452
 
                PanelToplevel *toplevel = li->data;
1453
 
                GdkScreen *toplevel_screen = gtk_window_get_screen (GTK_WINDOW (toplevel));
1454
 
                int toplevel_monitor = panel_toplevel_get_monitor (toplevel);
1455
 
 
1456
 
                if (toplevel_screen != screen ||
1457
 
                    panel_toplevel_get_is_attached (toplevel) ||
1458
 
                    toplevel_monitor < 0)
1459
 
                        continue;
1460
 
 
1461
 
                filled_spots[toplevel_monitor] |= panel_toplevel_get_orientation (toplevel);
1462
 
        }
1463
 
 
1464
 
        for (i = 0; i < panel_multiscreen_monitors (screen); i++) {
1465
 
                /* These are ordered based on "priority" of the
1466
 
                   orientation when picking it */
1467
 
                if ( ! (filled_spots[i] & PANEL_ORIENTATION_TOP)) {
1468
 
                        *orientation = PANEL_ORIENTATION_TOP;
1469
 
                        *monitor = i;
1470
 
                        found_a_spot = TRUE;
1471
 
                        break;
1472
 
                } else if ( ! (filled_spots[i] & PANEL_ORIENTATION_BOTTOM)) {
1473
 
                        *orientation = PANEL_ORIENTATION_BOTTOM;
1474
 
                        *monitor = i;
1475
 
                        found_a_spot = TRUE;
1476
 
                        break;
1477
 
                } else if ( ! (filled_spots[i] & PANEL_ORIENTATION_RIGHT)) {
1478
 
                        *orientation = PANEL_ORIENTATION_RIGHT;
1479
 
                        *monitor = i;
1480
 
                        found_a_spot = TRUE;
1481
 
                        break;
1482
 
                } else if ( ! (filled_spots[i] & PANEL_ORIENTATION_LEFT)) {
1483
 
                        *orientation = PANEL_ORIENTATION_LEFT;
1484
 
                        *monitor = i;
1485
 
                        found_a_spot = TRUE;
1486
 
                        break;
1487
 
                }
1488
 
        }
1489
 
 
1490
 
        g_free (filled_spots);
1491
 
 
1492
 
        return found_a_spot;
1493
 
}
1494
 
 
1495
 
void
1496
 
panel_profile_create_toplevel (GdkScreen *screen)
1497
 
{
1498
 
        GConfClient     *client;
1499
 
        const char      *key;
1500
 
        char            *id;
1501
 
        char            *dir;
1502
 
        PanelOrientation orientation;
1503
 
        int              monitor;
1504
 
       
1505
 
        g_return_if_fail (screen != NULL);
1506
 
 
1507
 
        client = panel_gconf_get_client ();
1508
 
 
1509
 
        id = panel_profile_find_new_id (PANEL_GCONF_TOPLEVELS);
1510
 
 
1511
 
        dir = g_strdup_printf (PANEL_CONFIG_DIR "/toplevels/%s", id);
1512
 
        panel_gconf_associate_schemas_in_dir (client, dir, PANEL_SCHEMAS_DIR "/toplevels");
1513
 
        g_free (dir);
1514
 
 
1515
 
        key = panel_gconf_full_key (PANEL_GCONF_TOPLEVELS, id, "screen");
1516
 
        gconf_client_set_int (client, key, gdk_screen_get_number (screen), NULL);
1517
 
 
1518
 
        if (panel_profile_find_empty_spot (screen, &orientation, &monitor)) {
1519
 
                key = panel_gconf_full_key (PANEL_GCONF_TOPLEVELS, id, "monitor");
1520
 
                gconf_client_set_int (client, key, monitor, NULL);
1521
 
 
1522
 
                key = panel_gconf_full_key (PANEL_GCONF_TOPLEVELS, id, "orientation");
1523
 
                gconf_client_set_string (client, key, panel_profile_map_orientation (orientation), NULL);
1524
 
        }
1525
 
        
1526
 
        panel_profile_add_to_list (PANEL_GCONF_TOPLEVELS, id);
1527
 
 
1528
 
        g_free (id);
1529
 
}
1530
 
 
1531
 
static void
1532
 
panel_profile_delete_toplevel_objects (const char        *toplevel_id,
1533
 
                                       PanelGConfKeyType  key_type)
1534
 
{
1535
 
        GConfClient *client;
1536
 
        const char  *key;
1537
 
        GSList      *new_list = NULL,*list, *l;
1538
 
 
1539
 
        client = panel_gconf_get_client ();
1540
 
 
1541
 
        key = panel_gconf_general_key (panel_gconf_key_type_to_id_list (key_type));
1542
 
        list = gconf_client_get_list (client, key, GCONF_VALUE_STRING, NULL);
1543
 
 
1544
 
        for (l = list; l; l = l->next) {
1545
 
                char *id = l->data;
1546
 
                char *parent_toplevel_id;
1547
 
 
1548
 
                key = panel_gconf_full_key (key_type, id, "toplevel_id");
1549
 
                parent_toplevel_id = gconf_client_get_string (client, key, NULL);
1550
 
 
1551
 
                if (parent_toplevel_id && !strcmp (toplevel_id, parent_toplevel_id)) {
1552
 
                        g_free (id);
1553
 
                        g_free (parent_toplevel_id);
1554
 
                        continue;
1555
 
                }
1556
 
 
1557
 
                new_list = g_slist_prepend (new_list, id);
1558
 
 
1559
 
                g_free (parent_toplevel_id);
1560
 
        }
1561
 
        g_slist_free (list);
1562
 
 
1563
 
        key = panel_gconf_general_key (panel_gconf_key_type_to_id_list (key_type));
1564
 
        gconf_client_set_list (client, key, GCONF_VALUE_STRING, new_list, NULL);
1565
 
 
1566
 
        for (l = new_list; l; l = l->next)
1567
 
                g_free (l->data);
1568
 
        g_slist_free (new_list);
1569
 
}
1570
 
 
1571
 
void
1572
 
panel_profile_delete_toplevel (PanelToplevel *toplevel)
1573
 
{
1574
 
        const char *toplevel_id;
1575
 
 
1576
 
        toplevel_id = panel_profile_get_toplevel_id (toplevel);
1577
 
 
1578
 
        panel_profile_delete_toplevel_objects (toplevel_id, PANEL_GCONF_OBJECTS);
1579
 
        panel_profile_delete_toplevel_objects (toplevel_id, PANEL_GCONF_APPLETS);
1580
 
 
1581
 
        panel_profile_remove_from_list (PANEL_GCONF_TOPLEVELS, toplevel_id);
1582
 
}
1583
 
 
1584
 
static GdkScreen *
1585
 
get_toplevel_screen (GConfClient   *client,
1586
 
                     const char    *toplevel_dir)
1587
 
{
1588
 
        GError     *error = NULL;
1589
 
        GdkDisplay *display;
1590
 
        const char *key;
1591
 
        int         screen_n;
1592
 
 
1593
 
        key = panel_gconf_sprintf ("%s/screen", toplevel_dir);
1594
 
        screen_n = gconf_client_get_int (client, key, &error);
1595
 
        if (error) {
1596
 
                g_warning (_("Error reading GConf integer value '%s': %s"),
1597
 
                           key, error->message);
1598
 
                g_error_free (error);
1599
 
                return gdk_screen_get_default ();
1600
 
        }
1601
 
 
1602
 
        display = gdk_display_get_default ();
1603
 
 
1604
 
        if (screen_n < 0 || screen_n >= gdk_display_get_n_screens (display)) {
1605
 
#if 0
1606
 
                g_warning (_("Panel '%s' is set to be displayed on screen %d which "
1607
 
                             "is not currently available. Not loading this panel."),
1608
 
                           toplevel_dir, screen_n);
1609
 
#endif
1610
 
                return NULL;
1611
 
        }
1612
 
 
1613
 
        return gdk_display_get_screen (display, screen_n);
1614
 
}
1615
 
 
1616
 
PanelToplevel *
1617
 
panel_profile_load_toplevel (GConfClient       *client,
1618
 
                             const char        *profile_dir,
1619
 
                             PanelGConfKeyType  type,
1620
 
                             const char        *toplevel_id)
1621
 
{
1622
 
        PanelToplevel *toplevel;
1623
 
        GdkScreen     *screen;
1624
 
        GError        *error;
1625
 
        const char    *key;
1626
 
        char          *toplevel_dir;
1627
 
        guint          notify_id;
1628
 
 
1629
 
        if (!toplevel_id || !toplevel_id [0])
1630
 
                return NULL;
1631
 
 
1632
 
        toplevel_dir = g_strdup_printf ("%s/toplevels/%s", profile_dir, toplevel_id);
1633
 
 
1634
 
        if (!gconf_client_dir_exists (client, toplevel_dir, NULL))
1635
 
                panel_gconf_associate_schemas_in_dir (
1636
 
                        client, toplevel_dir, PANEL_SCHEMAS_DIR "/toplevels");
1637
 
 
1638
 
        gconf_client_add_dir (client,
1639
 
                              toplevel_dir,
1640
 
                              GCONF_CLIENT_PRELOAD_ONELEVEL,
1641
 
                              NULL);
1642
 
 
1643
 
        key = panel_gconf_sprintf ("%s/background", toplevel_dir);
1644
 
        gconf_client_add_dir (client,
1645
 
                              key,
1646
 
                              GCONF_CLIENT_PRELOAD_ONELEVEL,
1647
 
                              NULL);
1648
 
 
1649
 
        if (!(screen = get_toplevel_screen (client, toplevel_dir))) {
1650
 
                gconf_client_remove_dir (client, key, NULL);
1651
 
                gconf_client_remove_dir (client, toplevel_dir, NULL);
1652
 
                g_free (toplevel_dir);
1653
 
                return NULL;
1654
 
        }
1655
 
 
1656
 
        toplevel = g_object_new (PANEL_TYPE_TOPLEVEL,
1657
 
                                 "screen", screen,
1658
 
                                 NULL);
1659
 
 
1660
 
#define GET_INT(k, fn)                                                              \
1661
 
        {                                                                           \
1662
 
                int val;                                                            \
1663
 
                error = NULL;                                                       \
1664
 
                key = panel_gconf_sprintf ("%s/" k, toplevel_dir);                  \
1665
 
                val = gconf_client_get_int (client, key, &error);                   \
1666
 
                if (!error)                                                         \
1667
 
                        panel_toplevel_set_##fn (toplevel, val);                    \
1668
 
                else {                                                              \
1669
 
                        g_warning (_("Error reading GConf integer value '%s': %s"), \
1670
 
                                   key, error->message);                            \
1671
 
                        g_error_free (error);                                       \
1672
 
                }                                                                   \
1673
 
        }
1674
 
 
1675
 
#define GET_BOOL(k, fn)                                                             \
1676
 
        {                                                                           \
1677
 
                gboolean val;                                                       \
1678
 
                error = NULL;                                                       \
1679
 
                key = panel_gconf_sprintf ("%s/" k, toplevel_dir);                  \
1680
 
                val = gconf_client_get_bool (client, key, &error);                  \
1681
 
                if (!error)                                                         \
1682
 
                        panel_toplevel_set_##fn (toplevel, val);                    \
1683
 
                else {                                                              \
1684
 
                        g_warning (_("Error reading GConf boolean value '%s': %s"), \
1685
 
                                   key, error->message);                            \
1686
 
                        g_error_free (error);                                       \
1687
 
                }                                                                   \
1688
 
        }
1689
 
 
1690
 
#define GET_STRING(k, fn)                                                           \
1691
 
        {                                                                           \
1692
 
                char *val;                                                          \
1693
 
                error = NULL;                                                       \
1694
 
                key = panel_gconf_sprintf ("%s/" k, toplevel_dir);                  \
1695
 
                val = gconf_client_get_string (client, key, &error);                \
1696
 
                if (!error && val) {                                                \
1697
 
                        set_##fn##_from_string (toplevel, val);                     \
1698
 
                        g_free (val);                                               \
1699
 
                } else if (error) {                                                 \
1700
 
                        g_warning (_("Error reading GConf string value '%s': %s"),  \
1701
 
                                   key, error->message);                            \
1702
 
                        g_error_free (error);                                       \
1703
 
                }                                                                   \
1704
 
        }
1705
 
 
1706
 
        GET_STRING ("name", name);
1707
 
        GET_INT ("monitor", monitor);
1708
 
        GET_BOOL ("expand", expand);
1709
 
        GET_STRING ("orientation", orientation);
1710
 
        GET_INT ("size", size);
1711
 
        GET_BOOL ("auto_hide", auto_hide);
1712
 
        GET_BOOL ("enable_animations", animate);
1713
 
        GET_BOOL ("enable_buttons", enable_buttons);
1714
 
        GET_BOOL ("enable_arrows", enable_arrows);
1715
 
        GET_INT ("hide_delay", hide_delay);
1716
 
        GET_INT ("unhide_delay", unhide_delay);
1717
 
        GET_INT ("auto_hide_size", auto_hide_size);
1718
 
        GET_STRING ("animation_speed", animation_speed);
1719
 
 
1720
 
#define GET_POSITION(a, b, c, fn)                                                   \
1721
 
        {                                                                           \
1722
 
                gboolean centered;                                                  \
1723
 
                int      position;                                                  \
1724
 
                int      position2;                                                 \
1725
 
                key = panel_gconf_sprintf ("%s/" c, toplevel_dir);                  \
1726
 
                centered = gconf_client_get_bool (client, key, &error);             \
1727
 
                if (!error) {                                                       \
1728
 
                        key = panel_gconf_sprintf ("%s/" a, toplevel_dir);          \
1729
 
                        position = gconf_client_get_int (client, key, &error);      \
1730
 
                }                                                                   \
1731
 
                if (!error) {                                                       \
1732
 
                        GConfValue *value;                                          \
1733
 
                        key = panel_gconf_sprintf ("%s/" b, toplevel_dir);          \
1734
 
                        /* we need to do this since the key was added in 2.19 and   \
1735
 
                         * the default value returned when the key is not set       \
1736
 
                         * (for people coming from older versions) is 0, which      \
1737
 
                         * is not what we want. */                                  \
1738
 
                        value = gconf_client_get_without_default (client, key, &error);\
1739
 
                        if (value && value->type == GCONF_VALUE_INT)                \
1740
 
                                position2 = gconf_value_get_int (value);            \
1741
 
                        else                                                        \
1742
 
                                position2 = -1;                                     \
1743
 
                                                                                    \
1744
 
                        if (value)                                                  \
1745
 
                                gconf_value_free (value);                           \
1746
 
                }                                                                   \
1747
 
                if (!error)                                                         \
1748
 
                        panel_toplevel_set_##fn (toplevel, position, position2,     \
1749
 
                                                 centered);                         \
1750
 
                else {                                                              \
1751
 
                        g_warning (_("Error reading GConf integer value '%s': %s"), \
1752
 
                                   key, error->message);                            \
1753
 
                        g_error_free (error);                                       \
1754
 
                }                                                                   \
1755
 
        }
1756
 
 
1757
 
        GET_POSITION ("x", "x_right", "x_centered", x);
1758
 
        GET_POSITION ("y", "y_bottom", "y_centered", y);
1759
 
 
1760
 
        panel_profile_load_background (toplevel, client, toplevel_dir);
1761
 
 
1762
 
        panel_profile_set_toplevel_id (toplevel, toplevel_id);
1763
 
 
1764
 
        panel_profile_connect_to_toplevel (toplevel);
1765
 
 
1766
 
        notify_id = panel_profile_toplevel_notify_add (
1767
 
                        toplevel,
1768
 
                        NULL,
1769
 
                        (GConfClientNotifyFunc) panel_profile_toplevel_change_notify,
1770
 
                        toplevel);
1771
 
        g_signal_connect (toplevel, "destroy",
1772
 
                          G_CALLBACK (panel_profile_disconnect_toplevel),
1773
 
                          GUINT_TO_POINTER (notify_id));
1774
 
 
1775
 
        notify_id = panel_profile_toplevel_notify_add (
1776
 
                        toplevel,
1777
 
                        "background",
1778
 
                        (GConfClientNotifyFunc) panel_profile_background_change_notify,
1779
 
                        toplevel);
1780
 
        g_signal_connect (toplevel, "destroy",
1781
 
                          G_CALLBACK (panel_profile_disconnect_toplevel),
1782
 
                          GUINT_TO_POINTER (notify_id));
1783
 
 
1784
 
        g_free (toplevel_dir);
1785
 
 
1786
 
        panel_setup (toplevel);
1787
 
 
1788
 
        return toplevel;
1789
 
}
1790
 
 
1791
 
static void
1792
 
panel_profile_load_and_show_toplevel (GConfClient       *client,
1793
 
                                      const char        *profile_dir,
1794
 
                                      PanelGConfKeyType  type,
1795
 
                                      const char        *toplevel_id)
1796
 
{
1797
 
        PanelToplevel *toplevel;
1798
 
        const char    *id_list;
1799
 
        const char    *key;
1800
 
        GConfValue    *value;
1801
 
        gboolean       loading_queued_applets;
1802
 
 
1803
 
        toplevel = panel_profile_load_toplevel (client, profile_dir, type, toplevel_id);
1804
 
        if (!toplevel)
1805
 
                return;
1806
 
 
1807
 
        gtk_widget_show (GTK_WIDGET (toplevel));
1808
 
 
1809
 
        loading_queued_applets = FALSE;
1810
 
 
1811
 
        /* reload list of objects to get those that might be on the new
1812
 
         * toplevel */
1813
 
        id_list = panel_gconf_key_type_to_id_list (PANEL_GCONF_OBJECTS);
1814
 
        key = panel_gconf_sprintf ("%s/general/%s", profile_dir, id_list);
1815
 
        value = gconf_client_get (client, key, NULL);
1816
 
        if (value) {
1817
 
                panel_profile_object_id_list_update (client, value,
1818
 
                                                     PANEL_GCONF_OBJECTS);
1819
 
                loading_queued_applets = TRUE;
1820
 
                gconf_value_free (value);
1821
 
        }
1822
 
 
1823
 
        id_list = panel_gconf_key_type_to_id_list (PANEL_GCONF_APPLETS);
1824
 
        key = panel_gconf_sprintf ("%s/general/%s", profile_dir, id_list);
1825
 
        value = gconf_client_get (client, key, NULL);
1826
 
        if (value) {
1827
 
                panel_profile_object_id_list_update (client, value,
1828
 
                                                     PANEL_GCONF_APPLETS);
1829
 
                loading_queued_applets = TRUE;
1830
 
                gconf_value_free (value);
1831
 
        }
1832
 
 
1833
 
        if (!loading_queued_applets)
1834
 
                panel_applet_load_queued_applets (FALSE);
1835
 
}
1836
 
 
1837
 
static void
1838
 
panel_profile_load_and_show_toplevel_startup (GConfClient       *client,
1839
 
                                              const char        *profile_dir,
1840
 
                                              PanelGConfKeyType  type,
1841
 
                                              const char        *toplevel_id)
1842
 
{
1843
 
        PanelToplevel *toplevel;
1844
 
 
1845
 
        toplevel = panel_profile_load_toplevel (client, profile_dir, type, toplevel_id);
1846
 
        if (toplevel)
1847
 
                gtk_widget_show (GTK_WIDGET (toplevel));
1848
 
}
1849
 
 
1850
 
static void
1851
 
panel_profile_destroy_toplevel (const char *id)
1852
 
{
1853
 
        PanelToplevel *toplevel;
1854
 
 
1855
 
        if (!(toplevel = panel_profile_get_toplevel_by_id (id)))
1856
 
                return;
1857
 
 
1858
 
        gtk_widget_destroy (GTK_WIDGET (toplevel));
1859
 
}
1860
 
 
1861
 
char *
1862
 
panel_profile_prepare_object_with_id (PanelObjectType  object_type,
1863
 
                                      const char      *toplevel_id,
1864
 
                                      int              position,
1865
 
                                      gboolean         right_stick)
1866
 
{
1867
 
        PanelGConfKeyType  key_type;
1868
 
        GConfClient       *client;
1869
 
        const char        *key;
1870
 
        char              *id;
1871
 
        char              *dir;
1872
 
 
1873
 
        key_type = (object_type == PANEL_OBJECT_APPLET) ? PANEL_GCONF_APPLETS : PANEL_GCONF_OBJECTS;
1874
 
 
1875
 
        client  = panel_gconf_get_client ();
1876
 
 
1877
 
        id = panel_profile_find_new_id (key_type);
1878
 
 
1879
 
        dir = g_strdup_printf (PANEL_CONFIG_DIR "/%s/%s",
1880
 
                               (key_type == PANEL_GCONF_APPLETS) ? "applets" : "objects",
1881
 
                               id);
1882
 
        panel_gconf_associate_schemas_in_dir (client, dir, PANEL_SCHEMAS_DIR "/objects");
1883
 
 
1884
 
        key = panel_gconf_full_key (key_type, id, "object_type");
1885
 
        gconf_client_set_string (client,
1886
 
                                 key,
1887
 
                                 gconf_enum_to_string (panel_object_type_map, object_type),
1888
 
                                 NULL);
1889
 
 
1890
 
        key = panel_gconf_full_key (key_type, id, "toplevel_id");
1891
 
        gconf_client_set_string (client, key, toplevel_id, NULL);
1892
 
 
1893
 
        key = panel_gconf_full_key (key_type, id, "position");
1894
 
        gconf_client_set_int (client, key, position, NULL);
1895
 
 
1896
 
        key = panel_gconf_full_key (key_type, id, "panel_right_stick");
1897
 
        gconf_client_set_bool (client, key, right_stick, NULL);
1898
 
 
1899
 
        g_free (dir);
1900
 
 
1901
 
        return id;
1902
 
}
1903
 
 
1904
 
char *
1905
 
panel_profile_prepare_object (PanelObjectType  object_type,
1906
 
                              PanelToplevel   *toplevel,
1907
 
                              int              position,
1908
 
                              gboolean         right_stick)
1909
 
{
1910
 
        return panel_profile_prepare_object_with_id (object_type,
1911
 
                                                     panel_profile_get_toplevel_id (toplevel),
1912
 
                                                     position,
1913
 
                                                     right_stick);
1914
 
}
1915
 
 
1916
 
void
1917
 
panel_profile_delete_object (AppletInfo *applet_info)
1918
 
{
1919
 
        PanelGConfKeyType  type;
1920
 
        const char        *id;
1921
 
 
1922
 
        type = (applet_info->type) == PANEL_OBJECT_APPLET ? PANEL_GCONF_APPLETS :
1923
 
                                                            PANEL_GCONF_OBJECTS;
1924
 
        id = panel_applet_get_id (applet_info);
1925
 
 
1926
 
        panel_profile_remove_from_list (type, id);
1927
 
}
1928
 
 
1929
 
static void
1930
 
panel_profile_load_object (GConfClient       *client,
1931
 
                           const char        *profile_dir,
1932
 
                           PanelGConfKeyType  type,
1933
 
                           const char        *id)
1934
 
{
1935
 
        PanelObjectType  object_type;
1936
 
        char            *object_dir;
1937
 
        const char      *key;
1938
 
        char            *type_string;
1939
 
        char            *toplevel_id;
1940
 
        int              position;
1941
 
        gboolean         right_stick;
1942
 
        gboolean         locked;
1943
 
 
1944
 
        object_dir = g_strdup_printf ("%s/%s/%s",
1945
 
                                      profile_dir,
1946
 
                                      type == PANEL_GCONF_OBJECTS ? "objects" : "applets",
1947
 
                                      id);
1948
 
 
1949
 
        gconf_client_add_dir (client, object_dir, GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
1950
 
 
1951
 
        key = panel_gconf_sprintf ("%s/object_type", object_dir);
1952
 
        type_string = gconf_client_get_string (client, key, NULL);
1953
 
        
1954
 
        if (!panel_profile_map_object_type_string (type_string, &object_type)) {
1955
 
                g_free (type_string);
1956
 
                gconf_client_remove_dir (client, object_dir, NULL);
1957
 
                g_free (object_dir);
1958
 
                return;
1959
 
        }
1960
 
        
1961
 
        key = panel_gconf_sprintf ("%s/position", object_dir);
1962
 
        position = gconf_client_get_int (client, key, NULL);
1963
 
        
1964
 
        key = panel_gconf_sprintf ("%s/toplevel_id", object_dir);
1965
 
        toplevel_id = gconf_client_get_string (client, key, NULL);
1966
 
 
1967
 
        key = panel_gconf_sprintf ("%s/panel_right_stick", object_dir);
1968
 
        right_stick = gconf_client_get_bool (client, key, NULL);
1969
 
 
1970
 
        key = panel_gconf_sprintf ("%s/locked", object_dir);
1971
 
        locked = gconf_client_get_bool (client, key, NULL);
1972
 
 
1973
 
        panel_applet_queue_applet_to_load (id,
1974
 
                                           object_type,
1975
 
                                           toplevel_id,
1976
 
                                           position,
1977
 
                                           right_stick,
1978
 
                                           locked);
1979
 
 
1980
 
        g_free (toplevel_id);
1981
 
        g_free (type_string);
1982
 
        g_free (object_dir);
1983
 
}
1984
 
 
1985
 
static void
1986
 
panel_profile_destroy_object (const char *id)
1987
 
{
1988
 
        AppletInfo *info;
1989
 
 
1990
 
        info = panel_applet_get_by_id (id);
1991
 
 
1992
 
        panel_applet_clean (info);
1993
 
}
1994
 
 
1995
 
static void
1996
 
panel_profile_delete_dir (GConfClient       *client,
1997
 
                          PanelGConfKeyType  type,
1998
 
                          const char        *id)
1999
 
{
2000
 
        const char *key;
2001
 
        char       *type_str;
2002
 
 
2003
 
        switch (type) {
2004
 
        case PANEL_GCONF_TOPLEVELS:
2005
 
                type_str = "toplevels";
2006
 
                break;
2007
 
        case PANEL_GCONF_OBJECTS:
2008
 
                type_str = "objects";
2009
 
                break;
2010
 
        case PANEL_GCONF_APPLETS:
2011
 
                type_str = "applets";
2012
 
                break;
2013
 
        default:
2014
 
                type_str = NULL;
2015
 
                g_assert_not_reached ();
2016
 
                break;
2017
 
        }
2018
 
 
2019
 
        if (type == PANEL_GCONF_TOPLEVELS) {
2020
 
                key = panel_gconf_sprintf (PANEL_CONFIG_DIR "/%s/%s/background",
2021
 
                                           type_str, id);
2022
 
                gconf_client_remove_dir (client, key, NULL);
2023
 
        }
2024
 
 
2025
 
        key = panel_gconf_sprintf (PANEL_CONFIG_DIR "/%s/%s",
2026
 
                                   type_str, id);
2027
 
        gconf_client_remove_dir (client, key, NULL);
2028
 
 
2029
 
        gconf_client_recursive_unset (client,
2030
 
                                      key,
2031
 
                                      GCONF_UNSET_INCLUDING_SCHEMA_NAMES,
2032
 
                                      NULL);
2033
 
}
2034
 
 
2035
 
static gboolean
2036
 
panel_profile_object_exists (GSList                *list,
2037
 
                             const char            *id,
2038
 
                             PanelProfileGetIdFunc  get_id_func)
2039
 
{
2040
 
        GSList *l;
2041
 
 
2042
 
        if (!list || !id)
2043
 
                return FALSE;
2044
 
 
2045
 
        for (l = list; l; l = l->next) {
2046
 
                const char *check_id;
2047
 
 
2048
 
                check_id = get_id_func (l->data);
2049
 
                g_assert (check_id != NULL);
2050
 
 
2051
 
                if (!strcmp (check_id, id))
2052
 
                        return TRUE;
2053
 
        }
2054
 
 
2055
 
        return FALSE;
2056
 
}
2057
 
 
2058
 
static gboolean
2059
 
panel_profile_id_exists (GSList     *id_list,
2060
 
                         const char *id)
2061
 
{
2062
 
        GSList *l;
2063
 
 
2064
 
        if (!id_list || !id)
2065
 
                return FALSE;
2066
 
 
2067
 
        for (l = id_list; l; l = l->next) {
2068
 
                const char *check_id = gconf_value_get_string (l->data);
2069
 
 
2070
 
                if (!strcmp (id, check_id))
2071
 
                        return TRUE;
2072
 
        }
2073
 
 
2074
 
        return FALSE;
2075
 
}
2076
 
 
2077
 
static void
2078
 
panel_profile_load_added_ids (GConfClient            *client,
2079
 
                              PanelGConfKeyType       type,
2080
 
                              GSList                 *list,
2081
 
                              GSList                 *id_list,
2082
 
                              PanelProfileGetIdFunc   get_id_func,
2083
 
                              PanelProfileLoadFunc    load_handler,
2084
 
                              PanelProfileOnLoadQueue on_load_queue)
2085
 
{
2086
 
        GSList *added_ids = NULL;
2087
 
        GSList *l;
2088
 
 
2089
 
        for (l = id_list; l; l = l->next) {
2090
 
                const char *id = gconf_value_get_string (l->data);
2091
 
 
2092
 
                if (!panel_profile_object_exists (list, id, get_id_func) &&
2093
 
                    (on_load_queue == NULL || !on_load_queue (id)))
2094
 
                        added_ids = g_slist_prepend (added_ids, g_strdup (id));
2095
 
        }
2096
 
 
2097
 
        for (l = added_ids; l; l = l->next) {
2098
 
                char *id;
2099
 
                id = (char *) l->data;
2100
 
 
2101
 
                if (id && id[0])
2102
 
                        load_handler (client, PANEL_CONFIG_DIR, type, id);
2103
 
 
2104
 
                g_free (l->data);
2105
 
                l->data = NULL;
2106
 
        }
2107
 
 
2108
 
        g_slist_free (added_ids);
2109
 
}
2110
 
 
2111
 
static void
2112
 
panel_profile_delete_removed_ids (GConfClient             *client,
2113
 
                                  PanelGConfKeyType        type,
2114
 
                                  GSList                  *list,
2115
 
                                  GSList                  *id_list,
2116
 
                                  PanelProfileGetIdFunc    get_id_func,
2117
 
                                  PanelProfileDestroyFunc  destroy_handler)
2118
 
{
2119
 
        GSList *removed_ids = NULL;
2120
 
        GSList *l;
2121
 
 
2122
 
        for (l = list; l; l = l->next) {
2123
 
                const char *id;
2124
 
 
2125
 
                id = get_id_func (l->data);
2126
 
 
2127
 
                if (!panel_profile_id_exists (id_list, id))
2128
 
                        removed_ids = g_slist_prepend (removed_ids, g_strdup (id));
2129
 
        }
2130
 
 
2131
 
        for (l = removed_ids; l; l = l->next) {
2132
 
                const char *id = l->data;
2133
 
 
2134
 
                panel_profile_delete_dir (client, type, id);
2135
 
                destroy_handler (id);
2136
 
 
2137
 
                g_free (l->data);
2138
 
                l->data = NULL;
2139
 
        }
2140
 
        g_slist_free (removed_ids);
2141
 
}
2142
 
 
2143
 
static void
2144
 
panel_profile_toplevel_id_list_notify (GConfClient *client,
2145
 
                                       guint        cnxn_id,
2146
 
                                       GConfEntry  *entry)
2147
 
{
2148
 
        GConfValue *value;
2149
 
        GSList     *l, *existing_toplevels;
2150
 
        GSList     *toplevel_ids;
2151
 
 
2152
 
        if (!(value = gconf_entry_get_value (entry)))
2153
 
                return;
2154
 
 
2155
 
        if (value->type != GCONF_VALUE_LIST ||
2156
 
            gconf_value_get_list_type (value) != GCONF_VALUE_STRING) {
2157
 
                gconf_value_free (value);
2158
 
                return;
2159
 
        }
2160
 
 
2161
 
        toplevel_ids = g_slist_copy (gconf_value_get_list (value));
2162
 
        toplevel_ids = panel_g_slist_make_unique (toplevel_ids,
2163
 
                                                  panel_gconf_value_strcmp,
2164
 
                                                  FALSE);
2165
 
 
2166
 
        existing_toplevels = NULL;
2167
 
        for (l = panel_toplevel_list_toplevels (); l; l = l->next) {
2168
 
                PanelToplevel *toplevel = l->data;
2169
 
 
2170
 
                /* Attached toplevels aren't on the id list */
2171
 
                if (panel_toplevel_get_is_attached (toplevel))
2172
 
                        continue;
2173
 
 
2174
 
                existing_toplevels = g_slist_prepend (existing_toplevels, toplevel);
2175
 
        }
2176
 
 
2177
 
        panel_profile_load_added_ids (client,
2178
 
                                      PANEL_GCONF_TOPLEVELS,
2179
 
                                      existing_toplevels,
2180
 
                                      toplevel_ids,
2181
 
                                      (PanelProfileGetIdFunc) panel_profile_get_toplevel_id,
2182
 
                                      (PanelProfileLoadFunc) panel_profile_load_and_show_toplevel,
2183
 
                                      (PanelProfileOnLoadQueue) NULL);
2184
 
 
2185
 
        panel_profile_delete_removed_ids (client,
2186
 
                                          PANEL_GCONF_TOPLEVELS,
2187
 
                                          existing_toplevels,
2188
 
                                          toplevel_ids,
2189
 
                                          (PanelProfileGetIdFunc) panel_profile_get_toplevel_id,
2190
 
                                          (PanelProfileDestroyFunc) panel_profile_destroy_toplevel);
2191
 
 
2192
 
        g_slist_free (existing_toplevels);
2193
 
        g_slist_free (toplevel_ids);
2194
 
}
2195
 
 
2196
 
static void
2197
 
panel_profile_object_id_list_update (GConfClient       *client,
2198
 
                                     GConfValue        *value,
2199
 
                                     PanelGConfKeyType  type)
2200
 
{
2201
 
        GSList *existing_applets;
2202
 
        GSList *sublist = NULL, *l;
2203
 
        GSList *object_ids;
2204
 
 
2205
 
        if (value->type != GCONF_VALUE_LIST ||
2206
 
            gconf_value_get_list_type (value) != GCONF_VALUE_STRING) {
2207
 
                gconf_value_free (value);
2208
 
                return;
2209
 
        }
2210
 
 
2211
 
        object_ids = g_slist_copy (gconf_value_get_list (value));
2212
 
        object_ids = panel_g_slist_make_unique (object_ids,
2213
 
                                                panel_gconf_value_strcmp,
2214
 
                                                FALSE);
2215
 
 
2216
 
        existing_applets = panel_applet_list_applets ();
2217
 
 
2218
 
        for (l = existing_applets; l; l = l->next) {
2219
 
                AppletInfo *info = l->data;
2220
 
 
2221
 
                if ((type == PANEL_GCONF_APPLETS && info->type == PANEL_OBJECT_APPLET) ||
2222
 
                    (type == PANEL_GCONF_OBJECTS && info->type != PANEL_OBJECT_APPLET))
2223
 
                        sublist = g_slist_prepend (sublist, info);
2224
 
        }
2225
 
 
2226
 
        panel_profile_load_added_ids (client,
2227
 
                                      type,
2228
 
                                      sublist,
2229
 
                                      object_ids,
2230
 
                                      (PanelProfileGetIdFunc) panel_applet_get_id,
2231
 
                                      (PanelProfileLoadFunc) panel_profile_load_object,
2232
 
                                      (PanelProfileOnLoadQueue) panel_applet_on_load_queue);
2233
 
 
2234
 
        panel_profile_delete_removed_ids (client,
2235
 
                                          type,
2236
 
                                          sublist,
2237
 
                                          object_ids,
2238
 
                                          (PanelProfileGetIdFunc) panel_applet_get_id,
2239
 
                                          (PanelProfileDestroyFunc) panel_profile_destroy_object);
2240
 
 
2241
 
        g_slist_free (sublist);
2242
 
        g_slist_free (object_ids);
2243
 
 
2244
 
        panel_applet_load_queued_applets (FALSE);
2245
 
}
2246
 
 
2247
 
static void
2248
 
panel_profile_object_id_list_notify (GConfClient *client,
2249
 
                                     guint        cnxn_id,
2250
 
                                     GConfEntry  *entry,
2251
 
                                     gpointer     data)
2252
 
{
2253
 
        GConfValue        *value;
2254
 
        PanelGConfKeyType  type = GPOINTER_TO_INT (data);
2255
 
 
2256
 
        if (!(value = gconf_entry_get_value (entry)))
2257
 
                return;
2258
 
 
2259
 
        panel_profile_object_id_list_update (client, value, type);
2260
 
}
2261
 
 
2262
 
static void
2263
 
panel_profile_load_list (GConfClient           *client,
2264
 
                         const char            *profile_dir,
2265
 
                         PanelGConfKeyType      type,
2266
 
                         PanelProfileLoadFunc   load_handler,
2267
 
                         GConfClientNotifyFunc  notify_handler)
2268
 
{
2269
 
 
2270
 
        const char *key;
2271
 
        GSList     *list;
2272
 
        GSList     *l;
2273
 
        const char *id_list;
2274
 
 
2275
 
        id_list = panel_gconf_key_type_to_id_list (type);
2276
 
 
2277
 
        key = panel_gconf_sprintf ("%s/general/%s", profile_dir, id_list);
2278
 
 
2279
 
        gconf_client_notify_add (client, key, notify_handler,
2280
 
                                 GINT_TO_POINTER (type),
2281
 
                                 NULL, NULL);
2282
 
 
2283
 
        list = gconf_client_get_list (client, key, GCONF_VALUE_STRING, NULL);
2284
 
        list = panel_g_slist_make_unique (list,
2285
 
                                          (GCompareFunc) strcmp,
2286
 
                                          TRUE);
2287
 
 
2288
 
        for (l = list; l; l = l->next) {
2289
 
                char *id;
2290
 
                id = (char *) l->data;
2291
 
 
2292
 
                if (id && id[0])
2293
 
                        load_handler (client, profile_dir, type, id);
2294
 
 
2295
 
                g_free (l->data);
2296
 
                l->data = NULL;
2297
 
        }
2298
 
        g_slist_free (list);
2299
 
}
2300
 
 
2301
 
static GSList *
2302
 
panel_profile_copy_defaults_for_screen (GConfClient       *client,
2303
 
                                        const char        *profile_dir,
2304
 
                                        int                screen_n,
2305
 
                                        PanelGConfKeyType  type)
2306
 
{
2307
 
        GSList     *default_ids, *l;
2308
 
        GSList     *new_ids = NULL;
2309
 
        const char *key;
2310
 
        const char *id_list, *type_str;
2311
 
 
2312
 
        id_list = panel_gconf_key_type_to_id_list (type);
2313
 
 
2314
 
        switch (type) {
2315
 
        case PANEL_GCONF_TOPLEVELS:
2316
 
                type_str    = "toplevels";
2317
 
                break;
2318
 
        case PANEL_GCONF_OBJECTS:
2319
 
                type_str    = "objects";
2320
 
                break;
2321
 
        case PANEL_GCONF_APPLETS:
2322
 
                type_str    = "applets";
2323
 
                break;
2324
 
        default:
2325
 
                type_str = NULL;
2326
 
                g_assert_not_reached ();
2327
 
                break;
2328
 
        }
2329
 
 
2330
 
        key = panel_gconf_sprintf (PANEL_DEFAULTS_DIR "/general/%s", id_list);
2331
 
        default_ids = gconf_client_get_list (client, key, GCONF_VALUE_STRING, NULL);
2332
 
 
2333
 
        for (l = default_ids; l; l = l->next) {
2334
 
                char *default_id = l->data;
2335
 
                char *new_id;
2336
 
                char *src_dir;
2337
 
                char *dest_dir;
2338
 
 
2339
 
                new_id = g_strdup_printf ("%s_screen%d", default_id, screen_n);
2340
 
 
2341
 
                src_dir  = g_strdup_printf (PANEL_DEFAULTS_DIR "/%s/%s", type_str, default_id);
2342
 
                dest_dir = g_strdup_printf ("%s/%s/%s", profile_dir, type_str, new_id);
2343
 
 
2344
 
                panel_gconf_copy_dir (client, src_dir, dest_dir);
2345
 
 
2346
 
                new_ids = g_slist_prepend (new_ids, new_id);
2347
 
 
2348
 
                g_free (src_dir);
2349
 
                g_free (dest_dir);
2350
 
                g_free (l->data);
2351
 
        }
2352
 
        g_slist_free (default_ids);
2353
 
 
2354
 
        return new_ids;
2355
 
}
2356
 
 
2357
 
static void
2358
 
panel_profile_append_new_ids (GConfClient       *client,
2359
 
                              PanelGConfKeyType  type,
2360
 
                              GSList            *new_ids)
2361
 
{
2362
 
        GSList     *list, *l;
2363
 
        const char *key;
2364
 
        const char *id_list;
2365
 
 
2366
 
        id_list = panel_gconf_key_type_to_id_list (type);
2367
 
 
2368
 
        key = panel_gconf_general_key (id_list);
2369
 
        list = gconf_client_get_list (client, key, GCONF_VALUE_STRING, NULL);
2370
 
 
2371
 
        for (l = new_ids; l; l = l->next)
2372
 
                list = g_slist_append (list, l->data);
2373
 
 
2374
 
        g_slist_free (new_ids);
2375
 
 
2376
 
        gconf_client_set_list (client, key, GCONF_VALUE_STRING, list, NULL);
2377
 
        
2378
 
        for (l = list; l; l = l->next)
2379
 
                g_free (l->data);
2380
 
        g_slist_free (list);
2381
 
}
2382
 
 
2383
 
static void
2384
 
panel_profile_copy_default_objects_for_screen (GConfClient       *client,
2385
 
                                               const char        *profile_dir,
2386
 
                                               int                screen_n,
2387
 
                                               PanelGConfKeyType  type)
2388
 
{
2389
 
        GSList *new_objects, *l, *next;
2390
 
 
2391
 
        new_objects = panel_profile_copy_defaults_for_screen (client, profile_dir, screen_n, type);
2392
 
 
2393
 
        for (l = new_objects; l; l = next) {
2394
 
                char       *object_id = l->data;
2395
 
                const char *key;
2396
 
                char       *toplevel_id;
2397
 
                char       *new_toplevel_id;
2398
 
 
2399
 
                next = l->next;
2400
 
 
2401
 
                key = panel_gconf_full_key (type, object_id, "toplevel_id");
2402
 
                toplevel_id = gconf_client_get_string (client, key, NULL);
2403
 
                if (!toplevel_id) {
2404
 
                        new_objects = g_slist_remove_link (new_objects, l);
2405
 
                        g_free (l->data);
2406
 
                        g_slist_free_1 (l);
2407
 
                        continue;
2408
 
                }
2409
 
 
2410
 
                new_toplevel_id = g_strdup_printf ("%s_screen%d", toplevel_id, screen_n);
2411
 
                gconf_client_set_string (client, key, new_toplevel_id, NULL);
2412
 
 
2413
 
                g_free (toplevel_id);
2414
 
                g_free (new_toplevel_id);
2415
 
        }
2416
 
 
2417
 
        panel_profile_append_new_ids (client, type, new_objects);
2418
 
}
2419
 
 
2420
 
/* FIXME:
2421
 
 *   We might want to do something more sophisticated like hardcode
2422
 
 *   the default panel setup as the fallback panels.
2423
 
 */
2424
 
static GSList *
2425
 
panel_profile_create_fallback_toplevel_list (GConfClient *client,
2426
 
                                             const char  *profile_dir)
2427
 
{
2428
 
        char *id;
2429
 
        char *dir;
2430
 
 
2431
 
        id = panel_profile_find_new_id (PANEL_GCONF_TOPLEVELS);
2432
 
 
2433
 
        dir = g_strdup_printf ("%s/toplevels/%s", profile_dir, id);
2434
 
        panel_gconf_associate_schemas_in_dir (client, dir, PANEL_SCHEMAS_DIR "/toplevels");
2435
 
        g_free (dir);
2436
 
 
2437
 
        return g_slist_prepend (NULL, id);
2438
 
}
2439
 
 
2440
 
static void
2441
 
panel_profile_load_defaults_on_screen (GConfClient *client,
2442
 
                                       const char  *profile_dir,
2443
 
                                       GdkScreen   *screen)
2444
 
{
2445
 
        GSList *new_toplevels, *l;
2446
 
        int     screen_n;
2447
 
 
2448
 
        screen_n = gdk_screen_get_number (screen);
2449
 
 
2450
 
        new_toplevels = panel_profile_copy_defaults_for_screen (
2451
 
                                client, profile_dir, screen_n, PANEL_GCONF_TOPLEVELS);
2452
 
        if (!new_toplevels) {
2453
 
                g_warning ("Failed to load default panel configuration. panel-default-setup.entries "
2454
 
                           "hasn't been installed using gconftool-2 --load ?\n");
2455
 
                new_toplevels = panel_profile_create_fallback_toplevel_list (client, profile_dir);
2456
 
        }
2457
 
 
2458
 
        for (l = new_toplevels; l; l = l->next) {
2459
 
                char       *toplevel_id = l->data;
2460
 
                const char *key;
2461
 
 
2462
 
                key = panel_gconf_full_key (PANEL_GCONF_TOPLEVELS,
2463
 
                                            toplevel_id,
2464
 
                                            "screen");
2465
 
                gconf_client_set_int (client, key, screen_n, NULL);
2466
 
        }
2467
 
 
2468
 
        panel_profile_append_new_ids (client, PANEL_GCONF_TOPLEVELS, new_toplevels);
2469
 
 
2470
 
        panel_profile_copy_default_objects_for_screen (
2471
 
                                client, profile_dir, screen_n, PANEL_GCONF_OBJECTS);
2472
 
        panel_profile_copy_default_objects_for_screen (
2473
 
                                client, profile_dir, screen_n, PANEL_GCONF_APPLETS);
2474
 
}
2475
 
 
2476
 
static void
2477
 
panel_profile_ensure_toplevel_per_screen (GConfClient *client,
2478
 
                                          const char  *profile_dir)
2479
 
{
2480
 
        GSList     *toplevels;
2481
 
        GSList     *empty_screens = NULL;
2482
 
        GSList     *l;
2483
 
        GdkDisplay *display;
2484
 
        int         n_screens, i;
2485
 
 
2486
 
        toplevels = panel_toplevel_list_toplevels ();
2487
 
 
2488
 
        display = gdk_display_get_default ();
2489
 
 
2490
 
        n_screens = gdk_display_get_n_screens (display);
2491
 
        for (i = 0; i < n_screens; i++) {
2492
 
                GdkScreen *screen;
2493
 
 
2494
 
                screen = gdk_display_get_screen (display, i);
2495
 
 
2496
 
                for (l = toplevels; l; l = l->next)
2497
 
                        if (gtk_window_get_screen (l->data) == screen)
2498
 
                                break;
2499
 
 
2500
 
                if (!l)
2501
 
                        empty_screens = g_slist_prepend (empty_screens, screen);
2502
 
        }
2503
 
 
2504
 
        for (l = empty_screens; l; l = l->next)
2505
 
                panel_profile_load_defaults_on_screen (client, profile_dir, l->data);
2506
 
 
2507
 
        g_slist_free (empty_screens);
2508
 
}
2509
 
 
2510
 
void
2511
 
panel_profile_load (void)
2512
 
{
2513
 
        GConfClient *client;
2514
 
 
2515
 
        client  = panel_gconf_get_client ();
2516
 
 
2517
 
        gconf_client_add_dir (client, PANEL_CONFIG_DIR "/general", GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
2518
 
 
2519
 
        panel_compatibility_maybe_copy_old_config (client);
2520
 
 
2521
 
        panel_compatibility_migrate_panel_id_list (client);
2522
 
 
2523
 
        panel_profile_load_list (client,
2524
 
                                 PANEL_CONFIG_DIR,
2525
 
                                 PANEL_GCONF_TOPLEVELS,
2526
 
                                 panel_profile_load_and_show_toplevel_startup,
2527
 
                                 (GConfClientNotifyFunc) panel_profile_toplevel_id_list_notify);
2528
 
        panel_profile_load_list (client,
2529
 
                                 PANEL_CONFIG_DIR,
2530
 
                                 PANEL_GCONF_OBJECTS,
2531
 
                                 panel_profile_load_object,
2532
 
                                 (GConfClientNotifyFunc) panel_profile_object_id_list_notify);
2533
 
        panel_profile_load_list (client,
2534
 
                                 PANEL_CONFIG_DIR,
2535
 
                                 PANEL_GCONF_APPLETS,
2536
 
                                 panel_profile_load_object,
2537
 
                                 (GConfClientNotifyFunc) panel_profile_object_id_list_notify);
2538
 
 
2539
 
        panel_profile_ensure_toplevel_per_screen (client, PANEL_CONFIG_DIR);
2540
 
 
2541
 
        panel_applet_load_queued_applets (TRUE);
2542
 
}
2543
 
 
2544
 
static gboolean
2545
 
get_program_listing_setting (const char *setting)
2546
 
{
2547
 
        GConfClient *client;
2548
 
        const char  *key;
2549
 
        gboolean     retval;
2550
 
 
2551
 
        client = panel_gconf_get_client ();
2552
 
 
2553
 
        key = panel_gconf_general_key (setting);
2554
 
        retval = gconf_client_get_bool (client, key, NULL);
2555
 
 
2556
 
        return retval;
2557
 
}
2558
 
 
2559
 
gboolean
2560
 
panel_profile_get_show_program_list (void)
2561
 
{
2562
 
        return get_program_listing_setting ("show_program_list");
2563
 
}
2564
 
 
2565
 
gboolean
2566
 
panel_profile_get_enable_program_list (void)
2567
 
{
2568
 
        return get_program_listing_setting ("enable_program_list");
2569
 
}
2570
 
 
2571
 
gboolean
2572
 
panel_profile_get_enable_autocompletion (void)
2573
 
{
2574
 
        return get_program_listing_setting ("enable_autocompletion");
2575
 
}
2576
 
 
2577
 
void
2578
 
panel_profile_set_show_program_list (gboolean show_program_list)
2579
 
{
2580
 
        GConfClient *client;
2581
 
        const char  *key;
2582
 
 
2583
 
        client = panel_gconf_get_client ();
2584
 
 
2585
 
        key = panel_gconf_general_key ("show_program_list");
2586
 
        gconf_client_set_bool (client, key, show_program_list, NULL);
2587
 
}
2588
 
 
2589
 
gboolean
2590
 
panel_profile_is_writable_show_program_list (void)
2591
 
{
2592
 
        GConfClient *client;
2593
 
        const char  *key;
2594
 
 
2595
 
        client = panel_gconf_get_client ();
2596
 
 
2597
 
        key = panel_gconf_general_key ("show_program_list");
2598
 
        return gconf_client_key_is_writable (client, key, NULL);
2599
 
}
2600
 
 
2601
 
gboolean
2602
 
panel_profile_can_be_moved_freely (PanelToplevel *toplevel)
2603
 
{
2604
 
        const char *key;
2605
 
        GConfClient *client;
2606
 
 
2607
 
        if (panel_lockdown_get_locked_down () ||
2608
 
            !panel_profile_is_writable_toplevel_orientation (toplevel))
2609
 
                return FALSE;
2610
 
 
2611
 
        client = panel_gconf_get_client ();
2612
 
 
2613
 
        key = panel_profile_get_toplevel_key (toplevel, "screen");
2614
 
        if (!gconf_client_key_is_writable (client, key, NULL))
2615
 
                return FALSE;
2616
 
 
2617
 
        key = panel_profile_get_toplevel_key (toplevel, "monitor");
2618
 
        if (!gconf_client_key_is_writable (client, key, NULL))
2619
 
                return FALSE;
2620
 
 
2621
 
        /* For expanded panels we don't really have to check 
2622
 
           x and y */
2623
 
        if (panel_toplevel_get_expand (toplevel))
2624
 
                return TRUE;
2625
 
 
2626
 
        key = panel_profile_get_toplevel_key (toplevel, "x");
2627
 
        if (!gconf_client_key_is_writable (client, key, NULL))
2628
 
                return FALSE;
2629
 
        key = panel_profile_get_toplevel_key (toplevel, "x_right");
2630
 
        if (!gconf_client_key_is_writable (client, key, NULL))
2631
 
                return FALSE;
2632
 
        key = panel_profile_get_toplevel_key (toplevel, "x_centered");
2633
 
        if (!gconf_client_key_is_writable (client, key, NULL))
2634
 
                return FALSE;
2635
 
 
2636
 
        key = panel_profile_get_toplevel_key (toplevel, "y");
2637
 
        if (!gconf_client_key_is_writable (client, key, NULL))
2638
 
                return FALSE;
2639
 
        key = panel_profile_get_toplevel_key (toplevel, "y_bottom");
2640
 
        if (!gconf_client_key_is_writable (client, key, NULL))
2641
 
                return FALSE;
2642
 
        key = panel_profile_get_toplevel_key (toplevel, "y_centered");
2643
 
        if (!gconf_client_key_is_writable (client, key, NULL))
2644
 
                return FALSE;
2645
 
 
2646
 
        return TRUE;
2647
 
}