[svn] Commit progress bar tweaks.

Published in <sxsd727cvc0.fsf@florida.arsdigita.de>.
This commit is contained in:
hniksic 2001-11-24 20:46:26 -08:00
parent 222e9465b7
commit 05463c7121
6 changed files with 131 additions and 61 deletions

View File

@ -1,3 +1,15 @@
2001-11-25 Hrvoje Niksic <hniksic@arsdigita.com>
* progress.c (dot_create): Align the "[ skipping ... ]" string
with the dots.
* retr.c (rate): Split into two functions: calc_rate and
retr_rate.
* progress.c (create_image): Draw a dummy progress bar even when
total size is unknown.
(display_image): Place the text cursor at the end of the "image".
2001-11-25 Hrvoje Niksic <hniksic@arsdigita.com> 2001-11-25 Hrvoje Niksic <hniksic@arsdigita.com>
* url.c (reencode_string): Use unsigned char, not char -- * url.c (reencode_string): Use unsigned char, not char --

View File

@ -924,7 +924,7 @@ Error in server response, closing control connection.\n"));
con->dltime = wtimer_elapsed (timer); con->dltime = wtimer_elapsed (timer);
wtimer_delete (timer); wtimer_delete (timer);
tms = time_str (NULL); tms = time_str (NULL);
tmrate = rate (*len - restval, con->dltime, 0); tmrate = retr_rate (*len - restval, con->dltime, 0);
/* Close data connection socket. */ /* Close data connection socket. */
closeport (dtsock); closeport (dtsock);
/* Close the local file. */ /* Close the local file. */
@ -1173,7 +1173,7 @@ ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con)
} }
/* Time? */ /* Time? */
tms = time_str (NULL); tms = time_str (NULL);
tmrate = rate (len - restval, con->dltime, 0); tmrate = retr_rate (len - restval, con->dltime, 0);
/* If we get out of the switch above without continue'ing, we've /* If we get out of the switch above without continue'ing, we've
successfully downloaded a file. Remember this fact. */ successfully downloaded a file. Remember this fact. */

View File

@ -1752,7 +1752,7 @@ The sizes do not match (local %ld) -- retrieving.\n"), local_size);
return RETROK; return RETROK;
} }
tmrate = rate (hstat.len - hstat.restval, hstat.dltime, 0); tmrate = retr_rate (hstat.len - hstat.restval, hstat.dltime, 0);
if (hstat.len == hstat.contlen) if (hstat.len == hstat.contlen)
{ {

View File

@ -190,9 +190,16 @@ dot_create (long initial, long total)
if (skipped) if (skipped)
{ {
logputs (LOG_VERBOSE, "\n "); /* leave spacing untranslated */ int skipped_k = (int) (skipped / 1024); /* skipped amount in K */
logprintf (LOG_VERBOSE, _("[ skipping %dK ]"), int skipped_k_len = numdigit (skipped_k);
(int) (skipped / 1024)); if (skipped_k_len < 5)
skipped_k_len = 5;
/* Align the [ skipping ... ] line with the dots. To do
that, insert the number of spaces equal to the number of
digits in the skipped amount in K. */
logprintf (LOG_VERBOSE, "\n%*s%s",
2 + skipped_k_len, "", _("[ skipping %dK ]"));
} }
logprintf (LOG_VERBOSE, "\n%5ldK", skipped / 1024); logprintf (LOG_VERBOSE, "\n%5ldK", skipped / 1024);
@ -224,7 +231,7 @@ print_download_speed (struct dot_progress *dp, long bytes)
{ {
long timer_value = wtimer_elapsed (dp->timer); long timer_value = wtimer_elapsed (dp->timer);
logprintf (LOG_VERBOSE, " %s", logprintf (LOG_VERBOSE, " %s",
rate (bytes, timer_value - dp->last_timer_value, 1)); retr_rate (bytes, timer_value - dp->last_timer_value, 1));
dp->last_timer_value = timer_value; dp->last_timer_value = timer_value;
} }
@ -380,6 +387,8 @@ struct bar_progress {
progress gauge was created. */ progress gauge was created. */
char *buffer; /* buffer where the bar "image" is char *buffer; /* buffer where the bar "image" is
stored. */ stored. */
int tick;
}; };
static void create_image PARAMS ((struct bar_progress *, long)); static void create_image PARAMS ((struct bar_progress *, long));
@ -468,44 +477,53 @@ create_image (struct bar_progress *bp, long dltime)
long size = bp->initial_length + bp->count; long size = bp->initial_length + bp->count;
/* The progress bar should look like this: /* The progress bar should look like this:
xxx% |=======> | xx KB/s nnnnn ETA: 00:00 xx% [=======> ] xx KB/s nnnnn ETA 00:00
Calculate its geometry: Calculate its geometry:
"xxx% " - percentage - 5 chars "xx% " or "100%" - percentage - 4 chars exactly
"| ... |" - progress bar decorations - 2 chars "[]" - progress bar decorations - 2 chars exactly
"1012.56 K/s " - dl rate - 12 chars "1012.56K/s " - dl rate - 11 chars exactly
"nnnn " - downloaded bytes - 11 chars "n,nnn,nnn,nnn " - downloaded bytes - 14 or less chars
"ETA: xx:xx:xx" - ETA - 13 chars "ETA xx:xx:xx" - ETA - 12 or less chars
"=====>..." - progress bar content - the rest "=====>..." - progress bar content - the rest
*/ */
int progress_len = screen_width - (5 + 2 + 12 + 11 + 13); int progress_size = screen_width - (4 + 2 + 11 + 14 + 12);
if (progress_len < 7) if (progress_size < 5)
progress_len = 0; progress_size = 0;
/* "xxx% " */ /* "xxx%" */
if (bp->total_length > 0) if (bp->total_length > 0)
{ {
int percentage = (int)(100.0 * size / bp->total_length); int percentage = (int)(100.0 * size / bp->total_length);
assert (percentage <= 100); assert (percentage <= 100);
sprintf (p, "%3d%% ", percentage); if (percentage < 100)
p += 5; sprintf (p, "%2d%% ", percentage);
else
strcpy (p, "100%");
p += 4;
}
else
{
int i = 5;
while (i--)
*p++ = ' ';
} }
/* The progress bar: "|====> | " */ /* The progress bar: "|====> |" */
if (progress_len && bp->total_length > 0) if (progress_size && bp->total_length > 0)
{ {
double fraction = (double)size / bp->total_length; double fraction = (double)size / bp->total_length;
int dlsz = (int)(fraction * progress_len); int dlsz = (int)(fraction * progress_size);
char *begin; char *begin;
assert (dlsz <= progress_len); assert (dlsz <= progress_size);
*p++ = '|'; *p++ = '[';
begin = p; begin = p;
if (dlsz > 0) if (dlsz > 0)
@ -516,20 +534,46 @@ create_image (struct bar_progress *bp, long dltime)
*p++ = '>'; *p++ = '>';
} }
while (p - begin < progress_len) while (p - begin < progress_size)
*p++ = ' '; *p++ = ' ';
*p++ = '|'; *p++ = ']';
*p++ = ' '; }
else if (progress_size)
{
/* If we can't draw a real progress bar, then at least show
*something* to the user. */
int ind = bp->tick % (progress_size * 2 - 6);
int i, pos;
/* Make the star move in two directions. */
if (ind < progress_size - 2)
pos = ind + 1;
else
pos = progress_size - (ind - progress_size + 5);
*p++ = '[';
for (i = 0; i < progress_size; i++)
{
if (i == pos - 1) *p++ = '<';
else if (i == pos ) *p++ = '=';
else if (i == pos + 1) *p++ = '>';
else
*p++ = ' ';
}
*p++ = ']';
++bp->tick;
} }
/* "1012.45 K/s " */ /* "1012.45K/s " */
if (dltime && bp->count) if (dltime && bp->count)
{ {
char *rt = rate (bp->count, dltime, 1); static char *short_units[] = { "B/s", "K/s", "M/s", "G/s" };
strcpy (p, rt); int units = 0;
double dlrate = calc_rate (bp->count, dltime, &units);
sprintf (p, "%7.2f%s ", dlrate, short_units[units]);
p += strlen (p); p += strlen (p);
*p++ = ' ';
} }
else else
{ {
@ -537,11 +581,15 @@ create_image (struct bar_progress *bp, long dltime)
p += 12; p += 12;
} }
/* "12376 " */ /* "1,234,567 " */
sprintf (p, "%ld ", size); /* If there are 7 or less digits (9 because of "legible" comas),
print the number in constant space. This will prevent the "ETA"
string from jerking as the data begins to arrive. */
sprintf (p, "%9s", legible (size));
p += strlen (p); p += strlen (p);
*p++ = ' ';
/* "ETA: xx:xx:xx" */ /* "ETA xx:xx:xx" */
if (bp->total_length > 0 && bp->count > 0) if (bp->total_length > 0 && bp->count > 0)
{ {
int eta, eta_hrs, eta_min, eta_sec; int eta, eta_hrs, eta_min, eta_sec;
@ -560,7 +608,6 @@ create_image (struct bar_progress *bp, long dltime)
*p++ = 'E'; *p++ = 'E';
*p++ = 'T'; *p++ = 'T';
*p++ = 'A'; *p++ = 'A';
*p++ = ':';
*p++ = ' '; *p++ = ' ';
if (eta_hrs > 99) if (eta_hrs > 99)
@ -574,8 +621,8 @@ create_image (struct bar_progress *bp, long dltime)
} }
else if (bp->total_length > 0) else if (bp->total_length > 0)
{ {
strcpy (p, "ETA: --:--"); strcpy (p, "ETA --:--");
p += 10; p += 9;
} }
assert (p - bp->buffer <= screen_width); assert (p - bp->buffer <= screen_width);
@ -591,15 +638,11 @@ create_image (struct bar_progress *bp, long dltime)
static void static void
display_image (char *buf) display_image (char *buf)
{ {
int len = strlen (buf); char *del_buf = alloca (screen_width + 1);
char *del_buf = alloca (len + 1); memset (del_buf, '\b', screen_width);
del_buf[screen_width] = '\0';
logputs (LOG_VERBOSE, buf);
memset (del_buf, '\b', len);
del_buf[len] = '\0';
logputs (LOG_VERBOSE, del_buf); logputs (LOG_VERBOSE, del_buf);
logputs (LOG_VERBOSE, buf);
} }
static void static void

View File

@ -147,16 +147,31 @@ get_contents (int fd, FILE *fp, long *len, long restval, long expected,
} }
/* Return a printed representation of the download rate, as /* Return a printed representation of the download rate, as
appropriate for the speed. Appropriate means that if rate is appropriate for the speed. If PAD is non-zero, strings will be
greater than 1K/s, kilobytes are used, and if rate is greater than padded to the width of 7 characters (xxxx.xx). */
1MB/s, megabytes are used.
If PAD is non-zero, strings will be padded to the width of 7
characters (xxxx.xx). */
char * char *
rate (long bytes, long msecs, int pad) retr_rate (long bytes, long msecs, int pad)
{
static char res[20];
static char *rate_names[] = {"B/s", "KB/s", "MB/s", "GB/s" };
int units = 0;
double dlrate = calc_rate (bytes, msecs, &units);
sprintf (res, pad ? "%7.2f %s" : "%.2f %s", dlrate, rate_names[units]);
return res;
}
/* Calculate the download rate and trim it as appropriate for the
speed. Appropriate means that if rate is greater than 1K/s,
kilobytes are used, and if rate is greater than 1MB/s, megabytes
are used.
UNITS is zero for B/s, one for KB/s, two for MB/s, and three for
GB/s. */
double
calc_rate (long bytes, long msecs, int *units)
{ {
static char res[15];
double dlrate; double dlrate;
assert (msecs >= 0); assert (msecs >= 0);
@ -170,18 +185,17 @@ rate (long bytes, long msecs, int pad)
dlrate = (double)1000 * bytes / msecs; dlrate = (double)1000 * bytes / msecs;
if (dlrate < 1024.0) if (dlrate < 1024.0)
sprintf (res, pad ? "%7.2f B/s" : "%.2f B/s", dlrate); *units = 0;
else if (dlrate < 1024.0 * 1024.0) else if (dlrate < 1024.0 * 1024.0)
sprintf (res, pad ? "%7.2f K/s" : "%.2f K/s", dlrate / 1024.0); *units = 1, dlrate /= 1024.0;
else if (dlrate < 1024.0 * 1024.0 * 1024.0) else if (dlrate < 1024.0 * 1024.0 * 1024.0)
sprintf (res, pad ? "%7.2f M/s" : "%.2f M/s", dlrate / (1024.0 * 1024.0)); *units = 2, dlrate /= (1024.0 * 1024.0);
else else
/* Maybe someone will need this one day. More realistically, it /* Maybe someone will need this one day. More realistically, it
will get tickled by buggy timers. */ will get tickled by buggy timers. */
sprintf (res, pad ? "%7.2f GB/s" : "%.2f GB/s", *units = 3, dlrate /= (1024.0 * 1024.0 * 1024.0);
dlrate / (1024.0 * 1024.0 * 1024.0));
return res; return dlrate;
} }
static int static int

View File

@ -28,7 +28,8 @@ uerr_t retrieve_url PARAMS ((const char *, char **, char **,
const char *, int *)); const char *, int *));
uerr_t retrieve_from_file PARAMS ((const char *, int, int *)); uerr_t retrieve_from_file PARAMS ((const char *, int, int *));
char *rate PARAMS ((long, long, int)); char *retr_rate PARAMS ((long, long, int));
double calc_rate PARAMS ((long, long, int *));
void printwhat PARAMS ((int, int)); void printwhat PARAMS ((int, int));
void downloaded_increase PARAMS ((unsigned long)); void downloaded_increase PARAMS ((unsigned long));