mirror of
https://github.com/MidnightCommander/mc
synced 2025-01-11 13:59:18 +03:00
File copy/move: make ETA accurate.
* (progress_update_one): update total progress bytes counter. Update progress info in the progress window only if file was processed successfully. Don't check buttons here. * (move_file_file): update progress info if file move wasn't aborted. * (copy_file_file): update progress info if stat() or open() failed (file size is unknown, but file counter shoud be updated). Modify caclulation and display of byte counters. * (panel_operate): simplify files processing loop. Remove action that already done via operate_one_file() call. Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
This commit is contained in:
parent
ff1a404bb3
commit
1e35ae3adb
@ -812,32 +812,32 @@ panel_operate_init_totals (const WPanel *panel, const vfs_path_t *source,
|
|||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static FileProgressStatus
|
static void
|
||||||
progress_update_one (file_op_context_t *ctx, off_t add)
|
progress_update_one (gboolean success, file_op_context_t *ctx, off_t add)
|
||||||
{
|
{
|
||||||
gint64 tv_current;
|
gint64 tv_current;
|
||||||
static gint64 tv_start = -1;
|
static gint64 tv_start = -1;
|
||||||
|
|
||||||
ctx->total_progress_count++;
|
ctx->total_progress_count++;
|
||||||
ctx->progress_bytes += (uintmax_t) add;
|
ctx->total_progress_bytes += (uintmax_t) add;
|
||||||
|
|
||||||
|
if (!success)
|
||||||
|
return;
|
||||||
|
|
||||||
tv_current = g_get_monotonic_time ();
|
tv_current = g_get_monotonic_time ();
|
||||||
|
|
||||||
if (tv_start < 0)
|
if (tv_start < 0)
|
||||||
tv_start = tv_current;
|
tv_start = tv_current;
|
||||||
|
else if (tv_current - tv_start > FILEOP_UPDATE_INTERVAL_US)
|
||||||
if (tv_current - tv_start > FILEOP_UPDATE_INTERVAL_US)
|
|
||||||
{
|
{
|
||||||
if (verbose && ctx->dialog_type == FILEGUI_DIALOG_MULTI_ITEM)
|
if (verbose && ctx->dialog_type == FILEGUI_DIALOG_MULTI_ITEM)
|
||||||
{
|
{
|
||||||
file_progress_show_count (ctx);
|
file_progress_show_count (ctx);
|
||||||
file_progress_show_total (ctx, ctx->progress_bytes, tv_current, TRUE);
|
file_progress_show_total (ctx, ctx->total_progress_bytes, tv_current, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
tv_start = tv_current;
|
tv_start = tv_current;
|
||||||
}
|
}
|
||||||
|
|
||||||
return file_progress_check_buttons (ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
@ -1217,7 +1217,7 @@ move_file_file (const WPanel *panel, file_op_context_t *ctx, const char *s, cons
|
|||||||
if (file_progress_check_buttons (ctx) == FILE_ABORT)
|
if (file_progress_check_buttons (ctx) == FILE_ABORT)
|
||||||
{
|
{
|
||||||
return_status = FILE_ABORT;
|
return_status = FILE_ABORT;
|
||||||
goto ret;
|
goto ret_fast;
|
||||||
}
|
}
|
||||||
|
|
||||||
mc_refresh ();
|
mc_refresh ();
|
||||||
@ -1280,11 +1280,7 @@ move_file_file (const WPanel *panel, file_op_context_t *ctx, const char *s, cons
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mc_rename (src_vpath, dst_vpath) == 0)
|
if (mc_rename (src_vpath, dst_vpath) == 0)
|
||||||
{
|
|
||||||
/* FIXME: do we really need to update progress in case of single file? */
|
|
||||||
return_status = progress_update_one (ctx, src_stat.st_size);
|
|
||||||
goto ret;
|
goto ret;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#if 0
|
#if 0
|
||||||
/* Comparison to EXDEV seems not to work in nfs if you're moving from
|
/* Comparison to EXDEV seems not to work in nfs if you're moving from
|
||||||
@ -1320,7 +1316,7 @@ move_file_file (const WPanel *panel, file_op_context_t *ctx, const char *s, cons
|
|||||||
panel_operate_init_totals (panel, src_vpath, &src_stat, ctx, TRUE,
|
panel_operate_init_totals (panel, src_vpath, &src_stat, ctx, TRUE,
|
||||||
FILEGUI_DIALOG_ONE_ITEM);
|
FILEGUI_DIALOG_ONE_ITEM);
|
||||||
if (return_status != FILE_CONT)
|
if (return_status != FILE_CONT)
|
||||||
goto ret;
|
goto ret_fast;
|
||||||
}
|
}
|
||||||
|
|
||||||
old_ask_overwrite = ctx->ask_overwrite;
|
old_ask_overwrite = ctx->ask_overwrite;
|
||||||
@ -1342,19 +1338,24 @@ move_file_file (const WPanel *panel, file_op_context_t *ctx, const char *s, cons
|
|||||||
|
|
||||||
return_status = file_progress_check_buttons (ctx);
|
return_status = file_progress_check_buttons (ctx);
|
||||||
if (return_status != FILE_CONT)
|
if (return_status != FILE_CONT)
|
||||||
goto ret;
|
goto ret_fast;
|
||||||
}
|
}
|
||||||
|
|
||||||
mc_refresh ();
|
mc_refresh ();
|
||||||
|
|
||||||
retry_src_remove:
|
retry_src_remove:
|
||||||
if (!try_remove_file (ctx, src_vpath, &return_status) && panel == NULL)
|
if (!try_remove_file (ctx, src_vpath, &return_status) && panel == NULL)
|
||||||
goto ret;
|
goto ret_fast;
|
||||||
|
|
||||||
if (!copy_done)
|
|
||||||
return_status = progress_update_one (ctx, src_stat.st_size);
|
|
||||||
|
|
||||||
ret:
|
ret:
|
||||||
|
if (return_status != FILE_ABORT)
|
||||||
|
{
|
||||||
|
/* if copy_done == TRUE, progress_update_one() was called in copy_file_file() */
|
||||||
|
if (!copy_done)
|
||||||
|
progress_update_one (TRUE, ctx, src_stat.st_size);
|
||||||
|
return_status = file_progress_check_buttons (ctx);
|
||||||
|
}
|
||||||
|
ret_fast:
|
||||||
vfs_path_free (src_vpath, TRUE);
|
vfs_path_free (src_vpath, TRUE);
|
||||||
vfs_path_free (dst_vpath, TRUE);
|
vfs_path_free (dst_vpath, TRUE);
|
||||||
|
|
||||||
@ -2320,9 +2321,19 @@ copy_file_file (file_op_context_t *ctx, const char *src_path, const char *dst_pa
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (return_status != FILE_RETRY)
|
if (return_status != FILE_RETRY)
|
||||||
|
{
|
||||||
|
/* unknown size */
|
||||||
|
progress_update_one (FALSE, ctx, 0);
|
||||||
goto ret_fast;
|
goto ret_fast;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* After ctx->stat_func() */
|
||||||
|
src_mode = src_stat.st_mode;
|
||||||
|
src_uid = src_stat.st_uid;
|
||||||
|
src_gid = src_stat.st_gid;
|
||||||
|
file_size = src_stat.st_size;
|
||||||
|
|
||||||
while (attrs_ok && mc_fgetflags (src_vpath, &attrs) != 0)
|
while (attrs_ok && mc_fgetflags (src_vpath, &attrs) != 0)
|
||||||
{
|
{
|
||||||
attrs_ok = FALSE;
|
attrs_ok = FALSE;
|
||||||
@ -2520,7 +2531,7 @@ copy_file_file (file_op_context_t *ctx, const char *src_path, const char *dst_pa
|
|||||||
ctx->ignore_all = TRUE;
|
ctx->ignore_all = TRUE;
|
||||||
ctx->do_append = FALSE;
|
ctx->do_append = FALSE;
|
||||||
}
|
}
|
||||||
goto ret_fast;
|
goto ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->do_reget != 0 && mc_lseek (src_desc, ctx->do_reget, SEEK_SET) != ctx->do_reget)
|
if (ctx->do_reget != 0 && mc_lseek (src_desc, ctx->do_reget, SEEK_SET) != ctx->do_reget)
|
||||||
@ -2546,6 +2557,7 @@ copy_file_file (file_op_context_t *ctx, const char *src_path, const char *dst_pa
|
|||||||
goto ret;
|
goto ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* After mc_fstat() */
|
||||||
src_mode = src_stat.st_mode;
|
src_mode = src_stat.st_mode;
|
||||||
src_uid = src_stat.st_uid;
|
src_uid = src_stat.st_uid;
|
||||||
src_gid = src_stat.st_gid;
|
src_gid = src_stat.st_gid;
|
||||||
@ -2737,7 +2749,7 @@ copy_file_file (file_op_context_t *ctx, const char *src_path, const char *dst_pa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->total_progress_bytes = ctx->progress_bytes + file_part + ctx->do_reget;
|
ctx->progress_bytes = file_part + ctx->do_reget;
|
||||||
|
|
||||||
const gint64 usecs = tv_current - tv_last_update;
|
const gint64 usecs = tv_current - tv_last_update;
|
||||||
|
|
||||||
@ -2758,13 +2770,12 @@ copy_file_file (file_op_context_t *ctx, const char *src_path, const char *dst_pa
|
|||||||
const char *stalled_msg =
|
const char *stalled_msg =
|
||||||
update_usecs > FILEOP_STALLING_INTERVAL_US ? _("(stalled)") : "";
|
update_usecs > FILEOP_STALLING_INTERVAL_US ? _("(stalled)") : "";
|
||||||
|
|
||||||
file_progress_show (ctx, file_part + ctx->do_reget, file_size, stalled_msg,
|
file_progress_show (ctx, ctx->progress_bytes, file_size, stalled_msg, force_update);
|
||||||
force_update);
|
|
||||||
if (ctx->dialog_type == FILEGUI_DIALOG_MULTI_ITEM)
|
if (ctx->dialog_type == FILEGUI_DIALOG_MULTI_ITEM)
|
||||||
{
|
{
|
||||||
file_progress_show_count (ctx);
|
file_progress_show_count (ctx);
|
||||||
file_progress_show_total (ctx, ctx->total_progress_bytes, tv_current,
|
file_progress_show_total (ctx, ctx->total_progress_bytes + ctx->progress_bytes,
|
||||||
force_update);
|
tv_current, force_update);
|
||||||
}
|
}
|
||||||
|
|
||||||
mc_refresh ();
|
mc_refresh ();
|
||||||
@ -2934,8 +2945,9 @@ copy_file_file (file_op_context_t *ctx, const char *src_path, const char *dst_pa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
progress_update_one (return_status == FILE_CONT, ctx, file_size);
|
||||||
if (return_status == FILE_CONT)
|
if (return_status == FILE_CONT)
|
||||||
return_status = progress_update_one (ctx, file_size);
|
return_status = file_progress_check_buttons (ctx);
|
||||||
|
|
||||||
ret_fast:
|
ret_fast:
|
||||||
vfs_path_free (src_vpath, TRUE);
|
vfs_path_free (src_vpath, TRUE);
|
||||||
@ -3608,7 +3620,6 @@ panel_operate (void *source_panel, FileOperation operation, gboolean force_singl
|
|||||||
value =
|
value =
|
||||||
panel_operate_init_totals (panel, NULL, NULL, ctx, file_op_compute_totals, dialog_type);
|
panel_operate_init_totals (panel, NULL, NULL, ctx, file_op_compute_totals, dialog_type);
|
||||||
if (value == FILE_CONT)
|
if (value == FILE_CONT)
|
||||||
{
|
|
||||||
/* Loop for every file, perform the actual copy operation */
|
/* Loop for every file, perform the actual copy operation */
|
||||||
for (i = 0; i < panel->dir.len; i++)
|
for (i = 0; i < panel->dir.len; i++)
|
||||||
{
|
{
|
||||||
@ -3621,32 +3632,14 @@ panel_operate (void *source_panel, FileOperation operation, gboolean force_singl
|
|||||||
src_stat = panel->dir.list[i].st;
|
src_stat = panel->dir.list[i].st;
|
||||||
|
|
||||||
value = operate_one_file (panel, ctx, source2, &src_stat, dest);
|
value = operate_one_file (panel, ctx, source2, &src_stat, dest);
|
||||||
|
|
||||||
if (value == FILE_ABORT)
|
if (value == FILE_ABORT)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (value == FILE_CONT)
|
if (value == FILE_CONT)
|
||||||
do_file_mark (panel, i, 0);
|
do_file_mark (panel, i, 0);
|
||||||
|
|
||||||
if (verbose)
|
|
||||||
{
|
|
||||||
if (ctx->dialog_type == FILEGUI_DIALOG_MULTI_ITEM)
|
|
||||||
{
|
|
||||||
file_progress_show_count (ctx);
|
|
||||||
file_progress_show_total (ctx, ctx->progress_bytes, g_get_monotonic_time (),
|
|
||||||
FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (operation != OP_DELETE)
|
|
||||||
file_progress_show (ctx, 0, 0, "", FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file_progress_check_buttons (ctx) == FILE_ABORT)
|
|
||||||
break;
|
|
||||||
|
|
||||||
mc_refresh ();
|
mc_refresh ();
|
||||||
} /* Loop for every file */
|
} /* Loop for every file */
|
||||||
}
|
|
||||||
} /* Many entries */
|
} /* Many entries */
|
||||||
|
|
||||||
clean_up:
|
clean_up:
|
||||||
|
Loading…
Reference in New Issue
Block a user