aboutsummaryrefslogtreecommitdiffstats
path: root/libemail-engine
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2011-04-13 22:30:40 +0800
committerMatthew Barnes <mbarnes@redhat.com>2012-06-03 11:00:40 +0800
commit3449e5fcc7f9c797fcde7f2a444b1eb7a934cd81 (patch)
treeff59febf4ac0c6316ef344ea25cee002088bd314 /libemail-engine
parentf78795f4dff8b225d78385c5e23e1cd44ee946ad (diff)
downloadgsoc2013-evolution-3449e5fcc7f9c797fcde7f2a444b1eb7a934cd81.tar.gz
gsoc2013-evolution-3449e5fcc7f9c797fcde7f2a444b1eb7a934cd81.tar.zst
gsoc2013-evolution-3449e5fcc7f9c797fcde7f2a444b1eb7a934cd81.zip
Adapt mail to the new ESource API.
Diffstat (limited to 'libemail-engine')
-rw-r--r--libemail-engine/Makefile.am2
-rw-r--r--libemail-engine/e-mail-authenticator.c267
-rw-r--r--libemail-engine/e-mail-authenticator.h76
-rw-r--r--libemail-engine/e-mail-session-utils.c40
-rw-r--r--libemail-engine/e-mail-session.c1055
-rw-r--r--libemail-engine/e-mail-session.h30
-rw-r--r--libemail-engine/e-mail-utils.c591
-rw-r--r--libemail-engine/e-mail-utils.h38
-rw-r--r--libemail-engine/mail-config.c21
-rw-r--r--libemail-engine/mail-config.h1
-rw-r--r--libemail-engine/mail-folder-cache.c11
-rw-r--r--libemail-engine/mail-ops.c360
-rw-r--r--libemail-engine/mail-ops.h1
13 files changed, 1711 insertions, 782 deletions
diff --git a/libemail-engine/Makefile.am b/libemail-engine/Makefile.am
index 4c64ea87e6..103a9d530f 100644
--- a/libemail-engine/Makefile.am
+++ b/libemail-engine/Makefile.am
@@ -22,6 +22,7 @@ libemail_engine_la_CPPFLAGS = \
libmailengineincludedir = $(privincludedir)/libemail-engine
libmailengineinclude_HEADERS = \
camel-null-store.h \
+ e-mail-authenticator.h \
e-mail-enums.h \
e-mail-enumtypes.h \
e-mail-folder-utils.h \
@@ -40,6 +41,7 @@ libmailengineinclude_HEADERS = \
libemail_engine_la_SOURCES = \
$(libmailengineinclude_HEADERS) \
camel-null-store.c \
+ e-mail-authenticator.c \
e-mail-enumtypes.c \
e-mail-folder-utils.c \
e-mail-junk-filter.c \
diff --git a/libemail-engine/e-mail-authenticator.c b/libemail-engine/e-mail-authenticator.c
new file mode 100644
index 0000000000..9729d35e1f
--- /dev/null
+++ b/libemail-engine/e-mail-authenticator.c
@@ -0,0 +1,267 @@
+/*
+ * e-mail-authenticator.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-authenticator.h"
+
+#include <config.h>
+#include <glib/gi18n-lib.h>
+
+#define E_MAIL_AUTHENTICATOR_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAIL_AUTHENTICATOR, EMailAuthenticatorPrivate))
+
+struct _EMailAuthenticatorPrivate {
+ CamelService *service;
+ gchar *mechanism;
+};
+
+enum {
+ PROP_0,
+ PROP_MECHANISM,
+ PROP_SERVICE
+};
+
+/* Forward Declarations */
+static void e_mail_authenticator_interface_init
+ (ESourceAuthenticatorInterface *interface);
+
+G_DEFINE_TYPE_WITH_CODE (
+ EMailAuthenticator,
+ e_mail_authenticator,
+ G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (
+ E_TYPE_SOURCE_AUTHENTICATOR,
+ e_mail_authenticator_interface_init))
+
+static void
+mail_authenticator_set_mechanism (EMailAuthenticator *auth,
+ const gchar *mechanism)
+{
+ g_return_if_fail (auth->priv->mechanism == NULL);
+
+ auth->priv->mechanism = g_strdup (mechanism);
+}
+
+static void
+mail_authenticator_set_service (EMailAuthenticator *auth,
+ CamelService *service)
+{
+ g_return_if_fail (CAMEL_IS_SERVICE (service));
+ g_return_if_fail (auth->priv->service == NULL);
+
+ auth->priv->service = g_object_ref (service);
+}
+
+static void
+mail_authenticator_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_MECHANISM:
+ mail_authenticator_set_mechanism (
+ E_MAIL_AUTHENTICATOR (object),
+ g_value_get_string (value));
+ return;
+
+ case PROP_SERVICE:
+ mail_authenticator_set_service (
+ E_MAIL_AUTHENTICATOR (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_authenticator_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_MECHANISM:
+ g_value_set_string (
+ value,
+ e_mail_authenticator_get_mechanism (
+ E_MAIL_AUTHENTICATOR (object)));
+ return;
+
+ case PROP_SERVICE:
+ g_value_set_object (
+ value,
+ e_mail_authenticator_get_service (
+ E_MAIL_AUTHENTICATOR (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_authenticator_dispose (GObject *object)
+{
+ EMailAuthenticatorPrivate *priv;
+
+ priv = E_MAIL_AUTHENTICATOR_GET_PRIVATE (object);
+
+ if (priv->service != NULL) {
+ g_object_unref (priv->service);
+ priv->service = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (e_mail_authenticator_parent_class)->dispose (object);
+}
+
+static void
+mail_authenticator_finalize (GObject *object)
+{
+ EMailAuthenticatorPrivate *priv;
+
+ priv = E_MAIL_AUTHENTICATOR_GET_PRIVATE (object);
+
+ g_free (priv->mechanism);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (e_mail_authenticator_parent_class)->finalize (object);
+}
+
+static ESourceAuthenticationResult
+mail_authenticator_try_password_sync (ESourceAuthenticator *auth,
+ const GString *password,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelService *service;
+ EMailAuthenticator *mail_auth;
+ CamelAuthenticationResult camel_result;
+ ESourceAuthenticationResult source_result;
+ const gchar *mechanism;
+
+ mail_auth = E_MAIL_AUTHENTICATOR (auth);
+ service = e_mail_authenticator_get_service (mail_auth);
+ mechanism = e_mail_authenticator_get_mechanism (mail_auth);
+
+ camel_service_set_password (service, password->str);
+
+ camel_result = camel_service_authenticate_sync (
+ service, mechanism, cancellable, error);
+
+ switch (camel_result) {
+ case CAMEL_AUTHENTICATION_ERROR:
+ source_result = E_SOURCE_AUTHENTICATION_ERROR;
+ break;
+ case CAMEL_AUTHENTICATION_ACCEPTED:
+ source_result = E_SOURCE_AUTHENTICATION_ACCEPTED;
+ break;
+ case CAMEL_AUTHENTICATION_REJECTED:
+ source_result = E_SOURCE_AUTHENTICATION_REJECTED;
+ break;
+ default:
+ g_set_error (
+ error, CAMEL_SERVICE_ERROR,
+ CAMEL_SERVICE_ERROR_CANT_AUTHENTICATE,
+ _("Invalid authentication result code (%d)"),
+ camel_result);
+ source_result = E_SOURCE_AUTHENTICATION_ERROR;
+ break;
+ }
+
+ return source_result;
+}
+
+static void
+e_mail_authenticator_class_init (EMailAuthenticatorClass *class)
+{
+ GObjectClass *object_class;
+
+ g_type_class_add_private (class, sizeof (EMailAuthenticatorPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = mail_authenticator_set_property;
+ object_class->get_property = mail_authenticator_get_property;
+ object_class->dispose = mail_authenticator_dispose;
+ object_class->finalize = mail_authenticator_finalize;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_MECHANISM,
+ g_param_spec_string (
+ "mechanism",
+ "Mechanism",
+ "Authentication mechanism",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SERVICE,
+ g_param_spec_object (
+ "service",
+ "Service",
+ "The CamelService to authenticate",
+ CAMEL_TYPE_SERVICE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+}
+
+static void
+e_mail_authenticator_interface_init (ESourceAuthenticatorInterface *interface)
+{
+ interface->try_password_sync = mail_authenticator_try_password_sync;
+}
+
+static void
+e_mail_authenticator_init (EMailAuthenticator *auth)
+{
+ auth->priv = E_MAIL_AUTHENTICATOR_GET_PRIVATE (auth);
+}
+
+ESourceAuthenticator *
+e_mail_authenticator_new (CamelService *service,
+ const gchar *mechanism)
+{
+ g_return_val_if_fail (CAMEL_IS_SERVICE (service), NULL);
+
+ return g_object_new (
+ E_TYPE_MAIL_AUTHENTICATOR,
+ "service", service, "mechanism", mechanism, NULL);
+}
+
+CamelService *
+e_mail_authenticator_get_service (EMailAuthenticator *auth)
+{
+ g_return_val_if_fail (E_IS_MAIL_AUTHENTICATOR (auth), NULL);
+
+ return auth->priv->service;
+}
+
+const gchar *
+e_mail_authenticator_get_mechanism (EMailAuthenticator *auth)
+{
+ g_return_val_if_fail (E_IS_MAIL_AUTHENTICATOR (auth), NULL);
+
+ return auth->priv->mechanism;
+}
+
diff --git a/libemail-engine/e-mail-authenticator.h b/libemail-engine/e-mail-authenticator.h
new file mode 100644
index 0000000000..bcc3299d1a
--- /dev/null
+++ b/libemail-engine/e-mail-authenticator.h
@@ -0,0 +1,76 @@
+/*
+ * e-mail-authenticator.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_AUTHENTICATOR_H
+#define E_MAIL_AUTHENTICATOR_H
+
+#include <camel/camel.h>
+#include <libedataserver/e-source-authenticator.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_AUTHENTICATOR \
+ (e_mail_authenticator_get_type ())
+#define E_MAIL_AUTHENTICATOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_AUTHENTICATOR, EMailAuthenticator))
+#define E_MAIL_AUTHENTICATOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_AUTHENTICATOR, EMailAuthenticatorClass))
+#define E_IS_MAIL_AUTHENTICATOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_AUTHENTICATOR))
+#define E_IS_MAIL_AUTHENTICATOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_AUTHENTICATOR))
+#define E_MAIL_AUTHENTICATOR_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_AUTHENTICATOR, EMailAuthenticatorClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailAuthenticator EMailAuthenticator;
+typedef struct _EMailAuthenticatorClass EMailAuthenticatorClass;
+typedef struct _EMailAuthenticatorPrivate EMailAuthenticatorPrivate;
+
+/**
+ * EMailAuthenticator:
+ *
+ * Contains only private data that should be read and manipulated using the
+ * functions below.
+ **/
+struct _EMailAuthenticator {
+ GObject parent;
+ EMailAuthenticatorPrivate *priv;
+};
+
+struct _EMailAuthenticatorClass {
+ GObjectClass parent_class;
+};
+
+GType e_mail_authenticator_get_type (void);
+ESourceAuthenticator *
+ e_mail_authenticator_new (CamelService *service,
+ const gchar *mechanism);
+CamelService * e_mail_authenticator_get_service
+ (EMailAuthenticator *auth);
+const gchar * e_mail_authenticator_get_mechanism
+ (EMailAuthenticator *auth);
+
+G_END_DECLS
+
+#endif /* E_MAIL_AUTHENTICATOR_H */
diff --git a/libemail-engine/e-mail-session-utils.c b/libemail-engine/e-mail-session-utils.c
index de1dec1713..26d4639867 100644
--- a/libemail-engine/e-mail-session-utils.c
+++ b/libemail-engine/e-mail-session-utils.c
@@ -23,11 +23,11 @@
#include "e-mail-session-utils.h"
#include <glib/gi18n-lib.h>
+#include <libedataserver/e-source-mail-submission.h>
#include <libemail-engine/e-mail-folder-utils.h>
#include <libemail-engine/e-mail-utils.h>
#include <libemail-engine/mail-tools.h>
-#include <libemail-utils/e-account-utils.h>
/* X-Mailer header value */
#define X_MAILER ("Evolution " VERSION SUB_VERSION " " VERSION_COMMENT)
@@ -671,7 +671,8 @@ e_mail_session_send_to (EMailSession *session,
CamelAddress *recipients;
CamelMedium *medium;
CamelMessageInfo *info;
- EAccount *account = NULL;
+ ESourceRegistry *registry;
+ ESource *source = NULL;
GPtrArray *post_to_uris;
struct _camel_header_raw *xev;
struct _camel_header_raw *header;
@@ -684,6 +685,8 @@ e_mail_session_send_to (EMailSession *session,
g_return_if_fail (E_IS_MAIL_SESSION (session));
g_return_if_fail (CAMEL_IS_MIME_MESSAGE (message));
+ registry = e_mail_session_get_registry (session);
+
medium = CAMEL_MEDIUM (message);
camel_medium_set_header (medium, "X-Mailer", X_MAILER);
@@ -692,28 +695,27 @@ e_mail_session_send_to (EMailSession *session,
/* Extract directives from X-Evolution headers. */
- string = camel_header_raw_find (&xev, "X-Evolution-Account", NULL);
+ string = camel_header_raw_find (&xev, "X-Evolution-Identity", NULL);
if (string != NULL) {
- gchar *account_uid;
-
- account_uid = g_strstrip (g_strdup (string));
- account = e_get_account_by_uid (account_uid);
- g_free (account_uid);
+ gchar *uid = g_strstrip (g_strdup (string));
+ source = e_source_registry_ref_source (registry, uid);
+ g_free (uid);
}
- if (account != NULL) {
- if (account->transport != NULL) {
+ if (E_IS_SOURCE (source)) {
+ ESourceMailSubmission *extension;
+ const gchar *extension_name;
- /* XXX Transport UIDs are kludgy right now. We
- * use the EAccount's regular UID and tack on
- * "-transport". Will be better soon. */
- transport_uid = g_strconcat (
- account->uid, "-transport", NULL);
+ extension_name = E_SOURCE_EXTENSION_MAIL_SUBMISSION;
+ extension = e_source_get_extension (source, extension_name);
- /* to reprompt password on sending if needed */
- account->transport->get_password_canceled = FALSE;
- }
- sent_folder_uri = g_strdup (account->sent_folder_uri);
+ string = e_source_mail_submission_get_sent_folder (extension);
+ sent_folder_uri = g_strdup (string);
+
+ string = e_source_mail_submission_get_transport_uid (extension);
+ transport_uid = g_strdup (string);
+
+ g_object_unref (source);
}
string = camel_header_raw_find (&xev, "X-Evolution-Fcc", NULL);
diff --git a/libemail-engine/e-mail-session.c b/libemail-engine/e-mail-session.c
index bc72e98652..ee1427ef7d 100644
--- a/libemail-engine/e-mail-session.c
+++ b/libemail-engine/e-mail-session.c
@@ -45,15 +45,22 @@
#include <libedataserver/e-flag.h>
#include <libedataserver/e-proxy.h>
#include <libebackend/e-extensible.h>
+#include <libedataserver/e-source-authentication.h>
+#include <libedataserver/e-source-camel.h>
+#include <libedataserver/e-source-mail-account.h>
+#include <libedataserver/e-source-mail-identity.h>
+#include <libedataserver/e-source-mail-submission.h>
+#include <libedataserver/e-source-mail-transport.h>
+#include <libedataserver/e-source-refresh.h>
#include <libedataserverui/e-passwords.h>
#include <libedataserver/e-data-server-util.h>
-#include "libemail-utils/e-account-utils.h"
#include "libemail-utils/mail-mt.h"
/* This is our hack, not part of libcamel. */
#include "camel-null-store.h"
+#include "e-mail-authenticator.h"
#include "e-mail-junk-filter.h"
#include "e-mail-session.h"
#include "e-mail-folder-utils.h"
@@ -70,9 +77,14 @@ typedef struct _AsyncContext AsyncContext;
struct _EMailSessionPrivate {
MailFolderCache *folder_cache;
+ ESourceRegistry *registry;
- EAccountList *account_list;
- gulong account_added_handler_id;
+ /* ESource UID -> Timeout ID */
+ GHashTable *auto_refresh_table;
+
+ gulong source_added_handler_id;
+ gulong source_removed_handler_id;
+ gulong default_mail_account_handler_id;
CamelStore *local_store;
CamelStore *vfolder_store;
@@ -101,6 +113,7 @@ enum {
PROP_FOLDER_CACHE,
PROP_JUNK_FILTER_NAME,
PROP_LOCAL_STORE,
+ PROP_REGISTRY,
PROP_VFOLDER_STORE
};
@@ -115,6 +128,7 @@ static const gchar *local_folder_names[E_MAIL_NUM_LOCAL_FOLDERS] = {
enum {
FLUSH_OUTBOX,
+ REFRESH_SERVICE,
STORE_ADDED,
STORE_REMOVED,
LAST_SIGNAL
@@ -317,21 +331,72 @@ async_context_free (AsyncContext *context)
}
static gchar *
-mail_session_make_key (CamelService *service,
- const gchar *item)
+mail_session_resolve_popb4smtp (ESourceRegistry *registry,
+ CamelService *smtp_service)
{
- gchar *key;
+ GList *list, *link;
+ const gchar *extension_name;
+ const gchar *smtp_uid;
+ gchar *pop_uid = NULL;
- if (service != NULL) {
- CamelURL *url;
+ /* Find a POP account that uses the given smtp_service as its
+ * transport. XXX This isn't foolproof though, since we don't
+ * check that the POP server is at the same domain as the SMTP
+ * server, which is kind of the point of POPB4SMTP. */
- url = camel_service_new_camel_url (service);
- key = camel_url_to_string (url, CAMEL_URL_HIDE_ALL);
- camel_url_free (url);
- } else
- key = g_strdup (item);
+ smtp_uid = camel_service_get_uid (smtp_service);
+ g_return_val_if_fail (smtp_uid != NULL, NULL);
+
+ 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)) {
+ ESource *source = E_SOURCE (link->data);
+ ESourceExtension *extension;
+ const gchar *backend_name;
+ gchar *uid;
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+ extension = e_source_get_extension (source, extension_name);
+
+ /* We're only interested in POP accounts. */
+
+ backend_name = e_source_backend_get_backend_name (
+ E_SOURCE_BACKEND (extension));
+ if (g_strcmp0 (backend_name, "pop") != 0)
+ continue;
+
+ /* Get the mail account's default mail identity. */
+
+ uid = e_source_mail_account_dup_identity_uid (
+ E_SOURCE_MAIL_ACCOUNT (extension));
+ source = e_source_registry_ref_source (registry, uid);
+ g_free (uid);
+
+ if (source == NULL)
+ continue;
+
+ /* Get the mail identity's default mail transport. */
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_SUBMISSION;
+ extension = e_source_get_extension (source, extension_name);
+
+ uid = e_source_mail_submission_dup_transport_uid (
+ E_SOURCE_MAIL_SUBMISSION (extension));
+
+ g_object_unref (source);
- return key;
+ if (g_strcmp0 (uid, smtp_uid) == 0) {
+ pop_uid = uid;
+ break;
+ }
+
+ g_free (uid);
+ }
+
+ g_list_free_full (list, (GDestroyNotify) g_object_unref);
+
+ return pop_uid;
}
static void
@@ -406,135 +471,181 @@ mail_session_set_junk_filter_name (EMailSession *session,
}
static void
-mail_session_add_by_account (EMailSession *session,
- EAccount *account)
-{
- CamelService *service = NULL;
- CamelProvider *provider;
- CamelURL *url = NULL;
- const gchar *protocol = NULL;
- gboolean have_source_url;
- GError *error = NULL;
-
- have_source_url =
- (account->source != NULL) &&
- (account->source->url != NULL);
+mail_session_refresh_cb (ESource *source,
+ CamelSession *session)
+{
+ CamelService *service;
+ const gchar *uid;
- if (have_source_url)
- url = camel_url_new (account->source->url, NULL);
+ uid = e_source_get_uid (source);
+ service = camel_session_get_service (session, uid);
+ g_return_if_fail (CAMEL_IS_SERVICE (service));
- protocol = (url != NULL) ? url->protocol : "none";
- provider = camel_provider_get (protocol, &error);
+ g_signal_emit (session, signals[REFRESH_SERVICE], 0, service);
+}
- if (url != NULL)
- camel_url_free (url);
+static void
+mail_session_add_from_source (EMailSession *session,
+ CamelProviderType type,
+ ESource *source)
+{
+ ESourceBackend *extension;
+ const gchar *uid;
+ const gchar *backend_name;
+ const gchar *display_name;
+ const gchar *extension_name;
+ GError *error = NULL;
- if (error != NULL) {
- g_warn_if_fail (provider == NULL);
- g_warning ("%s", error->message);
- g_error_free (error);
- return;
+ switch (type) {
+ case CAMEL_PROVIDER_STORE:
+ extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+ break;
+ case CAMEL_PROVIDER_TRANSPORT:
+ extension_name = E_SOURCE_EXTENSION_MAIL_TRANSPORT;
+ break;
+ default:
+ g_return_if_reached ();
}
- g_return_if_fail (provider != NULL);
+ uid = e_source_get_uid (source);
+ display_name = e_source_get_display_name (source);
+
+ extension = e_source_get_extension (source, extension_name);
+ backend_name = e_source_backend_get_backend_name (extension);
- /* Load the service, but don't connect. Check its provider,
- * and if this belongs in the folder tree model, add it. */
+ /* Sanity checks. */
+ g_return_if_fail (uid != NULL);
+ g_return_if_fail (backend_name != NULL);
- service = camel_session_add_service (
- CAMEL_SESSION (session),
- account->uid, provider->protocol,
- CAMEL_PROVIDER_STORE, &error);
+ /* Our own CamelSession.add_service() method will handle the
+ * resulting CamelService, so we don't need the return value. */
+ camel_session_add_service (
+ CAMEL_SESSION (session), uid,
+ backend_name, type, &error);
if (error != NULL) {
g_warning (
- "Failed to add service: %s: %s",
- account->name, error->message);
+ "Failed to add service '%s' (%s): %s",
+ display_name, uid, error->message);
g_error_free (error);
- return;
}
- camel_service_set_display_name (service, account->name);
+ /* Set up auto-refresh. */
+ extension_name = E_SOURCE_EXTENSION_REFRESH;
+ if (e_source_has_extension (source, extension_name)) {
+ guint timeout_id;
- /* While we're at it, add the account's transport (if it has one)
- * to the CamelSession. The transport's UID is a kludge for now.
- * We take the EAccount's UID and tack on "-transport". */
+ /* Transports should not have a refresh extension. */
+ g_warn_if_fail (type != CAMEL_PROVIDER_TRANSPORT);
- if (account->transport) {
- GError *transport_error = NULL;
+ timeout_id = e_source_refresh_add_timeout (
+ source, NULL, (ESourceRefreshFunc)
+ mail_session_refresh_cb, session,
+ (GDestroyNotify) NULL);
- url = camel_url_new (
- account->transport->url,
- &transport_error);
+ g_hash_table_insert (
+ session->priv->auto_refresh_table,
+ g_strdup (uid),
+ GUINT_TO_POINTER (timeout_id));
+ }
+}
- if (url != NULL) {
- provider = camel_provider_get (
- url->protocol, &transport_error);
- camel_url_free (url);
- } else
- provider = NULL;
+static void
+mail_session_source_added_cb (ESourceRegistry *registry,
+ ESource *source,
+ EMailSession *session)
+{
+ CamelProviderType provider_type;
+ const gchar *extension_name;
- if (provider != NULL) {
- gchar *transport_uid;
+ provider_type = CAMEL_PROVIDER_STORE;
+ extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
- transport_uid = g_strconcat (
- account->uid, "-transport", NULL);
+ if (e_source_has_extension (source, extension_name))
+ mail_session_add_from_source (session, provider_type, source);
- camel_session_add_service (
- CAMEL_SESSION (session),
- transport_uid, provider->protocol,
- CAMEL_PROVIDER_TRANSPORT, &transport_error);
+ provider_type = CAMEL_PROVIDER_TRANSPORT;
+ extension_name = E_SOURCE_EXTENSION_MAIL_TRANSPORT;
- g_free (transport_uid);
- }
+ if (e_source_has_extension (source, extension_name))
+ mail_session_add_from_source (session, provider_type, source);
+}
- if (transport_error) {
- g_warning (
- "%s: Failed to add transport service: %s",
- G_STRFUNC, transport_error->message);
- g_error_free (transport_error);
- }
- }
+static void
+mail_session_source_removed_cb (ESourceRegistry *registry,
+ ESource *source,
+ EMailSession *session)
+{
+ CamelSession *camel_session;
+ CamelService *service;
+ const gchar *uid;
+
+ camel_session = CAMEL_SESSION (session);
+
+ uid = e_source_get_uid (source);
+ service = camel_session_get_service (camel_session, uid);
+
+ if (CAMEL_IS_SERVICE (service))
+ camel_session_remove_service (camel_session, service);
}
static void
-mail_session_account_added_cb (EAccountList *account_list,
- EAccount *account,
- EMailSession *session)
+mail_session_default_mail_account_cb (ESourceRegistry *registry,
+ GParamSpec *pspec,
+ EMailSession *session)
{
- mail_session_add_by_account (session, account);
+ ESource *source;
+ ESourceMailAccount *extension;
+ const gchar *extension_name;
+ gchar *uid;
+
+ /* If the default mail account names a valid mail
+ * identity, make it the default mail identity. */
+
+ /* XXX I debated whether to have ESourceRegistry do this
+ * itself but it seems like an Evolution policy to me
+ * right now. I may change my mind in the future, or
+ * decide not to do this synchronization at all. */
+
+ source = e_source_registry_ref_default_mail_account (registry);
+ g_return_if_fail (source != NULL);
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+ extension = e_source_get_extension (source, extension_name);
+ uid = e_source_mail_account_dup_identity_uid (extension);
+
+ g_object_unref (source);
+ source = NULL;
+
+ if (uid != NULL) {
+ source = e_source_registry_ref_source (registry, uid);
+ g_free (uid);
+ }
+
+ if (source != NULL) {
+ e_source_registry_set_default_mail_identity (registry, source);
+ g_object_unref (source);
+ }
}
static void
-mail_session_add_local_store (EMailSession *session)
+mail_session_configure_local_store (EMailSession *session)
{
CamelLocalSettings *local_settings;
CamelSession *camel_session;
CamelSettings *settings;
CamelService *service;
const gchar *data_dir;
+ const gchar *uid;
gchar *path;
gint ii;
- GError *error = NULL;
camel_session = CAMEL_SESSION (session);
- service = camel_session_add_service (
- camel_session, E_MAIL_SESSION_LOCAL_UID,
- "maildir", CAMEL_PROVIDER_STORE, &error);
-
- /* XXX One could argue this is a fatal error
- * since we depend on it in so many places. */
- if (error != NULL) {
- g_critical ("%s: %s", G_STRFUNC, error->message);
- g_error_free (error);
- return;
- }
-
+ uid = E_MAIL_SESSION_LOCAL_UID;
+ service = camel_session_get_service (camel_session, uid);
g_return_if_fail (CAMEL_IS_SERVICE (service));
- camel_service_set_display_name (service, _("On This Computer"));
-
settings = camel_service_get_settings (service);
local_settings = CAMEL_LOCAL_SETTINGS (settings);
data_dir = camel_session_get_user_data_dir (camel_session);
@@ -582,6 +693,115 @@ mail_session_add_local_store (EMailSession *session)
}
static void
+mail_session_force_refresh (EMailSession *session)
+{
+ ESourceRegistry *registry;
+ GHashTableIter iter;
+ GSettings *settings;
+ gboolean unconditionally;
+ gpointer key;
+
+ /* Only refresh when the session is online. */
+ if (!camel_session_get_online (CAMEL_SESSION (session)))
+ return;
+
+ /* FIXME EMailSession should define properties for these. */
+ settings = g_settings_new ("org.gnome.evolution.mail");
+ unconditionally =
+ g_settings_get_boolean (settings, "send-recv-on-start") &&
+ g_settings_get_boolean (settings, "send-recv-all-on-start");
+ g_object_unref (settings);
+
+ registry = e_mail_session_get_registry (session);
+ g_hash_table_iter_init (&iter, session->priv->auto_refresh_table);
+
+ while (g_hash_table_iter_next (&iter, &key, NULL)) {
+ ESource *source;
+ ESourceRefresh *extension;
+ const gchar *extension_name;
+ gboolean refresh_enabled;
+
+ /* The hash table key is the ESource UID. */
+ source = e_source_registry_ref_source (registry, key);
+
+ if (source == NULL)
+ continue;
+
+ extension_name = E_SOURCE_EXTENSION_REFRESH;
+ extension = e_source_get_extension (source, extension_name);
+ refresh_enabled = e_source_refresh_get_enabled (extension);
+
+ if (refresh_enabled || unconditionally)
+ e_source_refresh_force_timeout (source);
+
+ g_object_unref (source);
+ }
+}
+
+static void
+mail_session_cancel_refresh (EMailSession *session)
+{
+ ESourceRegistry *registry;
+ GHashTableIter iter;
+ gpointer key, value;
+
+ registry = e_mail_session_get_registry (session);
+ g_hash_table_iter_init (&iter, session->priv->auto_refresh_table);
+
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ ESource *source;
+ guint timeout_id;
+
+ /* The hash table key is the ESource UID. */
+ source = e_source_registry_ref_source (registry, key);
+
+ /* The hash table value is the refresh timeout ID. */
+ timeout_id = GPOINTER_TO_UINT (value);
+
+ if (source == NULL)
+ continue;
+
+ e_source_refresh_remove_timeout (source, timeout_id);
+
+ g_object_unref (source);
+ }
+
+ /* All timeouts cancelled so clear the auto-refresh table. */
+ g_hash_table_remove_all (session->priv->auto_refresh_table);
+}
+
+static gboolean
+mail_session_idle_refresh_cb (EMailSession *session)
+{
+ /* This only runs once at startup (if settings allow). */
+
+ if (camel_session_get_online (CAMEL_SESSION (session))) {
+ mail_session_force_refresh (session);
+
+ /* Also flush the Outbox. */
+ g_signal_emit (session, signals[FLUSH_OUTBOX], 0);
+ }
+
+ /* Listen for network state changes and force a
+ * mail store refresh when coming back online. */
+ g_signal_connect (
+ session, "notify::online",
+ G_CALLBACK (mail_session_force_refresh), NULL);
+
+ return FALSE;
+}
+
+static void
+mail_session_set_registry (EMailSession *session,
+ ESourceRegistry *registry)
+{
+ g_return_if_fail (E_IS_SOURCE_REGISTRY (registry));
+ g_return_if_fail (session->priv->registry == NULL);
+
+ session->priv->registry = g_object_ref (registry);
+}
+
+static void
mail_session_set_property (GObject *object,
guint property_id,
const GValue *value,
@@ -593,6 +813,12 @@ mail_session_set_property (GObject *object,
E_MAIL_SESSION (object),
g_value_get_string (value));
return;
+
+ case PROP_REGISTRY:
+ mail_session_set_registry (
+ E_MAIL_SESSION (object),
+ g_value_get_object (value));
+ return;
}
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -626,6 +852,13 @@ mail_session_get_property (GObject *object,
E_MAIL_SESSION (object)));
return;
+ case PROP_REGISTRY:
+ g_value_set_object (
+ value,
+ e_mail_session_get_registry (
+ E_MAIL_SESSION (object)));
+ return;
+
case PROP_VFOLDER_STORE:
g_value_set_object (
value,
@@ -649,12 +882,22 @@ mail_session_dispose (GObject *object)
priv->folder_cache = NULL;
}
- if (priv->account_list != NULL) {
+ if (priv->registry != NULL) {
+ g_signal_handler_disconnect (
+ priv->registry,
+ priv->source_added_handler_id);
g_signal_handler_disconnect (
- priv->account_list,
- priv->account_added_handler_id);
- g_object_unref (priv->account_list);
- priv->account_list = NULL;
+ priv->registry,
+ priv->source_removed_handler_id);
+ g_signal_handler_disconnect (
+ priv->registry,
+ priv->default_mail_account_handler_id);
+
+ /* This requires the registry. */
+ mail_session_cancel_refresh (E_MAIL_SESSION (object));
+
+ g_object_unref (priv->registry);
+ priv->registry = NULL;
}
if (priv->local_store != NULL) {
@@ -674,27 +917,18 @@ mail_session_dispose (GObject *object)
}
static void
-mail_session_add_vfolder_store (EMailSession *session)
+mail_session_configure_vfolder_store (EMailSession *session)
{
CamelSession *camel_session;
CamelService *service;
- GError *error = NULL;
+ const gchar *uid;
camel_session = CAMEL_SESSION (session);
- service = camel_session_add_service (
- camel_session, E_MAIL_SESSION_VFOLDER_UID,
- "vfolder", CAMEL_PROVIDER_STORE, &error);
-
- if (error != NULL) {
- g_critical ("%s: %s", G_STRFUNC, error->message);
- g_error_free (error);
- return;
- }
-
+ uid = E_MAIL_SESSION_VFOLDER_UID;
+ service = camel_session_get_service (camel_session, uid);
g_return_if_fail (CAMEL_IS_SERVICE (service));
- camel_service_set_display_name (service, _("Search Folders"));
camel_service_connect_sync (service, NULL, NULL);
/* XXX There's more configuration to do in vfolder_load_storage()
@@ -712,6 +946,7 @@ mail_session_finalize (GObject *object)
priv = E_MAIL_SESSION_GET_PRIVATE (object);
+ g_hash_table_destroy (priv->auto_refresh_table);
g_hash_table_destroy (priv->junk_filters);
g_object_unref (priv->proxy);
@@ -737,73 +972,76 @@ mail_session_notify (GObject *object,
g_object_notify (object, "junk-filter-name");
}
-static gboolean
-mail_session_initialize_stores_idle (gpointer user_data)
-{
- EMailSession *session = user_data;
- EAccountList *account_list;
- EAccount *account;
- EIterator *iter;
-
- g_return_val_if_fail (session != NULL, FALSE);
-
- account_list = e_get_account_list ();
- iter = e_list_get_iterator (E_LIST (account_list));
-
- while (e_iterator_is_valid (iter)) {
- /* XXX EIterator misuses const. */
- account = (EAccount *) e_iterator_get (iter);
-
- mail_session_add_by_account (session, account);
-
- e_iterator_next (iter);
- }
-
- g_object_unref (iter);
-
- return FALSE;
-}
-
static void
mail_session_constructed (GObject *object)
{
EMailSession *session;
EExtensible *extensible;
+ ESourceRegistry *registry;
GType extension_type;
GList *list, *link;
GSettings *settings;
- EAccountList *account_list;
+ CamelProviderType provider_type;
+ const gchar *extension_name;
gulong handler_id;
session = E_MAIL_SESSION (object);
+ registry = e_mail_session_get_registry (session);
/* Chain up to parent's constructed() method. */
G_OBJECT_CLASS (e_mail_session_parent_class)->constructed (object);
- account_list = e_get_account_list ();
- session->priv->account_list = g_object_ref (account_list);
+ /* Add available mail accounts. */
- /* This must be created after the account store. */
- session->priv->folder_cache = mail_folder_cache_new (session);
+ provider_type = CAMEL_PROVIDER_STORE;
+ extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
- /* Add built-in CamelStores. */
- mail_session_add_local_store (session);
- mail_session_add_vfolder_store (session);
+ list = e_source_registry_list_sources (registry, extension_name);
- /* Give it a chance to load user settings, they are not loaded yet.
- *
- * XXX Is this the case where hiding such natural things like loading
- * user setting into an EExtension strikes back and proves itself
- * being suboptimal?
- */
- g_idle_add (mail_session_initialize_stores_idle, object);
+ for (link = list; link != NULL; link = g_list_next (link)) {
+ ESource *source = E_SOURCE (link->data);
+
+ mail_session_add_from_source (session, provider_type, source);
+ }
+
+ g_list_free_full (list, (GDestroyNotify) g_object_unref);
+
+ /* Add available mail transports. */
+
+ provider_type = CAMEL_PROVIDER_TRANSPORT;
+ extension_name = E_SOURCE_EXTENSION_MAIL_TRANSPORT;
+
+ list = e_source_registry_list_sources (registry, extension_name);
- /* Listen for account list updates. */
+ for (link = list; link != NULL; link = g_list_next (link)) {
+ ESource *source = E_SOURCE (link->data);
+
+ mail_session_add_from_source (session, provider_type, source);
+ }
+
+ g_list_free_full (list, (GDestroyNotify) g_object_unref);
+
+ /* Built-in stores require extra configuration. */
+
+ mail_session_configure_local_store (session);
+ mail_session_configure_vfolder_store (session);
+
+ /* Listen for registry changes. */
+
+ handler_id = g_signal_connect (
+ registry, "source-added",
+ G_CALLBACK (mail_session_source_added_cb), session);
+ session->priv->source_added_handler_id = handler_id;
handler_id = g_signal_connect (
- account_list, "account-added",
- G_CALLBACK (mail_session_account_added_cb), session);
- session->priv->account_added_handler_id = handler_id;
+ registry, "source-removed",
+ G_CALLBACK (mail_session_source_removed_cb), session);
+ session->priv->source_removed_handler_id = handler_id;
+
+ handler_id = g_signal_connect (
+ registry, "notify::default-mail-account",
+ G_CALLBACK (mail_session_default_mail_account_cb), session);
+ session->priv->default_mail_account_handler_id = handler_id;
extensible = E_EXTENSIBLE (object);
e_extensible_load_extensions (extensible);
@@ -852,10 +1090,11 @@ mail_session_constructed (GObject *object)
g_list_free (list);
+ settings = g_settings_new ("org.gnome.evolution.mail");
+
/* Bind the "junk-default-plugin" GSettings
* key to our "junk-filter-name" property. */
- settings = g_settings_new ("org.gnome.evolution.mail");
g_settings_bind (
settings, "junk-default-plugin",
object, "junk-filter-name",
@@ -872,6 +1111,19 @@ mail_session_constructed (GObject *object)
e_proxy_setup_proxy (session->priv->proxy);
+ /* Initialize the legacy message-passing framework
+ * before starting the first mail store refresh. */
+ mail_msg_init ();
+
+ /* The application is not yet fully initialized at this point,
+ * so run the first mail store refresh from an idle callback. */
+ if (g_settings_get_boolean (settings, "send-recv-on-start"))
+ g_idle_add_full (
+ G_PRIORITY_DEFAULT,
+ (GSourceFunc) mail_session_idle_refresh_cb,
+ g_object_ref (session),
+ (GDestroyNotify) g_object_unref);
+
g_object_unref (settings);
}
@@ -882,53 +1134,49 @@ mail_session_add_service (CamelSession *session,
CamelProviderType type,
GError **error)
{
+ ESourceRegistry *registry;
CamelService *service;
+ const gchar *extension_name;
+
+ registry = e_mail_session_get_registry (E_MAIL_SESSION (session));
+ extension_name = e_source_camel_get_extension_name (protocol);
/* Chain up to parents add_service() method. */
service = CAMEL_SESSION_CLASS (e_mail_session_parent_class)->
add_service (session, uid, protocol, type, error);
- /* Initialize the CamelSettings object from CamelURL parameters.
- * This is temporary; soon we'll read settings from key files. */
+ /* Configure the CamelService from the corresponding ESource. */
if (CAMEL_IS_SERVICE (service)) {
- EAccount *account;
- CamelURL *url = NULL;
-
- account = e_get_account_by_uid (uid);
- if (account != NULL) {
- const gchar *url_string = NULL;
-
- switch (type) {
- case CAMEL_PROVIDER_STORE:
- url_string = account->source->url;
- break;
- case CAMEL_PROVIDER_TRANSPORT:
- url_string = account->transport->url;
- break;
- default:
- break;
- }
-
- /* Be lenient about malformed URLs. */
- if (url_string != NULL)
- url = camel_url_new (url_string, NULL);
+ ESource *source;
+ ESource *tmp_source;
+
+ /* Each CamelService has a corresponding ESource. */
+ source = e_source_registry_ref_source (registry, uid);
+ g_return_val_if_fail (source != NULL, service);
+
+ tmp_source = e_source_registry_find_extension (
+ registry, source, extension_name);
+ if (tmp_source != NULL) {
+ g_object_unref (source);
+ source = tmp_source;
}
- if (url != NULL) {
- CamelSettings *settings;
+ /* This handles all the messy property bindings. */
+ e_source_camel_configure_service (source, service);
- settings = camel_service_get_settings (service);
- camel_settings_load_from_url (settings, url);
- camel_url_free (url);
+ g_object_bind_property (
+ source, "display-name",
+ service, "display-name",
+ G_BINDING_BIDIRECTIONAL |
+ G_BINDING_SYNC_CREATE);
- g_object_notify (G_OBJECT (service), "settings");
+ /* Migrate files for this service from its old
+ * URL-based directory to a UID-based directory
+ * if necessary. */
+ camel_service_migrate_files (service);
- /* Migrate files for this service from its old
- * URL-based directory to a UID-based directory
- * if necessary. */
- camel_service_migrate_files (service);
- }
+ g_object_unref (source);
}
return service;
@@ -942,114 +1190,69 @@ mail_session_get_password (CamelSession *session,
guint32 flags,
GError **error)
{
- EAccount *account = NULL;
- const gchar *display_name = NULL;
- const gchar *uid = NULL;
- gchar *ret = NULL;
+ ESourceRegistry *registry;
+ gchar *password = NULL;
- if (CAMEL_IS_SERVICE (service)) {
- display_name = camel_service_get_display_name (service);
- uid = camel_service_get_uid (service);
- account = e_get_account_by_uid (uid);
- }
+ /* XXX This method is now only for fringe cases. For normal
+ * CamelService authentication, use authenticate_sync().
+ *
+ * The two known fringe cases that still need this are:
+ *
+ * 1) CamelSaslPOPB4SMTP, where the CamelService is an SMTP
+ * transport and the item name is always "popb4smtp_uid".
+ * (This is a dirty hack, Camel just needs some way to
+ * pair up a CamelService and CamelTransport. Not sure
+ * what that should look like just yet...)
+ *
+ * 2) CamelGpgContext, where the CamelService is NULL and
+ * the item name is a user ID (I think). (Seahorse, or
+ * one of its dependent libraries, ought to handle this
+ * transparently once Camel fully transitions to GIO.)
+ */
- if (!strcmp(item, "popb4smtp_uid")) {
- /* not 100% mt safe, but should be ok */
- ret = g_strdup ((account != NULL) ? account->uid : uid);
- } else {
- gchar *key = mail_session_make_key (service, item);
- EAccountService *config_service = NULL;
-
- ret = e_passwords_get_password (NULL, key);
- if (ret == NULL || (flags & CAMEL_SESSION_PASSWORD_REPROMPT)) {
- gboolean remember;
-
- g_free (ret);
- ret = NULL;
-
- if (account != NULL) {
- if (CAMEL_IS_STORE (service))
- config_service = account->source;
- if (CAMEL_IS_TRANSPORT (service))
- config_service = account->transport;
- }
+ registry = e_mail_session_get_registry (E_MAIL_SESSION (session));
- remember = config_service ? config_service->save_passwd : FALSE;
-
- if (!config_service || (config_service &&
- !config_service->get_password_canceled)) {
- guint32 eflags;
- gchar *title;
-
- if (flags & CAMEL_SESSION_PASSPHRASE) {
- if (display_name != NULL)
- title = g_strdup_printf (
- _("Enter Passphrase for %s"),
- display_name);
- else
- title = g_strdup (
- _("Enter Passphrase"));
- } else {
- if (display_name != NULL)
- title = g_strdup_printf (
- _("Enter Password for %s"),
- display_name);
- else
- title = g_strdup (
- _("Enter Password"));
- }
- if ((flags & CAMEL_SESSION_PASSWORD_STATIC) != 0)
- eflags = E_PASSWORDS_REMEMBER_NEVER;
- else if (config_service == NULL)
- eflags = E_PASSWORDS_REMEMBER_SESSION;
- else
- eflags = E_PASSWORDS_REMEMBER_FOREVER;
-
- if (flags & CAMEL_SESSION_PASSWORD_REPROMPT)
- eflags |= E_PASSWORDS_REPROMPT;
-
- if (flags & CAMEL_SESSION_PASSWORD_SECRET)
- eflags |= E_PASSWORDS_SECRET;
-
- if (flags & CAMEL_SESSION_PASSPHRASE)
- eflags |= E_PASSWORDS_PASSPHRASE;
-
- /* HACK: breaks abstraction ...
- * e_account_writable() doesn't use the
- * EAccount, it also uses the same writable
- * key for source and transport. */
- if (!e_account_writable (NULL, E_ACCOUNT_SOURCE_SAVE_PASSWD))
- eflags |= E_PASSWORDS_DISABLE_REMEMBER;
-
- ret = e_passwords_ask_password (
- title, NULL, key, prompt,
- eflags, &remember, NULL);
-
- if (!ret)
- e_passwords_forget_password (NULL, key);
-
- g_free (title);
-
- if (ret && config_service) {
- config_service->save_passwd = remember;
- e_account_list_save (e_get_account_list ());
- }
-
- if (config_service)
- config_service->get_password_canceled = ret == NULL;
- }
- }
+ /* Handle the CamelSaslPOPB4SMTP case. */
+ if (g_strcmp0 (item, "popb4smtp_uid") == 0)
+ return mail_session_resolve_popb4smtp (registry, service);
+
+ /* Otherwise this had better be the CamelGpgContext case. */
+ g_return_val_if_fail (service == NULL, NULL);
+
+ password = e_passwords_get_password (NULL, item);
+
+ if (password == NULL || (flags & CAMEL_SESSION_PASSWORD_REPROMPT)) {
+ gboolean remember;
+ guint eflags = 0;
+
+ if (flags & CAMEL_SESSION_PASSWORD_STATIC)
+ eflags |= E_PASSWORDS_REMEMBER_NEVER;
+ else
+ eflags |= E_PASSWORDS_REMEMBER_SESSION;
+
+ if (flags & CAMEL_SESSION_PASSWORD_REPROMPT)
+ eflags |= E_PASSWORDS_REPROMPT;
+
+ if (flags & CAMEL_SESSION_PASSWORD_SECRET)
+ eflags |= E_PASSWORDS_SECRET;
- g_free (key);
+ if (flags & CAMEL_SESSION_PASSPHRASE)
+ eflags |= E_PASSWORDS_PASSPHRASE;
+
+ password = e_passwords_ask_password (
+ "", NULL, item, prompt, eflags, &remember, NULL);
+
+ if (password == NULL)
+ e_passwords_forget_password (NULL, item);
}
- if (ret == NULL)
+ if (password == NULL)
g_set_error (
error, G_IO_ERROR,
G_IO_ERROR_CANCELLED,
- _("User canceled operation."));
+ _("User cancelled operation"));
- return ret;
+ return password;
}
static gboolean
@@ -1058,13 +1261,13 @@ mail_session_forget_password (CamelSession *session,
const gchar *item,
GError **error)
{
- gchar *key;
-
- key = mail_session_make_key (service, item);
+ /* XXX The only remaining user of this method is CamelGpgContext,
+ * which does not provide a CamelService. Use 'item' as the
+ * password key. */
- e_passwords_forget_password (NULL, key);
+ g_return_val_if_fail (service == NULL, FALSE);
- g_free (key);
+ e_passwords_forget_password (NULL, item);
return TRUE;
}
@@ -1124,16 +1327,19 @@ static gboolean
mail_session_lookup_addressbook (CamelSession *session,
const gchar *name)
{
+ ESourceRegistry *registry;
CamelInternetAddress *addr;
gboolean ret;
if (!mail_config_get_lookup_book ())
return FALSE;
+ registry = e_mail_session_get_registry (E_MAIL_SESSION (session));
+
addr = camel_internet_address_new ();
camel_address_decode ((CamelAddress *) addr, name);
ret = em_utils_in_addressbook (
- addr, mail_config_get_lookup_book_local_only ());
+ registry, addr, mail_config_get_lookup_book_local_only ());
g_object_unref (addr);
return ret;
@@ -1146,13 +1352,16 @@ mail_session_forward_to (CamelSession *session,
const gchar *address,
GError **error)
{
- EAccount *account;
+ ESource *source;
+ ESourceRegistry *registry;
+ ESourceMailIdentity *extension;
CamelMimeMessage *forward;
CamelStream *mem;
CamelInternetAddress *addr;
CamelFolder *out_folder;
CamelMessageInfo *info;
CamelMedium *medium;
+ const gchar *extension_name;
const gchar *from_address;
const gchar *from_name;
const gchar *header_name;
@@ -1166,22 +1375,28 @@ mail_session_forward_to (CamelSession *session,
if (!*address) {
g_set_error (
error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
- _("No destination address provided, forward "
+ _("No destination address provided, forwarding "
"of the message has been cancelled."));
return FALSE;
}
- account = em_utils_guess_account_with_recipients (message, folder);
- if (!account) {
+ registry = e_mail_session_get_registry (E_MAIL_SESSION (session));
+
+ /* This returns a new ESource reference. */
+ source = em_utils_guess_mail_identity_with_recipients (
+ registry, message, folder);
+ if (source == NULL) {
g_set_error (
error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
- _("No account found to use, forward of the "
- "message has been cancelled."));
+ _("No identity found to use, forwarding "
+ "of the message has been cancelled."));
return FALSE;
}
- from_address = account->id->address;
- from_name = account->id->name;
+ extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
+ extension = e_source_get_extension (source, extension_name);
+ from_address = e_source_mail_identity_get_address (extension);
+ from_name = e_source_mail_identity_get_name (extension);
forward = camel_mime_message_new ();
@@ -1255,6 +1470,8 @@ mail_session_forward_to (CamelSession *session,
camel_message_info_free (info);
+ g_object_unref (source);
+
return TRUE;
}
@@ -1301,19 +1518,23 @@ mail_session_authenticate_sync (CamelSession *session,
GCancellable *cancellable,
GError **error)
{
+ ESource *source;
+ ESourceRegistry *registry;
+ ESourceAuthenticator *auth;
CamelServiceAuthType *authtype = NULL;
CamelAuthenticationResult result;
- CamelProvider *provider;
- CamelSettings *settings;
- const gchar *password;
- guint32 password_flags;
+ const gchar *uid;
+ gboolean authenticated;
GError *local_error = NULL;
/* Do not chain up. Camel's default method is only an example for
* subclasses to follow. Instead we mimic most of its logic here. */
- provider = camel_service_get_provider (service);
- settings = camel_service_get_settings (service);
+ registry = e_mail_session_get_registry (E_MAIL_SESSION (session));
+
+ /* Treat a mechanism name of "none" as NULL. */
+ if (g_strcmp0 (mechanism, "none") == 0)
+ mechanism = NULL;
/* APOP is one case where a non-SASL mechanism name is passed, so
* don't bail if the CamelServiceAuthType struct comes back NULL. */
@@ -1366,58 +1587,28 @@ mail_session_authenticate_sync (CamelSession *session,
g_clear_error (&local_error);
- password_flags = CAMEL_SESSION_PASSWORD_SECRET;
-
-retry:
- password = camel_service_get_password (service);
-
- if (password == NULL) {
- CamelNetworkSettings *network_settings;
- const gchar *host;
- const gchar *user;
- gchar *prompt;
- gchar *new_passwd;
+ /* Find a matching ESource for this CamelService. */
+ uid = camel_service_get_uid (service);
+ source = e_source_registry_ref_source (registry, uid);
- network_settings = CAMEL_NETWORK_SETTINGS (settings);
- host = camel_network_settings_get_host (network_settings);
- user = camel_network_settings_get_user (network_settings);
-
- prompt = camel_session_build_password_prompt (
- provider->name, user, host);
-
- new_passwd = camel_session_get_password (
- session, service, prompt, "password",
- password_flags, &local_error);
- camel_service_set_password (service, new_passwd);
- password = camel_service_get_password (service);
- g_free (new_passwd);
-
- g_free (prompt);
+ if (source == NULL) {
+ g_set_error (
+ error, CAMEL_SERVICE_ERROR,
+ CAMEL_SERVICE_ERROR_CANT_AUTHENTICATE,
+ _("No data source found for UID '%s'"), uid);
+ return FALSE;
+ }
- if (local_error != NULL) {
- g_propagate_error (error, local_error);
- return FALSE;
- }
+ auth = e_mail_authenticator_new (service, mechanism);
- if (password == NULL) {
- g_set_error (
- error, CAMEL_SERVICE_ERROR,
- CAMEL_SERVICE_ERROR_CANT_AUTHENTICATE,
- _("No password was provided"));
- return FALSE;
- }
- }
+ authenticated = e_source_registry_authenticate_sync (
+ registry, source, auth, cancellable, error);
- result = camel_service_authenticate_sync (
- service, mechanism, cancellable, error);
+ g_object_unref (auth);
- if (result == CAMEL_AUTHENTICATION_REJECTED) {
- password_flags |= CAMEL_SESSION_PASSWORD_REPROMPT;
- camel_service_set_password (service, NULL);
- goto retry;
- }
+ g_object_unref (source);
- return (result == CAMEL_AUTHENTICATION_ACCEPTED);
+ return authenticated;
}
static EMVFolderContext *
@@ -1493,6 +1684,18 @@ e_mail_session_class_init (EMailSessionClass *class)
g_object_class_install_property (
object_class,
+ PROP_REGISTRY,
+ g_param_spec_object (
+ "registry",
+ "Registry",
+ "Data source registry",
+ E_TYPE_SOURCE_REGISTRY,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
PROP_VFOLDER_STORE,
g_param_spec_object (
"vfolder-store",
@@ -1512,15 +1715,32 @@ e_mail_session_class_init (EMailSessionClass *class)
"flush-outbox",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
- 0, /* struct offset */
- NULL, NULL, /* accumulator */
+ G_STRUCT_OFFSET (EMailSessionClass, flush_outbox),
+ NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
/**
+ * EMailSession::refresh-service
+ * @session: the #EMailSession that emitted the signal
+ * @service: a #CamelService
+ *
+ * Emitted when @service should be refreshed.
+ **/
+ signals[REFRESH_SERVICE] = g_signal_new (
+ "refresh-service",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMailSessionClass, refresh_service),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ CAMEL_TYPE_SERVICE);
+
+ /**
* EMailSession::store-added
- * @session: the email session
- * @store: the CamelStore
+ * @session: the #EMailSession that emitted the signal
+ * @store: a #CamelStore
*
* Emitted when a store is added
**/
@@ -1528,16 +1748,16 @@ e_mail_session_class_init (EMailSessionClass *class)
"store-added",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
- 0, /* struct offset */
- NULL, NULL, /* accumulator */
+ G_STRUCT_OFFSET (EMailSessionClass, store_added),
+ NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
CAMEL_TYPE_STORE);
/**
* EMailSession::store-removed
- * @session: the email session
- * @store: the CamelStore
+ * @session: the #EMailSession that emitted the signal
+ * @store: a #CamelStore
*
* Emitted when a store is removed
**/
@@ -1545,25 +1765,37 @@ e_mail_session_class_init (EMailSessionClass *class)
"store-removed",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
- 0, /* struct offset */
- NULL, NULL, /* accumulator */
+ G_STRUCT_OFFSET (EMailSessionClass, store_removed),
+ NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
CAMEL_TYPE_STORE);
camel_null_store_register_provider ();
+
+ /* Make sure ESourceCamel picks up the "none" provider. */
+ e_source_camel_register_types ();
}
static void
e_mail_session_init (EMailSession *session)
{
+ GHashTable *auto_refresh_table;
GHashTable *junk_filters;
+ auto_refresh_table = g_hash_table_new_full (
+ (GHashFunc) g_str_hash,
+ (GEqualFunc) g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) NULL);
+
junk_filters = g_hash_table_new (
(GHashFunc) g_str_hash,
(GEqualFunc) g_str_equal);
session->priv = E_MAIL_SESSION_GET_PRIVATE (session);
+ session->priv->folder_cache = mail_folder_cache_new (session);
+ session->priv->auto_refresh_table = auto_refresh_table;
session->priv->junk_filters = junk_filters;
session->priv->proxy = e_proxy_new ();
@@ -1573,17 +1805,16 @@ e_mail_session_init (EMailSession *session)
session->priv->local_folder_uris =
g_ptr_array_new_with_free_func (
(GDestroyNotify) g_free);
-
- /* Initialize the EAccount setup. */
- e_account_writable (NULL, E_ACCOUNT_SOURCE_SAVE_PASSWD);
}
EMailSession *
-e_mail_session_new (void)
+e_mail_session_new (ESourceRegistry *registry)
{
const gchar *user_data_dir;
const gchar *user_cache_dir;
+ g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
+
user_data_dir = mail_session_get_data_dir ();
user_cache_dir = mail_session_get_cache_dir ();
@@ -1591,9 +1822,18 @@ e_mail_session_new (void)
E_TYPE_MAIL_SESSION,
"user-data-dir", user_data_dir,
"user-cache-dir", user_cache_dir,
+ "registry", registry,
NULL);
}
+ESourceRegistry *
+e_mail_session_get_registry (EMailSession *session)
+{
+ g_return_val_if_fail (E_IS_MAIL_SESSION (session), NULL);
+
+ return session->priv->registry;
+}
+
MailFolderCache *
e_mail_session_get_folder_cache (EMailSession *session)
{
@@ -1989,6 +2229,67 @@ e_mail_session_uri_to_folder_finish (EMailSession *session,
return g_object_ref (context->folder);
}
+gboolean
+e_binding_transform_service_to_source (GBinding *binding,
+ const GValue *source_value,
+ GValue *target_value,
+ gpointer session)
+{
+ CamelService *service;
+ ESourceRegistry *registry;
+ ESource *source;
+ const gchar *uid;
+ gboolean success = FALSE;
+
+ g_return_val_if_fail (G_IS_BINDING (binding), FALSE);
+ g_return_val_if_fail (E_IS_MAIL_SESSION (session), FALSE);
+
+ service = g_value_get_object (source_value);
+
+ if (!CAMEL_IS_SERVICE (service))
+ return FALSE;
+
+ uid = camel_service_get_uid (service);
+ registry = e_mail_session_get_registry (session);
+ source = e_source_registry_ref_source (registry, uid);
+
+ if (source != NULL) {
+ g_value_take_object (target_value, source);
+ success = TRUE;
+ }
+
+ return success;
+}
+
+gboolean
+e_binding_transform_source_to_service (GBinding *binding,
+ const GValue *source_value,
+ GValue *target_value,
+ gpointer session)
+{
+ CamelService *service;
+ ESource *source;
+ const gchar *uid;
+
+ g_return_val_if_fail (G_IS_BINDING (binding), FALSE);
+ g_return_val_if_fail (E_IS_MAIL_SESSION (session), FALSE);
+
+ source = g_value_get_object (source_value);
+
+ if (!E_IS_SOURCE (source))
+ return FALSE;
+
+ uid = e_source_get_uid (source);
+ service = camel_session_get_service (session, uid);
+
+ if (!CAMEL_IS_SERVICE (service))
+ return FALSE;
+
+ g_value_set_object (target_value, service);
+
+ return TRUE;
+}
+
/******************************** Legacy API *********************************/
void
diff --git a/libemail-engine/e-mail-session.h b/libemail-engine/e-mail-session.h
index 16a65928c3..bf436c7f1c 100644
--- a/libemail-engine/e-mail-session.h
+++ b/libemail-engine/e-mail-session.h
@@ -26,6 +26,7 @@
#define E_MAIL_SESSION_H
#include <camel/camel.h>
+#include <libedataserver/e-source-registry.h>
#include <libemail-engine/e-mail-enums.h>
#include <libemail-engine/mail-folder-cache.h>
#include <libemail-utils/em-vfolder-context.h>
@@ -67,12 +68,22 @@ struct _EMailSession {
struct _EMailSessionClass {
CamelSessionClass parent_class;
- EMVFolderContext * (*create_vfolder_context) (EMailSession *session);
-
+ EMVFolderContext *
+ (*create_vfolder_context)
+ (EMailSession *session);
+ void (*flush_outbox) (EMailSession *session);
+ void (*refresh_service) (EMailSession *session,
+ CamelService *service);
+ void (*store_added) (EMailSession *session,
+ CamelStore *store);
+ void (*store_removed) (EMailSession *session,
+ CamelStore *store);
};
GType e_mail_session_get_type (void);
-EMailSession * e_mail_session_new (void);
+EMailSession * e_mail_session_new (ESourceRegistry *registry);
+ESourceRegistry *
+ e_mail_session_get_registry (EMailSession *session);
MailFolderCache *
e_mail_session_get_folder_cache (EMailSession *session);
CamelStore * e_mail_session_get_local_store (EMailSession *session);
@@ -131,6 +142,19 @@ CamelFolder * e_mail_session_uri_to_folder_finish
EMVFolderContext *
e_mail_session_create_vfolder_context
(EMailSession *session);
+
+/* Useful GBinding transform functions */
+gboolean e_binding_transform_service_to_source
+ (GBinding *binding,
+ const GValue *source_value,
+ GValue *target_value,
+ gpointer session);
+gboolean e_binding_transform_source_to_service
+ (GBinding *binding,
+ const GValue *source_value,
+ GValue *target_value,
+ gpointer session);
+
/*** Legacy API ***/
void mail_session_flush_filter_log (EMailSession *session);
diff --git a/libemail-engine/e-mail-utils.c b/libemail-engine/e-mail-utils.c
index 61ef8d60ae..3838de3547 100644
--- a/libemail-engine/e-mail-utils.c
+++ b/libemail-engine/e-mail-utils.c
@@ -46,9 +46,14 @@
#include <libedataserver/e-data-server-util.h>
#include <libedataserver/e-flag.h>
#include <libedataserver/e-proxy.h>
+#include <libedataserver/e-source-address-book.h>
+#include <libedataserver/e-source-autocomplete.h>
+#include <libedataserver/e-source-mail-account.h>
+#include <libedataserver/e-source-mail-composition.h>
+#include <libedataserver/e-source-mail-identity.h>
+#include <libedataserver/e-source-mail-submission.h>
-#include "libemail-utils/e-account-utils.h"
-#include "libemail-utils/mail-mt.h"
+#include <libemail-utils/mail-mt.h>
#include "e-mail-folder-utils.h"
#include "e-mail-session.h"
@@ -58,131 +63,141 @@
#define d(x)
/**
- * em_utils_folder_is_templates:
+ * em_utils_folder_is_drafts:
+ * @registry: an #ESourceRegistry
* @folder: a #CamelFolder
*
- * Decides if @folder is a Templates folder.
+ * Decides if @folder is a Drafts folder.
*
- * Returns %TRUE if this is a Templates folder or %FALSE otherwise.
+ * Returns %TRUE if this is a Drafts folder or %FALSE otherwise.
**/
-
gboolean
-em_utils_folder_is_templates (CamelFolder *folder)
+em_utils_folder_is_drafts (ESourceRegistry *registry,
+ CamelFolder *folder)
{
- CamelFolder *local_templates_folder;
+ CamelFolder *local_drafts_folder;
CamelSession *session;
CamelStore *store;
- EAccountList *account_list;
- EIterator *iterator;
+ GList *list, *iter;
gchar *folder_uri;
- gboolean is_templates = FALSE;
+ gboolean is_drafts = FALSE;
+ const gchar *extension_name;
g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE);
store = camel_folder_get_parent_store (folder);
session = camel_service_get_session (CAMEL_SERVICE (store));
- local_templates_folder =
+ local_drafts_folder =
e_mail_session_get_local_folder (
- E_MAIL_SESSION (session), E_MAIL_LOCAL_FOLDER_TEMPLATES);
+ E_MAIL_SESSION (session), E_MAIL_LOCAL_FOLDER_DRAFTS);
- if (folder == local_templates_folder)
+ if (folder == local_drafts_folder)
return TRUE;
folder_uri = e_mail_folder_uri_from_folder (folder);
- account_list = e_get_account_list ();
- iterator = e_list_get_iterator (E_LIST (account_list));
+ store = camel_folder_get_parent_store (folder);
+ session = camel_service_get_session (CAMEL_SERVICE (store));
- while (!is_templates && e_iterator_is_valid (iterator)) {
- EAccount *account;
+ extension_name = E_SOURCE_EXTENSION_MAIL_COMPOSITION;
+ list = e_source_registry_list_sources (registry, extension_name);
- /* XXX EIterator misuses const. */
- account = (EAccount *) e_iterator_get (iterator);
+ for (iter = list; iter != NULL; iter = g_list_next (iter)) {
+ ESource *source = E_SOURCE (iter->data);
+ ESourceExtension *extension;
+ const gchar *drafts_folder_uri;
- if (account->templates_folder_uri != NULL)
- is_templates = e_mail_folder_uri_equal (
- session, folder_uri,
- account->templates_folder_uri);
+ extension = e_source_get_extension (source, extension_name);
+
+ drafts_folder_uri =
+ e_source_mail_composition_get_drafts_folder (
+ E_SOURCE_MAIL_COMPOSITION (extension));
+
+ if (drafts_folder_uri != NULL)
+ is_drafts = e_mail_folder_uri_equal (
+ session, folder_uri, drafts_folder_uri);
- e_iterator_next (iterator);
+ if (is_drafts)
+ break;
}
- g_object_unref (iterator);
+ g_list_free_full (list, (GDestroyNotify) g_object_unref);
g_free (folder_uri);
- return is_templates;
+ return is_drafts;
}
/**
- * em_utils_folder_is_drafts:
+ * em_utils_folder_is_templates:
+ * @registry: an #ESourceRegistry
* @folder: a #CamelFolder
*
- * Decides if @folder is a Drafts folder.
+ * Decides if @folder is a Templates folder.
*
- * Returns %TRUE if this is a Drafts folder or %FALSE otherwise.
+ * Returns %TRUE if this is a Templates folder or %FALSE otherwise.
**/
+
gboolean
-em_utils_folder_is_drafts (CamelFolder *folder)
+em_utils_folder_is_templates (ESourceRegistry *registry,
+ CamelFolder *folder)
{
- CamelFolder *local_drafts_folder;
+ CamelFolder *local_templates_folder;
CamelSession *session;
CamelStore *store;
- MailFolderCache *cache;
- EMailSession *mail_session;
- CamelFolderInfoFlags flags = 0;
- EAccountList *account_list;
- EIterator *iterator;
+ GList *list, *iter;
gchar *folder_uri;
- gboolean is_drafts = FALSE;
+ gboolean is_templates = FALSE;
+ const gchar *extension_name;
g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE);
store = camel_folder_get_parent_store (folder);
session = camel_service_get_session (CAMEL_SERVICE (store));
- mail_session = E_MAIL_SESSION (session);
- local_drafts_folder =
+ local_templates_folder =
e_mail_session_get_local_folder (
- mail_session, E_MAIL_LOCAL_FOLDER_DRAFTS);
+ E_MAIL_SESSION (session), E_MAIL_LOCAL_FOLDER_TEMPLATES);
- if (folder == local_drafts_folder)
+ if (folder == local_templates_folder)
return TRUE;
- cache = e_mail_session_get_folder_cache (mail_session);
+ folder_uri = e_mail_folder_uri_from_folder (folder);
- /* user can select Inbox as his Draft folder - in that case prefer Inbox type */
- if (mail_folder_cache_get_folder_info_flags (cache, folder, &flags) &&
- (flags & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_INBOX)
- return FALSE;
+ store = camel_folder_get_parent_store (folder);
+ session = camel_service_get_session (CAMEL_SERVICE (store));
- folder_uri = e_mail_folder_uri_from_folder (folder);
+ extension_name = E_SOURCE_EXTENSION_MAIL_COMPOSITION;
+ list = e_source_registry_list_sources (registry, extension_name);
- account_list = e_get_account_list ();
- iterator = e_list_get_iterator (E_LIST (account_list));
+ for (iter = list; iter != NULL; iter = g_list_next (iter)) {
+ ESource *source = E_SOURCE (iter->data);
+ ESourceExtension *extension;
+ const gchar *templates_folder_uri;
- while (!is_drafts && e_iterator_is_valid (iterator)) {
- EAccount *account;
+ extension = e_source_get_extension (source, extension_name);
- /* XXX EIterator misuses const. */
- account = (EAccount *) e_iterator_get (iterator);
+ templates_folder_uri =
+ e_source_mail_composition_get_templates_folder (
+ E_SOURCE_MAIL_COMPOSITION (extension));
- if (account->drafts_folder_uri != NULL)
- is_drafts = e_mail_folder_uri_equal (
- session, folder_uri,
- account->drafts_folder_uri);
+ if (templates_folder_uri != NULL)
+ is_templates = e_mail_folder_uri_equal (
+ session, folder_uri, templates_folder_uri);
- e_iterator_next (iterator);
+ if (is_templates)
+ break;
}
- g_object_unref (iterator);
+ g_list_free_full (list, (GDestroyNotify) g_object_unref);
g_free (folder_uri);
- return is_drafts;
+ return is_templates;
}
/**
* em_utils_folder_is_sent:
+ * @registry: an #ESourceRegistry
* @folder: a #CamelFolder
*
* Decides if @folder is a Sent folder.
@@ -190,59 +205,57 @@ em_utils_folder_is_drafts (CamelFolder *folder)
* Returns %TRUE if this is a Sent folder or %FALSE otherwise.
**/
gboolean
-em_utils_folder_is_sent (CamelFolder *folder)
+em_utils_folder_is_sent (ESourceRegistry *registry,
+ CamelFolder *folder)
{
CamelFolder *local_sent_folder;
CamelSession *session;
CamelStore *store;
- MailFolderCache *cache;
- EMailSession *mail_session;
- CamelFolderInfoFlags flags = 0;
- EAccountList *account_list;
- EIterator *iterator;
+ GList *list, *iter;
gchar *folder_uri;
gboolean is_sent = FALSE;
+ const gchar *extension_name;
g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE);
store = camel_folder_get_parent_store (folder);
session = camel_service_get_session (CAMEL_SERVICE (store));
- mail_session = E_MAIL_SESSION (session);
local_sent_folder =
e_mail_session_get_local_folder (
- mail_session, E_MAIL_LOCAL_FOLDER_SENT);
+ E_MAIL_SESSION (session), E_MAIL_LOCAL_FOLDER_SENT);
if (folder == local_sent_folder)
return TRUE;
- cache = e_mail_session_get_folder_cache (mail_session);
+ folder_uri = e_mail_folder_uri_from_folder (folder);
- /* user can select Inbox as his Sent folder - in that case prefer Inbox type */
- if (mail_folder_cache_get_folder_info_flags (cache, folder, &flags) &&
- (flags & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_INBOX)
- return FALSE;
+ store = camel_folder_get_parent_store (folder);
+ session = camel_service_get_session (CAMEL_SERVICE (store));
- folder_uri = e_mail_folder_uri_from_folder (folder);
+ extension_name = E_SOURCE_EXTENSION_MAIL_SUBMISSION;
+ list = e_source_registry_list_sources (registry, extension_name);
- account_list = e_get_account_list ();
- iterator = e_list_get_iterator (E_LIST (account_list));
+ for (iter = list; iter != NULL; iter = g_list_next (iter)) {
+ ESource *source = E_SOURCE (iter->data);
+ ESourceExtension *extension;
+ const gchar *sent_folder_uri;
- while (!is_sent && e_iterator_is_valid (iterator)) {
- EAccount *account;
+ extension = e_source_get_extension (source, extension_name);
- /* XXX EIterator misuses const. */
- account = (EAccount *) e_iterator_get (iterator);
+ sent_folder_uri =
+ e_source_mail_submission_get_sent_folder (
+ E_SOURCE_MAIL_SUBMISSION (extension));
- if (account->sent_folder_uri != NULL)
+ if (sent_folder_uri != NULL)
is_sent = e_mail_folder_uri_equal (
- session, folder_uri,
- account->sent_folder_uri);
+ session, folder_uri, sent_folder_uri);
- e_iterator_next (iterator);
+ if (is_sent)
+ break;
}
- g_object_unref (iterator);
+ g_list_free_full (list, (GDestroyNotify) g_object_unref);
g_free (folder_uri);
return is_sent;
@@ -250,6 +263,7 @@ em_utils_folder_is_sent (CamelFolder *folder)
/**
* em_utils_folder_is_outbox:
+ * @registry: an #ESourceRegistry
* @folder: a #CamelFolder
*
* Decides if @folder is an Outbox folder.
@@ -257,7 +271,8 @@ em_utils_folder_is_sent (CamelFolder *folder)
* Returns %TRUE if this is an Outbox folder or %FALSE otherwise.
**/
gboolean
-em_utils_folder_is_outbox (CamelFolder *folder)
+em_utils_folder_is_outbox (ESourceRegistry *registry,
+ CamelFolder *folder)
{
CamelStore *store;
CamelSession *session;
@@ -277,19 +292,6 @@ em_utils_folder_is_outbox (CamelFolder *folder)
/* ********************************************************************** */
-/* runs sync, in main thread */
-static gpointer
-emu_addr_setup (gpointer user_data)
-{
- GError *err = NULL;
- ESourceList **psource_list = user_data;
-
- if (!e_book_client_get_sources (psource_list, &err))
- g_error_free (err);
-
- return NULL;
-}
-
static void
emu_addr_cancel_stop (gpointer data)
{
@@ -405,33 +407,31 @@ static GHashTable *emu_books_hash = NULL;
* broken books, which failed to open for some reason */
static GHashTable *emu_broken_books_hash = NULL;
-static ESourceList *emu_books_source_list = NULL;
-
static gboolean
-search_address_in_addressbooks (const gchar *address,
+search_address_in_addressbooks (ESourceRegistry *registry,
+ const gchar *address,
gboolean local_only,
gboolean (*check_contact) (EContact *contact,
gpointer user_data),
gpointer user_data)
{
+ GList *list, *link;
+ GList *addr_sources = NULL;
gboolean found = FALSE, stop = FALSE, found_any = FALSE;
gchar *lowercase_addr;
gpointer ptr;
EBookQuery *book_query;
gchar *query;
- GSList *s, *g, *addr_sources = NULL;
GHook *hook_cancellable;
GCancellable *cancellable;
+ const gchar *extension_name;
if (!address || !*address)
return FALSE;
G_LOCK (contact_cache);
- if (!emu_books_source_list) {
- mail_call_main (
- MAIL_CALL_p_p, (MailMainFunc)
- emu_addr_setup, &emu_books_source_list);
+ if (emu_books_hash == NULL) {
emu_books_hash = g_hash_table_new_full (
g_str_hash, g_str_equal, g_free, g_object_unref);
emu_broken_books_hash = g_hash_table_new_full (
@@ -440,11 +440,6 @@ search_address_in_addressbooks (const gchar *address,
g_str_hash, g_str_equal, g_free, NULL);
}
- if (!emu_books_source_list) {
- G_UNLOCK (contact_cache);
- return FALSE;
- }
-
lowercase_addr = g_utf8_strdown (address, -1);
ptr = g_hash_table_lookup (contact_cache, lowercase_addr);
if (ptr != NULL && (check_contact == NULL || ptr == NOT_FOUND_BOOK)) {
@@ -457,35 +452,48 @@ search_address_in_addressbooks (const gchar *address,
query = e_book_query_to_string (book_query);
e_book_query_unref (book_query);
- for (g = e_source_list_peek_groups (emu_books_source_list);
- g; g = g_slist_next (g)) {
- ESourceGroup *group = g->data;
+ extension_name = E_SOURCE_EXTENSION_ADDRESS_BOOK;
+ list = e_source_registry_list_sources (registry, extension_name);
- if (!group)
- continue;
+ for (link = list; link != NULL; link = g_list_next (link)) {
+ ESource *source = E_SOURCE (link->data);
+ ESourceExtension *extension;
+ const gchar *backend_name;
+ gboolean source_is_local;
+ gboolean autocomplete;
+
+ extension_name = E_SOURCE_EXTENSION_ADDRESS_BOOK;
+ extension = e_source_get_extension (source, extension_name);
+
+ backend_name = e_source_backend_get_backend_name (
+ E_SOURCE_BACKEND (extension));
+
+ source_is_local = (g_strcmp0 (backend_name, "local") == 0);
- if (local_only && !(e_source_group_peek_base_uri (group) &&
- g_str_has_prefix (
- e_source_group_peek_base_uri (group), "local:")))
+ if (local_only && !source_is_local)
continue;
- for (s = e_source_group_peek_sources (group); s; s = g_slist_next (s)) {
- ESource *source = s->data;
- const gchar *completion = e_source_get_property (source, "completion");
+ extension_name = E_SOURCE_EXTENSION_AUTOCOMPLETE;
+ extension = e_source_get_extension (source, extension_name);
- if (completion && g_ascii_strcasecmp (completion, "true") == 0) {
- addr_sources = g_slist_prepend (
- addr_sources, g_object_ref (source));
- }
- }
+ autocomplete = e_source_autocomplete_get_include_me (
+ E_SOURCE_AUTOCOMPLETE (extension));
+
+ if (!autocomplete)
+ continue;
+
+ addr_sources = g_list_prepend (
+ addr_sources, g_object_ref (source));
}
+ g_list_free_full (list, (GDestroyNotify) g_object_unref);
+
cancellable = g_cancellable_new ();
hook_cancellable = mail_cancel_hook_add (
emu_addr_cancel_cancellable, cancellable);
- for (s = addr_sources; !stop && !found && s; s = g_slist_next (s)) {
- ESource *source = s->data;
+ for (link = addr_sources; !stop && !found && link != NULL; link = g_list_next (link)) {
+ ESource *source = E_SOURCE (link->data);
GSList *contacts;
EBookClient *book_client = NULL;
GHook *hook_stop;
@@ -620,7 +628,7 @@ search_address_in_addressbooks (const gchar *address,
mail_cancel_hook_remove (hook_cancellable);
g_object_unref (cancellable);
- g_slist_free_full (addr_sources, (GDestroyNotify) g_object_unref);
+ g_list_free_full (addr_sources, (GDestroyNotify) g_object_unref);
g_free (query);
@@ -637,16 +645,20 @@ search_address_in_addressbooks (const gchar *address,
}
gboolean
-em_utils_in_addressbook (CamelInternetAddress *iaddr,
+em_utils_in_addressbook (ESourceRegistry *registry,
+ CamelInternetAddress *iaddr,
gboolean local_only)
{
const gchar *addr;
+ g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), FALSE);
+
/* TODO: check all addresses? */
if (iaddr == NULL || !camel_internet_address_get (iaddr, 0, NULL, &addr))
return FALSE;
- return search_address_in_addressbooks (addr, local_only, NULL, NULL);
+ return search_address_in_addressbooks (
+ registry, addr, local_only, NULL, NULL);
}
static gboolean
@@ -687,7 +699,8 @@ G_LOCK_DEFINE_STATIC (photos_cache);
static GSList *photos_cache = NULL; /* list of PhotoInfo-s */
CamelMimePart *
-em_utils_contact_photo (CamelInternetAddress *cia,
+em_utils_contact_photo (ESourceRegistry *registry,
+ CamelInternetAddress *cia,
gboolean local_only)
{
const gchar *addr = NULL;
@@ -696,6 +709,8 @@ em_utils_contact_photo (CamelInternetAddress *cia,
GSList *p, *last = NULL;
gint cache_len;
+ g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
+
if (cia == NULL || !camel_internet_address_get (cia, 0, NULL, &addr) || !addr) {
return NULL;
}
@@ -722,7 +737,8 @@ em_utils_contact_photo (CamelInternetAddress *cia,
/* !p means the address had not been found in the cache */
if (!p && search_address_in_addressbooks (
- addr, local_only, extract_photo_data, &photo)) {
+ registry, addr, local_only, extract_photo_data, &photo)) {
+
PhotoInfo *pi;
/* keep only up to 10 photos in memory */
@@ -838,11 +854,6 @@ emu_free_mail_cache (void)
emu_broken_books_hash = NULL;
}
- if (emu_books_source_list) {
- g_object_unref (emu_books_source_list);
- emu_books_source_list = NULL;
- }
-
if (contact_cache) {
g_hash_table_destroy (contact_cache);
contact_cache = NULL;
@@ -859,70 +870,197 @@ emu_free_mail_cache (void)
G_UNLOCK (photos_cache);
}
-static EAccount *
-guess_account_from_folder (CamelFolder *folder)
+static ESource *
+guess_mail_account_from_folder (ESourceRegistry *registry,
+ CamelFolder *folder)
{
+ ESource *source;
CamelStore *store;
const gchar *uid;
+ /* Lookup an ESource by CamelStore UID. */
store = camel_folder_get_parent_store (folder);
uid = camel_service_get_uid (CAMEL_SERVICE (store));
+ source = e_source_registry_ref_source (registry, uid);
+
+ /* If we found an ESource, make sure it's a mail account. */
+ if (source != NULL) {
+ const gchar *extension_name;
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+ if (!e_source_has_extension (source, extension_name)) {
+ g_object_unref (source);
+ source = NULL;
+ }
+ }
- return e_get_account_by_uid (uid);
+ return source;
}
-static EAccount *
-guess_account_from_message (CamelMimeMessage *message)
+static ESource *
+guess_mail_account_from_message (ESourceRegistry *registry,
+ CamelMimeMessage *message)
{
+ ESource *source = NULL;
const gchar *uid;
+ /* Lookup an ESource by 'X-Evolution-Source' header. */
uid = camel_mime_message_get_source (message);
+ if (uid != NULL)
+ source = e_source_registry_ref_source (registry, uid);
- return (uid != NULL) ? e_get_account_by_uid (uid) : NULL;
+ /* If we found an ESource, make sure it's a mail account. */
+ if (source != NULL) {
+ const gchar *extension_name;
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+ if (!e_source_has_extension (source, extension_name)) {
+ g_object_unref (source);
+ source = NULL;
+ }
+ }
+
+ return source;
}
-EAccount *
-em_utils_guess_account (CamelMimeMessage *message,
- CamelFolder *folder)
+ESource *
+em_utils_guess_mail_account (ESourceRegistry *registry,
+ CamelMimeMessage *message,
+ CamelFolder *folder)
{
- EAccount *account = NULL;
+ ESource *source = NULL;
+ const gchar *newsgroups;
+ g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
g_return_val_if_fail (CAMEL_IS_MIME_MESSAGE (message), NULL);
if (folder != NULL)
g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL);
/* check for newsgroup header */
- if (folder != NULL
- && camel_medium_get_header (CAMEL_MEDIUM (message), "Newsgroups"))
- account = guess_account_from_folder (folder);
+ newsgroups = camel_medium_get_header (
+ CAMEL_MEDIUM (message), "Newsgroups");
+ if (folder != NULL && newsgroups != NULL)
+ source = guess_mail_account_from_folder (registry, folder);
/* check for source folder */
- if (account == NULL && folder != NULL)
- account = guess_account_from_folder (folder);
+ if (source == NULL && folder != NULL)
+ source = guess_mail_account_from_folder (registry, folder);
/* then message source */
- if (account == NULL)
- account = guess_account_from_message (message);
+ if (source == NULL)
+ source = guess_mail_account_from_message (registry, message);
+
+ return source;
+}
+
+ESource *
+em_utils_guess_mail_identity (ESourceRegistry *registry,
+ CamelMimeMessage *message,
+ CamelFolder *folder)
+{
+ ESource *source;
+ ESourceExtension *extension;
+ const gchar *extension_name;
+ const gchar *uid;
+
+ g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
+ g_return_val_if_fail (CAMEL_IS_MIME_MESSAGE (message), NULL);
+
+ if (folder != NULL)
+ g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL);
+
+ source = em_utils_guess_mail_account (registry, message, folder);
+
+ if (source == NULL)
+ return NULL;
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+ extension = e_source_get_extension (source, extension_name);
+
+ uid = e_source_mail_account_get_identity_uid (
+ E_SOURCE_MAIL_ACCOUNT (extension));
+ if (uid == NULL)
+ return NULL;
+
+ source = e_source_registry_ref_source (registry, uid);
+ if (source == NULL)
+ return NULL;
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
+ if (!e_source_has_extension (source, extension_name)) {
+ g_object_unref (source);
+ return NULL;
+ }
+
+ return source;
+}
+
+static gboolean
+mail_account_in_recipients (ESourceRegistry *registry,
+ ESource *source,
+ GHashTable *recipients)
+{
+ ESourceExtension *extension;
+ const gchar *extension_name;
+ const gchar *uid;
+ gboolean match = FALSE;
+ gchar *address;
+
+ /* Disregard disabled mail accounts. */
+ if (!e_source_get_enabled (source))
+ return FALSE;
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+ extension = e_source_get_extension (source, extension_name);
+
+ uid = e_source_mail_account_get_identity_uid (
+ E_SOURCE_MAIL_ACCOUNT (extension));
+ if (uid == NULL)
+ return FALSE;
+
+ source = e_source_registry_ref_source (registry, uid);
+ if (source == NULL)
+ return FALSE;
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
+ if (!e_source_has_extension (source, extension_name)) {
+ g_object_unref (source);
+ return FALSE;
+ }
+
+ extension = e_source_get_extension (source, extension_name);
- return account;
+ address = e_source_mail_identity_dup_address (
+ E_SOURCE_MAIL_IDENTITY (extension));
+
+ g_object_unref (source);
+
+ if (address != NULL) {
+ match = (g_hash_table_lookup (recipients, address) != NULL);
+ g_free (address);
+ }
+
+ return match;
}
-EAccount *
-em_utils_guess_account_with_recipients (CamelMimeMessage *message,
- CamelFolder *folder)
+ESource *
+em_utils_guess_mail_account_with_recipients (ESourceRegistry *registry,
+ CamelMimeMessage *message,
+ CamelFolder *folder)
{
- EAccount *account = NULL;
- EAccountList *account_list;
+ ESource *source = NULL;
GHashTable *recipients;
- EIterator *iterator;
CamelInternetAddress *addr;
+ GList *list, *iter;
+ const gchar *extension_name;
const gchar *type;
const gchar *key;
/* This policy is subject to debate and tweaking,
* but please also document the rational here. */
+ g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
g_return_val_if_fail (CAMEL_IS_MIME_MESSAGE (message), NULL);
/* Build a set of email addresses in which to test for membership.
@@ -952,53 +1090,126 @@ em_utils_guess_account_with_recipients (CamelMimeMessage *message,
}
/* First Preference: We were given a folder that maps to an
- * enabled account, and that account's email address appears
+ * enabled mail account, and that account's address appears
* in the list of To: or Cc: recipients. */
if (folder != NULL)
- account = guess_account_from_folder (folder);
-
- if (account == NULL || !account->enabled)
- goto second_preference;
+ source = guess_mail_account_from_folder (registry, folder);
- if ((key = account->id->address) == NULL)
+ if (source == NULL)
goto second_preference;
- if (g_hash_table_lookup (recipients, key) != NULL)
+ if (mail_account_in_recipients (registry, source, recipients))
goto exit;
second_preference:
- /* Second Preference: Choose any enabled account whose email
+ /* Second Preference: Choose any enabled mail account whose
* address appears in the list to To: or Cc: recipients. */
- account_list = e_get_account_list ();
- iterator = e_list_get_iterator (E_LIST (account_list));
+ if (source != NULL) {
+ g_object_unref (source);
+ source = NULL;
+ }
- while (e_iterator_is_valid (iterator)) {
- account = (EAccount *) e_iterator_get (iterator);
- e_iterator_next (iterator);
+ extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+ list = e_source_registry_list_sources (registry, extension_name);
- if (account == NULL || !account->enabled)
- continue;
+ for (iter = list; iter != NULL; iter = g_list_next (iter)) {
+ ESource *temp = E_SOURCE (iter->data);
- if ((key = account->id->address) == NULL)
- continue;
-
- if (g_hash_table_lookup (recipients, key) != NULL) {
- g_object_unref (iterator);
- goto exit;
+ if (mail_account_in_recipients (registry, temp, recipients)) {
+ source = g_object_ref (temp);
+ break;
}
}
- g_object_unref (iterator);
- /* Last Preference: Defer to em_utils_guess_account(). */
- account = em_utils_guess_account (message, folder);
+ g_list_free_full (list, (GDestroyNotify) g_object_unref);
+
+ if (source != NULL)
+ goto exit;
+
+ /* Last Preference: Defer to em_utils_guess_mail_account(). */
+ source = em_utils_guess_mail_account (registry, message, folder);
exit:
g_hash_table_destroy (recipients);
- return account;
+ return source;
+}
+
+ESource *
+em_utils_guess_mail_identity_with_recipients (ESourceRegistry *registry,
+ CamelMimeMessage *message,
+ CamelFolder *folder)
+{
+ ESource *source;
+ ESourceExtension *extension;
+ const gchar *extension_name;
+ const gchar *uid;
+
+ g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
+ g_return_val_if_fail (CAMEL_IS_MIME_MESSAGE (message), NULL);
+
+ source = em_utils_guess_mail_account_with_recipients (
+ registry, message, folder);
+
+ if (source == NULL)
+ return NULL;
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+ extension = e_source_get_extension (source, extension_name);
+
+ uid = e_source_mail_account_get_identity_uid (
+ E_SOURCE_MAIL_ACCOUNT (extension));
+ if (uid == NULL)
+ return NULL;
+
+ source = e_source_registry_ref_source (registry, uid);
+ if (source == NULL)
+ return NULL;
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
+ if (!e_source_has_extension (source, extension_name)) {
+ g_object_unref (source);
+ return NULL;
+ }
+
+ return source;
+}
+
+ESource *
+em_utils_ref_mail_identity_for_store (ESourceRegistry *registry,
+ CamelStore *store)
+{
+ ESourceMailAccount *extension;
+ ESource *source;
+ const gchar *extension_name;
+ const gchar *store_uid;
+ gchar *identity_uid;
+
+ g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
+ g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
+
+ store_uid = camel_service_get_uid (CAMEL_SERVICE (store));
+ g_return_val_if_fail (store_uid != NULL, NULL);
+
+ source = e_source_registry_ref_source (registry, store_uid);
+ g_return_val_if_fail (source != NULL, NULL);
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+ extension = e_source_get_extension (source, extension_name);
+ identity_uid = e_source_mail_account_dup_identity_uid (extension);
+
+ g_object_unref (source);
+ source = NULL;
+
+ if (identity_uid != NULL) {
+ source = e_source_registry_ref_source (registry, identity_uid);
+ g_free (identity_uid);
+ }
+
+ return source;
}
/**
diff --git a/libemail-engine/e-mail-utils.h b/libemail-engine/e-mail-utils.h
index ca8ed010ca..b3782876f4 100644
--- a/libemail-engine/e-mail-utils.h
+++ b/libemail-engine/e-mail-utils.h
@@ -23,21 +23,39 @@
#define E_MAIL_UTILS_H
#include <camel/camel.h>
-#include <libedataserver/e-account.h>
+#include <libedataserver/e-source-registry.h>
-gboolean em_utils_folder_is_drafts (CamelFolder *folder);
-gboolean em_utils_folder_is_templates (CamelFolder *folder);
-gboolean em_utils_folder_is_sent (CamelFolder *folder);
-gboolean em_utils_folder_is_outbox (CamelFolder *folder);
-gboolean em_utils_in_addressbook (CamelInternetAddress *addr,
+gboolean em_utils_folder_is_drafts (ESourceRegistry *registry,
+ CamelFolder *folder);
+gboolean em_utils_folder_is_templates (ESourceRegistry *registry,
+ CamelFolder *folder);
+gboolean em_utils_folder_is_sent (ESourceRegistry *registry,
+ CamelFolder *folder);
+gboolean em_utils_folder_is_outbox (ESourceRegistry *registry,
+ CamelFolder *folder);
+gboolean em_utils_in_addressbook (ESourceRegistry *registry,
+ CamelInternetAddress *addr,
gboolean local_only);
-CamelMimePart * em_utils_contact_photo (CamelInternetAddress *addr,
+CamelMimePart * em_utils_contact_photo (ESourceRegistry *registry,
+ CamelInternetAddress *addr,
gboolean local);
-EAccount * em_utils_guess_account (CamelMimeMessage *message,
+ESource * em_utils_guess_mail_account (ESourceRegistry *registry,
+ CamelMimeMessage *message,
+ CamelFolder *folder);
+ESource * em_utils_guess_mail_identity (ESourceRegistry *registry,
+ CamelMimeMessage *message,
+ CamelFolder *folder);
+ESource * em_utils_guess_mail_account_with_recipients
+ (ESourceRegistry *registry,
+ CamelMimeMessage *message,
CamelFolder *folder);
-EAccount * em_utils_guess_account_with_recipients
- (CamelMimeMessage *message,
+ESource * em_utils_guess_mail_identity_with_recipients
+ (ESourceRegistry *registry,
+ CamelMimeMessage *message,
CamelFolder *folder);
+ESource * em_utils_ref_mail_identity_for_store
+ (ESourceRegistry *registry,
+ CamelStore *store);
void emu_remove_from_mail_cache (const GSList *addresses);
void emu_remove_from_mail_cache_1 (const gchar *address);
void emu_free_mail_cache (void);
diff --git a/libemail-engine/mail-config.c b/libemail-engine/mail-config.c
index 09f0332567..af193f5844 100644
--- a/libemail-engine/mail-config.c
+++ b/libemail-engine/mail-config.c
@@ -31,9 +31,6 @@
#include <libedataserver/e-data-server-util.h>
-#include <libemail-utils/e-account-utils.h>
-#include <libemail-utils/e-signature-utils.h>
-
#include "e-mail-folder-utils.h"
#include "mail-config.h"
#include "mail-tools.h"
@@ -137,24 +134,6 @@ settings_int_value_changed (GSettings *settings,
*save_location = g_settings_get_int (settings, key);
}
-void
-mail_config_write (void)
-{
- EAccountList *account_list;
- ESignatureList *signature_list;
-
- if (!config)
- return;
-
- account_list = e_get_account_list ();
- signature_list = e_get_signature_list ();
-
- e_account_list_save (account_list);
- e_signature_list_save (signature_list);
-
- g_settings_sync ();
-}
-
gint
mail_config_get_address_count (void)
{
diff --git a/libemail-engine/mail-config.h b/libemail-engine/mail-config.h
index 0a1c618f35..cc836acf95 100644
--- a/libemail-engine/mail-config.h
+++ b/libemail-engine/mail-config.h
@@ -29,7 +29,6 @@ G_BEGIN_DECLS
/* Configuration */
void mail_config_init (EMailSession *session);
-void mail_config_write (void);
/* General Accessor functions */
diff --git a/libemail-engine/mail-folder-cache.c b/libemail-engine/mail-folder-cache.c
index 32a4b99dcf..ebc392fb62 100644
--- a/libemail-engine/mail-folder-cache.c
+++ b/libemail-engine/mail-folder-cache.c
@@ -341,11 +341,16 @@ update_1folder (MailFolderCache *cache,
const gchar *msg_subject,
CamelFolderInfo *info)
{
+ EMailSession *session;
+ ESourceRegistry *registry;
struct _folder_update *up;
CamelFolder *folder;
gint unread = -1;
gint deleted;
+ session = mail_folder_cache_get_session (cache);
+ registry = e_mail_session_get_registry (session);
+
folder = mfi->folder;
if (folder) {
gboolean folder_is_sent;
@@ -354,9 +359,9 @@ update_1folder (MailFolderCache *cache,
gboolean folder_is_vtrash;
gboolean special_case;
- folder_is_sent = em_utils_folder_is_sent (folder);
- folder_is_drafts = em_utils_folder_is_drafts (folder);
- folder_is_outbox = em_utils_folder_is_outbox (folder);
+ folder_is_sent = em_utils_folder_is_sent (registry, folder);
+ folder_is_drafts = em_utils_folder_is_drafts (registry, folder);
+ folder_is_outbox = em_utils_folder_is_outbox (registry, folder);
folder_is_vtrash = CAMEL_IS_VTRASH_FOLDER (folder);
special_case =
diff --git a/libemail-engine/mail-ops.c b/libemail-engine/mail-ops.c
index 217f75dc90..91e424b2f7 100644
--- a/libemail-engine/mail-ops.c
+++ b/libemail-engine/mail-ops.c
@@ -35,8 +35,9 @@
#include <glib/gi18n.h>
#include <libedataserver/e-data-server-util.h>
+#include <libedataserver/e-source-mail-account.h>
+#include <libedataserver/e-source-mail-submission.h>
-#include <libemail-utils/e-account-utils.h>
#include <libemail-utils/mail-mt.h>
#include "e-mail-utils.h"
@@ -222,12 +223,20 @@ fetch_mail_exec (struct _fetch_mail_msg *m,
GError **error)
{
struct _filter_mail_msg *fm = (struct _filter_mail_msg *) m;
+ GObjectClass *class;
CamelFolder *folder = NULL;
CamelService *service;
CamelSession *session;
+ CamelSettings *settings;
+ CamelStore *parent_store;
+ CamelUIDCache *cache = NULL;
CamelURL *url;
+ gboolean keep;
+ gboolean delete_fetched;
gboolean is_local_delivery = FALSE;
const gchar *uid = NULL;
+ const gchar *data_dir;
+ gchar *cachename;
gint i;
service = CAMEL_SERVICE (m->store);
@@ -239,6 +248,18 @@ fetch_mail_exec (struct _fetch_mail_msg *m,
goto exit;
g_object_ref (fm->destination);
+ service = CAMEL_SERVICE (m->store);
+ uid = camel_service_get_uid (service);
+ settings = camel_service_get_settings (service);
+
+ /* XXX This is a POP3-specific setting. */
+ class = G_OBJECT_GET_CLASS (settings);
+ if (g_object_class_find_property (class, "keep-on-server") != NULL)
+ g_object_get (settings, "keep-on-server", &keep, NULL);
+
+ /* Just for readability. */
+ delete_fetched = !keep;
+
url = camel_service_new_camel_url (service);
is_local_delivery = em_utils_is_local_delivery_mbox_file (url);
@@ -276,32 +297,26 @@ fetch_mail_exec (struct _fetch_mail_msg *m,
camel_url_free (url);
- if (folder != NULL) {
- /* This handles 'keep on server' stuff, if we have any new
- * uid's to copy across, we need to copy them to a new array
- * 'cause of the way fetch_mail_free works. */
- CamelUIDCache *cache = NULL;
- CamelStore *parent_store;
- CamelService *service;
- const gchar *data_dir;
- gchar *cachename;
+ if (folder == NULL)
+ goto exit;
- parent_store = camel_folder_get_parent_store (folder);
+ parent_store = camel_folder_get_parent_store (folder);
- if (m->fetch_count > 0) {
- /* We probably should fetch some old messages first. */
- m->still_more = camel_folder_fetch_messages_sync (folder, m->fetch_type,
- m->fetch_count, cancellable, error) ? 1 : 0;
- }
- service = CAMEL_SERVICE (parent_store);
- data_dir = camel_service_get_user_data_dir (service);
+ if (m->fetch_count > 0) {
+ /* We probably should fetch some old messages first. */
+ m->still_more = camel_folder_fetch_messages_sync (folder, m->fetch_type,
+ m->fetch_count, cancellable, error) ? 1 : 0;
+ }
+
+ service = CAMEL_SERVICE (parent_store);
+ data_dir = camel_service_get_user_data_dir (service);
- cachename = g_build_filename (data_dir, "uid-cache", NULL);
- cache = camel_uid_cache_new (cachename);
- g_free (cachename);
+ cachename = g_build_filename (data_dir, "uid-cache", NULL);
+ cache = camel_uid_cache_new (cachename);
+ g_free (cachename);
- if (cache) {
- GPtrArray *folder_uids, *cache_uids, *uids;
+ if (cache) {
+ GPtrArray *folder_uids, *cache_uids, *uids;
if (m->provider_fetch_inbox) {
g_object_unref (fm->destination);
@@ -325,46 +340,48 @@ fetch_mail_exec (struct _fetch_mail_msg *m,
camel_uid_cache_free_uids (cache_uids);
- fm->cache = cache;
- em_filter_folder_element_exec (fm, cancellable, error);
+ fm->cache = cache;
- /* need to uncancel so writes/etc. don't fail */
- if (g_cancellable_is_cancelled (m->cancellable))
- g_cancellable_reset (m->cancellable);
+ /* FIXME Should return a success/failure flag. */
+ em_filter_folder_element_exec (fm, cancellable, error);
- /* save the cache of uids that we've just downloaded */
- camel_uid_cache_save (cache);
- }
+ /* need to uncancel so writes/etc. don't fail */
+ if (g_cancellable_is_cancelled (m->cancellable))
+ g_cancellable_reset (m->cancellable);
- if (fm->delete && (!error || !*error)) {
- /* not keep on server - just delete all
- * the actual messages on the server */
- for (i = 0; i < folder_uids->len; i++) {
- camel_folder_delete_message (
- folder, folder_uids->pdata[i]);
- }
- }
+ /* save the cache of uids that we've just downloaded */
+ camel_uid_cache_save (cache);
+ }
- if ((fm->delete || cache_uids) && (!error || !*error)) {
- /* expunge messages (downloaded so far) */
- /* FIXME Not passing a GCancellable or GError here. */
- camel_folder_synchronize_sync (
- folder, fm->delete, NULL, NULL);
+ if (delete_fetched && (!error || !*error)) {
+ /* not keep on server - just delete all
+ * the actual messages on the server */
+ for (i = 0; i < folder_uids->len; i++) {
+ camel_folder_delete_message (
+ folder, folder_uids->pdata[i]);
}
+ }
- camel_uid_cache_destroy (cache);
- camel_folder_free_uids (folder, folder_uids);
- } else {
- em_filter_folder_element_exec (fm, cancellable, error);
+ if ((delete_fetched || cache_uids) && (!error || !*error)) {
+ /* expunge messages (downloaded so far) */
+ /* FIXME Not passing a GCancellable or GError here. */
+ camel_folder_synchronize_sync (
+ folder, delete_fetched, NULL, NULL);
}
- /* we unref the source folder here since we
- * may now block in finalize (we try to
- * disconnect cleanly) */
- g_object_unref (fm->source_folder);
- fm->source_folder = NULL;
+ camel_uid_cache_destroy (cache);
+ camel_folder_free_uids (folder, folder_uids);
+ } else {
+ /* FIXME Should return a success/failure flag. */
+ em_filter_folder_element_exec (fm, cancellable, error);
}
+ /* we unref the source folder here since we
+ * may now block in finalize (we try to
+ * disconnect cleanly) */
+ g_object_unref (fm->source_folder);
+ fm->source_folder = NULL;
+
exit:
if (!is_local_delivery && m->provider_unlock)
m->provider_unlock (uid);
@@ -414,8 +431,7 @@ static MailMsgInfo fetch_mail_info = {
/* ouch, a 'do everything' interface ... */
void
mail_fetch_mail (CamelStore *store,
- gint keep,
- CamelFetchType fetch_type,
+ CamelFetchType fetch_type,
gint fetch_count,
const gchar *type,
MailProviderFetchLockFunc lock_func,
@@ -442,7 +458,6 @@ mail_fetch_mail (CamelStore *store,
fm = (struct _filter_mail_msg *) m;
fm->session = g_object_ref (session);
m->store = g_object_ref (store);
- fm->delete = !keep;
fm->cache = NULL;
if (cancellable)
m->cancellable = g_object_ref (cancellable);
@@ -504,6 +519,44 @@ static void report_status (struct _send_queue_msg *m,
const gchar *desc,
...);
+static gboolean
+get_submission_details_from_identity (EMailSession *session,
+ const gchar *identity_uid,
+ gchar **out_transport_uid,
+ gchar **out_sent_folder_uri)
+{
+ ESource *source;
+ ESourceRegistry *registry;
+ ESourceExtension *extension;
+ const gchar *extension_name;
+
+ registry = e_mail_session_get_registry (session);
+ extension_name = E_SOURCE_EXTENSION_MAIL_SUBMISSION;
+ source = e_source_registry_ref_source (registry, identity_uid);
+
+ if (source == NULL)
+ return FALSE;
+
+ if (!e_source_has_extension (source, extension_name)) {
+ g_object_unref (source);
+ return FALSE;
+ }
+
+ extension = e_source_get_extension (source, extension_name);
+
+ *out_sent_folder_uri =
+ e_source_mail_submission_dup_sent_folder (
+ E_SOURCE_MAIL_SUBMISSION (extension));
+
+ *out_transport_uid =
+ e_source_mail_submission_dup_transport_uid (
+ E_SOURCE_MAIL_SUBMISSION (extension));
+
+ g_object_unref (source);
+
+ return TRUE;
+}
+
/* send 1 message to a specific transport */
static void
mail_send_message (struct _send_queue_msg *m,
@@ -514,11 +567,11 @@ mail_send_message (struct _send_queue_msg *m,
GCancellable *cancellable,
GError **error)
{
- EAccount *account = NULL;
+ CamelService *service;
const CamelInternetAddress *iaddr;
CamelAddress *from, *recipients;
CamelMessageInfo *info = NULL;
- CamelProvider *provider;
+ CamelProvider *provider = NULL;
gchar *transport_uid = NULL;
gchar *sent_folder_uri = NULL;
const gchar *resent_from, *tmp;
@@ -539,48 +592,31 @@ mail_send_message (struct _send_queue_msg *m,
err = g_string_new ("");
xev = mail_tool_remove_xevolution_headers (message);
- tmp = camel_header_raw_find (&xev, "X-Evolution-Account", NULL);
+ tmp = camel_header_raw_find (&xev, "X-Evolution-Identity", NULL);
if (tmp != NULL) {
- gchar *name;
-
- name = g_strstrip (g_strdup (tmp));
- if ((account = e_get_account_by_uid (name))
- /* 'old' x-evolution-account stored the name, how silly */
- || (account = e_get_account_by_name (name))) {
- if (account->transport) {
- CamelService *service;
- gchar *transport_uid;
-
- transport_uid = g_strconcat (
- account->uid, "-transport", NULL);
- service = camel_session_get_service (
- CAMEL_SESSION (m->session),
- transport_uid);
- g_free (transport_uid);
-
- if (CAMEL_IS_TRANSPORT (service))
- transport = CAMEL_TRANSPORT (service);
- }
+ gchar *identity_uid;
- sent_folder_uri = g_strdup (account->sent_folder_uri);
- }
- g_free (name);
+ identity_uid = g_strstrip (g_strdup (tmp));
+ get_submission_details_from_identity (
+ m->session, identity_uid,
+ &transport_uid, &sent_folder_uri);
+ g_free (identity_uid);
}
- if (!account) {
- /* default back to these headers */
- tmp = camel_header_raw_find(&xev, "X-Evolution-Transport", NULL);
- if (tmp)
- transport_uid = g_strstrip (g_strdup (tmp));
+ tmp = camel_header_raw_find (&xev, "X-Evolution-Transport", NULL);
+ if (transport_uid == NULL && tmp != NULL)
+ transport_uid = g_strstrip (g_strdup (tmp));
- tmp = camel_header_raw_find(&xev, "X-Evolution-Fcc", NULL);
- if (tmp)
- sent_folder_uri = g_strstrip (g_strdup (tmp));
- }
+ tmp = camel_header_raw_find (&xev, "X-Evolution-Fcc", NULL);
+ if (sent_folder_uri == NULL && tmp != NULL)
+ sent_folder_uri = g_strstrip (g_strdup (tmp));
- if (transport != NULL) {
- const gchar *uid;
+ service = camel_session_get_service (
+ CAMEL_SESSION (m->session), transport_uid);
+ if (service != NULL)
+ provider = camel_service_get_provider (service);
+ if (CAMEL_IS_TRANSPORT (service)) {
/* Let the dialog know the right account it is using. */
uid = camel_service_get_uid (CAMEL_SERVICE (transport));
report_status (m, CAMEL_FILTER_STATUS_ACTION, 0, uid);
@@ -607,12 +643,12 @@ mail_send_message (struct _send_queue_msg *m,
if (camel_address_length (recipients) > 0) {
if (!camel_service_connect_sync (
- CAMEL_SERVICE (transport), cancellable, error))
+ service, cancellable, error))
goto exit;
if (!camel_transport_send_to_sync (
- transport, message, from,
- recipients, cancellable, error))
+ CAMEL_TRANSPORT (service), message,
+ from, recipients, cancellable, error))
goto exit;
}
@@ -663,8 +699,6 @@ mail_send_message (struct _send_queue_msg *m,
}
}
- provider = camel_service_get_provider (CAMEL_SERVICE (transport));
-
if (provider == NULL
|| !(provider->flags & CAMEL_PROVIDER_DISABLE_SENT_FOLDER)) {
GError *local_error = NULL;
@@ -1362,9 +1396,10 @@ expunge_pop3_stores (CamelFolder *expunging,
CamelStore *parent_store;
CamelService *service;
CamelSession *session;
+ ESourceRegistry *registry;
GPtrArray *uids;
- EAccount *account;
- EIterator *iter;
+ GList *list, *link;
+ const gchar *extension_name;
gboolean success = TRUE;
guint ii;
@@ -1372,6 +1407,7 @@ expunge_pop3_stores (CamelFolder *expunging,
service = CAMEL_SERVICE (parent_store);
session = camel_service_get_session (service);
+ registry = e_mail_session_get_registry (E_MAIL_SESSION (session));
uids = camel_folder_get_uids (expunging);
@@ -1432,79 +1468,89 @@ expunge_pop3_stores (CamelFolder *expunging,
return TRUE;
}
- for (iter = e_list_get_iterator ((EList *) e_get_account_list ());
- e_iterator_is_valid (iter); e_iterator_next (iter)) {
- account = (EAccount *) e_iterator_get (iter);
+ extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+ list = e_source_registry_list_sources (registry, extension_name);
- if (account->enabled &&
- account->source && account->source->url &&
- g_str_has_prefix (account->source->url, "pop://")) {
- CamelFolder *folder;
- CamelService *service;
- CamelSettings *settings;
- gboolean any_found = FALSE;
- gboolean delete_expunged = FALSE;
- gboolean keep_on_server = FALSE;
+ for (link = list; link != NULL; link = g_list_next (link)) {
+ ESource *source = E_SOURCE (link->data);
+ ESourceBackend *extension;
+ CamelFolder *folder;
+ CamelService *service;
+ CamelSettings *settings;
+ const gchar *backend_name;
+ const gchar *source_uid;
+ gboolean any_found = FALSE;
+ gboolean delete_expunged = FALSE;
+ gboolean keep_on_server = FALSE;
+ gboolean enabled;
- service = camel_session_get_service (session, account->uid);
+ source_uid = e_source_get_uid (source);
+ enabled = e_source_get_enabled (source);
- if (!CAMEL_IS_STORE (service))
- continue;
+ extension = e_source_get_extension (source, extension_name);
+ backend_name = e_source_backend_get_backend_name (extension);
- settings = camel_service_get_settings (service);
- if (!settings)
- continue;
+ if (!enabled || g_strcmp0 (backend_name, "pop") != 0)
+ continue;
- g_object_get (
- settings,
- "delete-expunged", &delete_expunged,
- "keep-on-server", &keep_on_server,
- NULL);
+ service = camel_session_get_service (
+ CAMEL_SESSION (session), source_uid);
- if (!keep_on_server || !delete_expunged)
- continue;
+ settings = camel_service_get_settings (service);
- folder = e_mail_session_get_inbox_sync (
- E_MAIL_SESSION (session),
- account->uid, cancellable, error);
+ g_object_get (
+ settings,
+ "delete-expunged", &delete_expunged,
+ "keep-on-server", &keep_on_server,
+ NULL);
- /* Abort the loop on error. */
- if (folder == NULL) {
- success = FALSE;
- break;
- }
+ if (!keep_on_server || !delete_expunged)
+ continue;
- uids = camel_folder_get_uids (folder);
- if (uids) {
- for (ii = 0; ii < uids->len; ii++) {
- /* ensure the ID is from this account,
- * as it's generated by evolution */
- const gchar *source_uid;
-
- source_uid = g_hash_table_lookup (
- expunging_uids, uids->pdata[ii]);
- if (folder_is_from_source_uid (folder, source_uid)) {
- any_found = TRUE;
- camel_folder_delete_message (folder, uids->pdata[ii]);
- }
- }
- camel_folder_free_uids (folder, uids);
- }
+ folder = camel_store_get_inbox_folder_sync (
+ CAMEL_STORE (service), cancellable, error);
- if (any_found)
- success = camel_folder_synchronize_sync (
- folder, TRUE, cancellable, error);
+ /* Abort the loop on error. */
+ if (folder == NULL) {
+ success = FALSE;
+ break;
+ }
+
+ uids = camel_folder_get_uids (folder);
+ if (uids == NULL) {
g_object_unref (folder);
+ continue;
+ }
- /* Abort the loop on error. */
- if (!success)
- break;
+ for (ii = 0; ii < uids->len; ii++) {
+ /* ensure the ID is from this account,
+ * as it's generated by evolution */
+ const gchar *source_uid;
+
+ source_uid = g_hash_table_lookup (
+ expunging_uids, uids->pdata[ii]);
+ if (folder_is_from_source_uid (folder, source_uid)) {
+ any_found = TRUE;
+ camel_folder_delete_message (
+ folder, uids->pdata[ii]);
+ }
}
+
+ camel_folder_free_uids (folder, uids);
+
+ if (any_found)
+ success = camel_folder_synchronize_sync (
+ folder, TRUE, cancellable, error);
+
+ g_object_unref (folder);
+
+ /* Abort the loop on error. */
+ if (!success)
+ break;
}
- if (iter)
- g_object_unref (iter);
+ g_list_free_full (list, (GDestroyNotify) g_object_unref);
g_hash_table_destroy (expunging_uids);
diff --git a/libemail-engine/mail-ops.h b/libemail-engine/mail-ops.h
index d42268d8ad..7ec9b14f4f 100644
--- a/libemail-engine/mail-ops.h
+++ b/libemail-engine/mail-ops.h
@@ -79,7 +79,6 @@ typedef CamelFolder *
GError **error);
void mail_fetch_mail (CamelStore *store,
- gint keep,
CamelFetchType fetch_type,
gint fetch_count,
const gchar *type,