From d75f6c636406385abb50025b4c371dec262b1c4b Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Tue, 24 Jan 2012 22:18:20 -0500 Subject: Bug 668479: Missing transport-only accounts in Preferences Evolution kinda sorta supports multiple identities by allowing users to set up so-called "transport-only" accounts by choosing "None" for the account type. Add a CamelStore subclass for those types of accounts so they get added to EMailAccountStore. It's just a stupid hack to keep another stupid hack working, but this should sustain us until we can support multiple identities FOR REAL. --- libemail-engine/Makefile.am | 2 + libemail-engine/camel-null-store.c | 76 ++++++++++++++++++++++++++++++++++++++ libemail-engine/camel-null-store.h | 64 ++++++++++++++++++++++++++++++++ libemail-engine/e-mail-session.c | 60 +++++++++++++++--------------- mail/em-account-editor.c | 26 +++++++------ 5 files changed, 185 insertions(+), 43 deletions(-) create mode 100644 libemail-engine/camel-null-store.c create mode 100644 libemail-engine/camel-null-store.h diff --git a/libemail-engine/Makefile.am b/libemail-engine/Makefile.am index 88a0227aab..ce0a1ab392 100644 --- a/libemail-engine/Makefile.am +++ b/libemail-engine/Makefile.am @@ -20,6 +20,7 @@ libemail_engine_la_CPPFLAGS = \ libmailengineincludedir = $(privincludedir)/libemail-engine libmailengineinclude_HEADERS = \ + camel-null-store.h \ e-mail-enums.h \ e-mail-enumtypes.h \ e-mail-folder-utils.h \ @@ -36,6 +37,7 @@ libmailengineinclude_HEADERS = \ libemail_engine_la_SOURCES = \ $(libmailengineinclude_HEADERS) \ + camel-null-store.c \ e-mail-enumtypes.c \ e-mail-folder-utils.c \ e-mail-junk-filter.c \ diff --git a/libemail-engine/camel-null-store.c b/libemail-engine/camel-null-store.c new file mode 100644 index 0000000000..a4ebb53e33 --- /dev/null +++ b/libemail-engine/camel-null-store.c @@ -0,0 +1,76 @@ +/* + * camel-null-store.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 + * + */ + +#include "camel-null-store.h" + +#include +#include + +G_DEFINE_TYPE (CamelNullStore, camel_null_store, CAMEL_TYPE_STORE) + +static CamelProvider null_provider = { + /* protocol: */ "none", + /* name: */ N_("None"), + /* description: */ NULL, + /* domain: */ "mail", + + /* XXX This provider is not really a "source", the + * flag just gets it shown in the account editor. */ + (CamelProviderFlags) CAMEL_PROVIDER_IS_SOURCE, + + (CamelProviderURLFlags) 0, + (CamelProviderConfEntry *) NULL, + (CamelProviderPortEntry *) NULL, + (CamelProviderAutoDetectFunc) NULL, + /* object_types: */ { 0, 0 }, /* see below */ + /* authtypes: */ NULL, + (GHashFunc) camel_url_hash, + (GEqualFunc) camel_url_equal, + GETTEXT_PACKAGE +}; + +static void +camel_null_store_class_init (CamelNullStoreClass *class) +{ + /* We should never be invoking methods on a CamelNullStore, + * but thankfully, in case we do, CamelStore has NULL function + * pointer checks in all of its wrapper functions. So it will + * emit a runtime warning, which is what we want, and frees us + * from having to override any class methods here. */ +} + +static void +camel_null_store_init (CamelNullStore *store) +{ + /* nothing to do */ +} + +void +camel_null_store_register_provider (void) +{ + GType object_type; + + object_type = CAMEL_TYPE_NULL_STORE; + null_provider.object_types[CAMEL_PROVIDER_STORE] = object_type; + + object_type = G_TYPE_INVALID; + null_provider.object_types[CAMEL_PROVIDER_TRANSPORT] = object_type; + + camel_provider_register (&null_provider); +} + diff --git a/libemail-engine/camel-null-store.h b/libemail-engine/camel-null-store.h new file mode 100644 index 0000000000..cedcef4154 --- /dev/null +++ b/libemail-engine/camel-null-store.h @@ -0,0 +1,64 @@ +/* + * camel-null-store.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 + * + */ + +/* Evolution kinda sorta supports multiple identities by allowing users + * to set up so-called "transport-only" accounts by choosing "None" for + * the account type. This bizarre hack keeps that bizzare hack working + * until we can support multiple identities properly. */ + +#ifndef CAMEL_NULL_STORE_H +#define CAMEL_NULL_STORE_H + +#include + +/* Standard GObject macros */ +#define CAMEL_TYPE_NULL_STORE \ + (camel_null_store_get_type ()) +#define CAMEL_NULL_STORE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), CAMEL_TYPE_NULL_STORE, CamelNullStore)) +#define CAMEL_NULL_STORE_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), CAMEL_TYPE_NULL_STORE, CamelNullStoreClass)) +#define CAMEL_IS_NULL_STORE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), CAMEL_TYPE_NULL_STORE)) +#define CAMEL_IS_NULL_STORE_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), CAMEL_TYPE_NULL_STORE)) +#define CAMEL_NULL_STORE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), CAMEL_TYPE_NULL_STORE, CamelNullStoreClass)) + +G_BEGIN_DECLS + +typedef struct _CamelNullStore CamelNullStore; +typedef struct _CamelNullStoreClass CamelNullStoreClass; + +struct _CamelNullStore { + CamelStore parent; +}; + +struct _CamelNullStoreClass { + CamelStoreClass parent_class; +}; + +GType camel_null_store_get_type (void); +void camel_null_store_register_provider (void); + +#endif /* CAMEL_NULL_STORE_H */ diff --git a/libemail-engine/e-mail-session.c b/libemail-engine/e-mail-session.c index 46ed515675..f146f4510e 100644 --- a/libemail-engine/e-mail-session.c +++ b/libemail-engine/e-mail-session.c @@ -51,6 +51,9 @@ #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-junk-filter.h" #include "e-mail-session.h" #include "e-mail-folder-utils.h" @@ -406,36 +409,36 @@ mail_session_add_by_account (EMailSession *session, { CamelService *service = NULL; CamelProvider *provider; - CamelURL *url; - gboolean transport_only; + CamelURL *url = NULL; + const gchar *protocol = NULL; + gboolean have_source_url; GError *error = NULL; - /* check whether it's transport-only accounts */ - transport_only = - (account->source == NULL) || - (account->source->url == NULL) || - (*account->source->url == '\0'); - if (transport_only) - goto handle_transport; + have_source_url = + (account->source != NULL) && + (account->source->url != NULL); - /* Load the service, but don't connect. Check its provider, - * and if this belongs in the folder tree model, add it. */ + if (have_source_url) + url = camel_url_new (account->source->url, NULL); + + protocol = (url != NULL) ? url->protocol : "none"; + provider = camel_provider_get (protocol, &error); - url = camel_url_new (account->source->url, NULL); - if (url != NULL) { - provider = camel_provider_get (url->protocol, NULL); + if (url != NULL) camel_url_free (url); - } else { - provider = NULL; - } - if (provider == NULL) { - /* In case we do not have a provider here, we handle - * the special case of having multiple mail identities - * eg. a dummy account having just SMTP server defined */ - goto handle_transport; + if (error != NULL) { + g_warn_if_fail (provider == NULL); + g_warning ("%s", error->message); + g_error_free (error); + return; } + g_return_if_fail (provider != NULL); + + /* Load the service, but don't connect. Check its provider, + * and if this belongs in the folder tree model, add it. */ + service = camel_session_add_service ( CAMEL_SESSION (session), account->uid, provider->protocol, @@ -451,8 +454,6 @@ mail_session_add_by_account (EMailSession *session, camel_service_set_display_name (service, account->name); -handle_transport: - /* 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". */ @@ -851,13 +852,9 @@ mail_session_add_service (CamelSession *session, break; } - if (url_string != NULL) { - url = camel_url_new (url_string, error); - if (url == NULL) { - g_object_unref (service); - service = NULL; - } - } + /* Be lenient about malformed URLs. */ + if (url_string != NULL) + url = camel_url_new (url_string, NULL); } if (url != NULL) { @@ -1477,6 +1474,7 @@ e_mail_session_class_init (EMailSessionClass *class) G_TYPE_NONE, 1, CAMEL_TYPE_STORE); + camel_null_store_register_provider (); } static void diff --git a/mail/em-account-editor.c b/mail/em-account-editor.c index 0e5c948ba8..21f5da0095 100644 --- a/mail/em-account-editor.c +++ b/mail/em-account-editor.c @@ -301,7 +301,13 @@ static gint emae_provider_compare (const CamelProvider *p1, const CamelProvider *p2) { - /* sort providers based on "location" (ie. local or remote) */ + /* The "none" provider comes first. */ + if (g_strcmp0 (p1->protocol, "none") == 0) + return -1; + if (g_strcmp0 (p2->protocol, "none") == 0) + return 1; + + /* Then sort remote providers before local providers. */ if (p1->flags & CAMEL_PROVIDER_IS_REMOTE) { if (p2->flags & CAMEL_PROVIDER_IS_REMOTE) return 0; @@ -1381,7 +1387,13 @@ emae_account_url (EMAccountEditor *emae, account = em_account_editor_get_modified_account (emae); uri = e_account_get_string (account, urlid); - if (uri && uri[0]) + /* XXX Stupid hack for these stupid transport-only accounts. + * We've been saving these as invalid URI strings all this + * time; no protocol, just "//...". Catch it and fix it. */ + if (uri != NULL && g_str_has_prefix (uri, "//")) + return camel_url_new ("none:", NULL); + + if (uri != NULL && *uri != '\0') url = camel_url_new (uri, NULL); if (url == NULL) { @@ -2304,7 +2316,6 @@ emae_service_provider_changed (EMAccountEditorService *service) CamelProvider *provider = NULL; const gchar *description; - /* Protocol is NULL when server type is 'None'. */ if (service->protocol != NULL) provider = camel_provider_get (service->protocol, NULL); @@ -2389,7 +2400,6 @@ emae_service_provider_changed (EMAccountEditorService *service) gtk_widget_hide (service->ssl_hbox); gtk_widget_show (service->no_ssl); #endif - } else { gtk_widget_hide (service->frame); gtk_widget_hide (service->auth_frame); @@ -2459,12 +2469,6 @@ emae_refresh_providers (EMAccountEditor *emae, gtk_combo_box_text_remove_all (combo_box); - /* We just special case each type here, its just easier */ - if (service->type == CAMEL_PROVIDER_STORE) - gtk_combo_box_text_append ( - combo_box, NULL, - C_("mail-receiving", "None")); - for (link = emae->priv->providers; link != NULL; link = link->next) { CamelProvider *provider = link->data; @@ -2665,7 +2669,6 @@ emae_setup_service (EMAccountEditor *emae, service->protocol = g_intern_string (url->protocol); camel_url_free (url); - /* Protocol is NULL when server type is 'None'. */ if (service->protocol != NULL) provider = camel_provider_get (service->protocol, NULL); @@ -4392,7 +4395,6 @@ emae_check_service_complete (EMAccountEditor *emae, gboolean need_port; gboolean need_user; - /* Protocol is NULL when server type is 'None'. */ if (service->protocol != NULL) provider = camel_provider_get (service->protocol, NULL); -- cgit v1.2.3