From 449e05f1b232fa2a1a92ae7c08c0f2b8870ac23a Mon Sep 17 00:00:00 2001 From: Srinivasa Ragavan Date: Wed, 29 Feb 2012 16:50:51 +0530 Subject: Move EAlert* and e-xml-utils to libevolution-utils. --- libevolution-utils/e-alert-dialog.c | 405 +++++++++++++++ libevolution-utils/e-alert-dialog.h | 80 +++ libevolution-utils/e-alert-sink.c | 93 ++++ libevolution-utils/e-alert-sink.h | 62 +++ libevolution-utils/e-alert.c | 996 ++++++++++++++++++++++++++++++++++++ libevolution-utils/e-alert.h | 119 +++++ libevolution-utils/e-xml-utils.c | 448 ++++++++++++++++ libevolution-utils/e-xml-utils.h | 93 ++++ 8 files changed, 2296 insertions(+) create mode 100644 libevolution-utils/e-alert-dialog.c create mode 100644 libevolution-utils/e-alert-dialog.h create mode 100644 libevolution-utils/e-alert-sink.c create mode 100644 libevolution-utils/e-alert-sink.h create mode 100644 libevolution-utils/e-alert.c create mode 100644 libevolution-utils/e-alert.h create mode 100644 libevolution-utils/e-xml-utils.c create mode 100644 libevolution-utils/e-xml-utils.h (limited to 'libevolution-utils') diff --git a/libevolution-utils/e-alert-dialog.c b/libevolution-utils/e-alert-dialog.c new file mode 100644 index 0000000000..5f426aacd0 --- /dev/null +++ b/libevolution-utils/e-alert-dialog.c @@ -0,0 +1,405 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see + * + * + * Authors: + * Michael Zucchi + * Jonathon Jongsma + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * Copyright (C) 2009 Intel Corporation + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include "e-alert-dialog.h" + +#include "e-util.h" + +#define E_ALERT_DIALOG_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_ALERT_DIALOG, EAlertDialogPrivate)) + +struct _EAlertDialogPrivate { + GtkWidget *content_area; /* not referenced */ + EAlert *alert; +}; + +enum { + PROP_0, + PROP_ALERT +}; + +G_DEFINE_TYPE ( + EAlertDialog, + e_alert_dialog, + GTK_TYPE_DIALOG) + +static void +alert_dialog_set_alert (EAlertDialog *dialog, + EAlert *alert) +{ + g_return_if_fail (E_IS_ALERT (alert)); + g_return_if_fail (dialog->priv->alert == NULL); + + dialog->priv->alert = g_object_ref (alert); +} + +static void +alert_dialog_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_ALERT: + alert_dialog_set_alert ( + E_ALERT_DIALOG (object), + g_value_get_object (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +alert_dialog_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_ALERT: + g_value_set_object ( + value, e_alert_dialog_get_alert ( + E_ALERT_DIALOG (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +alert_dialog_dispose (GObject *object) +{ + EAlertDialogPrivate *priv; + + priv = E_ALERT_DIALOG_GET_PRIVATE (object); + + if (priv->alert) { + g_signal_handlers_disconnect_matched ( + priv->alert, G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, object); + g_object_unref (priv->alert); + priv->alert = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (e_alert_dialog_parent_class)->dispose (object); +} + +static void +alert_dialog_constructed (GObject *object) +{ + EAlert *alert; + EAlertDialog *dialog; + GtkWidget *action_area; + GtkWidget *content_area; + GtkWidget *container; + GtkWidget *widget; + PangoAttribute *attr; + PangoAttrList *list; + GList *actions; + const gchar *primary, *secondary; + gint default_response; + gint min_width = -1, prefer_width = -1; + gint height; + + /* Chain up to parent's constructed() method. */ + G_OBJECT_CLASS (e_alert_dialog_parent_class)->constructed (object); + + dialog = E_ALERT_DIALOG (object); + alert = e_alert_dialog_get_alert (dialog); + + default_response = e_alert_get_default_response (alert); + + gtk_window_set_title (GTK_WINDOW (dialog), " "); + + action_area = gtk_dialog_get_action_area (GTK_DIALOG (dialog)); + content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog)); + + gtk_widget_ensure_style (GTK_WIDGET (dialog)); + gtk_container_set_border_width (GTK_CONTAINER (action_area), 12); + gtk_container_set_border_width (GTK_CONTAINER (content_area), 0); + + gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE); + + /* Forward EAlert::response signals to GtkDialog::response. */ + g_signal_connect_swapped ( + alert, "response", + G_CALLBACK (gtk_dialog_response), dialog); + + /* Add buttons from actions. */ + actions = e_alert_peek_actions (alert); + if (!actions) { + GtkAction *action; + + /* Make sure there is at least one action, thus the dialog can be closed. */ + action = gtk_action_new ( + "alert-response-0", _("_Dismiss"), NULL, NULL); + e_alert_add_action (alert, action, GTK_RESPONSE_CLOSE); + g_object_unref (action); + + actions = e_alert_peek_actions (alert); + } + + while (actions != NULL) { + GtkWidget *button; + gpointer data; + + /* These actions are already wired to trigger an + * EAlert::response signal when activated, which + * will in turn call to gtk_dialog_response(), + * so we can add buttons directly to the action + * area without knowing their response IDs. + * (XXX Well, kind of. See below.) */ + + button = gtk_button_new (); + + gtk_widget_set_can_default (button, TRUE); + + gtk_activatable_set_related_action ( + GTK_ACTIVATABLE (button), + GTK_ACTION (actions->data)); + + gtk_box_pack_end ( + GTK_BOX (action_area), + button, FALSE, FALSE, 0); + + /* This is set in e_alert_add_action(). */ + data = g_object_get_data ( + actions->data, "e-alert-response-id"); + + /* Normally GtkDialog sets the initial focus widget to + * the button corresponding to the default response, but + * because the buttons are not directly tied to response + * IDs, we have set both the default widget and the + * initial focus widget ourselves. */ + if (GPOINTER_TO_INT (data) == default_response) { + gtk_widget_grab_default (button); + gtk_widget_grab_focus (button); + } + + actions = g_list_next (actions); + } + + widget = gtk_hbox_new (FALSE, 12); + gtk_container_set_border_width (GTK_CONTAINER (widget), 12); + gtk_box_pack_start (GTK_BOX (content_area), widget, FALSE, FALSE, 0); + gtk_widget_show (widget); + + container = widget; + + widget = e_alert_create_image (alert, GTK_ICON_SIZE_DIALOG); + gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.0); + gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); + gtk_widget_show (widget); + + widget = gtk_vbox_new (FALSE, 12); + gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); + dialog->priv->content_area = widget; + gtk_widget_show (widget); + + container = widget; + + primary = e_alert_get_primary_text (alert); + secondary = e_alert_get_secondary_text (alert); + + list = pango_attr_list_new (); + attr = pango_attr_scale_new (PANGO_SCALE_LARGE); + pango_attr_list_insert (list, attr); + attr = pango_attr_weight_new (PANGO_WEIGHT_BOLD); + pango_attr_list_insert (list, attr); + + widget = gtk_label_new (primary); + gtk_label_set_attributes (GTK_LABEL (widget), list); + gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE); + gtk_label_set_selectable (GTK_LABEL (widget), TRUE); + gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.0); + gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); + gtk_widget_set_can_focus (widget, FALSE); + gtk_widget_show (widget); + + widget = gtk_label_new (secondary); + gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE); + gtk_label_set_selectable (GTK_LABEL (widget), TRUE); + gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.0); + gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); + gtk_widget_set_can_focus (widget, FALSE); + gtk_widget_show (widget); + + widget = GTK_WIDGET (dialog); + + height = gtk_widget_get_allocated_height (widget); + gtk_widget_get_preferred_width_for_height ( + widget, height, &min_width, &prefer_width); + if (min_width < prefer_width) + gtk_window_set_default_size ( + GTK_WINDOW (dialog), MIN ( + (min_width + prefer_width) / 2, + min_width * 5 / 4), -1); + + pango_attr_list_unref (list); +} + +static void +e_alert_dialog_class_init (EAlertDialogClass *class) +{ + GObjectClass *object_class; + + g_type_class_add_private (class, sizeof (EAlertDialogPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = alert_dialog_set_property; + object_class->get_property = alert_dialog_get_property; + object_class->dispose = alert_dialog_dispose; + object_class->constructed = alert_dialog_constructed; + + g_object_class_install_property ( + object_class, + PROP_ALERT, + g_param_spec_object ( + "alert", + "Alert", + "Alert to be displayed", + E_TYPE_ALERT, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); +} + +static void +e_alert_dialog_init (EAlertDialog *dialog) +{ + dialog->priv = E_ALERT_DIALOG_GET_PRIVATE (dialog); +} + +GtkWidget * +e_alert_dialog_new (GtkWindow *parent, + EAlert *alert) +{ + g_return_val_if_fail (E_IS_ALERT (alert), NULL); + + return g_object_new ( + E_TYPE_ALERT_DIALOG, + "alert", alert, "transient-for", parent, NULL); +} + +GtkWidget * +e_alert_dialog_new_for_args (GtkWindow *parent, + const gchar *tag, + ...) +{ + GtkWidget *dialog; + EAlert *alert; + va_list ap; + + g_return_val_if_fail (tag != NULL, NULL); + + va_start (ap, tag); + alert = e_alert_new_valist (tag, ap); + va_end (ap); + + dialog = e_alert_dialog_new (parent, alert); + + g_object_unref (alert); + + return dialog; +} + +gint +e_alert_run_dialog (GtkWindow *parent, + EAlert *alert) +{ + GtkWidget *dialog; + gint response; + + g_return_val_if_fail (E_IS_ALERT (alert), 0); + + dialog = e_alert_dialog_new (parent, alert); + response = gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + + return response; +} + +gint +e_alert_run_dialog_for_args (GtkWindow *parent, + const gchar *tag, + ...) +{ + EAlert *alert; + gint response; + va_list ap; + + g_return_val_if_fail (tag != NULL, 0); + + va_start (ap, tag); + alert = e_alert_new_valist (tag, ap); + va_end (ap); + + response = e_alert_run_dialog (parent, alert); + + g_object_unref (alert); + + return response; +} + +/** + * e_alert_dialog_get_alert: + * @dialog: an #EAlertDialog + * + * Returns the #EAlert associated with @dialog. + * + * Returns: the #EAlert associated with @dialog + **/ +EAlert * +e_alert_dialog_get_alert (EAlertDialog *dialog) +{ + g_return_val_if_fail (E_IS_ALERT_DIALOG (dialog), NULL); + + return dialog->priv->alert; +} + +/** + * e_alert_dialog_get_content_area: + * @dialog: an #EAlertDialog + * + * Returns the vertical box containing the primary and secondary labels. + * Use this to pack additional widgets into the dialog with the proper + * horizontal alignment (maintaining the left margin below the image). + * + * Returns: the content area #GtkBox + **/ +GtkWidget * +e_alert_dialog_get_content_area (EAlertDialog *dialog) +{ + g_return_val_if_fail (E_IS_ALERT_DIALOG (dialog), NULL); + + return dialog->priv->content_area; +} diff --git a/libevolution-utils/e-alert-dialog.h b/libevolution-utils/e-alert-dialog.h new file mode 100644 index 0000000000..a8d1b1d6d5 --- /dev/null +++ b/libevolution-utils/e-alert-dialog.h @@ -0,0 +1,80 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see + * + * + * Authors: + * Michael Zucchi + * Jonathon Jongsma + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * Copyright (C) 2009 Intel Corporation + */ + +#ifndef E_ALERT_DIALOG_H +#define E_ALERT_DIALOG_H + +#include +#include + +/* Standard GObject macros */ +#define E_TYPE_ALERT_DIALOG \ + (e_alert_dialog_get_type ()) +#define E_ALERT_DIALOG(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_ALERT_DIALOG, EAlertDialog)) +#define E_ALERT_DIALOG_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_ALERT_DIALOG, EAlertDialogClass)) +#define E_IS_ALERT_DIALOG(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_ALERT_DIALOG)) +#define E_IS_ALERT_DIALOG_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_ALERT_DIALOG)) +#define E_ALERT_DIALOG_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_ALERT_DIALOG, EAlertDialogClass)) + +G_BEGIN_DECLS + +typedef struct _EAlertDialog EAlertDialog; +typedef struct _EAlertDialogClass EAlertDialogClass; +typedef struct _EAlertDialogPrivate EAlertDialogPrivate; + +struct _EAlertDialog { + GtkDialog parent; + EAlertDialogPrivate *priv; +}; + +struct _EAlertDialogClass { + GtkDialogClass parent_class; +}; + +GType e_alert_dialog_get_type (void); +GtkWidget * e_alert_dialog_new (GtkWindow *parent, + EAlert *alert); +GtkWidget * e_alert_dialog_new_for_args (GtkWindow *parent, + const gchar *tag, + ...) G_GNUC_NULL_TERMINATED; +gint e_alert_run_dialog (GtkWindow *parent, + EAlert *alert); +gint e_alert_run_dialog_for_args (GtkWindow *parent, + const gchar *tag, + ...) G_GNUC_NULL_TERMINATED; +EAlert * e_alert_dialog_get_alert (EAlertDialog *dialog); +GtkWidget * e_alert_dialog_get_content_area (EAlertDialog *dialog); + +G_END_DECLS + +#endif /* E_ALERT_DIALOG_H */ diff --git a/libevolution-utils/e-alert-sink.c b/libevolution-utils/e-alert-sink.c new file mode 100644 index 0000000000..ae3a7361e1 --- /dev/null +++ b/libevolution-utils/e-alert-sink.c @@ -0,0 +1,93 @@ +/* + * e-alert-sink.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see + * + */ + +/** + * SECTION: e-alert-sink + * @short_description: an interface to handle alerts + * @include: e-util/e-alert-sink.h + * + * A widget that implements #EAlertSink means it can handle #EAlerts, + * usually by displaying them to the user. + **/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "e-alert-sink.h" + +#include "e-alert-dialog.h" + +G_DEFINE_INTERFACE ( + EAlertSink, + e_alert_sink, + GTK_TYPE_WIDGET) + +static void +alert_sink_fallback (GtkWidget *widget, + EAlert *alert) +{ + GtkWidget *dialog; + gpointer parent; + + parent = gtk_widget_get_toplevel (widget); + parent = gtk_widget_is_toplevel (parent) ? parent : NULL; + + dialog = e_alert_dialog_new (parent, alert); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); +} + +static void +alert_sink_submit_alert (EAlertSink *alert_sink, + EAlert *alert) +{ + /* This is just a lame fallback handler. Implementors + * are strongly encouraged to override this method. */ + alert_sink_fallback (GTK_WIDGET (alert_sink), alert); +} + +static void +e_alert_sink_default_init (EAlertSinkInterface *interface) +{ + interface->submit_alert = alert_sink_submit_alert; +} + +/** + * e_alert_sink_submit_alert: + * @alert_sink: an #EAlertSink + * @alert: an #EAlert + * + * This function is a place to pass #EAlert objects. Beyond that it has no + * well-defined behavior. It's up to the widget implementing the #EAlertSink + * interface to decide what to do with them. + **/ +void +e_alert_sink_submit_alert (EAlertSink *alert_sink, + EAlert *alert) +{ + EAlertSinkInterface *interface; + + g_return_if_fail (E_IS_ALERT_SINK (alert_sink)); + g_return_if_fail (E_IS_ALERT (alert)); + + interface = E_ALERT_SINK_GET_INTERFACE (alert_sink); + g_return_if_fail (interface->submit_alert != NULL); + + interface->submit_alert (alert_sink, alert); +} diff --git a/libevolution-utils/e-alert-sink.h b/libevolution-utils/e-alert-sink.h new file mode 100644 index 0000000000..da5ae7b06f --- /dev/null +++ b/libevolution-utils/e-alert-sink.h @@ -0,0 +1,62 @@ +/* + * e-alert-sink.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see + * + */ + +#ifndef E_ALERT_SINK_H +#define E_ALERT_SINK_H + +#include +#include + +/* Standard GObject macros */ +#define E_TYPE_ALERT_SINK \ + (e_alert_sink_get_type ()) +#define E_ALERT_SINK(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_ALERT_SINK, EAlertSink)) +#define E_ALERT_SINK_INTERFACE(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_ALERT_SINK, EAlertSinkInterface)) +#define E_IS_ALERT_SINK(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_ALERT_SINK)) +#define E_IS_ALERT_SINK_INTERFACE(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_ALERT_SINK)) +#define E_ALERT_SINK_GET_INTERFACE(obj) \ + (G_TYPE_INSTANCE_GET_INTERFACE \ + ((obj), E_TYPE_ALERT_SINK, EAlertSinkInterface)) + +G_BEGIN_DECLS + +typedef struct _EAlertSink EAlertSink; +typedef struct _EAlertSinkInterface EAlertSinkInterface; + +struct _EAlertSinkInterface { + GTypeInterface parent_interface; + + void (*submit_alert) (EAlertSink *alert_sink, + EAlert *alert); +}; + +GType e_alert_sink_get_type (void); +void e_alert_sink_submit_alert (EAlertSink *alert_sink, + EAlert *alert); + +G_END_DECLS + +#endif /* E_ALERT_SINK_H */ diff --git a/libevolution-utils/e-alert.c b/libevolution-utils/e-alert.c new file mode 100644 index 0000000000..9ee7e05581 --- /dev/null +++ b/libevolution-utils/e-alert.c @@ -0,0 +1,996 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see + * + * + * Authors: + * Michael Zucchi + * Jonathon Jongsma + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * Copyright (C) 2009 Intel Corporation + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include +#include + +#include +#include + +#include + +#include "e-util.h" +#include "e-util-private.h" +#include "e-alert.h" +#include "e-alert-sink.h" + +#define d(x) + +#define E_ALERT_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_ALERT, EAlertPrivate)) + +typedef struct _EAlertButton EAlertButton; + +struct _e_alert { + const gchar *id; + GtkMessageType message_type; + gint default_response; + const gchar *primary_text; + const gchar *secondary_text; + EAlertButton *buttons; +}; + +struct _e_alert_table { + const gchar *domain; + const gchar *translation_domain; + GHashTable *alerts; +}; + +struct _EAlertButton { + EAlertButton *next; + const gchar *stock_id; + const gchar *label; + gint response_id; +}; + +static GHashTable *alert_table; + +/* ********************************************************************** */ + +static EAlertButton default_ok_button = { + NULL, GTK_STOCK_OK, NULL, GTK_RESPONSE_OK +}; + +static struct _e_alert default_alerts[] = { + { "error", GTK_MESSAGE_ERROR, GTK_RESPONSE_OK, + "{0}", "{1}", &default_ok_button }, + { "warning", GTK_MESSAGE_WARNING, GTK_RESPONSE_OK, + "{0}", "{1}", &default_ok_button } +}; + +/* ********************************************************************** */ + +struct _EAlertPrivate { + gchar *tag; + GPtrArray *args; + gchar *primary_text; + gchar *secondary_text; + 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 + * uses a hash table, which does not preserve order. */ + GQueue actions; +}; + +enum { + PROP_0, + PROP_ARGS, + PROP_TAG, + PROP_MESSAGE_TYPE, + PROP_PRIMARY_TEXT, + PROP_SECONDARY_TEXT +}; + +enum { + RESPONSE, + LAST_SIGNAL +}; + +static gulong signals[LAST_SIGNAL]; + +G_DEFINE_TYPE ( + EAlert, + e_alert, + G_TYPE_OBJECT) + +static gint +map_response (const gchar *name) +{ + GEnumClass *class; + GEnumValue *value; + + class = g_type_class_ref (GTK_TYPE_RESPONSE_TYPE); + value = g_enum_get_value_by_name (class, name); + g_type_class_unref (class); + + return (value != NULL) ? value->value : 0; +} + +static GtkMessageType +map_type (const gchar *nick) +{ + GEnumClass *class; + GEnumValue *value; + + class = g_type_class_ref (GTK_TYPE_MESSAGE_TYPE); + value = g_enum_get_value_by_nick (class, nick); + g_type_class_unref (class); + + return (value != NULL) ? value->value : GTK_MESSAGE_ERROR; +} + +/* + * XML format: + * + * + * Primary error text.? + * Secondary error text.? + *