Re: PATCH: use local path when dropping files onto icons



I've finally been able to finish of a patch that implements this.
Nautilus now uses gnome_desktop_item_launch to launch desktop items.
That avoids code duplication in nautilus/gnome-desktop.

Patch for gnome-desktop that adds a new launch option that nautilus
requires is attached. That patch also fixes a problem in gnome-desktop
that occurs when it gets the local path from uris incorrectly. (can
somebody have a look at how I added that new option, is 2<<0 correct for
that?)

Patch for nautilus makes it use the gnome-desktop stuff and cleans up
code in the directory view. As a bonus it also includes a simple fix for
41773 and executable text files.

Ok to commit?

- Frank
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/nautilus/ChangeLog,v
retrieving revision 1.5374
diff -u -p -r1.5374 ChangeLog
--- ChangeLog	14 Jun 2002 21:28:50 -0000	1.5374
+++ ChangeLog	18 Jun 2002 02:38:05 -0000
@@ -1,3 +1,21 @@
+2002-06-17  Frank Worsley  <fworsley shaw ca>
+
+	* libnautilus-private/nautilus-link-desktop-file.c:
+	(nautilus_link_desktop_file_get_link_uri_from_desktop):
+	return the desktop file path for a command: uri, instead
+	of the Exec field from the desktop file
+	
+	* src/file-manager/fm-directory-view.c:
+	(get_executable_text_file_action):
+	add a "run in terminal" option for executable text files
+	
+	(activate_callback), (fm_directory_view_move_copy_items):
+	use gnome_desktop_item_launch for launching desktop files,
+	that means we also support the Exec field parameters
+	
+	(execute_command_with_uris):
+	new function to implement the above
+
 2002-06-14  Damon Chaplin  <damon ximian com>
 
 	* src/nautilus-preferences-dialog.c (preferences_show_help): new
Index: libnautilus-private/nautilus-link-desktop-file.c
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-link-desktop-file.c,v
retrieving revision 1.20
diff -u -p -r1.20 nautilus-link-desktop-file.c
--- libnautilus-private/nautilus-link-desktop-file.c	23 May 2002 23:13:56 -0000	1.20
+++ libnautilus-private/nautilus-link-desktop-file.c	18 Jun 2002 02:38:05 -0000
@@ -266,9 +266,7 @@ nautilus_link_desktop_file_local_get_lin
 static char *
 nautilus_link_desktop_file_get_link_uri_from_desktop (GnomeDesktopItem *desktop_file)
 {
-	char *terminal_command;
 	const char *launch_string;
-	gboolean need_term;
 	const char *type;
 	char *retval;
 
@@ -284,15 +282,9 @@ nautilus_link_desktop_file_get_link_uri_
 		if (launch_string == NULL) {
 			return NULL;
 		}
-
-		need_term = gnome_desktop_item_get_boolean (desktop_file, "Terminal");
-		if (need_term) {
-			terminal_command = eel_gnome_make_terminal_command (launch_string);
-			retval = g_strconcat ("command:", terminal_command, NULL);
-			g_free (terminal_command);
-		} else {
-			retval = g_strconcat ("command:", launch_string, NULL);
-		}
+		
+		launch_string = gnome_desktop_item_get_location (desktop_file);
+		retval = g_strconcat ("command:", launch_string, NULL);
 	} else if (strcmp (type, "URL") == 0) {
 		/* Some old broken desktop files use this nonstandard feature, we need handle it though */
 		retval = g_strdup (gnome_desktop_item_get_string (desktop_file, "Exec"));
Index: src/file-manager/fm-directory-view.c
===================================================================
RCS file: /cvs/gnome/nautilus/src/file-manager/fm-directory-view.c,v
retrieving revision 1.540
diff -u -p -r1.540 fm-directory-view.c
--- src/file-manager/fm-directory-view.c	31 May 2002 05:41:53 -0000	1.540
+++ src/file-manager/fm-directory-view.c	18 Jun 2002 02:38:06 -0000
@@ -97,6 +97,7 @@
 
 #define RESPONSE_RUN 1000
 #define RESPONSE_DISPLAY 1001
+#define RESPONSE_RUN_IN_TERMINAL 1002
 
 /* MOD2 is num lock -- I would include MOD3-5 if I was sure they were not lock keys */
 #define ALL_NON_LOCK_MODIFIER_KEYS (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK)
@@ -248,6 +249,7 @@ typedef enum {
 
 typedef enum {
 	ACTIVATION_ACTION_LAUNCH,
+	ACTIVATION_ACTION_LAUNCH_IN_TERMINAL,
 	ACTIVATION_ACTION_DISPLAY,
 	ACTIVATION_ACTION_DO_NOTHING
 } ActivationAction;
@@ -334,6 +336,9 @@ static void     fm_directory_view_select
 								NautilusFile         *file);
 static void     monitor_file_for_open_with                     (FMDirectoryView      *view,
 								NautilusFile         *file);
+static void	execute_command_with_uris		       (FMDirectoryView	     *view,
+								const char	     *target_uri,
+								const GList	     *item_uris);
 
 EEL_CLASS_BOILERPLATE (FMDirectoryView, fm_directory_view, GTK_TYPE_SCROLLED_WINDOW)
 
@@ -4764,8 +4769,9 @@ get_executable_text_file_action (FMDirec
 	dialog = eel_create_question_dialog (prompt,
 					     _("Run or Display?"),
 					     _("Run"), RESPONSE_RUN,
-					     _("Display"), RESPONSE_DISPLAY,
+					     _("Run in terminal"), RESPONSE_RUN_IN_TERMINAL,
 					     fm_directory_view_get_containing_window (view));
+	gtk_dialog_add_button (dialog, _("Display"), RESPONSE_DISPLAY);
 	gtk_dialog_add_button (dialog, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
 	gtk_widget_show (GTK_WIDGET (dialog));
 	
@@ -4777,6 +4783,8 @@ get_executable_text_file_action (FMDirec
 	switch (response) {
 	case RESPONSE_RUN:
 		return ACTIVATION_ACTION_LAUNCH;
+	case RESPONSE_RUN_IN_TERMINAL:
+		return ACTIVATION_ACTION_LAUNCH_IN_TERMINAL;
 	case RESPONSE_DISPLAY:
 		return ACTIVATION_ACTION_DISPLAY;
 	default:
@@ -4789,11 +4797,10 @@ activate_callback (NautilusFile *file, g
 {
 	ActivateParameters *parameters;
 	FMDirectoryView *view;
-	char *uri, *command, *executable_path, *quoted_path, *name, *file_uri, *file_uri_scheme;
+	char *uri, *file_uri;
+	char *executable_path, *quoted_path, *name;
 	GnomeVFSMimeApplication *application;
 	ActivationAction action;
-	GnomeDesktopItem *desktop_item;
-	int error;
 	
 	parameters = callback_data;
 
@@ -4813,50 +4820,12 @@ activate_callback (NautilusFile *file, g
 		report_broken_symbolic_link (view, file);
 		action = ACTIVATION_ACTION_DO_NOTHING;
 	} else if (eel_istr_has_prefix (uri, NAUTILUS_COMMAND_SPECIFIER)) {
-		/* Don't allow command execution from remote locations where the
-		 * uri scheme isn't file:// (This is because files on for example
-		 * nfs are treated as remote)
-		 * to partially mitigate the security risk of
-		 * executing arbitrary commands.
-		 */
-		file_uri_scheme = nautilus_file_get_uri_scheme (file);
-		
-		if (!nautilus_file_is_local (file) && strcmp (file_uri_scheme, "file") != 0) {
-			eel_show_error_dialog
-				(_("Sorry, but you can't execute commands from "
-				   "a remote site due to security considerations."), 
-				 _("Can't execute remote links"),
-				 fm_directory_view_get_containing_window (view));
-			action = ACTIVATION_ACTION_DO_NOTHING;
-		} else {
-			file_uri = nautilus_file_get_uri (file); 
-			desktop_item = gnome_desktop_item_new_from_uri (file_uri, 0, NULL);
-			g_free (file_uri);
-			if (desktop_item == NULL) {
-				error = -1;
-			} else {
-				error = gnome_desktop_item_launch (desktop_item, NULL, 0, NULL);
-				gnome_desktop_item_unref (desktop_item);
-			}
-			if (error == -1) {
-				/* As an additional precaution, only execute
-				 * commands without any parameters, which is
-				 * enforced by using a call that uses
-				 * fork/execlp instead of system.
-				 * cf.: nautilus-program-choosing.c
-				 */
-				command = uri + strlen (NAUTILUS_COMMAND_SPECIFIER);
-				nautilus_launch_application_from_command ("",
-									  command,
-									  NULL, /* param */
-									  FALSE);
-			}
-
-			action = ACTIVATION_ACTION_DO_NOTHING;
-		}
-
-		g_free (file_uri_scheme);
+		file_uri = nautilus_file_get_uri (file);
+		execute_command_with_uris (view, file_uri, NULL);
+		action = ACTIVATION_ACTION_DO_NOTHING;
+		g_free (file_uri);
 	}
+
 	if (action != ACTIVATION_ACTION_DO_NOTHING && file_is_launchable (file)) {
 
 		action = ACTIVATION_ACTION_LAUNCH;
@@ -4881,20 +4850,17 @@ activate_callback (NautilusFile *file, g
 			action = get_executable_text_file_action (view, file);
 		}
 
-		if (action == ACTIVATION_ACTION_LAUNCH) {
+		if (action == ACTIVATION_ACTION_LAUNCH ||
+		    action == ACTIVATION_ACTION_LAUNCH_IN_TERMINAL) {
 			quoted_path = g_shell_quote (executable_path);
 			name = nautilus_file_get_name (file);
-			/* FIXME bugzilla.gnome.org 41773: This is a
-			 * lame way to run command-line tools, since
-			 * there's no terminal for the output. But if
-			 * we always had a terminal, that would be
-			 * just as bad.
-			 */
-			nautilus_launch_application_from_command (name, quoted_path, NULL, FALSE);
+			nautilus_launch_application_from_command 
+						(name, quoted_path, NULL,
+						 (action == ACTIVATION_ACTION_LAUNCH_IN_TERMINAL) /* use terminal */ );
 			g_free (name);
 			g_free (quoted_path);
 		}
-		
+
 		g_free (executable_path);
 	}
 
@@ -5658,6 +5624,101 @@ fm_directory_view_get_uri (FMDirectoryVi
 	return nautilus_directory_get_uri (view->details->model);
 }
 
+static void
+execute_command_with_uris (FMDirectoryView *view,
+			   const char  *target_uri,
+			   const GList *item_uris)
+{
+	GError *error;
+	GnomeDesktopItem *ditem;
+	const char *command_string;
+	char *local_path, *message;
+	const GList *p;
+	int total, count;
+
+	/* strip the leading "command:" */
+	if (eel_istr_has_prefix (target_uri, NAUTILUS_COMMAND_SPECIFIER)) {
+		target_uri += strlen (NAUTILUS_COMMAND_SPECIFIER);
+	}
+
+	/* Don't allow command execution from remote locations where the
+	 * uri scheme isn't file:// (This is because files on for example
+	 * nfs are treated as remote) to partially mitigate the security
+	 * risk of executing arbitrary commands.
+	 */
+	local_path = gnome_vfs_get_local_path_from_uri (target_uri);
+	if (local_path == NULL) {
+		eel_show_error_dialog
+			(_("Sorry, but you can't execute commands from "
+			   "a remote site due to security considerations."), 
+			 _("Can't execute remote links"),
+			 fm_directory_view_get_containing_window (view));
+	
+		return;
+	}
+	g_free (local_path);
+	
+	ditem = gnome_desktop_item_new_from_uri (target_uri,
+						GNOME_DESKTOP_ITEM_LOAD_ONLY_IF_EXISTS,
+						NULL);	
+	if (ditem == NULL) {
+		/* target must have been deleted in the meantime. */
+		/* FIXME: should we display an error for this? */
+		return;
+	}
+	
+	/* check if this app only supports local files */
+	command_string = gnome_desktop_item_get_string (ditem, GNOME_DESKTOP_ITEM_EXEC);
+	if ((strstr (command_string, "%F") || strstr (command_string, "%f"))
+		&& !(strstr (command_string, "%U") || strstr (command_string, "%u"))
+		&& item_uris != NULL) {
+	
+		/* count the number of uris with local paths */
+		count = 0;
+		total = g_list_length ((GList *) item_uris);
+		for (p = item_uris; p != NULL; p = p->next) {
+			local_path = gnome_vfs_get_local_path_from_uri ((const char *) p->data);
+			if (local_path != NULL) {
+				g_free (local_path);
+				count++;
+			}
+		}
+			
+		if (count != total) {
+			eel_show_error_dialog
+				(_("This drop target only supports local files.\n\n"
+				   "To open non-local files copy them to a local folder and then"
+				   " drop them again."),
+				 _("Drop target only supports local files"),
+				 fm_directory_view_get_containing_window (view));
+		}
+		
+		if (count == 0) {
+			gnome_desktop_item_unref (ditem);
+			return;
+		}
+	}
+	
+	error = NULL;
+	gnome_desktop_item_launch (ditem, (GList *) item_uris,
+				   GNOME_DESKTOP_ITEM_LAUNCH_APPEND_URIS,
+				   &error);
+
+	if (error != NULL) {
+		message = g_strconcat (_("There was an error launching the application.\n\n"
+					 "Details: "), error->message, NULL);
+		eel_show_error_dialog
+			(message,
+			 _("Error launching application"),
+			 fm_directory_view_get_containing_window (view));			
+			 
+		g_clear_error (&error);
+		g_free (message);
+	}
+	
+	gnome_desktop_item_unref (ditem);
+}
+
 void
 fm_directory_view_move_copy_items (const GList *item_uris,
 				   GArray *relative_item_points,
@@ -5666,9 +5727,6 @@ fm_directory_view_move_copy_items (const
 				   int x, int y,
 				   FMDirectoryView *view)
 {
-	char *command_string, *scanner;
-	int length;
-	const GList *p;
 	
 	g_assert (relative_item_points == NULL
 		  || relative_item_points->len == 0 
@@ -5679,34 +5737,7 @@ fm_directory_view_move_copy_items (const
 
 	/* special-case "command:" here instead of starting a move/copy */
 	if (eel_str_has_prefix (target_uri, NAUTILUS_COMMAND_SPECIFIER)) {
-		/* execute command, passing it the dragged uris */
-		
-		/* strip the leading "command:" */
-		target_uri += strlen (NAUTILUS_COMMAND_SPECIFIER);
-
-		/* how long will the command string be? */
-		length = strlen (target_uri) + 1;
-		for (p = item_uris; p != NULL; p = p->next) {
-			length += strlen ((const char *) p->data) + 1;
-		}
-		
-		command_string = g_malloc (length);
-		scanner = command_string;
-		
-		/* copy the command string */
-		strcpy (scanner, target_uri);
-		scanner += strlen (scanner);
-		
-		/* copy the uris */
-		for (p = item_uris; p != NULL; p = p->next) {
-			sprintf (scanner, " %s", (const char *) p->data);
-			scanner += strlen (scanner);
-		}
-		
-		/* execute the command */
-		eel_gnome_shell_execute (command_string);
-		
-		g_free (command_string);
+		execute_command_with_uris (view, target_uri, item_uris);
 		return;
 	}
 	
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gnome-desktop/ChangeLog,v
retrieving revision 1.446
diff -u -p -r1.446 ChangeLog
--- ChangeLog	17 Jun 2002 06:09:43 -0000	1.446
+++ ChangeLog	18 Jun 2002 02:42:18 -0000
@@ -1,3 +1,18 @@
+2002-06-17  Frank Worsley  <fworsley shaw ca>
+
+	* libgnome-desktop/gnome-desktop-item.c:
+	(stringify_files):
+	correctly determine local path for %f and %F parameters
+	in Exec field
+	
+	(ditem_execute), (gnome_desktop_item_launch):
+	support new launch options
+	
+	* libgnome-desktop/gnome-desktop-item.h:
+	added new GNOME_DESKTOP_ITEM_LAUNCH_APPEND_URIS option
+	to always append command line parameters even if no
+	Exec field parameters are present
+
 2002-06-17  Mark McLoughlin  <mark skynet ie>
 
 	* configure.in: Version 2.0.1.
Index: libgnome-desktop/gnome-desktop-item.c
===================================================================
RCS file: /cvs/gnome/gnome-desktop/libgnome-desktop/gnome-desktop-item.c,v
retrieving revision 1.103
diff -u -p -r1.103 gnome-desktop-item.c
--- libgnome-desktop/gnome-desktop-item.c	3 Jun 2002 20:24:18 -0000	1.103
+++ libgnome-desktop/gnome-desktop-item.c	18 Jun 2002 02:42:19 -0000
@@ -1079,18 +1079,28 @@ stringify_files (GSList *args,
 
 	for (li = args; li != NULL; li = li->next) {
 		GnomeVFSURI *uri = li->data;
-		if (gnome_vfs_uri_is_local (uri)) {
-			const char *path;
+		if (!strcmp (gnome_vfs_uri_get_scheme (uri), "file")) {
+			char *path, *local_path;
 			char *escaped;
-			path = gnome_vfs_uri_get_path (uri);
-			g_string_append (str, sep);
-
-			escaped = escape_single_quotes (path,
-							in_single_quotes,
-							in_double_quotes);
-			g_string_append (str, escaped);
-			g_free (escaped);
-
+			
+			path = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_NONE);
+			local_path = gnome_vfs_get_local_path_from_uri (path);
+
+			if (local_path != NULL) {
+				/* should never be null since we check for scheme
+				 * above, but you never know ...
+				 */
+				g_string_append (str, sep);
+	
+				escaped = escape_single_quotes (local_path,
+								in_single_quotes,
+								in_double_quotes);
+				g_string_append (str, escaped);
+				g_free (escaped);
+				g_free (local_path);
+			}
+			
+			g_free (path);
 			sep = " ";
 		}
 
@@ -1450,6 +1460,7 @@ ditem_execute (const GnomeDesktopItem *i
 	       GList *file_list,
 	       gboolean launch_only_one,
 	       gboolean use_current_dir,
+		 gboolean append_uris,
 	       GError **error)
 {
 	char **real_argv;
@@ -1462,7 +1473,7 @@ ditem_execute (const GnomeDesktopItem *i
 	const char *working_dir = NULL;
 	char **temp_argv = NULL;
 	int temp_argc = 0;
-	char *new_exec;
+	char *new_exec, *uris, *temp;
 	int launched = 0;
 
 	g_return_val_if_fail (item, -1);
@@ -1494,6 +1505,15 @@ ditem_execute (const GnomeDesktopItem *i
 					  exec,
 					  args, &arg_ptr, &added_status);
 
+		if (launched == 0 && added_status == ADDED_NONE && append_uris) {
+			uris = stringify_uris (args, FALSE, FALSE);
+			temp = g_strconcat (new_exec, " ", uris, NULL);
+			g_free (uris);
+			g_free (new_exec);
+			new_exec = temp;
+			added_status = ADDED_ALL;
+		}
+
 		if (launched > 0 && added_status == ADDED_NONE) {
 			g_free (new_exec);
 			break;
@@ -1670,6 +1690,7 @@ gnome_desktop_item_launch (const GnomeDe
 	ret = ditem_execute (item, the_exec, file_list,
 			     (flags & GNOME_DESKTOP_ITEM_LAUNCH_ONLY_ONE),
 			     (flags & GNOME_DESKTOP_ITEM_LAUNCH_USE_CURRENT_DIR),
+			     (flags & GNOME_DESKTOP_ITEM_LAUNCH_APPEND_URIS),
 			     error);
 
 	return ret;
Index: libgnome-desktop/gnome-desktop-item.h
===================================================================
RCS file: /cvs/gnome/gnome-desktop/libgnome-desktop/gnome-desktop-item.h,v
retrieving revision 1.41
diff -u -p -r1.41 gnome-desktop-item.h
--- libgnome-desktop/gnome-desktop-item.h	23 May 2002 14:32:50 -0000	1.41
+++ libgnome-desktop/gnome-desktop-item.h	18 Jun 2002 02:42:19 -0000
@@ -114,7 +114,11 @@ typedef enum {
 	 * handle one file and we have passed many */
         GNOME_DESKTOP_ITEM_LAUNCH_ONLY_ONE = 1<<0,
 	/* Use current directory instead of home directory */
-        GNOME_DESKTOP_ITEM_LAUNCH_USE_CURRENT_DIR = 1<<1
+        GNOME_DESKTOP_ITEM_LAUNCH_USE_CURRENT_DIR = 1<<1,
+	/* Append the list of URIs to the command if no Exec
+	 * parameter is specified, instead of launching the 
+	 * app without parameters. */
+	  GNOME_DESKTOP_ITEM_LAUNCH_APPEND_URIS = 2<<0
 } GnomeDesktopItemLaunchFlags;
 
 typedef enum {


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