diff options
author | Razvan Chitu <razvan.ch95@gmail.com> | 2016-07-30 18:50:10 +0300 |
---|---|---|
committer | Razvan Chitu <razvan.ch95@gmail.com> | 2016-08-19 15:52:16 +0300 |
commit | fd873c5086e53ee8624a6412c3dd6ff4d263c04b (patch) | |
tree | 00cd4b873d1c479010a61c9b01d445304ae35c74 /src/nautilus-rename-file-popover-controller.c | |
parent | 58f62f331889aca434f5f4831c2747eaa89c7756 (diff) | |
download | nautilus-fd873c5086e53ee8624a6412c3dd6ff4d263c04b.tar.gz |
files-view: move file name widget logic to separate controllers
The rename file popover and the new folder dialog share common logic for
validating file names entered by the user. The control logic was implemented
with a simple structure in files-view. Besides common logic, the structure also
held parameters specific to only one of the operations. Another problem is that
the current implementation does not allow flexibility in obtaining the file name
from the widgets and displaying error messages.
In order to fix this, reimplement the structure as an abstract class and create
two subclasses for the "Rename" and "New Folder" widgets.
https://bugzilla.gnome.org/show_bug.cgi?id=769336
Diffstat (limited to 'src/nautilus-rename-file-popover-controller.c')
-rw-r--r-- | src/nautilus-rename-file-popover-controller.c | 223 |
1 files changed, 223 insertions, 0 deletions
diff --git a/src/nautilus-rename-file-popover-controller.c b/src/nautilus-rename-file-popover-controller.c new file mode 100644 index 000000000..36a7c3451 --- /dev/null +++ b/src/nautilus-rename-file-popover-controller.c @@ -0,0 +1,223 @@ +#include <glib/gi18n.h> + +#include <eel/eel-vfs-extensions.h> + +#include "nautilus-rename-file-popover-controller.h" + +#include "nautilus-directory.h" +#include "nautilus-file-private.h" + + +#define RENAME_ENTRY_MIN_CHARS 20 +#define RENAME_ENTRY_MAX_CHARS 35 + +struct _NautilusRenameFilePopoverController { + NautilusFileNameWidgetController parent_instance; + + NautilusFile *target_file; + gboolean target_is_folder; + + GtkWidget *rename_file_popover; + + gint closed_handler_id; +}; + +G_DEFINE_TYPE (NautilusRenameFilePopoverController, nautilus_rename_file_popover_controller, NAUTILUS_TYPE_FILE_NAME_WIDGET_CONTROLLER) + +static void +rename_file_popover_controller_on_closed (GtkPopover *popover, + gpointer user_data) +{ + NautilusRenameFilePopoverController *controller; + + controller = NAUTILUS_RENAME_FILE_POPOVER_CONTROLLER (user_data); + + g_signal_handler_disconnect (controller->rename_file_popover, + controller->closed_handler_id); + controller->closed_handler_id = 0; + controller->rename_file_popover = NULL; + + g_signal_emit_by_name (controller, "cancelled"); +} + +static gboolean +nautilus_rename_file_popover_controller_name_is_valid (NautilusFileNameWidgetController *controller, + gchar *name, + gchar **error_message) +{ + NautilusRenameFilePopoverController *self; + + self = NAUTILUS_RENAME_FILE_POPOVER_CONTROLLER (controller); + + if (strlen (name) == 0) { + return FALSE; + } + + if (strstr (name, "/") != NULL) { + if (self->target_is_folder) { + *error_message = _("Folder names cannot contain “/”."); + } + else { + *error_message = _("File names cannot contain “/”."); + } + } else if (strcmp (name, ".") == 0){ + if (self->target_is_folder) { + *error_message = _("A folder cannot be called “.”."); + } + else { + *error_message = _("A file cannot be called “.”."); + } + } else if (strcmp (name, "..") == 0){ + if (self->target_is_folder) { + *error_message = _("A folder cannot be called “..”."); + } + else { + *error_message = _("A file cannot be called “..”."); + } + } + + return *error_message == NULL; +} + +static gboolean +nautilus_rename_file_popover_controller_ignore_existing_file (NautilusFileNameWidgetController *controller, + NautilusFile *existing_file) +{ + NautilusRenameFilePopoverController *self; + g_autofree gchar *display_name; + + self = NAUTILUS_RENAME_FILE_POPOVER_CONTROLLER (controller); + + display_name = nautilus_file_get_display_name (existing_file); + + return nautilus_file_compare_display_name (self->target_file, display_name) == 0; +} + +NautilusRenameFilePopoverController * +nautilus_rename_file_popover_controller_new (NautilusFile *target_file, + GdkRectangle *pointing_to, + GtkWidget *relative_to) +{ + NautilusRenameFilePopoverController *self; + g_autoptr (GtkBuilder) builder; + GtkWidget *rename_file_popover; + GtkWidget *error_label; + GtkWidget *name_entry; + GtkWidget *activate_button; + GtkWidget *name_label; + NautilusDirectory *containing_directory; + gint start_offset; + gint end_offset; + gint n_chars; + + builder = gtk_builder_new_from_resource ("/org/gnome/nautilus/ui/nautilus-rename-file-popover.ui"); + rename_file_popover = GTK_WIDGET (gtk_builder_get_object (builder, "rename_file_popover")); + 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, "rename_button")); + name_label = GTK_WIDGET (gtk_builder_get_object (builder, "name_label")); + + if (!nautilus_file_is_self_owned (target_file)) { + NautilusFile *parent_location; + + parent_location = nautilus_file_get_parent (target_file); + containing_directory = nautilus_directory_get_for_file (parent_location); + + nautilus_file_unref (parent_location); + } else { + containing_directory = nautilus_directory_get_for_file (target_file); + } + + self = g_object_new (NAUTILUS_TYPE_RENAME_FILE_POPOVER_CONTROLLER, + "error-label", error_label, + "name-entry", name_entry, + "activate-button", activate_button, + "containing-directory", containing_directory, NULL); + + self->target_is_folder = nautilus_file_is_directory (target_file); + self->target_file = nautilus_file_ref (target_file); + + self->rename_file_popover = rename_file_popover; + + self->closed_handler_id = g_signal_connect (rename_file_popover, + "closed", + (GCallback)rename_file_popover_controller_on_closed, + self); + g_signal_connect (rename_file_popover, + "unmap", + (GCallback)gtk_widget_destroy, + NULL); + + gtk_label_set_text (GTK_LABEL (name_label), + self->target_is_folder ? _("Folder name") : + _("File name")); + + gtk_entry_set_text (GTK_ENTRY (name_entry), + nautilus_file_get_display_name (target_file)); + + gtk_popover_set_default_widget (GTK_POPOVER (rename_file_popover), name_entry); + gtk_popover_set_pointing_to (GTK_POPOVER (rename_file_popover), pointing_to); + gtk_popover_set_relative_to (GTK_POPOVER (rename_file_popover), relative_to); + + gtk_widget_show (rename_file_popover); + + /* Select the name part withouth the file extension */ + eel_filename_get_rename_region (nautilus_file_get_display_name (target_file), + &start_offset, &end_offset); + n_chars = g_utf8_strlen (nautilus_file_get_display_name (target_file), -1); + gtk_entry_set_width_chars (GTK_ENTRY (name_entry), + MIN (MAX (n_chars, RENAME_ENTRY_MIN_CHARS), RENAME_ENTRY_MAX_CHARS)); + gtk_editable_select_region (GTK_EDITABLE (name_entry), start_offset, end_offset); + + nautilus_directory_unref (containing_directory); + + return self; +} + +NautilusFile * +nautilus_rename_file_popover_controller_get_target_file (NautilusRenameFilePopoverController *self) +{ + g_return_val_if_fail (NAUTILUS_IS_RENAME_FILE_POPOVER_CONTROLLER (self), NULL); + + return self->target_file; +} + +static void +nautilus_rename_file_popover_controller_init (NautilusRenameFilePopoverController *self) +{ + +} + +static void +nautilus_rename_file_popover_controller_finalize (GObject *object) +{ + NautilusRenameFilePopoverController *self; + + self = NAUTILUS_RENAME_FILE_POPOVER_CONTROLLER (object); + + if (self->rename_file_popover) { + if (self->closed_handler_id) { + g_signal_handler_disconnect (self->rename_file_popover, + self->closed_handler_id); + self->closed_handler_id = 0; + } + gtk_widget_hide (self->rename_file_popover); + self->rename_file_popover = NULL; + } + + nautilus_file_unref (self->target_file); + + G_OBJECT_CLASS (nautilus_rename_file_popover_controller_parent_class)->finalize (object); +} + +static void +nautilus_rename_file_popover_controller_class_init (NautilusRenameFilePopoverControllerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NautilusFileNameWidgetControllerClass *parent_class = NAUTILUS_FILE_NAME_WIDGET_CONTROLLER_CLASS (klass); + + object_class->finalize = nautilus_rename_file_popover_controller_finalize; + + parent_class->name_is_valid = nautilus_rename_file_popover_controller_name_is_valid; + parent_class->ignore_existing_file = nautilus_rename_file_popover_controller_ignore_existing_file; +} |