# HG changeset patch # User Colin Clark # Date 1460569992 -3600 # Node ID 38f6ecad0b5318c4d0cf0aeafe097ff8217e8d34 # Parent 00773211590e3f5b999bb37afcf070edc2325208 Issue #332 Rename function can delete files https://github.com/BestImageViewer/geeqie/issues/332 During a Rename operation, if the user assigns a single destination filename to multiple source files, an error dialog is shown and the operation is aborted. diff -r 00773211590e -r 38f6ecad0b53 src/filedata.c --- a/src/filedata.c Tue Apr 12 21:35:11 2016 +0200 +++ b/src/filedata.c Wed Apr 13 18:53:12 2016 +0100 @@ -2184,10 +2184,12 @@ * it should detect all possible problems with the planned operation */ -gint file_data_verify_ci(FileData *fd) +gint file_data_verify_ci(FileData *fd, GList *list) { gint ret = CHANGE_OK; gchar *dir; + GList *work = NULL; + FileData *fd1 = NULL; if (!fd->change) { @@ -2397,6 +2399,26 @@ g_free(dest_dir); } + /* During a rename operation, check if another planned destination file has + * the same filename + */ + if(fd->change->type == FILEDATA_CHANGE_RENAME) + { + work = list; + while (work) + { + fd1 = work->data; + work = work->next; + if (fd1 != NULL && fd != fd1 ) + { + if (!strcmp(fd->change->dest, fd1->change->dest)) + { + ret |= CHANGE_DUPLICATE_DEST; + } + } + } + } + fd->change->error = ret; if (ret == 0) DEBUG_1("Change checked: OK: %s", fd->path); @@ -2405,19 +2427,19 @@ } -gint file_data_sc_verify_ci(FileData *fd) +gint file_data_sc_verify_ci(FileData *fd, GList *list) { GList *work; gint ret; - ret = file_data_verify_ci(fd); + ret = file_data_verify_ci(fd, list); work = fd->sidecar_files; while (work) { FileData *sfd = work->data; - ret |= file_data_verify_ci(sfd); + ret |= file_data_verify_ci(sfd, list); work = work->next; } @@ -2500,6 +2522,12 @@ g_string_append(result, _("there are unsaved metadata changes for the file")); } + if (error & CHANGE_DUPLICATE_DEST) + { + if (result->len > 0) g_string_append(result, ", "); + g_string_append(result, _("another destination file has the same filename")); + } + return g_string_free(result, FALSE); } @@ -2526,7 +2554,7 @@ fd = work->data; work = work->next; - error = with_sidecars ? file_data_sc_verify_ci(fd) : file_data_verify_ci(fd); + error = with_sidecars ? file_data_sc_verify_ci(fd, list) : file_data_verify_ci(fd, list); all_errors |= error; common_errors &= error; diff -r 00773211590e -r 38f6ecad0b53 src/filedata.h --- a/src/filedata.h Tue Apr 12 21:35:11 2016 +0200 +++ b/src/filedata.h Wed Apr 13 18:53:12 2016 +0100 @@ -125,7 +125,7 @@ gchar *file_data_get_error_string(gint error); -gint file_data_verify_ci(FileData *fd); +gint file_data_verify_ci(FileData *fd, GList *list); gint file_data_verify_ci_list(GList *list, gchar **desc, gboolean with_sidecars); gboolean file_data_perform_ci(FileData *fd); @@ -135,7 +135,7 @@ void file_data_set_regroup_when_finished(FileData *fd, gboolean enable); -gint file_data_sc_verify_ci(FileData *fd); +gint file_data_sc_verify_ci(FileData *fd, GList *list); gboolean file_data_sc_perform_ci(FileData *fd); gboolean file_data_sc_apply_ci(FileData *fd); diff -r 00773211590e -r 38f6ecad0b53 src/typedefs.h --- a/src/typedefs.h Tue Apr 12 21:35:11 2016 +0200 +++ b/src/typedefs.h Wed Apr 13 18:53:12 2016 +0100 @@ -165,6 +165,7 @@ CHANGE_NO_READ_PERM = 1 << 8, CHANGE_NO_WRITE_PERM_DIR = 1 << 9, CHANGE_NO_DEST_DIR = 1 << 10, + CHANGE_DUPLICATE_DEST = 1 << 11, CHANGE_NO_WRITE_PERM_DEST = 1 << 12, CHANGE_DEST_EXISTS = 1 << 13, CHANGE_NO_SRC = 1 << 14, diff -r 00773211590e -r 38f6ecad0b53 src/utilops.c --- a/src/utilops.c Tue Apr 12 21:35:11 2016 +0200 +++ b/src/utilops.c Wed Apr 13 18:53:12 2016 +0100 @@ -36,7 +36,7 @@ #define DIALOG_WIDTH 750 -static GdkPixbuf *file_util_get_error_icon(FileData *fd, GtkWidget *widget); +static GdkPixbuf *file_util_get_error_icon(FileData *fd, GList *list, GtkWidget *widget); /* *-------------------------------------------------------------------------- @@ -473,7 +473,7 @@ gchar *sidecars; sidecars = with_sidecars ? file_data_sc_list_to_string(fd) : NULL; - GdkPixbuf *icon = file_util_get_error_icon(fd, view); + GdkPixbuf *icon = file_util_get_error_icon(fd, list, view); gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, UTILITY_COLUMN_FD, fd, @@ -891,7 +891,7 @@ } } -static GdkPixbuf *file_util_get_error_icon(FileData *fd, GtkWidget *widget) +static GdkPixbuf *file_util_get_error_icon(FileData *fd, GList *list, GtkWidget *widget) { static GdkPixbuf *pb_warning; static GdkPixbuf *pb_error; @@ -913,7 +913,7 @@ pb_apply = gtk_widget_render_icon(widget, GTK_STOCK_APPLY, GTK_ICON_SIZE_MENU, NULL); } - error = file_data_sc_verify_ci(fd); + error = file_data_sc_verify_ci(fd, list); if (!error) return pb_apply; @@ -957,7 +957,7 @@ else if (ud->dir_fd) { g_assert(ud->dir_fd->sidecar_files == NULL); // directories should not have sidecars - error = file_data_verify_ci(ud->dir_fd); + error = file_data_verify_ci(ud->dir_fd, ud->flist); if (error) desc = file_data_get_error_string(error); } else @@ -1191,59 +1191,74 @@ gtk_tree_model_get(store, &iter, UTILITY_COLUMN_FD, &fd, -1); g_assert(ud->with_sidecars); /* sidecars must be renamed too, it would break the pairing otherwise */ file_data_sc_update_ci_rename(fd, dest); + gtk_list_store_set(GTK_LIST_STORE(store), &iter, - UTILITY_COLUMN_PIXBUF, file_util_get_error_icon(fd, ud->listview), - UTILITY_COLUMN_DEST_PATH, fd->change->dest, - UTILITY_COLUMN_DEST_NAME, filename_from_path(fd->change->dest), - -1); + UTILITY_COLUMN_DEST_PATH, fd->change->dest, + UTILITY_COLUMN_DEST_NAME, filename_from_path(fd->change->dest), + -1); } - return; - } - - - front = gtk_entry_get_text(GTK_ENTRY(ud->auto_entry_front)); - end = gtk_entry_get_text(GTK_ENTRY(ud->auto_entry_end)); - padding = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(ud->auto_spin_pad)); - - format = gtk_entry_get_text(GTK_ENTRY(ud->format_entry)); - - if (mode == UTILITY_RENAME_FORMATTED) - { - start_n = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(ud->format_spin)); } else { - start_n = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(ud->auto_spin_start)); - } - - store = gtk_tree_view_get_model(GTK_TREE_VIEW(ud->listview)); - n = start_n; - valid = gtk_tree_model_get_iter_first(store, &iter); - while (valid) - { - gchar *dest; - FileData *fd; - gtk_tree_model_get(store, &iter, UTILITY_COLUMN_FD, &fd, -1); + front = gtk_entry_get_text(GTK_ENTRY(ud->auto_entry_front)); + end = gtk_entry_get_text(GTK_ENTRY(ud->auto_entry_end)); + padding = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(ud->auto_spin_pad)); + + format = gtk_entry_get_text(GTK_ENTRY(ud->format_entry)); if (mode == UTILITY_RENAME_FORMATTED) { - dest = file_util_rename_multiple_auto_format_name(format, fd->name, n); + start_n = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(ud->format_spin)); } else { - dest = g_strdup_printf("%s%0*d%s", front, padding, n, end); + start_n = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(ud->auto_spin_start)); } - g_assert(ud->with_sidecars); /* sidecars must be renamed too, it would break the pairing otherwise */ - file_data_sc_update_ci_rename(fd, dest); + store = gtk_tree_view_get_model(GTK_TREE_VIEW(ud->listview)); + n = start_n; + valid = gtk_tree_model_get_iter_first(store, &iter); + while (valid) + { + gchar *dest; + FileData *fd; + gtk_tree_model_get(store, &iter, UTILITY_COLUMN_FD, &fd, -1); + + if (mode == UTILITY_RENAME_FORMATTED) + { + dest = file_util_rename_multiple_auto_format_name(format, fd->name, n); + } + else + { + dest = g_strdup_printf("%s%0*d%s", front, padding, n, end); + } + + g_assert(ud->with_sidecars); /* sidecars must be renamed too, it would break the pairing otherwise */ + file_data_sc_update_ci_rename(fd, dest); + gtk_list_store_set(GTK_LIST_STORE(store), &iter, + UTILITY_COLUMN_DEST_PATH, fd->change->dest, + UTILITY_COLUMN_DEST_NAME, filename_from_path(fd->change->dest), + -1); + g_free(dest); + + n++; + valid = gtk_tree_model_iter_next(store, &iter); + } + } + + /* Check the other entries in the list - if there are + * multiple destination filenames with the same name the + * error icons must be updated + */ + valid = gtk_tree_model_get_iter_first(store, &iter); + while (valid) + { + FileData *fd; + gtk_tree_model_get(store, &iter, UTILITY_COLUMN_FD, &fd, -1); + gtk_list_store_set(GTK_LIST_STORE(store), &iter, - UTILITY_COLUMN_PIXBUF, file_util_get_error_icon(fd, ud->listview), - UTILITY_COLUMN_DEST_PATH, fd->change->dest, - UTILITY_COLUMN_DEST_NAME, filename_from_path(fd->change->dest), - -1); - g_free(dest); - - n++; + UTILITY_COLUMN_PIXBUF, file_util_get_error_icon(fd, ud->flist, ud->listview), + -1); valid = gtk_tree_model_iter_next(store, &iter); } @@ -1782,7 +1797,7 @@ g_string_append(message, _("\nStatus: ")); - error = ud->with_sidecars ? file_data_sc_verify_ci(fd) : file_data_verify_ci(fd); + error = ud->with_sidecars ? file_data_sc_verify_ci(fd, ud->flist) : file_data_verify_ci(fd, ud->flist); if (error) {