diff options
Diffstat (limited to 'src/nautilus-program-choosing.c')
-rw-r--r-- | src/nautilus-program-choosing.c | 662 |
1 files changed, 346 insertions, 316 deletions
diff --git a/src/nautilus-program-choosing.c b/src/nautilus-program-choosing.c index 871ca7053..92c6ddcf7 100644 --- a/src/nautilus-program-choosing.c +++ b/src/nautilus-program-choosing.c @@ -1,25 +1,24 @@ - /* nautilus-program-choosing.c - functions for selecting and activating - programs for opening/viewing particular files. - - Copyright (C) 2000 Eazel, Inc. - - The Gnome Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - see <http://www.gnu.org/licenses/>. - - Author: John Sullivan <sullivan@eazel.com> -*/ + * programs for opening/viewing particular files. + * + * Copyright (C) 2000 Eazel, Inc. + * + * The Gnome Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The Gnome Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the Gnome Library; see the file COPYING.LIB. If not, + * see <http://www.gnu.org/licenses/>. + * + * Author: John Sullivan <sullivan@eazel.com> + */ #include <config.h> #include "nautilus-program-choosing.h" @@ -39,364 +38,395 @@ #include <gdk/gdkx.h> void -nautilus_launch_application_for_mount (GAppInfo *app_info, - GMount *mount, - GtkWindow *parent_window) +nautilus_launch_application_for_mount (GAppInfo *app_info, + GMount *mount, + GtkWindow *parent_window) { - GFile *root; - NautilusFile *file; - GList *files; + GFile *root; + NautilusFile *file; + GList *files; - root = g_mount_get_root (mount); - file = nautilus_file_get (root); - g_object_unref (root); + root = g_mount_get_root (mount); + file = nautilus_file_get (root); + g_object_unref (root); - files = g_list_append (NULL, file); - nautilus_launch_application (app_info, - files, - parent_window); + files = g_list_append (NULL, file); + nautilus_launch_application (app_info, + files, + parent_window); - g_list_free_full (files, (GDestroyNotify) nautilus_file_unref); + g_list_free_full (files, (GDestroyNotify) nautilus_file_unref); } /** * nautilus_launch_application: - * + * * Fork off a process to launch an application with a given file as a - * parameter. Provide a parent window for error dialogs. - * + * parameter. Provide a parent window for error dialogs. + * * @application: The application to be launched. * @uris: The files whose locations should be passed as a parameter to the application. * @parent_window: A window to use as the parent for any error dialogs. */ void -nautilus_launch_application (GAppInfo *application, - GList *files, - GtkWindow *parent_window) +nautilus_launch_application (GAppInfo *application, + GList *files, + GtkWindow *parent_window) { - GList *uris, *l; - - uris = NULL; - for (l = files; l != NULL; l = l->next) { - uris = g_list_prepend (uris, nautilus_file_get_activation_uri (l->data)); - } - uris = g_list_reverse (uris); - nautilus_launch_application_by_uri (application, uris, - parent_window); - g_list_free_full (uris, g_free); + GList *uris, *l; + + uris = NULL; + for (l = files; l != NULL; l = l->next) + { + uris = g_list_prepend (uris, nautilus_file_get_activation_uri (l->data)); + } + uris = g_list_reverse (uris); + nautilus_launch_application_by_uri (application, uris, + parent_window); + g_list_free_full (uris, g_free); } void -nautilus_launch_application_by_uri (GAppInfo *application, - GList *uris, - GtkWindow *parent_window) +nautilus_launch_application_by_uri (GAppInfo *application, + GList *uris, + GtkWindow *parent_window) { - char *uri; - GList *locations, *l; - GFile *location; - NautilusFile *file; - gboolean result; - GError *error; - GdkDisplay *display; - GdkAppLaunchContext *launch_context; - NautilusIconInfo *icon; - int count, total; - - g_assert (uris != NULL); - - /* count the number of uris with local paths */ - count = 0; - total = g_list_length (uris); - locations = NULL; - for (l = uris; l != NULL; l = l->next) { - uri = l->data; - - location = g_file_new_for_uri (uri); - if (g_file_is_native (location)) { - count++; - } - locations = g_list_prepend (locations, location); - } - locations = g_list_reverse (locations); - - if (parent_window != NULL) { - display = gtk_widget_get_display (GTK_WIDGET (parent_window)); - } else { - display = gdk_display_get_default (); - } - - launch_context = gdk_display_get_app_launch_context (display); - - if (parent_window != NULL) { - gdk_app_launch_context_set_screen (launch_context, - gtk_window_get_screen (parent_window)); - } - - file = nautilus_file_get_by_uri (uris->data); - icon = nautilus_file_get_icon (file, - 48, gtk_widget_get_scale_factor (GTK_WIDGET (parent_window)), - 0); - nautilus_file_unref (file); - if (icon) { - gdk_app_launch_context_set_icon_name (launch_context, - nautilus_icon_info_get_used_name (icon)); - g_object_unref (icon); - } - - error = NULL; - - if (count == total) { - /* All files are local, so we can use g_app_info_launch () with - * the file list we constructed before. - */ - result = g_app_info_launch (application, - locations, - G_APP_LAUNCH_CONTEXT (launch_context), - &error); - } else { - /* Some files are non local, better use g_app_info_launch_uris (). - */ - result = g_app_info_launch_uris (application, - uris, - G_APP_LAUNCH_CONTEXT (launch_context), - &error); - } - - g_object_unref (launch_context); - - if (result) { - for (l = uris; l != NULL; l = l->next) { - file = nautilus_file_get_by_uri (l->data); - nautilus_recent_add_file (file, application); - nautilus_file_unref (file); - } - } - - g_list_free_full (locations, g_object_unref); + char *uri; + GList *locations, *l; + GFile *location; + NautilusFile *file; + gboolean result; + GError *error; + GdkDisplay *display; + GdkAppLaunchContext *launch_context; + NautilusIconInfo *icon; + int count, total; + + g_assert (uris != NULL); + + /* count the number of uris with local paths */ + count = 0; + total = g_list_length (uris); + locations = NULL; + for (l = uris; l != NULL; l = l->next) + { + uri = l->data; + + location = g_file_new_for_uri (uri); + if (g_file_is_native (location)) + { + count++; + } + locations = g_list_prepend (locations, location); + } + locations = g_list_reverse (locations); + + if (parent_window != NULL) + { + display = gtk_widget_get_display (GTK_WIDGET (parent_window)); + } + else + { + display = gdk_display_get_default (); + } + + launch_context = gdk_display_get_app_launch_context (display); + + if (parent_window != NULL) + { + gdk_app_launch_context_set_screen (launch_context, + gtk_window_get_screen (parent_window)); + } + + file = nautilus_file_get_by_uri (uris->data); + icon = nautilus_file_get_icon (file, + 48, gtk_widget_get_scale_factor (GTK_WIDGET (parent_window)), + 0); + nautilus_file_unref (file); + if (icon) + { + gdk_app_launch_context_set_icon_name (launch_context, + nautilus_icon_info_get_used_name (icon)); + g_object_unref (icon); + } + + error = NULL; + + if (count == total) + { + /* All files are local, so we can use g_app_info_launch () with + * the file list we constructed before. + */ + result = g_app_info_launch (application, + locations, + G_APP_LAUNCH_CONTEXT (launch_context), + &error); + } + else + { + /* Some files are non local, better use g_app_info_launch_uris (). + */ + result = g_app_info_launch_uris (application, + uris, + G_APP_LAUNCH_CONTEXT (launch_context), + &error); + } + + g_object_unref (launch_context); + + if (result) + { + for (l = uris; l != NULL; l = l->next) + { + file = nautilus_file_get_by_uri (l->data); + nautilus_recent_add_file (file, application); + nautilus_file_unref (file); + } + } + + g_list_free_full (locations, g_object_unref); } static void launch_application_from_command_internal (const gchar *full_command, - GdkScreen *screen, - gboolean use_terminal) + GdkScreen *screen, + gboolean use_terminal) { - GAppInfo *app; - GdkAppLaunchContext *ctx; - GdkDisplay *display; - - if (use_terminal) { - eel_gnome_open_terminal_on_screen (full_command, screen); - } else { - app = g_app_info_create_from_commandline (full_command, NULL, 0, NULL); - - if (app != NULL) { - display = gdk_screen_get_display (screen); - ctx = gdk_display_get_app_launch_context (display); - gdk_app_launch_context_set_screen (ctx, screen); - - g_app_info_launch (app, NULL, G_APP_LAUNCH_CONTEXT (ctx), NULL); - - g_object_unref (app); - g_object_unref (ctx); - } - } -} + GAppInfo *app; + GdkAppLaunchContext *ctx; + GdkDisplay *display; + + if (use_terminal) + { + eel_gnome_open_terminal_on_screen (full_command, screen); + } + else + { + app = g_app_info_create_from_commandline (full_command, NULL, 0, NULL); + + if (app != NULL) + { + display = gdk_screen_get_display (screen); + ctx = gdk_display_get_app_launch_context (display); + gdk_app_launch_context_set_screen (ctx, screen); + + g_app_info_launch (app, NULL, G_APP_LAUNCH_CONTEXT (ctx), NULL); + + g_object_unref (app); + g_object_unref (ctx); + } + } +} /** * nautilus_launch_application_from_command: - * + * * Fork off a process to launch an application with a given uri as * a parameter. - * + * * @command_string: The application to be launched, with any desired * command-line options. * @...: Passed as parameters to the application after quoting each of them. */ void nautilus_launch_application_from_command (GdkScreen *screen, - const char *command_string, - gboolean use_terminal, - ...) + const char *command_string, + gboolean use_terminal, + ...) { - char *full_command, *tmp; - char *quoted_parameter; - char *parameter; - va_list ap; + char *full_command, *tmp; + char *quoted_parameter; + char *parameter; + va_list ap; - full_command = g_strdup (command_string); + full_command = g_strdup (command_string); - va_start (ap, use_terminal); + va_start (ap, use_terminal); - while ((parameter = va_arg (ap, char *)) != NULL) { - quoted_parameter = g_shell_quote (parameter); - tmp = g_strconcat (full_command, " ", quoted_parameter, NULL); - g_free (quoted_parameter); + while ((parameter = va_arg (ap, char *)) != NULL) + { + quoted_parameter = g_shell_quote (parameter); + tmp = g_strconcat (full_command, " ", quoted_parameter, NULL); + g_free (quoted_parameter); - g_free (full_command); - full_command = tmp; + g_free (full_command); + full_command = tmp; + } - } + va_end (ap); - va_end (ap); + launch_application_from_command_internal (full_command, screen, use_terminal); - launch_application_from_command_internal (full_command, screen, use_terminal); - - g_free (full_command); + g_free (full_command); } /** * nautilus_launch_application_from_command: - * + * * Fork off a process to launch an application with a given uri as * a parameter. - * + * * @command_string: The application to be launched, with any desired * command-line options. * @parameters: Passed as parameters to the application after quoting each of them. */ void -nautilus_launch_application_from_command_array (GdkScreen *screen, - const char *command_string, - gboolean use_terminal, - const char * const * parameters) +nautilus_launch_application_from_command_array (GdkScreen *screen, + const char *command_string, + gboolean use_terminal, + const char * const *parameters) { - char *full_command, *tmp; - char *quoted_parameter; - const char * const *p; + char *full_command, *tmp; + char *quoted_parameter; + const char * const *p; - full_command = g_strdup (command_string); + full_command = g_strdup (command_string); - if (parameters != NULL) { - for (p = parameters; *p != NULL; p++) { - quoted_parameter = g_shell_quote (*p); - tmp = g_strconcat (full_command, " ", quoted_parameter, NULL); - g_free (quoted_parameter); + if (parameters != NULL) + { + for (p = parameters; *p != NULL; p++) + { + quoted_parameter = g_shell_quote (*p); + tmp = g_strconcat (full_command, " ", quoted_parameter, NULL); + g_free (quoted_parameter); - g_free (full_command); - full_command = tmp; - } - } + g_free (full_command); + full_command = tmp; + } + } - launch_application_from_command_internal (full_command, screen, use_terminal); + launch_application_from_command_internal (full_command, screen, use_terminal); - g_free (full_command); + g_free (full_command); } void nautilus_launch_desktop_file (GdkScreen *screen, - const char *desktop_file_uri, - const GList *parameter_uris, - GtkWindow *parent_window) + const char *desktop_file_uri, + const GList *parameter_uris, + GtkWindow *parent_window) { - GError *error; - char *message, *desktop_file_path; - const GList *p; - GList *files; - int total, count; - GFile *file, *desktop_file; - GDesktopAppInfo *app_info; - GdkAppLaunchContext *context; - - /* Don't allow command execution from remote locations - * to partially mitigate the security - * risk of executing arbitrary commands. - */ - desktop_file = g_file_new_for_uri (desktop_file_uri); - desktop_file_path = g_file_get_path (desktop_file); - if (!g_file_is_native (desktop_file)) { - g_free (desktop_file_path); - g_object_unref (desktop_file); - eel_show_error_dialog - (_("Sorry, but you cannot execute commands from " - "a remote site."), - _("This is disabled due to security considerations."), - parent_window); - - return; - } - g_object_unref (desktop_file); - - app_info = g_desktop_app_info_new_from_filename (desktop_file_path); - g_free (desktop_file_path); - if (app_info == NULL) { - eel_show_error_dialog - (_("There was an error launching the application."), - NULL, - parent_window); - return; - } - - /* count the number of uris with local paths */ - count = 0; - total = g_list_length ((GList *) parameter_uris); - files = NULL; - for (p = parameter_uris; p != NULL; p = p->next) { - file = g_file_new_for_uri ((const char *) p->data); - if (g_file_is_native (file)) { - count++; - } - files = g_list_prepend (files, file); - } - - /* check if this app only supports local files */ - if (g_app_info_supports_files (G_APP_INFO (app_info)) && - !g_app_info_supports_uris (G_APP_INFO (app_info)) && - parameter_uris != NULL) { - if (count == 0) { - /* all files are non-local */ - eel_show_error_dialog - (_("This drop target only supports local files."), - _("To open non-local files copy them to a local folder and then" - " drop them again."), - parent_window); - - g_list_free_full (files, g_object_unref); - g_object_unref (app_info); - return; - } else if (count != total) { - /* some files are non-local */ - eel_show_warning_dialog - (_("This drop target only supports local files."), - _("To open non-local files copy them to a local folder and then" - " drop them again. The local files you dropped have already been opened."), - parent_window); - } - } - - error = NULL; - context = gdk_display_get_app_launch_context (gtk_widget_get_display (GTK_WIDGET (parent_window))); - /* TODO: Ideally we should accept a timestamp here instead of using GDK_CURRENT_TIME */ - gdk_app_launch_context_set_timestamp (context, GDK_CURRENT_TIME); - gdk_app_launch_context_set_screen (context, - gtk_window_get_screen (parent_window)); - if (count == total) { - /* All files are local, so we can use g_app_info_launch () with - * the file list we constructed before. - */ - g_app_info_launch (G_APP_INFO (app_info), - files, - G_APP_LAUNCH_CONTEXT (context), - &error); - } else { - /* Some files are non local, better use g_app_info_launch_uris (). - */ - g_app_info_launch_uris (G_APP_INFO (app_info), - (GList *) parameter_uris, - G_APP_LAUNCH_CONTEXT (context), - &error); - } - if (error != NULL) { - message = g_strconcat (_("Details: "), error->message, NULL); - eel_show_error_dialog - (_("There was an error launching the application."), - message, - parent_window); - - g_error_free (error); - g_free (message); - } - - g_list_free_full (files, g_object_unref); - g_object_unref (context); - g_object_unref (app_info); + GError *error; + char *message, *desktop_file_path; + const GList *p; + GList *files; + int total, count; + GFile *file, *desktop_file; + GDesktopAppInfo *app_info; + GdkAppLaunchContext *context; + + /* Don't allow command execution from remote locations + * to partially mitigate the security + * risk of executing arbitrary commands. + */ + desktop_file = g_file_new_for_uri (desktop_file_uri); + desktop_file_path = g_file_get_path (desktop_file); + if (!g_file_is_native (desktop_file)) + { + g_free (desktop_file_path); + g_object_unref (desktop_file); + eel_show_error_dialog + (_("Sorry, but you cannot execute commands from " + "a remote site."), + _("This is disabled due to security considerations."), + parent_window); + + return; + } + g_object_unref (desktop_file); + + app_info = g_desktop_app_info_new_from_filename (desktop_file_path); + g_free (desktop_file_path); + if (app_info == NULL) + { + eel_show_error_dialog + (_("There was an error launching the application."), + NULL, + parent_window); + return; + } + + /* count the number of uris with local paths */ + count = 0; + total = g_list_length ((GList *) parameter_uris); + files = NULL; + for (p = parameter_uris; p != NULL; p = p->next) + { + file = g_file_new_for_uri ((const char *) p->data); + if (g_file_is_native (file)) + { + count++; + } + files = g_list_prepend (files, file); + } + + /* check if this app only supports local files */ + if (g_app_info_supports_files (G_APP_INFO (app_info)) && + !g_app_info_supports_uris (G_APP_INFO (app_info)) && + parameter_uris != NULL) + { + if (count == 0) + { + /* all files are non-local */ + eel_show_error_dialog + (_("This drop target only supports local files."), + _("To open non-local files copy them to a local folder and then" + " drop them again."), + parent_window); + + g_list_free_full (files, g_object_unref); + g_object_unref (app_info); + return; + } + else if (count != total) + { + /* some files are non-local */ + eel_show_warning_dialog + (_("This drop target only supports local files."), + _("To open non-local files copy them to a local folder and then" + " drop them again. The local files you dropped have already been opened."), + parent_window); + } + } + + error = NULL; + context = gdk_display_get_app_launch_context (gtk_widget_get_display (GTK_WIDGET (parent_window))); + /* TODO: Ideally we should accept a timestamp here instead of using GDK_CURRENT_TIME */ + gdk_app_launch_context_set_timestamp (context, GDK_CURRENT_TIME); + gdk_app_launch_context_set_screen (context, + gtk_window_get_screen (parent_window)); + if (count == total) + { + /* All files are local, so we can use g_app_info_launch () with + * the file list we constructed before. + */ + g_app_info_launch (G_APP_INFO (app_info), + files, + G_APP_LAUNCH_CONTEXT (context), + &error); + } + else + { + /* Some files are non local, better use g_app_info_launch_uris (). + */ + g_app_info_launch_uris (G_APP_INFO (app_info), + (GList *) parameter_uris, + G_APP_LAUNCH_CONTEXT (context), + &error); + } + if (error != NULL) + { + message = g_strconcat (_("Details: "), error->message, NULL); + eel_show_error_dialog + (_("There was an error launching the application."), + message, + parent_window); + + g_error_free (error); + g_free (message); + } + + g_list_free_full (files, g_object_unref); + g_object_unref (context); + g_object_unref (app_info); } |