~ubuntu-branches/ubuntu/oneiric/cairo-dock-plug-ins/oneiric-updates

« back to all changes in this revision

Viewing changes to GMenu/src/applet-menu.c

  • Committer: Bazaar Package Importer
  • Author(s): Didier Roche
  • Date: 2009-08-26 21:07:39 UTC
  • Revision ID: james.westby@ubuntu.com-20090826210739-gyjuuqezrzuluao4
Tags: upstream-2.0.8.1
ImportĀ upstreamĀ versionĀ 2.0.8.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
* This file is a part of the Cairo-Dock project
 
3
*
 
4
* Copyright : (C) see the 'copyright' file.
 
5
* E-mail    : see the 'copyright' file.
 
6
*
 
7
* This program is free software; you can redistribute it and/or
 
8
* modify it under the terms of the GNU General Public License
 
9
* as published by the Free Software Foundation; either version 3
 
10
* of the License, or (at your option) any later version.
 
11
*
 
12
* This program is distributed in the hope that it will be useful,
 
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
* GNU General Public License for more details.
 
16
* You should have received a copy of the GNU General Public License
 
17
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
18
*/
 
19
 
 
20
/******************************************************************************
 
21
 
 
22
This file is a part of the cairo-dock program, 
 
23
released under the terms of the GNU General Public License.
 
24
 
 
25
Adapted from the Gnome-panel for Cairo-Dock by Fabrice Rey (for any bug report, please mail me to fabounet@users.berlios.de)
 
26
 
 
27
******************************************************************************/
 
28
 
 
29
#include <string.h>
 
30
#include <cairo-dock.h>
 
31
 
 
32
#include "applet-struct.h"
 
33
#include "applet-menu-callbacks.h"
 
34
#include "applet-util.h"
 
35
#include "applet-menu.h"
 
36
 
 
37
static GSList *image_menu_items = NULL;
 
38
static GHashTable *loaded_icons = NULL;
 
39
 
 
40
 
 
41
GtkWidget * add_menu_separator (GtkWidget *menu)
 
42
{
 
43
        GtkWidget *menuitem;
 
44
        
 
45
        menuitem = gtk_separator_menu_item_new ();
 
46
        gtk_widget_set_sensitive (menuitem, FALSE);
 
47
        gtk_widget_show (menuitem);
 
48
        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
 
49
 
 
50
        return menuitem;
 
51
}
 
52
 
 
53
GtkWidget * create_fake_menu (GMenuTreeDirectory *directory)
 
54
{       
 
55
        GtkWidget *menu;
 
56
        guint      idle_id;
 
57
        
 
58
        menu = create_empty_menu ();
 
59
 
 
60
        g_object_set_data_full (G_OBJECT (menu),
 
61
                                "panel-menu-tree-directory",
 
62
                                gmenu_tree_item_ref (directory),
 
63
                                (GDestroyNotify) gmenu_tree_item_unref);
 
64
        
 
65
        g_object_set_data (G_OBJECT (menu),
 
66
                           "panel-menu-needs-loading",
 
67
                           GUINT_TO_POINTER (TRUE));
 
68
 
 
69
        g_signal_connect (menu, "show",
 
70
                          G_CALLBACK (submenu_to_display), NULL);
 
71
 
 
72
        idle_id = g_idle_add_full (G_PRIORITY_LOW,
 
73
                                   submenu_to_display_in_idle,
 
74
                                   menu,
 
75
                                   NULL);
 
76
        if (myData.iSidFakeMenuIdle != 0)
 
77
                g_source_remove (myData.iSidFakeMenuIdle);
 
78
        myData.iSidFakeMenuIdle = idle_id;
 
79
        g_object_set_data_full (G_OBJECT (menu),
 
80
                                "panel-menu-idle-id",
 
81
                                GUINT_TO_POINTER (idle_id),
 
82
                                remove_submenu_to_display_idle);
 
83
 
 
84
        g_signal_connect (menu, "button_press_event",
 
85
                          G_CALLBACK (menu_dummy_button_press_event), NULL);
 
86
 
 
87
        return menu;
 
88
}
 
89
 
 
90
void image_menu_destroy (GtkWidget *image, gpointer data)
 
91
{
 
92
        image_menu_items = g_slist_remove (image_menu_items, image);
 
93
}
 
94
 
 
95
 
 
96
static void reload_image_menu_items (void)
 
97
{
 
98
        GSList *l;
 
99
 
 
100
        for (l = image_menu_items; l; l = l->next) {
 
101
                GtkWidget *image = l->data;
 
102
                gboolean   is_mapped;
 
103
      
 
104
                is_mapped = GTK_WIDGET_MAPPED (image);
 
105
 
 
106
                if (is_mapped)
 
107
                        gtk_widget_unmap (image);
 
108
 
 
109
                gtk_image_set_from_pixbuf (GTK_IMAGE (image), NULL);
 
110
    
 
111
                if (is_mapped)
 
112
                        gtk_widget_map (image);
 
113
 
 
114
        }
 
115
}
 
116
 
 
117
static void
 
118
remove_pixmap_from_loaded (gpointer data, GObject *where_the_object_was)
 
119
{
 
120
        char *key = data;
 
121
 
 
122
        if (loaded_icons != NULL)
 
123
                g_hash_table_remove (loaded_icons, key);
 
124
 
 
125
        g_free (key);
 
126
}
 
127
GdkPixbuf * panel_make_menu_icon (GtkIconTheme *icon_theme,
 
128
                      const char   *icon,
 
129
                      const char   *fallback,
 
130
                      int           size,
 
131
                      gboolean     *long_operation)
 
132
{
 
133
        GdkPixbuf *pb;
 
134
        char *file, *key;
 
135
        gboolean loaded;
 
136
 
 
137
        g_return_val_if_fail (size > 0, NULL);
 
138
 
 
139
        file = NULL;
 
140
        if (icon != NULL)
 
141
                file = panel_find_icon (icon_theme, icon, size);
 
142
        if (file == NULL && fallback != NULL)
 
143
                file = panel_find_icon (icon_theme, fallback, size);
 
144
 
 
145
        if (file == NULL)
 
146
                return NULL;
 
147
 
 
148
        if (long_operation != NULL)
 
149
                *long_operation = TRUE;
 
150
 
 
151
        pb = NULL;
 
152
 
 
153
        loaded = FALSE;
 
154
 
 
155
        key = g_strdup_printf ("%d:%s", size, file);
 
156
 
 
157
        if (loaded_icons != NULL &&
 
158
            (pb = g_hash_table_lookup (loaded_icons, key)) != NULL) {
 
159
                if (pb != NULL)
 
160
                        g_object_ref (G_OBJECT (pb));
 
161
        }
 
162
 
 
163
        if (pb == NULL) {
 
164
                pb = gdk_pixbuf_new_from_file (file, NULL);
 
165
                if (pb) {
 
166
                        gint width, height;
 
167
 
 
168
                        width = gdk_pixbuf_get_width (pb);
 
169
                        height = gdk_pixbuf_get_height (pb);
 
170
                        
 
171
                        /* if we want 24 and we get 22, do nothing;
 
172
                         * else scale */
 
173
                        if (!(size - 2 <= width && width <= size &&
 
174
                              size - 2 <= height && height <= size)) {
 
175
                                GdkPixbuf *tmp;
 
176
 
 
177
                                tmp = gdk_pixbuf_scale_simple (pb, size, size,
 
178
                                                               GDK_INTERP_BILINEAR);
 
179
 
 
180
                                g_object_unref (pb);
 
181
                                pb = tmp;
 
182
                        }
 
183
                }
 
184
                                
 
185
                /* add icon to the hash table so we don't load it again */
 
186
                loaded = TRUE;
 
187
        }
 
188
 
 
189
        if (pb == NULL) {
 
190
                g_free (file);
 
191
                g_free (key);
 
192
                return NULL;
 
193
        }
 
194
 
 
195
        if (loaded &&
 
196
            (gdk_pixbuf_get_width (pb) != size &&
 
197
             gdk_pixbuf_get_height (pb) != size)) {
 
198
                GdkPixbuf *pb2;
 
199
                int        dest_width;
 
200
                int        dest_height;
 
201
                int        width;
 
202
                int        height;
 
203
 
 
204
                width  = gdk_pixbuf_get_width (pb);
 
205
                height = gdk_pixbuf_get_height (pb);
 
206
 
 
207
                if (height > width) {
 
208
                        dest_width  = (size * width) / height;
 
209
                        dest_height = size;
 
210
                } else {
 
211
                        dest_width  = size;
 
212
                        dest_height = (size * height) / width;
 
213
                }
 
214
 
 
215
                pb2 = gdk_pixbuf_scale_simple (pb, dest_width, dest_height,
 
216
                                               GDK_INTERP_BILINEAR);
 
217
                g_object_unref (G_OBJECT (pb));
 
218
                pb = pb2;
 
219
        }
 
220
 
 
221
        if (loaded) {
 
222
                if (loaded_icons == NULL)
 
223
                        loaded_icons = g_hash_table_new_full
 
224
                                (g_str_hash, g_str_equal,
 
225
                                 (GDestroyNotify) g_free,
 
226
                                 (GDestroyNotify) g_object_unref);
 
227
                g_hash_table_replace (loaded_icons,
 
228
                                      g_strdup (key),
 
229
                                      g_object_ref (G_OBJECT (pb)));
 
230
                g_object_weak_ref (G_OBJECT (pb),
 
231
                                   (GWeakNotify) remove_pixmap_from_loaded,
 
232
                                   g_strdup (key));
 
233
        } else {
 
234
                /* we didn't load from disk */
 
235
                if (long_operation != NULL)
 
236
                        *long_operation = FALSE;
 
237
        }
 
238
 
 
239
        g_free (file);
 
240
        g_free (key);
 
241
 
 
242
        return pb;
 
243
}
 
244
 
 
245
void panel_load_menu_image_deferred (GtkWidget   *image_menu_item,
 
246
                                GtkIconSize  icon_size,
 
247
                                const char  *stock_id,
 
248
                                GIcon       *gicon,
 
249
                                const char  *image_filename,
 
250
                                const char  *fallback_image_filename)
 
251
{
 
252
        IconToLoad *icon;
 
253
        GtkWidget *image;
 
254
        int        icon_height = PANEL_DEFAULT_MENU_ICON_SIZE;
 
255
 
 
256
        icon = g_new (IconToLoad, 1);
 
257
 
 
258
        gtk_icon_size_lookup (icon_size, NULL, &icon_height);
 
259
 
 
260
        image = gtk_image_new ();
 
261
        image->requisition.width  = icon_height;
 
262
        image->requisition.height = icon_height;
 
263
 
 
264
        /* this takes over the floating ref */
 
265
        icon->pixmap = g_object_ref (G_OBJECT (image));
 
266
        gtk_object_sink (GTK_OBJECT (image));
 
267
 
 
268
        icon->stock_id       = stock_id;
 
269
        if (gicon)
 
270
                icon->gicon  = g_object_ref (gicon);
 
271
        else
 
272
                icon->gicon  = NULL;
 
273
        icon->image          = g_strdup (image_filename);
 
274
        icon->fallback_image = g_strdup (fallback_image_filename);
 
275
        icon->icon_size      = icon_size;
 
276
 
 
277
        gtk_widget_show (image);
 
278
 
 
279
        g_object_set_data_full (G_OBJECT (image_menu_item),
 
280
                                "Panel:Image",
 
281
                                g_object_ref (image),
 
282
                                (GDestroyNotify) g_object_unref);
 
283
 
 
284
        if (myConfig.bHasIcons)
 
285
                gtk_image_menu_item_set_image (
 
286
                        GTK_IMAGE_MENU_ITEM (image_menu_item), image);
 
287
 
 
288
        g_signal_connect_data (image, "map",
 
289
                               G_CALLBACK (image_menu_shown), icon,
 
290
                               (GClosureNotify) icon_to_load_free, 0);
 
291
 
 
292
        g_signal_connect (image, "destroy",
 
293
                          G_CALLBACK (image_menu_destroy), NULL);
 
294
 
 
295
        image_menu_items = g_slist_prepend (image_menu_items, image);
 
296
}
 
297
GtkWidget * create_submenu_entry (GtkWidget          *menu,
 
298
                      GMenuTreeDirectory *directory)
 
299
{
 
300
        GtkWidget *menuitem;
 
301
 
 
302
        menuitem = gtk_image_menu_item_new ();
 
303
 
 
304
        panel_load_menu_image_deferred (menuitem,
 
305
                                        32, //panel_menu_icon_get_size (),
 
306
                                        NULL, NULL,
 
307
                                        gmenu_tree_directory_get_icon (directory),
 
308
                                        PANEL_ICON_FOLDER);
 
309
 
 
310
        setup_menuitem (menuitem,
 
311
                        32, //panel_menu_icon_get_size (),
 
312
                        NULL,
 
313
                        gmenu_tree_directory_get_name (directory));
 
314
 
 
315
        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
 
316
 
 
317
        gtk_widget_show (menuitem);
 
318
 
 
319
        return menuitem;
 
320
}
 
321
 
 
322
void create_submenu (GtkWidget          *menu,
 
323
                GMenuTreeDirectory *directory,
 
324
                GMenuTreeDirectory *alias_directory)
 
325
{
 
326
        GtkWidget *menuitem;
 
327
        GtkWidget *submenu;
 
328
 
 
329
        if (alias_directory)
 
330
                menuitem = create_submenu_entry (menu, alias_directory);
 
331
        else
 
332
                menuitem = create_submenu_entry (menu, directory);
 
333
        
 
334
        submenu = create_fake_menu (directory);
 
335
 
 
336
        gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
 
337
}
 
338
 
 
339
void create_header (GtkWidget       *menu,
 
340
               GMenuTreeHeader *header)
 
341
{
 
342
        GMenuTreeDirectory *directory;
 
343
        GtkWidget          *menuitem;
 
344
 
 
345
        directory = gmenu_tree_header_get_directory (header);
 
346
        menuitem = create_submenu_entry (menu, directory);
 
347
        gmenu_tree_item_unref (directory);
 
348
 
 
349
        g_object_set_data_full (G_OBJECT (menuitem),
 
350
                                "panel-gmenu-tree.header",
 
351
                                gmenu_tree_item_ref (header),
 
352
                                (GDestroyNotify) gmenu_tree_item_unref);
 
353
 
 
354
        g_signal_connect (menuitem, "activate",
 
355
                          G_CALLBACK (gtk_false), NULL);
 
356
}
 
357
 
 
358
void create_menuitem (GtkWidget          *menu,
 
359
                 GMenuTreeEntry     *entry,
 
360
                 GMenuTreeDirectory *alias_directory)
 
361
{
 
362
        GtkWidget  *menuitem;
 
363
        
 
364
        menuitem = gtk_image_menu_item_new ();
 
365
 
 
366
        g_object_set_data_full (G_OBJECT (menuitem),
 
367
                                "panel-menu-tree-entry",
 
368
                                gmenu_tree_item_ref (entry),
 
369
                                (GDestroyNotify) gmenu_tree_item_unref);
 
370
 
 
371
        if (alias_directory)
 
372
                //FIXME: we should probably use this data when we do dnd or
 
373
                //context menu for this menu item
 
374
                g_object_set_data_full (G_OBJECT (menuitem),
 
375
                                        "panel-menu-tree-alias-directory",
 
376
                                        gmenu_tree_item_ref (alias_directory),
 
377
                                        (GDestroyNotify) gmenu_tree_item_unref);
 
378
 
 
379
        panel_load_menu_image_deferred (menuitem,
 
380
                                        PANEL_DEFAULT_MENU_ICON_SIZE, //panel_menu_icon_get_size (),
 
381
                                        NULL, NULL,
 
382
                                        alias_directory ? gmenu_tree_directory_get_icon (alias_directory) :
 
383
                                                          gmenu_tree_entry_get_icon (entry),
 
384
                                        NULL);
 
385
 
 
386
        setup_menuitem (menuitem,
 
387
                        PANEL_DEFAULT_MENU_ICON_SIZE, //panel_menu_icon_get_size (),
 
388
                        NULL,
 
389
                        alias_directory ? gmenu_tree_directory_get_name (alias_directory) :
 
390
                                          gmenu_tree_entry_get_name (entry));
 
391
 
 
392
        if ((alias_directory &&
 
393
             gmenu_tree_directory_get_comment (alias_directory)) ||
 
394
            (!alias_directory &&
 
395
             gmenu_tree_entry_get_comment (entry)))
 
396
                panel_util_set_tooltip_text (menuitem,
 
397
                                             alias_directory ?
 
398
                                                gmenu_tree_directory_get_comment (alias_directory) :
 
399
                                                gmenu_tree_entry_get_comment (entry));
 
400
 
 
401
        /*g_signal_connect_after (menuitem, "button_press_event",
 
402
                                G_CALLBACK (menuitem_button_press_event), NULL);*/
 
403
 
 
404
        //if (!panel_lockdown_get_locked_down ()) {
 
405
        {
 
406
                static GtkTargetEntry menu_item_targets[] = {
 
407
                        { "text/uri-list", 0, 0 }
 
408
                };
 
409
 
 
410
                gtk_drag_source_set (menuitem,
 
411
                                     GDK_BUTTON1_MASK | GDK_BUTTON2_MASK,
 
412
                                     menu_item_targets, 1,
 
413
                                     GDK_ACTION_COPY);
 
414
 
 
415
                if (gmenu_tree_entry_get_icon (entry) != NULL) {
 
416
                        const char *icon;
 
417
                        char       *icon_no_ext;
 
418
 
 
419
                        icon = gmenu_tree_entry_get_icon (entry);
 
420
                        if (!g_path_is_absolute (icon)) {
 
421
                                icon_no_ext = panel_util_icon_remove_extension (icon);
 
422
                                gtk_drag_source_set_icon_name (menuitem,
 
423
                                                               icon_no_ext);
 
424
                                g_free (icon_no_ext);
 
425
                        }
 
426
                }
 
427
 
 
428
                g_signal_connect (G_OBJECT (menuitem), "drag_begin",
 
429
                                  G_CALLBACK (drag_begin_menu_cb), NULL);
 
430
                g_signal_connect (menuitem, "drag_data_get",
 
431
                                  G_CALLBACK (drag_data_get_menu_cb), entry);
 
432
                g_signal_connect (menuitem, "drag_end",
 
433
                                  G_CALLBACK (drag_end_menu_cb), NULL);
 
434
        }
 
435
 
 
436
        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
 
437
 
 
438
        g_signal_connect (menuitem, "activate",
 
439
                          G_CALLBACK (activate_app_def), entry);
 
440
 
 
441
        gtk_widget_show (menuitem);
 
442
}
 
443
 
 
444
void create_menuitem_from_alias (GtkWidget      *menu,
 
445
                            GMenuTreeAlias *alias)
 
446
{
 
447
        GMenuTreeItem *aliased_item;
 
448
 
 
449
        aliased_item = gmenu_tree_alias_get_item (alias);
 
450
 
 
451
        switch (gmenu_tree_item_get_type (aliased_item)) {
 
452
        case GMENU_TREE_ITEM_DIRECTORY:
 
453
                create_submenu (menu,
 
454
                                GMENU_TREE_DIRECTORY (aliased_item),
 
455
                                gmenu_tree_alias_get_directory (alias));
 
456
                break;
 
457
 
 
458
        case GMENU_TREE_ITEM_ENTRY:
 
459
                create_menuitem (menu,
 
460
                                 GMENU_TREE_ENTRY (aliased_item),
 
461
                                 gmenu_tree_alias_get_directory (alias));
 
462
                break;
 
463
 
 
464
        default:
 
465
                break;
 
466
        }
 
467
 
 
468
        gmenu_tree_item_unref (aliased_item);
 
469
}
 
470
 
 
471
 
 
472
static void
 
473
image_menuitem_size_request (GtkWidget      *menuitem,
 
474
                             GtkRequisition *requisition,
 
475
                             gpointer        data)
 
476
{
 
477
        GtkIconSize icon_size = (GtkIconSize) GPOINTER_TO_INT (data);
 
478
        int         icon_height;
 
479
        int         req_height;
 
480
 
 
481
        if (!gtk_icon_size_lookup (icon_size, NULL, &icon_height))
 
482
                return;
 
483
 
 
484
        /* If we don't have a pixmap for this menuitem
 
485
         * at least make sure its the same height as
 
486
         * the rest.
 
487
         * This is a bit ugly, since we should keep this in sync with what's in
 
488
         * gtk_menu_item_size_request()
 
489
         */
 
490
        req_height = icon_height;
 
491
        req_height += (GTK_CONTAINER (menuitem)->border_width +
 
492
                       menuitem->style->ythickness) * 2;
 
493
        requisition->height = MAX (requisition->height, req_height);
 
494
}
 
495
void setup_menuitem (GtkWidget   *menuitem,
 
496
                GtkIconSize  icon_size,
 
497
                GtkWidget   *image,
 
498
                const char  *title)
 
499
                               
 
500
{
 
501
        GtkWidget *label;
 
502
        char      *_title;
 
503
 
 
504
        /* this creates a label with an invisible mnemonic */
 
505
        label = g_object_new (GTK_TYPE_ACCEL_LABEL, NULL);
 
506
        _title = menu_escape_underscores_and_prepend (title);
 
507
        gtk_label_set_text_with_mnemonic (GTK_LABEL (label), _title);
 
508
        g_free (_title);
 
509
 
 
510
        gtk_label_set_pattern (GTK_LABEL (label), "");
 
511
 
 
512
        gtk_accel_label_set_accel_widget (GTK_ACCEL_LABEL (label), menuitem);
 
513
 
 
514
        gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
 
515
        gtk_widget_show (label);
 
516
 
 
517
        gtk_container_add (GTK_CONTAINER (menuitem), label);
 
518
 
 
519
        if (image) {
 
520
                g_object_set_data_full (G_OBJECT (menuitem),
 
521
                                        "Panel:Image",
 
522
                                        g_object_ref (image),
 
523
                                        (GDestroyNotify) g_object_unref);
 
524
                gtk_widget_show (image);
 
525
                if (myConfig.bHasIcons)
 
526
                        gtk_image_menu_item_set_image (
 
527
                                GTK_IMAGE_MENU_ITEM (menuitem), image);
 
528
        } else if (icon_size != GTK_ICON_SIZE_INVALID)
 
529
                g_signal_connect (menuitem, "size_request",
 
530
                                  G_CALLBACK (image_menuitem_size_request),
 
531
                                  GINT_TO_POINTER (icon_size));
 
532
 
 
533
        gtk_widget_show (menuitem);
 
534
}
 
535
 
 
536
GtkWidget * populate_menu_from_directory (GtkWidget          *menu,
 
537
                              GMenuTreeDirectory *directory)
 
538
{       
 
539
        GSList   *l;
 
540
        GSList   *items;
 
541
        gboolean  add_separator;
 
542
 
 
543
        add_separator = (GTK_MENU_SHELL (menu)->children != NULL);
 
544
 
 
545
        items = gmenu_tree_directory_get_contents (directory);
 
546
 
 
547
        for (l = items; l; l = l->next) {
 
548
                GMenuTreeItem *item = l->data;
 
549
 
 
550
                if (add_separator ||
 
551
                    gmenu_tree_item_get_type (item) == GMENU_TREE_ITEM_SEPARATOR) {
 
552
                        add_menu_separator (menu);
 
553
                        add_separator = FALSE;
 
554
                }
 
555
 
 
556
                switch (gmenu_tree_item_get_type (item)) {
 
557
                case GMENU_TREE_ITEM_DIRECTORY:
 
558
                        create_submenu (menu, GMENU_TREE_DIRECTORY (item), NULL);
 
559
                        break;
 
560
 
 
561
                case GMENU_TREE_ITEM_ENTRY:
 
562
                        create_menuitem (menu, GMENU_TREE_ENTRY (item), NULL);
 
563
                        break;
 
564
 
 
565
                case GMENU_TREE_ITEM_SEPARATOR :
 
566
                        /* already added */
 
567
                        break;
 
568
 
 
569
                case GMENU_TREE_ITEM_ALIAS:
 
570
                        create_menuitem_from_alias (menu, GMENU_TREE_ALIAS (item));
 
571
                        break;
 
572
 
 
573
                case GMENU_TREE_ITEM_HEADER:
 
574
                        create_header (menu, GMENU_TREE_HEADER (item));
 
575
                        break;
 
576
 
 
577
                default:
 
578
                        break;
 
579
                }
 
580
 
 
581
                gmenu_tree_item_unref (item);
 
582
        }
 
583
 
 
584
        g_slist_free (items);
 
585
 
 
586
        return menu;
 
587
}
 
588
 
 
589
 
 
590
 
 
591
void icon_theme_changed (GtkIconTheme *icon_theme,
 
592
                    gpointer      data)
 
593
{
 
594
        reload_image_menu_items ();
 
595
}
 
596
 
 
597
GtkWidget * panel_create_menu (void)
 
598
{
 
599
        GtkWidget       *retval;
 
600
        static gboolean  registered_icon_theme_changer = FALSE;
 
601
 
 
602
        if (!registered_icon_theme_changer) {
 
603
                registered_icon_theme_changer = TRUE;
 
604
 
 
605
                g_signal_connect (gtk_icon_theme_get_default (), "changed",
 
606
                                  G_CALLBACK (icon_theme_changed), NULL);
 
607
        }
 
608
        
 
609
        retval = gtk_menu_new ();
 
610
        
 
611
        /*panel_gconf_notify_add_while_alive ("/desktop/gnome/interface/menus_have_icons",
 
612
                                            (GConfClientNotifyFunc) menus_have_icons_changed,
 
613
                                            G_OBJECT (retval));*/
 
614
 
 
615
        /*g_signal_connect (retval, "key_press_event",
 
616
                          G_CALLBACK (panel_menu_key_press_handler),
 
617
                          NULL);*/
 
618
 
 
619
        return retval;
 
620
}
 
621
GtkWidget * create_empty_menu (void)
 
622
{
 
623
        GtkWidget *retval;
 
624
 
 
625
        retval = panel_create_menu ();
 
626
 
 
627
        //g_signal_connect (retval, "show", G_CALLBACK (setup_menu_panel), NULL);
 
628
 
 
629
        /* intercept all right button clicks makes sure they don't
 
630
           go to the object itself */
 
631
        g_signal_connect (retval, "button_press_event",
 
632
                          G_CALLBACK (menu_dummy_button_press_event), NULL);
 
633
 
 
634
        return retval;
 
635
}
 
636
 
 
637
static void _on_remove_tree (GMenuTree  *tree)
 
638
{
 
639
        cd_message ("%s (%x)", __func__, tree);
 
640
        //gmenu_tree_unref (tree);
 
641
}
 
642
 
 
643
GtkWidget * create_applications_menu (const char *menu_file,
 
644
                          const char *menu_path, GtkWidget *parent_menu)
 
645
{
 
646
        GMenuTree *tree;
 
647
        GtkWidget *menu;
 
648
        guint      idle_id;
 
649
 
 
650
        menu = (parent_menu ? parent_menu : create_empty_menu ());
 
651
        
 
652
        cd_message ("%s (%s)", __func__, menu_file);
 
653
        tree = gmenu_tree_lookup (menu_file, GMENU_TREE_FLAGS_NONE);
 
654
        cd_debug (" tree : %x", tree);
 
655
 
 
656
        g_object_set_data_full (G_OBJECT (menu),
 
657
                                "panel-menu-tree",
 
658
                                gmenu_tree_ref (tree),
 
659
                                (GDestroyNotify) _on_remove_tree);
 
660
 
 
661
        g_object_set_data_full (G_OBJECT (menu),
 
662
                                "panel-menu-tree-path",
 
663
                                g_strdup (menu_path ? menu_path : "/"),
 
664
                                (GDestroyNotify) g_free);
 
665
        
 
666
        g_object_set_data (G_OBJECT (menu),
 
667
                           "panel-menu-needs-loading",
 
668
                           GUINT_TO_POINTER (TRUE));
 
669
 
 
670
        g_signal_connect (menu, "show",
 
671
                          G_CALLBACK (submenu_to_display), NULL);
 
672
 
 
673
        idle_id = g_idle_add_full (G_PRIORITY_LOW,
 
674
                                   submenu_to_display_in_idle,
 
675
                                   menu,
 
676
                                   NULL);
 
677
        if (myData.iSidCreateMenuIdle != 0)
 
678
                g_source_remove (myData.iSidCreateMenuIdle);
 
679
        myData.iSidCreateMenuIdle = idle_id;
 
680
        g_object_set_data_full (G_OBJECT (menu),
 
681
                                "panel-menu-idle-id",
 
682
                                GUINT_TO_POINTER (idle_id),
 
683
                                remove_submenu_to_display_idle);
 
684
 
 
685
        g_signal_connect (menu, "button_press_event",
 
686
                          G_CALLBACK (menu_dummy_button_press_event), NULL);
 
687
 
 
688
        gmenu_tree_add_monitor (tree,
 
689
                               (GMenuTreeChangedFunc) handle_gmenu_tree_changed,
 
690
                               menu);
 
691
        g_signal_connect (menu, "destroy",
 
692
                          G_CALLBACK (remove_gmenu_tree_monitor), tree);
 
693
 
 
694
        gmenu_tree_unref (tree);
 
695
 
 
696
        return menu;
 
697
}
 
698
 
 
699
GtkWidget * create_main_menu (CairoDockModuleInstance *myApplet)
 
700
{
 
701
        GtkWidget *main_menu;
 
702
 
 
703
        main_menu = create_applications_menu ("applications.menu", NULL, NULL);
 
704
        g_signal_connect (G_OBJECT (main_menu),
 
705
                "deactivate",
 
706
                G_CALLBACK (cairo_dock_delete_menu),
 
707
                myContainer);
 
708
 
 
709
        g_object_set_data (G_OBJECT (main_menu),
 
710
                "panel-menu-append-callback",
 
711
                main_menu_append);
 
712
        g_object_set_data (G_OBJECT (main_menu),
 
713
                "panel-menu-append-callback-data",
 
714
                myApplet);
 
715
        
 
716
        myData.bIconsLoaded = myConfig.bHasIcons;
 
717
        
 
718
        return main_menu;
 
719
}