summaryrefslogtreecommitdiffstats
path: root/src/nautilus-compress-dialog-controller.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nautilus-compress-dialog-controller.c')
-rw-r--r--src/nautilus-compress-dialog-controller.c350
1 files changed, 350 insertions, 0 deletions
diff --git a/src/nautilus-compress-dialog-controller.c b/src/nautilus-compress-dialog-controller.c
new file mode 100644
index 0000000..d8aa792
--- /dev/null
+++ b/src/nautilus-compress-dialog-controller.c
@@ -0,0 +1,350 @@
+/* nautilus-compress-dialog-controller.h
+ *
+ * Copyright (C) 2016 the Nautilus developers
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#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"
+
+struct _NautilusCompressDialogController
+{
+ NautilusFileNameWidgetController parent_instance;
+
+ GtkWidget *compress_dialog;
+ GtkWidget *description_stack;
+ GtkWidget *name_entry;
+ GtkWidget *zip_radio_button;
+ GtkWidget *tar_xz_radio_button;
+ GtkWidget *seven_zip_radio_button;
+
+ const char *extension;
+
+ gulong 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)
+{
+ gboolean is_valid;
+
+ is_valid = TRUE;
+ if (strlen (name) == 0)
+ {
+ is_valid = FALSE;
+ }
+ else if (strstr (name, "/") != NULL)
+ {
+ is_valid = FALSE;
+ *error_message = _("Archive names cannot contain “/”.");
+ }
+ else if (strcmp (name, ".") == 0)
+ {
+ is_valid = FALSE;
+ *error_message = _("An archive cannot be called “.”.");
+ }
+ else if (strcmp (name, "..") == 0)
+ {
+ is_valid = FALSE;
+ *error_message = _("An archive cannot be called “..”.");
+ }
+ else if (nautilus_file_name_widget_controller_is_name_too_long (self, name))
+ {
+ is_valid = FALSE;
+ *error_message = _("Archive name is too long.");
+ }
+
+ if (is_valid && g_str_has_prefix (name, "."))
+ {
+ /* We must warn about the side effect */
+ *error_message = _("Archives with “.” at the beginning of their name are hidden.");
+ }
+
+ return is_valid;
+}
+
+static gchar *
+nautilus_compress_dialog_controller_get_new_name (NautilusFileNameWidgetController *controller)
+{
+ NautilusCompressDialogController *self;
+ g_autofree gchar *basename = NULL;
+ 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_label_name;
+ GtkWidget *active_button;
+
+ switch (format)
+ {
+ case NAUTILUS_COMPRESSION_ZIP:
+ {
+ extension = ".zip";
+ description_label_name = "zip-description-label";
+ active_button = self->zip_radio_button;
+ }
+ break;
+
+ case NAUTILUS_COMPRESSION_TAR_XZ:
+ {
+ extension = ".tar.xz";
+ description_label_name = "tar-xz-description-label";
+ active_button = self->tar_xz_radio_button;
+ }
+ break;
+
+ case NAUTILUS_COMPRESSION_7ZIP:
+ {
+ extension = ".7z";
+ description_label_name = "seven-zip-description-label";
+ active_button = self->seven_zip_radio_button;
+ }
+ break;
+
+ default:
+ {
+ g_assert_not_reached ();
+ }
+ break;
+ }
+
+ self->extension = extension;
+
+ gtk_stack_set_visible_child_name (GTK_STACK (self->description_stack),
+ description_label_name);
+
+ 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 = NULL;
+ GtkWidget *compress_dialog;
+ GtkWidget *error_revealer;
+ GtkWidget *error_label;
+ GtkWidget *name_entry;
+ GtkWidget *activate_button;
+ GtkWidget *description_stack;
+ 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_revealer = GTK_WIDGET (gtk_builder_get_object (builder, "error_revealer"));
+ 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_stack = GTK_WIDGET (gtk_builder_get_object (builder, "description_stack"));
+
+ gtk_window_set_transient_for (GTK_WINDOW (compress_dialog),
+ parent_window);
+
+ self = g_object_new (NAUTILUS_TYPE_COMPRESS_DIALOG_CONTROLLER,
+ "error-revealer", error_revealer,
+ "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_stack = description_stack;
+ 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)
+ {
+ g_clear_signal_handler (&self->response_handler_id, self->compress_dialog);
+ 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;
+}