summaryrefslogtreecommitdiff
path: root/src/nautilus-mime-actions.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nautilus-mime-actions.c')
-rw-r--r--src/nautilus-mime-actions.c255
1 files changed, 248 insertions, 7 deletions
diff --git a/src/nautilus-mime-actions.c b/src/nautilus-mime-actions.c
index 494d6dab2..55b5df82f 100644
--- a/src/nautilus-mime-actions.c
+++ b/src/nautilus-mime-actions.c
@@ -48,6 +48,8 @@
typedef enum
{
ACTIVATION_ACTION_ASK,
+ ACTIVATION_ACTION_LAUNCH,
+ ACTIVATION_ACTION_LAUNCH_IN_TERMINAL,
ACTIVATION_ACTION_OPEN_IN_VIEW,
ACTIVATION_ACTION_OPEN_IN_APPLICATION,
ACTIVATION_ACTION_EXTRACT,
@@ -75,6 +77,7 @@ typedef struct
gboolean timed_wait_active;
NautilusFileListHandle *files_handle;
gboolean tried_mounting;
+ char *activation_directory;
gboolean user_confirmation;
} ActivateParameters;
@@ -219,6 +222,10 @@ struct
/* Number of seconds until cancel dialog shows up */
#define DELAY_UNTIL_CANCEL_MSECS 5000
+#define RESPONSE_RUN 1000
+#define RESPONSE_DISPLAY 1001
+#define RESPONSE_RUN_IN_TERMINAL 1002
+
#define SILENT_WINDOW_OPEN_LIMIT 5
#define SILENT_OPEN_LIMIT 5
@@ -590,6 +597,115 @@ out:
}
static ActivationAction
+get_executable_text_file_action (GtkWindow *parent_window,
+ NautilusFile *file)
+{
+ GtkDialog *dialog;
+ char *file_name;
+ char *prompt;
+ char *detail;
+ int preferences_value;
+ int response;
+
+ g_assert (nautilus_file_contains_text (file));
+
+ preferences_value = g_settings_get_enum (nautilus_preferences,
+ NAUTILUS_PREFERENCES_EXECUTABLE_TEXT_ACTIVATION);
+ switch (preferences_value)
+ {
+ case NAUTILUS_EXECUTABLE_TEXT_LAUNCH:
+ {
+ return ACTIVATION_ACTION_LAUNCH;
+ }
+
+ case NAUTILUS_EXECUTABLE_TEXT_DISPLAY:
+ {
+ return ACTIVATION_ACTION_OPEN_IN_APPLICATION;
+ }
+
+ case NAUTILUS_EXECUTABLE_TEXT_ASK:
+ {
+ }
+ break;
+
+ default:
+ /* Complain non-fatally, since preference data can't be trusted */
+ g_warning ("Unknown value %d for NAUTILUS_PREFERENCES_EXECUTABLE_TEXT_ACTIVATION",
+ preferences_value);
+ }
+
+
+ file_name = nautilus_file_get_display_name (file);
+ prompt = g_strdup_printf (_("Do you want to run ā€œ%sā€, or display its contents?"),
+ file_name);
+ detail = g_strdup_printf (_("ā€œ%sā€ is an executable text file."),
+ file_name);
+ g_free (file_name);
+
+ dialog = eel_create_question_dialog (prompt,
+ detail,
+ _("Run in _Terminal"), RESPONSE_RUN_IN_TERMINAL,
+ _("_Display"), RESPONSE_DISPLAY,
+ parent_window);
+ gtk_dialog_add_button (dialog, _("_Cancel"), GTK_RESPONSE_CANCEL);
+ gtk_dialog_add_button (dialog, _("_Run"), RESPONSE_RUN);
+ gtk_dialog_set_default_response (dialog, GTK_RESPONSE_CANCEL);
+ gtk_widget_show (GTK_WIDGET (dialog));
+
+ g_free (prompt);
+ g_free (detail);
+
+ response = gtk_dialog_run (dialog);
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+
+ 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_OPEN_IN_APPLICATION;
+ }
+
+ default:
+ return ACTIVATION_ACTION_DO_NOTHING;
+ }
+}
+
+static ActivationAction
+get_default_executable_text_file_action (void)
+{
+ int preferences_value;
+
+ preferences_value = g_settings_get_enum (nautilus_preferences,
+ NAUTILUS_PREFERENCES_EXECUTABLE_TEXT_ACTIVATION);
+ switch (preferences_value)
+ {
+ case NAUTILUS_EXECUTABLE_TEXT_LAUNCH:
+ {
+ return ACTIVATION_ACTION_LAUNCH;
+ }
+
+ case NAUTILUS_EXECUTABLE_TEXT_DISPLAY:
+ {
+ return ACTIVATION_ACTION_OPEN_IN_APPLICATION;
+ }
+
+ case NAUTILUS_EXECUTABLE_TEXT_ASK:
+ default:
+ return ACTIVATION_ACTION_ASK;
+ }
+}
+
+static ActivationAction
get_activation_action (NautilusFile *file)
{
ActivationAction action;
@@ -615,13 +731,35 @@ get_activation_action (NautilusFile *file)
activation_uri = nautilus_file_get_uri (file);
}
- if (nautilus_file_opens_in_view (file))
+ action = ACTIVATION_ACTION_DO_NOTHING;
+ if (nautilus_file_is_launchable (file))
{
- action = ACTIVATION_ACTION_OPEN_IN_VIEW;
+ char *executable_path;
+
+ action = ACTIVATION_ACTION_LAUNCH;
+
+ executable_path = g_filename_from_uri (activation_uri, NULL, NULL);
+ if (!executable_path)
+ {
+ action = ACTIVATION_ACTION_DO_NOTHING;
+ }
+ else if (nautilus_file_contains_text (file))
+ {
+ action = get_default_executable_text_file_action ();
+ }
+ g_free (executable_path);
}
- else
+
+ if (action == ACTIVATION_ACTION_DO_NOTHING)
{
- action = ACTIVATION_ACTION_OPEN_IN_APPLICATION;
+ if (nautilus_file_opens_in_view (file))
+ {
+ action = ACTIVATION_ACTION_OPEN_IN_VIEW;
+ }
+ else
+ {
+ action = ACTIVATION_ACTION_OPEN_IN_APPLICATION;
+ }
}
g_free (activation_uri);
@@ -635,6 +773,16 @@ nautilus_mime_file_extracts (NautilusFile *file)
}
gboolean
+nautilus_mime_file_launches (NautilusFile *file)
+{
+ ActivationAction activation_action;
+
+ activation_action = get_activation_action (file);
+
+ return (activation_action == ACTIVATION_ACTION_LAUNCH);
+}
+
+gboolean
nautilus_mime_file_opens_in_external_app (NautilusFile *file)
{
ActivationAction activation_action;
@@ -689,6 +837,7 @@ activation_parameters_free (ActivateParameters *parameters)
nautilus_file_list_free (parameters->mountables);
nautilus_file_list_free (parameters->start_mountables);
nautilus_file_list_free (parameters->not_mounted);
+ g_free (parameters->activation_directory);
g_free (parameters->timed_wait_prompt);
g_assert (parameters->files_handle == NULL);
g_free (parameters);
@@ -816,6 +965,7 @@ typedef struct
NautilusFile *file;
GList *files;
NautilusWindowOpenFlags flags;
+ char *activation_directory;
gboolean user_confirmation;
char *uri;
GDBusProxy *proxy;
@@ -841,6 +991,7 @@ activate_parameters_install_free (ActivateParametersInstall *parameters_install)
nautilus_file_unref (parameters_install->file);
nautilus_file_list_free (parameters_install->files);
+ g_free (parameters_install->activation_directory);
g_free (parameters_install->uri);
g_free (parameters_install);
}
@@ -1044,6 +1195,7 @@ search_for_application_dbus_call_notify_cb (GDBusProxy *proxy,
nautilus_mime_activate_files (parameters_install->parent_window,
parameters_install->slot,
parameters_install->files,
+ parameters_install->activation_directory,
parameters_install->flags,
parameters_install->user_confirmation);
@@ -1192,6 +1344,7 @@ application_unhandled_uri (ActivateParameters *parameters,
parameters_install->parent_window = parameters->parent_window;
g_object_add_weak_pointer (G_OBJECT (parameters_install->parent_window), (gpointer *) &parameters_install->parent_window);
}
+ parameters_install->activation_directory = g_strdup (parameters->activation_directory);
parameters_install->file = file;
parameters_install->files = get_file_list_for_launch_locations (parameters->locations);
parameters_install->flags = parameters->flags;
@@ -1298,12 +1451,17 @@ activate_files (ActivateParameters *parameters)
NautilusWindowOpenFlags flags;
int count;
g_autofree char *old_working_dir = NULL;
+ GdkScreen *screen;
gboolean closed_window;
+ g_autoptr (GQueue) launch_files = NULL;
+ g_autoptr (GQueue) launch_in_terminal_files = NULL;
g_autoptr (GQueue) open_in_app_uris = NULL;
g_autoptr (GQueue) open_in_view_files = NULL;
GList *l;
ActivationAction action;
+ launch_files = g_queue_new ();
+ launch_in_terminal_files = g_queue_new ();
open_in_view_files = g_queue_new ();
open_in_app_uris = g_queue_new ();
@@ -1320,8 +1478,30 @@ activate_files (ActivateParameters *parameters)
}
action = get_activation_action (file);
+ if (action == ACTIVATION_ACTION_ASK)
+ {
+ /* Special case for executable text files, since it might be
+ * dangerous & unexpected to launch these.
+ */
+ pause_activation_timed_cancel (parameters);
+ action = get_executable_text_file_action (parameters->parent_window, file);
+ unpause_activation_timed_cancel (parameters);
+ }
+
switch (action)
{
+ case ACTIVATION_ACTION_LAUNCH:
+ {
+ g_queue_push_tail (launch_files, file);
+ }
+ break;
+
+ case ACTIVATION_ACTION_LAUNCH_IN_TERMINAL:
+ {
+ g_queue_push_tail (launch_in_terminal_files, file);
+ }
+ break;
+
case ACTIVATION_ACTION_OPEN_IN_VIEW:
{
g_queue_push_tail (open_in_view_files, file);
@@ -1346,7 +1526,7 @@ activate_files (ActivateParameters *parameters)
}
break;
- default:
+ case ACTIVATION_ACTION_ASK:
{
g_assert_not_reached ();
}
@@ -1354,6 +1534,54 @@ activate_files (ActivateParameters *parameters)
}
}
+ if (parameters->activation_directory &&
+ (!g_queue_is_empty (launch_files) ||
+ !g_queue_is_empty (launch_in_terminal_files)))
+ {
+ old_working_dir = g_get_current_dir ();
+ g_chdir (parameters->activation_directory);
+ }
+
+ screen = gtk_widget_get_screen (GTK_WIDGET (parameters->parent_window));
+ for (l = g_queue_peek_head_link (launch_files); l != NULL; l = l->next)
+ {
+ g_autofree char *uri = NULL;
+ g_autofree char *executable_path = NULL;
+ g_autofree char *quoted_path = NULL;
+
+ file = NAUTILUS_FILE (l->data);
+
+ uri = nautilus_file_get_activation_uri (file);
+ executable_path = g_filename_from_uri (uri, NULL, NULL);
+ quoted_path = g_shell_quote (executable_path);
+
+ DEBUG ("Launching file path %s", quoted_path);
+
+ nautilus_launch_application_from_command (screen, quoted_path, FALSE, NULL);
+ }
+
+ for (l = g_queue_peek_head_link (launch_in_terminal_files); l != NULL; l = l->next)
+ {
+ g_autofree char *uri = NULL;
+ g_autofree char *executable_path = NULL;
+ g_autofree char *quoted_path = NULL;
+
+ file = NAUTILUS_FILE (l->data);
+
+ uri = nautilus_file_get_activation_uri (file);
+ executable_path = g_filename_from_uri (uri, NULL, NULL);
+ quoted_path = g_shell_quote (executable_path);
+
+ DEBUG ("Launching in terminal file quoted path %s", quoted_path);
+
+ nautilus_launch_application_from_command (screen, quoted_path, TRUE, NULL);
+ }
+
+ if (old_working_dir != NULL)
+ {
+ g_chdir (old_working_dir);
+ }
+
count = g_queue_get_length (open_in_view_files);
flags = parameters->flags;
@@ -1522,7 +1750,8 @@ activation_mount_not_mounted_callback (GObject *source_object,
file);
if (loc)
{
- parameters->locations = g_list_remove (parameters->locations, loc);
+ parameters->locations =
+ g_list_remove (parameters->locations, loc);
launch_location_free (loc);
}
}
@@ -1941,10 +2170,20 @@ activation_start_mountables (ActivateParameters *parameters)
}
}
+/**
+ * nautilus_mime_activate_files:
+ *
+ * Activate a list of files. Each one might launch with an application or
+ * with a component. This is normally called only by subclasses.
+ * @view: FMDirectoryView in question.
+ * @files: A GList of NautilusFiles to activate.
+ *
+ **/
void
nautilus_mime_activate_files (GtkWindow *parent_window,
NautilusWindowSlot *slot,
GList *files,
+ const char *launch_directory,
NautilusWindowOpenFlags flags,
gboolean user_confirmation)
{
@@ -1971,6 +2210,7 @@ nautilus_mime_activate_files (GtkWindow *parent_window,
g_object_add_weak_pointer (G_OBJECT (parameters->parent_window), (gpointer *) &parameters->parent_window);
}
parameters->cancellable = g_cancellable_new ();
+ parameters->activation_directory = g_strdup (launch_directory);
parameters->locations = launch_locations_from_file_list (files);
parameters->flags = flags;
parameters->user_confirmation = user_confirmation;
@@ -2040,6 +2280,7 @@ void
nautilus_mime_activate_file (GtkWindow *parent_window,
NautilusWindowSlot *slot,
NautilusFile *file,
+ const char *launch_directory,
NautilusWindowOpenFlags flags)
{
GList *files;
@@ -2047,7 +2288,7 @@ nautilus_mime_activate_file (GtkWindow *parent_window,
g_return_if_fail (NAUTILUS_IS_FILE (file));
files = g_list_prepend (NULL, file);
- nautilus_mime_activate_files (parent_window, slot, files, flags, FALSE);
+ nautilus_mime_activate_files (parent_window, slot, files, launch_directory, flags, FALSE);
g_list_free (files);
}