Skip to content

Commit

Permalink
Issue #332 Rename function can delete files
Browse files Browse the repository at this point in the history
#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.
  • Loading branch information
Colin Clark committed Apr 13, 2016
1 parent cd4334e commit 010ed5d
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 50 deletions.
38 changes: 33 additions & 5 deletions src/filedata.c
Original file line number Diff line number Diff line change
Expand Up @@ -2184,10 +2184,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)
{
Expand Down Expand Up @@ -2397,6 +2399,26 @@ gint file_data_verify_ci(FileData *fd)
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);

Expand All @@ -2405,19 +2427,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;
}

Expand Down Expand Up @@ -2500,6 +2522,12 @@ gchar *file_data_get_error_string(gint error)
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);
}

Expand All @@ -2526,7 +2554,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;

Expand Down
4 changes: 2 additions & 2 deletions src/filedata.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,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);
Expand All @@ -135,7 +135,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);
Expand Down
1 change: 1 addition & 0 deletions src/typedefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ typedef enum {
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,
Expand Down
101 changes: 58 additions & 43 deletions src/utilops.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

/*
*--------------------------------------------------------------------------
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -891,7 +891,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;
Expand All @@ -913,7 +913,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;

Expand Down Expand Up @@ -957,7 +957,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
Expand Down Expand Up @@ -1191,59 +1191,74 @@ 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),
-1);
UTILITY_COLUMN_DEST_PATH, fd->change->dest,
UTILITY_COLUMN_DEST_NAME, filename_from_path(fd->change->dest),
-1);
}
return;
}
else
{
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));

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));
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));
}

format = gtk_entry_get_text(GTK_ENTRY(ud->format_entry));
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)
{
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));
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);
}
}

store = gtk_tree_view_get_model(GTK_TREE_VIEW(ud->listview));
n = start_n;
/* 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)
{
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_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);
}

Expand Down Expand Up @@ -1782,7 +1797,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)
{
Expand Down

0 comments on commit 010ed5d

Please sign in to comment.