From 70ea28f34c25cc21bac51286b7e2c767a2df5807 Mon Sep 17 00:00:00 2001 From: Glynn Foster Date: Mon, 19 May 2003 18:24:41 +0000 Subject: Make the progress dialog actually work and now uses g_io_channel. Woot! 2003-05-19 Glynn Foster * src/progress.c: Make the progress dialog actually work and now uses g_io_channel. Woot! Need to be able to cancel the dialog, which currently doesn't work too well. * TODO: Update. * help/C/zenity.xml: Update help documentation. --- ChangeLog | 10 +++ TODO | 3 +- help/C/zenity.xml | 13 +++- src/progress.c | 197 +++++++++++++++++++++++++++++++++--------------------- 4 files changed, 143 insertions(+), 80 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0f3002dd..7c289625 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2003-05-19 Glynn Foster + + * src/progress.c: Make the progress dialog actually work + and now uses g_io_channel. Woot! Need to be able to cancel + the dialog, which currently doesn't work too well. + + * TODO: Update. + + * help/C/zenity.xml: Update help documentation. + 2003-05-06 Glynn Foster * src/main.c: Update commandline error message, needs updating diff --git a/TODO b/TODO index 71579b3c..4272fcd6 100644 --- a/TODO +++ b/TODO @@ -1,10 +1,9 @@ -* Fix bugs in the list dialog with stdin +* Canceling progress dialog should kill off process and close the dialog * Add pixmap support to list dialog ? - Suggested by Dani Brody * Add new format ? --list --column=check,hide --column=pixmap --column=string,editable - Suggested by Dani Brody -* Fix up progress dialog so that it actually works * Add support for DML (Dialog Meta Language)? - ftp://ftp.pld.org.pl/people/malekith/dml/ - Suggested by Michal Moskal diff --git a/help/C/zenity.xml b/help/C/zenity.xml index 4503a722..6d6257ab 100644 --- a/help/C/zenity.xml +++ b/help/C/zenity.xml @@ -596,7 +596,8 @@ then your first pieces of data for each row must be either 'TRUE' or 'FALSE'. See examples below for how to fill data into this dialog. The List dialog may also be filled by providing data from standard input, column by column, row by row, each - seperated by a newline. + seperated by a newline, however the column headers must appear with the + --column option. @@ -683,7 +684,9 @@ Progress - To create a Progress dialog, use --progress. + To create a Progress dialog, use --progress. Zenity reads data from + standard input line by line, determining whether it should update the text (if the + line is prefixed with a '#') or the percentage (if the line is a digit). @@ -736,12 +739,16 @@ #!/bin/sh ( echo "10" ; sleep 1 + echo "# Updating mail logs" ; sleep 1 echo "20" ; sleep 1 + echo "# Resetting cron jobs" ; sleep 1 echo "50" ; sleep 1 + echo "This line will just be ignored" ; sleep 1 echo "75" ; sleep 1 + echo "# Rebooting system" ; sleep 1 echo "100" ; sleep 1 ) | - zenity --progress --dialog-title="Update System Logs" --text="Updating mail logs..." --percentage=0 + zenity --progress --dialog-title="Update System Logs" --text="Scanning mail logs..." --percentage=0 if [ "$?" = -1 ] ; then zenity --error --text="Update cancelled." diff --git a/src/progress.c b/src/progress.c index d7ae35e3..aad133a2 100644 --- a/src/progress.c +++ b/src/progress.c @@ -29,11 +29,130 @@ static guint timer; static GladeXML *glade_dialog; +static GIOChannel *channel; + gint zenity_progress_timeout (gpointer data); gint zenity_progress_pulsate_timeout (gpointer data); static void zenity_progress_dialog_response (GtkWidget *widget, int response, gpointer data); +static gboolean +zenity_progress_pulsate_progress_bar (gpointer user_data) +{ + gtk_progress_bar_pulse (GTK_PROGRESS_BAR (user_data)); + return TRUE; +} + +static gboolean +zenity_progress_handle_stdin (GIOChannel *channel, + GIOCondition condition, + gpointer data) +{ + static ZenityProgressData *progress_data; + static GtkWidget *progress_bar; + static GtkWidget *progress_label; + static gint pulsate_timeout = -1; + float percentage = 0.0; + + progress_data = (ZenityProgressData *) data; + progress_bar = glade_xml_get_widget (glade_dialog, "zenity_progress_bar"); + progress_label = glade_xml_get_widget (glade_dialog, "zenity_progress_text"); + + if ((condition == G_IO_IN) || (condition == G_IO_IN + G_IO_HUP)) { + GString *string; + GError *error = NULL; + + string = g_string_new (NULL); + + if (progress_data->pulsate) { + if (pulsate_timeout == -1) + pulsate_timeout = g_timeout_add (100, zenity_progress_pulsate_progress_bar, progress_bar); + } + + while (channel->is_readable != TRUE) + ; + do { + gint status; + + do { + status = g_io_channel_read_line_string (channel, string, NULL, &error); + + while (gtk_events_pending ()) + gtk_main_iteration (); + + } while (status == G_IO_STATUS_AGAIN); + + if (status != G_IO_STATUS_NORMAL) { + if (error) { + g_warning ("zenity_progress_handle_stdin () : %s", error->message); + g_error_free (error); + error = NULL; + } + continue; + } + + if (!g_ascii_strncasecmp (string->str, "#", 1)) { + gchar *match; + + /* We have a comment, so let's try to change the label */ + match = g_strstr_len (string->str, strlen (string->str), "#"); + match++; + gtk_label_set_text (GTK_LABEL (progress_label), g_strchomp (g_strchug (match))); + } else { + + if (!g_ascii_isdigit (*(string->str))) + continue; + + /* Now try to convert the thing to a number */ + percentage = atoi (string->str); + if (percentage > 100) + gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progress_bar), 1.0); + else + gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progress_bar), percentage / 100.0); + } + + } while (g_io_channel_get_buffer_condition (channel) == G_IO_IN); + g_string_free (string, TRUE); + } + + if (condition != G_IO_IN) { + /* We assume that we are done, so stop the pulsating and de-sensitize the buttons */ + GtkWidget *button; + GtkWidget *progress_bar; + + button = glade_xml_get_widget (glade_dialog, "zenity_progress_ok_button"); + gtk_widget_set_sensitive (button, TRUE); + gtk_widget_grab_focus (button); + + button = glade_xml_get_widget (glade_dialog, "zenity_progress_cancel_button"); + gtk_widget_set_sensitive (button, FALSE); + + progress_bar = glade_xml_get_widget (glade_dialog, "zenity_progress_bar"); + gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progress_bar), 1.0); + + if (progress_data->pulsate) { + g_source_remove (pulsate_timeout); + pulsate_timeout = -1; + } + + if (glade_dialog) + g_object_unref (glade_dialog); + + g_io_channel_shutdown (channel, TRUE, NULL); + return FALSE; + } + return TRUE; +} + +static void +zenity_progress_read_info (ZenityProgressData *progress_data) +{ + channel = g_io_channel_unix_new (0); + g_io_channel_set_encoding (channel, NULL, NULL); + g_io_channel_set_flags (channel, G_IO_FLAG_NONBLOCK, NULL); + g_io_add_watch (channel, G_IO_IN | G_IO_HUP, zenity_progress_handle_stdin, progress_data); +} + void zenity_progress (ZenityData *data, ZenityProgressData *progress_data) { @@ -76,85 +195,11 @@ zenity_progress (ZenityData *data, ZenityProgressData *progress_data) progress_data->percentage/100.0); gtk_widget_show (dialog); - if (!progress_data->pulsate) - timer = gtk_timeout_add (100, zenity_progress_timeout, progress_bar); - else - timer = gtk_timeout_add (100, zenity_progress_pulsate_timeout, progress_bar); + zenity_progress_read_info (progress_data); gtk_main (); } -gint -zenity_progress_timeout (gpointer data) -{ - gchar buffer[256]; - float percentage; - - while(gtk_events_pending()) { - gtk_main_iteration(); - - if (timer == 0) - return FALSE; - } - - if (scanf ("%255s", buffer) == EOF) { - GtkWidget *button; - - button = glade_xml_get_widget (glade_dialog, "zenity_progress_ok_button"); - gtk_widget_set_sensitive (button, TRUE); - gtk_widget_grab_focus (button); - - button = glade_xml_get_widget (glade_dialog, "zenity_progress_cancel_button"); - gtk_widget_set_sensitive (button, FALSE); - - if (glade_dialog) - g_object_unref (glade_dialog); - - return FALSE; - } else { - percentage = atoi (buffer); - - if (percentage > 100) - gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (data), 1.0); - else - gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (data), percentage / 100.0); - - return TRUE; - } -} - -gint -zenity_progress_pulsate_timeout (gpointer data) -{ - - while(gtk_events_pending()) { - gtk_main_iteration(); - - if (timer == 0) - return FALSE; - } - - if (feof (stdin)) { - gtk_progress_bar_pulse (GTK_PROGRESS_BAR (data)); - return FALSE; - } else { - GtkWidget *button; - - /* We stop the pulsating and switch the focus on the dialog buttons */ - - gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (data), 1.0); - - button = glade_xml_get_widget (glade_dialog, "zenity_progress_ok_button"); - gtk_widget_set_sensitive (button, TRUE); - gtk_widget_grab_focus (button); - - button = glade_xml_get_widget (glade_dialog, "zenity_progress_cancel_button"); - gtk_widget_set_sensitive (button, FALSE); - - return TRUE; - } -} - static void zenity_progress_dialog_response (GtkWidget *widget, int response, gpointer data) { @@ -167,6 +212,8 @@ zenity_progress_dialog_response (GtkWidget *widget, int response, gpointer data) break; case GTK_RESPONSE_CANCEL: + /* FIXME: This should kill off the parent process - not entirely sure how to achieve this */ + kill (0); zen_data->exit_code = 1; gtk_main_quit (); break; -- cgit