diff options
Diffstat (limited to 'src/nautilus-mime-actions.c')
-rw-r--r-- | src/nautilus-mime-actions.c | 255 |
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 *) ¶meters_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 *) ¶meters->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); } |