[evolution/mail-mt-cleanup: 5/7] Remove dependency on EMFolderTreeModel from EMailStore



commit 65c81fb014a9f414c80645449d7ef163b2641220
Author: Jonathon Jongsma <jonathon quotidian org>
Date:   Mon Jan 11 09:51:27 2010 -0600

    Remove dependency on EMFolderTreeModel from EMailStore
    
    To accomplish this, I again had to make this into a proper GObject so that I
    could achieve loose coupling via signals.  So EMailStore is now a gobject, and
    provides access to the singleton object via e_mail_store_get_default().
    
    This removes the need for EMailBackend to call e_mail_store_init() since it will
    simply be initialized the first time anybody attempts to get the singleton
    object.
    
    Since EMFolderTreeModel does not get updates pushed to it anymore, it needed to
    be redesigned a bit.  I made the EMailStore that it was modeling to be a
    property (named "store").  Upon construction, it reeds the list of existing
    stores from the EMailStore object and adds them to the model, then listens for
    the new "store-added" and "store-removed" signals to update itself when changes
    are made to the underlying stores.
    
    The rest of the changes in this patch are mostly adapting the e_mail_store_* API
    usage to take the new EMailStore* parameter as its first argument.

 mail/e-mail-backend.c                    |   13 +-
 mail/e-mail-migrate.c                    |    6 +-
 mail/e-mail-store.c                      |  306 ++++++++++++++++++++++--------
 mail/e-mail-store.h                      |   52 ++++-
 mail/em-account-editor.c                 |    3 +-
 mail/em-folder-tree-model.c              |   94 ++++++++-
 mail/em-folder-tree-model.h              |    3 +-
 mail/mail-vfolder.c                      |    8 +-
 modules/mail/e-mail-shell-backend.c      |    2 +-
 modules/mail/e-mail-shell-view-actions.c |    5 +-
 modules/mail/em-account-prefs.c          |    9 +-
 11 files changed, 384 insertions(+), 117 deletions(-)
---
diff --git a/mail/e-mail-backend.c b/mail/e-mail-backend.c
index c8459af..531ac2d 100644
--- a/mail/e-mail-backend.c
+++ b/mail/e-mail-backend.c
@@ -128,7 +128,7 @@ mail_backend_prepare_for_offline_cb (EShell *shell,
 		camel_session_set_network_state (session, FALSE);
 	}
 
-	e_mail_store_foreach (
+	e_mail_store_foreach (e_mail_store_get_default (),
 		(GHFunc) mail_store_prepare_for_offline_cb, activity);
 }
 
@@ -152,7 +152,7 @@ mail_backend_prepare_for_online_cb (EShell *shell,
 {
 	camel_session_set_online (session, TRUE);
 
-	e_mail_store_foreach (
+	e_mail_store_foreach (e_mail_store_get_default (),
 		(GHFunc) mail_store_prepare_for_online_cb, activity);
 }
 
@@ -250,13 +250,14 @@ mail_backend_prepare_for_quit_cb (EShell *shell,
 	mail_vfolder_shutdown ();
 
 	if (delete_junk)
-		e_mail_store_foreach (
+		e_mail_store_foreach (e_mail_store_get_default (),
 			(GHFunc) mail_backend_delete_junk, backend);
 
 	sync_data.activity = activity;
 	sync_data.empty_trash = empty_trash;
 
-	e_mail_store_foreach ((GHFunc) mail_backend_final_sync, &sync_data);
+	e_mail_store_foreach (e_mail_store_get_default (),
+			      (GHFunc) mail_backend_final_sync, &sync_data);
 
 	/* Cancel all activities. */
 	e_mail_task_manager_cancel_all ();
@@ -441,7 +442,6 @@ mail_backend_constructed (GObject *object)
 	EShell *shell;
 	EShellBackend *shell_backend;
 	MailFolderCache *folder_cache;
-	const gchar *data_dir;
 	gboolean online;
 
 	shell_backend = E_SHELL_BACKEND (object);
@@ -499,9 +499,6 @@ mail_backend_constructed (GObject *object)
 	g_signal_connect (
 		e_mail_task_manager_get_default (),
 		"task-added", G_CALLBACK (task_mgr_task_added_cb), shell_backend);
-
-	data_dir = e_shell_backend_get_data_dir (shell_backend);
-	e_mail_store_init (data_dir);
 }
 
 static void
diff --git a/mail/e-mail-migrate.c b/mail/e-mail-migrate.c
index f67ea38..9515194 100644
--- a/mail/e-mail-migrate.c
+++ b/mail/e-mail-migrate.c
@@ -14,8 +14,11 @@
  * 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/>
  *
+ * Authors:
+ *   Jonathon Jongsma <jonathon jongsma collabora co uk>
  *
  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ * Copyright (C) 2010 Intel Corporation
  *
  */
 
@@ -2954,7 +2957,8 @@ migrate_to_db (EShellBackend *shell_backend)
 			CamelException ex;
 
 			camel_exception_init (&ex);
-			e_mail_store_add_by_uri (service->url, name);
+			e_mail_store_add_by_uri (e_mail_store_get_default (),
+						 service->url, name);
 
 			store = (CamelStore *) camel_session_get_service (CAMEL_SESSION (session), service->url, CAMEL_PROVIDER_STORE, &ex);
 			info = camel_store_get_folder_info (store, NULL, CAMEL_STORE_FOLDER_INFO_RECURSIVE|CAMEL_STORE_FOLDER_INFO_FAST|CAMEL_STORE_FOLDER_INFO_SUBSCRIBED, &ex);
diff --git a/mail/e-mail-store.c b/mail/e-mail-store.c
index 2cc03ad..7995e55 100644
--- a/mail/e-mail-store.c
+++ b/mail/e-mail-store.c
@@ -14,8 +14,11 @@
  * 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/>
  *
+ * Authors:
+ *   Jonathon Jongsma <jonathon jongsma collabora co uk>
  *
  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ * Copyright (C) 2010 Intel Corporation
  *
  */
 
@@ -29,6 +32,8 @@
 #include <libedataserver/e-account-list.h>
 
 #include "e-util/e-account-utils.h"
+#include "e-util/e-marshal.h"
+#include "e-util/e-util.h"
 
 #include "mail/e-mail-local.h"
 #include "mail/em-folder-tree-model.h"
@@ -36,6 +41,66 @@
 #include "mail/mail-mt.h"
 #include "mail/mail-session.h"
 
+G_DEFINE_TYPE (EMailStore, e_mail_store, G_TYPE_OBJECT)
+
+#define E_MAIL_STORE_PRIVATE(o) \
+  (G_TYPE_INSTANCE_GET_PRIVATE ((o), E_TYPE_MAIL_STORE, EMailStorePrivate))
+
+struct _EMailStorePrivate
+{
+	gchar *data_dir;
+	CamelStore *vfolder_store;  /* XXX write a get() function for this */
+	GHashTable *store_table;
+
+	MailAsyncEvent *async_event;
+};
+
+enum {
+	PROP_0,
+	PROP_DATA_DIR
+};
+
+enum {
+	SIGNAL_STORE_ADDED,
+	SIGNAL_STORE_REMOVED,
+	LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
+static void
+e_mail_store_get_property (GObject *object,
+			   guint property_id,
+			   GValue *value,
+			   GParamSpec *pspec)
+{
+	EMailStore *store = (EMailStore*) object;
+	switch (property_id) {
+		case PROP_DATA_DIR:
+			g_value_set_string (value, store->priv->data_dir);
+			break;
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+	}
+}
+
+static void
+e_mail_store_set_property (GObject *object,
+			   guint property_id,
+			   const GValue *value,
+			   GParamSpec *pspec)
+{
+	EMailStore *store = (EMailStore*) object;
+	switch (property_id) {
+		case PROP_DATA_DIR:
+			store->priv->data_dir = g_value_dup_string (value);
+			break;
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+	}
+}
+
+
 typedef struct _StoreInfo StoreInfo;
 
 typedef void	(*AddStoreCallback)	(CamelStore *store,
@@ -57,11 +122,6 @@ struct _StoreInfo {
 	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)
@@ -136,8 +196,8 @@ store_table_free (StoreInfo *store_info)
 
 static gboolean
 mail_store_note_store_cb (CamelStore *store,
-                          CamelFolderInfo *info,
-                          gpointer user_data)
+			  CamelFolderInfo *info,
+			  gpointer user_data)
 {
 	StoreInfo *store_info = user_data;
 
@@ -147,9 +207,13 @@ mail_store_note_store_cb (CamelStore *store,
 	if (!store_info->removed) {
 		/* This keeps message counters up-to-date. */
 		if (store_info->vtrash != NULL)
-			mail_folder_cache_note_folder (mail_folder_cache_get_default (), store_info->vtrash);
+			mail_folder_cache_note_folder
+				(mail_folder_cache_get_default (),
+				 store_info->vtrash);
 		if (store_info->vjunk != NULL)
-			mail_folder_cache_note_folder (mail_folder_cache_get_default (), store_info->vjunk);
+			mail_folder_cache_note_folder
+				(mail_folder_cache_get_default (),
+				 store_info->vjunk);
 	}
 
 	store_info_unref (store_info);
@@ -158,24 +222,22 @@ mail_store_note_store_cb (CamelStore *store,
 }
 
 static void
-mail_store_add (CamelStore *store,
-                const gchar *display_name,
-                AddStoreCallback callback)
+mail_store_add (EMailStore *self,
+		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 ();
+	g_return_if_fail (self->priv->store_table != NULL);
 
 	store_info = store_info_new (store, display_name);
 	store_info->callback = callback;
 
-	g_hash_table_insert (store_table, store, store_info);
+	g_hash_table_insert (self->priv->store_table, store, store_info);
 
-	em_folder_tree_model_add_store (
-		default_model, store, store_info->display_name);
+	g_signal_emit (self, signals[SIGNAL_STORE_ADDED], 0, store,
+		       store_info->display_name);
 
 	mail_folder_cache_note_store (mail_folder_cache_get_default (),
 		store, NULL,
@@ -200,29 +262,29 @@ mail_store_add_local_done_cb (CamelStore *store,
 
 static void
 mail_store_add_local_cb (CamelStore *local_store,
-                         const gchar *display_name)
+                         const gchar *display_name,
+			 EMailStore *self)
 {
-	mail_store_add (
-		local_store, display_name,
-		(AddStoreCallback) mail_store_add_local_done_cb);
+	mail_store_add (self, local_store, display_name,
+			(AddStoreCallback) mail_store_add_local_done_cb);
 }
 
 static void
-mail_store_load_accounts (const gchar *data_dir)
+e_mail_store_constructed (GObject *object)
 {
 	CamelStore *local_store;
 	EAccountList *account_list;
 	EIterator *iter;
+	EMailStore *self = (EMailStore*) object;
 
 	/* Set up the local store. */
 
-	e_mail_local_init (data_dir);
+	e_mail_local_init (self->priv->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);
+	mail_async_event_emit (self->priv->async_event, MAIL_ASYNC_GUI,
+			       (MailAsyncFunc) mail_store_add_local_cb,
+			       local_store, _("On This Computer"), self);
 
 	/* Set up remote stores. */
 
@@ -253,51 +315,27 @@ mail_store_load_accounts (const gchar *data_dir)
 		if (g_str_has_prefix (uri, "mbox:"))
 			continue;
 
-		e_mail_store_add_by_uri (uri, display_name);
+		e_mail_store_add_by_uri (self, uri, display_name);
 	}
 
 	g_object_unref (iter);
 }
 
 void
-e_mail_store_init (const gchar *data_dir)
-{
-	static gboolean initialized = FALSE;
-
-	g_return_if_fail (data_dir != NULL);
-
-	/* This function is idempotent, but there should
-	 * be no need to call it more than once. */
-	if (initialized)
-		return;
-
-	/* 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)
+e_mail_store_add (EMailStore *self,
+		  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);
+	mail_store_add (self, store, display_name, NULL);
 }
 
 CamelStore *
-e_mail_store_add_by_uri (const gchar *uri,
-                         const gchar *display_name)
+e_mail_store_add_by_uri (EMailStore *self,
+			 const gchar *uri,
+			 const gchar *display_name)
 {
 	CamelService *service;
 	CamelProvider *provider;
@@ -323,7 +361,7 @@ e_mail_store_add_by_uri (const gchar *uri,
 	if (service == NULL)
 		goto fail;
 
-	e_mail_store_add (CAMEL_STORE (service), display_name);
+	e_mail_store_add (self, CAMEL_STORE (service), display_name);
 
 	camel_object_unref (service);
 
@@ -348,38 +386,37 @@ mail_store_remove_cb (CamelStore *store)
 }
 
 void
-e_mail_store_remove (CamelStore *store)
+e_mail_store_remove (EMailStore *self,
+		     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);
+	g_return_if_fail (self->priv->store_table != NULL);
+	g_return_if_fail (self->priv->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)
+	if (g_hash_table_lookup (self->priv->store_table, store) == NULL)
 		return;
 
 	camel_object_ref (store);
 
-	g_hash_table_remove (store_table, store);
+	g_hash_table_remove (self->priv->store_table, store);
 	mail_folder_cache_note_store_remove (mail_folder_cache_get_default (), store);
 
-	default_model = em_folder_tree_model_get_default ();
-	em_folder_tree_model_remove_store (default_model, store);
+	g_signal_emit (self, signals[SIGNAL_STORE_REMOVED], 0, store);
 
 	mail_async_event_emit (
-		async_event, MAIL_ASYNC_THREAD,
+		self->priv->async_event, MAIL_ASYNC_THREAD,
 		(MailAsyncFunc) mail_store_remove_cb,
 		store, NULL, NULL);
 }
 
 void
-e_mail_store_remove_by_uri (const gchar *uri)
+e_mail_store_remove_by_uri (EMailStore *self,
+			    const gchar *uri)
 {
 	CamelService *service;
 	CamelProvider *provider;
@@ -398,22 +435,23 @@ e_mail_store_remove_by_uri (const gchar *uri)
 	if (service == NULL)
 		return;
 
-	e_mail_store_remove (CAMEL_STORE (service));
+	e_mail_store_remove (self, CAMEL_STORE (service));
 
 	camel_object_unref (service);
 }
 
 void
-e_mail_store_foreach (GHFunc func,
-                      gpointer user_data)
+e_mail_store_foreach (EMailStore *self,
+		      GHFunc func,
+		      gpointer user_data)
 {
 	GHashTableIter iter;
 	gpointer key, value;
 
 	g_return_if_fail (func != NULL);
-	g_return_if_fail (store_table != NULL);
+	g_return_if_fail (self->priv->store_table != NULL);
 
-	g_hash_table_iter_init (&iter, store_table);
+	g_hash_table_iter_init (&iter, self->priv->store_table);
 
 	while (g_hash_table_iter_next (&iter, &key, &value)) {
 		StoreInfo *store_info = value;
@@ -425,3 +463,115 @@ e_mail_store_foreach (GHFunc func,
 		func (key, store_info->display_name, user_data);
 	}
 }
+
+static void
+e_mail_store_dispose (GObject *object)
+{
+	EMailStore *store = (EMailStore*) object;
+
+	if (store->priv->vfolder_store) {
+		camel_object_unref (store->priv->vfolder_store);
+		store->priv->vfolder_store = NULL;
+	}
+
+	G_OBJECT_CLASS (e_mail_store_parent_class)->dispose (object);
+}
+
+static void
+e_mail_store_finalize (GObject *object)
+{
+	EMailStore *store = (EMailStore*) object;
+
+	g_free (store->priv->data_dir);
+	g_hash_table_destroy (store->priv->store_table);
+	mail_async_event_destroy (store->priv->async_event);
+
+	G_OBJECT_CLASS (e_mail_store_parent_class)->finalize (object);
+}
+
+static void
+e_mail_store_init (EMailStore *self)
+{
+	self->priv = E_MAIL_STORE_PRIVATE (self);
+
+	self->priv->store_table = g_hash_table_new_full (
+		g_direct_hash, g_direct_equal,
+		(GDestroyNotify) NULL,
+		(GDestroyNotify) store_table_free);
+
+	self->priv->async_event = mail_async_event_new ();
+}
+
+static void
+e_mail_store_class_init (EMailStoreClass *klass)
+{
+	GObjectClass *object_class;
+
+	g_type_class_add_private (klass, sizeof (EMailStorePrivate));
+
+	object_class = G_OBJECT_CLASS (klass);
+	object_class->set_property = e_mail_store_set_property;
+	object_class->get_property = e_mail_store_get_property;
+	object_class->dispose = e_mail_store_dispose;
+	object_class->finalize = e_mail_store_finalize;
+	object_class->constructed = e_mail_store_constructed;
+
+	g_object_class_install_property (
+		object_class,
+		PROP_DATA_DIR,
+		g_param_spec_string (
+			"data-dir",
+			"Data Directory",
+			NULL,
+			NULL,
+			G_PARAM_READWRITE |
+			G_PARAM_CONSTRUCT_ONLY |
+			G_PARAM_STATIC_STRINGS));
+
+	/**
+	 * EMailStore::store-added
+	 * @store: the #CamelStore that was added
+	 * @display_name: the display name of the store
+	 *
+	 * Emitted when a store is added
+	 **/
+	signals[SIGNAL_STORE_ADDED] =
+		g_signal_new ("store-added",
+			      G_OBJECT_CLASS_TYPE (object_class),
+			      G_SIGNAL_RUN_LAST,
+			      0, /* offset */
+			      NULL, NULL, /* accumulator */
+			      e_marshal_VOID__BOXED_STRING,
+			      G_TYPE_NONE, 2, E_TYPE_CAMEL_OBJECT, G_TYPE_STRING);
+
+	/**
+	 * EMailStore::store-removed
+	 * @store: the #CamelStore that was removed
+	 *
+	 * Emitted when a store is removed
+	 **/
+	signals[SIGNAL_STORE_REMOVED] =
+		g_signal_new ("store-removed",
+			      G_OBJECT_CLASS_TYPE (object_class),
+			      G_SIGNAL_RUN_LAST,
+			      0, /* offset */
+			      NULL, NULL, /* accumulator */
+			      g_cclosure_marshal_VOID__BOXED,
+			      G_TYPE_NONE, 1, E_TYPE_CAMEL_OBJECT);
+}
+
+EMailStore *
+e_mail_store_new (const gchar *data_dir)
+{
+	return g_object_new (E_TYPE_MAIL_STORE, "data-dir", data_dir, NULL);
+}
+
+EMailStore* e_mail_store_get_default ()
+{
+	static EMailStore *default_store = NULL;
+
+	if (G_UNLIKELY (default_store == NULL))
+		default_store = e_mail_store_new (mail_session_get_data_dir ());
+
+	return default_store;
+}
diff --git a/mail/e-mail-store.h b/mail/e-mail-store.h
index bfd1ab4..bf62a58 100644
--- a/mail/e-mail-store.h
+++ b/mail/e-mail-store.h
@@ -14,8 +14,11 @@
  * 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/>
  *
+ * Authors:
+ *   Jonathon Jongsma <jonathon jongsma collabora co uk>
  *
  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ * Copyright (C) 2010 Intel Corporation
  *
  */
 
@@ -23,19 +26,50 @@
 #define E_MAIL_STORE_H
 
 #include <glib.h>
+#include <glib-object.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);
+#define E_TYPE_MAIL_STORE            e_mail_store_get_type()
+#define E_MAIL_STORE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_MAIL_STORE, EMailStore))
+#define E_MAIL_STORE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_MAIL_STORE, EMailStoreClass))
+#define E_IS_MAIL_STORE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_MAIL_STORE))
+#define E_IS_MAIL_STORE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_MAIL_STORE))
+#define E_MAIL_STORE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), E_TYPE_MAIL_STORE, EMailStoreClass))
+
+typedef struct _EMailStore EMailStore;
+typedef struct _EMailStoreClass EMailStoreClass;
+typedef struct _EMailStorePrivate EMailStorePrivate;
+
+/**
+ * EMailStore:
+ *
+ * Contains only private data that should be read and manipulated using the
+ * functions below.
+ */
+struct _EMailStore
+{
+	GObject parent;
+
+	EMailStorePrivate *priv;
+};
+
+struct _EMailStoreClass
+{
+	GObjectClass parent_class;
+};
+
+GType e_mail_store_get_type (void) G_GNUC_CONST;
+
+EMailStore* e_mail_store_new (const gchar *data_dir);
+EMailStore* e_mail_store_get_default ();
+
+void e_mail_store_add (EMailStore *self, CamelStore *store, const gchar *display_name);
+CamelStore * e_mail_store_add_by_uri (EMailStore *self, const gchar *uri, const gchar *display_name);
+void e_mail_store_remove (EMailStore *self, CamelStore *store);
+void e_mail_store_remove_by_uri (EMailStore *self, const gchar *uri);
+void e_mail_store_foreach (EMailStore *self, GHFunc func, gpointer user_data);
 
 G_END_DECLS
 
diff --git a/mail/em-account-editor.c b/mail/em-account-editor.c
index 6bd012e..9f78342 100644
--- a/mail/em-account-editor.c
+++ b/mail/em-account-editor.c
@@ -3235,7 +3235,8 @@ add_new_store (gchar *uri, CamelStore *store, gpointer user_data)
 	if (store == NULL)
 		return;
 
-	e_mail_store_add (store, account->name);
+	e_mail_store_add (e_mail_store_get_default (),
+			  store, account->name);
 }
 
 static void
diff --git a/mail/em-folder-tree-model.c b/mail/em-folder-tree-model.c
index c084043..80bbde6 100644
--- a/mail/em-folder-tree-model.c
+++ b/mail/em-folder-tree-model.c
@@ -12,11 +12,12 @@
  * 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/>
  *
- *
  * Authors:
- *		Jeffrey Stedfast <fejj ximian com>
+ *   Jeffrey Stedfast <fejj ximian com>
+ *   Jonathon Jongsma <jonathon jongsma collabora co uk>
  *
  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ * Copyright (C) 2010 Intel Corporation
  *
  */
 
@@ -76,6 +77,7 @@ struct _EMFolderTreeModelPrivate {
 
 	/* URI -> GtkTreeRowReference */
 	GHashTable *uri_index;
+	EMailStore *mail_store;
 
 	gulong account_changed_id;
 	gulong account_removed_id;
@@ -83,7 +85,8 @@ struct _EMFolderTreeModelPrivate {
 
 enum {
 	PROP_0,
-	PROP_SELECTION
+	PROP_SELECTION,
+	PROP_STORE
 };
 
 enum {
@@ -246,12 +249,17 @@ folder_tree_model_set_property (GObject *object,
                                 const GValue *value,
                                 GParamSpec *pspec)
 {
+	EMFolderTreeModel *model = EM_FOLDER_TREE_MODEL (object);
+
 	switch (property_id) {
 		case PROP_SELECTION:
-			em_folder_tree_model_set_selection (
-				EM_FOLDER_TREE_MODEL (object),
+			em_folder_tree_model_set_selection (model,
 				g_value_get_object (value));
 			return;
+		case PROP_STORE:
+			model->priv->mail_store =
+				g_value_dup_object (value);
+			return;
 	}
 
 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -263,12 +271,16 @@ folder_tree_model_get_property (GObject *object,
                                 GValue *value,
                                 GParamSpec *pspec)
 {
+	EMFolderTreeModel *model = EM_FOLDER_TREE_MODEL (object);
+
 	switch (property_id) {
 		case PROP_SELECTION:
 			g_value_set_object (
 				value,
-				em_folder_tree_model_get_selection (
-				EM_FOLDER_TREE_MODEL (object)));
+				em_folder_tree_model_get_selection (model));
+			return;
+		case PROP_STORE:
+			g_value_set_object (value, model->priv->mail_store);
 			return;
 	}
 
@@ -289,6 +301,11 @@ folder_tree_model_dispose (GObject *object)
 		priv->selection = NULL;
 	}
 
+	if (priv->mail_store) {
+		g_object_unref (priv->mail_store);
+		priv->mail_store = NULL;
+	}
+
 	/* Chain up to parent's dispose() method. */
 	G_OBJECT_CLASS (parent_class)->dispose (object);
 }
@@ -314,6 +331,50 @@ folder_tree_model_finalize (GObject *object)
 }
 
 static void
+mail_store_added_cb (EMailStore *store,
+		     CamelStore* camel_store,
+		     const gchar *display_name,
+		     gpointer data)
+{
+	em_folder_tree_model_add_store (EM_FOLDER_TREE_MODEL (data),
+					camel_store,
+					display_name);
+}
+
+static void
+mail_store_removed_cb (EMailStore *store,
+		       CamelStore* camel_store,
+		       gpointer data)
+{
+	em_folder_tree_model_remove_store (EM_FOLDER_TREE_MODEL (data),
+					   camel_store);
+}
+
+static void
+add_store_with_name (gpointer key, gpointer value, gpointer data)
+{
+	em_folder_tree_model_add_store (EM_FOLDER_TREE_MODEL (data),
+					key, value);
+}
+
+static void
+folder_tree_model_constructed (GObject *object)
+{
+	EMFolderTreeModel *model = (EMFolderTreeModel*) object;
+
+	g_return_if_fail (model->priv->mail_store);
+
+	/* add all of the pre-existing stores to the model */
+	e_mail_store_foreach (model->priv->mail_store, (GHFunc) add_store_with_name, model);
+
+	/* listen for changes to the backing stores */
+	g_signal_connect (model->priv->mail_store, "store-added",
+			  G_CALLBACK (mail_store_added_cb), model);
+	g_signal_connect (model->priv->mail_store, "store-removed",
+			  G_CALLBACK (mail_store_removed_cb), model);
+}
+
+static void
 folder_tree_model_class_init (EMFolderTreeModelClass *class)
 {
 	GObjectClass *object_class;
@@ -324,6 +385,7 @@ folder_tree_model_class_init (EMFolderTreeModelClass *class)
 	object_class = G_OBJECT_CLASS (class);
 	object_class->set_property = folder_tree_model_set_property;
 	object_class->get_property = folder_tree_model_get_property;
+	object_class->constructed = folder_tree_model_constructed;
 	object_class->dispose = folder_tree_model_dispose;
 	object_class->finalize = folder_tree_model_finalize;
 
@@ -337,6 +399,18 @@ folder_tree_model_class_init (EMFolderTreeModelClass *class)
 			GTK_TYPE_TREE_SELECTION,
 			G_PARAM_READWRITE));
 
+	g_object_class_install_property (
+		object_class,
+		PROP_STORE,
+		g_param_spec_object (
+			"store",
+			"mail store",
+			"The backing mail store",
+			E_TYPE_MAIL_STORE,
+			G_PARAM_READWRITE |
+			G_PARAM_CONSTRUCT_ONLY |
+			G_PARAM_STATIC_STRINGS));
+
 	signals[LOADING_ROW] = g_signal_new (
 		"loading-row",
 		G_OBJECT_CLASS_TYPE (object_class),
@@ -522,9 +596,9 @@ em_folder_tree_model_get_type (void)
 }
 
 EMFolderTreeModel *
-em_folder_tree_model_new (void)
+em_folder_tree_model_new (EMailStore *store)
 {
-	return g_object_new (EM_TYPE_FOLDER_TREE_MODEL, NULL);
+	return g_object_new (EM_TYPE_FOLDER_TREE_MODEL, "store", store, NULL);
 }
 
 EMFolderTreeModel *
@@ -533,7 +607,7 @@ em_folder_tree_model_get_default (void)
 	static EMFolderTreeModel *default_folder_tree_model;
 
 	if (G_UNLIKELY (default_folder_tree_model == NULL))
-		default_folder_tree_model = em_folder_tree_model_new ();
+		default_folder_tree_model = em_folder_tree_model_new (e_mail_store_get_default ());
 
 	return default_folder_tree_model;
 }
diff --git a/mail/em-folder-tree-model.h b/mail/em-folder-tree-model.h
index e0a73e0..3de7024 100644
--- a/mail/em-folder-tree-model.h
+++ b/mail/em-folder-tree-model.h
@@ -26,6 +26,7 @@
 #include <gtk/gtk.h>
 #include <camel/camel-store.h>
 #include <libedataserver/e-account-list.h>
+#include <mail/e-mail-store.h>
 
 /* Standard GObject macros */
 #define EM_TYPE_FOLDER_TREE_MODEL \
@@ -111,7 +112,7 @@ struct _EMFolderTreeModelClass {
 
 GType		em_folder_tree_model_get_type	(void);
 EMFolderTreeModel *
-		em_folder_tree_model_new	(void);
+		em_folder_tree_model_new	(EMailStore *store);
 EMFolderTreeModel *
 		em_folder_tree_model_get_default(void);
 GtkTreeSelection *
diff --git a/mail/mail-vfolder.c b/mail/mail-vfolder.c
index eb2ec1f..77aeb31 100644
--- a/mail/mail-vfolder.c
+++ b/mail/mail-vfolder.c
@@ -12,11 +12,12 @@
  * 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/>
  *
- *
  * Authors:
- *		Michael Zucchi <notzed ximian com>
+ *   Michael Zucchi <notzed ximian com>
+ *   Jonathon Jongsma <jonathon jongsma collabora co uk>
  *
  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ * Copyright (C) 2009-2010 Intel Corporation
  *
  */
 
@@ -1114,7 +1115,8 @@ vfolder_load_storage(void)
 	g_signal_connect(context, "rule_removed", G_CALLBACK(context_rule_removed), context);
 
 	/* load store to mail component */
-	e_mail_store_add_by_uri (storeuri, _("Search Folders"));
+	e_mail_store_add_by_uri (e_mail_store_get_default (),
+				 storeuri, _("Search Folders"));
 
 	/* and setup the rules we have */
 	rule = NULL;
diff --git a/modules/mail/e-mail-shell-backend.c b/modules/mail/e-mail-shell-backend.c
index 7ebdee6..56d5b50 100644
--- a/modules/mail/e-mail-shell-backend.c
+++ b/modules/mail/e-mail-shell-backend.c
@@ -266,7 +266,7 @@ mail_shell_backend_mail_sync (EMailShellBackend *mail_shell_backend)
 	if (mail_shell_backend->priv->mail_sync_in_progress)
 		goto exit;
 
-	e_mail_store_foreach (
+	e_mail_store_foreach (e_mail_store_get_default (),
 		(GHFunc) mail_shell_backend_sync_store_cb,
 		mail_shell_backend);
 
diff --git a/modules/mail/e-mail-shell-view-actions.c b/modules/mail/e-mail-shell-view-actions.c
index 02baf19..3de5eba 100644
--- a/modules/mail/e-mail-shell-view-actions.c
+++ b/modules/mail/e-mail-shell-view-actions.c
@@ -67,7 +67,7 @@ action_mail_account_disable_cb (GtkAction *action,
 
 	account->enabled = !account->enabled;
 	e_account_list_change (account_list, account);
-	e_mail_store_remove_by_uri (folder_uri);
+	e_mail_store_remove_by_uri (e_mail_store_get_default (), folder_uri);
 
 	if (account->parent_uid != NULL)
 		e_account_list_remove (account_list, account);
@@ -129,7 +129,8 @@ static void
 action_mail_download_cb (GtkAction *action,
                          EMailShellView *mail_shell_view)
 {
-	e_mail_store_foreach ((GHFunc) action_mail_download_foreach_cb, NULL);
+	e_mail_store_foreach (e_mail_store_get_default (),
+			      (GHFunc) action_mail_download_foreach_cb, NULL);
 }
 
 static void
diff --git a/modules/mail/em-account-prefs.c b/modules/mail/em-account-prefs.c
index eaacec6..1b9551f 100644
--- a/modules/mail/em-account-prefs.c
+++ b/modules/mail/em-account-prefs.c
@@ -59,7 +59,8 @@ account_prefs_enable_account_cb (EAccountTreeView *tree_view)
 	account = e_account_tree_view_get_selected (tree_view);
 	g_return_if_fail (account != NULL);
 
-	e_mail_store_add_by_uri (account->source->url, account->name);
+	e_mail_store_add_by_uri (e_mail_store_get_default (),
+				 account->source->url, account->name);
 }
 
 static void
@@ -92,7 +93,8 @@ account_prefs_disable_account_cb (EAccountTreeView *tree_view)
 
 	e_account_list_remove_account_proxies (account_list, account);
 
-	e_mail_store_remove_by_uri (account->source->url);
+	e_mail_store_remove_by_uri (e_mail_store_get_default (),
+				    account->source->url);
 }
 
 static void
@@ -213,7 +215,8 @@ account_prefs_delete_account (EAccountManager *manager)
 
 	/* Remove the account from the folder tree. */
 	if (account->enabled && account->source && account->source->url)
-		e_mail_store_remove_by_uri (account->source->url);
+		e_mail_store_remove_by_uri (e_mail_store_get_default (),
+					    account->source->url);
 
 	/* Remove all the proxies the account has created. */
 	if (has_proxies)



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