diff options
Diffstat (limited to 'src/nautilus-compress-dialog-controller.c')
-rw-r--r-- | src/nautilus-compress-dialog-controller.c | 350 |
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; +} |