From 30f9309b8a52bb0bd7ff6ef875795083e4a99969 Mon Sep 17 00:00:00 2001 From: Andrew Borodin Date: Sat, 15 Oct 2022 21:14:35 +0300 Subject: [PATCH] Ticket 4409: continue copy after interrupt. (copy_file_file): add button "Continue copy" to query dialog "Incomplete file was retrieved". (file_ui_op_dlg_callback): callback for copy/move progess dialog. Signed-off-by: Andrew Borodin --- src/filemanager/file.c | 46 ++++++++++++++++++++++++++++++--------- src/filemanager/filegui.c | 26 +++++++++++++++++++--- 2 files changed, 59 insertions(+), 13 deletions(-) diff --git a/src/filemanager/file.c b/src/filemanager/file.c index d3271080c..5303d4028 100644 --- a/src/filemanager/file.c +++ b/src/filemanager/file.c @@ -121,9 +121,11 @@ struct link /* Status of the destination file */ typedef enum { - DEST_NONE = 0, /* Not created */ - DEST_SHORT = 1, /* Created, not fully copied */ - DEST_FULL = 2 /* Created, fully copied */ + DEST_NONE = 0, /**< Not created */ + DEST_SHORT_QUERY, /**< Created, not fully copied, query to do */ + DEST_SHORT_KEEP, /**< Created, not fully copied, keep it */ + DEST_SHORT_DELETE, /**< Created, not fully copied, delete it */ + DEST_FULL /**< Created, fully copied */ } dest_status_t; /* Status of hard link creation */ @@ -2508,7 +2510,8 @@ copy_file_file (file_op_total_context_t * tctx, file_op_context_t * ctx, goto ret; } - dst_status = DEST_SHORT; /* file opened, but not fully copied */ + /* file opened, but not fully copied */ + dst_status = DEST_SHORT_QUERY; appending = ctx->do_append; ctx->do_append = FALSE; @@ -2696,15 +2699,36 @@ copy_file_file (file_op_total_context_t * tctx, file_op_context_t * ctx, mc_refresh (); return_status = check_progress_buttons (ctx); - if (return_status != FILE_CONT) { - mc_refresh (); - goto ret; + int query_res; + + query_res = + query_dialog (Q_ ("DialogTitle|Copy"), + _("Incomplete file was retrieved"), D_ERROR, 3, + _("&Delete"), _("&Keep"), _("&Continue copy")); + + switch (query_res) + { + case 0: + /* delete */ + dst_status = DEST_SHORT_DELETE; + goto ret; + + case 1: + /* keep */ + dst_status = DEST_SHORT_KEEP; + goto ret; + + default: + /* continue copy */ + break; + } } } - dst_status = DEST_FULL; /* copy successful, don't remove target file */ + /* copy successful */ + dst_status = DEST_FULL; } ret: @@ -2734,13 +2758,15 @@ copy_file_file (file_op_total_context_t * tctx, file_op_context_t * ctx, break; } - if (dst_status == DEST_SHORT) + if (dst_status == DEST_SHORT_QUERY) { /* Query to remove short file */ - if (query_dialog (Q_ ("DialogTitle|Copy"), _("Incomplete file was retrieved. Keep it?"), + if (query_dialog (Q_ ("DialogTitle|Copy"), _("Incomplete file was retrieved"), D_ERROR, 2, _("&Delete"), _("&Keep")) == 0) mc_unlink (dst_vpath); } + else if (dst_status == DEST_SHORT_DELETE) + mc_unlink (dst_vpath); else if (dst_status == DEST_FULL && !appending) { /* Copy has succeeded */ diff --git a/src/filemanager/filegui.c b/src/filemanager/filegui.c index cd1154df8..6d213472b 100644 --- a/src/filemanager/filegui.c +++ b/src/filemanager/filegui.c @@ -380,6 +380,27 @@ file_bps_prepare_for_show (char *buffer, long bps) /* --------------------------------------------------------------------------------------------- */ +static cb_ret_t +file_ui_op_dlg_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *data) +{ + switch (msg) + { + case MSG_ACTION: + /* Do not close the dialog because the query dialog will be shown */ + if (parm == CK_Cancel) + { + DIALOG (w)->ret_value = FILE_ABORT; /* for check_progress_buttons() */ + return MSG_HANDLED; + } + return MSG_NOT_HANDLED; + + default: + return dlg_default_callback (w, sender, msg, parm, data); + } +} + +/* --------------------------------------------------------------------------------------------- */ + /* The dialog layout: * * +---------------------- File exists -----------------------+ @@ -828,9 +849,8 @@ file_op_context_create_ui (file_op_context_t * ctx, gboolean with_eta, ui = ctx->ui; ui->replace_result = REPLACE_YES; - ui->op_dlg = - dlg_create (TRUE, 0, 0, dlg_height, dlg_width, WPOS_CENTER, FALSE, dialog_colors, NULL, - NULL, NULL, op_names[ctx->operation]); + ui->op_dlg = dlg_create (TRUE, 0, 0, dlg_height, dlg_width, WPOS_CENTER, FALSE, dialog_colors, + file_ui_op_dlg_callback, NULL, NULL, op_names[ctx->operation]); w = WIDGET (ui->op_dlg); g = GROUP (ui->op_dlg);