~albyrock87/awn-extras/extras_with_pidgineer

« back to all changes in this revision

Viewing changes to applets/maintained/cairo-menu/gnome-menu-builder.c

  • Committer: Alberto
  • Date: 2010-08-25 00:14:54 UTC
  • Revision ID: albyrock87+dev@gmail.com-20100825001454-xk2e92svlntj77id
Disabled Middle-Click debug

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2007, 2008, 2009 Rodney Cryderman <rcryderman@gmail.com>
 
3
 *
 
4
 * This program is free software; you can redistribute it and/or modify
 
5
 * it under the terms of the GNU General Public License as published by
 
6
 * the Free Software Foundation; either version 2 of the License, or
 
7
 * (at your option) any later version.
 
8
 *
 
9
 * This program is distributed in the hope that it will be useful,
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
 * GNU General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU General Public License
 
15
 * along with this program; if not, write to the Free Software
 
16
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
 
17
 *
 
18
*/
 
19
 
 
20
#include "config.h"
 
21
 
 
22
#include "gnome-menu-builder.h"
 
23
 
 
24
#define GMENU_I_KNOW_THIS_IS_UNSTABLE
 
25
#include <gnome-menus/gmenu-tree.h>
 
26
#include <glib/gi18n.h>
 
27
#include <libdesktop-agnostic/fdo.h>
 
28
#include <gio/gio.h>
 
29
 
 
30
#include <libawn/libawn.h>
 
31
#include "cairo-menu.h"
 
32
#include "cairo-menu-item.h"
 
33
#include "misc.h"
 
34
#include "cairo-menu-applet.h"
 
35
 
 
36
GMenuTree *  main_menu_tree = NULL;
 
37
GMenuTree *  settings_menu_tree = NULL;    
 
38
 
 
39
GtkWidget *  menu_build (MenuInstance * instance);
 
40
static GtkWidget * submenu_build (MenuInstance * instance);
 
41
 
 
42
static GtkWidget *
 
43
get_image_from_gicon (GIcon * gicon)
 
44
{
 
45
  const gchar *const * icon_names =NULL;
 
46
  GtkWidget * image = NULL;
 
47
  if (G_IS_THEMED_ICON (gicon))
 
48
  {
 
49
    icon_names = g_themed_icon_get_names (G_THEMED_ICON(gicon));
 
50
  }
 
51
  if (icon_names)
 
52
  {
 
53
    const gchar *const *i;
 
54
    for (i=icon_names; *i; i++)
 
55
    {
 
56
      image = get_gtk_image (*i);
 
57
      if (image)
 
58
      {
 
59
        break;
 
60
      }
 
61
    }
 
62
  }
 
63
  return image;
 
64
}
 
65
 
 
66
static gboolean
 
67
add_special_item (GtkWidget * menu,
 
68
                  const gchar * name, 
 
69
                  const gchar * icon_name,
 
70
                  const gchar * binary,
 
71
                  const gchar * args)
 
72
{
 
73
  GtkWidget * item;
 
74
  gchar *exec;
 
75
  GtkWidget * image;
 
76
  gchar * bin_path;
 
77
 
 
78
  bin_path = g_find_program_in_path (binary);
 
79
  if (!bin_path)
 
80
  {
 
81
    return FALSE;
 
82
  }
 
83
  if (bin_path != binary)
 
84
  {
 
85
    g_free (bin_path);
 
86
  }
 
87
  item = cairo_menu_item_new_with_label (name);
 
88
  image = get_gtk_image (icon_name);  
 
89
  if (image)
 
90
  {
 
91
    gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item),image);
 
92
  }
 
93
  exec = g_strdup_printf("%s %s", binary ,args);
 
94
  g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(_exec), exec);
 
95
  g_object_weak_ref (G_OBJECT(item),(GWeakNotify) g_free,exec);
 
96
  gtk_menu_shell_append(GTK_MENU_SHELL(menu),item);
 
97
  return TRUE;
 
98
}
 
99
 
 
100
static gboolean
 
101
_fill_session_menu (GtkWidget * menu)
 
102
{
 
103
  gboolean have_gnome_session_manager = dbus_service_exists ("org.gnome.SessionManager");
 
104
 
 
105
  if (have_gnome_session_manager)
 
106
  {
 
107
    add_special_item (menu,_("Logout"),"gnome-logout","gnome-session-save","--logout-dialog --gui");
 
108
  }
 
109
  else if (dbus_service_exists ("org.xfce.SessionManager") )
 
110
  {
 
111
    add_special_item (menu,_("Logout"),"gnome-logout","xfce4-session-logout","");
 
112
  }
 
113
  else
 
114
  {
 
115
    /* hope that gnome-session-save exists; needed for GNOME 2.22, at least. */
 
116
    add_special_item (menu, _("Logout"), "gnome-logout", "gnome-session-save",
 
117
                      "--kill --gui");
 
118
  }
 
119
  if (dbus_service_exists ("org.gnome.ScreenSaver"))
 
120
  {
 
121
    if (!add_special_item (menu,_("Lock Screen"),"gnome-lockscreen","gnome-screensaver-command","--lock"))
 
122
    {
 
123
      add_special_item (menu,_("Lock Screen"),"gnome-lockscreen","dbus-send","--session --dest=org.gnome.ScreenSaver --type=method_call --print-reply --reply-timeout=2000 /org/gnome/ScreenSaver org.gnome.ScreenSaver.Lock");
 
124
    }
 
125
  }
 
126
  else
 
127
  {
 
128
    add_special_item (menu,_("Lock Screen"),"system-lock-screen","xscreensaver-command","-lock");
 
129
  }
 
130
  if (dbus_service_exists ("org.freedesktop.PowerManagement"))
 
131
  {
 
132
    if (!add_special_item (menu,_("Suspend"),"gnome-session-suspend","gnome-power-cmd","suspend"))
 
133
    {
 
134
      add_special_item (menu,_("Suspend"),"gnome-session-suspend","dbus-send","--session --dest=org.freedesktop.PowerManagement --type=method_call --print-reply --reply-timeout=2000 /org/freedesktop/PowerManagement org.freedesktop.PowerManagement.Suspend");
 
135
    }
 
136
    
 
137
    if (!add_special_item (menu,_("Hibernate"),"gnome-session-hibernate","gnome-power-cmd","hibernate"))
 
138
    {
 
139
      add_special_item (menu,_("Hibernate"),"gnome-session-hibernate","dbus-send","--session --dest=org.freedesktop.PowerManagement --type=method_call --print-reply --reply-timeout=2000 /org/freedesktop/PowerManagement org.freedesktop.PowerManagement.Hibernate");
 
140
    }
 
141
 
 
142
  }
 
143
  else if (dbus_service_exists ("org.gnome.PowerManagement"))
 
144
  {
 
145
    if (!add_special_item (menu,_("Suspend"),"gnome-session-suspend","gnome-power-cmd","suspend"))
 
146
    {
 
147
 
 
148
    }
 
149
      
 
150
    if (!add_special_item (menu,_("Hibernate"),"gnome-session-hibernate","gnome-power-cmd","hibernate"))
 
151
    {
 
152
 
 
153
    }
 
154
  }
 
155
  
 
156
  if (have_gnome_session_manager)
 
157
  {
 
158
    add_special_item (menu,_("Shutdown"),"gnome-logout","gnome-session-save","--shutdown-dialog --gui");  
 
159
  }
 
160
  gtk_widget_show_all (menu);
 
161
  return FALSE;
 
162
}
 
163
 
 
164
static GtkWidget *
 
165
get_session_menu(void)
 
166
{
 
167
  GtkWidget *menu = cairo_menu_new();
 
168
  /*so we don't stall checking the dbus services on applet startup*/
 
169
  g_idle_add ((GSourceFunc)_fill_session_menu,menu);
 
170
  return menu;
 
171
}
 
172
/*
 
173
 TODO:
 
174
  check for existence of the various bins.
 
175
  why are vfs network mounts not showing?
 
176
  The menu item order needs to be fixed.
 
177
 */
 
178
static GtkWidget * 
 
179
_get_places_menu (GtkWidget * menu)
 
180
{  
 
181
  static GVolumeMonitor* vol_monitor = NULL;
 
182
  static DesktopAgnosticVFSGtkBookmarks *bookmarks_parser = NULL;  
 
183
  
 
184
  GtkWidget *item = NULL;
 
185
  GError *error = NULL;
 
186
  GtkWidget * image;
 
187
  gchar * exec;
 
188
  const gchar *desktop_dir = g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP);
 
189
  const gchar *homedir = g_get_home_dir();
 
190
 
 
191
  gtk_container_foreach (GTK_CONTAINER (menu),(GtkCallback)_remove_menu_item,menu);
 
192
 
 
193
  add_special_item (menu,_("Computer"),"computer","nautilus","computer:///");
 
194
  add_special_item (menu,_("Home"),"stock_home",XDG_OPEN,homedir);
 
195
  add_special_item (menu,_("Desktop"),"desktop",XDG_OPEN,desktop_dir?desktop_dir:homedir);
 
196
/*
 
197
TODO: check the trash and set to stock_trash_empty if trash is empty
 
198
                     */
 
199
  add_special_item (menu,_("Trash"),"stock_trash_full","nautilus","trash:///");
 
200
  add_special_item (menu,_("File System"),"system",XDG_OPEN,"/");
 
201
    
 
202
  if (!vol_monitor)
 
203
  {
 
204
    /*this is structured like this because get_places() is
 
205
    invoked any time there is a change in places... only want perform
 
206
    these actions once.*/
 
207
    vol_monitor = g_volume_monitor_get();
 
208
    bookmarks_parser = desktop_agnostic_vfs_gtk_bookmarks_new (NULL, TRUE);
 
209
  }
 
210
  g_signal_handlers_disconnect_by_func (vol_monitor, G_CALLBACK(_get_places_menu), menu);
 
211
  g_signal_handlers_disconnect_by_func (vol_monitor, G_CALLBACK(_get_places_menu), menu);
 
212
  g_signal_handlers_disconnect_by_func (vol_monitor, G_CALLBACK(_get_places_menu), menu);
 
213
  g_signal_handlers_disconnect_by_func (vol_monitor, G_CALLBACK(_get_places_menu), menu);    
 
214
  g_signal_handlers_disconnect_by_func (vol_monitor, G_CALLBACK(_get_places_menu), menu);
 
215
  g_signal_handlers_disconnect_by_func (vol_monitor, G_CALLBACK(_get_places_menu), menu);
 
216
  g_signal_handlers_disconnect_by_func (vol_monitor, G_CALLBACK(_get_places_menu), menu);
 
217
  g_signal_handlers_disconnect_by_func (G_OBJECT (bookmarks_parser), G_CALLBACK (_get_places_menu), menu);
 
218
    
 
219
  g_signal_connect_swapped(vol_monitor, "volume-changed", G_CALLBACK(_get_places_menu), menu);
 
220
  g_signal_connect_swapped(vol_monitor, "drive-changed", G_CALLBACK(_get_places_menu), menu);
 
221
  g_signal_connect_swapped(vol_monitor, "drive-connected", G_CALLBACK(_get_places_menu), menu);
 
222
  g_signal_connect_swapped(vol_monitor, "drive-disconnected", G_CALLBACK(_get_places_menu), menu);    
 
223
  g_signal_connect_swapped(vol_monitor, "mount-changed", G_CALLBACK(_get_places_menu), menu);
 
224
  g_signal_connect_swapped(vol_monitor, "mount-added", G_CALLBACK(_get_places_menu), menu);
 
225
  g_signal_connect_swapped(vol_monitor, "mount-removed", G_CALLBACK(_get_places_menu), menu);
 
226
  g_signal_connect_swapped (G_OBJECT (bookmarks_parser), "changed",
 
227
                      G_CALLBACK (_get_places_menu), menu);
 
228
 
 
229
    /*process mount etc*/
 
230
  GList *drives = g_volume_monitor_get_connected_drives(vol_monitor);
 
231
  GList *mounts = g_volume_monitor_get_mounts (vol_monitor);
 
232
  GList * iter;
 
233
 
 
234
/*  if (volumes)
 
235
  {
 
236
    g_message("Number of volumes: %d", g_list_length(volumes));
 
237
    g_list_foreach(volumes, (GFunc)_fillin_connected, menu);
 
238
  }*/
 
239
/*
 
240
     this iterating through mounts then drives may change.
 
241
     May go to using mounts and volumes.
 
242
     */
 
243
  for (iter = mounts; iter ; iter = g_list_next (iter))
 
244
  {
 
245
    GMount *mount = iter->data;
 
246
    gchar * name = g_mount_get_name (mount);
 
247
    GIcon * gicon = g_mount_get_icon (mount);
 
248
    GFile * file = g_mount_get_root (mount);
 
249
    gchar * uri = g_file_get_uri (file);
 
250
    item = cairo_menu_item_new_with_label (name);    
 
251
    image = get_image_from_gicon (gicon);
 
252
    if (image)
 
253
    {
 
254
      gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item),image);
 
255
    }    
 
256
    gtk_menu_shell_append (GTK_MENU_SHELL(menu),item);
 
257
 
 
258
    exec = g_strdup_printf("%s %s", XDG_OPEN, uri);
 
259
    g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(_exec), exec);  
 
260
    g_object_weak_ref (G_OBJECT(item), (GWeakNotify)g_free,exec);
 
261
    
 
262
    g_free (name);
 
263
    g_free (uri);
 
264
    g_object_unref (file);
 
265
    g_object_unref (gicon);
 
266
  }
 
267
 
 
268
  if (drives)
 
269
  {
 
270
    item = gtk_separator_menu_item_new ();
 
271
    gtk_menu_shell_append(GTK_MENU_SHELL(menu),item);
 
272
  }
 
273
    
 
274
  for (iter = drives; iter ; iter = g_list_next (iter))
 
275
  {
 
276
    GDrive * drive = iter->data;
 
277
    if (g_drive_has_volumes (drive))
 
278
    {
 
279
      GList * drive_volumes = g_drive_get_volumes (drive);
 
280
      GList * vol_iter = NULL;
 
281
      for (vol_iter =drive_volumes;vol_iter;vol_iter=g_list_next(vol_iter))
 
282
      {
 
283
        GVolume * volume = vol_iter->data;
 
284
        GIcon * gicon = g_volume_get_icon (volume);
 
285
        gchar * name = g_volume_get_name (volume);
 
286
        
 
287
        item = cairo_menu_item_new_with_label (name);
 
288
        image = get_image_from_gicon (gicon);
 
289
        if (image)
 
290
        {
 
291
          gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item),image);
 
292
        }            
 
293
        gtk_menu_shell_append(GTK_MENU_SHELL(menu),item);
 
294
        g_free (name);
 
295
      }
 
296
      g_list_foreach (drive_volumes,(GFunc)g_object_unref,NULL);
 
297
      g_list_free (drive_volumes);
 
298
    }
 
299
    else
 
300
    {
 
301
      gboolean mounted = FALSE;
 
302
      gchar * name = g_drive_get_name (drive);
 
303
      GIcon * gicon = g_drive_get_icon (drive);
 
304
      
 
305
      item = cairo_menu_item_new_with_label (name);
 
306
      image = get_image_from_gicon (gicon);
 
307
      if (image)
 
308
      {
 
309
        gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item),image);
 
310
      }          
 
311
      gtk_menu_shell_append(GTK_MENU_SHELL(menu),item);
 
312
      g_free (name);      
 
313
    }
 
314
  }
 
315
    
 
316
  g_list_foreach (drives,(GFunc)g_object_unref,NULL);
 
317
  g_list_free (drives);
 
318
  g_list_foreach (mounts,(GFunc)g_object_unref,NULL);
 
319
  g_list_free (mounts);
 
320
 
 
321
  add_special_item (menu,_("Network"),"network","nautilus","network:/");
 
322
  add_special_item (menu,_("Connect to Server"),"stock_connect","nautilus-connect-server","");
 
323
  item = gtk_separator_menu_item_new ();
 
324
  gtk_menu_shell_append(GTK_MENU_SHELL(menu),item);
 
325
 
 
326
    
 
327
  /* bookmarks    */
 
328
  GSList *bookmarks;
 
329
  GSList *node;
 
330
 
 
331
  bookmarks = desktop_agnostic_vfs_gtk_bookmarks_get_bookmarks (bookmarks_parser);
 
332
  for (node = bookmarks; node != NULL; node = node->next)
 
333
  {
 
334
    DesktopAgnosticVFSBookmark *bookmark;
 
335
    DesktopAgnosticVFSFile *b_file;
 
336
    const gchar *b_alias;
 
337
    gchar *b_path;
 
338
    gchar *b_uri;
 
339
    gchar *shell_quoted = NULL;
 
340
    gchar *icon_name = NULL;
 
341
    
 
342
    bookmark = (DesktopAgnosticVFSBookmark*)node->data;
 
343
    b_file = desktop_agnostic_vfs_bookmark_get_file (bookmark);
 
344
    b_alias = desktop_agnostic_vfs_bookmark_get_alias (bookmark);
 
345
    b_path = desktop_agnostic_vfs_file_get_path (b_file);
 
346
    b_uri = desktop_agnostic_vfs_file_get_uri (b_file);
 
347
 
 
348
    if (b_path)
 
349
    {
 
350
      shell_quoted = g_shell_quote (b_path);
 
351
      exec = g_strdup_printf("%s %s", XDG_OPEN,shell_quoted);
 
352
      g_free (shell_quoted);
 
353
      if (b_alias)
 
354
      {
 
355
        item = cairo_menu_item_new_with_label (b_alias);
 
356
        icon_name = g_utf8_strdown (b_alias,-1);
 
357
      }
 
358
      else
 
359
      {
 
360
        gchar * base = g_path_get_basename (b_path);
 
361
        item = cairo_menu_item_new_with_label (base);        
 
362
        icon_name = g_utf8_strdown (base,-1);        
 
363
        g_free (base);
 
364
      }
 
365
      g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(_exec), exec);              
 
366
      gtk_menu_shell_append(GTK_MENU_SHELL(menu),item);
 
367
    }
 
368
    else if ( strncmp(b_uri, "http", 4)==0 )
 
369
    {
 
370
      shell_quoted = g_shell_quote (b_uri);
 
371
      exec = g_strdup_printf("%s %s",XDG_OPEN,shell_quoted);
 
372
      g_free (shell_quoted);
 
373
      if (b_alias)
 
374
      {
 
375
        item = cairo_menu_item_new_with_label (b_alias);
 
376
        icon_name = g_utf8_strdown (b_alias,-1);        
 
377
      }
 
378
      else
 
379
      {
 
380
        gchar * base = g_path_get_basename (b_uri);
 
381
        item = cairo_menu_item_new_with_label (b_uri);
 
382
        icon_name = g_utf8_strdown (base,-1);        
 
383
        g_free (base);
 
384
      }
 
385
      g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(_exec), exec);              
 
386
      gtk_menu_shell_append(GTK_MENU_SHELL(menu),item);
 
387
    }
 
388
    /*
 
389
     non-http(s) uris.  open with nautils.  obviously we should be smarter about
 
390
     this
 
391
     */
 
392
    else if (b_uri)
 
393
    {
 
394
      shell_quoted = g_shell_quote (b_uri);
 
395
      exec = g_strdup_printf("%s %s", "nautilus" ,shell_quoted);
 
396
      g_free (shell_quoted);
 
397
      if (b_alias)
 
398
      {
 
399
        item = cairo_menu_item_new_with_label (b_alias);
 
400
        icon_name = g_utf8_strdown (b_alias,-1);        
 
401
      }
 
402
      else
 
403
      {
 
404
        gchar * base = g_path_get_basename (b_uri);
 
405
        item = cairo_menu_item_new_with_label (base);
 
406
        icon_name = g_utf8_strdown (base,-1);        
 
407
        g_free (base);
 
408
      }
 
409
      g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(_exec), exec);      
 
410
      gtk_menu_shell_append(GTK_MENU_SHELL(menu),item);
 
411
    }
 
412
    else
 
413
    {
 
414
      g_object_ref_sink (item);
 
415
      item = NULL;
 
416
    }
 
417
 
 
418
    if (item)
 
419
    {
 
420
      if (icon_name)
 
421
      {
 
422
        gchar * folderfied_icon_name = g_strdup_printf("folder-%s",icon_name);
 
423
        g_free (icon_name);
 
424
        icon_name = folderfied_icon_name;
 
425
        image = get_gtk_image (icon_name);
 
426
        g_free (icon_name);
 
427
      }
 
428
      if (!image)
 
429
      {
 
430
        image = get_gtk_image ("stock_folder");
 
431
      }
 
432
      if (image)
 
433
      {
 
434
        gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item),image);
 
435
      }
 
436
    }
 
437
    g_free (b_path);
 
438
    g_free (b_uri);
 
439
  }
 
440
  gtk_widget_show_all (menu);
 
441
  return menu;
 
442
}
 
443
 
 
444
GtkWidget * 
 
445
get_places_menu (void)
 
446
{
 
447
  GtkWidget *menu = cairo_menu_new();
 
448
  _get_places_menu (menu);
 
449
  return menu;
 
450
}
 
451
 
 
452
static GtkWidget *
 
453
fill_er_up(MenuInstance * instance,GMenuTreeDirectory *directory, GtkWidget * menu)
 
454
{
 
455
  static gint sanity_depth_count = 0;
 
456
  GSList * items = gmenu_tree_directory_get_contents(directory);
 
457
  GSList * tmp = items;
 
458
  GtkWidget * menu_item = NULL;
 
459
  GtkWidget * sub_menu = NULL;
 
460
  const gchar * txt;
 
461
  gchar * desktop_file;
 
462
  DesktopAgnosticFDODesktopEntry *entry;
 
463
  GtkWidget * image;
 
464
  gboolean detached_sub = FALSE;
 
465
  gchar * uri;
 
466
 
 
467
  sanity_depth_count++;
 
468
  if (sanity_depth_count>6)
 
469
  {
 
470
    sanity_depth_count--;
 
471
    g_warning ("%s: Exceeded max menu depth of 6 at %s",__func__,gmenu_tree_directory_get_name((GMenuTreeDirectory*)directory));
 
472
    return cairo_menu_new ();
 
473
  }
 
474
  if (!menu)
 
475
  {
 
476
    menu = cairo_menu_new ();
 
477
  }
 
478
  
 
479
  while (tmp != NULL)
 
480
  {
 
481
    GMenuTreeItem *item = tmp->data;
 
482
 
 
483
    switch (gmenu_tree_item_get_type(item))
 
484
    {
 
485
 
 
486
      case GMENU_TREE_ITEM_ENTRY:
 
487
        entry = NULL;
 
488
        if (gmenu_tree_entry_get_is_excluded ((GMenuTreeEntry *) item))
 
489
        {
 
490
          break;
 
491
        }
 
492
        if (gmenu_tree_entry_get_is_nodisplay ((GMenuTreeEntry *) item))
 
493
        {
 
494
          break;
 
495
        }
 
496
        txt = gmenu_tree_entry_get_name( (GMenuTreeEntry*)item);
 
497
        desktop_file = g_strdup (gmenu_tree_entry_get_desktop_file_path ((GMenuTreeEntry*)item));
 
498
        uri = g_strdup_printf("file://%s\n",desktop_file);
 
499
        if (desktop_file)
 
500
        {
 
501
          entry = get_desktop_entry (desktop_file);
 
502
        }
 
503
        if (entry)
 
504
        {
 
505
          gchar * icon_name;
 
506
          if (desktop_agnostic_fdo_desktop_entry_key_exists (entry,"Icon"))
 
507
          {
 
508
            icon_name = g_strdup(desktop_agnostic_fdo_desktop_entry_get_icon (entry));
 
509
          }
 
510
          else
 
511
          {
 
512
            icon_name = g_strdup ("stock_missing-image");
 
513
          }
 
514
          image = get_gtk_image (icon_name);
 
515
          menu_item = cairo_menu_item_new_with_label (txt?txt:"unknown");
 
516
          if (image)
 
517
          {
 
518
            gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),image);
 
519
          }
 
520
          gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item);
 
521
          gtk_widget_show_all (menu_item);
 
522
          g_signal_connect(G_OBJECT(menu_item), "activate", G_CALLBACK(_launch), desktop_file);
 
523
//          g_signal_connect(G_OBJECT(menu_item), "button-release-event", G_CALLBACK(_launch), desktop_file);
 
524
          cairo_menu_item_set_source (AWN_CAIRO_MENU_ITEM(menu_item),uri);
 
525
          g_free (uri);          
 
526
          g_object_unref (entry);
 
527
          g_free (icon_name);          
 
528
        }
 
529
        break;
 
530
 
 
531
      case GMENU_TREE_ITEM_DIRECTORY:
 
532
        if (!gmenu_tree_directory_get_is_nodisplay ( (GMenuTreeDirectory *) item) )
 
533
        {
 
534
          CallbackContainer * c;
 
535
          gchar * drop_data;
 
536
          c = g_malloc0 (sizeof(CallbackContainer));          
 
537
          c->icon_name = g_strdup(gmenu_tree_directory_get_icon ((GMenuTreeDirectory *)item));
 
538
          image = get_gtk_image (c->icon_name);
 
539
          if (!image)
 
540
          {
 
541
            image = get_gtk_image ("stock_folder");
 
542
          }
 
543
          sub_menu = GTK_WIDGET(fill_er_up( instance,(GMenuTreeDirectory*)item,NULL));
 
544
          txt = gmenu_tree_directory_get_name((GMenuTreeDirectory*)item);          
 
545
          menu_item = cairo_menu_item_new_with_label (txt?txt:"unknown");
 
546
          gtk_menu_item_set_submenu (GTK_MENU_ITEM(menu_item),sub_menu);
 
547
          if (image)
 
548
          {
 
549
            gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),image);
 
550
          }        
 
551
          gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item);
 
552
          c->file_path = g_strdup(gmenu_tree_directory_get_desktop_file_path ((GMenuTreeDirectory*)item));          
 
553
          c->display_name = g_strdup (gmenu_tree_directory_get_name ((GMenuTreeDirectory*)item));
 
554
          c->instance = instance;          
 
555
          /*
 
556
           TODO: possibly change data
 
557
           */
 
558
          drop_data = g_strdup_printf("cairo_menu_item_dir:///@@@%s@@@%s@@@%s\n",c->file_path,c->display_name,c->icon_name);
 
559
          cairo_menu_item_set_source (AWN_CAIRO_MENU_ITEM(menu_item),drop_data);
 
560
          g_free (drop_data);
 
561
          g_signal_connect (menu_item, "button-press-event",G_CALLBACK(_button_press_dir),c);
 
562
          g_object_weak_ref (G_OBJECT(menu_item),(GWeakNotify)_free_callback_container,c);
 
563
          break;
 
564
        }
 
565
        break;
 
566
      case GMENU_TREE_ITEM_HEADER:
 
567
//    printf("GMENU_TREE_ITEM_HEADER\n");
 
568
        break;
 
569
 
 
570
      case GMENU_TREE_ITEM_SEPARATOR:
 
571
        menu_item = gtk_separator_menu_item_new ();
 
572
        gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item);          
 
573
        break;
 
574
 
 
575
      case GMENU_TREE_ITEM_ALIAS:
 
576
//    printf("GMENU_TREE_ITEM_ALIAS\n");
 
577
        /*      {
 
578
             GMenuTreeItem *aliased_item;
 
579
 
 
580
             aliased_item = gmenu_tree_alias_get_item (GMENU_TREE_ALIAS (item));
 
581
             if (gmenu_tree_item_get_type (aliased_item) == GMENU_TREE_ITEM_ENTRY)
 
582
                print_entry (GMENU_TREE_ENTRY (aliased_item), path);
 
583
              }*/
 
584
        break;
 
585
 
 
586
      default:
 
587
        g_assert_not_reached();
 
588
        break;
 
589
    }
 
590
 
 
591
    gmenu_tree_item_unref(tmp->data);
 
592
    tmp = tmp->next;
 
593
  }
 
594
  g_slist_free(items);  
 
595
  if (menu)
 
596
  {
 
597
    gtk_widget_show_all (menu);
 
598
  }
 
599
  sanity_depth_count--;
 
600
  return menu;
 
601
}
 
602
 
 
603
static void
 
604
_run_dialog (GtkMenuItem * item, MenuInstance *instance)
 
605
{
 
606
  const gchar * cmd;
 
607
  gchar * file_path;
 
608
  cmd = instance->run_cmd_fn (AWN_APPLET(instance->applet));
 
609
  if (cmd)
 
610
  {
 
611
    g_spawn_command_line_async (cmd,NULL);
 
612
  }
 
613
}
 
614
 
 
615
static void
 
616
_search_dialog (GtkMenuItem * item, MenuInstance * instance)
 
617
{
 
618
  const gchar * cmd;
 
619
  cmd = instance->search_cmd_fn (AWN_APPLET(instance->applet));
 
620
  if (cmd)
 
621
  {
 
622
    g_spawn_command_line_async (cmd,NULL);
 
623
  }
 
624
}
 
625
 
 
626
static gboolean
 
627
_delayed_update (MenuInstance * instance)
 
628
{
 
629
  instance->source_id=0;  
 
630
  instance->menu = menu_build (instance);  
 
631
  return FALSE;
 
632
}
 
633
 
 
634
static void 
 
635
_menu_modified_cb(GMenuTree *tree,MenuInstance * instance)
 
636
{
 
637
 
 
638
  /*
 
639
 keeps a runaway stream of callbacks from occurring in certain circumstances
 
640
 */
 
641
  if (!instance->source_id)
 
642
  {
 
643
    instance->source_id = g_timeout_add_seconds (5,(GSourceFunc)_delayed_update,instance);
 
644
  }
 
645
}
 
646
 
 
647
static GMenuTreeDirectory *
 
648
find_menu_dir (MenuInstance * instance, GMenuTreeDirectory * root)
 
649
{
 
650
  g_return_val_if_fail (root,NULL);
 
651
  GSList * items = NULL;
 
652
  GSList * tmp;
 
653
  GMenuTreeDirectory * result = NULL;
 
654
  const gchar * txt = NULL;
 
655
 
 
656
  txt = gmenu_tree_directory_get_desktop_file_path (root);
 
657
  if (g_strcmp0(txt,instance->submenu_name)==0 )
 
658
  {
 
659
    gmenu_tree_item_ref (root);
 
660
    return root;
 
661
  }
 
662
 
 
663
  items = gmenu_tree_directory_get_contents(root);  
 
664
  tmp = items;
 
665
  while (tmp != NULL)
 
666
  {
 
667
    GMenuTreeItem *item = tmp->data;
 
668
 
 
669
    switch (gmenu_tree_item_get_type(item))
 
670
    {
 
671
      case GMENU_TREE_ITEM_DIRECTORY:
 
672
        if (!gmenu_tree_directory_get_is_nodisplay ( (GMenuTreeDirectory *) item) )
 
673
        {
 
674
          txt = gmenu_tree_directory_get_desktop_file_path ((GMenuTreeDirectory*)item);
 
675
          if (g_strcmp0(txt,instance->submenu_name)==0 )
 
676
          {
 
677
            result = (GMenuTreeDirectory*)item;
 
678
            break;            
 
679
          }
 
680
          else if (!result)  /*we're continuing looping if result to unref the remaining items*/
 
681
          {
 
682
            result = find_menu_dir (instance, (GMenuTreeDirectory *) item);
 
683
          }
 
684
        }
 
685
        /*deliberately falling through*/
 
686
      case GMENU_TREE_ITEM_ENTRY:
 
687
      case GMENU_TREE_ITEM_HEADER:
 
688
      case GMENU_TREE_ITEM_SEPARATOR:
 
689
      case GMENU_TREE_ITEM_ALIAS:
 
690
        gmenu_tree_item_unref(tmp->data);        
 
691
        break;
 
692
      default:
 
693
        g_assert_not_reached();
 
694
        break;
 
695
    }
 
696
    tmp = tmp->next;
 
697
  }
 
698
  g_slist_free(items);  
 
699
  return result;
 
700
}
 
701
 
 
702
static void
 
703
clear_menu (MenuInstance * instance)
 
704
{
 
705
  if (instance->menu)
 
706
  {
 
707
    GList * children = gtk_container_get_children (GTK_CONTAINER(instance->menu));
 
708
    GList * iter;
 
709
    for (iter = children;iter;)
 
710
    {
 
711
      if ( (iter->data !=instance->places) && (iter->data!=instance->recent)&& (iter->data!=instance->session))
 
712
      {
 
713
        gtk_container_remove (GTK_CONTAINER (instance->menu),iter->data);
 
714
        /*TODO  check if this is necessary*/
 
715
        g_list_free (children);        
 
716
        children = iter = gtk_container_get_children (GTK_CONTAINER(instance->menu));
 
717
        continue;
 
718
      }
 
719
      iter=g_list_next (iter);     
 
720
    }
 
721
    if (children)
 
722
    {
 
723
      g_list_free (children);
 
724
    }
 
725
  }
 
726
}
 
727
 
 
728
static gboolean
 
729
_submenu_delayed_update (MenuInstance * instance)
 
730
{
 
731
  instance->source_id=0;  
 
732
  instance->menu = submenu_build (instance);  
 
733
  return FALSE;
 
734
}
 
735
 
 
736
 
 
737
static void 
 
738
_submenu_modified_cb(GMenuTree *tree,MenuInstance * instance)
 
739
{
 
740
 
 
741
  /*
 
742
 keeps a runaway stream of callbacks from occurring in certain circumstances
 
743
 */
 
744
  if (!instance->source_id)
 
745
  {
 
746
    instance->source_id = g_timeout_add_seconds (5,(GSourceFunc)_submenu_delayed_update,instance);
 
747
  }
 
748
}
 
749
 
 
750
static void 
 
751
_remove_main_submenu_cb(MenuInstance * instance,GObject *where_the_object_was)
 
752
{
 
753
  g_debug ("%s",__func__);
 
754
  GMenuTreeDirectory *main_root;
 
755
  gmenu_tree_remove_monitor (main_menu_tree,(GMenuTreeChangedFunc)_submenu_modified_cb,instance);
 
756
}
 
757
 
 
758
static void 
 
759
_remove_settings_submenu_cb(MenuInstance * instance,GObject *where_the_object_was)
 
760
{
 
761
  g_debug ("%s",__func__);  
 
762
  GMenuTreeDirectory *main_root;
 
763
  gmenu_tree_remove_monitor (settings_menu_tree,(GMenuTreeChangedFunc)_submenu_modified_cb,instance);
 
764
}
 
765
 
 
766
static GtkWidget *
 
767
submenu_build (MenuInstance * instance)
 
768
{
 
769
  GMenuTreeDirectory *main_root;
 
770
  GMenuTreeDirectory *settings_root;
 
771
  GtkWidget * menu = NULL;
 
772
  /*
 
773
   if the menu is set then clear any menu items (except for places or recent)
 
774
   */
 
775
  clear_menu (instance);
 
776
  if (!main_menu_tree)
 
777
  {
 
778
    main_menu_tree = gmenu_tree_lookup("applications.menu", GMENU_TREE_FLAGS_NONE);
 
779
  }
 
780
  if (!settings_menu_tree)
 
781
  {
 
782
    settings_menu_tree = gmenu_tree_lookup("settings.menu", GMENU_TREE_FLAGS_NONE);
 
783
  }
 
784
  g_assert (main_menu_tree);
 
785
  /*
 
786
   get_places_menu() and get_recent_menu() are 
 
787
   responsible for managing updates in place.  Session should only need
 
788
   to be created once or may eventually need to follow the previously mentioned
 
789
   behaviour.   Regardless... they should only need to be created here from scratch,
 
790
   this fn should _not_ be invoked in a refresh of those menus.
 
791
 
 
792
   We don't want to rebuild the whole menu tree everytime a vfs change occurs 
 
793
   or a document is accessed
 
794
   */
 
795
  if (g_strcmp0(instance->submenu_name,":::PLACES")==0)
 
796
  {
 
797
    g_assert (!instance->menu);
 
798
    menu = get_places_menu ();
 
799
  }
 
800
  else if (g_strcmp0(instance->submenu_name,":::RECENT")==0)
 
801
  {
 
802
    g_assert (!instance->menu);    
 
803
    menu = get_recent_menu ();
 
804
  }
 
805
  else if (g_strcmp0(instance->submenu_name,":::SESSION")==0)
 
806
  {
 
807
    g_assert (!instance->menu);    
 
808
    menu = get_session_menu ();
 
809
  }
 
810
  else
 
811
  {
 
812
    GMenuTreeDirectory * menu_dir = NULL;    
 
813
    
 
814
    main_root = gmenu_tree_get_root_directory(main_menu_tree);
 
815
    g_assert (gmenu_tree_item_get_type( (GMenuTreeItem*)main_root) == GMENU_TREE_ITEM_DIRECTORY);
 
816
    g_assert (main_root);
 
817
    settings_root = gmenu_tree_get_root_directory(settings_menu_tree);
 
818
    if ( menu_dir = find_menu_dir (instance,main_root) )
 
819
    {
 
820
      /* if instance->menu then we're refreshing in a monitor callback*/
 
821
      gmenu_tree_remove_monitor (main_menu_tree,(GMenuTreeChangedFunc)_submenu_modified_cb,instance);
 
822
      gmenu_tree_add_monitor (main_menu_tree,(GMenuTreeChangedFunc)_submenu_modified_cb,instance);
 
823
      menu = fill_er_up(instance,menu_dir,instance->menu);
 
824
      g_object_weak_ref (G_OBJECT(menu), (GWeakNotify)_remove_main_submenu_cb,instance);
 
825
    }
 
826
    else if ( settings_root && (menu_dir = find_menu_dir (instance,settings_root)) )
 
827
    {
 
828
      gmenu_tree_remove_monitor (main_menu_tree,(GMenuTreeChangedFunc)_submenu_modified_cb,instance);
 
829
      gmenu_tree_add_monitor (main_menu_tree,(GMenuTreeChangedFunc)_submenu_modified_cb,instance);
 
830
      menu = fill_er_up(instance,menu_dir,instance->menu);
 
831
      g_object_weak_ref (G_OBJECT(menu), (GWeakNotify)_remove_settings_submenu_cb,instance);
 
832
    }
 
833
    if (menu_dir)
 
834
    {      
 
835
      gmenu_tree_item_unref(menu_dir);
 
836
    }
 
837
    gmenu_tree_item_unref(main_root);
 
838
    if (settings_root)
 
839
    {
 
840
      gmenu_tree_item_unref(settings_root);
 
841
    }
 
842
  }
 
843
  return instance->menu = menu;
 
844
}
 
845
 
 
846
/*
 
847
 TODO: add network, and trash
 
848
 
 
849
 */
 
850
GtkWidget * 
 
851
menu_build (MenuInstance * instance)
 
852
{
 
853
  GMenuTreeDirectory *root;
 
854
  GtkWidget * image = NULL;
 
855
  GtkWidget   *menu_item;
 
856
  GtkWidget * sub_menu;
 
857
  const gchar * txt;
 
858
  CallbackContainer * c;
 
859
  gchar * drop_data;
 
860
 
 
861
  if (instance->submenu_name)
 
862
  {
 
863
    return instance->menu = submenu_build (instance);
 
864
  }
 
865
  
 
866
  clear_menu (instance);    
 
867
  if (!main_menu_tree)
 
868
  {
 
869
    main_menu_tree = gmenu_tree_lookup("applications.menu", GMENU_TREE_FLAGS_NONE);
 
870
  }
 
871
  if (!settings_menu_tree)
 
872
  {
 
873
    settings_menu_tree = gmenu_tree_lookup("settings.menu", GMENU_TREE_FLAGS_NONE);
 
874
  }
 
875
 
 
876
  if (main_menu_tree)
 
877
  {
 
878
    root = gmenu_tree_get_root_directory(main_menu_tree);
 
879
    if (root)
 
880
    {
 
881
      g_assert (!instance->submenu_name);
 
882
      gmenu_tree_remove_monitor (main_menu_tree,(GMenuTreeChangedFunc)_menu_modified_cb,instance);    
 
883
      gmenu_tree_add_monitor (main_menu_tree,(GMenuTreeChangedFunc)_menu_modified_cb,instance);
 
884
      instance->menu = fill_er_up(instance,root,instance->menu);
 
885
      gmenu_tree_item_unref(root);
 
886
    }
 
887
  }
 
888
  if  (instance->menu)
 
889
  {  
 
890
      menu_item = gtk_separator_menu_item_new ();
 
891
      gtk_menu_shell_append(GTK_MENU_SHELL(instance->menu),menu_item);  
 
892
  }
 
893
  if (settings_menu_tree)
 
894
  {
 
895
    root = gmenu_tree_get_root_directory(settings_menu_tree);
 
896
    gmenu_tree_remove_monitor (settings_menu_tree,(GMenuTreeChangedFunc)_menu_modified_cb,instance);
 
897
    gmenu_tree_add_monitor (settings_menu_tree,(GMenuTreeChangedFunc)_menu_modified_cb,instance);
 
898
    if (!instance->menu)
 
899
    {
 
900
      g_debug ("%s:  No applications menu????",__func__);
 
901
      instance->menu = fill_er_up(instance,root,instance->menu);
 
902
    }
 
903
    else
 
904
    {
 
905
      sub_menu = fill_er_up (instance, root,instance->menu);
 
906
#if 0      
 
907
      sub_menu = fill_er_up(instance,root,NULL);
 
908
      c = g_malloc0 (sizeof(CallbackContainer));        
 
909
      c->icon_name = g_strdup(gmenu_tree_directory_get_icon (root));
 
910
      image = get_gtk_image (c->icon_name);
 
911
      txt = gmenu_tree_entry_get_name((GMenuTreeEntry*)root);        
 
912
      menu_item = cairo_menu_item_new_with_label (txt?txt:"unknown");        
 
913
      gtk_menu_item_set_submenu (GTK_MENU_ITEM(menu_item),sub_menu);
 
914
      if (image)
 
915
      {
 
916
        gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),image);
 
917
      }        
 
918
      gtk_menu_shell_append(GTK_MENU_SHELL(instance->menu),menu_item);
 
919
      c->file_path = g_strdup(gmenu_tree_directory_get_desktop_file_path (root));
 
920
      c->display_name = g_strdup ("Settings");
 
921
      drop_data = g_strdup_printf("cairo_menu_item_dir:///@@@%s@@@%s@@@%s\n",c->file_path,c->display_name,c->icon_name);
 
922
      cairo_menu_item_set_source (AWN_CAIRO_MENU_ITEM(menu_item),drop_data);
 
923
      g_free (drop_data);
 
924
      c->instance = instance;
 
925
      g_signal_connect (menu_item, "button-press-event",G_CALLBACK(_button_press_dir),c);
 
926
      g_object_weak_ref (G_OBJECT(menu_item),(GWeakNotify)_free_callback_container,c);
 
927
#endif
 
928
    }
 
929
    gmenu_tree_item_unref(root);    
 
930
  }
 
931
    
 
932
    /*TODO Check to make sure it is needed. Should not be displayed if 
 
933
      all flags are of the NO persuasion.*/
 
934
  if  (instance->menu)
 
935
  {
 
936
     menu_item = gtk_separator_menu_item_new ();
 
937
     gtk_menu_shell_append(GTK_MENU_SHELL(instance->menu),menu_item);  
 
938
  }
 
939
  
 
940
  if (! (instance->flags & MENU_BUILD_NO_PLACES) )
 
941
  {
 
942
    if (instance->places)
 
943
    {
 
944
      GList * children = gtk_container_get_children (GTK_CONTAINER(instance->menu));
 
945
      menu_item =instance->places;
 
946
      gtk_menu_reorder_child (GTK_MENU(instance->menu),menu_item,g_list_length (children));
 
947
      g_list_free (children);
 
948
    }
 
949
    else
 
950
    {
 
951
      sub_menu = get_places_menu ();
 
952
      gchar * icon_name;
 
953
      instance->places = menu_item = cairo_menu_item_new_with_label (_("Places"));
 
954
      image = get_gtk_image (icon_name = "places");
 
955
      if (!image)
 
956
      {
 
957
        image = get_gtk_image(icon_name = "stock_folder");
 
958
      }
 
959
      if (image)
 
960
      {
 
961
        gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),image);
 
962
      }
 
963
      gtk_menu_item_set_submenu (GTK_MENU_ITEM(menu_item),sub_menu);            
 
964
      gtk_menu_shell_append(GTK_MENU_SHELL(instance->menu),menu_item);
 
965
      c = g_malloc0 (sizeof(CallbackContainer));
 
966
      c->file_path = g_strdup(":::PLACES");
 
967
      c->display_name = g_strdup (_("Places"));
 
968
      c->icon_name = g_strdup(icon_name);        
 
969
      drop_data = g_strdup_printf("cairo_menu_item_dir:///@@@%s@@@%s@@@%s\n",c->file_path,c->display_name,c->icon_name);
 
970
      cairo_menu_item_set_source (AWN_CAIRO_MENU_ITEM(menu_item),drop_data);
 
971
      g_free (drop_data);
 
972
      c->instance = instance;
 
973
      g_signal_connect (menu_item, "button-press-event",G_CALLBACK(_button_press_dir),c);
 
974
      g_object_weak_ref (G_OBJECT(menu_item),(GWeakNotify)_free_callback_container,c);
 
975
    }
 
976
  }
 
977
  
 
978
  if (! (instance->flags & MENU_BUILD_NO_RECENT))
 
979
  {
 
980
    if (instance->recent)
 
981
    {
 
982
      GList * children = gtk_container_get_children (GTK_CONTAINER(instance->menu));
 
983
      menu_item =instance->recent;
 
984
      gtk_menu_reorder_child (GTK_MENU(instance->menu),menu_item,g_list_length (children));
 
985
      g_list_free (children);        
 
986
    }
 
987
    else
 
988
    {
 
989
      sub_menu = get_recent_menu ();        
 
990
      gchar * icon_name;
 
991
      instance->recent = menu_item = cairo_menu_item_new_with_label (_("Recent Documents"));
 
992
      image = get_gtk_image (icon_name = "document-open-recent");
 
993
      if (!image)
 
994
      {
 
995
        image = get_gtk_image(icon_name = "stock_folder");
 
996
      }
 
997
      if (image)
 
998
      {
 
999
        gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),image);
 
1000
      }
 
1001
      gtk_menu_item_set_submenu (GTK_MENU_ITEM(menu_item),sub_menu);
 
1002
      gtk_menu_shell_append(GTK_MENU_SHELL(instance->menu),menu_item);
 
1003
      c = g_malloc0 (sizeof(CallbackContainer));
 
1004
      c->file_path = g_strdup(":::RECENT");
 
1005
      c->display_name = g_strdup (_("Recent Documents"));
 
1006
      c->icon_name = g_strdup (icon_name);        
 
1007
      drop_data = g_strdup_printf("cairo_menu_item_dir:///@@@%s@@@%s@@@%s\n",c->file_path,c->display_name,c->icon_name);
 
1008
      cairo_menu_item_set_source (AWN_CAIRO_MENU_ITEM(menu_item),drop_data);
 
1009
      g_free (drop_data);
 
1010
      c->instance = instance;
 
1011
      g_signal_connect (menu_item, "button-press-event",G_CALLBACK(_button_press_dir),c);
 
1012
      g_object_weak_ref (G_OBJECT(menu_item),(GWeakNotify)_free_callback_container,c);
 
1013
    }
 
1014
  }
 
1015
 
 
1016
  /*TODO Check to make sure it is needed. avoid double separators*/
 
1017
  if  (instance->menu &&  (!(instance->flags & MENU_BUILD_NO_RECENT) || !(instance->flags & MENU_BUILD_NO_PLACES))&&
 
1018
     (!instance->check_menu_hidden_fn (instance->applet,":::RECENT") || !instance->check_menu_hidden_fn (instance->applet,":::PLACES")) )
 
1019
  {
 
1020
    menu_item = gtk_separator_menu_item_new ();
 
1021
    gtk_menu_shell_append(GTK_MENU_SHELL(instance->menu),menu_item);  
 
1022
  }
 
1023
 
 
1024
  if (! (instance->flags & MENU_BUILD_NO_SESSION))
 
1025
  {
 
1026
    if (instance->session)
 
1027
    {
 
1028
      GList * children = gtk_container_get_children (GTK_CONTAINER(instance->menu));
 
1029
      menu_item =instance->session;
 
1030
      gtk_menu_reorder_child (GTK_MENU(instance->menu),menu_item,g_list_length (children));
 
1031
      g_list_free (children); 
 
1032
    }
 
1033
    else
 
1034
    {    
 
1035
      sub_menu = get_session_menu ();
 
1036
      instance->session = menu_item = cairo_menu_item_new_with_label (_("Session"));
 
1037
      image = get_gtk_image ("session-properties");
 
1038
      if (image)
 
1039
      {
 
1040
        gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),image);
 
1041
      }        
 
1042
      gtk_menu_item_set_submenu (GTK_MENU_ITEM(menu_item),sub_menu);
 
1043
      gtk_menu_shell_append(GTK_MENU_SHELL(instance->menu),menu_item);
 
1044
 
 
1045
      c = g_malloc0 (sizeof(CallbackContainer));
 
1046
      c->file_path = g_strdup(":::SESSION");
 
1047
      c->display_name = g_strdup (_("Session"));
 
1048
      c->icon_name = g_strdup ("session-properties");      
 
1049
      drop_data = g_strdup_printf("cairo_menu_item_dir:///@@@%s@@@%s@@@%s\n",c->file_path,c->display_name,c->icon_name);
 
1050
      cairo_menu_item_set_source (AWN_CAIRO_MENU_ITEM(menu_item),drop_data);
 
1051
      g_free (drop_data);
 
1052
      c->instance = instance;
 
1053
      g_signal_connect (menu_item, "button-press-event",G_CALLBACK(_button_press_dir),c);
 
1054
      g_object_weak_ref (G_OBJECT(menu_item),(GWeakNotify)_free_callback_container,c);
 
1055
    }
 
1056
  }
 
1057
  
 
1058
  if (! (instance->flags & MENU_BUILD_NO_SEARCH))
 
1059
  {  
 
1060
    if ( !instance->submenu_name)
 
1061
    {    
 
1062
      /*generates a compiler warning due to the ellipse*/
 
1063
      menu_item = cairo_menu_item_new_with_label (_("Search\u2026"));
 
1064
      /* add proper ellipse*/
 
1065
      image = get_gtk_image ("stock_search");
 
1066
      if (image)
 
1067
      {
 
1068
        gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),image);
 
1069
      }        
 
1070
      gtk_menu_shell_append(GTK_MENU_SHELL(instance->menu),menu_item);
 
1071
      g_signal_connect (menu_item,"activate",G_CALLBACK(_search_dialog),instance);
 
1072
    }
 
1073
  }
 
1074
  
 
1075
  if (! (instance->flags & MENU_BUILD_NO_RUN))
 
1076
  {
 
1077
    if ( !instance->submenu_name)
 
1078
    {    
 
1079
      /*generates a compiler warning due to the ellipse*/    
 
1080
      menu_item = cairo_menu_item_new_with_label (_("Launch\u2026"));
 
1081
      /* add proper ellipse*/
 
1082
      image = get_gtk_image ("gnome-run");
 
1083
      if (image)
 
1084
      {
 
1085
        gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),image);
 
1086
      }        
 
1087
      gtk_menu_shell_append(GTK_MENU_SHELL(instance->menu),menu_item);
 
1088
      g_signal_connect (menu_item,"activate",G_CALLBACK(_run_dialog),instance);
 
1089
    }
 
1090
  }
 
1091
 
 
1092
  gtk_widget_show_all (instance->menu);
 
1093
 
 
1094
  if ( !instance->check_menu_hidden_fn || instance->check_menu_hidden_fn (instance->applet,":::RECENT"))
 
1095
  {
 
1096
    if (instance->recent)
 
1097
    {
 
1098
      gtk_widget_hide (instance->recent);
 
1099
    }
 
1100
  }
 
1101
  if ( !instance->check_menu_hidden_fn || instance->check_menu_hidden_fn (instance->applet,":::PLACES"))
 
1102
  {    
 
1103
    if (instance->places)
 
1104
    {
 
1105
      gtk_widget_hide (instance->places);
 
1106
    }  
 
1107
  }    
 
1108
  if ( !instance->check_menu_hidden_fn || instance->check_menu_hidden_fn (instance->applet,":::SESSION"))
 
1109
  {    
 
1110
    if (instance->session)
 
1111
    {
 
1112
      gtk_widget_hide (instance->session);
 
1113
    }
 
1114
  }
 
1115
  instance->done_once = TRUE;
 
1116
  return instance->menu;
 
1117
}