/* 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);
}