aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2010-12-08 05:30:15 +0800
committerMatthew Barnes <mbarnes@redhat.com>2012-06-03 11:00:39 +0800
commitae21bb5e661666159f212d008e0bacd850ec2cab (patch)
treed1813e55f36d9629878950535b3636391f39218e
parenta1be1eaa01f5f7cb317f868121dcf26e487ef25a (diff)
downloadgsoc2013-evolution-ae21bb5e661666159f212d008e0bacd850ec2cab.tar
gsoc2013-evolution-ae21bb5e661666159f212d008e0bacd850ec2cab.tar.gz
gsoc2013-evolution-ae21bb5e661666159f212d008e0bacd850ec2cab.tar.bz2
gsoc2013-evolution-ae21bb5e661666159f212d008e0bacd850ec2cab.tar.lz
gsoc2013-evolution-ae21bb5e661666159f212d008e0bacd850ec2cab.tar.xz
gsoc2013-evolution-ae21bb5e661666159f212d008e0bacd850ec2cab.tar.zst
gsoc2013-evolution-ae21bb5e661666159f212d008e0bacd850ec2cab.zip
Adapt libeutil to the new ESource API.
-rw-r--r--e-util/Makefile.am4
-rw-r--r--e-util/e-plugin-util.c497
-rw-r--r--e-util/e-plugin-util.h45
-rw-r--r--e-util/e-source-util.c187
-rw-r--r--e-util/e-source-util.h42
-rw-r--r--e-util/e-util.c46
-rw-r--r--e-util/e-util.h10
-rw-r--r--libemail-utils/e-account-utils.c252
-rw-r--r--libemail-utils/e-account-utils.h37
-rw-r--r--libemail-utils/e-signature-list.c501
-rw-r--r--libemail-utils/e-signature-list.h91
-rw-r--r--libemail-utils/e-signature-utils.c336
-rw-r--r--libemail-utils/e-signature-utils.h40
-rw-r--r--libemail-utils/e-signature.c749
-rw-r--r--libemail-utils/e-signature.h90
-rw-r--r--widgets/misc/Makefile.am8
-rw-r--r--widgets/misc/e-account-combo-box.c514
-rw-r--r--widgets/misc/e-account-combo-box.h85
-rw-r--r--widgets/misc/e-mail-account-manager.c384
-rw-r--r--widgets/misc/e-mail-account-manager.h77
-rw-r--r--widgets/misc/e-mail-account-tree-view.c575
-rw-r--r--widgets/misc/e-mail-account-tree-view.h83
-rw-r--r--widgets/misc/e-mail-identity-combo-box.c374
-rw-r--r--widgets/misc/e-mail-identity-combo-box.h76
-rw-r--r--widgets/misc/test-mail-accounts.c61
25 files changed, 1880 insertions, 3284 deletions
diff --git a/e-util/Makefile.am b/e-util/Makefile.am
index 63fce88fbe..0c7f7b3250 100644
--- a/e-util/Makefile.am
+++ b/e-util/Makefile.am
@@ -38,10 +38,10 @@ eutilinclude_HEADERS = \
e-print.h \
e-plugin.h \
e-plugin-ui.h \
- e-plugin-util.h \
e-selection.h \
e-sorter.h \
e-sorter-array.h \
+ e-source-util.h \
e-stock-request.h \
e-text-event-processor-emacs-like.h \
e-text-event-processor-types.h \
@@ -102,11 +102,11 @@ libeutil_la_SOURCES = \
e-poolv.c \
e-plugin.c \
e-plugin-ui.c \
- e-plugin-util.c \
e-print.c \
e-selection.c \
e-sorter.c \
e-sorter-array.c \
+ e-source-util.c \
e-stock-request.c \
e-text-event-processor-emacs-like.c \
e-text-event-processor.c \
diff --git a/e-util/e-plugin-util.c b/e-util/e-plugin-util.c
deleted file mode 100644
index 7fd343d4b1..0000000000
--- a/e-util/e-plugin-util.c
+++ /dev/null
@@ -1,497 +0,0 @@
-/*
- * 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 <http://www.gnu.org/licenses/>
- *
- *
- * Copyright (C) 1999-2010 Novell, Inc. (www.novell.com)
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <glib/gi18n.h>
-#include <gtk/gtk.h>
-#include <libsoup/soup.h>
-#include <libedataserver/e-source.h>
-#include <string.h>
-
-#include "e-plugin-util.h"
-
-/* name of a property on a widget with corresponding property name for an ESource */
-#define EPU_SP_NAME "e-source-property-name"
-
-#define EPU_CHECK_TRUE "epu-check-true-value"
-#define EPU_CHECK_FALSE "epu-check-false-value"
-
-static gboolean
-epu_is_uri_proto (const gchar *uri,
- const gchar *protocol)
-{
- gboolean res;
-
- g_return_val_if_fail (uri != NULL, FALSE);
- g_return_val_if_fail (protocol != NULL, FALSE);
-
- res = uri && g_ascii_strncasecmp (uri, protocol, strlen (protocol)) == 0;
-
- if (res)
- res = strchr (protocol, ':') != NULL || uri[strlen (protocol)] == ':';
-
- return res;
-}
-
-/**
- * e_plugin_util_is_source_proto:
- * @source: #ESource object
- * @protocol: protocol to check on, like "http", "https", ...
- *
- * Returns whether given source's uri is of the given protocol.
- *
- * Returns: whether given source's uri is of the given protocol.
- **/
-gboolean
-e_plugin_util_is_source_proto (ESource *source,
- const gchar *protocol)
-{
- gchar *uri;
- gboolean res;
-
- g_return_val_if_fail (E_IS_SOURCE (source), FALSE);
- g_return_val_if_fail (protocol != NULL, FALSE);
-
- uri = e_source_get_uri (source);
- res = epu_is_uri_proto (uri, protocol);
- g_free (uri);
-
- return res;
-}
-
-/**
- * e_plugin_util_is_group_proto:
- * @group: #ESourceGroup object
- * @protocol: protocol to check on, like "http", "https", ...
- *
- * Returns whether given groups' base uri is of the given protocol.
- *
- * Returns: whether given groups' base uri is of the given protocol.
- **/
-gboolean
-e_plugin_util_is_group_proto (ESourceGroup *group,
- const gchar *protocol)
-{
- g_return_val_if_fail (E_IS_SOURCE_GROUP (group), FALSE);
- g_return_val_if_fail (protocol != NULL, FALSE);
-
- return epu_is_uri_proto (e_source_group_peek_base_uri (group), protocol);
-}
-
-/**
- * e_plugin_util_replace_at_sign:
- * @str: string to work with
- *
- * Replaces all '@' with '%40' in @str.
- *
- * Returns: a newly-allocated string
- **/
-gchar *
-e_plugin_util_replace_at_sign (const gchar *str)
-{
- gchar *res, *at;
-
- if (!str)
- return NULL;
-
- res = g_strdup (str);
- while (at = strchr (res, '@'), at) {
- gchar *tmp = g_malloc0 (sizeof (gchar) * (1 + strlen (res) + 2));
-
- strncpy (tmp, res, at - res);
- strcat (tmp, "%40");
- strcat (tmp, at + 1);
-
- g_free (res);
- res = tmp;
- }
-
- return res;
-}
-
-/**
- * e_plugin_util_uri_no_proto:
- * @uri: #SoupURI object
- *
- * Returns uri encoded as string, without protocol part.
- * Returned pointer should be freed with g_free.
- *
- * Returns: uri encoded as string, without protocol part.
- **/
-gchar *
-e_plugin_util_uri_no_proto (SoupURI *uri)
-{
- gchar *full_uri, *uri_noproto;
- const gchar *tmp;
-
- g_return_val_if_fail (uri != NULL, NULL);
-
- full_uri = soup_uri_to_string (uri, FALSE);
- g_return_val_if_fail (full_uri != NULL, NULL);
-
- tmp = strstr (full_uri, "://");
- if (tmp && tmp < strchr (full_uri, '/')) {
- uri_noproto = g_strdup (tmp + 3);
- } else {
- uri_noproto = full_uri;
- full_uri = NULL;
- }
-
- g_free (full_uri);
-
- return uri_noproto;
-}
-
-static void
-epu_update_source_property (ESource *source,
- GObject *object,
- const gchar *value)
-{
- const gchar *property_name;
-
- g_return_if_fail (E_IS_SOURCE (source));
- g_return_if_fail (G_IS_OBJECT (object));
-
- property_name = g_object_get_data (object, EPU_SP_NAME);
- g_return_if_fail (property_name != NULL);
-
- e_source_set_property (source, property_name, value);
-}
-
-static void
-epu_entry_changed_cb (GObject *entry,
- ESource *source)
-{
- g_return_if_fail (GTK_IS_ENTRY (entry));
-
- epu_update_source_property (source, entry, gtk_entry_get_text (GTK_ENTRY (entry)));
-}
-
-static void
-epu_check_toggled_cb (GObject *button,
- ESource *source)
-{
- const gchar *true_value, *false_value;
-
- g_return_if_fail (GTK_IS_TOGGLE_BUTTON (button));
-
- true_value = g_object_get_data (button, EPU_CHECK_TRUE);
- false_value = g_object_get_data (button, EPU_CHECK_FALSE);
-
- epu_update_source_property (source, button, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)) ? true_value : false_value);
-}
-
-/**
- * e_plugin_util_add_entry:
- * @parent: two-columns #GtkTable or #GtkContainer, where to add new entry
- * @label: label for the entry; can be NULL for no label
- * @source: #ESource object to which tight the entry change; can be NULL for no property binding
- * @source_property: source's property name to use for a value; can be NULL for no property binding
- *
- * Adds a #GtkEntry to the table at the last row or to the container, with a given label.
- * The entry will be always at the second column of the table.
- * Value of an entry will be prefilled with a property value of the given
- * source, and the source will be updated on any change of the entry automatically.
- * Entry is shown by default.
- *
- * Returns: pointer to newly added #GtkEntry
- **/
-GtkWidget *
-e_plugin_util_add_entry (GtkWidget *parent,
- const gchar *label,
- ESource *source,
- const gchar *source_property)
-{
- GtkWidget *entry, *lbl = NULL;
- const gchar *value;
- gint row = -1;
-
- g_return_val_if_fail (parent != NULL, NULL);
- g_return_val_if_fail (GTK_IS_TABLE (parent) || GTK_IS_CONTAINER (parent), NULL);
-
- if (source || source_property) {
- g_return_val_if_fail (E_IS_SOURCE (source), NULL);
- g_return_val_if_fail (source_property != NULL, NULL);
- g_return_val_if_fail (*source_property != 0, NULL);
- }
-
- if (GTK_IS_TABLE (parent))
- g_object_get (parent, "n-rows", &row, NULL);
-
- if (label) {
- lbl = gtk_label_new_with_mnemonic (label);
- gtk_widget_show (lbl);
- gtk_misc_set_alignment (GTK_MISC (lbl), 0.0, 0.5);
- if (row != -1)
- gtk_table_attach (GTK_TABLE (parent), lbl, 0, 1, row, row + 1, GTK_FILL, 0, 0, 0);
- else
- gtk_container_add (GTK_CONTAINER (parent), lbl);
- }
-
- if (source)
- value = e_source_get_property (source, source_property);
- else
- value = NULL;
-
- entry = gtk_entry_new ();
- gtk_widget_show (entry);
- gtk_entry_set_text (GTK_ENTRY (entry), value ? value : "");
- if (row != -1)
- gtk_table_attach (GTK_TABLE (parent), entry, 1, 2, row, row + 1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
- else
- gtk_container_add (GTK_CONTAINER (parent), entry);
-
- if (lbl)
- gtk_label_set_mnemonic_widget (GTK_LABEL (lbl), entry);
-
- if (source) {
- g_object_set_data_full (G_OBJECT (entry), EPU_SP_NAME, g_strdup (source_property), g_free);
- g_signal_connect (
- entry, "changed",
- G_CALLBACK (epu_entry_changed_cb), source);
- }
-
- return entry;
-}
-
-/**
- * e_plugin_util_add_check:
- * @parent: either two-columns #GtkTable or #GtkContainer where to add new check box; or NULL to just create it
- * @label: label for the check; cannot be NULL
- * @source: #ESource object to which tight the check change; can be NULL for no property binding
- * @source_property: source's property name to use for a value; can be NULL for no property binding
- * @true_value: what value use for a checked state in a source
- * @false_value: what value use for an unchecked state in a source
- *
- * Adds a #GtkCheckButton to the parent (if provided) at the last row, with a given label.
- * The check will be always at the second column of the table.
- * Value of a check will be prefilled with a property value of the given
- * source, and the source will be updated on any change of the check automatically.
- * Check is shown by default.
- *
- * Returns: pointer to newly added #GtkCheckButton
- **/
-GtkWidget *
-e_plugin_util_add_check (GtkWidget *parent,
- const gchar *label,
- ESource *source,
- const gchar *source_property,
- const gchar *true_value,
- const gchar *false_value)
-{
- GtkWidget *check;
- const gchar *value;
- guint row;
-
- g_return_val_if_fail (parent == NULL || GTK_IS_TABLE (parent) || GTK_IS_CONTAINER (parent), NULL);
- g_return_val_if_fail (label != NULL, NULL);
-
- if (source || source_property) {
- g_return_val_if_fail (source != NULL, NULL);
- g_return_val_if_fail (E_IS_SOURCE (source), NULL);
- g_return_val_if_fail (source_property != NULL, NULL);
- g_return_val_if_fail (*source_property != 0, NULL);
- }
-
- if (source)
- value = e_source_get_property (source, source_property);
- else
- value = NULL;
-
- check = gtk_check_button_new_with_mnemonic (label);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check),
- value && (value == true_value ||
- (true_value && g_str_equal (value, true_value)) ||
- (!source && g_str_equal (value, "1"))));
- gtk_widget_show (check);
-
- if (parent && GTK_IS_TABLE (parent)) {
- g_object_get (parent, "n-rows", &row, NULL);
-
- gtk_table_attach (GTK_TABLE (parent), check, 1, 2, row , row + 1, GTK_FILL, 0, 0, 0);
- } else if (parent) {
- gtk_container_add (GTK_CONTAINER (parent), check);
- }
-
- if (source) {
- g_object_set_data_full (G_OBJECT (check), EPU_SP_NAME, g_strdup (source_property), g_free);
- g_object_set_data_full (G_OBJECT (check), EPU_CHECK_TRUE, g_strdup (true_value), g_free);
- g_object_set_data_full (G_OBJECT (check), EPU_CHECK_FALSE, g_strdup (false_value), g_free);
- g_signal_connect (
- check, "toggled",
- G_CALLBACK (epu_check_toggled_cb), source);
- }
-
- return check;
-}
-
-static void
-epu_update_refresh_value (GtkWidget *spin,
- GtkWidget *combobox,
- ESource *source)
-{
- gchar *value;
- gint setting = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin));
- switch (gtk_combo_box_get_active (GTK_COMBO_BOX (combobox))) {
- case 0:
- /* minutes */
- break;
- case 1:
- /* hours */
- setting *= 60;
- break;
- case 2:
- /* days */
- setting *= 1440;
- break;
- case 3:
- /* weeks */
- setting *= 10080;
- break;
- default:
- g_warning ("%s: Time unit out of range", G_STRFUNC);
- break;
- }
-
- value = g_strdup_printf ("%d", setting);
- epu_update_source_property (source, G_OBJECT (spin), value);
- g_free (value);
-}
-
-static void
-epu_refresh_spin_changed_cb (GtkWidget *spin,
- ESource *source)
-{
- g_return_if_fail (spin != NULL);
- g_return_if_fail (GTK_IS_SPIN_BUTTON (spin));
-
- epu_update_refresh_value (spin, g_object_get_data (G_OBJECT (spin), "refresh-combo"), source);
-}
-
-static void
-epu_refresh_combo_changed_cb (GtkWidget *combobox,
- ESource *source)
-{
- g_return_if_fail (combobox != NULL);
- g_return_if_fail (GTK_IS_COMBO_BOX (combobox));
-
- epu_update_refresh_value (g_object_get_data (G_OBJECT (combobox), "refresh-spin"), combobox, source);
-}
-
-/**
- * e_plugin_util_add_refresh:
- * @parent: two-columns #GtkTable where to add new "refresh" setup widgets or NULL to just create an hbox
- * @label: label for the widgets; can be NULL, but for parent == NULL is ignored
- * @source: #ESource object to which tight the refresh change; cannot be NULL
- * @source_property: source's property name to use for a value; cannot be NULL
- *
- * Adds widgets to setup Refresh interval. The stored value is in minutes.
- * Returns pointer to an HBox, which contains two widgets, spin and a combo box.
- * Both can be accessed by g_object_get_data with a name "refresh-spin" and "refresh-combo".
- *
- * Returns: a new refresh control widget
- **/
-GtkWidget *
-e_plugin_util_add_refresh (GtkWidget *parent,
- const gchar *label,
- ESource *source,
- const gchar *source_property)
-{
- GtkWidget *lbl = NULL, *hbox, *spin, *combo;
- const gchar *value;
- gint row = -1, value_num, item_num = 0;
-
- g_return_val_if_fail (parent == NULL || GTK_IS_TABLE (parent), NULL);
- g_return_val_if_fail (E_IS_SOURCE (source), NULL);
- g_return_val_if_fail (source_property != NULL, NULL);
- g_return_val_if_fail (*source_property != 0, NULL);
-
- if (parent)
- g_object_get (parent, "n-rows", &row, NULL);
-
- value = e_source_get_property (source, source_property);
- if (!value) {
- value = "30";
- e_source_set_property (source, source_property, value);
- }
-
- if (label && parent) {
- lbl = gtk_label_new_with_mnemonic (label);
- gtk_widget_show (lbl);
- gtk_misc_set_alignment (GTK_MISC (lbl), 0.0, 0.5);
- gtk_table_attach (GTK_TABLE (parent), lbl, 0, 1, row, row + 1, GTK_FILL, 0, 0, 0);
- }
-
- hbox = gtk_hbox_new (FALSE, 6);
- gtk_widget_show (hbox);
-
- spin = gtk_spin_button_new_with_range (0, 100, 1);
- gtk_widget_show (spin);
- gtk_box_pack_start (GTK_BOX (hbox), spin, FALSE, TRUE, 0);
-
- combo = gtk_combo_box_text_new ();
- gtk_widget_show (combo);
- gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), _("minutes"));
- gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), _("hours"));
- gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), _("days"));
- gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), _("weeks"));
- gtk_box_pack_start (GTK_BOX (hbox), combo, FALSE, TRUE, 0);
-
- value_num = value ? atoi (value) : 30;
-
- if (value_num && !(value_num % 10080)) {
- /* weeks */
- item_num = 3;
- value_num /= 10080;
- } else if (value_num && !(value_num % 1440)) {
- /* days */
- item_num = 2;
- value_num /= 1440;
- } else if (value_num && !(value_num % 60)) {
- /* hours */
- item_num = 1;
- value_num /= 60;
- }
-
- gtk_combo_box_set_active (GTK_COMBO_BOX (combo), item_num);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin), value_num);
-
- if (lbl)
- gtk_label_set_mnemonic_widget (GTK_LABEL (lbl), spin);
-
- g_object_set_data_full (G_OBJECT (spin), EPU_SP_NAME, g_strdup (source_property), g_free);
-
- g_object_set_data (G_OBJECT (combo), "refresh-spin", spin);
- g_object_set_data (G_OBJECT (spin), "refresh-combo", combo);
- g_object_set_data (G_OBJECT (hbox), "refresh-spin", spin);
- g_object_set_data (G_OBJECT (hbox), "refresh-combo", combo);
- g_signal_connect (
- combo, "changed",
- G_CALLBACK (epu_refresh_combo_changed_cb), source);
- g_signal_connect (
- spin, "value-changed",
- G_CALLBACK (epu_refresh_spin_changed_cb), source);
-
- if (parent)
- gtk_table_attach (GTK_TABLE (parent), hbox, 1, 2, row, row + 1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
-
- return hbox;
-}
diff --git a/e-util/e-plugin-util.h b/e-util/e-plugin-util.h
deleted file mode 100644
index de1b0b3487..0000000000
--- a/e-util/e-plugin-util.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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 <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- *
- * Copyright (C) 1999-2010 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _E_PLUGIN_UTIL_H
-#define _E_PLUGIN_UTIL_H
-
-#include <gtk/gtk.h>
-
-#include <libsoup/soup.h>
-
-#include <libedataserver/e-source.h>
-#include <libedataserver/e-source-group.h>
-
-gboolean e_plugin_util_is_source_proto (ESource *source, const gchar *protocol);
-gboolean e_plugin_util_is_group_proto (ESourceGroup *group, const gchar *protocol);
-
-gchar *e_plugin_util_replace_at_sign (const gchar *str);
-gchar *e_plugin_util_uri_no_proto (SoupURI *uri);
-
-/* common widgets used in plugin setup */
-GtkWidget *e_plugin_util_add_entry (GtkWidget *parent, const gchar *label, ESource *source, const gchar *source_property);
-GtkWidget *e_plugin_util_add_check (GtkWidget *parent, const gchar *label, ESource *source, const gchar *source_property, const gchar *true_value, const gchar *false_value);
-
-/* multipack widgets */
-GtkWidget *e_plugin_util_add_refresh (GtkWidget *parent, const gchar *label, ESource *source, const gchar *source_property);
-
-#endif /* _E_PLUGIN_UTIL_H */
diff --git a/e-util/e-source-util.c b/e-util/e-source-util.c
new file mode 100644
index 0000000000..61b7897d32
--- /dev/null
+++ b/e-util/e-source-util.c
@@ -0,0 +1,187 @@
+/*
+ * e-source-util.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 <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "e-source-util.h"
+
+typedef struct _AsyncContext AsyncContext;
+
+struct _AsyncContext {
+ EActivity *activity;
+ ESource *source;
+};
+
+static void
+async_context_free (AsyncContext *context)
+{
+ if (context->activity != NULL)
+ g_object_unref (context->activity);
+
+ if (context->source != NULL)
+ g_object_unref (context->source);
+
+ g_slice_free (AsyncContext, context);
+}
+
+static void
+source_util_remove_cb (ESource *source,
+ GAsyncResult *result,
+ AsyncContext *context)
+{
+ EActivity *activity;
+ EAlertSink *alert_sink;
+ GError *error = NULL;
+
+ activity = context->activity;
+ alert_sink = e_activity_get_alert_sink (activity);
+
+ e_source_remove_finish (source, result, &error);
+
+ if (e_activity_handle_cancellation (activity, error)) {
+ g_error_free (error);
+
+ } else if (error != NULL) {
+ e_alert_submit (
+ alert_sink,
+ "source:remove-source-fail",
+ e_source_get_display_name (context->source),
+ error->message, NULL);
+ g_error_free (error);
+
+ } else {
+ e_activity_set_state (activity, E_ACTIVITY_COMPLETED);
+ }
+
+ async_context_free (context);
+}
+
+/**
+ * e_source_util_remove:
+ * @source: the #ESource to be removed
+ * @alert_sink: an #EAlertSink
+ *
+ * Requests the D-Bus service to delete the key files for @source and all of
+ * its descendants and broadcast their removal to all clients. If an error
+ * occurs, an #EAlert will be posted to @alert_sink.
+ *
+ * This function does not block. The returned #EActivity can either be
+ * ignored or passed to something that can display activity status to the
+ * user, such as e_shell_backend_add_activity().
+ *
+ * Returns: an #EActivity to track the operation
+ **/
+EActivity *
+e_source_util_remove (ESource *source,
+ EAlertSink *alert_sink)
+{
+ AsyncContext *context;
+ GCancellable *cancellable;
+
+ g_return_val_if_fail (E_IS_SOURCE (source), NULL);
+ g_return_val_if_fail (E_IS_ALERT_SINK (alert_sink), NULL);
+
+ cancellable = g_cancellable_new ();
+
+ context = g_slice_new0 (AsyncContext);
+ context->activity = e_activity_new ();
+ context->source = g_object_ref (source);
+
+ e_activity_set_alert_sink (context->activity, alert_sink);
+ e_activity_set_cancellable (context->activity, cancellable);
+
+ e_source_remove (
+ source, cancellable, (GAsyncReadyCallback)
+ source_util_remove_cb, context);
+
+ g_object_unref (cancellable);
+
+ return context->activity;
+}
+
+static void
+source_util_write_cb (ESource *source,
+ GAsyncResult *result,
+ AsyncContext *context)
+{
+ EActivity *activity;
+ EAlertSink *alert_sink;
+ GError *error = NULL;
+
+ activity = context->activity;
+ alert_sink = e_activity_get_alert_sink (activity);
+
+ e_source_write_finish (source, result, &error);
+
+ if (e_activity_handle_cancellation (activity, error)) {
+ g_error_free (error);
+
+ } else if (error != NULL) {
+ e_alert_submit (
+ alert_sink,
+ "source:submit-data-fail",
+ error->message, NULL);
+ g_error_free (error);
+
+ } else {
+ e_activity_set_state (activity, E_ACTIVITY_COMPLETED);
+ }
+
+ async_context_free (context);
+}
+
+/**
+ * e_source_util_write:
+ * @source: an #ESource
+ * @alert_sink: an #EAlertSink
+ *
+ * Submits the current contents of @source to the D-Bus service to be
+ * written to disk and broadcast to other clients. If an error occurs,
+ * an #EAlert will be posted to @alert_sink.
+ *
+ * This function does not block. The returned #EActivity can either be
+ * ignored or passed to something that can display activity status to the
+ * user, such as e_shell_backend_add_activity().
+ *
+ * Returns: an #EActivity to track the operation
+ **/
+EActivity *
+e_source_util_write (ESource *source,
+ EAlertSink *alert_sink)
+{
+ AsyncContext *context;
+ GCancellable *cancellable;
+
+ g_return_val_if_fail (E_IS_SOURCE (source), NULL);
+ g_return_val_if_fail (E_IS_ALERT_SINK (alert_sink), NULL);
+
+ cancellable = g_cancellable_new ();
+
+ context = g_slice_new0 (AsyncContext);
+ context->activity = e_activity_new ();
+
+ e_activity_set_alert_sink (context->activity, alert_sink);
+ e_activity_set_cancellable (context->activity, cancellable);
+
+ e_source_write (
+ source, cancellable, (GAsyncReadyCallback)
+ source_util_write_cb, context);
+
+ g_object_unref (cancellable);
+
+ return context->activity;
+}
+
diff --git a/e-util/e-source-util.h b/e-util/e-source-util.h
new file mode 100644
index 0000000000..589e91b13c
--- /dev/null
+++ b/e-util/e-source-util.h
@@ -0,0 +1,42 @@
+/*
+ * e-source-util.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 <http://www.gnu.org/licenses/>
+ *
+ */
+
+/* These functions combine asynchronous ESource and ESourceRegistry methods
+ * with Evolution's EActivity and EAlert facilities to offer an easy-to-use,
+ * "fire-and-forget" API for ESource operations. Use these in situations
+ * where it's sufficient to just display an error message if the operation
+ * fails, and you don't need to operate on the result. */
+
+#ifndef E_SOURCE_UTIL_H
+#define E_SOURCE_UTIL_H
+
+#include <libedataserver/e-source.h>
+
+#include <e-util/e-activity.h>
+#include <libevolution-utils/e-alert-sink.h>
+
+G_BEGIN_DECLS
+
+EActivity * e_source_util_remove (ESource *source,
+ EAlertSink *alert_sink);
+EActivity * e_source_util_write (ESource *source,
+ EAlertSink *alert_sink);
+
+G_END_DECLS
+
+#endif /* E_SOURCE_UTIL_H */
diff --git a/e-util/e-util.c b/e-util/e-util.c
index 715735110c..38c1b85244 100644
--- a/e-util/e-util.c
+++ b/e-util/e-util.c
@@ -53,7 +53,6 @@
#include <camel/camel.h>
#include <libedataserver/e-data-server-util.h>
#include <libedataserver/e-categories.h>
-#include <libedataserver/e-source-list.h>
#include "filter/e-filter-option.h"
@@ -1334,31 +1333,6 @@ e_util_get_searchable_categories (void)
}
/**
- * e_util_set_source_combo_box_list:
- * @source_combo_box: an #ESourceComboBox
- * @source_gconf_path: GConf path with sources to use in an #ESourceList
- *
- * Sets an #ESourceList of a given GConf path to an #ESourceComboBox.
- **/
-void
-e_util_set_source_combo_box_list (GtkWidget *source_combo_box,
- const gchar *source_gconf_path)
-{
- ESourceList *source_list;
- GConfClient *gconf_client;
-
- g_return_if_fail (source_combo_box != NULL);
- g_return_if_fail (source_gconf_path != NULL);
-
- gconf_client = gconf_client_get_default ();
- source_list = e_source_list_new_for_gconf (
- gconf_client, source_gconf_path);
- g_object_set (source_combo_box, "source-list", source_list, NULL);
- g_object_unref (source_list);
- g_object_unref (gconf_client);
-}
-
-/**
* e_binding_transform_color_to_string:
* @binding: a #GBinding
* @source_value: a #GValue of type #GDK_TYPE_COLOR
@@ -1435,7 +1409,7 @@ e_binding_transform_string_to_color (GBinding *binding,
* @binding: a #GBinding
* @source_value: a #GValue of type #E_TYPE_SOURCE
* @target_value: a #GValue of type #G_TYPE_STRING
- * @source_list: an #ESourceList
+ * @registry: an #ESourceRegistry
*
* Transforms an #ESource object to its UID string.
*
@@ -1445,14 +1419,14 @@ gboolean
e_binding_transform_source_to_uid (GBinding *binding,
const GValue *source_value,
GValue *target_value,
- ESourceList *source_list)
+ ESourceRegistry *registry)
{
ESource *source;
const gchar *string;
gboolean success = FALSE;
g_return_val_if_fail (G_IS_BINDING (binding), FALSE);
- g_return_val_if_fail (E_IS_SOURCE_LIST (source_list), FALSE);
+ g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), FALSE);
source = g_value_get_object (source_value);
if (E_IS_SOURCE (source)) {
@@ -1469,34 +1443,34 @@ e_binding_transform_source_to_uid (GBinding *binding,
* @binding: a #GBinding
* @source_value: a #GValue of type #G_TYPE_STRING
* @target_value: a #GValue of type #E_TYPE_SOURCe
- * @source_list: an #ESourceList
+ * @registry: an #ESourceRegistry
*
* Transforms an #ESource UID string to the corresponding #ESource object
- * in @source_list.
+ * in @registry.
*
- * Returns: %TRUE if @source_list had an #ESource object with a matching
+ * Returns: %TRUE if @registry had an #ESource object with a matching
* UID string
**/
gboolean
e_binding_transform_uid_to_source (GBinding *binding,
const GValue *source_value,
GValue *target_value,
- ESourceList *source_list)
+ ESourceRegistry *registry)
{
ESource *source;
const gchar *string;
gboolean success = FALSE;
g_return_val_if_fail (G_IS_BINDING (binding), FALSE);
- g_return_val_if_fail (E_IS_SOURCE_LIST (source_list), FALSE);
+ g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), FALSE);
string = g_value_get_string (source_value);
if (string == NULL || *string == '\0')
return FALSE;
- source = e_source_list_peek_source_by_uid (source_list, string);
+ source = e_source_registry_ref_source (registry, string);
if (source != NULL) {
- g_value_set_object (target_value, source);
+ g_value_take_object (target_value, source);
success = TRUE;
}
diff --git a/e-util/e-util.h b/e-util/e-util.h
index bd9ad2dc05..af2232489e 100644
--- a/e-util/e-util.h
+++ b/e-util/e-util.h
@@ -32,7 +32,7 @@
#include <e-util/e-marshal.h>
#include <e-util/e-util-enums.h>
-#include <libedataserver/e-source-list.h>
+#include <libedataserver/e-source-registry.h>
/* e_get_user_data_dir() used to live here, so #include its new home
* for backward-compatibility (not that we really care about that). */
@@ -131,10 +131,6 @@ GSList * e_util_get_category_filter_options
(void);
GList * e_util_get_searchable_categories (void);
-void e_util_set_source_combo_box_list
- (GtkWidget *source_combo_box,
- const gchar *source_gconf_path);
-
/* Useful GBinding transform functions */
gboolean e_binding_transform_color_to_string
(GBinding *binding,
@@ -150,12 +146,12 @@ gboolean e_binding_transform_source_to_uid
(GBinding *binding,
const GValue *source_value,
GValue *target_value,
- ESourceList *source_list);
+ ESourceRegistry *registry);
gboolean e_binding_transform_uid_to_source
(GBinding *binding,
const GValue *source_value,
GValue *target_value,
- ESourceList *source_list);
+ ESourceRegistry *registry);
G_END_DECLS
diff --git a/libemail-utils/e-account-utils.c b/libemail-utils/e-account-utils.c
deleted file mode 100644
index 6e64d45747..0000000000
--- a/libemail-utils/e-account-utils.c
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * 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 <http://www.gnu.org/licenses/>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- */
-
-/**
- * SECTION: e-account-utils
- * @include: e-util/e-account-utils.h
- **/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "e-account-utils.h"
-
-#include <string.h>
-#include <gconf/gconf-client.h>
-
-static EAccountList *global_account_list;
-
-static gboolean
-account_has_transport_url (EAccount *account)
-{
- return (account != NULL) &&
- (account->enabled) &&
- (account->transport != NULL) &&
- (account->transport->url != NULL) &&
- (account->transport->url[0] != '\0');
-}
-
-/**
- * e_get_account_list:
- *
- * Returns the global #EAccountList.
- *
- * Returns: the global #EAccountList
- **/
-EAccountList *
-e_get_account_list (void)
-{
- if (G_UNLIKELY (global_account_list == NULL)) {
- GConfClient *client;
-
- client = gconf_client_get_default ();
- global_account_list = e_account_list_new (client);
- g_object_unref (client);
- }
-
- g_return_val_if_fail (global_account_list != NULL, NULL);
-
- return global_account_list;
-}
-
-/**
- * e_get_default_account:
- *
- * Returns the #EAccount marked as the default mail account.
- *
- * Returns: the default #EAccount
- **/
-EAccount *
-e_get_default_account (void)
-{
- EAccountList *account_list;
- const EAccount *account;
-
- account_list = e_get_account_list ();
- account = e_account_list_get_default (account_list);
-
- /* XXX EAccountList misuses const. */
- return (EAccount *) account;
-}
-
-/**
- * e_set_default_account:
- * @account: an #EAccount
- *
- * Marks @account as the default mail account.
- **/
-void
-e_set_default_account (EAccount *account)
-{
- EAccountList *account_list;
-
- g_return_if_fail (E_IS_ACCOUNT (account));
-
- account_list = e_get_account_list ();
- e_account_list_set_default (account_list, account);
-}
-
-/**
- * e_get_account_by_name:
- * @name: a mail account name
- *
- * Returns the #EAccount with the given name, or %NULL if no such
- * account exists.
- *
- * Returns: an #EAccount having the given account name, or %NULL
- **/
-EAccount *
-e_get_account_by_name (const gchar *name)
-{
- EAccountList *account_list;
- const EAccount *account;
- e_account_find_t find;
-
- g_return_val_if_fail (name != NULL, NULL);
-
- find = E_ACCOUNT_FIND_NAME;
- account_list = e_get_account_list ();
- account = e_account_list_find (account_list, find, name);
-
- /* XXX EAccountList misuses const. */
- return (EAccount *) account;
-}
-
-/**
- * e_get_account_by_uid:
- * @uid: a mail account UID
- *
- * Returns the #EAccount corresponding to the given unique identity (UID),
- * or %NULL if no such account exists. The @uid can refer to an #EAccount
- * UID, a #CamelStore UID, or even a #CamelTransport UID.
- *
- * Returns: the corresponding #EAccount, or %NULL
- **/
-EAccount *
-e_get_account_by_uid (const gchar *uid)
-{
- EAccountList *account_list;
- const EAccount *account;
- e_account_find_t find;
- gchar *account_uid;
-
- g_return_val_if_fail (uid != NULL, NULL);
-
- /* EAccounts have the following invariant:
- *
- * CamelStore UID == EAccount UID
- * CamelTransport UID == EAccount UID + "-transport"
- *
- * Therefore we can detect CamelTransport UIDs and convert them.
- */
- if (g_str_has_suffix (uid, "-transport"))
- account_uid = g_strndup (uid, strlen (uid) - 10);
- else
- account_uid = g_strdup (uid);
-
- find = E_ACCOUNT_FIND_UID;
- account_list = e_get_account_list ();
- account = e_account_list_find (account_list, find, account_uid);
-
- g_free (account_uid);
-
- /* XXX EAccountList misuses const. */
- return (EAccount *) account;
-}
-
-/**
- * e_get_any_enabled_account:
- *
- * Returns the default mail account if it's enabled, otherwise the first
- * enabled mail account in the global #EAccountList, or finally %NULL if
- * all mail accounts are disabled or none exist.
- *
- * Returns: an enabled #EAccount, or %NULL if there are none
- **/
-EAccount *
-e_get_any_enabled_account (void)
-{
- EAccount *account;
- EAccountList *account_list;
- EIterator *iter;
-
- account = e_get_default_account ();
- if (account != NULL && account->enabled)
- return account;
-
- account = NULL;
-
- account_list = e_get_account_list ();
- iter = e_list_get_iterator (E_LIST (account_list));
-
- while (e_iterator_is_valid (iter) && account == NULL) {
- EAccount *candidate;
-
- /* XXX EIterator misuses const. */
- candidate = (EAccount *) e_iterator_get (iter);
-
- if (candidate->enabled)
- account = candidate;
- else
- e_iterator_next (iter);
- }
-
- g_object_unref (iter);
-
- return account;
-}
-
-/**
- * e_get_default_transport:
- *
- * Returns transport information for the default account if it's enabled and
- * has transport information, or else from the first enabled mail account in
- * the global #EAccountList that has transport information, or finally %NULL
- * if no transport information could be found.
- *
- * Returns: an #EAccount with transport info, or %NULL
- **/
-EAccount *
-e_get_default_transport (void)
-{
- EAccountList *account_list;
- EAccount *account;
- EIterator *iterator;
-
- account = e_get_default_account ();
- if (account_has_transport_url (account))
- return account;
-
- account_list = e_get_account_list ();
- iterator = e_list_get_iterator (E_LIST (account_list));
-
- while (e_iterator_is_valid (iterator)) {
- /* XXX EIterator misuses const. */
- account = (EAccount *) e_iterator_get (iterator);
- if (account_has_transport_url (account)) {
- g_object_unref (iterator);
- return account;
- }
- e_iterator_next (iterator);
- }
-
- g_object_unref (iterator);
-
- return NULL;
-}
-
diff --git a/libemail-utils/e-account-utils.h b/libemail-utils/e-account-utils.h
deleted file mode 100644
index d7dbd283fd..0000000000
--- a/libemail-utils/e-account-utils.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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 <http://www.gnu.org/licenses/>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- */
-
-#ifndef E_ACCOUNT_UTILS_H
-#define E_ACCOUNT_UTILS_H
-
-#include <camel/camel.h>
-#include <libedataserver/e-account.h>
-#include <libedataserver/e-account-list.h>
-
-G_BEGIN_DECLS
-
-EAccountList * e_get_account_list (void);
-EAccount * e_get_default_account (void);
-void e_set_default_account (EAccount *account);
-EAccount * e_get_account_by_name (const gchar *name);
-EAccount * e_get_account_by_uid (const gchar *uid);
-EAccount * e_get_any_enabled_account (void);
-EAccount * e_get_default_transport (void);
-
-G_END_DECLS
-
-#endif /* E_ACCOUNT_UTILS_H */
diff --git a/libemail-utils/e-signature-list.c b/libemail-utils/e-signature-list.c
deleted file mode 100644
index 5be5d31ca1..0000000000
--- a/libemail-utils/e-signature-list.c
+++ /dev/null
@@ -1,501 +0,0 @@
-/*
- *
- * 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 <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Jeffrey Stedfast <fejj@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "e-signature-list.h"
-
-#include <string.h>
-
-#include <libedataserver/e-uid.h>
-
-#define E_SIGNATURE_LIST_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE \
- ((obj), E_TYPE_SIGNATURE_LIST, ESignatureListPrivate))
-
-struct _ESignatureListPrivate {
- GConfClient *gconf;
- guint notify_id;
- gboolean resave;
-};
-
-enum {
- SIGNATURE_ADDED,
- SIGNATURE_CHANGED,
- SIGNATURE_REMOVED,
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL] = { 0 };
-
-G_DEFINE_TYPE (
- ESignatureList,
- e_signature_list,
- E_TYPE_LIST)
-
-static void
-e_signature_list_dispose (GObject *object)
-{
- ESignatureList *list = (ESignatureList *) object;
-
- if (list->priv->gconf) {
- if (list->priv->notify_id != 0)
- gconf_client_notify_remove (
- list->priv->gconf, list->priv->notify_id);
- g_object_unref (list->priv->gconf);
- list->priv->gconf = NULL;
- }
-
- /* Chain up to parent's dispose() method. */
- G_OBJECT_CLASS (e_signature_list_parent_class)->dispose (object);
-}
-
-static void
-e_signature_list_class_init (ESignatureListClass *class)
-{
- GObjectClass *object_class;
-
- g_type_class_add_private (class, sizeof (ESignatureListPrivate));
-
- object_class = G_OBJECT_CLASS (class);
- object_class->dispose = e_signature_list_dispose;
-
- signals[SIGNATURE_ADDED] = g_signal_new (
- "signature-added",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (ESignatureListClass, signature_added),
- NULL, NULL,
- g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE, 1,
- E_TYPE_SIGNATURE);
-
- signals[SIGNATURE_CHANGED] = g_signal_new (
- "signature-changed",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (ESignatureListClass, signature_changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE, 1,
- E_TYPE_SIGNATURE);
-
- signals[SIGNATURE_REMOVED] = g_signal_new (
- "signature-removed",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (ESignatureListClass, signature_removed),
- NULL, NULL,
- g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE, 1,
- E_TYPE_SIGNATURE);
-}
-
-static void
-e_signature_list_init (ESignatureList *signature_list)
-{
- signature_list->priv = E_SIGNATURE_LIST_GET_PRIVATE (signature_list);
-}
-
-static GSList *
-add_autogen (ESignatureList *list,
- GSList *new_sigs)
-{
- ESignature *autogen;
-
- autogen = e_signature_new ();
- e_signature_set_autogenerated (autogen, TRUE);
-
- e_list_append (E_LIST (list), autogen);
-
- return g_slist_prepend (new_sigs, autogen);
-}
-
-static void
-gconf_signatures_changed (GConfClient *client,
- guint cnxn_id,
- GConfEntry *entry,
- gpointer user_data)
-{
- ESignatureList *signature_list = user_data;
- GSList *list, *l, *n, *new_sigs = NULL;
- gboolean have_autogen = FALSE;
- gboolean resave = FALSE;
- ESignature *signature;
- EList *old_sigs;
- EIterator *iter;
- gboolean found;
- gchar *uid;
-
- old_sigs = e_list_duplicate (E_LIST (signature_list));
-
- list = gconf_client_get_list (
- client, "/apps/evolution/mail/signatures",
- GCONF_VALUE_STRING, NULL);
- for (l = list; l; l = l->next) {
- found = FALSE;
- if ((uid = e_signature_uid_from_xml (l->data))) {
- /* See if this is an existing signature */
- iter = e_list_get_iterator (old_sigs);
- while (e_iterator_is_valid (iter)) {
- const gchar *signature_uid;
-
- signature = (ESignature *) e_iterator_get (iter);
- signature_uid = e_signature_get_uid (signature);
- if (!strcmp (signature_uid, uid)) {
- /* The signature still exists, so remove
- * it from "old_sigs" and update it. */
- found = TRUE;
- e_iterator_delete (iter);
- if (e_signature_set_from_xml (
- signature, l->data))
- g_signal_emit (
- signature_list,
- signals[SIGNATURE_CHANGED],
- 0, signature);
-
- have_autogen |=
- e_signature_get_autogenerated (
- signature);
-
- break;
- }
-
- e_iterator_next (iter);
- }
-
- g_object_unref (iter);
- }
-
- if (!found) {
- resave = TRUE;
-
- /* Must be a new signature */
- signature = e_signature_new_from_xml (l->data);
- if (signature) {
- have_autogen |=
- e_signature_get_autogenerated (signature);
-
- e_list_append (E_LIST (signature_list), signature);
- new_sigs = g_slist_prepend (new_sigs, signature);
- }
- }
-
- g_free (uid);
- }
-
- g_slist_foreach (list, (GFunc) g_free, NULL);
- g_slist_free (list);
-
- if (!have_autogen) {
- new_sigs = add_autogen (signature_list, new_sigs);
- resave = TRUE;
- }
-
- if (new_sigs != NULL) {
- /* Now emit signals for each added signature. */
- l = g_slist_reverse (new_sigs);
- while (l != NULL) {
- n = l->next;
- signature = l->data;
- g_signal_emit (
- signature_list,
- signals[SIGNATURE_ADDED], 0,
- signature);
- g_object_unref (signature);
- g_slist_free_1 (l);
- l = n;
- }
- }
-
- /* Anything left in old_sigs must have been deleted */
- iter = e_list_get_iterator (old_sigs);
- while (e_iterator_is_valid (iter)) {
- signature = (ESignature *) e_iterator_get (iter);
- e_list_remove (E_LIST (signature_list), signature);
- g_signal_emit (
- signature_list, signals[SIGNATURE_REMOVED], 0,
- signature);
- e_iterator_next (iter);
- }
-
- g_object_unref (iter);
- g_object_unref (old_sigs);
-
- signature_list->priv->resave = resave;
-}
-
-static gpointer
-copy_func (gconstpointer data,
- gpointer closure)
-{
- GObject *object = (GObject *) data;
-
- g_object_ref (object);
-
- return object;
-}
-
-static void
-free_func (gpointer data,
- gpointer closure)
-{
- g_object_unref (data);
-}
-
-/**
- * e_signature_list_new:
- *
- * Reads the list of signaturess from @gconf and listens for changes.
- * Will emit #signature_added, #signature_changed, and #signature_removed
- * signals according to notifications from GConf.
- *
- * You can modify the list using e_list_append(), e_list_remove(), and
- * e_iterator_delete(). After adding, removing, or changing accounts,
- * you must call e_signature_list_save() to push the changes back to
- * GConf.
- *
- * Return value: the list of signatures
- **/
-ESignatureList *
-e_signature_list_new (void)
-{
- ESignatureList *signature_list;
- GConfClient *client;
-
- signature_list = g_object_new (E_TYPE_SIGNATURE_LIST, NULL);
-
- client = gconf_client_get_default ();
- e_signature_list_construct (signature_list, client);
- g_object_unref (client);
-
- return signature_list;
-}
-
-void
-e_signature_list_construct (ESignatureList *signature_list,
- GConfClient *gconf)
-{
- g_return_if_fail (GCONF_IS_CLIENT (gconf));
-
- e_list_construct (E_LIST (signature_list), copy_func, free_func, NULL);
- signature_list->priv->gconf = gconf;
- g_object_ref (gconf);
-
- gconf_client_add_dir (signature_list->priv->gconf,
- "/apps/evolution/mail/signatures",
- GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
-
- signature_list->priv->notify_id =
- gconf_client_notify_add (signature_list->priv->gconf,
- "/apps/evolution/mail/signatures",
- gconf_signatures_changed, signature_list,
- NULL, NULL);
-
- gconf_signatures_changed (signature_list->priv->gconf,
- signature_list->priv->notify_id,
- NULL, signature_list);
-
- if (signature_list->priv->resave) {
- e_signature_list_save (signature_list);
- signature_list->priv->resave = FALSE;
- }
-}
-
-/**
- * e_signature_list_save:
- * @signature_list: an #ESignatureList
- *
- * Saves @signature_list to GConf. Signals will be emitted for changes.
- **/
-void
-e_signature_list_save (ESignatureList *signature_list)
-{
- GSList *list = NULL;
- ESignature *signature;
- EIterator *iter;
- gchar *xmlbuf;
-
- for (iter = e_list_get_iterator (E_LIST (signature_list));
- e_iterator_is_valid (iter);
- e_iterator_next (iter)) {
- signature = (ESignature *) e_iterator_get (iter);
-
- if ((xmlbuf = e_signature_to_xml (signature)))
- list = g_slist_append (list, xmlbuf);
- }
-
- g_object_unref (iter);
-
- gconf_client_set_list (signature_list->priv->gconf,
- "/apps/evolution/mail/signatures",
- GCONF_VALUE_STRING, list, NULL);
-
- while (list) {
- g_free (list->data);
- list = g_slist_remove (list, list->data);
- }
-
- gconf_client_suggest_sync (signature_list->priv->gconf, NULL);
-}
-
-/**
- * e_signature_list_add:
- * @signature_list: signature list
- * @signature: signature to add
- *
- * Add an signature to the signature list. Will emit the signature-changed
- * event.
- **/
-void
-e_signature_list_add (ESignatureList *signature_list,
- ESignature *signature)
-{
- e_list_append ((EList *) signature_list, signature);
- g_signal_emit (signature_list, signals[SIGNATURE_ADDED], 0, signature);
-}
-
-/**
- * e_signature_list_change:
- * @signature_list: signature list
- * @signature: signature to change
- *
- * Signal that the details of an signature have changed.
- **/
-void
-e_signature_list_change (ESignatureList *signature_list,
- ESignature *signature)
-{
- /* maybe the signature should do this itself ... */
- g_signal_emit (signature_list, signals[SIGNATURE_CHANGED], 0, signature);
-}
-
-/**
- * e_signature_list_remove:
- * @signature_list: signature list
- * @signature: signature
- *
- * Remove an signature from the signature list, and emit the
- * signature-removed signal. If the signature was the default signature,
- * then reset the default to the first signature.
- **/
-void
-e_signature_list_remove (ESignatureList *signature_list,
- ESignature *signature)
-{
- /* not sure if need to ref but no harm */
- g_object_ref (signature);
- e_list_remove ((EList *) signature_list, signature);
- g_signal_emit (signature_list, signals[SIGNATURE_REMOVED], 0, signature);
- g_object_unref (signature);
-}
-
-/**
- * e_signature_list_find_by_name:
- * @signature_list: an #ESignatureList
- * @name: the signature name to find
- *
- * Searches @signature_list for the given signature name.
- *
- * Returns: the matching signature or %NULL if it doesn't exist
- **/
-ESignature *
-e_signature_list_find_by_name (ESignatureList *signature_list,
- const gchar *signature_name)
-{
- ESignature *signature = NULL;
- EIterator *it;
-
- g_return_val_if_fail (E_IS_SIGNATURE_LIST (signature_list), NULL);
-
- /* this could use a callback for more flexibility ...
- * ... but this makes the common cases easier */
-
- if (signature_name == NULL)
- return NULL;
-
- for (it = e_list_get_iterator (E_LIST (signature_list));
- e_iterator_is_valid (it);
- e_iterator_next (it)) {
- const gchar *value;
-
- /* XXX EIterator misuses const. */
- signature = (ESignature *) e_iterator_get (it);
- value = e_signature_get_name (signature);
-
- if (g_strcmp0 (value, signature_name) == 0)
- break;
-
- signature = NULL;
- }
-
- g_object_unref (it);
-
- return signature;
-}
-
-/**
- * e_signature_list_find_by_uid:
- * @signature_list: an #ESignatureList
- * @name: the signature UID to find
- *
- * Searches @signature_list for the given signature UID.
- *
- * Returns: the matching signature or %NULL if it doesn't exist
- **/
-ESignature *
-e_signature_list_find_by_uid (ESignatureList *signature_list,
- const gchar *signature_uid)
-{
- ESignature *signature = NULL;
- EIterator *it;
-
- g_return_val_if_fail (E_IS_SIGNATURE_LIST (signature_list), NULL);
-
- /* this could use a callback for more flexibility ...
- * ... but this makes the common cases easier */
-
- if (signature_uid == NULL)
- return NULL;
-
- for (it = e_list_get_iterator (E_LIST (signature_list));
- e_iterator_is_valid (it);
- e_iterator_next (it)) {
- const gchar *value = NULL;
-
- /* XXX EIterator misuses const. */
- signature = (ESignature *) e_iterator_get (it);
- value = e_signature_get_uid (signature);
-
- if (g_strcmp0 (value, signature_uid) == 0)
- break;
-
- signature = NULL;
- }
-
- g_object_unref (it);
-
- return signature;
-}
diff --git a/libemail-utils/e-signature-list.h b/libemail-utils/e-signature-list.h
deleted file mode 100644
index ebcb4b28e2..0000000000
--- a/libemail-utils/e-signature-list.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- *
- * 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 <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Jeffrey Stedfast <fejj@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef E_SIGNATURE_LIST_H
-#define E_SIGNATURE_LIST_H
-
-#include <gconf/gconf-client.h>
-#include <libedataserver/e-list.h>
-#include <libemail-utils/e-signature.h>
-
-/* Standard GObject macros */
-#define E_TYPE_SIGNATURE_LIST \
- (e_signature_list_get_type ())
-#define E_SIGNATURE_LIST(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST \
- ((obj), E_TYPE_SIGNATURE_LIST, ESignatureList))
-#define E_SIGNATURE_LIST_CLASS(cls) \
- (G_TYPE_CHECK_CLASS_CAST \
- ((cls), E_TYPE_SIGNATURE_LIST, ESignatureListClass))
-#define E_IS_SIGNATURE_LIST(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE \
- ((obj), E_TYPE_SIGNATURE_LIST))
-#define E_IS_SIGNATURE_LIST_CLASS(cls) \
- (G_TYPE_CHECK_CLASS_TYPE \
- ((cls), E_TYPE_SIGNATURE_LIST))
-#define E_SIGNATURE_LIST_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS \
- ((obj), E_TYPE_SIGNATURE_LIST, ESignatureListClass))
-
-G_BEGIN_DECLS
-
-typedef struct _ESignatureList ESignatureList;
-typedef struct _ESignatureListClass ESignatureListClass;
-typedef struct _ESignatureListPrivate ESignatureListPrivate;
-
-struct _ESignatureList {
- EList parent;
- ESignatureListPrivate *priv;
-};
-
-struct _ESignatureListClass {
- EListClass parent_class;
-
- /* Signals */
- void (*signature_added) (ESignatureList *signature_list,
- ESignature *signature);
- void (*signature_changed) (ESignatureList *signature_list,
- ESignature *signature);
- void (*signature_removed) (ESignatureList *signature_list,
- ESignature *signature);
-};
-
-GType e_signature_list_get_type (void);
-ESignatureList *e_signature_list_new (void);
-void e_signature_list_construct (ESignatureList *signature_list,
- GConfClient *client);
-void e_signature_list_save (ESignatureList *signature_list);
-void e_signature_list_add (ESignatureList *signature_list,
- ESignature *signature);
-void e_signature_list_change (ESignatureList *signature_list,
- ESignature *signature);
-void e_signature_list_remove (ESignatureList *signature_list,
- ESignature *signature);
-ESignature * e_signature_list_find_by_name (ESignatureList *signature_list,
- const gchar *signature_name);
-ESignature * e_signature_list_find_by_uid (ESignatureList *signature_list,
- const gchar *signature_uid);
-
-G_END_DECLS
-
-#endif /* E_SIGNATURE_LIST_H */
diff --git a/libemail-utils/e-signature-utils.c b/libemail-utils/e-signature-utils.c
deleted file mode 100644
index ca46f053db..0000000000
--- a/libemail-utils/e-signature-utils.c
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * e-signature-utils.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 <http://www.gnu.org/licenses/>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "e-signature-utils.h"
-
-#include <errno.h>
-#include <camel/camel.h>
-#include <glib/gstdio.h>
-
-#ifndef G_OS_WIN32
-#include <sys/wait.h>
-#endif
-
-#include <libedataserver/e-data-server-util.h>
-
-static ESignatureList *global_signature_list;
-
-ESignatureList *
-e_get_signature_list (void)
-{
- if (G_UNLIKELY (global_signature_list == NULL))
- global_signature_list = e_signature_list_new ();
-
- g_return_val_if_fail (global_signature_list != NULL, NULL);
-
- return global_signature_list;
-}
-
-ESignature *
-e_get_signature_by_name (const gchar *name)
-{
- ESignatureList *signature_list;
-
- g_return_val_if_fail (name != NULL, NULL);
-
- signature_list = e_get_signature_list ();
-
- return e_signature_list_find_by_name (signature_list, name);
-}
-
-ESignature *
-e_get_signature_by_uid (const gchar *uid)
-{
- ESignatureList *signature_list;
-
- g_return_val_if_fail (uid != NULL, NULL);
-
- signature_list = e_get_signature_list ();
-
- return e_signature_list_find_by_uid (signature_list, uid);
-}
-
-gchar *
-e_create_signature_file (GError **error)
-{
- const gchar *data_dir;
- gchar basename[32];
- gchar *filename;
- gchar *pathname;
- gint32 ii;
-
- data_dir = e_get_user_data_dir ();
- pathname = g_build_filename (data_dir, "signatures", NULL);
- filename = NULL;
-
- if (g_mkdir_with_parents (pathname, 0700) < 0) {
- g_set_error (
- error, G_FILE_ERROR,
- g_file_error_from_errno (errno),
- "%s: %s", pathname, g_strerror (errno));
- g_free (pathname);
- return NULL;
- }
-
- for (ii = 0; ii < G_MAXINT32; ii++) {
-
- g_snprintf (
- basename, sizeof (basename),
- "signature-%" G_GINT32_FORMAT, ii);
-
- g_free (filename);
- filename = g_build_filename (pathname, basename, NULL);
-
- if (!g_file_test (filename, G_FILE_TEST_EXISTS)) {
- gint fd;
-
- fd = g_creat (filename, 0600);
- if (fd >= 0) {
- close (fd);
- break;
- }
-
- /* If we failed once we're probably going
- * to continue failing, so just give up. */
- g_set_error (
- error, G_FILE_ERROR,
- g_file_error_from_errno (errno),
- "%s: %s", filename, g_strerror (errno));
- g_free (filename);
- filename = NULL;
- break;
- }
- }
-
- /* If there are actually G_MAXINT32 signature files, the
- * most recent signature file we be overwritten. Sorry. */
-
- return filename;
-}
-
-gchar *
-e_read_signature_file (ESignature *signature,
- gboolean convert_to_html,
- GError **error)
-{
- CamelStream *input_stream;
- CamelStream *output_stream;
- GByteArray *buffer;
- const gchar *filename;
- gboolean is_html;
- gchar *content;
- gsize length;
- gint fd;
-
- g_return_val_if_fail (E_IS_SIGNATURE (signature), NULL);
-
- filename = e_signature_get_filename (signature);
- is_html = e_signature_get_is_html (signature);
-
- fd = g_open (filename, O_RDONLY, 0);
- if (fd < 0) {
- g_set_error (
- error, G_FILE_ERROR,
- g_file_error_from_errno (errno),
- "%s: %s", filename, g_strerror (errno));
- return NULL;
- }
-
- input_stream = camel_stream_fs_new_with_fd (fd);
-
- if (!is_html && convert_to_html) {
- CamelStream *filtered_stream;
- CamelMimeFilter *filter;
- gint32 flags;
-
- filtered_stream =
- camel_stream_filter_new (input_stream);
- g_object_unref (input_stream);
-
- flags =
- CAMEL_MIME_FILTER_TOHTML_PRESERVE_8BIT |
- CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS |
- CAMEL_MIME_FILTER_TOHTML_CONVERT_ADDRESSES |
- CAMEL_MIME_FILTER_TOHTML_CONVERT_SPACES;
- filter = camel_mime_filter_tohtml_new (flags, 0);
- camel_stream_filter_add (
- CAMEL_STREAM_FILTER (filtered_stream), filter);
- g_object_unref (filter);
-
- input_stream = filtered_stream;
- }
-
- buffer = g_byte_array_new ();
- output_stream = camel_stream_mem_new ();
- camel_stream_mem_set_byte_array (
- CAMEL_STREAM_MEM (output_stream), buffer);
- camel_stream_write_to_stream (input_stream, output_stream, NULL, NULL);
- g_object_unref (output_stream);
- g_object_unref (input_stream);
-
- /* Make sure the buffer is nul-terminated. */
- length = (gsize) buffer->len;
- g_byte_array_append (buffer, (guint8 *) "", 1);
- content = (gchar *) g_byte_array_free (buffer, FALSE);
-
- /* Signatures are saved as UTF-8, but we still need to check that
- * the signature is valid UTF-8 because the user may be opening
- * a signature file that is in his/her locale character set. If
- * it's not in UTF-8 then try converting from the current locale. */
- if (!g_utf8_validate (content, length, NULL)) {
- gchar *utf8;
-
- utf8 = g_locale_to_utf8 (content, length, NULL, NULL, error);
- g_free (content);
- content = utf8;
- }
-
- return content;
-}
-
-gchar *
-e_run_signature_script (const gchar *filename)
-{
- /* FIXME Make this cross-platform, prefer GLib functions over
- * POSIX, and report errors via GError instead of dumping
- * messages to the terminal where users won't see them. */
-
-#ifndef G_OS_WIN32
- gint in_fds[2];
- pid_t pid;
-
- g_return_val_if_fail (filename != NULL, NULL);
-
- if (pipe (in_fds) == -1) {
- g_warning (
- "Failed to create pipe to '%s': %s",
- filename, g_strerror (errno));
- return NULL;
- }
-
- pid = fork ();
-
- /* Child Process */
- if (pid == 0) {
- gint maxfd, ii;
-
- close (in_fds[0]);
- if (dup2 (in_fds[1], STDOUT_FILENO) < 0)
- _exit (255);
- close (in_fds[1]);
-
- setsid ();
-
- maxfd = sysconf (_SC_OPEN_MAX);
- for (ii = 3; ii < maxfd; ii++) {
- if (ii == STDIN_FILENO)
- continue;
- if (ii == STDOUT_FILENO)
- continue;
- if (ii == STDERR_FILENO)
- continue;
- fcntl (ii, F_SETFD, FD_CLOEXEC);
- }
-
- execlp ("/bin/sh", "/bin/sh", "-c", filename, NULL);
-
- g_warning (
- "Could not execute '%s': %s",
- filename, g_strerror (errno));
-
- _exit (255);
-
- /* Parent Process */
- } else if (pid > 0) {
- CamelStream *output_stream;
- CamelStream *input_stream;
- GByteArray *buffer;
- gchar *content;
- gsize length;
- gint result;
- gint status;
-
- close (in_fds[1]);
-
- buffer = g_byte_array_new ();
- output_stream = camel_stream_mem_new ();
- camel_stream_mem_set_byte_array (
- CAMEL_STREAM_MEM (output_stream), buffer);
-
- input_stream = camel_stream_fs_new_with_fd (in_fds[0]);
- camel_stream_write_to_stream (
- input_stream, output_stream, NULL, NULL);
- g_object_unref (input_stream);
-
- g_object_unref (output_stream);
-
- /* Make sure the buffer is nul-terminated. */
- length = (gsize) buffer->len;
- g_byte_array_append (buffer, (guchar *) "", 1);
- content = (gchar *) g_byte_array_free (buffer, FALSE);
-
- /* Signature scripts are supposed to generate UTF-8 content,
- * but because users are known to never read the manual, we
- * try to do our best if the content isn't valid UTF-8 by
- * assuming that the content is in the user's locale
- * character set. */
- if (!g_utf8_validate (content, length, NULL)) {
- gchar *utf8;
-
- /* XXX Should pass a GError here. */
- utf8 = g_locale_to_utf8 (
- content, length, NULL, NULL, NULL);
- g_free (content);
- content = utf8;
- }
-
- /* Wait for the script process to terminate. */
- result = waitpid (pid, &status, 0);
-
- if (result == -1 && errno == EINTR) {
- /* Child process is hanging... */
- kill (pid, SIGTERM);
- sleep (1);
- result = waitpid (pid, &status, WNOHANG);
- if (result == 0) {
- /* ...still hanging, set phasers to KILL. */
- kill (pid, SIGKILL);
- sleep (1);
- waitpid (pid, &status, WNOHANG);
- }
- }
-
- return content;
-
- /* Forking Failed */
- } else {
- g_warning (
- "Failed to create child process '%s': %s",
- filename, g_strerror (errno));
- close (in_fds[0]);
- close (in_fds[1]);
- }
-#endif
-
- return NULL;
-}
diff --git a/libemail-utils/e-signature-utils.h b/libemail-utils/e-signature-utils.h
deleted file mode 100644
index a642a136f1..0000000000
--- a/libemail-utils/e-signature-utils.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * e-signature-utils.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 <http://www.gnu.org/licenses/>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- */
-
-#ifndef E_SIGNATURE_UTILS_H
-#define E_SIGNATURE_UTILS_H
-
-#include <gtk/gtk.h>
-#include <libemail-utils/e-signature.h>
-#include <libemail-utils/e-signature-list.h>
-
-G_BEGIN_DECLS
-
-ESignatureList *e_get_signature_list (void);
-ESignature * e_get_signature_by_name (const gchar *name);
-ESignature * e_get_signature_by_uid (const gchar *uid);
-gchar * e_create_signature_file (GError **error);
-gchar * e_read_signature_file (ESignature *signature,
- gboolean convert_to_html,
- GError **error);
-gchar * e_run_signature_script (const gchar *filename);
-
-G_END_DECLS
-
-#endif /* E_SIGNATURE_UTILS_H */
diff --git a/libemail-utils/e-signature.c b/libemail-utils/e-signature.c
deleted file mode 100644
index e568c63bd2..0000000000
--- a/libemail-utils/e-signature.c
+++ /dev/null
@@ -1,749 +0,0 @@
-/*
- *
- * 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 <http://www.gnu.org/licenses/>
- *
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-
-#include <libxml/tree.h>
-#include <libxml/parser.h>
-#include <libxml/xmlmemory.h>
-
-#include <glib/gi18n-lib.h>
-
-#include <libedataserver/e-uid.h>
-#include <libedataserver/e-data-server-util.h>
-
-#include "e-signature.h"
-
-#define E_SIGNATURE_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE \
- ((obj), E_TYPE_SIGNATURE, ESignaturePrivate))
-
-struct _ESignaturePrivate {
- gchar *filename;
- gchar *name;
- gchar *uid;
-
- gboolean autogenerated;
- gboolean is_html;
- gboolean is_script;
-};
-
-enum {
- PROP_0,
- PROP_AUTOGENERATED,
- PROP_FILENAME,
- PROP_IS_HTML,
- PROP_IS_SCRIPT,
- PROP_NAME,
- PROP_UID
-};
-
-G_DEFINE_TYPE (
- ESignature,
- e_signature,
- G_TYPE_OBJECT)
-
-static gboolean
-xml_set_bool (xmlNodePtr node,
- const gchar *name,
- gboolean *val)
-{
- gboolean v_boolean;
- gchar *buf;
-
- if ((buf = (gchar *) xmlGetProp (node, (xmlChar *) name))) {
- v_boolean = (!strcmp (buf, "true") || !strcmp (buf, "yes"));
- xmlFree (buf);
-
- if (v_boolean != *val) {
- *val = v_boolean;
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-static gboolean
-xml_set_prop (xmlNodePtr node,
- const gchar *name,
- gchar **val)
-{
- gchar *buf, *new_val;
-
- buf = (gchar *) xmlGetProp (node, (xmlChar *) name);
- new_val = g_strdup (buf);
- xmlFree (buf);
-
- /* We can use strcmp here whether the value is UTF8 or
- * not, since we only care if the bytes changed.
- */
- if (!*val || strcmp (*val, new_val)) {
- g_free (*val);
- *val = new_val;
- return TRUE;
- } else {
- g_free (new_val);
- return FALSE;
- }
-}
-
-static gboolean
-xml_set_content (xmlNodePtr node,
- gchar **val)
-{
- gchar *buf, *new_val;
-
- buf = (gchar *) xmlNodeGetContent (node);
- new_val = g_strdup (buf);
- xmlFree (buf);
-
- /* We can use strcmp here whether the value is UTF8 or
- * not, since we only care if the bytes changed. */
- if (!*val || strcmp (*val, new_val)) {
- g_free (*val);
- *val = new_val;
- return TRUE;
- } else {
- g_free (new_val);
- return FALSE;
- }
-}
-
-static void
-signature_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- switch (property_id) {
- case PROP_AUTOGENERATED:
- e_signature_set_autogenerated (
- E_SIGNATURE (object),
- g_value_get_boolean (value));
- return;
-
- case PROP_FILENAME:
- e_signature_set_filename (
- E_SIGNATURE (object),
- g_value_get_string (value));
- return;
-
- case PROP_IS_HTML:
- e_signature_set_is_html (
- E_SIGNATURE (object),
- g_value_get_boolean (value));
- return;
-
- case PROP_IS_SCRIPT:
- e_signature_set_is_script (
- E_SIGNATURE (object),
- g_value_get_boolean (value));
- return;
-
- case PROP_NAME:
- e_signature_set_name (
- E_SIGNATURE (object),
- g_value_get_string (value));
- return;
-
- case PROP_UID:
- e_signature_set_uid (
- E_SIGNATURE (object),
- g_value_get_string (value));
- return;
- }
-
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
-}
-
-static void
-signature_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- switch (property_id) {
- case PROP_AUTOGENERATED:
- g_value_set_boolean (
- value, e_signature_get_autogenerated (
- E_SIGNATURE (object)));
- return;
-
- case PROP_FILENAME:
- g_value_set_string (
- value, e_signature_get_filename (
- E_SIGNATURE (object)));
- return;
-
- case PROP_IS_HTML:
- g_value_set_boolean (
- value, e_signature_get_is_html (
- E_SIGNATURE (object)));
- return;
-
- case PROP_IS_SCRIPT:
- g_value_set_boolean (
- value, e_signature_get_is_script (
- E_SIGNATURE (object)));
- return;
-
- case PROP_NAME:
- g_value_set_string (
- value, e_signature_get_name (
- E_SIGNATURE (object)));
- return;
-
- case PROP_UID:
- g_value_set_string (
- value, e_signature_get_uid (
- E_SIGNATURE (object)));
- return;
- }
-
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
-}
-
-static void
-signature_finalize (GObject *object)
-{
- ESignaturePrivate *priv;
-
- priv = E_SIGNATURE (object)->priv;
-
- g_free (priv->filename);
- g_free (priv->name);
- g_free (priv->uid);
-
- /* Chain up to parent's finalize() method. */
- G_OBJECT_CLASS (e_signature_parent_class)->finalize (object);
-}
-
-static void
-e_signature_class_init (ESignatureClass *class)
-{
- GObjectClass *object_class;
-
- g_type_class_add_private (class, sizeof (ESignaturePrivate));
-
- object_class = G_OBJECT_CLASS (class);
- object_class->set_property = signature_set_property;
- object_class->get_property = signature_get_property;
- object_class->finalize = signature_finalize;
-
- g_object_class_install_property (
- object_class,
- PROP_AUTOGENERATED,
- g_param_spec_boolean (
- "autogenerated",
- "Autogenerated",
- NULL,
- FALSE,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT));
-
- g_object_class_install_property (
- object_class,
- PROP_FILENAME,
- g_param_spec_string (
- "filename",
- "Filename",
- NULL,
- NULL,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT));
-
- g_object_class_install_property (
- object_class,
- PROP_IS_HTML,
- g_param_spec_boolean (
- "is-html",
- "Is HTML",
- NULL,
- FALSE,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT));
-
- g_object_class_install_property (
- object_class,
- PROP_IS_SCRIPT,
- g_param_spec_boolean (
- "is-script",
- "Is Script",
- NULL,
- FALSE,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT));
-
- g_object_class_install_property (
- object_class,
- PROP_NAME,
- g_param_spec_string (
- "name",
- "Name",
- NULL,
- NULL,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT));
-
- g_object_class_install_property (
- object_class,
- PROP_UID,
- g_param_spec_string (
- "uid",
- "UID",
- NULL,
- NULL,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT));
-}
-
-static void
-e_signature_init (ESignature *signature)
-{
- signature->priv = E_SIGNATURE_GET_PRIVATE (signature);
-}
-
-/**
- * e_signature_new:
- *
- * Returns a new signature which can be filled in and
- * added to an #ESignatureList.
- *
- * Returns: a new #ESignature
- **/
-ESignature *
-e_signature_new (void)
-{
- ESignature *signature;
-
- signature = g_object_new (E_TYPE_SIGNATURE, NULL);
- signature->priv->uid = e_uid_new ();
-
- return signature;
-}
-
-/**
- * e_signature_new_from_xml:
- * @xml: an XML signature description
- *
- * Return value: a new #ESignature based on the data in @xml, or %NULL
- * if @xml could not be parsed as valid signature data.
- **/
-ESignature *
-e_signature_new_from_xml (const gchar *xml)
-{
- ESignature *signature;
-
- signature = g_object_new (E_TYPE_SIGNATURE, NULL);
-
- if (!e_signature_set_from_xml (signature, xml)) {
- g_object_unref (signature);
- return NULL;
- }
-
- return signature;
-}
-
-/**
- * e_signature_uid_from_xml:
- * @xml: an XML signature description
- *
- * Return value: the permanent UID of the signature described by @xml
- * (or %NULL if @xml could not be parsed or did not contain a uid).
- * The caller must free this string.
- **/
-gchar *
-e_signature_uid_from_xml (const gchar *xml)
-{
- xmlNodePtr node;
- xmlDocPtr doc;
- gchar *uid = NULL;
-
- if (!(doc = xmlParseDoc ((xmlChar *) xml)))
- return NULL;
-
- node = doc->children;
- if (strcmp ((gchar *)node->name, "signature") != 0) {
- xmlFreeDoc (doc);
- return NULL;
- }
-
- xml_set_prop (node, "uid", &uid);
- xmlFreeDoc (doc);
-
- return uid;
-}
-
-/**
- * e_signature_set_from_xml:
- * @signature: an #ESignature
- * @xml: an XML signature description.
- *
- * Changes @signature to match @xml.
- *
- * Returns: %TRUE if the signature was loaded or %FALSE otherwise
- **/
-gboolean
-e_signature_set_from_xml (ESignature *signature,
- const gchar *xml)
-{
- gboolean changed = FALSE;
- xmlNodePtr node, cur;
- xmlDocPtr doc;
- gboolean bool;
- gchar *buf;
-
- if (!(doc = xmlParseDoc ((xmlChar *) xml)))
- return FALSE;
-
- node = doc->children;
- if (strcmp ((gchar *)node->name, "signature") != 0) {
- xmlFreeDoc (doc);
- return FALSE;
- }
-
- buf = NULL;
- xml_set_prop (node, "uid", &buf);
-
- if (buf && *buf) {
- g_free (signature->priv->uid);
- signature->priv->uid = buf;
- }
-
- changed |= xml_set_prop (node, "name", &signature->priv->name);
- changed |= xml_set_bool (node, "auto", &signature->priv->autogenerated);
-
- if (e_signature_get_autogenerated (signature)) {
- xmlFreeDoc (doc);
-
- return changed;
- }
-
- buf = NULL;
- xml_set_prop (node, "format", &buf);
- if (buf && !strcmp (buf, "text/html"))
- bool = TRUE;
- else
- bool = FALSE;
- g_free (buf);
-
- if (e_signature_get_is_html (signature) != bool) {
- e_signature_set_is_html (signature, bool);
- changed = TRUE;
- }
-
- cur = node->children;
- while (cur) {
- if (!strcmp ((gchar *)cur->name, "filename")) {
- changed |= xml_set_content (
- cur, &signature->priv->filename);
- changed |= xml_set_bool (
- cur, "script", &signature->priv->is_script);
- break;
- } else if (!strcmp ((gchar *)cur->name, "script")) {
- /* this is for handling 1.4 signature script definitions */
- changed |= xml_set_content (
- cur, &signature->priv->filename);
- if (!e_signature_get_is_script (signature)) {
- e_signature_set_is_script (signature, TRUE);
- changed = TRUE;
- }
- break;
- }
- cur = cur->next;
- }
-
- /* If the signature is not a script, replace the directory
- * part with the current signatures directory. This makes
- * moving the signatures directory transparent. */
- if (!e_signature_get_is_script (signature)) {
- const gchar *user_data_dir;
- gchar *basename;
- gchar *filename;
-
- user_data_dir = e_get_user_data_dir ();
-
- filename = signature->priv->filename;
- basename = g_path_get_basename (filename);
- signature->priv->filename = g_build_filename (
- user_data_dir, "signatures", basename, NULL);
- g_free (basename);
- g_free (filename);
- }
-
- xmlFreeDoc (doc);
-
- return changed;
-}
-
-/**
- * e_signature_to_xml:
- * @signature: an #ESignature
- *
- * Return value: an XML representation of @signature, which the caller
- * must free.
- **/
-gchar *
-e_signature_to_xml (ESignature *signature)
-{
- xmlChar *xmlbuf;
- gchar *tmp;
- xmlNodePtr root, node;
- xmlDocPtr doc;
- const gchar *string;
- gint n;
-
- doc = xmlNewDoc ((xmlChar *) "1.0");
-
- root = xmlNewDocNode (doc, NULL, (xmlChar *) "signature", NULL);
- xmlDocSetRootElement (doc, root);
-
- string = e_signature_get_name (signature);
- xmlSetProp (root, (xmlChar *) "name", (xmlChar *) string);
-
- string = e_signature_get_uid (signature);
- xmlSetProp (root, (xmlChar *) "uid", (xmlChar *) string);
-
- if (e_signature_get_autogenerated (signature))
- string = "true";
- else
- string = "false";
- xmlSetProp (root, (xmlChar *) "auto", (xmlChar *) string);
-
- if (!e_signature_get_autogenerated (signature)) {
- if (e_signature_get_is_html (signature))
- string = "text/html";
- else
- string = "text/plain";
- xmlSetProp (root, (xmlChar *) "format", (xmlChar *) string);
-
- string = e_signature_get_filename (signature);
- if (string != NULL) {
-
- /* For scripts we save the full filename,
- * for normal signatures just the basename. */
- if (e_signature_get_is_script (signature)) {
- node = xmlNewTextChild (
- root, NULL, (xmlChar *) "filename",
- (xmlChar *) string);
- xmlSetProp (
- node, (xmlChar *) "script",
- (xmlChar *) "true");
- } else {
- gchar *basename;
-
- basename = g_path_get_basename (string);
- node = xmlNewTextChild (
- root, NULL, (xmlChar *) "filename",
- (xmlChar *) basename);
- g_free (basename);
- }
- }
- } else {
- /* this is to make Evolution-1.4 and older 1.5 versions happy */
- xmlSetProp (root, (xmlChar *) "format", (xmlChar *) "text/html");
- }
-
- xmlDocDumpMemory (doc, &xmlbuf, &n);
- xmlFreeDoc (doc);
-
- /* remap to glib memory */
- tmp = g_malloc (n + 1);
- memcpy (tmp, xmlbuf, n);
- tmp[n] = '\0';
- xmlFree (xmlbuf);
-
- return tmp;
-}
-
-gboolean
-e_signature_is_equal (ESignature *signature1,
- ESignature *signature2)
-{
- const gchar *uid1;
- const gchar *uid2;
-
- g_return_val_if_fail (E_IS_SIGNATURE (signature1), FALSE);
- g_return_val_if_fail (E_IS_SIGNATURE (signature2), FALSE);
-
- /* XXX Simply compares the UIDs. Not fool-proof. */
- uid1 = e_signature_get_uid (signature1);
- uid2 = e_signature_get_uid (signature2);
-
- return (g_strcmp0 (uid1, uid2) == 0);
-}
-
-gboolean
-e_signature_get_autogenerated (ESignature *signature)
-{
- g_return_val_if_fail (E_IS_SIGNATURE (signature), FALSE);
-
- return signature->priv->autogenerated;
-}
-
-void
-e_signature_set_autogenerated (ESignature *signature,
- gboolean autogenerated)
-{
- g_return_if_fail (E_IS_SIGNATURE (signature));
-
- if (signature->priv->autogenerated == autogenerated)
- return;
-
- signature->priv->autogenerated = autogenerated;
-
- /* Autogenerated flags overrides several properties. */
- g_object_freeze_notify (G_OBJECT (signature));
- g_object_notify (G_OBJECT (signature), "autogenerated");
- g_object_notify (G_OBJECT (signature), "filename");
- g_object_notify (G_OBJECT (signature), "is-html");
- g_object_notify (G_OBJECT (signature), "is-script");
- g_object_notify (G_OBJECT (signature), "name");
- g_object_thaw_notify (G_OBJECT (signature));
-}
-
-const gchar *
-e_signature_get_filename (ESignature *signature)
-{
- g_return_val_if_fail (E_IS_SIGNATURE (signature), NULL);
-
- /* Autogenerated flags overrides the filename property. */
- if (e_signature_get_autogenerated (signature))
- return NULL;
-
- return signature->priv->filename;
-}
-
-void
-e_signature_set_filename (ESignature *signature,
- const gchar *filename)
-{
- g_return_if_fail (E_IS_SIGNATURE (signature));
-
- g_free (signature->priv->filename);
- signature->priv->filename = g_strdup (filename);
-
- g_object_notify (G_OBJECT (signature), "filename");
-}
-
-gboolean
-e_signature_get_is_html (ESignature *signature)
-{
- g_return_val_if_fail (E_IS_SIGNATURE (signature), FALSE);
-
- /* Autogenerated flag overrides the is-html property. */
- if (e_signature_get_autogenerated (signature))
- return FALSE;
-
- return signature->priv->is_html;
-}
-
-void
-e_signature_set_is_html (ESignature *signature,
- gboolean is_html)
-{
- g_return_if_fail (E_IS_SIGNATURE (signature));
-
- if (signature->priv->is_html == is_html)
- return;
-
- signature->priv->is_html = is_html;
-
- g_object_notify (G_OBJECT (signature), "is-html");
-}
-
-gboolean
-e_signature_get_is_script (ESignature *signature)
-{
- g_return_val_if_fail (E_IS_SIGNATURE (signature), FALSE);
-
- /* Autogenerated flags overrides the is-script property. */
- if (e_signature_get_autogenerated (signature))
- return FALSE;
-
- return signature->priv->is_script;
-}
-
-void
-e_signature_set_is_script (ESignature *signature,
- gboolean is_script)
-{
- g_return_if_fail (E_IS_SIGNATURE (signature));
-
- if (signature->priv->is_script == is_script)
- return;
-
- signature->priv->is_script = is_script;
-
- g_object_notify (G_OBJECT (signature), "is-script");
-}
-
-const gchar *
-e_signature_get_name (ESignature *signature)
-{
- g_return_val_if_fail (E_IS_SIGNATURE (signature), NULL);
-
- /* Autogenerated flag overrides the name property. */
- if (e_signature_get_autogenerated (signature))
- return _("Autogenerated");
-
- return signature->priv->name;
-}
-
-void
-e_signature_set_name (ESignature *signature,
- const gchar *name)
-{
- g_return_if_fail (E_IS_SIGNATURE (signature));
-
- g_free (signature->priv->name);
- signature->priv->name = g_strdup (name);
-
- g_object_notify (G_OBJECT (signature), "name");
-}
-
-const gchar *
-e_signature_get_uid (ESignature *signature)
-{
- g_return_val_if_fail (E_IS_SIGNATURE (signature), NULL);
-
- return signature->priv->uid;
-}
-
-void
-e_signature_set_uid (ESignature *signature,
- const gchar *uid)
-{
- g_return_if_fail (E_IS_SIGNATURE (signature));
-
- g_free (signature->priv->uid);
-
- if (uid == NULL)
- signature->priv->uid = e_uid_new ();
- else
- signature->priv->uid = g_strdup (uid);
-
- g_object_notify (G_OBJECT (signature), "uid");
-}
diff --git a/libemail-utils/e-signature.h b/libemail-utils/e-signature.h
deleted file mode 100644
index fad1faffa3..0000000000
--- a/libemail-utils/e-signature.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- *
- * 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 <http://www.gnu.org/licenses/>
- *
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef E_SIGNATURE_H
-#define E_SIGNATURE_H
-
-#include <glib-object.h>
-
-/* Standard GObject macros */
-#define E_TYPE_SIGNATURE \
- (e_signature_get_type ())
-#define E_SIGNATURE(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST \
- ((obj), E_TYPE_SIGNATURE, ESignature))
-#define E_SIGNATURE_CLASS(cls) \
- (G_TYPE_CHECK_CLASS_CAST \
- ((cls), E_TYPE_SIGNATURE, ESignatureClass))
-#define E_IS_SIGNATURE(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE \
- ((obj), E_TYPE_SIGNATURE))
-#define E_IS_SIGNATURE_CLASS(cls) \
- (G_TYPE_CHECK_CLASS_TYPE \
- ((cls), E_TYPE_SIGNATURE))
-#define E_SIGNATURE_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS \
- ((obj), E_TYPE_SIGNATURE, ESignatureClass))
-
-G_BEGIN_DECLS
-
-typedef struct _ESignature ESignature;
-typedef struct _ESignatureClass ESignatureClass;
-typedef struct _ESignaturePrivate ESignaturePrivate;
-
-struct _ESignature {
- GObject parent;
- ESignaturePrivate *priv;
-};
-
-struct _ESignatureClass {
- GObjectClass parent_class;
-};
-
-GType e_signature_get_type (void);
-ESignature * e_signature_new (void);
-ESignature * e_signature_new_from_xml (const gchar *xml);
-gchar * e_signature_uid_from_xml (const gchar *xml);
-gboolean e_signature_set_from_xml (ESignature *signature,
- const gchar *xml);
-gchar * e_signature_to_xml (ESignature *signature);
-gboolean e_signature_is_equal (ESignature *signature1,
- ESignature *signature2);
-gboolean e_signature_get_autogenerated (ESignature *signature);
-void e_signature_set_autogenerated (ESignature *signature,
- gboolean autogenerated);
-const gchar * e_signature_get_filename (ESignature *signature);
-void e_signature_set_filename (ESignature *signature,
- const gchar *filename);
-gboolean e_signature_get_is_html (ESignature *signature);
-void e_signature_set_is_html (ESignature *signature,
- gboolean is_html);
-gboolean e_signature_get_is_script (ESignature *signature);
-void e_signature_set_is_script (ESignature *signature,
- gboolean is_script);
-const gchar * e_signature_get_name (ESignature *signature);
-void e_signature_set_name (ESignature *signature,
- const gchar *name);
-const gchar * e_signature_get_uid (ESignature *signature);
-void e_signature_set_uid (ESignature *signature,
- const gchar *uid);
-
-G_END_DECLS
-
-#endif /* E_SIGNATURE_H */
diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am
index c09a78f70c..bb3c662d5c 100644
--- a/widgets/misc/Makefile.am
+++ b/widgets/misc/Makefile.am
@@ -5,7 +5,6 @@ widgetsincludedir = $(privincludedir)/misc
ui_DATA = e-send-options.ui
widgetsinclude_HEADERS = \
- e-account-combo-box.h \
e-action-combo-box.h \
e-activity-bar.h \
e-activity-proxy.h \
@@ -38,6 +37,9 @@ widgetsinclude_HEADERS = \
e-image-chooser.h \
e-import-assistant.h \
e-interval-chooser.h \
+ e-mail-account-manager.h \
+ e-mail-account-tree-view.h \
+ e-mail-identity-combo-box.h \
e-map.h \
e-menu-tool-action.h \
e-menu-tool-button.h \
@@ -93,7 +95,6 @@ libemiscwidgets_la_CPPFLAGS = \
libemiscwidgets_la_SOURCES = \
$(widgetsinclude_HEADERS) \
- e-account-combo-box.c \
e-action-combo-box.c \
e-activity-bar.c \
e-activity-proxy.c \
@@ -126,6 +127,9 @@ libemiscwidgets_la_SOURCES = \
e-image-chooser.c \
e-import-assistant.c \
e-interval-chooser.c \
+ e-mail-account-manager.c \
+ e-mail-account-tree-view.c \
+ e-mail-identity-combo-box.c \
e-map.c \
e-menu-tool-action.c \
e-menu-tool-button.c \
diff --git a/widgets/misc/e-account-combo-box.c b/widgets/misc/e-account-combo-box.c
deleted file mode 100644
index 9c750f9ec4..0000000000
--- a/widgets/misc/e-account-combo-box.c
+++ /dev/null
@@ -1,514 +0,0 @@
-/*
- * e-account-combo-box.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 <http://www.gnu.org/licenses/>
- *
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "e-account-combo-box.h"
-
-#include <string.h>
-
-#define E_ACCOUNT_COMBO_BOX_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE \
- ((obj), E_TYPE_ACCOUNT_COMBO_BOX, EAccountComboBoxPrivate))
-
-enum {
- COLUMN_STRING,
- COLUMN_ACCOUNT
-};
-
-enum {
- REFRESHED,
- LAST_SIGNAL
-};
-
-struct _EAccountComboBoxPrivate {
- EAccountList *account_list;
- GHashTable *index;
- gint num_displayed_accounts;
-};
-
-static CamelSession *camel_session;
-static guint signal_ids[LAST_SIGNAL];
-
-G_DEFINE_TYPE (
- EAccountComboBox,
- e_account_combo_box,
- GTK_TYPE_COMBO_BOX)
-
-static gboolean
-account_combo_box_has_dupes (GList *list,
- const gchar *address)
-{
- GList *iter;
- guint count = 0;
-
- /* Look for duplicates of the given email address. */
- for (iter = list; iter != NULL; iter = iter->next) {
- EAccount *account = iter->data;
-
- if (g_ascii_strcasecmp (account->id->address, address) == 0)
- count++;
- }
-
- return (count > 1);
-}
-
-static EAccount *
-account_combo_box_choose_account (EAccountComboBox *combo_box)
-{
- EAccountList *account_list;
- EAccount *account;
- GtkTreeModel *model;
- GtkTreeIter iter;
-
- account_list = e_account_combo_box_get_account_list (combo_box);
- g_return_val_if_fail (account_list != NULL, NULL);
-
- /* First try the default account. */
-
- /* XXX EAccountList misuses const. */
- account = (EAccount *)
- e_account_list_get_default (account_list);
-
- /* If there is no default account, give up. */
- if (account == NULL)
- return NULL;
-
- /* Make sure the default account appears in the combo box. */
- if (g_hash_table_lookup (combo_box->priv->index, account) != NULL)
- return account;
-
- /* Default account is disabled or otherwise unusable,
- * so fall back to the first account in the combo box. */
-
- model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box));
-
- if (!gtk_tree_model_get_iter_first (model, &iter))
- return NULL;
-
- gtk_tree_model_get (model, &iter, COLUMN_ACCOUNT, &account, -1);
-
- return account;
-}
-
-static gboolean
-account_combo_box_test_account (EAccount *account)
-{
- CamelService *service;
- gboolean writable = FALSE;
-
- /* Account must be enabled. */
- if (!account->enabled)
- return FALSE;
-
- /* Account must have a non-empty email address. */
- if (account->id->address == NULL || *account->id->address == '\0')
- return FALSE;
-
- /* XXX Not sure I understand this part. */
- if (account->parent_uid == NULL)
- return TRUE;
-
- /* Account must be writable. */
- service = camel_session_get_service (camel_session, account->uid);
- if (CAMEL_IS_STORE (service)) {
- CamelStore *store = CAMEL_STORE (service);
- writable = (store->mode & CAMEL_STORE_WRITE);
- }
-
- return writable;
-}
-
-static void
-account_combo_box_refresh_cb (EAccountList *account_list,
- EAccount *unused,
- EAccountComboBox *combo_box)
-{
- GtkListStore *store;
- GtkTreeModel *model;
- EIterator *account_iter;
- EAccount *account;
- GHashTable *index;
- GList *list = NULL;
- GList *iter;
-
- combo_box->priv->num_displayed_accounts = 0;
-
- store = gtk_list_store_new (2, G_TYPE_STRING, E_TYPE_ACCOUNT);
- model = GTK_TREE_MODEL (store);
- index = combo_box->priv->index;
-
- g_hash_table_remove_all (index);
-
- if (account_list == NULL)
- goto skip;
-
- /* Build a list of EAccounts to display. */
- account_iter = e_list_get_iterator (E_LIST (account_list));
- while (e_iterator_is_valid (account_iter)) {
- EAccount *account;
-
- /* XXX EIterator misuses const. */
- account = (EAccount *) e_iterator_get (account_iter);
- if (account_combo_box_test_account (account))
- list = g_list_prepend (list, account);
- e_iterator_next (account_iter);
- }
- g_object_unref (account_iter);
-
- list = g_list_reverse (list);
-
- /* Populate the list store and index. */
- for (iter = list; iter != NULL; iter = iter->next) {
- GtkTreeRowReference *reference;
- GtkTreeIter tree_iter;
- GtkTreePath *path;
- gchar *string;
-
- account = iter->data;
- combo_box->priv->num_displayed_accounts++;
-
- /* Show the account name for duplicate email addresses. */
- if (account_combo_box_has_dupes (list, account->id->address))
- string = g_strdup_printf (
- "%s <%s> (%s)",
- account->id->name,
- account->id->address,
- account->name);
- else
- string = g_strdup_printf (
- "%s <%s>",
- account->id->name,
- account->id->address);
-
- gtk_list_store_append (store, &tree_iter);
- gtk_list_store_set (
- store, &tree_iter,
- COLUMN_STRING, string,
- COLUMN_ACCOUNT, account, -1);
-
- path = gtk_tree_model_get_path (model, &tree_iter);
- reference = gtk_tree_row_reference_new (model, path);
- g_hash_table_insert (index, account, reference);
- gtk_tree_path_free (path);
-
- g_free (string);
- }
-
- g_list_free (list);
-
-skip:
- /* Restore the previously selected account. */
- account = e_account_combo_box_get_active (combo_box);
- if (account != NULL)
- g_object_ref (account);
- gtk_combo_box_set_model (GTK_COMBO_BOX (combo_box), model);
- e_account_combo_box_set_active (combo_box, account);
- if (account != NULL)
- g_object_unref (account);
-
- g_signal_emit (combo_box, signal_ids[REFRESHED], 0);
-}
-
-static GObject *
-account_combo_box_constructor (GType type,
- guint n_construct_properties,
- GObjectConstructParam *construct_properties)
-{
- GObject *object;
- GObjectClass *parent_class;
- GtkCellRenderer *renderer;
-
- /* Chain up to parent's constructor() method. */
- parent_class = G_OBJECT_CLASS (e_account_combo_box_parent_class);
- object = parent_class->constructor (
- type, n_construct_properties, construct_properties);
-
- renderer = gtk_cell_renderer_text_new ();
-
- gtk_cell_layout_pack_start (
- GTK_CELL_LAYOUT (object), renderer, TRUE);
- gtk_cell_layout_add_attribute (
- GTK_CELL_LAYOUT (object), renderer, "text", COLUMN_STRING);
-
- return object;
-}
-
-static void
-account_combo_box_dispose (GObject *object)
-{
- EAccountComboBoxPrivate *priv;
-
- priv = E_ACCOUNT_COMBO_BOX_GET_PRIVATE (object);
-
- if (priv->account_list != NULL) {
- g_signal_handlers_disconnect_by_func (
- priv->account_list,
- account_combo_box_refresh_cb, object);
- g_object_unref (priv->account_list);
- priv->account_list = NULL;
- }
-
- g_hash_table_remove_all (priv->index);
-
- /* Chain up to parent's dispose() method. */
- G_OBJECT_CLASS (e_account_combo_box_parent_class)->dispose (object);
-}
-
-static void
-account_combo_box_finalize (GObject *object)
-{
- EAccountComboBoxPrivate *priv;
-
- priv = E_ACCOUNT_COMBO_BOX_GET_PRIVATE (object);
-
- g_hash_table_destroy (priv->index);
-
- /* Chain up to parent's finalize() method. */
- G_OBJECT_CLASS (e_account_combo_box_parent_class)->finalize (object);
-}
-
-static void
-e_account_combo_box_class_init (EAccountComboBoxClass *class)
-{
- GObjectClass *object_class;
-
- g_type_class_add_private (class, sizeof (EAccountComboBoxPrivate));
-
- object_class = G_OBJECT_CLASS (class);
- object_class->constructor = account_combo_box_constructor;
- object_class->dispose = account_combo_box_dispose;
- object_class->finalize = account_combo_box_finalize;
-
- signal_ids[REFRESHED] = g_signal_new (
- "refreshed",
- G_TYPE_FROM_CLASS (class),
- G_SIGNAL_RUN_LAST,
- 0, NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-}
-
-static void
-e_account_combo_box_init (EAccountComboBox *combo_box)
-{
- GHashTable *index;
-
- /* Reverse-lookup index */
- index = g_hash_table_new_full (
- g_direct_hash, g_direct_equal,
- (GDestroyNotify) g_object_unref,
- (GDestroyNotify) gtk_tree_row_reference_free);
-
- combo_box->priv = E_ACCOUNT_COMBO_BOX_GET_PRIVATE (combo_box);
- combo_box->priv->index = index;
-}
-
-GtkWidget *
-e_account_combo_box_new (void)
-{
- return g_object_new (E_TYPE_ACCOUNT_COMBO_BOX, NULL);
-}
-
-void
-e_account_combo_box_set_session (CamelSession *session)
-{
- /* XXX Really gross hack.
- *
- * We need a CamelSession to test whether a given EAccount is
- * writable. The global CamelSession object is defined in the
- * mailer, but we're too far down the stack to access it. So
- * we have to rely on someone passing us a reference to it.
- *
- * A much cleaner solution would be to store the writeability
- * of an account directly into the EAccount, but this would likely
- * require breaking ABI and all the fun that goes along with that.
- */
-
- camel_session = session;
-}
-
-EAccountList *
-e_account_combo_box_get_account_list (EAccountComboBox *combo_box)
-{
- g_return_val_if_fail (E_IS_ACCOUNT_COMBO_BOX (combo_box), NULL);
-
- return combo_box->priv->account_list;
-}
-
-void
-e_account_combo_box_set_account_list (EAccountComboBox *combo_box,
- EAccountList *account_list)
-{
- EAccountComboBoxPrivate *priv;
-
- g_return_if_fail (E_IS_ACCOUNT_COMBO_BOX (combo_box));
-
- if (account_list != NULL)
- g_return_if_fail (E_IS_ACCOUNT_LIST (account_list));
-
- priv = E_ACCOUNT_COMBO_BOX_GET_PRIVATE (combo_box);
-
- if (priv->account_list != NULL) {
- g_signal_handlers_disconnect_by_func (
- priv->account_list,
- account_combo_box_refresh_cb, combo_box);
- g_object_unref (priv->account_list);
- priv->account_list = NULL;
- }
-
- if (account_list != NULL) {
- priv->account_list = g_object_ref (account_list);
-
- /* Listen for changes to the account list. */
- g_signal_connect (
- priv->account_list, "account-added",
- G_CALLBACK (account_combo_box_refresh_cb), combo_box);
- g_signal_connect (
- priv->account_list, "account-changed",
- G_CALLBACK (account_combo_box_refresh_cb), combo_box);
- g_signal_connect (
- priv->account_list, "account-removed",
- G_CALLBACK (account_combo_box_refresh_cb), combo_box);
- }
-
- account_combo_box_refresh_cb (account_list, NULL, combo_box);
-}
-
-EAccount *
-e_account_combo_box_get_active (EAccountComboBox *combo_box)
-{
- EAccount *account;
- GtkTreeModel *model;
- GtkTreeIter iter;
- gboolean iter_set;
-
- g_return_val_if_fail (E_IS_ACCOUNT_COMBO_BOX (combo_box), NULL);
-
- iter_set = gtk_combo_box_get_active_iter (
- GTK_COMBO_BOX (combo_box), &iter);
- if (!iter_set)
- return NULL;
-
- model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box));
- gtk_tree_model_get (model, &iter, COLUMN_ACCOUNT, &account, -1);
-
- return account;
-}
-
-gboolean
-e_account_combo_box_set_active (EAccountComboBox *combo_box,
- EAccount *account)
-{
- EAccountList *account_list;
- GtkTreeRowReference *reference;
- GtkTreeModel *model;
- GtkTreePath *path;
- GtkTreeIter iter;
- gboolean iter_set;
-
- g_return_val_if_fail (E_IS_ACCOUNT_COMBO_BOX (combo_box), FALSE);
-
- if (account != NULL)
- g_return_val_if_fail (E_IS_ACCOUNT (account), FALSE);
-
- account_list = combo_box->priv->account_list;
- g_return_val_if_fail (account_list != NULL, FALSE);
-
- /* NULL means choose an account ourselves. */
- if (account == NULL)
- account = account_combo_box_choose_account (combo_box);
-
- if (account == NULL)
- return FALSE;
-
- /* Lookup the tree row reference for the account. */
- reference = g_hash_table_lookup (combo_box->priv->index, account);
- if (reference == NULL)
- return FALSE;
-
- /* Convert the reference to a tree iterator. */
- path = gtk_tree_row_reference_get_path (reference);
- model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box));
- iter_set = gtk_tree_model_get_iter (model, &iter, path);
- gtk_tree_path_free (path);
-
- if (!iter_set)
- return FALSE;
-
- /* Activate the corresponding combo box item. */
- gtk_combo_box_set_active_iter (GTK_COMBO_BOX (combo_box), &iter);
-
- return TRUE;
-}
-
-const gchar *
-e_account_combo_box_get_active_name (EAccountComboBox *combo_box)
-{
- EAccount *account;
-
- g_return_val_if_fail (E_IS_ACCOUNT_COMBO_BOX (combo_box), NULL);
-
- account = e_account_combo_box_get_active (combo_box);
- return (account != NULL) ? account->name : NULL;
-}
-
-gboolean
-e_account_combo_box_set_active_name (EAccountComboBox *combo_box,
- const gchar *account_name)
-{
- EAccountList *account_list;
- EAccount *account;
-
- g_return_val_if_fail (E_IS_ACCOUNT_COMBO_BOX (combo_box), FALSE);
-
- account_list = combo_box->priv->account_list;
- g_return_val_if_fail (account_list != NULL, FALSE);
-
- /* XXX EAccountList misuses const. */
- account = (EAccount *) e_account_list_find (
- account_list, E_ACCOUNT_FIND_NAME, account_name);
-
- if (account == NULL)
- return FALSE;
-
- return e_account_combo_box_set_active (combo_box, account);
-}
-
-/**
- * e_account_combo_box_count_displayed_accounts:
- * @combo_box: an #EAccountComboBox
- *
- * Counts the number of accounts that are displayed in the @combo_box. This may not
- * be the actual number of accounts that are configured, as some of those accounts
- * may be disabled by the user.
- *
- * Return value: number of active and valid accounts as shown in the @combo_box.
- */
-gint
-e_account_combo_box_count_displayed_accounts (EAccountComboBox *combo_box)
-{
- g_return_val_if_fail (E_IS_ACCOUNT_COMBO_BOX (combo_box), -1);
-
- return combo_box->priv->num_displayed_accounts;
-}
diff --git a/widgets/misc/e-account-combo-box.h b/widgets/misc/e-account-combo-box.h
deleted file mode 100644
index aa29c97306..0000000000
--- a/widgets/misc/e-account-combo-box.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * e-account-combo-box.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 <http://www.gnu.org/licenses/>
- *
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef E_ACCOUNT_COMBO_BOX_H
-#define E_ACCOUNT_COMBO_BOX_H
-
-#include <gtk/gtk.h>
-#include <camel/camel.h>
-#include <libedataserver/e-account.h>
-#include <libedataserver/e-account-list.h>
-
-/* Standard GObject macros */
-#define E_TYPE_ACCOUNT_COMBO_BOX \
- (e_account_combo_box_get_type ())
-#define E_ACCOUNT_COMBO_BOX(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST \
- ((obj), E_TYPE_ACCOUNT_COMBO_BOX, EAccountComboBox))
-#define E_ACCOUNT_COMBO_BOX_CLASS(cls) \
- (G_TYPE_CHECK_CLASS_CAST \
- ((cls), E_TYPE_ACCOUNT_COMBO_BOX, EAccountComboBoxClass))
-#define E_IS_ACCOUNT_COMBO_BOX(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE \
- ((obj), E_TYPE_ACCOUNT_COMBO_BOX))
-#define E_IS_ACCOUNT_COMBO_BOX_CLASS(cls) \
- (G_TYPE_CHECK_CLASS_TYPE \
- ((cls), E_TYPE_ACCOUNT_COMBO_BOX))
-#define E_ACCOUNT_COMBO_BOX_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS \
- ((obj), E_TYPE_ACCOUNT_COMBO_BOX, EAccountComboBoxClass))
-
-G_BEGIN_DECLS
-
-typedef struct _EAccountComboBox EAccountComboBox;
-typedef struct _EAccountComboBoxClass EAccountComboBoxClass;
-typedef struct _EAccountComboBoxPrivate EAccountComboBoxPrivate;
-
-struct _EAccountComboBox {
- GtkComboBox parent;
- EAccountComboBoxPrivate *priv;
-};
-
-struct _EAccountComboBoxClass {
- GtkComboBoxClass parent_class;
-};
-
-GType e_account_combo_box_get_type (void);
-GtkWidget * e_account_combo_box_new (void);
-void e_account_combo_box_set_session (CamelSession *session);
-EAccountList * e_account_combo_box_get_account_list
- (EAccountComboBox *combo_box);
-void e_account_combo_box_set_account_list
- (EAccountComboBox *combo_box,
- EAccountList *account_list);
-EAccount * e_account_combo_box_get_active (EAccountComboBox *combo_box);
-gboolean e_account_combo_box_set_active (EAccountComboBox *combo_box,
- EAccount *account);
-const gchar * e_account_combo_box_get_active_name
- (EAccountComboBox *combo_box);
-gboolean e_account_combo_box_set_active_name
- (EAccountComboBox *combo_box,
- const gchar *account_name);
-gint e_account_combo_box_count_displayed_accounts
- (EAccountComboBox *combo_box);
-
-G_END_DECLS
-
-#endif /* E_ACCOUNT_COMBO_BOX_H */
diff --git a/widgets/misc/e-mail-account-manager.c b/widgets/misc/e-mail-account-manager.c
new file mode 100644
index 0000000000..fd5e999a90
--- /dev/null
+++ b/widgets/misc/e-mail-account-manager.c
@@ -0,0 +1,384 @@
+/*
+ * e-mail-account-manager.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 <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "e-mail-account-manager.h"
+
+#include <config.h>
+#include <glib/gi18n-lib.h>
+#include <gdk/gdkkeysyms.h>
+
+#include "e-mail-account-tree-view.h"
+
+#define E_MAIL_ACCOUNT_MANAGER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAIL_ACCOUNT_MANAGER, EMailAccountManagerPrivate))
+
+struct _EMailAccountManagerPrivate {
+ ESourceRegistry *registry;
+
+ GtkWidget *tree_view; /* not referenced */
+ GtkWidget *add_button; /* not referenced */
+ GtkWidget *edit_button; /* not referenced */
+ GtkWidget *delete_button; /* not referenced */
+ GtkWidget *default_button; /* not referenced */
+};
+
+enum {
+ PROP_0,
+ PROP_REGISTRY
+};
+
+enum {
+ ADD_ACCOUNT,
+ EDIT_ACCOUNT,
+ DELETE_ACCOUNT,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
+G_DEFINE_TYPE (
+ EMailAccountManager,
+ e_mail_account_manager,
+ GTK_TYPE_TABLE)
+
+static gboolean
+mail_account_manager_key_press_event_cb (EMailAccountManager *manager,
+ GdkEventKey *event)
+{
+ if (event->keyval == GDK_KEY_Delete) {
+ e_mail_account_manager_delete_account (manager);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+mail_account_manager_selection_changed_cb (EMailAccountManager *manager,
+ GtkTreeSelection *selection)
+{
+ EMailAccountTreeView *tree_view;
+ ESourceRegistry *registry;
+ ESource *default_source;
+ ESource *source;
+ GtkWidget *add_button;
+ GtkWidget *edit_button;
+ GtkWidget *delete_button;
+ GtkWidget *default_button;
+ gboolean sensitive;
+
+ add_button = manager->priv->add_button;
+ edit_button = manager->priv->edit_button;
+ delete_button = manager->priv->delete_button;
+ default_button = manager->priv->default_button;
+
+ registry = e_mail_account_manager_get_registry (manager);
+ tree_view = E_MAIL_ACCOUNT_TREE_VIEW (manager->priv->tree_view);
+
+ source = e_mail_account_tree_view_get_selected_source (tree_view);
+ default_source = e_source_registry_get_default_mail_account (registry);
+
+ if (source == NULL)
+ gtk_widget_grab_focus (add_button);
+
+ sensitive = (source != NULL);
+ gtk_widget_set_sensitive (edit_button, sensitive);
+
+ sensitive = (source != NULL);
+ gtk_widget_set_sensitive (delete_button, sensitive);
+
+ sensitive = (source != NULL && source != default_source);
+ gtk_widget_set_sensitive (default_button, sensitive);
+}
+
+static void
+mail_account_manager_set_registry (EMailAccountManager *manager,
+ ESourceRegistry *registry)
+{
+ g_return_if_fail (E_IS_SOURCE_REGISTRY (registry));
+ g_return_if_fail (manager->priv->registry == NULL);
+
+ manager->priv->registry = g_object_ref (registry);
+}
+
+static void
+mail_account_manager_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_REGISTRY:
+ mail_account_manager_set_registry (
+ E_MAIL_ACCOUNT_MANAGER (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_account_manager_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_REGISTRY:
+ g_value_set_object (
+ value,
+ e_mail_account_manager_get_registry (
+ E_MAIL_ACCOUNT_MANAGER (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_account_manager_dispose (GObject *object)
+{
+ EMailAccountManagerPrivate *priv;
+
+ priv = E_MAIL_ACCOUNT_MANAGER_GET_PRIVATE (object);
+
+ if (priv->registry != NULL) {
+ g_object_unref (priv->registry);
+ priv->registry = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (e_mail_account_manager_parent_class)->dispose (object);
+}
+
+static void
+mail_account_manager_constructed (GObject *object)
+{
+ EMailAccountManager *manager;
+ ESourceRegistry *registry;
+ GtkTreeSelection *selection;
+ GtkWidget *container;
+ GtkWidget *widget;
+
+ manager = E_MAIL_ACCOUNT_MANAGER (object);
+ registry = e_mail_account_manager_get_registry (manager);
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (e_mail_account_manager_parent_class)->
+ constructed (object);
+
+ gtk_table_resize (GTK_TABLE (manager), 1, 2);
+ gtk_table_set_col_spacings (GTK_TABLE (manager), 6);
+ gtk_table_set_row_spacings (GTK_TABLE (manager), 12);
+
+ container = GTK_WIDGET (manager);
+
+ widget = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (
+ GTK_SCROLLED_WINDOW (widget),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (
+ GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN);
+ gtk_table_attach (
+ GTK_TABLE (container), widget, 0, 1, 0, 1,
+ GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ widget = e_mail_account_tree_view_new (registry);
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ manager->priv->tree_view = widget; /* not referenced */
+ gtk_widget_show (widget);
+
+ g_signal_connect_swapped (
+ widget, "key-press-event",
+ G_CALLBACK (mail_account_manager_key_press_event_cb),
+ manager);
+
+ g_signal_connect_swapped (
+ widget, "row-activated",
+ G_CALLBACK (e_mail_account_manager_edit_account),
+ manager);
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
+
+ g_signal_connect_swapped (
+ selection, "changed",
+ G_CALLBACK (mail_account_manager_selection_changed_cb),
+ manager);
+
+ container = GTK_WIDGET (manager);
+
+ widget = gtk_vbutton_box_new ();
+ gtk_button_box_set_layout (
+ GTK_BUTTON_BOX (widget), GTK_BUTTONBOX_START);
+ gtk_box_set_spacing (GTK_BOX (widget), 6);
+ gtk_table_attach (
+ GTK_TABLE (container), widget,
+ 1, 2, 0, 2, 0, GTK_FILL, 0, 0);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ widget = gtk_button_new_from_stock (GTK_STOCK_ADD);
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ manager->priv->add_button = widget; /* not referenced */
+ gtk_widget_show (widget);
+
+ g_signal_connect_swapped (
+ widget, "clicked",
+ G_CALLBACK (e_mail_account_manager_add_account), manager);
+
+ widget = gtk_button_new_from_stock (GTK_STOCK_EDIT);
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ manager->priv->edit_button = widget; /* not referenced */
+ gtk_widget_show (widget);
+
+ g_signal_connect_swapped (
+ widget, "clicked",
+ G_CALLBACK (e_mail_account_manager_edit_account), manager);
+
+ widget = gtk_button_new_from_stock (GTK_STOCK_DELETE);
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ manager->priv->delete_button = widget; /* not referenced */
+ gtk_widget_show (widget);
+
+ g_signal_connect_swapped (
+ widget, "clicked",
+ G_CALLBACK (e_mail_account_manager_delete_account), manager);
+
+ widget = gtk_button_new_with_mnemonic (_("De_fault"));
+ gtk_button_set_image (
+ GTK_BUTTON (widget),
+ gtk_image_new_from_icon_name (
+ "emblem-default", GTK_ICON_SIZE_BUTTON));
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ manager->priv->default_button = widget; /* not referenced */
+ gtk_widget_show (widget);
+
+ g_signal_connect_swapped (
+ widget, "clicked",
+ G_CALLBACK (e_mail_account_tree_view_enable_selected),
+ manager->priv->tree_view);
+}
+
+static void
+e_mail_account_manager_class_init (EMailAccountManagerClass *class)
+{
+ GObjectClass *object_class;
+
+ g_type_class_add_private (class, sizeof (EMailAccountManagerPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = mail_account_manager_set_property;
+ object_class->get_property = mail_account_manager_get_property;
+ object_class->dispose = mail_account_manager_dispose;
+ object_class->constructed = mail_account_manager_constructed;
+
+ /* XXX If we moved the account editor to /widgets/misc we
+ * could handle adding and editing accounts directly. */
+
+ g_object_class_install_property (
+ object_class,
+ PROP_REGISTRY,
+ g_param_spec_object (
+ "registry",
+ "Registry",
+ NULL,
+ E_TYPE_SOURCE_REGISTRY,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ signals[ADD_ACCOUNT] = g_signal_new (
+ "add-account",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMailAccountManagerClass, add_account),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[EDIT_ACCOUNT] = g_signal_new (
+ "edit-account",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMailAccountManagerClass, edit_account),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[DELETE_ACCOUNT] = g_signal_new (
+ "delete-account",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMailAccountManagerClass, delete_account),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+static void
+e_mail_account_manager_init (EMailAccountManager *manager)
+{
+ manager->priv = E_MAIL_ACCOUNT_MANAGER_GET_PRIVATE (manager);
+}
+
+GtkWidget *
+e_mail_account_manager_new (ESourceRegistry *registry)
+{
+ g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
+
+ return g_object_new (
+ E_TYPE_MAIL_ACCOUNT_MANAGER,
+ "registry", registry, NULL);
+}
+
+void
+e_mail_account_manager_add_account (EMailAccountManager *manager)
+{
+ g_return_if_fail (E_IS_MAIL_ACCOUNT_MANAGER (manager));
+
+ g_signal_emit (manager, signals[ADD_ACCOUNT], 0);
+}
+
+void
+e_mail_account_manager_edit_account (EMailAccountManager *manager)
+{
+ g_return_if_fail (E_IS_MAIL_ACCOUNT_MANAGER (manager));
+
+ g_signal_emit (manager, signals[EDIT_ACCOUNT], 0);
+}
+
+void
+e_mail_account_manager_delete_account (EMailAccountManager *manager)
+{
+ g_return_if_fail (E_IS_MAIL_ACCOUNT_MANAGER (manager));
+
+ g_signal_emit (manager, signals[DELETE_ACCOUNT], 0);
+}
+
+ESourceRegistry *
+e_mail_account_manager_get_registry (EMailAccountManager *manager)
+{
+ g_return_val_if_fail (E_IS_MAIL_ACCOUNT_MANAGER (manager), NULL);
+
+ return manager->priv->registry;
+}
diff --git a/widgets/misc/e-mail-account-manager.h b/widgets/misc/e-mail-account-manager.h
new file mode 100644
index 0000000000..4afbe7052d
--- /dev/null
+++ b/widgets/misc/e-mail-account-manager.h
@@ -0,0 +1,77 @@
+/*
+ * e-mail-account-manager.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 <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef E_MAIL_ACCOUNT_MANAGER_H
+#define E_MAIL_ACCOUNT_MANAGER_H
+
+#include <gtk/gtk.h>
+#include <libedataserver/e-source-registry.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_ACCOUNT_MANAGER \
+ (e_mail_account_manager_get_type ())
+#define E_MAIL_ACCOUNT_MANAGER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_ACCOUNT_MANAGER, EMailAccountManager))
+#define E_MAIL_ACCOUNT_MANAGER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_ACCOUNT_MANAGER, EMailAccountManagerClass))
+#define E_IS_MAIL_ACCOUNT_MANAGER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_ACCOUNT_MANAGER))
+#define E_IS_MAIL_ACCOUNT_MANAGER_CLASS(cls) \
+ (G_TYPE_CHECK_INSTANCE_CLASS \
+ ((cls), E_TYPE_MAIL_ACCOUNT_MANAGER))
+#define E_MAIL_ACCOUNT_MANAGER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_ACCOUNT_MANAGER, EMailAccountManagerClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailAccountManager EMailAccountManager;
+typedef struct _EMailAccountManagerClass EMailAccountManagerClass;
+typedef struct _EMailAccountManagerPrivate EMailAccountManagerPrivate;
+
+struct _EMailAccountManager {
+ GtkTable parent;
+ EMailAccountManagerPrivate *priv;
+};
+
+struct _EMailAccountManagerClass {
+ GtkTableClass parent_class;
+
+ void (*add_account) (EMailAccountManager *manager);
+ void (*edit_account) (EMailAccountManager *manager);
+ void (*delete_account) (EMailAccountManager *manager);
+};
+
+GType e_mail_account_manager_get_type (void) G_GNUC_CONST;
+GtkWidget * e_mail_account_manager_new (ESourceRegistry *registry);
+void e_mail_account_manager_add_account
+ (EMailAccountManager *manager);
+void e_mail_account_manager_edit_account
+ (EMailAccountManager *manager);
+void e_mail_account_manager_delete_account
+ (EMailAccountManager *manager);
+ESourceRegistry *
+ e_mail_account_manager_get_registry
+ (EMailAccountManager *manager);
+
+G_END_DECLS
+
+#endif /* E_MAIL_ACCOUNT_MANAGER_H */
diff --git a/widgets/misc/e-mail-account-tree-view.c b/widgets/misc/e-mail-account-tree-view.c
new file mode 100644
index 0000000000..45d6a0d72e
--- /dev/null
+++ b/widgets/misc/e-mail-account-tree-view.c
@@ -0,0 +1,575 @@
+/*
+ * e-mail-account-tree-view.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 <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "e-mail-account-tree-view.h"
+
+#include <config.h>
+#include <glib/gi18n-lib.h>
+
+#include <libedataserver/e-source-mail-account.h>
+
+#define E_MAIL_ACCOUNT_TREE_VIEW_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAIL_ACCOUNT_TREE_VIEW, EMailAccountTreeViewPrivate))
+
+#define SOURCE_IS_MAIL_ACCOUNT(source) \
+ (e_source_has_extension ((source), E_SOURCE_EXTENSION_MAIL_ACCOUNT))
+
+struct _EMailAccountTreeViewPrivate {
+ ESourceRegistry *registry;
+ guint refresh_idle_id;
+};
+
+enum {
+ PROP_0,
+ PROP_REGISTRY
+};
+
+enum {
+ ENABLE_SELECTED,
+ DISABLE_SELECTED,
+ LAST_SIGNAL
+};
+
+enum {
+ COLUMN_DISPLAY_NAME,
+ COLUMN_BACKEND_NAME,
+ COLUMN_DEFAULT,
+ COLUMN_ENABLED,
+ COLUMN_UID
+};
+
+static guint signals[LAST_SIGNAL];
+
+G_DEFINE_TYPE (
+ EMailAccountTreeView,
+ e_mail_account_tree_view,
+ GTK_TYPE_TREE_VIEW)
+
+static gboolean
+mail_account_tree_view_refresh_idle_cb (EMailAccountTreeView *tree_view)
+{
+ /* The refresh function will clear the idle ID. */
+ e_mail_account_tree_view_refresh (tree_view);
+
+ return FALSE;
+}
+
+static void
+mail_account_tree_view_registry_changed (ESourceRegistry *registry,
+ ESource *source,
+ EMailAccountTreeView *tree_view)
+{
+ /* If the ESource in question has a "Mail Account" extension,
+ * schedule a refresh of the tree model. Otherwise ignore it.
+ * We use an idle callback to limit how frequently we refresh
+ * the tree model, in case the registry is emitting lots of
+ * signals at once. */
+
+ if (!SOURCE_IS_MAIL_ACCOUNT (source))
+ return;
+
+ if (tree_view->priv->refresh_idle_id > 0)
+ return;
+
+ tree_view->priv->refresh_idle_id = gdk_threads_add_idle (
+ (GSourceFunc) mail_account_tree_view_refresh_idle_cb,
+ tree_view);
+}
+
+static void
+mail_account_tree_view_enabled_toggled_cb (GtkCellRendererToggle *cell_renderer,
+ const gchar *path_string,
+ EMailAccountTreeView *tree_view)
+{
+ GtkTreeSelection *selection;
+ GtkTreePath *path;
+
+ /* Chain the selection first so we enable or disable the
+ * correct account. */
+ path = gtk_tree_path_new_from_string (path_string);
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
+ gtk_tree_selection_select_path (selection, path);
+ gtk_tree_path_free (path);
+
+ if (gtk_cell_renderer_toggle_get_active (cell_renderer))
+ e_mail_account_tree_view_disable_selected (tree_view);
+ else
+ e_mail_account_tree_view_enable_selected (tree_view);
+}
+
+static void
+mail_account_tree_view_set_registry (EMailAccountTreeView *tree_view,
+ ESourceRegistry *registry)
+{
+ g_return_if_fail (E_IS_SOURCE_REGISTRY (registry));
+ g_return_if_fail (tree_view->priv->registry == NULL);
+
+ tree_view->priv->registry = g_object_ref (registry);
+
+ g_signal_connect (
+ registry, "source-added",
+ G_CALLBACK (mail_account_tree_view_registry_changed),
+ tree_view);
+
+ g_signal_connect (
+ registry, "source-changed",
+ G_CALLBACK (mail_account_tree_view_registry_changed),
+ tree_view);
+
+ g_signal_connect (
+ registry, "source-removed",
+ G_CALLBACK (mail_account_tree_view_registry_changed),
+ tree_view);
+}
+
+static void
+mail_account_tree_view_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_REGISTRY:
+ mail_account_tree_view_set_registry (
+ E_MAIL_ACCOUNT_TREE_VIEW (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_account_tree_view_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_REGISTRY:
+ g_value_set_object (
+ value,
+ e_mail_account_tree_view_get_registry (
+ E_MAIL_ACCOUNT_TREE_VIEW (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_account_tree_view_dispose (GObject *object)
+{
+ EMailAccountTreeViewPrivate *priv;
+
+ priv = E_MAIL_ACCOUNT_TREE_VIEW_GET_PRIVATE (object);
+
+ if (priv->registry != NULL) {
+ g_signal_handlers_disconnect_matched (
+ priv->registry, G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, object);
+ g_object_unref (priv->registry);
+ priv->registry = NULL;
+ }
+
+ if (priv->refresh_idle_id > 0) {
+ g_source_remove (priv->refresh_idle_id);
+ priv->refresh_idle_id = 0;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (e_mail_account_tree_view_parent_class)->
+ dispose (object);
+}
+
+static void
+mail_account_tree_view_constructed (GObject *object)
+{
+ GtkTreeView *tree_view;
+ GtkTreeViewColumn *column;
+ GtkCellRenderer *cell_renderer;
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (e_mail_account_tree_view_parent_class)->
+ constructed (object);
+
+ tree_view = GTK_TREE_VIEW (object);
+ gtk_tree_view_set_headers_visible (tree_view, TRUE);
+
+ /* Column: Enabled */
+
+ column = gtk_tree_view_column_new ();
+ gtk_tree_view_column_set_expand (column, FALSE);
+ gtk_tree_view_column_set_title (column, _("Enabled"));
+
+ cell_renderer = gtk_cell_renderer_toggle_new ();
+ gtk_tree_view_column_pack_start (column, cell_renderer, TRUE);
+
+ g_signal_connect (
+ cell_renderer, "toggled",
+ G_CALLBACK (mail_account_tree_view_enabled_toggled_cb),
+ tree_view);
+
+ gtk_tree_view_column_add_attribute (
+ column, cell_renderer, "active", COLUMN_ENABLED);
+
+ gtk_tree_view_append_column (tree_view, column);
+
+ /* Column: Account Name */
+
+ column = gtk_tree_view_column_new ();
+ gtk_tree_view_column_set_expand (column, TRUE);
+ gtk_tree_view_column_set_title (column, _("Account Name"));
+
+ cell_renderer = gtk_cell_renderer_text_new ();
+ g_object_set (cell_renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
+ gtk_tree_view_column_pack_start (column, cell_renderer, TRUE);
+
+ gtk_tree_view_column_add_attribute (
+ column, cell_renderer, "text", COLUMN_DISPLAY_NAME);
+
+ cell_renderer = gtk_cell_renderer_text_new ();
+ g_object_set (cell_renderer, "text", _("Default"), NULL);
+ gtk_tree_view_column_pack_end (column, cell_renderer, FALSE);
+
+ gtk_tree_view_column_add_attribute (
+ column, cell_renderer, "visible", COLUMN_DISPLAY_NAME);
+
+ cell_renderer = gtk_cell_renderer_pixbuf_new ();
+ g_object_set (
+ cell_renderer, "icon-name", "emblem-default",
+ "stock-size", GTK_ICON_SIZE_MENU, NULL);
+ gtk_tree_view_column_pack_end (column, cell_renderer, FALSE);
+
+ gtk_tree_view_column_add_attribute (
+ column, cell_renderer, "visible", COLUMN_DISPLAY_NAME);
+
+ gtk_tree_view_append_column (tree_view, column);
+
+ /* Column: Type */
+
+ column = gtk_tree_view_column_new ();
+ gtk_tree_view_column_set_expand (column, FALSE);
+ gtk_tree_view_column_set_title (column, _("Type"));
+
+ cell_renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_column_pack_start (column, cell_renderer, TRUE);
+
+ gtk_tree_view_column_add_attribute (
+ column, cell_renderer, "text", COLUMN_BACKEND_NAME);
+
+ gtk_tree_view_append_column (tree_view, column);
+
+ e_mail_account_tree_view_refresh (E_MAIL_ACCOUNT_TREE_VIEW (object));
+}
+
+static void
+mail_account_tree_view_enable_selected (EMailAccountTreeView *tree_view)
+{
+ ESource *source;
+ ESourceMailAccount *mail_account;
+ const gchar *extension_name;
+ GError *error = NULL;
+
+ source = e_mail_account_tree_view_get_selected_source (tree_view);
+
+ if (source == NULL)
+ return;
+
+ /* The source should already be a mail account. */
+ g_return_if_fail (SOURCE_IS_MAIL_ACCOUNT (source));
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+ mail_account = e_source_get_extension (source, extension_name);
+
+ /* Avoid unnecessary signal emissions and disk writes. */
+ if (e_source_mail_account_get_enabled (mail_account))
+ return;
+
+ e_source_mail_account_set_enabled (mail_account, TRUE);
+
+ if (!e_source_sync (source, &error)) {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+ }
+}
+
+static void
+mail_account_tree_view_disable_selected (EMailAccountTreeView *tree_view)
+{
+ ESource *source;
+ ESourceMailAccount *mail_account;
+ const gchar *extension_name;
+ GError *error = NULL;
+
+ source = e_mail_account_tree_view_get_selected_source (tree_view);
+
+ if (source == NULL)
+ return;
+
+ /* The source should already be a mail account. */
+ g_return_if_fail (SOURCE_IS_MAIL_ACCOUNT (source));
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+ mail_account = e_source_get_extension (source, extension_name);
+
+ /* Avoid unnecessary signal emissions and disk writes. */
+ if (!e_source_mail_account_get_enabled (mail_account))
+ return;
+
+ e_source_mail_account_set_enabled (mail_account, FALSE);
+
+ if (!e_source_sync (source, &error)) {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+ }
+}
+
+static void
+e_mail_account_tree_view_class_init (EMailAccountTreeViewClass *class)
+{
+ GObjectClass *object_class;
+
+ g_type_class_add_private (class, sizeof (EMailAccountTreeViewPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = mail_account_tree_view_set_property;
+ object_class->get_property = mail_account_tree_view_get_property;
+ object_class->dispose = mail_account_tree_view_dispose;
+ object_class->constructed = mail_account_tree_view_constructed;
+
+ class->enable_selected = mail_account_tree_view_enable_selected;
+ class->disable_selected = mail_account_tree_view_disable_selected;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_REGISTRY,
+ g_param_spec_object (
+ "registry",
+ "Registry",
+ NULL,
+ E_TYPE_SOURCE_REGISTRY,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
+ signals[ENABLE_SELECTED] = g_signal_new (
+ "enable-selected",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMailAccountTreeViewClass, enable_selected),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[DISABLE_SELECTED] = g_signal_new (
+ "disable-selected",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMailAccountTreeViewClass, disable_selected),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+static void
+e_mail_account_tree_view_init (EMailAccountTreeView *tree_view)
+{
+ tree_view->priv = E_MAIL_ACCOUNT_TREE_VIEW_GET_PRIVATE (tree_view);
+}
+
+GtkWidget *
+e_mail_account_tree_view_new (ESourceRegistry *registry)
+{
+ g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
+
+ return g_object_new (
+ E_TYPE_MAIL_ACCOUNT_TREE_VIEW,
+ "registry", registry, NULL);
+}
+
+void
+e_mail_account_tree_view_refresh (EMailAccountTreeView *tree_view)
+{
+ ESourceRegistry *registry;
+ GtkTreeModel *tree_model;
+ ESource *default_source;
+ ESource *source;
+ GList *list, *link;
+ const gchar *extension_name;
+ gchar *saved_uid = NULL;
+
+ g_return_if_fail (E_IS_MAIL_ACCOUNT_TREE_VIEW (tree_view));
+
+ if (tree_view->priv->refresh_idle_id > 0) {
+ g_source_remove (tree_view->priv->refresh_idle_id);
+ tree_view->priv->refresh_idle_id = 0;
+ }
+
+ registry = e_mail_account_tree_view_get_registry (tree_view);
+ tree_model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view));
+
+ source = e_mail_account_tree_view_get_selected_source (tree_view);
+ if (source != NULL)
+ saved_uid = g_strdup (e_source_get_uid (source));
+
+ default_source = e_source_registry_get_default_mail_account (registry);
+
+ gtk_list_store_clear (GTK_LIST_STORE (tree_model));
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+ list = e_source_registry_list_sources (registry, extension_name);
+
+ for (link = list; link != NULL; link = g_list_next (link)) {
+ ESourceMailAccount *mail_account;
+ GtkTreeIter iter;
+ const gchar *backend_name;
+ const gchar *display_name;
+ const gchar *uid;
+ gboolean is_default;
+ gboolean is_enabled;
+
+ source = E_SOURCE (link->data);
+ mail_account = e_source_get_extension (source, extension_name);
+
+ display_name = e_source_get_display_name (source);
+ backend_name = e_source_get_backend_name (source);
+ is_default = e_source_equal (source, default_source);
+ is_enabled = e_source_mail_account_get_enabled (mail_account);
+ uid = e_source_get_uid (source);
+
+ gtk_list_store_append (GTK_LIST_STORE (tree_model), &iter);
+
+ gtk_list_store_set (
+ GTK_LIST_STORE (tree_model), &iter,
+ COLUMN_DISPLAY_NAME, display_name,
+ COLUMN_BACKEND_NAME, backend_name,
+ COLUMN_DEFAULT, is_default,
+ COLUMN_ENABLED, is_enabled,
+ COLUMN_UID, uid, -1);
+ }
+
+ g_list_free (list);
+
+ /* Try and restore the previous selected source,
+ * or else just pick the default mail account. */
+
+ source = NULL;
+
+ if (saved_uid != NULL) {
+ source = e_source_registry_lookup_by_uid (registry, saved_uid);
+ g_free (saved_uid);
+ }
+
+ if (source == NULL)
+ source = default_source;
+
+ if (source != NULL)
+ e_mail_account_tree_view_set_selected_source (
+ tree_view, source);
+}
+
+void
+e_mail_account_tree_view_enable_selected (EMailAccountTreeView *tree_view)
+{
+ g_return_if_fail (E_IS_MAIL_ACCOUNT_TREE_VIEW (tree_view));
+
+ g_signal_emit (tree_view, signals[ENABLE_SELECTED], 0);
+}
+
+void
+e_mail_account_tree_view_disable_selected (EMailAccountTreeView *tree_view)
+{
+ g_return_if_fail (E_IS_MAIL_ACCOUNT_TREE_VIEW (tree_view));
+
+ g_signal_emit (tree_view, signals[DISABLE_SELECTED], 0);
+}
+
+ESourceRegistry *
+e_mail_account_tree_view_get_registry (EMailAccountTreeView *tree_view)
+{
+ g_return_val_if_fail (E_IS_MAIL_ACCOUNT_TREE_VIEW (tree_view), NULL);
+
+ return tree_view->priv->registry;
+}
+
+ESource *
+e_mail_account_tree_view_get_selected_source (EMailAccountTreeView *tree_view)
+{
+ ESourceRegistry *registry;
+ GtkTreeSelection *selection;
+ GtkTreeModel *tree_model;
+ GtkTreeIter iter;
+ ESource *source;
+ gchar *uid;
+
+ g_return_val_if_fail (E_IS_MAIL_ACCOUNT_TREE_VIEW (tree_view), NULL);
+
+ registry = e_mail_account_tree_view_get_registry (tree_view);
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
+
+ if (!gtk_tree_selection_get_selected (selection, &tree_model, &iter))
+ return NULL;
+
+ gtk_tree_model_get (tree_model, &iter, COLUMN_UID, &uid, -1);
+ source = e_source_registry_lookup_by_uid (registry, uid);
+ g_free (uid);
+
+ return source;
+}
+
+void
+e_mail_account_tree_view_set_selected_source (EMailAccountTreeView *tree_view,
+ ESource *source)
+{
+ ESourceRegistry *registry;
+ GtkTreeSelection *selection;
+ GtkTreeModel *tree_model;
+ GtkTreeIter iter;
+ gboolean valid;
+
+ g_return_if_fail (E_IS_MAIL_ACCOUNT_TREE_VIEW (tree_view));
+ g_return_if_fail (E_IS_SOURCE (source));
+
+ /* It is a programming error to pass an ESource that has no
+ * "Mail Account" extension. */
+ g_return_if_fail (SOURCE_IS_MAIL_ACCOUNT (source));
+
+ registry = e_mail_account_tree_view_get_registry (tree_view);
+ tree_model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view));
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
+
+ valid = gtk_tree_model_get_iter_first (tree_model, &iter);
+
+ while (valid) {
+ ESource *candidate;
+ gchar *uid;
+
+ gtk_tree_model_get (tree_model, &iter, COLUMN_UID, &uid, -1);
+ candidate = e_source_registry_lookup_by_uid (registry, uid);
+ g_free (uid);
+
+ if (candidate != NULL && e_source_equal (source, candidate)) {
+ gtk_tree_selection_select_iter (selection, &iter);
+ break;
+ }
+
+ valid = gtk_tree_model_iter_next (tree_model, &iter);
+ }
+}
diff --git a/widgets/misc/e-mail-account-tree-view.h b/widgets/misc/e-mail-account-tree-view.h
new file mode 100644
index 0000000000..4bf9099191
--- /dev/null
+++ b/widgets/misc/e-mail-account-tree-view.h
@@ -0,0 +1,83 @@
+/*
+ * e-mail-account-tree-view.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 <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef E_MAIL_ACCOUNT_TREE_VIEW_H
+#define E_MAIL_ACCOUNT_TREE_VIEW_H
+
+#include <gtk/gtk.h>
+#include <libedataserver/e-source-registry.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_ACCOUNT_TREE_VIEW \
+ (e_mail_account_tree_view_get_type ())
+#define E_MAIL_ACCOUNT_TREE_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_ACCOUNT_TREE_VIEW, EMailAccountTreeView))
+#define E_MAIL_ACCOUNT_TREE_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_ACCOUNT_TREE_VIEW, EMailAccountTreeViewClass))
+#define E_IS_MAIL_ACCOUNT_TREE_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_ACCOUNT_TREE_VIEW))
+#define E_IS_MAIL_ACCOUNT_TREE_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_ACCOUNT_TREE_VIEW))
+#define E_MAIL_ACCOUNT_TREE_VIEW_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_ACCOUNT_TREE_VIEW, EMailAccountTreeViewClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailAccountTreeView EMailAccountTreeView;
+typedef struct _EMailAccountTreeViewClass EMailAccountTreeViewClass;
+typedef struct _EMailAccountTreeViewPrivate EMailAccountTreeViewPrivate;
+
+struct _EMailAccountTreeView {
+ GtkTreeView parent;
+ EMailAccountTreeViewPrivate *priv;
+};
+
+struct _EMailAccountTreeViewClass {
+ GtkTreeViewClass parent_class;
+
+ void (*enable_selected) (EMailAccountTreeView *tree_view);
+ void (*disable_selected) (EMailAccountTreeView *tree_view);
+};
+
+GType e_mail_account_tree_view_get_type
+ (void) G_GNUC_CONST;
+GtkWidget * e_mail_account_tree_view_new
+ (ESourceRegistry *registry);
+void e_mail_account_tree_view_refresh
+ (EMailAccountTreeView *tree_view);
+void e_mail_account_tree_view_enable_selected
+ (EMailAccountTreeView *tree_view);
+void e_mail_account_tree_view_disable_selected
+ (EMailAccountTreeView *tree_view);
+ESourceRegistry *
+ e_mail_account_tree_view_get_registry
+ (EMailAccountTreeView *tree_view);
+ESource * e_mail_account_tree_view_get_selected_source
+ (EMailAccountTreeView *tree_view);
+void e_mail_account_tree_view_set_selected_source
+ (EMailAccountTreeView *tree_view,
+ ESource *source);
+
+G_END_DECLS
+
+#endif /* E_MAIL_ACCOUNT_TREE_VIEW_H */
diff --git a/widgets/misc/e-mail-identity-combo-box.c b/widgets/misc/e-mail-identity-combo-box.c
new file mode 100644
index 0000000000..4b830153a2
--- /dev/null
+++ b/widgets/misc/e-mail-identity-combo-box.c
@@ -0,0 +1,374 @@
+/*
+ * e-mail-identity-combo-box.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 <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "e-mail-identity-combo-box.h"
+
+#include <libedataserver/e-source-mail-account.h>
+#include <libedataserver/e-source-mail-identity.h>
+
+#define E_MAIL_IDENTITY_COMBO_BOX_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAIL_IDENTITY_COMBO_BOX, EMailIdentityComboBoxPrivate))
+
+#define SOURCE_IS_MAIL_IDENTITY(source) \
+ (e_source_has_extension ((source), E_SOURCE_EXTENSION_MAIL_IDENTITY))
+
+struct _EMailIdentityComboBoxPrivate {
+ ESourceRegistry *registry;
+ guint refresh_idle_id;
+};
+
+enum {
+ PROP_0,
+ PROP_REGISTRY
+};
+
+enum {
+ COLUMN_DISPLAY_NAME,
+ COLUMN_UID
+};
+
+G_DEFINE_TYPE (
+ EMailIdentityComboBox,
+ e_mail_identity_combo_box,
+ GTK_TYPE_COMBO_BOX)
+
+static gboolean
+mail_identity_combo_box_refresh_idle_cb (EMailIdentityComboBox *combo_box)
+{
+ /* The refresh function will clear the idle ID. */
+ e_mail_identity_combo_box_refresh (combo_box);
+
+ return FALSE;
+}
+
+static void
+mail_identity_combo_box_registry_changed (ESourceRegistry *registry,
+ ESource *source,
+ EMailIdentityComboBox *combo_box)
+{
+ /* If the ESource in question has a "Mail Identity" extension,
+ * schedule a refresh of the tree model. Otherwise ignore it.
+ * We use an idle callback to limit how frequently we refresh
+ * the tree model, in case the registry is emitting lots of
+ * signals at once. */
+
+ if (!SOURCE_IS_MAIL_IDENTITY (source))
+ return;
+
+ if (combo_box->priv->refresh_idle_id > 0)
+ return;
+
+ combo_box->priv->refresh_idle_id = gdk_threads_add_idle (
+ (GSourceFunc) mail_identity_combo_box_refresh_idle_cb,
+ combo_box);
+}
+
+static ESource *
+mail_identity_combo_box_get_default (EMailIdentityComboBox *combo_box)
+{
+ ESource *source;
+ ESourceRegistry *registry;
+ ESourceMailAccount *mail_account;
+ const gchar *extension_name;
+ const gchar *uid;
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+ registry = e_mail_identity_combo_box_get_registry (combo_box);
+ source = e_source_registry_get_default_mail_account (registry);
+
+ if (source == NULL)
+ return NULL;
+
+ if (!e_source_has_extension (source, extension_name))
+ return NULL;
+
+ mail_account = e_source_get_extension (source, extension_name);
+ uid = e_source_mail_account_get_identity (mail_account);
+
+ if (uid == NULL)
+ return NULL;
+
+ return e_source_registry_lookup_by_uid (registry, uid);
+}
+
+static void
+mail_identity_combo_box_set_registry (EMailIdentityComboBox *combo_box,
+ ESourceRegistry *registry)
+{
+ g_return_if_fail (E_IS_SOURCE_REGISTRY (registry));
+ g_return_if_fail (combo_box->priv->registry == NULL);
+
+ combo_box->priv->registry = g_object_ref (registry);
+
+ g_signal_connect (
+ registry, "source-added",
+ G_CALLBACK (mail_identity_combo_box_registry_changed),
+ combo_box);
+
+ g_signal_connect (
+ registry, "source-changed",
+ G_CALLBACK (mail_identity_combo_box_registry_changed),
+ combo_box);
+
+ g_signal_connect (
+ registry, "source-removed",
+ G_CALLBACK (mail_identity_combo_box_registry_changed),
+ combo_box);
+}
+
+static void
+mail_identity_combo_box_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_REGISTRY:
+ mail_identity_combo_box_set_registry (
+ E_MAIL_IDENTITY_COMBO_BOX (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_identity_combo_box_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_REGISTRY:
+ g_value_set_object (
+ value,
+ e_mail_identity_combo_box_get_registry (
+ E_MAIL_IDENTITY_COMBO_BOX (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_identity_combo_box_dispose (GObject *object)
+{
+ EMailIdentityComboBoxPrivate *priv;
+
+ priv = E_MAIL_IDENTITY_COMBO_BOX_GET_PRIVATE (object);
+
+ if (priv->registry != NULL) {
+ g_signal_handlers_disconnect_matched (
+ priv->registry, G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, object);
+ g_object_unref (priv->registry);
+ priv->registry = NULL;
+ }
+
+ if (priv->refresh_idle_id > 0) {
+ g_source_remove (priv->refresh_idle_id);
+ priv->refresh_idle_id = 0;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (e_mail_identity_combo_box_parent_class)->
+ dispose (object);
+}
+
+static void
+mail_identity_combo_box_constructed (GObject *object)
+{
+ GtkListStore *list_store;
+ GtkComboBox *combo_box;
+ GtkCellLayout *cell_layout;
+ GtkCellRenderer *cell_renderer;
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (e_mail_identity_combo_box_parent_class)->
+ constructed (object);
+
+ combo_box = GTK_COMBO_BOX (object);
+ cell_layout = GTK_CELL_LAYOUT (object);
+
+ list_store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
+ gtk_combo_box_set_model (combo_box, GTK_TREE_MODEL (list_store));
+ gtk_combo_box_set_id_column (combo_box, COLUMN_UID);
+ g_object_unref (list_store);
+
+ cell_renderer = gtk_cell_renderer_text_new ();
+ gtk_cell_layout_pack_start (cell_layout, cell_renderer, TRUE);
+ gtk_cell_layout_add_attribute (
+ cell_layout, cell_renderer, "text", COLUMN_DISPLAY_NAME);
+
+ e_mail_identity_combo_box_refresh (E_MAIL_IDENTITY_COMBO_BOX (object));
+}
+
+static void
+e_mail_identity_combo_box_class_init (EMailIdentityComboBoxClass *class)
+{
+ GObjectClass *object_class;
+
+ g_type_class_add_private (class, sizeof (EMailIdentityComboBoxPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = mail_identity_combo_box_set_property;
+ object_class->get_property = mail_identity_combo_box_get_property;
+ object_class->dispose = mail_identity_combo_box_dispose;
+ object_class->constructed = mail_identity_combo_box_constructed;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_REGISTRY,
+ g_param_spec_object (
+ "registry",
+ "Registry",
+ NULL,
+ E_TYPE_SOURCE_REGISTRY,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+}
+
+static void
+e_mail_identity_combo_box_init (EMailIdentityComboBox *combo_box)
+{
+ combo_box->priv = E_MAIL_IDENTITY_COMBO_BOX_GET_PRIVATE (combo_box);
+}
+
+GtkWidget *
+e_mail_identity_combo_box_new (ESourceRegistry *registry)
+{
+ g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
+
+ return g_object_new (
+ E_TYPE_MAIL_IDENTITY_COMBO_BOX,
+ "registry", registry, NULL);
+}
+
+void
+e_mail_identity_combo_box_refresh (EMailIdentityComboBox *combo_box)
+{
+ ESourceRegistry *registry;
+ GtkTreeModel *tree_model;
+ ESource *source;
+ GList *list, *link;
+ const gchar *extension_name;
+ gchar *saved_uid = NULL;
+
+ g_return_if_fail (E_IS_MAIL_IDENTITY_COMBO_BOX (combo_box));
+
+ if (combo_box->priv->refresh_idle_id > 0) {
+ g_source_remove (combo_box->priv->refresh_idle_id);
+ combo_box->priv->refresh_idle_id = 0;
+ }
+
+ registry = e_mail_identity_combo_box_get_registry (combo_box);
+ tree_model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box));
+
+ source = e_mail_identity_combo_box_get_active_source (combo_box);
+ if (source != NULL)
+ saved_uid = g_strdup (e_source_get_uid (source));
+
+ gtk_list_store_clear (GTK_LIST_STORE (tree_model));
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
+ list = e_source_registry_list_sources (registry, extension_name);
+
+ for (link = list; link != NULL; link = g_list_next (link)) {
+ GtkTreeIter iter;
+ const gchar *display_name;
+ const gchar *uid;
+
+ source = E_SOURCE (link->data);
+ display_name = e_source_get_display_name (source);
+ uid = e_source_get_uid (source);
+
+ gtk_list_store_append (GTK_LIST_STORE (tree_model), &iter);
+
+ gtk_list_store_set (
+ GTK_LIST_STORE (tree_model), &iter,
+ COLUMN_DISPLAY_NAME, display_name,
+ COLUMN_UID, uid, -1);
+ }
+
+ g_list_free (list);
+
+ /* Try and restore the previous selected source, or else pick
+ * the default identity of the default mail account. If even
+ * that fails, just pick the first item. */
+
+ source = NULL;
+
+ if (saved_uid != NULL) {
+ source = e_source_registry_lookup_by_uid (registry, saved_uid);
+ g_free (saved_uid);
+ }
+
+ if (source == NULL)
+ source = mail_identity_combo_box_get_default (combo_box);
+
+ if (source != NULL)
+ e_mail_identity_combo_box_set_active_source (combo_box, source);
+ else
+ gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), 0);
+}
+
+ESourceRegistry *
+e_mail_identity_combo_box_get_registry (EMailIdentityComboBox *combo_box)
+{
+ g_return_val_if_fail (E_IS_MAIL_IDENTITY_COMBO_BOX (combo_box), NULL);
+
+ return combo_box->priv->registry;
+}
+
+ESource *
+e_mail_identity_combo_box_get_active_source (EMailIdentityComboBox *combo_box)
+{
+ ESourceRegistry *registry;
+ ESource *source = NULL;
+ const gchar *uid;
+
+ g_return_val_if_fail (E_IS_MAIL_IDENTITY_COMBO_BOX (combo_box), NULL);
+
+ registry = e_mail_identity_combo_box_get_registry (combo_box);
+ uid = gtk_combo_box_get_active_id (GTK_COMBO_BOX (combo_box));
+
+ if (uid != NULL)
+ source = e_source_registry_lookup_by_uid (registry, uid);
+
+ return source;
+}
+
+void
+e_mail_identity_combo_box_set_active_source (EMailIdentityComboBox *combo_box,
+ ESource *active_source)
+{
+ const gchar *uid;
+
+ g_return_if_fail (E_IS_MAIL_IDENTITY_COMBO_BOX (combo_box));
+ g_return_if_fail (E_IS_SOURCE (active_source));
+
+ /* It is a programming error to pass an ESource that has no
+ * "Mail Identity" extension. */
+ g_return_if_fail (SOURCE_IS_MAIL_IDENTITY (active_source));
+
+ uid = e_source_get_uid (active_source);
+ gtk_combo_box_set_active_id (GTK_COMBO_BOX (combo_box), uid);
+}
diff --git a/widgets/misc/e-mail-identity-combo-box.h b/widgets/misc/e-mail-identity-combo-box.h
new file mode 100644
index 0000000000..b40957df7a
--- /dev/null
+++ b/widgets/misc/e-mail-identity-combo-box.h
@@ -0,0 +1,76 @@
+/*
+ * e-mail-identity-combo-box.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 <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef E_MAIL_IDENTITY_COMBO_BOX_H
+#define E_MAIL_IDENTITY_COMBO_BOX_H
+
+#include <gtk/gtk.h>
+#include <libedataserver/e-source-registry.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_IDENTITY_COMBO_BOX \
+ (e_mail_identity_combo_box_get_type ())
+#define E_MAIL_IDENTITY_COMBO_BOX(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_IDENTITY_COMBO_BOX, EMailIdentityComboBox))
+#define E_MAIL_IDENTITY_COMBO_BOX_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_IDENTITY_COMBO_BOX, EMailIdentityComboBoxClass))
+#define E_IS_MAIL_IDENTITY_COMBO_BOX(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_IDENTITY_COMBO_BOX))
+#define E_IS_MAIL_IDENTITY_COMBO_BOX_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_IDENTITY_COMBO_BOX))
+#define E_MAIL_IDENTITY_COMBO_BOX_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_IDENTITY_COMBO_BOX, EMailIdentityComboBoxClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailIdentityComboBox EMailIdentityComboBox;
+typedef struct _EMailIdentityComboBoxClass EMailIdentityComboBoxClass;
+typedef struct _EMailIdentityComboBoxPrivate EMailIdentityComboBoxPrivate;
+
+struct _EMailIdentityComboBox {
+ GtkComboBox parent;
+ EMailIdentityComboBoxPrivate *priv;
+};
+
+struct _EMailIdentityComboBoxClass {
+ GtkComboBoxClass parent_class;
+};
+
+GType e_mail_identity_combo_box_get_type
+ (void) G_GNUC_CONST;
+GtkWidget * e_mail_identity_combo_box_new
+ (ESourceRegistry *registry);
+void e_mail_identity_combo_box_refresh
+ (EMailIdentityComboBox *combo_box);
+ESourceRegistry *
+ e_mail_identity_combo_box_get_registry
+ (EMailIdentityComboBox *combo_box);
+ESource * e_mail_identity_combo_box_get_active_source
+ (EMailIdentityComboBox *combo_box);
+void e_mail_identity_combo_box_set_active_source
+ (EMailIdentityComboBox *combo_box,
+ ESource *active_source);
+
+G_END_DECLS
+
+#endif /* E_MAIL_IDENTITY_COMBO_BOX_H */
diff --git a/widgets/misc/test-mail-accounts.c b/widgets/misc/test-mail-accounts.c
new file mode 100644
index 0000000000..92069b4bb2
--- /dev/null
+++ b/widgets/misc/test-mail-accounts.c
@@ -0,0 +1,61 @@
+/*
+ * test-mail-accounts.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 <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include <misc/e-mail-account-manager.h>
+#include <misc/e-mail-identity-combo-box.h>
+
+gint
+main (gint argc, gchar **argv)
+{
+ ESourceRegistry *registry;
+ GtkWidget *container;
+ GtkWidget *widget;
+ GtkWidget *window;
+
+ gtk_init (&argc, &argv);
+
+ registry = e_source_registry_get_default ();
+
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title (GTK_WINDOW (window), "Mail Sources");
+ gtk_widget_set_default_size (GTK_WINDOW (window), 400, 400);
+ gtk_container_set_border_width (GTK_CONTAINER (window), 12);
+ gtk_widget_show (window);
+
+ g_signal_connect (
+ window, "delete-event",
+ G_CALLBACK (gtk_main_quit), NULL);
+
+ widget = gtk_vbox_new (FALSE, 12);
+ gtk_container_add (GTK_CONTAINER (window), widget);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ widget = e_mail_identity_combo_box_new (registry);
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ widget = e_mail_account_manager_new (registry);
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ gtk_widget_show (widget);
+
+ gtk_main ();
+
+ return 0;
+}