Index: menu.c
===================================================================
RCS file: /cvs/gnome/gnome-panel/gnome-panel/menu.c,v
retrieving revision 1.729
diff -u -p -r1.729 menu.c
--- menu.c	15 Dec 2004 09:30:39 -0000	1.729
+++ menu.c	6 Jan 2005 01:07:12 -0000
@@ -1088,6 +1088,35 @@ drag_data_get_string_cb (GtkWidget *widg
 }
 
 void
+setup_uri_drag (GtkWidget  *menuitem,
+		const char *uri,
+		const char *icon)
+{
+	static GtkTargetEntry menu_item_targets[] = {
+		{ "text/uri-list", 0, 0 }
+	};
+
+	if (panel_lockdown_get_locked_down ())
+		return;
+
+	gtk_drag_source_set (menuitem,
+			     GDK_BUTTON1_MASK|GDK_BUTTON2_MASK,
+			     menu_item_targets, 1,
+			     GDK_ACTION_COPY);
+
+	/* FIXME: waiting for bug #116577
+	gtk_drag_source_set_icon_name (GTK_WIDGET (button), icon); */
+	
+	g_signal_connect_data (G_OBJECT (menuitem), "drag_data_get",
+			       G_CALLBACK (drag_data_get_string_cb),
+			       g_strdup (uri),
+			       (GClosureNotify)g_free,
+			       0 /* connect_flags */);
+	g_signal_connect (G_OBJECT (menuitem), "drag_end",
+			  G_CALLBACK (drag_end_menu_cb), NULL);
+}
+
+void
 setup_internal_applet_drag (GtkWidget             *menuitem,
 			    PanelActionButtonType  type)
 {
@@ -1284,6 +1313,10 @@ handle_menu_tree_changed (MenuTree  *tre
 
 	g_object_set_data (G_OBJECT (menu),
 			   "panel-menu-needs-loading",
+			   GUINT_TO_POINTER (TRUE));
+
+	g_object_set_data (G_OBJECT (menu),
+			   "panel-menu-needs-appending",
 			   GUINT_TO_POINTER (TRUE));
 }
 
Index: menu.h
===================================================================
RCS file: /cvs/gnome/gnome-panel/gnome-panel/menu.h,v
retrieving revision 1.102
diff -u -p -r1.102 menu.h
--- menu.h	15 Dec 2004 09:30:39 -0000	1.102
+++ menu.h	6 Jan 2005 01:07:12 -0000
@@ -50,6 +50,9 @@ GtkWidget      *create_main_menu        
 
 void		setup_internal_applet_drag (GtkWidget             *menuitem,
 					    PanelActionButtonType  type);
+void            setup_uri_drag             (GtkWidget  *menuitem,
+					    const char *uri,
+					    const char *icon);
 
 GtkWidget *	panel_create_menu              (void);
 
Index: panel-action-button.c
===================================================================
RCS file: /cvs/gnome/gnome-panel/gnome-panel/panel-action-button.c,v
retrieving revision 1.36
diff -u -p -r1.36 panel-action-button.c
--- panel-action-button.c	16 Dec 2004 20:24:05 -0000	1.36
+++ panel-action-button.c	6 Jan 2005 01:07:12 -0000
@@ -286,7 +286,7 @@ static PanelAction actions [] = {
 		PANEL_ACTION_LOCK,
 		NULL,
 		"gnome-lockscreen",
-		N_("Lock screen"),
+		N_("Lock Screen"),
 		N_("Protect your computer from unauthorized use"),
 		"gospanel-21",
 		"ACTION:lock:NEW",
Index: panel-addto.c
===================================================================
RCS file: /cvs/gnome/gnome-panel/gnome-panel/panel-addto.c,v
retrieving revision 1.23
diff -u -p -r1.23 panel-addto.c
--- panel-addto.c	1 Jan 2005 15:23:11 -0000	1.23
+++ panel-addto.c	6 Jan 2005 01:07:13 -0000
@@ -59,6 +59,7 @@ typedef struct {
 
 	GSList       *applet_list;
 	GSList       *application_list;
+	GSList       *settings_list;
 
 	guint         name_notify;
 
@@ -203,7 +204,7 @@ panel_addto_append_internal_applets (GSL
 			internal_addto_items [i].description = _(internal_addto_items [i].description);
 		}
 
-                list = g_slist_append (list, &internal_addto_items [i]);
+                list = g_slist_prepend (list, &internal_addto_items [i]);
         }
 
 	translated = TRUE;
@@ -224,7 +225,7 @@ panel_addto_append_internal_applets (GSL
 		info->iid         = (char *) panel_action_get_drag_id (i);
 		info->static_data = TRUE;
 
-                list = g_slist_append (list, info);
+                list = g_slist_prepend (list, info);
 	}
 
         return list;
@@ -424,7 +425,7 @@ panel_addto_query_applets (GSList *list)
 		applet->iid = g_strdup (info->iid);
 		applet->static_data = FALSE;
 
-		list = g_slist_append (list, applet);
+		list = g_slist_prepend (list, applet);
 	}
 
 	g_slist_free (langs_gslist);
@@ -557,7 +558,7 @@ panel_addto_make_application_list (GSLis
 		 * So the iid is built when we select the row.
 		 */
 
-		*parent_list = g_slist_append (*parent_list, data);
+		*parent_list = g_slist_prepend (*parent_list, data);
 
 		panel_addto_make_application_list (&data->children, subdir);
 
@@ -579,11 +580,13 @@ panel_addto_make_application_list (GSLis
 		data->item_info.launcher_path = g_strdup (menu_tree_entry_get_desktop_file_path (entry));
 		data->item_info.static_data = FALSE;
 
-		*parent_list = g_slist_append (*parent_list, data);
+		*parent_list = g_slist_prepend (*parent_list, data);
 
 		menu_tree_entry_unref (entry);
 	}
 	g_slist_free (entries);
+
+	*parent_list = g_slist_reverse (*parent_list);
 }
 
 static void
@@ -648,6 +651,29 @@ panel_addto_make_application_model (Pane
 
 	menu_tree_unref (tree);
 
+	tree = menu_tree_lookup ("settings.menu");
+
+	if ((root = menu_tree_get_root_directory (tree))) {
+		GtkTreeIter iter;
+
+		gtk_tree_store_append (store, &iter, NULL);
+		gtk_tree_store_set (store, &iter,
+				    COLUMN_ICON, NULL,
+				    COLUMN_TEXT, NULL,
+				    COLUMN_DATA, NULL,
+				    COLUMN_SEARCH, NULL,
+				    -1);
+
+		panel_addto_make_application_list (&dialog->settings_list,
+						   root);
+		panel_addto_populate_application_model (store, NULL,
+							dialog->settings_list);
+
+		menu_tree_directory_unref (root);
+	}
+
+	menu_tree_unref (tree);
+
 	return GTK_TREE_MODEL (store);
 }
 
@@ -866,6 +892,7 @@ panel_addto_dialog_free (PanelAddtoDialo
 	g_slist_free (dialog->applet_list);
 
 	panel_addto_dialog_free_application_list (dialog->application_list);
+	panel_addto_dialog_free_application_list (dialog->settings_list);
 
 	if (dialog->menu_tree)
 		menu_tree_unref (dialog->menu_tree);
Index: panel-context-menu.c
===================================================================
RCS file: /cvs/gnome/gnome-panel/gnome-panel/panel-context-menu.c,v
retrieving revision 1.2
diff -u -p -r1.2 panel-context-menu.c
--- panel-context-menu.c	19 Dec 2004 11:23:44 -0000	1.2
+++ panel-context-menu.c	6 Jan 2005 01:07:13 -0000
@@ -46,24 +46,6 @@
 #include "panel-addto.h"
 
 static void
-panel_context_menu_show_about_gnome (GtkWidget *menuitem,
-				     char      *program_path)
-{
-	GdkScreen *screen = menuitem_to_screen (menuitem);
-	GError    *error = NULL;
-
-	if (!gdk_spawn_command_line_on_screen (screen, program_path, &error)) {
-		panel_error_dialog (screen,
-				    "cannot_exec_about_gnome", TRUE,
-				    _("Cannot execute '%s'"),
-				    _("%s: %s"),
-				    _("About GNOME"),
-				    program_path, error->message);
-		g_error_free (error);
-	}
-}
-
-static void
 panel_context_menu_show_help (GtkWidget *w,
 			      gpointer data)
 {
@@ -312,7 +294,6 @@ panel_context_menu_create (PanelWidget *
 {
 	GtkWidget *retval;
 	GtkWidget *menuitem;
-	char      *gnome_about;
 
 	if (panel->master_widget) {
 		gpointer    *pointer;
@@ -361,23 +342,6 @@ panel_context_menu_create (PanelWidget *
 			  G_CALLBACK (panel_context_menu_show_about_dialog),
 			  NULL);
 	
-	gnome_about = g_find_program_in_path ("gnome-about");
-	if (gnome_about) {
-		add_menu_separator (retval);
-
-		menuitem = gtk_image_menu_item_new ();
-		setup_menuitem (menuitem,
-				GTK_ICON_SIZE_MENU,
-				gtk_image_new_from_stock (GTK_STOCK_ABOUT,
-							  GTK_ICON_SIZE_MENU),
-				_("About _GNOME"),
-				FALSE);
-		gtk_menu_shell_append (GTK_MENU_SHELL (retval), menuitem);
-		g_signal_connect_data (menuitem, "activate",
-				       G_CALLBACK (panel_context_menu_show_about_gnome),
-				       gnome_about, (GClosureNotify) g_free, 0);
-	}
-
 	g_object_set_data (G_OBJECT (retval), "menu_panel", panel);
 
 	return retval;
Index: panel-menu-bar.c
===================================================================
RCS file: /cvs/gnome/gnome-panel/gnome-panel/panel-menu-bar.c,v
retrieving revision 1.44
diff -u -p -r1.44 panel-menu-bar.c
--- panel-menu-bar.c	4 Jan 2005 14:30:52 -0000	1.44
+++ panel-menu-bar.c	6 Jan 2005 01:07:13 -0000
@@ -1,7 +1,8 @@
 /*
- * panel-menu-bar.c: panel Applications/Actions menu bar
+ * panel-menu-bar.c: panel Applications/Places/Desktop menu bar
  *
  * Copyright (C) 2003 Sun Microsystems, Inc.
+ * Copyright (C) 2004 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
@@ -20,6 +21,7 @@
  *
  * Authors:
  *	Mark McLoughlin <mark@skynet.ie>
+ *	Vincent Untz <vincent@vuntz.net>
  */
 
 #include <config.h>
@@ -29,6 +31,9 @@
 #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"
@@ -36,23 +41,194 @@
 #include "panel-recent.h"
 #include "applet.h"
 #include "menu.h"
+#include "panel-gconf.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
+ *   + if a menu is open and get updated, it should reappear and not just
+ *     disappear
+ *   + see FIXME
+ */
+
 #define PANEL_MENU_BAR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PANEL_TYPE_MENU_BAR, PanelMenuBarPrivate))
 
 struct _PanelMenuBarPrivate {
-	AppletInfo            *info;
-	PanelWidget           *panel;
+	AppletInfo  *info;
+	PanelWidget *panel;
+
+	GtkWidget   *applications_menu;
+	GtkWidget   *places_menu;
+	GtkWidget   *desktop_menu;
+	GtkWidget   *applications_item;
+	GtkWidget   *places_item;
+	GtkWidget   *desktop_item;
+
+	GnomeVFSMonitorHandle *bookmarks_monitor;
 
-	GtkWidget             *applications_menu;
-	GtkWidget             *actions_menu;
-	GtkWidget             *actions_item;
+	gulong       volume_mounted_id;
+	gulong       volume_unmounted_id;
 };
 
+static GnomeVFSVolumeMonitor *volume_monitor = NULL;
+
 static GObjectClass *parent_class;
-static GtkWidget *panel_menu_bar_create_actions_menu (PanelMenuBar *menubar);
+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 (path_freeme)
+		g_free (path_freeme);
+}
 
 static void
 panel_menu_bar_show_menu (PanelMenuBar *menubar,
@@ -84,65 +260,369 @@ panel_menu_bar_connect_menu_signals (Pan
 }
 
 static void
-panel_menu_bar_recreate_actions_menu (PanelMenuBar *menubar)
+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_places_menu (PanelMenuBar *menubar)
 {
-	if (menubar->priv->actions_menu) {
-		gtk_widget_destroy (menubar->priv->actions_menu);
-		menubar->priv->actions_menu = panel_menu_bar_create_actions_menu (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->actions_menu);
-		gtk_menu_item_set_submenu (GTK_MENU_ITEM (menubar->priv->actions_item),
-					   menubar->priv->actions_menu);
+						     &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 GtkWidget *
-panel_menu_bar_create_actions_menu (PanelMenuBar *menubar)
+static void
+panel_menu_bar_recreate_desktop_menu (PanelMenuBar *menubar)
+{
+	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_append_applications_menu (GtkWidget    *menu,
+					 PanelMenuBar *menubar)
 {
-	GtkWidget *actions_menu;
 	GtkWidget *item;
-	gboolean   separator_inserted;
-	gboolean   last_is_separator;
 
-	actions_menu = panel_create_menu ();
+	if (!g_object_get_data (G_OBJECT (menu), "panel-menu-needs-appending"))
+		return;
 
-	last_is_separator = FALSE;
+	g_object_set_data (G_OBJECT (menu), "panel-menu-needs-appending", NULL);
 
 	item = menu_create_action_item (PANEL_ACTION_RUN);
-	if (item != NULL) {
-		gtk_menu_shell_append (GTK_MENU_SHELL (actions_menu), item);
-		add_menu_separator (actions_menu);
-		last_is_separator = TRUE;
+
+	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);
 	}
+}
 
-	if (panel_is_program_in_path  ("gnome-search-tool")) {
-		item = menu_create_action_item (PANEL_ACTION_SEARCH);
-		if (item != NULL) {
-			gtk_menu_shell_append (GTK_MENU_SHELL (actions_menu),
-					       item);
-			last_is_separator = FALSE;
+static GtkWidget *
+panel_menu_bar_create_applications_menu (PanelMenuBar *menubar)
+{
+	GtkWidget *applications_menu;
+
+	applications_menu = create_applications_menu ("applications.menu", NULL);
+
+	g_object_set_data (G_OBJECT (applications_menu),
+			   "panel-menu-needs-appending",
+			   GUINT_TO_POINTER (TRUE));
+
+	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)
+{
+	char *filename;
+	char *contents;
+
+	filename = g_build_filename (g_get_home_dir (),
+				     BOOKMARKS_FILENAME, NULL);
+
+	if (g_file_get_contents (filename, &contents, NULL, NULL)) {
+		gchar      **lines;
+		GHashTable  *table;
+		int          i;
+		GnomeVFSURI *uri;
+		char        *basename;
+		char        *display_uri;
+		char        *tooltip;
+
+		lines = g_strsplit (contents, "\n", -1);
+		table = g_hash_table_new (g_str_hash, g_str_equal);
+
+		//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])) {
+				uri = gnome_vfs_uri_new (lines[i]);
+				if (!gnome_vfs_uri_exists (uri)) {
+					gnome_vfs_uri_unref (uri);
+					continue;
+				}
+
+				display_uri = gnome_vfs_format_uri_for_display (lines[i]);
+				/* 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,
+						menu,
+						G_CALLBACK (activate_uri),
+						lines[i]);
+
+				g_hash_table_insert (table, lines[i], lines[i]);
+
+				g_free (basename);
+				g_free (tooltip);
+				gnome_vfs_uri_unref (uri);
+			}
 		}
+
+		g_free (contents);
+		g_hash_table_destroy (table);
+		g_strfreev (lines);
+	}
+
+	g_free (filename);
+}
+
+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;
+		}
+	}
+
+	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);
+
+		add_menu = gtk_menu_new (); //FIXME parent_set lorsqu'il est reconstruit?
+		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);
 	}
 
-	panel_recent_append_documents_menu (actions_menu);
+	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;
+
+	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",
+						  _("Desktop"),
+						  _("Desktop directory"),
+						  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 0
+	item = menu_create_action_item (PANEL_ACTION_CONNECT_SERVER);
+	if (item != NULL)
+		gtk_menu_shell_append (GTK_MENU_SHELL (places_menu), item);
+#endif
+
+	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) {
-			if (!last_is_separator)
-				add_menu_separator (actions_menu);
-			gtk_menu_shell_append (GTK_MENU_SHELL (actions_menu),
+		if (item != NULL)
+			gtk_menu_shell_append (GTK_MENU_SHELL (desktop_menu),
 					       item);
-			last_is_separator = FALSE;
-		}
 	}
 
+	panel_menu_bar_append_from_desktop (desktop_menu,
+					    "yelp.desktop");
+
+	panel_menu_bar_append_from_desktop (desktop_menu,
+					    "gnome-about.desktop");
+
 	separator_inserted = FALSE;
 
 	item = menu_create_action_item (PANEL_ACTION_LOCK);
 	if (item != NULL) {
-		add_menu_separator (actions_menu);
-		gtk_menu_shell_append (GTK_MENU_SHELL (actions_menu), item);
+		add_menu_separator (desktop_menu);
+		gtk_menu_shell_append (GTK_MENU_SHELL (desktop_menu), item);
 		separator_inserted = TRUE;
 	}
 
@@ -151,50 +631,123 @@ panel_menu_bar_create_actions_menu (Pane
 
 		if (item != NULL) {
 			if (!separator_inserted)
-				add_menu_separator (actions_menu);
-			gtk_menu_shell_append (GTK_MENU_SHELL (actions_menu),
+				add_menu_separator (desktop_menu);
+			gtk_menu_shell_append (GTK_MENU_SHELL (desktop_menu),
 					       item);
 		}
 	}
+}
+
+static GtkWidget *
+panel_menu_bar_create_desktop_menu (PanelMenuBar *menubar)
+{
+	GtkWidget *desktop_menu;
+
+	desktop_menu = create_applications_menu ("settings.menu", NULL);
+
+	g_object_set_data (G_OBJECT (desktop_menu),
+			   "panel-menu-needs-appending",
+			   GUINT_TO_POINTER (TRUE));
 
-	return actions_menu;
+	g_signal_connect (desktop_menu, "show",
+			  G_CALLBACK (panel_menu_bar_append_desktop_menu),
+			  menubar);
+
+	return desktop_menu;
 }
 
 static void
 panel_menu_bar_instance_init (PanelMenuBar      *menubar,
 			      PanelMenuBarClass *klass)
 {
-	GtkWidget *item;
 	GtkWidget *image;
+	char      *bookmarks_filename;
+	char      *bookmarks_uri;
 
 	menubar->priv = PANEL_MENU_BAR_GET_PRIVATE (menubar);
 
 	menubar->priv->info = NULL;
 
-	menubar->priv->applications_menu = create_applications_menu ("applications.menu", 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->actions_menu = panel_menu_bar_create_actions_menu (menubar);
+	menubar->priv->places_menu = panel_menu_bar_create_places_menu (menubar);
 	panel_menu_bar_connect_menu_signals (menubar,
-					     &menubar->priv->actions_menu);
+					     &menubar->priv->places_menu);
 
-	item = gtk_image_menu_item_new_with_label (_("Applications"));
+	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_stock (PANEL_STOCK_GNOME_LOGO,
 					  panel_menu_bar_icon_get_size ());
-	gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
+	gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menubar->priv->applications_item),
+				       image);
 
-	gtk_menu_item_set_submenu (GTK_MENU_ITEM (item),
+	gtk_menu_item_set_submenu (GTK_MENU_ITEM (menubar->priv->applications_item),
 				   menubar->priv->applications_menu);
-	gtk_menu_shell_append (GTK_MENU_SHELL (menubar), item);
+	gtk_menu_shell_append (GTK_MENU_SHELL (menubar),
+			       menubar->priv->applications_item);
 
-	menubar->priv->actions_item = gtk_menu_item_new_with_label (_("Actions"));
-	gtk_menu_item_set_submenu (GTK_MENU_ITEM (menubar->priv->actions_item),
-				   menubar->priv->actions_menu);
+	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);
 	gtk_menu_shell_append (GTK_MENU_SHELL (menubar),
-			       menubar->priv->actions_item);
+			       menubar->priv->places_item);
 
-	panel_lockdown_notify_add (G_CALLBACK (panel_menu_bar_recreate_actions_menu),
+	menubar->priv->desktop_item = gtk_menu_item_new_with_label (_("Desktop"));
+	gtk_menu_item_set_submenu (GTK_MENU_ITEM (menubar->priv->desktop_item),
+				   menubar->priv->desktop_menu);
+	gtk_menu_shell_append (GTK_MENU_SHELL (menubar),
+			       menubar->priv->desktop_item);
+
+	panel_lockdown_notify_add (G_CALLBACK (panel_menu_bar_recreate_desktop_menu),
 				   menubar);
 }
 
@@ -208,12 +761,18 @@ panel_menu_bar_parent_set (GtkWidget *wi
 
 	menubar->priv->panel = (PanelWidget *) widget->parent;
 
-	panel_applet_menu_set_recurse (GTK_MENU (menubar->priv->applications_menu),
-				       "menu_panel",
-				       menubar->priv->panel);
-	panel_applet_menu_set_recurse (GTK_MENU (menubar->priv->actions_menu),
-				       "menu_panel",
-				       menubar->priv->panel);
+	if (menubar->priv->applications_menu)
+		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);
 }
 
 static void
@@ -239,12 +798,43 @@ panel_menu_bar_size_allocate (GtkWidget 
 }
 
 static void
+panel_menu_bar_finalize (GObject *object)
+{
+	PanelMenuBar *menubar = (PanelMenuBar *) object;
+
+	panel_lockdown_notify_remove (G_CALLBACK (panel_menu_bar_recreate_desktop_menu),
+				      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);
+}
+
+static void
 panel_menu_bar_class_init (PanelMenuBarClass *klass)
 {
+	GObjectClass   *gobject_class   = (GObjectClass   *) klass;
 	GtkWidgetClass *widget_class = (GtkWidgetClass *) klass;
 
 	parent_class = g_type_class_peek_parent (klass);
 
+	gobject_class->finalize  = panel_menu_bar_finalize;
 	widget_class->parent_set = panel_menu_bar_parent_set;
 	widget_class->size_allocate = panel_menu_bar_size_allocate;
 
