Mercurial > hg > forks > geeqie
changeset 2389:3f644bf81860
CopyMoveRename
In Copy, Move and Rename operations, show a thumbnail of the source file
and, if the destination already exists, show a thumbnail for that also.
Use the Rename dialogue for Copy and Move operations also.
author | Colin Clark <cclark@mcb.net> |
---|---|
date | Wed, 20 Jul 2016 13:20:24 +0100 |
parents | cedc3017e78a |
children | 8677e636f51c |
files | src/filedata.c src/utilops.c |
diffstat | 2 files changed, 191 insertions(+), 50 deletions(-) [+] |
line wrap: on
line diff
--- a/src/filedata.c Fri Jul 15 18:39:02 2016 +0100 +++ b/src/filedata.c Wed Jul 20 13:20:24 2016 +0100 @@ -376,8 +376,15 @@ if (fd) { DEBUG_1("planned change: using %s -> %s", path_utf8, fd->path); - file_data_ref(fd); - file_data_apply_ci(fd); + if (!isfile(fd->path)) + { + file_data_ref(fd); + file_data_apply_ci(fd); + } + else + { + fd = NULL; + } } } @@ -2412,7 +2419,9 @@ /* During a rename operation, check if another planned destination file has * the same filename */ - if(fd->change->type == FILEDATA_CHANGE_RENAME) + if(fd->change->type == FILEDATA_CHANGE_RENAME || + fd->change->type == FILEDATA_CHANGE_COPY || + fd->change->type == FILEDATA_CHANGE_MOVE) { work = list; while (work)
--- a/src/utilops.c Fri Jul 15 18:39:02 2016 +0100 +++ b/src/utilops.c Wed Jul 20 13:20:24 2016 +0100 @@ -52,37 +52,38 @@ *-------------------------------------------------------------------------- */ -#define DIALOG_DEF_IMAGE_DIM_X 200 -#define DIALOG_DEF_IMAGE_DIM_Y 150 +#define DIALOG_DEF_IMAGE_DIM_X 150 +#define DIALOG_DEF_IMAGE_DIM_Y 100 static void generic_dialog_add_image(GenericDialog *gd, GtkWidget *box, FileData *fd1, const gchar *header1, + gboolean second_image, FileData *fd2, const gchar *header2, gboolean show_filename) { ImageWindow *imd; - GtkWidget *hbox = NULL; + GtkWidget *preview_box = NULL; GtkWidget *vbox; GtkWidget *label = NULL; if (!box) box = gd->vbox; - if (fd2) + if (second_image) { - hbox = pref_box_new(box, TRUE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE); + preview_box = pref_box_new(box, TRUE, GTK_ORIENTATION_VERTICAL, PREF_PAD_SPACE); } /* image 1 */ vbox = gtk_vbox_new(FALSE, PREF_PAD_GAP); - if (hbox) + if (preview_box) { GtkWidget *sep; - gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0); - - sep = gtk_vseparator_new(); - gtk_box_pack_start(GTK_BOX(hbox), sep, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(preview_box), vbox, TRUE, TRUE, 0); + + sep = gtk_hseparator_new(); + gtk_box_pack_start(GTK_BOX(preview_box), sep, FALSE, FALSE, 0); gtk_widget_show(sep); } else @@ -119,9 +120,9 @@ /* image 2 */ - if (hbox && fd2) + if (preview_box) { - vbox = pref_box_new(hbox, TRUE, GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP); + vbox = pref_box_new(preview_box, TRUE, GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP); if (header2) { @@ -136,27 +137,18 @@ g_object_set(G_OBJECT(imd->pr), "zoom_expand", FALSE, NULL); gtk_widget_set_size_request(imd->widget, DIALOG_DEF_IMAGE_DIM_X, DIALOG_DEF_IMAGE_DIM_Y); gtk_box_pack_start(GTK_BOX(vbox), imd->widget, TRUE, TRUE, 0); - image_change_fd(imd, fd2, 0.0); + if (fd2) image_change_fd(imd, fd2, 0.0); gtk_widget_show(imd->widget); - pref_label_new(vbox, fd2->name); + if (show_filename) + { + label = pref_label_new(vbox, (fd2 == NULL) ? "" : fd2->name); + } + g_object_set_data(G_OBJECT(gd->dialog), "img_image2", imd); + g_object_set_data(G_OBJECT(gd->dialog), "img_label2", label); } } -static void generic_dialog_image_set(GenericDialog *gd, FileData *fd) -{ - ImageWindow *imd; - GtkWidget *label; - - imd = g_object_get_data(G_OBJECT(gd->dialog), "img_image"); - label = g_object_get_data(G_OBJECT(gd->dialog), "img_label"); - - if (!imd) return; - - image_change_fd(imd, fd, 0.0); - if (label) gtk_label_set_text(GTK_LABEL(label), fd->name); -} - /* *-------------------------------------------------------------------------- * Wrappers to aid in setting additional dialog properties (unde mouse, etc.) @@ -259,6 +251,7 @@ typedef enum { UTILITY_PHASE_START = 0, + UTILITY_PHASE_INTERMEDIATE, UTILITY_PHASE_ENTERING, UTILITY_PHASE_CHECKED, UTILITY_PHASE_DONE, @@ -358,6 +351,48 @@ guint idle_id; /* event source id */ }; +static void generic_dialog_image_set(UtilityData *ud, FileData *fd) +{ + ImageWindow *imd; + GtkWidget *label; + FileData *fd2 = NULL; + gchar *buf; + + imd = g_object_get_data(G_OBJECT(ud->gd->dialog), "img_image"); + label = g_object_get_data(G_OBJECT(ud->gd->dialog), "img_label"); + + if (!imd) return; + + image_change_fd(imd, fd, 0.0); + buf = g_strjoin("\n", text_from_time(fd->date), text_from_size(fd->size), NULL); + if (label) gtk_label_set_text(GTK_LABEL(label), buf); + g_free(buf); + + if (ud->type == UTILITY_TYPE_RENAME || ud->type == UTILITY_TYPE_COPY || ud->type == UTILITY_TYPE_MOVE) + { + imd = g_object_get_data(G_OBJECT(ud->gd->dialog), "img_image2"); + label = g_object_get_data(G_OBJECT(ud->gd->dialog), "img_label2"); + + if (imd) + { + if (isfile(fd->change->dest)) + { + fd2 = file_data_new_group(fd->change->dest); + image_change_fd(imd, fd2, 0.0); + buf = g_strjoin("\n", text_from_time(fd2->date), text_from_size(fd2->size), NULL); + if (label && fd->change->dest) gtk_label_set_text(GTK_LABEL(label), buf); + file_data_unref(fd2); + g_free(buf); + } + else + { + image_change_fd(imd, NULL, 0.0); + if (label) gtk_label_set_text(GTK_LABEL(label), ""); + } + } + } +} + static gboolean file_util_write_metadata_first(UtilityType type, UtilityPhase phase, GList *flist, const gchar *dest_path, const gchar *editor_key, GtkWidget *parent); #define UTILITY_LIST_MIN_WIDTH 250 @@ -1095,14 +1130,37 @@ static void file_util_fdlg_ok_cb(FileDialog *fdlg, gpointer data) { UtilityData *ud = data; + gchar *desc = NULL; + GenericDialog *d = NULL; file_util_dest_folder_update_path(ud); - if (isdir(ud->dest_path)) file_dialog_sync_history(fdlg, TRUE); - file_dialog_close(fdlg); - - ud->fdlg = NULL; - - file_util_dialog_run(ud); + if (isdir(ud->dest_path)) + { + file_dialog_sync_history(fdlg, TRUE); + file_dialog_close(fdlg); + ud->fdlg = NULL; + file_util_dialog_run(ud); + } + else + { + /* During copy/move operations it is necessary to ensure that the + * target directory exists before continuing with the next step. + * If not revert to the select directory dialog + */ + desc = g_strdup_printf(_("%s is not a directory"), ud->dest_path); + + d = file_util_gen_dlg(ud->messages.title, "dlg_confirm", + ud->parent, TRUE, + file_util_check_abort_cb, ud); + generic_dialog_add_message(d, GTK_STOCK_DIALOG_WARNING, _("This operation can't continue:"), desc); + + gtk_widget_show(d->dialog); + ud->phase = UTILITY_PHASE_START; + + file_dialog_close(fdlg); + ud->fdlg = NULL; + g_free(desc); + } } @@ -1176,7 +1234,8 @@ { GtkTreeModel *store; GtkTreeSelection *selection; - GtkTreeIter iter; + GtkTreeIter iter, iter_selected; + GtkTreePath *path_iter, *path_selected; const gchar *front; const gchar *end; const gchar *format; @@ -1185,6 +1244,8 @@ gint padding; gint n; gint mode; + gchar *dirname; + gchar *destname; mode = gtk_notebook_get_current_page(GTK_NOTEBOOK(ud->notebook)); @@ -1198,7 +1259,23 @@ 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); + + dirname = g_path_get_dirname(fd->change->dest); + destname = g_build_filename(dirname, dest, NULL); + switch (ud->type) + { + case UTILITY_TYPE_RENAME: + file_data_sc_update_ci_rename(fd, dest); + break; + case UTILITY_TYPE_COPY: + file_data_sc_update_ci_copy(fd, destname); + break; + case UTILITY_TYPE_MOVE: + file_data_sc_update_ci_move(fd, destname); + break; + default:; + } + generic_dialog_image_set(ud, fd); gtk_list_store_set(GTK_LIST_STORE(store), &iter, UTILITY_COLUMN_DEST_PATH, fd->change->dest, @@ -1242,13 +1319,43 @@ } g_assert(ud->with_sidecars); /* sidecars must be renamed too, it would break the pairing otherwise */ - file_data_sc_update_ci_rename(fd, dest); + + dirname = g_path_get_dirname(fd->change->dest); + destname = g_build_filename(dirname, dest, NULL); + + switch (ud->type) + { + case UTILITY_TYPE_RENAME: + file_data_sc_update_ci_rename(fd, dest); + break; + case UTILITY_TYPE_COPY: + file_data_sc_update_ci_copy(fd, destname); + break; + case UTILITY_TYPE_MOVE: + file_data_sc_update_ci_move(fd, destname); + break; + default:; + } + + g_free(dirname); + g_free(destname); + g_free(dest); + + selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(ud->listview)); + gtk_tree_selection_get_selected(selection, &store, &iter_selected); + path_iter=gtk_tree_model_get_path(store,&iter); + path_selected=gtk_tree_model_get_path(store,&iter_selected); + if (!gtk_tree_path_compare(path_iter,path_selected)) + { + generic_dialog_image_set(ud, fd); + } + gtk_tree_path_free(path_iter); + gtk_tree_path_free(path_selected); + 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); } @@ -1317,11 +1424,11 @@ !gtk_tree_model_get_iter(store, &iter, tpath)) return TRUE; gtk_tree_model_get(store, &iter, UTILITY_COLUMN_FD, &fd, -1); - generic_dialog_image_set(ud->gd, fd); + generic_dialog_image_set(ud, fd); ud->sel_fd = fd; - if (ud->type == UTILITY_TYPE_RENAME) + if (ud->type == UTILITY_TYPE_RENAME || ud->type == UTILITY_TYPE_COPY || ud->type == UTILITY_TYPE_MOVE) { const gchar *name = filename_from_path(fd->change->dest); @@ -1413,7 +1520,7 @@ gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE); gtk_tree_selection_set_select_function(selection, file_util_preview_cb, ud, NULL); - generic_dialog_add_image(ud->gd, box, NULL, NULL, NULL, NULL, FALSE); + generic_dialog_add_image(ud->gd, box, NULL, NULL, FALSE, NULL, NULL, FALSE); if (ud->type == UTILITY_TYPE_DELETE || ud->type == UTILITY_TYPE_DELETE_LINK || @@ -1479,7 +1586,7 @@ } -static void file_util_dialog_init_source_dest(UtilityData *ud) +static void file_util_dialog_init_source_dest(UtilityData *ud, gboolean second_image) { GtkTreeModel *store; GtkTreeSelection *selection; @@ -1522,7 +1629,14 @@ G_CALLBACK(file_util_rename_preview_order_cb), ud); gtk_widget_set_size_request(ud->listview, 300, 150); - generic_dialog_add_image(ud->gd, box, NULL, NULL, NULL, NULL, FALSE); + if (second_image) + { + generic_dialog_add_image(ud->gd, box, NULL, "Source", TRUE, NULL, "Destination", TRUE); + } + else + { + generic_dialog_add_image(ud->gd, box, NULL, NULL, FALSE, NULL, NULL, FALSE); + } // gtk_container_add(GTK_CONTAINER(scrolled), view); gtk_widget_show(ud->gd->dialog); @@ -1678,21 +1792,37 @@ case UTILITY_TYPE_EDITOR: case UTILITY_TYPE_WRITE_METADATA: file_util_dialog_init_simple_list(ud); + ud->phase = UTILITY_PHASE_ENTERING; break; case UTILITY_TYPE_RENAME: - file_util_dialog_init_source_dest(ud); + file_util_dialog_init_source_dest(ud, TRUE); + ud->phase = UTILITY_PHASE_ENTERING; break; case UTILITY_TYPE_COPY: case UTILITY_TYPE_MOVE: + file_util_dialog_init_dest_folder(ud); + ud->phase = UTILITY_PHASE_INTERMEDIATE; + break; case UTILITY_TYPE_FILTER: case UTILITY_TYPE_CREATE_FOLDER: file_util_dialog_init_dest_folder(ud); + ud->phase = UTILITY_PHASE_ENTERING; break; case UTILITY_TYPE_RENAME_FOLDER: ud->phase = UTILITY_PHASE_CANCEL; /* FIXME - not handled for now */ file_util_dialog_run(ud); return; } + break; + case UTILITY_PHASE_INTERMEDIATE: + switch (ud->type) + { + case UTILITY_TYPE_COPY: + case UTILITY_TYPE_MOVE: + file_util_dialog_init_source_dest(ud, TRUE); + break; + default:; + } ud->phase = UTILITY_PHASE_ENTERING; break; case UTILITY_PHASE_ENTERING: @@ -1847,7 +1977,7 @@ box = generic_dialog_add_message(gd, stock_id, _("File details"), message); - generic_dialog_add_image(gd, box, fd, NULL, NULL, NULL, FALSE); + generic_dialog_add_image(gd, box, fd, NULL, FALSE, NULL, NULL, FALSE); gtk_widget_show(gd->dialog); @@ -1944,7 +2074,7 @@ i++; } - generic_dialog_add_image(gd, box, fd, NULL, NULL, NULL, FALSE); + generic_dialog_add_image(gd, box, fd, NULL, FALSE, NULL, NULL, FALSE); gtk_widget_set_size_request(gd->dialog, DIALOG_WIDTH, -1); gtk_widget_show(gd->dialog); @@ -2090,6 +2220,7 @@ ud->flist = flist; ud->content_list = NULL; ud->parent = parent; + ud->details_func = file_util_details_dialog; if (dest_path) ud->dest_path = g_strdup(dest_path); @@ -2139,6 +2270,7 @@ ud->flist = flist; ud->content_list = NULL; ud->parent = parent; + ud->details_func = file_util_details_dialog; if (dest_path) ud->dest_path = g_strdup(dest_path);