summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRazvan Chitu <razvan.ch95@gmail.com>2016-08-21 23:02:54 +0300
committerRazvan Chitu <razvan.ch95@gmail.com>2016-08-23 00:37:17 +0300
commite9efd047b242cb4e8bb72b498bd0853e09add39e (patch)
treebe7f1754b0a25942f319b9f2ba309530735d3763
parent9d8de33448073196b3a7d649330e9a4da9fefd7f (diff)
downloadnautilus-e9efd047b242cb4e8bb72b498bd0853e09add39e.tar.gz
files-view: add menu action and dialog for compression
Add an context menu action for compression and a dialog for selecting the file name and compression format. Add a controller class for managing the compression dialog. https://bugzilla.gnome.org/show_bug.cgi?id=770199
-rw-r--r--src/Makefile.am2
-rw-r--r--src/nautilus-compress-dialog-controller.c294
-rw-r--r--src/nautilus-compress-dialog-controller.h17
-rw-r--r--src/nautilus-files-view.c202
-rw-r--r--src/resources/nautilus.gresource.xml1
-rw-r--r--src/resources/ui/nautilus-compress-dialog.ui144
-rw-r--r--src/resources/ui/nautilus-files-view-context-menus.ui5
7 files changed, 665 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 6532c0101..c925f4129 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -278,6 +278,8 @@ nautilus_no_main_sources = \
nautilus-rename-file-popover-controller.h \
nautilus-new-folder-dialog-controller.c \
nautilus-new-folder-dialog-controller.h \
+ nautilus-compress-dialog-controller.c \
+ nautilus-compress-dialog-controller.h \
nautilus-operations-ui-manager.c \
nautilus-operations-ui-manager.h \
nautilus-file-operations.c \
diff --git a/src/nautilus-compress-dialog-controller.c b/src/nautilus-compress-dialog-controller.c
new file mode 100644
index 000000000..9a31e655d
--- /dev/null
+++ b/src/nautilus-compress-dialog-controller.c
@@ -0,0 +1,294 @@
+#include <glib/gi18n.h>
+#include <gnome-autoar/gnome-autoar.h>
+
+#include <eel/eel-vfs-extensions.h>
+
+#include "nautilus-compress-dialog-controller.h"
+
+#include "nautilus-global-preferences.h"
+
+#define ZIP_DESCRIPTION _("Compatible with all operating systems.")
+#define TAR_XZ_DESCRIPTION _("Smaller archives but Linux and Mac only.")
+#define SEVEN_ZIP_DESCRIPTION _("Smaller archives but must be installed on Windows and Mac.")
+
+struct _NautilusCompressDialogController {
+ NautilusFileNameWidgetController parent_instance;
+
+ GtkWidget *compress_dialog;
+ GtkWidget *description_label;
+ GtkWidget *name_entry;
+ GtkWidget *zip_radio_button;
+ GtkWidget *tar_xz_radio_button;
+ GtkWidget *seven_zip_radio_button;
+
+ const char *extension;
+
+ gint response_handler_id;
+};
+
+G_DEFINE_TYPE (NautilusCompressDialogController, nautilus_compress_dialog_controller, NAUTILUS_TYPE_FILE_NAME_WIDGET_CONTROLLER);
+
+static gboolean
+nautilus_compress_dialog_controller_name_is_valid (NautilusFileNameWidgetController *self,
+ gchar *name,
+ gchar **error_message)
+{
+ if (strlen (name) == 0) {
+ return FALSE;
+ }
+
+ if (strstr (name, "/") != NULL) {
+ *error_message = _("Archive names cannot contain “/”.");
+ } else if (strcmp (name, ".") == 0){
+ *error_message = _("An archive cannot be called “.”.");
+ } else if (strcmp (name, "..") == 0){
+ *error_message = _("An archive cannot be called “..”.");
+ }
+
+ return *error_message == NULL;
+}
+
+static gchar *
+nautilus_compress_dialog_controller_get_new_name (NautilusFileNameWidgetController *controller)
+{
+ NautilusCompressDialogController *self;
+ g_autofree gchar *basename;
+ gchar *error_message = NULL;
+ gboolean valid_name;
+
+ self = NAUTILUS_COMPRESS_DIALOG_CONTROLLER (controller);
+
+ basename = NAUTILUS_FILE_NAME_WIDGET_CONTROLLER_CLASS (nautilus_compress_dialog_controller_parent_class)->get_new_name (controller);
+ /* Do not check or add the extension if the name is invalid */
+ valid_name = nautilus_compress_dialog_controller_name_is_valid (controller,
+ basename,
+ &error_message);
+
+ if (!valid_name) {
+ return g_strdup (basename);
+ }
+
+ if (g_str_has_suffix (basename, self->extension)) {
+ return g_strdup (basename);
+ }
+
+ return g_strconcat (basename, self->extension, NULL);
+}
+
+static void
+compress_dialog_controller_on_response (GtkDialog *dialog,
+ gint response_id,
+ gpointer user_data)
+{
+ NautilusCompressDialogController *controller;
+
+ controller = NAUTILUS_COMPRESS_DIALOG_CONTROLLER (user_data);
+
+ if (response_id != GTK_RESPONSE_OK) {
+ g_signal_emit_by_name (controller, "cancelled");
+ }
+}
+
+static void
+update_selected_format (NautilusCompressDialogController *self,
+ NautilusCompressionFormat format)
+{
+ const char *extension;
+ const char *description;
+ GtkWidget *active_button;
+
+ switch (format) {
+ case NAUTILUS_COMPRESSION_ZIP:
+ extension = ".zip";
+ description = ZIP_DESCRIPTION;
+ active_button = self->zip_radio_button;
+ break;
+ case NAUTILUS_COMPRESSION_TAR_XZ:
+ extension = ".tar.xz";
+ description = TAR_XZ_DESCRIPTION;
+ active_button = self->tar_xz_radio_button;
+ break;
+ case NAUTILUS_COMPRESSION_7ZIP:
+ extension = ".7z";
+ description = SEVEN_ZIP_DESCRIPTION;
+ active_button = self->seven_zip_radio_button;
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+
+ self->extension = extension;
+
+ gtk_label_set_text (GTK_LABEL (self->description_label),
+ description);
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (active_button),
+ TRUE);
+
+ g_settings_set_enum (nautilus_compression_preferences,
+ NAUTILUS_PREFERENCES_DEFAULT_COMPRESSION_FORMAT,
+ format);
+ /* Since the extension changes when the button is toggled, force a
+ * verification of the new file name by simulating an entry change
+ */
+ g_signal_emit_by_name (self->name_entry, "changed");
+}
+
+static void
+zip_radio_button_on_toggled (GtkToggleButton *toggle_button,
+ gpointer user_data)
+{
+ NautilusCompressDialogController *controller;
+
+ controller = NAUTILUS_COMPRESS_DIALOG_CONTROLLER (user_data);
+
+ if (!gtk_toggle_button_get_active (toggle_button)) {
+ return;
+ }
+
+ update_selected_format (controller,
+ NAUTILUS_COMPRESSION_ZIP);
+}
+
+static void
+tar_xz_radio_button_on_toggled (GtkToggleButton *toggle_button,
+ gpointer user_data)
+{
+ NautilusCompressDialogController *controller;
+
+ controller = NAUTILUS_COMPRESS_DIALOG_CONTROLLER (user_data);
+
+ if (!gtk_toggle_button_get_active (toggle_button)) {
+ return;
+ }
+
+ update_selected_format (controller,
+ NAUTILUS_COMPRESSION_TAR_XZ);
+}
+
+static void
+seven_zip_radio_button_on_toggled (GtkToggleButton *toggle_button,
+ gpointer user_data)
+{
+ NautilusCompressDialogController *controller;
+
+ controller = NAUTILUS_COMPRESS_DIALOG_CONTROLLER (user_data);
+
+ if (!gtk_toggle_button_get_active (toggle_button)) {
+ return;
+ }
+
+ update_selected_format (controller,
+ NAUTILUS_COMPRESSION_7ZIP);
+}
+
+NautilusCompressDialogController *
+nautilus_compress_dialog_controller_new (GtkWindow *parent_window,
+ NautilusDirectory *destination_directory,
+ gchar *initial_name)
+{
+ NautilusCompressDialogController *self;
+ g_autoptr (GtkBuilder) builder;
+ GtkWidget *compress_dialog;
+ GtkWidget *error_label;
+ GtkWidget *name_entry;
+ GtkWidget *activate_button;
+ GtkWidget *description_label;
+ GtkWidget *zip_radio_button;
+ GtkWidget *tar_xz_radio_button;
+ GtkWidget *seven_zip_radio_button;
+ NautilusCompressionFormat format;
+
+ builder = gtk_builder_new_from_resource ("/org/gnome/nautilus/ui/nautilus-compress-dialog.ui");
+ compress_dialog = GTK_WIDGET (gtk_builder_get_object (builder, "compress_dialog"));
+ error_label = GTK_WIDGET (gtk_builder_get_object (builder, "error_label"));
+ name_entry = GTK_WIDGET (gtk_builder_get_object (builder, "name_entry"));
+ activate_button = GTK_WIDGET (gtk_builder_get_object (builder, "activate_button"));
+ zip_radio_button = GTK_WIDGET (gtk_builder_get_object (builder, "zip_radio_button"));
+ tar_xz_radio_button = GTK_WIDGET (gtk_builder_get_object (builder, "tar_xz_radio_button"));
+ seven_zip_radio_button = GTK_WIDGET (gtk_builder_get_object (builder, "seven_zip_radio_button"));
+ description_label = GTK_WIDGET (gtk_builder_get_object (builder, "description_label"));
+
+ gtk_window_set_transient_for (GTK_WINDOW (compress_dialog),
+ parent_window);
+
+ self = g_object_new (NAUTILUS_TYPE_COMPRESS_DIALOG_CONTROLLER,
+ "error-label", error_label,
+ "name-entry", name_entry,
+ "activate-button", activate_button,
+ "containing-directory", destination_directory, NULL);
+
+ self->compress_dialog = compress_dialog;
+ self->zip_radio_button = zip_radio_button;
+ self->tar_xz_radio_button = tar_xz_radio_button;
+ self->seven_zip_radio_button = seven_zip_radio_button;
+ self->description_label = description_label;
+ self->name_entry = name_entry;
+
+ self->response_handler_id = g_signal_connect (compress_dialog,
+ "response",
+ (GCallback)compress_dialog_controller_on_response,
+ self);
+
+ gtk_builder_add_callback_symbols (builder,
+ "zip_radio_button_on_toggled",
+ G_CALLBACK (zip_radio_button_on_toggled),
+ "tar_xz_radio_button_on_toggled",
+ G_CALLBACK (tar_xz_radio_button_on_toggled),
+ "seven_zip_radio_button_on_toggled",
+ G_CALLBACK (seven_zip_radio_button_on_toggled),
+ NULL);
+ gtk_builder_connect_signals (builder, self);
+
+ format = g_settings_get_enum (nautilus_compression_preferences,
+ NAUTILUS_PREFERENCES_DEFAULT_COMPRESSION_FORMAT);
+
+ update_selected_format (self, format);
+
+ if (initial_name != NULL) {
+ gtk_entry_set_text (GTK_ENTRY (name_entry), initial_name);
+ }
+
+ gtk_widget_show_all (compress_dialog);
+
+ return self;
+}
+
+static void
+nautilus_compress_dialog_controller_init (NautilusCompressDialogController *self)
+{
+
+}
+
+static void
+nautilus_compress_dialog_controller_finalize (GObject *object)
+{
+ NautilusCompressDialogController *self;
+
+ self = NAUTILUS_COMPRESS_DIALOG_CONTROLLER (object);
+
+ if (self->compress_dialog != NULL) {
+ if (self->response_handler_id > 0) {
+ g_signal_handler_disconnect (self->compress_dialog,
+ self->response_handler_id);
+ self->response_handler_id = 0;
+ }
+ gtk_widget_destroy (self->compress_dialog);
+ self->compress_dialog = NULL;
+ }
+
+ G_OBJECT_CLASS (nautilus_compress_dialog_controller_parent_class)->finalize (object);
+}
+
+static void
+nautilus_compress_dialog_controller_class_init (NautilusCompressDialogControllerClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ NautilusFileNameWidgetControllerClass *parent_class = NAUTILUS_FILE_NAME_WIDGET_CONTROLLER_CLASS (klass);
+
+ object_class->finalize = nautilus_compress_dialog_controller_finalize;
+
+ parent_class->get_new_name = nautilus_compress_dialog_controller_get_new_name;
+ parent_class->name_is_valid = nautilus_compress_dialog_controller_name_is_valid;
+}
diff --git a/src/nautilus-compress-dialog-controller.h b/src/nautilus-compress-dialog-controller.h
new file mode 100644
index 000000000..b33767c8e
--- /dev/null
+++ b/src/nautilus-compress-dialog-controller.h
@@ -0,0 +1,17 @@
+#ifndef NAUTILUS_COMPRESS_DIALOG_CONTROLLER_H
+#define NAUTILUS_COMPRESS_DIALOG_CONTROLLER_H
+
+#include <glib.h>
+#include <gtk/gtk.h>
+
+#include "nautilus-file-name-widget-controller.h"
+#include "nautilus-directory.h"
+
+#define NAUTILUS_TYPE_COMPRESS_DIALOG_CONTROLLER nautilus_compress_dialog_controller_get_type ()
+G_DECLARE_FINAL_TYPE (NautilusCompressDialogController, nautilus_compress_dialog_controller, NAUTILUS, COMPRESS_DIALOG_CONTROLLER, NautilusFileNameWidgetController)
+
+NautilusCompressDialogController * nautilus_compress_dialog_controller_new (GtkWindow *parent_window,
+ NautilusDirectory *destination_directory,
+ gchar *initial_name);
+
+#endif /* NAUTILUS_COMPRESS_DIALOG_CONTROLLER_H */
diff --git a/src/nautilus-files-view.c b/src/nautilus-files-view.c
index d35b2cdb2..cd7aa2772 100644
--- a/src/nautilus-files-view.c
+++ b/src/nautilus-files-view.c
@@ -54,6 +54,7 @@
#include <glib/gi18n.h>
#include <glib/gstdio.h>
#include <gio/gio.h>
+#include <gnome-autoar/gnome-autoar.h>
#include <math.h>
#include <string.h>
#include <sys/types.h>
@@ -81,6 +82,7 @@
#include "nautilus-file-name-widget-controller.h"
#include "nautilus-rename-file-popover-controller.h"
#include "nautilus-new-folder-dialog-controller.h"
+#include "nautilus-compress-dialog-controller.h"
#include "nautilus-global-preferences.h"
#include "nautilus-link.h"
#include "nautilus-metadata.h"
@@ -177,6 +179,7 @@ struct NautilusFilesViewDetails
NautilusRenameFilePopoverController *rename_file_controller;
NautilusNewFolderDialogController *new_folder_controller;
+ NautilusCompressDialogController *compress_controller;
gboolean supports_zooming;
@@ -1897,6 +1900,188 @@ nautilus_files_view_new_folder_dialog_new (NautilusFilesView *view,
nautilus_directory_unref (containing_directory);
}
+typedef struct {
+ NautilusFilesView *view;
+ GHashTable *added_locations;
+} CompressData;
+
+static void
+compress_done (GFile *new_file,
+ gboolean success,
+ gpointer user_data)
+{
+ CompressData *data;
+ NautilusFilesView *view;
+ NautilusFile *file;
+
+ data = user_data;
+ view = data->view;
+
+ if (view == NULL) {
+ goto out;
+ }
+
+ g_signal_handlers_disconnect_by_func (view,
+ G_CALLBACK (track_newly_added_locations),
+ data->added_locations);
+
+ if (!success) {
+ goto out;
+ }
+
+ file = nautilus_file_get (new_file);
+
+ if (g_hash_table_contains (data->added_locations, new_file)) {
+ /* The file was already added */
+ nautilus_files_view_select_file (view, file);
+ nautilus_files_view_reveal_selection (view);
+ } else {
+ g_hash_table_insert (view->details->pending_reveal,
+ file,
+ GUINT_TO_POINTER (TRUE));
+ }
+
+ nautilus_file_unref (file);
+ out:
+ g_hash_table_destroy (data->added_locations);
+
+ if (data->view != NULL) {
+ g_object_remove_weak_pointer (G_OBJECT (data->view),
+ (gpointer *) &data->view);
+ }
+
+ g_free (data);
+}
+
+static void
+compress_dialog_controller_on_name_accepted (NautilusFileNameWidgetController *controller,
+ gpointer user_data)
+{
+ NautilusFilesView *view;
+ g_autofree gchar *name;
+ GList *selection;
+ GList *source_files = NULL;
+ GList *l;
+ CompressData *data;
+ g_autoptr (GFile) output;
+ NautilusCompressionFormat compression_format;
+ AutoarFormat format;
+ AutoarFilter filter;
+
+ view = NAUTILUS_FILES_VIEW (user_data);
+
+ selection = nautilus_files_view_get_selection_for_file_transfer (view);
+
+ for (l = selection; l != NULL; l = l->next) {
+ source_files = g_list_prepend (source_files,
+ nautilus_file_get_location (l->data));
+ }
+ source_files = g_list_reverse (source_files);
+
+ name = nautilus_file_name_widget_controller_get_new_name (controller);
+ output = g_file_get_child (view->details->location, name);
+
+ data = g_new (CompressData, 1);
+ data->view = view;
+ data->added_locations = g_hash_table_new_full (g_file_hash, (GEqualFunc)g_file_equal,
+ g_object_unref, NULL);
+ g_object_add_weak_pointer (G_OBJECT (data->view),
+ (gpointer *) &data->view);
+
+ g_signal_connect_data (view,
+ "add-file",
+ G_CALLBACK (track_newly_added_locations),
+ data->added_locations,
+ NULL,
+ G_CONNECT_AFTER);
+
+ compression_format = g_settings_get_enum (nautilus_compression_preferences,
+ NAUTILUS_PREFERENCES_DEFAULT_COMPRESSION_FORMAT);
+
+ switch (compression_format) {
+ case NAUTILUS_COMPRESSION_ZIP:
+ format = AUTOAR_FORMAT_ZIP;
+ filter = AUTOAR_FILTER_NONE;
+ break;
+ case NAUTILUS_COMPRESSION_TAR_XZ:
+ format = AUTOAR_FORMAT_TAR;
+ filter = AUTOAR_FILTER_XZ;
+ break;
+ case NAUTILUS_COMPRESSION_7ZIP:
+ format = AUTOAR_FORMAT_7ZIP;
+ filter = AUTOAR_FILTER_NONE;
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ nautilus_file_operations_compress (source_files, output,
+ format,
+ filter,
+ nautilus_files_view_get_containing_window (view),
+ compress_done,
+ data);
+
+ nautilus_file_list_free (selection);
+ g_list_free_full (source_files, g_object_unref);
+ g_clear_object (&view->details->compress_controller);
+}
+
+static void
+compress_dialog_controller_on_cancelled (NautilusNewFolderDialogController *controller,
+ gpointer user_data)
+{
+ NautilusFilesView *view;
+
+ view = NAUTILUS_FILES_VIEW (user_data);
+
+ g_clear_object (&view->details->compress_controller);
+}
+
+
+static void
+nautilus_files_view_compress_dialog_new (NautilusFilesView *view)
+{
+
+ NautilusDirectory *containing_directory;
+ GList *selection;
+ g_autofree char *common_prefix = NULL;
+
+ if (view->details->compress_controller != NULL) {
+ return;
+ }
+
+ containing_directory = nautilus_directory_get_by_uri (nautilus_files_view_get_backing_uri (view));
+
+ selection = nautilus_view_get_selection (NAUTILUS_VIEW (view));
+
+ if (g_list_length (selection) == 1) {
+ g_autofree char *display_name;
+
+ display_name = nautilus_file_get_display_name (selection->data);
+
+ common_prefix = eel_filename_strip_extension (display_name);
+ } else {
+ common_prefix = nautilus_get_common_filename_prefix (selection,
+ MIN_COMMON_FILENAME_PREFIX_LENGTH);
+ }
+
+ view->details->compress_controller = nautilus_compress_dialog_controller_new (nautilus_files_view_get_containing_window (view),
+ containing_directory,
+ common_prefix);
+
+ g_signal_connect (view->details->compress_controller,
+ "name-accepted",
+ (GCallback)compress_dialog_controller_on_name_accepted,
+ view);
+ g_signal_connect (view->details->compress_controller,
+ "cancelled",
+ (GCallback)compress_dialog_controller_on_cancelled,
+ view);
+
+ nautilus_file_list_free (selection);
+}
+
static void
nautilus_files_view_new_folder (NautilusFilesView *directory_view,
gboolean with_selection)
@@ -2709,6 +2894,7 @@ nautilus_files_view_finalize (GObject *object)
g_clear_object (&view->details->toolbar_menu_sections->extended_section);
g_clear_object (&view->details->rename_file_controller);
g_clear_object (&view->details->new_folder_controller);
+ g_clear_object (&view->details->compress_controller);
g_free (view->details->toolbar_menu_sections);
g_hash_table_destroy (view->details->non_ready_files);
@@ -5640,6 +5826,16 @@ action_extract_to (GSimpleAction *action,
nautilus_file_list_free (selection);
}
+static void
+action_compress (GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
+{
+ NautilusFilesView *view = user_data;
+
+ nautilus_files_view_compress_dialog_new (view);
+}
+
#define BG_KEY_PRIMARY_COLOR "primary-color"
#define BG_KEY_SECONDARY_COLOR "secondary-color"
@@ -6079,6 +6275,7 @@ const GActionEntry view_entries[] = {
{ "rename", action_rename},
{ "extract-here", action_extract_here },
{ "extract-to", action_extract_to },
+ { "compress", action_compress },
{ "properties", action_properties},
{ "set-as-wallpaper", action_set_as_wallpaper },
{ "mount-volume", action_mount_volume },
@@ -6451,6 +6648,11 @@ real_update_actions_state (NautilusFilesView *view)
can_extract_here));
action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
+ "compress");
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
+ !can_extract_files && can_create_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/nautilus.gresource.xml b/src/resources/nautilus.gresource.xml
index a5917fcc7..05b9a4db9 100644
--- a/src/resources/nautilus.gresource.xml
+++ b/src/resources/nautilus.gresource.xml
@@ -9,6 +9,7 @@
<file>ui/nautilus-toolbar-menu.ui</file>
<file>ui/nautilus-toolbar-view-menu.ui</file>
<file>ui/nautilus-create-folder-dialog.ui</file>
+ <file>ui/nautilus-compress-dialog.ui</file>
<file>ui/nautilus-rename-file-popover.ui</file>
<file>ui/nautilus-files-view-context-menus.ui</file>
<file>ui/nautilus-progress-info-widget.ui</file>
diff --git a/src/resources/ui/nautilus-compress-dialog.ui b/src/resources/ui/nautilus-compress-dialog.ui
new file mode 100644
index 000000000..0aa9f11bc
--- /dev/null
+++ b/src/resources/ui/nautilus-compress-dialog.ui
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <requires lib="gtk+" version="3.14"/>
+ <object class="GtkDialog" id="compress_dialog">
+ <property name="title" translatable="true">Create Archive</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="window_position">center-on-parent</property>
+ <property name="destroy_with_parent">True</property>
+ <property name="type_hint">dialog</property>
+ <property name="use-header-bar">1</property>
+ <property name="width_request">490</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="vbox">
+ <property name="orientation">vertical</property>
+ <property name="margin_top">18</property>
+ <property name="margin_bottom">12</property>
+ <property name="margin_start">18</property>
+ <property name="margin_end">18</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="name_label">
+ <property name="label" translatable="yes">Archive name</property>
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="name_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="error_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="hbox">
+ <property name="orientation">horizontal</property>
+ <property name="homogeneous">True</property>
+ <property name="spacing">0</property>
+ <child>
+ <object class="GtkRadioButton" id="zip_radio_button">
+ <property name="label" translatable="no">.zip</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="zip_radio_button_on_toggled"/>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="tar_xz_radio_button">
+ <property name="label" translatable="no">.tar.xz</property>
+ <property name="group">zip_radio_button</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="tar_xz_radio_button_on_toggled"/>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="seven_zip_radio_button">
+ <property name="label" translatable="no">.7z</property>
+ <property name="group">zip_radio_button</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="seven_zip_radio_button_on_toggled"/>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</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>
+ <child>
+ <object class="GtkLabel" id="description_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">5</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="action">
+ <object class="GtkButton" id="cancel_button">
+ <property name="label" translatable="yes">Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ </object>
+ </child>
+ <child type="action">
+ <object class="GtkButton" id="activate_button">
+ <property name="label" translatable="yes">Create</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="sensitive">False</property>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="ok" default="true">activate_button</action-widget>
+ <action-widget response="cancel">cancel_button</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/src/resources/ui/nautilus-files-view-context-menus.ui b/src/resources/ui/nautilus-files-view-context-menus.ui
index 564201f18..31f26fbbb 100644
--- a/src/resources/ui/nautilus-files-view-context-menus.ui
+++ b/src/resources/ui/nautilus-files-view-context-menus.ui
@@ -245,6 +245,11 @@
<attribute name="action">view.extract-to</attribute>
<attribute name="hidden-when">action-disabled</attribute>
</item>
+ <item>
+ <attribute name="label" translatable="yes">C_ompress…</attribute>
+ <attribute name="action">view.compress</attribute>
+ <attribute name="hidden-when">action-disabled</attribute>
+ </item>
</section>
<section>
<item>