[nautilus/allow-launching-binaries: 4/4] general: Revert to allow running binaries and scripts



commit ac886102c23c8eae4759a240193473e1b00f7352
Author: Carlos Soriano <csoriano redhat com>
Date:   Fri May 18 17:04:04 2018 +0200

    general: Revert to allow running binaries and scripts
    
    Recently we removed the ability to launch binaries and scripts in
    commit 3a22ed5b8e3bb.
    
    A few cases appeared that we need to support, specially for enterprise
    and content creators. Specifically, cases similar to https://gitlab.gnome.org/GNOME/nautilus/issues/434
    
    This also shows that is hard to predict cases like these, as some
    complex setups might be needed for specific workflows.
    
    This commits allow to run binaries and scripts as before, and further
    investigation in these cases need to be done if we ever want to tweak
    the workflow of running binaries.
    
    More discussion about improving binaries/script handling is being
    proposed and discussed in https://gitlab.gnome.org/GNOME/nautilus/issues/443

 data/org.gnome.nautilus.gschema.xml             |  11 +
 src/nautilus-file.c                             |  22 ++
 src/nautilus-file.h                             |   1 +
 src/nautilus-files-view.c                       |  25 ++-
 src/nautilus-global-preferences.h               |  12 +-
 src/nautilus-mime-actions.c                     | 255 +++++++++++++++++++++++-
 src/nautilus-mime-actions.h                     |  18 +-
 src/nautilus-places-view.c                      |   3 +
 src/nautilus-preferences-window.c               |  16 ++
 src/resources/ui/nautilus-preferences-window.ui |  94 +++++++++
 10 files changed, 436 insertions(+), 21 deletions(-)
---
diff --git a/data/org.gnome.nautilus.gschema.xml b/data/org.gnome.nautilus.gschema.xml
index 4cdce260e..3dc5f7deb 100644
--- a/data/org.gnome.nautilus.gschema.xml
+++ b/data/org.gnome.nautilus.gschema.xml
@@ -11,6 +11,12 @@
     <value value="1" nick="double"/>
   </enum>
 
+  <enum id="org.gnome.nautilus.ActivationChoice">
+    <value value="0" nick="launch"/>
+    <value value="1" nick="display"/>
+    <value value="2" nick="ask"/>
+  </enum>
+
   <enum id="org.gnome.nautilus.FolderView">
     <value value="0" nick="icon-view"/>
     <value value="1" nick="list-view"/>
@@ -115,6 +121,11 @@
       <summary>Type of click used to launch/open files</summary>
       <description>Possible values are “single” to launch files on a single click, or “double” to launch 
them on a double click.</description>
     </key>
+    <key name="executable-text-activation" enum="org.gnome.nautilus.ActivationChoice">
+      <default>'display'</default>
+      <summary>What to do with executable text files when activated</summary>
+      <description>What to do with executable text files when they are activated (single or double clicked). 
Possible values are “launch” to launch them as programs, “ask” to ask what to do via a dialog, and “display” 
to display them as text files.</description>
+    </key>
     <key type="b" name="install-mime-activation">
       <default>true</default>
       <summary>Show the package installer for unknown MIME types</summary>
diff --git a/src/nautilus-file.c b/src/nautilus-file.c
index 08ffc7291..e85c09694 100644
--- a/src/nautilus-file.c
+++ b/src/nautilus-file.c
@@ -8161,6 +8161,28 @@ nautilus_file_get_file_info_error (NautilusFile *file)
     return file->details->get_info_error;
 }
 
+/**
+ * nautilus_file_contains_text
+ *
+ * Check if this file contains text.
+ * This is private and is used to decide whether or not to read the top left text.
+ * @file: NautilusFile representing the file in question.
+ *
+ * Returns: TRUE if @file has a text MIME type.
+ *
+ **/
+gboolean
+nautilus_file_contains_text (NautilusFile *file)
+{
+    if (file == NULL)
+    {
+        return FALSE;
+    }
+
+    /* All text files inherit from text/plain */
+    return nautilus_file_is_mime_type (file, "text/plain");
+}
+
 /**
  * nautilus_file_is_executable
  *
diff --git a/src/nautilus-file.h b/src/nautilus-file.h
index 3d803214f..0eb5b3a96 100644
--- a/src/nautilus-file.h
+++ b/src/nautilus-file.h
@@ -171,6 +171,7 @@ void                    nautilus_file_invalidate_attributes             (Nautilu
 void                    nautilus_file_invalidate_all_attributes         (NautilusFile                   
*file);
 
 /* Basic attributes for file objects. */
+gboolean                nautilus_file_contains_text                     (NautilusFile                   
*file);
 char *                  nautilus_file_get_display_name                  (NautilusFile                   
*file);
 char *                  nautilus_file_get_edit_name                     (NautilusFile                   
*file);
 char *                  nautilus_file_get_name                          (NautilusFile                   
*file);
diff --git a/src/nautilus-files-view.c b/src/nautilus-files-view.c
index 76ccfeb8d..728e4fa49 100644
--- a/src/nautilus-files-view.c
+++ b/src/nautilus-files-view.c
@@ -64,6 +64,7 @@
 #include "nautilus-file-private.h"
 #include "nautilus-file-undo-manager.h"
 #include "nautilus-file-utilities.h"
+#include "nautilus-file.h"
 #include "nautilus-floating-bar.h"
 #include "nautilus-global-preferences.h"
 #include "nautilus-icon-info.h"
@@ -1194,6 +1195,7 @@ nautilus_files_view_activate_files (NautilusFilesView       *view,
     NautilusFilesViewPrivate *priv;
     GList *files_to_extract;
     GList *files_to_activate;
+    char *path;
 
     if (files == NULL)
     {
@@ -1225,12 +1227,15 @@ nautilus_files_view_activate_files (NautilusFilesView       *view,
         extract_files_to_chosen_location (view, files_to_extract);
     }
 
+    path = get_view_directory (view);
     nautilus_mime_activate_files (nautilus_files_view_get_containing_window (view),
                                   priv->slot,
                                   files_to_activate,
+                                  path,
                                   flags,
                                   confirm_multiple);
 
+    g_free (path);
     g_list_free (files_to_extract);
     g_list_free (files_to_activate);
 }
@@ -7716,6 +7721,7 @@ update_selection_menu (NautilusFilesView *view)
     GList *l;
     gint selection_count;
     gboolean show_app;
+    gboolean show_run;
     gboolean show_extract;
     gboolean item_opens_in_view;
     gchar *item_label;
@@ -7756,7 +7762,7 @@ update_selection_menu (NautilusFilesView *view)
     g_free (item_label);
 
     /* Open With <App> menu item */
-    show_extract = show_app = item_opens_in_view = selection_count != 0;
+    show_extract = show_app = show_run = item_opens_in_view = selection_count != 0;
     for (l = selection; l != NULL; l = l->next)
     {
         NautilusFile *file;
@@ -7773,12 +7779,17 @@ update_selection_menu (NautilusFilesView *view)
             show_app = FALSE;
         }
 
+        if (!nautilus_mime_file_launches (file))
+        {
+            show_run = FALSE;
+        }
+
         if (!nautilus_file_opens_in_view (file))
         {
             item_opens_in_view = FALSE;
         }
 
-        if (!show_extract && !show_app && !item_opens_in_view)
+        if (!show_extract && !show_app && !show_run && !item_opens_in_view)
         {
             break;
         }
@@ -7807,6 +7818,10 @@ update_selection_menu (NautilusFilesView *view)
         g_free (escaped_app);
         g_object_unref (app);
     }
+    else if (show_run)
+    {
+        item_label = g_strdup (_("Run"));
+    }
     else if (show_extract)
     {
         item_label = nautilus_files_view_supports_extract_here (view) ?
@@ -8767,9 +8782,9 @@ nautilus_files_view_move_copy_items (NautilusFilesView *view,
 
     target_file = nautilus_file_get_existing_by_uri (target_uri);
     if (copy_action == GDK_ACTION_COPY &&
-        nautilus_is_file_roller_installed () &&
-        target_file != NULL &&
-        nautilus_file_is_archive (target_file))
+             nautilus_is_file_roller_installed () &&
+             target_file != NULL &&
+             nautilus_file_is_archive (target_file))
     {
         char *command, *quoted_uri, *tmp;
         const GList *l;
diff --git a/src/nautilus-global-preferences.h b/src/nautilus-global-preferences.h
index 439f20f1f..0ccc1937b 100644
--- a/src/nautilus-global-preferences.h
+++ b/src/nautilus-global-preferences.h
@@ -51,6 +51,9 @@ typedef enum
 /* Drag and drop preferences */
 #define NAUTILUS_PREFERENCES_OPEN_FOLDER_ON_DND_HOVER          "open-folder-on-dnd-hover"
 
+/* Activating executable text files */
+#define NAUTILUS_PREFERENCES_EXECUTABLE_TEXT_ACTIVATION                "executable-text-activation"
+
 /* Installing new packages when unknown mime type activated */
 #define NAUTILUS_PREFERENCES_INSTALL_MIME_ACTIVATION           "install-mime-activation"
 
@@ -107,6 +110,13 @@ enum
        NAUTILUS_CLICK_POLICY_DOUBLE
 };
 
+enum
+{
+       NAUTILUS_EXECUTABLE_TEXT_LAUNCH,
+       NAUTILUS_EXECUTABLE_TEXT_DISPLAY,
+       NAUTILUS_EXECUTABLE_TEXT_ASK
+};
+
 typedef enum
 {
        NAUTILUS_SPEED_TRADEOFF_ALWAYS,
@@ -158,4 +168,4 @@ extern GSettings *gnome_lockdown_preferences;
 extern GSettings *gnome_background_preferences;
 extern GSettings *gnome_interface_preferences;
 
-G_END_DECLS
+G_END_DECLS
\ No newline at end of file
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
 
@@ -589,6 +596,115 @@ out:
     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 = 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)
 {
@@ -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);
 
@@ -634,6 +772,16 @@ nautilus_mime_file_extracts (NautilusFile *file)
     return get_activation_action (file) == ACTIVATION_ACTION_EXTRACT;
 }
 
+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)
 {
@@ -689,6 +837,7 @@ activation_parameters_free (ActivateParameters *parameters)
     nautilus_file_list_free (parameters->mountables);
     nautilus_file_list_free (parameters->start_mountables);
     nautilus_file_list_free (parameters->not_mounted);
+    g_free (parameters->activation_directory);
     g_free (parameters->timed_wait_prompt);
     g_assert (parameters->files_handle == NULL);
     g_free (parameters);
@@ -816,6 +965,7 @@ typedef struct
     NautilusFile *file;
     GList *files;
     NautilusWindowOpenFlags flags;
+    char *activation_directory;
     gboolean user_confirmation;
     char *uri;
     GDBusProxy *proxy;
@@ -841,6 +991,7 @@ activate_parameters_install_free (ActivateParametersInstall *parameters_install)
 
     nautilus_file_unref (parameters_install->file);
     nautilus_file_list_free (parameters_install->files);
+    g_free (parameters_install->activation_directory);
     g_free (parameters_install->uri);
     g_free (parameters_install);
 }
@@ -1044,6 +1195,7 @@ search_for_application_dbus_call_notify_cb (GDBusProxy   *proxy,
     nautilus_mime_activate_files (parameters_install->parent_window,
                                   parameters_install->slot,
                                   parameters_install->files,
+                                  parameters_install->activation_directory,
                                   parameters_install->flags,
                                   parameters_install->user_confirmation);
 
@@ -1192,6 +1344,7 @@ application_unhandled_uri (ActivateParameters *parameters,
         parameters_install->parent_window = parameters->parent_window;
         g_object_add_weak_pointer (G_OBJECT (parameters_install->parent_window), (gpointer *) 
&parameters_install->parent_window);
     }
+    parameters_install->activation_directory = g_strdup (parameters->activation_directory);
     parameters_install->file = file;
     parameters_install->files = get_file_list_for_launch_locations (parameters->locations);
     parameters_install->flags = parameters->flags;
@@ -1298,12 +1451,17 @@ activate_files (ActivateParameters *parameters)
     NautilusWindowOpenFlags flags;
     int count;
     g_autofree char *old_working_dir = NULL;
+    GdkScreen *screen;
     gboolean closed_window;
+    g_autoptr (GQueue) launch_files = NULL;
+    g_autoptr (GQueue) launch_in_terminal_files = NULL;
     g_autoptr (GQueue) open_in_app_uris = NULL;
     g_autoptr (GQueue) open_in_view_files = NULL;
     GList *l;
     ActivationAction action;
 
+    launch_files = g_queue_new ();
+    launch_in_terminal_files = g_queue_new ();
     open_in_view_files = g_queue_new ();
     open_in_app_uris = g_queue_new ();
 
@@ -1320,8 +1478,30 @@ activate_files (ActivateParameters *parameters)
         }
 
         action = get_activation_action (file);
+        if (action == ACTIVATION_ACTION_ASK)
+        {
+            /* Special case for executable text files, since it might be
+             * dangerous & unexpected to launch these.
+             */
+            pause_activation_timed_cancel (parameters);
+            action = get_executable_text_file_action (parameters->parent_window, file);
+            unpause_activation_timed_cancel (parameters);
+        }
+
         switch (action)
         {
+            case ACTIVATION_ACTION_LAUNCH:
+            {
+                g_queue_push_tail (launch_files, file);
+            }
+            break;
+
+            case ACTIVATION_ACTION_LAUNCH_IN_TERMINAL:
+            {
+                g_queue_push_tail (launch_in_terminal_files, file);
+            }
+            break;
+
             case ACTIVATION_ACTION_OPEN_IN_VIEW:
             {
                 g_queue_push_tail (open_in_view_files, file);
@@ -1346,7 +1526,7 @@ activate_files (ActivateParameters *parameters)
             }
             break;
 
-            default:
+            case ACTIVATION_ACTION_ASK:
             {
                 g_assert_not_reached ();
             }
@@ -1354,6 +1534,54 @@ activate_files (ActivateParameters *parameters)
         }
     }
 
+    if (parameters->activation_directory &&
+        (!g_queue_is_empty (launch_files) ||
+         !g_queue_is_empty (launch_in_terminal_files)))
+    {
+        old_working_dir = g_get_current_dir ();
+        g_chdir (parameters->activation_directory);
+    }
+
+    screen = gtk_widget_get_screen (GTK_WIDGET (parameters->parent_window));
+    for (l = g_queue_peek_head_link (launch_files); l != NULL; l = l->next)
+    {
+        g_autofree char *uri = NULL;
+        g_autofree char *executable_path = NULL;
+        g_autofree char *quoted_path = NULL;
+
+        file = NAUTILUS_FILE (l->data);
+
+        uri = nautilus_file_get_activation_uri (file);
+        executable_path = g_filename_from_uri (uri, NULL, NULL);
+        quoted_path = g_shell_quote (executable_path);
+
+        DEBUG ("Launching file path %s", quoted_path);
+
+        nautilus_launch_application_from_command (screen, quoted_path, FALSE, NULL);
+    }
+
+    for (l = g_queue_peek_head_link (launch_in_terminal_files); l != NULL; l = l->next)
+    {
+        g_autofree char *uri = NULL;
+        g_autofree char *executable_path = NULL;
+        g_autofree char *quoted_path = NULL;
+
+        file = NAUTILUS_FILE (l->data);
+
+        uri = nautilus_file_get_activation_uri (file);
+        executable_path = g_filename_from_uri (uri, NULL, NULL);
+        quoted_path = g_shell_quote (executable_path);
+
+        DEBUG ("Launching in terminal file quoted path %s", quoted_path);
+
+        nautilus_launch_application_from_command (screen, quoted_path, TRUE, NULL);
+    }
+
+    if (old_working_dir != NULL)
+    {
+        g_chdir (old_working_dir);
+    }
+
     count = g_queue_get_length (open_in_view_files);
 
     flags = parameters->flags;
@@ -1522,7 +1750,8 @@ activation_mount_not_mounted_callback (GObject      *source_object,
                                                  file);
             if (loc)
             {
-                parameters->locations = g_list_remove (parameters->locations, loc);
+                parameters->locations =
+                    g_list_remove (parameters->locations, loc);
                 launch_location_free (loc);
             }
         }
@@ -1941,10 +2170,20 @@ activation_start_mountables (ActivateParameters *parameters)
     }
 }
 
+/**
+ * nautilus_mime_activate_files:
+ *
+ * Activate a list of files. Each one might launch with an application or
+ * with a component. This is normally called only by subclasses.
+ * @view: FMDirectoryView in question.
+ * @files: A GList of NautilusFiles to activate.
+ *
+ **/
 void
 nautilus_mime_activate_files (GtkWindow               *parent_window,
                               NautilusWindowSlot      *slot,
                               GList                   *files,
+                              const char              *launch_directory,
                               NautilusWindowOpenFlags  flags,
                               gboolean                 user_confirmation)
 {
@@ -1971,6 +2210,7 @@ nautilus_mime_activate_files (GtkWindow               *parent_window,
         g_object_add_weak_pointer (G_OBJECT (parameters->parent_window), (gpointer *) 
&parameters->parent_window);
     }
     parameters->cancellable = g_cancellable_new ();
+    parameters->activation_directory = g_strdup (launch_directory);
     parameters->locations = launch_locations_from_file_list (files);
     parameters->flags = flags;
     parameters->user_confirmation = user_confirmation;
@@ -2040,6 +2280,7 @@ void
 nautilus_mime_activate_file (GtkWindow               *parent_window,
                              NautilusWindowSlot      *slot,
                              NautilusFile            *file,
+                             const char              *launch_directory,
                              NautilusWindowOpenFlags  flags)
 {
     GList *files;
@@ -2047,7 +2288,7 @@ nautilus_mime_activate_file (GtkWindow               *parent_window,
     g_return_if_fail (NAUTILUS_IS_FILE (file));
 
     files = g_list_prepend (NULL, file);
-    nautilus_mime_activate_files (parent_window, slot, files, flags, FALSE);
+    nautilus_mime_activate_files (parent_window, slot, files, launch_directory, flags, FALSE);
     g_list_free (files);
 }
 
diff --git a/src/nautilus-mime-actions.h b/src/nautilus-mime-actions.h
index 1725b8c1d..29be6b07c 100644
--- a/src/nautilus-mime-actions.h
+++ b/src/nautilus-mime-actions.h
@@ -39,14 +39,16 @@ gboolean               nautilus_mime_file_extracts                        (Nauti
 gboolean               nautilus_mime_file_opens_in_external_app           (NautilusFile            *file);
 gboolean               nautilus_mime_file_launches                        (NautilusFile            *file);
 void                   nautilus_mime_activate_files                       (GtkWindow               
*parent_window,
-                                                                           NautilusWindowSlot      *slot,
-                                                                           GList                   *files,
-                                                                           NautilusWindowOpenFlags  flags,
-                                                                           gboolean                 
user_confirmation);
+                                                                          NautilusWindowSlot      *slot,
+                                                                          GList                   *files,
+                                                                          const char              
*launch_directory,
+                                                                          NautilusWindowOpenFlags  flags,
+                                                                          gboolean                 
user_confirmation);
 void                   nautilus_mime_activate_file                        (GtkWindow               
*parent_window,
-                                                                           NautilusWindowSlot      
*slot_info,
-                                                                           NautilusFile            *file,
-                                                                           NautilusWindowOpenFlags  flags);
+                                                                          NautilusWindowSlot      *slot_info,
+                                                                          NautilusFile            *file,
+                                                                          const char              
*launch_directory,
+                                                                          NautilusWindowOpenFlags  flags);
 gint                   nautilus_mime_types_get_number_of_groups           (void);
 const gchar*           nautilus_mime_types_group_get_name                 (gint                     
group_index);
-GList*                 nautilus_mime_types_group_get_mimetypes            (gint                     
group_index);
+GList*                 nautilus_mime_types_group_get_mimetypes            (gint                     
group_index);
\ No newline at end of file
diff --git a/src/nautilus-places-view.c b/src/nautilus-places-view.c
index c1e8b397a..3611ecdc3 100644
--- a/src/nautilus-places-view.c
+++ b/src/nautilus-places-view.c
@@ -95,13 +95,16 @@ open_location_cb (NautilusPlacesView *view,
     {
         NautilusFile *file;
         GtkWidget *window;
+        char *path;
 
+        path = "other-locations:///";
         file = nautilus_file_get (location);
         window = gtk_widget_get_toplevel (GTK_WIDGET (view));
 
         nautilus_mime_activate_file (GTK_WINDOW (window),
                                      NAUTILUS_WINDOW_SLOT (slot),
                                      file,
+                                     path,
                                      flags);
         nautilus_file_unref (file);
     }
diff --git a/src/nautilus-preferences-window.c b/src/nautilus-preferences-window.c
index 75134bf7f..48861cfb4 100644
--- a/src/nautilus-preferences-window.c
+++ b/src/nautilus-preferences-window.c
@@ -79,6 +79,18 @@ static const char * const click_behavior_components[] =
 
 static const char * const click_behavior_values[] = {"single", "double", NULL};
 
+static const char * const executable_text_components[] =
+{
+    "scripts_execute_radiobutton", "scripts_view_radiobutton",
+    "scripts_confirm_radiobutton", NULL
+};
+
+static const char * const executable_text_values[] =
+{
+    "launch", "display", "ask",
+    NULL
+};
+
 static const char * const recursive_search_components[] =
 {
     "search_recursive_only_this_computer_radiobutton", "search_recursive_all_locations_radiobutton", 
"search_recursive_never_radiobutton", NULL
@@ -467,6 +479,10 @@ static void nautilus_preferences_window_setup(GtkBuilder *builder,
     bind_builder_radio (
         builder, nautilus_preferences, (const char **) click_behavior_components,
         NAUTILUS_PREFERENCES_CLICK_POLICY, (const char **) click_behavior_values);
+    bind_builder_radio (builder, nautilus_preferences,
+                        (const char **) executable_text_components,
+                        NAUTILUS_PREFERENCES_EXECUTABLE_TEXT_ACTIVATION,
+                        (const char **) executable_text_values);
     bind_builder_radio (builder, nautilus_preferences,
                         (const char **) recursive_search_components,
                         NAUTILUS_PREFERENCES_RECURSIVE_SEARCH,
diff --git a/src/resources/ui/nautilus-preferences-window.ui b/src/resources/ui/nautilus-preferences-window.ui
index 803d25a57..8cf07ff5f 100644
--- a/src/resources/ui/nautilus-preferences-window.ui
+++ b/src/resources/ui/nautilus-preferences-window.ui
@@ -593,6 +593,100 @@
                     <property name="position">1</property>
                   </packing>
                 </child>
+                <child>
+                  <object class="GtkBox" id="vbox7">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="orientation">vertical</property>
+                    <property name="spacing">6</property>
+                    <child>
+                      <object class="GtkLabel" id="label12">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">Executable Text Files</property>
+                        <property name="xalign">0</property>
+                        <attributes>
+                          <attribute name="weight" value="PANGO_WEIGHT_BOLD"/>
+                        </attributes>
+                        <accessibility>
+                          <relation type="label-for" target="vbox7"/>
+                        </accessibility>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkRadioButton" id="scripts_view_radiobutton">
+                        <property name="label" translatable="yes">_Display them</property>
+                        <property name="use_action_appearance">False</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">False</property>
+                        <property name="use_underline">True</property>
+                        <property name="xalign">0</property>
+                        <property name="draw_indicator">True</property>
+                        <property name="group">scripts_execute_radiobutton</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkRadioButton" id="scripts_execute_radiobutton">
+                        <property name="label" translatable="yes">_Run them</property>
+                        <property name="use_action_appearance">False</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">False</property>
+                        <property name="use_underline">True</property>
+                        <property name="xalign">0</property>
+                        <property name="draw_indicator">True</property>
+                        <property name="group">scripts_view_radiobutton</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">3</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkRadioButton" id="scripts_confirm_radiobutton">
+                        <property name="label" translatable="yes">_Ask what to do</property>
+                        <property name="use_action_appearance">False</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">False</property>
+                        <property name="use_underline">True</property>
+                        <property name="xalign">0</property>
+                        <property name="draw_indicator">True</property>
+                        <property name="group">scripts_execute_radiobutton</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">4</property>
+                      </packing>
+                    </child>
+                    <child internal-child="accessible">
+                      <object class="AtkObject" id="vbox7-atkobject">
+                        <property name="AtkObject::accessible-role">38</property>
+                      </object>
+                    </child>
+                    <accessibility>
+                      <relation type="labelled-by" target="label12"/>
+                    </accessibility>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">2</property>
+                  </packing>
+                </child>
                 <child>
                   <object class="GtkBox" id="vbox8">
                     <property name="visible">True</property>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]