Index: Makefile.am
===================================================================
RCS file: /cvs/gnome/gnome-panel/gnome-panel/Makefile.am,v
retrieving revision 1.347
diff -u -p -r1.347 Makefile.am
--- Makefile.am	7 Feb 2005 21:19:53 -0000	1.347
+++ Makefile.am	17 Feb 2005 18:51:59 -0000
@@ -99,6 +99,7 @@ panel_sources =			\
 	panel-action-button.c	\
 	panel-menu-bar.c        \
 	panel-menu-button.c     \
+	panel-menu-items.c      \
 	panel-recent.c		\
 	panel-gdk-pixbuf-extensions.c \
 	panel-action-protocol.c	\
@@ -143,6 +144,7 @@ panel_headers =			\
 	panel-action-button.h	\
 	panel-menu-bar.h        \
 	panel-menu-button.h     \
+	panel-menu-items.h      \
 	panel-recent.h		\
 	panel-gdk-pixbuf-extensions.h \
 	panel-action-protocol.h	\
Index: menu.c
===================================================================
RCS file: /cvs/gnome/gnome-panel/gnome-panel/menu.c,v
retrieving revision 1.738
diff -u -p -r1.738 menu.c
--- menu.c	1 Feb 2005 22:16:26 -0000	1.738
+++ menu.c	17 Feb 2005 18:51:59 -0000
@@ -41,6 +41,7 @@
 #include "panel-recent.h"
 #include "panel-profile.h"
 #include "panel-menu-button.h"
+#include "panel-menu-items.h"
 #include "panel-globals.h"
 #include "panel-run-dialog.h"
 #include "panel-lockdown.h"
@@ -106,39 +107,10 @@ static void
 activate_app_def (GtkWidget     *menuitem,
 		  MenuTreeEntry *entry)
 {
-	GnomeDesktopItem *item;
-	GError           *error;
 	const char       *path;
 
 	path = menu_tree_entry_get_desktop_file_path (entry);
-
-	error = NULL;
-	item = gnome_desktop_item_new_from_file (path, 0, &error);
-	if (item) {
-		g_assert (error == NULL);
-
-		panel_ditem_launch (
-			item, NULL, 0, menuitem_to_screen (menuitem), &error);
-		if (error) {
-			panel_error_dialog (menuitem_to_screen (menuitem),
-					    "cannot_launch_entry", TRUE,
-					    _("Cannot launch entry"),
-					    "%s",
-					    error->message);
-
-			g_error_free (error);
-		}
-		gnome_desktop_item_unref (item);
-	} else {
-		g_assert (error != NULL);
-
-		panel_error_dialog (menuitem_to_screen (menuitem),
-				    "cannot_load_entry", TRUE,
-				    _("Cannot load entry"),
-				    "%s",
-				    error->message);
-		g_error_free (error);
-	}
+	panel_menu_item_activate_desktop_file (menuitem, path);
 }
 
 PanelWidget *
@@ -187,6 +159,10 @@ setup_menu_panel (GtkWidget *menu)
 
 	panel = menu_get_panel (menu);
 	g_object_set_data (G_OBJECT (menu), "menu_panel", panel);
+
+	if (panel)
+		gtk_menu_set_screen (GTK_MENU (menu),
+				     gtk_widget_get_screen (GTK_WIDGET (panel)));
 }
 
 GdkScreen *
@@ -310,8 +286,12 @@ create_empty_menu (void)
 
 	retval = panel_create_menu ();
 
-	g_signal_connect (
-		retval, "show", G_CALLBACK (setup_menu_panel), NULL);
+	g_signal_connect (retval, "show", G_CALLBACK (setup_menu_panel), NULL);
+
+	/* intercept all right button clicks makes sure they don't
+	   go to the object itself */
+	g_signal_connect (retval, "button_press_event",
+			  G_CALLBACK (menu_dummy_button_press_event), NULL);
 
 	return retval;
 }
@@ -707,7 +687,6 @@ add_menu_to_panel (GtkWidget     *menuit
 	int                insertion_pos;
 	char              *menu_path;
 	char              *menu_filename;
-	GtkWidget         *parent;
 
 	menu_filename = g_object_get_data (G_OBJECT (menuitem->parent),
 					   "panel-menu-tree-filename");
@@ -1483,96 +1462,46 @@ setup_menu_item_with_icon (GtkWidget   *
 
 	setup_menuitem (item, icon_size, NULL, title, invisible_mnemonic);
 }
-  
-GtkWidget *
-menu_create_action_item (PanelActionButtonType action_type)
+
+static void
+main_menu_append (GtkWidget   *main_menu,
+		  PanelWidget *panel)
 {
 	GtkWidget *item;
 
-	if (panel_action_get_is_disabled (action_type))
-		return NULL;
+	if (!g_object_get_data (G_OBJECT (main_menu),
+				"panel-menu-needs-appending"))
+		return;
 
-	item = gtk_image_menu_item_new ();
-        setup_menu_item_with_icon (item,
-				   panel_menu_icon_get_size (),
-				   panel_action_get_icon_name (action_type),
-				   NULL,
-				   panel_action_get_text (action_type),
-				   TRUE);
-
-	gtk_tooltips_set_tip (panel_tooltips,
-			      item,
-			      panel_action_get_tooltip (action_type),
-			      NULL);
-
-	g_signal_connect (item, "activate",
-			  panel_action_get_invoke (action_type), NULL);
-	g_signal_connect (G_OBJECT (item), "button_press_event",
-			  G_CALLBACK (menu_dummy_button_press_event), NULL);
-	setup_internal_applet_drag (item, action_type);
+	g_object_set_data (G_OBJECT (main_menu),
+			   "panel-menu-needs-appending", NULL);
 
-	return item;
+	add_menu_separator (main_menu);
+
+	item = panel_place_menu_item_new (TRUE);
+	panel_place_menu_item_set_panel (item, panel);
+	gtk_menu_shell_append (GTK_MENU_SHELL (main_menu), item);
+	gtk_widget_show (item);
+
+	item = panel_desktop_menu_item_new (TRUE, FALSE);
+	panel_desktop_menu_item_set_panel (item, panel);
+	gtk_menu_shell_append (GTK_MENU_SHELL (main_menu), item);
+	gtk_widget_show (item);
+
+	panel_menu_items_append_lock_logout (main_menu);
 }
 
 GtkWidget *
 create_main_menu (PanelWidget *panel)
 {
 	GtkWidget *main_menu;
-	GtkWidget *applications_menu;
-	GtkWidget *menuitem;
 
-	main_menu = create_empty_menu ();
+	main_menu = create_applications_menu ("applications.menu", NULL);
 	g_object_set_data (G_OBJECT (main_menu), "menu_panel", panel);
+	/* FIXME need to update the panel on parent_set */
 
-	menuitem = gtk_image_menu_item_new ();
-	setup_menu_item_with_icon (menuitem,
-				   panel_menu_icon_get_size (),
-				   "gnome-applications",
-				   NULL,
-				   _("Applications"),
-				   TRUE);
-	gtk_menu_shell_append (GTK_MENU_SHELL (main_menu), menuitem);
-
-	applications_menu = create_applications_menu ("applications.menu",
-						      NULL);
-	gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), applications_menu);
-
-	add_menu_separator (main_menu);
-
-	menuitem = menu_create_action_item (PANEL_ACTION_RUN);
-	if (menuitem != NULL)
-		gtk_menu_shell_append (GTK_MENU_SHELL (main_menu), menuitem);
-
-	if (panel_is_program_in_path  ("gnome-search-tool")) {
-		menuitem = menu_create_action_item (PANEL_ACTION_SEARCH);
-		if (menuitem != NULL)
-			gtk_menu_shell_append (GTK_MENU_SHELL (main_menu),
-					       menuitem);
-	}
-
-	panel_recent_append_documents_menu (main_menu);
-
-	add_menu_separator (main_menu);
-
-	if (panel_is_program_in_path ("gnome-screenshot")) {
-		menuitem = menu_create_action_item (PANEL_ACTION_SCREENSHOT);
-		if (menuitem != NULL)
-			gtk_menu_shell_append (GTK_MENU_SHELL (main_menu),
-					       menuitem);
-
-		add_menu_separator (main_menu);
-	}
-
-	if (panel_is_program_in_path  ("xscreensaver")) {
-		menuitem = menu_create_action_item (PANEL_ACTION_LOCK);
-		if (menuitem != NULL)
-			gtk_menu_shell_append (GTK_MENU_SHELL (main_menu),
-					       menuitem);
-	}
-
-	menuitem = menu_create_action_item (PANEL_ACTION_LOGOUT);
-	if (menuitem != NULL)
-		gtk_menu_shell_append (GTK_MENU_SHELL (main_menu), menuitem);
+	g_signal_connect (main_menu, "show",
+			  G_CALLBACK (main_menu_append), panel);
 
 	return main_menu;
 }
Index: menu.h
===================================================================
RCS file: /cvs/gnome/gnome-panel/gnome-panel/menu.h,v
retrieving revision 1.104
diff -u -p -r1.104 menu.h
--- menu.h	29 Jan 2005 15:50:43 -0000	1.104
+++ menu.h	17 Feb 2005 18:51:59 -0000
@@ -41,8 +41,6 @@ void            setup_menu_item_with_ico
 					   const char       *title,
 					   gboolean          invisible_mnemonic);
 
-GtkWidget      *menu_create_action_item   (PanelActionButtonType action_type);
-
 GtkWidget      *create_empty_menu         (void);
 GtkWidget      *create_applications_menu  (const char  *menu_file,
 					   const char  *menu_path);
Index: panel-menu-bar.c
===================================================================
RCS file: /cvs/gnome/gnome-panel/gnome-panel/panel-menu-bar.c,v
retrieving revision 1.56
diff -u -p -r1.56 panel-menu-bar.c
--- panel-menu-bar.c	10 Feb 2005 20:36:24 -0000	1.56
+++ panel-menu-bar.c	17 Feb 2005 18:51:59 -0000
@@ -31,35 +31,16 @@
 #include <string.h>
 #include <glib/gi18n.h>
 
-#include <libgnomevfs/gnome-vfs.h>
-#include <libgnomeui/gnome-url.h>
-
 #include "panel-util.h"
 #include "panel-background.h"
 #include "panel-action-button.h"
-#include "panel-stock-icons.h"
-#include "panel-recent.h"
 #include "applet.h"
 #include "menu.h"
-#include "panel-gconf.h"
+#include "panel-menu-items.h"
 #include "panel-globals.h"
 #include "panel-profile.h"
 #include "panel-lockdown.h"
-
-#define BOOKMARKS_FILENAME      ".gtk-bookmarks"
-#define DESKTOP_IS_HOME_DIR_DIR "/apps/nautilus/preferences"
-#define DESKTOP_IS_HOME_DIR_KEY "/apps/nautilus/preferences/desktop_is_home_dir"
-#define MAX_ITEMS_OR_SUBMENU    5
-
-/*
- * TODO:
- *   + drag and drop loses icon for URIs
- *   + drag and drop of bookmarks/network places/removable media should create
- *     a menu button
- *   + if a menu is open and get updated, it should reappear and not just
- *     disappear
- *   + see FIXME
- */
+#include "panel-stock-icons.h"
 
 #define PANEL_MENU_BAR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PANEL_TYPE_MENU_BAR, PanelMenuBarPrivate))
 
@@ -68,244 +49,13 @@ struct _PanelMenuBarPrivate {
 	PanelWidget *panel;
 
 	GtkWidget   *applications_menu;
-	GtkWidget   *places_menu;
-	GtkWidget   *desktop_menu;
 	GtkWidget   *applications_item;
 	GtkWidget   *places_item;
 	GtkWidget   *desktop_item;
-
-	GnomeVFSMonitorHandle *bookmarks_monitor;
-
-	gulong       volume_mounted_id;
-	gulong       volume_unmounted_id;
 };
 
-static GnomeVFSVolumeMonitor *volume_monitor = NULL;
-
 static GObjectClass *parent_class;
 static GtkWidget *panel_menu_bar_create_applications_menu (PanelMenuBar *menubar);
-static GtkWidget *panel_menu_bar_create_places_menu (PanelMenuBar *menubar);
-static GtkWidget *panel_menu_bar_create_desktop_menu (PanelMenuBar *menubar);
-
-static void
-activate_uri (GtkWidget *menuitem,
-	      char      *path)
-{
-	GError    *error = NULL;
-	GdkScreen *screen;
-	char      *url;
-	char      *escaped;
-
-	screen = menuitem_to_screen (menuitem);
-
-	url = gnome_vfs_make_uri_from_input_with_dirs (path,
-						       GNOME_VFS_MAKE_URI_DIR_HOMEDIR);
-	gnome_url_show_on_screen (url, screen, &error);
-
-	if (error) {
-		escaped = g_markup_escape_text (url, -1);
-		panel_error_dialog (screen, "cannot_show_url", TRUE,
-				    _("Cannot display location '%s'"),
-				    "%s",
-				    escaped,
-				    error->message);
-
-		g_error_free (error);
-		g_free (escaped);
-	}
-	g_free (url);
-}
-
-static void
-activate_app_def (GtkWidget *menuitem,
-		  char      *path)
-{
-	GnomeDesktopItem *item;
-	GError           *error;
-
-	error = NULL;
-	item = gnome_desktop_item_new_from_file (path, 0, &error);
-	if (item) {
-		g_assert (error == NULL);
-
-		panel_ditem_launch (item, NULL, 0,
-				    menuitem_to_screen (menuitem), &error);
-		if (error) {
-			panel_error_dialog (menuitem_to_screen (menuitem),
-					    "cannot_launch_entry", TRUE,
-					    _("Cannot launch entry"),
-					    "%s",
-					    error->message);
-
-			g_error_free (error);
-		}
-		gnome_desktop_item_unref (item);
-	} else {
-		g_assert (error != NULL);
-
-		panel_error_dialog (menuitem_to_screen (menuitem),
-				    "cannot_load_entry", TRUE,
-				    _("Cannot load entry"),
-				    "%s",
-				    error->message);
-		g_error_free (error);
-	}
-}
-
-static void
-panel_menu_bar_append_from_desktop (GtkWidget *menu,
-				    char      *path)
-{
-	GKeyFile  *key_file;
-	gboolean   loaded;
-	GtkWidget *item;
-	char      *path_freeme;
-	char      *full_path;
-	char      *icon;
-	char      *name;
-	char      *comment;
-
-	path_freeme = NULL;
-
-	key_file = g_key_file_new ();
-
-	if (g_path_is_absolute (path)) {
-		loaded = g_key_file_load_from_file (key_file, path,
-						    G_KEY_FILE_NONE, NULL);
-		full_path = path;
-	} else {
-		char *lookup_file;
-		char *desktop_path;
-
-		if (!g_str_has_suffix (path, ".desktop")) {
-			desktop_path = g_strconcat (path, ".desktop", NULL);
-		} else {
-			desktop_path = path;
-		}
-
-		lookup_file = g_strconcat ("applications", G_DIR_SEPARATOR_S,
-					   desktop_path, NULL);
-		loaded = g_key_file_load_from_data_dirs (key_file, lookup_file,
-							 &path_freeme,
-							 G_KEY_FILE_NONE,
-							 NULL);
-		full_path = path_freeme;
-		g_free (lookup_file);
-
-		if (desktop_path != path)
-			g_free (desktop_path);
-	}
-
-	if (!loaded) {
-		g_key_file_free (key_file);
-		if (path_freeme)
-			g_free (path_freeme);
-		return;
-	}
-
-	icon    = g_key_file_get_locale_string (key_file, "Desktop Entry",
-						"Icon", NULL, NULL);
-	name    = g_key_file_get_locale_string (key_file, "Desktop Entry",
-						"Name", NULL, NULL);
-	comment = g_key_file_get_locale_string (key_file, "Desktop Entry",
-						"Comment", NULL, NULL);
-
-	item = gtk_image_menu_item_new ();
-	setup_menu_item_with_icon (item, panel_menu_icon_get_size (),
-				   icon, NULL, name, TRUE);
-
-	if (comment != NULL)
-		gtk_tooltips_set_tip (panel_tooltips, item, comment, NULL);
-
-	gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
-	g_signal_connect_data (item, "activate",
-			       G_CALLBACK (activate_app_def),
-			       g_strdup (full_path),
-			       (GClosureNotify) g_free, 0);
-	g_signal_connect (G_OBJECT (item), "button_press_event",
-			  G_CALLBACK (menu_dummy_button_press_event), NULL);
-	setup_uri_drag (item, full_path, icon);
-
-	g_key_file_free (key_file);
-
-	if (icon)
-		g_free (icon);
-
-	if (name)
-		g_free (name);
-
-	if (comment)
-		g_free (comment);
-
-	if (path_freeme)
-		g_free (path_freeme);
-}
-
-static void
-panel_menu_bar_show_menu (PanelMenuBar *menubar,
-			  GtkWidget    *menu)
-{
-	gtk_menu_set_screen (GTK_MENU (menu),
-			     gtk_widget_get_screen (GTK_WIDGET (menubar)));
-}
-
-static void
-panel_menu_bar_connect_menu_signals (PanelMenuBar  *menubar,
-				     GtkWidget    **menu)
-{
-	/* intercept all right button clicks makes sure they don't
-	   go to the object itself */
-	g_signal_connect (*menu, "button_press_event",
-			  G_CALLBACK (menu_dummy_button_press_event), NULL);
-
-	g_signal_connect (*menu, "destroy", G_CALLBACK (gtk_widget_destroyed),
-			  menu);
-
-	g_signal_connect_swapped (*menu, "show",
-				  G_CALLBACK (panel_menu_bar_show_menu),
-				  menubar);
-
-	g_signal_connect_swapped (*menu, "hide",
-				  G_CALLBACK (gtk_menu_shell_deselect), 
-				  menubar);
-}
-
-static void
-panel_menu_bar_append_place_item (PanelMenuBar *menubar,
-				  const char   *icon_name,
-				  const char   *title,
-				  const char   *tooltip,
-				  GtkWidget    *menu,
-				  GCallback     callback,
-				  const char   *uri)
-{
-	GtkWidget *item;
-	char      *user_data;
-
-	item = gtk_image_menu_item_new ();
-	setup_menu_item_with_icon (item,
-				   panel_menu_icon_get_size (),
-				   icon_name,
-				   NULL,
-				   title,
-				   TRUE);
-
-	gtk_tooltips_set_tip (panel_tooltips,
-			      item,
-			      tooltip,
-			      NULL);
-
-	gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
-
-	user_data = g_strdup (uri);
-	g_signal_connect_data (item, "activate", callback, user_data,
-			       (GClosureNotify) g_free, 0);
-
-	g_signal_connect (G_OBJECT (item), "button_press_event",
-			  G_CALLBACK (menu_dummy_button_press_event), NULL);
-
-	setup_uri_drag (item, uri, icon_name);
-}
 
 static void
 panel_menu_bar_recreate_menus (PanelMenuBar *menubar)
@@ -313,42 +63,12 @@ panel_menu_bar_recreate_menus (PanelMenu
 	if (menubar->priv->applications_menu) {
 		gtk_widget_destroy (menubar->priv->applications_menu);
 		menubar->priv->applications_menu = panel_menu_bar_create_applications_menu (menubar);
-		panel_menu_bar_connect_menu_signals (menubar,
-						     &menubar->priv->applications_menu);
 		panel_applet_menu_set_recurse (GTK_MENU (menubar->priv->applications_menu),
 					       "menu_panel",
 					       menubar->priv->panel);
 		gtk_menu_item_set_submenu (GTK_MENU_ITEM (menubar->priv->applications_item),
 					   menubar->priv->applications_menu);
 	}
-
-	if (menubar->priv->desktop_menu) {
-		gtk_widget_destroy (menubar->priv->desktop_menu);
-		menubar->priv->desktop_menu = panel_menu_bar_create_desktop_menu (menubar);
-		panel_menu_bar_connect_menu_signals (menubar,
-						     &menubar->priv->desktop_menu);
-		panel_applet_menu_set_recurse (GTK_MENU (menubar->priv->desktop_menu),
-					       "menu_panel",
-					       menubar->priv->panel);
-		gtk_menu_item_set_submenu (GTK_MENU_ITEM (menubar->priv->desktop_item),
-					   menubar->priv->desktop_menu);
-	}
-}
-
-static void
-panel_menu_bar_recreate_places_menu (PanelMenuBar *menubar)
-{
-	if (menubar->priv->places_menu) {
-		gtk_widget_destroy (menubar->priv->places_menu);
-		menubar->priv->places_menu = panel_menu_bar_create_places_menu (menubar);
-		panel_menu_bar_connect_menu_signals (menubar,
-						     &menubar->priv->places_menu);
-		panel_applet_menu_set_recurse (GTK_MENU (menubar->priv->places_menu),
-					       "menu_panel",
-					       menubar->priv->panel);
-		gtk_menu_item_set_submenu (GTK_MENU_ITEM (menubar->priv->places_item),
-					   menubar->priv->places_menu);
-	}
 }
 
 static void
@@ -362,362 +82,39 @@ panel_menu_bar_append_applications_menu 
 
 	g_object_set_data (G_OBJECT (menu), "panel-menu-needs-appending", NULL);
 
-	item = menu_create_action_item (PANEL_ACTION_RUN);
+	item = panel_menu_items_create_action_item (PANEL_ACTION_RUN);
 
-	if (item != NULL &&
-	    GTK_MENU_SHELL (menubar->priv->applications_menu)->children != NULL) {
-		add_menu_separator (menubar->priv->applications_menu);
-		gtk_menu_shell_append (GTK_MENU_SHELL (menubar->priv->applications_menu),
-				       item);
-	}
-}
-
-static GtkWidget *
-panel_menu_bar_create_applications_menu (PanelMenuBar *menubar)
-{
-	GtkWidget *applications_menu;
-
-	applications_menu = create_applications_menu ("applications.menu", NULL);
-
-	g_signal_connect (applications_menu, "show",
-			  G_CALLBACK (panel_menu_bar_append_applications_menu),
-			  menubar);
-
-	return applications_menu;
-}
-
-static void
-panel_menu_bar_desktop_is_home_dir_changed (GConfClient  *client,
-					    guint         cnxn_id,
-					    GConfEntry   *entry,
-					    PanelMenuBar *menubar)
-{
-	panel_menu_bar_recreate_places_menu (menubar);
-}
-
-static void
-panel_menu_bar_gtk_bookmarks_changed (GnomeVFSMonitorHandle *handle,
-				      const gchar *monitor_uri,
-				      const gchar *info_uri,
-				      GnomeVFSMonitorEventType event_type,
-				      gpointer user_data)
-{
-	g_assert (PANEL_IS_MENU_BAR (user_data));
-
-	panel_menu_bar_recreate_places_menu (PANEL_MENU_BAR (user_data));
-}
-
-static void
-panel_menu_bar_volume_changed (GnomeVFSVolumeMonitor *monitor,
-			       GnomeVFSVolume        *volume,
-			       PanelMenuBar          *menubar)
-{
-	panel_menu_bar_recreate_places_menu (menubar);
-}
-
-static void
-panel_menu_bar_append_gtk_bookmarks (PanelMenuBar *menubar,
-				     GtkWidget    *menu)
-{
-	GtkWidget   *add_menu;
-	char        *filename;
-	char        *contents;
-	gchar      **lines;
-	GHashTable  *table;
-	int          i;
-	GSList      *add_files, *l;
-	GnomeVFSURI *uri;
-
-	filename = g_build_filename (g_get_home_dir (),
-				     BOOKMARKS_FILENAME, NULL);
-
-	if (!g_file_get_contents (filename, &contents, NULL, NULL)) {
-		g_free (filename);
-		return;
-	}
-
-	g_free (filename);
-
-	lines = g_strsplit (contents, "\n", -1);
-	g_free (contents);
-
-	table = g_hash_table_new (g_str_hash, g_str_equal);
-	add_files = NULL;
-
-	//FIXME gnome_vfs_uri_exists: could there be an authentication
-	//dialog if there's a bookmarks to sftp://something?
-	for (i = 0; lines[i]; i++) {
-		if (lines[i][0] && !g_hash_table_lookup (table, lines[i])) {
-			char *unescaped_uri;
-
-			unescaped_uri = gnome_vfs_unescape_string (lines[i],
-								   "");
-			uri = gnome_vfs_uri_new (unescaped_uri);
-			g_free (unescaped_uri);
-
-			if (!gnome_vfs_uri_exists (uri)) {
-				gnome_vfs_uri_unref (uri);
-				continue;
-			}
-
-			add_files = g_slist_prepend (add_files, uri);
-			g_hash_table_insert (table, lines[i], lines[i]);
-		}
-	}
-
-	g_hash_table_destroy (table);
-	g_strfreev (lines);
-
-	add_files = g_slist_reverse (add_files);
-
-	if (g_slist_length (add_files) <= MAX_ITEMS_OR_SUBMENU) {
-		add_menu = menu;
-	} else {
-		GtkWidget *item;
-
-		item = gtk_image_menu_item_new ();
-		setup_menu_item_with_icon (item, panel_menu_icon_get_size (),
-					   "stock_bookmark", NULL,
-					   _("Bookmarks"), TRUE);
-
-		gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
-		gtk_widget_show (item);
-
-		add_menu = create_empty_menu ();
-		gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), add_menu);
-	}
-
-	for (l = add_files; l; l = l->next) {
-		char *full_uri;
-		char *display_uri;
-		char *tooltip;
-		char *basename;
-
-		uri = l->data;
-		full_uri = gnome_vfs_uri_to_string (uri,
-						    GNOME_VFS_URI_HIDE_NONE);
-
-		display_uri = gnome_vfs_format_uri_for_display (full_uri);
-		/* Translators: %s is a URI */
-		tooltip = g_strdup_printf (_("Open '%s'"), display_uri);
-		g_free (display_uri);
-
-		basename = gnome_vfs_uri_extract_short_name (uri);
-		panel_menu_bar_append_place_item (menubar, "gnome-fs-directory",
-						  basename, tooltip, add_menu,
-						  G_CALLBACK (activate_uri),
-						  full_uri);
-
-		g_free (basename);
-		g_free (tooltip);
-		g_free (full_uri);
-		gnome_vfs_uri_unref (uri);
-	}
+	if (item != NULL) {
+		gboolean  add_separator;
+		GList    *children;
 
-	g_slist_free (add_files);
-}
+		children = gtk_container_get_children (GTK_CONTAINER (menu));
 
-static void
-panel_menu_bar_append_volumes (PanelMenuBar *menubar,
-			       GtkWidget    *menu,
-			       gboolean      connected_volumes)
-{
-	GtkWidget *add_menu;
-	GList     *volumes, *l;
-	GSList    *add_volumes, *sl;
-
-	volumes = gnome_vfs_volume_monitor_get_mounted_volumes (volume_monitor);
-	add_volumes = NULL;
-
-	for (l = volumes; l; l = l->next) {
-		GnomeVFSVolume *volume = l->data;
-
-		if (!gnome_vfs_volume_is_user_visible (volume) ||
-		    !gnome_vfs_volume_is_mounted (volume))
-			continue;
-
-		switch (gnome_vfs_volume_get_volume_type (volume)) {
-		case GNOME_VFS_VOLUME_TYPE_CONNECTED_SERVER:
-			if (connected_volumes)
-				add_volumes = g_slist_prepend (add_volumes,
-							       volume);
-			break;
-		default:
-			if (!connected_volumes)
-				add_volumes = g_slist_prepend (add_volumes,
-							       volume);
-			break;
+		if (children != NULL) {
+			while (children->next != NULL)
+				children = children->next;
+			add_separator = !GTK_IS_SEPARATOR (GTK_WIDGET (children->data));
 		}
-	}
-
-	add_volumes = g_slist_reverse (add_volumes);
 
-	if (g_slist_length (add_volumes) <= MAX_ITEMS_OR_SUBMENU) {
-		add_menu = menu;
-	} else {
-		GtkWidget *item;
-
-		if (connected_volumes)
-			item = gtk_menu_item_new_with_label (_("Network Places"));
-		else
-			item = gtk_menu_item_new_with_label (_("Removable Media"));
+		if (add_separator)
+			add_menu_separator (menu);
 
 		gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
-		gtk_widget_show (item);
-
-		add_menu = create_empty_menu ();
-		gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), add_menu);
-	}
-
-	for (sl = add_volumes; sl; sl = sl->next) {
-		GnomeVFSVolume *volume = sl->data;
-		char           *icon;
-		char           *display_name;
-		char           *activation_uri;
-
-		icon           = gnome_vfs_volume_get_icon (volume);
-		display_name   = gnome_vfs_volume_get_display_name (volume);
-		activation_uri = gnome_vfs_volume_get_activation_uri (volume);
-
-		panel_menu_bar_append_place_item (menubar,
-						  icon,
-						  display_name,
-						  display_name, //FIXME tooltip
-						  add_menu,
-						  G_CALLBACK (activate_uri),
-						  activation_uri);
-
-		g_free (icon);
-		g_free (display_name);
-		g_free (activation_uri);
-	}
-
-	g_slist_free (add_volumes);
-
-	g_list_foreach (volumes, (GFunc) gnome_vfs_volume_unref, NULL);
-	g_list_free (volumes);
-}
-
-static GtkWidget *
-panel_menu_bar_create_places_menu (PanelMenuBar *menubar)
-{
-	GtkWidget *places_menu;
-	GtkWidget *item;
-
-	places_menu = panel_create_menu ();
-
-	panel_menu_bar_append_from_desktop (places_menu,
-					    "nautilus-home.desktop");
-
-	if (!gconf_client_get_bool (panel_gconf_get_client (),
-				    DESKTOP_IS_HOME_DIR_KEY,
-				    NULL))
-		panel_menu_bar_append_place_item (menubar, "gnome-fs-desktop",
-						  /* Translators: Desktop is
-						   * used here as in "Desktop
-						   * Folder" (this is not the
-						   * Desktop environment). Do
-						   * not keep "Desktop Folder|"
-						   * in the translation */
-						  Q_("Desktop Folder|Desktop"),
-						  _("Open the desktop as a folder"),
-						  places_menu,
-						  G_CALLBACK (activate_uri),
-						  "Desktop");
-
-	panel_menu_bar_append_gtk_bookmarks (menubar, places_menu);
-	add_menu_separator (places_menu);
-
-	panel_menu_bar_append_from_desktop (places_menu,
-					    "nautilus-computer.desktop");
-	panel_menu_bar_append_volumes (menubar, places_menu, FALSE);
-	add_menu_separator (places_menu);
-
-	panel_menu_bar_append_from_desktop (places_menu,
-					    "network-scheme.desktop");
-	panel_menu_bar_append_volumes (menubar, places_menu, TRUE);
-
-	if (panel_is_program_in_path ("nautilus-connect-server")) {
-		item = menu_create_action_item (PANEL_ACTION_CONNECT_SERVER);
-		if (item != NULL)
-			gtk_menu_shell_append (GTK_MENU_SHELL (places_menu),
-					       item);
-	}
-
-	add_menu_separator (places_menu);
-
-	panel_menu_bar_append_from_desktop (places_menu,
-					    "gnome-search-tool.desktop");
-
-	panel_recent_append_documents_menu (places_menu);
-
-	return places_menu;
-}
-
-static void
-panel_menu_bar_append_desktop_menu (GtkWidget    *menu,
-				    PanelMenuBar *menubar)
-{
-	GtkWidget *desktop_menu;
-	GtkWidget *item;
-	gboolean   separator_inserted;
-
-	if (!g_object_get_data (G_OBJECT (menu), "panel-menu-needs-appending"))
-		return;
-
-	g_object_set_data (G_OBJECT (menu), "panel-menu-needs-appending", NULL);
-
-	desktop_menu = menubar->priv->desktop_menu;
-
-	if (GTK_MENU_SHELL (desktop_menu)->children != NULL)
-		add_menu_separator (desktop_menu);
-
-	if (panel_is_program_in_path ("gnome-screenshot")) {
-		item = menu_create_action_item (PANEL_ACTION_SCREENSHOT);
-		if (item != NULL)
-			gtk_menu_shell_append (GTK_MENU_SHELL (desktop_menu),
-					       item);
-	}
-
-	panel_menu_bar_append_from_desktop (desktop_menu,
-					    "yelp.desktop");
-
-	panel_menu_bar_append_from_desktop (desktop_menu,
-					    "gnome-about.desktop");
-
-	separator_inserted = FALSE;
-
-	if (panel_is_program_in_path ("xscreensaver")) {
-		item = menu_create_action_item (PANEL_ACTION_LOCK);
-		if (item != NULL) {
-			add_menu_separator (desktop_menu);
-			gtk_menu_shell_append (GTK_MENU_SHELL (desktop_menu), item);
-			separator_inserted = TRUE;
-		}
-	}
-
-	item = menu_create_action_item (PANEL_ACTION_LOGOUT);
-	if (item != NULL) {
-		if (!separator_inserted) {
-			add_menu_separator (desktop_menu);
-			separator_inserted = TRUE;
-		}
-		gtk_menu_shell_append (GTK_MENU_SHELL (desktop_menu), item);
 	}
 }
 
 static GtkWidget *
-panel_menu_bar_create_desktop_menu (PanelMenuBar *menubar)
+panel_menu_bar_create_applications_menu (PanelMenuBar *menubar)
 {
-	GtkWidget *desktop_menu;
+	GtkWidget *applications_menu;
 
-	desktop_menu = create_applications_menu ("settings.menu", NULL);
+	applications_menu = create_applications_menu ("applications.menu", NULL);
 
-	g_signal_connect (desktop_menu, "show",
-			  G_CALLBACK (panel_menu_bar_append_desktop_menu),
+	g_signal_connect (applications_menu, "show",
+			  G_CALLBACK (panel_menu_bar_append_applications_menu),
 			  menubar);
 
-	return desktop_menu;
+	return applications_menu;
 }
 
 static void
@@ -725,68 +122,12 @@ panel_menu_bar_instance_init (PanelMenuB
 			      PanelMenuBarClass *klass)
 {
 	GtkWidget *image;
-	char      *bookmarks_filename;
-	char      *bookmarks_uri;
 
 	menubar->priv = PANEL_MENU_BAR_GET_PRIVATE (menubar);
 
 	menubar->priv->info = NULL;
 
-	gconf_client_add_dir (panel_gconf_get_client (),
-			      DESKTOP_IS_HOME_DIR_DIR,
-			      GCONF_CLIENT_PRELOAD_NONE,
-			      NULL);
-
-	panel_gconf_notify_add_while_alive (DESKTOP_IS_HOME_DIR_KEY,
-					    (GConfClientNotifyFunc) panel_menu_bar_desktop_is_home_dir_changed,
-					    G_OBJECT (menubar));
-
-	bookmarks_filename = g_build_filename (g_get_home_dir (),
-					       BOOKMARKS_FILENAME, NULL);
-	bookmarks_uri = gnome_vfs_get_uri_from_local_path (bookmarks_filename);
-
-	if (bookmarks_uri) {
-		GnomeVFSResult result;
-		result = gnome_vfs_monitor_add (&menubar->priv->bookmarks_monitor,
-						bookmarks_uri,
-						GNOME_VFS_MONITOR_FILE,
-						panel_menu_bar_gtk_bookmarks_changed,
-						menubar);
-		if (result != GNOME_VFS_OK)
-			g_warning ("Failed to add file monitor for %s: %s\n",
-				   bookmarks_uri,
-				   gnome_vfs_result_to_string (result));
-
-		g_free (bookmarks_uri);
-	} else {
-		g_warning ("Could not make URI of ~/"BOOKMARKS_FILENAME);
-	}
-
-	g_free (bookmarks_filename);
-
-	if (!volume_monitor)
-		volume_monitor = gnome_vfs_get_volume_monitor ();
-
-	menubar->priv->volume_mounted_id = g_signal_connect (volume_monitor,
-							     "volume_mounted",
-							     G_CALLBACK (panel_menu_bar_volume_changed),
-							     menubar);
-	menubar->priv->volume_unmounted_id = g_signal_connect (volume_monitor,
-							       "volume_unmounted",
-							       G_CALLBACK (panel_menu_bar_volume_changed),
-							       menubar);
-
 	menubar->priv->applications_menu = panel_menu_bar_create_applications_menu (menubar);
-	panel_menu_bar_connect_menu_signals (menubar,
-					     &menubar->priv->applications_menu);
-
-	menubar->priv->places_menu = panel_menu_bar_create_places_menu (menubar);
-	panel_menu_bar_connect_menu_signals (menubar,
-					     &menubar->priv->places_menu);
-
-	menubar->priv->desktop_menu = panel_menu_bar_create_desktop_menu (menubar);
-	panel_menu_bar_connect_menu_signals (menubar,
-					     &menubar->priv->desktop_menu);
 
 	menubar->priv->applications_item = gtk_image_menu_item_new_with_label (_("Applications"));
 	image = gtk_image_new_from_icon_name (PANEL_GNOME_LOGO_ICON,
@@ -799,18 +140,11 @@ panel_menu_bar_instance_init (PanelMenuB
 	gtk_menu_shell_append (GTK_MENU_SHELL (menubar),
 			       menubar->priv->applications_item);
 
-	menubar->priv->places_item = gtk_menu_item_new_with_label (_("Places"));
-	gtk_menu_item_set_submenu (GTK_MENU_ITEM (menubar->priv->places_item),
-				   menubar->priv->places_menu);
+	menubar->priv->places_item = panel_place_menu_item_new (FALSE);
 	gtk_menu_shell_append (GTK_MENU_SHELL (menubar),
 			       menubar->priv->places_item);
 
-	/* Translators: Desktop is used here as in "Desktop Environment" (this
-	 * is not the Desktop folder). Do not keep "Desktop Environment|" in
-	 * the translation. */
-	menubar->priv->desktop_item = gtk_menu_item_new_with_label (Q_("Desktop Environment|Desktop"));
-	gtk_menu_item_set_submenu (GTK_MENU_ITEM (menubar->priv->desktop_item),
-				   menubar->priv->desktop_menu);
+	menubar->priv->desktop_item = panel_desktop_menu_item_new (FALSE, TRUE);
 	gtk_menu_shell_append (GTK_MENU_SHELL (menubar),
 			       menubar->priv->desktop_item);
 
@@ -832,14 +166,12 @@ panel_menu_bar_parent_set (GtkWidget *wi
 		panel_applet_menu_set_recurse (GTK_MENU (menubar->priv->applications_menu),
 					       "menu_panel",
 					       menubar->priv->panel);
-	if (menubar->priv->places_menu)
-		panel_applet_menu_set_recurse (GTK_MENU (menubar->priv->places_menu),
-					       "menu_panel",
-					       menubar->priv->panel);
-	if (menubar->priv->desktop_menu)
-		panel_applet_menu_set_recurse (GTK_MENU (menubar->priv->desktop_menu),
-					       "menu_panel",
-					       menubar->priv->panel);
+	if (menubar->priv->places_item)
+		panel_place_menu_item_set_panel (menubar->priv->places_item,
+						 menubar->priv->panel);
+	if (menubar->priv->desktop_item)
+		panel_desktop_menu_item_set_panel (menubar->priv->desktop_item,
+						   menubar->priv->panel);
 }
 
 static void
@@ -871,24 +203,6 @@ panel_menu_bar_finalize (GObject *object
 
 	panel_lockdown_notify_remove (G_CALLBACK (panel_menu_bar_recreate_menus),
 				      menubar);
-
-	gconf_client_remove_dir (panel_gconf_get_client (),
-				 DESKTOP_IS_HOME_DIR_DIR,
-				 NULL);
-
-	if (menubar->priv->bookmarks_monitor != NULL)
-		gnome_vfs_monitor_cancel (menubar->priv->bookmarks_monitor);
-	menubar->priv->bookmarks_monitor = NULL;
-
-	if (menubar->priv->volume_mounted_id)
-		g_signal_handler_disconnect (volume_monitor,
-					     menubar->priv->volume_mounted_id);
-	menubar->priv->volume_mounted_id = 0;
-
-	if (menubar->priv->volume_unmounted_id)
-		g_signal_handler_disconnect (volume_monitor,
-					     menubar->priv->volume_unmounted_id);
-	menubar->priv->volume_unmounted_id = 0;
 
 	parent_class->finalize (object);
 }
Index: panel-menu-items.c
===================================================================
RCS file: panel-menu-items.c
diff -N panel-menu-items.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ panel-menu-items.c	17 Feb 2005 18:51:59 -0000
@@ -0,0 +1,966 @@
+/*
+ * Copyright (C) 2005 Vincent Untz
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Authors:
+ *	Vincent Untz <vincent@vuntz.net>
+ *
+ * Based on code from panel-menu-bar.c
+ */
+
+/*
+ * TODO:
+ *   + drag and drop loses icon for URIs
+ *   + drag and drop of bookmarks/network places/removable media should create
+ *     a menu button
+ *   + if a menu is open and gets updated, it should reappear and not just
+ *     disappear
+ */
+
+#include <config.h>
+
+#include "panel-menu-items.h"
+
+#include <string.h>
+#include <glib/gi18n.h>
+
+#include <libgnomevfs/gnome-vfs.h>
+#include <libgnomeui/gnome-url.h>
+
+#include "menu.h"
+#include "panel-action-button.h"
+#include "panel-globals.h"
+#include "panel-lockdown.h"
+#include "panel-recent.h"
+#include "panel-stock-icons.h"
+#include "panel-util.h"
+
+#define BOOKMARKS_FILENAME      ".gtk-bookmarks"
+#define DESKTOP_IS_HOME_DIR_DIR "/apps/nautilus/preferences"
+#define DESKTOP_IS_HOME_DIR_KEY "/apps/nautilus/preferences/desktop_is_home_dir"
+#define MAX_ITEMS_OR_SUBMENU    5
+
+#define PANEL_PLACE_MENU_ITEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PANEL_TYPE_PLACE_MENU_ITEM, PanelPlaceMenuItemPrivate))
+#define PANEL_DESKTOP_MENU_ITEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PANEL_TYPE_DESKTOP_MENU_ITEM, PanelDesktopMenuItemPrivate))
+
+struct _PanelPlaceMenuItemPrivate {
+	GtkWidget   *menu;
+	PanelWidget *panel;
+
+	GnomeVFSMonitorHandle *bookmarks_monitor;
+
+	gulong       volume_mounted_id;
+	gulong       volume_unmounted_id;
+
+	guint        use_image : 1;
+};
+
+struct _PanelDesktopMenuItemPrivate {
+	GtkWidget   *menu;
+	PanelWidget *panel;
+
+	guint        use_image : 1;
+	guint        append_lock_logout : 1;
+};
+
+static GObjectClass *place_parent_class;
+static GObjectClass *desktop_parent_class;
+
+static GnomeVFSVolumeMonitor *volume_monitor = NULL;
+
+static void
+activate_uri (GtkWidget *menuitem,
+	      char      *path)
+{
+	GError    *error = NULL;
+	GdkScreen *screen;
+	char      *url;
+	char      *escaped;
+
+	screen = menuitem_to_screen (menuitem);
+
+	url = gnome_vfs_make_uri_from_input_with_dirs (path,
+						       GNOME_VFS_MAKE_URI_DIR_HOMEDIR);
+	gnome_url_show_on_screen (url, screen, &error);
+
+	if (error) {
+		escaped = g_markup_escape_text (url, -1);
+		panel_error_dialog (screen, "cannot_show_url", TRUE,
+				    _("Cannot display location '%s'"),
+				    "%s",
+				    escaped,
+				    error->message);
+
+		g_error_free (error);
+		g_free (escaped);
+	}
+	g_free (url);
+}
+ 
+static void
+panel_menu_items_append_from_desktop (GtkWidget *menu,
+				      char      *path)
+{
+	GKeyFile  *key_file;
+	gboolean   loaded;
+	GtkWidget *item;
+	char      *path_freeme;
+	char      *full_path;
+	char      *icon;
+	char      *name;
+	char      *comment;
+
+	path_freeme = NULL;
+
+	key_file = g_key_file_new ();
+
+	if (g_path_is_absolute (path)) {
+		loaded = g_key_file_load_from_file (key_file, path,
+						    G_KEY_FILE_NONE, NULL);
+		full_path = path;
+	} else {
+		char *lookup_file;
+		char *desktop_path;
+
+		if (!g_str_has_suffix (path, ".desktop")) {
+			desktop_path = g_strconcat (path, ".desktop", NULL);
+		} else {
+			desktop_path = path;
+		}
+
+		lookup_file = g_strconcat ("applications", G_DIR_SEPARATOR_S,
+					   desktop_path, NULL);
+		loaded = g_key_file_load_from_data_dirs (key_file, lookup_file,
+							 &path_freeme,
+							 G_KEY_FILE_NONE,
+							 NULL);
+		full_path = path_freeme;
+		g_free (lookup_file);
+
+		if (desktop_path != path)
+			g_free (desktop_path);
+	}
+
+	if (!loaded) {
+		g_key_file_free (key_file);
+		if (path_freeme)
+			g_free (path_freeme);
+		return;
+	}
+
+	icon    = g_key_file_get_locale_string (key_file, "Desktop Entry",
+						"Icon", NULL, NULL);
+	name    = g_key_file_get_locale_string (key_file, "Desktop Entry",
+						"Name", NULL, NULL);
+	comment = g_key_file_get_locale_string (key_file, "Desktop Entry",
+						"Comment", NULL, NULL);
+
+	item = gtk_image_menu_item_new ();
+	setup_menu_item_with_icon (item, panel_menu_icon_get_size (),
+				   icon, NULL, name, TRUE);
+
+	if (comment != NULL)
+		gtk_tooltips_set_tip (panel_tooltips, item, comment, NULL);
+
+	gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+	g_signal_connect_data (item, "activate",
+			       G_CALLBACK (panel_menu_item_activate_desktop_file),
+			       g_strdup (full_path),
+			       (GClosureNotify) g_free, 0);
+	g_signal_connect (G_OBJECT (item), "button_press_event",
+			  G_CALLBACK (menu_dummy_button_press_event), NULL);
+	setup_uri_drag (item, full_path, icon);
+
+	g_key_file_free (key_file);
+
+	if (icon)
+		g_free (icon);
+
+	if (name)
+		g_free (name);
+
+	if (comment)
+		g_free (comment);
+
+	if (path_freeme)
+		g_free (path_freeme);
+}
+
+static void
+panel_menu_items_append_place_item (const char *icon_name,
+				    const char *title,
+				    const char *tooltip,
+				    GtkWidget  *menu,
+				    GCallback   callback,
+				    const char *uri)
+{
+	GtkWidget *item;
+	char      *user_data;
+
+	item = gtk_image_menu_item_new ();
+	setup_menu_item_with_icon (item,
+				   panel_menu_icon_get_size (),
+				   icon_name,
+				   NULL,
+				   title,
+				   TRUE);
+
+	gtk_tooltips_set_tip (panel_tooltips,
+			      item,
+			      tooltip,
+			      NULL);
+
+	gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+
+	user_data = g_strdup (uri);
+	g_signal_connect_data (item, "activate", callback, user_data,
+			       (GClosureNotify) g_free, 0);
+
+	g_signal_connect (G_OBJECT (item), "button_press_event",
+			  G_CALLBACK (menu_dummy_button_press_event), NULL);
+
+	setup_uri_drag (item, uri, icon_name);
+}
+
+static void
+panel_place_menu_item_append_gtk_bookmarks (GtkWidget *menu)
+{
+	GtkWidget   *add_menu;
+	char        *filename;
+	char        *contents;
+	gchar      **lines;
+	GHashTable  *table;
+	int          i;
+	GSList      *add_files, *l;
+	GnomeVFSURI *uri;
+
+	filename = g_build_filename (g_get_home_dir (),
+				     BOOKMARKS_FILENAME, NULL);
+
+	if (!g_file_get_contents (filename, &contents, NULL, NULL)) {
+		g_free (filename);
+		return;
+	}
+
+	g_free (filename);
+
+	lines = g_strsplit (contents, "\n", -1);
+	g_free (contents);
+
+	table = g_hash_table_new (g_str_hash, g_str_equal);
+	add_files = NULL;
+
+	//FIXME gnome_vfs_uri_exists: could there be an authentication
+	//dialog if there's a bookmarks to sftp://something?
+	for (i = 0; lines[i]; i++) {
+		if (lines[i][0] && !g_hash_table_lookup (table, lines[i])) {
+			char *unescaped_uri;
+
+			unescaped_uri = gnome_vfs_unescape_string (lines[i],
+								   "");
+			uri = gnome_vfs_uri_new (unescaped_uri);
+			g_free (unescaped_uri);
+
+			if (!gnome_vfs_uri_exists (uri)) {
+				gnome_vfs_uri_unref (uri);
+				continue;
+			}
+
+			add_files = g_slist_prepend (add_files, uri);
+			g_hash_table_insert (table, lines[i], lines[i]);
+		}
+	}
+
+	g_hash_table_destroy (table);
+	g_strfreev (lines);
+
+	add_files = g_slist_reverse (add_files);
+
+	if (g_slist_length (add_files) <= MAX_ITEMS_OR_SUBMENU) {
+		add_menu = menu;
+	} else {
+		GtkWidget *item;
+
+		item = gtk_image_menu_item_new ();
+		setup_menu_item_with_icon (item, panel_menu_icon_get_size (),
+					   "stock_bookmark", NULL,
+					   _("Bookmarks"), TRUE);
+
+		gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+		gtk_widget_show (item);
+
+		add_menu = create_empty_menu ();
+		gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), add_menu);
+	}
+
+	for (l = add_files; l; l = l->next) {
+		char *full_uri;
+		char *display_uri;
+		char *tooltip;
+		char *basename;
+
+		uri = l->data;
+		full_uri = gnome_vfs_uri_to_string (uri,
+						    GNOME_VFS_URI_HIDE_NONE);
+
+		display_uri = gnome_vfs_format_uri_for_display (full_uri);
+		/* Translators: %s is a URI */
+		tooltip = g_strdup_printf (_("Open '%s'"), display_uri);
+		g_free (display_uri);
+
+		basename = gnome_vfs_uri_extract_short_name (uri);
+		panel_menu_items_append_place_item ("gnome-fs-directory",
+						    basename,
+						    tooltip,
+						    add_menu,
+						    G_CALLBACK (activate_uri),
+						    full_uri);
+
+		g_free (basename);
+		g_free (tooltip);
+		g_free (full_uri);
+		gnome_vfs_uri_unref (uri);
+	}
+
+	g_slist_free (add_files);
+}
+
+static void
+panel_place_menu_item_append_volumes (GtkWidget *menu,
+				      gboolean   connected_volumes)
+{
+	GtkWidget *add_menu;
+	GList     *volumes, *l;
+	GSList    *add_volumes, *sl;
+
+	volumes = gnome_vfs_volume_monitor_get_mounted_volumes (volume_monitor);
+	add_volumes = NULL;
+
+	for (l = volumes; l; l = l->next) {
+		GnomeVFSVolume *volume = l->data;
+
+		if (!gnome_vfs_volume_is_user_visible (volume) ||
+		    !gnome_vfs_volume_is_mounted (volume))
+			continue;
+
+		switch (gnome_vfs_volume_get_volume_type (volume)) {
+		case GNOME_VFS_VOLUME_TYPE_CONNECTED_SERVER:
+			if (connected_volumes)
+				add_volumes = g_slist_prepend (add_volumes,
+							       volume);
+			break;
+		default:
+			if (!connected_volumes)
+				add_volumes = g_slist_prepend (add_volumes,
+							       volume);
+			break;
+		}
+	}
+
+	add_volumes = g_slist_reverse (add_volumes);
+
+	if (g_slist_length (add_volumes) <= MAX_ITEMS_OR_SUBMENU) {
+		add_menu = menu;
+	} else {
+		GtkWidget *item;
+
+		if (connected_volumes)
+			item = gtk_menu_item_new_with_label (_("Network Places"));
+		else
+			item = gtk_menu_item_new_with_label (_("Removable Media"));
+
+		gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+		gtk_widget_show (item);
+
+		add_menu = create_empty_menu ();
+		gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), add_menu);
+	}
+
+	for (sl = add_volumes; sl; sl = sl->next) {
+		GnomeVFSVolume *volume = sl->data;
+		char           *icon;
+		char           *display_name;
+		char           *activation_uri;
+
+		icon           = gnome_vfs_volume_get_icon (volume);
+		display_name   = gnome_vfs_volume_get_display_name (volume);
+		activation_uri = gnome_vfs_volume_get_activation_uri (volume);
+
+		panel_menu_items_append_place_item (icon,
+						    display_name,
+						    display_name, //FIXME tooltip
+						    add_menu,
+						    G_CALLBACK (activate_uri),
+						    activation_uri);
+
+		g_free (icon);
+		g_free (display_name);
+		g_free (activation_uri);
+	}
+
+	g_slist_free (add_volumes);
+
+	g_list_foreach (volumes, (GFunc) gnome_vfs_volume_unref, NULL);
+	g_list_free (volumes);
+}
+
+
+static GtkWidget *
+panel_place_menu_item_create_menu (void)
+{
+	GtkWidget *places_menu;
+	GtkWidget *item;
+
+	places_menu = panel_create_menu ();
+
+	panel_menu_items_append_from_desktop (places_menu,
+					      "nautilus-home.desktop");
+
+	if (!gconf_client_get_bool (panel_gconf_get_client (),
+				    DESKTOP_IS_HOME_DIR_KEY,
+				    NULL))
+		panel_menu_items_append_place_item (
+				"gnome-fs-desktop",
+				/* Translators: Desktop is used here as in
+				 * "Desktop Folder" (this is not the Desktop
+				 * environment). Do not keep "Desktop Folder|"
+				 * in the translation */
+				Q_("Desktop Folder|Desktop"),
+				_("Open the desktop as a folder"),
+				places_menu,
+				G_CALLBACK (activate_uri),
+				"Desktop");
+
+	panel_place_menu_item_append_gtk_bookmarks (places_menu);
+	add_menu_separator (places_menu);
+
+	panel_menu_items_append_from_desktop (places_menu,
+					      "nautilus-computer.desktop");
+	panel_place_menu_item_append_volumes (places_menu, FALSE);
+	add_menu_separator (places_menu);
+
+	panel_menu_items_append_from_desktop (places_menu,
+					      "network-scheme.desktop");
+	panel_place_menu_item_append_volumes (places_menu, TRUE);
+
+	if (panel_is_program_in_path ("nautilus-connect-server")) {
+		item = panel_menu_items_create_action_item (PANEL_ACTION_CONNECT_SERVER);
+		if (item != NULL)
+			gtk_menu_shell_append (GTK_MENU_SHELL (places_menu),
+					       item);
+	}
+
+	add_menu_separator (places_menu);
+
+	panel_menu_items_append_from_desktop (places_menu,
+					      "gnome-search-tool.desktop");
+
+	panel_recent_append_documents_menu (places_menu);
+
+	return places_menu;
+}
+
+static void
+panel_place_menu_item_recreate_menu (GtkWidget *widget)
+{
+	PanelPlaceMenuItem *place_item;
+
+	place_item = PANEL_PLACE_MENU_ITEM (widget);
+
+	if (place_item->priv->menu) {
+		gtk_widget_destroy (place_item->priv->menu);
+		place_item->priv->menu = panel_place_menu_item_create_menu ();
+		gtk_menu_item_set_submenu (GTK_MENU_ITEM (place_item),
+					   place_item->priv->menu);
+		panel_applet_menu_set_recurse (GTK_MENU (place_item->priv->menu),
+					       "menu_panel",
+					       place_item->priv->panel);
+	}
+}
+
+static void
+panel_place_menu_item_is_home_dir_changed (GConfClient *client,
+					   guint        cnxn_id,
+					   GConfEntry  *entry,
+					   GtkWidget   *place_item)
+{
+	panel_place_menu_item_recreate_menu (place_item);
+}
+
+static void
+panel_place_menu_item_gtk_bookmarks_changed (GnomeVFSMonitorHandle *handle,
+					     const gchar *monitor_uri,
+					     const gchar *info_uri,
+					     GnomeVFSMonitorEventType event_type,
+					     gpointer user_data)
+{
+	panel_place_menu_item_recreate_menu (GTK_WIDGET (user_data));
+}
+
+static void
+panel_place_menu_item_volume_changed (GnomeVFSVolumeMonitor *monitor,
+				      GnomeVFSVolume        *volume,
+				      GtkWidget             *place_menu)
+{
+	panel_place_menu_item_recreate_menu (place_menu);
+}
+
+static void
+panel_desktop_menu_item_append_menu (GtkWidget            *menu,
+				     PanelDesktopMenuItem *parent)
+{
+	gboolean   add_separator;
+	GList     *children;
+	GtkWidget *item;
+
+	if (!g_object_get_data (G_OBJECT (menu), "panel-menu-needs-appending"))
+		return;
+
+	g_object_set_data (G_OBJECT (menu), "panel-menu-needs-appending", NULL);
+
+	add_separator = FALSE;
+	children = gtk_container_get_children (GTK_CONTAINER (menu));
+
+	if (children != NULL) {
+		while (children->next != NULL)
+			children = children->next;
+		add_separator = !GTK_IS_SEPARATOR (GTK_WIDGET (children->data));
+	}
+
+	if (add_separator)
+		add_menu_separator (menu);
+
+	if (panel_is_program_in_path ("gnome-screenshot")) {
+		item = panel_menu_items_create_action_item (PANEL_ACTION_SCREENSHOT);
+		if (item != NULL)
+			gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+	}
+
+	panel_menu_items_append_from_desktop (menu, "yelp.desktop");
+	panel_menu_items_append_from_desktop (menu, "gnome-about.desktop");
+
+	if (parent->priv->append_lock_logout)
+		panel_menu_items_append_lock_logout (menu);
+}
+
+static GtkWidget *
+panel_desktop_menu_item_create_menu (PanelDesktopMenuItem *desktop_item)
+{
+	GtkWidget *desktop_menu;
+
+	desktop_menu = create_applications_menu ("settings.menu", NULL);
+
+	g_signal_connect (desktop_menu, "show",
+			  G_CALLBACK (panel_desktop_menu_item_append_menu),
+			  desktop_item);
+
+	return desktop_menu;
+}
+
+static void
+panel_desktop_menu_item_recreate_menu (PanelDesktopMenuItem *desktop_item)
+{
+	if (desktop_item->priv->menu) {
+		gtk_widget_destroy (desktop_item->priv->menu);
+		desktop_item->priv->menu = panel_desktop_menu_item_create_menu (desktop_item);
+		gtk_menu_item_set_submenu (GTK_MENU_ITEM (desktop_item),
+					   desktop_item->priv->menu);
+		panel_applet_menu_set_recurse (GTK_MENU (desktop_item->priv->menu),
+					       "menu_panel",
+					       desktop_item->priv->panel);
+	}
+}
+
+static void
+panel_place_menu_item_finalize (GObject *object)
+{
+	PanelPlaceMenuItem *menuitem = (PanelPlaceMenuItem *) object;
+
+	gconf_client_remove_dir (panel_gconf_get_client (),
+				 DESKTOP_IS_HOME_DIR_DIR,
+				 NULL);
+
+	if (menuitem->priv->bookmarks_monitor != NULL)
+		gnome_vfs_monitor_cancel (menuitem->priv->bookmarks_monitor);
+	menuitem->priv->bookmarks_monitor = NULL;
+
+	if (menuitem->priv->volume_mounted_id)
+		g_signal_handler_disconnect (volume_monitor,
+					     menuitem->priv->volume_mounted_id);
+	menuitem->priv->volume_mounted_id = 0;
+
+	if (menuitem->priv->volume_unmounted_id)
+		g_signal_handler_disconnect (volume_monitor,
+					     menuitem->priv->volume_unmounted_id);
+	menuitem->priv->volume_unmounted_id = 0;
+
+	place_parent_class->finalize (object);
+}
+
+static void
+panel_desktop_menu_item_finalize (GObject *object)
+{
+	PanelDesktopMenuItem *menuitem = (PanelDesktopMenuItem *) object;
+
+	if (menuitem->priv->append_lock_logout)
+		panel_lockdown_notify_remove (G_CALLBACK (panel_desktop_menu_item_recreate_menu),
+					      menuitem);
+	desktop_parent_class->finalize (object);
+}
+
+static void
+panel_place_menu_item_instance_init (PanelPlaceMenuItem      *menuitem,
+				     PanelPlaceMenuItemClass *klass)
+{
+	char *bookmarks_filename;
+	char *bookmarks_uri;
+
+	menuitem->priv = PANEL_PLACE_MENU_ITEM_GET_PRIVATE (menuitem);
+
+	gconf_client_add_dir (panel_gconf_get_client (),
+			      DESKTOP_IS_HOME_DIR_DIR,
+			      GCONF_CLIENT_PRELOAD_NONE,
+			      NULL);
+
+	panel_gconf_notify_add_while_alive (DESKTOP_IS_HOME_DIR_KEY,
+					    (GConfClientNotifyFunc) panel_place_menu_item_is_home_dir_changed,
+					    G_OBJECT (menuitem));
+
+	bookmarks_filename = g_build_filename (g_get_home_dir (),
+					       BOOKMARKS_FILENAME, NULL);
+	bookmarks_uri = gnome_vfs_get_uri_from_local_path (bookmarks_filename);
+
+	if (bookmarks_uri) {
+		GnomeVFSResult result;
+		result = gnome_vfs_monitor_add (&menuitem->priv->bookmarks_monitor,
+						bookmarks_uri,
+						GNOME_VFS_MONITOR_FILE,
+						panel_place_menu_item_gtk_bookmarks_changed,
+						menuitem);
+		if (result != GNOME_VFS_OK)
+			g_warning ("Failed to add file monitor for %s: %s\n",
+				   bookmarks_uri,
+				   gnome_vfs_result_to_string (result));
+
+		g_free (bookmarks_uri);
+	} else {
+		g_warning ("Could not make URI of ~/"BOOKMARKS_FILENAME);
+	}
+
+	g_free (bookmarks_filename);
+
+	if (!volume_monitor)
+		volume_monitor = gnome_vfs_get_volume_monitor ();
+
+	menuitem->priv->volume_mounted_id = g_signal_connect (volume_monitor,
+							      "volume_mounted",
+							      G_CALLBACK (panel_place_menu_item_volume_changed),
+							      menuitem);
+	menuitem->priv->volume_unmounted_id = g_signal_connect (volume_monitor,
+							        "volume_unmounted",
+							        G_CALLBACK (panel_place_menu_item_volume_changed),
+							        menuitem);
+
+}
+
+static void
+panel_desktop_menu_item_instance_init (PanelDesktopMenuItem      *menuitem,
+				       PanelDesktopMenuItemClass *klass)
+{
+	menuitem->priv = PANEL_DESKTOP_MENU_ITEM_GET_PRIVATE (menuitem);
+}
+
+static void
+panel_place_menu_item_class_init (PanelPlaceMenuItemClass *klass)
+{
+	GObjectClass *gobject_class = (GObjectClass   *) klass;
+
+	place_parent_class = g_type_class_peek_parent (klass);
+	gobject_class->finalize  = panel_place_menu_item_finalize;
+
+	g_type_class_add_private (klass, sizeof (PanelPlaceMenuItemPrivate));
+}
+
+static void
+panel_desktop_menu_item_class_init (PanelDesktopMenuItemClass *klass)
+{
+	GObjectClass *gobject_class = (GObjectClass   *) klass;
+
+	desktop_parent_class = g_type_class_peek_parent (klass);
+	gobject_class->finalize  = panel_desktop_menu_item_finalize;
+
+	g_type_class_add_private (klass, sizeof (PanelDesktopMenuItemPrivate));
+}
+
+GType
+panel_place_menu_item_get_type (void)
+{
+	static GType type = 0;
+
+	if (!type) {
+		static const GTypeInfo info = {
+			sizeof (PanelPlaceMenuItemClass),
+			NULL,
+			NULL,
+			(GClassInitFunc) panel_place_menu_item_class_init,
+			NULL,
+			NULL,
+			sizeof (PanelPlaceMenuItem),
+			0,
+			(GInstanceInitFunc) panel_place_menu_item_instance_init,
+			NULL
+		};
+
+		type = g_type_register_static (GTK_TYPE_IMAGE_MENU_ITEM,
+					       "PanelPlaceMenuItem", &info, 0);
+	}
+
+	return type;
+}
+
+GType
+panel_desktop_menu_item_get_type (void)
+{
+	static GType type = 0;
+
+	if (!type) {
+		static const GTypeInfo info = {
+			sizeof (PanelDesktopMenuItemClass),
+			NULL,
+			NULL,
+			(GClassInitFunc) panel_desktop_menu_item_class_init,
+			NULL,
+			NULL,
+			sizeof (PanelDesktopMenuItem),
+			0,
+			(GInstanceInitFunc) panel_desktop_menu_item_instance_init,
+			NULL
+		};
+
+		type = g_type_register_static (GTK_TYPE_IMAGE_MENU_ITEM,
+					       "PanelDesktopMenuItem", &info, 0);
+	}
+
+	return type;
+}
+
+
+GtkWidget *
+panel_place_menu_item_new (gboolean use_image)
+{
+	PanelPlaceMenuItem *menuitem;
+	GtkWidget          *accel_label;
+
+	menuitem = g_object_new (PANEL_TYPE_PLACE_MENU_ITEM, NULL);
+
+	accel_label = gtk_accel_label_new (_("Places"));
+	gtk_misc_set_alignment (GTK_MISC (accel_label), 0.0, 0.5);
+
+	gtk_container_add (GTK_CONTAINER (menuitem), accel_label);
+	gtk_accel_label_set_accel_widget (GTK_ACCEL_LABEL (accel_label),
+					  GTK_WIDGET (menuitem));
+	gtk_widget_show (accel_label);
+
+	menuitem->priv->use_image = use_image;
+	if (use_image) {
+		GtkWidget *image;
+
+		image = gtk_image_new_from_icon_name ("gnome-applications",
+						      panel_menu_icon_get_size ());
+
+		gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem),
+					       image);
+	}
+
+	menuitem->priv->menu = panel_place_menu_item_create_menu ();
+	gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem),
+				   menuitem->priv->menu);
+
+	return GTK_WIDGET (menuitem);
+}
+
+GtkWidget *
+panel_desktop_menu_item_new (gboolean use_image,
+			     gboolean append_lock_logout)
+{
+	PanelDesktopMenuItem *menuitem;
+	GtkWidget            *accel_label;
+
+	menuitem = g_object_new (PANEL_TYPE_DESKTOP_MENU_ITEM, NULL);
+
+	/* Translators: Desktop is used here as in "Desktop Environment" (this
+	 * is not the Desktop folder). Do not keep "Desktop Environment|" in
+	 * the translation. */
+	accel_label = gtk_accel_label_new (Q_("Desktop Environment|Desktop"));
+	gtk_misc_set_alignment (GTK_MISC (accel_label), 0.0, 0.5);
+
+	gtk_container_add (GTK_CONTAINER (menuitem), accel_label);
+	gtk_accel_label_set_accel_widget (GTK_ACCEL_LABEL (accel_label),
+					  GTK_WIDGET (menuitem));
+	gtk_widget_show (accel_label);
+
+	menuitem->priv->use_image = use_image;
+	if (use_image) {
+		GtkWidget *image;
+
+		image = gtk_image_new_from_icon_name ("gnome-applications",
+						      panel_menu_icon_get_size ());
+
+		gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem),
+					       image);
+	}
+
+	menuitem->priv->append_lock_logout = append_lock_logout;
+	if (append_lock_logout)
+		panel_lockdown_notify_add (G_CALLBACK (panel_desktop_menu_item_recreate_menu),
+					   menuitem);
+
+	menuitem->priv->menu = panel_desktop_menu_item_create_menu (menuitem);
+	gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem),
+				   menuitem->priv->menu);
+
+	return GTK_WIDGET (menuitem);
+}
+
+void
+panel_place_menu_item_set_panel (GtkWidget   *item,
+				 PanelWidget *panel)
+{
+	PanelPlaceMenuItem *place_item;
+
+	place_item = PANEL_PLACE_MENU_ITEM (item);
+
+	place_item->priv->panel = panel;
+	panel_applet_menu_set_recurse (GTK_MENU (place_item->priv->menu),
+				       "menu_panel", panel);
+}
+
+void
+panel_desktop_menu_item_set_panel (GtkWidget   *item,
+				   PanelWidget *panel)
+{
+	PanelDesktopMenuItem *desktop_item;
+
+	desktop_item = PANEL_DESKTOP_MENU_ITEM (item);
+
+	desktop_item->priv->panel = panel;
+	panel_applet_menu_set_recurse (GTK_MENU (desktop_item->priv->menu),
+				       "menu_panel", panel);
+}
+
+GtkWidget *
+panel_menu_items_create_action_item (PanelActionButtonType action_type)
+{
+	GtkWidget *item;
+
+	if (panel_action_get_is_disabled (action_type))
+		return NULL;
+
+	item = gtk_image_menu_item_new ();
+        setup_menu_item_with_icon (item,
+				   panel_menu_icon_get_size (),
+				   panel_action_get_icon_name (action_type),
+				   NULL,
+				   panel_action_get_text (action_type),
+				   TRUE);
+
+	gtk_tooltips_set_tip (panel_tooltips,
+			      item,
+			      panel_action_get_tooltip (action_type),
+			      NULL);
+
+	g_signal_connect (item, "activate",
+			  panel_action_get_invoke (action_type), NULL);
+	g_signal_connect (G_OBJECT (item), "button_press_event",
+			  G_CALLBACK (menu_dummy_button_press_event), NULL);
+	setup_internal_applet_drag (item, action_type);
+
+	return item;
+}
+
+void
+panel_menu_items_append_lock_logout (GtkWidget *menu)
+{
+	gboolean   separator_inserted;
+	GList     *children;
+	GtkWidget *item;
+
+	separator_inserted = FALSE;
+	children = gtk_container_get_children (GTK_CONTAINER (menu));
+
+	if (children != NULL) {
+		while (children->next != NULL)
+			children = children->next;
+		separator_inserted = GTK_IS_SEPARATOR (GTK_WIDGET (children->data));
+	}
+
+	if (panel_is_program_in_path ("xscreensaver")) {
+		item = panel_menu_items_create_action_item (PANEL_ACTION_LOCK);
+		if (item != NULL) {
+			if (!separator_inserted) {
+				add_menu_separator (menu);
+				separator_inserted = TRUE;
+			}
+
+			gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+		}
+	}
+
+	item = panel_menu_items_create_action_item (PANEL_ACTION_LOGOUT);
+	if (item != NULL) {
+		if (!separator_inserted)
+			add_menu_separator (menu);
+
+		gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+	}
+}
+
+void
+panel_menu_item_activate_desktop_file (GtkWidget  *menuitem,
+				       const char *path)
+{
+	GnomeDesktopItem *item;
+	GError           *error;
+
+	error = NULL;
+	item = gnome_desktop_item_new_from_file (path, 0, &error);
+	if (item) {
+		g_assert (error == NULL);
+
+		panel_ditem_launch (item, NULL, 0,
+				    menuitem_to_screen (menuitem), &error);
+		if (error) {
+			panel_error_dialog (menuitem_to_screen (menuitem),
+					    "cannot_launch_entry", TRUE,
+					    _("Cannot launch entry"),
+					    "%s",
+					    error->message);
+
+			g_error_free (error);
+		}
+		gnome_desktop_item_unref (item);
+	} else {
+		g_assert (error != NULL);
+
+		panel_error_dialog (menuitem_to_screen (menuitem),
+				    "cannot_load_entry", TRUE,
+				    _("Cannot load entry"),
+				    "%s",
+				    error->message);
+		g_error_free (error);
+	}
+}
Index: panel-menu-items.h
===================================================================
RCS file: panel-menu-items.h
diff -N panel-menu-items.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ panel-menu-items.h	17 Feb 2005 18:51:59 -0000
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2005 Vincent Untz
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Authors:
+ *	Vincent Untz <vincent@vuntz.net>
+ *
+ * Based on code from panel-menu-bar.c
+ */
+
+
+#ifndef __PANEL_MENU_ITEMS_H__
+#define __PANEL_MENU_ITEMS_H__
+
+#include <gtk/gtkmenuitem.h>
+#include "panel-widget.h"
+
+G_BEGIN_DECLS
+
+#define PANEL_TYPE_PLACE_MENU_ITEM         (panel_place_menu_item_get_type ())
+#define PANEL_PLACE_MENU_ITEM(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), PANEL_TYPE_PLACE_MENU_ITEM, PanelPlaceMenuItem))
+#define PANEL_PLACE_MENU_ITEM_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), PANEL_TYPE_PLACE_MENU_ITEM, PanelPlaceMenuItemClass))
+#define PANEL_IS_PLACE_MENU_ITEM(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), PANEL_TYPE_PLACE_MENU_ITEM))
+#define PANEL_IS_PLACE_MENU_ITEM_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), PANEL_TYPE_PLACE_MENU_ITEM))
+#define PANEL_PLACE_MENU_ITEM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), PANEL_TYPE_PLACE_MENU_ITEM, PanelPlaceMenuItemClass))
+
+typedef struct _PanelPlaceMenuItem        PanelPlaceMenuItem;
+typedef struct _PanelPlaceMenuItemClass   PanelPlaceMenuItemClass;
+typedef struct _PanelPlaceMenuItemPrivate PanelPlaceMenuItemPrivate;
+
+struct _PanelPlaceMenuItem{
+	GtkImageMenuItem            menuitem;
+
+	PanelPlaceMenuItemPrivate  *priv;
+};
+
+struct _PanelPlaceMenuItemClass {
+	GtkImageMenuItemClass       menuitem_class;
+};
+
+GType panel_place_menu_item_get_type (void) G_GNUC_CONST;
+
+
+
+#define PANEL_TYPE_DESKTOP_MENU_ITEM         (panel_desktop_menu_item_get_type ())
+#define PANEL_DESKTOP_MENU_ITEM(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), PANEL_TYPE_DESKTOP_MENU_ITEM, PanelDesktopMenuItem))
+#define PANEL_DESKTOP_MENU_ITEM_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), PANEL_TYPE_DESKTOP_MENU_ITEM, PanelDesktopMenuItemClass))
+#define PANEL_IS_DESKTOP_MENU_ITEM(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), PANEL_TYPE_DESKTOP_MENU_ITEM))
+#define PANEL_IS_DESKTOP_MENU_ITEM_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), PANEL_TYPE_DESKTOP_MENU_ITEM))
+#define PANEL_DESKTOP_MENU_ITEM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), PANEL_TYPE_DESKTOP_MENU_ITEM, PanelDesktopMenuItemClass))
+
+typedef struct _PanelDesktopMenuItem        PanelDesktopMenuItem;
+typedef struct _PanelDesktopMenuItemClass   PanelDesktopMenuItemClass;
+typedef struct _PanelDesktopMenuItemPrivate PanelDesktopMenuItemPrivate;
+
+struct _PanelDesktopMenuItem{
+	GtkImageMenuItem            menuitem;
+
+	PanelDesktopMenuItemPrivate  *priv;
+};
+
+struct _PanelDesktopMenuItemClass {
+	GtkImageMenuItemClass       menuitem_class;
+};
+
+GType panel_desktop_menu_item_get_type (void) G_GNUC_CONST;
+
+
+GtkWidget *panel_place_menu_item_new   (gboolean use_image);
+GtkWidget *panel_desktop_menu_item_new (gboolean use_image,
+					gboolean append_lock_logout);
+
+void panel_place_menu_item_set_panel   (GtkWidget   *item,
+					PanelWidget *panel);
+void panel_desktop_menu_item_set_panel (GtkWidget   *item,
+					PanelWidget *panel);
+
+GtkWidget *panel_menu_items_create_action_item (PanelActionButtonType action_type);
+void panel_menu_items_append_lock_logout (GtkWidget *menu);
+void panel_menu_item_activate_desktop_file (GtkWidget  *menuitem,
+					    const char *path);
+
+G_END_DECLS
+
+#endif /* __PANEL_MENU_ITEMS_H__ */
