aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--e-util/e-alert.c48
-rw-r--r--e-util/e-alert.h2
-rw-r--r--widgets/misc/e-alert-bar.c12
3 files changed, 57 insertions, 5 deletions
diff --git a/e-util/e-alert.c b/e-util/e-alert.c
index 20199bc638..30afa8a9fe 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 4d6b2671b4..f62e612235 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 05f87cc752..8ed6bc3ff7 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