summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2007-11-02 09:28:19 +0000
committerAlexander Larsson <alexl@src.gnome.org>2007-11-02 09:28:19 +0000
commitacab031be6390c5f8515ac33b631c6122f6947f2 (patch)
tree835ca435a07d1476b136ac0cf313e9217f28bb0c
parent919cdfeca93046f2a1eaddbe70491b64d15f5dac (diff)
downloadnautilus-acab031be6390c5f8515ac33b631c6122f6947f2.tar.gz
Add nautilus_file_is_launchable
2007-11-02 Alexander Larsson <alexl@redhat.com> * libnautilus-private/nautilus-file.[ch]: Add nautilus_file_is_launchable * libnautilus-private/nautilus-program-choosing.c: Add launched apps to recent files * libnautilus-private/nautilus-mime-actions.[ch]: * src/file-manager/fm-directory-view.[ch]: Move all the file activaton code from FMDirectoryView to a common place in nautilus-mime-actions svn path=/branches/gio-branch/; revision=13399
-rw-r--r--ChangeLog13
-rw-r--r--libnautilus-private/nautilus-file.c18
-rw-r--r--libnautilus-private/nautilus-file.h1
-rw-r--r--libnautilus-private/nautilus-mime-actions.c1144
-rw-r--r--libnautilus-private/nautilus-mime-actions.h37
-rw-r--r--libnautilus-private/nautilus-program-choosing.c7
-rw-r--r--src/file-manager/fm-directory-view.c1235
-rw-r--r--src/file-manager/fm-directory-view.h11
8 files changed, 1305 insertions, 1161 deletions
diff --git a/ChangeLog b/ChangeLog
index 1f0bb8fe7..0a0325560 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2007-11-02 Alexander Larsson <alexl@redhat.com>
+
+ * libnautilus-private/nautilus-file.[ch]:
+ Add nautilus_file_is_launchable
+
+ * libnautilus-private/nautilus-program-choosing.c:
+ Add launched apps to recent files
+
+ * libnautilus-private/nautilus-mime-actions.[ch]:
+ * src/file-manager/fm-directory-view.[ch]:
+ Move all the file activaton code from FMDirectoryView
+ to a common place in nautilus-mime-actions
+
2007-11-01 Alexander Larsson <alexl@redhat.com>
* libnautilus-private/nautilus-file-operations.[ch]:
diff --git a/libnautilus-private/nautilus-file.c b/libnautilus-private/nautilus-file.c
index dc35b5323..e81d0b937 100644
--- a/libnautilus-private/nautilus-file.c
+++ b/libnautilus-private/nautilus-file.c
@@ -5366,6 +5366,24 @@ nautilus_file_is_mime_type (NautilusFile *file, const char *mime_type)
mime_type);
}
+gboolean
+nautilus_file_is_launchable (NautilusFile *file)
+{
+ gboolean type_can_be_executable;
+
+ type_can_be_executable = FALSE;
+ if (file->details->mime_type == NULL) {
+ type_can_be_executable = g_content_type_can_be_executable (eel_ref_str_peek (file->details->mime_type));
+ }
+
+ return type_can_be_executable &&
+ nautilus_file_can_get_permissions (file) &&
+ nautilus_file_can_execute (file) &&
+ nautilus_file_is_executable (file) &&
+ !nautilus_file_is_directory (file);
+}
+
+
/**
* nautilus_file_get_emblem_icons
*
diff --git a/libnautilus-private/nautilus-file.h b/libnautilus-private/nautilus-file.h
index 2474a2d4d..77ad336c3 100644
--- a/libnautilus-private/nautilus-file.h
+++ b/libnautilus-private/nautilus-file.h
@@ -171,6 +171,7 @@ GFileType nautilus_file_get_file_type (Nautilu
char * nautilus_file_get_mime_type (NautilusFile *file);
gboolean nautilus_file_is_mime_type (NautilusFile *file,
const char *mime_type);
+gboolean nautilus_file_is_launchable (NautilusFile *file);
gboolean nautilus_file_is_symbolic_link (NautilusFile *file);
gboolean nautilus_file_is_mountpoint (NautilusFile *file);
char * nautilus_file_get_volume_free_space (NautilusFile *file);
diff --git a/libnautilus-private/nautilus-mime-actions.c b/libnautilus-private/nautilus-mime-actions.c
index 28b2613d2..0f34eca43 100644
--- a/libnautilus-private/nautilus-mime-actions.c
+++ b/libnautilus-private/nautilus-mime-actions.c
@@ -24,12 +24,103 @@
#include <config.h>
#include "nautilus-mime-actions.h"
-
+
+#include <eel/eel-glib-extensions.h>
+#include <eel/eel-stock-dialogs.h>
+#include <eel/eel-string.h>
+#include <eel/eel-mount-operation.h>
+#include <glib/gi18n.h>
+#include <string.h>
+#include <unistd.h>
+
#include "nautilus-file-attributes.h"
#include "nautilus-file.h"
+#include "nautilus-file-operations.h"
#include "nautilus-metadata.h"
-#include <eel/eel-glib-extensions.h>
-#include <string.h>
+#include "nautilus-program-choosing.h"
+#include "nautilus-desktop-icon-file.h"
+#include "nautilus-global-preferences.h"
+#include "nautilus-debug-log.h"
+
+typedef enum {
+ ACTIVATION_ACTION_LAUNCH_DESKTOP_FILE,
+ ACTIVATION_ACTION_LAUNCH_APPLICATION_FROM_COMMAND,
+ ACTIVATION_ACTION_ASK,
+ ACTIVATION_ACTION_LAUNCH,
+ ACTIVATION_ACTION_LAUNCH_IN_TERMINAL,
+ ACTIVATION_ACTION_OPEN_IN_VIEW,
+ ACTIVATION_ACTION_OPEN_IN_APPLICATION,
+ ACTIVATION_ACTION_DO_NOTHING,
+} ActivationAction;
+
+typedef struct {
+ GAppInfo *application;
+ GList *files;
+} ApplicationLaunchParameters;
+
+typedef struct {
+ NautilusWindowInfo *window_info;
+ GtkWindow *parent_window;
+ GCancellable *cancellable;
+ GList *files;
+ GList *mountables;
+ GList *not_mounted;
+ NautilusWindowOpenMode mode;
+ NautilusWindowOpenFlags flags;
+ char *timed_wait_prompt;
+ NautilusFileListHandle *files_handle;
+ gboolean tried_mounting;
+ char *activation_directory;
+} ActivateParameters;
+
+/* 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
+
+/* This number controls a maximum character count for a URL that is
+ * displayed as part of a dialog. It's fairly arbitrary -- big enough
+ * to allow most "normal" URIs to display in full, but small enough to
+ * prevent the dialog from getting insanely wide.
+ */
+#define MAX_URI_IN_DIALOG_LENGTH 60
+
+static void cancel_activate_callback (gpointer callback_data);
+static void activate_activation_uris_ready_callback (GList *files,
+ gpointer callback_data);
+static void activation_mount_mountables (ActivateParameters *parameters);
+static void activate_callback (GList *files,
+ gpointer callback_data);
+static void activation_mount_not_mounted (ActivateParameters *parameters);
+
+
+
+
+static ApplicationLaunchParameters *
+application_launch_parameters_new (GAppInfo *application,
+ GList *files)
+{
+ ApplicationLaunchParameters *result;
+
+ result = g_new0 (ApplicationLaunchParameters, 1);
+ result->application = g_object_ref (application);
+ result->files = nautilus_file_list_copy (files);
+
+ return result;
+}
+
+static void
+application_launch_parameters_free (ApplicationLaunchParameters *parameters)
+{
+ g_object_unref (parameters->application);
+ nautilus_file_list_free (parameters->files);
+
+ g_free (parameters);
+}
static GList*
filter_nautilus_handler (GList *apps)
@@ -428,3 +519,1050 @@ nautilus_mime_has_any_applications_for_files (GList *files)
return ret;
}
+
+
+
+static void
+trash_or_delete_files (GtkWindow *parent_window,
+ const GList *files,
+ gboolean delete_if_all_already_in_trash)
+{
+ GList *locations;
+ const GList *node;
+
+ locations = NULL;
+ for (node = files; node != NULL; node = node->next) {
+ locations = g_list_prepend (locations,
+ nautilus_file_get_location ((NautilusFile *) node->data));
+ }
+
+ locations = g_list_reverse (locations);
+
+ nautilus_file_operations_trash_or_delete (locations,
+ parent_window,
+ NULL, NULL);
+ eel_g_object_list_free (locations);
+}
+
+static void
+report_broken_symbolic_link (GtkWindow *parent_window, NautilusFile *file)
+{
+ char *target_path;
+ char *display_name;
+ char *prompt;
+ char *detail;
+ GtkDialog *dialog;
+ GList file_as_list;
+ int response;
+
+ g_assert (nautilus_file_is_broken_symbolic_link (file));
+
+ display_name = nautilus_file_get_display_name (file);
+ if (nautilus_file_is_in_trash (file)) {
+ prompt = g_strdup_printf (_("The Link \"%s\" is Broken."), display_name);
+ } else {
+ prompt = g_strdup_printf (_("The Link \"%s\" is Broken. Move it to Trash?"), display_name);
+ }
+ g_free (display_name);
+
+ target_path = nautilus_file_get_symbolic_link_target_path (file);
+ if (target_path == NULL) {
+ detail = g_strdup (_("This link can't be used, because it has no target."));
+ } else {
+ detail = g_strdup_printf (_("This link can't be used, because its target "
+ "\"%s\" doesn't exist."), target_path);
+ }
+
+ if (nautilus_file_is_in_trash (file)) {
+ eel_run_simple_dialog (GTK_WIDGET (parent_window), FALSE, GTK_MESSAGE_WARNING,
+ prompt, detail, GTK_STOCK_CANCEL, NULL);
+ goto out;
+ }
+
+ dialog = eel_show_yes_no_dialog (prompt, detail, _("Mo_ve to Trash"), GTK_STOCK_CANCEL,
+ parent_window);
+
+ gtk_dialog_set_default_response (dialog, GTK_RESPONSE_YES);
+
+ /* Make this modal to avoid problems with reffing the view & file
+ * to keep them around in case the view changes, which would then
+ * cause the old view not to be destroyed, which would cause its
+ * merged Bonobo items not to be un-merged. Maybe we need to unmerge
+ * explicitly when disconnecting views instead of relying on the
+ * unmerge in Destroy. But since BonoboUIHandler is probably going
+ * to change wildly, I don't want to mess with this now.
+ */
+
+ response = gtk_dialog_run (dialog);
+ gtk_object_destroy (GTK_OBJECT (dialog));
+
+ if (response == GTK_RESPONSE_YES) {
+ file_as_list.data = file;
+ file_as_list.next = NULL;
+ file_as_list.prev = NULL;
+ trash_or_delete_files (parent_window, &file_as_list, TRUE);
+ }
+
+out:
+ g_free (prompt);
+ g_free (target_path);
+ g_free (detail);
+}
+
+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 = eel_preferences_get_enum
+ (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, GTK_STOCK_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_object_destroy (GTK_OBJECT (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 = eel_preferences_get_enum
+ (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;
+ }
+}
+
+gboolean
+nautilus_mime_file_opens_in_view (NautilusFile *file)
+{
+ return (nautilus_file_is_directory (file) ||
+ NAUTILUS_IS_DESKTOP_ICON_FILE (file) ||
+ nautilus_file_is_nautilus_link (file));
+}
+
+static ActivationAction
+get_activation_action (NautilusFile *file)
+{
+ ActivationAction action;
+ char *activation_uri;
+
+ activation_uri = nautilus_file_get_activation_uri (file);
+ if (activation_uri == NULL) {
+ activation_uri = nautilus_file_get_uri (file);
+ }
+
+ action = ACTIVATION_ACTION_DO_NOTHING;
+
+ if (eel_str_has_prefix (activation_uri, NAUTILUS_DESKTOP_COMMAND_SPECIFIER)) {
+ action = ACTIVATION_ACTION_LAUNCH_DESKTOP_FILE;
+ } else if (eel_str_has_prefix (activation_uri, NAUTILUS_COMMAND_SPECIFIER)) {
+ action = ACTIVATION_ACTION_LAUNCH_APPLICATION_FROM_COMMAND;
+ } else if (nautilus_file_is_launchable (file)) {
+ 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);
+ }
+
+ if (action == ACTIVATION_ACTION_DO_NOTHING) {
+ if (nautilus_mime_file_opens_in_view (file)) {
+ action = ACTIVATION_ACTION_OPEN_IN_VIEW;
+ } else {
+ action = ACTIVATION_ACTION_OPEN_IN_APPLICATION;
+ }
+ }
+ g_free (activation_uri);
+
+ return action;
+}
+
+gboolean
+nautilus_mime_file_opens_in_external_app (NautilusFile *file)
+{
+ ActivationAction activation_action;
+
+ activation_action = get_activation_action (file);
+
+ return (activation_action == ACTIVATION_ACTION_OPEN_IN_APPLICATION);
+}
+
+
+static unsigned int
+mime_application_hash (GAppInfo *app)
+{
+ return g_str_hash (g_app_info_get_id (app));
+}
+
+static void
+list_to_parameters_foreach (GAppInfo *application,
+ GList *files,
+ GList **ret)
+{
+ ApplicationLaunchParameters *parameters;
+
+ files = g_list_reverse (files);
+
+ parameters = application_launch_parameters_new
+ (application, files);
+ *ret = g_list_prepend (*ret, parameters);
+}
+
+
+/**
+ * fm_directory_view_make_activation_parameters
+ *
+ * Construct a list of ApplicationLaunchParameters from a list of NautilusFiles,
+ * where files that have the same default application are put into the same
+ * launch parameter, and others are put into the unhandled_files list.
+ *
+ * @files: Files to use for construction.
+ * @unhandled_files: Files without any default application will be put here.
+ *
+ * Return value: Newly allocated list of ApplicationLaunchParameters.
+ **/
+static GList *
+fm_directory_view_make_activation_parameters (GList *files,
+ GList **unhandled_files)
+{
+ GList *ret, *l, *app_files;
+ NautilusFile *file;
+ GAppInfo *app, *old_app;
+ GHashTable *app_table;
+
+ ret = NULL;
+ *unhandled_files = NULL;
+
+ app_table = g_hash_table_new_full
+ ((GHashFunc) mime_application_hash,
+ (GEqualFunc) g_app_info_equal,
+ (GDestroyNotify) g_object_unref,
+ (GDestroyNotify) g_list_free);
+
+ for (l = files; l != NULL; l = l->next) {
+ file = NAUTILUS_FILE (l->data);
+
+ app = nautilus_mime_get_default_application_for_file (file);
+ if (app != NULL) {
+ app_files = NULL;
+
+ if (g_hash_table_lookup_extended (app_table, app,
+ (gpointer *) &old_app,
+ (gpointer *) &app_files)) {
+ g_hash_table_steal (app_table, old_app);
+
+ app_files = g_list_prepend (app_files, file);
+
+ g_object_unref (app);
+ app = old_app;
+ } else {
+ app_files = g_list_prepend (NULL, file);
+ }
+
+ g_hash_table_insert (app_table, app, app_files);
+ } else {
+ *unhandled_files = g_list_prepend (*unhandled_files, file);
+ }
+ }
+
+ g_hash_table_foreach (app_table,
+ (GHFunc) list_to_parameters_foreach,
+ &ret);
+
+ g_hash_table_destroy (app_table);
+
+ *unhandled_files = g_list_reverse (*unhandled_files);
+
+ return g_list_reverse (ret);
+}
+
+static gboolean
+file_was_cancelled (NautilusFile *file)
+{
+ GError *error;
+
+ error = nautilus_file_get_file_info_error (file);
+ return
+ error != NULL &&
+ error->domain == G_IO_ERROR &&
+ error->code == G_IO_ERROR_CANCELLED;
+
+}
+
+
+static gboolean
+file_was_not_mounted (NautilusFile *file)
+{
+ GError *error;
+
+ error = nautilus_file_get_file_info_error (file);
+ return
+ error != NULL &&
+ error->domain == G_IO_ERROR &&
+ error->code == G_IO_ERROR_NOT_MOUNTED;
+}
+
+static void
+activation_parameters_free (ActivateParameters *parameters)
+{
+ if (parameters->window_info) {
+ g_object_remove_weak_pointer (G_OBJECT (parameters->window_info), (gpointer *)&parameters->window_info);
+ }
+ if (parameters->parent_window) {
+ g_object_remove_weak_pointer (G_OBJECT (parameters->parent_window), (gpointer *)&parameters->parent_window);
+ }
+ g_object_unref (parameters->cancellable);
+ nautilus_file_list_free (parameters->files);
+ nautilus_file_list_free (parameters->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);
+}
+
+static void
+cancel_activate_callback (gpointer callback_data)
+{
+ /* TODO-gio */
+}
+
+static void
+activation_start_timed_cancel (ActivateParameters *parameters)
+{
+ eel_timed_wait_start_with_duration
+ (DELAY_UNTIL_CANCEL_MSECS,
+ cancel_activate_callback,
+ parameters,
+ parameters->timed_wait_prompt,
+ parameters->parent_window);
+}
+
+static void
+activate_mount_op_active (EelMountOperation *operation,
+ gboolean is_active,
+ ActivateParameters *parameters)
+{
+ if (is_active) {
+ eel_timed_wait_stop (cancel_activate_callback, parameters);
+ } else {
+ activation_start_timed_cancel (parameters);
+ }
+}
+
+static gboolean
+confirm_multiple_windows (GtkWindow *parent_window, int count)
+{
+ GtkDialog *dialog;
+ char *prompt;
+ char *detail;
+ int response;
+
+ if (count <= SILENT_WINDOW_OPEN_LIMIT) {
+ return TRUE;
+ }
+
+ prompt = _("Are you sure you want to open all files?");
+ detail = g_strdup_printf (ngettext("This will open %d separate window.",
+ "This will open %d separate windows.", count), count);
+ dialog = eel_show_yes_no_dialog (prompt, detail,
+ GTK_STOCK_OK, GTK_STOCK_CANCEL,
+ parent_window);
+ g_free (detail);
+
+ response = gtk_dialog_run (dialog);
+ gtk_object_destroy (GTK_OBJECT (dialog));
+
+ return response == GTK_RESPONSE_YES;
+}
+
+static void
+activate_files (ActivateParameters *parameters)
+{
+ NautilusFile *file;
+ GList *launch_desktop_files;
+ GList *launch_from_command_files;
+ GList *launch_files;
+ GList *launch_in_terminal_files;
+ GList *open_in_app_files;
+ GList *open_in_app_parameters;
+ GList *unhandled_open_in_app_files;
+ ApplicationLaunchParameters *one_parameters;
+ GList *open_in_view_files;
+ GList *l;
+ int count;
+ char *uri;
+ char *executable_path, *quoted_path, *name;
+ char *old_working_dir;
+ ActivationAction action;
+ GdkScreen *screen;
+
+ screen = gtk_widget_get_screen (GTK_WIDGET (parameters->parent_window));
+
+ launch_desktop_files = NULL;
+ launch_from_command_files = NULL;
+ launch_files = NULL;
+ launch_in_terminal_files = NULL;
+ open_in_app_files = NULL;
+ open_in_view_files = NULL;
+
+ for (l = parameters->files; l != NULL; l = l->next) {
+ file = NAUTILUS_FILE (l->data);
+
+ if (file_was_cancelled (file)) {
+ continue;
+ }
+
+ 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.
+ */
+ action = get_executable_text_file_action (parameters->parent_window, file);
+ }
+
+ switch (action) {
+ case ACTIVATION_ACTION_LAUNCH_DESKTOP_FILE :
+ launch_desktop_files = g_list_prepend (launch_desktop_files, file);
+ break;
+ case ACTIVATION_ACTION_LAUNCH_APPLICATION_FROM_COMMAND :
+ launch_from_command_files = g_list_prepend (launch_from_command_files, file);
+ break;
+ case ACTIVATION_ACTION_LAUNCH :
+ launch_files = g_list_prepend (launch_files, file);
+ break;
+ case ACTIVATION_ACTION_LAUNCH_IN_TERMINAL :
+ launch_in_terminal_files = g_list_prepend (launch_in_terminal_files, file);
+ break;
+ case ACTIVATION_ACTION_OPEN_IN_VIEW :
+ open_in_view_files = g_list_prepend (open_in_view_files, file);
+ break;
+ case ACTIVATION_ACTION_OPEN_IN_APPLICATION :
+ open_in_app_files = g_list_prepend (open_in_app_files, file);
+ break;
+ case ACTIVATION_ACTION_DO_NOTHING :
+ break;
+ case ACTIVATION_ACTION_ASK :
+ g_assert_not_reached ();
+ break;
+ }
+ }
+
+ launch_desktop_files = g_list_reverse (launch_desktop_files);
+ for (l = launch_desktop_files; l != NULL; l = l->next) {
+ file = NAUTILUS_FILE (l->data);
+
+ uri = nautilus_file_get_uri (file);
+ nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER,
+ "directory view activate_callback launch_desktop_file window=%p: %s",
+ parameters->parent_window, uri);
+ nautilus_launch_desktop_file (screen, uri, NULL,
+ parameters->parent_window);
+ g_free (uri);
+ }
+
+ launch_from_command_files = g_list_reverse (launch_from_command_files);
+ for (l = launch_from_command_files; l != NULL; l = l->next) {
+ file = NAUTILUS_FILE (l->data);
+
+ uri = nautilus_file_get_activation_uri (file);
+
+ nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER,
+ "directory view activate_callback launch_application_from_command window=%p: %s",
+ parameters->parent_window, uri);
+
+ nautilus_launch_application_from_command (
+ screen, NULL, uri + strlen (NAUTILUS_COMMAND_SPECIFIER),
+ NULL, FALSE);
+ g_free (uri);
+ }
+
+ old_working_dir = NULL;
+ if (parameters->activation_directory &&
+ (launch_files != NULL || launch_in_terminal_files != NULL)) {
+ old_working_dir = g_get_current_dir ();
+ chdir (parameters->activation_directory);
+
+ }
+
+ launch_files = g_list_reverse (launch_files);
+ for (l = launch_files; l != NULL; l = l->next) {
+ 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);
+ name = nautilus_file_get_name (file);
+
+ nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER,
+ "directory view activate_callback launch_file window=%p: %s",
+ parameters->parent_window, quoted_path);
+
+ nautilus_launch_application_from_command (screen, name, quoted_path, NULL, FALSE);
+ g_free (name);
+ g_free (quoted_path);
+ g_free (executable_path);
+ g_free (uri);
+
+ }
+
+ launch_in_terminal_files = g_list_reverse (launch_in_terminal_files);
+ for (l = launch_in_terminal_files; l != NULL; l = l->next) {
+ 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);
+ name = nautilus_file_get_name (file);
+
+ nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER,
+ "directory view activate_callback launch_in_terminal window=%p: %s",
+ parameters->parent_window, quoted_path);
+
+ nautilus_launch_application_from_command (screen, name, quoted_path, NULL, TRUE);
+ g_free (name);
+ g_free (quoted_path);
+ g_free (executable_path);
+ g_free (uri);
+ }
+
+ if (old_working_dir != NULL) {
+ chdir (old_working_dir);
+ g_free (old_working_dir);
+ }
+
+ open_in_view_files = g_list_reverse (open_in_view_files);
+ count = g_list_length (open_in_view_files);
+ if (parameters->window_info != NULL &&
+ confirm_multiple_windows (parameters->parent_window, count)) {
+ NautilusWindowOpenFlags flags;
+
+ flags = parameters->flags;
+ if (count > 1) {
+ flags |= NAUTILUS_WINDOW_OPEN_FLAG_NEW_WINDOW;
+ }
+
+ for (l = open_in_view_files; l != NULL; l = l->next) {
+ GFile *f;
+ /* The ui should ask for navigation or object windows
+ * depending on what the current one is */
+ file = NAUTILUS_FILE (l->data);
+
+ uri = nautilus_file_get_activation_uri (file);
+ f = g_file_new_for_uri (uri);
+ nautilus_window_info_open_location (parameters->window_info,
+ f, parameters->mode, flags, NULL);
+ g_object_unref (f);
+ g_free (uri);
+ }
+ }
+
+ open_in_app_parameters = NULL;
+ unhandled_open_in_app_files = NULL;
+
+ if (open_in_app_files != NULL) {
+ open_in_app_files = g_list_reverse (open_in_app_files);
+
+ open_in_app_parameters = fm_directory_view_make_activation_parameters
+ (open_in_app_files, &unhandled_open_in_app_files);
+ }
+
+ for (l = open_in_app_parameters; l != NULL; l = l->next) {
+ one_parameters = l->data;
+
+ nautilus_launch_application (one_parameters->application,
+ one_parameters->files,
+ parameters->parent_window);
+ application_launch_parameters_free (one_parameters);
+ }
+
+ for (l = unhandled_open_in_app_files; l != NULL; l = l->next) {
+ GFile *location;
+ char *full_uri_for_display;
+ char *uri_for_display;
+ char *error_message;
+
+ file = NAUTILUS_FILE (l->data);
+
+ location = nautilus_file_get_location (file);
+ full_uri_for_display = g_file_get_parse_name (location);
+ g_object_unref (location);
+
+ /* Truncate the URI so it doesn't get insanely wide. Note that even
+ * though the dialog uses wrapped text, if the URI doesn't contain
+ * white space then the text-wrapping code is too stupid to wrap it.
+ */
+ uri_for_display = eel_str_middle_truncate
+ (full_uri_for_display, MAX_URI_IN_DIALOG_LENGTH);
+ g_free (full_uri_for_display);
+
+ error_message = g_strdup_printf (_("Couldn't display \"%s\"."),
+ uri_for_display);
+
+ g_free (uri_for_display);
+
+ eel_show_error_dialog (error_message,
+ _("There is no application installed for this file type"),
+ parameters->parent_window);
+ g_free (error_message);
+ }
+
+ if (open_in_app_parameters != NULL ||
+ unhandled_open_in_app_files != NULL) {
+ if ((parameters->flags & NAUTILUS_WINDOW_OPEN_FLAG_CLOSE_BEHIND) != 0 &&
+ parameters->window_info != NULL &&
+ nautilus_window_info_get_window_type (parameters->window_info) == NAUTILUS_WINDOW_SPATIAL) {
+ nautilus_window_info_close (parameters->window_info);
+ }
+ }
+
+ g_list_free (launch_desktop_files);
+ g_list_free (launch_from_command_files);
+ g_list_free (launch_files);
+ g_list_free (launch_in_terminal_files);
+ g_list_free (open_in_view_files);
+ g_list_free (open_in_app_files);
+ g_list_free (open_in_app_parameters);
+ g_list_free (unhandled_open_in_app_files);
+
+ eel_timed_wait_stop (cancel_activate_callback, parameters);
+ activation_parameters_free (parameters);
+}
+
+static void
+activation_mount_not_mounted_callback (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ ActivateParameters *parameters = user_data;
+ GError *error;
+ NautilusFile *file;
+
+ file = parameters->not_mounted->data;
+
+ error = NULL;
+ if (!g_mount_for_location_finish (G_FILE (source_object), res, &error)) {
+ if (error->domain != G_IO_ERROR &&
+ error->code != G_IO_ERROR_CANCELLED &&
+ error->code != G_IO_ERROR_ALREADY_MOUNTED) {
+ eel_show_error_dialog (_("Unable to mount location"),
+ error->message, NULL);
+ }
+
+ if (error->domain != G_IO_ERROR &&
+ error->code != G_IO_ERROR_ALREADY_MOUNTED) {
+ parameters->files = g_list_remove (parameters->files, file);
+ nautilus_file_unref (file);
+ }
+
+ g_error_free (error);
+ }
+
+ parameters->not_mounted = g_list_delete_link (parameters->not_mounted,
+ parameters->not_mounted);
+ nautilus_file_unref (file);
+
+ activation_mount_not_mounted (parameters);
+}
+
+static void
+activation_mount_not_mounted (ActivateParameters *parameters)
+{
+ NautilusFile *file;
+ GFile *location;
+ GMountOperation *mount_op;
+
+ if (parameters->not_mounted != NULL) {
+ file = parameters->not_mounted->data;
+ mount_op = eel_mount_operation_new (parameters->parent_window);
+ g_signal_connect (mount_op, "active_changed", (GCallback)activate_mount_op_active, parameters);
+ location = nautilus_file_get_location (file);
+ g_mount_for_location (location, mount_op, parameters->cancellable,
+ activation_mount_not_mounted_callback, parameters);
+ g_object_unref (location);
+ g_object_unref (mount_op);
+ return;
+ }
+
+ parameters->tried_mounting = TRUE;
+ nautilus_file_list_call_when_ready
+ (parameters->files,
+ nautilus_mime_actions_get_required_file_attributes () | NAUTILUS_FILE_ATTRIBUTE_LINK_INFO,
+ &parameters->files_handle,
+ activate_callback, parameters);
+}
+
+
+static void
+activate_callback (GList *files, gpointer callback_data)
+{
+ ActivateParameters *parameters = callback_data;
+ GList *l, *next;
+ NautilusFile *file;
+
+ parameters->files_handle = NULL;
+
+ for (l = parameters->files; l != NULL; l = next) {
+ file = NAUTILUS_FILE (l->data);
+ next = l->next;
+
+ if (file_was_cancelled (file)) {
+ nautilus_file_unref (file);
+ parameters->files = g_list_delete_link (parameters->files, l);
+ continue;
+ }
+
+ if (file_was_not_mounted (file)) {
+ if (parameters->tried_mounting) {
+ nautilus_file_unref (file);
+ parameters->files = g_list_delete_link (parameters->files, l);
+ } else {
+ parameters->not_mounted = g_list_prepend (parameters->not_mounted,
+ nautilus_file_ref (file));
+ }
+ continue;
+ }
+ }
+
+
+ if (parameters->not_mounted != NULL) {
+ activation_mount_not_mounted (parameters);
+ } else {
+ activate_files (parameters);
+ }
+}
+
+static void
+activate_activation_uris_ready_callback (GList *files_ignore,
+ gpointer callback_data)
+{
+ ActivateParameters *parameters = callback_data;
+ GList *l, *next;
+ NautilusFile *file;
+
+ parameters->files_handle = NULL;
+
+ for (l = parameters->files; l != NULL; l = next) {
+ file = NAUTILUS_FILE (l->data);
+ next = l->next;
+
+ if (file_was_cancelled (file)) {
+ nautilus_file_unref (file);
+ parameters->files = g_list_delete_link (parameters->files, l);
+ continue;
+ }
+
+ if (nautilus_file_is_broken_symbolic_link (file)) {
+ nautilus_file_unref (file);
+ parameters->files = g_list_delete_link (parameters->files, l);
+ report_broken_symbolic_link (parameters->parent_window, file);
+ continue;
+ }
+ }
+
+ if (parameters->files == NULL) {
+ eel_timed_wait_stop (cancel_activate_callback, parameters);
+ activation_parameters_free (parameters);
+ return;
+ }
+
+ /* Convert the files to the actual activation uri files */
+ for (l = parameters->files; l != NULL; l = l->next) {
+ char *uri;
+ file = NAUTILUS_FILE (l->data);
+
+ /* We want the file for the activation URI since we care
+ * about the attributes for that, not for the original file.
+ */
+ uri = nautilus_file_get_activation_uri (file);
+ if (uri != NULL &&
+ !(g_str_has_prefix (uri, NAUTILUS_DESKTOP_COMMAND_SPECIFIER) ||
+ g_str_has_prefix (uri, NAUTILUS_COMMAND_SPECIFIER))) {
+ NautilusFile *actual_file;
+
+ actual_file = nautilus_file_get_by_uri (uri);
+ if (actual_file != NULL) {
+ nautilus_file_unref (file);
+ l->data = actual_file;
+ }
+ }
+ g_free (uri);
+ }
+
+
+ /* get the parameters for the actual files */
+ nautilus_file_list_call_when_ready
+ (parameters->files,
+ nautilus_mime_actions_get_required_file_attributes () | NAUTILUS_FILE_ATTRIBUTE_LINK_INFO,
+ &parameters->files_handle,
+ activate_callback, parameters);
+}
+
+static void
+activation_get_activation_uris (ActivateParameters *parameters)
+{
+ GList *l;
+ NautilusFile *file;
+
+ /* link target info might be stale, re-read it */
+ for (l = parameters->files; l != NULL; l = l->next) {
+ file = NAUTILUS_FILE (l->data);
+
+ if (file_was_cancelled (file)) {
+ nautilus_file_unref (file);
+ parameters->files = g_list_delete_link (parameters->files, l);
+ continue;
+ }
+
+ if (nautilus_file_is_symbolic_link (file)) {
+ nautilus_file_invalidate_attributes
+ (file,
+ NAUTILUS_FILE_ATTRIBUTE_INFO |
+ NAUTILUS_FILE_ATTRIBUTE_LINK_INFO);
+ }
+ }
+
+ if (parameters->files == NULL) {
+ eel_timed_wait_stop (cancel_activate_callback, parameters);
+ activation_parameters_free (parameters);
+ return;
+ }
+
+ nautilus_file_list_call_when_ready
+ (parameters->files,
+ NAUTILUS_FILE_ATTRIBUTE_INFO |
+ NAUTILUS_FILE_ATTRIBUTE_LINK_INFO,
+ &parameters->files_handle,
+ activate_activation_uris_ready_callback, parameters);
+}
+
+
+static void
+activation_mountable_mounted (NautilusFile *file,
+ GFile *result_location,
+ GError *error,
+ gpointer callback_data)
+{
+ ActivateParameters *parameters = callback_data;
+ NautilusFile *target_file;
+
+ /* Remove from list of files that have to be mounted */
+ parameters->mountables = g_list_remove (parameters->mountables, file);
+ nautilus_file_unref (file);
+
+ if (error == NULL) {
+ /* Replace file with the result of the mount */
+
+ target_file = nautilus_file_get (result_location);
+
+ parameters->files = g_list_remove (parameters->files, file);
+ nautilus_file_unref (file);
+
+ parameters->files = g_list_prepend (parameters->files, target_file);
+ } else {
+ /* Remove failed file */
+
+ if (error->domain != G_IO_ERROR &&
+ error->code != G_IO_ERROR_ALREADY_MOUNTED) {
+ parameters->files = g_list_remove (parameters->files, file);
+ nautilus_file_unref (file);
+ }
+
+ if (error->domain != G_IO_ERROR &&
+ error->code != G_IO_ERROR_CANCELLED &&
+ error->code != G_IO_ERROR_ALREADY_MOUNTED) {
+ eel_show_error_dialog (_("Unable to mount location"),
+ error->message, NULL);
+ }
+ }
+
+ /* Mount more mountables */
+ activation_mount_mountables (parameters);
+}
+
+
+static void
+activation_mount_mountables (ActivateParameters *parameters)
+{
+ NautilusFile *file;
+ GMountOperation *mount_op;
+
+ if (parameters->mountables != NULL) {
+ file = parameters->mountables->data;
+ mount_op = eel_mount_operation_new (parameters->parent_window);
+ g_signal_connect (mount_op, "active_changed", (GCallback)activate_mount_op_active, parameters);
+ nautilus_file_mount (file,
+ mount_op,
+ activation_mountable_mounted,
+ parameters);
+ g_object_unref (mount_op);
+ return;
+ }
+
+ activation_get_activation_uris (parameters);
+}
+
+
+/**
+ * fm_directory_view_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,
+ NautilusWindowInfo *window_info,
+ GList *files,
+ const char *launch_directory,
+ NautilusWindowOpenMode mode,
+ NautilusWindowOpenFlags flags)
+{
+ ActivateParameters *parameters;
+ char *file_name;
+ int file_count;
+ GList *l, *next;
+ NautilusFile *file;
+
+ if (files == NULL) {
+ return;
+ }
+
+ nautilus_debug_log_with_file_list (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, files,
+ "fm_directory_view_activate_files window=%p",
+ parent_window);
+
+ parameters = g_new0 (ActivateParameters, 1);
+ parameters->window_info = window_info;
+ g_object_add_weak_pointer (G_OBJECT (parameters->window_info), (gpointer *)&parameters->window_info);
+ if (parent_window) {
+ parameters->parent_window = 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->files = nautilus_file_list_copy (files);
+ parameters->mode = mode;
+ parameters->flags = flags;
+
+ file_count = g_list_length (files);
+ if (file_count == 1) {
+ file_name = nautilus_file_get_display_name (files->data);
+ parameters->timed_wait_prompt = g_strdup_printf (_("Opening \"%s\"."), file_name);
+ g_free (file_name);
+ } else {
+ parameters->timed_wait_prompt = g_strdup_printf (ngettext ("Opening %d item.",
+ "Opening %d items.",
+ file_count),
+ file_count);
+ }
+
+
+ for (l = parameters->files; l != NULL; l = next) {
+ file = NAUTILUS_FILE (l->data);
+ next = l->next;
+
+ if (nautilus_file_can_mount (file)) {
+ parameters->mountables = g_list_prepend (parameters->mountables,
+ nautilus_file_ref (file));
+ }
+ }
+
+ activation_start_timed_cancel (parameters);
+ activation_mount_mountables (parameters);
+}
+
+/**
+ * fm_directory_view_activate_file:
+ *
+ * Activate a file in this view. This might involve switching the displayed
+ * location for the current window, or launching an application.
+ * @view: FMDirectoryView in question.
+ * @file: A NautilusFile representing the file in this view to activate.
+ * @use_new_window: Should this item be opened in a new window?
+ *
+ **/
+
+void
+nautilus_mime_activate_file (GtkWindow *parent_window,
+ NautilusWindowInfo *window_info,
+ NautilusFile *file,
+ const char *launch_directory,
+ NautilusWindowOpenMode mode,
+ NautilusWindowOpenFlags flags)
+{
+ GList *files;
+
+ g_return_if_fail (NAUTILUS_IS_FILE (file));
+
+ files = g_list_prepend (NULL, file);
+ nautilus_mime_activate_files (parent_window, window_info, files, launch_directory, mode, flags);
+ g_list_free (files);
+}
diff --git a/libnautilus-private/nautilus-mime-actions.h b/libnautilus-private/nautilus-mime-actions.h
index f3d5ba784..888fc5646 100644
--- a/libnautilus-private/nautilus-mime-actions.h
+++ b/libnautilus-private/nautilus-mime-actions.h
@@ -28,16 +28,33 @@
#include <gio/gappinfo.h>
#include <libnautilus-private/nautilus-file.h>
+#include <libnautilus-private/nautilus-window-info.h>
+
+NautilusFileAttributes nautilus_mime_actions_get_required_file_attributes (void);
+
+GAppInfo * nautilus_mime_get_default_application_for_file (NautilusFile *file);
+GList * nautilus_mime_get_applications_for_file (NautilusFile *file);
+
+GAppInfo * nautilus_mime_get_default_application_for_files (GList *files);
+GList * nautilus_mime_get_applications_for_files (GList *file);
+
+gboolean nautilus_mime_has_any_applications_for_file (NautilusFile *file);
+gboolean nautilus_mime_has_any_applications_for_files (GList *files);
+
+gboolean nautilus_mime_file_opens_in_view (NautilusFile *file);
+gboolean nautilus_mime_file_opens_in_external_app (NautilusFile *file);
+void nautilus_mime_activate_files (GtkWindow *parent_window,
+ NautilusWindowInfo *window_info,
+ GList *files,
+ const char *launch_directory,
+ NautilusWindowOpenMode mode,
+ NautilusWindowOpenFlags flags);
+void nautilus_mime_activate_file (GtkWindow *parent_window,
+ NautilusWindowInfo *window_info,
+ NautilusFile *file,
+ const char *launch_directory,
+ NautilusWindowOpenMode mode,
+ NautilusWindowOpenFlags flags);
-NautilusFileAttributes nautilus_mime_actions_get_required_file_attributes (void);
-
-GAppInfo * nautilus_mime_get_default_application_for_file (NautilusFile *file);
-GList * nautilus_mime_get_applications_for_file (NautilusFile *file);
-
-GAppInfo * nautilus_mime_get_default_application_for_files (GList *files);
-GList * nautilus_mime_get_applications_for_files (GList *file);
-
-gboolean nautilus_mime_has_any_applications_for_file (NautilusFile *file);
-gboolean nautilus_mime_has_any_applications_for_files (GList *files);
#endif /* NAUTILUS_MIME_ACTIONS_H */
diff --git a/libnautilus-private/nautilus-program-choosing.c b/libnautilus-private/nautilus-program-choosing.c
index 611e189f0..7f878f85e 100644
--- a/libnautilus-private/nautilus-program-choosing.c
+++ b/libnautilus-private/nautilus-program-choosing.c
@@ -30,6 +30,7 @@
#include "nautilus-global-preferences.h"
#include "nautilus-icon-info.h"
#include "nautilus-vfs-utils.h"
+#include "nautilus-recent.h"
#include <eel/eel-glib-extensions.h>
#include <eel/eel-gnome-extensions.h>
#include <eel/eel-vfs-extensions.h>
@@ -607,6 +608,12 @@ nautilus_launch_application (GAppInfo *application,
g_warning ("Can't open app: %s\n", error->message);
#endif
}
+ } else {
+ for (l = files; l != NULL; l = l->next) {
+ file = NAUTILUS_FILE (l->data);
+
+ nautilus_recent_add_file (file, application);
+ }
}
eel_g_object_list_free (locations);
diff --git a/src/file-manager/fm-directory-view.c b/src/file-manager/fm-directory-view.c
index 635f6028d..4986562be 100644
--- a/src/file-manager/fm-directory-view.c
+++ b/src/file-manager/fm-directory-view.c
@@ -99,9 +99,6 @@
#include <libnautilus-private/nautilus-signaller.h>
#include <unistd.h>
-/* Number of seconds until cancel dialog shows up */
-#define DELAY_UNTIL_CANCEL_MSECS 5000
-
/* Minimum starting update inverval */
#define UPDATE_INTERVAL_MIN 100
/* Maximum update interval */
@@ -118,10 +115,6 @@
#define DUPLICATE_HORIZONTAL_ICON_OFFSET 70
#define DUPLICATE_VERTICAL_ICON_OFFSET 30
-#define RESPONSE_RUN 1000
-#define RESPONSE_DISPLAY 1001
-#define RESPONSE_RUN_IN_TERMINAL 1002
-
#define MAX_QUEUED_UPDATES 500
#define FM_DIRECTORY_VIEW_MENU_PATH_APPLICATIONS_SUBMENU_PLACEHOLDER "/MenuBar/File/Open Placeholder/Open With/Applications Placeholder"
@@ -145,13 +138,6 @@
#define MAX_MENU_LEVELS 5
#define TEMPLATE_LIMIT 30
-/* This number controls a maximum character count for a URL that is
- * displayed as part of a dialog. It's fairly arbitrary -- big enough
- * to allow most "normal" URIs to display in full, but small enough to
- * prevent the dialog from getting insanely wide.
- */
-#define MAX_URI_IN_DIALOG_LENGTH 60
-
/* Directory where user scripts are placed */
#define NAUTILUS_SCRIPTS_DIR ".gnome2/nautilus-scripts"
@@ -284,32 +270,6 @@ struct FMDirectoryViewDetails
GdkPoint context_menu_position;
};
-typedef enum {
- ACTIVATION_ACTION_LAUNCH_DESKTOP_FILE,
- ACTIVATION_ACTION_LAUNCH_APPLICATION_FROM_COMMAND,
- ACTIVATION_ACTION_ASK,
- ACTIVATION_ACTION_LAUNCH,
- ACTIVATION_ACTION_LAUNCH_IN_TERMINAL,
- ACTIVATION_ACTION_OPEN_IN_VIEW,
- ACTIVATION_ACTION_OPEN_IN_APPLICATION,
- ACTIVATION_ACTION_DO_NOTHING,
-} ActivationAction;
-
-typedef struct {
- NautilusWindowInfo *window_info;
- GtkWindow *parent_window;
- GCancellable *cancellable;
- GList *files;
- GList *mountables;
- GList *not_mounted;
- NautilusWindowOpenMode mode;
- NautilusWindowOpenFlags flags;
- char *timed_wait_prompt;
- NautilusFileListHandle *files_handle;
- gboolean tried_mounting;
- char *activation_directory;
-} ActivateParameters;
-
typedef struct {
NautilusFile *file;
NautilusDirectory *directory;
@@ -327,9 +287,7 @@ static const GtkTargetEntry clipboard_targets[] = {
/* forward declarations */
-static void cancel_activate_callback (gpointer callback_data);
static gboolean display_selection_info_idle_callback (gpointer data);
-static gboolean file_is_launchable (NautilusFile *file);
static void fm_directory_view_class_init (FMDirectoryViewClass *klass);
static void fm_directory_view_init (FMDirectoryView *view);
static void fm_directory_view_duplicate_selection (FMDirectoryView *view,
@@ -341,10 +299,6 @@ static void fm_directory_view_create_links_for_files (FMDirectoryView
static void trash_or_delete_files (GtkWindow *parent_window,
const GList *files,
gboolean delete_if_all_already_in_trash);
-static void fm_directory_view_activate_file (FMDirectoryView *view,
- NautilusFile *file,
- NautilusWindowOpenMode mode,
- NautilusWindowOpenFlags flags);
static void load_directory (FMDirectoryView *view,
NautilusDirectory *directory);
static void fm_directory_view_merge_menus (FMDirectoryView *view);
@@ -376,18 +330,11 @@ static void fm_directory_view_trash_state_changed_callback (NautilusTrashMon
gpointer callback_data);
static void fm_directory_view_select_file (FMDirectoryView *view,
NautilusFile *file);
-static void activate_activation_uris_ready_callback (GList *files,
- gpointer callback_data);
static GdkDragAction ask_link_action (FMDirectoryView *view);
static void update_templates_directory (FMDirectoryView *view);
static void user_dirs_changed (FMDirectoryView *view);
-static void activation_mount_mountables (ActivateParameters *parameters);
-static void activate_callback (GList *files,
- gpointer callback_data);
-static void activation_mount_not_mounted (ActivateParameters *parameters);
-
static void action_open_scripts_folder_callback (GtkAction *action,
gpointer callback_data);
static void action_cut_files_callback (GtkAction *action,
@@ -463,6 +410,37 @@ typedef struct {
FMDirectoryView *directory_view;
} CreateTemplateParameters;
+static ApplicationLaunchParameters *
+application_launch_parameters_new (GAppInfo *application,
+ GList *files,
+ FMDirectoryView *directory_view)
+{
+ ApplicationLaunchParameters *result;
+
+ result = g_new0 (ApplicationLaunchParameters, 1);
+ result->application = g_object_ref (application);
+ result->files = nautilus_file_list_copy (files);
+
+ if (directory_view != NULL) {
+ g_object_ref (directory_view);
+ result->directory_view = directory_view;
+ }
+
+ return result;
+}
+
+static void
+application_launch_parameters_free (ApplicationLaunchParameters *parameters)
+{
+ g_object_unref (parameters->application);
+ nautilus_file_list_free (parameters->files);
+
+ if (parameters->directory_view != NULL) {
+ g_object_unref (parameters->directory_view);
+ }
+
+ g_free (parameters);
+}
static GList *
file_and_directory_list_to_files (GList *fad_list)
@@ -538,37 +516,6 @@ file_and_directory_hash (gconstpointer v)
}
-static ApplicationLaunchParameters *
-application_launch_parameters_new (GAppInfo *application,
- GList *files,
- FMDirectoryView *directory_view)
-{
- ApplicationLaunchParameters *result;
-
- result = g_new0 (ApplicationLaunchParameters, 1);
- result->application = g_object_ref (application);
- result->files = nautilus_file_list_copy (files);
-
- if (directory_view != NULL) {
- g_object_ref (directory_view);
- result->directory_view = directory_view;
- }
-
- return result;
-}
-
-static void
-application_launch_parameters_free (ApplicationLaunchParameters *parameters)
-{
- g_object_unref (parameters->application);
- nautilus_file_list_free (parameters->files);
-
- if (parameters->directory_view != NULL) {
- g_object_unref (parameters->directory_view);
- }
-
- g_free (parameters);
-}
static ScriptLaunchParameters *
@@ -709,6 +656,55 @@ selection_not_empty_in_menu_callback (FMDirectoryView *view, GList *selection)
return FALSE;
}
+static char *
+get_view_directory (FMDirectoryView *view)
+{
+ char *uri, *path;
+ GFile *f;
+
+ uri = nautilus_directory_get_uri (view->details->model);
+ if (eel_uri_is_desktop (uri)) {
+ g_free (uri);
+ uri = nautilus_get_desktop_directory_uri ();
+
+ }
+ f = g_file_new_for_uri (uri);
+ path = g_file_get_path (f);
+ g_object_unref (f);
+ g_free (uri);
+
+ return path;
+}
+
+
+void
+fm_directory_view_activate_files (FMDirectoryView *view,
+ GList *files,
+ NautilusWindowOpenMode mode,
+ NautilusWindowOpenFlags flags)
+{
+ nautilus_mime_activate_files (fm_directory_view_get_containing_window (view),
+ view->details->window,
+ files,
+ get_view_directory (view),
+ mode,
+ flags);
+}
+
+void
+fm_directory_view_activate_file (FMDirectoryView *view,
+ NautilusFile *file,
+ NautilusWindowOpenMode mode,
+ NautilusWindowOpenFlags flags)
+{
+ nautilus_mime_activate_file (fm_directory_view_get_containing_window (view),
+ view->details->window,
+ file,
+ get_view_directory (view),
+ mode,
+ flags);
+}
+
static void
action_open_callback (GtkAction *action,
gpointer callback_data)
@@ -719,7 +715,8 @@ action_open_callback (GtkAction *action,
view = FM_DIRECTORY_VIEW (callback_data);
selection = fm_directory_view_get_selection (view);
- fm_directory_view_activate_files (view, selection,
+ fm_directory_view_activate_files (view,
+ selection,
NAUTILUS_WINDOW_OPEN_ACCORDING_TO_MODE,
0);
nautilus_file_list_free (selection);
@@ -735,7 +732,8 @@ action_open_close_parent_callback (GtkAction *action,
view = FM_DIRECTORY_VIEW (callback_data);
selection = fm_directory_view_get_selection (view);
- fm_directory_view_activate_files (view, selection,
+ fm_directory_view_activate_files (view,
+ selection,
NAUTILUS_WINDOW_OPEN_ACCORDING_TO_MODE,
NAUTILUS_WINDOW_OPEN_FLAG_CLOSE_BEHIND);
nautilus_file_list_free (selection);
@@ -763,29 +761,6 @@ action_open_alternate_callback (GtkAction *action,
}
static void
-fm_directory_view_launch_application (GAppInfo *application,
- GList *files,
- GtkWindow *parent_window)
-{
- NautilusFile *file;
- GList *l;
-
- g_assert (application != NULL);
- g_assert (NAUTILUS_IS_FILE (files->data));
-
- nautilus_debug_log_with_file_list (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, files,
- "fm_directory_view_launch_application window=%p", parent_window);
-
- nautilus_launch_application (application, files, parent_window);
-
- for (l = files; l != NULL; l = l->next) {
- file = NAUTILUS_FILE (l->data);
-
- nautilus_recent_add_file (file, application);
- }
-}
-
-static void
open_location (FMDirectoryView *directory_view,
const char *new_uri,
NautilusWindowOpenMode mode,
@@ -822,7 +797,7 @@ application_selected_cb (NautilusOpenWithDialog *dialog,
files.next = NULL;
files.prev = NULL;
files.data = file;
- fm_directory_view_launch_application (app, &files, parent_window);
+ nautilus_launch_application (app, &files, parent_window);
}
static void
@@ -3953,7 +3928,7 @@ open_with_launch_application_callback (GtkAction *action,
ApplicationLaunchParameters *launch_parameters;
launch_parameters = (ApplicationLaunchParameters *) callback_data;
- fm_directory_view_launch_application
+ nautilus_launch_application
(launch_parameters->application,
launch_parameters->files,
fm_directory_view_get_containing_window (launch_parameters->directory_view));
@@ -4138,139 +4113,6 @@ add_application_to_open_with_menu (FMDirectoryView *view,
}
-static ActivationAction
-get_default_executable_text_file_action (void)
-{
- int preferences_value;
-
- preferences_value = eel_preferences_get_enum
- (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_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 = eel_preferences_get_enum
- (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, GTK_STOCK_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_object_destroy (GTK_OBJECT (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 gboolean
-can_use_component_for_file (NautilusFile *file)
-{
- return (nautilus_file_is_directory (file) ||
- NAUTILUS_IS_DESKTOP_ICON_FILE (file) ||
- nautilus_file_is_nautilus_link (file));
-}
-
-static ActivationAction
-get_activation_action (NautilusFile *file)
-{
- ActivationAction action;
- char *activation_uri;
-
- activation_uri = nautilus_file_get_activation_uri (file);
- if (activation_uri == NULL) {
- activation_uri = nautilus_file_get_uri (file);
- }
-
- action = ACTIVATION_ACTION_DO_NOTHING;
-
- if (eel_str_has_prefix (activation_uri, NAUTILUS_DESKTOP_COMMAND_SPECIFIER)) {
- action = ACTIVATION_ACTION_LAUNCH_DESKTOP_FILE;
- } else if (eel_str_has_prefix (activation_uri, NAUTILUS_COMMAND_SPECIFIER)) {
- action = ACTIVATION_ACTION_LAUNCH_APPLICATION_FROM_COMMAND;
- } else if (file_is_launchable (file)) {
- 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);
- }
-
- if (action == ACTIVATION_ACTION_DO_NOTHING) {
- if (can_use_component_for_file (file)) {
- action = ACTIVATION_ACTION_OPEN_IN_VIEW;
- } else {
- action = ACTIVATION_ACTION_OPEN_IN_APPLICATION;
- }
- }
- g_free (activation_uri);
-
- return action;
-}
-
static void
reset_open_with_menu (FMDirectoryView *view, GList *selection)
{
@@ -4284,7 +4126,6 @@ reset_open_with_menu (FMDirectoryView *view, GList *selection)
GtkUIManager *ui_manager;
GtkAction *action;
GAppInfo *default_app;
- ActivationAction activation_action;
/* Clear any previous inserted items in the applications and viewers placeholders */
@@ -4307,10 +4148,8 @@ reset_open_with_menu (FMDirectoryView *view, GList *selection)
file = NAUTILUS_FILE (node->data);
other_applications_visible &=
- (!can_use_component_for_file (file) ||
+ (!nautilus_mime_file_opens_in_view (file) ||
nautilus_file_is_directory (file));
-
- activation_action = get_activation_action (file);
}
default_app = NULL;
@@ -4661,26 +4500,6 @@ reset_extension_actions_menu (FMDirectoryView *view, GList *selection)
}
static char *
-get_view_directory (FMDirectoryView *view)
-{
- char *uri, *path;
- GFile *f;
-
- uri = nautilus_directory_get_uri (view->details->model);
- if (eel_uri_is_desktop (uri)) {
- g_free (uri);
- uri = nautilus_get_desktop_directory_uri ();
-
- }
- f = g_file_new_for_uri (uri);
- path = g_file_get_path (f);
- g_object_unref (f);
- g_free (uri);
-
- return path;
-}
-
-static char *
change_to_view_directory (FMDirectoryView *view)
{
char *path;
@@ -5068,7 +4887,7 @@ update_directory_in_scripts_menu (FMDirectoryView *view, NautilusDirectory *dire
for (node = file_list; node != NULL; node = node->next) {
file = node->data;
- if (file_is_launchable (file)) {
+ if (nautilus_file_is_launchable (file)) {
add_script_to_scripts_menus (view, file, menu_path, popup_path, popup_bg_path);
any_scripts = TRUE;
} else if (nautilus_file_is_directory (file)) {
@@ -7001,7 +6820,6 @@ real_update_menus (FMDirectoryView *view)
gboolean show_save_search;
gboolean save_search_sensitive;
gboolean show_save_search_as;
- ActivationAction activation_action;
GtkAction *action;
GAppInfo *app;
@@ -7045,10 +6863,8 @@ real_update_menus (FMDirectoryView *view)
NautilusFile *file;
file = NAUTILUS_FILE (selection->data);
-
- activation_action = get_activation_action (file);
-
- if (activation_action != ACTIVATION_ACTION_OPEN_IN_APPLICATION) {
+
+ if (!nautilus_mime_file_opens_in_external_app (file)) {
show_app = FALSE;
}
@@ -7440,877 +7256,6 @@ fm_directory_view_notify_selection_changed (FMDirectoryView *view)
nautilus_file_list_free (selection);
}
-static gboolean
-file_is_launchable (NautilusFile *file)
-{
- char *mime_type;
- gboolean type_can_be_executable;
-
- mime_type = nautilus_file_get_mime_type (file);
- type_can_be_executable = g_content_type_can_be_executable (mime_type);
- g_free (mime_type);
-
- return type_can_be_executable &&
- nautilus_file_can_get_permissions (file) &&
- nautilus_file_can_execute (file) &&
- nautilus_file_is_executable (file) &&
- !nautilus_file_is_directory (file);
-}
-
-static void
-report_broken_symbolic_link (GtkWindow *parent_window, NautilusFile *file)
-{
- char *target_path;
- char *display_name;
- char *prompt;
- char *detail;
- GtkDialog *dialog;
- GList file_as_list;
- int response;
-
- g_assert (nautilus_file_is_broken_symbolic_link (file));
-
- display_name = nautilus_file_get_display_name (file);
- if (nautilus_file_is_in_trash (file)) {
- prompt = g_strdup_printf (_("The Link \"%s\" is Broken."), display_name);
- } else {
- prompt = g_strdup_printf (_("The Link \"%s\" is Broken. Move it to Trash?"), display_name);
- }
- g_free (display_name);
-
- target_path = nautilus_file_get_symbolic_link_target_path (file);
- if (target_path == NULL) {
- detail = g_strdup (_("This link can't be used, because it has no target."));
- } else {
- detail = g_strdup_printf (_("This link can't be used, because its target "
- "\"%s\" doesn't exist."), target_path);
- }
-
- if (nautilus_file_is_in_trash (file)) {
- eel_run_simple_dialog (GTK_WIDGET (parent_window), FALSE, GTK_MESSAGE_WARNING,
- prompt, detail, GTK_STOCK_CANCEL, NULL);
- goto out;
- }
-
- dialog = eel_show_yes_no_dialog (prompt, detail, _("Mo_ve to Trash"), GTK_STOCK_CANCEL,
- parent_window);
-
- gtk_dialog_set_default_response (dialog, GTK_RESPONSE_YES);
-
- /* Make this modal to avoid problems with reffing the view & file
- * to keep them around in case the view changes, which would then
- * cause the old view not to be destroyed, which would cause its
- * merged Bonobo items not to be un-merged. Maybe we need to unmerge
- * explicitly when disconnecting views instead of relying on the
- * unmerge in Destroy. But since BonoboUIHandler is probably going
- * to change wildly, I don't want to mess with this now.
- */
-
- response = gtk_dialog_run (dialog);
- gtk_object_destroy (GTK_OBJECT (dialog));
-
- if (response == GTK_RESPONSE_YES) {
- file_as_list.data = file;
- file_as_list.next = NULL;
- file_as_list.prev = NULL;
- trash_or_delete_files (parent_window, &file_as_list, TRUE);
- }
-
-out:
- g_free (prompt);
- g_free (target_path);
- g_free (detail);
-}
-
-static void
-list_to_parameters_foreach (GAppInfo *application,
- GList *files,
- GList **ret)
-{
- ApplicationLaunchParameters *parameters;
-
- files = g_list_reverse (files);
-
- parameters = application_launch_parameters_new
- (application, files, NULL);
- *ret = g_list_prepend (*ret, parameters);
-}
-
-static unsigned int
-mime_application_hash (GAppInfo *app)
-{
- return g_str_hash (g_app_info_get_id (app));
-}
-
-/**
- * fm_directory_view_make_activation_parameters
- *
- * Construct a list of ApplicationLaunchParameters from a list of NautilusFiles,
- * where files that have the same default application are put into the same
- * launch parameter, and others are put into the unhandled_files list.
- *
- * @files: Files to use for construction.
- * @unhandled_files: Files without any default application will be put here.
- *
- * Return value: Newly allocated list of ApplicationLaunchParameters.
- **/
-static GList *
-fm_directory_view_make_activation_parameters (GList *files,
- GList **unhandled_files)
-{
- GList *ret, *l, *app_files;
- NautilusFile *file;
- GAppInfo *app, *old_app;
- GHashTable *app_table;
-
- ret = NULL;
- *unhandled_files = NULL;
-
- app_table = g_hash_table_new_full
- ((GHashFunc) mime_application_hash,
- (GEqualFunc) g_app_info_equal,
- (GDestroyNotify) g_object_unref,
- (GDestroyNotify) g_list_free);
-
- for (l = files; l != NULL; l = l->next) {
- file = NAUTILUS_FILE (l->data);
-
- app = nautilus_mime_get_default_application_for_file (file);
- if (app != NULL) {
- app_files = NULL;
-
- if (g_hash_table_lookup_extended (app_table, app,
- (gpointer *) &old_app,
- (gpointer *) &app_files)) {
- g_hash_table_steal (app_table, old_app);
-
- app_files = g_list_prepend (app_files, file);
-
- g_object_unref (app);
- app = old_app;
- } else {
- app_files = g_list_prepend (NULL, file);
- }
-
- g_hash_table_insert (app_table, app, app_files);
- } else {
- *unhandled_files = g_list_prepend (*unhandled_files, file);
- }
- }
-
- g_hash_table_foreach (app_table,
- (GHFunc) list_to_parameters_foreach,
- &ret);
-
- g_hash_table_destroy (app_table);
-
- *unhandled_files = g_list_reverse (*unhandled_files);
-
- return g_list_reverse (ret);
-}
-
-static gboolean
-file_was_cancelled (NautilusFile *file)
-{
- GError *error;
-
- error = nautilus_file_get_file_info_error (file);
- return
- error != NULL &&
- error->domain == G_IO_ERROR &&
- error->code == G_IO_ERROR_CANCELLED;
-
-}
-
-
-static gboolean
-file_was_not_mounted (NautilusFile *file)
-{
- GError *error;
-
- error = nautilus_file_get_file_info_error (file);
- return
- error != NULL &&
- error->domain == G_IO_ERROR &&
- error->code == G_IO_ERROR_NOT_MOUNTED;
-}
-
-static void
-activation_parameters_free (ActivateParameters *parameters)
-{
- if (parameters->window_info) {
- g_object_remove_weak_pointer (G_OBJECT (parameters->window_info), (gpointer *)&parameters->window_info);
- }
- if (parameters->parent_window) {
- g_object_remove_weak_pointer (G_OBJECT (parameters->parent_window), (gpointer *)&parameters->parent_window);
- }
- g_object_unref (parameters->cancellable);
- nautilus_file_list_free (parameters->files);
- nautilus_file_list_free (parameters->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);
-}
-
-static void
-cancel_activate_callback (gpointer callback_data)
-{
- /* TODO */
-}
-
-static void
-activation_start_timed_cancel (ActivateParameters *parameters)
-{
- eel_timed_wait_start_with_duration
- (DELAY_UNTIL_CANCEL_MSECS,
- cancel_activate_callback,
- parameters,
- parameters->timed_wait_prompt,
- parameters->parent_window);
-}
-
-static void
-activate_mount_op_active (EelMountOperation *operation,
- gboolean is_active,
- ActivateParameters *parameters)
-{
- if (is_active) {
- eel_timed_wait_stop (cancel_activate_callback, parameters);
- } else {
- activation_start_timed_cancel (parameters);
- }
-}
-
-static void
-activate_files (ActivateParameters *parameters)
-{
- NautilusFile *file;
- GList *launch_desktop_files;
- GList *launch_from_command_files;
- GList *launch_files;
- GList *launch_in_terminal_files;
- GList *open_in_app_files;
- GList *open_in_app_parameters;
- GList *unhandled_open_in_app_files;
- ApplicationLaunchParameters *one_parameters;
- GList *open_in_view_files;
- GList *l;
- int count;
- char *uri;
- char *executable_path, *quoted_path, *name;
- char *old_working_dir;
- ActivationAction action;
- GdkScreen *screen;
-
- screen = gtk_widget_get_screen (GTK_WIDGET (parameters->parent_window));
-
- launch_desktop_files = NULL;
- launch_from_command_files = NULL;
- launch_files = NULL;
- launch_in_terminal_files = NULL;
- open_in_app_files = NULL;
- open_in_view_files = NULL;
-
- for (l = parameters->files; l != NULL; l = l->next) {
- file = NAUTILUS_FILE (l->data);
-
- if (file_was_cancelled (file)) {
- continue;
- }
-
- 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.
- */
- action = get_executable_text_file_action (parameters->parent_window, file);
- }
-
- switch (action) {
- case ACTIVATION_ACTION_LAUNCH_DESKTOP_FILE :
- launch_desktop_files = g_list_prepend (launch_desktop_files, file);
- break;
- case ACTIVATION_ACTION_LAUNCH_APPLICATION_FROM_COMMAND :
- launch_from_command_files = g_list_prepend (launch_from_command_files, file);
- break;
- case ACTIVATION_ACTION_LAUNCH :
- launch_files = g_list_prepend (launch_files, file);
- break;
- case ACTIVATION_ACTION_LAUNCH_IN_TERMINAL :
- launch_in_terminal_files = g_list_prepend (launch_in_terminal_files, file);
- break;
- case ACTIVATION_ACTION_OPEN_IN_VIEW :
- open_in_view_files = g_list_prepend (open_in_view_files, file);
- break;
- case ACTIVATION_ACTION_OPEN_IN_APPLICATION :
- open_in_app_files = g_list_prepend (open_in_app_files, file);
- break;
- case ACTIVATION_ACTION_DO_NOTHING :
- break;
- case ACTIVATION_ACTION_ASK :
- g_assert_not_reached ();
- break;
- }
- }
-
- launch_desktop_files = g_list_reverse (launch_desktop_files);
- for (l = launch_desktop_files; l != NULL; l = l->next) {
- file = NAUTILUS_FILE (l->data);
-
- uri = nautilus_file_get_uri (file);
- nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER,
- "directory view activate_callback launch_desktop_file window=%p: %s",
- parameters->parent_window, uri);
- nautilus_launch_desktop_file (screen, uri, NULL,
- parameters->parent_window);
- g_free (uri);
- }
-
- launch_from_command_files = g_list_reverse (launch_from_command_files);
- for (l = launch_from_command_files; l != NULL; l = l->next) {
- file = NAUTILUS_FILE (l->data);
-
- uri = nautilus_file_get_activation_uri (file);
-
- nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER,
- "directory view activate_callback launch_application_from_command window=%p: %s",
- parameters->parent_window, uri);
-
- nautilus_launch_application_from_command (
- screen, NULL, uri + strlen (NAUTILUS_COMMAND_SPECIFIER),
- NULL, FALSE);
- g_free (uri);
- }
-
- old_working_dir = NULL;
- if (parameters->activation_directory &&
- (launch_files != NULL || launch_in_terminal_files != NULL)) {
- old_working_dir = g_get_current_dir ();
- chdir (parameters->activation_directory);
-
- }
-
- launch_files = g_list_reverse (launch_files);
- for (l = launch_files; l != NULL; l = l->next) {
- 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);
- name = nautilus_file_get_name (file);
-
- nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER,
- "directory view activate_callback launch_file window=%p: %s",
- parameters->parent_window, quoted_path);
-
- nautilus_launch_application_from_command (screen, name, quoted_path, NULL, FALSE);
- g_free (name);
- g_free (quoted_path);
- g_free (executable_path);
- g_free (uri);
-
- }
-
- launch_in_terminal_files = g_list_reverse (launch_in_terminal_files);
- for (l = launch_in_terminal_files; l != NULL; l = l->next) {
- 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);
- name = nautilus_file_get_name (file);
-
- nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER,
- "directory view activate_callback launch_in_terminal window=%p: %s",
- parameters->parent_window, quoted_path);
-
- nautilus_launch_application_from_command (screen, name, quoted_path, NULL, TRUE);
- g_free (name);
- g_free (quoted_path);
- g_free (executable_path);
- g_free (uri);
- }
-
- if (old_working_dir != NULL) {
- chdir (old_working_dir);
- g_free (old_working_dir);
- }
-
- open_in_view_files = g_list_reverse (open_in_view_files);
- count = g_list_length (open_in_view_files);
- if (parameters->window_info != NULL &&
- fm_directory_view_confirm_multiple_windows (parameters->parent_window, count)) {
- NautilusWindowOpenFlags flags;
-
- flags = parameters->flags;
- if (count > 1) {
- flags |= NAUTILUS_WINDOW_OPEN_FLAG_NEW_WINDOW;
- }
-
- for (l = open_in_view_files; l != NULL; l = l->next) {
- GFile *f;
- /* The ui should ask for navigation or object windows
- * depending on what the current one is */
- file = NAUTILUS_FILE (l->data);
-
- uri = nautilus_file_get_activation_uri (file);
- f = g_file_new_for_uri (uri);
- nautilus_window_info_open_location (parameters->window_info,
- f, parameters->mode, flags, NULL);
- g_object_unref (f);
- g_free (uri);
- }
- }
-
- open_in_app_parameters = NULL;
- unhandled_open_in_app_files = NULL;
-
- if (open_in_app_files != NULL) {
- open_in_app_files = g_list_reverse (open_in_app_files);
-
- open_in_app_parameters = fm_directory_view_make_activation_parameters
- (open_in_app_files, &unhandled_open_in_app_files);
- }
-
- for (l = open_in_app_parameters; l != NULL; l = l->next) {
- one_parameters = l->data;
-
- fm_directory_view_launch_application (
- one_parameters->application,
- one_parameters->files,
- parameters->parent_window);
- application_launch_parameters_free (one_parameters);
- }
-
- for (l = unhandled_open_in_app_files; l != NULL; l = l->next) {
- GFile *location;
- char *full_uri_for_display;
- char *uri_for_display;
- char *error_message;
-
- file = NAUTILUS_FILE (l->data);
-
- location = nautilus_file_get_location (file);
- full_uri_for_display = g_file_get_parse_name (location);
- g_object_unref (location);
-
- /* Truncate the URI so it doesn't get insanely wide. Note that even
- * though the dialog uses wrapped text, if the URI doesn't contain
- * white space then the text-wrapping code is too stupid to wrap it.
- */
- uri_for_display = eel_str_middle_truncate
- (full_uri_for_display, MAX_URI_IN_DIALOG_LENGTH);
- g_free (full_uri_for_display);
-
- error_message = g_strdup_printf (_("Couldn't display \"%s\"."),
- uri_for_display);
-
- g_free (uri_for_display);
-
- eel_show_error_dialog (error_message,
- _("There is no application installed for this file type"),
- parameters->parent_window);
- g_free (error_message);
- }
-
- if (open_in_app_parameters != NULL ||
- unhandled_open_in_app_files != NULL) {
- if ((parameters->flags & NAUTILUS_WINDOW_OPEN_FLAG_CLOSE_BEHIND) != 0 &&
- parameters->window_info != NULL &&
- nautilus_window_info_get_window_type (parameters->window_info) == NAUTILUS_WINDOW_SPATIAL) {
- nautilus_window_info_close (parameters->window_info);
- }
- }
-
- g_list_free (launch_desktop_files);
- g_list_free (launch_from_command_files);
- g_list_free (launch_files);
- g_list_free (launch_in_terminal_files);
- g_list_free (open_in_view_files);
- g_list_free (open_in_app_files);
- g_list_free (open_in_app_parameters);
- g_list_free (unhandled_open_in_app_files);
-
- eel_timed_wait_stop (cancel_activate_callback, parameters);
- activation_parameters_free (parameters);
-}
-
-static void
-activation_mount_not_mounted_callback (GObject *source_object,
- GAsyncResult *res,
- gpointer user_data)
-{
- ActivateParameters *parameters = user_data;
- GError *error;
- NautilusFile *file;
-
- file = parameters->not_mounted->data;
-
- error = NULL;
- if (!g_mount_for_location_finish (G_FILE (source_object), res, &error)) {
- if (error->domain != G_IO_ERROR &&
- error->code != G_IO_ERROR_CANCELLED &&
- error->code != G_IO_ERROR_ALREADY_MOUNTED) {
- eel_show_error_dialog (_("Unable to mount location"),
- error->message, NULL);
- }
-
- if (error->domain != G_IO_ERROR &&
- error->code != G_IO_ERROR_ALREADY_MOUNTED) {
- parameters->files = g_list_remove (parameters->files, file);
- nautilus_file_unref (file);
- }
-
- g_error_free (error);
- }
-
- parameters->not_mounted = g_list_delete_link (parameters->not_mounted,
- parameters->not_mounted);
- nautilus_file_unref (file);
-
- activation_mount_not_mounted (parameters);
-}
-
-static void
-activation_mount_not_mounted (ActivateParameters *parameters)
-{
- NautilusFile *file;
- GFile *location;
- GMountOperation *mount_op;
-
- if (parameters->not_mounted != NULL) {
- file = parameters->not_mounted->data;
- mount_op = eel_mount_operation_new (parameters->parent_window);
- g_signal_connect (mount_op, "active_changed", (GCallback)activate_mount_op_active, parameters);
- location = nautilus_file_get_location (file);
- g_mount_for_location (location, mount_op, parameters->cancellable,
- activation_mount_not_mounted_callback, parameters);
- g_object_unref (location);
- g_object_unref (mount_op);
- return;
- }
-
- parameters->tried_mounting = TRUE;
- nautilus_file_list_call_when_ready
- (parameters->files,
- nautilus_mime_actions_get_required_file_attributes () | NAUTILUS_FILE_ATTRIBUTE_LINK_INFO,
- &parameters->files_handle,
- activate_callback, parameters);
-}
-
-
-static void
-activate_callback (GList *files, gpointer callback_data)
-{
- ActivateParameters *parameters = callback_data;
- GList *l, *next;
- NautilusFile *file;
-
- parameters->files_handle = NULL;
-
- for (l = parameters->files; l != NULL; l = next) {
- file = NAUTILUS_FILE (l->data);
- next = l->next;
-
- if (file_was_cancelled (file)) {
- nautilus_file_unref (file);
- parameters->files = g_list_delete_link (parameters->files, l);
- continue;
- }
-
- if (file_was_not_mounted (file)) {
- if (parameters->tried_mounting) {
- nautilus_file_unref (file);
- parameters->files = g_list_delete_link (parameters->files, l);
- } else {
- parameters->not_mounted = g_list_prepend (parameters->not_mounted,
- nautilus_file_ref (file));
- }
- continue;
- }
- }
-
-
- if (parameters->not_mounted != NULL) {
- activation_mount_not_mounted (parameters);
- } else {
- activate_files (parameters);
- }
-}
-
-static void
-activate_activation_uris_ready_callback (GList *files_ignore,
- gpointer callback_data)
-{
- ActivateParameters *parameters = callback_data;
- GList *l, *next;
- NautilusFile *file;
-
- parameters->files_handle = NULL;
-
- for (l = parameters->files; l != NULL; l = next) {
- file = NAUTILUS_FILE (l->data);
- next = l->next;
-
- if (file_was_cancelled (file)) {
- nautilus_file_unref (file);
- parameters->files = g_list_delete_link (parameters->files, l);
- continue;
- }
-
- if (nautilus_file_is_broken_symbolic_link (file)) {
- nautilus_file_unref (file);
- parameters->files = g_list_delete_link (parameters->files, l);
- report_broken_symbolic_link (parameters->parent_window, file);
- continue;
- }
- }
-
- if (parameters->files == NULL) {
- eel_timed_wait_stop (cancel_activate_callback, parameters);
- activation_parameters_free (parameters);
- return;
- }
-
- /* Convert the files to the actual activation uri files */
- for (l = parameters->files; l != NULL; l = l->next) {
- char *uri;
- file = NAUTILUS_FILE (l->data);
-
- /* We want the file for the activation URI since we care
- * about the attributes for that, not for the original file.
- */
- uri = nautilus_file_get_activation_uri (file);
- if (uri != NULL &&
- !(g_str_has_prefix (uri, NAUTILUS_DESKTOP_COMMAND_SPECIFIER) ||
- g_str_has_prefix (uri, NAUTILUS_COMMAND_SPECIFIER))) {
- NautilusFile *actual_file;
-
- actual_file = nautilus_file_get_by_uri (uri);
- if (actual_file != NULL) {
- nautilus_file_unref (file);
- l->data = actual_file;
- }
- }
- g_free (uri);
- }
-
-
- /* get the parameters for the actual files */
- nautilus_file_list_call_when_ready
- (parameters->files,
- nautilus_mime_actions_get_required_file_attributes () | NAUTILUS_FILE_ATTRIBUTE_LINK_INFO,
- &parameters->files_handle,
- activate_callback, parameters);
-}
-
-static void
-activation_get_activation_uris (ActivateParameters *parameters)
-{
- GList *l;
- NautilusFile *file;
-
- /* link target info might be stale, re-read it */
- for (l = parameters->files; l != NULL; l = l->next) {
- file = NAUTILUS_FILE (l->data);
-
- if (file_was_cancelled (file)) {
- nautilus_file_unref (file);
- parameters->files = g_list_delete_link (parameters->files, l);
- continue;
- }
-
- if (nautilus_file_is_symbolic_link (file)) {
- nautilus_file_invalidate_attributes
- (file,
- NAUTILUS_FILE_ATTRIBUTE_INFO |
- NAUTILUS_FILE_ATTRIBUTE_LINK_INFO);
- }
- }
-
- if (parameters->files == NULL) {
- eel_timed_wait_stop (cancel_activate_callback, parameters);
- activation_parameters_free (parameters);
- return;
- }
-
- nautilus_file_list_call_when_ready
- (parameters->files,
- NAUTILUS_FILE_ATTRIBUTE_INFO |
- NAUTILUS_FILE_ATTRIBUTE_LINK_INFO,
- &parameters->files_handle,
- activate_activation_uris_ready_callback, parameters);
-}
-
-
-static void
-activation_mountable_mounted (NautilusFile *file,
- GFile *result_location,
- GError *error,
- gpointer callback_data)
-{
- ActivateParameters *parameters = callback_data;
- NautilusFile *target_file;
-
- /* Remove from list of files that have to be mounted */
- parameters->mountables = g_list_remove (parameters->mountables, file);
- nautilus_file_unref (file);
-
- if (error == NULL) {
- /* Replace file with the result of the mount */
-
- target_file = nautilus_file_get (result_location);
-
- parameters->files = g_list_remove (parameters->files, file);
- nautilus_file_unref (file);
-
- parameters->files = g_list_prepend (parameters->files, target_file);
- } else {
- /* Remove failed file */
-
- if (error->domain != G_IO_ERROR &&
- error->code != G_IO_ERROR_ALREADY_MOUNTED) {
- parameters->files = g_list_remove (parameters->files, file);
- nautilus_file_unref (file);
- }
-
- if (error->domain != G_IO_ERROR &&
- error->code != G_IO_ERROR_CANCELLED &&
- error->code != G_IO_ERROR_ALREADY_MOUNTED) {
- eel_show_error_dialog (_("Unable to mount location"),
- error->message, NULL);
- }
- }
-
- /* Mount more mountables */
- activation_mount_mountables (parameters);
-}
-
-
-static void
-activation_mount_mountables (ActivateParameters *parameters)
-{
- NautilusFile *file;
- GMountOperation *mount_op;
-
- if (parameters->mountables != NULL) {
- file = parameters->mountables->data;
- mount_op = eel_mount_operation_new (parameters->parent_window);
- g_signal_connect (mount_op, "active_changed", (GCallback)activate_mount_op_active, parameters);
- nautilus_file_mount (file,
- mount_op,
- activation_mountable_mounted,
- parameters);
- g_object_unref (mount_op);
- return;
- }
-
- activation_get_activation_uris (parameters);
-}
-
-
-/**
- * fm_directory_view_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
-fm_directory_view_activate_files (FMDirectoryView *view,
- GList *files,
- NautilusWindowOpenMode mode,
- NautilusWindowOpenFlags flags)
-{
- ActivateParameters *parameters;
- GtkWindow *window;
- char *file_name;
- int file_count;
- GList *l, *next;
- NautilusFile *file;
-
- g_return_if_fail (FM_IS_DIRECTORY_VIEW (view));
-
- if (files == NULL) {
- return;
- }
-
- window = fm_directory_view_get_containing_window (view);
-
- nautilus_debug_log_with_file_list (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, files,
- "fm_directory_view_activate_files window=%p",
- window);
-
- parameters = g_new0 (ActivateParameters, 1);
- parameters->window_info = view->details->window;
- g_object_add_weak_pointer (G_OBJECT (parameters->window_info), (gpointer *)&parameters->window_info);
- if (window) {
- parameters->parent_window = window;
- g_object_add_weak_pointer (G_OBJECT (parameters->parent_window), (gpointer *)&parameters->parent_window);
- }
- parameters->cancellable = g_cancellable_new ();
- parameters->activation_directory = get_view_directory (view);
- parameters->files = nautilus_file_list_copy (files);
- parameters->mode = mode;
- parameters->flags = flags;
-
- file_count = g_list_length (files);
- if (file_count == 1) {
- file_name = nautilus_file_get_display_name (files->data);
- parameters->timed_wait_prompt = g_strdup_printf (_("Opening \"%s\"."), file_name);
- g_free (file_name);
- } else {
- parameters->timed_wait_prompt = g_strdup_printf (ngettext ("Opening %d item.",
- "Opening %d items.",
- file_count),
- file_count);
- }
-
-
- for (l = parameters->files; l != NULL; l = next) {
- file = NAUTILUS_FILE (l->data);
- next = l->next;
-
- if (nautilus_file_can_mount (file)) {
- parameters->mountables = g_list_prepend (parameters->mountables,
- nautilus_file_ref (file));
- }
- }
-
- activation_start_timed_cancel (parameters);
- activation_mount_mountables (parameters);
-}
-
-/**
- * fm_directory_view_activate_file:
- *
- * Activate a file in this view. This might involve switching the displayed
- * location for the current window, or launching an application.
- * @view: FMDirectoryView in question.
- * @file: A NautilusFile representing the file in this view to activate.
- * @use_new_window: Should this item be opened in a new window?
- *
- **/
-static void
-fm_directory_view_activate_file (FMDirectoryView *view,
- NautilusFile *file,
- NautilusWindowOpenMode mode,
- NautilusWindowOpenFlags flags)
-{
- GList *files;
-
- g_return_if_fail (FM_IS_DIRECTORY_VIEW (view));
- g_return_if_fail (NAUTILUS_IS_FILE (file));
-
- files = g_list_prepend (NULL, file);
- fm_directory_view_activate_files (view, files, mode, flags);
- g_list_free (files);
-}
-
static void
file_changed_callback (NautilusFile *file, gpointer callback_data)
{
diff --git a/src/file-manager/fm-directory-view.h b/src/file-manager/fm-directory-view.h
index a37615511..b0d8932ff 100644
--- a/src/file-manager/fm-directory-view.h
+++ b/src/file-manager/fm-directory-view.h
@@ -40,6 +40,7 @@
#include <eel/eel-string-list.h>
#include <libnautilus-private/nautilus-view.h>
#include <libnautilus-private/nautilus-window-info.h>
+#include <gio/gappinfo.h>
typedef struct FMDirectoryView FMDirectoryView;
typedef struct FMDirectoryViewClass FMDirectoryViewClass;
@@ -372,9 +373,13 @@ gboolean fm_directory_view_get_loading (FMDirect
/* Hooks for subclasses to call. These are normally called only by
* FMDirectoryView and its subclasses
*/
-void fm_directory_view_activate_files (FMDirectoryView *view,
- GList *files,
- NautilusWindowOpenMode mode,
+void fm_directory_view_activate_files (FMDirectoryView *view,
+ GList *files,
+ NautilusWindowOpenMode mode,
+ NautilusWindowOpenFlags flags);
+void fm_directory_view_activate_file (FMDirectoryView *view,
+ NautilusFile *file,
+ NautilusWindowOpenMode mode,
NautilusWindowOpenFlags flags);
void fm_directory_view_start_batching_selection_changes (FMDirectoryView *view);
void fm_directory_view_stop_batching_selection_changes (FMDirectoryView *view);