aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathon Jongsma <jonathon@quotidian.org>2009-11-25 06:27:08 +0800
committerJonathon Jongsma <jonathon@quotidian.org>2009-12-01 03:29:25 +0800
commitae8f6d681c0512089f9259de0fd1b270396991d5 (patch)
tree45955945a454da85b89f7b2aae3a3554904c64b5
parent407f96826f41fe5d74d7224be99dff59492d8ee4 (diff)
downloadgsoc2013-evolution-ae8f6d681c0512089f9259de0fd1b270396991d5.tar.gz
gsoc2013-evolution-ae8f6d681c0512089f9259de0fd1b270396991d5.tar.zst
gsoc2013-evolution-ae8f6d681c0512089f9259de0fd1b270396991d5.zip
Refactor error reporting to separate error from dialogs
Previously, Most things reported errors directly. This is evidenced by the fact that e_error_new() returns a GtkDialog*. This patch attempts to de-couple error-reporting from the UI. It introduces a simple stuct (EError) that describes the error which is returned much like a GError by passing it as an output parameter to a function. e_error_new() now returns a newly-allocated EError*, but the function signature has changed to no longer accept a parent GtkWidget, so the API change should be detected at compile time. I kept the convenience dialog functions, but renamed them slightly: - e_error_new() -> e_error_new_dialog() - e_error_run() -> e_error_run_dialog() Build is currently broken because nothing has been ported to use this new API yet. https://bugzilla.gnome.org/show_bug.cgi?id=602963
-rw-r--r--e-util/e-error.c186
-rw-r--r--e-util/e-error.h19
2 files changed, 121 insertions, 84 deletions
diff --git a/e-util/e-error.c b/e-util/e-error.c
index 049e090fdc..47d7548c70 100644
--- a/e-util/e-error.c
+++ b/e-util/e-error.c
@@ -39,6 +39,23 @@
#define d(x)
+struct _EError
+{
+ gchar *tag;
+ GPtrArray *args;
+};
+
+void
+e_error_free (EError *error)
+{
+ if (error == NULL)
+ return;
+ g_free (error->tag);
+ /* arg strings will be freed automatically since we set a free func when
+ * creating the ptr array */
+ g_ptr_array_free (error->args, TRUE);
+}
+
struct _e_error_button {
struct _e_error_button *next;
const gchar *stock;
@@ -403,8 +420,50 @@ ee_response(GtkWidget *w, guint button, struct _e_error *e)
}
}
+EError *
+e_error_newv(const gchar *tag, const gchar *arg0, va_list ap)
+{
+ gchar *tmp;
+ GPtrArray *args;
+ EError *err = g_slice_new0 (EError);
+ err->tag = g_strdup (tag);
+ err->args = g_ptr_array_new_with_free_func (g_free);
+
+ tmp = (gchar *)arg0;
+ while (tmp) {
+ g_ptr_array_add(args, g_strdup (tmp));
+ tmp = va_arg(ap, gchar *);
+ }
+
+ return err;
+}
+
+/**
+ * e_error_new:
+ * @tag: error identifier
+ * @arg0: The first argument for the error formatter. The list must
+ * be NULL terminated.
+ *
+ * Creates a new EError. 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.
+ **/
+EError *
+e_error_new(const gchar *tag, const gchar *arg0, ...)
+{
+ EError *e;
+ va_list ap;
+
+ va_start(ap, arg0);
+ e = e_error_newv(tag, arg0, ap);
+ va_end(ap);
+
+ return e;
+}
+
GtkWidget *
-e_error_newv(GtkWindow *parent, const gchar *tag, const gchar *arg0, va_list ap)
+e_error_new_dialog(GtkWindow *parent, EError *error)
{
struct _e_error_table *table;
struct _e_error *e;
@@ -414,10 +473,11 @@ e_error_newv(GtkWindow *parent, const gchar *tag, const gchar *arg0, va_list ap)
GtkWidget *content_area;
gchar *tmp, *domain, *id;
GString *out, *oerr;
- GPtrArray *args;
GtkDialog *dialog;
gchar *str, *perr=NULL, *serr=NULL;
+ g_return_val_if_fail (error != NULL, NULL);
+
if (error_table == NULL)
ee_load_tables();
@@ -438,8 +498,8 @@ e_error_newv(GtkWindow *parent, const gchar *tag, const gchar *arg0, va_list ap)
"Something called %s() with a NULL parent window. "
"This is no longer legal, please fix it.", G_STRFUNC);
- domain = alloca(strlen(tag)+1);
- strcpy(domain, tag);
+ domain = alloca(strlen(error->tag)+1);
+ strcpy(domain, error->tag);
id = strchr(domain, ':');
if (id)
*id++ = 0;
@@ -448,7 +508,7 @@ e_error_newv(GtkWindow *parent, const gchar *tag, const gchar *arg0, va_list ap)
|| (table = g_hash_table_lookup(error_table, domain)) == NULL
|| (e = g_hash_table_lookup(table->errors, id)) == NULL) {
/* setup a dummy error */
- str = g_strdup_printf(_("Internal error, unknown error '%s' requested"), tag);
+ str = g_strdup_printf(_("Internal error, unknown error '%s' requested"), error->tag);
tmp = g_strdup_printf("<span weight=\"bold\">%s</span>", str);
g_free(str);
w = gtk_label_new(NULL);
@@ -505,17 +565,10 @@ e_error_newv(GtkWindow *parent, const gchar *tag, const gchar *arg0, va_list ap)
gtk_misc_set_alignment((GtkMisc *)w, 0.0, 0.0);
gtk_box_pack_start((GtkBox *)hbox, w, FALSE, FALSE, 12);
- args = g_ptr_array_new();
- tmp = (gchar *)arg0;
- while (tmp) {
- g_ptr_array_add(args, tmp);
- tmp = va_arg(ap, gchar *);
- }
-
out = g_string_new("");
if (e->title && *e->title) {
- ee_build_label(out, e->title, args, FALSE);
+ ee_build_label(out, e->title, error->args, FALSE);
gtk_window_set_title((GtkWindow *)dialog, out->str);
g_string_truncate(out, 0);
} else
@@ -523,23 +576,22 @@ e_error_newv(GtkWindow *parent, const gchar *tag, const gchar *arg0, va_list ap)
if (e->primary) {
g_string_append(out, "<span weight=\"bold\" size=\"larger\">");
- ee_build_label(out, e->primary, args, TRUE);
+ ee_build_label(out, e->primary, error->args, TRUE);
g_string_append(out, "</span>\n\n");
oerr = g_string_new("");
- ee_build_label(oerr, e->primary, args, FALSE);
+ ee_build_label(oerr, e->primary, error->args, FALSE);
perr = g_strdup (oerr->str);
g_string_free (oerr, TRUE);
} else
perr = g_strdup (gtk_window_get_title (GTK_WINDOW (dialog)));
if (e->secondary) {
- ee_build_label(out, e->secondary, args, TRUE);
+ ee_build_label(out, e->secondary, error->args, TRUE);
oerr = g_string_new("");
- ee_build_label(oerr, e->secondary, args, TRUE);
+ ee_build_label(oerr, e->secondary, error->args, TRUE);
serr = g_strdup (oerr->str);
g_string_free (oerr, TRUE);
}
- g_ptr_array_free(args, TRUE);
if (e->scroll) {
scroll = gtk_scrolled_window_new (NULL, NULL);
@@ -567,69 +619,13 @@ e_error_newv(GtkWindow *parent, const gchar *tag, const gchar *arg0, va_list ap)
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.
- **/
-GtkWidget *
-e_error_new(GtkWindow *parent, const gchar *tag, const gchar *arg0, ...)
-{
- GtkWidget *w;
- va_list ap;
-
- va_start(ap, arg0);
- w = e_error_newv(parent, tag, arg0, ap);
- va_end(ap);
-
- return w;
-}
-
-gint
-e_error_runv(GtkWindow *parent, const gchar *tag, const gchar *arg0, va_list ap)
-{
- GtkWidget *w;
- gint 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.
- **/
gint
-e_error_run(GtkWindow *parent, const gchar *tag, const gchar *arg0, ...)
+e_error_run_dialog(GtkWindow *parent, EError *error)
{
GtkWidget *w;
- va_list ap;
gint res;
- va_start(ap, arg0);
- w = e_error_newv(parent, tag, arg0, ap);
- va_end(ap);
+ w = e_error_new_dialog(parent, error);
res = gtk_dialog_run((GtkDialog *)w);
gtk_widget_destroy(w);
@@ -638,7 +634,7 @@ e_error_run(GtkWindow *parent, const gchar *tag, const gchar *arg0, ...)
}
/**
- * e_error_count_buttons:
+ * e_error_dialog_count_buttons:
* @dialog: a #GtkDialog
*
* Counts the number of buttons in @dialog's action area.
@@ -646,7 +642,7 @@ e_error_run(GtkWindow *parent, const gchar *tag, const gchar *arg0, ...)
* Returns: number of action area buttons
**/
guint
-e_error_count_buttons (GtkDialog *dialog)
+e_error_dialog_count_buttons (GtkDialog *dialog)
{
GtkWidget *container;
GList *children, *iter;
@@ -666,3 +662,37 @@ e_error_count_buttons (GtkDialog *dialog)
return n_buttons;
}
+
+GtkWidget *
+e_error_new_dialog_for_args (GtkWindow *parent, const gchar *tag, const gchar *arg0, ...)
+{
+ GtkWidget *w;
+ EError *e;
+ va_list ap;
+
+ va_start(ap, arg0);
+ e = e_error_newv(tag, arg0, ap);
+ va_end(ap);
+
+ w = e_error_new_dialog (parent, e);
+ e_error_free (e);
+
+ return w;
+}
+
+gint
+e_error_run_dialog_for_args (GtkWindow *parent, const gchar *tag, const gchar *arg0, ...)
+{
+ EError *e;
+ va_list ap;
+ gint response;
+
+ va_start(ap, arg0);
+ e = e_error_newv(tag, arg0, ap);
+ va_end(ap);
+
+ response = e_error_run_dialog (parent, e);
+ e_error_free (e);
+
+ return response;
+}
diff --git a/e-util/e-error.h b/e-util/e-error.h
index 38de4c86ed..8068668a26 100644
--- a/e-util/e-error.h
+++ b/e-util/e-error.h
@@ -47,13 +47,20 @@
/* takes filename, reason */
#define E_ERROR_NO_LOAD_FILE "system:no-save-file"
-/* Note that all errors returned are standard GtkDialoge's */
-GtkWidget *e_error_new(GtkWindow *parent, const gchar *tag, const gchar *arg0, ...);
-GtkWidget *e_error_newv(GtkWindow *parent, const gchar *tag, const gchar *arg0, va_list ap);
+typedef struct _EError EError;
-gint e_error_run(GtkWindow *parent, const gchar *tag, const gchar *arg0, ...);
-gint e_error_runv(GtkWindow *parent, const gchar *tag, const gchar *arg0, va_list ap);
+EError *e_error_new(const gchar *tag, const gchar *arg0, ...);
+EError *e_error_newv(const gchar *tag, const gchar *arg0, va_list ap);
-guint e_error_count_buttons (GtkDialog *dialog);
+void e_error_free (EError *error);
+
+/* Convenience functions for displaying the error in a GtkDialog */
+GtkWidget *e_error_new_dialog(GtkWindow *parent, EError *error);
+GtkWidget *e_error_new_dialog_for_args (GtkWindow *parent, const gchar *tag, const gchar *arg0, ...);
+
+gint e_error_run_dialog(GtkWindow *parent, EError *error);
+gint e_error_run_dialog_for_args (GtkWindow *parent, const gchar *tag, const gchar *arg0, ...);
+
+guint e_error_dialog_count_buttons (GtkDialog *dialog);
#endif /* !_E_ERROR_H */