/* 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 . * * Author: John Sullivan */ #include #include "nautilus-program-choosing.h" #include "nautilus-file.h" #include "nautilus-global-preferences.h" #include "nautilus-scheme.h" #include "nautilus-ui-utilities.h" #include #include #include #include #include #include static void add_file_to_recent (NautilusFile *file, GAppInfo *application) { const gchar *scheme; GtkRecentData recent_data; g_autofree char *uri = nautilus_file_get_activation_uri (file); if (uri == NULL) { uri = nautilus_file_get_uri (file); } /* do not add trash:// etc */ scheme = g_uri_peek_scheme (uri); if (scheme != NULL && (g_str_equal (scheme, SCHEME_TRASH) || g_str_equal (scheme, SCHEME_SEARCH) || g_str_equal (scheme, SCHEME_RECENT))) { return; } recent_data.display_name = NULL; recent_data.description = NULL; recent_data.mime_type = g_strdup (nautilus_file_get_mime_type (file)); recent_data.app_name = g_strdup (g_get_application_name ()); recent_data.app_exec = g_strdup (g_app_info_get_commandline (application)); recent_data.groups = NULL; recent_data.is_private = FALSE; gtk_recent_manager_add_full (gtk_recent_manager_get_default (), uri, &recent_data); g_free (recent_data.mime_type); g_free (recent_data.app_name); g_free (recent_data.app_exec); } void nautilus_launch_application_for_mount (GAppInfo *app_info, GMount *mount, GtkWindow *parent_window) { g_autoptr (GFile) root = g_mount_get_root (mount); g_autoptr (NautilusFile) file = nautilus_file_get (root); nautilus_launch_application (app_info, &(NautilusFileList){ .data = file }, parent_window); } /** * 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. * * @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, NautilusFileList *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); } static GdkAppLaunchContext * get_launch_context (GtkWindow *parent_window) { GdkDisplay *display; GdkAppLaunchContext *launch_context; 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); return launch_context; } void 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; g_autoptr (GdkAppLaunchContext) launch_context = NULL; GIcon *icon; gboolean all_uris_local = TRUE; g_assert (uris != NULL); 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)) { all_uris_local = FALSE; } locations = g_list_prepend (locations, location); } locations = g_list_reverse (locations); launch_context = get_launch_context (parent_window); file = nautilus_file_get_by_uri (uris->data); icon = nautilus_file_get_gicon (file, NAUTILUS_FILE_ICON_FLAGS_NONE); nautilus_file_unref (file); if (icon) { gdk_app_launch_context_set_icon (launch_context, icon); g_object_unref (icon); } error = NULL; if (all_uris_local) { /* 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); } if (result) { for (l = uris; l != NULL; l = l->next) { file = nautilus_file_get_by_uri (l->data); add_file_to_recent (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, GdkDisplay *display, gboolean use_terminal) { GAppInfoCreateFlags flags; g_autoptr (GError) error = NULL; g_autoptr (GAppInfo) app = NULL; flags = G_APP_INFO_CREATE_NONE; if (use_terminal) { flags = G_APP_INFO_CREATE_NEEDS_TERMINAL; } app = g_app_info_create_from_commandline (full_command, NULL, flags, &error); if (app != NULL && !(use_terminal && display == NULL)) { g_autoptr (GdkAppLaunchContext) context = NULL; context = gdk_display_get_app_launch_context (display); g_app_info_launch (app, NULL, G_APP_LAUNCH_CONTEXT (context), &error); } if (error != NULL) { g_message ("Could not start app: %s", error->message); } } /** * 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 (GdkDisplay *display, const char *command_string, gboolean use_terminal, ...) { char *full_command, *tmp; char *quoted_parameter; char *parameter; va_list ap; full_command = g_strdup (command_string); 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); g_free (full_command); full_command = tmp; } va_end (ap); launch_application_from_command_internal (full_command, display, use_terminal); 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 (GdkDisplay *display, const char *command_string, gboolean use_terminal, const char * const *parameters) { char *full_command, *tmp; char *quoted_parameter; const char * const *p; 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); g_free (full_command); full_command = tmp; } } launch_application_from_command_internal (full_command, display, use_terminal); g_free (full_command); }