[nautilus/wip/razvan/automatic-decompression: 13/14] files-view: add context menu actions for extracting files



commit fbc850f4ca9f4548b0d5fb3b99d99eddf953a6bc
Author: Razvan Chitu <razvan ch95 gmail com>
Date:   Mon Jul 25 09:17:01 2016 +0300

    files-view: add context menu actions for extracting files
    
    The context menu actions are similar to the ones offered by file-roller, but
    make use of the internal extract operation.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=768646

 src/nautilus-application.c                         |   18 +++
 src/nautilus-application.h                         |    2 +
 src/nautilus-file.c                                |   39 ++-----
 src/nautilus-files-view.c                          |  133 ++++++++++++++++++++
 .../ui/nautilus-files-view-context-menus.ui        |   10 ++
 5 files changed, 171 insertions(+), 31 deletions(-)
---
diff --git a/src/nautilus-application.c b/src/nautilus-application.c
index 989f31d..5fc671b 100644
--- a/src/nautilus-application.c
+++ b/src/nautilus-application.c
@@ -76,6 +76,8 @@ typedef struct {
        GList *windows;
 
         GHashTable *notifications;
+
+        AutoarPref *ar_preferences;
 } NautilusApplicationPrivate;
 
 G_DEFINE_TYPE_WITH_PRIVATE (NautilusApplication, nautilus_application, GTK_TYPE_APPLICATION);
@@ -547,6 +549,8 @@ nautilus_application_finalize (GObject *object)
        g_clear_object (&priv->fdb_manager);
        g_clear_object (&priv->search_provider);
 
+        g_clear_object (&priv->ar_preferences);
+
        g_list_free (priv->windows);
 
         g_hash_table_destroy (priv->notifications);
@@ -948,6 +952,7 @@ static void
 nautilus_application_init (NautilusApplication *self)
 {
         NautilusApplicationPrivate *priv;
+        g_autoptr (GSettings) archive_settings;
 
         priv = nautilus_application_get_instance_private (self);
 
@@ -960,6 +965,9 @@ nautilus_application_init (NautilusApplication *self)
 
         nautilus_ensure_extension_points ();
         nautilus_ensure_extension_builtins ();
+
+        archive_settings = g_settings_new (AUTOAR_PREF_DEFAULT_GSCHEMA_ID);
+        priv->ar_preferences = autoar_pref_new_with_gsettings (archive_settings);
 }
 
 static void
@@ -1038,6 +1046,16 @@ nautilus_application_get_default (void)
         return self;
 }
 
+AutoarPref *
+nautilus_application_get_autoar_preferences (NautilusApplication *self)
+{
+        NautilusApplicationPrivate *priv;
+
+        priv = nautilus_application_get_instance_private (self);
+
+        return priv->ar_preferences;
+}
+
 void
 nautilus_application_send_notification (NautilusApplication *self,
                                         const gchar         *notification_id,
diff --git a/src/nautilus-application.h b/src/nautilus-application.h
index 197a276..57911d7 100644
--- a/src/nautilus-application.h
+++ b/src/nautilus-application.h
@@ -24,6 +24,7 @@
 #include <gdk/gdk.h>
 #include <gio/gio.h>
 #include <gtk/gtk.h>
+#include <gnome-autoar/autoar.h>
 
 #include "nautilus-bookmark-list.h"
 #include "nautilus-window.h"
@@ -71,6 +72,7 @@ void nautilus_application_open_location_full (NautilusApplication     *applicati
                                               NautilusWindowSlot      *target_slot);
 
 NautilusApplication *nautilus_application_get_default (void);
+AutoarPref * nautilus_application_get_autoar_preferences (NautilusApplication *self);
 void nautilus_application_send_notification (NautilusApplication *self,
                                              const gchar         *notification_id,
                                              GNotification       *notification);
diff --git a/src/nautilus-file.c b/src/nautilus-file.c
index e85ffa3..9919db0 100644
--- a/src/nautilus-file.c
+++ b/src/nautilus-file.c
@@ -22,6 +22,7 @@
 #include <config.h>
 #include "nautilus-file.h"
 
+#include "nautilus-application.h"
 #include "nautilus-directory-notify.h"
 #include "nautilus-directory-private.h"
 #include "nautilus-signaller.h"
@@ -51,6 +52,7 @@
 #include <glib/gstdio.h>
 #include <gio/gio.h>
 #include <glib.h>
+#include <gnome-autoar/autoar.h>
 #include <gdesktop-enums.h>
 #include <libnautilus-extension/nautilus-file-info.h>
 #include <libnautilus-extension/nautilus-extension-private.h>
@@ -7013,38 +7015,13 @@ real_is_special_link (NautilusFile *file)
 gboolean
 nautilus_file_is_archive (NautilusFile *file)
 {
-       char *mime_type;
-       int i;
-       static const char * archive_mime_types[] = { "application/x-gtar",
-                                                    "application/x-zip",
-                                                    "application/x-zip-compressed",
-                                                    "application/zip",
-                                                    "application/x-zip",
-                                                    "application/x-tar",
-                                                    "application/x-7z-compressed",
-                                                    "application/x-rar",
-                                                    "application/x-rar-compressed",
-                                                    "application/x-jar",
-                                                    "application/x-java-archive",
-                                                    "application/x-war",
-                                                    "application/x-ear",
-                                                    "application/x-arj",
-                                                    "application/x-gzip",
-                                                    "application/x-bzip-compressed-tar",
-                                                    "application/x-compressed-tar" };
-
-       g_return_val_if_fail (file != NULL, FALSE);
-
-       mime_type = nautilus_file_get_mime_type (file);
-       for (i = 0; i < G_N_ELEMENTS (archive_mime_types); i++) {
-               if (!strcmp (mime_type, archive_mime_types[i])) {
-                       g_free (mime_type);
-                       return TRUE;
-               }
-       }
-       g_free (mime_type);
+        g_autofree char *mime_type;
+        AutoarPref *ar_preferences;
 
-       return FALSE;
+        ar_preferences = nautilus_application_get_autoar_preferences (nautilus_application_get_default ());
+        mime_type = nautilus_file_get_mime_type (file);
+
+        return autoar_pref_check_mime_type_d (ar_preferences, mime_type);
 }
 
 
diff --git a/src/nautilus-files-view.c b/src/nautilus-files-view.c
index bf8fc5f..98bc731 100644
--- a/src/nautilus-files-view.c
+++ b/src/nautilus-files-view.c
@@ -676,6 +676,18 @@ showing_recent_directory (NautilusFilesView *view)
 }
 
 static gboolean
+showing_remote_directory (NautilusFilesView *view)
+{
+        NautilusFile *file;
+
+        file = nautilus_files_view_get_directory_as_file (view);
+        if (file != NULL) {
+                return nautilus_file_is_remote (file);
+        }
+        return FALSE;
+}
+
+static gboolean
 nautilus_files_view_supports_creating_files (NautilusFilesView *view)
 {
         g_return_val_if_fail (NAUTILUS_IS_FILES_VIEW (view), FALSE);
@@ -5631,6 +5643,94 @@ action_rename (GSimpleAction *action,
         real_action_rename (NAUTILUS_FILES_VIEW (user_data), FALSE);
 }
 
+static void
+nautilus_files_view_extract_selection (NautilusFilesView *view,
+                                       GFile             *destination)
+{
+        GList *selection;
+        GList *l;
+
+        selection = nautilus_view_get_selection (NAUTILUS_VIEW (view));
+
+        for (l = selection; l != NULL; l = l->next) {
+                GFile *source;
+
+                source = nautilus_file_get_location (NAUTILUS_FILE (l->data));
+
+                nautilus_file_operations_extract (source,
+                                                  destination,
+                                                  nautilus_files_view_get_containing_window (view),
+                                                  NULL,
+                                                  NULL);
+        }
+
+        nautilus_file_list_free (selection);
+}
+
+static void
+action_extract_here (GSimpleAction *action,
+                     GVariant      *state,
+                     gpointer       user_data)
+{
+        NautilusFilesView *view = user_data;
+
+        nautilus_files_view_extract_selection (view,
+                                               nautilus_view_get_location (NAUTILUS_VIEW (view)));
+}
+
+static void
+on_extract_destination_dialog_response (GtkDialog *dialog,
+                                        gint       response_id,
+                                        gpointer   user_data)
+{
+        NautilusFilesView *view = user_data;
+
+        if (response_id == GTK_RESPONSE_OK) {
+                g_autoptr (GFile) target_file;
+
+                target_file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
+
+                nautilus_files_view_extract_selection (view,
+                                                       target_file);
+        }
+
+        gtk_widget_destroy (GTK_WIDGET (dialog));
+}
+
+static void
+action_extract_to (GSimpleAction *action,
+                   GVariant      *state,
+                   gpointer       user_data)
+{
+        NautilusFilesView *view = user_data;
+        GtkWidget *dialog;
+        g_autofree char *uri;
+
+        dialog = gtk_file_chooser_dialog_new (_("Select Extract Destination"),
+                                              GTK_WINDOW (nautilus_files_view_get_window (view)),
+                                              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);
+
+        uri = nautilus_directory_get_uri (view->details->model);
+        gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dialog), uri);
+
+        g_signal_connect (dialog, "response",
+                          G_CALLBACK (on_extract_destination_dialog_response),
+                          view);
+
+        gtk_widget_show_all (dialog);
+}
+
+
 #define BG_KEY_PRIMARY_COLOR      "primary-color"
 #define BG_KEY_SECONDARY_COLOR    "secondary-color"
 #define BG_KEY_COLOR_TYPE         "color-shading-type"
@@ -6067,6 +6167,8 @@ const GActionEntry view_entries[] = {
         { "restore-from-trash", action_restore_from_trash},
         { "paste-into", action_paste_files_into },
         { "rename", action_rename},
+        { "extract-here", action_extract_here },
+        { "extract-to", action_extract_to },
         { "properties", action_properties},
         { "set-as-wallpaper", action_set_as_wallpaper },
         { "mount-volume", action_mount_volume },
@@ -6304,6 +6406,21 @@ all_in_trash (GList *files)
         return TRUE;
 }
 
+static gboolean
+can_extract_all (GList *files)
+{
+        NautilusFile *file;
+        GList *l;
+
+        for (l = files; l != NULL; l = l->next) {
+                file = l->data;
+                if (!nautilus_file_is_archive (file)) {
+                        return FALSE;
+                }
+        }
+        return TRUE;
+}
+
 GActionGroup *
 nautilus_files_view_get_action_group (NautilusFilesView *view)
 {
@@ -6331,6 +6448,8 @@ real_update_actions_state (NautilusFilesView *view)
         gboolean can_copy_files;
         gboolean can_link_from_copied_files;
         gboolean can_paste_files_into;
+        gboolean can_extract_files;
+        gboolean can_extract_here;
         gboolean item_opens_in_view;
         gboolean is_read_only;
         GAction *action;
@@ -6378,6 +6497,11 @@ real_update_actions_state (NautilusFilesView *view)
         can_paste_files_into = (!selection_contains_recent &&
                                 selection_count == 1 &&
                                 can_paste_into_file (NAUTILUS_FILE (selection->data)));
+        can_extract_files = selection_count != 0 &&
+                            can_extract_all (selection);
+        can_extract_here = can_create_files &&
+                           !selection_contains_remote &&
+                           !selection_contains_search;
          settings_show_delete_permanently = g_settings_get_boolean (nautilus_preferences,
                                                                     
NAUTILUS_PREFERENCES_SHOW_DELETE_PERMANENTLY);
          settings_show_create_link = g_settings_get_boolean (nautilus_preferences,
@@ -6402,6 +6526,15 @@ 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);
+
+        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);
+
+        action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
                                              "open-item-location");
 
         g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
diff --git a/src/resources/ui/nautilus-files-view-context-menus.ui 
b/src/resources/ui/nautilus-files-view-context-menus.ui
index b40d242..9d4ac30 100644
--- a/src/resources/ui/nautilus-files-view-context-menus.ui
+++ b/src/resources/ui/nautilus-files-view-context-menus.ui
@@ -235,6 +235,16 @@
     </section>
     <section>
       <attribute name="id">extensions</attribute>
+      <item>
+        <attribute name="label" translatable="yes">Extract Here</attribute>
+        <attribute name="action">view.extract-here</attribute>
+        <attribute name="hidden-when">action-disabled</attribute>
+      </item>
+      <item>
+        <attribute name="label" translatable="yes">Extract to…</attribute>
+        <attribute name="action">view.extract-to</attribute>
+        <attribute name="hidden-when">action-disabled</attribute>
+      </item>
     </section>
     <section>
       <item>


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