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