From 673550b6d326e111867fa78ba4d796045715202e Mon Sep 17 00:00:00 2001 From: Scott Pakin Date: Tue, 5 Aug 2014 15:22:12 -0600 Subject: [PATCH] Added time-remaining support to progress bars Introduced a --time-remaining command-line option that uses the time and percent complete to extrapolate the time remaining until progress reaches 100%. --- src/option.c | 17 +++++++++++++++++ src/progress.c | 37 +++++++++++++++++++++++++++++++++++++ src/zenity.h | 1 + src/zenity.ui | 12 ++++++++++++ 4 files changed, 67 insertions(+) diff --git a/src/option.c b/src/option.c index f5c84d5..c1e3a77 100644 --- a/src/option.c +++ b/src/option.c @@ -98,6 +98,7 @@ static gboolean zenity_progress_pulsate; static gboolean zenity_progress_auto_close; static gboolean zenity_progress_auto_kill; static gboolean zenity_progress_no_cancel; +static gboolean zenity_progress_time_remaining; /* Question Dialog Options */ static gboolean zenity_question_active; @@ -767,6 +768,15 @@ static GOptionEntry progress_options[] = { N_("Hide Cancel button"), NULL }, + { + "time-remaining", + '\0', + 0, + G_OPTION_ARG_NONE, + &zenity_progress_time_remaining, + N_("Estimate when progress will reach 100%"), + NULL + }, { NULL } @@ -1551,6 +1561,7 @@ zenity_progress_pre_callback (GOptionContext *context, zenity_progress_auto_close = FALSE; zenity_progress_auto_kill = FALSE; zenity_progress_no_cancel = FALSE; + zenity_progress_time_remaining = FALSE; return TRUE; } @@ -1935,6 +1946,7 @@ zenity_progress_post_callback (GOptionContext *context, results->progress_data->autokill = zenity_progress_auto_kill; results->progress_data->percentage = zenity_progress_percentage; results->progress_data->no_cancel = zenity_progress_no_cancel; + results->progress_data->time_remaining = zenity_progress_time_remaining; } else { if (zenity_progress_pulsate) zenity_option_error (zenity_option_get_name (progress_options, &zenity_progress_pulsate), @@ -1951,9 +1963,14 @@ zenity_progress_post_callback (GOptionContext *context, if (zenity_progress_auto_kill) zenity_option_error (zenity_option_get_name (progress_options, &zenity_progress_auto_kill), ERROR_SUPPORT); + if (zenity_progress_no_cancel) zenity_option_error (zenity_option_get_name (progress_options, &zenity_progress_no_cancel), ERROR_SUPPORT); + + if (zenity_progress_time_remaining) + zenity_option_error (zenity_option_get_name (progress_options, &zenity_progress_time_remaining), + ERROR_SUPPORT); } return TRUE; diff --git a/src/progress.c b/src/progress.c index cbffe08..0054487 100644 --- a/src/progress.c +++ b/src/progress.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "zenity.h" #include "util.h" @@ -72,6 +73,39 @@ zenity_progress_pulsate_start (GObject *progress_bar) } } +static void +zenity_progress_update_time_remaining (ZenityProgressData *progress_data) +{ + static GObject *progress_time = NULL; + static time_t start_time = (time_t)(-1); + float percentage = progress_data->percentage; + + if (progress_time == NULL) + progress_time = gtk_builder_get_object (builder, "zenity_progress_time"); + if (start_time == (time_t)(-1) || percentage <= 0.0 || percentage >= 100.0) { + start_time = time(NULL); + gtk_label_set_text (GTK_LABEL (progress_time), ""); + } else { + time_t current_time = time (NULL); + time_t elapsed_time = current_time - start_time; + time_t total_time = (time_t) (100.0*elapsed_time/progress_data->percentage); + time_t remaining_time = total_time - elapsed_time; + gulong hours, minutes, seconds; + gchar *remaining_message; + + seconds = (gulong) (remaining_time%60); + remaining_time /= 60; + minutes = (gulong) (remaining_time%60); + remaining_time /= 60; + hours = (gulong) remaining_time; + + remaining_message = g_strdup_printf (_("Time remaining: %lu:%02lu:%02lu"), + hours, minutes, seconds); + gtk_label_set_text (GTK_LABEL (progress_time), remaining_message); + g_free (remaining_message); + } +} + static gboolean zenity_progress_handle_stdin (GIOChannel *channel, GIOCondition condition, @@ -160,6 +194,9 @@ zenity_progress_handle_stdin (GIOChannel *channel, progress_data->percentage = percentage; + if (progress_data->time_remaining == TRUE) + zenity_progress_update_time_remaining (progress_data); + if (percentage == 100) { GObject *button; diff --git a/src/zenity.h b/src/zenity.h index d3606cd..4cf7a04 100644 --- a/src/zenity.h +++ b/src/zenity.h @@ -105,6 +105,7 @@ typedef struct { gboolean autokill; gdouble percentage; gboolean no_cancel; + gboolean time_remaining; } ZenityProgressData; typedef struct { diff --git a/src/zenity.ui b/src/zenity.ui index 61bea5e..5b40e9e 100644 --- a/src/zenity.ui +++ b/src/zenity.ui @@ -870,6 +870,18 @@ 1 + + + True + False + 0 + + + False + False + 2 + + False