Merge branch '2503_compute_totals'

* 2503_compute_totals:
  Grammar.
  Calculate and show copied bytes for all files.
  Update file operation statistics for every processing file.
  Simplify constructing of file operation progress dialog.
  Ticket #2503: don't show total file operation info
This commit is contained in:
Andrew Borodin 2012-01-10 20:13:22 +03:00
commit 6318295a2b
6 changed files with 106 additions and 86 deletions

View File

@ -461,17 +461,14 @@ make_symlink (FileOpContext * ctx, const char *src_path, const char *dst_path)
/* --------------------------------------------------------------------------------------------- */
static FileProgressStatus
progress_update_one (FileOpTotalContext * tctx, FileOpContext * ctx, off_t add,
gboolean is_toplevel_file)
progress_update_one (FileOpTotalContext * tctx, FileOpContext * ctx, off_t add)
{
struct timeval tv_current;
static struct timeval tv_start = { };
if (is_toplevel_file || ctx->progress_totals_computed)
{
tctx->progress_count++;
tctx->progress_bytes += (uintmax_t) add;
}
tctx->progress_count++;
tctx->progress_bytes += (uintmax_t) add;
if (tv_start.tv_sec == 0)
{
gettimeofday (&tv_start, (struct timezone *) NULL);
@ -728,13 +725,13 @@ copy_file_file_display_progress (FileOpTotalContext * tctx, FileOpContext * ctx,
/* 3. Compute ETA */
dt = (tv_current.tv_sec - tv_transfer_start.tv_sec);
if (n_read_total)
if (n_read_total == 0)
ctx->eta_secs = 0.0;
else
{
ctx->eta_secs = ((dt / (double) n_read_total) * file_size) - dt;
ctx->bps = n_read_total / ((dt < 1) ? 1 : dt);
}
else
ctx->eta_secs = 0.0;
/* 4. Compute BPS rate */
ctx->bps_time = (tv_current.tv_sec - tv_transfer_start.tv_sec);
@ -746,8 +743,8 @@ copy_file_file_display_progress (FileOpTotalContext * tctx, FileOpContext * ctx,
if (ctx->progress_bytes != 0)
{
uintmax_t remain_bytes;
tctx->copyed_bytes = tctx->progress_bytes + n_read_total + ctx->do_reget;
remain_bytes = ctx->progress_bytes - tctx->copyed_bytes;
remain_bytes = ctx->progress_bytes - tctx->copied_bytes;
#if 1
{
int total_secs = tv_current.tv_sec - tctx->transfer_start.tv_sec;
@ -755,7 +752,7 @@ copy_file_file_display_progress (FileOpTotalContext * tctx, FileOpContext * ctx,
if (total_secs < 1)
total_secs = 1;
tctx->bps = tctx->copyed_bytes / total_secs;
tctx->bps = tctx->copied_bytes / total_secs;
tctx->eta_secs = (tctx->bps != 0) ? remain_bytes / tctx->bps : 0;
}
#else
@ -833,7 +830,7 @@ move_file_file (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s, c
}
if (mc_rename (s, d) == 0)
return progress_update_one (tctx, ctx, src_stats.st_size, TRUE);
return progress_update_one (tctx, ctx, src_stats.st_size);
}
#if 0
/* Comparison to EXDEV seems not to work in nfs if you're moving from
@ -890,7 +887,7 @@ move_file_file (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s, c
}
if (!copy_done)
return_status = progress_update_one (tctx, ctx, src_stats.st_size, TRUE);
return_status = progress_update_one (tctx, ctx, src_stats.st_size);
return return_status;
}
@ -902,8 +899,7 @@ move_file_file (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s, c
/** Don't update progress status if progress_count==NULL */
static FileProgressStatus
erase_file (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s,
gboolean is_toplevel_file)
erase_file (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s)
{
int return_status;
struct stat buf;
@ -933,7 +929,7 @@ erase_file (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s,
if (tctx->progress_count == 0)
return FILE_CONT;
return progress_update_one (tctx, ctx, buf.st_size, is_toplevel_file);
return progress_update_one (tctx, ctx, buf.st_size);
}
/* --------------------------------------------------------------------------------------------- */
@ -977,7 +973,7 @@ recursive_erase (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s)
if (S_ISDIR (buf.st_mode))
return_status = recursive_erase (tctx, ctx, path);
else
return_status = erase_file (tctx, ctx, path, 0);
return_status = erase_file (tctx, ctx, path);
g_free (path);
}
mc_closedir (reading);
@ -1341,7 +1337,7 @@ copy_file_file (FileOpTotalContext * tctx, FileOpContext * ctx,
struct stat sb, sb2;
struct utimbuf utb;
gboolean dst_exists = FALSE, appending = FALSE;
off_t n_read_total = 0, file_size = -1;
off_t file_size = -1;
FileProgressStatus return_status, temp_status;
struct timeval tv_transfer_start;
dest_status_t dst_status = DEST_NONE;
@ -1600,13 +1596,14 @@ copy_file_file (FileOpTotalContext * tctx, FileOpContext * ctx,
goto ret;
{
off_t n_read_total = 0;
struct timeval tv_current, tv_last_update, tv_last_input;
int secs, update_secs;
const char *stalled_msg = "";
tv_last_update = tv_transfer_start;
for (;;)
while (TRUE)
{
char buf[BUF_8K];
@ -1659,6 +1656,9 @@ copy_file_file (FileOpTotalContext * tctx, FileOpContext * ctx,
goto ret;
}
}
tctx->copied_bytes = tctx->progress_bytes + n_read_total + ctx->do_reget;
secs = (tv_current.tv_sec - tv_last_update.tv_sec);
update_secs = (tv_current.tv_sec - tv_last_input.tv_sec);
@ -1685,9 +1685,7 @@ copy_file_file (FileOpTotalContext * tctx, FileOpContext * ctx,
if (verbose && ctx->dialog_type == FILEGUI_DIALOG_MULTI_ITEM)
{
file_progress_show_count (ctx, tctx->progress_count, ctx->progress_count);
file_progress_show_total (tctx, ctx,
tctx->progress_bytes + n_read_total + ctx->do_reget,
force_update);
file_progress_show_total (tctx, ctx, tctx->copied_bytes, force_update);
}
file_progress_show (ctx, n_read_total + ctx->do_reget, file_size, stalled_msg,
@ -1793,7 +1791,7 @@ copy_file_file (FileOpTotalContext * tctx, FileOpContext * ctx,
}
if (return_status == FILE_CONT)
return_status = progress_update_one (tctx, ctx, file_size, tctx->is_toplevel_file);
return_status = progress_update_one (tctx, ctx, file_size);
return return_status;
}
@ -2056,7 +2054,7 @@ copy_dir_dir (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s, con
return_status = erase_dir_iff_empty (ctx, path);
}
else
return_status = erase_file (tctx, ctx, path, FALSE);
return_status = erase_file (tctx, ctx, path);
}
}
g_free (path);
@ -2195,7 +2193,7 @@ move_dir_dir (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s, con
return_status = erase_dir_iff_empty (ctx, erase_list->name);
}
else
return_status = erase_file (tctx, ctx, erase_list->name, FALSE);
return_status = erase_file (tctx, ctx, erase_list->name);
lp = erase_list;
erase_list = erase_list->next;
g_free (lp);
@ -2692,7 +2690,7 @@ panel_operate (void *source_panel, FileOperation operation, gboolean force_singl
if (S_ISDIR (src_stat.st_mode))
value = erase_dir (tctx, ctx, source_with_path);
else
value = erase_file (tctx, ctx, source_with_path, 1);
value = erase_file (tctx, ctx, source_with_path);
}
else
{
@ -2785,7 +2783,7 @@ panel_operate (void *source_panel, FileOperation operation, gboolean force_singl
if (S_ISDIR (src_stat.st_mode))
value = erase_dir (tctx, ctx, source_with_path);
else
value = erase_file (tctx, ctx, source_with_path, 1);
value = erase_file (tctx, ctx, source_with_path);
}
else
{

View File

@ -110,11 +110,6 @@ int classic_progressbar = 1;
/* Hack: the vfs code should not rely on this */
#define WITH_FULL_PATHS 1
/* File operate window sizes */
#define WX 58
#define WY 11
#define FCOPY_LABEL_X 3
#define truncFileString(ui, s) str_trunc (s, 52)
#define truncFileStringSecure(ui, s) path_trunc (s, 52)
@ -526,11 +521,10 @@ file_op_context_create_ui_without_init (FileOpContext * ctx, gboolean with_eta,
filegui_dialog_type_t dialog_type)
{
FileOpContextUI *ui;
int minus = 0, total_reserve = 0;
const char *abort_button_label = N_("&Abort");
const char *skip_button_label = N_("&Skip");
int abort_button_width, skip_button_width, buttons_width;
int dlg_width;
int dlg_width, dlg_height;
g_return_if_fail (ctx != NULL);
g_return_if_fail (ctx->ui == NULL);
@ -544,7 +538,8 @@ file_op_context_create_ui_without_init (FileOpContext * ctx, gboolean with_eta,
skip_button_width = str_term_width1 (skip_button_label) + 3;
buttons_width = abort_button_width + skip_button_width + 2;
dlg_width = max (WX, buttons_width + 6);
dlg_width = max (58, buttons_width + 6);
dlg_height = 17; /* to make compiler happy :) */
ui = g_new0 (FileOpContextUI, 1);
ctx->ui = ui;
@ -554,68 +549,64 @@ file_op_context_create_ui_without_init (FileOpContext * ctx, gboolean with_eta,
switch (dialog_type)
{
case FILEGUI_DIALOG_ONE_ITEM:
total_reserve = 0;
minus = verbose ? 0 : 2;
dlg_height = verbose ? 12 : 10;
break;
case FILEGUI_DIALOG_MULTI_ITEM:
total_reserve = 5;
minus = verbose ? 0 : 7;
dlg_height = !verbose ? 10 : file_op_compute_totals ? 17 : 15;
break;
case FILEGUI_DIALOG_DELETE_ITEM:
total_reserve = -5;
minus = 0;
dlg_height = 7;
break;
}
ctx->recursive_result = RECURSIVE_YES;
ui->replace_result = REPLACE_YES;
ui->showing_eta = with_eta;
ui->showing_eta = with_eta && file_op_compute_totals;
ui->showing_bps = with_eta;
ui->op_dlg =
create_dlg (TRUE, 0, 0, WY - minus + 1 + total_reserve, dlg_width,
create_dlg (TRUE, 0, 0, dlg_height, dlg_width,
dialog_colors, NULL, NULL, op_names[ctx->operation], DLG_CENTER | DLG_REVERSE);
add_widget (ui->op_dlg,
button_new (WY - minus - 2 + total_reserve,
dlg_width / 2 + 1, FILE_ABORT,
button_new (dlg_height - 3, dlg_width / 2 + 1, FILE_ABORT,
NORMAL_BUTTON, abort_button_label, NULL));
add_widget (ui->op_dlg,
button_new (WY - minus - 2 + total_reserve,
dlg_width / 2 - 1 - skip_button_width, FILE_SKIP,
button_new (dlg_height - 3, dlg_width / 2 - 1 - skip_button_width, FILE_SKIP,
NORMAL_BUTTON, skip_button_label, NULL));
if (verbose && dialog_type == FILEGUI_DIALOG_MULTI_ITEM)
{
add_widget (ui->op_dlg, hline_new (8, 1, dlg_width - 2));
int dy = file_op_compute_totals ? 2 : 0;
add_widget (ui->op_dlg, ui->total_bytes_label = label_new (8, FCOPY_LABEL_X + 15, ""));
add_widget (ui->op_dlg, ui->progress_total_gauge =
gauge_new (9, FCOPY_LABEL_X + 3, 0, 100, 0));
if (file_op_compute_totals)
add_widget (ui->op_dlg, ui->progress_total_gauge =
gauge_new (7 + dy, 3 + 3, 0, 100, 0));
add_widget (ui->op_dlg, ui->total_files_processed_label =
label_new (11, FCOPY_LABEL_X, ""));
label_new (9 + dy, 3, ""));
add_widget (ui->op_dlg, ui->time_label = label_new (12, FCOPY_LABEL_X, ""));
add_widget (ui->op_dlg, ui->time_label = label_new (10 + dy, 3, ""));
add_widget (ui->op_dlg, ui->total_bytes_label = label_new (8, 3 + 15, ""));
add_widget (ui->op_dlg, hline_new (8, 1, dlg_width - 2));
}
add_widget (ui->op_dlg, ui->progress_file_label = label_new (7, FCOPY_LABEL_X, ""));
add_widget (ui->op_dlg, ui->progress_file_label = label_new (7, 3, ""));
add_widget (ui->op_dlg, ui->progress_file_gauge = gauge_new (6, FCOPY_LABEL_X + 3, 0, 100, 0));
add_widget (ui->op_dlg, ui->progress_file_gauge = gauge_new (6, 3 + 3, 0, 100, 0));
add_widget (ui->op_dlg, ui->file_string[1] = label_new (5, FCOPY_LABEL_X, ""));
add_widget (ui->op_dlg, ui->file_string[1] = label_new (5, 3, ""));
add_widget (ui->op_dlg, ui->file_label[1] = label_new (4, FCOPY_LABEL_X, ""));
add_widget (ui->op_dlg, ui->file_string[0] = label_new (3, FCOPY_LABEL_X, ""));
add_widget (ui->op_dlg, ui->file_label[0] = label_new (2, FCOPY_LABEL_X, ""));
add_widget (ui->op_dlg, ui->file_label[1] = label_new (4, 3, ""));
add_widget (ui->op_dlg, ui->file_string[0] = label_new (3, 3, ""));
add_widget (ui->op_dlg, ui->file_label[0] = label_new (2, 3, ""));
if ((right_panel == current_panel) && !classic_progressbar)
{
ui->progress_file_gauge->from_left_to_right = FALSE;
if (verbose && dialog_type == FILEGUI_DIALOG_MULTI_ITEM)
if (verbose && file_op_compute_totals && dialog_type == FILEGUI_DIALOG_MULTI_ITEM)
ui->progress_total_gauge->from_left_to_right = FALSE;
}
}
@ -694,8 +685,13 @@ file_progress_show (FileOpContext * ctx, off_t done, off_t total,
if (ui->showing_eta && ctx->eta_secs > 0.5)
{
file_eta_prepare_for_show (buffer2, ctx->eta_secs, FALSE);
file_bps_prepare_for_show (buffer3, ctx->bps);
g_snprintf (buffer, BUF_TINY, "%s (%s) %s", buffer2, buffer3, stalled_msg);
if (ctx->bps == 0)
g_snprintf (buffer, BUF_TINY, "%s %s", buffer2, stalled_msg);
else
{
file_bps_prepare_for_show (buffer3, ctx->bps);
g_snprintf (buffer, BUF_TINY, "%s (%s) %s", buffer2, buffer3, stalled_msg);
}
}
else
{
@ -717,14 +713,17 @@ file_progress_show_count (FileOpContext * ctx, size_t done, size_t total)
g_return_if_fail (ctx->ui != NULL);
ui = ctx->ui;
g_snprintf (buffer, BUF_TINY, _("Files processed: %zu of %zu"), done, total);
if (file_op_compute_totals)
g_snprintf (buffer, BUF_TINY, _("Files processed: %zu/%zu"), done, total);
else
g_snprintf (buffer, BUF_TINY, _("Files processed: %zu"), done);
label_set_text (ui->total_files_processed_label, buffer);
}
/* --------------------------------------------------------------------------------------------- */
void
file_progress_show_total (FileOpTotalContext * tctx, FileOpContext * ctx, uintmax_t copyed_bytes,
file_progress_show_total (FileOpTotalContext * tctx, FileOpContext * ctx, uintmax_t copied_bytes,
gboolean show_summary)
{
char buffer[BUF_TINY];
@ -739,30 +738,56 @@ file_progress_show_total (FileOpTotalContext * tctx, FileOpContext * ctx, uintma
ui = ctx->ui;
if (ctx->progress_bytes != 0)
if (file_op_compute_totals)
{
gauge_set_value (ui->progress_total_gauge, 1024,
(int) (1024 * copyed_bytes / ctx->progress_bytes));
gauge_show (ui->progress_total_gauge, 1);
if (ctx->progress_bytes == 0)
gauge_show (ui->progress_total_gauge, 0);
else
{
gauge_set_value (ui->progress_total_gauge, 1024,
(int) (1024 * copied_bytes / ctx->progress_bytes));
gauge_show (ui->progress_total_gauge, 1);
}
}
else
gauge_show (ui->progress_total_gauge, 0);
if (!show_summary && tctx->bps == 0)
return;
gettimeofday (&tv_current, NULL);
file_frmt_time (buffer2, tv_current.tv_sec - tctx->transfer_start.tv_sec);
file_eta_prepare_for_show (buffer3, tctx->eta_secs, TRUE);
file_bps_prepare_for_show (buffer4, (long) tctx->bps);
g_snprintf (buffer, BUF_TINY, _("Time: %s %s (%s)"), buffer2, buffer3, buffer4);
if (file_op_compute_totals)
{
file_eta_prepare_for_show (buffer3, tctx->eta_secs, TRUE);
if (tctx->bps == 0)
g_snprintf (buffer, BUF_TINY, _("Time: %s %s"), buffer2, buffer3);
else
{
file_bps_prepare_for_show (buffer4, (long) tctx->bps);
g_snprintf (buffer, BUF_TINY, _("Time: %s %s (%s)"), buffer2, buffer3, buffer4);
}
}
else
{
if (tctx->bps == 0)
g_snprintf (buffer, BUF_TINY, _("Time: %s"), buffer2);
else
{
file_bps_prepare_for_show (buffer4, (long) tctx->bps);
g_snprintf (buffer, BUF_TINY, _("Time: %s (%s)"), buffer2, buffer4);
}
}
label_set_text (ui->time_label, buffer);
size_trunc_len (buffer2, 5, tctx->copyed_bytes, 0, panels_options.kilobyte_si);
size_trunc_len (buffer3, 5, ctx->progress_bytes, 0, panels_options.kilobyte_si);
g_snprintf (buffer, BUF_TINY, _("Total: %s of %s"), buffer2, buffer3);
size_trunc_len (buffer2, 5, tctx->copied_bytes, 0, panels_options.kilobyte_si);
if (!file_op_compute_totals)
g_snprintf (buffer, BUF_TINY, _(" Total: %s "), buffer2);
else
{
size_trunc_len (buffer3, 5, ctx->progress_bytes, 0, panels_options.kilobyte_si);
g_snprintf (buffer, BUF_TINY, _(" Total: %s/%s "), buffer2, buffer3);
}
label_set_text (ui->total_bytes_label, buffer);
}

View File

@ -35,7 +35,7 @@ void file_progress_show (FileOpContext * ctx, off_t done, off_t total,
const char *stalled_msg, gboolean force_update);
void file_progress_show_count (FileOpContext * ctx, size_t done, size_t total);
void file_progress_show_total (FileOpTotalContext * tctx, FileOpContext * ctx,
uintmax_t copyed_bytes, gboolean show_summary);
uintmax_t copied_bytes, gboolean show_summary);
void file_progress_show_source (FileOpContext * ctx, const char *path);
void file_progress_show_target (FileOpContext * ctx, const char *path);
void file_progress_show_deleting (FileOpContext * ctx, const char *path);

View File

@ -114,7 +114,6 @@ file_op_total_context_new (void)
FileOpTotalContext *tctx;
tctx = g_new0 (FileOpTotalContext, 1);
tctx->ask_overwrite = TRUE;
tctx->is_toplevel_file = TRUE;
return tctx;
}

View File

@ -167,14 +167,13 @@ typedef struct
{
size_t progress_count;
uintmax_t progress_bytes;
uintmax_t copyed_bytes;
uintmax_t copied_bytes;
size_t bps;
size_t bps_count;
struct timeval transfer_start;
double eta_secs;
gboolean ask_overwrite;
gboolean is_toplevel_file;
} FileOpTotalContext;
/*** global variables defined in .c file *********************************************************/

View File

@ -759,7 +759,6 @@ tree_copy (WTree * tree, const char *default_dest)
tctx = file_op_total_context_new ();
file_op_context_create_ui (ctx, FALSE, FILEGUI_DIALOG_MULTI_ITEM);
tctx->ask_overwrite = FALSE;
tctx->is_toplevel_file = FALSE;
copy_dir_dir (tctx, ctx, tree->selected_ptr->name, dest, TRUE, FALSE, FALSE, NULL);
file_op_total_context_destroy (tctx);
file_op_context_destroy (ctx);