/* Display of downloads progression stuff. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "elinks.h" #include "bfu/dialog.h" #include "dialogs/progress.h" #include "intl/libintl.h" #include "network/progress.h" #include "terminal/draw.h" #include "util/conv.h" #include "util/error.h" #include "util/memory.h" #include "util/string.h" static char * get_progress_msg_2(struct progress *progress, struct terminal *term, int wide, int full, const char *separator, char *type) { struct string msg; int newlines = separator[strlen(separator) - 1] == '\n'; if (!init_string(&msg)) return NULL; /* FIXME: The following is a PITA from the l10n standpoint. A *big* * one, _("of")-like pearls are a nightmare. Format strings need to * be introduced to this fuggy corner of code as well. --pasky */ add_to_string(&msg, type); add_char_to_string(&msg, ' '); add_xnum_to_string(&msg, progress->pos); if (progress->size >= 0) { add_char_to_string(&msg, ' '); add_to_string(&msg, _("of", term)); add_char_to_string(&msg, ' '); add_xnum_to_string(&msg, progress->size); } add_to_string(&msg, separator); if (wide) { /* Do the following only if there is room */ add_to_string(&msg, _(full ? (newlines ? N_("Average speed") : N_("average speed")) : N_("avg"), term)); add_char_to_string(&msg, ' '); add_xnum_to_string(&msg, progress->average_speed); add_to_string(&msg, "/s"); add_to_string(&msg, ", "); add_to_string(&msg, _(full ? N_("current speed") : N_("cur"), term)); add_char_to_string(&msg, ' '), add_xnum_to_string(&msg, progress->current_speed); add_to_string(&msg, "/s"); add_to_string(&msg, separator); add_to_string(&msg, _(full ? (newlines ? N_("Elapsed time") : N_("elapsed time")) : N_("ETT"), term)); add_char_to_string(&msg, ' '); add_timeval_to_string(&msg, &progress->elapsed); } else { add_to_string(&msg, _(newlines ? N_("Speed") : N_("speed"), term)); add_char_to_string(&msg, ' '); add_xnum_to_string(&msg, progress->average_speed); add_to_string(&msg, "/s"); } if (progress->size >= 0 && progress->loaded > 0) { add_to_string(&msg, ", "); add_to_string(&msg, _(full ? N_("estimated time") : N_("ETA"), term)); add_char_to_string(&msg, ' '); add_timeval_to_string(&msg, &progress->estimated_time); } return msg.source; } char * get_upload_progress_msg(struct progress *progress, struct terminal *term, int wide, int full, const char *separator) { return get_progress_msg_2(progress, term, wide, full, separator, _("Sent", term)); } char * get_progress_msg(struct progress *progress, struct terminal *term, int wide, int full, const char *separator) { return get_progress_msg_2(progress, term, wide, full, separator, _("Received", term)); } void draw_progress_bar_node(struct progress *progress, struct terminal *term, int x, int y, int width, char *text, unsigned int meter_color_node) { /* Note : values > 100% are theorically possible and were seen. */ int percent = 0; struct el_box barprogress; if (progress->size > 0) percent = (int) ((longlong) 100 * progress->pos / progress->size); /* Draw the progress meter part "[### ]" */ if (!text && width > 2) { width -= 2; draw_text_node(term, x++, y, "[", 1, 0, 0); draw_text_node(term, x + width, y, "]", 1, 0, 0); } if (!meter_color_node) meter_color_node = get_bfu_color_node(term, "dialog.meter"); set_box(&barprogress, x, y, int_min(width * percent / 100, width), 1); draw_box_node(term, &barprogress, ' ', 0, meter_color_node); /* On error, will print '?' only, should not occur. */ if (text) { width = int_min(width, strlen(text)); } else if (width > 1) { static char s[] = "????"; /* Reduce or enlarge at will. */ unsigned int slen = 0; int max = int_min(sizeof(s), width) - 1; if (ulongcat(s, &slen, percent, max, 0)) { s[0] = '?'; slen = 1; } s[slen++] = '%'; /* Draw the percentage centered in the progress meter */ x += (1 + width - slen) / 2; assert(slen <= width); width = slen; text = s; } draw_text_node(term, x, y, text, width, 0, 0); }