summaryrefslogtreecommitdiff
path: root/src/nautilus-rename-file-popover-controller.c
diff options
context:
space:
mode:
authorRazvan Chitu <razvan.ch95@gmail.com>2016-07-30 18:50:10 +0300
committerRazvan Chitu <razvan.ch95@gmail.com>2016-08-19 15:52:16 +0300
commitfd873c5086e53ee8624a6412c3dd6ff4d263c04b (patch)
tree00cd4b873d1c479010a61c9b01d445304ae35c74 /src/nautilus-rename-file-popover-controller.c
parent58f62f331889aca434f5f4831c2747eaa89c7756 (diff)
downloadnautilus-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.c223
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;
+}