[nautilus/wip/razvan/automatic-decompression: 21/21] general: add preference for automatic decompression of archives



commit c98fe640fde81f246c98258f085ec313e9a1f4c4
Author: Razvan Chitu <razvan ch95 gmail com>
Date:   Mon Jul 25 09:20:39 2016 +0300

    general: add preference for automatic decompression of archives
    
    With the extract operation being handled internally, compressed files can be
    automatically extracted instead of being opened in file-roller. In order to
    implement this, make extraction the default action for activating selected
    archives.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=768646

 data/org.gnome.nautilus.gschema.xml             |    5 +
 src/nautilus-files-view.c                       |   30 +++++-
 src/nautilus-global-preferences.h               |    3 +
 src/nautilus-mime-actions.c                     |  114 ++++++++++++++++++++++-
 src/nautilus-mime-actions.h                     |    3 +
 src/nautilus-places-view.c                      |    1 +
 src/nautilus-preferences-window.c               |    5 +
 src/resources/ui/nautilus-preferences-window.ui |   46 +++++++++
 8 files changed, 200 insertions(+), 7 deletions(-)
---
diff --git a/data/org.gnome.nautilus.gschema.xml b/data/org.gnome.nautilus.gschema.xml
index 4be43d2..4128180 100644
--- a/data/org.gnome.nautilus.gschema.xml
+++ b/data/org.gnome.nautilus.gschema.xml
@@ -103,6 +103,11 @@
       <summary>Whether to ask for confirmation when deleting files, or emptying the Trash</summary>
       <description>If set to true, then Nautilus will ask for confirmation when you attempt to delete files, 
or empty the Trash.</description>
     </key>
+    <key type="b" name="automatic-decompression">
+      <default>true</default>
+      <summary>Whether to extract compressed files instead of opening them</summary>
+      <description>If set to true, then Nautilus will automatically extract compressed files instead of 
opening them in another application</description>
+    </key>
     <key name="show-directory-item-counts" enum="org.gnome.nautilus.SpeedTradeoff">
       <aliases><alias value='local_only' target='local-only'/></aliases>
       <default>'local-only'</default>
diff --git a/src/nautilus-files-view.c b/src/nautilus-files-view.c
index 9505c85..d2e7697 100644
--- a/src/nautilus-files-view.c
+++ b/src/nautilus-files-view.c
@@ -1129,6 +1129,7 @@ nautilus_files_view_activate_files (NautilusFilesView       *view,
         path = get_view_directory (view);
         nautilus_mime_activate_files (nautilus_files_view_get_containing_window (view),
                                       view->details->slot,
+                                      nautilus_files_view_get_directory_as_file (view),
                                       files,
                                       path,
                                       flags,
@@ -1147,6 +1148,7 @@ nautilus_files_view_activate_file (NautilusFilesView       *view,
         path = get_view_directory (view);
         nautilus_mime_activate_file (nautilus_files_view_get_containing_window (view),
                                      view->details->slot,
+                                     nautilus_files_view_get_directory_as_file (view),
                                      file,
                                      path,
                                      flags);
@@ -6472,6 +6474,7 @@ real_update_actions_state (NautilusFilesView *view)
         gboolean show_detect_media;
         gboolean settings_show_delete_permanently;
         gboolean settings_show_create_link;
+        gboolean settings_automatic_decompression;
         GDriveStartStopType start_stop_type;
 
         view_action_group = view->details->view_action_group;
@@ -6514,6 +6517,8 @@ real_update_actions_state (NautilusFilesView *view)
                                                                     
NAUTILUS_PREFERENCES_SHOW_DELETE_PERMANENTLY);
          settings_show_create_link = g_settings_get_boolean (nautilus_preferences,
                                                              NAUTILUS_PREFERENCES_SHOW_CREATE_LINK);
+        settings_automatic_decompression = g_settings_get_boolean (nautilus_preferences,
+                                                                   
NAUTILUS_PREFERENCES_AUTOMATIC_DECOMPRESSION);
 
         /* Right click actions */
         /* Selection menu actions */
@@ -6536,11 +6541,16 @@ real_update_actions_state (NautilusFilesView *view)
         action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
                                              "extract-here");
         g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
-                                     can_extract_files && can_extract_here);
+                                     can_extract_files &&
+                                     !settings_automatic_decompression &&
+                                     can_extract_here);
 
         action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
                                              "extract-to");
-        g_simple_action_set_enabled (G_SIMPLE_ACTION (action), can_extract_files);
+        g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
+                                     can_extract_files &&
+                                     (!settings_automatic_decompression ||
+                                      can_extract_here));
 
         action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
                                              "open-item-location");
@@ -6799,7 +6809,9 @@ update_selection_menu (NautilusFilesView *view)
         GList *selection, *l;
         NautilusFile *file;
         gint selection_count;
-        gboolean show_app, show_run;
+        gboolean show_app;
+        gboolean show_run;
+        gboolean show_extract;
         gboolean item_opens_in_view;
         gchar *item_label;
         GAppInfo *app;
@@ -6837,11 +6849,15 @@ update_selection_menu (NautilusFilesView *view)
         g_free (item_label);
 
         /* Open With <App> menu item */
-        show_app = show_run = 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;
 
-                file = NAUTILUS_FILE (selection->data);
+                file = NAUTILUS_FILE (l->data);
+
+                if (!nautilus_mime_file_extracts (file)) {
+                        show_extract = FALSE;
+                }
 
                 if (!nautilus_mime_file_opens_in_external_app (file)) {
                         show_app = FALSE;
@@ -6881,6 +6897,10 @@ update_selection_menu (NautilusFilesView *view)
                 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) ?
+                             g_strdup (_("Extract Here")) :
+                             g_strdup (_("Extract to…"));
         } else {
                 item_label = g_strdup (_("Open"));
         }
diff --git a/src/nautilus-global-preferences.h b/src/nautilus-global-preferences.h
index ef1f8aa..bd665e3 100644
--- a/src/nautilus-global-preferences.h
+++ b/src/nautilus-global-preferences.h
@@ -32,6 +32,9 @@ G_BEGIN_DECLS
 /* Trash options */
 #define NAUTILUS_PREFERENCES_CONFIRM_TRASH                     "confirm-trash"
 
+/* Automatic decompression */
+#define NAUTILUS_PREFERENCES_AUTOMATIC_DECOMPRESSION            "automatic-decompression"
+
 /* Display  */
 #define NAUTILUS_PREFERENCES_SHOW_HIDDEN_FILES                 "show-hidden"
 
diff --git a/src/nautilus-mime-actions.c b/src/nautilus-mime-actions.c
index e196dce..c5e9c61 100644
--- a/src/nautilus-mime-actions.c
+++ b/src/nautilus-mime-actions.c
@@ -43,6 +43,7 @@
 #include "nautilus-program-choosing.h"
 #include "nautilus-global-preferences.h"
 #include "nautilus-signaller.h"
+#include "nautilus-application.h"
 
 #define DEBUG_FLAG NAUTILUS_DEBUG_MIME
 #include "nautilus-debug.h"
@@ -54,6 +55,7 @@ typedef enum {
        ACTIVATION_ACTION_LAUNCH_IN_TERMINAL,
        ACTIVATION_ACTION_OPEN_IN_VIEW,
        ACTIVATION_ACTION_OPEN_IN_APPLICATION,
+        ACTIVATION_ACTION_EXTRACT,
        ACTIVATION_ACTION_DO_NOTHING,
 } ActivationAction;
 
@@ -71,6 +73,7 @@ typedef struct {
        NautilusWindowSlot *slot;
        gpointer window;
        GtkWindow *parent_window;
+        NautilusFile *parent_directory;
        GCancellable *cancellable;
        GList *locations;
        GList *mountables;
@@ -677,6 +680,13 @@ get_activation_action (NautilusFile *file)
 {
        ActivationAction action;
        char *activation_uri;
+        gboolean can_extract;
+        can_extract =  g_settings_get_boolean (nautilus_preferences,
+                                               NAUTILUS_PREFERENCES_AUTOMATIC_DECOMPRESSION);
+
+        if (can_extract && nautilus_file_is_archive (file)) {
+                return ACTIVATION_ACTION_EXTRACT;
+        }
 
        if (nautilus_file_is_nautilus_link (file)) {
                return ACTIVATION_ACTION_LAUNCH_DESKTOP_FILE;
@@ -690,7 +700,7 @@ get_activation_action (NautilusFile *file)
        action = ACTIVATION_ACTION_DO_NOTHING;
        if (nautilus_file_is_launchable (file)) {
                char *executable_path;
-               
+
                action = ACTIVATION_ACTION_LAUNCH;
                
                executable_path = g_filename_from_uri (activation_uri, NULL, NULL);
@@ -715,6 +725,12 @@ get_activation_action (NautilusFile *file)
 }
 
 gboolean
+nautilus_mime_file_extracts (NautilusFile *file)
+{
+        return get_activation_action (file) == ACTIVATION_ACTION_EXTRACT;
+}
+
+gboolean
 nautilus_mime_file_launches (NautilusFile *file)
 {
        ActivationAction activation_action;
@@ -871,6 +887,9 @@ activation_parameters_free (ActivateParameters *parameters)
        if (parameters->parent_window) {
                g_object_remove_weak_pointer (G_OBJECT (parameters->parent_window), (gpointer 
*)&parameters->parent_window);
        }
+        if (parameters->parent_directory) {
+                nautilus_file_unref (parameters->parent_directory);
+        }
        g_object_unref (parameters->cancellable);
        launch_location_list_free (parameters->locations);
        nautilus_file_list_free (parameters->mountables);
@@ -980,6 +999,7 @@ confirm_multiple_windows (GtkWindow *parent_window,
 typedef struct {
        NautilusWindowSlot *slot;
        GtkWindow *parent_window;
+        NautilusFile *parent_directory;
        NautilusFile *file;
        GList *files;
        NautilusWindowOpenFlags flags;
@@ -999,6 +1019,9 @@ activate_parameters_install_free (ActivateParametersInstall *parameters_install)
        if (parameters_install->parent_window) {
                g_object_remove_weak_pointer (G_OBJECT (parameters_install->parent_window), (gpointer 
*)&parameters_install->parent_window);
        }
+        if (parameters_install->parent_directory) {
+                nautilus_file_unref (parameters_install->parent_directory);
+        }
 
        if (parameters_install->proxy != NULL) {
                g_object_unref (parameters_install->proxy);
@@ -1195,6 +1218,7 @@ search_for_application_dbus_call_notify_cb (GDBusProxy   *proxy,
        /* activate the file again */
        nautilus_mime_activate_files (parameters_install->parent_window,
                                      parameters_install->slot,
+                                      parameters_install->parent_directory,
                                      parameters_install->files,
                                      parameters_install->activation_directory,
                                      parameters_install->flags,
@@ -1337,6 +1361,9 @@ application_unhandled_uri (ActivateParameters *parameters, char *uri)
                parameters_install->parent_window = parameters->parent_window;
                g_object_add_weak_pointer (G_OBJECT (parameters_install->parent_window), (gpointer 
*)&parameters_install->parent_window);
        }
+        if (parameters->parent_directory) {
+                parameters_install->parent_directory = nautilus_file_ref (parameters->parent_directory);
+        }
        parameters_install->activation_directory = g_strdup (parameters->activation_directory);
        parameters_install->file = file;
        parameters_install->files = get_file_list_for_launch_locations (parameters->locations);
@@ -1506,6 +1533,7 @@ activate_files (ActivateParameters *parameters)
        GList *open_in_app_uris;
        GList *open_in_app_parameters;
        GList *unhandled_open_in_app_uris;
+        GList *extract_files;
        ApplicationLaunchParameters *one_parameters;
        GList *open_in_view_files;
        GList *l;
@@ -1528,6 +1556,7 @@ activate_files (ActivateParameters *parameters)
        launch_in_terminal_files = NULL;
        open_in_app_uris = NULL;
        open_in_view_files = NULL;
+        extract_files = NULL;
 
        for (l = parameters->locations; l != NULL; l = l->next) {
                location = l->data;
@@ -1560,6 +1589,9 @@ activate_files (ActivateParameters *parameters)
                case ACTIVATION_ACTION_OPEN_IN_VIEW :
                        open_in_view_files = g_list_prepend (open_in_view_files, file);
                        break;
+                case ACTIVATION_ACTION_EXTRACT :
+                        extract_files = g_list_prepend (extract_files, file);
+                        break;
                case ACTIVATION_ACTION_OPEN_IN_APPLICATION :
                        open_in_app_uris = g_list_prepend (open_in_app_uris, location->uri);
                        break;
@@ -1674,6 +1706,73 @@ activate_files (ActivateParameters *parameters)
                }
        }
 
+        extract_files = g_list_reverse (extract_files);
+        if (extract_files) {
+                g_autoptr (GFile) output = NULL;
+                gboolean directory_supports_extracting;
+
+                directory_supports_extracting =
+                        nautilus_file_can_write (parameters->parent_directory) &&
+                        !nautilus_file_is_in_trash (parameters->parent_directory) &&
+                        !nautilus_file_is_in_search (parameters->parent_directory) &&
+                        !nautilus_file_is_in_recent (parameters->parent_directory) &&
+                        !nautilus_file_is_remote (parameters->parent_directory);
+
+                if (directory_supports_extracting) {
+                        output = nautilus_file_get_location (parameters->parent_directory); 
+                } else {
+                        GtkWidget *dialog;
+                        gint response;
+
+                        pause_activation_timed_cancel (parameters);
+
+                        dialog = gtk_file_chooser_dialog_new (_("Select Extract Destination"),
+                                                              GTK_WINDOW (parameters->parent_window),
+                                                              GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+                                                              _("_Cancel"), GTK_RESPONSE_CANCEL,
+                                                              _("_Select"), GTK_RESPONSE_OK,
+                                                              NULL);
+                        gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (dialog), FALSE);
+
+                        gtk_dialog_set_default_response (GTK_DIALOG (dialog),
+                                                         GTK_RESPONSE_OK);
+
+                        gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
+                        gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
+
+                        if (parameters->parent_directory) {
+                                g_autofree char *uri;
+
+                                uri = nautilus_file_get_uri (parameters->parent_directory);
+                                gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dialog), uri);    
 
+                        }
+
+                        response = gtk_dialog_run (GTK_DIALOG (dialog));
+                        if (response == GTK_RESPONSE_OK) {
+                                output = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
+                        }
+
+                        gtk_widget_destroy (dialog);
+
+                        unpause_activation_timed_cancel (parameters);
+                }
+
+                if (output != NULL) {
+                        for (l = extract_files; l != NULL; l = l->next) {
+                                file = NAUTILUS_FILE (l->data);
+                                g_autoptr (GFile) source;
+
+                                source = nautilus_file_get_location (file);
+
+                                nautilus_file_operations_extract (source,
+                                                                  output,
+                                                                  parameters->parent_window,
+                                                                  NULL,
+                                                                  NULL);
+                        }                        
+                }
+        }
+
        open_in_app_parameters = NULL;
        unhandled_open_in_app_uris = NULL;
 
@@ -2171,6 +2270,7 @@ activation_start_mountables (ActivateParameters *parameters)
 void
 nautilus_mime_activate_files (GtkWindow *parent_window,
                              NautilusWindowSlot *slot,
+                              NautilusFile *parent_directory,
                              GList *files,
                              const char *launch_directory,
                              NautilusWindowOpenFlags flags,
@@ -2196,6 +2296,9 @@ nautilus_mime_activate_files (GtkWindow *parent_window,
                parameters->parent_window = parent_window;
                g_object_add_weak_pointer (G_OBJECT (parameters->parent_window), (gpointer 
*)&parameters->parent_window);
        }
+        if (parent_directory) {
+                parameters->parent_directory = nautilus_file_ref (parent_directory);
+        }
        parameters->cancellable = g_cancellable_new ();
        parameters->activation_directory = g_strdup (launch_directory);
        parameters->locations = launch_locations_from_file_list (files);
@@ -2254,6 +2357,7 @@ nautilus_mime_activate_files (GtkWindow *parent_window,
 void
 nautilus_mime_activate_file (GtkWindow *parent_window,
                             NautilusWindowSlot *slot,
+                             NautilusFile *parent_directory,
                             NautilusFile *file,
                             const char *launch_directory,
                             NautilusWindowOpenFlags flags)
@@ -2263,7 +2367,13 @@ 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, launch_directory, flags, FALSE);
+       nautilus_mime_activate_files (parent_window,
+                                      slot,
+                                      parent_directory,
+                                      files,
+                                      launch_directory,
+                                      flags,
+                                      FALSE);
        g_list_free (files);
 }
 
diff --git a/src/nautilus-mime-actions.h b/src/nautilus-mime-actions.h
index f96ca66..e6c8b9f 100644
--- a/src/nautilus-mime-actions.h
+++ b/src/nautilus-mime-actions.h
@@ -38,15 +38,18 @@ GList *                nautilus_mime_get_applications_for_file            (Nauti
 GAppInfo *             nautilus_mime_get_default_application_for_files    (GList                   *files);
 
 gboolean               nautilus_mime_file_opens_in_external_app           (NautilusFile            *file);
+gboolean               nautilus_mime_file_extracts                        (NautilusFile            *file);
 gboolean               nautilus_mime_file_launches                        (NautilusFile            *file);
 void                   nautilus_mime_activate_files                       (GtkWindow               
*parent_window,
                                                                           NautilusWindowSlot      *slot,
+                                                                           NautilusFile            
*parent_directory,
                                                                           GList                   *files,
                                                                           const char              
*launch_directory,
                                                                           NautilusWindowOpenFlags  flags,
                                                                           gboolean                 
user_confirmation);
 void                   nautilus_mime_activate_file                        (GtkWindow               
*parent_window,
                                                                           NautilusWindowSlot      *slot_info,
+                                                                           NautilusFile            
*parent_directory,
                                                                           NautilusFile            *file,
                                                                           const char              
*launch_directory,
                                                                           NautilusWindowOpenFlags  flags);
diff --git a/src/nautilus-places-view.c b/src/nautilus-places-view.c
index 4b79da8..50f1f80 100644
--- a/src/nautilus-places-view.c
+++ b/src/nautilus-places-view.c
@@ -92,6 +92,7 @@ open_location_cb (NautilusPlacesView *view,
                 nautilus_mime_activate_file (GTK_WINDOW (window),
                                              NAUTILUS_WINDOW_SLOT (slot),
                                              file,
+                                             file,
                                              path,
                                              flags);
                 nautilus_file_unref (file);
diff --git a/src/nautilus-preferences-window.c b/src/nautilus-preferences-window.c
index 5fe783b..875b233 100644
--- a/src/nautilus-preferences-window.c
+++ b/src/nautilus-preferences-window.c
@@ -58,6 +58,8 @@
   "use_tree_view_checkbutton"
 #define NAUTILUS_PREFERENCES_DIALOG_TRASH_CONFIRM_WIDGET                       \
   "trash_confirm_checkbutton"
+#define NAUTILUS_PREFERENCES_DIALOG_AUTOMATIC_DECOMPRESSION_WIDGET             \
+  "automatic_decompression_checkbutton"
 
 /* int enums */
 #define NAUTILUS_PREFERENCES_DIALOG_THUMBNAIL_LIMIT_WIDGET                     \
@@ -432,6 +434,9 @@ static void nautilus_preferences_window_setup(GtkBuilder *builder,
   bind_builder_bool(builder, nautilus_preferences,
                     NAUTILUS_PREFERENCES_DIALOG_TRASH_CONFIRM_WIDGET,
                     NAUTILUS_PREFERENCES_CONFIRM_TRASH);
+  bind_builder_bool (builder, nautilus_preferences,
+                     NAUTILUS_PREFERENCES_DIALOG_AUTOMATIC_DECOMPRESSION_WIDGET,
+                     NAUTILUS_PREFERENCES_AUTOMATIC_DECOMPRESSION);
   bind_builder_bool(builder, nautilus_list_view_preferences,
                     NAUTILUS_PREFERENCES_DIALOG_LIST_VIEW_USE_TREE_WIDGET,
                     NAUTILUS_PREFERENCES_LIST_VIEW_USE_TREE);
diff --git a/src/resources/ui/nautilus-preferences-window.ui b/src/resources/ui/nautilus-preferences-window.ui
index 17c32b2..90ae4d7 100644
--- a/src/resources/ui/nautilus-preferences-window.ui
+++ b/src/resources/ui/nautilus-preferences-window.ui
@@ -756,6 +756,52 @@ More information will appear when zooming closer.</property>
                 <property name="position">3</property>
               </packing>
             </child>
+            <child>
+              <object class="GtkBox" id="vbox10">
+                <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="label17">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">Compressed Files</property>
+                    <property name="xalign">0</property>
+                    <attributes>
+                      <attribute name="weight" value="bold"/>
+                    </attributes>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkCheckButton" id="automatic_decompression_checkbutton">
+                    <property name="label" translatable="yes">E_xtract compressed files instead of opening 
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>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="position">2</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">4</property>
+              </packing>
+            </child>
           </object>
           <packing>
             <property name="position">1</property>


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