[evolution/kill-bonobo] Forgot to add new files.



commit 9ef14bd7eb341f176b4f8ce24b1679d5ef6aee2e
Author: Matthew Barnes <mbarnes redhat com>
Date:   Wed Jun 24 06:46:36 2009 -0400

    Forgot to add new files.

 mail/e-mail-local.c |  130 ++++++++++++++++
 mail/e-mail-local.h |   50 ++++++
 mail/e-mail-store.c |  423 +++++++++++++++++++++++++++++++++++++++++++++++++++
 mail/e-mail-store.h |   42 +++++
 4 files changed, 645 insertions(+), 0 deletions(-)
---
diff --git a/mail/e-mail-local.c b/mail/e-mail-local.c
new file mode 100644
index 0000000..0944c7d
--- /dev/null
+++ b/mail/e-mail-local.c
@@ -0,0 +1,130 @@
+/*
+ * e-mail-local.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-mail-local.h"
+
+#include <glib/gi18n.h>
+
+#include "mail/mail-session.h"
+
+#define CHECK_LOCAL_FOLDER_TYPE(type) \
+	((type) < G_N_ELEMENTS (default_local_folders))
+
+/* The array elements correspond to EMailLocalFolder. */
+static struct {
+	const gchar *display_name;
+	CamelFolder *folder;
+	gchar *folder_uri;
+} default_local_folders[] = {
+	{ N_("Inbox") },
+	{ N_("Drafts") },
+	{ N_("Outbox") },
+	{ N_("Sent") },
+	{ N_("Templates") },
+	{ "Inbox" }  /* "always local" inbox */
+};
+
+static CamelStore *local_store;
+
+void
+e_mail_local_init (const gchar *data_dir)
+{
+	static gboolean initialized = FALSE;
+	CamelException ex;
+	CamelService *service;
+	CamelURL *url;
+	gchar *temp;
+	gint ii;
+
+	g_return_if_fail (!initialized);
+	g_return_if_fail (data_dir != NULL);
+
+	camel_exception_init (&ex);
+
+	url = camel_url_new ("mbox:", NULL);
+	temp = g_build_filename (data_dir, "local", NULL);
+	camel_url_set_path (url, temp);
+	g_free (temp);
+
+	temp = camel_url_to_string (url, 0);
+	service = camel_session_get_service (
+		session, temp, CAMEL_PROVIDER_STORE, &ex);
+	g_free (temp);
+
+	if (camel_exception_is_set (&ex))
+		goto fail;
+
+	/* Populate the rest of the default_local_folders array. */
+	for (ii = 0; ii < G_N_ELEMENTS (default_local_folders); ii++) {
+		const gchar *display_name;
+		gchar *folder_uri;
+
+		display_name = default_local_folders[ii].display_name;
+
+		/* XXX Should this URI be account relative? */
+		camel_url_set_fragment (url, display_name);
+		folder_uri = camel_url_to_string (url, 0);
+
+		default_local_folders[ii].folder_uri = folder_uri;
+		default_local_folders[ii].folder = camel_store_get_folder (
+			CAMEL_STORE (service), display_name,
+			CAMEL_STORE_FOLDER_CREATE, &ex);
+
+		camel_exception_clear (&ex);
+	}
+
+	camel_url_free (url);
+
+	camel_object_ref (service);
+	local_store = CAMEL_STORE (service);
+
+	return;
+
+fail:
+	g_warning ("Could not initialize local store/folder: %s", ex.desc);
+
+	camel_exception_clear (&ex);
+	camel_url_free (url);
+}
+
+CamelFolder *
+e_mail_local_get_folder (EMailLocalFolder type)
+{
+	g_return_val_if_fail (CHECK_LOCAL_FOLDER_TYPE (type), NULL);
+
+	return default_local_folders[type].folder;
+}
+
+const gchar *
+e_mail_local_get_folder_uri (EMailLocalFolder type)
+{
+	g_return_val_if_fail (CHECK_LOCAL_FOLDER_TYPE (type), NULL);
+
+	return default_local_folders[type].folder_uri;
+}
+
+CamelStore *
+e_mail_local_get_store (void)
+{
+	g_return_val_if_fail (CAMEL_IS_STORE (local_store), NULL);
+
+	return local_store;
+}
diff --git a/mail/e-mail-local.h b/mail/e-mail-local.h
new file mode 100644
index 0000000..1bd34e4
--- /dev/null
+++ b/mail/e-mail-local.h
@@ -0,0 +1,50 @@
+/*
+ * e-mail-local.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_MAIL_LOCAL_H
+#define E_MAIL_LOCAL_H
+
+#include <glib.h>
+#include <camel/camel-folder.h>
+#include <camel/camel-store.h>
+
+G_BEGIN_DECLS
+
+/* XXX E_MAIL_FOLDER_TEMPLATES is a prime example of why
+ *     templates should be a core feature, not a plugin. */
+typedef enum {
+	E_MAIL_FOLDER_INBOX,
+	E_MAIL_FOLDER_DRAFTS,
+	E_MAIL_FOLDER_OUTBOX,
+	E_MAIL_FOLDER_SENT,
+	E_MAIL_FOLDER_TEMPLATES,
+	E_MAIL_FOLDER_LOCAL_INBOX,
+	E_MAIL_NUM_LOCAL_FOLDERS
+} EMailLocalFolder;
+
+void		e_mail_local_init		(const gchar *data_dir);
+CamelFolder *	e_mail_local_get_folder		(EMailLocalFolder type);
+const gchar *	e_mail_local_get_folder_uri	(EMailLocalFolder type);
+CamelStore *	e_mail_local_get_store		(void);
+
+G_END_DECLS
+
+#endif /* E_MAIL_LOCAL_H */
diff --git a/mail/e-mail-store.c b/mail/e-mail-store.c
new file mode 100644
index 0000000..1fc3eb5
--- /dev/null
+++ b/mail/e-mail-store.c
@@ -0,0 +1,423 @@
+/*
+ * e-mail-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/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-mail-store.h"
+
+#include <glib/gi18n.h>
+#include <camel/camel-service.h>
+#include <camel/camel-session.h>
+#include <camel/camel-url.h>
+#include <libedataserver/e-account.h>
+#include <libedataserver/e-account-list.h>
+
+#include "e-util/e-account-utils.h"
+
+#include "mail/e-mail-local.h"
+#include "mail/em-folder-tree-model.h"
+#include "mail/mail-folder-cache.h"
+#include "mail/mail-mt.h"
+#include "mail/mail-session.h"
+
+typedef struct _StoreInfo StoreInfo;
+
+typedef void	(*AddStoreCallback)	(CamelStore *store,
+					 CamelFolderInfo *info,
+					 StoreInfo *store_info);
+
+struct _StoreInfo {
+	gint ref_count;
+
+	CamelStore *store;
+	gchar *display_name;
+
+	/* Hold a reference to keep them alive. */
+	CamelFolder *vtrash;
+	CamelFolder *vjunk;
+
+	AddStoreCallback callback;
+
+	guint removed : 1;
+};
+
+CamelStore *vfolder_store;  /* XXX write a get() function for this */
+static GHashTable *store_table;
+
+static MailAsyncEvent *async_event;
+
+static StoreInfo *
+store_info_new (CamelStore *store,
+                const gchar *display_name)
+{
+	CamelService *service;
+	StoreInfo *store_info;
+
+	g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
+
+	service = CAMEL_SERVICE (store);
+
+	store_info = g_slice_new0 (StoreInfo);
+	store_info->ref_count = 1;
+
+	camel_object_ref (store);
+	store_info->store = store;
+
+	if (display_name == NULL)
+		store_info->display_name =
+			camel_service_get_name (service, TRUE);
+	else
+		store_info->display_name = g_strdup (display_name);
+
+	/* If these are vfolders then they need to be opened now,
+	 * otherwise they won't keep track of all folders. */
+	if (store->flags & CAMEL_STORE_VTRASH)
+		store_info->vtrash = camel_store_get_trash (store, NULL);
+	if (store->flags & CAMEL_STORE_VJUNK)
+		store_info->vjunk = camel_store_get_junk (store, NULL);
+
+	return store_info;
+}
+
+static StoreInfo *
+store_info_ref (StoreInfo *store_info)
+{
+	g_return_val_if_fail (store_info != NULL, store_info);
+	g_return_val_if_fail (store_info->ref_count > 0, store_info);
+
+	g_atomic_int_add (&store_info->ref_count, 1);
+
+	return store_info;
+}
+
+static void
+store_info_unref (StoreInfo *store_info)
+{
+	g_return_if_fail (store_info != NULL);
+	g_return_if_fail (store_info->ref_count > 0);
+
+	if (g_atomic_int_exchange_and_add (&store_info->ref_count, -1) > 1)
+		return;
+
+	camel_object_unref (store_info->store);
+	g_free (store_info->display_name);
+
+	if (store_info->vtrash != NULL)
+		camel_object_unref (store_info->vtrash);
+
+	if (store_info->vjunk != NULL)
+		camel_object_unref (store_info->vjunk);
+
+	g_slice_free (StoreInfo, store_info);
+}
+
+static void
+store_table_free (StoreInfo *store_info)
+{
+	store_info->removed = 1;
+	store_info_unref (store_info);
+}
+
+static gboolean
+mail_store_note_store_cb (CamelStore *store,
+                          CamelFolderInfo *info,
+                          gpointer user_data)
+{
+	StoreInfo *store_info = user_data;
+
+	if (store_info->callback != NULL)
+		store_info->callback (store, info, store_info);
+
+	if (!store_info->removed) {
+		/* This keeps message counters up-to-date. */
+		if (store_info->vtrash != NULL)
+			mail_note_folder (store_info->vtrash);
+		if (store_info->vjunk != NULL)
+			mail_note_folder (store_info->vjunk);
+	}
+
+	store_info_unref (store_info);
+
+	return TRUE;
+}
+
+static void
+mail_store_add (CamelStore *store,
+                const gchar *display_name,
+                AddStoreCallback callback)
+{
+	EMFolderTreeModel *default_model;
+	StoreInfo *store_info;
+
+	g_return_if_fail (store_table != NULL);
+
+	default_model = em_folder_tree_model_get_default ();
+
+	store_info = store_info_new (store, display_name);
+	store_info->callback = callback;
+
+	g_hash_table_insert (store_table, store, store_info);
+
+	em_folder_tree_model_add_store (
+		default_model, store, store_info->display_name);
+
+	mail_note_store (
+		store, NULL,
+		mail_store_note_store_cb,
+		store_info_ref (store_info));
+}
+
+static void
+mail_store_add_local_done_cb (CamelStore *store,
+                              CamelFolderInfo *info,
+                              StoreInfo *store_info)
+{
+	CamelFolder *folder;
+	gint ii;
+
+	for (ii = 0; ii < E_MAIL_NUM_LOCAL_FOLDERS; ii++) {
+		folder = e_mail_local_get_folder (ii);
+		if (folder != NULL)
+			mail_note_folder (folder);
+	}
+}
+
+static void
+mail_store_add_local_cb (CamelStore *local_store,
+                         const gchar *display_name)
+{
+	mail_store_add (
+		local_store, display_name,
+		(AddStoreCallback) mail_store_add_local_done_cb);
+}
+
+static void
+mail_store_load_accounts (const gchar *data_dir)
+{
+	CamelStore *local_store;
+	EAccountList *account_list;
+	EIterator *iter;
+
+	/* Set up the local store. */
+
+	e_mail_local_init (data_dir);
+	local_store = e_mail_local_get_store ();
+
+	mail_async_event_emit (
+		async_event, MAIL_ASYNC_GUI,
+		(MailAsyncFunc) mail_store_add_local_cb,
+		local_store, _("On This Computer"), NULL);
+
+	/* Set up remote stores. */
+
+	account_list = e_get_account_list ();
+
+	for (iter = e_list_get_iterator ((EList *) account_list);
+		e_iterator_is_valid (iter); e_iterator_next (iter)) {
+
+		EAccountService *service;
+		EAccount *account;
+		const gchar *display_name;
+		const gchar *uri;
+
+		account = (EAccount *) e_iterator_get (iter);
+		display_name = account->name;
+		service = account->source;
+		uri = service->url;
+
+		if (!account->enabled)
+			continue;
+
+		if (uri == NULL || *uri == '\0')
+			continue;
+
+		/* HACK: mbox URI's are handled by the local store setup
+		 *       above.  Any that come through as account sources
+		 *       are really movemail sources! */
+		if (g_str_has_prefix (uri, "mbox:"))
+			continue;
+
+		e_mail_store_add_by_uri (uri, display_name);
+	}
+
+	g_object_unref (iter);
+}
+
+void
+e_mail_store_init (const gchar *data_dir)
+{
+	static gboolean initialized = FALSE;
+
+	g_return_if_fail (!initialized);
+	g_return_if_fail (data_dir != NULL);
+
+	/* Initialize global variables. */
+
+	store_table = g_hash_table_new_full (
+		g_direct_hash, g_direct_equal,
+		(GDestroyNotify) NULL,
+		(GDestroyNotify) store_table_free);
+
+	async_event = mail_async_event_new ();
+
+	mail_store_load_accounts (data_dir);
+
+	initialized = TRUE;
+}
+
+void
+e_mail_store_add (CamelStore *store,
+                  const gchar *display_name)
+{
+	g_return_if_fail (CAMEL_IS_STORE (store));
+	g_return_if_fail (display_name != NULL);
+
+	mail_store_add (store, display_name, NULL);
+}
+
+CamelStore *
+e_mail_store_add_by_uri (const gchar *uri,
+                         const gchar *display_name)
+{
+	CamelService *service;
+	CamelProvider *provider;
+	CamelException ex;
+
+	g_return_val_if_fail (uri != NULL, NULL);
+	g_return_val_if_fail (display_name != NULL, NULL);
+
+	camel_exception_init (&ex);
+
+	/* Load the service, but don't connect.  Check its provider,
+	 * and if this belongs in the folder tree model, add it. */
+
+	provider = camel_provider_get (uri, &ex);
+	if (provider == NULL)
+		goto fail;
+
+	if (!(provider->flags & CAMEL_PROVIDER_IS_STORAGE))
+		return NULL;
+
+	service = camel_session_get_service (
+		session, uri, CAMEL_PROVIDER_STORE, &ex);
+	if (service == NULL)
+		goto fail;
+
+	e_mail_store_add (CAMEL_STORE (service), display_name);
+
+	camel_object_unref (service);
+
+	return CAMEL_STORE (service);
+
+fail:
+	/* FIXME: Show an error dialog. */
+	g_warning (
+		"Couldn't get service: %s: %s", uri,
+		camel_exception_get_description (&ex));
+	camel_exception_clear (&ex);
+
+	return NULL;
+}
+
+/* Helper for e_mail_store_remove() */
+static void
+mail_store_remove_cb (CamelStore *store)
+{
+	camel_service_disconnect (CAMEL_SERVICE (store), TRUE, NULL);
+	camel_object_unref (store);
+}
+
+void
+e_mail_store_remove (CamelStore *store)
+{
+	EMFolderTreeModel *default_model;
+
+	g_return_if_fail (CAMEL_IS_STORE (store));
+	g_return_if_fail (store_table != NULL);
+	g_return_if_fail (async_event != NULL);
+
+	/* Because the store table holds a reference to each store used
+	 * as a key in it, none of them will ever be gc'ed, meaning any
+	 * call to camel_session_get_{service,store} with the same URL
+	 * will always return the same object.  So this works. */
+
+	if (g_hash_table_lookup (store_table, store) == NULL)
+		return;
+
+	camel_object_ref (store);
+
+	g_hash_table_remove (store_table, store);
+	mail_note_store_remove (store);
+
+	default_model = em_folder_tree_model_get_default ();
+	em_folder_tree_model_remove_store (default_model, store);
+
+	mail_async_event_emit (
+		async_event, MAIL_ASYNC_THREAD,
+		(MailAsyncFunc) mail_store_remove_cb,
+		store, NULL, NULL);
+}
+
+void
+e_mail_store_remove_by_uri (const gchar *uri)
+{
+	CamelService *service;
+	CamelProvider *provider;
+
+	g_return_if_fail (uri != NULL);
+
+	provider = camel_provider_get (uri, NULL);
+	if (provider == NULL)
+		return;
+
+	if (!(provider->flags & CAMEL_PROVIDER_IS_STORAGE))
+		return;
+
+	service = camel_session_get_service (
+		session, uri, CAMEL_PROVIDER_STORE, NULL);
+	if (service == NULL)
+		return;
+
+	e_mail_store_remove (CAMEL_STORE (service));
+
+	camel_object_unref (service);
+}
+
+void
+e_mail_store_foreach (GHFunc func,
+                      gpointer user_data)
+{
+	GHashTableIter iter;
+	gpointer key, value;
+
+	g_return_if_fail (func != NULL);
+	g_return_if_fail (store_table != NULL);
+
+	g_hash_table_iter_init (&iter, store_table);
+
+	while (g_hash_table_iter_next (&iter, &key, &value)) {
+		StoreInfo *store_info = value;
+
+		/* Just being paranoid. */
+		g_return_if_fail (CAMEL_IS_STORE (key));
+		g_return_if_fail (store_info != NULL);
+
+		func (key, store_info->display_name, user_data);
+	}
+}
diff --git a/mail/e-mail-store.h b/mail/e-mail-store.h
new file mode 100644
index 0000000..bfd1ab4
--- /dev/null
+++ b/mail/e-mail-store.h
@@ -0,0 +1,42 @@
+/*
+ * e-mail-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/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_MAIL_STORE_H
+#define E_MAIL_STORE_H
+
+#include <glib.h>
+#include <camel/camel-store.h>
+
+G_BEGIN_DECLS
+
+void		e_mail_store_init		(const gchar *data_dir);
+void		e_mail_store_add		(CamelStore *store,
+						 const gchar *display_name);
+CamelStore *	e_mail_store_add_by_uri		(const gchar *uri,
+						 const gchar *display_name);
+void		e_mail_store_remove		(CamelStore *store);
+void		e_mail_store_remove_by_uri	(const gchar *uri);
+void		e_mail_store_foreach		(GHFunc func,
+						 gpointer user_data);
+
+G_END_DECLS
+
+#endif /* E_MAIL_STORE_H */



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