[evolution] Adapt modules/mail to the new ESource API.



commit 992373c8b0ac5ab0fe8ad495577a5a7a4a57b0b0
Author: Matthew Barnes <mbarnes redhat com>
Date:   Wed Apr 13 10:31:24 2011 -0400

    Adapt modules/mail to the new ESource API.

 modules/mail-config/e-mail-config-google-summary.c |  370 ++++++++++++++++
 modules/mail-config/e-mail-config-yahoo-summary.c  |  349 +++++++++++++++
 modules/mail/e-mail-shell-backend.c                |  108 +++---
 modules/mail/e-mail-shell-backend.h                |    3 +-
 modules/mail/e-mail-shell-view-actions.c           |   60 +++-
 modules/mail/e-mail-shell-view-private.c           |  452 +++++++-------------
 modules/mail/e-mail-shell-view-private.h           |   13 +-
 modules/mail/e-mail-shell-view.c                   |   47 ++-
 modules/mail/em-account-prefs.c                    |    7 +-
 modules/mail/em-composer-prefs.c                   |   27 +-
 10 files changed, 1027 insertions(+), 409 deletions(-)
---
diff --git a/modules/mail-config/e-mail-config-google-summary.c b/modules/mail-config/e-mail-config-google-summary.c
new file mode 100644
index 0000000..c53202f
--- /dev/null
+++ b/modules/mail-config/e-mail-config-google-summary.c
@@ -0,0 +1,370 @@
+/*
+ * e-mail-config-google-summary.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-config-google-summary.h"
+
+#include <config.h>
+#include <glib/gi18n-lib.h>
+
+#include <libedataserver/e-data-server-util.h>
+#include <libedataserver/e-source-authentication.h>
+#include <libedataserver/e-source-collection.h>
+#include <libedataserver/e-source-mail-identity.h>
+
+#include <mail/e-mail-config-summary-page.h>
+
+#define E_MAIL_CONFIG_GOOGLE_SUMMARY_GET_PRIVATE(obj) \
+	(G_TYPE_INSTANCE_GET_PRIVATE \
+	((obj), E_TYPE_MAIL_CONFIG_GOOGLE_SUMMARY, EMailConfigGoogleSummaryPrivate))
+
+#define GOOGLE_HELP_URI \
+	"http://support.google.com/mail/bin/answer.py?hl=en&answer=77695";
+
+struct _EMailConfigGoogleSummaryPrivate {
+	ESource *collection_source;
+
+	/* Widgets (not referenced) */
+	GtkWidget *calendar_toggle;
+	GtkWidget *contacts_toggle;
+
+	gboolean applicable;
+};
+
+enum {
+	PROP_0,
+	PROP_APPLICABLE
+};
+
+G_DEFINE_DYNAMIC_TYPE (
+	EMailConfigGoogleSummary,
+	e_mail_config_google_summary,
+	E_TYPE_EXTENSION)
+
+static EMailConfigSummaryPage *
+mail_config_google_summary_get_summary_page (EMailConfigGoogleSummary *extension)
+{
+	EExtensible *extensible;
+
+	extensible = e_extension_get_extensible (E_EXTENSION (extension));
+
+	return E_MAIL_CONFIG_SUMMARY_PAGE (extensible);
+}
+
+static gboolean
+mail_config_google_summary_is_applicable (EMailConfigSummaryPage *page)
+{
+	ESource *source;
+	const gchar *extension_name;
+	const gchar *host = NULL;
+
+	/* FIXME We should tie this into EMailAutoconfig to avoid
+	 *       hard-coding Google domain names.  Maybe retain the
+	 *       <emailProvider id="..."> it matched so we can just
+	 *       check for, in this case, "googlemail.com".
+	 *
+	 *       Source:
+	 *       http://api.gnome.org/evolution/autoconfig/1.1/google.com
+	 */
+
+	source = e_mail_config_summary_page_get_account_source (page);
+
+	extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
+	if (e_source_has_extension (source, extension_name)) {
+		ESourceAuthentication *extension;
+		extension = e_source_get_extension (source, extension_name);
+		host = e_source_authentication_get_host (extension);
+	}
+
+	if (host == NULL)
+		return FALSE;
+
+	if (e_util_utf8_strstrcase (host, "gmail.com") != NULL)
+		return TRUE;
+
+	if (e_util_utf8_strstrcase (host, "googlemail.com") != NULL)
+		return TRUE;
+
+	return FALSE;
+}
+
+static void
+mail_config_google_summary_refresh_cb (EMailConfigSummaryPage *page,
+                                       EMailConfigGoogleSummary *extension)
+{
+	extension->priv->applicable =
+		mail_config_google_summary_is_applicable (page);
+
+	g_object_notify (G_OBJECT (extension), "applicable");
+}
+
+static void
+mail_config_google_summary_commit_changes_cb (EMailConfigSummaryPage *page,
+                                              GQueue *source_queue,
+                                              EMailConfigGoogleSummary *extension)
+{
+	ESource *source;
+	ESourceCollection *collection_extension;
+	ESourceMailIdentity *identity_extension;
+	GtkToggleButton *toggle_button;
+	GList *head, *link;
+	const gchar *address;
+	const gchar *parent_uid;
+	const gchar *extension_name;
+	gboolean calendar_active;
+	gboolean contacts_active;
+
+	/* If this is not a Google account, do nothing (obviously). */
+	if (!e_mail_config_google_summary_get_applicable (extension))
+		return;
+
+	toggle_button = GTK_TOGGLE_BUTTON (extension->priv->calendar_toggle);
+	calendar_active = gtk_toggle_button_get_active (toggle_button);
+
+	toggle_button = GTK_TOGGLE_BUTTON (extension->priv->contacts_toggle);
+	contacts_active = gtk_toggle_button_get_active (toggle_button);
+
+	/* If the user declined both Calendar and Contacts, do nothing. */
+	if (!calendar_active && !contacts_active)
+		return;
+
+	/* The collection identity is the user's email address. */
+	source = e_mail_config_summary_page_get_identity_source (page);
+	extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
+	identity_extension = e_source_get_extension (source, extension_name);
+	address = e_source_mail_identity_get_address (identity_extension);
+
+	source = extension->priv->collection_source;
+	extension_name = E_SOURCE_EXTENSION_COLLECTION;
+	collection_extension = e_source_get_extension (source, extension_name);
+	e_source_collection_set_identity (collection_extension, address);
+
+	/* All queued sources become children of the collection source. */
+	parent_uid = e_source_get_uid (source);
+	head = g_queue_peek_head_link (source_queue);
+	for (link = head; link != NULL; link = g_list_next (link))
+		e_source_set_parent (E_SOURCE (link->data), parent_uid);
+
+	/* Push this AFTER iterating over the source queue. */
+	g_queue_push_head (source_queue, g_object_ref (source));
+
+	/* The "google-backend" module in E-D-S will handle the rest. */
+}
+
+static void
+mail_config_google_summary_get_property (GObject *object,
+                                         guint property_id,
+                                         GValue *value,
+                                         GParamSpec *pspec)
+{
+	switch (property_id) {
+		case PROP_APPLICABLE:
+			g_value_set_boolean (
+				value,
+				e_mail_config_google_summary_get_applicable (
+				E_MAIL_CONFIG_GOOGLE_SUMMARY (object)));
+			return;
+	}
+
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_config_google_summary_dispose (GObject *object)
+{
+	EMailConfigGoogleSummaryPrivate *priv;
+
+	priv = E_MAIL_CONFIG_GOOGLE_SUMMARY_GET_PRIVATE (object);
+
+	if (priv->collection_source != NULL) {
+		g_object_unref (priv->collection_source);
+		priv->collection_source = NULL;
+	}
+
+	/* Chain up to parent's dispose() method. */
+	G_OBJECT_CLASS (e_mail_config_google_summary_parent_class)->
+		dispose (object);
+}
+
+static void
+mail_config_google_summary_constructed (GObject *object)
+{
+	EMailConfigGoogleSummary *extension;
+	EMailConfigSummaryPage *page;
+	ESourceCollection *collection_extension;
+	ESource *source;
+	GtkWidget *container;
+	GtkWidget *widget;
+	const gchar *extension_name;
+	const gchar *text;
+	gchar *markup;
+
+	extension = E_MAIL_CONFIG_GOOGLE_SUMMARY (object);
+
+	/* Chain up to parent's constructed() method. */
+	G_OBJECT_CLASS (e_mail_config_google_summary_parent_class)->
+		constructed (object);
+
+	page = mail_config_google_summary_get_summary_page (extension);
+
+	/* Use g_signal_connect_after() so the EMailConfigSummaryPage
+	 * class methods run first.  They make changes to the sources
+	 * the we either want to utilize or override. */
+
+	g_signal_connect_after (
+		page, "refresh",
+		G_CALLBACK (mail_config_google_summary_refresh_cb),
+		extension);
+
+	g_signal_connect_after (
+		page, "commit-changes",
+		G_CALLBACK (mail_config_google_summary_commit_changes_cb),
+		extension);
+
+	container = GTK_WIDGET (page);
+
+	widget = gtk_grid_new ();
+	gtk_grid_set_row_spacing (GTK_GRID (widget), 6);
+	gtk_grid_set_column_spacing (GTK_GRID (widget), 6);
+	gtk_box_pack_start (GTK_BOX (page), widget, FALSE, FALSE, 0);
+
+	g_object_bind_property (
+		extension, "applicable",
+		widget, "visible",
+		G_BINDING_SYNC_CREATE);
+
+	container = widget;
+
+	text = _("Google Features");
+	markup = g_markup_printf_escaped ("<b>%s</b>", text);
+	widget = gtk_label_new (markup);
+	gtk_label_set_use_markup (GTK_LABEL (widget), TRUE);
+	gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+	gtk_grid_attach (GTK_GRID (container), widget, 0, 0, 1, 1);
+	gtk_widget_show (widget);
+	g_free (markup);
+
+	text = _("Add Google Ca_lendar to this account");
+	widget = gtk_check_button_new_with_mnemonic (text);
+	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
+	gtk_widget_set_margin_left (widget, 12);
+	gtk_grid_attach (GTK_GRID (container), widget, 0, 1, 1, 1);
+	extension->priv->calendar_toggle = widget;  /* not referenced */
+	gtk_widget_show (widget);
+
+	text = _("Add Google Con_tacts to this account");
+	widget = gtk_check_button_new_with_mnemonic (text);
+	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
+	gtk_widget_set_margin_left (widget, 12);
+	gtk_grid_attach (GTK_GRID (container), widget, 0, 2, 1, 1);
+	extension->priv->contacts_toggle = widget;  /* not referenced */
+	gtk_widget_show (widget);
+
+	text = _("You may need to enable IMAP access");
+	widget = gtk_link_button_new_with_label (GOOGLE_HELP_URI, text);
+	gtk_widget_set_margin_left (widget, 12);
+	gtk_grid_attach (GTK_GRID (container), widget, 0, 3, 1, 1);
+	gtk_widget_show (widget);
+
+	source = extension->priv->collection_source;
+	extension_name = E_SOURCE_EXTENSION_COLLECTION;
+	collection_extension = e_source_get_extension (source, extension_name);
+
+	g_object_bind_property (
+		page, "account-name",
+		source, "display-name",
+		G_BINDING_SYNC_CREATE);
+
+	g_object_bind_property (
+		extension->priv->calendar_toggle, "active",
+		collection_extension, "calendar-enabled",
+		G_BINDING_SYNC_CREATE);
+
+	g_object_bind_property (
+		extension->priv->contacts_toggle, "active",
+		collection_extension, "contacts-enabled",
+		G_BINDING_SYNC_CREATE);
+}
+
+static void
+e_mail_config_google_summary_class_init (EMailConfigGoogleSummaryClass *class)
+{
+	GObjectClass *object_class;
+	EExtensionClass *extension_class;
+
+	g_type_class_add_private (
+		class, sizeof (EMailConfigGoogleSummaryPrivate));
+
+	object_class = G_OBJECT_CLASS (class);
+	object_class->get_property = mail_config_google_summary_get_property;
+	object_class->dispose = mail_config_google_summary_dispose;
+	object_class->constructed = mail_config_google_summary_constructed;
+
+	extension_class = E_EXTENSION_CLASS (class);
+	extension_class->extensible_type = E_TYPE_MAIL_CONFIG_SUMMARY_PAGE;
+
+	g_object_class_install_property (
+		object_class,
+		PROP_APPLICABLE,
+		g_param_spec_boolean (
+			"applicable",
+			"Applicable",
+			"Whether this extension is applicable "
+			"to the current mail account settings",
+			FALSE,
+			G_PARAM_READABLE));
+}
+
+static void
+e_mail_config_google_summary_class_finalize (EMailConfigGoogleSummaryClass *class)
+{
+}
+
+static void
+e_mail_config_google_summary_init (EMailConfigGoogleSummary *extension)
+{
+	ESource *source;
+	ESourceBackend *backend_extension;
+	const gchar *extension_name;
+
+	extension->priv = E_MAIL_CONFIG_GOOGLE_SUMMARY_GET_PRIVATE (extension);
+
+	source = e_source_new (NULL, NULL, NULL);
+	extension_name = E_SOURCE_EXTENSION_COLLECTION;
+	backend_extension = e_source_get_extension (source, extension_name);
+	e_source_backend_set_backend_name (backend_extension, "google");
+	extension->priv->collection_source = source;
+}
+
+void
+e_mail_config_google_summary_type_register (GTypeModule *type_module)
+{
+	/* XXX G_DEFINE_DYNAMIC_TYPE declares a static type registration
+	 *     function, so we have to wrap it with a public function in
+	 *     order to register types from a separate compilation unit. */
+	e_mail_config_google_summary_register_type (type_module);
+}
+
+gboolean
+e_mail_config_google_summary_get_applicable (EMailConfigGoogleSummary *extension)
+{
+	g_return_val_if_fail (
+		E_IS_MAIL_CONFIG_GOOGLE_SUMMARY (extension), FALSE);
+
+	return extension->priv->applicable;
+}
+
diff --git a/modules/mail-config/e-mail-config-yahoo-summary.c b/modules/mail-config/e-mail-config-yahoo-summary.c
new file mode 100644
index 0000000..c97585d
--- /dev/null
+++ b/modules/mail-config/e-mail-config-yahoo-summary.c
@@ -0,0 +1,349 @@
+/*
+ * e-mail-config-yahoo-summary.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-config-yahoo-summary.h"
+
+#include <config.h>
+#include <glib/gi18n-lib.h>
+
+#include <libedataserver/e-data-server-util.h>
+#include <libedataserver/e-source-authentication.h>
+#include <libedataserver/e-source-collection.h>
+#include <libedataserver/e-source-mail-identity.h>
+
+#include <mail/e-mail-config-summary-page.h>
+
+#define E_MAIL_CONFIG_YAHOO_SUMMARY_GET_PRIVATE(obj) \
+	(G_TYPE_INSTANCE_GET_PRIVATE \
+	((obj), E_TYPE_MAIL_CONFIG_YAHOO_SUMMARY, EMailConfigYahooSummaryPrivate))
+
+struct _EMailConfigYahooSummaryPrivate {
+	ESource *collection_source;
+
+	/* Widgets (not referenced) */
+	GtkWidget *calendar_toggle;
+
+	gboolean applicable;
+};
+
+enum {
+	PROP_0,
+	PROP_APPLICABLE
+};
+
+G_DEFINE_DYNAMIC_TYPE (
+	EMailConfigYahooSummary,
+	e_mail_config_yahoo_summary,
+	E_TYPE_EXTENSION)
+
+static EMailConfigSummaryPage *
+mail_config_yahoo_summary_get_summary_page (EMailConfigYahooSummary *extension)
+{
+	EExtensible *extensible;
+
+	extensible = e_extension_get_extensible (E_EXTENSION (extension));
+
+	return E_MAIL_CONFIG_SUMMARY_PAGE (extensible);
+}
+
+static gboolean
+mail_config_yahoo_summary_is_applicable (EMailConfigSummaryPage *page)
+{
+	ESource *source;
+	const gchar *extension_name;
+	const gchar *host = NULL;
+
+	/* FIXME We should tie this into EMailAutoconfig to avoid
+	 *       hard-coding Yahoo domain names.  Maybe retain the
+	 *       <emailProvider id="..."> it matched so we can just
+	 *       check for, in this case, "yahoo.com".
+	 *
+	 *       Source:
+	 *       http://api.gnome.org/evolution/autoconfig/1.1/yahoo.com
+	 */
+
+	source = e_mail_config_summary_page_get_account_source (page);
+
+	extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
+	if (e_source_has_extension (source, extension_name)) {
+		ESourceAuthentication *extension;
+		extension = e_source_get_extension (source, extension_name);
+		host = e_source_authentication_get_host (extension);
+	}
+
+	if (host == NULL)
+		return FALSE;
+
+	if (e_util_utf8_strstrcase (host, "yahoo.com") != NULL)
+		return TRUE;
+
+	if (e_util_utf8_strstrcase (host, "ymail.com") != NULL)
+		return TRUE;
+
+	if (e_util_utf8_strstrcase (host, "rocketmail.com") != NULL)
+		return TRUE;
+
+	return FALSE;
+}
+
+static void
+mail_config_yahoo_summary_refresh_cb (EMailConfigSummaryPage *page,
+                                      EMailConfigYahooSummary *extension)
+{
+	extension->priv->applicable =
+		mail_config_yahoo_summary_is_applicable (page);
+
+	g_object_notify (G_OBJECT (extension), "applicable");
+}
+
+static void
+mail_config_yahoo_summary_commit_changes_cb (EMailConfigSummaryPage *page,
+                                             GQueue *source_queue,
+                                             EMailConfigYahooSummary *extension)
+{
+	ESource *source;
+	ESourceCollection *collection_extension;
+	ESourceMailIdentity *identity_extension;
+	GtkToggleButton *toggle_button;
+	GList *head, *link;
+	const gchar *address;
+	const gchar *parent_uid;
+	const gchar *extension_name;
+	gboolean calendar_active;
+
+	/* If this is not a Yahoo! account, do nothing (obviously). */
+	if (!e_mail_config_yahoo_summary_get_applicable (extension))
+		return;
+
+	toggle_button = GTK_TOGGLE_BUTTON (extension->priv->calendar_toggle);
+	calendar_active = gtk_toggle_button_get_active (toggle_button);
+
+	/* If the user declined to add a Calendar, do nothing. */
+	if (!calendar_active)
+		return;
+
+	/* The collection identity is the user's email address. */
+	source = e_mail_config_summary_page_get_identity_source (page);
+	extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
+	identity_extension = e_source_get_extension (source, extension_name);
+	address = e_source_mail_identity_get_address (identity_extension);
+
+	source = extension->priv->collection_source;
+	extension_name = E_SOURCE_EXTENSION_COLLECTION;
+	collection_extension = e_source_get_extension (source, extension_name);
+	e_source_collection_set_identity (collection_extension, address);
+
+	/* All queued sources become children of the collection source. */
+	parent_uid = e_source_get_uid (source);
+	head = g_queue_peek_head_link (source_queue);
+	for (link = head; link != NULL; link = g_list_next (link))
+		e_source_set_parent (E_SOURCE (link->data), parent_uid);
+
+	/* Push this AFTER iterating over the source queue. */
+	g_queue_push_head (source_queue, g_object_ref (source));
+
+	/* The "yahoo-backend" module in E-D-S will handle the rest. */
+}
+
+static void
+mail_config_yahoo_summary_get_property (GObject *object,
+                                        guint property_id,
+                                        GValue *value,
+                                        GParamSpec *pspec)
+{
+	switch (property_id) {
+		case PROP_APPLICABLE:
+			g_value_set_boolean (
+				value,
+				e_mail_config_yahoo_summary_get_applicable (
+				E_MAIL_CONFIG_YAHOO_SUMMARY (object)));
+			return;
+	}
+
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_config_yahoo_summary_dispose (GObject *object)
+{
+	EMailConfigYahooSummaryPrivate *priv;
+
+	priv = E_MAIL_CONFIG_YAHOO_SUMMARY_GET_PRIVATE (object);
+
+	if (priv->collection_source != NULL) {
+		g_object_unref (priv->collection_source);
+		priv->collection_source = NULL;
+	}
+
+	/* Chain up to parent's dispose() method. */
+	G_OBJECT_CLASS (e_mail_config_yahoo_summary_parent_class)->
+		dispose (object);
+}
+
+static void
+mail_config_yahoo_summary_constructed (GObject *object)
+{
+	EMailConfigYahooSummary *extension;
+	EMailConfigSummaryPage *page;
+	ESourceCollection *collection_extension;
+	ESource *source;
+	GtkWidget *container;
+	GtkWidget *widget;
+	const gchar *extension_name;
+	const gchar *text;
+	gchar *markup;
+
+	extension = E_MAIL_CONFIG_YAHOO_SUMMARY (object);
+
+	/* Chain up to parent's constructed() method. */
+	G_OBJECT_CLASS (e_mail_config_yahoo_summary_parent_class)->
+		constructed (object);
+
+	page = mail_config_yahoo_summary_get_summary_page (extension);
+
+	/* Use g_signal_connect_after() so the EMailConfigSummaryPage
+	 * class methods run first.  They make changes to the sources
+	 * that we either want to utilize or override. */
+
+	g_signal_connect_after (
+		page, "refresh",
+		G_CALLBACK (mail_config_yahoo_summary_refresh_cb),
+		extension);
+
+	g_signal_connect_after (
+		page, "commit-changes",
+		G_CALLBACK (mail_config_yahoo_summary_commit_changes_cb),
+		extension);
+
+	container = GTK_WIDGET (page);
+
+	widget = gtk_grid_new ();
+	gtk_grid_set_row_spacing (GTK_GRID (widget), 6);
+	gtk_grid_set_column_spacing (GTK_GRID (widget), 6);
+	gtk_box_pack_start (GTK_BOX (page), widget, FALSE, FALSE, 0);
+
+	g_object_bind_property (
+		extension, "applicable",
+		widget, "visible",
+		G_BINDING_SYNC_CREATE);
+
+	container = widget;
+
+	text = _("Yahoo! Features");
+	markup = g_markup_printf_escaped ("<b>%s</b>", text);
+	widget = gtk_label_new (markup);
+	gtk_label_set_use_markup (GTK_LABEL (widget), TRUE);
+	gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+	gtk_grid_attach (GTK_GRID (container), widget, 0, 0, 2, 1);
+	gtk_widget_show (widget);
+	g_free (markup);
+
+	text = _("Add Yahoo! Ca_lendar to this account");
+	widget = gtk_check_button_new_with_mnemonic (text);
+	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
+	gtk_widget_set_margin_left (widget, 12);
+	gtk_grid_attach (GTK_GRID (container), widget, 0, 1, 2, 1);
+	extension->priv->calendar_toggle = widget;  /* not referenced */
+	gtk_widget_show (widget);
+
+	source = extension->priv->collection_source;
+	extension_name = E_SOURCE_EXTENSION_COLLECTION;
+	collection_extension = e_source_get_extension (source, extension_name);
+
+	g_object_bind_property (
+		page, "account-name",
+		source, "display-name",
+		G_BINDING_SYNC_CREATE);
+
+	g_object_bind_property (
+		extension->priv->calendar_toggle, "active",
+		collection_extension, "calendar-enabled",
+		G_BINDING_SYNC_CREATE);
+}
+
+static void
+e_mail_config_yahoo_summary_class_init (EMailConfigYahooSummaryClass *class)
+{
+	GObjectClass *object_class;
+	EExtensionClass *extension_class;
+
+	g_type_class_add_private (
+		class, sizeof (EMailConfigYahooSummaryPrivate));
+
+	object_class = G_OBJECT_CLASS (class);
+	object_class->get_property = mail_config_yahoo_summary_get_property;
+	object_class->dispose = mail_config_yahoo_summary_dispose;
+	object_class->constructed = mail_config_yahoo_summary_constructed;
+
+	extension_class = E_EXTENSION_CLASS (class);
+	extension_class->extensible_type = E_TYPE_MAIL_CONFIG_SUMMARY_PAGE;
+
+	g_object_class_install_property (
+		object_class,
+		PROP_APPLICABLE,
+		g_param_spec_boolean (
+			"applicable",
+			"Applicable",
+			"Whether this extension is applicable "
+			"to the current mail account settings",
+			FALSE,
+			G_PARAM_READABLE));
+}
+
+static void
+e_mail_config_yahoo_summary_class_finalize (EMailConfigYahooSummaryClass *class)
+{
+}
+
+static void
+e_mail_config_yahoo_summary_init (EMailConfigYahooSummary *extension)
+{
+	ESource *source;
+	ESourceBackend *backend_extension;
+	const gchar *extension_name;
+
+	extension->priv = E_MAIL_CONFIG_YAHOO_SUMMARY_GET_PRIVATE (extension);
+
+	source = e_source_new (NULL, NULL, NULL);
+	extension_name = E_SOURCE_EXTENSION_COLLECTION;
+	backend_extension = e_source_get_extension (source, extension_name);
+	e_source_backend_set_backend_name (backend_extension, "yahoo");
+	extension->priv->collection_source = source;
+
+	/* XXX No CardDAV support yet, sadly. */
+	e_source_collection_set_contacts_enabled (
+		E_SOURCE_COLLECTION (backend_extension), FALSE);
+}
+
+void
+e_mail_config_yahoo_summary_type_register (GTypeModule *type_module)
+{
+	/* XXX G_DEFINE_DYNAMIC_TYPE declares a static type registration
+	 *     function, so we have to wrap it with a public function in
+	 *     order to register types from a separate compilation unit. */
+	e_mail_config_yahoo_summary_register_type (type_module);
+}
+
+gboolean
+e_mail_config_yahoo_summary_get_applicable (EMailConfigYahooSummary *extension)
+{
+	g_return_val_if_fail (
+		E_IS_MAIL_CONFIG_YAHOO_SUMMARY (extension), FALSE);
+
+	return extension->priv->applicable;
+}
diff --git a/modules/mail/e-mail-shell-backend.c b/modules/mail/e-mail-shell-backend.c
index 43a4cf5..2f8e9c8 100644
--- a/modules/mail/e-mail-shell-backend.c
+++ b/modules/mail/e-mail-shell-backend.c
@@ -27,6 +27,9 @@
 
 #include <glib/gi18n.h>
 
+#include <libedataserver/e-source-registry.h>
+#include <libedataserver/e-source-mail-transport.h>
+
 #include <e-util/e-import.h>
 #include <e-util/e-util.h>
 
@@ -48,8 +51,9 @@
 #include <libemail-engine/mail-ops.h>
 
 #include <mail/e-mail-browser.h>
+#include <mail/e-mail-config-assistant.h>
+#include <mail/e-mail-config-window.h>
 #include <mail/e-mail-reader.h>
-#include <mail/em-account-editor.h>
 #include <mail/em-composer-utils.h>
 #include <mail/em-folder-utils.h>
 #include <mail/em-format-hook.h>
@@ -192,13 +196,26 @@ action_mail_message_new_cb (GtkAction *action,
 	EShellSidebar *shell_sidebar;
 	EShellView *shell_view;
 	EShell *shell;
+	ESourceRegistry *registry;
 	EMFolderTree *folder_tree;
 	CamelFolder *folder = NULL;
 	CamelStore *store;
+	GList *list;
+	const gchar *extension_name;
 	const gchar *view_name;
+	gboolean no_transport_defined;
 	gchar *folder_name;
 
 	shell = e_shell_window_get_shell (shell_window);
+	registry = e_shell_get_registry (shell);
+
+	extension_name = E_SOURCE_EXTENSION_MAIL_TRANSPORT;
+	list = e_source_registry_list_sources (registry, extension_name);
+	no_transport_defined = (list == NULL);
+	g_list_free_full (list, (GDestroyNotify) g_object_unref);
+
+	if (no_transport_defined)
+		return;
 
 	/* Take care not to unnecessarily load the mail shell view. */
 	view_name = e_shell_window_get_active_view (shell_window);
@@ -538,8 +555,6 @@ mail_shell_backend_start (EShellBackend *shell_backend)
 		g_error_free (error);
 	}
 
-	mail_autoreceive_init (session);
-
 	if (g_getenv ("CAMEL_FLUSH_CHANGES") != NULL)
 		priv->mail_sync_source_id = g_timeout_add_seconds (
 			mail_config_get_sync_timeout (),
@@ -706,96 +721,73 @@ void
 e_mail_shell_backend_new_account (EMailShellBackend *mail_shell_backend,
                                   GtkWindow *parent)
 {
+	GtkWidget *assistant;
+	EMailBackend *backend;
+	EMailSession *session;
+
 #ifdef WITH_CAPPLET
 	EShell *shell;
 	EShellBackend *shell_backend;
 #endif /* WITH_CAPPLET */
-	EMailShellBackendPrivate *priv;
 
 	g_return_if_fail (mail_shell_backend != NULL);
 	g_return_if_fail (E_IS_MAIL_SHELL_BACKEND (mail_shell_backend));
 
-	priv = mail_shell_backend->priv;
+	assistant = mail_shell_backend->priv->assistant;
 
-	if (priv->assistant != NULL) {
-		gtk_window_present (GTK_WINDOW (priv->assistant));
+	if (assistant != NULL) {
+		gtk_window_present (GTK_WINDOW (assistant));
 		return;
 	}
 
+	backend = E_MAIL_BACKEND (mail_shell_backend);
+	session = e_mail_backend_get_session (backend);
+
 #ifdef WITH_CAPPLET
 	shell_backend = E_SHELL_BACKEND (mail_shell_backend);
 	shell = e_shell_backend_get_shell (shell_backend);
 
 	if (e_shell_get_express_mode (shell))
-		priv->assistant = mail_capplet_shell_new (0, TRUE, FALSE);
+		assistant = mail_capplet_shell_new (0, TRUE, FALSE);
 #endif /* WITH_CAPPLET */
 
-	if (priv->assistant == NULL) {
-		EMAccountEditor *emae;
-
-		/** @HookPoint-EMConfig: New Mail Account Assistant
-		 * @Id: org.gnome.evolution.mail.config.accountAssistant
-		 * @Type: E_CONFIG_ASSISTANT
-		 * @Class: org.gnome.evolution.mail.config:1.0
-		 * @Target: EMConfigTargetAccount
-		 *
-		 * The new mail account assistant.
-		 */
-		emae = em_account_editor_new (
-			NULL, EMAE_ASSISTANT, E_MAIL_BACKEND (mail_shell_backend),
-			"org.gnome.evolution.mail.config.accountAssistant");
-		e_config_create_window (
-			E_CONFIG (emae->config), NULL,
-			_("Evolution Account Assistant"));
-		priv->assistant = E_CONFIG (emae->config)->window;
-		g_object_set_data_full (
-			G_OBJECT (priv->assistant), "AccountEditor",
-			emae, (GDestroyNotify) g_object_unref);
-	}
+	if (assistant == NULL)
+		assistant = e_mail_config_assistant_new (session);
+
+	gtk_window_set_transient_for (GTK_WINDOW (assistant), parent);
+	gtk_widget_show (assistant);
+
+	mail_shell_backend->priv->assistant = assistant;
 
 	g_object_add_weak_pointer (
-		G_OBJECT (priv->assistant), &priv->assistant);
-	gtk_window_set_transient_for (GTK_WINDOW (priv->assistant), parent);
-	gtk_widget_show (priv->assistant);
+		G_OBJECT (mail_shell_backend->priv->assistant),
+		&mail_shell_backend->priv->assistant);
 }
 
 void
 e_mail_shell_backend_edit_account (EMailShellBackend *mail_shell_backend,
                                    GtkWindow *parent,
-                                   EAccount *account)
+                                   ESource *mail_account)
 {
 	EMailShellBackendPrivate *priv;
-	EMAccountEditor *emae;
+	EMailBackend *backend;
+	EMailSession *session;
 
-	g_return_if_fail (mail_shell_backend != NULL);
 	g_return_if_fail (E_IS_MAIL_SHELL_BACKEND (mail_shell_backend));
-	g_return_if_fail (account != NULL);
+	g_return_if_fail (E_IS_SOURCE (mail_account));
 
 	priv = mail_shell_backend->priv;
 
+	backend = E_MAIL_BACKEND (mail_shell_backend);
+	session = e_mail_backend_get_session (backend);
+
 	if (priv->editor != NULL) {
 		gtk_window_present (GTK_WINDOW (priv->editor));
 		return;
 	}
 
-	/** @HookPoint-EMConfig: Mail Account Editor
-	 * @Id: org.gnome.evolution.mail.config.accountEditor
-	 * @Type: E_CONFIG_BOOK
-	 * @Class: org.gnome.evolution.mail.config:1.0
-	 * @Target: EMConfigTargetAccount
-	 *
-	 * The account editor window.
-	 */
-	emae = em_account_editor_new (
-		account, EMAE_NOTEBOOK, E_MAIL_BACKEND (mail_shell_backend),
-		"org.gnome.evolution.mail.config.accountEditor");
-	e_config_create_window (
-		E_CONFIG (emae->config), parent, _("Account Editor"));
-	priv->editor = E_CONFIG (emae->config)->window;
-	g_object_set_data_full (
-		G_OBJECT (priv->editor), "AccountEditor",
-		emae, (GDestroyNotify) g_object_unref);
-
+	priv->editor = e_mail_config_window_new (session, mail_account);
+	gtk_window_set_transient_for (GTK_WINDOW (priv->editor), parent);
 	g_object_add_weak_pointer (G_OBJECT (priv->editor), &priv->editor);
 	gtk_widget_show (priv->editor);
 }
@@ -892,11 +884,13 @@ static void
 mbox_fill_preview_cb (GObject *preview,
                       CamelMimeMessage *msg)
 {
+	EShell *shell;
 	EMailDisplay *display;
 	EMFormat *formatter;
 	GHashTable *formatters;
 	SoupSession *soup_session;
 	EMailSession *mail_session;
+	ESourceRegistry *registry;
 	gchar *mail_uri;
 
 	g_return_if_fail (preview != NULL);
@@ -916,7 +910,9 @@ mbox_fill_preview_cb (GObject *preview,
 
 	mail_uri = em_format_build_mail_uri (NULL, msg->message_id, NULL, NULL);
 
-	mail_session = e_mail_session_new ();
+	shell = e_shell_get_default ();
+	registry = e_shell_get_registry (shell);
+	mail_session = e_mail_session_new (registry);
 
 	formatter = EM_FORMAT (
 		em_format_html_display_new (
diff --git a/modules/mail/e-mail-shell-backend.h b/modules/mail/e-mail-shell-backend.h
index 3b820a0..0b76ea3 100644
--- a/modules/mail/e-mail-shell-backend.h
+++ b/modules/mail/e-mail-shell-backend.h
@@ -22,7 +22,6 @@
 #ifndef E_MAIL_SHELL_BACKEND_H
 #define E_MAIL_SHELL_BACKEND_H
 
-#include <libedataserver/e-account.h>
 #include <mail/e-mail-backend.h>
 
 /* Standard GObject macros */
@@ -69,7 +68,7 @@ void		e_mail_shell_backend_new_account
 void		e_mail_shell_backend_edit_account
 						(EMailShellBackend *mail_shell_backend,
 						 GtkWindow *parent,
-						 EAccount *account);
+						 ESource *mail_account);
 
 /* XXX Find a better place for this function. */
 GSList *	e_mail_labels_get_filter_options (void);
diff --git a/modules/mail/e-mail-shell-view-actions.c b/modules/mail/e-mail-shell-view-actions.c
index 5de1e50..afe347c 100644
--- a/modules/mail/e-mail-shell-view-actions.c
+++ b/modules/mail/e-mail-shell-view-actions.c
@@ -118,9 +118,12 @@ action_mail_account_properties_cb (GtkAction *action,
                                    EMailShellView *mail_shell_view)
 {
 	EMailShellSidebar *mail_shell_sidebar;
+	EShell *shell;
 	EShellView *shell_view;
 	EShellWindow *shell_window;
 	EShellBackend *shell_backend;
+	ESourceRegistry *registry;
+	ESource *source;
 	EMFolderTree *folder_tree;
 	CamelService *service;
 	CamelStore *store;
@@ -131,6 +134,7 @@ action_mail_account_properties_cb (GtkAction *action,
 	shell_view = E_SHELL_VIEW (mail_shell_view);
 	shell_backend = e_shell_view_get_shell_backend (shell_view);
 	shell_window = e_shell_view_get_shell_window (shell_view);
+	shell = e_shell_backend_get_shell (shell_backend);
 
 	folder_tree = e_mail_shell_sidebar_get_folder_tree (mail_shell_sidebar);
 	store = em_folder_tree_get_selected_store (folder_tree);
@@ -138,11 +142,15 @@ action_mail_account_properties_cb (GtkAction *action,
 
 	service = CAMEL_SERVICE (store);
 	uid = camel_service_get_uid (service);
-
+	registry = e_shell_get_registry (shell);
+	source = e_source_registry_ref_source (registry, uid);
+	g_return_if_fail (source != NULL);
+	
 	e_mail_shell_backend_edit_account (
 		E_MAIL_SHELL_BACKEND (shell_backend),
-		GTK_WINDOW (shell_window),
-		e_get_account_by_uid (uid));
+		GTK_WINDOW (shell_window), source);
+
+	g_object_unref (source);
 }
 
 static void
@@ -841,24 +849,58 @@ static void
 action_mail_send_receive_cb (GtkAction *action,
                              EMailShellView *mail_shell_view)
 {
-	e_mail_shell_view_send_receive (
-		mail_shell_view, E_MAIL_SEND_RECEIVE_BOTH, NULL);
+	EShellView *shell_view;
+	EShellWindow *shell_window;
+	EShellBackend *shell_backend;
+	EMailBackend *backend;
+	EMailSession *session;
+
+	shell_view = E_SHELL_VIEW (mail_shell_view);
+	shell_window = e_shell_view_get_shell_window (shell_view);
+	shell_backend = e_shell_view_get_shell_backend (shell_view);
+
+	backend = E_MAIL_BACKEND (shell_backend);
+	session = e_mail_backend_get_session (backend);
+
+	mail_send_receive (GTK_WINDOW (shell_window), session);
 }
 
 static void
 action_mail_send_receive_receive_all_cb (GtkAction *action,
                                          EMailShellView *mail_shell_view)
 {
-	e_mail_shell_view_send_receive (
-		mail_shell_view, E_MAIL_SEND_RECEIVE_RECEIVE, NULL);
+	EShellView *shell_view;
+	EShellWindow *shell_window;
+	EShellBackend *shell_backend;
+	EMailBackend *backend;
+	EMailSession *session;
+
+	shell_view = E_SHELL_VIEW (mail_shell_view);
+	shell_window = e_shell_view_get_shell_window (shell_view);
+	shell_backend = e_shell_view_get_shell_backend (shell_view);
+
+	backend = E_MAIL_BACKEND (shell_backend);
+	session = e_mail_backend_get_session (backend);
+
+	mail_receive (GTK_WINDOW (shell_window), session);
 }
 
 static void
 action_mail_send_receive_send_all_cb (GtkAction *action,
                                       EMailShellView *mail_shell_view)
 {
-	e_mail_shell_view_send_receive (
-		mail_shell_view, E_MAIL_SEND_RECEIVE_SEND, NULL);
+	EShellView *shell_view;
+	EShellBackend *shell_backend;
+	EMailBackend *backend;
+	EMailSession *session;
+
+	shell_view = E_SHELL_VIEW (mail_shell_view);
+	shell_backend = e_shell_view_get_shell_backend (shell_view);
+
+	backend = E_MAIL_BACKEND (shell_backend);
+	session = e_mail_backend_get_session (backend);
+
+	mail_send (session);
 }
 
 static void
diff --git a/modules/mail/e-mail-shell-view-private.c b/modules/mail/e-mail-shell-view-private.c
index e043d7d..002d4cc 100644
--- a/modules/mail/e-mail-shell-view-private.c
+++ b/modules/mail/e-mail-shell-view-private.c
@@ -890,10 +890,13 @@ void
 e_mail_shell_view_update_sidebar (EMailShellView *mail_shell_view)
 {
 	EMailShellContent *mail_shell_content;
+	EShellBackend *shell_backend;
 	EShellSidebar *shell_sidebar;
 	EShellView *shell_view;
+	EShell *shell;
 	EMailReader *reader;
 	EMailView *mail_view;
+	ESourceRegistry *registry;
 	CamelStore *parent_store;
 	CamelFolder *folder;
 	GPtrArray *uids;
@@ -915,8 +918,12 @@ e_mail_shell_view_update_sidebar (EMailShellView *mail_shell_view)
 	mail_view = e_mail_shell_content_get_mail_view (mail_shell_content);
 
 	shell_view = E_SHELL_VIEW (mail_shell_view);
+	shell_backend = e_shell_view_get_shell_backend (shell_view);
 	shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
 
+	shell = e_shell_backend_get_shell (shell_backend);
+	registry = e_shell_get_registry (shell);
+
 	reader = E_MAIL_READER (mail_view);
 	folder = e_mail_reader_get_folder (reader);
 
@@ -979,19 +986,19 @@ e_mail_shell_view_update_sidebar (EMailShellView *mail_shell_view)
 				num_junked), num_junked);
 
 	/* "Drafts" folder */
-	} else if (em_utils_folder_is_drafts (folder)) {
+	} else if (em_utils_folder_is_drafts (registry, folder)) {
 		g_string_append_printf (
 			buffer, ngettext ("%d draft", "%d drafts",
 			num_visible), num_visible);
 
 	/* "Outbox" folder */
-	} else if (em_utils_folder_is_outbox (folder)) {
+	} else if (em_utils_folder_is_outbox (registry, folder)) {
 		g_string_append_printf (
 			buffer, ngettext ("%d unsent", "%d unsent",
 			num_visible), num_visible);
 
 	/* "Sent" folder */
-	} else if (em_utils_folder_is_sent (folder)) {
+	} else if (em_utils_folder_is_sent (registry, folder)) {
 		g_string_append_printf (
 			buffer, ngettext ("%d sent", "%d sent",
 			num_visible), num_visible);
@@ -1044,308 +1051,195 @@ e_mail_shell_view_update_sidebar (EMailShellView *mail_shell_view)
 	g_string_free (buffer, TRUE);
 }
 
-void
-e_mail_shell_view_send_receive (EMailShellView *mail_shell_view,
-                                EMailSendReceiveMode mode,
-                                const gchar *account_uid)
-{
-	EShellView *shell_view;
-	EShellWindow *shell_window;
-	EShellBackend *shell_backend;
-	EMailBackend *backend;
-	EMailSession *session;
-
-	g_return_if_fail (mail_shell_view != NULL);
+typedef struct {
+	GtkMenuShell *menu;
+	CamelSession *session;
+	ESourceRegistry *registry;
 
-	shell_view = E_SHELL_VIEW (mail_shell_view);
-	shell_window = e_shell_view_get_shell_window (shell_view);
-	shell_backend = e_shell_view_get_shell_backend (shell_view);
+	/* GtkMenuItem -> ESource */
+	GHashTable *menu_items;
 
-	backend = E_MAIL_BACKEND (shell_backend);
-	session = e_mail_backend_get_session (backend);
-
-	em_utils_clear_get_password_canceled_accounts_flag ();
-
-	if (!account_uid) {
-		switch (mode) {
-		case E_MAIL_SEND_RECEIVE_BOTH:
-			mail_send_receive (GTK_WINDOW (shell_window), session);
-			break;
-		case E_MAIL_SEND_RECEIVE_RECEIVE:
-			mail_receive (GTK_WINDOW (shell_window), session);
-			break;
-		case E_MAIL_SEND_RECEIVE_SEND:
-			mail_send (session);
-			break;
-		}
-	} else {
-		/* allow only receive on individual accounts */
-		EAccount *account;
-		CamelService *service;
-
-		account = e_get_account_by_uid (account_uid);
-		g_return_if_fail (account != NULL);
-
-		if (!account->enabled)
-			return;
-
-		service = camel_session_get_service (
-			CAMEL_SESSION (session), account->uid);
-
-		mail_receive_service (service);
-	}
-}
+	/* Signal handlers */
+	gulong source_added_id;
+	gulong source_removed_id;
+} SendReceiveData;
 
 static GtkMenuItem *
-send_receive_find_account_menu_item (GtkMenuShell *menu,
-                                     EAccount *account)
+send_receive_find_menu_item (SendReceiveData *data,
+                             gpointer source)
 {
-	GList *children, *child;
+	GHashTableIter iter;
+	gpointer menu_item;
+	gpointer candidate;
 
-	g_return_val_if_fail (menu != NULL, NULL);
-	g_return_val_if_fail (account != NULL, NULL);
-	g_return_val_if_fail (account->uid != NULL, NULL);
+	g_hash_table_iter_init (&iter, data->menu_items);
 
-	children = gtk_container_get_children (GTK_CONTAINER (menu));
-
-	for (child = children; child != NULL; child = child->next) {
-		GObject *obj = child->data;
-		const gchar *uid;
-
-		if (!obj)
-			continue;
-
-		uid = g_object_get_data (obj, "e-account-uid");
-		if (!uid)
-			continue;
-
-		if (g_strcmp0 (uid, account->uid) == 0) {
-			g_list_free (children);
-
-			return GTK_MENU_ITEM (obj);
-		}
-	}
-
-	g_list_free (children);
+	while (g_hash_table_iter_next (&iter, &menu_item, &candidate))
+		if (source == candidate)
+			return GTK_MENU_ITEM (menu_item);
 
 	return NULL;
 }
 
-static gint
-send_receive_get_account_index (EAccount *account)
-{
-	gint res;
-	EAccountList *accounts;
-	EIterator *iterator;
-
-	g_return_val_if_fail (account != NULL, -1);
-
-	accounts = e_get_account_list ();
-	g_return_val_if_fail (accounts != NULL, -1);
-
-	res = 0;
-	for (iterator = e_list_get_iterator (E_LIST (accounts));
-	     e_iterator_is_valid (iterator);
-	     e_iterator_next (iterator)) {
-		EAccount *candidate;
-		const gchar *name;
-
-		candidate = (EAccount *) e_iterator_get (iterator);
-
-		if (candidate == NULL)
-			continue;
-
-		if (!candidate->enabled)
-			continue;
-
-		if (candidate->source == NULL)
-			continue;
-
-		if (candidate->source->url == NULL)
-			continue;
-
-		if (*candidate->source->url == '\0')
-			continue;
-
-		name = e_account_get_string (candidate, E_ACCOUNT_NAME);
-		if (name == NULL || *name == '\0')
-			continue;
-
-		if (candidate->uid == NULL)
-			continue;
-
-		if (*candidate->uid == '\0')
-			continue;
-
-		if (g_strcmp0 (candidate->uid, account->uid) == 0) {
-			g_object_unref (iterator);
-			return res;
-		}
-
-		res++;
-	}
-
-	g_object_unref (iterator);
-
-	return -1;
-}
-
 static void
-send_receive_account_item_activate_cb (GtkMenuItem *item,
-                                       GtkMenuShell *menu)
+send_receive_account_item_activate_cb (GtkMenuItem *menu_item,
+                                       SendReceiveData *data)
 {
-	EMailShellView *mail_shell_view;
-	const gchar *account_uid;
+	ESource *source;
+	CamelService *service;
+	const gchar *uid;
 
-	g_return_if_fail (item != NULL);
-	g_return_if_fail (menu != NULL);
+	source = g_hash_table_lookup (data->menu_items, menu_item);
+	g_return_if_fail (E_IS_SOURCE (source));
 
-	mail_shell_view = g_object_get_data (G_OBJECT (menu), "mail-shell-view");
-	g_return_if_fail (mail_shell_view != NULL);
+	/* Shouldn't get here if the source is disabled. */
+	g_return_if_fail (e_source_get_enabled (source));
 
-	account_uid = g_object_get_data (G_OBJECT (item), "e-account-uid");
-	g_return_if_fail (account_uid != NULL);
+	uid = e_source_get_uid (source);
+	service = camel_session_get_service (data->session, uid);
+	g_return_if_fail (CAMEL_IS_SERVICE (service));
 
-	e_mail_shell_view_send_receive (
-		mail_shell_view, E_MAIL_SEND_RECEIVE_RECEIVE, account_uid);
+	mail_receive_service (service);
 }
 
 static void
-send_receive_add_to_menu (GtkMenuShell *menu,
-                          EAccount *account,
-                          gint insert_index)
+send_receive_add_to_menu (SendReceiveData *data,
+                          ESource *source,
+                          gint position)
 {
-	const gchar *name;
-	GtkWidget *item;
-
-	g_return_if_fail (menu != NULL);
-	g_return_if_fail (account != NULL);
-
-	if (send_receive_find_account_menu_item (menu, account) != NULL)
-		return;
-
-	if (account->source == NULL)
-		return;
+	GtkWidget *menu_item;
 
-	if (account->source->url == NULL)
+	if (send_receive_find_menu_item (data, source) != NULL)
 		return;
 
-	if (*account->source->url == '\0')
-		return;
+	menu_item = gtk_menu_item_new ();
+	gtk_widget_show (menu_item);
 
-	name = e_account_get_string (account, E_ACCOUNT_NAME);
-	if (name == NULL || *name == '\0')
-		return;
+	g_object_bind_property (
+		source, "display-name",
+		menu_item, "label",
+		G_BINDING_SYNC_CREATE);
 
-	if (account->uid == NULL)
-		return;
+	g_object_bind_property (
+		source, "enabled",
+		menu_item, "visible",
+		G_BINDING_SYNC_CREATE);
 
-	if (*account->uid == '\0')
-		return;
+	g_hash_table_insert (
+		data->menu_items, menu_item,
+		g_object_ref (source));
 
-	item = gtk_menu_item_new_with_label (name);
-	gtk_widget_show (item);
-	g_object_set_data_full (
-		G_OBJECT (item), "e-account-uid",
-		g_strdup (account->uid), g_free);
 	g_signal_connect (
-		item, "activate",
-		G_CALLBACK (send_receive_account_item_activate_cb), menu);
+		menu_item, "activate",
+		G_CALLBACK (send_receive_account_item_activate_cb), data);
 
-	/* it's index between accounts, not in the menu */
-	if (insert_index < 0)
-		gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+	/* Position is with respect to the sorted list of ESources
+	 * with a mail account extension, not menu item position. */
+	if (position < 0)
+		gtk_menu_shell_append (data->menu, menu_item);
 	else
-		gtk_menu_shell_insert (
-			GTK_MENU_SHELL (menu), item, insert_index + 4);
+		gtk_menu_shell_insert (data->menu, menu_item, position + 4);
 }
 
 static void
-send_receive_remove_from_menu (GtkMenuShell *menu,
-                               EAccount *account)
+send_receive_menu_source_added_cb (ESourceRegistry *registry,
+                                   ESource *source,
+                                   SendReceiveData *data)
 {
-	GtkMenuItem *item;
-
-	g_return_if_fail (menu != NULL);
-	g_return_if_fail (account != NULL);
+	const gchar *extension_name;
+	GList *list;
+	gint position;
 
-	item = send_receive_find_account_menu_item (menu, account);
-	if (item == NULL)
+	extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+	if (!e_source_has_extension (source, extension_name))
 		return;
 
-	gtk_container_remove (GTK_CONTAINER (menu), GTK_WIDGET (item));
+	/* List is already sorted by display name. */
+	list = e_source_registry_list_sources (data->registry, extension_name);
+	position = g_list_index (list, source);
+	g_list_free_full (list, (GDestroyNotify) g_object_unref);
+
+	send_receive_add_to_menu (data, source, position);
 }
 
 static void
-send_receive_menu_account_added_cb (EAccountList *list,
-                                    EAccount *account,
-                                    GtkMenuShell *menu)
+send_receive_menu_source_removed_cb (ESourceRegistry *registry,
+                                     ESource *source,
+                                     SendReceiveData *data)
 {
-	g_return_if_fail (account != NULL);
-	g_return_if_fail (menu != NULL);
+	GtkMenuItem *menu_item;
+	const gchar *extension_name;
 
-	if (account->enabled)
-		send_receive_add_to_menu (
-			menu, account,
-			send_receive_get_account_index (account));
-}
+	extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+	if (!e_source_has_extension (source, extension_name))
+		return;
 
-static void
-send_receive_menu_account_changed_cb (EAccountList *list,
-                                      EAccount *account,
-                                      GtkMenuShell *menu)
-{
-	g_return_if_fail (account != NULL);
-	g_return_if_fail (menu != NULL);
-
-	if (account->enabled) {
-		GtkMenuItem *item;
-
-		item = send_receive_find_account_menu_item (menu, account);
-
-		if (item) {
-			if (account->source == NULL ||
-				account->source->url == NULL ||
-				*account->source->url == '\0') {
-				send_receive_remove_from_menu (menu, account);
-			} else {
-				const gchar *name;
-
-				name = e_account_get_string (
-					account, E_ACCOUNT_NAME);
-				if (name != NULL && *name != '\0')
-					gtk_menu_item_set_label (item, name);
-			}
-		} else {
-			send_receive_add_to_menu (
-				menu, account,
-				send_receive_get_account_index (account));
-		}
-	} else {
-		send_receive_remove_from_menu (menu, account);
-	}
+	menu_item = send_receive_find_menu_item (data, source);
+	if (menu_item == NULL)
+		return;
+
+	g_hash_table_remove (data->menu_items, menu_item);
+
+	gtk_container_remove (
+		GTK_CONTAINER (data->menu),
+		GTK_WIDGET (menu_item));
 }
 
 static void
-send_receive_menu_account_removed_cb (EAccountList *list,
-                                      EAccount *account,
-                                      GtkMenuShell *menu)
+send_receive_data_free (SendReceiveData *data)
 {
-	g_return_if_fail (account != NULL);
-	g_return_if_fail (menu != NULL);
+	g_signal_handler_disconnect (data->registry, data->source_added_id);
+	g_signal_handler_disconnect (data->registry, data->source_removed_id);
 
-	send_receive_remove_from_menu (menu, account);
+	g_object_unref (data->session);
+	g_object_unref (data->registry);
+
+	g_hash_table_destroy (data->menu_items);
+
+	g_slice_free (SendReceiveData, data);
 }
 
-static void
-menu_weak_ref_cb (gpointer accounts,
-                  GObject *where_the_object_was)
+static SendReceiveData *
+send_receive_data_new (EMailShellView *mail_shell_view,
+                       GtkWidget *menu)
 {
-	g_return_if_fail (accounts != NULL);
+	SendReceiveData *data;
+	EShellView *shell_view;
+	EShellBackend *shell_backend;
+	ESourceRegistry *registry;
+	EMailBackend *backend;
+	EMailSession *session;
+
+	shell_view = E_SHELL_VIEW (mail_shell_view);
+	shell_backend = e_shell_view_get_shell_backend (shell_view);
 
-	g_signal_handlers_disconnect_matched (
-		accounts, G_SIGNAL_MATCH_DATA,
-		0, 0, NULL, NULL, where_the_object_was);
+	backend = E_MAIL_BACKEND (shell_backend);
+	session = e_mail_backend_get_session (backend);
+	registry = e_mail_session_get_registry (session);
+
+	data = g_slice_new0 (SendReceiveData);
+	data->menu = GTK_MENU_SHELL (menu);  /* do not reference */
+	data->session = g_object_ref (session);
+	data->registry = g_object_ref (registry);
+
+	data->menu_items = g_hash_table_new_full (
+		(GHashFunc) g_direct_hash,
+		(GEqualFunc) g_direct_equal,
+		(GDestroyNotify) NULL,
+		(GDestroyNotify) g_object_unref);
+
+	data->source_added_id = g_signal_connect (
+		registry, "source-added",
+		G_CALLBACK (send_receive_menu_source_added_cb), data);
+	data->source_removed_id = g_signal_connect (
+		registry, "source-removed",
+		G_CALLBACK (send_receive_menu_source_removed_cb), data);
+
+	g_object_weak_ref (
+		G_OBJECT (menu), (GWeakNotify)
+		send_receive_data_free, data);
+
+	return data;
 }
 
 static GtkWidget *
@@ -1353,18 +1247,28 @@ create_send_receive_submenu (EMailShellView *mail_shell_view)
 {
 	EShellView *shell_view;
 	EShellWindow *shell_window;
-	EAccountList *accounts;
+	EShellBackend *shell_backend;
+	ESourceRegistry *registry;
+	EMailBackend *backend;
+	EMailSession *session;
 	GtkWidget *menu;
 	GtkAccelGroup *accel_group;
 	GtkUIManager *ui_manager;
 	GtkAction *action;
+	GList *list, *link;
+	SendReceiveData *data;
+	const gchar *extension_name;
 
 	g_return_val_if_fail (mail_shell_view != NULL, NULL);
 
 	shell_view = E_SHELL_VIEW (mail_shell_view);
 	shell_window = e_shell_view_get_shell_window (shell_view);
+	shell_backend = e_shell_view_get_shell_backend (shell_view);
+
+	backend = E_MAIL_BACKEND (shell_backend);
+	session = e_mail_backend_get_session (backend);
+	registry = e_mail_session_get_registry (session);
 
-	accounts = e_get_account_list ();
 	menu = gtk_menu_new ();
 	ui_manager = e_shell_window_get_ui_manager (shell_window);
 	accel_group = gtk_ui_manager_get_accel_group (ui_manager);
@@ -1393,46 +1297,18 @@ create_send_receive_submenu (EMailShellView *mail_shell_view)
 		GTK_MENU_SHELL (menu),
 		gtk_separator_menu_item_new ());
 
-	if (accounts) {
-		EIterator *iterator;
-
-		for (iterator = e_list_get_iterator (E_LIST (accounts));
-		     e_iterator_is_valid (iterator);
-		     e_iterator_next (iterator)) {
-			EAccount *account;
+	data = send_receive_data_new (mail_shell_view, menu);
 
-			account = (EAccount *) e_iterator_get (iterator);
+	extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+	list = e_source_registry_list_sources (registry, extension_name);
 
-			if (account == NULL)
-				continue;
+	for (link = list; link != NULL; link = g_list_next (link))
+		send_receive_add_to_menu (data, E_SOURCE (link->data), -1);
 
-			if (!account->enabled)
-				continue;
-
-			send_receive_add_to_menu (
-				GTK_MENU_SHELL (menu), account, -1);
-		}
-
-		g_object_unref (iterator);
-
-		g_signal_connect (
-			accounts, "account-added",
-			G_CALLBACK (send_receive_menu_account_added_cb), menu);
-		g_signal_connect (
-			accounts, "account-changed",
-			G_CALLBACK (send_receive_menu_account_changed_cb), menu);
-		g_signal_connect (
-			accounts, "account-removed",
-			G_CALLBACK (send_receive_menu_account_removed_cb), menu);
-
-		g_object_weak_ref (
-			G_OBJECT (menu), menu_weak_ref_cb, accounts);
-	}
+	g_list_free_full (list, (GDestroyNotify) g_object_unref);
 
 	gtk_widget_show_all (menu);
 
-	g_object_set_data (G_OBJECT (menu), "mail-shell-view", mail_shell_view);
-
 	return menu;
 }
 
diff --git a/modules/mail/e-mail-shell-view-private.h b/modules/mail/e-mail-shell-view-private.h
index 2a884f4..f9c3ba2 100644
--- a/modules/mail/e-mail-shell-view-private.h
+++ b/modules/mail/e-mail-shell-view-private.h
@@ -27,14 +27,13 @@
 #include <glib/gi18n.h>
 #include <gtkhtml/gtkhtml.h>
 #include <camel/camel-search-private.h>  /* for camel_search_word */
+#include <libedataserver/e-source-mail-account.h>
 
 #include <e-util/e-util.h>
 #include <e-util/e-ui-manager.h>
 
 #include <filter/e-filter-part.h>
 
-#include <libemail-utils/e-account-utils.h>
-
 #include <libemail-engine/e-mail-folder-utils.h>
 #include <libemail-engine/e-mail-session.h>
 #include <libemail-engine/e-mail-session-utils.h>
@@ -133,12 +132,6 @@ enum {
 	MAIL_SCOPE_ALL_ACCOUNTS
 };
 
-typedef enum  {
-	E_MAIL_SEND_RECEIVE_BOTH,
-	E_MAIL_SEND_RECEIVE_RECEIVE,
-	E_MAIL_SEND_RECEIVE_SEND
-} EMailSendReceiveMode;
-
 struct _EMailShellViewPrivate {
 
 	/*** Other Stuff ***/
@@ -194,10 +187,6 @@ void		e_mail_shell_view_update_search_filter
 					(EMailShellView *mail_shell_view);
 void		e_mail_shell_view_update_sidebar
 					(EMailShellView *mail_shell_view);
-void		e_mail_shell_view_send_receive
-					(EMailShellView *mail_shell_view,
-					 EMailSendReceiveMode mode,
-					 const gchar *account_uid);
 void		e_mail_shell_view_update_send_receive_menus
 					(EMailShellView *mail_shell_view);
 
diff --git a/modules/mail/e-mail-shell-view.c b/modules/mail/e-mail-shell-view.c
index 1a08251..cbcf24f 100644
--- a/modules/mail/e-mail-shell-view.c
+++ b/modules/mail/e-mail-shell-view.c
@@ -223,6 +223,7 @@ mail_shell_view_execute_search (EShellView *shell_view)
 	EMailBackend *backend;
 	EMailSession *session;
 	MailFolderCache *cache;
+	ESourceRegistry *registry;
 	EMFolderTree *folder_tree;
 	GtkWidget *message_list;
 	EFilterRule *rule;
@@ -269,6 +270,7 @@ mail_shell_view_execute_search (EShellView *shell_view)
 	folder = e_mail_reader_get_folder (reader);
 	message_list = e_mail_reader_get_message_list (reader);
 
+	registry = e_mail_session_get_registry (session);
 	label_store = e_mail_ui_session_get_label_store (E_MAIL_UI_SESSION (session));
 
 	action = ACTION (MAIL_SEARCH_SUBJECT_OR_ADDRESSES_CONTAIN);
@@ -388,7 +390,7 @@ filter:
 			break;
 
 		case MAIL_FILTER_RECENT_MESSAGES:
-			if (em_utils_folder_is_sent (folder))
+			if (em_utils_folder_is_sent (registry, folder))
 				temp = g_strdup_printf (
 					"(and %s (match-all "
 					"(> (get-sent-date) "
@@ -405,7 +407,7 @@ filter:
 			break;
 
 		case MAIL_FILTER_LAST_5_DAYS_MESSAGES:
-			if (em_utils_folder_is_sent (folder))
+			if (em_utils_folder_is_sent (registry, folder))
 				temp = g_strdup_printf (
 					"(and %s (match-all "
 					"(> (get-sent-date) "
@@ -808,12 +810,14 @@ mail_shell_view_update_actions (EShellView *shell_view)
 	EMailShellSidebar *mail_shell_sidebar;
 	EShellSidebar *shell_sidebar;
 	EShellWindow *shell_window;
+	EShell *shell;
 	EMFolderTree *folder_tree;
 	EMFolderTreeModel *model;
 	EMailReader *reader;
 	EMailView *mail_view;
 	CamelStore *store;
-	EAccount *account;
+	ESourceRegistry *registry;
+	ESource *source = NULL;
 	GtkAction *action;
 	GList *list, *link;
 	const gchar *label;
@@ -839,6 +843,8 @@ mail_shell_view_update_actions (EShellView *shell_view)
 	E_SHELL_VIEW_CLASS (parent_class)->update_actions (shell_view);
 
 	shell_window = e_shell_view_get_shell_window (shell_view);
+	shell = e_shell_window_get_shell (shell_window);
+	registry = e_shell_get_registry (shell);
 
 	mail_shell_view = E_MAIL_SHELL_VIEW (shell_view);
 	mail_shell_content = mail_shell_view->priv->mail_shell_content;
@@ -880,11 +886,29 @@ mail_shell_view_update_actions (EShellView *shell_view)
 
 		service = CAMEL_SERVICE (store);
 		uid = camel_service_get_uid (service);
-		account = e_get_account_by_uid (uid);
-
+		source = e_source_registry_ref_source (registry, uid);
 		store_is_vstore = g_strcmp0 (uid, E_MAIL_SESSION_VFOLDER_UID) == 0;
-	} else
-		account = NULL;
+	}
+
+	if (source != NULL) {
+		ESourceExtension *extension;
+		const gchar *backend_name;
+		const gchar *extension_name;
+
+		extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+		extension = e_source_get_extension (source, extension_name);
+
+		backend_name =
+			e_source_backend_get_backend_name (
+			E_SOURCE_BACKEND (extension));
+
+		/* FIXME This belongs in a GroupWise plugin. */
+		account_is_groupwise =
+			(g_strcmp0 (backend_name, "groupwise") == 0) &&
+			(e_source_get_parent (source) != NULL);
+
+		g_object_unref (source);
+	}
 
 	if (uri != NULL) {
 		GtkTreeRowReference *reference;
@@ -908,11 +932,6 @@ mail_shell_view_update_actions (EShellView *shell_view)
 			g_free (folder_uri);
 		}
 
-		/* FIXME This belongs in a GroupWise plugin. */
-		account_is_groupwise =
-			(g_strrstr (uri, "groupwise://") != NULL) &&
-			account != NULL && account->parent_uid != NULL;
-
 		reference = em_folder_tree_model_lookup_uri (model, uri);
 		if (reference != NULL) {
 			GtkTreePath *path;
@@ -943,7 +962,7 @@ mail_shell_view_update_actions (EShellView *shell_view)
 	g_list_free (list);
 
 	action = ACTION (MAIL_ACCOUNT_DISABLE);
-	sensitive = (account != NULL) && folder_is_store;
+	sensitive = (store != NULL) && folder_is_store;
 	if (account_is_groupwise)
 		label = _("Proxy _Logout");
 	else
@@ -956,7 +975,7 @@ mail_shell_view_update_actions (EShellView *shell_view)
 	gtk_action_set_sensitive (action, sensitive);
 
 	action = ACTION (MAIL_ACCOUNT_PROPERTIES);
-	sensitive = account != NULL && folder_is_store;
+	sensitive = (store != NULL) && folder_is_store;
 	gtk_action_set_sensitive (action, sensitive);
 
 	action = ACTION (MAIL_FLUSH_OUTBOX);
diff --git a/modules/mail/em-account-prefs.c b/modules/mail/em-account-prefs.c
index 95a9f30..17af8a4 100644
--- a/modules/mail/em-account-prefs.c
+++ b/modules/mail/em-account-prefs.c
@@ -38,12 +38,9 @@
 
 #include <shell/e-shell.h>
 
-#include <libemail-utils/e-account-utils.h>
-
 #include <mail/e-mail-backend.h>
 #include <mail/e-mail-ui-session.h>
 #include <mail/em-config.h>
-#include <mail/em-account-editor.h>
 #include <mail/em-utils.h>
 #include <mail/mail-vfolder-ui.h>
 
@@ -183,7 +180,7 @@ account_prefs_add_account (EMailAccountManager *manager)
 
 static void
 account_prefs_edit_account (EMailAccountManager *manager,
-                            EAccount *account)
+                            ESource *source)
 {
 	EMAccountPrefsPrivate *priv;
 	gpointer parent;
@@ -194,7 +191,7 @@ account_prefs_edit_account (EMailAccountManager *manager,
 	parent = gtk_widget_is_toplevel (parent) ? parent : NULL;
 
 	e_mail_shell_backend_edit_account (
-		E_MAIL_SHELL_BACKEND (priv->backend), parent, account);
+		E_MAIL_SHELL_BACKEND (priv->backend), parent, source);
 }
 
 static void
diff --git a/modules/mail/em-composer-prefs.c b/modules/mail/em-composer-prefs.c
index a71a8cf..647e789 100644
--- a/modules/mail/em-composer-prefs.c
+++ b/modules/mail/em-composer-prefs.c
@@ -41,16 +41,12 @@
 #include <e-util/e-util.h>
 #include <e-util/e-util-private.h>
 
-#include <libemail-utils/e-signature-utils.h>
-
 #include <composer/e-msg-composer.h>
 
 #include <shell/e-shell-utils.h>
 
 #include <misc/e-charset-combo-box.h>
-#include <misc/e-signature-editor.h>
-#include <misc/e-signature-manager.h>
-#include <misc/e-signature-preview.h>
+#include <misc/e-mail-signature-manager.h>
 
 #include <mail/em-config.h>
 #include <mail/em-folder-selection-button.h>
@@ -323,8 +319,7 @@ em_composer_prefs_construct (EMComposerPrefs *prefs,
 	GtkWidget *toplevel, *widget, *info_pixmap;
 	GtkWidget *container;
 	EShellSettings *shell_settings;
-	ESignatureList *signature_list;
-	ESignatureTreeView *signature_tree_view;
+	ESourceRegistry *registry;
 	GtkTreeView *view;
 	GtkListStore *store;
 	GtkTreeSelection *selection;
@@ -334,6 +329,7 @@ em_composer_prefs_construct (EMComposerPrefs *prefs,
 	GSList *l;
 	gint i;
 
+	registry = e_shell_get_registry (shell);
 	shell_settings = e_shell_get_shell_settings (shell);
 
 	/* Make sure our custom widget classes are registered with
@@ -551,10 +547,9 @@ em_composer_prefs_construct (EMComposerPrefs *prefs,
 		NULL, (GDestroyNotify) NULL);
 
 	/* Signatures */
-	signature_list = e_get_signature_list ();
 	container = e_builder_get_widget (
 		prefs->builder, "signature-alignment");
-	widget = e_signature_manager_new (signature_list);
+	widget = e_mail_signature_manager_new (registry);
 	gtk_container_add (GTK_CONTAINER (container), widget);
 	gtk_widget_show (widget);
 
@@ -571,20 +566,6 @@ em_composer_prefs_construct (EMComposerPrefs *prefs,
 			widget, "prefer-html",
 			G_BINDING_SYNC_CREATE);
 
-	signature_tree_view = e_signature_manager_get_tree_view (
-		E_SIGNATURE_MANAGER (widget));
-
-	container = e_builder_get_widget (
-		prefs->builder, "signature-preview-scrolled-window");
-	widget = e_signature_preview_new ();
-	gtk_container_add (GTK_CONTAINER (container), widget);
-	gtk_widget_show (widget);
-
-	g_object_bind_property (
-		signature_tree_view, "selected",
-		widget, "signature",
-		G_BINDING_SYNC_CREATE);
-
 	/* Sanitize the dialog for Express mode */
 	e_shell_hide_widgets_for_express_mode (
 		shell, prefs->builder,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]