[evolution] Bug #351025 - Make the order of the mail accounts configurable



commit e0548d25707ad8c4713e2e74c622a92bf4988545
Author: Milan Crha <mcrha redhat com>
Date:   Mon Sep 26 11:45:59 2011 +0200

    Bug #351025 - Make the order of the mail accounts configurable

 mail/e-mail-backend.c                 |   35 ++-
 mail/e-mail-backend.h                 |    7 +
 mail/e-mail-reader.c                  |    6 +-
 mail/e-mail-sidebar.c                 |    2 +-
 mail/e-mail-store.c                   |   36 ++-
 mail/em-composer-utils.c              |    2 +-
 mail/em-folder-selection-button.c     |    4 +-
 mail/em-folder-tree-model.c           |  367 +++++++++++++---
 mail/em-folder-tree-model.h           |   11 +-
 mail/em-folder-tree.c                 |    2 +-
 mail/em-folder-utils.c                |   19 +-
 mail/em-subscription-editor.c         |    2 +-
 mail/em-utils.c                       |  168 +++++++
 mail/em-utils.h                       |    4 +
 mail/em-vfolder-rule.c                |    2 +-
 mail/evolution-mail.schemas.in        |   35 ++-
 mail/message-list.c                   |    2 +-
 modules/mail/e-mail-shell-settings.c  |    8 +
 modules/mail/e-mail-shell-view.c      |    2 +-
 modules/mail/em-account-prefs.c       |   95 ++++-
 plugins/mark-all-read/mark-all-read.c |    6 +-
 widgets/misc/e-account-manager.c      |  103 +++++
 widgets/misc/e-account-tree-view.c    |  772 ++++++++++++++++++++++++++++++++-
 widgets/misc/e-account-tree-view.h    |   46 ++
 24 files changed, 1628 insertions(+), 108 deletions(-)
---
diff --git a/mail/e-mail-backend.c b/mail/e-mail-backend.c
index c9ee133..ff37b7a 100644
--- a/mail/e-mail-backend.c
+++ b/mail/e-mail-backend.c
@@ -71,9 +71,16 @@ enum {
 	PROP_SESSION
 };
 
+enum {
+	ACCOUNT_SORT_ORDER_CHANGED,
+	LAST_SIGNAL
+};
+
 /* FIXME Kill this thing.  It's a horrible hack. */
 extern gint camel_application_is_exiting;
 
+static guint signals[LAST_SIGNAL];
+
 G_DEFINE_ABSTRACT_TYPE (
 	EMailBackend,
 	e_mail_backend,
@@ -538,7 +545,7 @@ mail_backend_folder_changed_cb (MailFolderCache *folder_cache,
                                 const gchar *msg_uid,
                                 const gchar *msg_sender,
                                 const gchar *msg_subject,
-                                EShell *shell)
+                                EMailBackend *mail_backend)
 {
 	CamelFolder *folder = NULL;
 	EMEvent *event = em_event_peek ();
@@ -565,12 +572,12 @@ mail_backend_folder_changed_cb (MailFolderCache *folder_cache,
 	folder_type = (flags & CAMEL_FOLDER_TYPE_MASK);
 	target->is_inbox = (folder_type == CAMEL_FOLDER_TYPE_INBOX);
 
-	model = em_folder_tree_model_get_default ();
+	model = em_folder_tree_model_get_default (mail_backend);
 	target->display_name = em_folder_tree_model_get_folder_name (
 		model, store, folder_name);
 
 	if (target->new > 0)
-		e_shell_event (shell, "mail-icon", (gpointer) "mail-unread");
+		e_shell_event (e_shell_backend_get_shell (E_SHELL_BACKEND (mail_backend)), "mail-icon", (gpointer) "mail-unread");
 
 	/** @Event: folder.changed
 	 * @Title: Folder changed
@@ -766,7 +773,7 @@ mail_backend_constructed (GObject *object)
 	e_account_combo_box_set_session (CAMEL_SESSION (priv->session));
 
 	/* FIXME EMailBackend should own the default EMFolderTreeModel. */
-	folder_tree_model = em_folder_tree_model_get_default ();
+	folder_tree_model = em_folder_tree_model_get_default (E_MAIL_BACKEND (shell_backend));
 	em_folder_tree_model_set_session (folder_tree_model, priv->session);
 
 	g_signal_connect (
@@ -801,7 +808,7 @@ mail_backend_constructed (GObject *object)
 
 	g_signal_connect (
 		folder_cache, "folder-changed",
-		G_CALLBACK (mail_backend_folder_changed_cb), shell);
+		G_CALLBACK (mail_backend_folder_changed_cb), shell_backend);
 
 	mail_config_init (priv->session);
 	mail_msg_init ();
@@ -838,6 +845,15 @@ e_mail_backend_class_init (EMailBackendClass *class)
 			NULL,
 			E_TYPE_MAIL_SESSION,
 			G_PARAM_READABLE));
+
+	signals[ACCOUNT_SORT_ORDER_CHANGED] = g_signal_new (
+		"account-sort-order-changed",
+		G_TYPE_FROM_CLASS (class),
+		G_SIGNAL_RUN_LAST,
+		G_STRUCT_OFFSET (EMailBackendClass, account_sort_order_changed),
+		NULL, NULL,
+		g_cclosure_marshal_VOID__VOID,
+		G_TYPE_NONE, 0);
 }
 
 static void
@@ -934,3 +950,12 @@ e_mail_backend_submit_alert (EMailBackend *backend,
 	e_alert_submit_valist (E_ALERT_SINK (shell_content), tag, va);
 	va_end (va);
 }
+
+void
+e_mail_backend_account_sort_order_changed (EMailBackend *backend)
+{
+	g_return_if_fail (backend != NULL);
+	g_return_if_fail (E_IS_MAIL_BACKEND (backend));
+
+	g_signal_emit (backend, signals[ACCOUNT_SORT_ORDER_CHANGED], 0);
+}
diff --git a/mail/e-mail-backend.h b/mail/e-mail-backend.h
index 6d42519..4d3cc10 100644
--- a/mail/e-mail-backend.h
+++ b/mail/e-mail-backend.h
@@ -67,6 +67,10 @@ struct _EMailBackendClass {
 						(EMailBackend *backend);
 	gboolean	(*empty_trash_policy_decision)
 						(EMailBackend *backend);
+
+	/* Signals */
+	void		(*account_sort_order_changed)
+						(EMailBackend *backend);
 };
 
 GType		e_mail_backend_get_type		(void);
@@ -79,6 +83,9 @@ void		e_mail_backend_submit_alert	(EMailBackend *backend,
 						 const gchar *tag,
 						 ...) G_GNUC_NULL_TERMINATED;
 
+void		e_mail_backend_account_sort_order_changed
+						(EMailBackend *backend);
+
 G_END_DECLS
 
 #endif /* E_MAIL_BACKEND_H */
diff --git a/mail/e-mail-reader.c b/mail/e-mail-reader.c
index 430f71d..a8e3899 100644
--- a/mail/e-mail-reader.c
+++ b/mail/e-mail-reader.c
@@ -300,7 +300,7 @@ action_mail_copy_cb (GtkAction *action,
 	window = e_mail_reader_get_window (reader);
 	uids = e_mail_reader_get_selected_uids (reader);
 
-	model = em_folder_tree_model_get_default ();
+	model = em_folder_tree_model_get_default (backend);
 
 	dialog = em_folder_selector_new (
 		window, backend, model,
@@ -732,7 +732,7 @@ action_mail_mark_unread_cb (GtkAction *action,
 
 	/* Notify the tree model that the user has marked messages as
 	 * unread so it doesn't mistake the event as new mail arriving. */
-	model = em_folder_tree_model_get_default ();
+	model = em_folder_tree_model_get_default (e_mail_reader_get_backend (reader));
 	folder = e_mail_reader_get_folder (reader);
 	em_folder_tree_model_user_marked_unread (model, folder, n_marked);
 }
@@ -806,7 +806,7 @@ action_mail_move_cb (GtkAction *action,
 	uids = e_mail_reader_get_selected_uids (reader);
 	window = e_mail_reader_get_window (reader);
 
-	model = em_folder_tree_model_get_default ();
+	model = em_folder_tree_model_get_default (backend);
 
 	dialog = em_folder_selector_new (
 		window, backend, model,
diff --git a/mail/e-mail-sidebar.c b/mail/e-mail-sidebar.c
index 35048f8..6a971ea 100644
--- a/mail/e-mail-sidebar.c
+++ b/mail/e-mail-sidebar.c
@@ -471,7 +471,7 @@ e_mail_sidebar_new (EMailBackend *backend,
 	g_return_val_if_fail (E_IS_MAIL_BACKEND (backend), NULL);
 	g_return_val_if_fail (E_IS_ALERT_SINK (alert_sink), NULL);
 
-	model = em_folder_tree_model_get_default ();
+	model = em_folder_tree_model_get_default (backend);
 
 	return g_object_new (
 		E_TYPE_MAIL_SIDEBAR,
diff --git a/mail/e-mail-store.c b/mail/e-mail-store.c
index ea44e42..7b77743 100644
--- a/mail/e-mail-store.c
+++ b/mail/e-mail-store.c
@@ -39,6 +39,9 @@
 #include "mail/mail-mt.h"
 #include "mail/mail-ops.h"
 
+#include "shell/e-shell.h"
+#include "shell/e-shell-settings.h"
+
 typedef struct _StoreInfo StoreInfo;
 
 typedef void	(*AddStoreCallback)	(MailFolderCache *folder_cache,
@@ -152,6 +155,32 @@ mail_store_note_store_cb (MailFolderCache *folder_cache,
 	return TRUE;
 }
 
+static gboolean
+special_mail_store_is_enabled (CamelStore *store)
+{
+	CamelService *service;
+	EShell *shell;
+	EShellSettings *shell_settings;
+	const gchar *uid, *prop = NULL;
+
+	service = CAMEL_SERVICE (store);
+	g_return_val_if_fail (service, FALSE);
+
+	uid = camel_service_get_uid (service);
+	if (g_strcmp0 (uid, "local") == 0)
+		prop = "mail-enable-local-folders";
+	else if (g_strcmp0 (uid, "vfolder") == 0)
+		prop = "mail-enable-search-folders";
+
+	if (!prop)
+		return TRUE;
+
+	shell = e_shell_get_default ();
+	shell_settings = e_shell_get_shell_settings (shell);
+
+	return e_shell_settings_get_boolean (shell_settings, prop);
+}
+
 static void
 mail_store_add (EMailSession *session,
                 CamelStore *store,
@@ -165,7 +194,7 @@ mail_store_add (EMailSession *session,
 	g_return_if_fail (store != NULL);
 	g_return_if_fail (CAMEL_IS_STORE (store));
 
-	default_model = em_folder_tree_model_get_default ();
+	default_model = em_folder_tree_model_get_default (NULL);
 	folder_cache = e_mail_session_get_folder_cache (session);
 
 	store_info = store_info_new (store);
@@ -173,7 +202,8 @@ mail_store_add (EMailSession *session,
 
 	g_hash_table_insert (store_table, store, store_info);
 
-	em_folder_tree_model_add_store (default_model, store);
+	if (special_mail_store_is_enabled (store))
+		em_folder_tree_model_add_store (default_model, store);
 
 	mail_folder_cache_note_store (
 		folder_cache, CAMEL_SESSION (session), store, NULL,
@@ -387,7 +417,7 @@ e_mail_store_remove (EMailSession *session,
 	folder_cache = e_mail_session_get_folder_cache (session);
 	mail_folder_cache_note_store_remove (folder_cache, store);
 
-	default_model = em_folder_tree_model_get_default ();
+	default_model = em_folder_tree_model_get_default (NULL);
 	em_folder_tree_model_remove_store (default_model, store);
 
 	mail_disconnect_store (store);
diff --git a/mail/em-composer-utils.c b/mail/em-composer-utils.c
index 8c98040..e42559a 100644
--- a/mail/em-composer-utils.c
+++ b/mail/em-composer-utils.c
@@ -2989,7 +2989,7 @@ post_header_clicked_cb (EComposerPostHeader *header,
 	shell_backend = e_shell_get_backend_by_name (shell, "mail");
 
 	/* FIXME Limit the folder tree to the NNTP account? */
-	model = em_folder_tree_model_get_default ();
+	model = em_folder_tree_model_get_default (E_MAIL_BACKEND (shell_backend));
 
 	dialog = em_folder_selector_new (
 		GTK_WINDOW (composer),
diff --git a/mail/em-folder-selection-button.c b/mail/em-folder-selection-button.c
index 3f05147..26a3c9c 100644
--- a/mail/em-folder-selection-button.c
+++ b/mail/em-folder-selection-button.c
@@ -272,13 +272,13 @@ folder_selection_button_clicked (GtkButton *button)
 
 		session = e_mail_backend_get_session (priv->backend);
 
-		model = em_folder_tree_model_new ();
+		model = em_folder_tree_model_new (priv->backend);
 		em_folder_tree_model_set_session (model, session);
 		em_folder_tree_model_add_store (model, priv->store);
 	}
 
 	if (model == NULL)
-		model = g_object_ref (em_folder_tree_model_get_default ());
+		model = g_object_ref (em_folder_tree_model_get_default (priv->backend));
 
 	dialog = em_folder_selector_new (
 		parent, priv->backend, model,
diff --git a/mail/em-folder-tree-model.c b/mail/em-folder-tree-model.c
index eb26ad5..2116faf 100644
--- a/mail/em-folder-tree-model.c
+++ b/mail/em-folder-tree-model.c
@@ -69,6 +69,7 @@ struct _EMFolderTreeModelPrivate {
 
 	EAccountList *accounts;
 	EMailSession *session;
+	EMailBackend *backend;
 
 	/* CamelStore -> EMFolderTreeStoreInfo */
 	GHashTable *store_index;
@@ -84,7 +85,8 @@ struct _EMFolderTreeModelPrivate {
 enum {
 	PROP_0,
 	PROP_SELECTION,
-	PROP_SESSION
+	PROP_SESSION,
+	PROP_BACKEND
 };
 
 enum {
@@ -124,55 +126,69 @@ folder_tree_model_sort (GtkTreeModel *model,
                         GtkTreeIter *b,
                         gpointer user_data)
 {
-	EShell *shell;
+	EShell *shell = user_data;
 	gchar *aname, *bname;
 	CamelStore *store;
 	gboolean is_store;
 	guint32 aflags, bflags;
+	guint asortorder, bsortorder;
 	gint rv = -2;
 
-	/* XXX Pass the EShell in as user_data. */
-	shell = e_shell_get_default ();
-
 	gtk_tree_model_get (
 		model, a,
 		COL_BOOL_IS_STORE, &is_store,
 		COL_POINTER_CAMEL_STORE, &store,
 		COL_STRING_DISPLAY_NAME, &aname,
-		COL_UINT_FLAGS, &aflags, -1);
+		COL_UINT_FLAGS, &aflags,
+		COL_UINT_SORTORDER, &asortorder,
+		-1);
 
 	gtk_tree_model_get (
 		model, b,
 		COL_STRING_DISPLAY_NAME, &bname,
-		COL_UINT_FLAGS, &bflags, -1);
+		COL_UINT_FLAGS, &bflags,
+		COL_UINT_SORTORDER, &bsortorder,
+		-1);
 
 	if (is_store) {
-		/* On This Computer is always first, and Search Folders
-		 * is always last. */
-		if (e_shell_get_express_mode (shell)) {
-			if (!strcmp (aname, _("On This Computer")) &&
-				!strcmp (bname, _("Search Folders")))
-				rv = -1;
-			else if (!strcmp (bname, _("On This Computer")) &&
-				!strcmp (aname, _("Search Folders")))
-				rv = 1;
-			else if (!strcmp (aname, _("On This Computer")))
-				rv = 1;
-			else if (!strcmp (bname, _("On This Computer")))
-				rv = -1;
-				else if (!strcmp (aname, _("Search Folders")))
-				rv = 1;
-			else if (!strcmp (bname, _("Search Folders")))
-				rv = -1;
-		} else {
-			if (!strcmp (aname, _("On This Computer")))
+		if (e_shell_settings_get_boolean (e_shell_get_shell_settings (shell), "mail-sort-accounts-alpha")) {
+			const gchar *on_this_computer = _("On This Computer");
+			const gchar *search_folders = _("Search Folders");
+
+			/* On This Computer is always first, and Search Folders
+			 * is always last. */
+			if (e_shell_get_express_mode (shell)) {
+				if (g_str_equal (aname, on_this_computer) &&
+				    g_str_equal (bname, search_folders))
+					rv = -1;
+				else if (g_str_equal (bname, on_this_computer) &&
+					 g_str_equal (aname, search_folders))
+					rv = 1;
+				else if (g_str_equal (aname, on_this_computer))
+					rv = 1;
+				else if (g_str_equal (bname, on_this_computer))
+					rv = -1;
+				else if (g_str_equal (aname, search_folders))
+					rv = 1;
+				else if (g_str_equal (bname, search_folders))
+					rv = -1;
+			} else {
+				if (g_str_equal (aname, on_this_computer))
+					rv = -1;
+				else if (g_str_equal (bname, on_this_computer))
+					rv = 1;
+				else if (g_str_equal (aname, search_folders))
+					rv = 1;
+				else if (g_str_equal (bname, search_folders))
+					rv = -1;
+			}
+		} else if (asortorder || bsortorder) {
+			if (asortorder < bsortorder)
 				rv = -1;
-			else if (!strcmp (bname, _("On This Computer")))
-				rv = 1;
-			else if (!strcmp (aname, _("Search Folders")))
+			else if (asortorder > bsortorder)
 				rv = 1;
-			else if (!strcmp (bname, _("Search Folders")))
-				rv = -1;
+			else
+				rv = 0;
 		}
 	} else if (store == vfolder_store) {
 		/* UNMATCHED is always last. */
@@ -191,6 +207,8 @@ folder_tree_model_sort (GtkTreeModel *model,
 	if (aname == NULL) {
 		if (bname == NULL)
 			rv = 0;
+		else
+			rv = -1;
 	} else if (bname == NULL)
 		rv = 1;
 
@@ -260,6 +278,106 @@ account_added_cb (EAccountList *accounts,
 }
 
 static void
+folder_tree_model_sort_changed (EMFolderTreeModel *tree_model)
+{
+	GtkTreeModel *model;
+	EShellBackend *shell_backend;
+
+	g_return_if_fail (tree_model != NULL);
+	g_return_if_fail (EM_IS_FOLDER_TREE_MODEL (tree_model));
+
+	model = GTK_TREE_MODEL (tree_model);
+	if (!model)
+		return;
+
+	shell_backend = E_SHELL_BACKEND (em_folder_tree_model_get_backend (tree_model));
+
+	/* this invokes also sort on a GtkTreeStore */
+	gtk_tree_sortable_set_default_sort_func (
+		GTK_TREE_SORTABLE (model),
+		folder_tree_model_sort, e_shell_backend_get_shell (shell_backend), NULL);
+}
+
+static void
+account_sort_order_changed_cb (EMFolderTreeModel *folder_tree_model)
+{
+	EMailBackend *mail_backend;
+	GtkTreeModel *model;
+	GtkTreeStore *tree_store;
+	GtkTreeIter iter;
+
+	g_return_if_fail (folder_tree_model != NULL);
+
+	model = GTK_TREE_MODEL (folder_tree_model);
+	g_return_if_fail (model != NULL);
+
+	tree_store = GTK_TREE_STORE (folder_tree_model);
+	g_return_if_fail (tree_store != NULL);
+
+	if (!gtk_tree_model_get_iter_first (model, &iter))
+		return;
+
+	mail_backend = em_folder_tree_model_get_backend (folder_tree_model);
+
+	do {
+		CamelStore *store = NULL;
+
+		gtk_tree_model_get (model, &iter, COL_POINTER_CAMEL_STORE, &store, -1);
+
+		if (store) {
+			const gchar *account_uid;
+			guint sortorder;
+
+			account_uid = camel_service_get_uid (CAMEL_SERVICE (store));
+			sortorder = em_utils_get_account_sort_order (mail_backend, account_uid);
+
+			gtk_tree_store_set (tree_store, &iter, COL_UINT_SORTORDER, sortorder, -1);
+		}
+	} while (gtk_tree_model_iter_next (model, &iter));
+
+	folder_tree_model_sort_changed (folder_tree_model);
+}
+
+static void
+add_remove_special_folder (EMFolderTreeModel *model, const gchar *account_uid, gboolean add)
+{
+	EMailSession *session;
+	CamelService *service;
+
+	session = em_folder_tree_model_get_session (model);
+
+	service = camel_session_get_service (CAMEL_SESSION (session), account_uid);
+
+	if (!CAMEL_IS_STORE (service))
+		return;
+
+	if (add)
+		em_folder_tree_model_add_store (model, CAMEL_STORE (service));
+	else
+		em_folder_tree_model_remove_store (model, CAMEL_STORE (service));
+}
+
+static void
+enable_local_folders_changed_cb (EMFolderTreeModel *model, GParamSpec *spec, EShellSettings *shell_settings)
+{
+	g_return_if_fail (model != NULL);
+	g_return_if_fail (shell_settings != NULL);
+
+	add_remove_special_folder (model, "local",
+		e_shell_settings_get_boolean (shell_settings, "mail-enable-local-folders"));
+}
+
+static void
+enable_search_folders_changed_cb (EMFolderTreeModel *model, GParamSpec *spec, EShellSettings *shell_settings)
+{
+	g_return_if_fail (model != NULL);
+	g_return_if_fail (shell_settings != NULL);
+
+	add_remove_special_folder (model, "vfolder",
+		e_shell_settings_get_boolean (shell_settings, "mail-enable-search-folders"));
+}
+
+static void
 folder_tree_model_selection_finalized_cb (EMFolderTreeModel *model)
 {
 	model->priv->selection = NULL;
@@ -285,6 +403,11 @@ folder_tree_model_set_property (GObject *object,
 				EM_FOLDER_TREE_MODEL (object),
 				g_value_get_object (value));
 			return;
+		case PROP_BACKEND:
+			em_folder_tree_model_set_backend (
+				EM_FOLDER_TREE_MODEL (object),
+				g_value_get_object (value));
+			return;
 	}
 
 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -310,11 +433,74 @@ folder_tree_model_get_property (GObject *object,
 				em_folder_tree_model_get_session (
 				EM_FOLDER_TREE_MODEL (object)));
 			return;
+		case PROP_BACKEND:
+			g_value_set_object (
+				value,
+				em_folder_tree_model_get_backend (
+				EM_FOLDER_TREE_MODEL (object)));
+			return;
 	}
 
 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 }
 
+
+static void
+folder_tree_model_constructed (GObject *object)
+{
+	EShell *shell;
+	EShellSettings *shell_settings;
+	EMFolderTreeModel *model;
+
+	GType col_types[] = {
+		G_TYPE_STRING,   /* display name */
+		G_TYPE_POINTER,  /* store object */
+		G_TYPE_STRING,   /* full name */
+		G_TYPE_STRING,   /* icon name */
+		G_TYPE_STRING,   /* uri */
+		G_TYPE_UINT,     /* unread count */
+		G_TYPE_UINT,     /* flags */
+		G_TYPE_BOOLEAN,  /* is a store node */
+		G_TYPE_BOOLEAN,  /* is a folder node */
+		G_TYPE_BOOLEAN,  /* has not-yet-loaded subfolders */
+		G_TYPE_UINT,     /* last known unread count */
+		G_TYPE_BOOLEAN,  /* folder is a draft folder */
+		G_TYPE_UINT	 /* user's sortorder */
+	};
+
+	model = EM_FOLDER_TREE_MODEL (object);
+	shell = e_shell_backend_get_shell (E_SHELL_BACKEND (model->priv->backend));
+	shell_settings = e_shell_get_shell_settings (shell);
+
+	gtk_tree_store_set_column_types (
+		GTK_TREE_STORE (model), NUM_COLUMNS, col_types);
+	gtk_tree_sortable_set_default_sort_func (
+		GTK_TREE_SORTABLE (model),
+		folder_tree_model_sort, shell, NULL);
+	gtk_tree_sortable_set_sort_column_id (
+		GTK_TREE_SORTABLE (model),
+		GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
+		GTK_SORT_ASCENDING);
+
+	model->priv->accounts = e_get_account_list ();
+	model->priv->account_changed_id = g_signal_connect (
+		model->priv->accounts, "account-changed",
+		G_CALLBACK (account_changed_cb), model);
+	model->priv->account_removed_id = g_signal_connect (
+		model->priv->accounts, "account-removed",
+		G_CALLBACK (account_removed_cb), model);
+	model->priv->account_added_id = g_signal_connect (
+		model->priv->accounts, "account-added",
+		G_CALLBACK (account_added_cb), model);
+
+	g_signal_connect_swapped (model->priv->backend, "account-sort-order-changed", G_CALLBACK (account_sort_order_changed_cb), model);
+	g_signal_connect_swapped (shell_settings, "notify::mail-sort-accounts-alpha", G_CALLBACK (account_sort_order_changed_cb), model);
+	g_signal_connect_swapped (shell_settings, "notify::mail-enable-local-folders", G_CALLBACK (enable_local_folders_changed_cb), model);
+	g_signal_connect_swapped (shell_settings, "notify::mail-enable-search-folders", G_CALLBACK (enable_search_folders_changed_cb), model);
+
+	G_OBJECT_CLASS (parent_class)->constructed (object);
+}
+
 static void
 folder_tree_model_dispose (GObject *object)
 {
@@ -334,6 +520,24 @@ folder_tree_model_dispose (GObject *object)
 		priv->session = NULL;
 	}
 
+	if (priv->backend) {
+		EShell *shell;
+		EShellSettings *shell_settings;
+		EMFolderTreeModel *model;
+
+		model = EM_FOLDER_TREE_MODEL (object);
+		shell = e_shell_backend_get_shell (E_SHELL_BACKEND (priv->backend));
+		shell_settings = e_shell_get_shell_settings (shell);
+
+		g_signal_handlers_disconnect_by_func (priv->backend, G_CALLBACK (account_sort_order_changed_cb), model);
+		g_signal_handlers_disconnect_by_func (shell_settings, G_CALLBACK (account_sort_order_changed_cb), model);
+		g_signal_handlers_disconnect_by_func (shell_settings, G_CALLBACK (enable_local_folders_changed_cb), model);
+		g_signal_handlers_disconnect_by_func (shell_settings, G_CALLBACK (enable_search_folders_changed_cb), model);
+
+		g_object_unref (priv->backend);
+		priv->backend = NULL;
+	}
+
 	/* Chain up to parent's dispose() method. */
 	G_OBJECT_CLASS (parent_class)->dispose (object);
 }
@@ -370,6 +574,7 @@ em_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;
 
@@ -393,6 +598,16 @@ em_folder_tree_model_class_init (EMFolderTreeModelClass *class)
 			E_TYPE_MAIL_SESSION,
 			G_PARAM_READWRITE));
 
+	g_object_class_install_property (
+		object_class,
+		PROP_BACKEND,
+		g_param_spec_object (
+			"backend",
+			NULL,
+			NULL,
+			E_TYPE_MAIL_BACKEND,
+			G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
 	signals[LOADING_ROW] = g_signal_new (
 		"loading-row",
 		G_OBJECT_CLASS_TYPE (object_class),
@@ -477,21 +692,6 @@ em_folder_tree_model_init (EMFolderTreeModel *model)
 	GHashTable *store_index;
 	GHashTable *uri_index;
 
-	GType col_types[] = {
-		G_TYPE_STRING,   /* display name */
-		G_TYPE_POINTER,  /* store object */
-		G_TYPE_STRING,   /* full name */
-		G_TYPE_STRING,   /* icon name */
-		G_TYPE_STRING,   /* uri */
-		G_TYPE_UINT,     /* unread count */
-		G_TYPE_UINT,     /* flags */
-		G_TYPE_BOOLEAN,  /* is a store node */
-		G_TYPE_BOOLEAN,  /* is a folder node */
-		G_TYPE_BOOLEAN,  /* has not-yet-loaded subfolders */
-		G_TYPE_UINT,      /* last known unread count */
-		G_TYPE_BOOLEAN  /* folder is a draft folder */
-	};
-
 	store_index = g_hash_table_new_full (
 		g_direct_hash, g_direct_equal,
 		(GDestroyNotify) NULL,
@@ -505,42 +705,29 @@ em_folder_tree_model_init (EMFolderTreeModel *model)
 	model->priv = EM_FOLDER_TREE_MODEL_GET_PRIVATE (model);
 	model->priv->store_index = store_index;
 	model->priv->uri_index = uri_index;
-
-	gtk_tree_store_set_column_types (
-		GTK_TREE_STORE (model), NUM_COLUMNS, col_types);
-	gtk_tree_sortable_set_default_sort_func (
-		GTK_TREE_SORTABLE (model),
-		folder_tree_model_sort, NULL, NULL);
-	gtk_tree_sortable_set_sort_column_id (
-		GTK_TREE_SORTABLE (model),
-		GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
-		GTK_SORT_ASCENDING);
-
-	model->priv->accounts = e_get_account_list ();
-	model->priv->account_changed_id = g_signal_connect (
-		model->priv->accounts, "account-changed",
-		G_CALLBACK (account_changed_cb), model);
-	model->priv->account_removed_id = g_signal_connect (
-		model->priv->accounts, "account-removed",
-		G_CALLBACK (account_removed_cb), model);
-	model->priv->account_added_id = g_signal_connect (
-		model->priv->accounts, "account-added",
-		G_CALLBACK (account_added_cb), model);
 }
 
 EMFolderTreeModel *
-em_folder_tree_model_new (void)
+em_folder_tree_model_new (EMailBackend *mail_backend)
 {
-	return g_object_new (EM_TYPE_FOLDER_TREE_MODEL, NULL);
+	return g_object_new (EM_TYPE_FOLDER_TREE_MODEL, "backend", mail_backend, NULL);
 }
 
 EMFolderTreeModel *
-em_folder_tree_model_get_default (void)
+em_folder_tree_model_get_default (EMailBackend *mail_backend)
 {
 	static EMFolderTreeModel *default_folder_tree_model;
 
-	if (G_UNLIKELY (default_folder_tree_model == NULL))
-		default_folder_tree_model = em_folder_tree_model_new ();
+	if (G_UNLIKELY (default_folder_tree_model == NULL)) {
+		if (!mail_backend) {
+			EShell *shell;
+
+			shell = e_shell_get_default ();
+			mail_backend = E_MAIL_BACKEND (e_shell_get_backend_by_name (shell, "mail"));
+		}
+
+		default_folder_tree_model = em_folder_tree_model_new (mail_backend);
+	}
 
 	return default_folder_tree_model;
 }
@@ -620,6 +807,33 @@ em_folder_tree_model_set_session (EMFolderTreeModel *model,
 	g_object_notify (G_OBJECT (model), "session");
 }
 
+EMailBackend *
+em_folder_tree_model_get_backend (EMFolderTreeModel *model)
+{
+	g_return_val_if_fail (EM_IS_FOLDER_TREE_MODEL (model), NULL);
+
+	return model->priv->backend;
+}
+
+void
+em_folder_tree_model_set_backend (EMFolderTreeModel *model,
+                                  EMailBackend *backend)
+{
+	g_return_if_fail (EM_IS_FOLDER_TREE_MODEL (model));
+
+	if (backend != NULL) {
+		g_return_if_fail (E_IS_MAIL_BACKEND (backend));
+		g_object_ref (backend);
+	}
+
+	if (model->priv->backend != NULL)
+		g_object_unref (model->priv->backend);
+
+	model->priv->backend = backend;
+
+	g_object_notify (G_OBJECT (model), "backend");
+}
+
 void
 em_folder_tree_model_set_folder_info (EMFolderTreeModel *model,
                                       GtkTreeIter *iter,
@@ -1002,6 +1216,7 @@ void
 em_folder_tree_model_add_store (EMFolderTreeModel *model,
                                 CamelStore *store)
 {
+	EMailBackend *mail_backend;
 	EMFolderTreeModelStoreInfo *si;
 	GtkTreeRowReference *reference;
 	GtkTreeStore *tree_store;
@@ -1011,6 +1226,7 @@ em_folder_tree_model_add_store (EMFolderTreeModel *model,
 	CamelProvider *provider;
 	CamelURL *service_url;
 	const gchar *display_name;
+	const gchar *account_uid;
 	gchar *uri;
 
 	g_return_if_fail (EM_IS_FOLDER_TREE_MODEL (model));
@@ -1022,6 +1238,7 @@ em_folder_tree_model_add_store (EMFolderTreeModel *model,
 	provider = camel_service_get_provider (service);
 	service_url = camel_service_get_camel_url (service);
 	display_name = camel_service_get_display_name (service);
+	account_uid = camel_service_get_uid (service);
 
 	/* Ignore stores that should not be added to the tree model. */
 
@@ -1040,6 +1257,8 @@ em_folder_tree_model_add_store (EMFolderTreeModel *model,
 
 	uri = camel_url_to_string (service_url, CAMEL_URL_HIDE_ALL);
 
+	mail_backend = em_folder_tree_model_get_backend (model);
+
 	/* Add the store to the tree. */
 	gtk_tree_store_append (tree_store, &iter, NULL);
 	gtk_tree_store_set (
@@ -1049,7 +1268,9 @@ em_folder_tree_model_add_store (EMFolderTreeModel *model,
 		COL_STRING_FULL_NAME, NULL,
 		COL_BOOL_LOAD_SUBDIRS, TRUE,
 		COL_BOOL_IS_STORE, TRUE,
-		COL_STRING_URI, uri, -1);
+		COL_STRING_URI, uri,
+		COL_UINT_SORTORDER, em_utils_get_account_sort_order (mail_backend, account_uid),
+		-1);
 
 	path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter);
 	reference = gtk_tree_row_reference_new (GTK_TREE_MODEL (model), path);
diff --git a/mail/em-folder-tree-model.h b/mail/em-folder-tree-model.h
index 1bf5483..3765cfe 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.h>
 
+#include <mail/e-mail-backend.h>
 #include <mail/e-mail-session.h>
 
 /* Standard GObject macros */
@@ -72,6 +73,7 @@ enum {
 					 * been added to the tree */
 	COL_UINT_UNREAD_LAST_SEL,	/* last known unread count */
 	COL_BOOL_IS_DRAFT,		/* %TRUE for a draft folder */
+	COL_UINT_SORTORDER,		/* user sort-order for the node */
 	NUM_COLUMNS
 };
 
@@ -109,9 +111,9 @@ struct _EMFolderTreeModelClass {
 
 GType		em_folder_tree_model_get_type	(void);
 EMFolderTreeModel *
-		em_folder_tree_model_new	(void);
+		em_folder_tree_model_new	(EMailBackend *mail_backend);
 EMFolderTreeModel *
-		em_folder_tree_model_get_default (void);
+		em_folder_tree_model_get_default (EMailBackend *mail_backend);
 GtkTreeSelection *
 		em_folder_tree_model_get_selection
 					(EMFolderTreeModel *model);
@@ -123,6 +125,11 @@ EMailSession *	em_folder_tree_model_get_session
 void		em_folder_tree_model_set_session
 					(EMFolderTreeModel *model,
 					 EMailSession *session);
+EMailBackend *	em_folder_tree_model_get_backend
+					(EMFolderTreeModel *model);
+void		em_folder_tree_model_set_backend
+					(EMFolderTreeModel *model,
+					 EMailBackend *backend);
 void		em_folder_tree_model_set_folder_info
 					(EMFolderTreeModel *model,
 					 GtkTreeIter *iter,
diff --git a/mail/em-folder-tree.c b/mail/em-folder-tree.c
index 061c354..6212f8a 100644
--- a/mail/em-folder-tree.c
+++ b/mail/em-folder-tree.c
@@ -1770,7 +1770,7 @@ em_folder_tree_new (EMailBackend *backend,
 	g_return_val_if_fail (E_IS_MAIL_BACKEND (backend), NULL);
 	g_return_val_if_fail (E_IS_ALERT_SINK (alert_sink), NULL);
 
-	model = em_folder_tree_model_get_default ();
+	model = em_folder_tree_model_get_default (backend);
 
 	return em_folder_tree_new_with_model (backend, alert_sink, model);
 }
diff --git a/mail/em-folder-utils.c b/mail/em-folder-utils.c
index 775dfbb..54586ad 100644
--- a/mail/em-folder-utils.c
+++ b/mail/em-folder-utils.c
@@ -487,7 +487,7 @@ em_folder_utils_copy_folder (GtkWindow *parent,
 	label = delete ? _("_Move") : _("C_opy");
 	title = delete ? _("Move Folder To") : _("Copy Folder To");
 
-	model = em_folder_tree_model_get_default ();
+	model = em_folder_tree_model_get_default (backend);
 
 	dialog = em_folder_selector_new (
 		parent, backend, model,
@@ -547,6 +547,8 @@ em_folder_utils_create_folder (GtkWindow *parent,
                                EMFolderTree *emft,
                                const gchar *initial_uri)
 {
+	EShell *shell;
+	EShellSettings *shell_settings;
 	EMailSession *session;
 	EMFolderSelector *selector;
 	EMFolderTree *folder_tree;
@@ -560,7 +562,10 @@ em_folder_utils_create_folder (GtkWindow *parent,
 	g_return_if_fail (GTK_IS_WINDOW (parent));
 	g_return_if_fail (E_IS_MAIL_BACKEND (backend));
 
-	model = em_folder_tree_model_new ();
+	shell = e_shell_backend_get_shell (E_SHELL_BACKEND (backend));
+	shell_settings = e_shell_get_shell_settings (shell);
+
+	model = em_folder_tree_model_new (backend);
 	session = e_mail_backend_get_session (backend);
 	em_folder_tree_model_set_session (model, session);
 
@@ -569,6 +574,7 @@ em_folder_utils_create_folder (GtkWindow *parent,
 	for (link = list; link != NULL; link = g_list_next (link)) {
 		CamelService *service;
 		CamelStore *store;
+		const gchar *uid, *prop = NULL;
 
 		service = CAMEL_SERVICE (link->data);
 
@@ -580,6 +586,15 @@ em_folder_utils_create_folder (GtkWindow *parent,
 		if ((store->flags & CAMEL_STORE_CAN_EDIT_FOLDERS) == 0)
 			continue;
 
+		uid = camel_service_get_uid (service);
+		if (g_strcmp0 (uid, "local") == 0)
+			prop = "mail-enable-local-folders";
+		else if (g_strcmp0 (uid, "vfolder") == 0)
+			prop = "mail-enable-search-folders";
+
+		if (prop && !e_shell_settings_get_boolean (shell_settings, prop))
+			continue;
+
 		em_folder_tree_model_add_store (model, store);
 	}
 
diff --git a/mail/em-subscription-editor.c b/mail/em-subscription-editor.c
index e2452d7..2dca93b 100644
--- a/mail/em-subscription-editor.c
+++ b/mail/em-subscription-editor.c
@@ -1077,7 +1077,7 @@ subscription_editor_realize (GtkWidget *widget)
 
 	/* Find stores to display, and watch for the initial store. */
 
-	model = em_folder_tree_model_get_default ();
+	model = em_folder_tree_model_get_default (NULL);
 	list = em_folder_tree_model_list_stores (model);
 
 	for (link = list; link != NULL; link = g_list_next (link)) {
diff --git a/mail/em-utils.c b/mail/em-utils.c
index 9681653..5ff9388 100644
--- a/mail/em-utils.c
+++ b/mail/em-utils.c
@@ -84,6 +84,8 @@ extern const gchar *shell_builtin_backend;
 
 #define d(x)
 
+static void free_account_sort_order_cache (void);
+
 gboolean
 em_utils_ask_open_many (GtkWindow *parent,
                         gint how_many)
@@ -2014,6 +2016,8 @@ emu_free_mail_cache (void)
 	photos_cache = NULL;
 
 	G_UNLOCK (photos_cache);
+
+	free_account_sort_order_cache ();
 }
 
 void
@@ -2369,3 +2373,167 @@ em_utils_disconnect_service_sync (CamelService *service,
 
 	return res;
 }
+
+G_LOCK_DEFINE_STATIC (accounts_sort_order_cache);
+static GHashTable *accounts_sort_order_cache = NULL; /* account_uid string to sort order uint */
+
+static void
+free_account_sort_order_cache (void)
+{
+	G_LOCK (accounts_sort_order_cache);
+
+	if (accounts_sort_order_cache) {
+		g_hash_table_destroy (accounts_sort_order_cache);
+		accounts_sort_order_cache = NULL;
+	}
+
+	G_UNLOCK (accounts_sort_order_cache);
+}
+
+static void
+fill_accounts_sort_order_cache (EMailBackend *backend, gboolean force_reload)
+{
+	GSList *account_uids;
+
+	G_LOCK (accounts_sort_order_cache);
+
+	if (!force_reload && accounts_sort_order_cache) {
+		G_UNLOCK (accounts_sort_order_cache);
+		return;
+	}
+
+	if (!accounts_sort_order_cache)
+		accounts_sort_order_cache = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+	else
+		g_hash_table_remove_all (accounts_sort_order_cache);
+
+	account_uids = em_utils_load_accounts_sort_order (backend);
+	if (account_uids) {
+		GSList *iter;
+		guint index;
+
+		for (index = 1, iter = account_uids; iter; index++, iter = iter->next) {
+			if (iter->data)
+				g_hash_table_insert (accounts_sort_order_cache, iter->data, GUINT_TO_POINTER (index));
+		}
+
+		/* items are stolen into the cache */
+		/* g_slist_foreach (account_uids, (GFunc) g_free, NULL); */
+		g_slist_free (account_uids);
+	}
+
+	G_UNLOCK (accounts_sort_order_cache);
+}
+
+static gchar *
+emu_get_sort_order_filename (EMailBackend *backend)
+{
+	g_return_val_if_fail (backend != NULL, NULL);
+
+	return g_build_filename (
+		e_shell_backend_get_config_dir (E_SHELL_BACKEND (backend)),
+		"sortorder.ini", NULL);
+}
+
+static GKeyFile *
+emu_get_sort_order_key_file (EMailBackend *backend)
+{
+	gchar *filename;
+	GKeyFile *key_file;
+
+	g_return_val_if_fail (backend != NULL, NULL);
+
+	filename = emu_get_sort_order_filename (backend);
+	g_return_val_if_fail (filename != NULL, NULL);
+
+	key_file = g_key_file_new ();
+	g_key_file_load_from_file (key_file, filename, G_KEY_FILE_NONE, NULL);
+
+	g_free (filename);
+
+	return key_file;
+}
+
+void
+em_utils_save_accounts_sort_order (EMailBackend *backend, const GSList *account_uids)
+{
+	gchar *filename;
+	GKeyFile *key_file;
+	gint ii;
+	gchar key[32];
+	gchar *content;
+	gsize length = 0;
+
+	key_file = emu_get_sort_order_key_file (backend);
+	g_return_if_fail (key_file != NULL);
+
+	filename = emu_get_sort_order_filename (backend);
+	g_return_if_fail (filename != NULL);
+
+	g_key_file_remove_group (key_file, "accounts", NULL);
+
+	for (ii = 0; account_uids; ii++, account_uids = account_uids->next) {
+		sprintf (key, "%d", ii);
+
+		g_key_file_set_string (key_file, "accounts", key, account_uids->data);
+	}
+
+	content = g_key_file_to_data (key_file, &length, NULL);
+	if (content)
+		g_file_set_contents (filename, content, length, NULL);
+
+	g_free (content);
+	g_free (filename);
+	g_key_file_free (key_file);
+
+	fill_accounts_sort_order_cache (backend, TRUE);
+	e_mail_backend_account_sort_order_changed (backend);
+}
+
+GSList *
+em_utils_load_accounts_sort_order (EMailBackend *backend)
+{
+	GKeyFile *key_file;
+	GSList *account_uids = NULL;
+	gchar key[32];
+	gchar *value;
+	gint ii;
+
+	key_file = emu_get_sort_order_key_file (backend);
+	g_return_val_if_fail (key_file != NULL, NULL);
+
+	ii = 0;
+	do {
+		sprintf (key, "%d", ii);
+		ii++;
+
+		value = g_key_file_get_string (key_file, "accounts", key, NULL);
+		if (!value)
+			break;
+
+		account_uids = g_slist_prepend (account_uids, value);
+	} while (*key);
+
+	g_key_file_free (key_file);
+
+	return g_slist_reverse (account_uids);
+}
+
+guint
+em_utils_get_account_sort_order (EMailBackend *backend, const gchar *account_uid)
+{
+	guint res;
+
+	g_return_val_if_fail (backend != NULL, 0);
+	g_return_val_if_fail (account_uid != NULL, 0);
+
+	fill_accounts_sort_order_cache (backend, FALSE);
+
+	G_LOCK (accounts_sort_order_cache);
+
+	res = GPOINTER_TO_UINT (g_hash_table_lookup (accounts_sort_order_cache, account_uid));
+
+	G_UNLOCK (accounts_sort_order_cache);
+
+	return res;
+}
diff --git a/mail/em-utils.h b/mail/em-utils.h
index e8ffd19..e6ebe8c 100644
--- a/mail/em-utils.h
+++ b/mail/em-utils.h
@@ -99,6 +99,10 @@ gboolean em_utils_is_local_delivery_mbox_file (CamelURL *url);
 gboolean em_utils_connect_service_sync (CamelService *service, GCancellable *cancellable, GError **error);
 gboolean em_utils_disconnect_service_sync (CamelService *service, gboolean clean, GCancellable *cancellable, GError **error);
 
+void	em_utils_save_accounts_sort_order (EMailBackend *backend, const GSList *account_uids);
+GSList *em_utils_load_accounts_sort_order (EMailBackend *backend);
+guint	em_utils_get_account_sort_order   (EMailBackend *backend, const gchar *account_uid);
+
 G_END_DECLS
 
 #endif /* __EM_UTILS_H__ */
diff --git a/mail/em-vfolder-rule.c b/mail/em-vfolder-rule.c
index be18f2c..fbb7117 100644
--- a/mail/em-vfolder-rule.c
+++ b/mail/em-vfolder-rule.c
@@ -610,7 +610,7 @@ source_add (GtkWidget *widget,
 
 	backend = em_vfolder_rule_get_backend (data->vr);
 
-	model = em_folder_tree_model_get_default ();
+	model = em_folder_tree_model_get_default (backend);
 
 	dialog = em_folder_selector_new (
 		parent, backend, model,
diff --git a/mail/evolution-mail.schemas.in b/mail/evolution-mail.schemas.in
index f1dcd73..82be131 100644
--- a/mail/evolution-mail.schemas.in
+++ b/mail/evolution-mail.schemas.in
@@ -678,6 +678,20 @@
     </schema>
 
     <schema>
+      <key>/schemas/apps/evolution/mail/display/enable_local</key>
+      <applyto>/apps/evolution/mail/display/enable_local</applyto>
+      <owner>evolution-mail</owner>
+      <type>bool</type>
+      <default>true</default>
+      <locale name="C">
+         <short>Enable local folders</short>
+         <long>
+          Whether to show local folders (On This Computer) in a folder tree.
+         </long>
+      </locale>
+    </schema>
+
+    <schema>
       <key>/schemas/apps/evolution/mail/display/safe_list</key>
       <applyto>/apps/evolution/mail/display/safe_list</applyto>
       <owner>evolution-mail</owner>
@@ -885,7 +899,7 @@
          </long>
       </locale>
     </schema>
-    
+
     <schema>
       <key>/schemas/apps/evolution/mail/display/paned_view_headers_state</key>
       <applyto>/apps/evolution/mail/display/paned_view_headers_state</applyto>
@@ -901,7 +915,24 @@
       	</long>
       </locale>
     </schema>
-      
+
+    <schema>
+      <key>/schemas/apps/evolution/mail/display/sort_accounts_alpha</key>
+      <applyto>/apps/evolution/mail/display/sort_accounts_alpha</applyto>
+      <owner>evolution-mail</owner>
+      <type>bool</type>
+      <default>true</default>
+      <locale name="C">
+      	<short>Sort accounts alphabetically in a folder tree</short>
+      	<long>
+      	   Tells how to sort accounts in a folder tree used in a Mail view.
+	   When set to true accounts are sorted alphabetically, with an exception
+	   of On This Computer and Search folders, otherwise accounts are
+	   sorted based on an order given by a user.
+      	</long>
+      </locale>
+    </schema>
+
     <!-- Mail Browser -->
 
     <schema>
diff --git a/mail/message-list.c b/mail/message-list.c
index d98f860..cd44b95 100644
--- a/mail/message-list.c
+++ b/mail/message-list.c
@@ -4191,7 +4191,7 @@ on_click (ETree *tree,
 	if (col == COL_MESSAGE_STATUS && (flags & CAMEL_MESSAGE_SEEN)) {
 		EMFolderTreeModel *model;
 
-		model = em_folder_tree_model_get_default ();
+		model = em_folder_tree_model_get_default (list->priv->backend);
 		em_folder_tree_model_user_marked_unread (
 			model, list->folder, 1);
 	}
diff --git a/modules/mail/e-mail-shell-settings.c b/modules/mail/e-mail-shell-settings.c
index 99402d5..b0d5f1e 100644
--- a/modules/mail/e-mail-shell-settings.c
+++ b/modules/mail/e-mail-shell-settings.c
@@ -142,6 +142,10 @@ e_mail_shell_settings_init (EShellBackend *shell_backend)
 		"/apps/evolution/mail/display/enable_vfolders");
 
 	e_shell_settings_install_property_for_key (
+		"mail-enable-local-folders",
+		"/apps/evolution/mail/display/enable_local");
+
+	e_shell_settings_install_property_for_key (
 		"mail-font-monospace",
 		"/apps/evolution/mail/display/fonts/monospace");
 
@@ -201,6 +205,10 @@ e_mail_shell_settings_init (EShellBackend *shell_backend)
 		"/apps/evolution/mail/display/show_real_date");
 
 	e_shell_settings_install_property_for_key (
+		"mail-sort-accounts-alpha",
+		"/apps/evolution/mail/display/sort_accounts_alpha");
+
+	e_shell_settings_install_property_for_key (
 		"mail-prompt-delete-in-vfolder",
 		"/apps/evolution/mail/prompts/delete_in_vfolder");
 
diff --git a/modules/mail/e-mail-shell-view.c b/modules/mail/e-mail-shell-view.c
index 5759b58..3a92ce2 100644
--- a/modules/mail/e-mail-shell-view.c
+++ b/modules/mail/e-mail-shell-view.c
@@ -868,7 +868,7 @@ mail_shell_view_update_actions (EShellView *shell_view)
 	shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
 	state = e_shell_sidebar_check_state (shell_sidebar);
 
-	model = em_folder_tree_model_get_default ();
+	model = em_folder_tree_model_get_default (e_mail_reader_get_backend (reader));
 
 	folder_allows_children =
 		(state & E_MAIL_SIDEBAR_FOLDER_ALLOWS_CHILDREN);
diff --git a/modules/mail/em-account-prefs.c b/modules/mail/em-account-prefs.c
index b43f1fb..1b11b41 100644
--- a/modules/mail/em-account-prefs.c
+++ b/modules/mail/em-account-prefs.c
@@ -40,6 +40,8 @@
 #include "e-mail-store.h"
 #include "em-config.h"
 #include "em-account-editor.h"
+#include "em-utils.h"
+#include "mail-vfolder.h"
 #include "shell/e-shell.h"
 #include "capplet/settings/mail-capplet-shell.h"
 
@@ -59,6 +61,36 @@ G_DEFINE_TYPE (
 	em_account_prefs,
 	E_TYPE_ACCOUNT_MANAGER)
 
+static gboolean
+account_prefs_toggle_enable_special (EMAccountPrefs *prefs, EAccountTreeViewSelectedType type, gboolean enabled)
+{
+	const gchar *prop = NULL;
+	EShell *shell;
+	EShellSettings *shell_settings;
+
+	g_return_val_if_fail (prefs != NULL, FALSE);
+	g_return_val_if_fail (prefs->priv != NULL, FALSE);
+
+	if (type == E_ACCOUNT_TREE_VIEW_SELECTED_LOCAL)
+		prop = "mail-enable-local-folders";
+	else if (type == E_ACCOUNT_TREE_VIEW_SELECTED_VFOLDER)
+		prop = "mail-enable-search-folders";
+
+	if (!prop)
+		return FALSE;
+
+	shell = e_shell_backend_get_shell (E_SHELL_BACKEND (prefs->priv->backend));
+	shell_settings = e_shell_get_shell_settings (shell);
+
+	e_shell_settings_set_boolean (shell_settings, prop, enabled);
+
+	/* make sure "Search Folders" are loaded when enabled */
+	if (enabled && type == E_ACCOUNT_TREE_VIEW_SELECTED_VFOLDER)
+		vfolder_load_storage (prefs->priv->backend);
+
+	return TRUE;
+}
+
 static void
 account_prefs_enable_account_cb (EAccountTreeView *tree_view,
                                  EMAccountPrefs *prefs)
@@ -67,6 +99,11 @@ account_prefs_enable_account_cb (EAccountTreeView *tree_view,
 	EMailSession *session;
 
 	account = e_account_tree_view_get_selected (tree_view);
+	if (!account) {
+		if (account_prefs_toggle_enable_special (prefs, e_account_tree_view_get_selected_type (tree_view), TRUE))
+			return;
+	}
+
 	g_return_if_fail (account != NULL);
 
 	session = e_mail_backend_get_session (prefs->priv->backend);
@@ -84,6 +121,11 @@ account_prefs_disable_account_cb (EAccountTreeView *tree_view,
 	gint response;
 
 	account = e_account_tree_view_get_selected (tree_view);
+	if (!account) {
+		if (account_prefs_toggle_enable_special (prefs, e_account_tree_view_get_selected_type (tree_view), FALSE))
+			return;
+	}
+
 	g_return_if_fail (account != NULL);
 
 	account_list = e_account_tree_view_get_account_list (tree_view);
@@ -380,14 +422,35 @@ em_account_prefs_init (EMAccountPrefs *prefs)
 		G_CALLBACK (account_prefs_disable_account_cb), prefs);
 }
 
+static void
+account_tree_view_sort_order_changed_cb (EAccountTreeView *tree_view, EMailBackend *backend)
+{
+	GSList *account_uids;
+
+	g_return_if_fail (tree_view != NULL);
+	g_return_if_fail (backend != NULL);
+
+	account_uids = e_account_tree_view_get_sort_order (tree_view);
+	if (!account_uids)
+		return;
+
+	em_utils_save_accounts_sort_order (backend, account_uids);
+
+	g_slist_foreach (account_uids, (GFunc) g_free, NULL);
+	g_slist_free (account_uids);
+}
+
 GtkWidget *
 em_account_prefs_new (EPreferencesWindow *window)
 {
 	EShell *shell;
 	EShellBackend *shell_backend;
 	EAccountList *account_list;
+	EAccountTreeView *tree_view;
 	EMailSession *session;
 	const gchar *data_dir;
+	GtkWidget *res;
+	GSList *account_uids;
 
 	account_list = e_get_account_list ();
 	g_return_val_if_fail (E_IS_ACCOUNT_LIST (account_list), NULL);
@@ -402,10 +465,40 @@ em_account_prefs_new (EPreferencesWindow *window)
 	/* Make sure the e-mail-local is initialized. */
 	e_mail_local_init (session, data_dir);
 
-	return g_object_new (
+	res = g_object_new (
 		EM_TYPE_ACCOUNT_PREFS,
 		"account-list", account_list,
 		"backend", shell_backend, NULL);
+
+	tree_view = e_account_manager_get_tree_view (E_ACCOUNT_MANAGER (res));
+	e_account_tree_view_set_express_mode (tree_view, e_shell_get_express_mode (shell));
+
+	g_object_bind_property (
+		e_shell_get_shell_settings (shell), "mail-sort-accounts-alpha",
+		tree_view, "sort-alpha",
+		G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
+
+	g_object_bind_property (
+		e_shell_get_shell_settings (shell), "mail-enable-local-folders",
+		tree_view, "enable-local-folders",
+		G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
+
+	g_object_bind_property (
+		e_shell_get_shell_settings (shell), "mail-enable-search-folders",
+		tree_view, "enable-search-folders",
+		G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
+
+	account_uids = em_utils_load_accounts_sort_order (E_MAIL_BACKEND (shell_backend));
+	if (account_uids) {
+		e_account_tree_view_set_sort_order (tree_view, account_uids);
+		g_slist_foreach (account_uids, (GFunc) g_free, NULL);
+		g_slist_free (account_uids);
+	}
+
+	g_signal_connect (tree_view, "sort-order-changed",
+		G_CALLBACK (account_tree_view_sort_order_changed_cb), shell_backend);
+
+	return res;
 }
 
 EMailBackend *
diff --git a/plugins/mark-all-read/mark-all-read.c b/plugins/mark-all-read/mark-all-read.c
index 4fe19cf..ab85494 100644
--- a/plugins/mark-all-read/mark-all-read.c
+++ b/plugins/mark-all-read/mark-all-read.c
@@ -318,7 +318,7 @@ scan_folder_tree_for_unread_helper (GtkTreeModel *model,
 }
 
 static gint
-scan_folder_tree_for_unread (const gchar *folder_uri)
+scan_folder_tree_for_unread (EMailBackend *backend, const gchar *folder_uri)
 {
 	GtkTreeRowReference *reference;
 	EMFolderTreeModel *model;
@@ -338,7 +338,7 @@ scan_folder_tree_for_unread (const gchar *folder_uri)
 	if (folder_uri == NULL)
 		return 0;
 
-	model = em_folder_tree_model_get_default ();
+	model = em_folder_tree_model_get_default (backend);
 	reference = em_folder_tree_model_lookup_uri (model, folder_uri);
 
 	if (gtk_tree_row_reference_valid (reference)) {
@@ -602,7 +602,7 @@ update_actions_cb (EShellView *shell_view,
 	g_object_get (shell_sidebar, "folder-tree", &folder_tree, NULL);
 	folder_uri = em_folder_tree_get_selected_uri (folder_tree);
 
-	visible = (scan_folder_tree_for_unread (folder_uri) > 0);
+	visible = (scan_folder_tree_for_unread (E_MAIL_BACKEND (e_shell_view_get_shell_backend (shell_view)), folder_uri) > 0);
 	gtk_action_set_visible (action, visible);
 
 	g_object_unref (folder_tree);
diff --git a/widgets/misc/e-account-manager.c b/widgets/misc/e-account-manager.c
index e4ee687..b2c0583 100644
--- a/widgets/misc/e-account-manager.c
+++ b/widgets/misc/e-account-manager.c
@@ -37,6 +37,9 @@ struct _EAccountManagerPrivate {
 	GtkWidget *edit_button;
 	GtkWidget *delete_button;
 	GtkWidget *default_button;
+	GtkWidget *sort_toggle;
+	GtkWidget *sort_up_button;
+	GtkWidget *sort_down_button;
 };
 
 enum {
@@ -96,16 +99,22 @@ account_manager_selection_changed_cb (EAccountManager *manager,
 	EAccountList *account_list;
 	EAccount *default_account;
 	EAccount *account;
+	GtkTreeModel *model = NULL;
+	GtkTreeIter iter1, iter2;
 	GtkWidget *add_button;
 	GtkWidget *edit_button;
 	GtkWidget *delete_button;
 	GtkWidget *default_button;
+	GtkWidget *sort_up_button;
+	GtkWidget *sort_down_button;
 	gboolean sensitive;
 
 	add_button = manager->priv->add_button;
 	edit_button = manager->priv->edit_button;
 	delete_button = manager->priv->delete_button;
 	default_button = manager->priv->default_button;
+	sort_up_button = manager->priv->sort_up_button;
+	sort_down_button = manager->priv->sort_down_button;
 
 	tree_view = e_account_manager_get_tree_view (manager);
 	account = e_account_tree_view_get_selected (tree_view);
@@ -126,6 +135,50 @@ account_manager_selection_changed_cb (EAccountManager *manager,
 
 	sensitive = (account != NULL && account != default_account);
 	gtk_widget_set_sensitive (default_button, sensitive);
+
+	sensitive = !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (manager->priv->sort_toggle)) &&
+		    gtk_tree_selection_get_selected (selection, &model, &iter1);
+	iter2 = iter1;
+	gtk_widget_set_sensitive (sort_up_button, sensitive && gtk_tree_model_iter_previous (model, &iter1));
+	gtk_widget_set_sensitive (sort_down_button, sensitive && gtk_tree_model_iter_next (model, &iter2));
+}
+
+static void
+account_manager_sort_toggled_cb (EAccountManager *manager)
+{
+	GtkTreeView *tree_view;
+	GtkTreeSelection *selection;
+
+	tree_view = GTK_TREE_VIEW (e_account_manager_get_tree_view (manager));
+	selection = gtk_tree_view_get_selection (tree_view);
+
+	account_manager_selection_changed_cb (manager, selection);
+}
+
+static void
+account_manager_sort_up_cb (EAccountManager *manager)
+{
+	GtkTreeView *tree_view;
+	GtkTreeSelection *selection;
+
+	tree_view = GTK_TREE_VIEW (e_account_manager_get_tree_view (manager));
+	selection = gtk_tree_view_get_selection (tree_view);
+
+	e_account_tree_view_move_up (e_account_manager_get_tree_view (manager));
+	account_manager_selection_changed_cb (manager, selection);
+}
+
+static void
+account_manager_sort_down_cb (EAccountManager *manager)
+{
+	GtkTreeView *tree_view;
+	GtkTreeSelection *selection;
+
+	tree_view = GTK_TREE_VIEW (e_account_manager_get_tree_view (manager));
+	selection = gtk_tree_view_get_selection (tree_view);
+
+	e_account_tree_view_move_down (e_account_manager_get_tree_view (manager));
+	account_manager_selection_changed_cb (manager, selection);
 }
 
 static void
@@ -195,6 +248,21 @@ account_manager_dispose (GObject *object)
 		priv->delete_button = NULL;
 	}
 
+	if (priv->sort_toggle != NULL) {
+		g_object_unref (priv->sort_toggle);
+		priv->sort_toggle = NULL;
+	}
+
+	if (priv->sort_up_button != NULL) {
+		g_object_unref (priv->sort_up_button);
+		priv->sort_up_button = NULL;
+	}
+
+	if (priv->sort_down_button != NULL) {
+		g_object_unref (priv->sort_down_button);
+		priv->sort_down_button = NULL;
+	}
+
 	/* Chain up to parent's dispose() method. */
 	G_OBJECT_CLASS (e_account_manager_parent_class)->dispose (object);
 }
@@ -312,6 +380,23 @@ e_account_manager_init (EAccountManager *manager)
 
 	container = GTK_WIDGET (manager);
 
+	widget = gtk_check_button_new_with_mnemonic (_("Use default Evolution _sort order for accounts"));
+	manager->priv->sort_toggle = g_object_ref (widget);
+	gtk_widget_show (widget);
+	gtk_table_attach (
+		GTK_TABLE (container), widget, 0, 1, 1, 2,
+		GTK_EXPAND | GTK_FILL, 0, 4, 0);
+
+	g_object_bind_property (
+		manager->priv->tree_view, "sort-alpha",
+		widget, "active",
+		G_BINDING_BIDIRECTIONAL |
+		G_BINDING_SYNC_CREATE);
+
+	g_signal_connect_swapped (
+		widget, "toggled",
+		G_CALLBACK (account_manager_sort_toggled_cb), manager);
+
 	widget = gtk_vbutton_box_new ();
 	gtk_button_box_set_layout (
 		GTK_BUTTON_BOX (widget), GTK_BUTTONBOX_START);
@@ -361,6 +446,24 @@ e_account_manager_init (EAccountManager *manager)
 	g_signal_connect_swapped (
 		widget, "clicked",
 		G_CALLBACK (account_manager_default_clicked_cb), manager);
+
+	widget = gtk_button_new_from_stock (GTK_STOCK_GO_UP);
+	gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+	manager->priv->sort_up_button = g_object_ref (widget);
+	gtk_widget_show (widget);
+
+	g_signal_connect_swapped (
+		widget, "clicked",
+		G_CALLBACK (account_manager_sort_up_cb), manager);
+
+	widget = gtk_button_new_from_stock (GTK_STOCK_GO_DOWN);
+	gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+	manager->priv->sort_down_button = g_object_ref (widget);
+	gtk_widget_show (widget);
+
+	g_signal_connect_swapped (
+		widget, "clicked",
+		G_CALLBACK (account_manager_sort_down_cb), manager);
 }
 
 GtkWidget *
diff --git a/widgets/misc/e-account-tree-view.c b/widgets/misc/e-account-tree-view.c
index 18c39dc..a213643 100644
--- a/widgets/misc/e-account-tree-view.c
+++ b/widgets/misc/e-account-tree-view.c
@@ -33,25 +33,35 @@ enum {
 	COLUMN_DEFAULT,
 	COLUMN_ENABLED,
 	COLUMN_NAME,
-	COLUMN_PROTOCOL
+	COLUMN_PROTOCOL,
+	COLUMN_SORTORDER
 };
 
 enum {
 	PROP_0,
 	PROP_ACCOUNT_LIST,
-	PROP_SELECTED
+	PROP_SELECTED,
+	PROP_SORT_ALPHA,
+	PROP_EXPRESS_MODE,
+	PROP_ENABLE_LOCAL_FOLDERS,
+	PROP_ENABLE_SEARCH_FOLDERS
 };
 
 enum {
 	ENABLE_ACCOUNT,
 	DISABLE_ACCOUNT,
 	REFRESHED,
+	SORT_ORDER_CHANGED,
 	LAST_SIGNAL
 };
 
 struct _EAccountTreeViewPrivate {
 	EAccountList *account_list;
 	GHashTable *index;
+	gboolean sort_alpha;
+	gboolean express_mode;
+	gboolean enable_local_folders;
+	gboolean enable_search_folders;
 };
 
 static guint signals[LAST_SIGNAL];
@@ -61,10 +71,124 @@ G_DEFINE_TYPE (
 	e_account_tree_view,
 	GTK_TYPE_TREE_VIEW)
 
+static gint
+account_tree_view_sort (GtkTreeModel *model,
+                        GtkTreeIter *a,
+                        GtkTreeIter *b,
+                        gpointer user_data)
+{
+	gint rv = -2;
+	gchar *aname = NULL, *bname = NULL;
+	EAccount *aaccount = NULL, *baccount = NULL;
+	guint asortorder = 0, bsortorder = 0;
+
+	gtk_tree_model_get (model, a,
+		COLUMN_ACCOUNT, &aaccount,
+		COLUMN_NAME, &aname,
+		COLUMN_SORTORDER, &asortorder,
+		-1);
+
+	gtk_tree_model_get (model, b,
+		COLUMN_ACCOUNT, &baccount,
+		COLUMN_NAME, &bname,
+		COLUMN_SORTORDER, &bsortorder,
+		-1);
+
+	if ((!aaccount || !baccount || !e_account_tree_view_get_sort_alpha (user_data)) && aname && bname) {
+		if (e_account_tree_view_get_sort_alpha (user_data)) {
+			const gchar *on_this_computer = _("On This Computer");
+			const gchar *search_folders = _("Search Folders");
+
+			if (e_account_tree_view_get_express_mode (user_data)) {
+				if (g_str_equal (aname, on_this_computer) &&
+				    g_str_equal (bname, search_folders))
+					rv = -1;
+				else if (g_str_equal (bname, on_this_computer) &&
+					 g_str_equal (aname, search_folders))
+					rv = 1;
+				else if (g_str_equal (aname, on_this_computer))
+					rv = 1;
+				else if (g_str_equal (bname, on_this_computer))
+					rv = -1;
+				else if (g_str_equal (aname, search_folders))
+					rv = 1;
+				else if (g_str_equal (bname, search_folders))
+					rv = -1;
+			} else {
+				if (g_str_equal (aname, on_this_computer))
+					rv = -1;
+				else if (g_str_equal (bname, on_this_computer))
+					rv = 1;
+				else if (g_str_equal (aname, search_folders))
+					rv = 1;
+				else if (g_str_equal (bname, search_folders))
+					rv = -1;
+			}
+		} else {
+			if (asortorder < bsortorder)
+				rv = -1;
+			else if (asortorder > bsortorder)
+				rv = 1;
+			else
+				rv = 0;
+		}
+	}
+
+	if (rv == -2) {
+		if (aname == NULL) {
+			if (bname == NULL)
+				rv = 0;
+			else
+				rv = -1;
+		} else if (bname == NULL)
+			rv = 1;
+
+		if (rv == -2)
+			rv = g_utf8_collate (aname, bname);
+	}
+
+	g_free (aname);
+	g_free (bname);
+
+	if (aaccount)
+		g_object_unref (aaccount);
+	if (baccount)
+		g_object_unref (baccount);
+
+	return rv;
+}
+
+static void
+account_tree_view_normalize_sortorder_column (EAccountTreeView *tree_view)
+{
+	GtkListStore *list_store;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	guint index;
+
+	g_return_if_fail (tree_view != NULL);
+	g_return_if_fail (E_IS_ACCOUNT_TREE_VIEW (tree_view));
+
+	model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view));
+	if (!model || !gtk_tree_model_get_iter_first (model, &iter))
+		return;
+
+	list_store = GTK_LIST_STORE (model);
+	g_return_if_fail (list_store != NULL);
+
+	index = 1;
+	do {
+		gtk_list_store_set (list_store, &iter, COLUMN_SORTORDER, index, -1);
+
+		index++;
+	} while (gtk_tree_model_iter_next (model, &iter));
+}
+
 static gboolean
 account_tree_view_refresh_timeout_cb (gpointer ptree_view)
 {
 	EAccountTreeView *tree_view;
+	EAccountTreeViewSelectedType selected;
 	EAccountList *account_list;
 	EAccount *account;
 	GtkListStore *store;
@@ -73,18 +197,28 @@ account_tree_view_refresh_timeout_cb (gpointer ptree_view)
 	EIterator *account_iter;
 	EAccount *default_account;
 	GHashTable *index;
+	GSList *sort_order;
 	GList *list = NULL;
 	GList *iter;
 
 	tree_view = ptree_view;
 	account_list = e_account_tree_view_get_account_list (tree_view);
+	sort_order = e_account_tree_view_get_sort_order (tree_view);
 
 	store = gtk_list_store_new (
-		5, E_TYPE_ACCOUNT, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
-		G_TYPE_STRING, G_TYPE_STRING);
+		6, E_TYPE_ACCOUNT, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
+		G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT);
 	model = GTK_TREE_MODEL (store);
 	index = tree_view->priv->index;
 
+	gtk_tree_sortable_set_default_sort_func (
+		GTK_TREE_SORTABLE (model),
+		account_tree_view_sort, tree_view, NULL);
+	gtk_tree_sortable_set_sort_column_id (
+		GTK_TREE_SORTABLE (model),
+		GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
+		GTK_SORT_ASCENDING);
+
 	g_hash_table_remove_all (index);
 
 	if (account_list == NULL)
@@ -148,8 +282,28 @@ account_tree_view_refresh_timeout_cb (gpointer ptree_view)
 			camel_url_free (url);
 	}
 
-skip:
+	gtk_list_store_append (store, &tree_iter);
+	gtk_list_store_set (
+		store, &tree_iter,
+		COLUMN_ACCOUNT, NULL,
+		COLUMN_DEFAULT, FALSE,
+		COLUMN_ENABLED, tree_view->priv->enable_local_folders,
+		COLUMN_NAME, _("On This Computer"),
+		COLUMN_PROTOCOL, NULL,
+		-1);
+
+	gtk_list_store_append (store, &tree_iter);
+	gtk_list_store_set (
+		store, &tree_iter,
+		COLUMN_ACCOUNT, NULL,
+		COLUMN_DEFAULT, FALSE,
+		COLUMN_ENABLED, tree_view->priv->enable_search_folders,
+		COLUMN_NAME, _("Search Folders"),
+		COLUMN_PROTOCOL, NULL,
+		-1);
+ skip:
 	/* Restore the previously selected account. */
+	selected = e_account_tree_view_get_selected_type (tree_view);
 	account = e_account_tree_view_get_selected (tree_view);
 	if (account != NULL)
 		g_object_ref (account);
@@ -157,6 +311,13 @@ skip:
 	e_account_tree_view_set_selected (tree_view, account);
 	if (account != NULL)
 		g_object_unref (account);
+	else if (selected == E_ACCOUNT_TREE_VIEW_SELECTED_LOCAL ||
+		 selected == E_ACCOUNT_TREE_VIEW_SELECTED_VFOLDER)
+		e_account_tree_view_set_selected_type (tree_view, selected);
+
+	e_account_tree_view_set_sort_order (tree_view, sort_order);
+	g_slist_foreach (sort_order, (GFunc) g_free, NULL);
+	g_slist_free (sort_order);
 
 	g_signal_emit (tree_view, signals[REFRESHED], 0);
 
@@ -302,6 +463,26 @@ account_tree_view_set_property (GObject *object,
 				E_ACCOUNT_TREE_VIEW (object),
 				g_value_get_object (value));
 			return;
+		case PROP_SORT_ALPHA:
+			e_account_tree_view_set_sort_alpha (
+				E_ACCOUNT_TREE_VIEW (object),
+				g_value_get_boolean (value));
+			return;
+		case PROP_EXPRESS_MODE:
+			e_account_tree_view_set_express_mode (
+				E_ACCOUNT_TREE_VIEW (object),
+				g_value_get_boolean (value));
+			return;
+		case PROP_ENABLE_LOCAL_FOLDERS:
+			e_account_tree_view_set_enable_local_folders (
+				E_ACCOUNT_TREE_VIEW (object),
+				g_value_get_boolean (value));
+			return;
+		case PROP_ENABLE_SEARCH_FOLDERS:
+			e_account_tree_view_set_enable_search_folders (
+				E_ACCOUNT_TREE_VIEW (object),
+				g_value_get_boolean (value));
+			return;
 	}
 
 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -327,6 +508,30 @@ account_tree_view_get_property (GObject *object,
 				e_account_tree_view_get_selected (
 				E_ACCOUNT_TREE_VIEW (object)));
 			return;
+		case PROP_SORT_ALPHA:
+			g_value_set_boolean (
+				value,
+				e_account_tree_view_get_sort_alpha (
+				E_ACCOUNT_TREE_VIEW (object)));
+			return;
+		case PROP_EXPRESS_MODE:
+			g_value_set_boolean (
+				value,
+				e_account_tree_view_get_express_mode (
+				E_ACCOUNT_TREE_VIEW (object)));
+			return;
+		case PROP_ENABLE_LOCAL_FOLDERS:
+			g_value_set_boolean (
+				value,
+				e_account_tree_view_get_enable_local_folders (
+				E_ACCOUNT_TREE_VIEW (object)));
+			return;
+		case PROP_ENABLE_SEARCH_FOLDERS:
+			g_value_set_boolean (
+				value,
+				e_account_tree_view_get_enable_search_folders (
+				E_ACCOUNT_TREE_VIEW (object)));
+			return;
 	}
 
 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -442,6 +647,46 @@ e_account_tree_view_class_init (EAccountTreeViewClass *class)
 			G_PARAM_READWRITE |
 			G_PARAM_CONSTRUCT));
 
+	g_object_class_install_property (
+		object_class,
+		PROP_SORT_ALPHA,
+		g_param_spec_boolean (
+			"sort-alpha",
+			"Sort alphabetically",
+			NULL,
+			TRUE,
+			G_PARAM_READWRITE));
+
+	g_object_class_install_property (
+		object_class,
+		PROP_EXPRESS_MODE,
+		g_param_spec_boolean (
+			"express-mode",
+			"Express Mode sorting",
+			NULL,
+			FALSE,
+			G_PARAM_READWRITE));
+
+	g_object_class_install_property (
+		object_class,
+		PROP_ENABLE_LOCAL_FOLDERS,
+		g_param_spec_boolean (
+			"enable-local-folders",
+			"Enable Local Folders",
+			NULL,
+			TRUE,
+			G_PARAM_READWRITE));
+
+	g_object_class_install_property (
+		object_class,
+		PROP_ENABLE_SEARCH_FOLDERS,
+		g_param_spec_boolean (
+			"enable-search-folders",
+			"Enable Search Folders",
+			NULL,
+			TRUE,
+			G_PARAM_READWRITE));
+
 	signals[ENABLE_ACCOUNT] = g_signal_new (
 		"enable-account",
 		G_TYPE_FROM_CLASS (class),
@@ -468,6 +713,15 @@ e_account_tree_view_class_init (EAccountTreeViewClass *class)
 		NULL, NULL,
 		g_cclosure_marshal_VOID__VOID,
 		G_TYPE_NONE, 0);
+
+	signals[SORT_ORDER_CHANGED] = g_signal_new (
+		"sort-order-changed",
+		G_TYPE_FROM_CLASS (class),
+		G_SIGNAL_RUN_LAST,
+		G_STRUCT_OFFSET (EAccountTreeViewClass, sort_order_changed),
+		NULL, NULL,
+		g_cclosure_marshal_VOID__VOID,
+		G_TYPE_NONE, 0);
 }
 
 static void
@@ -485,6 +739,10 @@ e_account_tree_view_init (EAccountTreeView *tree_view)
 	tree_view->priv = G_TYPE_INSTANCE_GET_PRIVATE (
 		tree_view, E_TYPE_ACCOUNT_TREE_VIEW, EAccountTreeViewPrivate);
 	tree_view->priv->index = index;
+	tree_view->priv->sort_alpha = TRUE;
+	tree_view->priv->express_mode = FALSE;
+	tree_view->priv->enable_local_folders = TRUE;
+	tree_view->priv->enable_search_folders = TRUE;
 
 	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
 
@@ -622,3 +880,507 @@ e_account_tree_view_set_selected (EAccountTreeView *tree_view,
 
 	return TRUE;
 }
+
+/**
+ * e_account_tree_view_get_selected_type:
+ * @tree_view: an #EAccountTreeView
+ *
+ * Returns: What node type is selected. This is useful for virtual
+ * nodes "On This Computer" and "Search Folders", which doesn't have
+ * their #EAccount representations. if the function returns
+ * #E_ACCOUNT_TREE_VIEW_SELECTED_ACCOUNT, then the selected account
+ * can be obtained with e_account_tree_view_get_selected().
+ *
+ * Since: 3.4
+ **/
+EAccountTreeViewSelectedType
+e_account_tree_view_get_selected_type (EAccountTreeView *tree_view)
+{
+	EAccountTreeViewSelectedType res = E_ACCOUNT_TREE_VIEW_SELECTED_NONE;
+	EAccount *account = NULL;
+	gchar *name = NULL;
+	GtkTreeSelection *selection;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+
+	g_return_val_if_fail (tree_view != NULL, E_ACCOUNT_TREE_VIEW_SELECTED_NONE);
+	g_return_val_if_fail (E_IS_ACCOUNT_TREE_VIEW (tree_view), E_ACCOUNT_TREE_VIEW_SELECTED_NONE);
+
+	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
+	if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+		return E_ACCOUNT_TREE_VIEW_SELECTED_NONE;
+
+	gtk_tree_model_get (model, &iter,
+		COLUMN_ACCOUNT, &account,
+		COLUMN_NAME, &name,
+		-1);
+
+	if (account) {
+		res = E_ACCOUNT_TREE_VIEW_SELECTED_ACCOUNT;
+		g_object_unref (account);
+	} else if (name) {
+		if (g_str_equal (name, _("On This Computer")))
+			res = E_ACCOUNT_TREE_VIEW_SELECTED_LOCAL;
+		else if (g_str_equal (name, _("Search Folders")))
+			res = E_ACCOUNT_TREE_VIEW_SELECTED_VFOLDER;
+	}
+
+	g_free (name);
+
+	return res;
+}
+
+/**
+ * e_account_tree_view_set_selected_type:
+ * @tree_view: an #EAccountTreeView
+ * @select: what to select; see below what can be used here
+ *
+ * Selects special nodes in a view. Can be only either #E_ACCOUNT_TREE_VIEW_SELECTED_LOCAL
+ * or #E_ACCOUNT_TREE_VIEW_SELECTED_VFOLDER.
+ *
+ * Since: 3.4
+ **/
+void
+e_account_tree_view_set_selected_type (EAccountTreeView *tree_view, EAccountTreeViewSelectedType select)
+{
+	GtkTreeSelection *selection;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	gboolean found;
+
+	g_return_if_fail (tree_view != NULL);
+	g_return_if_fail (E_IS_ACCOUNT_TREE_VIEW (tree_view));
+
+	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
+	model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view));
+
+	if (!model || !gtk_tree_model_get_iter_first (model, &iter))
+		return;
+
+	if (select != E_ACCOUNT_TREE_VIEW_SELECTED_LOCAL &&
+	    select != E_ACCOUNT_TREE_VIEW_SELECTED_VFOLDER)
+		return;
+
+	found = FALSE;
+	do {
+		gchar *name = NULL;
+		EAccount *account = NULL;
+
+		gtk_tree_model_get (model, &iter,
+			COLUMN_ACCOUNT, &account,
+			COLUMN_NAME, &name,
+			-1);
+
+		if (account) {
+			g_object_unref (account);
+		} else {
+			switch (select) {
+			case E_ACCOUNT_TREE_VIEW_SELECTED_LOCAL:
+				found = g_strcmp0 (name, _("On This Computer")) == 0;
+				break;
+			case E_ACCOUNT_TREE_VIEW_SELECTED_VFOLDER:
+				found = g_strcmp0 (name, _("Search Folders")) == 0;
+				break;
+			default:
+				break;
+			}
+		}
+
+		g_free (name);
+	} while (!found && gtk_tree_model_iter_next (model, &iter));
+
+	if (found)
+		gtk_tree_selection_select_iter (selection, &iter);
+}
+
+static guint
+account_tree_view_get_slist_index (const GSList *account_uids, const gchar *uid)
+{
+	guint res = 0;
+
+	while (account_uids) {
+		if (g_strcmp0 (uid, account_uids->data) == 0)
+			return res;
+
+		account_uids = account_uids->next;
+		res++;
+	}
+
+	return -1;
+}
+
+/**
+ * e_account_tree_view_set_sort_order:
+ * @tree_view: an #EAccountTreeView
+ * @account_uids: a #GSList of account uids as string
+ *
+ * Sets user sort order for accounts based on the order
+ * in @account_uids. This is used only when sort
+ * alphabetically is set to #FALSE.
+ *
+ * Since: 3.4
+ **/
+void
+e_account_tree_view_set_sort_order (EAccountTreeView *tree_view, const GSList *account_uids)
+{
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+
+	g_return_if_fail (tree_view != NULL);
+	g_return_if_fail (E_IS_ACCOUNT_TREE_VIEW (tree_view));
+
+	model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view));
+
+	if (!model || !gtk_tree_model_get_iter_first (model, &iter))
+		return;
+
+	do {
+		gchar *name = NULL;
+		EAccount *account = NULL;
+		guint sort_order = 0;
+
+		gtk_tree_model_get (model, &iter,
+			COLUMN_ACCOUNT, &account,
+			COLUMN_NAME, &name,
+			-1);
+
+		if (account) {
+			sort_order = account_tree_view_get_slist_index (account_uids, account->uid) + 1;
+			g_object_unref (account);
+		} else if (g_strcmp0 (name, _("On This Computer")) == 0) {
+			sort_order = account_tree_view_get_slist_index (account_uids, "local") + 1;
+		} else if (g_strcmp0 (name, _("Search Folders")) == 0) {
+			sort_order = account_tree_view_get_slist_index (account_uids, "vfolder") + 1;
+		} else {
+			g_warn_if_reached ();
+		}
+
+		gtk_list_store_set (GTK_LIST_STORE (model), &iter, COLUMN_SORTORDER, sort_order, -1);
+		g_free (name);
+	} while (gtk_tree_model_iter_next (model, &iter));
+
+	account_tree_view_normalize_sortorder_column (tree_view);
+	e_account_tree_view_sort_changed (tree_view);
+}
+
+static gint
+eval_order_by_sort_hash_cb (gconstpointer a, gconstpointer b, gpointer user_data)
+{
+	guint asortorder = GPOINTER_TO_UINT (g_hash_table_lookup (user_data, a));
+	guint bsortorder = GPOINTER_TO_UINT (g_hash_table_lookup (user_data, b));
+
+	if (asortorder < bsortorder)
+		return -1;
+	if (asortorder > bsortorder)
+		return 1;
+
+	return 0;
+}
+
+/**
+ * e_account_tree_view_get_sort_order:
+ * @tree_view: an #EAccountTreeView
+ *
+ * Returns: Newly allocated #GSList of newly allocated strings
+ * containing account UIDs in order as user wish to see them.
+ * Each item of the returned list should be freed with g_free()
+ * and the list itself should be freed with g_slist_free(), when
+ * no longer needed.
+ *
+ * Since: 3.4
+ **/
+GSList *
+e_account_tree_view_get_sort_order (EAccountTreeView *tree_view)
+{
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	GHashTable *hash;
+	GSList *res = NULL;
+
+	g_return_val_if_fail (tree_view != NULL, NULL);
+	g_return_val_if_fail (E_IS_ACCOUNT_TREE_VIEW (tree_view), NULL);
+
+	model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view));
+
+	if (!model || !gtk_tree_model_get_iter_first (model, &iter))
+		return NULL;
+
+	hash = g_hash_table_new (g_direct_hash, g_direct_equal);
+
+	do {
+		gchar *toadd = NULL;
+		gchar *name = NULL;
+		EAccount *account = NULL;
+		guint sort_order = 0;
+
+		gtk_tree_model_get (model, &iter,
+			COLUMN_ACCOUNT, &account,
+			COLUMN_NAME, &name,
+			COLUMN_SORTORDER, &sort_order,
+			-1);
+
+		if (account) {
+			toadd = g_strdup (account->uid);
+			g_object_unref (account);
+		} else if (g_strcmp0 (name, _("On This Computer")) == 0) {
+			toadd = g_strdup ("local");
+		} else if (g_strcmp0 (name, _("Search Folders")) == 0) {
+			toadd = g_strdup ("vfolder");
+		} else {
+			g_warn_if_reached ();
+		}
+
+		if (toadd) {
+			g_hash_table_insert (hash, toadd, GUINT_TO_POINTER (sort_order));
+			res = g_slist_prepend (res, toadd);
+		}
+
+		g_free (name);
+	} while (gtk_tree_model_iter_next (model, &iter));
+
+	res = g_slist_sort_with_data (res, eval_order_by_sort_hash_cb, hash);
+
+	g_hash_table_destroy (hash);
+
+	return res;
+}
+
+/**
+ * e_account_tree_view_sort_changed:
+ * @tree_view: an #EAccountTreeView
+ *
+ * Notifies @tree_view about sort order change, thus it resorts
+ * items in a view.
+ *
+ * Since: 3.4
+ **/
+void
+e_account_tree_view_sort_changed (EAccountTreeView *tree_view)
+{
+	GtkTreeModel *model;
+
+	g_return_if_fail (tree_view != NULL);
+	g_return_if_fail (E_IS_ACCOUNT_TREE_VIEW (tree_view));
+
+	model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view));
+	if (!model)
+		return;
+
+	/* this invokes also sort on a GtkListStore */
+	gtk_tree_sortable_set_default_sort_func (
+		GTK_TREE_SORTABLE (model),
+		account_tree_view_sort, tree_view, NULL);
+}
+
+static void
+account_tree_view_swap_sort_order (EAccountTreeView *tree_view, gint direction)
+{
+	GtkTreeSelection *selection;
+	GtkTreeModel *model;
+	GtkTreeIter iter1, iter2;
+	guint sortorder1, sortorder2;
+
+	g_return_if_fail (tree_view != NULL);
+	g_return_if_fail (E_IS_ACCOUNT_TREE_VIEW (tree_view));
+	g_return_if_fail (direction != 0);
+
+	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
+	if (!gtk_tree_selection_get_selected (selection, &model, &iter1))
+		return;
+
+	iter2 = iter1;
+	if ((direction < 0 && !gtk_tree_model_iter_previous (model, &iter2)) ||
+	    (direction > 0 && !gtk_tree_model_iter_next (model, &iter2)))
+		return;
+
+	gtk_tree_model_get (model, &iter1, COLUMN_SORTORDER, &sortorder1, -1);
+	gtk_tree_model_get (model, &iter2, COLUMN_SORTORDER, &sortorder2, -1);
+
+	gtk_list_store_set (GTK_LIST_STORE (model), &iter1, COLUMN_SORTORDER, sortorder2, -1);
+	gtk_list_store_set (GTK_LIST_STORE (model), &iter2, COLUMN_SORTORDER, sortorder1, -1);
+
+	e_account_tree_view_sort_changed (tree_view);
+
+	g_signal_emit (tree_view, signals[SORT_ORDER_CHANGED], 0);
+}
+
+/**
+ * e_account_tree_view_move_up:
+ * @tree_view: an #EAccountTreeView
+ * 
+ * Moves currently selected node up within user's sort order.
+ *
+ * Since: 3.4
+ **/
+void
+e_account_tree_view_move_up (EAccountTreeView *tree_view)
+{
+	g_return_if_fail (tree_view != NULL);
+	g_return_if_fail (E_IS_ACCOUNT_TREE_VIEW (tree_view));
+
+	account_tree_view_swap_sort_order (tree_view, -1);
+}
+
+/**
+ * e_account_tree_view_move_down:
+ * @tree_view: an #EAccountTreeView
+ * 
+ * Moves currently selected node down within user's sort order.
+ *
+ * Since: 3.4
+ **/
+void
+e_account_tree_view_move_down (EAccountTreeView *tree_view)
+{
+	g_return_if_fail (tree_view != NULL);
+	g_return_if_fail (E_IS_ACCOUNT_TREE_VIEW (tree_view));
+
+	account_tree_view_swap_sort_order (tree_view, +1);
+}
+
+void
+e_account_tree_view_set_sort_alpha (EAccountTreeView *tree_view, gboolean sort_alpha)
+{
+	g_return_if_fail (tree_view != NULL);
+	g_return_if_fail (E_IS_ACCOUNT_TREE_VIEW (tree_view));
+	g_return_if_fail (tree_view->priv != NULL);
+
+	if ((tree_view->priv->sort_alpha ? 1 : 0) == (sort_alpha ? 1 : 0))
+		return;
+
+	tree_view->priv->sort_alpha = sort_alpha;
+
+	g_object_notify (G_OBJECT (tree_view), "sort-alpha");
+	e_account_tree_view_sort_changed (tree_view);
+}
+
+gboolean
+e_account_tree_view_get_sort_alpha (EAccountTreeView *tree_view)
+{
+	g_return_val_if_fail (tree_view != NULL, FALSE);
+	g_return_val_if_fail (E_IS_ACCOUNT_TREE_VIEW (tree_view), FALSE);
+	g_return_val_if_fail (tree_view->priv != NULL, FALSE);
+
+	return tree_view->priv->sort_alpha;
+}
+
+void
+e_account_tree_view_set_express_mode (EAccountTreeView *tree_view, gboolean express_mode)
+{
+	g_return_if_fail (tree_view != NULL);
+	g_return_if_fail (E_IS_ACCOUNT_TREE_VIEW (tree_view));
+	g_return_if_fail (tree_view->priv != NULL);
+
+	if ((tree_view->priv->express_mode ? 1 : 0) == (express_mode ? 1 : 0))
+		return;
+
+	tree_view->priv->express_mode = express_mode;
+
+	g_object_notify (G_OBJECT (tree_view), "express-mode");
+	e_account_tree_view_sort_changed (tree_view);
+}
+
+gboolean
+e_account_tree_view_get_express_mode (EAccountTreeView *tree_view)
+{
+	g_return_val_if_fail (tree_view != NULL, FALSE);
+	g_return_val_if_fail (E_IS_ACCOUNT_TREE_VIEW (tree_view), FALSE);
+	g_return_val_if_fail (tree_view->priv != NULL, FALSE);
+
+	return tree_view->priv->express_mode;
+}
+
+static void
+update_special_enable_state (EAccountTreeView *tree_view, const gchar *display_name, gboolean enabled)
+{
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	GtkListStore *list_store;
+
+	g_return_if_fail (tree_view != NULL);
+	g_return_if_fail (display_name != NULL);
+
+	model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view));
+	if (!model)
+		return;
+
+	list_store = GTK_LIST_STORE (model);
+	g_return_if_fail (list_store != NULL);
+
+	if (!gtk_tree_model_get_iter_first (model, &iter))
+		return;
+
+	do {
+		gchar *name = NULL;
+		EAccount *account = NULL;
+
+		gtk_tree_model_get (model, &iter,
+			COLUMN_ACCOUNT, &account,
+			COLUMN_NAME, &name,
+			-1);
+
+		if (account) {
+			g_object_unref (account);
+		} else if (g_strcmp0 (name, display_name) == 0) {
+			gtk_list_store_set (list_store, &iter, COLUMN_ENABLED, enabled, -1);
+			g_free (name);
+			break;
+		}
+
+		g_free (name);
+	} while (gtk_tree_model_iter_next (model, &iter));
+}
+
+void
+e_account_tree_view_set_enable_local_folders (EAccountTreeView *tree_view, gboolean enabled)
+{
+	g_return_if_fail (tree_view != NULL);
+	g_return_if_fail (E_IS_ACCOUNT_TREE_VIEW (tree_view));
+	g_return_if_fail (tree_view->priv != NULL);
+
+	if ((tree_view->priv->enable_local_folders ? 1 : 0) == (enabled ? 1 : 0))
+		return;
+
+	tree_view->priv->enable_local_folders = enabled;
+
+	g_object_notify (G_OBJECT (tree_view), "enable-local-folders");
+
+	update_special_enable_state (tree_view, _("On This Computer"), enabled);
+}
+
+gboolean
+e_account_tree_view_get_enable_local_folders (EAccountTreeView *tree_view)
+{
+	g_return_val_if_fail (tree_view != NULL, FALSE);
+	g_return_val_if_fail (E_IS_ACCOUNT_TREE_VIEW (tree_view), FALSE);
+	g_return_val_if_fail (tree_view->priv != NULL, FALSE);
+
+	return tree_view->priv->enable_local_folders;
+}
+
+void
+e_account_tree_view_set_enable_search_folders (EAccountTreeView *tree_view, gboolean enabled)
+{
+	g_return_if_fail (tree_view != NULL);
+	g_return_if_fail (E_IS_ACCOUNT_TREE_VIEW (tree_view));
+	g_return_if_fail (tree_view->priv != NULL);
+
+	if ((tree_view->priv->enable_search_folders ? 1 : 0) == (enabled ? 1 : 0))
+		return;
+
+	tree_view->priv->enable_search_folders = enabled;
+
+	g_object_notify (G_OBJECT (tree_view), "enable-search-folders");
+
+	update_special_enable_state (tree_view, _("Search Folders"), enabled);
+}
+
+gboolean
+e_account_tree_view_get_enable_search_folders (EAccountTreeView *tree_view)
+{
+	g_return_val_if_fail (tree_view != NULL, FALSE);
+	g_return_val_if_fail (E_IS_ACCOUNT_TREE_VIEW (tree_view), FALSE);
+	g_return_val_if_fail (tree_view->priv != NULL, FALSE);
+
+	return tree_view->priv->enable_search_folders;
+}
diff --git a/widgets/misc/e-account-tree-view.h b/widgets/misc/e-account-tree-view.h
index e9b2f7f..d62d040 100644
--- a/widgets/misc/e-account-tree-view.h
+++ b/widgets/misc/e-account-tree-view.h
@@ -47,6 +47,14 @@
 
 G_BEGIN_DECLS
 
+typedef enum
+{
+	E_ACCOUNT_TREE_VIEW_SELECTED_NONE,
+	E_ACCOUNT_TREE_VIEW_SELECTED_ACCOUNT,
+	E_ACCOUNT_TREE_VIEW_SELECTED_LOCAL,
+	E_ACCOUNT_TREE_VIEW_SELECTED_VFOLDER
+} EAccountTreeViewSelectedType;
+
 typedef struct _EAccountTreeView EAccountTreeView;
 typedef struct _EAccountTreeViewClass EAccountTreeViewClass;
 typedef struct _EAccountTreeViewPrivate EAccountTreeViewPrivate;
@@ -62,6 +70,7 @@ struct _EAccountTreeViewClass {
 	void		(*enable_account)	(EAccountTreeView *tree_view);
 	void		(*disable_account)	(EAccountTreeView *tree_view);
 	void		(*refreshed)		(EAccountTreeView *tree_view);
+	void		(*sort_order_changed)	(EAccountTreeView *tree_view);
 };
 
 GType		e_account_tree_view_get_type	(void);
@@ -80,6 +89,43 @@ EAccount *	e_account_tree_view_get_selected
 gboolean	e_account_tree_view_set_selected
 						(EAccountTreeView *tree_view,
 						 EAccount *account);
+EAccountTreeViewSelectedType
+		e_account_tree_view_get_selected_type
+						(EAccountTreeView *tree_view);
+void		e_account_tree_view_set_selected_type
+						(EAccountTreeView *tree_view,
+						 EAccountTreeViewSelectedType select);
+
+void		e_account_tree_view_set_sort_order
+						(EAccountTreeView *tree_view,
+						 const GSList *account_uids);
+
+GSList *	e_account_tree_view_get_sort_order
+						(EAccountTreeView *tree_view);
+
+void		e_account_tree_view_sort_changed
+						(EAccountTreeView *tree_view);
+void		e_account_tree_view_move_up	(EAccountTreeView *tree_view);
+void		e_account_tree_view_move_down	(EAccountTreeView *tree_view);
+
+void		e_account_tree_view_set_sort_alpha
+						(EAccountTreeView *tree_view,
+						 gboolean sort_alpha);
+gboolean	e_account_tree_view_get_sort_alpha
+						(EAccountTreeView *tree_view);
+void		e_account_tree_view_set_express_mode
+						(EAccountTreeView *tree_view,
+						 gboolean express_mode);
+gboolean	e_account_tree_view_get_express_mode
+						(EAccountTreeView *tree_view);
+void		e_account_tree_view_set_enable_local_folders
+						(EAccountTreeView *tree_view, gboolean enabled);
+gboolean	e_account_tree_view_get_enable_local_folders
+						(EAccountTreeView *tree_view);
+void		e_account_tree_view_set_enable_search_folders
+						(EAccountTreeView *tree_view, gboolean enabled);
+gboolean	e_account_tree_view_get_enable_search_folders
+						(EAccountTreeView *tree_view);
 
 G_END_DECLS
 



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