From 819554d92fdd26a1e1050d687573bffbe1436aa0 Mon Sep 17 00:00:00 2001 From: Ernestas Kulik Date: Thu, 12 May 2016 17:23:47 +0300 Subject: files-view: fix renaming logic When renaming a file from the popover, the code checks if there is an existing file with the name entered and the name entered does not match the name of the file being renamed. That has a side effect of allowing the original filename to be entered without reporting an error. Some problems arise when the model includes files from different directories (e.g. when searching or expanding directories in the list view). When searching, the code will not allow a rename if there are files with the entered name, despite being in separate directories. When renaming a file in an expanded directory, the code will ignore files inside it and only check the currently opened one. This also applies when creating new folders. This commit fixes that by checking for duplicate names inside the parent directory when renaming and checking the directory at nautilus_file_view_get_backing_uri() when creating new folders. https://bugzilla.gnome.org/show_bug.cgi?id=757385 --- src/nautilus-files-view.c | 101 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 92 insertions(+), 9 deletions(-) diff --git a/src/nautilus-files-view.c b/src/nautilus-files-view.c index 021943a40..dd28b4f60 100644 --- a/src/nautilus-files-view.c +++ b/src/nautilus-files-view.c @@ -1795,21 +1795,31 @@ validate_file_name (const gchar *name, } static void -file_name_widget_entry_on_changed (gpointer user_data) -{ +file_name_widget_entry_on_directory_info_ready (NautilusDirectory *directory, + GList *files, + gpointer callback_data) { FileNameWidgetData *data; - NautilusFile *existing_file; gchar *name; gchar *error_message; + NautilusFile *existing_file; gboolean valid_name; gboolean duplicated; - data = (FileNameWidgetData *) user_data; + data = (FileNameWidgetData *) callback_data; + + if (data->view == NULL) { + nautilus_directory_unref (directory); + return; + } + + g_object_remove_weak_pointer (G_OBJECT (data->view), + (gpointer *) &data->view); + name = g_strstrip (g_strdup (gtk_entry_get_text (GTK_ENTRY (data->name_entry)))); error_message = validate_file_name (name, data->target_is_folder); gtk_label_set_label (GTK_LABEL (data->error_label), error_message); - existing_file = nautilus_directory_get_file_by_name (data->view->details->model, name); + existing_file = nautilus_directory_get_file_by_name (directory, name); valid_name = strlen (name) > 0 && error_message == NULL; /* If there is a target file and the name is the same, we don't show it @@ -1840,6 +1850,37 @@ file_name_widget_entry_on_changed (gpointer user_data) nautilus_file_unref (existing_file); g_free (name); + + nautilus_directory_unref (directory); +} + +static void +file_name_widget_entry_on_changed (gpointer user_data) +{ + FileNameWidgetData *data; + NautilusFile *parent_location; + NautilusDirectory *containing_dir; + + data = (FileNameWidgetData *) user_data; + + if (data->target_file != NULL && + !nautilus_file_is_self_owned (data->target_file)) { + parent_location = nautilus_file_get_parent (data->target_file); + containing_dir = nautilus_directory_get_for_file (parent_location); + + nautilus_file_unref (parent_location); + } else { + containing_dir = nautilus_directory_get_by_uri (nautilus_files_view_get_backing_uri (data->view)); + } + + g_object_add_weak_pointer (G_OBJECT (data->view), + (gpointer *) &data->view); + + nautilus_directory_call_when_ready (containing_dir, + NAUTILUS_FILE_ATTRIBUTE_INFO, + TRUE, + file_name_widget_entry_on_directory_info_ready, + data); } static void @@ -1916,8 +1957,9 @@ rename_file_on_name_accepted (gpointer user_data) } static void -file_name_widget_on_activate (gpointer user_data) -{ +file_name_widget_on_directory_info_ready (NautilusDirectory *directory, + GList *files, + gpointer callback_data) { FileNameWidgetData *data; NautilusFile *existing_file; gchar *name; @@ -1925,9 +1967,20 @@ file_name_widget_on_activate (gpointer user_data) gboolean valid_name; gboolean duplicated; - data = (FileNameWidgetData *) user_data; + data = (FileNameWidgetData *) callback_data; + + if (data->view == NULL) { + nautilus_directory_unref (directory); + return; + } + + g_object_remove_weak_pointer (G_OBJECT (data->view), + (gpointer *) &data->view); + name = g_strstrip (g_strdup (gtk_entry_get_text (GTK_ENTRY (data->name_entry)))); - existing_file = nautilus_directory_get_file_by_name (data->view->details->model, name); + + existing_file = nautilus_directory_get_file_by_name (directory, name); + error_message = validate_file_name (name, data->target_is_folder); valid_name = strlen (name) > 0 && error_message == NULL; duplicated = existing_file != NULL && @@ -1955,6 +2008,36 @@ file_name_widget_on_activate (gpointer user_data) if (existing_file != NULL) nautilus_file_unref (existing_file); + nautilus_directory_unref (directory); +} + +static void +file_name_widget_on_activate (gpointer user_data) +{ + FileNameWidgetData *data; + NautilusFile *parent_location; + NautilusDirectory *containing_dir; + + data = (FileNameWidgetData *) user_data; + + if (data->target_file != NULL && + !nautilus_file_is_self_owned (data->target_file)) { + parent_location = nautilus_file_get_parent (data->target_file); + containing_dir = nautilus_directory_get_for_file (parent_location); + + nautilus_file_unref (parent_location); + } else { + containing_dir = nautilus_directory_get_by_uri (nautilus_files_view_get_backing_uri (data->view)); + } + + g_object_add_weak_pointer (G_OBJECT (data->view), + (gpointer *) &data->view); + + nautilus_directory_call_when_ready (containing_dir, + NAUTILUS_FILE_ATTRIBUTE_INFO, + TRUE, + file_name_widget_on_directory_info_ready, + data); } static void -- cgit v1.2.1