[evolution] Bug 668479: Missing transport-only accounts in Preferences



commit d75f6c636406385abb50025b4c371dec262b1c4b
Author: Matthew Barnes <mbarnes redhat com>
Date:   Tue Jan 24 22:18:20 2012 -0500

    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(-)
---
diff --git a/libemail-engine/Makefile.am b/libemail-engine/Makefile.am
index 88a0227..ce0a1ab 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 0000000..a4ebb53
--- /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 <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "camel-null-store.h"
+
+#include <config.h>
+#include <glib/gi18n-lib.h>
+
+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 0000000..cedcef4
--- /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 <http://www.gnu.org/licenses/>
+ *
+ */
+
+/* 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 <camel/camel.h>
+
+/* 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 46ed515..f146f45 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 0e5c948..21f5da0 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);
 



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