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

« back to all changes in this revision

Viewing changes to gnome-panel/drawer.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2011-05-30 11:04:49 UTC
  • mfrom: (1.3.4 upstream)
  • mto: This revision was merged to the branch mainline in revision 204.
  • Revision ID: james.westby@ubuntu.com-20110530110449-ut1tc5t61rpvf9e3
Tags: upstream-3.0.2
ImportĀ upstreamĀ versionĀ 3.0.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * GNOME panel drawer module.
3
 
 * (C) 1997 The Free Software Foundation
4
 
 *
5
 
 * Authors: Miguel de Icaza
6
 
 *          Federico Mena
7
 
 *          George Lebl
8
 
 */
9
 
 
10
 
#include <config.h>
11
 
#include <stdio.h>
12
 
#include <sys/types.h>
13
 
#include <sys/stat.h>
14
 
#include <unistd.h>
15
 
#include <dirent.h>
16
 
#include <string.h>
17
 
 
18
 
#include <glib/gi18n.h>
19
 
#include <gdk/gdkkeysyms.h>
20
 
 
21
 
#include "drawer.h"
22
 
 
23
 
#include "applet.h"
24
 
#include "button-widget.h"
25
 
#include "panel-config-global.h"
26
 
#include "panel-gconf.h"
27
 
#include "panel-profile.h"
28
 
#include "panel-util.h"
29
 
#include "xstuff.h"
30
 
#include "panel-globals.h"
31
 
#include "panel-lockdown.h"
32
 
#include "panel-icon-names.h"
33
 
 
34
 
static void
35
 
drawer_click (GtkWidget *w, Drawer *drawer)
36
 
{
37
 
        if (!panel_toplevel_get_is_hidden (drawer->toplevel))
38
 
                panel_toplevel_hide (drawer->toplevel, FALSE, -1);
39
 
        else 
40
 
                panel_toplevel_unhide (drawer->toplevel);
41
 
}
42
 
 
43
 
static void
44
 
toplevel_destroyed (GtkWidget *widget,
45
 
                    Drawer    *drawer)
46
 
{
47
 
        drawer->toplevel = NULL;
48
 
        gtk_widget_destroy (drawer->button);
49
 
}
50
 
 
51
 
static void
52
 
destroy_drawer (GtkWidget *widget,
53
 
                Drawer    *drawer)
54
 
{
55
 
        GConfClient *client;
56
 
        int          i;
57
 
 
58
 
        client = panel_gconf_get_client ();
59
 
 
60
 
        for (i = 0; i < PANEL_DRAWER_N_LISTENERS; i++) {
61
 
                if (drawer->listeners [i])
62
 
                        gconf_client_notify_remove (client, drawer->listeners [i]);
63
 
                drawer->listeners [i] = 0;
64
 
        }
65
 
 
66
 
        if (drawer->toplevel)
67
 
                gtk_widget_destroy (GTK_WIDGET (drawer->toplevel));
68
 
        drawer->toplevel = NULL;
69
 
 
70
 
        if (drawer->close_timeout_id)
71
 
                g_source_remove (drawer->close_timeout_id);
72
 
        drawer->close_timeout_id = 0;
73
 
}
74
 
 
75
 
static void
76
 
drawer_focus_panel_widget (Drawer           *drawer,
77
 
                           GtkDirectionType  direction)
78
 
{
79
 
        PanelWidget *panel_widget;
80
 
 
81
 
        panel_widget = panel_toplevel_get_panel_widget (drawer->toplevel);
82
 
 
83
 
        gtk_window_present (GTK_WINDOW (drawer->toplevel));
84
 
        gtk_container_set_focus_child (GTK_CONTAINER (panel_widget), NULL);
85
 
        gtk_widget_child_focus (GTK_WIDGET (panel_widget), direction);
86
 
}
87
 
 
88
 
static gboolean
89
 
key_press_drawer (GtkWidget   *widget,
90
 
                  GdkEventKey *event,
91
 
                  Drawer      *drawer)
92
 
{
93
 
        gboolean retval = TRUE;
94
 
        GtkOrientation orient;
95
 
 
96
 
        if (event->state & gtk_accelerator_get_default_mod_mask ())
97
 
                return FALSE;
98
 
 
99
 
        orient = PANEL_WIDGET (gtk_widget_get_parent (drawer->button))->orient;
100
 
 
101
 
        switch (event->keyval) {
102
 
        case GDK_Up:
103
 
        case GDK_KP_Up:
104
 
                if (orient == GTK_ORIENTATION_HORIZONTAL) {
105
 
                        if (!panel_toplevel_get_is_hidden (drawer->toplevel))
106
 
                                drawer_focus_panel_widget (drawer, GTK_DIR_TAB_BACKWARD);
107
 
                } else {
108
 
                        /* let default focus movement happen */
109
 
                        retval = FALSE;
110
 
                }
111
 
                break;
112
 
        case GDK_Left:
113
 
        case GDK_KP_Left:
114
 
                if (orient == GTK_ORIENTATION_VERTICAL) {
115
 
                        if (!panel_toplevel_get_is_hidden (drawer->toplevel))
116
 
                                drawer_focus_panel_widget (drawer, GTK_DIR_TAB_BACKWARD);
117
 
                } else {
118
 
                        /* let default focus movement happen */
119
 
                        retval = FALSE;
120
 
                }
121
 
                break;
122
 
        case GDK_Down:
123
 
        case GDK_KP_Down:
124
 
                if (orient == GTK_ORIENTATION_HORIZONTAL) {
125
 
                        if (!panel_toplevel_get_is_hidden (drawer->toplevel))
126
 
                                drawer_focus_panel_widget (drawer, GTK_DIR_TAB_FORWARD);
127
 
                } else {
128
 
                        /* let default focus movement happen */
129
 
                        retval = FALSE;
130
 
                }
131
 
                break;
132
 
        case GDK_Right:
133
 
        case GDK_KP_Right:
134
 
                if (orient == GTK_ORIENTATION_VERTICAL) {
135
 
                        if (!panel_toplevel_get_is_hidden (drawer->toplevel))
136
 
                                drawer_focus_panel_widget (drawer, GTK_DIR_TAB_FORWARD);
137
 
                } else {
138
 
                        /* let default focus movement happen */
139
 
                        retval = FALSE;
140
 
                }
141
 
                break;
142
 
        case GDK_Escape:
143
 
                panel_toplevel_hide (drawer->toplevel, FALSE, -1);
144
 
                break;
145
 
        default:
146
 
                retval = FALSE;
147
 
                break;
148
 
        }
149
 
 
150
 
        return retval;
151
 
}
152
 
 
153
 
/*
154
 
 * This function implements Esc moving focus from the drawer to the drawer
155
 
 * icon and closing the drawer and Shift+Esc moving focus from the drawer
156
 
 * to the drawer icon without closing the drawer when focus is in the drawer.
157
 
 */
158
 
static gboolean
159
 
key_press_drawer_widget (GtkWidget   *widget,
160
 
                         GdkEventKey *event,
161
 
                         Drawer      *drawer)
162
 
{
163
 
        PanelWidget *panel_widget;
164
 
 
165
 
        if (event->keyval != GDK_Escape)
166
 
                return FALSE;
167
 
 
168
 
        panel_widget = panel_toplevel_get_panel_widget (drawer->toplevel);
169
 
 
170
 
        gtk_window_present (GTK_WINDOW (panel_widget->toplevel));
171
 
 
172
 
        if ((event->state & gtk_accelerator_get_default_mod_mask ()) == GDK_SHIFT_MASK ||
173
 
            panel_toplevel_get_is_hidden (drawer->toplevel))
174
 
                return TRUE;
175
 
 
176
 
        panel_toplevel_hide (drawer->toplevel, FALSE, -1);
177
 
 
178
 
        return TRUE;
179
 
}
180
 
 
181
 
static void 
182
 
drag_data_received_cb (GtkWidget          *widget,
183
 
                       GdkDragContext     *context,
184
 
                       gint                x,
185
 
                       gint                y,
186
 
                       GtkSelectionData   *selection_data,
187
 
                       guint               info,
188
 
                       guint               time_,
189
 
                       Drawer             *drawer)
190
 
{
191
 
        PanelWidget *panel_widget;
192
 
 
193
 
        if (!panel_check_dnd_target_data (widget, context, &info, NULL)) {
194
 
                gtk_drag_finish (context, FALSE, FALSE, time_);
195
 
                return;
196
 
        }
197
 
 
198
 
        panel_widget = panel_toplevel_get_panel_widget (drawer->toplevel);
199
 
 
200
 
        panel_receive_dnd_data (
201
 
                panel_widget, info, -1, selection_data, context, time_);
202
 
}
203
 
 
204
 
static gboolean
205
 
drag_motion_cb (GtkWidget          *widget,
206
 
                GdkDragContext     *context,
207
 
                int                 x,
208
 
                int                 y,
209
 
                guint               time_,
210
 
                Drawer             *drawer)
211
 
{
212
 
        PanelWidget *panel_widget;
213
 
        guint        info = 0;
214
 
 
215
 
        if (!panel_check_dnd_target_data (widget, context, &info, NULL))
216
 
                return FALSE;
217
 
 
218
 
        panel_widget = panel_toplevel_get_panel_widget (drawer->toplevel);
219
 
 
220
 
        if (!panel_check_drop_forbidden (panel_widget, context, info, time_))
221
 
                return FALSE;
222
 
 
223
 
        if (drawer->close_timeout_id)
224
 
                g_source_remove (drawer->close_timeout_id);
225
 
        drawer->close_timeout_id = 0;
226
 
 
227
 
        button_widget_set_dnd_highlight (BUTTON_WIDGET (widget), TRUE);
228
 
 
229
 
        if (panel_toplevel_get_is_hidden (drawer->toplevel)) {
230
 
                panel_toplevel_unhide (drawer->toplevel);
231
 
                drawer->opened_for_drag = TRUE;
232
 
        }
233
 
 
234
 
        return TRUE;
235
 
}
236
 
 
237
 
static gboolean
238
 
close_drawer_in_idle (gpointer data)
239
 
{
240
 
        Drawer *drawer = (Drawer *) data;
241
 
 
242
 
        drawer->close_timeout_id = 0;
243
 
 
244
 
        if (drawer->opened_for_drag) {
245
 
                panel_toplevel_hide (drawer->toplevel, FALSE, -1);
246
 
                drawer->opened_for_drag = FALSE;
247
 
        }
248
 
 
249
 
        return FALSE;
250
 
}
251
 
 
252
 
static void
253
 
queue_drawer_close_for_drag (Drawer *drawer)
254
 
{
255
 
        if (!drawer->close_timeout_id)
256
 
                drawer->close_timeout_id =
257
 
                        g_timeout_add_seconds (1, close_drawer_in_idle, drawer);
258
 
}
259
 
 
260
 
static void
261
 
drag_leave_cb (GtkWidget      *widget,
262
 
               GdkDragContext *context,
263
 
               guint           time_,
264
 
               Drawer         *drawer)
265
 
{
266
 
        queue_drawer_close_for_drag (drawer);
267
 
 
268
 
        button_widget_set_dnd_highlight (BUTTON_WIDGET (widget), FALSE);
269
 
}
270
 
 
271
 
static gboolean
272
 
drag_drop_cb (GtkWidget      *widget,
273
 
              GdkDragContext *context,
274
 
              int             x,
275
 
              int             y,
276
 
              guint           time_,
277
 
              Drawer         *drawer)
278
 
{
279
 
        GdkAtom atom = NULL;
280
 
 
281
 
        if (!panel_check_dnd_target_data (widget, context, NULL, &atom))
282
 
                return FALSE;
283
 
 
284
 
        gtk_drag_get_data (widget, context, atom, time_);
285
 
 
286
 
        return TRUE;
287
 
}
288
 
 
289
 
static void  
290
 
drag_data_get_cb (GtkWidget          *widget,
291
 
                  GdkDragContext     *context,
292
 
                  GtkSelectionData   *selection_data,
293
 
                  guint               info,
294
 
                  guint               time,
295
 
                  Drawer             *drawer)
296
 
{
297
 
        char *foo;
298
 
 
299
 
        foo = g_strdup_printf ("DRAWER:%d", panel_find_applet_index (widget));
300
 
 
301
 
        gtk_selection_data_set (selection_data,
302
 
                                gtk_selection_data_get_target (selection_data), 8, (guchar *)foo,
303
 
                                strlen (foo));
304
 
 
305
 
        g_free (foo);
306
 
}
307
 
 
308
 
static void
309
 
set_tooltip_and_name (Drawer     *drawer,
310
 
                      const char *tooltip)
311
 
{
312
 
        g_return_if_fail (drawer != NULL);
313
 
        g_return_if_fail (tooltip != NULL);
314
 
 
315
 
        if (tooltip && !tooltip [0])
316
 
                tooltip = NULL;
317
 
 
318
 
        panel_toplevel_set_name (drawer->toplevel, tooltip);
319
 
        panel_util_set_tooltip_text (drawer->button, tooltip);
320
 
}
321
 
 
322
 
static Drawer *
323
 
create_drawer_applet (PanelToplevel    *toplevel,
324
 
                      PanelToplevel    *parent_toplevel,
325
 
                      const char       *tooltip,
326
 
                      const char       *custom_icon,
327
 
                      gboolean          use_custom_icon,
328
 
                      PanelOrientation  orientation)
329
 
{
330
 
        Drawer *drawer;
331
 
        AtkObject *atk_obj;
332
 
        
333
 
        drawer = g_new0 (Drawer, 1);
334
 
 
335
 
        drawer->toplevel = toplevel;
336
 
 
337
 
        if (!use_custom_icon || !custom_icon || !custom_icon [0]) {
338
 
                drawer->button = button_widget_new (PANEL_ICON_DRAWER, TRUE,
339
 
                                                    orientation);
340
 
        } else {
341
 
                drawer->button = button_widget_new (custom_icon, TRUE,
342
 
                                                    orientation);
343
 
        }
344
 
 
345
 
        if (!drawer->button) {
346
 
                g_free (drawer);
347
 
                return NULL;
348
 
        }
349
 
        atk_obj = gtk_widget_get_accessible (drawer->button);
350
 
        atk_object_set_name (atk_obj, _("Drawer")); 
351
 
 
352
 
        set_tooltip_and_name (drawer, tooltip);
353
 
 
354
 
        gtk_drag_dest_set (drawer->button, 0, NULL, 0, 0); 
355
 
 
356
 
        g_signal_connect (drawer->button, "drag_data_get",
357
 
                          G_CALLBACK (drag_data_get_cb), drawer);
358
 
        g_signal_connect (drawer->button, "drag_data_received",
359
 
                          G_CALLBACK (drag_data_received_cb), drawer);
360
 
        g_signal_connect (drawer->button, "drag_motion",
361
 
                          G_CALLBACK (drag_motion_cb), drawer);
362
 
        g_signal_connect (drawer->button, "drag_leave",
363
 
                          G_CALLBACK (drag_leave_cb), drawer);
364
 
        g_signal_connect (drawer->button, "drag_drop",
365
 
                          G_CALLBACK (drag_drop_cb), drawer);
366
 
 
367
 
        g_signal_connect (drawer->button, "clicked",
368
 
                          G_CALLBACK (drawer_click), drawer);
369
 
        g_signal_connect (drawer->button, "destroy",
370
 
                          G_CALLBACK (destroy_drawer), drawer);
371
 
        g_signal_connect (drawer->button, "key_press_event",
372
 
                          G_CALLBACK (key_press_drawer), drawer);
373
 
        g_signal_connect (toplevel, "destroy",
374
 
                          G_CALLBACK (toplevel_destroyed), drawer);
375
 
 
376
 
        gtk_widget_show (drawer->button);
377
 
 
378
 
        g_signal_connect (drawer->toplevel, "key_press_event",
379
 
                          G_CALLBACK (key_press_drawer_widget), drawer);
380
 
 
381
 
        panel_toplevel_attach_to_widget (
382
 
                toplevel, parent_toplevel, GTK_WIDGET (drawer->button));
383
 
 
384
 
        return drawer;
385
 
}
386
 
 
387
 
static PanelToplevel *
388
 
create_drawer_toplevel (const char *drawer_id)
389
 
{
390
 
        PanelToplevel *toplevel;
391
 
        GConfClient   *client;
392
 
        const char    *key;
393
 
        char          *toplevel_id;
394
 
 
395
 
        client  = panel_gconf_get_client ();
396
 
 
397
 
        toplevel_id = panel_profile_find_new_id (PANEL_GCONF_TOPLEVELS);
398
 
        
399
 
        toplevel = panel_profile_load_toplevel (client, PANEL_CONFIG_DIR,
400
 
                                                PANEL_GCONF_TOPLEVELS, toplevel_id);
401
 
 
402
 
        if (!toplevel) {
403
 
                g_free (toplevel_id);
404
 
                return NULL;
405
 
        }
406
 
 
407
 
        key = panel_gconf_full_key (PANEL_GCONF_OBJECTS, drawer_id, "attached_toplevel_id");
408
 
        gconf_client_set_string (client, key, toplevel_id, NULL);
409
 
        g_free (toplevel_id);
410
 
 
411
 
        panel_profile_set_toplevel_enable_buttons (toplevel, TRUE);
412
 
        panel_profile_set_toplevel_enable_arrows (toplevel, TRUE);
413
 
 
414
 
        return toplevel;
415
 
}
416
 
 
417
 
static void
418
 
drawer_button_size_allocated (GtkWidget     *widget,
419
 
                              GtkAllocation *alloc,
420
 
                              Drawer        *drawer)
421
 
{
422
 
        if (!gtk_widget_get_realized (widget))
423
 
                return;
424
 
 
425
 
        gtk_widget_queue_resize (GTK_WIDGET (drawer->toplevel));
426
 
 
427
 
        g_object_set_data (G_OBJECT (widget), "allocated", GINT_TO_POINTER (TRUE));
428
 
}
429
 
 
430
 
static void
431
 
panel_drawer_use_custom_icon_changed (GConfClient *client,
432
 
                                      guint        cnxn_id,
433
 
                                      GConfEntry  *entry,
434
 
                                      Drawer      *drawer)
435
 
{
436
 
        gboolean  use_custom_icon;
437
 
        char     *custom_icon = NULL;
438
 
 
439
 
        if (!entry->value || entry->value->type != GCONF_VALUE_BOOL)
440
 
                return;
441
 
 
442
 
        use_custom_icon = gconf_value_get_bool (entry->value);
443
 
 
444
 
        if (use_custom_icon) {
445
 
                const char *key;
446
 
 
447
 
                key = panel_gconf_full_key (PANEL_GCONF_OBJECTS, drawer->info->id, "custom_icon");
448
 
                custom_icon = gconf_client_get_string (client, key, NULL);
449
 
        }
450
 
 
451
 
        button_widget_set_icon_name (BUTTON_WIDGET (drawer->button), custom_icon);
452
 
 
453
 
        g_free (custom_icon);
454
 
}
455
 
 
456
 
static void
457
 
panel_drawer_custom_icon_changed (GConfClient *client,
458
 
                                  guint        cnxn_id,
459
 
                                  GConfEntry  *entry,
460
 
                                  Drawer      *drawer)
461
 
{
462
 
        const char *custom_icon;
463
 
 
464
 
        if (!entry->value || entry->value->type != GCONF_VALUE_STRING)
465
 
                return;
466
 
 
467
 
        custom_icon = gconf_value_get_string (entry->value);
468
 
 
469
 
        if (custom_icon && custom_icon [0]) {
470
 
                const char *key;
471
 
                gboolean    use_custom_icon;
472
 
 
473
 
                key = panel_gconf_full_key (PANEL_GCONF_OBJECTS, drawer->info->id, "use_custom_icon");
474
 
                use_custom_icon = gconf_client_get_bool (client, key, NULL);
475
 
                if (use_custom_icon)
476
 
                        button_widget_set_icon_name (BUTTON_WIDGET (drawer->button), custom_icon);
477
 
        }
478
 
}
479
 
 
480
 
static void
481
 
panel_drawer_tooltip_changed (GConfClient *client,
482
 
                              guint        cnxn_id,
483
 
                              GConfEntry  *entry,
484
 
                              Drawer      *drawer)
485
 
{
486
 
        if (!entry->value || entry->value->type != GCONF_VALUE_STRING)
487
 
                return;
488
 
 
489
 
        set_tooltip_and_name (drawer,
490
 
                              gconf_value_get_string (entry->value));
491
 
}
492
 
 
493
 
static void
494
 
panel_drawer_connect_to_gconf (Drawer *drawer)
495
 
{
496
 
        GConfClient *client;
497
 
        const char  *key;
498
 
        int          i = 0;
499
 
 
500
 
        client  = panel_gconf_get_client ();
501
 
        
502
 
        key = panel_gconf_full_key (PANEL_GCONF_OBJECTS, drawer->info->id, "use_custom_icon");
503
 
        drawer->listeners [i++] =
504
 
                gconf_client_notify_add (client, key,
505
 
                                         (GConfClientNotifyFunc) panel_drawer_use_custom_icon_changed,
506
 
                                         drawer, NULL, NULL);
507
 
 
508
 
        key = panel_gconf_full_key (PANEL_GCONF_OBJECTS, drawer->info->id, "custom_icon");
509
 
        drawer->listeners [i++] =
510
 
                gconf_client_notify_add (client, key,
511
 
                                         (GConfClientNotifyFunc) panel_drawer_custom_icon_changed,
512
 
                                         drawer, NULL, NULL);
513
 
 
514
 
        key = panel_gconf_full_key (PANEL_GCONF_OBJECTS, drawer->info->id, "tooltip");
515
 
        drawer->listeners [i++] =
516
 
                gconf_client_notify_add (client, key,
517
 
                                         (GConfClientNotifyFunc) panel_drawer_tooltip_changed,
518
 
                                         drawer, NULL, NULL);
519
 
 
520
 
        g_assert (i == PANEL_DRAWER_N_LISTENERS);
521
 
}
522
 
 
523
 
static gboolean
524
 
drawer_changes_enabled (void)
525
 
{
526
 
  return !panel_lockdown_get_locked_down ();
527
 
}
528
 
 
529
 
static void
530
 
load_drawer_applet (char          *toplevel_id,
531
 
                    const char    *custom_icon,
532
 
                    gboolean       use_custom_icon,
533
 
                    const char    *tooltip,
534
 
                    PanelToplevel *parent_toplevel,
535
 
                    gboolean       locked,
536
 
                    int            pos,
537
 
                    gboolean       exactpos,
538
 
                    const char    *id)
539
 
{
540
 
        PanelOrientation  orientation;
541
 
        PanelToplevel    *toplevel = NULL;
542
 
        Drawer           *drawer = NULL;
543
 
        PanelWidget      *panel_widget;
544
 
 
545
 
        orientation = panel_toplevel_get_orientation (parent_toplevel);
546
 
 
547
 
        if (toplevel_id)
548
 
                toplevel = panel_profile_get_toplevel_by_id (toplevel_id);
549
 
 
550
 
        if (!toplevel)
551
 
                toplevel = create_drawer_toplevel (id);
552
 
 
553
 
        if (toplevel) {
554
 
                panel_toplevel_hide (toplevel, FALSE, -1);
555
 
                drawer = create_drawer_applet (toplevel,
556
 
                                               parent_toplevel,
557
 
                                               tooltip,
558
 
                                               custom_icon,
559
 
                                               use_custom_icon,
560
 
                                               orientation);
561
 
        }
562
 
 
563
 
        if (!drawer)
564
 
                return;
565
 
 
566
 
        panel_widget = panel_toplevel_get_panel_widget (parent_toplevel);
567
 
 
568
 
        drawer->info = panel_applet_register (drawer->button, drawer,
569
 
                                              (GDestroyNotify) g_free,
570
 
                                              panel_widget,
571
 
                                              locked, pos, exactpos,
572
 
                                              PANEL_OBJECT_DRAWER, id);
573
 
 
574
 
        if (!drawer->info) {
575
 
                gtk_widget_destroy (GTK_WIDGET (toplevel));
576
 
                return;
577
 
        }
578
 
 
579
 
        g_signal_connect_after (drawer->button, "size_allocate",
580
 
                                G_CALLBACK (drawer_button_size_allocated), drawer);
581
 
 
582
 
        panel_widget_add_forbidden (panel_toplevel_get_panel_widget (drawer->toplevel));
583
 
        panel_widget_set_applet_expandable (panel_widget, GTK_WIDGET (drawer->button), FALSE, TRUE);
584
 
        panel_widget_set_applet_size_constrained (panel_widget, GTK_WIDGET (drawer->button), TRUE);
585
 
 
586
 
        panel_applet_add_callback (drawer->info,
587
 
                                   "add",
588
 
                                   GTK_STOCK_ADD,
589
 
                                   _("_Add to Drawer..."),
590
 
                                   drawer_changes_enabled);
591
 
 
592
 
        panel_applet_add_callback (drawer->info,
593
 
                                   "properties",
594
 
                                   GTK_STOCK_PROPERTIES,
595
 
                                   _("_Properties"),
596
 
                                   drawer_changes_enabled);
597
 
 
598
 
        panel_applet_add_callback (drawer->info,
599
 
                                   "help",
600
 
                                   GTK_STOCK_HELP,
601
 
                                   _("_Help"),
602
 
                                   NULL);
603
 
 
604
 
        panel_drawer_connect_to_gconf (drawer);
605
 
}
606
 
 
607
 
static void
608
 
panel_drawer_prepare (const char  *drawer_id,
609
 
                      const char  *custom_icon,
610
 
                      gboolean     use_custom_icon,
611
 
                      const char  *tooltip,
612
 
                      char       **attached_toplevel_id)
613
 
{
614
 
        GConfClient *client;
615
 
        const char  *key;
616
 
 
617
 
        client  = panel_gconf_get_client ();
618
 
 
619
 
        if (tooltip) {
620
 
                key = panel_gconf_full_key (PANEL_GCONF_OBJECTS, drawer_id, "tooltip");
621
 
                gconf_client_set_string (client, key, tooltip, NULL);
622
 
        }
623
 
 
624
 
        key = panel_gconf_full_key (PANEL_GCONF_OBJECTS, drawer_id, "use_custom_icon");
625
 
        gconf_client_set_bool (client, key, use_custom_icon, NULL);
626
 
 
627
 
        if (custom_icon) {
628
 
                key = panel_gconf_full_key (PANEL_GCONF_OBJECTS, drawer_id, "custom_icon");
629
 
                gconf_client_set_string (client, key, custom_icon, NULL);
630
 
        }
631
 
 
632
 
        if (attached_toplevel_id) {
633
 
                char *toplevel_id;
634
 
                char *toplevel_dir;
635
 
 
636
 
                toplevel_id = panel_profile_find_new_id (PANEL_GCONF_TOPLEVELS);
637
 
 
638
 
                toplevel_dir = g_strdup_printf (PANEL_CONFIG_DIR "/toplevels/%s",
639
 
                                                toplevel_id);
640
 
                panel_gconf_associate_schemas_in_dir (client, toplevel_dir, PANEL_SCHEMAS_DIR "/toplevels");
641
 
        
642
 
                key = panel_gconf_full_key (PANEL_GCONF_OBJECTS, drawer_id, "attached_toplevel_id");
643
 
                gconf_client_set_string (client, key, toplevel_id, NULL);
644
 
                
645
 
                key = panel_gconf_full_key (PANEL_GCONF_TOPLEVELS, toplevel_id, "enable_buttons");
646
 
                gconf_client_set_bool (client, key, TRUE, NULL);
647
 
 
648
 
                key = panel_gconf_full_key (PANEL_GCONF_TOPLEVELS, toplevel_id, "enable_arrows");
649
 
                gconf_client_set_bool (client, key, TRUE, NULL);
650
 
 
651
 
                *attached_toplevel_id = toplevel_id;
652
 
        }
653
 
}
654
 
 
655
 
void
656
 
panel_drawer_create (PanelToplevel *toplevel,
657
 
                     int            position,
658
 
                     const char    *custom_icon,
659
 
                     gboolean       use_custom_icon,
660
 
                     const char    *tooltip)
661
 
{
662
 
        char *id;
663
 
 
664
 
        id = panel_profile_prepare_object (PANEL_OBJECT_DRAWER, toplevel, position, FALSE);
665
 
 
666
 
        panel_drawer_prepare (id, custom_icon, use_custom_icon, tooltip, NULL);
667
 
 
668
 
        panel_profile_add_to_list (PANEL_GCONF_OBJECTS, id);
669
 
 
670
 
        g_free (id);
671
 
}
672
 
 
673
 
char *
674
 
panel_drawer_create_with_id (const char    *toplevel_id,
675
 
                             int            position,
676
 
                             const char    *custom_icon,
677
 
                             gboolean       use_custom_icon,
678
 
                             const char    *tooltip)
679
 
{
680
 
        char *id;
681
 
        char *attached_toplevel_id = NULL;
682
 
 
683
 
        id = panel_profile_prepare_object_with_id (PANEL_OBJECT_DRAWER, toplevel_id, position, FALSE);
684
 
 
685
 
        panel_drawer_prepare (id, custom_icon, use_custom_icon, tooltip, &attached_toplevel_id);
686
 
 
687
 
        panel_profile_add_to_list (PANEL_GCONF_OBJECTS, id);
688
 
 
689
 
        g_free (id);
690
 
 
691
 
        return attached_toplevel_id;
692
 
}
693
 
 
694
 
void
695
 
drawer_load_from_gconf (PanelWidget *panel_widget,
696
 
                        gboolean     locked,
697
 
                        gint         position,
698
 
                        const char  *id)
699
 
{
700
 
        GConfClient *client;
701
 
        const char  *key;
702
 
        gboolean     use_custom_icon;
703
 
        char        *toplevel_id;
704
 
        char        *custom_icon;
705
 
        char        *tooltip;
706
 
 
707
 
        g_return_if_fail (panel_widget != NULL);
708
 
        g_return_if_fail (id != NULL);
709
 
 
710
 
        client  = panel_gconf_get_client ();
711
 
 
712
 
        key = panel_gconf_full_key (PANEL_GCONF_OBJECTS, id, "attached_toplevel_id");
713
 
        toplevel_id = gconf_client_get_string (client, key, NULL);
714
 
 
715
 
        panel_profile_load_toplevel (client, PANEL_CONFIG_DIR, PANEL_GCONF_TOPLEVELS, toplevel_id);
716
 
 
717
 
        key = panel_gconf_full_key (PANEL_GCONF_OBJECTS, id, "use_custom_icon");
718
 
        use_custom_icon = gconf_client_get_bool (client, key, NULL);
719
 
        
720
 
        key = panel_gconf_full_key (PANEL_GCONF_OBJECTS, id, "custom_icon");
721
 
        custom_icon = gconf_client_get_string (client, key, NULL);
722
 
 
723
 
        key = panel_gconf_full_key (PANEL_GCONF_OBJECTS, id, "tooltip");
724
 
        tooltip = gconf_client_get_string (client, key, NULL);
725
 
 
726
 
        load_drawer_applet (toplevel_id,
727
 
                            custom_icon,
728
 
                            use_custom_icon,
729
 
                            tooltip,
730
 
                            panel_widget->toplevel,
731
 
                            locked,
732
 
                            position,
733
 
                            TRUE,
734
 
                            id);
735
 
 
736
 
        g_free (toplevel_id);
737
 
        g_free (custom_icon);
738
 
        g_free (tooltip);
739
 
}
740
 
 
741
 
void
742
 
panel_drawer_set_dnd_enabled (Drawer   *drawer,
743
 
                              gboolean  dnd_enabled)
744
 
{
745
 
        if (dnd_enabled) {
746
 
                static GtkTargetEntry dnd_targets[] = {
747
 
                        { "application/x-panel-applet-internal", 0, 0 }
748
 
                };
749
 
 
750
 
                gtk_widget_set_has_window (drawer->button, TRUE);
751
 
                gtk_drag_source_set (drawer->button,
752
 
                                     GDK_BUTTON1_MASK,
753
 
                                     dnd_targets, 1,
754
 
                                     GDK_ACTION_MOVE);
755
 
                //FIXME: we're forgetting the use_custom_icon case, here
756
 
                gtk_drag_source_set_icon_name (drawer->button,
757
 
                                               button_widget_get_icon_name (BUTTON_WIDGET (drawer->button)));
758
 
 
759
 
                gtk_widget_set_has_window (drawer->button, FALSE);
760
 
 
761
 
        } else
762
 
                gtk_drag_source_unset (drawer->button);
763
 
}
764
 
 
765
 
static void
766
 
drawer_deletion_response (GtkWidget     *dialog,
767
 
                        int            response,
768
 
                        Drawer         *drawer)
769
 
{
770
 
        if (response == GTK_RESPONSE_OK)
771
 
                panel_profile_delete_object (drawer->info);
772
 
 
773
 
        gtk_widget_destroy (dialog);
774
 
}
775
 
 
776
 
void 
777
 
drawer_query_deletion (Drawer *drawer)
778
 
{
779
 
        GtkWidget *dialog;
780
 
 
781
 
         if (drawer->toplevel) {
782
 
                PanelWidget *panel_widget;
783
 
 
784
 
                panel_widget = panel_toplevel_get_panel_widget (
785
 
                                                        drawer->toplevel);
786
 
 
787
 
                if (!panel_global_config_get_confirm_panel_remove () ||
788
 
                    !g_list_length (panel_widget->applet_list)) {
789
 
                        panel_profile_delete_object (drawer->info);
790
 
                        return;
791
 
                }
792
 
 
793
 
                dialog = panel_deletion_dialog (drawer->toplevel);
794
 
 
795
 
                g_signal_connect (dialog, "response",
796
 
                                  G_CALLBACK (drawer_deletion_response),
797
 
                                  drawer);
798
 
 
799
 
                g_signal_connect_object (drawer->toplevel, "destroy",
800
 
                                         G_CALLBACK (gtk_widget_destroy),
801
 
                                         dialog,
802
 
                                         G_CONNECT_SWAPPED);
803
 
 
804
 
                gtk_widget_show_all (dialog);
805
 
        }
806
 
}