diff options
author | Guy Harris <guy@alum.mit.edu> | 2002-08-28 10:07:37 +0000 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2002-08-28 10:07:37 +0000 |
commit | abe6b6bcc8e56b3606dec883ead36658a296088e (patch) | |
tree | 0d0ee2965686033c7aee032eb363afa81da06afb /gtk | |
parent | 666f3feec35f96f3cf0a0edbac0299efcf705545 (diff) |
From Ulf Lamping: extend the progress dialog box to give more progress
information.
Fix the types of some variables (make the file position in
"read_cap_file()" a "long", as Wiretap supports "long" offsets, and make
processed-packet counts in packet-processing loops "int"s, as the total
packet count in a "capture_file" structure is an "int").
svn path=/trunk/; revision=6112
Diffstat (limited to 'gtk')
-rw-r--r-- | gtk/progress_dlg.c | 167 |
1 files changed, 145 insertions, 22 deletions
diff --git a/gtk/progress_dlg.c b/gtk/progress_dlg.c index 81a6ca1be0..8e1ad889a7 100644 --- a/gtk/progress_dlg.c +++ b/gtk/progress_dlg.c @@ -1,12 +1,11 @@ /* progress_dlg.c * Routines for progress-bar (modal) dialog * - * $Id: progress_dlg.c,v 1.11 2002/07/30 10:13:16 guy Exp $ + * $Id: progress_dlg.c,v 1.12 2002/08/28 10:07:37 guy Exp $ * * Ethereal - Network traffic analyzer - * By Gerald Combs <gerald@zing.org> + * By Gerald Combs <gerald@ethereal.com> * Copyright 1998 Gerald Combs - * * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -41,6 +40,12 @@ static void stop_cb(GtkWidget *w, gpointer data); */ struct progdlg { GtkWidget *dlg_w; /* top-level window widget */ + GTimeVal start_time; + GtkLabel *status_lb; + GtkLabel *elapsed_lb; + GtkLabel *time_left_lb; + GtkLabel *percentage_lb; + gchar title[200]; }; /* @@ -49,10 +54,11 @@ struct progdlg { * needs in order to manipulate the dialog, and return a pointer to * it. * - * The first argument is the title to give the dialog box; the second - * argument is the string to put in the "stop this operation" button; - * the third argument is a pointer to a Boolean variable that will be - * set to TRUE if the user hits that button. + * The first argument is the task to do, e.g. "Loading". + * The second argument is the item to do, e.g. "capture.cap". + * The third argument is the string to put in the "stop this operation" button. + * The fourth argument is a pointer to a Boolean variable that will be + * set to TRUE if the user hits that button. * * XXX - provide a way to specify the progress in units, with the total * number of units specified as an argument when the progress dialog @@ -65,15 +71,22 @@ struct progdlg { * be read. */ progdlg_t * -create_progress_dlg(const gchar *title, const gchar *stop_title, +create_progress_dlg(const gchar *task_title, const gchar *item_title, const gchar *stop_title, gboolean *stop_flag) { progdlg_t *dlg; - GtkWidget *dlg_w, *main_vb, *title_lb, *prog_bar, *bbox, *stop_bt; + GtkWidget *dlg_w, *main_vb, *title_lb, *status_lb, *elapsed_lb, *time_left_lb, *percentage_lb; + GtkWidget *prog_bar, *bbox, *stop_bt; + GtkWidget *static_vb, *tmp_lb, *main_hb, *dynamic_vb, *percentage_hb; + gchar tmp[100]; + dlg = g_malloc(sizeof (progdlg_t)); - dlg_w = dlg_window_new(title); + g_snprintf(dlg->title, sizeof(dlg->title), "%s: %s", + task_title, item_title); + + dlg_w = dlg_window_new(dlg->title); gtk_window_set_modal(GTK_WINDOW(dlg_w), TRUE); /* @@ -83,30 +96,94 @@ create_progress_dlg(const gchar *title, const gchar *stop_title, gtk_container_border_width(GTK_CONTAINER(main_vb), 5); gtk_container_add(GTK_CONTAINER(dlg_w), main_vb); + + /* + * Static labels (left dialog side, labels aligned to the right) + */ + static_vb = gtk_vbox_new(FALSE, 1); + g_snprintf (tmp, sizeof(tmp), "%s:", task_title); + tmp_lb = gtk_label_new(tmp); + gtk_misc_set_alignment(GTK_MISC(tmp_lb), 1.0, 0.0); + gtk_box_pack_start(GTK_BOX(static_vb), tmp_lb, FALSE, TRUE, 3); + tmp_lb = gtk_label_new("Status:"); + gtk_misc_set_alignment(GTK_MISC(tmp_lb), 1.0, 0.0); + gtk_box_pack_start(GTK_BOX(static_vb), tmp_lb, FALSE, TRUE, 3); + tmp_lb = gtk_label_new("Elapsed Time:"); + gtk_misc_set_alignment(GTK_MISC(tmp_lb), 1.0, 0.0); + gtk_box_pack_start(GTK_BOX(static_vb), tmp_lb, FALSE, TRUE, 3); + tmp_lb = gtk_label_new("Time Left:"); + gtk_misc_set_alignment(GTK_MISC(tmp_lb), 1.0, 0.0); + gtk_box_pack_start(GTK_BOX(static_vb), tmp_lb, FALSE, TRUE, 3); + tmp_lb = gtk_label_new("Progress:"); + gtk_misc_set_alignment(GTK_MISC(tmp_lb), 1.0, 0.0); + gtk_box_pack_start(GTK_BOX(static_vb), tmp_lb, FALSE, TRUE, 3); + + /* - * Put the title here as a label indicating what we're + * Dynamic labels (right dialog side, labels aligned to the left) + */ + dynamic_vb = gtk_vbox_new(FALSE, 1); + + /* + * Put the item_title here as a label indicating what we're * doing; set its alignment and padding so it's aligned on the * left. */ - title_lb = gtk_label_new(title); - gtk_box_pack_start(GTK_BOX(main_vb), title_lb, FALSE, TRUE, 3); + title_lb = gtk_label_new(item_title); + gtk_box_pack_start(GTK_BOX(dynamic_vb), title_lb, FALSE, TRUE, 3); gtk_misc_set_alignment(GTK_MISC(title_lb), 0.0, 0.0); gtk_misc_set_padding(GTK_MISC(title_lb), 0.0, 0.0); + /* same for "Status" */ + status_lb = gtk_label_new(""); + gtk_box_pack_start(GTK_BOX(dynamic_vb), status_lb, FALSE, TRUE, 3); + gtk_misc_set_alignment(GTK_MISC(status_lb), 0.0, 0.0); + gtk_misc_set_padding(GTK_MISC(status_lb), 0.0, 0.0); + dlg->status_lb = (GtkLabel *) status_lb; + + /* same for "Elapsed Time" */ + elapsed_lb = gtk_label_new("00:00"); + gtk_box_pack_start(GTK_BOX(dynamic_vb), elapsed_lb, FALSE, TRUE, 3); + gtk_misc_set_alignment(GTK_MISC(elapsed_lb), 0.0, 0.0); + gtk_misc_set_padding(GTK_MISC(elapsed_lb), 0.0, 0.0); + dlg->elapsed_lb = (GtkLabel *) elapsed_lb; + + /* same for "Time Left" */ + time_left_lb = gtk_label_new("--:--"); + gtk_box_pack_start(GTK_BOX(dynamic_vb), time_left_lb, FALSE, TRUE, 3); + gtk_misc_set_alignment(GTK_MISC(time_left_lb), 0.0, 0.0); + gtk_misc_set_padding(GTK_MISC(time_left_lb), 0.0, 0.0); + dlg->time_left_lb = (GtkLabel *) time_left_lb; + /* - * The progress bar. + * The progress bar (in its own horizontal box, including percentage value) */ + percentage_hb = gtk_hbox_new(FALSE, 1); + gtk_box_pack_start(GTK_BOX(dynamic_vb), percentage_hb, FALSE, TRUE, 3); + prog_bar = gtk_progress_bar_new(); gtk_progress_set_activity_mode(GTK_PROGRESS(prog_bar), FALSE); - gtk_box_pack_start(GTK_BOX(main_vb), prog_bar, FALSE, TRUE, 3); + gtk_box_pack_start(GTK_BOX(percentage_hb), prog_bar, FALSE, TRUE, 3); + + percentage_lb = gtk_label_new(" 0%"); + gtk_misc_set_alignment(GTK_MISC(percentage_lb), 0.0, 0.0); + gtk_box_pack_start(GTK_BOX(percentage_hb), percentage_lb, FALSE, TRUE, 3); + dlg->percentage_lb = (GtkLabel *) percentage_lb; /* - * Attach a pointer to the progress bar widget to the top-level - * widget. + * Attach a pointer to the progress bar widget to the top-level widget. */ gtk_object_set_data(GTK_OBJECT(dlg_w), PROG_BAR_KEY, prog_bar); /* + * Static and dynamic boxes are now complete + */ + main_hb = gtk_hbox_new(FALSE, 1); + gtk_box_pack_start(GTK_BOX(main_hb), static_vb, FALSE, TRUE, 3); + gtk_box_pack_start(GTK_BOX(main_hb), dynamic_vb, FALSE, TRUE, 3); + gtk_box_pack_start(GTK_BOX(main_vb), main_hb, FALSE, TRUE, 3); + + /* * Button row: cancel button. * (We put it in an HButtonBox, even though there's only one * of them, so that it doesn't expand to the width of the window.) @@ -135,16 +212,20 @@ create_progress_dlg(const gchar *title, const gchar *stop_title, dlg->dlg_w = dlg_w; + g_get_current_time(&dlg->start_time); + return dlg; } progdlg_t * -delayed_create_progress_dlg(const gchar *title, const gchar *stop_title, - gboolean *stop_flag, GTimeVal *start_time, gfloat progress) +delayed_create_progress_dlg(const gchar *task_title, const gchar *item_title, + const gchar *stop_title, gboolean *stop_flag, + GTimeVal *start_time, gfloat progress) { GTimeVal time_now; gfloat delta_time; gfloat min_display; + progdlg_t *dlg; #define INIT_DELAY 0.5 * 1e6 #define MIN_DISPLAY_DEFAULT 2.0 * 1e6 @@ -195,7 +276,12 @@ delayed_create_progress_dlg(const gchar *title, const gchar *stop_title, if (progress >= (delta_time / (delta_time + min_display))) return NULL; - return create_progress_dlg(title, stop_title, stop_flag); + dlg = create_progress_dlg(task_title, item_title, stop_title, stop_flag); + + /* set dialog start_time to the start of processing, not box creation */ + dlg->start_time = *start_time; + + return dlg; } /* @@ -228,14 +314,51 @@ stop_cb(GtkWidget *w _U_, gpointer data) } /* - * Set the percentage value of the progress bar. + * Update the progress information of the progress dialog box. */ void -update_progress_dlg(progdlg_t *dlg, gfloat percentage) +update_progress_dlg(progdlg_t *dlg, gfloat percentage, gchar *status) { GtkWidget *dlg_w = dlg->dlg_w; GtkWidget *prog_bar; + GTimeVal time_now; + gfloat delta_time; + gulong ul_left; + gulong ul_elapsed; + gulong ul_percentage; + gchar tmp[100]; + + + /* calculate some timing values */ + g_get_current_time(&time_now); + + delta_time = (time_now.tv_sec - dlg->start_time.tv_sec) * 1e6 + + time_now.tv_usec - dlg->start_time.tv_usec; + ul_percentage = percentage * 100; + ul_elapsed = delta_time / 1000 / 1000; + + /* update labels */ + g_snprintf(tmp, sizeof(tmp), "%lu%% of %s", ul_percentage, dlg->title); + gtk_window_set_title(GTK_WINDOW(dlg_w), tmp); + + gtk_label_set_text(dlg->status_lb, status); + + g_snprintf(tmp, sizeof(tmp), "%lu%%", ul_percentage); + gtk_label_set_text(dlg->percentage_lb, tmp); + + g_snprintf(tmp, sizeof(tmp), "%02lu:%02lu", ul_elapsed / 60, ul_elapsed % 60); + gtk_label_set_text(dlg->elapsed_lb, tmp); + + /* show "Time Left" only, + * if at least 5% and 3 seconds running (to get a useful estimation) */ + if (ul_percentage >= 5 && delta_time >= 3 * 1e6) { + ul_left = (delta_time / percentage - delta_time) / 1000 / 1000; + + g_snprintf(tmp, sizeof(tmp), "%02lu:%02lu", ul_left / 60, ul_left % 60); + gtk_label_set_text(dlg->time_left_lb, tmp); + } + /* update progress bar */ prog_bar = gtk_object_get_data(GTK_OBJECT(dlg_w), PROG_BAR_KEY); gtk_progress_bar_update(GTK_PROGRESS_BAR(prog_bar), percentage); |