[nautilus: 3/4] sidebar: redesign the Places sidebar



commit a59e586adf32eea64c9c4ae08a5482d2a9c37fb1
Author: Cosimo Cecchi <cosimoc gnome org>
Date:   Wed Aug 25 19:58:39 2010 +0200

    sidebar: redesign the Places sidebar
    
    According to http://live.gnome.org/Nautilus/UIRoadmap/Places

 src/nautilus-places-sidebar.c |  764 ++++++++++++++++++++++++++++-------------
 1 files changed, 522 insertions(+), 242 deletions(-)
---
diff --git a/src/nautilus-places-sidebar.c b/src/nautilus-places-sidebar.c
index 810cef1..cc8548a 100644
--- a/src/nautilus-places-sidebar.c
+++ b/src/nautilus-places-sidebar.c
@@ -52,13 +52,16 @@
 #include "nautilus-places-sidebar.h"
 #include "nautilus-window.h"
 
-#define EJECT_BUTTON_XPAD 5
+#define EJECT_BUTTON_XPAD 6
+#define ICON_CELL_XPAD 6
 
 typedef struct {
 	GtkScrolledWindow  parent;
 	GtkTreeView        *tree_view;
-	GtkCellRenderer    *icon_cell_renderer;
 	GtkCellRenderer    *eject_text_cell_renderer;
+	GtkCellRenderer    *icon_cell_renderer;
+	GtkCellRenderer    *icon_padding_cell_renderer;
+	GtkCellRenderer    *padding_cell_renderer;
 	char 	           *uri;
 	GtkListStore       *store;
 	GtkTreeModel       *filter_model;
@@ -66,6 +69,9 @@ typedef struct {
 	NautilusBookmarkList *bookmarks;
 	GVolumeMonitor *volume_monitor;
 
+	gboolean devices_header_added;
+	gboolean bookmarks_header_added;
+
 	/* DnD */
 	GList     *drag_list;
 	gboolean  drag_data_received;
@@ -118,10 +124,11 @@ enum {
 	PLACES_SIDEBAR_COLUMN_EJECT,
 	PLACES_SIDEBAR_COLUMN_NO_EJECT,
 	PLACES_SIDEBAR_COLUMN_BOOKMARK,
-	PLACES_SIDEBAR_COLUMN_NO_BOOKMARK,
 	PLACES_SIDEBAR_COLUMN_TOOLTIP,
 	PLACES_SIDEBAR_COLUMN_EJECT_ICON,
-	
+	PLACES_SIDEBAR_COLUMN_SECTION_TYPE,
+	PLACES_SIDEBAR_COLUMN_HEADING_TEXT,
+
 	PLACES_SIDEBAR_COLUMN_COUNT
 };
 
@@ -129,9 +136,16 @@ typedef enum {
 	PLACES_BUILT_IN,
 	PLACES_MOUNTED_VOLUME,
 	PLACES_BOOKMARK,
-	PLACES_SEPARATOR
+	PLACES_HEADING,
 } PlaceType;
 
+typedef enum {
+	SECTION_DEVICES,
+	SECTION_BOOKMARKS,
+	SECTION_COMPUTER,
+	SECTION_NETWORK,
+} SectionType;
+
 static void  nautilus_places_sidebar_iface_init        (NautilusSidebarIface         *iface);
 static void  sidebar_provider_iface_init               (NautilusSidebarProviderIface *iface);
 static GType nautilus_places_sidebar_provider_get_type (void);
@@ -228,9 +242,82 @@ get_eject_icon (gboolean highlighted)
 	return eject;
 }
 
+static gboolean
+is_built_in_bookmark (NautilusFile *file)
+{
+	gboolean built_in;
+	gint idx;
+
+	built_in = FALSE;
+
+	for (idx = 0; idx < G_USER_N_DIRECTORIES; idx++) {
+		/* PUBLIC_SHARE and TEMPLATES are not in our built-in list */
+		if (nautilus_file_is_user_special_directory (file, idx)) {
+			if (idx != G_USER_DIRECTORY_PUBLIC_SHARE &&  idx != G_USER_DIRECTORY_TEMPLATES) {
+				built_in = TRUE;
+			}
+
+			break;
+		}
+	}
+
+	return built_in;
+}
+
+static GtkTreeIter
+add_heading (NautilusPlacesSidebar *sidebar,
+	     SectionType section_type,
+	     const gchar *title)
+{
+	GtkTreeIter iter, child_iter;
+
+	gtk_list_store_append (sidebar->store, &iter);
+	gtk_list_store_set (sidebar->store, &iter,
+			    PLACES_SIDEBAR_COLUMN_ROW_TYPE, PLACES_HEADING,
+			    PLACES_SIDEBAR_COLUMN_SECTION_TYPE, section_type,	
+			    PLACES_SIDEBAR_COLUMN_HEADING_TEXT, title,
+			    PLACES_SIDEBAR_COLUMN_EJECT, FALSE,
+			    PLACES_SIDEBAR_COLUMN_NO_EJECT, TRUE,
+			    -1);
+
+	gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (sidebar->filter_model));
+	gtk_tree_model_filter_convert_child_iter_to_iter (GTK_TREE_MODEL_FILTER (sidebar->filter_model),
+							  &child_iter,
+							  &iter);
+
+	return child_iter;
+}
+
+static void
+check_heading_for_section (NautilusPlacesSidebar *sidebar,
+			   SectionType section_type)
+{
+	switch (section_type) {
+	case SECTION_DEVICES:
+		if (!sidebar->devices_header_added) {
+			add_heading (sidebar, SECTION_DEVICES,
+				     _("Devices"));
+			sidebar->devices_header_added = TRUE;
+		}
+
+		break;
+	case SECTION_BOOKMARKS:
+		if (!sidebar->bookmarks_header_added) {
+			add_heading (sidebar, SECTION_BOOKMARKS,
+				     _("Bookmarks"));
+			sidebar->bookmarks_header_added = TRUE;
+		}
+
+		break;
+	default:
+		break;
+	}
+}
+
 static GtkTreeIter
 add_place (NautilusPlacesSidebar *sidebar,
 	   PlaceType place_type,
+	   SectionType section_type,
 	   const char *name,
 	   GIcon *icon,
 	   const char *uri,
@@ -248,11 +335,14 @@ add_place (NautilusPlacesSidebar *sidebar,
 	gboolean show_eject, show_unmount;
 	gboolean show_eject_button;
 
+	check_heading_for_section (sidebar, section_type);
+
 	icon_size = nautilus_get_icon_size_for_stock_size (GTK_ICON_SIZE_MENU);
 	icon_info = nautilus_icon_info_lookup (icon, icon_size);
 
 	pixbuf = nautilus_icon_info_get_pixbuf_at_size (icon_info, icon_size);
 	g_object_unref (icon_info);
+
 	check_unmount_and_eject (mount, volume, drive,
 				 &show_unmount, &show_eject);
 
@@ -266,7 +356,12 @@ add_place (NautilusPlacesSidebar *sidebar,
 		show_eject_button = (show_unmount || show_eject);
 	}
 
-	eject = get_eject_icon (FALSE);
+	if (show_eject_button) {
+		eject = get_eject_icon (FALSE);
+	} else {
+		eject = NULL;
+	}
+
 	gtk_list_store_append (sidebar->store, &iter);
 	gtk_list_store_set (sidebar->store, &iter,
 			    PLACES_SIDEBAR_COLUMN_ICON, pixbuf,
@@ -280,9 +375,9 @@ add_place (NautilusPlacesSidebar *sidebar,
 			    PLACES_SIDEBAR_COLUMN_EJECT, show_eject_button,
 			    PLACES_SIDEBAR_COLUMN_NO_EJECT, !show_eject_button,
 			    PLACES_SIDEBAR_COLUMN_BOOKMARK, place_type != PLACES_BOOKMARK,
-			    PLACES_SIDEBAR_COLUMN_NO_BOOKMARK, place_type == PLACES_BOOKMARK,
 			    PLACES_SIDEBAR_COLUMN_TOOLTIP, tooltip,
 			    PLACES_SIDEBAR_COLUMN_EJECT_ICON, eject,
+			    PLACES_SIDEBAR_COLUMN_SECTION_TYPE, section_type,
 			    -1);
 
 	if (pixbuf != NULL) {
@@ -327,7 +422,7 @@ update_places (NautilusPlacesSidebar *sidebar)
 {
 	NautilusBookmark *bookmark;
 	GtkTreeSelection *selection;
-	GtkTreeIter iter, last_iter;
+	GtkTreeIter last_iter;
 	GtkTreePath *select_path;
 	GtkTreeModel *model;
 	GVolumeMonitor *volume_monitor;
@@ -339,10 +434,13 @@ update_places (NautilusPlacesSidebar *sidebar)
 	GVolume *volume;
 	int bookmark_count, index;
 	char *location, *mount_uri, *name, *desktop_path, *last_uri;
+	const gchar *path;
 	GIcon *icon;
 	GFile *root;
 	NautilusWindowSlotInfo *slot;
 	char *tooltip;
+	GList *network_mounts;
+	NautilusFile *file;
 
 	model = NULL;
 	last_uri = NULL;
@@ -356,69 +454,17 @@ update_places (NautilusPlacesSidebar *sidebar)
 	}
 	gtk_list_store_clear (sidebar->store);
 
+	sidebar->devices_header_added = FALSE;
+	sidebar->bookmarks_header_added = FALSE;
+
 	slot = nautilus_window_info_get_active_slot (sidebar->window);
 	location = nautilus_window_slot_info_get_current_location (slot);
 
-	/* add built in bookmarks */
-	desktop_path = nautilus_get_desktop_directory ();
-
-	if (strcmp (g_get_home_dir(), desktop_path) != 0) {
-		char *display_name;
-
-		mount_uri = nautilus_get_home_directory_uri ();
-		display_name = g_filename_display_basename (g_get_home_dir ());
-		icon = g_themed_icon_new (NAUTILUS_ICON_HOME);
-		last_iter = add_place (sidebar, PLACES_BUILT_IN,
-				       display_name, icon,
-				       mount_uri, NULL, NULL, NULL, 0,
-				       _("Open your personal folder"));
-		g_object_unref (icon);
-		g_free (display_name);
-		compare_for_selection (sidebar,
-				       location, mount_uri, last_uri,
-				       &last_iter, &select_path);
-		g_free (mount_uri);
-	}
-
-	mount_uri = g_filename_to_uri (desktop_path, NULL, NULL);
-	icon = g_themed_icon_new (NAUTILUS_ICON_DESKTOP);
-	last_iter = add_place (sidebar, PLACES_BUILT_IN,
-			       _("Desktop"), icon,
-			       mount_uri, NULL, NULL, NULL, 0,
-			       _("Open the contents of your desktop in a folder"));
-	g_object_unref (icon);
-	compare_for_selection (sidebar,
-			       location, mount_uri, last_uri,
-			       &last_iter, &select_path);
-	g_free (mount_uri);
-	g_free (desktop_path);
-	
- 	mount_uri = "file:///"; /* No need to strdup */
-	icon = g_themed_icon_new (NAUTILUS_ICON_FILESYSTEM);
-	last_iter = add_place (sidebar, PLACES_BUILT_IN,
-			       _("File System"), icon,
-			       mount_uri, NULL, NULL, NULL, 0,
-			       _("Open the contents of the File System"));
-	g_object_unref (icon);
-	compare_for_selection (sidebar,
-			       location, mount_uri, last_uri,
-			       &last_iter, &select_path);
-
- 	mount_uri = "network:///"; /* No need to strdup */
-	icon = g_themed_icon_new (NAUTILUS_ICON_NETWORK);
-	last_iter = add_place (sidebar, PLACES_BUILT_IN,
-			       _("Network"), icon,
-			       mount_uri, NULL, NULL, NULL, 0,
-			       _("Browse the contents of the network"));
-	g_object_unref (icon);
-	compare_for_selection (sidebar,
-			       location, mount_uri, last_uri,
-			       &last_iter, &select_path);
-
 	volume_monitor = sidebar->volume_monitor;
 
 	/* first go through all connected drives */
 	drives = g_volume_monitor_get_connected_drives (volume_monitor);
+
 	for (l = drives; l != NULL; l = l->next) {
 		drive = l->data;
 
@@ -434,7 +480,9 @@ update_places (NautilusPlacesSidebar *sidebar)
 					mount_uri = g_file_get_uri (root);
 					name = g_mount_get_name (mount);
 					tooltip = g_file_get_parse_name (root);
+
 					last_iter = add_place (sidebar, PLACES_MOUNTED_VOLUME,
+							       SECTION_DEVICES,
 							       name, icon, mount_uri,
 							       drive, volume, mount, 0, tooltip);
 					compare_for_selection (sidebar,
@@ -458,7 +506,9 @@ update_places (NautilusPlacesSidebar *sidebar)
 					icon = g_volume_get_icon (volume);
 					name = g_volume_get_name (volume);
 					tooltip = g_strdup_printf (_("Mount and open %s"), name);
+
 					last_iter = add_place (sidebar, PLACES_MOUNTED_VOLUME,
+							       SECTION_DEVICES,
 							       name, icon, NULL,
 							       drive, volume, NULL, 0, tooltip);
 					g_object_unref (icon);
@@ -481,7 +531,9 @@ update_places (NautilusPlacesSidebar *sidebar)
 				icon = g_drive_get_icon (drive);
 				name = g_drive_get_name (drive);
 				tooltip = g_strdup_printf (_("Mount and open %s"), name);
+
 				last_iter = add_place (sidebar, PLACES_BUILT_IN,
+						       SECTION_DEVICES,
 						       name, icon, NULL,
 						       drive, NULL, NULL, 0, tooltip);
 				g_object_unref (icon);
@@ -512,6 +564,7 @@ update_places (NautilusPlacesSidebar *sidebar)
 			g_object_unref (root);
 			name = g_mount_get_name (mount);
 			last_iter = add_place (sidebar, PLACES_MOUNTED_VOLUME,
+					       SECTION_DEVICES,
 					       name, icon, mount_uri,
 					       NULL, volume, mount, 0, tooltip);
 			compare_for_selection (sidebar,
@@ -527,6 +580,7 @@ update_places (NautilusPlacesSidebar *sidebar)
 			icon = g_volume_get_icon (volume);
 			name = g_volume_get_name (volume);
 			last_iter = add_place (sidebar, PLACES_MOUNTED_VOLUME,
+					       SECTION_DEVICES,
 					       name, icon, NULL,
 					       NULL, volume, NULL, 0, name);
 			g_object_unref (icon);
@@ -535,9 +589,136 @@ update_places (NautilusPlacesSidebar *sidebar)
 		g_object_unref (volume);
 	}
 	g_list_free (volumes);
+	
+	/* add bookmarks */
+	bookmark_count = nautilus_bookmark_list_length (sidebar->bookmarks);
+
+	for (index = 0; index < bookmark_count; ++index) {
+		bookmark = nautilus_bookmark_list_item_at (sidebar->bookmarks, index);
+
+		if (nautilus_bookmark_uri_known_not_to_exist (bookmark)) {
+			continue;
+		}
+
+		root = nautilus_bookmark_get_location (bookmark);
+		file = nautilus_file_get (root);
+
+		if (is_built_in_bookmark (file)) {
+			g_object_unref (root);
+			nautilus_file_unref (file);
+			continue;
+		}
+
+		name = nautilus_bookmark_get_name (bookmark);
+		icon = nautilus_bookmark_get_icon (bookmark);
+		mount_uri = nautilus_bookmark_get_uri (bookmark);
+		tooltip = g_file_get_parse_name (root);
+
+		last_iter = add_place (sidebar, PLACES_BOOKMARK,
+				       SECTION_BOOKMARKS,
+				       name, icon, mount_uri,
+				       NULL, NULL, NULL, index,
+				       tooltip);
+		compare_for_selection (sidebar,
+				       location, mount_uri, last_uri,
+				       &last_iter, &select_path);
+		g_free (name);
+		g_object_unref (root);
+		g_object_unref (icon);
+		g_free (mount_uri);
+		g_free (tooltip);
+	}
+
+	last_iter = add_heading (sidebar, SECTION_COMPUTER,
+			       _("Computer"));
+
+	/* add built in bookmarks */
+	desktop_path = nautilus_get_desktop_directory ();
+
+	/* home folder */
+	if (strcmp (g_get_home_dir(), desktop_path) != 0) {
+		char *display_name;
+
+		mount_uri = nautilus_get_home_directory_uri ();
+		display_name = g_filename_display_basename (g_get_home_dir ());
+		icon = g_themed_icon_new (NAUTILUS_ICON_HOME);
+		last_iter = add_place (sidebar, PLACES_BUILT_IN,
+				       SECTION_COMPUTER,
+				       display_name, icon,
+				       mount_uri, NULL, NULL, NULL, 0,
+				       _("Open your personal folder"));
+		g_object_unref (icon);
+		g_free (display_name);
+		compare_for_selection (sidebar,
+				       location, mount_uri, last_uri,
+				       &last_iter, &select_path);
+		g_free (mount_uri);
+	}
+
+	/* desktop */
+	mount_uri = g_filename_to_uri (desktop_path, NULL, NULL);
+	icon = g_themed_icon_new (NAUTILUS_ICON_DESKTOP);
+	last_iter = add_place (sidebar, PLACES_BUILT_IN,
+			       SECTION_COMPUTER,
+			       _("Desktop"), icon,
+			       mount_uri, NULL, NULL, NULL, 0,
+			       _("Open the contents of your desktop in a folder"));
+	g_object_unref (icon);
+	compare_for_selection (sidebar,
+			       location, mount_uri, last_uri,
+			       &last_iter, &select_path);
+	g_free (mount_uri);
+	g_free (desktop_path);
+
+	/* file system root */
+ 	mount_uri = "file:///"; /* No need to strdup */
+	icon = g_themed_icon_new (NAUTILUS_ICON_FILESYSTEM);
+	last_iter = add_place (sidebar, PLACES_BUILT_IN,
+			       SECTION_COMPUTER,
+			       _("File System"), icon,
+			       mount_uri, NULL, NULL, NULL, 0,
+			       _("Open the contents of the File System"));
+	g_object_unref (icon);
+	compare_for_selection (sidebar,
+			       location, mount_uri, last_uri,
+			       &last_iter, &select_path);
+
+	
+	/* XDG directories */
+	for (index = 0; index < G_USER_N_DIRECTORIES; index++) {
+
+		if (index == G_USER_DIRECTORY_DESKTOP ||
+		    index == G_USER_DIRECTORY_TEMPLATES ||
+		    index == G_USER_DIRECTORY_PUBLIC_SHARE) {
+			continue;
+		}
+
+		path = g_get_user_special_dir (index);
+		root = g_file_new_for_path (path);
+		name = g_file_get_basename (root);
+		icon = nautilus_user_special_directory_get_gicon (index);
+		mount_uri = g_file_get_uri (root);
+		tooltip = g_file_get_parse_name (root);
+
+		last_iter = add_place (sidebar, PLACES_BUILT_IN,
+				       SECTION_COMPUTER,
+				       name, icon, mount_uri,
+				       NULL, NULL, NULL, 0,
+				       tooltip);
+		compare_for_selection (sidebar,
+				       location, mount_uri, last_uri,
+				       &last_iter, &select_path);
+		g_free (name);
+		g_object_unref (root);
+		g_object_unref (icon);
+		g_free (mount_uri);
+		g_free (tooltip);
+	}
 
 	/* add mounts that has no volume (/etc/mtab mounts, ftp, sftp,...) */
+	network_mounts = NULL;
 	mounts = g_volume_monitor_get_mounts (volume_monitor);
+
 	for (l = mounts; l != NULL; l = l->next) {
 		mount = l->data;
 		if (g_mount_is_shadowed (mount)) {
@@ -550,12 +731,19 @@ update_places (NautilusPlacesSidebar *sidebar)
 			g_object_unref (mount);
 			continue;
 		}
-		icon = g_mount_get_icon (mount);
 		root = g_mount_get_default_location (mount);
+
+		if (!g_file_is_native (root)) {
+			network_mounts = g_list_prepend (network_mounts, g_object_ref (mount));
+			continue;
+		}
+
+		icon = g_mount_get_icon (mount);
 		mount_uri = g_file_get_uri (root);
 		name = g_mount_get_name (mount);
 		tooltip = g_file_get_parse_name (root);
 		last_iter = add_place (sidebar, PLACES_MOUNTED_VOLUME,
+				       SECTION_COMPUTER,
 				       name, icon, mount_uri,
 				       NULL, NULL, mount, 0, tooltip);
 		compare_for_selection (sidebar,
@@ -573,6 +761,7 @@ update_places (NautilusPlacesSidebar *sidebar)
 	mount_uri = "trash:///"; /* No need to strdup */
 	icon = nautilus_trash_monitor_get_icon ();
 	last_iter = add_place (sidebar, PLACES_BUILT_IN,
+			       SECTION_COMPUTER,
 			       _("Trash"), icon, mount_uri,
 			       NULL, NULL, NULL, 0,
 			       _("Open the trash"));
@@ -581,41 +770,48 @@ update_places (NautilusPlacesSidebar *sidebar)
 			       &last_iter, &select_path);
 	g_object_unref (icon);
 
-	/* add separator */
-
-	gtk_list_store_append (sidebar->store, &iter);
-	gtk_list_store_set (sidebar->store, &iter,
-			    PLACES_SIDEBAR_COLUMN_ROW_TYPE, PLACES_SEPARATOR,
-			    -1);
-
-	/* add bookmarks */
+	/* network */
+	last_iter = add_heading (sidebar, SECTION_NETWORK,
+				 _("Network"));
 
-	bookmark_count = nautilus_bookmark_list_length (sidebar->bookmarks);
-	for (index = 0; index < bookmark_count; ++index) {
-		bookmark = nautilus_bookmark_list_item_at (sidebar->bookmarks, index);
-
-		if (nautilus_bookmark_uri_known_not_to_exist (bookmark)) {
-			continue;
-		}
-
-		name = nautilus_bookmark_get_name (bookmark);
-		icon = nautilus_bookmark_get_icon (bookmark);
-		mount_uri = nautilus_bookmark_get_uri (bookmark);
-		root = nautilus_bookmark_get_location (bookmark);
+	network_mounts = g_list_reverse (network_mounts);
+	for (l = network_mounts; l != NULL; l = l->next) {
+		mount = l->data;
+		root = g_mount_get_default_location (mount);
+		icon = g_mount_get_icon (mount);
+		mount_uri = g_file_get_uri (root);
+		name = g_mount_get_name (mount);
 		tooltip = g_file_get_parse_name (root);
-		last_iter = add_place (sidebar, PLACES_BOOKMARK,
+		last_iter = add_place (sidebar, PLACES_MOUNTED_VOLUME,
+				       SECTION_NETWORK,
 				       name, icon, mount_uri,
-				       NULL, NULL, NULL, index, 
-				       tooltip);
+				       NULL, NULL, mount, 0, tooltip);
 		compare_for_selection (sidebar,
 				       location, mount_uri, last_uri,
 				       &last_iter, &select_path);
-		g_free (name);
 		g_object_unref (root);
+		g_object_unref (mount);
 		g_object_unref (icon);
+		g_free (name);
 		g_free (mount_uri);
 		g_free (tooltip);
 	}
+
+	eel_g_object_list_free (network_mounts);
+
+	/* network:// */
+ 	mount_uri = "network:///"; /* No need to strdup */
+	icon = g_themed_icon_new (NAUTILUS_ICON_NETWORK);
+	last_iter = add_place (sidebar, PLACES_BUILT_IN,
+			       SECTION_NETWORK,
+			       _("Browse Network"), icon,
+			       mount_uri, NULL, NULL, NULL, 0,
+			       _("Browse the contents of the network"));
+	g_object_unref (icon);
+	compare_for_selection (sidebar,
+			       location, mount_uri, last_uri,
+			       &last_iter, &select_path);
+	
 	g_free (location);
 
 	if (select_path != NULL) {
@@ -629,22 +825,6 @@ update_places (NautilusPlacesSidebar *sidebar)
 	g_free (last_uri);
 }
 
-static gboolean
-nautilus_shortcuts_row_separator_func (GtkTreeModel *model,
-				       GtkTreeIter  *iter,
-				       gpointer      data)
-{
-	PlaceType	 	type; 
-
-  	gtk_tree_model_get (model, iter, PLACES_SIDEBAR_COLUMN_ROW_TYPE, &type, -1);
-  
-  	if (type == PLACES_SEPARATOR) {
-   		return TRUE;
-	}
-
-  	return FALSE;
-}
-
 static void
 mount_added_callback (GVolumeMonitor *volume_monitor,
 		      GMount *mount,
@@ -738,11 +918,21 @@ over_eject_button (NautilusPlacesSidebar *sidebar,
 		gtk_widget_style_get (GTK_WIDGET (sidebar->tree_view),
 				      "horizontal-separator", &width,
 				      NULL);
-		total_width += width / 2;
+		total_width += width;
 
 		direction = gtk_widget_get_direction (GTK_WIDGET (sidebar->tree_view));
 		if (direction != GTK_TEXT_DIR_RTL) {
 			gtk_tree_view_column_cell_get_position (column,
+								sidebar->padding_cell_renderer,
+								NULL, &width);
+			total_width += width;
+
+			gtk_tree_view_column_cell_get_position (column,
+								sidebar->icon_padding_cell_renderer,
+								NULL, &width);
+			total_width += width;
+			
+			gtk_tree_view_column_cell_get_position (column,
 								sidebar->icon_cell_renderer,
 								NULL, &width);
 			total_width += width;
@@ -832,93 +1022,75 @@ loading_uri_callback (NautilusWindowInfo *window,
     	}
 }
 
-
-static unsigned int
-get_bookmark_index (GtkTreeView *tree_view)
+/* Computes the appropriate row and position for dropping */
+static gboolean
+compute_drop_position (GtkTreeView *tree_view,
+		       int                      x,
+		       int                      y,
+		       GtkTreePath            **path,
+		       GtkTreeViewDropPosition *pos,
+		       NautilusPlacesSidebar *sidebar)
 {
 	GtkTreeModel *model;
-	GtkTreePath *p;
 	GtkTreeIter iter;
 	PlaceType place_type;
-	int bookmark_index;
+	SectionType section_type;
 
-	model = gtk_tree_view_get_model (tree_view);
+	if (!gtk_tree_view_get_dest_row_at_pos (tree_view,
+					   x,
+					   y,
+					   path,
+					   pos)) {
+		return FALSE;
+	}
 
-	bookmark_index = -1;
+	model = gtk_tree_view_get_model (tree_view);
 
-	/* find separator */
-	p = gtk_tree_path_new_first ();
-	while (p != NULL) {
-		gtk_tree_model_get_iter (model, &iter, p);
-		gtk_tree_model_get (model, &iter,
-				    PLACES_SIDEBAR_COLUMN_ROW_TYPE, &place_type,
-				    -1);
+	gtk_tree_model_get_iter (model, &iter, *path);
+	gtk_tree_model_get (model, &iter,
+			    PLACES_SIDEBAR_COLUMN_ROW_TYPE, &place_type,
+			    PLACES_SIDEBAR_COLUMN_SECTION_TYPE, &section_type,
+			    -1);
 
-		if (place_type == PLACES_SEPARATOR) {
-			bookmark_index = *gtk_tree_path_get_indices (p) + 1;
-			break;
-		}
+	if (place_type == PLACES_HEADING && section_type != SECTION_BOOKMARKS) {
+		/* never drop on headings, but special case the bookmarks heading,
+		 * so we can drop bookmarks in between it and the first item.
+		 */
 
-		gtk_tree_path_next (p);
+		gtk_tree_path_free (*path);
+		*path = NULL;
+		
+		return FALSE;
 	}
-	gtk_tree_path_free (p);
 
-	g_assert (bookmark_index >= 0);
+	if (section_type != SECTION_BOOKMARKS &&
+	    sidebar->drag_data_received &&
+	    sidebar->drag_data_info == GTK_TREE_MODEL_ROW) {
+		/* don't allow dropping bookmarks into non-bookmark areas */
 
-	return bookmark_index;
-}
-
-/* Computes the appropriate row and position for dropping */
-static void
-compute_drop_position (GtkTreeView *tree_view,
-				 int                      x,
-				 int                      y,
-				 GtkTreePath            **path,
-				 GtkTreeViewDropPosition *pos,
-				 NautilusPlacesSidebar *sidebar)
-{
-	int bookmarks_index;
-	int num_rows;
-	int row;
-	
-	bookmarks_index = get_bookmark_index (tree_view);
-	
-	num_rows = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (sidebar->filter_model), NULL);
+		gtk_tree_path_free (*path);
+		*path = NULL;
 
-	if (!gtk_tree_view_get_dest_row_at_pos (tree_view,
-					   x,
-					   y,
-					   path,
-					   pos)) {
-		row = num_rows - 1;
-		*path = gtk_tree_path_new_from_indices (row, -1);
-		*pos = GTK_TREE_VIEW_DROP_AFTER;
-		return;
+		return FALSE;
 	}
-	
-	row = *gtk_tree_path_get_indices (*path);
-	gtk_tree_path_free (*path);
-	
-	if (row == bookmarks_index - 1) {
-		/* Only allow to drop after separator */
+
+	if (section_type == SECTION_BOOKMARKS) {
 		*pos = GTK_TREE_VIEW_DROP_AFTER;
-	} else if (row < bookmarks_index) {
-		/* Hardcoded shortcuts can only be dragged into */
+	} else {
+		/* non-bookmark shortcuts can only be dragged into */
 		*pos = GTK_TREE_VIEW_DROP_INTO_OR_BEFORE;
-	} else if (row >= num_rows) {
-		row = num_rows - 1;
-		*pos = GTK_TREE_VIEW_DROP_AFTER;
-	} else if (*pos != GTK_TREE_VIEW_DROP_BEFORE &&
-		   sidebar->drag_data_received &&
-		   sidebar->drag_data_info == GTK_TREE_MODEL_ROW) {
+	}
+
+	if (*pos != GTK_TREE_VIEW_DROP_BEFORE &&
+	    sidebar->drag_data_received &&
+	    sidebar->drag_data_info == GTK_TREE_MODEL_ROW) {
 		/* bookmark rows are never dragged into other bookmark rows */
 		*pos = GTK_TREE_VIEW_DROP_AFTER;
 	}
 
-	*path = gtk_tree_path_new_from_indices (row, -1);
+	return TRUE;
 }
 
-
 static gboolean
 get_drag_data (GtkTreeView *tree_view,
 	       GdkDragContext *context, 
@@ -954,7 +1126,8 @@ free_drag_data (NautilusPlacesSidebar *sidebar)
 static gboolean
 can_accept_file_as_bookmark (NautilusFile *file)
 {
-	return nautilus_file_is_directory (file);
+	return (nautilus_file_is_directory (file) &&
+		!is_built_in_bookmark (file));
 }
 
 static gboolean
@@ -991,8 +1164,9 @@ drag_motion_callback (GtkTreeView *tree_view,
 	GtkTreePath *path;
 	GtkTreeViewDropPosition pos;
 	int action;
-	GtkTreeIter iter, child_iter;
+	GtkTreeIter iter;
 	char *uri;
+	gboolean res;
 
 	if (!sidebar->drag_data_received) {
 		if (!get_drag_data (tree_view, context, time)) {
@@ -1000,7 +1174,12 @@ drag_motion_callback (GtkTreeView *tree_view,
 		}
 	}
 
-	compute_drop_position (tree_view, x, y, &path, &pos, sidebar);
+	path = NULL;
+	res = compute_drop_position (tree_view, x, y, &path, &pos, sidebar);
+
+	if (!res) {
+		goto out;
+	}
 
 	if (pos == GTK_TREE_VIEW_DROP_BEFORE ||
 	    pos == GTK_TREE_VIEW_DROP_AFTER ) {
@@ -1018,11 +1197,8 @@ drag_motion_callback (GtkTreeView *tree_view,
 		} else {
 			gtk_tree_model_get_iter (sidebar->filter_model,
 						 &iter, path);
-			gtk_tree_model_filter_convert_iter_to_child_iter (
-				GTK_TREE_MODEL_FILTER (sidebar->filter_model),
-				&child_iter, &iter);
-			gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store),
-					    &child_iter,
+			gtk_tree_model_get (GTK_TREE_MODEL (sidebar->filter_model),
+					    &iter,
 					    PLACES_SIDEBAR_COLUMN_URI, &uri,
 					    -1);
 			nautilus_drag_default_drop_action_for_icons (context, uri,
@@ -1032,8 +1208,15 @@ drag_motion_callback (GtkTreeView *tree_view,
 		}
 	}
 
-	gtk_tree_view_set_drag_dest_row (tree_view, path, pos);
-	gtk_tree_path_free (path);
+	if (action != 0) {
+		gtk_tree_view_set_drag_dest_row (tree_view, path, pos);
+	}
+
+	if (path != NULL) {
+		gtk_tree_path_free (path);
+	}
+
+ out:
 	g_signal_stop_emission_by_name (tree_view, "drag-motion");
 
 	if (action != 0) {
@@ -1151,16 +1334,10 @@ get_selected_iter (NautilusPlacesSidebar *sidebar,
 		   GtkTreeIter *iter)
 {
 	GtkTreeSelection *selection;
-	GtkTreeIter parent_iter;
 
 	selection = gtk_tree_view_get_selection (sidebar->tree_view);
-	if (!gtk_tree_selection_get_selected (selection, NULL, &parent_iter)) {
-		return FALSE;
-	}
-	gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (sidebar->filter_model),
-							  iter,
-							  &parent_iter);
-	return TRUE;
+
+	return gtk_tree_selection_get_selected (selection, NULL, iter);
 }
 
 /* Reorders the selected bookmark to the specified position */
@@ -1177,7 +1354,7 @@ reorder_bookmarks (NautilusPlacesSidebar *sidebar,
 	if (!get_selected_iter (sidebar, &iter))
 		g_assert_not_reached ();
 
-	gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store), &iter,
+	gtk_tree_model_get (GTK_TREE_MODEL (sidebar->filter_model), &iter,
 			    PLACES_SIDEBAR_COLUMN_ROW_TYPE, &type,
 			    PLACES_SIDEBAR_COLUMN_INDEX, &old_position,
 			    -1);
@@ -1210,7 +1387,8 @@ drag_data_received_callback (GtkWidget *widget,
 	GtkTreeModel *model;
 	char *drop_uri;
 	GList *selection_list, *uris;
-	PlaceType type; 
+	PlaceType place_type;
+	SectionType section_type;
 	gboolean success;
 
 	tree_view = GTK_TREE_VIEW (widget);
@@ -1246,16 +1424,17 @@ drag_data_received_callback (GtkWidget *widget,
 		}
 
 		gtk_tree_model_get (model, &iter,
-				    PLACES_SIDEBAR_COLUMN_ROW_TYPE, &type,
+				    PLACES_SIDEBAR_COLUMN_SECTION_TYPE, &section_type,
+    				    PLACES_SIDEBAR_COLUMN_ROW_TYPE, &place_type,
 				    PLACES_SIDEBAR_COLUMN_INDEX, &position,
 				    -1);
 
-		if (type != PLACES_SEPARATOR && type != PLACES_BOOKMARK) {
+		if (section_type != SECTION_BOOKMARKS) {
 			goto out;
 		}
 
-		if (type == PLACES_BOOKMARK &&
-		    tree_pos == GTK_TREE_VIEW_DROP_AFTER) {
+		if (tree_pos == GTK_TREE_VIEW_DROP_AFTER && place_type != PLACES_HEADING) {
+			/* heading already has position 0 */
 			position++;
 		}
 
@@ -1449,7 +1628,7 @@ bookmarks_check_popup_sensitivity (NautilusPlacesSidebar *sidebar)
 	}
 
 	if (get_selected_iter (sidebar, &iter)) {
-		gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store), &iter,
+		gtk_tree_model_get (GTK_TREE_MODEL (sidebar->filter_model), &iter,
 				    PLACES_SIDEBAR_COLUMN_ROW_TYPE, &type,
 				    PLACES_SIDEBAR_COLUMN_DRIVE, &drive,
 				    PLACES_SIDEBAR_COLUMN_VOLUME, &volume,
@@ -1723,7 +1902,7 @@ rename_selected_bookmark (NautilusPlacesSidebar *sidebar)
 	GList *renderers;
 	
 	if (get_selected_iter (sidebar, &iter)) {
-		path = gtk_tree_model_get_path (GTK_TREE_MODEL (sidebar->store), &iter);
+		path = gtk_tree_model_get_path (GTK_TREE_MODEL (sidebar->filter_model), &iter);
 		column = gtk_tree_view_get_column (GTK_TREE_VIEW (sidebar->tree_view), 0);
 		renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (column));
 		cell = g_list_nth_data (renderers, 3);
@@ -1754,7 +1933,7 @@ remove_selected_bookmarks (NautilusPlacesSidebar *sidebar)
 		return;
 	}
 	
-	gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store), &iter,
+	gtk_tree_model_get (GTK_TREE_MODEL (sidebar->filter_model), &iter,
 			    PLACES_SIDEBAR_COLUMN_ROW_TYPE, &type,
 			    -1);
 
@@ -1762,7 +1941,7 @@ remove_selected_bookmarks (NautilusPlacesSidebar *sidebar)
 		return;
 	}
 
-	gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store), &iter,
+	gtk_tree_model_get (GTK_TREE_MODEL (sidebar->filter_model), &iter,
 			    PLACES_SIDEBAR_COLUMN_INDEX, &index,
 			    -1);
 
@@ -1787,7 +1966,7 @@ mount_shortcut_cb (GtkMenuItem           *item,
 		return;
 	}
 
-	gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store), &iter,
+	gtk_tree_model_get (GTK_TREE_MODEL (sidebar->filter_model), &iter,
 			    PLACES_SIDEBAR_COLUMN_VOLUME, &volume,
 			    -1);
 
@@ -1829,7 +2008,7 @@ do_unmount_selection (NautilusPlacesSidebar *sidebar)
 		return;
 	}
 
-	gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store), &iter,
+	gtk_tree_model_get (GTK_TREE_MODEL (sidebar->filter_model), &iter,
 			    PLACES_SIDEBAR_COLUMN_MOUNT, &mount,
 			    -1);
 
@@ -1971,7 +2150,7 @@ eject_shortcut_cb (GtkMenuItem           *item,
 		return;
 	}
 
-	gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store), &iter,
+	gtk_tree_model_get (GTK_TREE_MODEL (sidebar->filter_model), &iter,
 			    PLACES_SIDEBAR_COLUMN_MOUNT, &mount,
 			    PLACES_SIDEBAR_COLUMN_VOLUME, &volume,
 			    PLACES_SIDEBAR_COLUMN_DRIVE, &drive,
@@ -2040,7 +2219,7 @@ eject_or_unmount_selection (NautilusPlacesSidebar *sidebar)
 		return FALSE;
 	}
 
-	path = gtk_tree_model_get_path (GTK_TREE_MODEL (sidebar->store), &iter);
+	path = gtk_tree_model_get_path (GTK_TREE_MODEL (sidebar->filter_model), &iter);
 	if (path == NULL) {
 		return FALSE;
 	}
@@ -2087,7 +2266,7 @@ rescan_shortcut_cb (GtkMenuItem           *item,
 		return;
 	}
 
-	gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store), &iter,
+	gtk_tree_model_get (GTK_TREE_MODEL (sidebar->filter_model), &iter,
 			    PLACES_SIDEBAR_COLUMN_DRIVE, &drive,
 			    -1);
 
@@ -2139,7 +2318,7 @@ start_shortcut_cb (GtkMenuItem           *item,
 		return;
 	}
 
-	gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store), &iter,
+	gtk_tree_model_get (GTK_TREE_MODEL (sidebar->filter_model), &iter,
 			    PLACES_SIDEBAR_COLUMN_DRIVE, &drive,
 			    -1);
 
@@ -2195,7 +2374,7 @@ stop_shortcut_cb (GtkMenuItem           *item,
 		return;
 	}
 
-	gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store), &iter,
+	gtk_tree_model_get (GTK_TREE_MODEL (sidebar->filter_model), &iter,
 			    PLACES_SIDEBAR_COLUMN_DRIVE, &drive,
 			    -1);
 
@@ -2593,8 +2772,8 @@ bookmarks_edited (GtkCellRenderer       *cell,
 	g_object_set (cell, "editable", FALSE, NULL);
 	
 	path = gtk_tree_path_new_from_string (path_string);
-	gtk_tree_model_get_iter (GTK_TREE_MODEL (sidebar->store), &iter, path);
-	gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store), &iter,
+	gtk_tree_model_get_iter (GTK_TREE_MODEL (sidebar->filter_model), &iter, path);
+	gtk_tree_model_get (GTK_TREE_MODEL (sidebar->filter_model), &iter,
 		            PLACES_SIDEBAR_COLUMN_INDEX, &index,
 		            -1);
 	gtk_tree_path_free (path);
@@ -2628,6 +2807,85 @@ trash_state_changed_cb (NautilusTrashMonitor *trash_monitor,
 }
 
 static void
+icon_cell_renderer_func (GtkTreeViewColumn *column,
+			 GtkCellRenderer *cell,
+			 GtkTreeModel *model,
+			 GtkTreeIter *iter,
+			 gpointer user_data)
+{
+	NautilusPlacesSidebar *sidebar;
+	PlaceType type;
+
+	sidebar = user_data;
+
+	gtk_tree_model_get (model, iter,
+			    PLACES_SIDEBAR_COLUMN_ROW_TYPE, &type,
+			    -1);
+
+	if (type == PLACES_HEADING) {
+		g_object_set (cell,
+			      "visible", FALSE,
+			      NULL);
+	} else {
+		g_object_set (cell,
+			      "visible", TRUE,
+			      NULL);
+	}
+}
+
+static void
+padding_cell_renderer_func (GtkTreeViewColumn *column,
+			    GtkCellRenderer *cell,
+			    GtkTreeModel *model,
+			    GtkTreeIter *iter,
+			    gpointer user_data)
+{
+	PlaceType type;
+
+	gtk_tree_model_get (model, iter,
+			    PLACES_SIDEBAR_COLUMN_ROW_TYPE, &type,
+			    -1);
+
+	if (type == PLACES_HEADING) {
+		g_object_set (cell,
+			      "visible", FALSE,
+			      "xpad", 0,
+			      "ypad", 0,
+			      NULL);
+	} else {
+		g_object_set (cell,
+			      "visible", TRUE,
+			      "xpad", 3,
+			      "ypad", 3,
+			      NULL);
+	}
+}
+
+static void
+heading_cell_renderer_func (GtkTreeViewColumn *column,
+			    GtkCellRenderer *cell,
+			    GtkTreeModel *model,
+			    GtkTreeIter *iter,
+			    gpointer user_data)
+{
+	PlaceType type;
+
+	gtk_tree_model_get (model, iter,
+			    PLACES_SIDEBAR_COLUMN_ROW_TYPE, &type,
+			    -1);
+
+	if (type == PLACES_HEADING) {
+		g_object_set (cell,
+			      "visible", TRUE,
+			      NULL);
+	} else {
+		g_object_set (cell,
+			      "visible", FALSE,
+			      NULL);
+	}
+}
+
+static void
 nautilus_places_sidebar_init (NautilusPlacesSidebar *sidebar)
 {
 	GtkTreeView       *tree_view;
@@ -2643,21 +2901,57 @@ nautilus_places_sidebar_init (NautilusPlacesSidebar *sidebar)
 	gtk_scrolled_window_set_hadjustment (GTK_SCROLLED_WINDOW (sidebar), NULL);
 	gtk_scrolled_window_set_vadjustment (GTK_SCROLLED_WINDOW (sidebar), NULL);
 	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sidebar), GTK_SHADOW_IN);
-	
+
   	/* tree view */
 	tree_view = GTK_TREE_VIEW (gtk_tree_view_new ());
 	gtk_tree_view_set_headers_visible (tree_view, FALSE);
 
 	col = GTK_TREE_VIEW_COLUMN (gtk_tree_view_column_new ());
 
+	/* initial padding */
+	cell = gtk_cell_renderer_text_new ();
+	sidebar->padding_cell_renderer = cell;
+	gtk_tree_view_column_pack_start (col, cell, FALSE);
+	g_object_set (cell,
+		      "xpad", 6,
+		      NULL);
+
+	/* headings */
+	cell = gtk_cell_renderer_text_new ();
+	gtk_tree_view_column_pack_start (col, cell, FALSE);
+	gtk_tree_view_column_set_attributes (col, cell,
+					     "text", PLACES_SIDEBAR_COLUMN_HEADING_TEXT,
+					     NULL);
+	g_object_set (cell,
+		      "weight", PANGO_WEIGHT_BOLD,
+		      "weight-set", TRUE,
+		      "ypad", 6,
+		      "xpad", 0,
+		      NULL);
+	gtk_tree_view_column_set_cell_data_func (col, cell,
+						 heading_cell_renderer_func,
+						 sidebar, NULL);
+
+	/* icon padding */
+	cell = gtk_cell_renderer_text_new ();
+	sidebar->icon_padding_cell_renderer = cell;
+	gtk_tree_view_column_pack_start (col, cell, FALSE);
+	gtk_tree_view_column_set_cell_data_func (col, cell,
+						 padding_cell_renderer_func,
+						 sidebar, NULL);
+
+	/* icon renderer */
 	cell = gtk_cell_renderer_pixbuf_new ();
 	sidebar->icon_cell_renderer = cell;
 	gtk_tree_view_column_pack_start (col, cell, FALSE);
 	gtk_tree_view_column_set_attributes (col, cell,
 					     "pixbuf", PLACES_SIDEBAR_COLUMN_ICON,
 					     NULL);
+	gtk_tree_view_column_set_cell_data_func (col, cell,
+						 icon_cell_renderer_func,
+						 sidebar, NULL);
 
-	
+	/* eject text renderer */
 	cell = gtk_cell_renderer_text_new ();
 	sidebar->eject_text_cell_renderer = cell;
 	gtk_tree_view_column_pack_start (col, cell, TRUE);
@@ -2670,7 +2964,7 @@ nautilus_places_sidebar_init (NautilusPlacesSidebar *sidebar)
 		      "ellipsize-set", TRUE,
 		      NULL);
 
-
+	/* eject icon renderer */
 	cell = gtk_cell_renderer_pixbuf_new ();
 	g_object_set (cell,
 		      "mode", GTK_CELL_RENDERER_MODE_ACTIVATABLE,
@@ -2683,6 +2977,7 @@ nautilus_places_sidebar_init (NautilusPlacesSidebar *sidebar)
 					     "pixbuf", PLACES_SIDEBAR_COLUMN_EJECT_ICON,
 					     NULL);
 
+	/* normal text renderer */
 	cell = gtk_cell_renderer_text_new ();
 	gtk_tree_view_column_pack_start (col, cell, TRUE);
 	g_object_set (G_OBJECT (cell), "editable", FALSE, NULL);
@@ -2701,11 +2996,6 @@ nautilus_places_sidebar_init (NautilusPlacesSidebar *sidebar)
 	g_signal_connect (cell, "editing-canceled", 
 			  G_CALLBACK (bookmarks_editing_canceled), sidebar);
 
-	gtk_tree_view_set_row_separator_func (tree_view,
-					      nautilus_shortcuts_row_separator_func,
-					      NULL,
-					      NULL);
-
 	/* this is required to align the eject buttons to the right */
 	gtk_tree_view_column_set_max_width (GTK_TREE_VIEW_COLUMN (col), NAUTILUS_ICON_SIZE_SMALLER);
 	gtk_tree_view_append_column (tree_view, col);
@@ -2722,10 +3012,10 @@ nautilus_places_sidebar_init (NautilusPlacesSidebar *sidebar)
 					     G_TYPE_BOOLEAN,
 					     G_TYPE_BOOLEAN,
 					     G_TYPE_BOOLEAN,
-					     G_TYPE_BOOLEAN,
 					     G_TYPE_STRING,
-					     GDK_TYPE_PIXBUF
-					     );
+					     GDK_TYPE_PIXBUF,
+					     G_TYPE_INT,
+					     G_TYPE_STRING);
 
 	gtk_tree_view_set_tooltip_column (tree_view, PLACES_SIDEBAR_COLUMN_TOOLTIP);
 
@@ -2765,6 +3055,7 @@ nautilus_places_sidebar_init (NautilusPlacesSidebar *sidebar)
 			  G_CALLBACK (drag_data_received_callback), sidebar);
 	g_signal_connect (tree_view, "drag-drop",
 			  G_CALLBACK (drag_drop_callback), sidebar);
+
 	g_signal_connect (selection, "changed",
 			  G_CALLBACK (bookmarks_selection_changed_cb), sidebar);
 	g_signal_connect (tree_view, "popup-menu",
@@ -2989,31 +3280,21 @@ static gboolean
 nautilus_shortcuts_model_filter_row_draggable (GtkTreeDragSource *drag_source,
 					       GtkTreePath       *path)
 {
-	NautilusShortcutsModelFilter *model;
-	int pos;
-	int bookmarks_pos;
-	int num_bookmarks;
-
-	model = NAUTILUS_SHORTCUTS_MODEL_FILTER (drag_source);
-
-	pos = *gtk_tree_path_get_indices (path);
-	bookmarks_pos = get_bookmark_index (model->sidebar->tree_view);
-	num_bookmarks = nautilus_bookmark_list_length (model->sidebar->bookmarks);
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	PlaceType place_type;
+	SectionType section_type;
 
-	return (pos >= bookmarks_pos && pos < bookmarks_pos + num_bookmarks);
-}
+	model = GTK_TREE_MODEL (drag_source);
 
-/* GtkTreeDragSource::drag_data_get implementation for the shortcuts filter model */
-static gboolean
-nautilus_shortcuts_model_filter_drag_data_get (GtkTreeDragSource *drag_source,
-					       GtkTreePath       *path,
-					       GtkSelectionData  *selection_data)
-{
-	NautilusShortcutsModelFilter *model;
-
-	model = NAUTILUS_SHORTCUTS_MODEL_FILTER (drag_source);
+	gtk_tree_model_get_iter (model, &iter, path);
+	gtk_tree_model_get (model, &iter,
+			    PLACES_SIDEBAR_COLUMN_ROW_TYPE, &place_type,
+			    PLACES_SIDEBAR_COLUMN_SECTION_TYPE, &section_type,
+			    -1);
 
-	/* FIXME */
+	if (place_type != PLACES_HEADING && section_type == SECTION_BOOKMARKS)
+		return TRUE;
 
 	return FALSE;
 }
@@ -3023,7 +3304,6 @@ static void
 nautilus_shortcuts_model_filter_drag_source_iface_init (GtkTreeDragSourceIface *iface)
 {
 	iface->row_draggable = nautilus_shortcuts_model_filter_row_draggable;
-	iface->drag_data_get = nautilus_shortcuts_model_filter_drag_data_get;
 }
 
 static GtkTreeModel *



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]