[PATCH] Fixed drag and drop between Nautilus and Mozilla



Hi,

Not entirely unmotivated by the bounty I have been working on #127553,
"Drag and Drop between Gnome and Mozilla". I got the thing mostly
solved, but the code could use some reviewing, and I need some
directions for solving the last remaining issue:

nautilus_link_local_create just overwrites any file without asking. So,
we need an overwrite confirmation dialog. However, the standard one is
nested in nautilus-file-operations.c:handle_transfer_overwrite. I could
move it into its own function, which could then be used in
nautilus_link_local_create as well. Another option would be
link_local_creating the links in tmp files, and then using
fm_directory_view_move_copy_items to move them to the right place.

I'll attach the patch to this mail as well for increased reviewing
convenience.

Cheers,
Jorn
Index: libnautilus-private/nautilus-link-desktop-file.c
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-link-desktop-file.c,v
retrieving revision 1.29
diff -u -r1.29 nautilus-link-desktop-file.c
--- libnautilus-private/nautilus-link-desktop-file.c	12 Oct 2004 10:32:45 -0000	1.29
+++ libnautilus-private/nautilus-link-desktop-file.c	9 Jan 2005 19:58:24 -0000
@@ -116,7 +116,7 @@
 	g_return_val_if_fail (target_uri != NULL, FALSE);
 
 	escaped_name = gnome_vfs_escape_string (file_name);
-	uri = g_strdup_printf ("%s/%s", directory_uri, escaped_name);
+	uri = g_strdup_printf ("%s/%s.desktop", directory_uri, escaped_name);
 	g_free (escaped_name);
 
 	contents = g_strdup_printf ("[Desktop Entry]\n"
Index: src/file-manager/fm-icon-view.c
===================================================================
RCS file: /cvs/gnome/nautilus/src/file-manager/fm-icon-view.c,v
retrieving revision 1.301
diff -u -r1.301 fm-icon-view.c
--- src/file-manager/fm-icon-view.c	22 Nov 2004 15:24:38 -0000	1.301
+++ src/file-manager/fm-icon-view.c	9 Jan 2005 19:58:31 -0000
@@ -46,6 +46,7 @@
 #include <gtk/gtkradioaction.h>
 #include <gtk/gtksignal.h>
 #include <gtk/gtkwindow.h>
+#include <gtk/gtkstock.h>
 #include <libgnome/gnome-i18n.h>
 #include <libgnome/gnome-config.h>
 #include <libgnome/gnome-desktop-item.h>
@@ -187,7 +188,9 @@
 								       NautilusFile         *file,
 								       gboolean              start_flag);
 static void                 update_layout_menus                       (FMIconView           *view);
-
+static int                  ask_link_action                           (FMIconView           *view,
+								       char                 *uri,
+								       int                   n_uris);
 
 static void fm_icon_view_iface_init (NautilusViewIface *iface);
 
@@ -2469,16 +2472,15 @@
 	GdkPoint point;
 	char *uri;
 	char *path;
-	char *stripped_uri;
 	char *container_uri;
 	char *mime_type;
-	const char *last_slash, *link_name;
-	char *link_file_name;
-	int n_uris, n_links;
+	int n_uris;
 	gboolean all_local;
 	GArray *points;
 	GdkScreen *screen;
 	int screen_num;
+	GList *remote_uri_list = NULL, *symlink_uri_list = NULL;
+	int n_remote_uris, n_symlink_uris;
 
 	if (item_uris == NULL) {
 		return;
@@ -2550,27 +2552,27 @@
 	}
 	nautilus_icon_dnd_uri_list_free_strings (uri_list);
 
+	if (n_uris == 1) {
+		GdkPoint tmp_point = { 0, 0 };
+
+		/* pass in a 1-item array of icon positions, relative to x, y */
+		points = g_array_new (FALSE, TRUE, sizeof (GdkPoint));
+		g_array_append_val (points, tmp_point);
+	} else {
+		points = NULL;
+	}
+
 	if (all_local == TRUE &&
 	    (action == GDK_ACTION_COPY ||
 	     action == GDK_ACTION_MOVE)) {
 		/* Copying files */
-		if (n_uris == 1) {
-			GdkPoint tmp_point = { 0, 0 };
-
-			/* pass in a 1-item array of icon positions, relative to x, y */
-			points = g_array_new (FALSE, TRUE, sizeof (GdkPoint));
-			g_array_append_val (points, tmp_point);
-		} else {
-			points = NULL;
-		}
 		fm_directory_view_move_copy_items (real_uri_list, points,
 						   container_uri,
 						   action, x, y, FM_DIRECTORY_VIEW (view));
-		
-		if (points)
-			g_array_free (points, TRUE);
 	} else {
-		n_links = 0;
+		n_remote_uris = 0;
+		n_symlink_uris = 0;
+
 		for (node = real_uri_list; node != NULL; node = node->next) {
 			/* Make a link using the desktop file contents? */
 			uri = node->data;
@@ -2598,38 +2600,27 @@
 			if (entry != NULL) {
 				/* FIXME: Handle name conflicts? */
 				nautilus_link_local_create_from_gnome_entry (entry, container_uri, 
-				                                             (n_links > 0) ? NULL: &point, screen_num);
+				                                             &point, screen_num);
 
 				gnome_desktop_item_unref (entry);
 				continue;
 			}
 
-			/* Make a link from the URI alone. Generate the file
-			 * name by extracting the basename of the URI.
+			/* Only an URI specified. If the URI is local, create a
+			 * symbolic link. Otherwise, ask whether to create a
+			 * bookmark or to copy/download the file.
 			 */
-			/* FIXME: This should be using eel_uri_get_basename
-			 * instead of a "roll our own" solution.
-			 */
-			stripped_uri = eel_str_strip_trailing_chr (uri, '/');
-			last_slash = strrchr (stripped_uri, '/');
-			link_name = last_slash == NULL ? NULL : last_slash + 1;
-			
-			if (!eel_str_is_empty (link_name)) {
-				link_file_name = g_strconcat (link_name, ".desktop", NULL);
-				/* FIXME: Handle name conflicts? */
-				nautilus_link_local_create (container_uri,
-							    link_file_name,
-							    link_name,
-							    NULL, uri,
-							    (n_links > 0) ? NULL: &point, 
-							    screen_num,
-							    NAUTILUS_LINK_GENERIC);
-				g_free (link_file_name);
+			if (eel_is_remote_uri (uri)) {
+				/* Create a list of remote uris, so that we only
+				 * once have to ask what to do
+				 */
+				remote_uri_list = g_list_append (remote_uri_list, uri);
+				n_remote_uris++;
+			} else {
+				symlink_uri_list = g_list_append (symlink_uri_list, uri);
+				n_symlink_uris++;
 			}
-			
-			n_links++;
-			g_free (stripped_uri);
-			
+
 			/* The following break statement handles mozilla urls.  
 			 * Do not remove it; otherwise, nautilus will create two 
 			 * links when the url is dropped on the desktop.
@@ -2638,12 +2629,66 @@
 				break;
 			}
 		}
+
+		if (n_remote_uris > 0) {
+			char *link_name;
+			char *sample_uri;
+			int n_links;
+			int link_action;
+
+			/* Take a sample uri to get the protocol */
+			sample_uri = remote_uri_list->data;
+			link_action = ask_link_action (view, sample_uri, n_remote_uris);
+
+			switch (link_action) {
+			case GDK_ACTION_COPY:
+				fm_directory_view_move_copy_items (remote_uri_list, points,
+								   container_uri,
+								   GDK_ACTION_COPY, x, y, FM_DIRECTORY_VIEW (view));
+				break;
+			case GDK_ACTION_LINK:
+				n_links = 0;
+				for (node = remote_uri_list; node != NULL; node = node->next) {
+					uri = node->data;
+
+					link_name = eel_uri_get_basename (uri);
+					if (!eel_str_is_empty (link_name)) {
+						/* FIXME: Handle name conflicts? */
+						nautilus_link_local_create (container_uri, link_name,
+									    "gnome-fs-bookmark", uri,
+									    (n_links > 0) ? NULL : &point,
+									    screen_num,
+									    NAUTILUS_LINK_GENERIC);
+						n_links++;
+					}
+					g_free (link_name);
+				}
+
+				break;
+			case -1:
+				break;
+			default:
+				g_assert_not_reached ();
+				break;
+			}
+
+			g_list_free (remote_uri_list);
+		}
+
+		if (n_symlink_uris > 0) {
+			fm_directory_view_move_copy_items (symlink_uri_list, points,
+							   container_uri,
+							   GDK_ACTION_LINK, x, y, FM_DIRECTORY_VIEW (view));
+			g_list_free (symlink_uri_list);
+		}
 	}
-	
+
 	nautilus_icon_dnd_uri_list_free_strings (real_uri_list);
 
+	if (points)
+		g_array_free (points, TRUE);
+
 	g_free (container_uri);
-	
 }
 
 static char *
@@ -2680,6 +2725,69 @@
 			nautilus_file_unref (file);
 		}
 	}
+}
+
+static int
+ask_link_action (FMIconView *view, char *uri, int n_uris)
+{
+	const char *prompt, *detail, *link_action, *copy_action;
+	char *scheme;
+	int button_pressed, result;
+
+	scheme = eel_uri_get_scheme (uri);
+	if (strcmp (scheme, "http") == 0) {
+		if (n_uris > 1) {
+			prompt = _("Download the links?");
+			detail = _("You can download the links or create bookmarks.");
+		} else {
+			prompt = _("Download the link?");
+			detail = _("You can download the link or create a bookmark.");
+		}
+
+		link_action = _("_Bookmark");
+		copy_action = _("_Download");
+	} else {
+		if (n_uris > 1) {
+			prompt = _("Copy the files?");
+			detail = _("You can copy the files or create links.");
+		} else {
+			prompt = _("Copy the file?");
+			detail = _("You can copy the file or create a link.");
+		}
+
+		link_action = _("C_opy");
+		copy_action = _("_Link");
+	}
+	g_free (scheme);
+
+	button_pressed = eel_run_simple_dialog (GTK_WIDGET (fm_directory_view_get_containing_window (FM_DIRECTORY_VIEW (view))),
+			                        TRUE,
+			                        GTK_MESSAGE_QUESTION,
+                                                prompt,
+                                                detail,
+                                                NULL, /* as per HIG */
+                                                link_action,
+                                                GTK_STOCK_CANCEL,
+                                                copy_action,
+                                                NULL);
+
+	switch (button_pressed) {
+	case 0:
+		result = GDK_ACTION_LINK;
+		break;
+	case 1:
+	case GTK_RESPONSE_DELETE_EVENT:
+		result = -1;
+		break;
+	case 2:
+		result = GDK_ACTION_COPY;
+		break;
+	default:
+		g_assert_not_reached ();
+		result = -1;
+	}
+
+	return result;
 }
 
 static void


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