aboutsummaryrefslogtreecommitdiffstats
path: root/gtk/progress_dlg.c
diff options
context:
space:
mode:
Diffstat (limited to 'gtk/progress_dlg.c')
-rw-r--r--gtk/progress_dlg.c167
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);