Hi
If multiple files are selected for renaming and the manual rename option
is used, it is possible to input the same destination filename for more
than one file.
If the operation is executed, files will be overwritten with no warning.
I don't think this should be permitted to happen with a program like
Geeqie - inexperienced users should be given more protection.
I have attached a patch which might solve the problem. Perhaps someone
else could review the code?
Colin Clark
diff --git a/src/filedata.c b/src/filedata.c
index 388037f..bd73058 100644
--- a/src/filedata.c
+++ b/src/filedata.c
@@ -2014,10 +2014,12 @@ gboolean file_data_sc_update_ci_unspecified_list(GList *fd_list, const gchar *de
* 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)
{
@@ -2227,6 +2229,26 @@ gint file_data_verify_ci(FileData *fd)
g_free(dest_dir);
}
+ /* During a rename operation, check if another 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_WARN_DUPLICATE_DEST;
+ }
+ }
+ }
+ }
+
fd->change->error = ret;
if (ret == 0) DEBUG_1("Change checked: OK: %s", fd->path);
@@ -2235,19 +2257,19 @@ gint file_data_verify_ci(FileData *fd)
}
-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;
}
@@ -2330,6 +2352,12 @@ gchar *file_data_get_error_string(gint error)
g_string_append(result, _("there are unsaved metadata changes for the file"));
}
+ if (error & CHANGE_WARN_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);
}
@@ -2356,7 +2384,7 @@ gint file_data_verify_ci_list(GList *list, gchar **desc, gboolean with_sidecars)
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 --git a/src/filedata.h b/src/filedata.h
index d3c5c63..03b3ae4 100644
--- a/src/filedata.h
+++ b/src/filedata.h
@@ -110,7 +110,7 @@ gboolean file_data_sc_update_ci_unspecified(FileData *fd, const gchar *dest_path
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);
@@ -120,7 +120,7 @@ void file_data_free_ci_list(GList *fd_list);
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 --git a/src/typedefs.h b/src/typedefs.h
index cc10b54..c535908 100644
--- a/src/typedefs.h
+++ b/src/typedefs.h
@@ -159,6 +159,7 @@ typedef enum {
CHANGE_WARN_SAME = 1 << 2,
CHANGE_WARN_CHANGED_EXT = 1 << 3,
CHANGE_WARN_UNSAVED_META = 1 << 4,
+ CHANGE_WARN_DUPLICATE_DEST = 1 << 5,
CHANGE_ERROR_MASK = (~0) << 8, /* the values below are fatal errors */
CHANGE_NO_READ_PERM = 1 << 8,
CHANGE_NO_WRITE_PERM_DIR = 1 << 9,
diff --git a/src/utilops.c b/src/utilops.c
index e32a18d..f6b2469 100644
--- a/src/utilops.c
+++ b/src/utilops.c
@@ -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 @@ static GtkWidget *file_util_dialog_add_list(GtkWidget *box, GList *list, gboolea
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,
@@ -893,7 +893,7 @@ void file_util_perform_ci(UtilityData *ud)
}
}
-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;
@@ -915,7 +915,7 @@ static GdkPixbuf *file_util_get_error_icon(FileData *fd, GtkWidget *widget)
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;
@@ -959,7 +959,7 @@ void file_util_check_ci(UtilityData *ud)
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
@@ -1193,11 +1193,26 @@ static void file_util_rename_preview_update(UtilityData *ud)
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),
+ UTILITY_COLUMN_DEST_PATH, fd->change->dest,
+ UTILITY_COLUMN_DEST_NAME, filename_from_path(fd->change->dest),
+ -1);
+
+ /* 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)
+ {
+ 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->flist, ud->listview),
-1);
+ valid = gtk_tree_model_iter_next(store, &iter);
+ }
}
return;
}
@@ -1239,7 +1254,7 @@ static void file_util_rename_preview_update(UtilityData *ud)
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_PIXBUF, file_util_get_error_icon(fd, ud->flist, ud->listview),
UTILITY_COLUMN_DEST_PATH, fd->change->dest,
UTILITY_COLUMN_DEST_NAME, filename_from_path(fd->change->dest),
-1);
@@ -1784,7 +1799,7 @@ static gchar *file_util_details_get_message(UtilityData *ud, FileData *fd, const
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)
{
------------------------------------------------------------------------------
Special Offer-- Download ArcSight Logger for FREE (a $49 USD value)!
Finally, a world-class log management solution at an even better price-free!
Download using promo code Free_Logger_4_Dev2Dev. Offer expires
February 28th, so secure your free ArcSight Logger TODAY!
http://p.sf.net/sfu/arcsight-sfd2d
_______________________________________________
Geeqie-devel mailing list
Geeqie-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/geeqie-devel