diff --git a/composer/mail-composer-errors.xml.in b/composer/mail-composer-errors.xml.in
new file mode 100644
index 0000000000..442891d09f
--- /dev/null
+++ b/composer/mail-composer-errors.xml.in
@@ -0,0 +1,35 @@
+
+
+
+
+ <_primary>You cannot attach the file `${0}' to this message.
+ <_secondary>${0}
+
+
+
+ <_primary>The file `${0}' is not a regular file and cannot be sent in a message.
+
+
+
+ <_primary>Directories can not be attached to Messages.
+ <_secondary>To attach the contents of this directory, either attach the files in this directory individually, or create an archive of the directory and attach it.
+
+
+
+ <_title>Unfinished messages found
+ <_primary>Do you want to recover unfinished messages?
+ <_secondary>Evolution quit unexpectedly while you were composing a new message. Recovering the message will allow you to continue where you left off.
+
+
+
+
+
+ <_title>Warning: Modified Message
+ <_primary>Are you sure you want to discard the message, titled '{0}', you are composing?
+ <_secondary>Closing this composer window will discard the message permanently, unless you choose to save the message in your Drafts folder. This will allow you to continue the message at a later date.
+
+
+
+
+
+
diff --git a/filter/filter-errors.xml.in b/filter/filter-errors.xml.in
new file mode 100644
index 0000000000..97bbd9c8fb
--- /dev/null
+++ b/filter/filter-errors.xml.in
@@ -0,0 +1,51 @@
+
+
+
+
+ <_primary>Missing date.
+ <_secondary>You must choose a date.
+
+
+
+ <_primary>Missing file name.
+ <_secondary>You must specify a file name.
+
+
+
+ <_primary>File "{0}" does not exist or is not a regular file.
+ <_secondary>You must specify a file name.
+
+
+
+ <_primary>Missing folder.
+ <_secondary>You must specify a folder.
+
+
+
+ <_primary>Bad regular expression "{0}".
+ <_secondary>Could not compile regular expression "{1}".
+
+
+
+ <_primary>Missing name.
+ <_secondary>You must name this filter.
+
+
+
+ <_primary>Missing name.
+ <_secondary>You must name this vFolder.
+
+
+
+ <_primary>Name "{0}" already used.
+ <_secondary>Please choose another name.
+
+
+
+ <_primary>No sources selected.
+ <_secondary>You must specify at least one folder as a source.
+Either by selecting the folders individually, and/or by selecting
+all local folders, all remote folders, or both.
+
+
+
\ No newline at end of file
diff --git a/mail/mail-errors.xml.in b/mail/mail-errors.xml.in
new file mode 100644
index 0000000000..81a7d09af0
--- /dev/null
+++ b/mail/mail-errors.xml.in
@@ -0,0 +1,293 @@
+
+
+
+
+ <_primary>Invalid authentication
+ <_secondary>This server does not support this type of authentication and may not support authentication at all.
+
+
+
+ <_primary>Your login to your server "{0}" as "{0}" failed.
+ <_secondary>Check to make sure your password is spelled correctly. Remember that many passwords are case sensitive; your caps lock might be on.
+
+
+
+ <_primary>Are you sure you want to send a message in HTML format?
+ <_secondary>Please make sure the following recipients are willing and able to receive HTML email:
+{0}
+Send anyway?
+
+
+
+
+
+ <_primary>Are you sure you want to send a message without a subject?
+ <_secondary>Adding a meaningful Subject line to your messages will give your recipients an idea of what your mail is about.
+
+
+
+
+
+ <_primary>Are you sure you want to send a message with only BCC recipients?
+ <_secondary>The contact list you are sending to is configured to hide list recipients.
+
+Many email systems add an Apparently-To header to messages that only have BCC recipients. This header, if added, will list all of your recipients in your message. To avoid this, you should add at least one To: or CC: recipient.
+
+
+
+
+
+ <_primary>Are you sure you want to send a message with only BCC recipients?
+ <_secondary>Many email systems add an Apparently-To header to messages that only have BCC recipients. This header, if added, will list all of your recipients to your message anyway. To avoid this, you should add at least one To: or CC: recipient.
+
+
+
+
+
+ <_primary>This message cannot be sent because you have not specified any Recipients
+ <_secondary>Please enter a valid email address in the To: field. You can search for email addresses by clicking on the To: button next to the entry box.
+
+
+
+ <_primary>Use default drafts folder?
+ <_secondary>Unable to open the drafts folder for this account. Use the system drafts folder instead?
+
+
+
+
+
+ <_primary>Are you sure you want to permanently remove all the deleted message in folder "{0}"?
+ <_secondary>If you continue, you will not be able to recover these messages.
+
+
+
+
+
+ <_primary>Are you sure you want to permanently remove all the deleted messages in all folders?
+ <_secondary>If you continue, you will not be able to recover these messages.
+
+
+
+
+
+ <_primary>You have unsent messages, do you wish to quit anyway?
+ <_secondary>If you quit, these messages will not be sent until Evolution is started again.
+
+
+
+
+
+ <_primary>Your message message, with the subject "{0}" was not delivered.
+ <_secondary>The message was sent via the "sendmail" external application. Sendmail reports the following error: status 67: mail not sent.
+The message is stored in the Outbox folder. Check the message for errors and resend.
+
+
+
+ <_primary>Error while {0}.
+ <_secondary>{1}.
+
+
+
+ <_primary>Error while performing operation.
+ <_secondary>{0}.
+
+
+
+ <_primary>{0}
+
+
+
+ <_primary>{0}
+
+
+
+
+
+ <_primary>{0}
+
+
+
+ <_primary>{0}
+
+
+
+
+
+ <_primary>{0}
+
+
+
+ <_primary>{0}
+
+
+
+
+
+ <_primary>Enter password for {0}
+
+
+
+
+
+ <_primary>Error loading filter definitions.
+ <_secondary>{0}
+
+
+
+ <_primary>Cannot save to directory "{0}".
+ <_secondary>{1}
+
+
+
+ <_title>Overwrite file?
+ <_primary>File exists "{0}".
+ <_secondary>Do you wish to overwrite it?
+
+
+
+
+
+ <_primary>Cannot save to file "{0}".
+ <_secondary>Cannot create the save directory, because "{1}"
+
+
+
+ <_primary>Cannot create temporary save directory.
+ <_secondary>Because "{1}".
+
+
+
+ <_primary>Cannot save to file "{0}".
+ <_secondary>File exists but cannot overwrite it.
+
+
+
+ <_primary>Cannot save to file "{0}".
+ <_secondary>File exists but is not a regular file.
+
+
+
+ <_primary>Cannot delete folder "{0}".
+ <_secondary>Because "{1}".
+
+
+
+ <_primary>Cannot delete system folder "{0}".
+ <_secondary>System folders are required for Ximian Evolution to function correctly and cannot be renamed, moved, or deleted.
+
+
+
+ <_primary>Cannot rename or move system folder "{0}".
+ <_secondary>System folders are required for Ximian Evolution to function correctly and cannot be renamed, moved, or deleted.
+
+
+
+ <_title>Delete "{0}"?
+ <_primary>Really delete folder "{0}" and all of its subfolders?
+ <_secondary>If you delete the folder, all of its contents and its subfolders contents will be deleted permanently.
+
+
+
+
+
+ <_primary>Cannot rename "{0}" to "{1}".
+ <_secondary>A folder named "{1}" already exists. Please use a different name.
+
+
+
+ <_primary>Cannot rename "{0}" to "{1}".
+ <_secondary>Because "{2}".
+
+
+
+ <_primary>Cannot move folder "{0}" to "{1}".
+ <_secondary>Cannot open source "{2}".
+
+
+
+ <_primary>Cannot move folder "{0}" to "{1}".
+ <_secondary>Cannot open target "{2}".
+
+
+
+ <_primary>Cannot copy folder "{0}" to "{1}".
+ <_secondary>Cannot open source "{2}".
+
+
+
+ <_primary>Cannot copy folder "{0}" to "{1}".
+ <_secondary>Cannot open target "{2}".
+
+
+
+ <_primary>Cannot create folder "{0}".
+ <_secondary>Cannot open source "{1}"
+
+
+
+ <_primary>Cannot save changes to account.
+ <_secondary>You have not filled in all of the required information.
+
+
+
+ <_primary>Cannot save changes to account.
+ <_secondary>You may not create two accounts with the same name.
+
+
+
+ <_title>Delete account?
+ <_primary>Are you sure you want to delete this account?
+ <_secondary>If you proceed, the account information will be deleted permanently.
+
+
+
+
+
+ <_primary>Could not save signature file.
+ <_secondary>Because "{0}".
+
+
+
+ <_primary>Cannot set signature script "{0}".
+ <_secondary>The script file must exist and be executable.
+
+
+
+ <_title>Discard changed?
+ <_primary>Do you wish to save your changes?
+ <_secondary>This signature has been changed, but has not been saved.
+
+
+
+
+
+
+ <_primary>Cannot edit vFolder "{0}" as it does not exist.
+ <_secondary>This folder may have been added implictly, go to the virtual folder editor to add it explictly, if required.
+
+
+
+ <_primary>Cannot add vFolder "{0}".
+ <_secondary>A folder named "{1}" already exists. Please use a different name.
+
+
+
+ <_primary>vFolders automatically updated.
+ <_secondary>The following vFolder(s):
+{0}
+Used the now removed folder:
+ "{1}"
+And have been updated.
+
+
+
+ <_primary>Mail filters automatically updated.
+ <_secondary>The following filter rule(s):
+{0}
+Used the now removed folder:
+ "{1}"
+And have been updated.
+
+
+
+
diff --git a/widgets/misc/e-error.c b/widgets/misc/e-error.c
new file mode 100644
index 0000000000..f7cc9ee7bf
--- /dev/null
+++ b/widgets/misc/e-error.c
@@ -0,0 +1,550 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- *
+ *
+ * Authors: Michael Zucchi
+ *
+ * Copyright 2004 Novell Inc. (www.novell.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include
+#include
+#include
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#include "e-error.h"
+
+#define d(x) x
+
+struct _e_error_button {
+ struct _e_error_button *next;
+ char *stock;
+ char *label;
+ int response;
+};
+
+struct _e_error {
+ guint32 flags;
+ char *id;
+ int type;
+ int default_response;
+ char *title;
+ char *primary;
+ char *secondary;
+ struct _e_error_button *buttons;
+};
+
+struct _e_error_table {
+ char *domain;
+ GHashTable *errors;
+};
+
+static GHashTable *error_table;
+
+/* ********************************************************************** */
+
+static struct _e_error_button default_ok_button = {
+ NULL, "gtk-ok", NULL, GTK_RESPONSE_OK
+};
+
+static struct _e_error default_errors[] = {
+ { GTK_DIALOG_MODAL, "error", 3, GTK_RESPONSE_OK, N_("Evolution Error"), "{0}", "{1}", &default_ok_button },
+ { GTK_DIALOG_MODAL, "error-primary", 3, GTK_RESPONSE_OK, N_("Evolution Error"), "{0}", NULL, &default_ok_button },
+ { GTK_DIALOG_MODAL, "warning", 1, GTK_RESPONSE_OK, N_("Evolution Warning"), "{0}", "{1}", &default_ok_button },
+ { GTK_DIALOG_MODAL, "warning-primary", 1, GTK_RESPONSE_OK, N_("Evolution Warning"), "{0}", NULL, &default_ok_button },
+};
+
+/* ********************************************************************** */
+
+static struct {
+ char *name;
+ int id;
+} response_map[] = {
+ { "GTK_RESPONSE_REJECT", GTK_RESPONSE_REJECT },
+ { "GTK_RESPONSE_ACCEPT", GTK_RESPONSE_ACCEPT },
+ { "GTK_RESPONSE_OK", GTK_RESPONSE_OK },
+ { "GTK_RESPONSE_CANCEL", GTK_RESPONSE_CANCEL },
+ { "GTK_RESPONSE_CLOSE", GTK_RESPONSE_CLOSE },
+ { "GTK_RESPONSE_YES", GTK_RESPONSE_YES },
+ { "GTK_RESPONSE_NO", GTK_RESPONSE_NO },
+ { "GTK_RESPONSE_APPLY", GTK_RESPONSE_APPLY },
+ { "GTK_RESPONSE_HELP", GTK_RESPONSE_HELP },
+};
+
+static int
+map_response(const char *name)
+{
+ int i;
+
+ for (i=0;inext) {
+ const char *lang = l->data;
+
+ for (scan = base;scan;scan=scan->next) {
+ if (!strcmp(scan->name, name)) {
+ char *xmllang = xmlGetProp(scan, "xml:lang");
+
+ if (xmllang) {
+ if (!strcmp(xmllang, lang)) {
+ xmlFree(xmllang);
+ return scan;
+ }
+ xmlFree(xmllang);
+ } else {
+ langc = scan;
+ if (strcmp(lang, "C") == 0)
+ return scan;
+ }
+ }
+ }
+ }
+
+ return langc;
+}
+
+/*
+ XML format:
+
+
+ <_title>Window Title?
+ <_primary>Primary error text.?
+ <_secondary>Secondary error text.?
+
+
+ Because we use intltool we need to do some weird shit to do with
+ languages. title, primary and secondary will be expanded into
+ per-language tags, specified using xml:lang property.
+
+ The _label property will remain as plain english and we need to use
+ gettext to extract it.
+*/
+static void
+ee_load(const char *path)
+{
+ xmlDocPtr doc;
+ xmlNodePtr root, error, scan, node;
+ struct _e_error *e;
+ struct _e_error_button *lastbutton;
+ struct _e_error_table *table;
+ char *tmp;
+
+ d(printf("loading error file %s\n", path));
+
+ doc = xmlParseFile(path);
+ if (doc == NULL) {
+ g_warning("Error file '%s' not found", path);
+ return;
+ }
+
+ root = xmlDocGetRootElement(doc);
+ if (root == NULL
+ || strcmp(root->name, "error-list") != 0
+ || (tmp = xmlGetProp(root, "domain")) == NULL) {
+ g_warning("Error file '%s' invalid format", path);
+ xmlFreeDoc(doc);
+ return;
+ }
+
+ table = g_malloc0(sizeof(*table));
+ table->domain = g_strdup(tmp);
+ g_free(tmp);
+ table->errors = g_hash_table_new(g_str_hash, g_str_equal);
+
+ for (error = root->children;error;error = error->next) {
+ if (!strcmp(error->name, "error")) {
+ tmp = xmlGetProp(error, "id");
+ if (tmp == NULL)
+ continue;
+
+ e = g_malloc0(sizeof(*e));
+ e->id = g_strdup(tmp);
+ xmlFree(tmp);
+ lastbutton = (struct _e_error_button *)&e->buttons;
+
+ tmp = xmlGetProp(error, "modal");
+ if (tmp) {
+ if (!strcmp(tmp, "true"))
+ e->flags |= GTK_DIALOG_MODAL;
+ xmlFree(tmp);
+ }
+
+ tmp = xmlGetProp(error, "type");
+ e->type = map_type(tmp);
+ if (tmp)
+ xmlFree(tmp);
+
+ tmp = xmlGetProp(error, "default");
+ if (tmp) {
+ e->default_response = map_response(tmp);
+ xmlFree(tmp);
+ }
+
+ node = find_node(error->children, "primary");
+ if (node && (tmp = xmlNodeGetContent(node))) {
+ e->primary = g_strdup(tmp);
+ xmlFree(tmp);
+ }
+
+ node = find_node(error->children, "secondary");
+ if (node && (tmp = xmlNodeGetContent(node))) {
+ e->secondary = g_strdup(tmp);
+ xmlFree(tmp);
+ }
+
+ node = find_node(error->children, "title");
+ if (node && (tmp = xmlNodeGetContent(node))) {
+ e->title = g_strdup(tmp);
+ xmlFree(tmp);
+ }
+
+ for (scan = error->children;scan;scan=scan->next) {
+ if (!strcmp(scan->name, "button")) {
+ struct _e_error_button *b;
+
+ b = g_malloc0(sizeof(*b));
+ tmp = xmlGetProp(scan, "stock");
+ if (tmp) {
+ b->stock = g_strdup(tmp);
+ xmlFree(tmp);
+ }
+ tmp = xmlGetProp(scan, "label");
+ if (tmp) {
+ b->label = g_strdup(_(tmp));
+ xmlFree(tmp);
+ }
+ tmp = xmlGetProp(scan, "response");
+ if (tmp) {
+ b->response = map_response(tmp);
+ xmlFree(tmp);
+ }
+
+ if (b->stock == NULL && b->label == NULL) {
+ g_warning("Error file '%s': missing button details in error '%s'", path, e->id);
+ g_free(b->stock);
+ g_free(b->label);
+ g_free(b);
+ } else {
+ lastbutton->next = b;
+ lastbutton = b;
+ }
+ }
+ }
+
+ g_hash_table_insert(table->errors, e->id, e);
+ }
+ }
+
+ xmlFreeDoc(doc);
+
+ g_hash_table_insert(error_table, table->domain, table);
+}
+
+static void
+ee_load_tables(void)
+{
+ DIR *dir;
+ struct dirent *d;
+ const char *base = EVOLUTION_PRIVDATADIR "/errors";
+ struct _e_error_table *table;
+ int i;
+
+ if (error_table != NULL)
+ return;
+
+ error_table = g_hash_table_new(g_str_hash, g_str_equal);
+
+ /* setup system error types */
+ table = g_malloc0(sizeof(*table));
+ table->domain = "system";
+ table->errors = g_hash_table_new(g_str_hash, g_str_equal);
+ for (i=0;ierrors, default_errors[i].id, &default_errors[i]);
+ g_hash_table_insert(error_table, table->domain, table);
+
+ /* look for installed error tables */
+ dir = opendir(base);
+ if (dir == NULL)
+ return;
+
+ while ( (d = readdir(dir)) ) {
+ char *path;
+
+ if (d->d_name[0] == '.')
+ continue;
+
+ path = g_build_filename(base, d->d_name, NULL);
+ ee_load(path);
+ g_free(path);
+ }
+
+ closedir(dir);
+}
+
+static void
+ee_build_label(GString *out, const char *fmt, GPtrArray *args)
+{
+ const char *end, *newstart;
+ int id;
+
+ 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)
+ 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);
+}
+
+GtkWidget *
+e_error_newv(GtkWindow *parent, const char *tag, const char *arg0, va_list ap)
+{
+ struct _e_error_table *table;
+ struct _e_error *e;
+ struct _e_error_button *b;
+ GtkWidget *hbox, *w;
+ char *tmp, *domain, *id;
+ GString *out;
+ GPtrArray *args;
+ GtkDialog *dialog;
+
+ if (error_table == NULL)
+ ee_load_tables();
+
+ dialog = (GtkDialog *)gtk_dialog_new();
+ gtk_dialog_set_has_separator(dialog, FALSE);
+
+ if (parent)
+ gtk_window_set_transient_for((GtkWindow *)dialog, parent);
+
+ domain = alloca(strlen(tag)+1);
+ strcpy(domain, tag);
+ id = strchr(domain, ':');
+ if (id)
+ *id++ = 0;
+
+ if ( id == NULL
+ || (table = g_hash_table_lookup(error_table, domain)) == NULL
+ || (e = g_hash_table_lookup(table->errors, id)) == NULL) {
+ /* setup a dummy error */
+ tmp = g_strdup_printf(_("Internal error, unknown error '%s' requested"), tag);
+ w = gtk_label_new(NULL);
+ gtk_label_set_line_wrap((GtkLabel *)w, TRUE);
+ gtk_label_set_markup((GtkLabel *)w, tmp);
+ gtk_widget_show(w);
+ gtk_box_pack_start((GtkBox *)dialog->vbox, w, TRUE, TRUE, 12);
+
+ return (GtkWidget *)dialog;
+ }
+
+ if (e->flags & GTK_DIALOG_MODAL)
+ gtk_window_set_modal((GtkWindow *)dialog, TRUE);
+ gtk_window_set_destroy_with_parent((GtkWindow *)dialog, TRUE);
+
+ b = e->buttons;
+ if (b == NULL) {
+ gtk_dialog_add_button(dialog, GTK_STOCK_OK, GTK_RESPONSE_OK);
+ } else {
+ for (b = e->buttons;b;b=b->next) {
+ /* TODO: allow stock icons on non-stock labels */
+ if (b->stock)
+ gtk_dialog_add_button(dialog, b->stock, b->response);
+ else
+ gtk_dialog_add_button(dialog, b->label, b->response);
+ }
+ }
+
+ if (e->default_response)
+ gtk_dialog_set_default_response(dialog, e->default_response);
+
+ hbox = gtk_hbox_new(FALSE, 0);
+ gtk_container_set_border_width((GtkContainer *)hbox, 12);
+
+ w = gtk_image_new_from_stock(type_map[e->type].icon, GTK_ICON_SIZE_DIALOG);
+ gtk_box_pack_start((GtkBox *)hbox, w, TRUE, TRUE, 12);
+
+ args = g_ptr_array_new();
+ tmp = (char *)arg0;
+ while (tmp) {
+ g_ptr_array_add(args, tmp);
+ tmp = va_arg(ap, char *);
+ }
+
+ out = g_string_new("");
+
+ if (e->title) {
+ ee_build_label(out, _(e->title), args);
+ gtk_window_set_title((GtkWindow *)dialog, _(e->title));
+ g_string_truncate(out, 0);
+ } else
+ gtk_window_set_title((GtkWindow *)dialog, _(type_map[e->type].title));
+
+
+ if (e->primary) {
+ g_string_append(out, "");
+ ee_build_label(out, _(e->primary), args);
+ g_string_append(out, "\n\n");
+ }
+
+ if (e->secondary)
+ ee_build_label(out, _(e->secondary), args);
+
+ g_ptr_array_free(args, TRUE);
+
+ w = gtk_label_new(NULL);
+ gtk_label_set_line_wrap((GtkLabel *)w, TRUE);
+ gtk_label_set_markup((GtkLabel *)w, out->str);
+ g_string_free(out, TRUE);
+ gtk_box_pack_start((GtkBox *)hbox, w, FALSE, FALSE, 0);
+ gtk_widget_show_all(hbox);
+
+ gtk_box_pack_start((GtkBox *)dialog->vbox, hbox, TRUE, TRUE, 0);
+
+ return (GtkWidget *)dialog;
+}
+
+/**
+ * e_error_new:
+ * @parent:
+ * @tag: error identifier
+ * @arg0: The first argument for the error formatter. The list must
+ * be NULL terminated.
+ *
+ * Creates a new error widget. The @tag argument is used to determine
+ * which error to use, it is in the format domain:error-id. The NULL
+ * terminated list of arguments, starting with @arg0 is used to fill
+ * out the error definition.
+ *
+ * Return value: A GtkDialog which can be used for showing an error
+ * dialog asynchronously.
+ **/
+struct _GtkWidget *
+e_error_new(struct _GtkWindow *parent, const char *tag, const char *arg0, ...)
+{
+ GtkWidget *w;
+ va_list ap;
+
+ va_start(ap, arg0);
+ w = e_error_newv(parent, tag, arg0, ap);
+ va_end(ap);
+
+ return w;
+}
+
+int
+e_error_runv(GtkWindow *parent, const char *tag, const char *arg0, va_list ap)
+{
+ GtkWidget *w;
+ int res;
+
+ w = e_error_newv(parent, tag, arg0, ap);
+
+ res = gtk_dialog_run((GtkDialog *)w);
+ gtk_widget_destroy(w);
+
+ return res;
+}
+
+/**
+ * e_error_run:
+ * @parent:
+ * @tag:
+ * @arg0:
+ *
+ * Sets up, displays, runs and destroys a standard evolution error
+ * dialog based on @tag, which is in the format domain:error-id.
+ *
+ * Return value: The response id of the button pressed.
+ **/
+int
+e_error_run(GtkWindow *parent, const char *tag, const char *arg0, ...)
+{
+ GtkWidget *w;
+ va_list ap;
+ int res;
+
+ va_start(ap, arg0);
+ w = e_error_newv(parent, tag, arg0, ap);
+ va_end(ap);
+
+ res = gtk_dialog_run((GtkDialog *)w);
+ gtk_widget_destroy(w);
+
+ return res;
+}
+
+
diff --git a/widgets/misc/e-error.h b/widgets/misc/e-error.h
new file mode 100644
index 0000000000..9da24e6004
--- /dev/null
+++ b/widgets/misc/e-error.h
@@ -0,0 +1,40 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- *
+ *
+ * Authors: Michael Zucchi
+ *
+ * Copyright 2004 Novell Inc. (www.novell.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _E_ERROR_H
+#define _E_ERROR_H
+
+#include
+
+struct _GtkWindow;
+
+#define E_ERROR_WARNING "system:warning"
+#define E_ERROR_WARNING_PRIMARY "system:warning-primary"
+#define E_ERROR_ERROR "system:error"
+#define E_ERROR_ERROR_PRIMARY "system:error-primary"
+
+struct _GtkWidget *e_error_new(struct _GtkWindow *parent, const char *tag, const char *arg0, ...);
+struct _GtkWidget *e_error_newv(struct _GtkWindow *parent, const char *tag, const char *arg0, va_list ap);
+
+int e_error_run(struct _GtkWindow *parent, const char *tag, const char *arg0, ...);
+int e_error_runv(struct _GtkWindow *parent, const char *tag, const char *arg0, va_list ap);
+
+#endif /* !_E_ERROR_H */