[evolution] EAlertBar: Make warnings time out after 5 minutes



commit ac5adbd8fb5ee604d825c60da9fb2df99322a58f
Author: Matthew Barnes <mbarnes redhat com>
Date:   Fri Mar 25 14:20:19 2011 -0400

    EAlertBar: Make warnings time out after 5 minutes
    
    Warnings are generally meant for transient errors.  No need to leave
    them up indefinitely.  Close them automatically if the user hasn't
    responded after a reasonable period of time has elapsed.

 e-util/e-alert.c           |   48 ++++++++++++++++++++++++++++++++++++++++---
 e-util/e-alert.h           |    2 +
 widgets/misc/e-alert-bar.c |   12 ++++++++++-
 3 files changed, 57 insertions(+), 5 deletions(-)
---
diff --git a/e-util/e-alert.c b/e-util/e-alert.c
index 20199bc..30afa8a 100644
--- a/e-util/e-alert.c
+++ b/e-util/e-alert.c
@@ -91,6 +91,7 @@ struct _EAlertPrivate {
 	struct _e_alert *definition;
 	GtkMessageType message_type;
 	gint default_response;
+	guint timeout_id;
 
 	/* It may occur to one that we could use a GtkActionGroup here,
 	 * but we need to preserve the button order and GtkActionGroup
@@ -414,6 +415,14 @@ alert_set_tag (EAlert *alert,
 	alert->priv->definition = definition;
 }
 
+static gboolean
+alert_timeout_cb (EAlert *alert)
+{
+	e_alert_response (alert, alert->priv->default_response);
+
+	return FALSE;
+}
+
 static void
 alert_set_property (GObject *object,
                     guint property_id,
@@ -497,13 +506,17 @@ alert_get_property (GObject *object,
 static void
 alert_dispose (GObject *object)
 {
-	EAlertPrivate *priv;
+	EAlert *alert = E_ALERT (object);
 
-	priv = E_ALERT (object)->priv;
+	if (alert->priv->timeout_id > 0) {
+		g_source_remove (alert->priv->timeout_id);
+		alert->priv->timeout_id = 0;
+	}
 
-	while (!g_queue_is_empty (&priv->actions)) {
-		GtkAction *action = g_queue_pop_head (&priv->actions);
+	while (!g_queue_is_empty (&alert->priv->actions)) {
+		GtkAction *action;
 
+		action = g_queue_pop_head (&alert->priv->actions);
 		g_signal_handlers_disconnect_by_func (
 			action, G_CALLBACK (alert_action_activate), object);
 		g_object_unref (action);
@@ -923,6 +936,33 @@ e_alert_response (EAlert *alert,
 	g_signal_emit (alert, signals[RESPONSE], 0, response_id);
 }
 
+/**
+ * e_alert_start_timer:
+ * @alert: an #EAlert
+ * @seconds: seconds until timeout occurs
+ *
+ * Starts an internal timer for @alert.  When the timer expires, @alert
+ * will emit the default response.  There is only one timer per #EAlert,
+ * so calling this function repeatedly on the same #EAlert will restart
+ * its timer each time.  If @seconds is zero, the timer is cancelled and
+ * no response will be emitted.
+ **/
+void
+e_alert_start_timer (EAlert *alert,
+                     guint seconds)
+{
+	g_return_if_fail (E_IS_ALERT (alert));
+
+	if (alert->priv->timeout_id > 0) {
+		g_source_remove (alert->priv->timeout_id);
+		alert->priv->timeout_id = 0;
+	}
+
+	if (seconds > 0)
+		alert->priv->timeout_id = g_timeout_add_seconds (
+			seconds, (GSourceFunc) alert_timeout_cb, alert);
+}
+
 void
 e_alert_submit (EAlertSink *alert_sink,
                 const gchar *tag,
diff --git a/e-util/e-alert.h b/e-util/e-alert.h
index 4d6b267..f62e612 100644
--- a/e-util/e-alert.h
+++ b/e-util/e-alert.h
@@ -104,6 +104,8 @@ GtkWidget *	e_alert_create_image		(EAlert *alert,
 						 GtkIconSize size);
 void		e_alert_response		(EAlert *alert,
 						 gint response_id);
+void		e_alert_start_timer		(EAlert *alert,
+						 guint seconds);
 
 void		e_alert_submit			(struct _EAlertSink *alert_sink,
 						 const gchar *tag,
diff --git a/widgets/misc/e-alert-bar.c b/widgets/misc/e-alert-bar.c
index 05f87cc..8ed6bc3 100644
--- a/widgets/misc/e-alert-bar.c
+++ b/widgets/misc/e-alert-bar.c
@@ -22,7 +22,10 @@
 #include <glib/gi18n-lib.h>
 
 /* GTK_ICON_SIZE_DIALOG is a tad too big. */
-#define ICON_SIZE	GTK_ICON_SIZE_DND
+#define ICON_SIZE GTK_ICON_SIZE_DND
+
+/* Dismiss warnings automatically after 5 minutes. */
+#define WARNING_TIMEOUT_SECONDS (5 * 60)
 
 struct _EAlertBarPrivate {
 	GQueue alerts;
@@ -108,6 +111,13 @@ alert_bar_show_alert (EAlertBar *alert_bar)
 	gtk_image_set_from_stock (image, stock_id, ICON_SIZE);
 
 	gtk_widget_show (GTK_WIDGET (alert_bar));
+
+	/* Warnings are generally meant for transient errors.
+	 * No need to leave them up indefinitely.  Close them
+	 * automatically if the user hasn't responded after a
+	 * reasonable period of time has elapsed. */
+	if (message_type == GTK_MESSAGE_WARNING)
+		e_alert_start_timer (alert, WARNING_TIMEOUT_SECONDS);
 }
 
 static void



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