aboutsummaryrefslogtreecommitdiffstats
path: root/e-util/e-alert.c
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2010-09-30 09:11:44 +0800
committerMatthew Barnes <mbarnes@redhat.com>2010-09-30 09:11:44 +0800
commit0e4c54eddced72c9639001849148fe1813c5dc4e (patch)
tree3ba53e853901d3b7e733b6aed145c5eb54e6a2fc /e-util/e-alert.c
parentd3b09614221d075452496a5198a3910d07eb2818 (diff)
downloadgsoc2013-evolution-0e4c54eddced72c9639001849148fe1813c5dc4e.tar.gz
gsoc2013-evolution-0e4c54eddced72c9639001849148fe1813c5dc4e.tar.zst
gsoc2013-evolution-0e4c54eddced72c9639001849148fe1813c5dc4e.zip
Messin around with EAlerts.
Trying out a new interface called EAlertSink. The idea is to centralize how errors are shown to the user. A GtkWindow subclass would implement the EAlertSink interface, which consists of a single method: void (*submit_alert) (EAlertSink *alert_sink, EAlert *alert); The subclass has complete control over what to do with the EAlert, although I imagine we'll wind up implementing various alert-handling policies as standalone widgets such as EAlertDialog. I'd like to try an EAlertInfoBar. Code that would otherwise display an error dialog itself would instead pass the EAlert to an appropriate EAlertSink and be done with it. Nothing is final yet. Still hacking on EAlert trying to find an API that feels right for these use cases.
Diffstat (limited to 'e-util/e-alert.c')
-rw-r--r--e-util/e-alert.c595
1 files changed, 355 insertions, 240 deletions
diff --git a/e-util/e-alert.c b/e-util/e-alert.c
index 49ba6af36b..65ab57bd8f 100644
--- a/e-util/e-alert.c
+++ b/e-util/e-alert.c
@@ -38,6 +38,7 @@
#include "e-util.h"
#include "e-util-private.h"
#include "e-alert.h"
+#include "e-alert-sink.h"
#define d(x)
@@ -46,14 +47,11 @@
((obj), E_TYPE_ALERT, EAlertPrivate))
struct _e_alert {
- guint32 flags;
const gchar *id;
- gint type;
+ GtkMessageType message_type;
gint default_response;
- const gchar *title;
- const gchar *primary;
- const gchar *secondary;
- gboolean scroll;
+ const gchar *primary_text;
+ const gchar *secondary_text;
struct _e_alert_button *buttons;
};
@@ -72,12 +70,10 @@ static struct _e_alert_button default_ok_button = {
};
static struct _e_alert default_alerts[] = {
- { GTK_DIALOG_MODAL, "error", 3, GTK_RESPONSE_OK,
- N_("Evolution Error"), "{0}", "{1}", FALSE,
- &default_ok_button },
- { GTK_DIALOG_MODAL, "warning", 1, GTK_RESPONSE_OK,
- N_("Evolution Warning"), "{0}", "{1}", FALSE,
- &default_ok_button }
+ { "error", GTK_MESSAGE_ERROR, GTK_RESPONSE_OK,
+ "{0}", "{1}", &default_ok_button },
+ { "warning", GTK_MESSAGE_WARNING, GTK_RESPONSE_OK,
+ "{0}", "{1}", &default_ok_button }
};
/* ********************************************************************** */
@@ -109,28 +105,16 @@ map_response (const gchar *name)
return 0;
}
-static struct {
- const gchar *name;
- const gchar *icon;
-} type_map[] = {
- { "info", GTK_STOCK_DIALOG_INFO },
- { "warning", GTK_STOCK_DIALOG_WARNING },
- { "question", GTK_STOCK_DIALOG_QUESTION },
- { "error", GTK_STOCK_DIALOG_ERROR },
-};
-
-static gint
-map_type (const gchar *name)
+static GtkMessageType
+map_type (const gchar *nick)
{
- gint i;
+ GEnumClass *class;
+ GEnumValue *value;
- if (name) {
- for (i = 0; i < G_N_ELEMENTS (type_map); i++)
- if (!strcmp (name, type_map[i].name))
- return i;
- }
+ class = g_type_class_peek (GTK_TYPE_MESSAGE_TYPE);
+ value = g_enum_get_value_by_nick (class, nick);
- return 3;
+ return (value != NULL) ? value->value : GTK_MESSAGE_ERROR;
}
G_DEFINE_TYPE (
@@ -140,22 +124,28 @@ G_DEFINE_TYPE (
enum {
PROP_0,
+ PROP_ARGS,
PROP_TAG,
- PROP_ARGS
+ PROP_MESSAGE_TYPE,
+ PROP_PRIMARY_TEXT,
+ PROP_SECONDARY_TEXT
};
struct _EAlertPrivate {
gchar *tag;
GPtrArray *args;
+ gchar *primary_text;
+ gchar *secondary_text;
struct _e_alert *definition;
+ GtkMessageType message_type;
+ gint default_response;
};
/*
XML format:
<error id="error-id" type="info|warning|question|error"?
- response="default_response"? modal="true"? >
- <title>Window Title</title>?
+ response="default_response"? >
<primary>Primary error text.</primary>?
<secondary>Secondary error text.</secondary>?
<button stock="stock-button-id"? label="button label"?
@@ -225,20 +215,12 @@ e_alert_load (const gchar *path)
e = g_malloc0 (sizeof (*e));
e->id = g_strdup (tmp);
- e->scroll = FALSE;
xmlFree (tmp);
lastbutton = (struct _e_alert_button *)&e->buttons;
- tmp = (gchar *)xmlGetProp(error, (const guchar *)"modal");
- if (tmp) {
- if (!strcmp(tmp, "true"))
- e->flags |= GTK_DIALOG_MODAL;
- xmlFree (tmp);
- }
-
tmp = (gchar *)xmlGetProp(error, (const guchar *)"type");
- e->type = map_type (tmp);
+ e->message_type = map_type (tmp);
if (tmp)
xmlFree (tmp);
@@ -248,27 +230,15 @@ e_alert_load (const gchar *path)
xmlFree (tmp);
}
- tmp = (gchar *)xmlGetProp(error, (const guchar *)"scroll");
- if (tmp) {
- if (!strcmp(tmp, "yes"))
- e->scroll = TRUE;
- xmlFree (tmp);
- }
-
for (scan = error->children;scan;scan=scan->next) {
if (!strcmp((gchar *)scan->name, "primary")) {
if ((tmp = (gchar *)xmlNodeGetContent (scan))) {
- e->primary = g_strdup (dgettext (table->translation_domain, tmp));
+ e->primary_text = g_strdup (dgettext (table->translation_domain, tmp));
xmlFree (tmp);
}
} else if (!strcmp((gchar *)scan->name, "secondary")) {
if ((tmp = (gchar *)xmlNodeGetContent (scan))) {
- e->secondary = g_strdup (dgettext (table->translation_domain, tmp));
- xmlFree (tmp);
- }
- } else if (!strcmp((gchar *)scan->name, "title")) {
- if ((tmp = (gchar *)xmlNodeGetContent (scan))) {
- e->title = g_strdup (dgettext (table->translation_domain, tmp));
+ e->secondary_text = g_strdup (dgettext (table->translation_domain, tmp));
xmlFree (tmp);
}
} else if (!strcmp((gchar *)scan->name, "button")) {
@@ -361,120 +331,232 @@ e_alert_load_tables (void)
g_free (base);
}
+static gchar *
+alert_format_string (const gchar *format,
+ GPtrArray *args)
+{
+ GString *string;
+ const gchar *end, *newstart;
+ gint id;
+
+ string = g_string_sized_new (strlen (format));
+
+ while (format
+ && (newstart = strchr (format, '{'))
+ && (end = strchr (newstart+1, '}'))) {
+ g_string_append_len (string, format, newstart - format);
+ id = atoi (newstart + 1);
+ if (id < args->len) {
+ g_string_append (string, args->pdata[id]);
+ } else
+ g_warning("Error references argument %d not supplied by caller", id);
+ format = end + 1;
+ }
+
+ g_string_append (string, format);
+
+ return g_string_free (string, FALSE);
+}
+
static void
-e_alert_get_property (GObject *object, guint property_id,
- GValue *value, GParamSpec *pspec)
+alert_set_tag (EAlert *alert,
+ const gchar *tag)
{
- EAlert *alert = (EAlert*) object;
+ struct _e_alert *definition;
+ struct _e_alert_table *table;
+ gchar *domain, *id;
- switch (property_id)
- {
- case PROP_TAG:
- g_value_set_string (value, alert->priv->tag);
- break;
- case PROP_ARGS:
- g_value_set_boxed (value, alert->priv->args);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ alert->priv->tag = g_strdup (tag);
+
+ g_return_if_fail (alert_table);
+
+ domain = g_alloca (strlen (tag) + 1);
+ strcpy (domain, tag);
+ id = strchr (domain, ':');
+ if (id)
+ *id++ = 0;
+ else {
+ g_warning ("Alert tag '%s' is missing a domain", tag);
+ return;
}
+
+ table = g_hash_table_lookup (alert_table, domain);
+ g_return_if_fail (table);
+
+ definition = g_hash_table_lookup (table->alerts, id);
+ g_warn_if_fail (definition);
+
+ alert->priv->definition = definition;
+ e_alert_set_message_type (alert, definition->message_type);
+ e_alert_set_default_response (alert, definition->default_response);
}
static void
-e_alert_set_property (GObject *object, guint property_id,
- const GValue *value, GParamSpec *pspec)
+alert_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
EAlert *alert = (EAlert*) object;
- switch (property_id)
- {
+ switch (property_id) {
case PROP_TAG:
- alert->priv->tag = g_value_dup_string (value);
- break;
+ alert_set_tag (
+ E_ALERT (object),
+ g_value_get_string (value));
+ return;
+
case PROP_ARGS:
alert->priv->args = g_value_dup_boxed (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ return;
+
+ case PROP_MESSAGE_TYPE:
+ e_alert_set_message_type (
+ E_ALERT (object),
+ g_value_get_enum (value));
+ return;
+
+ case PROP_PRIMARY_TEXT:
+ e_alert_set_primary_text (
+ E_ALERT (object),
+ g_value_get_string (value));
+ return;
+
+ case PROP_SECONDARY_TEXT:
+ e_alert_set_secondary_text (
+ E_ALERT (object),
+ g_value_get_string (value));
+ return;
}
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
static void
-e_alert_dispose (GObject *object)
+alert_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
{
EAlert *alert = (EAlert*) object;
- if (alert->priv->tag) {
- g_free (alert->priv->tag);
- alert->priv->tag = NULL;
- }
+ switch (property_id) {
+ case PROP_TAG:
+ g_value_set_string (value, alert->priv->tag);
+ return;
- if (alert->priv->args) {
- /* arg strings will be freed automatically since we set a free func when
- * creating the ptr array */
- g_boxed_free (G_TYPE_PTR_ARRAY, alert->priv->args);
- alert->priv->args = NULL;
+ case PROP_ARGS:
+ g_value_set_boxed (value, alert->priv->args);
+ return;
+
+ case PROP_MESSAGE_TYPE:
+ g_value_set_enum (
+ value, e_alert_get_message_type (
+ E_ALERT (object)));
+ return;
+
+ case PROP_PRIMARY_TEXT:
+ g_value_set_string (
+ value, e_alert_get_primary_text (
+ E_ALERT (object)));
+ return;
+
+ case PROP_SECONDARY_TEXT:
+ g_value_set_string (
+ value, e_alert_get_secondary_text (
+ E_ALERT (object)));
+ return;
}
- G_OBJECT_CLASS (e_alert_parent_class)->dispose (object);
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
static void
-e_alert_constructed (GObject *obj)
+alert_finalize (GObject *object)
{
- EAlert *alert = E_ALERT (obj);
-
- struct _e_alert_table *table;
- gchar *domain, *id;
-
- g_return_if_fail (alert_table);
- g_return_if_fail (alert->priv->tag);
+ EAlertPrivate *priv;
- domain = g_alloca (strlen (alert->priv->tag)+1);
- strcpy (domain, alert->priv->tag);
- id = strchr (domain, ':');
- if (id)
- *id++ = 0;
-
- table = g_hash_table_lookup (alert_table, domain);
- g_return_if_fail (table);
+ priv = E_ALERT_GET_PRIVATE (object);
- alert->priv->definition = g_hash_table_lookup (table->alerts, id);
+ g_free (priv->tag);
+ g_free (priv->primary_text);
+ g_free (priv->secondary_text);
- g_warn_if_fail (alert->priv->definition);
+ g_ptr_array_free (priv->args, TRUE);
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (e_alert_parent_class)->finalize (object);
}
+
static void
-e_alert_class_init (EAlertClass *klass)
+e_alert_class_init (EAlertClass *class)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- g_type_class_add_private (klass, sizeof (EAlertPrivate));
-
- object_class->get_property = e_alert_get_property;
- object_class->set_property = e_alert_set_property;
- object_class->dispose = e_alert_dispose;
- object_class->constructed = e_alert_constructed;
-
- g_object_class_install_property (object_class,
- PROP_TAG,
- g_param_spec_string ("tag",
- "alert tag",
- "A tag describing the alert",
- "",
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (object_class,
- PROP_ARGS,
- g_param_spec_boxed ("args",
- "Arguments",
- "Arguments for formatting the alert",
- G_TYPE_PTR_ARRAY,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS));
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+ g_type_class_add_private (class, sizeof (EAlertPrivate));
+
+ object_class->set_property = alert_set_property;
+ object_class->get_property = alert_get_property;
+ object_class->finalize = alert_finalize;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_ARGS,
+ g_param_spec_boxed (
+ "args",
+ "Arguments",
+ "Arguments for formatting the alert",
+ G_TYPE_PTR_ARRAY,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_TAG,
+ g_param_spec_string (
+ "tag",
+ "alert tag",
+ "A tag describing the alert",
+ "",
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_MESSAGE_TYPE,
+ g_param_spec_enum (
+ "message-type",
+ NULL,
+ NULL,
+ GTK_TYPE_MESSAGE_TYPE,
+ GTK_MESSAGE_ERROR,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_PRIMARY_TEXT,
+ g_param_spec_string (
+ "primary-text",
+ NULL,
+ NULL,
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SECONDARY_TEXT,
+ g_param_spec_string (
+ "secondary-text",
+ NULL,
+ NULL,
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
e_alert_load_tables ();
}
@@ -502,17 +584,17 @@ EAlert *
e_alert_new (const gchar *tag, ...)
{
EAlert *e;
- va_list ap;
+ va_list va;
- va_start (ap, tag);
- e = e_alert_new_valist (tag, ap);
- va_end (ap);
+ va_start (va, tag);
+ e = e_alert_new_valist (tag, va);
+ va_end (va);
return e;
}
EAlert *
-e_alert_new_valist (const gchar *tag, va_list ap)
+e_alert_new_valist (const gchar *tag, va_list va)
{
EAlert *alert;
GPtrArray *args;
@@ -520,10 +602,10 @@ e_alert_new_valist (const gchar *tag, va_list ap)
args = g_ptr_array_new_with_free_func (g_free);
- tmp = va_arg (ap, gchar *);
+ tmp = va_arg (va, gchar *);
while (tmp) {
g_ptr_array_add (args, g_strdup (tmp));
- tmp = va_arg (ap, gchar *);
+ tmp = va_arg (va, gchar *);
}
alert = e_alert_new_array (tag, args);
@@ -539,138 +621,114 @@ e_alert_new_array (const gchar *tag, GPtrArray *args)
return g_object_new (E_TYPE_ALERT, "tag", tag, "args", args, NULL);
}
-/* unfortunately, gmarkup_escape doesn't expose its gstring based api :( */
-static void
-e_alert_append_text_escaped (GString *out, const gchar *text)
+gint
+e_alert_get_default_response (EAlert *alert)
{
- gchar *markup;
+ g_return_val_if_fail (E_IS_ALERT (alert), 0);
- markup = g_markup_escape_text (text, -1);
- g_string_append (out, markup);
- g_free (markup);
+ return alert->priv->default_response;
}
-static void
-e_alert_format_string (GString *out,
- const gchar *fmt,
- GPtrArray *args,
- gboolean escape_args)
+void
+e_alert_set_default_response (EAlert *alert,
+ gint response_id)
{
- const gchar *end, *newstart;
- gint id;
+ g_return_if_fail (E_IS_ALERT (alert));
- while (fmt
- && (newstart = strchr (fmt, '{'))
- && (end = strchr (newstart+1, '}'))) {
- g_string_append_len (out, fmt, newstart-fmt);
- id = atoi (newstart+1);
- if (id < args->len) {
- if (escape_args)
- e_alert_append_text_escaped (out, args->pdata[id]);
- else
- g_string_append (out, args->pdata[id]);
- } else
- g_warning("Error references argument %d not supplied by caller", id);
- fmt = end+1;
- }
-
- g_string_append (out, fmt);
+ alert->priv->default_response = response_id;
}
-guint32
-e_alert_get_flags (EAlert *alert)
+GtkMessageType
+e_alert_get_message_type (EAlert *alert)
{
- g_return_val_if_fail (alert && alert->priv && alert->priv->definition, 0);
- return alert->priv->definition->flags;
-}
+ g_return_val_if_fail (E_IS_ALERT (alert), GTK_MESSAGE_OTHER);
-const gchar *
-e_alert_peek_stock_image (EAlert *alert)
-{
- g_return_val_if_fail (alert && alert->priv && alert->priv->definition, NULL);
- return type_map[alert->priv->definition->type].icon;
+ return alert->priv->message_type;
}
-gint
-e_alert_get_default_response (EAlert *alert)
+void
+e_alert_set_message_type (EAlert *alert,
+ GtkMessageType message_type)
{
- g_return_val_if_fail (alert && alert->priv && alert->priv->definition, 0);
- return alert->priv->definition->default_response;
+ g_return_if_fail (E_IS_ALERT (alert));
+
+ alert->priv->message_type = message_type;
+
+ g_object_notify (G_OBJECT (alert), "message-type");
}
-gchar *
-e_alert_get_title (EAlert *alert,
- gboolean escaped)
+const gchar *
+e_alert_get_primary_text (EAlert *alert)
{
- GString *formatted;
+ g_return_val_if_fail (E_IS_ALERT (alert), NULL);
- g_return_val_if_fail (alert && alert->priv && alert->priv->definition, NULL);
-
- formatted = g_string_new ("");
+ if (alert->priv->primary_text != NULL)
+ goto exit;
- if (alert->priv->definition->title != NULL)
- e_alert_format_string (
- formatted, alert->priv->definition->title,
- alert->priv->args, escaped);
+ if (alert->priv->definition == NULL)
+ goto exit;
- return g_string_free (formatted, FALSE);
-}
+ if (alert->priv->definition->primary_text == NULL)
+ goto exit;
-gchar *
-e_alert_get_primary_text (EAlert *alert,
- gboolean escaped)
-{
- GString *formatted;
+ if (alert->priv->args == NULL)
+ goto exit;
- g_return_val_if_fail (alert && alert->priv, NULL);
+ alert->priv->primary_text = alert_format_string (
+ alert->priv->definition->primary_text,
+ alert->priv->args);
- formatted = g_string_new ("");
+exit:
+ return alert->priv->primary_text;
+}
- if (alert->priv->definition != NULL)
- if (alert->priv->definition->primary != NULL) {
- e_alert_format_string (
- formatted, alert->priv->definition->primary,
- alert->priv->args, escaped);
- } else {
- gchar *title;
+void
+e_alert_set_primary_text (EAlert *alert,
+ const gchar *primary_text)
+{
+ g_return_if_fail (E_IS_ALERT (alert));
- title = e_alert_get_title (alert, escaped);
- g_string_append (formatted, title);
- g_free (title);
- }
- else {
- g_string_append_printf (
- formatted,
- _("Internal error, unknown error '%s' requested"),
- alert->priv->tag);
- }
+ g_free (alert->priv->primary_text);
+ alert->priv->primary_text = g_strdup (primary_text);
- return g_string_free (formatted, FALSE);
+ g_object_notify (G_OBJECT (alert), "primary-text");
}
-gchar *
-e_alert_get_secondary_text (EAlert *alert,
- gboolean escaped)
+const gchar *
+e_alert_get_secondary_text (EAlert *alert)
{
- GString *formatted;
+ g_return_val_if_fail (E_IS_ALERT (alert), NULL);
- g_return_val_if_fail (alert && alert->priv && alert->priv->definition, NULL);
+ if (alert->priv->secondary_text != NULL)
+ goto exit;
+
+ if (alert->priv->definition == NULL)
+ goto exit;
+
+ if (alert->priv->definition->secondary_text == NULL)
+ goto exit;
- formatted = g_string_new ("");
+ if (alert->priv->args == NULL)
+ goto exit;
- if (alert->priv->definition->secondary != NULL)
- e_alert_format_string (
- formatted, alert->priv->definition->secondary,
- alert->priv->args, escaped);
+ alert->priv->secondary_text = alert_format_string (
+ alert->priv->definition->secondary_text,
+ alert->priv->args);
- return g_string_free (formatted, FALSE);
+exit:
+ return alert->priv->secondary_text;
}
-gboolean
-e_alert_get_scroll (EAlert *alert)
+void
+e_alert_set_secondary_text (EAlert *alert,
+ const gchar *secondary_text)
{
- g_return_val_if_fail (alert && alert->priv && alert->priv->definition, FALSE);
- return alert->priv->definition->scroll;
+ g_return_if_fail (E_IS_ALERT (alert));
+
+ g_free (alert->priv->secondary_text);
+ alert->priv->secondary_text = g_strdup (secondary_text);
+
+ g_object_notify (G_OBJECT (alert), "secondary-text");
}
struct _e_alert_button *
@@ -679,3 +737,60 @@ e_alert_peek_buttons (EAlert *alert)
g_return_val_if_fail (alert && alert->priv && alert->priv->definition, NULL);
return alert->priv->definition->buttons;
}
+
+GtkWidget *
+e_alert_create_image (EAlert *alert,
+ GtkIconSize size)
+{
+ const gchar *stock_id;
+
+ g_return_val_if_fail (E_IS_ALERT (alert), NULL);
+
+ switch (e_alert_get_message_type (alert)) {
+ case GTK_MESSAGE_INFO:
+ stock_id = GTK_STOCK_DIALOG_INFO;
+ break;
+ case GTK_MESSAGE_WARNING:
+ stock_id = GTK_STOCK_DIALOG_WARNING;
+ break;
+ case GTK_MESSAGE_QUESTION:
+ stock_id = GTK_STOCK_DIALOG_QUESTION;
+ break;
+ case GTK_MESSAGE_ERROR:
+ stock_id = GTK_STOCK_DIALOG_ERROR;
+ break;
+ default:
+ stock_id = GTK_STOCK_MISSING_IMAGE;
+ g_warn_if_reached ();
+ break;
+ }
+
+ return gtk_image_new_from_stock (stock_id, size);
+}
+
+void
+e_alert_submit (GtkWidget *widget,
+ const gchar *tag,
+ ...)
+{
+ va_list va;
+
+ va_start (va, tag);
+ e_alert_submit_valist (widget, tag, va);
+ va_end (va);
+}
+
+void
+e_alert_submit_valist (GtkWidget *widget,
+ const gchar *tag,
+ va_list va)
+{
+ EAlert *alert;
+
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+ g_return_if_fail (tag != NULL);
+
+ alert = e_alert_new_valist (tag, va);
+ e_alert_sink_submit_alert (widget, alert);
+ g_object_unref (alert);
+}