[zenity/time_remaining] Added time-remaining support to progress bars



commit 8d4af2c017ace3efd4752c194f306efaa1b34ca9
Author: Scott Pakin <pakin lanl gov>
Date:   Tue Aug 5 15:22:12 2014 -0600

    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(+), 0 deletions(-)
---
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 <sys/types.h>
 #include <unistd.h>
 #include <signal.h>
+#include <time.h>
 #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 @@
                 <property name="position">1</property>
               </packing>
             </child>
+            <child>
+              <object class="GtkLabel" id="zenity_progress_time">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="xalign">0</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">2</property>
+              </packing>
+            </child>
           </object>
           <packing>
             <property name="expand">False</property>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]