Hi, please see http://bugs.gnome.org/619743 for description of the
bug, I'm attaching tha patch here also, please test it and let me know
your comments..

Thank you
From 1fb446e00054d9115ca7361c41df4db3af5a1da5 Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Nelson=20Ben=C3=ADtez=20Le=C3=B3n?= <nbenitezl+gn...@gmail.com>
Date: Wed, 26 May 2010 19:17:44 +0200
Subject: [PATCH] Select and reveal files dropped from XDS (#619743)

---
 libnautilus-private/nautilus-icon-dnd.c            |  104 ++++++++++++++++++++
 libnautilus-private/nautilus-tree-view-drag-dest.c |   72 ++++++++++++++
 2 files changed, 176 insertions(+), 0 deletions(-)

diff --git a/libnautilus-private/nautilus-icon-dnd.c b/libnautilus-private/nautilus-icon-dnd.c
index 263cd05..f207b55 100644
--- a/libnautilus-private/nautilus-icon-dnd.c
+++ b/libnautilus-private/nautilus-icon-dnd.c
@@ -60,6 +60,8 @@
 #include <stdio.h>
 #include <string.h>
 
+#define XDS_SELECT_FILES_TIMEOUT 3
+
 static const GtkTargetEntry drag_types [] = {
 	{ NAUTILUS_ICON_DND_GNOME_ICON_LIST_TYPE, 0, NAUTILUS_ICON_DND_GNOME_ICON_LIST },
 	{ NAUTILUS_ICON_DND_URI_LIST_TYPE, 0, NAUTILUS_ICON_DND_URI_LIST },
@@ -1703,6 +1705,88 @@ nautilus_icon_dnd_end_drag (NautilusIconContainer *container)
 	 */
 }
 
+typedef struct {
+	GObject *instance;
+	GObject *instance2;
+	gulong id_inserted_cb;
+	gulong id_changed_cb;
+} DisconnectXdsData;
+
+static gboolean
+disconnect_xds_signals (gpointer data)
+{
+	DisconnectXdsData *disc;
+	disc = (DisconnectXdsData *) data;
+	g_signal_handler_disconnect ((gpointer) disc->instance, disc->id_inserted_cb);
+	g_signal_handler_disconnect ((gpointer) disc->instance2, disc->id_changed_cb);
+	g_object_unref (disc->instance);
+	g_object_unref (disc->instance2);
+	g_free (disc);
+
+	return FALSE;
+}
+
+static void
+nautilus_xds_icon_added_cb (NautilusIconContainer *container,
+			    NautilusIconData *icon_data,
+			    gpointer data)
+{
+	NautilusIcon *xds_icon;
+	GList *selection = NULL;
+
+	xds_icon = g_hash_table_lookup (container->details->icon_set, icon_data);
+	if (xds_icon) {
+		selection = nautilus_icon_container_get_selection (container);
+		if (selection != NULL) {
+			if (g_list_find (selection, xds_icon->data) == NULL) {
+				selection = g_list_prepend (selection, xds_icon->data);
+				nautilus_icon_container_set_selection (container, selection);
+			}
+		} else {
+			selection = g_list_prepend (selection, xds_icon->data);
+			nautilus_icon_container_set_selection (container, selection);
+			nautilus_icon_container_reveal (container, xds_icon->data);
+		}
+		g_list_free (selection);
+	}
+}
+
+static void
+nautilus_xds_icon_changed_cb (NautilusDirectory *directory,
+			      GList *changed_files,
+			      gpointer data)
+{
+	NautilusIconContainer *container;
+	NautilusIcon *xds_icon;
+	NautilusFile *file;
+	GList *p;
+	GList *selection = NULL;
+	char *uri;
+
+	container = NAUTILUS_ICON_CONTAINER (data);
+	for (p = changed_files; p != NULL; p = p->next) {
+		file = NAUTILUS_FILE (p->data);
+		uri = nautilus_file_get_uri (file);
+		xds_icon = nautilus_icon_container_get_icon_by_uri (container, uri);
+		if (xds_icon) {
+			selection = nautilus_icon_container_get_selection (container);
+			if (selection != NULL) {
+				if (g_list_find (selection, xds_icon->data) == NULL) {
+					selection = g_list_prepend (selection, xds_icon->data);
+					nautilus_icon_container_set_selection (container, selection);
+				}
+			} else {
+				selection = g_list_prepend (selection, xds_icon->data);
+				nautilus_icon_container_set_selection (container, selection);
+				nautilus_icon_container_reveal (container, xds_icon->data);
+			}
+			g_list_free (selection);
+			selection = NULL;
+		}
+		g_free (uri);
+	}
+}
+
 /** this callback is called in 2 cases.
     It is called upon drag_motion events to get the actual data 
     In that case, it just makes sure it gets the data.
@@ -1848,9 +1932,29 @@ drag_data_received_callback (GtkWidget *widget,
 			           drag_info->direct_save_uri != NULL) {
 				GdkPoint p;
 				GFile *location;
+				DisconnectXdsData *disc_data;
+				NautilusDirectory *nautdir;
+				GFile *dir;
+				gulong insert_cb;
+				gulong changed_cb;
 
 				location = g_file_new_for_uri (drag_info->direct_save_uri);
 
+				dir = g_file_get_parent (location);
+				nautdir = nautilus_directory_get (dir);
+				g_object_unref (dir);
+				changed_cb = g_signal_connect (G_OBJECT (nautdir), "files_changed", 
+						G_CALLBACK (nautilus_xds_icon_changed_cb), NAUTILUS_ICON_CONTAINER (widget));
+				nautilus_icon_container_unselect_all (NAUTILUS_ICON_CONTAINER (widget));
+				insert_cb = g_signal_connect (G_OBJECT (widget), "icon_added", 
+						G_CALLBACK (nautilus_xds_icon_added_cb), NULL);
+				disc_data = g_new0 (DisconnectXdsData, 1);
+				disc_data->instance = g_object_ref (widget);
+				disc_data->instance2 = G_OBJECT (nautdir);
+				disc_data->id_inserted_cb = insert_cb;
+				disc_data->id_changed_cb = changed_cb;
+				g_timeout_add_seconds (XDS_SELECT_FILES_TIMEOUT, (GSourceFunc) disconnect_xds_signals, disc_data);
+
 				nautilus_file_changes_queue_file_added (location);
 				p.x = x; p.y = y;
 				nautilus_file_changes_queue_schedule_position_set (
diff --git a/libnautilus-private/nautilus-tree-view-drag-dest.c b/libnautilus-private/nautilus-tree-view-drag-dest.c
index b0fa10e..74a3acd 100644
--- a/libnautilus-private/nautilus-tree-view-drag-dest.c
+++ b/libnautilus-private/nautilus-tree-view-drag-dest.c
@@ -45,6 +45,7 @@
 #define AUTO_SCROLL_MARGIN 20
 
 #define HOVER_EXPAND_TIMEOUT 1
+#define XDS_SELECT_FILES_TIMEOUT 3
 
 struct _NautilusTreeViewDragDestDetails {
 	GtkTreeView *tree_view;
@@ -775,6 +776,63 @@ receive_dropped_keyword (NautilusTreeViewDragDest *dest,
 	g_free (drop_target_uri);
 }
 
+typedef struct {
+	GObject *instance;
+	gulong id_inserted_cb;
+	gulong id_changed_cb;
+} DisconnectXdsData;
+
+static gboolean
+disconnect_xds_signals (gpointer data)
+{
+	DisconnectXdsData *disc;
+	disc = (DisconnectXdsData *) data;
+	g_signal_handler_disconnect ((gpointer) disc->instance, disc->id_inserted_cb);
+	g_signal_handler_disconnect ((gpointer) disc->instance, disc->id_changed_cb);
+	g_object_unref (disc->instance);
+	g_free (disc);
+
+	return FALSE;
+}
+
+static void
+xds_row_changed_cb (GtkTreeModel     *tree_model,
+		    GtkTreePath      *file_path,
+		    GtkTreeIter      *iter,
+		    NautilusTreeViewDragDest *dest)
+{
+	GtkTreeSelection *selection;
+	selection = gtk_tree_view_get_selection (dest->details->tree_view);
+
+	if (gtk_tree_selection_count_selected_rows (selection)) {
+		gtk_tree_selection_select_path (selection, file_path);
+	} else {
+		gtk_tree_selection_select_path (selection, file_path);
+		gtk_tree_view_scroll_to_cell (dest->details->tree_view,
+					      file_path, NULL,
+					      FALSE, 0.0, 0.0);
+	}
+}
+
+static void
+xds_row_inserted_cb (GtkTreeModel     *tree_model,
+		     GtkTreePath      *file_path,
+		     GtkTreeIter      *iter,
+		     NautilusTreeViewDragDest *dest)
+{
+	GtkTreeSelection *selection;
+	selection = gtk_tree_view_get_selection (dest->details->tree_view);
+
+	if (gtk_tree_selection_count_selected_rows (selection)) {
+		gtk_tree_selection_select_path (selection, file_path);
+	} else {
+		gtk_tree_selection_select_path (selection, file_path);
+		gtk_tree_view_scroll_to_cell (dest->details->tree_view,
+					      file_path, NULL,
+					      FALSE, 0.0, 0.0);
+	}
+}
+
 static gboolean
 receive_xds (NautilusTreeViewDragDest *dest,
 	     GtkWidget *widget,
@@ -783,6 +841,9 @@ receive_xds (NautilusTreeViewDragDest *dest,
 	     int x, int y)
 {
 	GFile *location;
+	DisconnectXdsData *disc_data;
+	gulong insert_cb;
+	gulong changed_cb;
 
 	if (dest->details->drag_data->format == 8 
 	    && dest->details->drag_data->length == 1 
@@ -798,6 +859,17 @@ receive_xds (NautilusTreeViewDragDest *dest,
 		g_assert (dest->details->direct_save_uri != NULL);
 		location = g_file_new_for_uri (dest->details->direct_save_uri);
 
+		gtk_tree_selection_unselect_all (gtk_tree_view_get_selection (dest->details->tree_view));
+		insert_cb = g_signal_connect_after (G_OBJECT (gtk_tree_view_get_model (dest->details->tree_view)), "row-inserted",
+					 G_CALLBACK (xds_row_inserted_cb), dest);
+		changed_cb = g_signal_connect_after (G_OBJECT (gtk_tree_view_get_model (dest->details->tree_view)), "row-changed",
+					 G_CALLBACK (xds_row_changed_cb), dest);
+		disc_data = g_new0 (DisconnectXdsData, 1);
+		disc_data->instance = g_object_ref (gtk_tree_view_get_model (dest->details->tree_view));
+		disc_data->id_inserted_cb = insert_cb;
+		disc_data->id_changed_cb = changed_cb;
+		g_timeout_add_seconds (XDS_SELECT_FILES_TIMEOUT, (GSourceFunc) disconnect_xds_signals, disc_data);
+
 		nautilus_file_changes_queue_file_added (location);
 		nautilus_file_changes_consume_changes (TRUE);
 
-- 
1.6.3.3

-- 
nautilus-list mailing list
nautilus-list@gnome.org
http://mail.gnome.org/mailman/listinfo/nautilus-list

Reply via email to