[evolution/vfolder-prep] Move vfolders to libemail-engine and rest as mail-vfolder-ui. It all works and the daemon can now st



commit 6014d9a386e4a5f4e243fddb58b628c8cac15d22
Author: Srinivasa Ragavan <sragavan gnome org>
Date:   Fri Mar 2 15:40:34 2012 +0530

    Move vfolders to libemail-engine and rest as mail-vfolder-ui. It all works and
    the daemon can now start the vfolder storage without bothering much with the
    UI.

 libemail-engine/Makefile.am                |    3 +
 libemail-engine/e-mail-session.c           |   90 +++++++-
 libemail-engine/e-mail-session.h           |   10 +-
 {mail => libemail-engine}/mail-vfolder.c   |  349 +++-------------------------
 libemail-engine/mail-vfolder.h             |   37 +++
 libemail-utils/mail-mt.c                   |   14 +-
 libemail-utils/mail-mt.h                   |    9 +-
 mail/Makefile.am                           |    8 +-
 mail/e-mail-account-store.c                |    2 +-
 mail/e-mail-backend.c                      |   18 ++-
 mail/e-mail-reader-utils.c                 |    2 +-
 mail/e-mail-reader.c                       |    2 +-
 mail/e-mail-ui-session.c                   |   78 +------
 mail/e-mail-ui-session.h                   |    2 -
 mail/em-folder-properties.c                |    2 +-
 mail/em-folder-tree.c                      |    2 +-
 mail/em-folder-utils.c                     |    2 +-
 mail/mail-autofilter.c                     |    2 +-
 mail/mail-vfolder-ui.c                     |  327 ++++++++++++++++++++++++++
 mail/{mail-vfolder.h => mail-vfolder-ui.h} |   10 +-
 modules/mail/e-mail-shell-backend.c        |    4 +-
 modules/mail/e-mail-shell-view-private.h   |    2 +-
 modules/mail/em-account-prefs.c            |    6 +-
 23 files changed, 571 insertions(+), 410 deletions(-)
---
diff --git a/libemail-engine/Makefile.am b/libemail-engine/Makefile.am
index ff88867..01274d5 100644
--- a/libemail-engine/Makefile.am
+++ b/libemail-engine/Makefile.am
@@ -16,6 +16,7 @@ libemail_engine_la_CPPFLAGS = \
 	-I$(top_builddir) \
 	$(EVOLUTION_DATA_SERVER_CFLAGS) \
 	$(GNOME_PLATFORM_CFLAGS) \
+	-DEVOLUTION_PRIVDATADIR=\""$(privdatadir)"\"	\
 	$(NULL)
 
 libmailengineincludedir = $(privincludedir)/libemail-engine
@@ -33,6 +34,7 @@ libmailengineinclude_HEADERS =  \
 	mail-folder-cache.h \
 	mail-ops.h \
 	mail-tools.h \
+	mail-vfolder.h	\
 	$(NULL)
 
 libemail_engine_la_SOURCES =  \
@@ -49,6 +51,7 @@ libemail_engine_la_SOURCES =  \
 	mail-folder-cache.c \
 	mail-ops.c \
 	mail-tools.c \
+	mail-vfolder.c	\
 	$(NULL)
 
 libemail_engine_la_LIBADD = \
diff --git a/libemail-engine/e-mail-session.c b/libemail-engine/e-mail-session.c
index f146f45..3bd38e6 100644
--- a/libemail-engine/e-mail-session.c
+++ b/libemail-engine/e-mail-session.c
@@ -75,6 +75,7 @@ struct _EMailSessionPrivate {
 	gulong account_added_handler_id;
 
 	CamelStore *local_store;
+	CamelStore *vfolder_store;
 
 	FILE *filter_logfile;
 	GHashTable *junk_filters;
@@ -99,7 +100,8 @@ enum {
 	PROP_0,
 	PROP_FOLDER_CACHE,
 	PROP_JUNK_FILTER_NAME,
-	PROP_LOCAL_STORE
+	PROP_LOCAL_STORE,
+	PROP_VFOLDER_STORE	
 };
 
 static const gchar *local_folder_names[E_MAIL_NUM_LOCAL_FOLDERS] = {
@@ -623,6 +625,13 @@ mail_session_get_property (GObject *object,
 				e_mail_session_get_local_store (
 				E_MAIL_SESSION (object)));
 			return;
+
+		case PROP_VFOLDER_STORE:
+			g_value_set_object (
+				value,
+				e_mail_session_get_vfolder_store (
+				E_MAIL_SESSION (object)));
+			return;			
 	}
 
 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -653,6 +662,10 @@ mail_session_dispose (GObject *object)
 		priv->local_store = NULL;
 	}
 
+	if (priv->vfolder_store != NULL) {
+		g_object_unref (priv->vfolder_store);
+		priv->vfolder_store = NULL;
+	}
 	g_ptr_array_set_size (priv->local_folders, 0);
 	g_ptr_array_set_size (priv->local_folder_uris, 0);
 
@@ -661,6 +674,38 @@ mail_session_dispose (GObject *object)
 }
 
 static void
+mail_session_add_vfolder_store (EMailSession *session)
+{
+	CamelSession *camel_session;
+	CamelService *service;
+	GError *error = NULL;
+
+	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;
+	}
+
+	g_return_if_fail (CAMEL_IS_SERVICE (service));
+
+	camel_service_set_display_name (service, _("Search Folders"));
+	em_utils_connect_service_sync (service, NULL, NULL);
+
+	/* XXX There's more configuration to do in vfolder_load_storage()
+	 *     but it requires an EMailBackend, which we don't have access
+	 *     to from here, so it has to be called from elsewhere.  Kinda
+	 *     thinking about reworking that... */
+
+	session->priv->vfolder_store = g_object_ref (service);
+}
+
+static void
 mail_session_finalize (GObject *object)
 {
 	EMailSessionPrivate *priv;
@@ -743,6 +788,7 @@ mail_session_constructed (GObject *object)
 
 	/* Add built-in CamelStores. */
 	mail_session_add_local_store (session);
+	mail_session_add_vfolder_store (session);
 
 	/* Give it a chance to load user settings, they are not loaded yet.
 	 *
@@ -1362,12 +1408,18 @@ retry:
 	return (result == CAMEL_AUTHENTICATION_ACCEPTED);
 }
 
+static EMVFolderContext *
+mail_session_create_vfolder_context (EMailSession *session)
+{
+	return em_vfolder_context_new ();
+}
+
 static void
 e_mail_session_class_init (EMailSessionClass *class)
 {
 	GObjectClass *object_class;
 	CamelSessionClass *session_class;
-
+	
 	g_type_class_add_private (class, sizeof (EMailSessionPrivate));
 
 	object_class = G_OBJECT_CLASS (class);
@@ -1389,6 +1441,8 @@ e_mail_session_class_init (EMailSessionClass *class)
 	session_class->get_socks_proxy = mail_session_get_socks_proxy;
 	session_class->authenticate_sync = mail_session_authenticate_sync;
 
+	class->create_vfolder_context = mail_session_create_vfolder_context;
+
 	g_object_class_install_property (
 		object_class,
 		PROP_FOLDER_CACHE,
@@ -1425,6 +1479,17 @@ e_mail_session_class_init (EMailSessionClass *class)
 			G_PARAM_READABLE |
 			G_PARAM_STATIC_STRINGS));
 
+	g_object_class_install_property (
+		object_class,
+		PROP_VFOLDER_STORE,
+		g_param_spec_object (
+			"vfolder-store",
+			"Search Folder Store",
+			"Built-in search folder store",
+			CAMEL_TYPE_STORE,
+			G_PARAM_READABLE |
+			G_PARAM_STATIC_STRINGS));	
+
 	/**
 	 * EMailSession::flush-outbox
 	 * @session: the email session
@@ -1963,3 +2028,24 @@ mail_session_get_config_dir (void)
 	return mail_config_dir;
 }
 
+CamelStore *
+e_mail_session_get_vfolder_store (EMailSession *session)
+{
+	g_return_val_if_fail (E_IS_MAIL_SESSION (session), NULL);
+
+	return session->priv->vfolder_store;
+}
+
+EMVFolderContext *
+e_mail_session_create_vfolder_context (EMailSession *session)
+{
+	EMailSessionClass *class;
+
+	g_return_val_if_fail (E_IS_MAIL_SESSION (session), NULL);
+
+	class = E_MAIL_SESSION_GET_CLASS (session);
+	g_return_val_if_fail (class->create_vfolder_context != NULL, NULL);
+
+	return class->create_vfolder_context (session);
+}
+
diff --git a/libemail-engine/e-mail-session.h b/libemail-engine/e-mail-session.h
index af7892d..16a6592 100644
--- a/libemail-engine/e-mail-session.h
+++ b/libemail-engine/e-mail-session.h
@@ -28,6 +28,7 @@
 #include <camel/camel.h>
 #include <libemail-engine/e-mail-enums.h>
 #include <libemail-engine/mail-folder-cache.h>
+#include <libemail-utils/em-vfolder-context.h>
 
 /* Standard GObject macros */
 #define E_TYPE_MAIL_SESSION \
@@ -65,6 +66,9 @@ struct _EMailSession {
 
 struct _EMailSessionClass {
 	CamelSessionClass parent_class;
+
+	EMVFolderContext *	(*create_vfolder_context)		(EMailSession *session);
+
 };
 
 GType		e_mail_session_get_type		(void);
@@ -72,6 +76,8 @@ EMailSession *	e_mail_session_new		(void);
 MailFolderCache *
 		e_mail_session_get_folder_cache	(EMailSession *session);
 CamelStore *	e_mail_session_get_local_store	(EMailSession *session);
+CamelStore *	e_mail_session_get_vfolder_store
+						(EMailSession *session);
 CamelFolder *	e_mail_session_get_local_folder	(EMailSession *session,
 						 EMailLocalFolder type);
 const gchar *	e_mail_session_get_local_folder_uri
@@ -122,7 +128,9 @@ CamelFolder *	e_mail_session_uri_to_folder_finish
 						(EMailSession *session,
 						 GAsyncResult *result,
 						 GError **error);
-
+EMVFolderContext *
+		e_mail_session_create_vfolder_context
+						(EMailSession *session);
 /*** Legacy API ***/
 
 void		mail_session_flush_filter_log	(EMailSession *session);
diff --git a/mail/mail-vfolder.c b/libemail-engine/mail-vfolder.c
similarity index 75%
rename from mail/mail-vfolder.c
rename to libemail-engine/mail-vfolder.c
index 1435c39..3ad3559 100644
--- a/mail/mail-vfolder.c
+++ b/libemail-engine/mail-vfolder.c
@@ -29,7 +29,6 @@
 #include <glib/gi18n.h>
 
 #include "libevolution-utils/e-alert-dialog.h"
-#include "e-util/e-util-private.h"
 
 #include "libemail-utils/mail-mt.h"
 #include "libemail-engine/mail-folder-cache.h"
@@ -39,19 +38,15 @@
 #include "libemail-engine/mail-ops.h"
 #include "libemail-engine/mail-tools.h"
 
-#include "e-mail-backend.h"
-#include "em-folder-tree-model.h"
-#include "em-utils.h"
-#include "em-vfolder-editor-context.h"
-#include "em-vfolder-editor.h"
-#include "em-vfolder-editor-rule.h"
-#include "mail-autofilter.h"
+#include <libemail-utils/em-vfolder-context.h>
+#include <libemail-utils/em-vfolder-rule.h>
 #include "mail-vfolder.h"
-#include "e-mail-ui-session.h"
 
 #define d(x)  /* (printf("%s:%s: ",  G_STRLOC, G_STRFUNC), (x))*/
 
-static EMVFolderContext *context;	/* context remains open all time */
+/* Note: Once we completely move mail to EDS, this context wont be available for UI. 
+ * and vfoldertypes.xml should be moved here really. */
+EMVFolderContext *context;	/* context remains open all time */
 
 /* lock for accessing shared resources (below) */
 G_LOCK_DEFINE_STATIC (vfolder);
@@ -436,7 +431,6 @@ done:
 
 /**
  * mail_vfolder_delete_folder:
- * @backend: an #EMailBackend
  * @store: a #CamelStore
  * @folder_name: a folder name
  *
@@ -453,8 +447,7 @@ done:
  * NOTE: This function must be called from the main thread.
  */
 static void
-mail_vfolder_delete_folder (EMailBackend *backend,
-                            CamelStore *store,
+mail_vfolder_delete_folder (CamelStore *store,
                             const gchar *folder_name)
 {
 	ERuleContext *rule_context;
@@ -467,7 +460,6 @@ mail_vfolder_delete_folder (EMailBackend *backend,
 	guint changed_count;
 	gchar *uri;
 
-	g_return_if_fail (E_IS_MAIL_BACKEND (backend));
 	g_return_if_fail (CAMEL_IS_STORE (store));
 	g_return_if_fail (folder_name != NULL);
 
@@ -551,7 +543,7 @@ done:
 		const gchar *config_dir;
 		gchar *user, *info;
 
-		alert_sink = e_mail_backend_get_alert_sink (backend);
+		alert_sink = mail_msg_get_alert_sink ();
 
 		info = g_strdup_printf (ngettext (
 			/* Translators: The first %s is name of the affected
@@ -671,7 +663,7 @@ mail_vfolder_rename_folder (CamelStore *store,
 
 /* ********************************************************************** */
 
-static void context_rule_added (ERuleContext *ctx, EFilterRule *rule);
+static void context_rule_added (ERuleContext *ctx, EFilterRule *rule, EMailSession *session);
 
 static void
 rule_add_sources (EMailSession *session,
@@ -701,6 +693,16 @@ rule_add_sources (EMailSession *session,
 	*sources_urip = sources_uri;
 }
 
+static EMailSession *
+get_session (CamelFolder *folder)
+{
+	CamelStore *store;
+	
+	store = camel_folder_get_parent_store (folder);
+
+	return (EMailSession *) camel_service_get_session (CAMEL_SERVICE (store));
+}
+
 static void
 rule_changed (EFilterRule *rule,
               CamelFolder *folder)
@@ -711,9 +713,9 @@ rule_changed (EFilterRule *rule,
 	GList *sources_folder = NULL;
 	GString *query;
 	const gchar *full_name;
-
+	
 	full_name = camel_folder_get_full_name (folder);
-	session = em_vfolder_editor_rule_get_session (EM_VFOLDER_EDITOR_RULE (rule));
+	session = get_session (folder);
 
 	service = camel_session_get_service (
 		CAMEL_SESSION (session), E_MAIL_SESSION_VFOLDER_UID);
@@ -807,16 +809,14 @@ rule_changed (EFilterRule *rule,
 
 static void
 context_rule_added (ERuleContext *ctx,
-                    EFilterRule *rule)
+                    EFilterRule *rule,
+		    EMailSession *session)
 {
-	EMailSession *session;
 	CamelFolder *folder;
 	CamelService *service;
 
 	d(printf("rule added: %s\n", rule->name));
 
-	session = em_vfolder_editor_rule_get_session (EM_VFOLDER_EDITOR_RULE (rule));
-
 	service = camel_session_get_service (
 		CAMEL_SESSION (session), E_MAIL_SESSION_VFOLDER_UID);
 	g_return_if_fail (CAMEL_IS_SERVICE (service));
@@ -840,16 +840,14 @@ context_rule_added (ERuleContext *ctx,
 
 static void
 context_rule_removed (ERuleContext *ctx,
-                      EFilterRule *rule)
+                      EFilterRule *rule,
+		      EMailSession *session)
 {
-	EMailSession *session;
 	CamelService *service;
 	gpointer key, folder = NULL;
 
 	d(printf("rule removed; %s\n", rule->name));
 
-	session = em_vfolder_editor_rule_get_session (EM_VFOLDER_EDITOR_RULE (rule));
-
 	service = camel_session_get_service (
 		CAMEL_SESSION (session), E_MAIL_SESSION_VFOLDER_UID);
 	g_return_if_fail (CAMEL_IS_SERVICE (service));
@@ -877,10 +875,11 @@ store_folder_deleted_cb (CamelStore *store,
 {
 	EFilterRule *rule;
 	gchar *user;
+	EMailSession *session;
 
 	d(printf("Folder deleted: %s\n", info->name));
 	store = store;
-
+	session = (EMailSession *) camel_service_get_session ((CamelService *) store);
 	/* Warning not thread safe, but might be enough */
 
 	G_LOCK (vfolder);
@@ -984,10 +983,9 @@ folder_unavailable_cb (MailFolderCache *cache,
 static void
 folder_deleted_cb (MailFolderCache *cache,
                    CamelStore *store,
-                   const gchar *folder_name,
-                   EMailBackend *backend)
+                   const gchar *folder_name)
 {
-	mail_vfolder_delete_folder (backend, store, folder_name);
+	mail_vfolder_delete_folder (store, folder_name);
 }
 
 static void
@@ -1001,7 +999,7 @@ folder_renamed_cb (MailFolderCache *cache,
 }
 
 void
-vfolder_load_storage (EMailBackend *backend)
+vfolder_load_storage (EMailSession *session)
 {
 	/* lock for loading storage, it is safe to call it more than once */
 	G_LOCK_DEFINE_STATIC (vfolder_hash);
@@ -1011,12 +1009,9 @@ vfolder_load_storage (EMailBackend *backend)
 	gchar *user;
 	EFilterRule *rule;
 	MailFolderCache *folder_cache;
-	EMailSession *session;
 	gchar *xmlfile;
 	GSettings *settings;
 
-	g_return_if_fail (E_IS_MAIL_BACKEND (backend));
-
 	G_LOCK (vfolder_hash);
 
 	if (vfolder_hash) {
@@ -1030,8 +1025,7 @@ vfolder_load_storage (EMailBackend *backend)
 	G_UNLOCK (vfolder_hash);
 
 	config_dir = mail_session_get_config_dir ();
-	session = e_mail_backend_get_session (backend);
-	vfolder_store = e_mail_ui_session_get_vfolder_store (E_MAIL_UI_SESSION (session));
+	vfolder_store = e_mail_session_get_vfolder_store (E_MAIL_SESSION (session));
 
 	g_signal_connect (
 		vfolder_store, "folder-deleted",
@@ -1043,7 +1037,10 @@ vfolder_load_storage (EMailBackend *backend)
 
 	/* load our rules */
 	user = g_build_filename (config_dir, "vfolders.xml", NULL);
-	context = (EMVFolderContext *) em_vfolder_editor_context_new (session);
+	/* This needs editor context which is only in the mail/. But really to run here we dont need editor context.
+	 * So till we split this to EDS, we would let mail/ create this and later one it is any ways two separate
+	 * contexts. */
+	context = e_mail_session_create_vfolder_context (session);
 
 	xmlfile = g_build_filename (EVOLUTION_PRIVDATADIR, "vfoldertypes.xml", NULL);
 	if (e_rule_context_load ((ERuleContext *) context,
@@ -1055,17 +1052,17 @@ vfolder_load_storage (EMailBackend *backend)
 
 	g_signal_connect (
 		context, "rule_added",
-		G_CALLBACK (context_rule_added), context);
+		G_CALLBACK (context_rule_added), session);
 	g_signal_connect (
 		context, "rule_removed",
-		G_CALLBACK (context_rule_removed), context);
+		G_CALLBACK (context_rule_removed), session);
 
 	/* and setup the rules we have */
 	rule = NULL;
 	while ((rule = e_rule_context_next_rule ((ERuleContext *) context, rule, NULL))) {
 		if (rule->name) {
 			d(printf("rule added: %s\n", rule->name));
-			context_rule_added ((ERuleContext *) context, rule);
+			context_rule_added ((ERuleContext *) context, rule, session);
 		} else {
 			d(printf("invalid rule (%p) encountered: rule->name is NULL\n", rule));
 		}
@@ -1086,282 +1083,12 @@ vfolder_load_storage (EMailBackend *backend)
 		G_CALLBACK (folder_unavailable_cb), NULL);
 	g_signal_connect (
 		folder_cache, "folder-deleted",
-		G_CALLBACK (folder_deleted_cb), backend);
+		G_CALLBACK (folder_deleted_cb), NULL);
 	g_signal_connect (
 		folder_cache, "folder-renamed",
 		G_CALLBACK (folder_renamed_cb), NULL);
 }
 
-void
-vfolder_edit (EMailBackend *backend,
-              GtkWindow *parent_window)
-{
-	EShellBackend *shell_backend;
-	GtkWidget *dialog;
-	const gchar *config_dir;
-	gchar *filename;
-
-	g_return_if_fail (E_IS_MAIL_BACKEND (backend));
-	g_return_if_fail (GTK_IS_WINDOW (parent_window));
-
-	shell_backend = E_SHELL_BACKEND (backend);
-	config_dir = e_shell_backend_get_config_dir (shell_backend);
-	filename = g_build_filename (config_dir, "vfolders.xml", NULL);
-
-	vfolder_load_storage (backend);
-
-	dialog = em_vfolder_editor_new (context);
-	gtk_window_set_title (
-		GTK_WINDOW (dialog), _("Search Folders"));
-	gtk_window_set_transient_for (
-		GTK_WINDOW (dialog), parent_window);
-
-	switch (gtk_dialog_run (GTK_DIALOG (dialog))) {
-		case GTK_RESPONSE_OK:
-			e_rule_context_save ((ERuleContext *) context, filename);
-			break;
-		default:
-			e_rule_context_revert ((ERuleContext *) context, filename);
-			break;
-	}
-
-	gtk_widget_destroy (dialog);
-}
-
-static void
-vfolder_edit_response_cb (GtkWidget *dialog,
-                          gint response_id,
-                          gpointer user_data)
-{
-	if (response_id == GTK_RESPONSE_OK) {
-		GObject *object;
-		EFilterRule *rule;
-		EFilterRule *newrule;
-		const gchar *config_dir;
-		gchar *user;
-
-		object = G_OBJECT (dialog);
-		rule = g_object_get_data (object, "vfolder-rule");
-		newrule = g_object_get_data (object, "vfolder-newrule");
-
-		e_filter_rule_copy (rule, newrule);
-		config_dir = mail_session_get_config_dir ();
-		user = g_build_filename (config_dir, "vfolders.xml", NULL);
-		e_rule_context_save ((ERuleContext *) context, user);
-		g_free (user);
-	}
-
-	gtk_widget_destroy (dialog);
-}
-
-void
-vfolder_edit_rule (EMailSession *session,
-                   const gchar *folder_uri,
-                   EAlertSink *alert_sink)
-{
-	GtkWidget *dialog;
-	GtkWidget *widget;
-	GtkWidget *container;
-	EFilterRule *rule = NULL;
-	EFilterRule *newrule;
-	gchar *folder_name = NULL;
-
-	g_return_if_fail (E_IS_MAIL_SESSION (session));
-	g_return_if_fail (folder_uri != NULL);
-	g_return_if_fail (E_IS_ALERT_SINK (alert_sink));
-
-	e_mail_folder_uri_parse (
-		CAMEL_SESSION (session), folder_uri,
-		NULL, &folder_name, NULL);
-
-	if (folder_name != NULL) {
-		rule = e_rule_context_find_rule (
-			(ERuleContext *) context, folder_name, NULL);
-		g_free (folder_name);
-	}
-
-	if (rule == NULL) {
-		/* TODO: we should probably just create it ... */
-		e_alert_submit (
-			alert_sink, "mail:vfolder-notexist",
-			folder_uri, NULL);
-		return;
-	}
-
-	g_object_ref (rule);
-	newrule = e_filter_rule_clone (rule);
-
-	dialog = gtk_dialog_new_with_buttons (
-		_("Edit Search Folder"), NULL,
-		GTK_DIALOG_DESTROY_WITH_PARENT,
-		GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-		GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);
-
-	gtk_container_set_border_width (GTK_CONTAINER (dialog), 6);
-	gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
-
-	gtk_window_set_default_size (GTK_WINDOW (dialog), 500, 500);
-	gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE);
-
-	container = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
-	gtk_box_set_spacing (GTK_BOX (container), 6);
-
-	widget = e_filter_rule_get_widget (
-		(EFilterRule *) newrule, (ERuleContext *) context);
-	gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
-	gtk_widget_show (widget);
-
-	g_object_set_data_full (
-		G_OBJECT (dialog), "vfolder-rule",
-		rule, (GDestroyNotify) g_object_unref);
-	g_object_set_data_full (
-		G_OBJECT (dialog), "vfolder-newrule",
-		newrule, (GDestroyNotify) g_object_unref);
-
-	g_signal_connect (
-		dialog, "response",
-		G_CALLBACK (vfolder_edit_response_cb), NULL);
-
-	gtk_widget_show (dialog);
-}
-
-static void
-new_rule_clicked (GtkWidget *w,
-                  gint button,
-                  gpointer data)
-{
-	if (button == GTK_RESPONSE_OK) {
-		const gchar *config_dir;
-		gchar *user;
-		EFilterRule *rule = g_object_get_data((GObject *)w, "rule");
-		EAlert *alert = NULL;
-
-		if (!e_filter_rule_validate (rule, &alert)) {
-			e_alert_run_dialog (GTK_WINDOW (w), alert);
-			g_object_unref (alert);
-			return;
-		}
-
-		if (e_rule_context_find_rule (
-			(ERuleContext *) context, rule->name, rule->source)) {
-			e_alert_run_dialog_for_args (
-				GTK_WINDOW (w), "mail:vfolder-notunique",
-				rule->name, NULL);
-			return;
-		}
-
-		g_object_ref (rule);
-		e_rule_context_add_rule ((ERuleContext *) context, rule);
-		config_dir = mail_session_get_config_dir ();
-		user = g_build_filename (config_dir, "vfolders.xml", NULL);
-		e_rule_context_save ((ERuleContext *) context, user);
-		g_free (user);
-	}
-
-	gtk_widget_destroy (w);
-}
-
-static void
-new_rule_changed_cb (EFilterRule *rule,
-                     GtkDialog *dialog)
-{
-	g_return_if_fail (rule != NULL);
-	g_return_if_fail (dialog != NULL);
-
-	gtk_dialog_set_response_sensitive (
-		dialog, GTK_RESPONSE_OK, rule->parts != NULL);
-}
-
-/* clones a filter/search rule into a matching vfolder rule
- * (assuming the same system definitions) */
-EFilterRule *
-vfolder_clone_rule (EMailSession *session,
-                    EFilterRule *in)
-{
-	EFilterRule *rule;
-	xmlNodePtr xml;
-
-	g_return_val_if_fail (E_IS_MAIL_SESSION (session), NULL);
-
-	rule = em_vfolder_editor_rule_new (session);
-
-	xml = e_filter_rule_xml_encode (in);
-	e_filter_rule_xml_decode (rule, xml, (ERuleContext *) context);
-	xmlFreeNodeList (xml);
-
-	return rule;
-}
-
-/* adds a rule with a gui */
-void
-vfolder_gui_add_rule (EMVFolderRule *rule)
-{
-	GtkWidget *w;
-	GtkDialog *gd;
-	GtkWidget *container;
-
-	w = e_filter_rule_get_widget ((EFilterRule *) rule, (ERuleContext *) context);
-
-	gd = (GtkDialog *) gtk_dialog_new_with_buttons (
-		_("New Search Folder"),
-		NULL,
-		GTK_DIALOG_DESTROY_WITH_PARENT,
-		GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-		GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);
-
-	gtk_dialog_set_default_response (gd, GTK_RESPONSE_OK);
-	gtk_container_set_border_width (GTK_CONTAINER (gd), 6);
-
-	container = gtk_dialog_get_content_area (gd);
-	gtk_box_set_spacing (GTK_BOX (container), 6);
-
-	g_object_set (gd, "resizable", TRUE, NULL);
-	gtk_window_set_default_size (GTK_WINDOW (gd), 500, 500);
-	gtk_box_pack_start (GTK_BOX (container), w, TRUE, TRUE, 0);
-	gtk_widget_show ((GtkWidget *) gd);
-	g_object_set_data_full (
-		G_OBJECT (gd), "rule", rule,
-		(GDestroyNotify) g_object_unref);
-	g_signal_connect (
-		rule, "changed",
-		G_CALLBACK (new_rule_changed_cb), gd);
-	new_rule_changed_cb ((EFilterRule *) rule, gd);
-	g_signal_connect (
-		gd, "response",
-		G_CALLBACK (new_rule_clicked), NULL);
-	gtk_widget_show ((GtkWidget *) gd);
-}
-
-void
-vfolder_gui_add_from_message (EMailSession *session,
-                              CamelMimeMessage *message,
-                              gint flags,
-                              CamelFolder *folder)
-{
-	EMVFolderRule *rule;
-
-	g_return_if_fail (CAMEL_IS_MIME_MESSAGE (message));
-
-	rule = (EMVFolderRule *) em_vfolder_rule_from_message (
-		context, message, flags, folder);
-	vfolder_gui_add_rule (rule);
-}
-
-void
-vfolder_gui_add_from_address (EMailSession *session,
-                              CamelInternetAddress *addr,
-                              gint flags,
-                              CamelFolder *folder)
-{
-	EMVFolderRule *rule;
-
-	g_return_if_fail (addr != NULL);
-
-	rule = (EMVFolderRule *) em_vfolder_rule_from_address (
-		context, addr, flags, folder);
-	vfolder_gui_add_rule (rule);
-}
-
 static void
 vfolder_foreach_cb (gpointer key,
                     gpointer data,
diff --git a/libemail-engine/mail-vfolder.h b/libemail-engine/mail-vfolder.h
new file mode 100644
index 0000000..eafd6ba
--- /dev/null
+++ b/libemail-engine/mail-vfolder.h
@@ -0,0 +1,37 @@
+/*
+ * 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/>
+ *
+ *
+ * Authors:
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef _MAIL_VFOLDER_H
+#define _MAIL_VFOLDER_H
+
+#include <camel/camel.h>
+
+#include <filter/e-filter-part.h>
+#include <filter/e-filter-rule.h>
+#include <libemail-engine/e-mail-session.h>
+#include <libemail-utils/em-vfolder-rule.h>
+
+void		vfolder_load_storage		(EMailSession *session);
+
+/* close up, clean up */
+void		mail_vfolder_shutdown		(void);
+
+#endif
diff --git a/libemail-utils/mail-mt.c b/libemail-utils/mail-mt.c
index ec2c529..b25257e 100644
--- a/libemail-utils/mail-mt.c
+++ b/libemail-utils/mail-mt.c
@@ -50,6 +50,7 @@ static MailMsgFreeActivityFunc free_activity = NULL;
 static MailMsgCompleteActivityFunc complete_activity = NULL;
 static MailMsgAlertErrorFunc alert_error = NULL;
 static MailMsgCancelActivityFunc cancel_activity = NULL;
+static MailMsgGetAlertSinkFunc get_alert_sink = NULL;
 
 void
 mail_msg_register_activities (MailMsgCreateActivityFunc acreate,
@@ -57,7 +58,8 @@ mail_msg_register_activities (MailMsgCreateActivityFunc acreate,
                               MailMsgFreeActivityFunc freeact,
                               MailMsgCompleteActivityFunc comp_act,
                               MailMsgCancelActivityFunc cancel_act,
-                              MailMsgAlertErrorFunc ealert)
+                              MailMsgAlertErrorFunc ealert,
+			      MailMsgGetAlertSinkFunc ealertsink)
 {
 	/* XXX This is an utter hack to keep EActivity out
 	 *     of EDS and still let Evolution do EActivity. */
@@ -67,6 +69,16 @@ mail_msg_register_activities (MailMsgCreateActivityFunc acreate,
 	complete_activity = comp_act;
 	cancel_activity = cancel_act;
 	alert_error = ealert;
+	get_alert_sink = ealertsink;
+}
+
+EAlertSink *
+mail_msg_get_alert_sink ()
+{
+	if (get_alert_sink)
+		return get_alert_sink ();
+
+	return NULL;
 }
 
 static void
diff --git a/libemail-utils/mail-mt.h b/libemail-utils/mail-mt.h
index 055464b..d2a20d2 100644
--- a/libemail-utils/mail-mt.h
+++ b/libemail-utils/mail-mt.h
@@ -24,6 +24,7 @@
 #define _MAIL_MT
 
 #include <camel/camel.h>
+#include <libevolution-utils/e-alert-sink.h>
 
 typedef struct _MailMsg MailMsg;
 typedef struct _MailMsgInfo MailMsgInfo;
@@ -44,6 +45,8 @@ typedef void    (*MailMsgCancelActivityFunc)	(GCancellable *cancellable);
 typedef void    (*MailMsgAlertErrorFunc)	(GCancellable *cancellable,
 						 const gchar *what,
 						 const gchar *message);
+typedef EAlertSink *
+		(*MailMsgGetAlertSinkFunc)	(void);
 
 struct _MailMsg {
 	MailMsgInfo *info;
@@ -62,6 +65,9 @@ struct _MailMsgInfo {
 	MailMsgFreeFunc free;
 };
 
+/* Just till we move this out to EDS */
+EAlertSink *	mail_msg_get_alert_sink (void);
+
 /* setup ports */
 void mail_msg_init (void);
 void mail_msg_register_activities (MailMsgCreateActivityFunc,
@@ -69,7 +75,8 @@ void mail_msg_register_activities (MailMsgCreateActivityFunc,
 				   MailMsgFreeActivityFunc,
 				   MailMsgCompleteActivityFunc,
 				   MailMsgCancelActivityFunc,
-				   MailMsgAlertErrorFunc);
+				   MailMsgAlertErrorFunc,
+				   MailMsgGetAlertSinkFunc);
 
 gboolean mail_in_main_thread (void);
 
diff --git a/mail/Makefile.am b/mail/Makefile.am
index ebc3f66..b30c4d0 100644
--- a/mail/Makefile.am
+++ b/mail/Makefile.am
@@ -92,7 +92,7 @@ mailinclude_HEADERS =					\
 	mail-autofilter.h				\
 	mail-guess-servers.h				\
 	mail-send-recv.h				\
-	mail-vfolder.h					\
+	mail-vfolder-ui.h				\
 	message-list.h
 
 if ENABLE_CLUTTER
@@ -151,13 +151,13 @@ libevolution_mail_la_SOURCES =				\
 	em-subscription-editor.c			\
 	em-sync-stream.c				\
 	em-utils.c					\
-	em-vfolder-editor-context.c				\
-	em-vfolder-editor-rule.c				\
+	em-vfolder-editor-context.c			\
+	em-vfolder-editor-rule.c			\
 	em-vfolder-editor.c				\
 	mail-autofilter.c				\
 	mail-guess-servers.c				\
 	mail-send-recv.c				\
-	mail-vfolder.c					\
+	mail-vfolder-ui.c				\
 	message-list.c
 
 if ENABLE_CLUTTER
diff --git a/mail/e-mail-account-store.c b/mail/e-mail-account-store.c
index f22160c..2dac692 100644
--- a/mail/e-mail-account-store.c
+++ b/mail/e-mail-account-store.c
@@ -30,7 +30,7 @@
 #include <libemail-utils/e-account-utils.h>
 #include <libemail-engine/mail-ops.h>
 
-#include <mail/mail-vfolder.h>
+#include <mail/mail-vfolder-ui.h>
 
 #define E_MAIL_ACCOUNT_STORE_GET_PRIVATE(obj) \
 	(G_TYPE_INSTANCE_GET_PRIVATE \
diff --git a/mail/e-mail-backend.c b/mail/e-mail-backend.c
index 75866f3..cc095a3 100644
--- a/mail/e-mail-backend.c
+++ b/mail/e-mail-backend.c
@@ -55,7 +55,7 @@
 #include <mail/em-utils.h>
 #include <mail/mail-autofilter.h>
 #include <mail/mail-send-recv.h>
-#include <mail/mail-vfolder.h>
+#include <mail/mail-vfolder-ui.h>
 
 #define E_MAIL_BACKEND_GET_PRIVATE(obj) \
 	(G_TYPE_INSTANCE_GET_PRIVATE \
@@ -919,6 +919,19 @@ mail_mt_alert_error (GCancellable *cancellable,
 			message, NULL);
 }
 
+static EAlertSink *
+mail_mt_get_alert_sink ()
+{
+	EShell *shell;
+	EShellBackend *shell_backend;
+
+	shell = e_shell_get_default ();
+	shell_backend = e_shell_get_backend_by_name (
+		shell, "mail");
+
+	return e_mail_backend_get_alert_sink (E_MAIL_BACKEND(shell_backend));
+}
+
 static void
 mail_backend_constructed (GObject *object)
 {
@@ -1024,7 +1037,8 @@ mail_backend_constructed (GObject *object)
 		mail_mt_free_activity,
 		mail_mt_complete_acitivity,
 		mail_mt_cancel_activity,
-		mail_mt_alert_error);
+		mail_mt_alert_error,
+		mail_mt_get_alert_sink);
 
 	/* Chain up to parent's constructed() method. */
 	G_OBJECT_CLASS (e_mail_backend_parent_class)->constructed (object);
diff --git a/mail/e-mail-reader-utils.c b/mail/e-mail-reader-utils.c
index bba721e..bc87295 100644
--- a/mail/e-mail-reader-utils.c
+++ b/mail/e-mail-reader-utils.c
@@ -48,7 +48,7 @@
 #include "mail/em-format-html-print.h"
 #include "mail/em-utils.h"
 #include "mail/mail-autofilter.h"
-#include "mail/mail-vfolder.h"
+#include "mail/mail-vfolder-ui.h"
 #include "mail/message-list.h"
 
 typedef struct _AsyncContext AsyncContext;
diff --git a/mail/e-mail-reader.c b/mail/e-mail-reader.c
index c7e2c07..53d4c31 100644
--- a/mail/e-mail-reader.c
+++ b/mail/e-mail-reader.c
@@ -57,7 +57,7 @@
 #include "mail/em-folder-tree.h"
 #include "mail/em-utils.h"
 #include "mail/mail-autofilter.h"
-#include "mail/mail-vfolder.h"
+#include "mail/mail-vfolder-ui.h"
 #include "mail/message-list.h"
 
 #if HAVE_CLUTTER
diff --git a/mail/e-mail-ui-session.c b/mail/e-mail-ui-session.c
index 90c1349..fd9a4a9 100644
--- a/mail/e-mail-ui-session.c
+++ b/mail/e-mail-ui-session.c
@@ -65,6 +65,7 @@
 #include "e-mail-ui-session.h"
 #include "em-composer-utils.h"
 #include "em-filter-context.h"
+#include "em-vfolder-editor-context.h"
 #include "em-filter-rule.h"
 #include "em-utils.h"
 #include "libemail-engine/mail-config.h"
@@ -81,7 +82,6 @@ typedef struct _SourceContext SourceContext;
 
 struct _EMailUISessionPrivate {
 	FILE *filter_logfile;
-	CamelStore *vfolder_store;
 	EMailAccountStore *account_store;
 	EMailLabelListStore *label_store;
 
@@ -92,8 +92,7 @@ struct _EMailUISessionPrivate {
 enum {
 	PROP_0,
 	PROP_ACCOUNT_STORE,
-	PROP_LABEL_STORE,
-	PROP_VFOLDER_STORE
+	PROP_LABEL_STORE
 };
 
 enum {
@@ -493,11 +492,6 @@ mail_ui_session_dispose (GObject *object)
 		priv->label_store = NULL;
 	}
 
-	if (priv->vfolder_store != NULL) {
-		g_object_unref (priv->vfolder_store);
-		priv->vfolder_store = NULL;
-	}
-
 	if (priv->account_list != NULL) {
 		g_signal_handler_disconnect (
 			priv->account_list,
@@ -511,38 +505,6 @@ mail_ui_session_dispose (GObject *object)
 }
 
 static void
-mail_ui_session_add_vfolder_store (EMailUISession *uisession)
-{
-	CamelSession *camel_session;
-	CamelService *service;
-	GError *error = NULL;
-
-	camel_session = CAMEL_SESSION (uisession);
-
-	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;
-	}
-
-	g_return_if_fail (CAMEL_IS_SERVICE (service));
-
-	camel_service_set_display_name (service, _("Search Folders"));
-	em_utils_connect_service_sync (service, NULL, NULL);
-
-	/* XXX There's more configuration to do in vfolder_load_storage()
-	 *     but it requires an EMailBackend, which we don't have access
-	 *     to from here, so it has to be called from elsewhere.  Kinda
-	 *     thinking about reworking that... */
-
-	uisession->priv->vfolder_store = g_object_ref (service);
-}
-
-static void
 mail_ui_session_account_changed_cb (EAccountList *account_list,
                                  EAccount *account,
                                  EMailSession *session)
@@ -645,8 +607,6 @@ mail_ui_session_constructed (GObject *object)
 
 	em_folder_tree_model_set_session (folder_tree_model, session);
 
-	mail_ui_session_add_vfolder_store (uisession);
-
 	g_idle_add (mail_ui_session_initialize_stores_idle, object);
 
 	handler_id = g_signal_connect (
@@ -736,13 +696,6 @@ mail_ui_session_get_property (GObject *object,
 				e_mail_ui_session_get_label_store (
 				E_MAIL_UI_SESSION (object)));
 			return;
-
-		case PROP_VFOLDER_STORE:
-			g_value_set_object (
-				value,
-				e_mail_ui_session_get_vfolder_store (
-				E_MAIL_UI_SESSION (object)));
-			return;
 	}
 
 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -791,11 +744,18 @@ mail_ui_session_add_service (CamelSession *session,
 	return service;
 }
 
+static EMVFolderContext *
+mail_ui_session_create_vfolder_context (EMailSession *session)
+{
+	return (EMVFolderContext *) em_vfolder_editor_context_new (session);
+}
+
 static void
 e_mail_ui_session_class_init (EMailUISessionClass *class)
 {
 	GObjectClass *object_class;
 	CamelSessionClass *session_class;
+	EMailSessionClass *emailsession_class;
 
 	g_type_class_add_private (class, sizeof (EMailUISessionPrivate));
 
@@ -810,16 +770,8 @@ e_mail_ui_session_class_init (EMailUISessionClass *class)
 	session_class->get_filter_driver = mail_ui_session_get_filter_driver;
 	session_class->add_service = mail_ui_session_add_service;
 
-	g_object_class_install_property (
-		object_class,
-		PROP_VFOLDER_STORE,
-		g_param_spec_object (
-			"vfolder-store",
-			"Search Folder Store",
-			"Built-in search folder store",
-			CAMEL_TYPE_STORE,
-			G_PARAM_READABLE |
-			G_PARAM_STATIC_STRINGS));
+	emailsession_class = E_MAIL_SESSION_CLASS (class);
+	emailsession_class->create_vfolder_context = mail_ui_session_create_vfolder_context;
 
 	g_object_class_install_property (
 		object_class,
@@ -874,14 +826,6 @@ e_mail_ui_session_get_account_store (EMailUISession *session)
 	return session->priv->account_store;
 }
 
-CamelStore *
-e_mail_ui_session_get_vfolder_store (EMailUISession *session)
-{
-	g_return_val_if_fail (E_IS_MAIL_UI_SESSION (session), NULL);
-
-	return session->priv->vfolder_store;
-}
-
 void
 e_mail_ui_session_add_activity (EMailUISession *session,
                                 EActivity *activity)
diff --git a/mail/e-mail-ui-session.h b/mail/e-mail-ui-session.h
index 1a36487..f6ef4b4 100644
--- a/mail/e-mail-ui-session.h
+++ b/mail/e-mail-ui-session.h
@@ -77,8 +77,6 @@ struct _EMailUISessionClass {
 
 GType		e_mail_ui_session_get_type		(void);
 EMailSession *	e_mail_ui_session_new			(void);
-CamelStore *	e_mail_ui_session_get_vfolder_store
-						(EMailUISession *session);
 EMailAccountStore *
 		e_mail_ui_session_get_account_store
 						(EMailUISession *session);
diff --git a/mail/em-folder-properties.c b/mail/em-folder-properties.c
index 08ed28d..d6ab5ac 100644
--- a/mail/em-folder-properties.c
+++ b/mail/em-folder-properties.c
@@ -38,7 +38,7 @@
 #include "e-mail-backend.h"
 #include "e-mail-ui-session.h"
 #include "em-config.h"
-#include "mail-vfolder.h"
+#include "mail-vfolder-ui.h"
 
 typedef struct _AsyncContext AsyncContext;
 
diff --git a/mail/em-folder-tree.c b/mail/em-folder-tree.c
index d8234f9..2d1e28e 100644
--- a/mail/em-folder-tree.c
+++ b/mail/em-folder-tree.c
@@ -61,7 +61,7 @@
 #include "em-folder-properties.h"
 #include "em-event.h"
 #include "mail-send-recv.h"
-#include "mail-vfolder.h"
+#include "mail-vfolder-ui.h"
 
 #include "e-mail-ui-session.h"
 
diff --git a/mail/em-folder-utils.c b/mail/em-folder-utils.c
index cbf458a..5d8c258 100644
--- a/mail/em-folder-utils.c
+++ b/mail/em-folder-utils.c
@@ -62,7 +62,7 @@
 #include "em-folder-utils.h"
 #include "em-folder-selector.h"
 #include "em-folder-properties.h"
-#include "mail-vfolder.h"
+#include "mail-vfolder-ui.h"
 
 #define d(x)
 
diff --git a/mail/mail-autofilter.c b/mail/mail-autofilter.c
index 4db48df..f0876a4 100644
--- a/mail/mail-autofilter.c
+++ b/mail/mail-autofilter.c
@@ -32,7 +32,7 @@
 #include <libemail-engine/e-mail-folder-utils.h>
 #include <libemail-engine/e-mail-session.h>
 
-#include "mail-vfolder.h"
+#include "mail-vfolder-ui.h"
 #include "mail-autofilter.h"
 #include "em-utils.h"
 #include "libevolution-utils/e-alert-dialog.h"
diff --git a/mail/mail-vfolder-ui.c b/mail/mail-vfolder-ui.c
new file mode 100644
index 0000000..14b55d1
--- /dev/null
+++ b/mail/mail-vfolder-ui.c
@@ -0,0 +1,327 @@
+/*
+ * 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/>
+ *
+ *
+ * Authors:
+ *		Michael Zucchi <notzed ximian com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include <glib/gi18n.h>
+
+#include "libevolution-utils/e-alert-dialog.h"
+#include "e-util/e-util-private.h"
+
+#include "libemail-utils/mail-mt.h"
+#include "libemail-engine/mail-folder-cache.h"
+#include "libemail-engine/e-mail-folder-utils.h"
+#include "libemail-engine/e-mail-session.h"
+#include "libemail-engine/e-mail-utils.h"
+#include "libemail-engine/mail-ops.h"
+#include "libemail-engine/mail-tools.h"
+
+#include "e-mail-backend.h"
+#include "em-folder-tree-model.h"
+#include "em-utils.h"
+#include "em-vfolder-editor-context.h"
+#include "em-vfolder-editor.h"
+#include "em-vfolder-editor-rule.h"
+#include "mail-autofilter.h"
+#include "mail-vfolder-ui.h"
+#include "e-mail-ui-session.h"
+
+#define d(x)  /* (printf("%s:%s: ",  G_STRLOC, G_STRFUNC), (x))*/
+
+/* NOTE: Once mail is moved to EDS, this context needs to be created ofr Mail UI. */
+extern EMVFolderContext *context;	/* context remains open all time */
+
+void
+vfolder_edit (EMailBackend *backend,
+              GtkWindow *parent_window)
+{
+	EShellBackend *shell_backend;
+	GtkWidget *dialog;
+	const gchar *config_dir;
+	gchar *filename;
+	EMailSession *session;
+
+	g_return_if_fail (E_IS_MAIL_BACKEND (backend));
+	g_return_if_fail (GTK_IS_WINDOW (parent_window));
+
+	shell_backend = E_SHELL_BACKEND (backend);
+	config_dir = e_shell_backend_get_config_dir (shell_backend);
+	filename = g_build_filename (config_dir, "vfolders.xml", NULL);
+	session = e_mail_backend_get_session (backend);
+
+	vfolder_load_storage (session);
+
+	dialog = em_vfolder_editor_new (context);
+	gtk_window_set_title (
+		GTK_WINDOW (dialog), _("Search Folders"));
+	gtk_window_set_transient_for (
+		GTK_WINDOW (dialog), parent_window);
+
+	switch (gtk_dialog_run (GTK_DIALOG (dialog))) {
+		case GTK_RESPONSE_OK:
+			e_rule_context_save ((ERuleContext *) context, filename);
+			break;
+		default:
+			e_rule_context_revert ((ERuleContext *) context, filename);
+			break;
+	}
+
+	gtk_widget_destroy (dialog);
+}
+
+static void
+vfolder_edit_response_cb (GtkWidget *dialog,
+                          gint response_id,
+                          gpointer user_data)
+{
+	if (response_id == GTK_RESPONSE_OK) {
+		GObject *object;
+		EFilterRule *rule;
+		EFilterRule *newrule;
+		const gchar *config_dir;
+		gchar *user;
+
+		object = G_OBJECT (dialog);
+		rule = g_object_get_data (object, "vfolder-rule");
+		newrule = g_object_get_data (object, "vfolder-newrule");
+
+		e_filter_rule_copy (rule, newrule);
+		config_dir = mail_session_get_config_dir ();
+		user = g_build_filename (config_dir, "vfolders.xml", NULL);
+		e_rule_context_save ((ERuleContext *) context, user);
+		g_free (user);
+	}
+
+	gtk_widget_destroy (dialog);
+}
+
+void
+vfolder_edit_rule (EMailSession *session,
+                   const gchar *folder_uri,
+                   EAlertSink *alert_sink)
+{
+	GtkWidget *dialog;
+	GtkWidget *widget;
+	GtkWidget *container;
+	EFilterRule *rule = NULL;
+	EFilterRule *newrule;
+	gchar *folder_name = NULL;
+
+	g_return_if_fail (E_IS_MAIL_SESSION (session));
+	g_return_if_fail (folder_uri != NULL);
+	g_return_if_fail (E_IS_ALERT_SINK (alert_sink));
+
+	e_mail_folder_uri_parse (
+		CAMEL_SESSION (session), folder_uri,
+		NULL, &folder_name, NULL);
+
+	if (folder_name != NULL) {
+		rule = e_rule_context_find_rule (
+			(ERuleContext *) context, folder_name, NULL);
+		g_free (folder_name);
+	}
+
+	if (rule == NULL) {
+		/* TODO: we should probably just create it ... */
+		e_alert_submit (
+			alert_sink, "mail:vfolder-notexist",
+			folder_uri, NULL);
+		return;
+	}
+
+	g_object_ref (rule);
+	newrule = e_filter_rule_clone (rule);
+
+	dialog = gtk_dialog_new_with_buttons (
+		_("Edit Search Folder"), NULL,
+		GTK_DIALOG_DESTROY_WITH_PARENT,
+		GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+		GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);
+
+	gtk_container_set_border_width (GTK_CONTAINER (dialog), 6);
+	gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+
+	gtk_window_set_default_size (GTK_WINDOW (dialog), 500, 500);
+	gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE);
+
+	container = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+	gtk_box_set_spacing (GTK_BOX (container), 6);
+
+	widget = e_filter_rule_get_widget (
+		(EFilterRule *) newrule, (ERuleContext *) context);
+	gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+	gtk_widget_show (widget);
+
+	g_object_set_data_full (
+		G_OBJECT (dialog), "vfolder-rule",
+		rule, (GDestroyNotify) g_object_unref);
+	g_object_set_data_full (
+		G_OBJECT (dialog), "vfolder-newrule",
+		newrule, (GDestroyNotify) g_object_unref);
+
+	g_signal_connect (
+		dialog, "response",
+		G_CALLBACK (vfolder_edit_response_cb), NULL);
+
+	gtk_widget_show (dialog);
+}
+
+static void
+new_rule_clicked (GtkWidget *w,
+                  gint button,
+                  gpointer data)
+{
+	if (button == GTK_RESPONSE_OK) {
+		const gchar *config_dir;
+		gchar *user;
+		EFilterRule *rule = g_object_get_data((GObject *)w, "rule");
+		EAlert *alert = NULL;
+
+		if (!e_filter_rule_validate (rule, &alert)) {
+			e_alert_run_dialog (GTK_WINDOW (w), alert);
+			g_object_unref (alert);
+			return;
+		}
+
+		if (e_rule_context_find_rule (
+			(ERuleContext *) context, rule->name, rule->source)) {
+			e_alert_run_dialog_for_args (
+				GTK_WINDOW (w), "mail:vfolder-notunique",
+				rule->name, NULL);
+			return;
+		}
+
+		g_object_ref (rule);
+		e_rule_context_add_rule ((ERuleContext *) context, rule);
+		config_dir = mail_session_get_config_dir ();
+		user = g_build_filename (config_dir, "vfolders.xml", NULL);
+		e_rule_context_save ((ERuleContext *) context, user);
+		g_free (user);
+	}
+
+	gtk_widget_destroy (w);
+}
+
+static void
+new_rule_changed_cb (EFilterRule *rule,
+                     GtkDialog *dialog)
+{
+	g_return_if_fail (rule != NULL);
+	g_return_if_fail (dialog != NULL);
+
+	gtk_dialog_set_response_sensitive (
+		dialog, GTK_RESPONSE_OK, rule->parts != NULL);
+}
+
+/* clones a filter/search rule into a matching vfolder rule
+ * (assuming the same system definitions) */
+EFilterRule *
+vfolder_clone_rule (EMailSession *session,
+                    EFilterRule *in)
+{
+	EFilterRule *rule;
+	xmlNodePtr xml;
+
+	g_return_val_if_fail (E_IS_MAIL_SESSION (session), NULL);
+
+	rule = em_vfolder_editor_rule_new (session);
+
+	xml = e_filter_rule_xml_encode (in);
+	e_filter_rule_xml_decode (rule, xml, (ERuleContext *) context);
+	xmlFreeNodeList (xml);
+
+	return rule;
+}
+
+/* adds a rule with a gui */
+void
+vfolder_gui_add_rule (EMVFolderRule *rule)
+{
+	GtkWidget *w;
+	GtkDialog *gd;
+	GtkWidget *container;
+
+	w = e_filter_rule_get_widget ((EFilterRule *) rule, (ERuleContext *) context);
+
+	gd = (GtkDialog *) gtk_dialog_new_with_buttons (
+		_("New Search Folder"),
+		NULL,
+		GTK_DIALOG_DESTROY_WITH_PARENT,
+		GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+		GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);
+
+	gtk_dialog_set_default_response (gd, GTK_RESPONSE_OK);
+	gtk_container_set_border_width (GTK_CONTAINER (gd), 6);
+
+	container = gtk_dialog_get_content_area (gd);
+	gtk_box_set_spacing (GTK_BOX (container), 6);
+
+	g_object_set (gd, "resizable", TRUE, NULL);
+	gtk_window_set_default_size (GTK_WINDOW (gd), 500, 500);
+	gtk_box_pack_start (GTK_BOX (container), w, TRUE, TRUE, 0);
+	gtk_widget_show ((GtkWidget *) gd);
+	g_object_set_data_full (
+		G_OBJECT (gd), "rule", rule,
+		(GDestroyNotify) g_object_unref);
+	g_signal_connect (
+		rule, "changed",
+		G_CALLBACK (new_rule_changed_cb), gd);
+	new_rule_changed_cb ((EFilterRule *) rule, gd);
+	g_signal_connect (
+		gd, "response",
+		G_CALLBACK (new_rule_clicked), NULL);
+	gtk_widget_show ((GtkWidget *) gd);
+}
+
+void
+vfolder_gui_add_from_message (EMailSession *session,
+                              CamelMimeMessage *message,
+                              gint flags,
+                              CamelFolder *folder)
+{
+	EMVFolderRule *rule;
+
+	g_return_if_fail (CAMEL_IS_MIME_MESSAGE (message));
+
+	rule = (EMVFolderRule *) em_vfolder_rule_from_message (
+		context, message, flags, folder);
+	vfolder_gui_add_rule (rule);
+}
+
+void
+vfolder_gui_add_from_address (EMailSession *session,
+                              CamelInternetAddress *addr,
+                              gint flags,
+                              CamelFolder *folder)
+{
+	EMVFolderRule *rule;
+
+	g_return_if_fail (addr != NULL);
+
+	rule = (EMVFolderRule *) em_vfolder_rule_from_address (
+		context, addr, flags, folder);
+	vfolder_gui_add_rule (rule);
+}
diff --git a/mail/mail-vfolder.h b/mail/mail-vfolder-ui.h
similarity index 90%
rename from mail/mail-vfolder.h
rename to mail/mail-vfolder-ui.h
index fc03e88..55b838c 100644
--- a/mail/mail-vfolder.h
+++ b/mail/mail-vfolder-ui.h
@@ -19,8 +19,8 @@
  *
  */
 
-#ifndef _MAIL_VFOLDER_H
-#define _MAIL_VFOLDER_H
+#ifndef _MAIL_VFOLDER_UI_H
+#define _MAIL_VFOLDER_UI_H
 
 #include <camel/camel.h>
 
@@ -29,8 +29,8 @@
 #include <mail/e-mail-backend.h>
 #include <libemail-utils/em-vfolder-rule.h>
 #include <shell/e-shell-view.h>
+#include <libemail-engine/mail-vfolder.h>
 
-void		vfolder_load_storage		(EMailBackend *backend);
 void		vfolder_edit			(EMailBackend *backend,
 						 GtkWindow *parent_window);
 void		vfolder_edit_rule		(EMailSession *session,
@@ -47,8 +47,4 @@ void		vfolder_gui_add_from_address	(EMailSession *session,
 						 CamelInternetAddress *addr,
 						 gint flags,
 						 CamelFolder *folder);
-
-/* close up, clean up */
-void		mail_vfolder_shutdown		(void);
-
 #endif
diff --git a/modules/mail/e-mail-shell-backend.c b/modules/mail/e-mail-shell-backend.c
index 79832ab..25902f3 100644
--- a/modules/mail/e-mail-shell-backend.c
+++ b/modules/mail/e-mail-shell-backend.c
@@ -54,7 +54,7 @@
 #include <mail/em-format-html-display.h>
 #include <mail/em-utils.h>
 #include <mail/mail-send-recv.h>
-#include <mail/mail-vfolder.h>
+#include <mail/mail-vfolder-ui.h>
 #include <mail/importers/mail-importer.h>
 #include <mail/e-mail-ui-session.h>
 
@@ -518,7 +518,7 @@ mail_shell_backend_start (EShellBackend *shell_backend)
 	enable_search_folders = e_shell_settings_get_boolean (
 		shell_settings, "mail-enable-search-folders");
 	if (enable_search_folders)
-		vfolder_load_storage (backend);
+		vfolder_load_storage (session);
 
 	if (!e_mail_account_store_load_sort_order (account_store, &error)) {
 		g_warning ("%s: %s", G_STRFUNC, error->message);
diff --git a/modules/mail/e-mail-shell-view-private.h b/modules/mail/e-mail-shell-view-private.h
index c60d5c6..2a884f4 100644
--- a/modules/mail/e-mail-shell-view-private.h
+++ b/modules/mail/e-mail-shell-view-private.h
@@ -63,7 +63,7 @@
 #include <mail/em-utils.h>
 #include <mail/mail-autofilter.h>
 #include <mail/mail-send-recv.h>
-#include <mail/mail-vfolder.h>
+#include <mail/mail-vfolder-ui.h>
 #include <mail/message-list.h>
 
 #include "e-mail-shell-backend.h"
diff --git a/modules/mail/em-account-prefs.c b/modules/mail/em-account-prefs.c
index 18fed16..1e492be 100644
--- a/modules/mail/em-account-prefs.c
+++ b/modules/mail/em-account-prefs.c
@@ -47,7 +47,7 @@
 #include <mail/em-config.h>
 #include <mail/em-account-editor.h>
 #include <mail/em-utils.h>
-#include <mail/mail-vfolder.h>
+#include <mail/mail-vfolder-ui.h>
 
 #define EM_ACCOUNT_PREFS_GET_PRIVATE(obj) \
 	(G_TYPE_INSTANCE_GET_PRIVATE \
@@ -78,14 +78,16 @@ account_prefs_service_enabled_cb (EMailAccountStore *store,
 {
 	EMailBackend *backend;
 	const gchar *uid;
+	EMailSession *session;
 
 	uid = camel_service_get_uid (service);
 	backend = em_account_prefs_get_backend (prefs);
+	session = e_mail_backend_get_session (backend);
 
 	/* FIXME Kind of a gross hack.  EMailSession doesn't have
 	 *       access to EMailBackend so it can't do this itself. */
 	if (g_strcmp0 (uid, E_MAIL_SESSION_VFOLDER_UID) == 0)
-		vfolder_load_storage (backend);
+		vfolder_load_storage (session);
 }
 
 static void



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