Re: [PATCH] allow to drop URIs, URLs and text to subfolders



Am Freitag, den 07.07.2006, 12:41 +0200 schrieb Alexander Larsson: 
> On Thu, 2006-06-22 at 22:17 +0200, Christian Neumair wrote:
> > The attached patch considers subfolders as drop targets for non-GNOME
> > Icon List drag data that refers to files.
> 
> -		                nautilus_marshal_VOID__STRING_ENUM_INT_INT,
> -		                G_TYPE_NONE, 4,
> +		                nautilus_marshal_VOID__STRING_STRING_ENUM_INT_INT,
> +		                G_TYPE_NONE, 5,
> +				G_TYPE_STRING,
> This changes signal marhsaller types, but not the method definition in
> nautilus-icon-container.h.

Good catch, this patch also makes some more args const in the .h
prototypes.

> > (garbage from other patches)
> > (...)
> (...) 
> This is something else. If a menu plugin really needs that they can do
> it themselves, and anyway it shouldn't be done by changing
> process-global environment vars, but by using gdk_spawn*.

I'm very sorry that once again I submitted a patch mish-mash.

> @@ -383,9 +385,27 @@ get_drop_action (NautilusTreeViewDragDes
>  		return action;
>  		
>  	case NAUTILUS_ICON_DND_URL:
> -		return nautilus_drag_default_drop_action_for_url (context);
> +		drop_target = get_drop_target_uri_for_path (dest, path);
> +
> +		if (drop_target == NULL) {
> +			return 0;
> +		}
> +
> +		action = nautilus_drag_default_drop_action_for_url (context);
> +
> +		g_free (drop_target);
> +
> +		return action;
>  		
> 
> Are these really right? Doesn't that block dropping on the background?

No, because get_drop_path will return the container URI if path is NULL,
and we feed get_drop_path into get_drop_action.

The attached patch also fixes the DND highlighting of an empty tree
view, and ensures that drags on the header are ignored.

Because it significantly changes some DND codepaths, having this patch
in before your vacation (and thus, before the next release) would be
great.

-- 
Christian Neumair <chris gnome-de org>
Index: libnautilus-private/nautilus-file-dnd.c
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-file-dnd.c,v
retrieving revision 1.7
diff -u -p -r1.7 nautilus-file-dnd.c
--- libnautilus-private/nautilus-file-dnd.c	12 Dec 2005 16:59:10 -0000	1.7
+++ libnautilus-private/nautilus-file-dnd.c	8 Jul 2006 10:26:58 -0000
@@ -32,19 +32,14 @@
 #include <eel/eel-glib-extensions.h>
 #include <eel/eel-string.h>
 
-gboolean
-nautilus_drag_can_accept_item (NautilusFile *drop_target_item,
-			       const char *item_uri)
+static gboolean
+nautilus_drag_can_accept_files (NautilusFile *drop_target_item)
 {
 	NautilusDirectory *directory;
-	gboolean res;
-	
-	if (nautilus_file_matches_uri (drop_target_item, item_uri)) {
-		/* can't accept itself */
-		return FALSE;
-	}
-	
+
 	if (nautilus_file_is_directory (drop_target_item)) {
+		gboolean res;
+
 		/* target is a directory, accept if editable */
 		directory = nautilus_directory_get_for_file (drop_target_item);
 		res = nautilus_directory_is_editable (directory);
@@ -68,7 +63,19 @@ nautilus_drag_can_accept_item (NautilusF
 	
 	return FALSE;
 }
-					       
+
+gboolean
+nautilus_drag_can_accept_item (NautilusFile *drop_target_item,
+			       const char *item_uri)
+{
+	if (nautilus_file_matches_uri (drop_target_item, item_uri)) {
+		/* can't accept itself */
+		return FALSE;
+	}
+
+	return nautilus_drag_can_accept_files (drop_target_item);
+}
+				       
 gboolean
 nautilus_drag_can_accept_items (NautilusFile *drop_target_item,
 				const GList *items)
@@ -92,6 +99,39 @@ nautilus_drag_can_accept_items (Nautilus
 	}
 	
 	return TRUE;
+}
+
+gboolean
+nautilus_drag_can_accept_info (NautilusFile *drop_target_item,
+			       NautilusIconDndTargetType drag_type,
+			       const GList *items)
+{
+	switch (drag_type) {
+		case NAUTILUS_ICON_DND_GNOME_ICON_LIST:
+			return nautilus_drag_can_accept_items (drop_target_item, items);
+
+		case NAUTILUS_ICON_DND_URI_LIST:
+		case NAUTILUS_ICON_DND_URL:
+		case NAUTILUS_ICON_DND_TEXT:
+			return nautilus_drag_can_accept_files (drop_target_item);
+
+		case NAUTILUS_ICON_DND_KEYWORD:
+			return TRUE;
+
+		case NAUTILUS_ICON_DND_ROOTWINDOW_DROP:
+			return FALSE;
+
+		/* TODO return TRUE for folders as soon as drop handling is implemented */
+		case NAUTILUS_ICON_DND_COLOR:
+		case NAUTILUS_ICON_DND_BGIMAGE:
+		case NAUTILUS_ICON_DND_RESET_BACKGROUND:
+			return FALSE;
+
+		default:
+			g_assert_not_reached ();
+			return FALSE;
+	}
+	
 }
 
 void
Index: libnautilus-private/nautilus-file-dnd.h
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-file-dnd.h,v
retrieving revision 1.5
diff -u -p -r1.5 nautilus-file-dnd.h
--- libnautilus-private/nautilus-file-dnd.h	22 Feb 2002 18:54:15 -0000	1.5
+++ libnautilus-private/nautilus-file-dnd.h	8 Jul 2006 10:26:58 -0000
@@ -25,6 +25,7 @@
 #ifndef NAUTILUS_FILE_DND_H
 #define NAUTILUS_FILE_DND_H
 
+#include <libnautilus-private/nautilus-dnd.h>
 #include <libnautilus-private/nautilus-file.h>
 
 #define NAUTILUS_FILE_DND_ERASE_KEYWORD "erase"
@@ -33,6 +34,9 @@ gboolean nautilus_drag_can_accept_item  
 						     const char   *item_uri);
 gboolean nautilus_drag_can_accept_items             (NautilusFile *drop_target_item,
 						     const GList  *items);
+gboolean nautilus_drag_can_accept_info              (NautilusFile *drop_target_item,
+						     NautilusIconDndTargetType drag_type,
+						     const GList *items);
 void     nautilus_drag_file_receive_dropped_keyword (NautilusFile *file,
 						     const char   *keyword);
 
Index: libnautilus-private/nautilus-icon-container.c
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-icon-container.c,v
retrieving revision 1.415
diff -u -p -r1.415 nautilus-icon-container.c
--- libnautilus-private/nautilus-icon-container.c	15 May 2006 22:55:24 -0000	1.415
+++ libnautilus-private/nautilus-icon-container.c	8 Jul 2006 10:27:35 -0000
@@ -4596,8 +4596,9 @@ nautilus_icon_container_class_init (Naut
 		                G_STRUCT_OFFSET (NautilusIconContainerClass, 
 						     handle_url),
 		                NULL, NULL,
-		                nautilus_marshal_VOID__STRING_ENUM_INT_INT,
-		                G_TYPE_NONE, 4,
+		                nautilus_marshal_VOID__STRING_STRING_ENUM_INT_INT,
+		                G_TYPE_NONE, 5,
+				G_TYPE_STRING,
 				G_TYPE_STRING,
 				GDK_TYPE_DRAG_ACTION,
 				G_TYPE_INT,
@@ -4609,8 +4610,9 @@ nautilus_icon_container_class_init (Naut
 		                G_STRUCT_OFFSET (NautilusIconContainerClass, 
 						     handle_uri_list),
 		                NULL, NULL,
-		                nautilus_marshal_VOID__STRING_ENUM_INT_INT,
-		                G_TYPE_NONE, 4,
+		                nautilus_marshal_VOID__STRING_STRING_ENUM_INT_INT,
+		                G_TYPE_NONE, 5,
+				G_TYPE_STRING,
 				G_TYPE_STRING,
 				GDK_TYPE_DRAG_ACTION,
 				G_TYPE_INT,
@@ -4622,8 +4624,9 @@ nautilus_icon_container_class_init (Naut
 		                G_STRUCT_OFFSET (NautilusIconContainerClass, 
 						 handle_text),
 		                NULL, NULL,
-		                nautilus_marshal_VOID__STRING_ENUM_INT_INT,
-		                G_TYPE_NONE, 4,
+		                nautilus_marshal_VOID__STRING_STRING_ENUM_INT_INT,
+		                G_TYPE_NONE, 5,
+				G_TYPE_STRING,
 				G_TYPE_STRING,
 				GDK_TYPE_DRAG_ACTION,
 				G_TYPE_INT,
Index: libnautilus-private/nautilus-icon-container.h
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-icon-container.h,v
retrieving revision 1.92
diff -u -p -r1.92 nautilus-icon-container.h
--- libnautilus-private/nautilus-icon-container.h	15 May 2006 22:55:24 -0000	1.92
+++ libnautilus-private/nautilus-icon-container.h	8 Jul 2006 10:27:37 -0000
@@ -93,24 +93,27 @@ typedef struct {
 	void         (* context_click_selection)  (NautilusIconContainer *container,
 						   GdkEventButton *event);
 	void	     (* move_copy_items)	  (NautilusIconContainer *container,
-						   GList *item_uris,
+						   const GList *item_uris,
 						   GdkPoint *relative_item_points,
 						   const char *target_uri,
 						   GdkDragAction action,
 						   int x,
 						   int y);
 	void	     (* handle_url)		  (NautilusIconContainer *container,
-						   char *url,
+						   const char *url,
+						   const char *target_uri,
 						   GdkDragAction action,
 						   int x,
 						   int y);
 	void	     (* handle_uri_list)    	  (NautilusIconContainer *container,
-						   char *uri_list,
+						   const char *uri_list,
+						   const char *target_uri,
 						   GdkDragAction action,
 						   int x,
 						   int y);
 	void	     (* handle_text)		  (NautilusIconContainer *container,
-						   char *text,
+						   const char *text,
+						   const char *target_uri,
 						   GdkDragAction action,
 						   int x,
 						   int y);
Index: libnautilus-private/nautilus-icon-dnd.c
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-icon-dnd.c,v
retrieving revision 1.154
diff -u -p -r1.154 nautilus-icon-dnd.c
--- libnautilus-private/nautilus-icon-dnd.c	15 May 2006 22:55:24 -0000	1.154
+++ libnautilus-private/nautilus-icon-dnd.c	8 Jul 2006 10:27:40 -0000
@@ -84,6 +84,10 @@ static void     dnd_highlight_queue_redr
 static GtkTargetList *drop_types_list = NULL;
 static GtkTargetList *drop_types_list_root = NULL;
 
+static char * nautilus_icon_container_find_drop_target (NautilusIconContainer *container,
+							GdkDragContext *context,
+							int x, int y, gboolean *icon_hit);
+
 static EelCanvasItem *
 create_selection_shadow (NautilusIconContainer *container,
 			 GList *list)
@@ -618,44 +622,65 @@ receive_dropped_keyword (NautilusIconCon
 
 /* handle dropped url */
 static void
-receive_dropped_url (NautilusIconContainer *container, const char *encoded_url, GdkDragAction action, int x, int y)
+receive_dropped_url (NautilusIconContainer *container, const char *encoded_url, GdkDragContext *context, int x, int y)
 {
+	char *drop_target;
+
 	if (encoded_url == NULL) {
 		return;
 	}
 
+	drop_target = nautilus_icon_container_find_drop_target (container, context, x, y, NULL);
+
 	g_signal_emit_by_name (container, "handle_url",
 			       encoded_url,
-			       action,
+			       drop_target,
+			       context->action,
 			       x, y);
+
+	g_free (drop_target);
 }
 
 /* handle dropped uri list */
 static void
-receive_dropped_uri_list (NautilusIconContainer *container, const char *uri_list, GdkDragAction action, int x, int y)
+receive_dropped_uri_list (NautilusIconContainer *container, const char *uri_list, GdkDragContext *context, int x, int y)
 {	
+	char *drop_target;
+
 	if (uri_list == NULL) {
 		return;
 	}
-	
+
+	drop_target = nautilus_icon_container_find_drop_target (container, context, x, y, NULL);
+
 	g_signal_emit_by_name (container, "handle_uri_list",
 				 uri_list,
-				 action,
+				 drop_target,
+				 context->action,
 				 x, y);
+
+	g_free (drop_target);
 }
 
 /* handle dropped text */
 static void
-receive_dropped_text (NautilusIconContainer *container, const char *text, GdkDragAction action, int x, int y)
+receive_dropped_text (NautilusIconContainer *container, const char *text, GdkDragContext *context, int x, int y)
 {	
+	char *drop_target;
+
 	if (text == NULL) {
 		return;
 	}
+
+	drop_target = nautilus_icon_container_find_drop_target (container, context, x, y, NULL);
 	
 	g_signal_emit_by_name (container, "handle_text",
 			       text,
-			       action,
+			       drop_target,
+			       context->action,
 			       x, y);
+
+	g_free (drop_target);
 }
 
 static int
@@ -939,8 +964,11 @@ nautilus_icon_container_find_drop_target
 	NautilusFile *file;
 	char *icon_uri;
 
-	*icon_hit = FALSE;
-	if (container->details->dnd_info->drag_info.selection_list == NULL) {
+	if (icon_hit) {
+		*icon_hit = FALSE;
+	}
+
+	if (!container->details->dnd_info->drag_info.got_drop_data_type) {
 		return NULL;
 	}
 
@@ -959,8 +987,9 @@ nautilus_icon_container_find_drop_target
 		if (icon_uri != NULL) {
 			file = nautilus_file_get (icon_uri);
 
-			if (!nautilus_drag_can_accept_items (file, 
-					container->details->dnd_info->drag_info.selection_list)) {
+			if (!nautilus_drag_can_accept_info (file,
+							    container->details->dnd_info->drag_info.data_type,
+							    container->details->dnd_info->drag_info.selection_list)) {
 			 	/* the item we dropped our selection on cannot accept the items,
 			 	 * do the same thing as if we just dropped the items on the canvas
 				 */
@@ -973,11 +1002,16 @@ nautilus_icon_container_find_drop_target
 	}
 
 	if (drop_target_icon == NULL) {
-		*icon_hit = FALSE;
+		if (icon_hit) {
+			*icon_hit = FALSE;
+		}
+
 		return get_container_uri (container);
 	}
 	
-	*icon_hit = TRUE;
+	if (icon_hit) {
+		*icon_hit = TRUE;
+	}
 	return nautilus_icon_container_get_icon_drop_target_uri (container, drop_target_icon);
 }
 
@@ -1177,10 +1211,6 @@ nautilus_icon_dnd_update_drop_target (Na
 	char *uri;
 	
 	g_assert (NAUTILUS_IS_ICON_CONTAINER (container));
-	if ((container->details->dnd_info->drag_info.selection_list == NULL) 
-	   && (container->details->dnd_info->drag_info.data_type != NAUTILUS_ICON_DND_KEYWORD)) {
-		return;
-	}
 
 	canvas_widget_to_world (EEL_CANVAS (container), x, y, &world_x, &world_y);
 
@@ -1199,8 +1229,9 @@ nautilus_icon_dnd_update_drop_target (Na
 		    file = nautilus_file_get (uri);
 		    g_free (uri);
 		
-		    if (!nautilus_drag_can_accept_items (file,
-							 container->details->dnd_info->drag_info.selection_list)) {
+		    if (!nautilus_drag_can_accept_info (file,
+					    		container->details->dnd_info->drag_info.data_type,
+							container->details->dnd_info->drag_info.selection_list)) {
 			    icon = NULL;
 		    }
 
@@ -1642,20 +1673,20 @@ drag_data_received_callback (GtkWidget *
 		case NAUTILUS_ICON_DND_URL:
 			receive_dropped_url
 				(NAUTILUS_ICON_CONTAINER (widget),
-				 (char *) data->data, context->action, x, y);
+				 (char *) data->data, context, x, y);
 			success = TRUE;
 			break;
 		case NAUTILUS_ICON_DND_URI_LIST:
 			receive_dropped_uri_list
 				(NAUTILUS_ICON_CONTAINER (widget),
-				 (char *) data->data, context->action, x, y);
+				 (char *) data->data, context, x, y);
 			success = TRUE;
 			break;
 		case NAUTILUS_ICON_DND_TEXT:
 			tmp = gtk_selection_data_get_text (data);
 			receive_dropped_text
 				(NAUTILUS_ICON_CONTAINER (widget),
-				 (char *) tmp, context->action, x, y);
+				 (char *) tmp, context, x, y);
 			success = TRUE;
 			g_free (tmp);
 			break;
Index: libnautilus-private/nautilus-marshal.list
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-marshal.list,v
retrieving revision 1.11
diff -u -p -r1.11 nautilus-marshal.list
--- libnautilus-private/nautilus-marshal.list	12 Dec 2005 16:59:10 -0000	1.11
+++ libnautilus-private/nautilus-marshal.list	8 Jul 2006 10:27:44 -0000
@@ -16,5 +16,6 @@ VOID:POINTER,POINTER
 VOID:POINTER,POINTER,POINTER,ENUM,INT,INT
 VOID:POINTER,STRING
 VOID:POINTER,STRING,ENUM,INT,INT
+VOID:STRING,STRING,ENUM,INT,INT
 VOID:STRING,ENUM,INT,INT
 VOID:STRING,STRING
Index: libnautilus-private/nautilus-tree-view-drag-dest.c
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-tree-view-drag-dest.c,v
retrieving revision 1.14
diff -u -p -r1.14 nautilus-tree-view-drag-dest.c
--- libnautilus-private/nautilus-tree-view-drag-dest.c	27 Feb 2006 21:54:58 -0000	1.14
+++ libnautilus-private/nautilus-tree-view-drag-dest.c	8 Jul 2006 10:27:45 -0000
@@ -205,8 +205,7 @@ set_widget_highlight (NautilusTreeViewDr
 			g_signal_connect_object (dest->details->tree_view,
 						 "expose_event",
 						 G_CALLBACK (highlight_expose),
-						 dest,
-						 G_CONNECT_AFTER);
+						 dest, 0);
 	}
 	gtk_widget_queue_draw (GTK_WIDGET (dest->details->tree_view));
 }
@@ -306,7 +305,7 @@ get_drop_path (NautilusTreeViewDragDest 
 	NautilusFile *file;
 	GtkTreePath *ret;
 	
-	if (!path) {
+	if (!path || !dest->details->have_drag_data) {
 		return NULL;
 	}
 
@@ -315,7 +314,9 @@ get_drop_path (NautilusTreeViewDragDest 
 
 	/* Go up the tree until we find a file that can accept a drop */
 	while (file == NULL /* dummy row */ ||
-	       !nautilus_drag_can_accept_items (file, dest->details->drag_list)) {
+	       !nautilus_drag_can_accept_info (file,
+		       			       dest->details->drag_type,
+					       dest->details->drag_list)) {
 		if (gtk_tree_path_get_depth (ret) == 1) {
 			gtk_tree_path_free (ret);
 			ret = NULL;
@@ -333,8 +334,8 @@ get_drop_path (NautilusTreeViewDragDest 
 }
 
 static char *
-get_drop_target (NautilusTreeViewDragDest *dest, 
-		 GtkTreePath *path)
+get_drop_target_uri_for_path (NautilusTreeViewDragDest *dest,
+			      GtkTreePath *path)
 {
 	NautilusFile *file;
 	char *target;
@@ -366,7 +367,7 @@ get_drop_action (NautilusTreeViewDragDes
 
 	switch (dest->details->drag_type) {
 	case NAUTILUS_ICON_DND_GNOME_ICON_LIST :
-		drop_target = get_drop_target (dest, path);
+		drop_target = get_drop_target_uri_for_path (dest, path);
 		
 		if (!drop_target) {
 			return 0;
@@ -383,9 +384,27 @@ get_drop_action (NautilusTreeViewDragDes
 		return action;
 		
 	case NAUTILUS_ICON_DND_URL:
-		return nautilus_drag_default_drop_action_for_url (context);
+		drop_target = get_drop_target_uri_for_path (dest, path);
+
+		if (drop_target == NULL) {
+			return 0;
+		}
+
+		action = nautilus_drag_default_drop_action_for_url (context);
+
+		g_free (drop_target);
+
+		return action;
 		
 	case NAUTILUS_ICON_DND_URI_LIST :
+		drop_target = get_drop_target_uri_for_path (dest, path);
+
+		if (drop_target == NULL) {
+			return 0;
+		}
+
+		g_free (drop_target);
+
 		return context->suggested_action;
 
 	case NAUTILUS_ICON_DND_TEXT:
@@ -417,6 +436,7 @@ drag_motion_callback (GtkWidget *widget,
 	GtkTreeModel *model;
 	GtkTreeIter drop_iter;
 	GtkTreeViewDropPosition pos;
+	GdkWindow *bin_window;
 	guint action;
 
 	dest = NAUTILUS_TREE_VIEW_DRAG_DEST (data);
@@ -430,8 +450,17 @@ drag_motion_callback (GtkWidget *widget,
 	}
 	drop_path = get_drop_path (dest, path);
 	
-	action = get_drop_action (dest, context, drop_path);
-	
+	action = 0;
+	bin_window = gtk_tree_view_get_bin_window (GTK_TREE_VIEW (widget));
+	if (bin_window != NULL) {
+		int bin_x, bin_y;
+		gdk_window_get_position (bin_window, &bin_x, &bin_y);
+		if (bin_y <= y) {
+			/* ignore drags on the header */
+			action = get_drop_action (dest, context, drop_path);
+		}
+	}
+
 	gtk_tree_view_get_drag_dest_row (GTK_TREE_VIEW (widget), &old_drop_path,
 					 NULL);
 	
@@ -497,24 +526,43 @@ drag_leave_callback (GtkWidget *widget,
 	remove_expand_timeout (dest);
 }
 
-static void
-receive_uris (NautilusTreeViewDragDest *dest,
-	      GdkDragContext *context,
-	      GList *source_uris,
-	      int x, int y)
+static char *
+get_drop_target_uri_at_pos (NautilusTreeViewDragDest *dest, int x, int y)
 {
 	char *drop_target;
 	GtkTreePath *path;
 	GtkTreePath *drop_path;
 	GtkTreeViewDropPosition pos;
-	GdkDragAction action;
 
 	gtk_tree_view_get_dest_row_at_pos (dest->details->tree_view, x, y, 
 					   &path, &pos);
 
 	drop_path = get_drop_path (dest, path);
 
-	drop_target = get_drop_target (dest, drop_path);
+	drop_target = get_drop_target_uri_for_path (dest, drop_path);
+
+	if (path != NULL) {
+		gtk_tree_path_free (path);
+	}
+
+	if (drop_path != NULL) {
+		gtk_tree_path_free (drop_path);
+	}
+
+	return drop_target;
+}
+
+static void
+receive_uris (NautilusTreeViewDragDest *dest,
+	      GdkDragContext *context,
+	      GList *source_uris,
+	      int x, int y)
+{
+	char *drop_target;
+	GdkDragAction action;
+
+	drop_target = get_drop_target_uri_at_pos (dest, x, y);
+	g_assert (drop_target != NULL);
 
 	if (context->action == GDK_ACTION_ASK) {
 		if (nautilus_drag_selection_includes_special_link (dest->details->drag_list)) {
@@ -540,14 +588,6 @@ receive_uris (NautilusTreeViewDragDest *
 			       x, y);
 	}
 
-	if (path) {
-		gtk_tree_path_free (path);
-	}
-
-	if (drop_path) {
-		gtk_tree_path_free (drop_path);
-	}
-
 	g_free (drop_target);
 }
 
@@ -583,14 +623,22 @@ receive_dropped_uri_list (NautilusTreeVi
 			  GdkDragContext *context,
 			  int x, int y)
 {
+	char *drop_target;
+
 	if (!dest->details->drag_data) {
 		return;
 	}
 
+	drop_target = get_drop_target_uri_at_pos (dest, x, y);
+	g_assert (drop_target != NULL);
+
 	g_signal_emit (dest, signals[HANDLE_URI_LIST], 0,
 		       (char*)dest->details->drag_data->data,
+		       drop_target,
 		       context->action,
 		       x, y);
+
+	g_free (drop_target);
 }
 
 static void
@@ -598,18 +646,24 @@ receive_dropped_text (NautilusTreeViewDr
 		      GdkDragContext *context,
 		      int x, int y)
 {
+	char *drop_target;
 	char *text;
 
 	if (!dest->details->drag_data) {
 		return;
 	}
 
+	drop_target = get_drop_target_uri_at_pos (dest, x, y);
+	g_assert (drop_target != NULL);
+
 	text = gtk_selection_data_get_text (dest->details->drag_data);
 	g_signal_emit (dest, signals[HANDLE_TEXT], 0,
-		       (char *) text,
+		       (char *) text, drop_target,
 		       context->action,
 		       x, y);
+
 	g_free (text);
+	g_free (drop_target);
 }
 
 
@@ -618,14 +672,22 @@ receive_dropped_url (NautilusTreeViewDra
 		     GdkDragContext *context,
 		     int x, int y)
 {
+	char *drop_target;
+
 	if (!dest->details->drag_data) {
 		return;
 	}
 
+	drop_target = get_drop_target_uri_at_pos (dest, x, y);
+	g_assert (drop_target != NULL);
+
 	g_signal_emit (dest, signals[HANDLE_URL], 0,
 		       (char*)dest->details->drag_data->data,
+		       drop_target,
 		       context->action,
 		       x, y);
+
+	g_free (drop_target);
 }
 
 static void
@@ -634,15 +696,14 @@ receive_dropped_keyword (NautilusTreeVie
 			 int x, int y)
 {
 	char *drop_target_uri;
-	GtkTreePath *path, *drop_path;
 	NautilusFile *drop_target_file;
 
-	gtk_tree_view_get_dest_row_at_pos (dest->details->tree_view, x, y, 
-					   &path, NULL);
-
-	drop_path = get_drop_path (dest, path);
+	if (!dest->details->drag_data) {
+		return;
+	}
 
-	drop_target_uri = get_drop_target (dest, drop_path);
+	drop_target_uri = get_drop_target_uri_at_pos (dest, x, y);
+	g_assert (drop_target_uri != NULL);
 
 	drop_target_file = nautilus_file_get (drop_target_uri);
 
@@ -652,15 +713,6 @@ receive_dropped_keyword (NautilusTreeVie
 		nautilus_file_unref (drop_target_file);
 	}
 
-
-	if (path) {
-		gtk_tree_path_free (path);
-	}
-
-	if (drop_path) {
-		gtk_tree_path_free (drop_path);
-	}
-
 	g_free (drop_target_uri);
 }
 
@@ -854,8 +906,9 @@ nautilus_tree_view_drag_dest_class_init 
 			      G_STRUCT_OFFSET (NautilusTreeViewDragDestClass, 
 					       handle_url),
 			      NULL, NULL,
-			      nautilus_marshal_VOID__STRING_ENUM_INT_INT,
-			      G_TYPE_NONE, 4,
+			      nautilus_marshal_VOID__STRING_STRING_ENUM_INT_INT,
+			      G_TYPE_NONE, 5,
+			      G_TYPE_STRING,
 			      G_TYPE_STRING,
 			      GDK_TYPE_DRAG_ACTION,
 			      G_TYPE_INT,
@@ -867,8 +920,9 @@ nautilus_tree_view_drag_dest_class_init 
 			      G_STRUCT_OFFSET (NautilusTreeViewDragDestClass, 
 					       handle_uri_list),
 			      NULL, NULL,
-			      nautilus_marshal_VOID__STRING_ENUM_INT_INT,
-			      G_TYPE_NONE, 4,
+			      nautilus_marshal_VOID__STRING_STRING_ENUM_INT_INT,
+			      G_TYPE_NONE, 5,
+			      G_TYPE_STRING,
 			      G_TYPE_STRING,
 			      GDK_TYPE_DRAG_ACTION,
 			      G_TYPE_INT,
@@ -880,8 +934,9 @@ nautilus_tree_view_drag_dest_class_init 
 			      G_STRUCT_OFFSET (NautilusTreeViewDragDestClass, 
 					       handle_text),
 			      NULL, NULL,
-			      nautilus_marshal_VOID__STRING_ENUM_INT_INT,
-			      G_TYPE_NONE, 4,
+			      nautilus_marshal_VOID__STRING_STRING_ENUM_INT_INT,
+			      G_TYPE_NONE, 5,
+			      G_TYPE_STRING,
 			      G_TYPE_STRING,
 			      GDK_TYPE_DRAG_ACTION,
 			      G_TYPE_INT,
Index: libnautilus-private/nautilus-tree-view-drag-dest.h
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-tree-view-drag-dest.h,v
retrieving revision 1.3
diff -u -p -r1.3 nautilus-tree-view-drag-dest.h
--- libnautilus-private/nautilus-tree-view-drag-dest.h	5 Jul 2005 12:23:34 -0000	1.3
+++ libnautilus-private/nautilus-tree-view-drag-dest.h	8 Jul 2006 10:27:45 -0000
@@ -65,17 +65,20 @@ struct _NautilusTreeViewDragDestClass {
 				 int x,
 				 int y);
 	void (* handle_url)     (NautilusTreeViewDragDest *dest,
-				 char *url,
+				 const char *url,
+				 const char *target_uri,
 				 GdkDragAction action,
 				 int x,
 				 int y);
 	void (* handle_uri_list) (NautilusTreeViewDragDest *dest,
-				  char *uri_list,
+				  const char *uri_list,
+				  const char *target_uri,
 				  GdkDragAction action,
 				  int x,
 				  int y);
 	void (* handle_text)    (NautilusTreeViewDragDest *dest,
-				  char *text,
+				  const char *text,
+				  const char *target_uri,
 				  GdkDragAction action,
 				  int x,
 				  int y);
Index: src/file-manager/fm-directory-view.c
===================================================================
RCS file: /cvs/gnome/nautilus/src/file-manager/fm-directory-view.c,v
retrieving revision 1.745
diff -u -p -r1.745 fm-directory-view.c
--- src/file-manager/fm-directory-view.c	16 Jun 2006 15:40:18 -0000	1.745
+++ src/file-manager/fm-directory-view.c	8 Jul 2006 10:28:17 -0000
@@ -1415,7 +1415,7 @@ action_new_empty_file_callback (GtkActio
 {                
         g_assert (FM_IS_DIRECTORY_VIEW (callback_data));
 
-	fm_directory_view_new_file (FM_DIRECTORY_VIEW (callback_data), NULL);
+	fm_directory_view_new_file (FM_DIRECTORY_VIEW (callback_data), NULL, NULL);
 }
 
 static void
@@ -4217,36 +4217,45 @@ setup_new_folder_data (FMDirectoryView *
 
 static void
 fm_directory_view_new_file_with_initial_contents (FMDirectoryView *directory_view,
+						  const char *parent_uri,
 						  const char *initial_contents)
 {
 	GdkPoint *pos;
 	NewFolderData *data;
-	char *parent_uri;
+
+	g_assert (parent_uri != NULL);
 
 	data = setup_new_folder_data (directory_view);
 
 	pos = context_menu_to_file_operation_position (directory_view);
 
-	parent_uri = fm_directory_view_get_backing_uri (directory_view);
 	nautilus_file_operations_new_file (GTK_WIDGET (directory_view),
 					   pos, parent_uri,
 					   initial_contents,
 					   new_folder_done, data);
-
-	g_free (parent_uri);
 }
 
 void
 fm_directory_view_new_file (FMDirectoryView *directory_view,
+			    const char *parent_uri,
 			    NautilusFile *source)
 {
 	GdkPoint *pos;
 	NewFolderData *data;
-	char *parent_uri;
 	char *source_uri;
+	char *container_uri;
+
+	container_uri = NULL;
+	if (parent_uri == NULL) {
+		container_uri = fm_directory_view_get_backing_uri (directory_view);
+		g_assert (container_uri != NULL);
+	}
 
 	if (source == NULL) {
-		fm_directory_view_new_file_with_initial_contents (directory_view, NULL);
+		fm_directory_view_new_file_with_initial_contents (directory_view,
+								  parent_uri != NULL ? parent_uri : container_uri,
+								  NULL);
+		g_free (container_uri);
 		return;
 	}
 
@@ -4257,17 +4266,16 @@ fm_directory_view_new_file (FMDirectoryV
 	data = setup_new_folder_data (directory_view);
 
 	source_uri = nautilus_file_get_uri (source);
-	parent_uri = fm_directory_view_get_backing_uri (directory_view);
 
 	nautilus_file_operations_new_file_from_template (GTK_WIDGET (directory_view),
 							 pos,
-							 parent_uri,
+							 parent_uri != NULL ? parent_uri : container_uri,
 							 NULL,
 							 source_uri,
 							 new_folder_done, data);
 
-	g_free (parent_uri);
 	g_free (source_uri);
+	g_free (container_uri);
 }
 
 /* handle the open command */
@@ -5567,7 +5575,7 @@ create_template_callback (GtkAction *act
 
 	parameters = callback_data;
 	
-	fm_directory_view_new_file (parameters->directory_view, parameters->file);
+	fm_directory_view_new_file (parameters->directory_view, NULL, parameters->file);
 }
 
 static void
@@ -9632,6 +9640,7 @@ ask_link_action (FMDirectoryView *view)
 void
 fm_directory_view_handle_url_drop (FMDirectoryView  *view,
 				   const char       *encoded_url,
+				   const char       *target_uri,
 				   GdkDragAction     action,
 				   int               x,
 				   int               y)
@@ -9652,10 +9661,13 @@ fm_directory_view_handle_url_drop (FMDir
 		return;
 	}
 
-	container_uri = fm_directory_view_get_backing_uri (view);
-	g_return_if_fail (container_uri != NULL);
+	container_uri = NULL;
+	if (target_uri == NULL) {
+		container_uri = fm_directory_view_get_backing_uri (view);
+		g_assert (container_uri != NULL);
+	}
 
-	if (eel_vfs_has_capability (container_uri,
+	if (eel_vfs_has_capability (target_uri != NULL ? target_uri : container_uri,
 				    EEL_VFS_CAPABILITY_IS_REMOTE_AND_SLOW)) {
 		eel_show_warning_dialog (_("Drag and drop is not supported."),
 					 _("Drag and drop is only supported on local file systems."),
@@ -9736,7 +9748,7 @@ fm_directory_view_handle_url_drop (FMDir
 			screen = gtk_widget_get_screen (GTK_WIDGET (view));
 			screen_num = gdk_screen_get_number (screen);
 
-			nautilus_link_local_create (container_uri,
+			nautilus_link_local_create (target_uri != NULL ? target_uri : container_uri,
 						    link_name,
 						    link_display_name,
 						    "gnome-fs-bookmark",
@@ -9758,7 +9770,7 @@ fm_directory_view_handle_url_drop (FMDir
 		uri_list = g_list_append (uri_list, url);
 
 		fm_directory_view_move_copy_items (uri_list, points,
-						   container_uri,
+						   target_uri != NULL ? target_uri : container_uri,
 						   action, x, y, view);
 
 		g_list_free (uri_list);
@@ -9773,6 +9785,7 @@ fm_directory_view_handle_url_drop (FMDir
 void
 fm_directory_view_handle_uri_list_drop (FMDirectoryView  *view,
 					const char       *item_uris,
+					const char       *target_uri,
 					GdkDragAction     action,
 					int               x,
 					int               y)
@@ -9787,8 +9800,11 @@ fm_directory_view_handle_uri_list_drop (
 		return;
 	}
 
-	container_uri = fm_directory_view_get_backing_uri (view);
-	g_return_if_fail (container_uri != NULL);
+	container_uri = NULL;
+	if (target_uri == NULL) {
+		container_uri = fm_directory_view_get_backing_uri (view);
+		g_assert (container_uri != NULL);
+	}
 
 	if (action == GDK_ACTION_ASK) {
 		action = nautilus_drag_drop_action_ask
@@ -9847,7 +9863,7 @@ fm_directory_view_handle_uri_list_drop (
 	}
 
 	fm_directory_view_move_copy_items (real_uri_list, points,
-					   container_uri,
+					   target_uri != NULL ? target_uri : container_uri,
 					   action, x, y, view);
 
 	eel_g_list_free_deep (real_uri_list);
@@ -9861,6 +9877,7 @@ fm_directory_view_handle_uri_list_drop (
 void
 fm_directory_view_handle_text_drop (FMDirectoryView  *view,
 				    const char       *text,
+				    const char       *target_uri,
 				    GdkDragAction     action,
 				    int               x,
 				    int               y)
@@ -9873,11 +9890,14 @@ fm_directory_view_handle_text_drop (FMDi
 
 	g_return_if_fail (action == GDK_ACTION_COPY);
 
-	container_uri = fm_directory_view_get_backing_uri (view);
-	g_return_if_fail (container_uri != NULL);
+	container_uri = NULL;
+	if (target_uri == NULL) {
+		container_uri = fm_directory_view_get_backing_uri (view);
+		g_assert (container_uri != NULL);
+	}
 
 	fm_directory_view_new_file_with_initial_contents (
-		view, text);
+		view, target_uri != NULL ? target_uri : container_uri, text);
 
 	g_free (container_uri);
 }
Index: src/file-manager/fm-directory-view.h
===================================================================
RCS file: /cvs/gnome/nautilus/src/file-manager/fm-directory-view.h,v
retrieving revision 1.144
diff -u -p -r1.144 fm-directory-view.h
--- src/file-manager/fm-directory-view.h	30 Mar 2006 19:37:22 -0000	1.144
+++ src/file-manager/fm-directory-view.h	8 Jul 2006 10:28:19 -0000
@@ -404,21 +404,25 @@ gboolean	    fm_directory_view_should_so
 void                fm_directory_view_update_menus                     (FMDirectoryView  *view);
 void                fm_directory_view_new_folder                       (FMDirectoryView  *view);
 void                fm_directory_view_new_file                         (FMDirectoryView  *view,
+									const char       *parent_uri,
 									NautilusFile     *source);
 void                fm_directory_view_ignore_hidden_file_preferences   (FMDirectoryView  *view);
 void                fm_directory_view_init_view_iface                  (NautilusViewIface *iface);
 void                fm_directory_view_handle_url_drop                  (FMDirectoryView  *view,
 									const char       *encoded_url,
+									const char       *target_uri,
 									GdkDragAction     action,
 									int               x,
 									int               y);
 void                fm_directory_view_handle_uri_list_drop             (FMDirectoryView  *view,
 									const char       *item_uris,
+									const char       *target_uri,
 									GdkDragAction     action,
 									int               x,
 									int               y);
 void                fm_directory_view_handle_text_drop                 (FMDirectoryView  *view,
 									const char       *text,
+									const char       *target_uri,
 									GdkDragAction     action,
 									int               x,
 									int               y);
Index: src/file-manager/fm-icon-view.c
===================================================================
RCS file: /cvs/gnome/nautilus/src/file-manager/fm-icon-view.c,v
retrieving revision 1.323
diff -u -p -r1.323 fm-icon-view.c
--- src/file-manager/fm-icon-view.c	15 May 2006 22:55:25 -0000	1.323
+++ src/file-manager/fm-icon-view.c	8 Jul 2006 10:28:24 -0000
@@ -2527,26 +2527,29 @@ create_icon_container (FMIconView *icon_
 /* Handles an URL received from Mozilla */
 static void
 icon_view_handle_url (NautilusIconContainer *container, const char *encoded_url,
+		      const char *target_uri,
 		      GdkDragAction action, int x, int y, FMIconView *view)
 {
 	fm_directory_view_handle_url_drop (FM_DIRECTORY_VIEW (view),
-					   encoded_url, action, x, y);
+					   encoded_url, target_uri, action, x, y);
 }
 
 static void
 icon_view_handle_uri_list (NautilusIconContainer *container, const char *item_uris,
+			   const char *target_uri,
 			   GdkDragAction action, int x, int y, FMIconView *view)
 {
 	fm_directory_view_handle_uri_list_drop (FM_DIRECTORY_VIEW (view),
-						item_uris, action, x, y);
+						item_uris, target_uri, action, x, y);
 }
 
 static void
 icon_view_handle_text (NautilusIconContainer *container, const char *text,
+		       const char *target_uri,
 		       GdkDragAction action, int x, int y, FMIconView *view)
 {
 	fm_directory_view_handle_text_drop (FM_DIRECTORY_VIEW (view),
-					    text, action, x, y);
+					    text, target_uri, action, x, y);
 }
 
 static char *
Index: src/file-manager/fm-list-view.c
===================================================================
RCS file: /cvs/gnome/nautilus/src/file-manager/fm-list-view.c,v
retrieving revision 1.270
diff -u -p -r1.270 fm-list-view.c
--- src/file-manager/fm-list-view.c	24 May 2006 13:20:42 -0000	1.270
+++ src/file-manager/fm-list-view.c	8 Jul 2006 10:28:28 -0000
@@ -1044,26 +1044,28 @@ get_file_for_path_callback (NautilusTree
 /* Handles an URL received from Mozilla */
 static void
 list_view_handle_url (NautilusTreeViewDragDest *dest, const char *encoded_url,
-		      GdkDragAction action, int x, int y, FMListView *view)
+		      const char *target_uri, GdkDragAction action, int x, int y, FMListView *view)
 {
 	fm_directory_view_handle_url_drop (FM_DIRECTORY_VIEW (view),
-					   encoded_url, action, x, y);
+					   encoded_url, target_uri, action, x, y);
 }
 
 static void
 list_view_handle_uri_list (NautilusTreeViewDragDest *dest, const char *item_uris,
+			   const char *target_uri,
 			   GdkDragAction action, int x, int y, FMListView *view)
 {
 	fm_directory_view_handle_uri_list_drop (FM_DIRECTORY_VIEW (view),
-						item_uris, action, x, y);
+						item_uris, target_uri, action, x, y);
 }
 
 static void
 list_view_handle_text (NautilusTreeViewDragDest *dest, const char *text,
+		       const char *target_uri,
 		       GdkDragAction action, int x, int y, FMListView *view)
 {
 	fm_directory_view_handle_text_drop (FM_DIRECTORY_VIEW (view),
-					    text, action, x, y);
+					    text, target_uri, action, x, y);
 }
 
 static void


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