/* 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 .
*
*/
#include
#include
#include
#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;
}