aboutsummaryrefslogtreecommitdiffstats
path: root/mail
diff options
context:
space:
mode:
Diffstat (limited to 'mail')
-rw-r--r--mail/Makefile.am10
-rw-r--r--mail/e-mail-account-manager.c565
-rw-r--r--mail/e-mail-account-manager.h78
-rw-r--r--mail/e-mail-account-store.c1439
-rw-r--r--mail/e-mail-account-store.h144
-rw-r--r--mail/e-mail-account-tree-view.c283
-rw-r--r--mail/e-mail-account-tree-view.h75
-rw-r--r--mail/e-mail-backend.c187
-rw-r--r--mail/e-mail-backend.h7
-rw-r--r--mail/e-mail-local.c154
-rw-r--r--mail/e-mail-local.h39
-rw-r--r--mail/e-mail-migrate.c33
-rw-r--r--mail/e-mail-reader-utils.c12
-rw-r--r--mail/e-mail-session-utils.c5
-rw-r--r--mail/e-mail-session.c563
-rw-r--r--mail/e-mail-session.h20
-rw-r--r--mail/e-mail-sidebar.c11
-rw-r--r--mail/e-mail-store.c500
-rw-r--r--mail/e-mail-store.h47
-rw-r--r--mail/e-mail.h2
-rw-r--r--mail/em-account-editor.c131
-rw-r--r--mail/em-composer-utils.c99
-rw-r--r--mail/em-composer-utils.h3
-rw-r--r--mail/em-folder-properties.c23
-rw-r--r--mail/em-folder-selection-button.c5
-rw-r--r--mail/em-folder-tree-model.c442
-rw-r--r--mail/em-folder-tree-model.h8
-rw-r--r--mail/em-folder-tree.c54
-rw-r--r--mail/em-folder-utils.c23
-rw-r--r--mail/em-utils.c206
-rw-r--r--mail/em-utils.h4
-rw-r--r--mail/em-vfolder-rule.c1
-rw-r--r--mail/importers/evolution-mbox-importer.c10
-rw-r--r--mail/importers/mail-importer.c4
-rw-r--r--mail/mail-config.c1
-rw-r--r--mail/mail-folder-cache.c426
-rw-r--r--mail/mail-folder-cache.h23
-rw-r--r--mail/mail-ops.c49
-rw-r--r--mail/mail-send-recv.c47
-rw-r--r--mail/mail-vfolder.c40
40 files changed, 4042 insertions, 1731 deletions
diff --git a/mail/Makefile.am b/mail/Makefile.am
index 0859c55c06..8310cff129 100644
--- a/mail/Makefile.am
+++ b/mail/Makefile.am
@@ -46,6 +46,9 @@ libevolution_mail_la_CPPFLAGS = \
mailinclude_HEADERS = \
e-mail.h \
+ e-mail-account-manager.h \
+ e-mail-account-store.h \
+ e-mail-account-tree-view.h \
e-mail-attachment-bar.h \
e-mail-backend.h \
e-mail-browser.h \
@@ -61,7 +64,6 @@ mailinclude_HEADERS = \
e-mail-label-list-store.h \
e-mail-label-manager.h \
e-mail-label-tree-view.h \
- e-mail-local.h \
e-mail-message-pane.h \
e-mail-migrate.h \
e-mail-notebook-view.h \
@@ -72,7 +74,6 @@ mailinclude_HEADERS = \
e-mail-session.h \
e-mail-sidebar.h \
e-mail-store-utils.h \
- e-mail-store.h \
e-mail-tag-editor.h \
e-mail-view.h \
em-account-editor.h \
@@ -121,6 +122,9 @@ mailinclude_HEADERS += \
endif
libevolution_mail_la_SOURCES = \
+ e-mail-account-manager.c \
+ e-mail-account-store.c \
+ e-mail-account-tree-view.c \
e-mail-attachment-bar.c \
e-mail-backend.c \
e-mail-browser.c \
@@ -135,7 +139,6 @@ libevolution_mail_la_SOURCES = \
e-mail-label-list-store.c \
e-mail-label-manager.c \
e-mail-label-tree-view.c \
- e-mail-local.c \
e-mail-message-pane.c \
e-mail-migrate.c \
e-mail-notebook-view.c \
@@ -146,7 +149,6 @@ libevolution_mail_la_SOURCES = \
e-mail-session.c \
e-mail-sidebar.c \
e-mail-store-utils.c \
- e-mail-store.c \
e-mail-tag-editor.c \
e-mail-view.c \
em-account-editor.c \
diff --git a/mail/e-mail-account-manager.c b/mail/e-mail-account-manager.c
new file mode 100644
index 0000000000..97a4fe3fe0
--- /dev/null
+++ b/mail/e-mail-account-manager.c
@@ -0,0 +1,565 @@
+/*
+ * e-mail-account-manager.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "e-mail-account-manager.h"
+
+#include <config.h>
+#include <glib/gi18n-lib.h>
+#include <gdk/gdkkeysyms.h>
+
+#include <mail/e-mail-account-tree-view.h>
+
+#define E_MAIL_ACCOUNT_MANAGER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAIL_ACCOUNT_MANAGER, EMailAccountManagerPrivate))
+
+#define DEFAULT_ORDER_RESPONSE GTK_RESPONSE_APPLY
+
+struct _EMailAccountManagerPrivate {
+ EMailAccountStore *store;
+ gulong row_changed_handler_id;
+
+ GtkWidget *tree_view; /* not referenced */
+ GtkWidget *add_button; /* not referenced */
+ GtkWidget *edit_button; /* not referenced */
+ GtkWidget *delete_button; /* not referenced */
+ GtkWidget *default_button; /* not referenced */
+};
+
+enum {
+ PROP_0,
+ PROP_STORE
+};
+
+enum {
+ ADD_ACCOUNT,
+ EDIT_ACCOUNT,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
+G_DEFINE_TYPE (
+ EMailAccountManager,
+ e_mail_account_manager,
+ GTK_TYPE_TABLE)
+
+static void
+mail_account_manager_add_cb (EMailAccountManager *manager)
+{
+ e_mail_account_manager_add_account (manager);
+}
+
+static void
+mail_account_manager_edit_cb (EMailAccountManager *manager)
+{
+ EMailAccountTreeView *tree_view;
+ EAccount *account;
+ CamelService *service;
+ const gchar *uid;
+
+ tree_view = E_MAIL_ACCOUNT_TREE_VIEW (manager->priv->tree_view);
+ service = e_mail_account_tree_view_get_selected_service (tree_view);
+
+ uid = camel_service_get_uid (service);
+ account = e_get_account_by_uid (uid);
+ g_return_if_fail (account != NULL);
+
+ e_mail_account_manager_edit_account (manager, account);
+}
+
+static void
+mail_account_manager_remove_cb (EMailAccountManager *manager)
+{
+ EMailAccountTreeView *tree_view;
+ EMailAccountStore *store;
+ CamelService *service;
+ gpointer parent;
+
+ tree_view = E_MAIL_ACCOUNT_TREE_VIEW (manager->priv->tree_view);
+ service = e_mail_account_tree_view_get_selected_service (tree_view);
+
+ parent = gtk_widget_get_toplevel (GTK_WIDGET (manager));
+ parent = gtk_widget_is_toplevel (parent) ? parent : NULL;
+
+ store = e_mail_account_manager_get_store (manager);
+ e_mail_account_store_remove_service (store, parent, service);
+}
+
+static void
+mail_account_manager_enable_cb (EMailAccountManager *manager)
+{
+ EMailAccountTreeView *tree_view;
+ EMailAccountStore *store;
+ CamelService *service;
+ gpointer parent;
+
+ tree_view = E_MAIL_ACCOUNT_TREE_VIEW (manager->priv->tree_view);
+ service = e_mail_account_tree_view_get_selected_service (tree_view);
+
+ parent = gtk_widget_get_toplevel (GTK_WIDGET (manager));
+ parent = gtk_widget_is_toplevel (parent) ? parent : NULL;
+
+ store = e_mail_account_manager_get_store (manager);
+ e_mail_account_store_enable_service (store, parent, service);
+}
+
+static void
+mail_account_manager_disable_cb (EMailAccountManager *manager)
+{
+ EMailAccountTreeView *tree_view;
+ EMailAccountStore *store;
+ CamelService *service;
+ gpointer parent;
+
+ tree_view = E_MAIL_ACCOUNT_TREE_VIEW (manager->priv->tree_view);
+ service = e_mail_account_tree_view_get_selected_service (tree_view);
+
+ parent = gtk_widget_get_toplevel (GTK_WIDGET (manager));
+ parent = gtk_widget_is_toplevel (parent) ? parent : NULL;
+
+ store = e_mail_account_manager_get_store (manager);
+ e_mail_account_store_disable_service (store, parent, service);
+}
+
+static void
+mail_account_manager_default_cb (EMailAccountManager *manager)
+{
+ EMailAccountTreeView *tree_view;
+ EMailAccountStore *store;
+ CamelService *service;
+
+ tree_view = E_MAIL_ACCOUNT_TREE_VIEW (manager->priv->tree_view);
+ service = e_mail_account_tree_view_get_selected_service (tree_view);
+
+ store = e_mail_account_manager_get_store (manager);
+ e_mail_account_store_set_default_service (store, service);
+}
+
+static void
+mail_account_manager_info_bar_response_cb (EMailAccountManager *manager,
+ gint response)
+{
+ EMailAccountStore *store;
+
+ store = e_mail_account_manager_get_store (manager);
+
+ if (response == DEFAULT_ORDER_RESPONSE)
+ e_mail_account_store_reorder_services (store, NULL);
+}
+
+static gboolean
+mail_account_manager_key_press_event_cb (EMailAccountManager *manager,
+ GdkEventKey *event)
+{
+ if (event->keyval == GDK_KEY_Delete) {
+ mail_account_manager_remove_cb (manager);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+mail_account_manager_row_changed_cb (GtkTreeModel *tree_model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ EMailAccountManager *manager)
+{
+ GtkTreeView *tree_view;
+ GtkTreeSelection *selection;
+
+ tree_view = GTK_TREE_VIEW (manager->priv->tree_view);
+ selection = gtk_tree_view_get_selection (tree_view);
+
+ /* Update buttons for the selected row (which is not
+ * necessarily the row that changed, but do it anyway). */
+ g_signal_emit_by_name (selection, "changed");
+}
+
+static void
+mail_account_manager_selection_changed_cb (EMailAccountManager *manager,
+ GtkTreeSelection *selection)
+{
+ GtkTreeModel *tree_model;
+ GtkTreeIter iter;
+ EMailAccountStore *store;
+ CamelService *default_service;
+ CamelService *service;
+ GtkWidget *add_button;
+ GtkWidget *edit_button;
+ GtkWidget *delete_button;
+ GtkWidget *default_button;
+ gboolean builtin;
+ gboolean sensitive;
+ gboolean not_default;
+
+ add_button = manager->priv->add_button;
+ edit_button = manager->priv->edit_button;
+ delete_button = manager->priv->delete_button;
+ default_button = manager->priv->default_button;
+
+ if (gtk_tree_selection_get_selected (selection, &tree_model, &iter)) {
+ gtk_tree_model_get (
+ tree_model, &iter,
+ E_MAIL_ACCOUNT_STORE_COLUMN_SERVICE, &service,
+ E_MAIL_ACCOUNT_STORE_COLUMN_BUILTIN, &builtin,
+ -1);
+ } else {
+ service = NULL;
+ builtin = FALSE;
+ }
+
+ store = e_mail_account_manager_get_store (manager);
+ default_service = e_mail_account_store_get_default_service (store);
+ not_default = (service != default_service);
+
+ if (service == NULL)
+ gtk_widget_grab_focus (add_button);
+
+ sensitive = (service != NULL && !builtin);
+ gtk_widget_set_sensitive (edit_button, sensitive);
+
+ sensitive = (service != NULL && !builtin);
+ gtk_widget_set_sensitive (delete_button, sensitive);
+
+ sensitive = (service != NULL && !builtin && not_default);
+ gtk_widget_set_sensitive (default_button, sensitive);
+}
+
+static void
+mail_account_manager_set_store (EMailAccountManager *manager,
+ EMailAccountStore *store)
+{
+ g_return_if_fail (E_IS_MAIL_ACCOUNT_STORE (store));
+ g_return_if_fail (manager->priv->store == NULL);
+
+ manager->priv->store = g_object_ref (store);
+}
+
+static void
+mail_account_manager_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_STORE:
+ mail_account_manager_set_store (
+ E_MAIL_ACCOUNT_MANAGER (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_account_manager_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_STORE:
+ g_value_set_object (
+ value,
+ e_mail_account_manager_get_store (
+ E_MAIL_ACCOUNT_MANAGER (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_account_manager_dispose (GObject *object)
+{
+ EMailAccountManagerPrivate *priv;
+
+ priv = E_MAIL_ACCOUNT_MANAGER_GET_PRIVATE (object);
+
+ if (priv->store != NULL) {
+ g_signal_handler_disconnect (
+ priv->store, priv->row_changed_handler_id);
+ g_object_unref (priv->store);
+ priv->store = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (e_mail_account_manager_parent_class)->dispose (object);
+}
+
+static void
+mail_account_manager_constructed (GObject *object)
+{
+ EMailAccountManager *manager;
+ EMailAccountStore *store;
+ GtkTreeSelection *selection;
+ GtkWidget *container;
+ GtkWidget *widget;
+ gulong handler_id;
+
+ manager = E_MAIL_ACCOUNT_MANAGER (object);
+ store = e_mail_account_manager_get_store (manager);
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (e_mail_account_manager_parent_class)->
+ constructed (object);
+
+ g_object_bind_property (
+ store, "busy",
+ manager, "sensitive",
+ G_BINDING_SYNC_CREATE |
+ G_BINDING_INVERT_BOOLEAN);
+
+ handler_id = g_signal_connect (
+ store, "row-changed",
+ G_CALLBACK (mail_account_manager_row_changed_cb),
+ manager);
+
+ /* We disconnect the handler in dispose(). */
+ manager->priv->row_changed_handler_id = handler_id;
+
+ gtk_table_resize (GTK_TABLE (manager), 2, 2);
+ gtk_table_set_col_spacings (GTK_TABLE (manager), 6);
+ gtk_table_set_row_spacings (GTK_TABLE (manager), 0);
+
+ container = GTK_WIDGET (manager);
+
+ widget = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (
+ GTK_SCROLLED_WINDOW (widget),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (
+ GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN);
+ gtk_table_attach (
+ GTK_TABLE (container), widget, 0, 1, 0, 1,
+ GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ widget = e_mail_account_tree_view_new (store);
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ manager->priv->tree_view = widget; /* not referenced */
+ gtk_widget_show (widget);
+
+ g_signal_connect_swapped (
+ widget, "enable",
+ G_CALLBACK (mail_account_manager_enable_cb), manager);
+
+ g_signal_connect_swapped (
+ widget, "disable",
+ G_CALLBACK (mail_account_manager_disable_cb), manager);
+
+ g_signal_connect_swapped (
+ widget, "key-press-event",
+ G_CALLBACK (mail_account_manager_key_press_event_cb),
+ manager);
+
+ g_signal_connect_swapped (
+ widget, "row-activated",
+ G_CALLBACK (mail_account_manager_edit_cb), manager);
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
+
+ g_signal_connect_swapped (
+ selection, "changed",
+ G_CALLBACK (mail_account_manager_selection_changed_cb),
+ manager);
+
+ container = GTK_WIDGET (manager);
+
+ widget = gtk_frame_new (NULL);
+ gtk_frame_set_shadow_type (
+ GTK_FRAME (widget), GTK_SHADOW_IN);
+ gtk_table_attach (
+ GTK_TABLE (container), widget,
+ 0, 1, 1, 2, GTK_FILL, 0, 0, 0);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ widget = gtk_info_bar_new ();
+ gtk_info_bar_set_message_type (
+ GTK_INFO_BAR (widget), GTK_MESSAGE_INFO);
+ gtk_info_bar_add_button (
+ GTK_INFO_BAR (widget),
+ _("_Restore Default"),
+ DEFAULT_ORDER_RESPONSE);
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ gtk_widget_show (widget);
+
+ g_signal_connect_swapped (
+ widget, "response",
+ G_CALLBACK (mail_account_manager_info_bar_response_cb),
+ manager);
+
+ container = gtk_info_bar_get_content_area (GTK_INFO_BAR (widget));
+
+ widget = gtk_label_new (
+ _("You can drag and drop account names to reorder them."));
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ gtk_widget_show (widget);
+
+ container = GTK_WIDGET (manager);
+
+ widget = gtk_vbutton_box_new ();
+ gtk_button_box_set_layout (
+ GTK_BUTTON_BOX (widget), GTK_BUTTONBOX_START);
+ gtk_box_set_spacing (GTK_BOX (widget), 6);
+ gtk_table_attach (
+ GTK_TABLE (container), widget,
+ 1, 2, 0, 2, 0, GTK_FILL, 0, 0);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ widget = gtk_button_new_from_stock (GTK_STOCK_ADD);
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ manager->priv->add_button = widget; /* not referenced */
+ gtk_widget_show (widget);
+
+ g_signal_connect_swapped (
+ widget, "clicked",
+ G_CALLBACK (mail_account_manager_add_cb), manager);
+
+ widget = gtk_button_new_from_stock (GTK_STOCK_EDIT);
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ manager->priv->edit_button = widget; /* not referenced */
+ gtk_widget_show (widget);
+
+ g_signal_connect_swapped (
+ widget, "clicked",
+ G_CALLBACK (mail_account_manager_edit_cb), manager);
+
+ widget = gtk_button_new_from_stock (GTK_STOCK_DELETE);
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ manager->priv->delete_button = widget; /* not referenced */
+ gtk_widget_show (widget);
+
+ g_signal_connect_swapped (
+ widget, "clicked",
+ G_CALLBACK (mail_account_manager_remove_cb), manager);
+
+ widget = gtk_button_new_with_mnemonic (_("De_fault"));
+ gtk_button_set_image (
+ GTK_BUTTON (widget),
+ gtk_image_new_from_icon_name (
+ "emblem-default", GTK_ICON_SIZE_BUTTON));
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ manager->priv->default_button = widget; /* not referenced */
+ gtk_widget_show (widget);
+
+ g_signal_connect_swapped (
+ widget, "clicked",
+ G_CALLBACK (mail_account_manager_default_cb), manager);
+
+ /* Initialize button states. */
+ g_signal_emit_by_name (selection, "changed");
+}
+
+static void
+e_mail_account_manager_class_init (EMailAccountManagerClass *class)
+{
+ GObjectClass *object_class;
+
+ g_type_class_add_private (class, sizeof (EMailAccountManagerPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = mail_account_manager_set_property;
+ object_class->get_property = mail_account_manager_get_property;
+ object_class->dispose = mail_account_manager_dispose;
+ object_class->constructed = mail_account_manager_constructed;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_STORE,
+ g_param_spec_object (
+ "store",
+ "Store",
+ NULL,
+ E_TYPE_MAIL_ACCOUNT_STORE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
+ signals[ADD_ACCOUNT] = g_signal_new (
+ "add-account",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMailAccountManagerClass, add_account),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[EDIT_ACCOUNT] = g_signal_new (
+ "edit-account",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMailAccountManagerClass, edit_account),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ E_TYPE_ACCOUNT);
+}
+
+static void
+e_mail_account_manager_init (EMailAccountManager *manager)
+{
+ manager->priv = E_MAIL_ACCOUNT_MANAGER_GET_PRIVATE (manager);
+}
+
+GtkWidget *
+e_mail_account_manager_new (EMailAccountStore *store)
+{
+ g_return_val_if_fail (E_IS_MAIL_ACCOUNT_STORE (store), NULL);
+
+ return g_object_new (
+ E_TYPE_MAIL_ACCOUNT_MANAGER,
+ "store", store, NULL);
+}
+
+EMailAccountStore *
+e_mail_account_manager_get_store (EMailAccountManager *manager)
+{
+ g_return_val_if_fail (E_IS_MAIL_ACCOUNT_MANAGER (manager), NULL);
+
+ return manager->priv->store;
+}
+
+void
+e_mail_account_manager_add_account (EMailAccountManager *manager)
+{
+ g_return_if_fail (E_IS_MAIL_ACCOUNT_MANAGER (manager));
+
+ g_signal_emit (manager, signals[ADD_ACCOUNT], 0);
+}
+
+void
+e_mail_account_manager_edit_account (EMailAccountManager *manager,
+ EAccount *account)
+{
+ g_return_if_fail (E_IS_MAIL_ACCOUNT_MANAGER (manager));
+ g_return_if_fail (E_IS_ACCOUNT (account));
+
+ g_signal_emit (manager, signals[EDIT_ACCOUNT], 0, account);
+}
+
diff --git a/mail/e-mail-account-manager.h b/mail/e-mail-account-manager.h
new file mode 100644
index 0000000000..23f7890500
--- /dev/null
+++ b/mail/e-mail-account-manager.h
@@ -0,0 +1,78 @@
+/*
+ * e-mail-account-manager.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef E_MAIL_ACCOUNT_MANAGER_H
+#define E_MAIL_ACCOUNT_MANAGER_H
+
+#include <gtk/gtk.h>
+#include <e-util/e-account-utils.h>
+#include <mail/e-mail-account-store.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_ACCOUNT_MANAGER \
+ (e_mail_account_manager_get_type ())
+#define E_MAIL_ACCOUNT_MANAGER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_ACCOUNT_MANAGER, EMailAccountManager))
+#define E_MAIL_ACCOUNT_MANAGER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_ACCOUNT_MANAGER, EMailAccountManagerClass))
+#define E_IS_MAIL_ACCOUNT_MANAGER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_ACCOUNT_MANAGER))
+#define E_IS_MAIL_ACCOUNT_MANAGER_CLASS(cls) \
+ (G_TYPE_CHECK_INSTANCE_CLASS \
+ ((cls), E_TYPE_MAIL_ACCOUNT_MANAGER))
+#define E_MAIL_ACCOUNT_MANAGER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_ACCOUNT_MANAGER, EMailAccountManagerClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailAccountManager EMailAccountManager;
+typedef struct _EMailAccountManagerClass EMailAccountManagerClass;
+typedef struct _EMailAccountManagerPrivate EMailAccountManagerPrivate;
+
+struct _EMailAccountManager {
+ GtkTable parent;
+ EMailAccountManagerPrivate *priv;
+};
+
+struct _EMailAccountManagerClass {
+ GtkTableClass parent_class;
+
+ /* Signals */
+ void (*add_account) (EMailAccountManager *manager);
+ void (*edit_account) (EMailAccountManager *manager,
+ EAccount *account);
+};
+
+GType e_mail_account_manager_get_type (void) G_GNUC_CONST;
+GtkWidget * e_mail_account_manager_new (EMailAccountStore *store);
+EMailAccountStore *
+ e_mail_account_manager_get_store
+ (EMailAccountManager *manager);
+void e_mail_account_manager_add_account
+ (EMailAccountManager *manager);
+void e_mail_account_manager_edit_account
+ (EMailAccountManager *manager,
+ EAccount *account);
+
+G_END_DECLS
+
+#endif /* E_MAIL_ACCOUNT_MANAGER_H */
diff --git a/mail/e-mail-account-store.c b/mail/e-mail-account-store.c
new file mode 100644
index 0000000000..ccfbe3b879
--- /dev/null
+++ b/mail/e-mail-account-store.c
@@ -0,0 +1,1439 @@
+/*
+ * e-mail-account-store.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "e-mail-account-store.h"
+
+#include <config.h>
+#include <glib/gstdio.h>
+#include <glib/gi18n-lib.h>
+
+#include <libebackend/e-extensible.h>
+
+#include <e-util/e-marshal.h>
+#include <e-util/e-account-utils.h>
+#include <e-util/e-alert-dialog.h>
+#include <mail/mail-ops.h>
+#include <mail/mail-vfolder.h>
+
+#define E_MAIL_ACCOUNT_STORE_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAIL_ACCOUNT_STORE, EMailAccountStorePrivate))
+
+typedef struct _IndexItem IndexItem;
+
+struct _EMailAccountStorePrivate {
+ CamelService *default_service;
+ GHashTable *service_index;
+ gchar *sort_order_filename;
+ gboolean express_mode;
+ gpointer session; /* weak pointer */
+ guint busy_count;
+};
+
+struct _IndexItem {
+ CamelService *service;
+ GtkTreeRowReference *reference;
+ gulong notify_handler_id;
+};
+
+enum {
+ PROP_0,
+ PROP_BUSY,
+ PROP_DEFAULT_SERVICE,
+ PROP_EXPRESS_MODE,
+ PROP_SESSION
+};
+
+enum {
+ SERVICE_ADDED,
+ SERVICE_REMOVED,
+ SERVICE_ENABLED,
+ SERVICE_DISABLED,
+ SERVICES_REORDERED,
+ REMOVE_REQUESTED,
+ ENABLE_REQUESTED,
+ DISABLE_REQUESTED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
+/* Forward Declarations */
+static void e_mail_account_store_interface_init
+ (GtkTreeModelIface *interface);
+
+G_DEFINE_TYPE_WITH_CODE (
+ EMailAccountStore,
+ e_mail_account_store,
+ GTK_TYPE_LIST_STORE,
+ G_IMPLEMENT_INTERFACE (
+ GTK_TYPE_TREE_MODEL,
+ e_mail_account_store_interface_init)
+ G_IMPLEMENT_INTERFACE (
+ E_TYPE_EXTENSIBLE, NULL))
+
+static void
+index_item_free (IndexItem *item)
+{
+ g_signal_handler_disconnect (
+ item->service, item->notify_handler_id);
+
+ g_object_unref (item->service);
+ gtk_tree_row_reference_free (item->reference);
+
+ g_slice_free (IndexItem, item);
+}
+
+static void
+mail_account_store_save_default (EMailAccountStore *store)
+{
+ EAccountList *account_list;
+ EAccount *account;
+ CamelService *service;
+ const gchar *uid;
+
+ service = e_mail_account_store_get_default_service (store);
+
+ account_list = e_get_account_list ();
+ uid = camel_service_get_uid (service);
+ account = e_get_account_by_uid (uid);
+ g_return_if_fail (account != NULL);
+
+ e_account_list_set_default (account_list, account);
+}
+
+static gboolean
+mail_account_store_get_iter (EMailAccountStore *store,
+ CamelService *service,
+ GtkTreeIter *iter)
+{
+ IndexItem *item;
+ GtkTreeModel *model;
+ GtkTreePath *path;
+ gboolean iter_set;
+
+ g_return_val_if_fail (service != NULL, FALSE);
+
+ item = g_hash_table_lookup (store->priv->service_index, service);
+
+ if (item == NULL)
+ return FALSE;
+
+ if (!gtk_tree_row_reference_valid (item->reference))
+ return FALSE;
+
+ model = gtk_tree_row_reference_get_model (item->reference);
+ path = gtk_tree_row_reference_get_path (item->reference);
+ iter_set = gtk_tree_model_get_iter (model, iter, path);
+ gtk_tree_path_free (path);
+
+ return iter_set;
+}
+
+static gint
+mail_account_store_default_compare (CamelService *service_a,
+ CamelService *service_b,
+ EMailAccountStore *store)
+{
+ const gchar *display_name_a;
+ const gchar *display_name_b;
+ const gchar *uid_a;
+ const gchar *uid_b;
+
+ uid_a = camel_service_get_uid (service_a);
+ uid_b = camel_service_get_uid (service_b);
+
+ /* Check for special cases first. */
+
+ if (e_mail_account_store_get_express_mode (store)) {
+ if (g_str_equal (uid_a, E_MAIL_SESSION_LOCAL_UID) &&
+ g_str_equal (uid_b, E_MAIL_SESSION_VFOLDER_UID))
+ return -1;
+ else if (g_str_equal (uid_b, E_MAIL_SESSION_LOCAL_UID) &&
+ g_str_equal (uid_a, E_MAIL_SESSION_VFOLDER_UID))
+ return 1;
+ else if (g_str_equal (uid_a, E_MAIL_SESSION_LOCAL_UID))
+ return 1;
+ else if (g_str_equal (uid_b, E_MAIL_SESSION_LOCAL_UID))
+ return -1;
+ else if (g_str_equal (uid_a, E_MAIL_SESSION_VFOLDER_UID))
+ return 1;
+ else if (g_str_equal (uid_a, E_MAIL_SESSION_VFOLDER_UID))
+ return -1;
+ } else {
+ if (g_str_equal (uid_a, E_MAIL_SESSION_LOCAL_UID))
+ return -1;
+ else if (g_str_equal (uid_b, E_MAIL_SESSION_LOCAL_UID))
+ return 1;
+ else if (g_str_equal (uid_a, E_MAIL_SESSION_VFOLDER_UID))
+ return 1;
+ else if (g_str_equal (uid_b, E_MAIL_SESSION_VFOLDER_UID))
+ return -1;
+ }
+
+ /* Otherwise sort them alphabetically. */
+
+ display_name_a = camel_service_get_display_name (service_a);
+ display_name_b = camel_service_get_display_name (service_b);
+
+ if (display_name_a == NULL)
+ display_name_a = "";
+
+ if (display_name_b == NULL)
+ display_name_b = "";
+
+ return g_utf8_collate (display_name_a, display_name_b);
+}
+
+static void
+mail_account_store_update_row (EMailAccountStore *store,
+ CamelService *service,
+ GtkTreeIter *iter)
+{
+ CamelProvider *provider;
+ gboolean is_default;
+ const gchar *backend_name;
+ const gchar *display_name;
+
+ is_default = (service == store->priv->default_service);
+ display_name = camel_service_get_display_name (service);
+
+ provider = camel_service_get_provider (service);
+ backend_name = (provider != NULL) ? provider->protocol : NULL;
+
+ gtk_list_store_set (
+ GTK_LIST_STORE (store), iter,
+ E_MAIL_ACCOUNT_STORE_COLUMN_DEFAULT, is_default,
+ E_MAIL_ACCOUNT_STORE_COLUMN_BACKEND_NAME, backend_name,
+ E_MAIL_ACCOUNT_STORE_COLUMN_DISPLAY_NAME, display_name,
+ -1);
+}
+
+static void
+mail_account_store_service_notify_cb (CamelService *service,
+ GParamSpec *pspec,
+ EMailAccountStore *store)
+{
+ GtkTreeIter iter;
+
+ if (mail_account_store_get_iter (store, service, &iter))
+ mail_account_store_update_row (store, service, &iter);
+}
+
+static void
+mail_account_store_clean_index (EMailAccountStore *store)
+{
+ GQueue trash = G_QUEUE_INIT;
+ GHashTable *hash_table;
+ GHashTableIter iter;
+ gpointer key, value;
+
+ hash_table = store->priv->service_index;
+ g_hash_table_iter_init (&iter, hash_table);
+
+ /* Remove index items with invalid GtkTreeRowReferences. */
+
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ IndexItem *item = value;
+
+ if (!gtk_tree_row_reference_valid (item->reference))
+ g_queue_push_tail (&trash, key);
+ }
+
+ while ((key = g_queue_pop_head (&trash)) != NULL)
+ g_hash_table_remove (hash_table, key);
+}
+
+static void
+mail_account_store_update_index (EMailAccountStore *store,
+ GtkTreePath *path,
+ GtkTreeIter *iter)
+{
+ CamelService *service = NULL;
+ GHashTable *hash_table;
+ GtkTreeModel *model;
+ IndexItem *item;
+
+ model = GTK_TREE_MODEL (store);
+ hash_table = store->priv->service_index;
+
+ gtk_tree_model_get (
+ model, iter,
+ E_MAIL_ACCOUNT_STORE_COLUMN_SERVICE, &service, -1);
+
+ if (service == NULL)
+ return;
+
+ item = g_hash_table_lookup (hash_table, service);
+
+ if (item == NULL) {
+ item = g_slice_new0 (IndexItem);
+ item->service = g_object_ref (service);
+
+ item->notify_handler_id = g_signal_connect (
+ service, "notify", G_CALLBACK (
+ mail_account_store_service_notify_cb), store);
+
+ g_hash_table_insert (hash_table, item->service, item);
+ }
+
+ /* Update the row reference so the IndexItem will survive
+ * drag-and-drop (new row is inserted, old row is deleted). */
+ gtk_tree_row_reference_free (item->reference);
+ item->reference = gtk_tree_row_reference_new (model, path);
+
+ g_object_unref (service);
+}
+
+static void
+mail_account_store_set_session (EMailAccountStore *store,
+ EMailSession *session)
+{
+ g_return_if_fail (E_IS_MAIL_SESSION (session));
+ g_return_if_fail (store->priv->session == NULL);
+
+ store->priv->session = session;
+
+ g_object_add_weak_pointer (
+ G_OBJECT (store->priv->session),
+ &store->priv->session);
+}
+
+static void
+mail_account_store_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_DEFAULT_SERVICE:
+ e_mail_account_store_set_default_service (
+ E_MAIL_ACCOUNT_STORE (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_EXPRESS_MODE:
+ e_mail_account_store_set_express_mode (
+ E_MAIL_ACCOUNT_STORE (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_SESSION:
+ mail_account_store_set_session (
+ E_MAIL_ACCOUNT_STORE (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_account_store_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_BUSY:
+ g_value_set_boolean (
+ value,
+ e_mail_account_store_get_busy (
+ E_MAIL_ACCOUNT_STORE (object)));
+ return;
+
+ case PROP_DEFAULT_SERVICE:
+ g_value_set_object (
+ value,
+ e_mail_account_store_get_default_service (
+ E_MAIL_ACCOUNT_STORE (object)));
+ return;
+
+ case PROP_EXPRESS_MODE:
+ g_value_set_boolean (
+ value,
+ e_mail_account_store_get_express_mode (
+ E_MAIL_ACCOUNT_STORE (object)));
+ return;
+
+ case PROP_SESSION:
+ g_value_set_object (
+ value,
+ e_mail_account_store_get_session (
+ E_MAIL_ACCOUNT_STORE (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_account_store_dispose (GObject *object)
+{
+ EMailAccountStorePrivate *priv;
+
+ priv = E_MAIL_ACCOUNT_STORE_GET_PRIVATE (object);
+
+ if (priv->session != NULL) {
+ g_object_remove_weak_pointer (
+ G_OBJECT (priv->session), &priv->session);
+ priv->session = NULL;
+ }
+
+ if (priv->default_service != NULL) {
+ g_object_unref (priv->default_service);
+ priv->default_service = NULL;
+ }
+
+ g_hash_table_remove_all (priv->service_index);
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (e_mail_account_store_parent_class)->dispose (object);
+}
+
+static void
+mail_account_store_finalize (GObject *object)
+{
+ EMailAccountStorePrivate *priv;
+
+ priv = E_MAIL_ACCOUNT_STORE_GET_PRIVATE (object);
+
+ g_warn_if_fail (priv->busy_count == 0);
+ g_hash_table_destroy (priv->service_index);
+ g_free (priv->sort_order_filename);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (e_mail_account_store_parent_class)->finalize (object);
+}
+
+static void
+mail_account_store_constructed (GObject *object)
+{
+ EMailAccountStore *store;
+ const gchar *config_dir;
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (e_mail_account_store_parent_class)->constructed (object);
+
+ store = E_MAIL_ACCOUNT_STORE (object);
+ config_dir = mail_session_get_config_dir ();
+
+ /* XXX Should we take the filename as a constructor property? */
+ store->priv->sort_order_filename = g_build_filename (
+ config_dir, "sortorder.ini", NULL);
+
+ /* XXX This is kinda lame, but should work until EAccount dies. */
+ g_signal_connect (
+ object, "notify::default-service",
+ G_CALLBACK (mail_account_store_save_default), NULL);
+
+ e_extensible_load_extensions (E_EXTENSIBLE (object));
+}
+
+static void
+mail_account_store_service_added (EMailAccountStore *store,
+ CamelService *service)
+{
+ /* Placeholder so subclasses can safely chain up. */
+}
+
+static void
+mail_account_store_service_removed (EMailAccountStore *store,
+ CamelService *service)
+{
+ /* XXX On the account-mgmt branch this operation is asynchronous.
+ * The 'busy_count' is bumped until changes are written back
+ * to the D-Bus service. For now I guess we'll just block. */
+
+ EAccountList *account_list;
+ EAccount *account;
+ const gchar *uid;
+
+ account_list = e_get_account_list ();
+ uid = camel_service_get_uid (service);
+ account = e_get_account_by_uid (uid);
+ g_return_if_fail (account != NULL);
+
+ if (account->enabled) {
+ CamelProvider *provider;
+
+ provider = camel_service_get_provider (service);
+ g_return_if_fail (provider != NULL);
+
+ if (provider->flags & CAMEL_PROVIDER_IS_STORAGE)
+ mail_disconnect_store (CAMEL_STORE (service));
+ }
+
+ /* Remove all the proxies the account has created.
+ * FIXME This proxy stuff belongs in evolution-groupwise. */
+ e_account_list_remove_account_proxies (account_list, account);
+
+ e_account_list_remove (account_list, account);
+
+ e_account_list_save (account_list);
+}
+
+static void
+mail_account_store_service_enabled (EMailAccountStore *store,
+ CamelService *service)
+{
+ /* XXX On the account-mgmt branch this operation is asynchronous.
+ * The 'busy_count' is bumped until changes are written back
+ * to the D-Bus service. For now I guess we'll just block. */
+
+ GSettings *settings;
+ const gchar *uid;
+
+ uid = camel_service_get_uid (service);
+
+ /* Handle built-in services that don't have an EAccount. */
+
+ if (g_strcmp0 (uid, E_MAIL_SESSION_LOCAL_UID) == 0) {
+ settings = g_settings_new ("org.gnome.evolution.mail");
+ g_settings_set_boolean (settings, "enable-local", TRUE);
+ g_object_unref (settings);
+
+ } else if (g_strcmp0 (uid, E_MAIL_SESSION_VFOLDER_UID) == 0) {
+ settings = g_settings_new ("org.gnome.evolution.mail");
+ g_settings_set_boolean (settings, "enable-vfolders", TRUE);
+ g_object_unref (settings);
+
+ } else {
+ EAccountList *account_list;
+ EAccount *account;
+
+ account_list = e_get_account_list ();
+ account = e_get_account_by_uid (uid);
+ g_return_if_fail (account != NULL);
+
+ account->enabled = TRUE;
+
+ e_account_list_change (account_list, account);
+ e_account_list_save (account_list);
+ }
+}
+
+static void
+mail_account_store_service_disabled (EMailAccountStore *store,
+ CamelService *service)
+{
+ /* XXX On the account-mgmt branch this operation is asynchronous.
+ * The 'busy_count' is bumped until changes are written back
+ * to the D-Bus service. For now I guess we'll just block. */
+
+ GSettings *settings;
+ const gchar *uid;
+
+ uid = camel_service_get_uid (service);
+
+ /* Handle built-in services that don't have an EAccount. */
+
+ if (g_strcmp0 (uid, E_MAIL_SESSION_LOCAL_UID) == 0) {
+ settings = g_settings_new ("org.gnome.evolution.mail");
+ g_settings_set_boolean (settings, "enable-local", FALSE);
+ g_object_unref (settings);
+
+ } else if (g_strcmp0 (uid, E_MAIL_SESSION_VFOLDER_UID) == 0) {
+ settings = g_settings_new ("org.gnome.evolution.mail");
+ g_settings_set_boolean (settings, "enable-vfolders", FALSE);
+ g_object_unref (settings);
+
+ } else {
+ EAccountList *account_list;
+ EAccount *account;
+ CamelProvider *provider;
+
+ account_list = e_get_account_list ();
+ account = e_get_account_by_uid (uid);
+ g_return_if_fail (account != NULL);
+
+ account->enabled = FALSE;
+
+ provider = camel_service_get_provider (service);
+ g_return_if_fail (provider != NULL);
+
+ if (provider->flags & CAMEL_PROVIDER_IS_STORAGE)
+ mail_disconnect_store (CAMEL_STORE (service));
+
+ /* FIXME This proxy stuff belongs in evolution-groupwise. */
+ e_account_list_remove_account_proxies (account_list, account);
+
+ if (account->parent_uid != NULL)
+ e_account_list_remove (account_list, account);
+
+ e_account_list_change (account_list, account);
+ e_account_list_save (account_list);
+ }
+}
+
+static void
+mail_account_store_services_reordered (EMailAccountStore *store,
+ gboolean default_restored)
+{
+ /* XXX Should this be made asynchronous? */
+
+ GError *error = NULL;
+
+ if (default_restored) {
+ const gchar *filename;
+
+ filename = store->priv->sort_order_filename;
+
+ if (g_file_test (filename, G_FILE_TEST_EXISTS))
+ g_unlink (filename);
+
+ return;
+ }
+
+ if (!e_mail_account_store_save_sort_order (store, &error)) {
+ g_warning ("%s: %s", G_STRFUNC, error->message);
+ g_error_free (error);
+ }
+}
+
+static gboolean
+mail_account_store_remove_requested (EMailAccountStore *store,
+ GtkWindow *parent_window,
+ CamelService *service)
+{
+ EAccountList *account_list;
+ EAccount *account;
+ const gchar *alert;
+ const gchar *uid;
+ gint response;
+
+ account_list = e_get_account_list ();
+ uid = camel_service_get_uid (service);
+ account = e_get_account_by_uid (uid);
+
+ g_return_val_if_fail (account != NULL, FALSE);
+
+ /* FIXME This proxy stuff belongs in evolution-groupwise. */
+ if (e_account_list_account_has_proxies (account_list, account))
+ alert = "mail:ask-delete-account-with-proxies";
+ else
+ alert = "mail:ask-delete-account";
+
+ response = e_alert_run_dialog_for_args (parent_window, alert, NULL);
+
+ return (response == GTK_RESPONSE_YES);
+}
+
+static gboolean
+mail_account_store_enable_requested (EMailAccountStore *store,
+ GtkWindow *parent_window,
+ CamelService *service)
+{
+ return TRUE;
+}
+
+static gboolean
+mail_account_store_disable_requested (EMailAccountStore *store,
+ GtkWindow *parent_window,
+ CamelService *service)
+{
+ EAccountList *account_list;
+ EAccount *account;
+ const gchar *uid;
+ gint response;
+
+ account_list = e_get_account_list ();
+ uid = camel_service_get_uid (service);
+ account = e_get_account_by_uid (uid);
+
+ /* "On This Computer" and "Search Folders" do not have
+ * EAccounts, so just silently return TRUE if we failed
+ * to find a matching EAccount for the CamelService. */
+
+ /* Silently return TRUE if we failed to find a matching
+ * EAccount since "On This Computer" and "Search Folders"
+ * do not have EAccounts. */
+ if (account == NULL)
+ return TRUE;
+
+ /* FIXME This proxy stuff belongs in evolution-groupwise. */
+ if (e_account_list_account_has_proxies (account_list, account))
+ response = e_alert_run_dialog_for_args (
+ parent_window,
+ "mail:ask-delete-proxy-accounts", NULL);
+ else
+ response = GTK_RESPONSE_YES;
+
+ return (response == GTK_RESPONSE_YES);
+}
+
+static void
+mail_account_store_row_changed (GtkTreeModel *tree_model,
+ GtkTreePath *path,
+ GtkTreeIter *iter)
+{
+ EMailAccountStore *store;
+
+ /* Neither GtkTreeModel nor GtkListStore implements
+ * this method, so there is nothing to chain up to. */
+
+ store = E_MAIL_ACCOUNT_STORE (tree_model);
+ mail_account_store_update_index (store, path, iter);
+}
+
+static void
+mail_account_store_row_inserted (GtkTreeModel *tree_model,
+ GtkTreePath *path,
+ GtkTreeIter *iter)
+{
+ EMailAccountStore *store;
+
+ /* Neither GtkTreeModel nor GtkListStore implements
+ * this method, so there is nothing to chain up to. */
+
+ store = E_MAIL_ACCOUNT_STORE (tree_model);
+ mail_account_store_update_index (store, path, iter);
+}
+
+static gboolean
+mail_account_store_true_proceed (GSignalInvocationHint *ihint,
+ GValue *return_accumulator,
+ const GValue *handler_return,
+ gpointer not_used)
+{
+ gboolean proceed;
+
+ proceed = g_value_get_boolean (handler_return);
+ g_value_set_boolean (return_accumulator, proceed);
+
+ return proceed;
+}
+
+static void
+e_mail_account_store_class_init (EMailAccountStoreClass *class)
+{
+ GObjectClass *object_class;
+
+ g_type_class_add_private (class, sizeof (EMailAccountStorePrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = mail_account_store_set_property;
+ object_class->get_property = mail_account_store_get_property;
+ object_class->dispose = mail_account_store_dispose;
+ object_class->finalize = mail_account_store_finalize;
+ object_class->constructed = mail_account_store_constructed;
+
+ class->service_added = mail_account_store_service_added;
+ class->service_removed = mail_account_store_service_removed;
+ class->service_enabled = mail_account_store_service_enabled;
+ class->service_disabled = mail_account_store_service_disabled;
+ class->services_reordered = mail_account_store_services_reordered;
+ class->remove_requested = mail_account_store_remove_requested;
+ class->enable_requested = mail_account_store_enable_requested;
+ class->disable_requested = mail_account_store_disable_requested;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_BUSY,
+ g_param_spec_boolean (
+ "busy",
+ "Busy",
+ "Whether async operations are in progress",
+ FALSE,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_DEFAULT_SERVICE,
+ g_param_spec_object (
+ "default-service",
+ "Default Service",
+ "Default mail store",
+ CAMEL_TYPE_SERVICE,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_EXPRESS_MODE,
+ g_param_spec_boolean (
+ "express-mode",
+ "Express Mode",
+ "Whether express mode is enabled",
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SESSION,
+ g_param_spec_object (
+ "session",
+ "Session",
+ "Mail session",
+ E_TYPE_MAIL_SESSION,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
+ signals[SERVICE_ADDED] = g_signal_new (
+ "service-added",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMailAccountStoreClass, service_added),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ CAMEL_TYPE_SERVICE);
+
+ signals[SERVICE_REMOVED] = g_signal_new (
+ "service-removed",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMailAccountStoreClass, service_removed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ CAMEL_TYPE_SERVICE);
+
+ signals[SERVICE_ENABLED] = g_signal_new (
+ "service-enabled",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMailAccountStoreClass, service_enabled),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ CAMEL_TYPE_SERVICE);
+
+ signals[SERVICE_DISABLED] = g_signal_new (
+ "service-disabled",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMailAccountStoreClass, service_disabled),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ CAMEL_TYPE_SERVICE);
+
+ signals[SERVICES_REORDERED] = g_signal_new (
+ "services-reordered",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMailAccountStoreClass, services_reordered),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOOLEAN,
+ G_TYPE_NONE, 1,
+ G_TYPE_BOOLEAN);
+
+ signals[REMOVE_REQUESTED] = g_signal_new (
+ "remove-requested",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMailAccountStoreClass, remove_requested),
+ mail_account_store_true_proceed, NULL,
+ e_marshal_BOOLEAN__OBJECT_OBJECT,
+ G_TYPE_BOOLEAN, 2,
+ GTK_TYPE_WINDOW,
+ CAMEL_TYPE_SERVICE);
+
+ signals[ENABLE_REQUESTED] = g_signal_new (
+ "enable-requested",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMailAccountStoreClass, enable_requested),
+ mail_account_store_true_proceed, NULL,
+ e_marshal_BOOLEAN__OBJECT_OBJECT,
+ G_TYPE_BOOLEAN, 2,
+ GTK_TYPE_WINDOW,
+ CAMEL_TYPE_SERVICE);
+
+ signals[DISABLE_REQUESTED] = g_signal_new (
+ "disable-requested",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMailAccountStoreClass, disable_requested),
+ mail_account_store_true_proceed, NULL,
+ e_marshal_BOOLEAN__OBJECT_OBJECT,
+ G_TYPE_BOOLEAN, 2,
+ GTK_TYPE_WINDOW,
+ CAMEL_TYPE_SERVICE);
+}
+
+static void
+e_mail_account_store_interface_init (GtkTreeModelIface *interface)
+{
+ interface->row_changed = mail_account_store_row_changed;
+ interface->row_inserted = mail_account_store_row_inserted;
+}
+
+static void
+e_mail_account_store_init (EMailAccountStore *store)
+{
+ GType types[E_MAIL_ACCOUNT_STORE_NUM_COLUMNS];
+ GHashTable *service_index;
+ gint ii = 0;
+
+ service_index = g_hash_table_new_full (
+ (GHashFunc) g_direct_hash,
+ (GEqualFunc) g_direct_equal,
+ (GDestroyNotify) NULL,
+ (GDestroyNotify) index_item_free);
+
+ store->priv = E_MAIL_ACCOUNT_STORE_GET_PRIVATE (store);
+ store->priv->service_index = service_index;
+
+ types[ii++] = CAMEL_TYPE_SERVICE; /* COLUMN_SERVICE */
+ types[ii++] = G_TYPE_BOOLEAN; /* COLUMN_BUILTIN */
+ types[ii++] = G_TYPE_BOOLEAN; /* COLUMN_ENABLED */
+ types[ii++] = G_TYPE_BOOLEAN; /* COLUMN_DEFAULT */
+ types[ii++] = G_TYPE_STRING; /* COLUMN_BACKEND_NAME */
+ types[ii++] = G_TYPE_STRING; /* COLUMN_DISPLAY_NAME */
+
+ g_assert (ii == E_MAIL_ACCOUNT_STORE_NUM_COLUMNS);
+
+ gtk_list_store_set_column_types (
+ GTK_LIST_STORE (store),
+ G_N_ELEMENTS (types), types);
+}
+
+EMailAccountStore *
+e_mail_account_store_new (EMailSession *session)
+{
+ g_return_val_if_fail (E_IS_MAIL_SESSION (session), NULL);
+
+ return g_object_new (
+ E_TYPE_MAIL_ACCOUNT_STORE,
+ "session", session, NULL);
+}
+
+void
+e_mail_account_store_clear (EMailAccountStore *store)
+{
+ g_return_if_fail (E_IS_MAIL_ACCOUNT_STORE (store));
+
+ gtk_list_store_clear (GTK_LIST_STORE (store));
+ g_hash_table_remove_all (store->priv->service_index);
+}
+
+gboolean
+e_mail_account_store_get_busy (EMailAccountStore *store)
+{
+ g_return_val_if_fail (E_IS_MAIL_ACCOUNT_STORE (store), FALSE);
+
+ return (store->priv->busy_count > 0);
+}
+
+EMailSession *
+e_mail_account_store_get_session (EMailAccountStore *store)
+{
+ g_return_val_if_fail (E_IS_MAIL_ACCOUNT_STORE (store), NULL);
+
+ return E_MAIL_SESSION (store->priv->session);
+}
+
+CamelService *
+e_mail_account_store_get_default_service (EMailAccountStore *store)
+{
+ g_return_val_if_fail (E_IS_MAIL_ACCOUNT_STORE (store), NULL);
+
+ return store->priv->default_service;
+}
+
+void
+e_mail_account_store_set_default_service (EMailAccountStore *store,
+ CamelService *service)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ gboolean iter_set;
+
+ g_return_if_fail (E_IS_MAIL_ACCOUNT_STORE (store));
+
+ if (service == store->priv->default_service)
+ return;
+
+ if (service != NULL) {
+ g_return_if_fail (CAMEL_IS_SERVICE (service));
+ g_object_ref (service);
+ }
+
+ if (store->priv->default_service != NULL)
+ g_object_unref (store->priv->default_service);
+
+ store->priv->default_service = service;
+
+ model = GTK_TREE_MODEL (store);
+ iter_set = gtk_tree_model_get_iter_first (model, &iter);
+
+ while (iter_set) {
+ CamelService *candidate;
+
+ gtk_tree_model_get (
+ model, &iter,
+ E_MAIL_ACCOUNT_STORE_COLUMN_SERVICE,
+ &candidate, -1);
+
+ gtk_list_store_set (
+ GTK_LIST_STORE (model), &iter,
+ E_MAIL_ACCOUNT_STORE_COLUMN_DEFAULT,
+ service == candidate, -1);
+
+ g_object_unref (candidate);
+
+ iter_set = gtk_tree_model_iter_next (model, &iter);
+ }
+
+ g_object_notify (G_OBJECT (store), "default-service");
+}
+
+gboolean
+e_mail_account_store_get_express_mode (EMailAccountStore *store)
+{
+ g_return_val_if_fail (E_IS_MAIL_ACCOUNT_STORE (store), FALSE);
+
+ return store->priv->express_mode;
+}
+
+void
+e_mail_account_store_set_express_mode (EMailAccountStore *store,
+ gboolean express_mode)
+{
+ g_return_if_fail (E_IS_MAIL_ACCOUNT_STORE (store));
+
+ store->priv->express_mode = express_mode;
+
+ g_object_notify (G_OBJECT (store), "express-mode");
+}
+
+void
+e_mail_account_store_add_service (EMailAccountStore *store,
+ CamelService *service)
+{
+ GSettings *settings;
+ GtkTreeIter iter;
+ const gchar *filename;
+ const gchar *uid;
+ gboolean builtin;
+ gboolean enabled;
+
+ g_return_if_fail (E_IS_MAIL_ACCOUNT_STORE (store));
+ g_return_if_fail (CAMEL_IS_SERVICE (service));
+
+ /* Avoid duplicate services in the account store. */
+ if (mail_account_store_get_iter (store, service, &iter))
+ g_return_if_reached ();
+
+ uid = camel_service_get_uid (service);
+
+ /* Handle built-in services that don't have an EAccount. */
+
+ if (g_strcmp0 (uid, E_MAIL_SESSION_LOCAL_UID) == 0) {
+ builtin = TRUE;
+
+ settings = g_settings_new ("org.gnome.evolution.mail");
+ enabled = g_settings_get_boolean (settings, "enable-local");
+ g_object_unref (settings);
+
+ } else if (g_strcmp0 (uid, E_MAIL_SESSION_VFOLDER_UID) == 0) {
+ builtin = TRUE;
+
+ settings = g_settings_new ("org.gnome.evolution.mail");
+ enabled = g_settings_get_boolean (settings, "enable-vfolders");
+ g_object_unref (settings);
+
+ } else {
+ EAccount *account;
+
+ account = e_get_account_by_uid (uid);
+ g_return_if_fail (account != NULL);
+
+ builtin = FALSE;
+ enabled = account->enabled;
+ }
+
+ /* Where do we insert new services now that accounts can be
+ * reordered? This is just a simple policy I came up with.
+ * It's certainly subject to debate and tweaking.
+ *
+ * Always insert new services in row 0 initially. Then test
+ * for the presence of the sort order file. If present, the
+ * user has messed around with the ordering so leave the new
+ * service at row 0. If not present, services are sorted in
+ * their default order. So re-apply the default order using
+ * e_mail_account_store_reorder_services(store, NULL) so the
+ * new service moves to its proper default position. */
+
+ gtk_list_store_prepend (GTK_LIST_STORE (store), &iter);
+
+ gtk_list_store_set (
+ GTK_LIST_STORE (store), &iter,
+ E_MAIL_ACCOUNT_STORE_COLUMN_SERVICE, service,
+ E_MAIL_ACCOUNT_STORE_COLUMN_BUILTIN, builtin,
+ E_MAIL_ACCOUNT_STORE_COLUMN_ENABLED, enabled,
+ -1);
+
+ /* This populates the rest of the columns. */
+ mail_account_store_update_row (store, service, &iter);
+
+ g_signal_emit (store, signals[SERVICE_ADDED], 0, service);
+
+ if (enabled)
+ g_signal_emit (store, signals[SERVICE_ENABLED], 0, service);
+ else
+ g_signal_emit (store, signals[SERVICE_DISABLED], 0, service);
+
+ filename = store->priv->sort_order_filename;
+
+ if (!g_file_test (filename, G_FILE_TEST_EXISTS))
+ e_mail_account_store_reorder_services (store, NULL);
+}
+
+void
+e_mail_account_store_remove_service (EMailAccountStore *store,
+ GtkWindow *parent_window,
+ CamelService *service)
+{
+ GtkTreeIter iter;
+ gboolean proceed;
+
+ g_return_if_fail (E_IS_MAIL_ACCOUNT_STORE (store));
+ g_return_if_fail (CAMEL_IS_SERVICE (service));
+
+ if (!mail_account_store_get_iter (store, service, &iter))
+ g_return_if_reached ();
+
+ /* Possibly request user confirmation. */
+ g_signal_emit (
+ store, signals[REMOVE_REQUESTED], 0,
+ parent_window, service, &proceed);
+
+ if (proceed) {
+ g_object_ref (service);
+
+ gtk_list_store_remove (GTK_LIST_STORE (store), &iter);
+
+ mail_account_store_clean_index (store);
+
+ g_signal_emit (store, signals[SERVICE_REMOVED], 0, service);
+
+ g_object_unref (service);
+ }
+}
+
+void
+e_mail_account_store_enable_service (EMailAccountStore *store,
+ GtkWindow *parent_window,
+ CamelService *service)
+{
+ GtkTreeIter iter;
+ gboolean proceed;
+
+ g_return_if_fail (E_IS_MAIL_ACCOUNT_STORE (store));
+ g_return_if_fail (CAMEL_IS_SERVICE (service));
+
+ if (!mail_account_store_get_iter (store, service, &iter))
+ g_return_if_reached ();
+
+ /* Possibly request user confirmation. */
+ g_signal_emit (
+ store, signals[ENABLE_REQUESTED], 0,
+ parent_window, service, &proceed);
+
+ if (proceed) {
+ gtk_list_store_set (
+ GTK_LIST_STORE (store), &iter,
+ E_MAIL_ACCOUNT_STORE_COLUMN_ENABLED, TRUE, -1);
+
+ g_signal_emit (store, signals[SERVICE_ENABLED], 0, service);
+ }
+}
+
+void
+e_mail_account_store_disable_service (EMailAccountStore *store,
+ GtkWindow *parent_window,
+ CamelService *service)
+{
+ GtkTreeIter iter;
+ gboolean proceed;
+
+ g_return_if_fail (E_IS_MAIL_ACCOUNT_STORE (store));
+ g_return_if_fail (CAMEL_IS_SERVICE (service));
+
+ if (!mail_account_store_get_iter (store, service, &iter))
+ g_return_if_reached ();
+
+ /* Possibly request user confirmation. */
+ g_signal_emit (
+ store, signals[DISABLE_REQUESTED], 0,
+ parent_window, service, &proceed);
+
+ if (proceed) {
+ gtk_list_store_set (
+ GTK_LIST_STORE (store), &iter,
+ E_MAIL_ACCOUNT_STORE_COLUMN_ENABLED, FALSE, -1);
+
+ g_signal_emit (store, signals[SERVICE_DISABLED], 0, service);
+ }
+}
+
+void
+e_mail_account_store_reorder_services (EMailAccountStore *store,
+ GQueue *ordered_services)
+{
+ GQueue *current_order = NULL;
+ GQueue *default_order = NULL;
+ GtkTreeModel *tree_model;
+ GtkTreeIter iter;
+ gboolean use_default_order;
+ gboolean iter_set;
+ GList *head, *link;
+ gint *new_order;
+ gint n_children;
+ gint new_pos = 0;
+ guint length;
+
+ g_return_if_fail (E_IS_MAIL_ACCOUNT_STORE (store));
+
+ tree_model = GTK_TREE_MODEL (store);
+ n_children = gtk_tree_model_iter_n_children (tree_model, NULL);
+
+ /* Treat NULL queues and empty queues the same. */
+ if (ordered_services != NULL && g_queue_is_empty (ordered_services))
+ ordered_services = NULL;
+
+ use_default_order = (ordered_services == NULL);
+
+ if (ordered_services != NULL) {
+ length = g_queue_get_length (ordered_services);
+ g_return_if_fail (length == n_children);
+ }
+
+ current_order = g_queue_new ();
+ iter_set = gtk_tree_model_get_iter_first (tree_model, &iter);
+
+ /* Build a queue of CamelServices in the order they appear in
+ * the list store. We'll use this to construct the mapping to
+ * pass to gtk_list_store_reorder(). */
+ while (iter_set) {
+ GValue value = G_VALUE_INIT;
+ const gint column = E_MAIL_ACCOUNT_STORE_COLUMN_SERVICE;
+
+ gtk_tree_model_get_value (tree_model, &iter, column, &value);
+ g_queue_push_tail (current_order, g_value_get_object (&value));
+ g_value_unset (&value);
+
+ iter_set = gtk_tree_model_iter_next (tree_model, &iter);
+ }
+
+ /* If a custom ordering was not given, revert to default. */
+ if (use_default_order) {
+ default_order = g_queue_copy (current_order);
+
+ g_queue_sort (
+ default_order, (GCompareDataFunc)
+ mail_account_store_default_compare, store);
+
+ ordered_services = default_order;
+ }
+
+ new_order = g_new0 (gint, n_children);
+ head = g_queue_peek_head_link (ordered_services);
+
+ for (link = head; link != NULL; link = g_list_next (link)) {
+ GList *matching_link;
+ gint old_pos;
+
+ matching_link = g_queue_find (current_order, link->data);
+
+ if (matching_link == NULL || matching_link->data == NULL)
+ break;
+
+ old_pos = g_queue_link_index (current_order, matching_link);
+
+ matching_link->data = NULL;
+ new_order[new_pos++] = old_pos;
+ }
+
+ if (new_pos == n_children) {
+ gtk_list_store_reorder (GTK_LIST_STORE (store), new_order);
+ g_signal_emit (
+ store, signals[SERVICES_REORDERED], 0,
+ use_default_order);
+ }
+
+ g_free (new_order);
+
+ if (current_order != NULL)
+ g_queue_free (current_order);
+
+ if (default_order != NULL)
+ g_queue_free (default_order);
+}
+
+gint
+e_mail_account_store_compare_services (EMailAccountStore *store,
+ CamelService *service_a,
+ CamelService *service_b)
+{
+ GtkTreeModel *model;
+ GtkTreePath *path_a;
+ GtkTreePath *path_b;
+ GtkTreeIter iter_a;
+ GtkTreeIter iter_b;
+ gboolean iter_a_set;
+ gboolean iter_b_set;
+ gint result;
+
+ g_return_val_if_fail (E_IS_MAIL_ACCOUNT_STORE (store), -1);
+ g_return_val_if_fail (CAMEL_IS_SERVICE (service_a), -1);
+ g_return_val_if_fail (CAMEL_IS_SERVICE (service_b), -1);
+
+ /* XXX This is horribly inefficient but should be
+ * over a small enough set to not be noticable. */
+
+ iter_a_set = mail_account_store_get_iter (store, service_a, &iter_a);
+ iter_b_set = mail_account_store_get_iter (store, service_b, &iter_b);
+
+ if (!iter_a_set && !iter_b_set)
+ return 0;
+
+ if (!iter_a_set)
+ return -1;
+
+ if (!iter_b_set)
+ return 1;
+
+ model = GTK_TREE_MODEL (store);
+
+ path_a = gtk_tree_model_get_path (model, &iter_a);
+ path_b = gtk_tree_model_get_path (model, &iter_b);
+
+ result = gtk_tree_path_compare (path_a, path_b);
+
+ gtk_tree_path_free (path_a);
+ gtk_tree_path_free (path_b);
+
+ return result;
+}
+
+gboolean
+e_mail_account_store_load_sort_order (EMailAccountStore *store,
+ GError **error)
+{
+ GQueue service_queue = G_QUEUE_INIT;
+ EMailSession *session;
+ GKeyFile *key_file;
+ const gchar *filename;
+ gchar **service_uids;
+ gboolean success = TRUE;
+ gsize ii, length;
+
+ g_return_val_if_fail (E_IS_MAIL_ACCOUNT_STORE (store), FALSE);
+
+ session = e_mail_account_store_get_session (store);
+
+ key_file = g_key_file_new ();
+ filename = store->priv->sort_order_filename;
+
+ if (g_file_test (filename, G_FILE_TEST_EXISTS))
+ success = g_key_file_load_from_file (
+ key_file, filename, G_KEY_FILE_NONE, error);
+
+ if (!success) {
+ g_key_file_free (key_file);
+ return FALSE;
+ }
+
+ /* If the key is not present, length is set to zero. */
+ service_uids = g_key_file_get_string_list (
+ key_file, "Accounts", "SortOrder", &length, NULL);
+
+ for (ii = 0; ii < length; ii++) {
+ CamelService *service;
+
+ service = camel_session_get_service (
+ CAMEL_SESSION (session), service_uids[ii]);
+ if (service != NULL)
+ g_queue_push_tail (&service_queue, service);
+ }
+
+ e_mail_account_store_reorder_services (store, &service_queue);
+
+ g_queue_clear (&service_queue);
+ g_strfreev (service_uids);
+
+ g_key_file_free (key_file);
+
+ return TRUE;
+}
+
+gboolean
+e_mail_account_store_save_sort_order (EMailAccountStore *store,
+ GError **error)
+{
+ GKeyFile *key_file;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ const gchar **service_uids;
+ const gchar *filename;
+ gchar *contents;
+ gboolean iter_set;
+ gboolean success;
+ gsize length;
+ gsize ii = 0;
+
+ g_return_val_if_fail (E_IS_MAIL_ACCOUNT_STORE (store), FALSE);
+
+ model = GTK_TREE_MODEL (store);
+ length = gtk_tree_model_iter_n_children (model, NULL);
+
+ /* Empty store, nothing to save. */
+ if (length == 0)
+ return TRUE;
+
+ service_uids = g_new0 (const gchar *, length);
+
+ iter_set = gtk_tree_model_get_iter_first (model, &iter);
+
+ while (iter_set) {
+ GValue value = G_VALUE_INIT;
+ const gint column = E_MAIL_ACCOUNT_STORE_COLUMN_SERVICE;
+ CamelService *service;
+
+ gtk_tree_model_get_value (model, &iter, column, &value);
+ service = g_value_get_object (&value);
+ service_uids[ii++] = camel_service_get_uid (service);
+ g_value_unset (&value);
+
+ iter_set = gtk_tree_model_iter_next (model, &iter);
+ }
+
+ key_file = g_key_file_new ();
+ filename = store->priv->sort_order_filename;
+
+ g_key_file_set_string_list (
+ key_file, "Accounts", "SortOrder", service_uids, length);
+
+ contents = g_key_file_to_data (key_file, &length, NULL);
+ success = g_file_set_contents (filename, contents, length, error);
+ g_free (contents);
+
+ g_key_file_free (key_file);
+
+ g_free (service_uids);
+
+ return success;
+}
+
diff --git a/mail/e-mail-account-store.h b/mail/e-mail-account-store.h
new file mode 100644
index 0000000000..e4355da3a8
--- /dev/null
+++ b/mail/e-mail-account-store.h
@@ -0,0 +1,144 @@
+/*
+ * e-mail-account-store.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef E_MAIL_ACCOUNT_STORE_H
+#define E_MAIL_ACCOUNT_STORE_H
+
+#include <gtk/gtk.h>
+#include <camel/camel.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_ACCOUNT_STORE \
+ (e_mail_account_store_get_type ())
+#define E_MAIL_ACCOUNT_STORE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_ACCOUNT_STORE, EMailAccountStore))
+#define E_MAIL_ACCOUNT_STORE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_ACCOUNT_STORE, EMailAccountStoreClass))
+#define E_IS_MAIL_ACCOUNT_STORE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_ACCOUNT_STORE))
+#define E_IS_MAIL_ACOCUNT_STORE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_ACCOUNT_STORE))
+#define E_MAIL_ACCOUNT_STORE_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_ACCOUNT_STORE, EMailAccountStoreClass))
+
+G_BEGIN_DECLS
+
+/* Avoid a circular dependency. */
+typedef struct _EMailSession EMailSession;
+
+typedef enum {
+ E_MAIL_ACCOUNT_STORE_COLUMN_SERVICE,
+ E_MAIL_ACCOUNT_STORE_COLUMN_BUILTIN,
+ E_MAIL_ACCOUNT_STORE_COLUMN_ENABLED,
+ E_MAIL_ACCOUNT_STORE_COLUMN_DEFAULT,
+ E_MAIL_ACCOUNT_STORE_COLUMN_BACKEND_NAME,
+ E_MAIL_ACCOUNT_STORE_COLUMN_DISPLAY_NAME,
+ E_MAIL_ACCOUNT_STORE_NUM_COLUMNS
+} EMailAccountStoreColumn;
+
+typedef struct _EMailAccountStore EMailAccountStore;
+typedef struct _EMailAccountStoreClass EMailAccountStoreClass;
+typedef struct _EMailAccountStorePrivate EMailAccountStorePrivate;
+
+struct _EMailAccountStore {
+ GtkListStore parent;
+ EMailAccountStorePrivate *priv;
+};
+
+struct _EMailAccountStoreClass {
+ GtkListStoreClass parent_class;
+
+ /* Signals */
+ void (*service_added) (EMailAccountStore *store,
+ CamelService *service);
+ void (*service_removed) (EMailAccountStore *store,
+ CamelService *service);
+ void (*service_enabled) (EMailAccountStore *store,
+ CamelService *service);
+ void (*service_disabled) (EMailAccountStore *store,
+ CamelService *service);
+ void (*services_reordered) (EMailAccountStore *store,
+ gboolean default_restored);
+
+ /* These signals are for confirmation dialogs.
+ * Signal handler should return FALSE to abort. */
+ gboolean (*remove_requested) (EMailAccountStore *store,
+ GtkWindow *parent_window,
+ CamelService *service);
+ gboolean (*enable_requested) (EMailAccountStore *store,
+ GtkWindow *parent_window,
+ CamelService *service);
+ gboolean (*disable_requested) (EMailAccountStore *store,
+ GtkWindow *parent_window,
+ CamelService *service);
+};
+
+GType e_mail_account_store_get_type (void) G_GNUC_CONST;
+EMailAccountStore *
+ e_mail_account_store_new (EMailSession *session);
+void e_mail_account_store_clear (EMailAccountStore *store);
+gboolean e_mail_account_store_get_busy (EMailAccountStore *store);
+EMailSession * e_mail_account_store_get_session
+ (EMailAccountStore *store);
+CamelService * e_mail_account_store_get_default_service
+ (EMailAccountStore *store);
+void e_mail_account_store_set_default_service
+ (EMailAccountStore *store,
+ CamelService *service);
+gboolean e_mail_account_store_get_express_mode
+ (EMailAccountStore *store);
+void e_mail_account_store_set_express_mode
+ (EMailAccountStore *store,
+ gboolean express_mode);
+void e_mail_account_store_add_service
+ (EMailAccountStore *store,
+ CamelService *service);
+void e_mail_account_store_remove_service
+ (EMailAccountStore *store,
+ GtkWindow *parent_window,
+ CamelService *service);
+void e_mail_account_store_enable_service
+ (EMailAccountStore *store,
+ GtkWindow *parent_window,
+ CamelService *service);
+void e_mail_account_store_disable_service
+ (EMailAccountStore *store,
+ GtkWindow *parent_window,
+ CamelService *service);
+void e_mail_account_store_reorder_services
+ (EMailAccountStore *store,
+ GQueue *ordered_services);
+gint e_mail_account_store_compare_services
+ (EMailAccountStore *store,
+ CamelService *service_a,
+ CamelService *service_b);
+gboolean e_mail_account_store_load_sort_order
+ (EMailAccountStore *store,
+ GError **error);
+gboolean e_mail_account_store_save_sort_order
+ (EMailAccountStore *store,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* E_MAIL_ACCOUNT_STORE_H */
diff --git a/mail/e-mail-account-tree-view.c b/mail/e-mail-account-tree-view.c
new file mode 100644
index 0000000000..269a03d777
--- /dev/null
+++ b/mail/e-mail-account-tree-view.c
@@ -0,0 +1,283 @@
+/*
+ * e-mail-account-tree-view.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "e-mail-account-tree-view.h"
+
+#include <config.h>
+#include <glib/gi18n-lib.h>
+
+#define E_MAIL_ACCOUNT_TREE_VIEW_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAIL_ACCOUNT_TREE_VIEW, EMailAccountTreeViewPrivate))
+
+struct _EMailAccountTreeViewPrivate {
+ gint placeholder;
+};
+
+enum {
+ ENABLE,
+ DISABLE,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
+G_DEFINE_TYPE (
+ EMailAccountTreeView,
+ e_mail_account_tree_view,
+ GTK_TYPE_TREE_VIEW)
+
+static void
+mail_account_tree_view_enabled_toggled_cb (GtkCellRendererToggle *cell_renderer,
+ const gchar *path_string,
+ EMailAccountTreeView *tree_view)
+{
+ GtkTreeSelection *selection;
+ GtkTreePath *path;
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
+
+ /* Change the selection first so we act on the correct service. */
+ path = gtk_tree_path_new_from_string (path_string);
+ gtk_tree_selection_select_path (selection, path);
+ gtk_tree_path_free (path);
+
+ if (gtk_cell_renderer_toggle_get_active (cell_renderer))
+ g_signal_emit (tree_view, signals[DISABLE], 0);
+ else
+ g_signal_emit (tree_view, signals[ENABLE], 0);
+}
+
+static void
+mail_account_tree_view_constructed (GObject *object)
+{
+ GtkTreeView *tree_view;
+ GtkTreeViewColumn *column;
+ GtkCellRenderer *cell_renderer;
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (e_mail_account_tree_view_parent_class)->
+ constructed (object);
+
+ tree_view = GTK_TREE_VIEW (object);
+
+ gtk_tree_view_set_reorderable (tree_view, TRUE);
+
+ /* Column: Enabled */
+
+ column = gtk_tree_view_column_new ();
+ gtk_tree_view_column_set_expand (column, FALSE);
+ gtk_tree_view_column_set_title (column, _("Enabled"));
+
+ cell_renderer = gtk_cell_renderer_toggle_new ();
+ gtk_tree_view_column_pack_start (column, cell_renderer, TRUE);
+
+ g_signal_connect (
+ cell_renderer, "toggled",
+ G_CALLBACK (mail_account_tree_view_enabled_toggled_cb),
+ tree_view);
+
+ gtk_tree_view_column_add_attribute (
+ column, cell_renderer, "active",
+ E_MAIL_ACCOUNT_STORE_COLUMN_ENABLED);
+
+ gtk_tree_view_append_column (tree_view, column);
+
+ /* Column: Account Name */
+
+ column = gtk_tree_view_column_new ();
+ gtk_tree_view_column_set_expand (column, TRUE);
+ gtk_tree_view_column_set_title (column, _("Account Name"));
+
+ cell_renderer = gtk_cell_renderer_text_new ();
+ g_object_set (cell_renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
+ gtk_tree_view_column_pack_start (column, cell_renderer, TRUE);
+
+ gtk_tree_view_column_add_attribute (
+ column, cell_renderer, "text",
+ E_MAIL_ACCOUNT_STORE_COLUMN_DISPLAY_NAME);
+
+ cell_renderer = gtk_cell_renderer_text_new ();
+ g_object_set (cell_renderer, "text", _("Default"), NULL);
+ gtk_tree_view_column_pack_end (column, cell_renderer, FALSE);
+
+ gtk_tree_view_column_add_attribute (
+ column, cell_renderer, "visible",
+ E_MAIL_ACCOUNT_STORE_COLUMN_DEFAULT);
+
+ cell_renderer = gtk_cell_renderer_pixbuf_new ();
+ g_object_set (
+ cell_renderer, "icon-name", "emblem-default",
+ "stock-size", GTK_ICON_SIZE_MENU, NULL);
+ gtk_tree_view_column_pack_end (column, cell_renderer, FALSE);
+
+ gtk_tree_view_column_add_attribute (
+ column, cell_renderer, "visible",
+ E_MAIL_ACCOUNT_STORE_COLUMN_DEFAULT);
+
+ gtk_tree_view_append_column (tree_view, column);
+
+ /* Column: Type */
+
+ column = gtk_tree_view_column_new ();
+ gtk_tree_view_column_set_expand (column, FALSE);
+ gtk_tree_view_column_set_title (column, _("Type"));
+
+ cell_renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_column_pack_start (column, cell_renderer, TRUE);
+
+ gtk_tree_view_column_add_attribute (
+ column, cell_renderer, "text",
+ E_MAIL_ACCOUNT_STORE_COLUMN_BACKEND_NAME);
+
+ gtk_tree_view_append_column (tree_view, column);
+}
+
+static void
+mail_account_tree_view_drag_end (GtkWidget *widget,
+ GdkDragContext *context)
+{
+ GtkTreeModel *tree_model;
+
+ /* Chain up to parent's drag_end() method. */
+ GTK_WIDGET_CLASS (e_mail_account_tree_view_parent_class)->
+ drag_end (widget, context);
+
+ tree_model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));
+ g_return_if_fail (E_IS_MAIL_ACCOUNT_STORE (tree_model));
+
+ g_signal_emit_by_name (tree_model, "services-reordered", FALSE);
+}
+
+static void
+e_mail_account_tree_view_class_init (EMailAccountTreeViewClass *class)
+{
+ GObjectClass *object_class;
+ GtkWidgetClass *widget_class;
+
+ g_type_class_add_private (class, sizeof (EMailAccountTreeViewPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->constructed = mail_account_tree_view_constructed;
+
+ widget_class = GTK_WIDGET_CLASS (class);
+ widget_class->drag_end = mail_account_tree_view_drag_end;
+
+ signals[ENABLE] = g_signal_new (
+ "enable",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMailAccountTreeViewClass, enable),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[DISABLE] = g_signal_new (
+ "disable",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMailAccountTreeViewClass, disable),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+static void
+e_mail_account_tree_view_init (EMailAccountTreeView *tree_view)
+{
+ tree_view->priv = E_MAIL_ACCOUNT_TREE_VIEW_GET_PRIVATE (tree_view);
+}
+
+GtkWidget *
+e_mail_account_tree_view_new (EMailAccountStore *store)
+{
+ g_return_val_if_fail (E_IS_MAIL_ACCOUNT_STORE (store), NULL);
+
+ return g_object_new (
+ E_TYPE_MAIL_ACCOUNT_TREE_VIEW,
+ "model", store, NULL);
+}
+
+CamelService *
+e_mail_account_tree_view_get_selected_service (EMailAccountTreeView *tree_view)
+{
+ GtkTreeSelection *selection;
+ GtkTreeModel *tree_model;
+ GtkTreeIter iter;
+ CamelService *service;
+ GValue value = G_VALUE_INIT;
+ gint column;
+
+ g_return_val_if_fail (E_IS_MAIL_ACCOUNT_TREE_VIEW (tree_view), NULL);
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
+
+ if (!gtk_tree_selection_get_selected (selection, &tree_model, &iter))
+ return NULL;
+
+ /* By convention, "get" functions don't return a new object
+ * reference, so use gtk_tree_model_get_value() to avoid it.
+ * The caller can always reference the object if needed. */
+
+ column = E_MAIL_ACCOUNT_STORE_COLUMN_SERVICE;
+ gtk_tree_model_get_value (tree_model, &iter, column, &value);
+ service = g_value_get_object (&value);
+ g_value_unset (&value);
+
+ g_warn_if_fail (CAMEL_IS_SERVICE (service));
+
+ return service;
+}
+
+void
+e_mail_account_tree_view_set_selected_service (EMailAccountTreeView *tree_view,
+ CamelService *service)
+{
+ GtkTreeSelection *selection;
+ GtkTreeModel *tree_model;
+ GtkTreeIter iter;
+ gboolean iter_set;
+
+ g_return_if_fail (E_IS_MAIL_ACCOUNT_TREE_VIEW (tree_view));
+ g_return_if_fail (CAMEL_IS_SERVICE (service));
+
+ tree_model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view));
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
+
+ iter_set = gtk_tree_model_get_iter_first (tree_model, &iter);
+
+ while (iter_set) {
+ GValue value = G_VALUE_INIT;
+ CamelService *candidate;
+ gint column;
+
+ column = E_MAIL_ACCOUNT_STORE_COLUMN_SERVICE;
+ gtk_tree_model_get_value (tree_model, &iter, column, &value);
+ candidate = g_value_get_object (&value);
+ g_value_unset (&value);
+
+ g_warn_if_fail (CAMEL_IS_SERVICE (candidate));
+
+ if (service == candidate) {
+ gtk_tree_selection_select_iter (selection, &iter);
+ break;
+ }
+
+ iter_set = gtk_tree_model_iter_next (tree_model, &iter);
+ }
+}
diff --git a/mail/e-mail-account-tree-view.h b/mail/e-mail-account-tree-view.h
new file mode 100644
index 0000000000..e1fff8385a
--- /dev/null
+++ b/mail/e-mail-account-tree-view.h
@@ -0,0 +1,75 @@
+/*
+ * e-mail-account-tree-view.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef E_MAIL_ACCOUNT_TREE_VIEW_H
+#define E_MAIL_ACCOUNT_TREE_VIEW_H
+
+#include <gtk/gtk.h>
+#include <mail/e-mail-account-store.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_ACCOUNT_TREE_VIEW \
+ (e_mail_account_tree_view_get_type ())
+#define E_MAIL_ACCOUNT_TREE_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_ACCOUNT_TREE_VIEW, EMailAccountTreeView))
+#define E_MAIL_ACCOUNT_TREE_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_ACCOUNT_TREE_VIEW, EMailAccountTreeViewClass))
+#define E_IS_MAIL_ACCOUNT_TREE_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_ACCOUNT_TREE_VIEW))
+#define E_IS_MAIL_ACCOUNT_TREE_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_ACCOUNT_TREE_VIEW))
+#define E_MAIL_ACCOUNT_TREE_VIEW_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_ACCOUNT_TREE_VIEW, EMailAccountTreeViewClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailAccountTreeView EMailAccountTreeView;
+typedef struct _EMailAccountTreeViewClass EMailAccountTreeViewClass;
+typedef struct _EMailAccountTreeViewPrivate EMailAccountTreeViewPrivate;
+
+struct _EMailAccountTreeView {
+ GtkTreeView parent;
+ EMailAccountTreeViewPrivate *priv;
+};
+
+struct _EMailAccountTreeViewClass {
+ GtkTreeViewClass parent_class;
+
+ /* Signals */
+ void (*enable) (EMailAccountTreeView *tree_view);
+ void (*disable) (EMailAccountTreeView *tree_view);
+};
+
+GType e_mail_account_tree_view_get_type
+ (void) G_GNUC_CONST;
+GtkWidget * e_mail_account_tree_view_new
+ (EMailAccountStore *store);
+CamelService * e_mail_account_tree_view_get_selected_service
+ (EMailAccountTreeView *tree_view);
+void e_mail_account_tree_view_set_selected_service
+ (EMailAccountTreeView *tree_view,
+ CamelService *service);
+
+G_END_DECLS
+
+#endif /* E_MAIL_ACCOUNT_TREE_VIEW_H */
diff --git a/mail/e-mail-backend.c b/mail/e-mail-backend.c
index aedbdd2626..0640c7ff53 100644
--- a/mail/e-mail-backend.c
+++ b/mail/e-mail-backend.c
@@ -41,10 +41,8 @@
#include "shell/e-shell.h"
#include "mail/e-mail-folder-utils.h"
-#include "mail/e-mail-local.h"
#include "mail/e-mail-migrate.h"
#include "mail/e-mail-session.h"
-#include "mail/e-mail-store.h"
#include "mail/e-mail-store-utils.h"
#include "mail/em-event.h"
#include "mail/em-folder-tree-model.h"
@@ -71,16 +69,9 @@ 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,
@@ -135,18 +126,6 @@ mail_backend_store_operation_done_cb (CamelStore *store,
g_object_unref (activity);
}
-/* Helper for mail_backend_prepare_for_offline_cb() */
-static void
-mail_store_prepare_for_offline_cb (CamelService *service,
- EActivity *activity)
-{
- /* FIXME Not passing a GCancellable. */
- e_mail_store_go_offline (
- CAMEL_STORE (service), G_PRIORITY_DEFAULT, NULL,
- (GAsyncReadyCallback) mail_backend_store_operation_done_cb,
- g_object_ref (activity));
-}
-
static void
mail_backend_prepare_for_offline_cb (EShell *shell,
EActivity *activity,
@@ -154,6 +133,7 @@ mail_backend_prepare_for_offline_cb (EShell *shell,
{
GtkWindow *window;
EMailSession *session;
+ GList *list, *link;
gboolean synchronize = FALSE;
window = e_shell_get_active_window (shell);
@@ -170,20 +150,25 @@ mail_backend_prepare_for_offline_cb (EShell *shell,
CAMEL_SESSION (session), FALSE);
}
- e_mail_store_foreach (
- session, (GFunc) mail_store_prepare_for_offline_cb, activity);
-}
+ list = camel_session_list_services (CAMEL_SESSION (session));
-/* Helper for mail_backend_prepare_for_online_cb() */
-static void
-mail_store_prepare_for_online_cb (CamelService *service,
- EActivity *activity)
-{
- /* FIXME Not passing a GCancellable. */
- e_mail_store_go_online (
- CAMEL_STORE (service), G_PRIORITY_DEFAULT, NULL,
- (GAsyncReadyCallback) mail_backend_store_operation_done_cb,
- g_object_ref (activity));
+ for (link = list; link != NULL; link = g_list_next (link)) {
+ CamelService *service;
+
+ service = CAMEL_SERVICE (link->data);
+
+ if (!CAMEL_IS_STORE (service))
+ continue;
+
+ /* FIXME Not passing a GCancellable. */
+ e_mail_store_go_offline (
+ CAMEL_STORE (service), G_PRIORITY_DEFAULT,
+ NULL, (GAsyncReadyCallback)
+ mail_backend_store_operation_done_cb,
+ g_object_ref (activity));
+ }
+
+ g_list_free (list);
}
static void
@@ -192,17 +177,35 @@ mail_backend_prepare_for_online_cb (EShell *shell,
EMailBackend *backend)
{
EMailSession *session;
+ GList *list, *link;
session = e_mail_backend_get_session (backend);
camel_session_set_online (CAMEL_SESSION (session), TRUE);
- e_mail_store_foreach (
- session, (GFunc) mail_store_prepare_for_online_cb, activity);
+ list = camel_session_list_services (CAMEL_SESSION (session));
+
+ for (link = list; link != NULL; link = g_list_next (link)) {
+ CamelService *service;
+
+ service = CAMEL_SERVICE (link->data);
+
+ if (!CAMEL_IS_STORE (service))
+ continue;
+
+ /* FIXME Not passing a GCancellable. */
+ e_mail_store_go_online (
+ CAMEL_STORE (service), G_PRIORITY_DEFAULT,
+ NULL, (GAsyncReadyCallback)
+ mail_backend_store_operation_done_cb,
+ g_object_ref (activity));
+ }
+
+ g_list_free (link);
}
/* Helper for mail_backend_prepare_for_quit_cb() */
static void
-mail_backend_delete_junk (CamelStore *store,
+mail_backend_delete_junk (CamelService *service,
EMailBackend *backend)
{
CamelFolder *folder;
@@ -212,7 +215,8 @@ mail_backend_delete_junk (CamelStore *store,
guint ii;
/* FIXME camel_store_get_junk_folder_sync() may block. */
- folder = camel_store_get_junk_folder_sync (store, NULL, NULL);
+ folder = camel_store_get_junk_folder_sync (
+ CAMEL_STORE (service), NULL, NULL);
if (folder == NULL)
return;
@@ -232,24 +236,6 @@ mail_backend_delete_junk (CamelStore *store,
}
/* Helper for mail_backend_prepare_for_quit_cb() */
-static void
-mail_backend_final_sync (CamelStore *store,
- gpointer user_data)
-{
- struct {
- EActivity *activity;
- gboolean empty_trash;
- } *sync_data = user_data;
-
- /* FIXME Not passing a GCancellable. */
- /* FIXME This operation should be queued. */
- camel_store_synchronize (
- store, sync_data->empty_trash, G_PRIORITY_DEFAULT, NULL,
- (GAsyncReadyCallback) mail_backend_store_operation_done_cb,
- g_object_ref (sync_data->activity));
-}
-
-/* Helper for mail_backend_prepare_for_quit_cb() */
static gboolean
mail_backend_poll_to_quit (EActivity *activity)
{
@@ -273,14 +259,10 @@ mail_backend_prepare_for_quit_cb (EShell *shell,
{
EAccountList *account_list;
EMailSession *session;
+ GList *list, *link;
gboolean delete_junk;
gboolean empty_trash;
- struct {
- EActivity *activity;
- gboolean empty_trash;
- } sync_data;
-
session = e_mail_backend_get_session (backend);
delete_junk = e_mail_backend_delete_junk_policy_decision (backend);
@@ -296,15 +278,40 @@ mail_backend_prepare_for_quit_cb (EShell *shell,
/* Cancel all pending activities. */
mail_cancel_all ();
- if (delete_junk)
- e_mail_store_foreach (
- session, (GFunc) mail_backend_delete_junk, backend);
+ list = camel_session_list_services (CAMEL_SESSION (session));
+
+ if (delete_junk) {
+ for (link = list; link != NULL; link = g_list_next (link)) {
+ CamelService *service;
+
+ service = CAMEL_SERVICE (link->data);
+
+ if (!CAMEL_IS_STORE (service))
+ continue;
+
+ mail_backend_delete_junk (service, backend);
+ }
+ }
+
+ for (link = list; link != NULL; link = g_list_next (link)) {
+ CamelService *service;
- sync_data.activity = activity;
- sync_data.empty_trash = empty_trash;
+ service = CAMEL_SERVICE (link->data);
- e_mail_store_foreach (
- session, (GFunc) mail_backend_final_sync, &sync_data);
+ if (!CAMEL_IS_STORE (service))
+ continue;
+
+ /* FIXME Not passing a GCancellable. */
+ /* FIXME This operation should be queued. */
+ camel_store_synchronize (
+ CAMEL_STORE (service),
+ empty_trash, G_PRIORITY_DEFAULT,
+ NULL, (GAsyncReadyCallback)
+ mail_backend_store_operation_done_cb,
+ g_object_ref (activity));
+ }
+
+ g_list_free (list);
/* Now we poll until all activities are actually cancelled or finished.
* Reffing the activity delays quitting; the reference count
@@ -324,6 +331,8 @@ mail_backend_quit_requested_cb (EShell *shell,
EShellQuitReason reason,
EShellBackend *mail_shell_backend)
{
+ EMailBackend *backend;
+ EMailSession *session;
CamelFolder *folder;
GtkWindow *window;
gint response;
@@ -348,7 +357,11 @@ mail_backend_quit_requested_cb (EShell *shell,
/* Check Outbox for any unsent messages. */
- folder = e_mail_local_get_folder (E_MAIL_LOCAL_FOLDER_OUTBOX);
+ backend = E_MAIL_BACKEND (mail_shell_backend);
+ session = e_mail_backend_get_session (backend);
+
+ folder = e_mail_session_get_local_folder (
+ session, E_MAIL_LOCAL_FOLDER_OUTBOX);
if (folder == NULL)
return;
@@ -373,6 +386,7 @@ mail_backend_folder_deleted_cb (MailFolderCache *folder_cache,
CamelStoreClass *class;
EAccountList *account_list;
EIterator *iterator;
+ EMailSession *session;
const gchar *local_drafts_folder_uri;
const gchar *local_sent_folder_uri;
gboolean write_config = FALSE;
@@ -385,10 +399,15 @@ mail_backend_folder_deleted_cb (MailFolderCache *folder_cache,
class = CAMEL_STORE_GET_CLASS (store);
g_return_if_fail (class->compare_folder_name != NULL);
+ session = e_mail_backend_get_session (backend);
+
local_drafts_folder_uri =
- e_mail_local_get_folder_uri (E_MAIL_LOCAL_FOLDER_DRAFTS);
+ e_mail_session_get_local_folder_uri (
+ session, E_MAIL_LOCAL_FOLDER_DRAFTS);
+
local_sent_folder_uri =
- e_mail_local_get_folder_uri (E_MAIL_LOCAL_FOLDER_SENT);
+ e_mail_session_get_local_folder_uri (
+ session, E_MAIL_LOCAL_FOLDER_SENT);
uri = e_mail_folder_uri_build (store, folder_name);
@@ -744,7 +763,6 @@ mail_backend_constructed (GObject *object)
EMailBackendPrivate *priv;
EShell *shell;
EShellBackend *shell_backend;
- EMFolderTreeModel *folder_tree_model;
MailFolderCache *folder_cache;
priv = E_MAIL_BACKEND_GET_PRIVATE (object);
@@ -779,14 +797,6 @@ mail_backend_constructed (GObject *object)
* Give EAccountComboBox a CamelSession property. */
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 ();
-
- /* FIXME This is creating a circular reference. Perhaps the
- * should only hold a weak pointer to EMailBackend? */
- em_folder_tree_model_set_backend (
- folder_tree_model, E_MAIL_BACKEND (object));
-
g_signal_connect (
shell, "prepare-for-offline",
G_CALLBACK (mail_backend_prepare_for_offline_cb),
@@ -856,15 +866,6 @@ 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
@@ -965,11 +966,3 @@ e_mail_backend_submit_alert (EMailBackend *backend,
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 4d3cc10799..6d425197f3 100644
--- a/mail/e-mail-backend.h
+++ b/mail/e-mail-backend.h
@@ -67,10 +67,6 @@ 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);
@@ -83,9 +79,6 @@ 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-local.c b/mail/e-mail-local.c
deleted file mode 100644
index 28d174e303..0000000000
--- a/mail/e-mail-local.c
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * e-mail-local.c
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "e-mail-local.h"
-
-#include <glib/gi18n.h>
-
-#include "e-mail-folder-utils.h"
-
-#define CHECK_LOCAL_FOLDER_TYPE(type) \
- ((type) < G_N_ELEMENTS (default_local_folders))
-
-/* The array elements correspond to EMailLocalFolder. */
-static struct {
- const gchar *display_name;
- CamelFolder *folder;
- gchar *folder_uri;
-} default_local_folders[] = {
- { N_("Inbox") },
- { N_("Drafts") },
- { N_("Outbox") },
- { N_("Sent") },
- { N_("Templates") },
- { "Inbox" } /* "always local" inbox */
-};
-
-static CamelStore *local_store;
-static gboolean mail_local_initialized = FALSE;
-
-void
-e_mail_local_init (EMailSession *session,
- const gchar *data_dir)
-{
- CamelSettings *settings;
- CamelService *service;
- gchar *path;
- gint ii;
- GError *error = NULL;
-
- if (mail_local_initialized)
- return;
-
- g_return_if_fail (E_IS_MAIL_SESSION (session));
- g_return_if_fail (data_dir != NULL);
-
- mail_local_initialized = TRUE;
-
- service = camel_session_add_service (
- CAMEL_SESSION (session),
- "local", "maildir",
- CAMEL_PROVIDER_STORE, &error);
-
- camel_service_set_display_name (service, _("On This Computer"));
-
- settings = camel_service_get_settings (service);
-
- path = g_build_filename (data_dir, "local", NULL);
- g_object_set (settings, "path", path, NULL);
- g_free (path);
-
- /* Shouldn't need to worry about other mail applications
- * altering files in our local mail store. */
- g_object_set (service, "need-summary-check", FALSE, NULL);
-
- if (error != NULL)
- goto fail;
-
- /* Populate the rest of the default_local_folders array. */
- for (ii = 0; ii < G_N_ELEMENTS (default_local_folders); ii++) {
- const gchar *display_name;
-
- display_name = default_local_folders[ii].display_name;
-
- default_local_folders[ii].folder_uri =
- e_mail_folder_uri_build (
- CAMEL_STORE (service), display_name);
-
- /* FIXME camel_store_get_folder() may block. */
- if (!strcmp (display_name, "Inbox"))
- default_local_folders[ii].folder =
- camel_store_get_inbox_folder_sync (
- CAMEL_STORE (service), NULL, &error);
- else
- default_local_folders[ii].folder =
- camel_store_get_folder_sync (
- CAMEL_STORE (service), display_name,
- CAMEL_STORE_FOLDER_CREATE, NULL, &error);
-
- if (error != NULL) {
- g_critical ("%s", error->message);
- g_clear_error (&error);
- }
- }
-
- local_store = g_object_ref (service);
-
- return;
-
-fail:
- g_critical (
- "Could not initialize local store/folder: %s",
- error->message);
-
- g_error_free (error);
-}
-
-CamelFolder *
-e_mail_local_get_folder (EMailLocalFolder type)
-{
- g_return_val_if_fail (mail_local_initialized, NULL);
- g_return_val_if_fail (CHECK_LOCAL_FOLDER_TYPE (type), NULL);
-
- return default_local_folders[type].folder;
-}
-
-const gchar *
-e_mail_local_get_folder_uri (EMailLocalFolder type)
-{
- g_return_val_if_fail (mail_local_initialized, NULL);
- g_return_val_if_fail (CHECK_LOCAL_FOLDER_TYPE (type), NULL);
-
- return default_local_folders[type].folder_uri;
-}
-
-CamelStore *
-e_mail_local_get_store (void)
-{
- g_return_val_if_fail (mail_local_initialized, NULL);
- g_return_val_if_fail (CAMEL_IS_STORE (local_store), NULL);
-
- return local_store;
-}
diff --git a/mail/e-mail-local.h b/mail/e-mail-local.h
deleted file mode 100644
index 282a0feacb..0000000000
--- a/mail/e-mail-local.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * e-mail-local.h
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef E_MAIL_LOCAL_H
-#define E_MAIL_LOCAL_H
-
-#include <camel/camel.h>
-#include <mail/e-mail-enums.h>
-#include <mail/e-mail-session.h>
-
-G_BEGIN_DECLS
-
-void e_mail_local_init (EMailSession *session,
- const gchar *data_dir);
-CamelFolder * e_mail_local_get_folder (EMailLocalFolder type);
-const gchar * e_mail_local_get_folder_uri (EMailLocalFolder type);
-CamelStore * e_mail_local_get_store (void);
-
-G_END_DECLS
-
-#endif /* E_MAIL_LOCAL_H */
diff --git a/mail/e-mail-migrate.c b/mail/e-mail-migrate.c
index f3ce503012..fdf5684e0a 100644
--- a/mail/e-mail-migrate.c
+++ b/mail/e-mail-migrate.c
@@ -64,8 +64,6 @@
#include "e-mail-backend.h"
#include "e-mail-folder-utils.h"
-#include "e-mail-local.h"
-#include "e-mail-store.h"
#include "em-utils.h"
#define d(x) x
@@ -277,7 +275,7 @@ emm_setup_initial (const gchar *data_dir)
d(printf("Setting up initial mail tree\n"));
- base = g_build_filename(data_dir, "local", NULL);
+ base = g_build_filename (data_dir, "local", NULL);
if (g_mkdir_with_parents (base, 0700) == -1 && errno != EEXIST) {
g_free (base);
return FALSE;
@@ -671,7 +669,7 @@ create_mbox_account (EShellBackend *shell_backend,
{
EMailBackend *mail_backend;
EMailSession *mail_session;
- CamelStore *store;
+ CamelService *service;
CamelURL *url;
EAccountList *accounts;
EAccount *account;
@@ -682,9 +680,6 @@ create_mbox_account (EShellBackend *shell_backend,
mail_session = e_mail_backend_get_session (mail_backend);
data_dir = e_shell_backend_get_data_dir (shell_backend);
- /* Initialize the mail stores early so we can add a new one. */
- e_mail_store_init (mail_session, data_dir);
-
account = e_account_new ();
account->enabled = TRUE;
@@ -716,15 +711,20 @@ create_mbox_account (EShellBackend *shell_backend,
goto exit;
}
+ /* This will also add it to the EMailSession. */
e_account_list_add (accounts, account);
- store = e_mail_store_add_by_account (mail_session, account);
- folder_uri = e_mail_folder_uri_build (store, "Sent");
+ service = camel_session_get_service (
+ CAMEL_SESSION (mail_session), account->uid);
+
+ folder_uri = e_mail_folder_uri_build (
+ CAMEL_STORE (service), "Sent");
e_account_set_string (
account, E_ACCOUNT_SENT_FOLDER_URI, folder_uri);
g_free (folder_uri);
- folder_uri = e_mail_folder_uri_build (store, "Drafts");
+ folder_uri = e_mail_folder_uri_build (
+ CAMEL_STORE (service), "Drafts");
e_account_set_string (
account, E_ACCOUNT_DRAFTS_FOLDER_URI, folder_uri);
g_free (folder_uri);
@@ -743,6 +743,8 @@ exit:
static void
change_sent_and_drafts_local_folders (EShellBackend *shell_backend)
{
+ EMailBackend *backend;
+ EMailSession *session;
EAccountList *accounts;
EIterator *iter;
const gchar *data_dir;
@@ -754,6 +756,9 @@ change_sent_and_drafts_local_folders (EShellBackend *shell_backend)
if (!accounts)
return;
+ backend = E_MAIL_BACKEND (shell_backend);
+ session = e_mail_backend_get_session (backend);
+
data_dir = e_shell_backend_get_data_dir (shell_backend);
tmp_uri = g_strconcat ("mbox:", data_dir, "/", "local", NULL);
@@ -797,8 +802,8 @@ change_sent_and_drafts_local_folders (EShellBackend *shell_backend)
changed = TRUE;
e_account_set_string (
account, E_ACCOUNT_DRAFTS_FOLDER_URI,
- e_mail_local_get_folder_uri (
- E_MAIL_LOCAL_FOLDER_DRAFTS));
+ e_mail_session_get_local_folder_uri (
+ session, E_MAIL_LOCAL_FOLDER_DRAFTS));
}
uri = e_account_get_string (account, E_ACCOUNT_SENT_FOLDER_URI);
@@ -806,8 +811,8 @@ change_sent_and_drafts_local_folders (EShellBackend *shell_backend)
changed = TRUE;
e_account_set_string (
account, E_ACCOUNT_SENT_FOLDER_URI,
- e_mail_local_get_folder_uri (
- E_MAIL_LOCAL_FOLDER_SENT));
+ e_mail_session_get_local_folder_uri (
+ session, E_MAIL_LOCAL_FOLDER_SENT));
}
}
diff --git a/mail/e-mail-reader-utils.c b/mail/e-mail-reader-utils.c
index a58eb1f441..ffca3d89ac 100644
--- a/mail/e-mail-reader-utils.c
+++ b/mail/e-mail-reader-utils.c
@@ -40,7 +40,6 @@
#include "mail/e-mail-backend.h"
#include "mail/e-mail-browser.h"
#include "mail/e-mail-folder-utils.h"
-#include "mail/e-mail-local.h"
#include "mail/em-composer-utils.h"
#include "mail/em-format-html-print.h"
#include "mail/em-utils.h"
@@ -191,15 +190,16 @@ void
e_mail_reader_delete_folder (EMailReader *reader,
CamelFolder *folder)
{
- CamelStore *local_store;
- CamelStore *parent_store;
EMailBackend *backend;
EMailSession *session;
EAlertSink *alert_sink;
+ CamelStore *parent_store;
MailFolderCache *folder_cache;
GtkWindow *parent = e_shell_get_active_window (NULL);
GtkWidget *dialog;
+ gboolean store_is_local;
const gchar *full_name;
+ const gchar *uid;
CamelFolderInfoFlags flags = 0;
gboolean have_flags;
@@ -209,14 +209,16 @@ e_mail_reader_delete_folder (EMailReader *reader,
full_name = camel_folder_get_full_name (folder);
parent_store = camel_folder_get_parent_store (folder);
+ uid = camel_service_get_uid (CAMEL_SERVICE (parent_store));
+ store_is_local = (g_strcmp0 (uid, E_MAIL_SESSION_LOCAL_UID) == 0);
+
backend = e_mail_reader_get_backend (reader);
session = e_mail_backend_get_session (backend);
- local_store = e_mail_local_get_store ();
alert_sink = e_mail_reader_get_alert_sink (reader);
folder_cache = e_mail_session_get_folder_cache (session);
- if (parent_store == local_store &&
+ if (store_is_local &&
mail_reader_is_special_local_folder (full_name)) {
e_mail_backend_submit_alert (
backend, "mail:no-delete-special-folder",
diff --git a/mail/e-mail-session-utils.c b/mail/e-mail-session-utils.c
index eca58bcad0..f1c27a3425 100644
--- a/mail/e-mail-session-utils.c
+++ b/mail/e-mail-session-utils.c
@@ -27,7 +27,6 @@
#include <glib/gi18n-lib.h>
#include <mail/mail-tools.h>
-#include <mail/e-mail-local.h>
#include <mail/e-mail-folder-utils.h>
#include <e-util/e-account-utils.h>
#include <filter/e-filter-rule.h>
@@ -508,7 +507,9 @@ mail_session_send_to_thread (GSimpleAsyncResult *simple,
/* Append the sent message to a Sent folder. */
- local_sent_folder = e_mail_local_get_folder (E_MAIL_LOCAL_FOLDER_SENT);
+ local_sent_folder =
+ e_mail_session_get_local_folder (
+ session, E_MAIL_LOCAL_FOLDER_SENT);
/* Try to extract a CamelFolder from the Sent folder URI. */
if (context->sent_folder_uri != NULL) {
diff --git a/mail/e-mail-session.c b/mail/e-mail-session.c
index 03f4961206..6d04c2c23d 100644
--- a/mail/e-mail-session.c
+++ b/mail/e-mail-session.c
@@ -52,9 +52,9 @@
#include "e-util/e-alert-dialog.h"
#include "e-util/e-util-private.h"
+#include "e-mail-account-store.h"
#include "e-mail-folder-utils.h"
#include "e-mail-junk-filter.h"
-#include "e-mail-local.h"
#include "e-mail-session.h"
#include "em-composer-utils.h"
#include "em-filter-context.h"
@@ -71,13 +71,26 @@
((obj), E_TYPE_MAIL_SESSION, EMailSessionPrivate))
typedef struct _AsyncContext AsyncContext;
+typedef struct _SourceContext SourceContext;
struct _EMailSessionPrivate {
+ EMailAccountStore *account_store;
MailFolderCache *folder_cache;
+ EAccountList *account_list;
+ gulong account_added_handler_id;
+ gulong account_changed_handler_id;
+
+ CamelStore *local_store;
+ CamelStore *vfolder_store;
+
FILE *filter_logfile;
GHashTable *junk_filters;
EProxy *proxy;
+
+ /* Local folder cache. */
+ GPtrArray *local_folders;
+ GPtrArray *local_folder_uris;
};
struct _AsyncContext {
@@ -90,10 +103,27 @@ struct _AsyncContext {
CamelFolder *folder;
};
+struct _SourceContext {
+ EMailSession *session;
+ CamelService *service;
+};
+
enum {
PROP_0,
+ PROP_ACCOUNT_STORE,
PROP_FOLDER_CACHE,
- PROP_JUNK_FILTER_NAME
+ PROP_JUNK_FILTER_NAME,
+ PROP_LOCAL_STORE,
+ PROP_VFOLDER_STORE
+};
+
+static const gchar *local_folder_names[E_MAIL_NUM_LOCAL_FOLDERS] = {
+ N_("Inbox"), /* E_MAIL_LOCAL_FOLDER_INBOX */
+ N_("Drafts"), /* E_MAIL_LOCAL_FOLDER_DRAFTS */
+ N_("Outbox"), /* E_MAIL_LOCAL_FOLDER_OUTBOX */
+ N_("Sent"), /* E_MAIL_LOCAL_FOLDER_SENT */
+ N_("Templates"), /* E_MAIL_LOCAL_FOLDER_TEMPLATES */
+ "Inbox" /* E_MAIL_LOCAL_FOLDER_LOCAL_INBOX */
};
static gchar *mail_data_dir;
@@ -463,6 +493,18 @@ async_context_free (AsyncContext *context)
g_slice_free (AsyncContext, context);
}
+static void
+source_context_free (SourceContext *context)
+{
+ if (context->session != NULL)
+ g_object_unref (context->session);
+
+ if (context->service != NULL)
+ g_object_unref (context->service);
+
+ g_slice_free (SourceContext, context);
+}
+
static gchar *
mail_session_make_key (CamelService *service,
const gchar *item)
@@ -553,6 +595,270 @@ mail_session_set_junk_filter_name (EMailSession *session,
}
static void
+mail_session_add_by_account (EMailSession *session,
+ EAccount *account)
+{
+ CamelService *service = NULL;
+ CamelProvider *provider;
+ CamelURL *url;
+ gboolean transport_only;
+ GError *error = NULL;
+
+ /* check whether it's transport-only accounts */
+ transport_only =
+ (account->source == NULL) ||
+ (account->source->url == NULL) ||
+ (*account->source->url == '\0');
+ if (transport_only)
+ goto handle_transport;
+
+ /* Load the service, but don't connect. Check its provider,
+ * and if this belongs in the folder tree model, add it. */
+
+ url = camel_url_new (account->source->url, NULL);
+ if (url != NULL) {
+ provider = camel_provider_get (url->protocol, NULL);
+ camel_url_free (url);
+ } else {
+ provider = NULL;
+ }
+
+ if (provider == NULL) {
+ /* In case we do not have a provider here, we handle
+ * the special case of having multiple mail identities
+ * eg. a dummy account having just SMTP server defined */
+ goto handle_transport;
+ }
+
+ service = camel_session_add_service (
+ CAMEL_SESSION (session),
+ account->uid, provider->protocol,
+ CAMEL_PROVIDER_STORE, &error);
+
+ if (error != NULL) {
+ g_warning (
+ "Failed to add service: %s: %s",
+ account->name, error->message);
+ g_error_free (error);
+ return;
+ }
+
+ camel_service_set_display_name (service, account->name);
+
+handle_transport:
+
+ /* While we're at it, add the account's transport (if it has one)
+ * to the CamelSession. The transport's UID is a kludge for now.
+ * We take the EAccount's UID and tack on "-transport". */
+
+ if (account->transport) {
+ GError *transport_error = NULL;
+
+ url = camel_url_new (
+ account->transport->url,
+ &transport_error);
+
+ if (url != NULL) {
+ provider = camel_provider_get (
+ url->protocol, &transport_error);
+ camel_url_free (url);
+ } else
+ provider = NULL;
+
+ if (provider != NULL) {
+ gchar *transport_uid;
+
+ transport_uid = g_strconcat (
+ account->uid, "-transport", NULL);
+
+ camel_session_add_service (
+ CAMEL_SESSION (session),
+ transport_uid, provider->protocol,
+ CAMEL_PROVIDER_TRANSPORT, &transport_error);
+
+ g_free (transport_uid);
+ }
+
+ if (transport_error) {
+ g_warning (
+ "%s: Failed to add transport service: %s",
+ G_STRFUNC, transport_error->message);
+ g_error_free (transport_error);
+ }
+ }
+}
+
+static void
+mail_session_account_added_cb (EAccountList *account_list,
+ EAccount *account,
+ EMailSession *session)
+{
+ mail_session_add_by_account (session, account);
+}
+
+static void
+mail_session_account_changed_cb (EAccountList *account_list,
+ EAccount *account,
+ EMailSession *session)
+{
+ EMFolderTreeModel *folder_tree_model;
+ CamelService *service;
+
+ service = camel_session_get_service (
+ CAMEL_SESSION (session), account->uid);
+
+ if (!CAMEL_IS_STORE (service))
+ return;
+
+ /* Update the display name of the corresponding CamelStore.
+ * EMailAccountStore listens for "notify" signals from each
+ * service so it will detect this and update the model.
+ *
+ * XXX If EAccount defined GObject properties we could just
+ * bind EAccount:name to CamelService:display-name and
+ * be done with it. Oh well.
+ */
+
+ camel_service_set_display_name (service, account->name);
+
+ /* Remove the store from the folder tree model and, if the
+ * account is still enabled, re-add it. Easier than trying
+ * to update the model with the store in place.
+ *
+ * em_folder_tree_model_add_store() already knows which types
+ * of stores to disregard, so we don't have to deal with that
+ * here. */
+
+ folder_tree_model = em_folder_tree_model_get_default ();
+
+ em_folder_tree_model_remove_store (
+ folder_tree_model, CAMEL_STORE (service));
+
+ if (account->enabled)
+ em_folder_tree_model_add_store (
+ folder_tree_model, CAMEL_STORE (service));
+}
+
+static gboolean
+mail_session_add_service_cb (SourceContext *context)
+{
+ EMailAccountStore *store;
+
+ store = e_mail_session_get_account_store (context->session);
+ e_mail_account_store_add_service (store, context->service);
+
+ return FALSE;
+}
+
+static void
+mail_session_add_local_store (EMailSession *session)
+{
+ CamelLocalSettings *local_settings;
+ CamelSession *camel_session;
+ CamelSettings *settings;
+ CamelService *service;
+ const gchar *data_dir;
+ gchar *path;
+ gint ii;
+ GError *error = NULL;
+
+ camel_session = CAMEL_SESSION (session);
+
+ service = camel_session_add_service (
+ camel_session, E_MAIL_SESSION_LOCAL_UID,
+ "maildir", CAMEL_PROVIDER_STORE, &error);
+
+ /* XXX One could argue this is a fatal error
+ * since we depend on it in so many places. */
+ 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, _("On This Computer"));
+
+ settings = camel_service_get_settings (service);
+ local_settings = CAMEL_LOCAL_SETTINGS (settings);
+ data_dir = camel_session_get_user_data_dir (camel_session);
+
+ path = g_build_filename (data_dir, E_MAIL_SESSION_LOCAL_UID, NULL);
+ camel_local_settings_set_path (local_settings, path);
+ g_free (path);
+
+ /* Shouldn't need to worry about other mail applications
+ * altering files in our local mail store. */
+ g_object_set (service, "need-summary-check", FALSE, NULL);
+
+ /* Populate the local folder cache. */
+ for (ii = 0; ii < E_MAIL_NUM_LOCAL_FOLDERS; ii++) {
+ CamelFolder *folder;
+ gchar *folder_uri;
+ const gchar *display_name;
+ GError *error = NULL;
+
+ display_name = local_folder_names[ii];
+
+ /* XXX This blocks but should be fast. */
+ if (ii == E_MAIL_LOCAL_FOLDER_LOCAL_INBOX)
+ folder = camel_store_get_inbox_folder_sync (
+ CAMEL_STORE (service), NULL, &error);
+ else
+ folder = camel_store_get_folder_sync (
+ CAMEL_STORE (service), display_name,
+ CAMEL_STORE_FOLDER_CREATE, NULL, &error);
+
+ folder_uri = e_mail_folder_uri_build (
+ CAMEL_STORE (service), display_name);
+
+ /* The arrays take ownership of the items added. */
+ g_ptr_array_add (session->priv->local_folders, folder);
+ g_ptr_array_add (session->priv->local_folder_uris, folder_uri);
+
+ if (error != NULL) {
+ g_critical ("%s: %s", G_STRFUNC, error->message);
+ g_error_free (error);
+ }
+ }
+
+ session->priv->local_store = g_object_ref (service);
+}
+
+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_set_property (GObject *object,
guint property_id,
const GValue *value,
@@ -576,6 +882,13 @@ mail_session_get_property (GObject *object,
GParamSpec *pspec)
{
switch (property_id) {
+ case PROP_ACCOUNT_STORE:
+ g_value_set_object (
+ value,
+ e_mail_session_get_account_store (
+ E_MAIL_SESSION (object)));
+ return;
+
case PROP_FOLDER_CACHE:
g_value_set_object (
value,
@@ -589,6 +902,20 @@ mail_session_get_property (GObject *object,
mail_session_get_junk_filter_name (
E_MAIL_SESSION (object)));
return;
+
+ case PROP_LOCAL_STORE:
+ g_value_set_object (
+ value,
+ 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);
@@ -601,11 +928,41 @@ mail_session_dispose (GObject *object)
priv = E_MAIL_SESSION_GET_PRIVATE (object);
+ if (priv->account_store != NULL) {
+ e_mail_account_store_clear (priv->account_store);
+ g_object_unref (priv->account_store);
+ priv->account_store = NULL;
+ }
+
if (priv->folder_cache != NULL) {
g_object_unref (priv->folder_cache);
priv->folder_cache = NULL;
}
+ if (priv->account_list != NULL) {
+ g_signal_handler_disconnect (
+ priv->account_list,
+ priv->account_added_handler_id);
+ g_signal_handler_disconnect (
+ priv->account_list,
+ priv->account_changed_handler_id);
+ g_object_unref (priv->account_list);
+ priv->account_list = NULL;
+ }
+
+ if (priv->local_store != NULL) {
+ g_object_unref (priv->local_store);
+ 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);
+
/* Chain up to parent's dispose() method. */
G_OBJECT_CLASS (e_mail_session_parent_class)->dispose (object);
}
@@ -620,6 +977,9 @@ mail_session_finalize (GObject *object)
g_hash_table_destroy (priv->junk_filters);
g_object_unref (priv->proxy);
+ g_ptr_array_free (priv->local_folders, TRUE);
+ g_ptr_array_free (priv->local_folder_uris, TRUE);
+
g_free (mail_data_dir);
g_free (mail_config_dir);
@@ -642,17 +1002,87 @@ mail_session_notify (GObject *object,
static void
mail_session_constructed (GObject *object)
{
- EMailSessionPrivate *priv;
+ EMFolderTreeModel *folder_tree_model;
+ EMailSession *session;
EExtensible *extensible;
GType extension_type;
- GList *list, *iter;
+ GList *list, *link;
GSettings *settings;
+ EAccountList *account_list;
+ EIterator *iter;
+ EAccount *account;
+ gulong handler_id;
- priv = E_MAIL_SESSION_GET_PRIVATE (object);
+ session = E_MAIL_SESSION (object);
/* Chain up to parent's constructed() method. */
G_OBJECT_CLASS (e_mail_session_parent_class)->constructed (object);
+ account_list = e_get_account_list ();
+ session->priv->account_list = g_object_ref (account_list);
+
+ session->priv->account_store = e_mail_account_store_new (session);
+
+ /* This must be created after the account store. */
+ session->priv->folder_cache = mail_folder_cache_new (session);
+
+ /* XXX Make sure the folder tree model is created before we
+ * add built-in CamelStores so it gets signals from the
+ * EMailAccountStore.
+ *
+ * XXX This is creating a circular reference. Perhaps the
+ * model should only hold a weak pointer to EMailSession?
+ *
+ * FIXME EMailSession should just own the default instance.
+ */
+ folder_tree_model = em_folder_tree_model_get_default ();
+ em_folder_tree_model_set_session (folder_tree_model, session);
+
+ /* Add built-in CamelStores. */
+
+ mail_session_add_local_store (session);
+ mail_session_add_vfolder_store (session);
+
+ /* Load user-defined mail accounts. */
+
+ iter = e_list_get_iterator (E_LIST (account_list));
+
+ while (e_iterator_is_valid (iter)) {
+ /* XXX EIterator misuses const. */
+ account = (EAccount *) e_iterator_get (iter);
+
+ if (account->enabled)
+ mail_session_add_by_account (session, account);
+
+ e_iterator_next (iter);
+ }
+
+ g_object_unref (iter);
+
+ /* Initialize which account is default. */
+
+ account = e_get_default_account ();
+ if (account != NULL) {
+ CamelService *service;
+
+ service = camel_session_get_service (
+ CAMEL_SESSION (session), account->uid);
+ e_mail_account_store_set_default_service (
+ session->priv->account_store, service);
+ }
+
+ /* Listen for account list updates. */
+
+ handler_id = g_signal_connect (
+ account_list, "account-added",
+ G_CALLBACK (mail_session_account_added_cb), session);
+ session->priv->account_added_handler_id = handler_id;
+
+ handler_id = g_signal_connect (
+ account_list, "account-changed",
+ G_CALLBACK (mail_session_account_changed_cb), session);
+ session->priv->account_changed_handler_id = handler_id;
+
extensible = E_EXTENSIBLE (object);
e_extensible_load_extensions (extensible);
@@ -661,11 +1091,11 @@ mail_session_constructed (GObject *object)
extension_type = E_TYPE_MAIL_JUNK_FILTER;
list = e_extensible_list_extensions (extensible, extension_type);
- for (iter = list; iter != NULL; iter = g_list_next (iter)) {
+ for (link = list; link != NULL; link = g_list_next (link)) {
EMailJunkFilter *junk_filter;
EMailJunkFilterClass *class;
- junk_filter = E_MAIL_JUNK_FILTER (iter->data);
+ junk_filter = E_MAIL_JUNK_FILTER (link->data);
class = E_MAIL_JUNK_FILTER_GET_CLASS (junk_filter);
if (!CAMEL_IS_JUNK_FILTER (junk_filter)) {
@@ -693,17 +1123,21 @@ mail_session_constructed (GObject *object)
/* No need to reference the EMailJunkFilter since
* EMailSession owns the reference to it already. */
g_hash_table_insert (
- priv->junk_filters,
+ session->priv->junk_filters,
(gpointer) class->filter_name,
junk_filter);
}
g_list_free (list);
- /* Bind the "junk-default-plugin" GSettings key to our "junk-filter-name" property. */
+ /* Bind the "junk-default-plugin" GSettings
+ * key to our "junk-filter-name" property. */
settings = g_settings_new ("org.gnome.evolution.mail");
- g_settings_bind (settings, "junk-default-plugin", object, "junk-filter-name", G_SETTINGS_BIND_DEFAULT);
+ g_settings_bind (
+ settings, "junk-default-plugin",
+ object, "junk-filter-name",
+ G_SETTINGS_BIND_DEFAULT);
g_object_unref (settings);
}
@@ -765,6 +1199,22 @@ mail_session_add_service (CamelSession *session,
}
}
+ /* Inform the EMailAccountStore of the new CamelService
+ * from an idle callback so the service has a chance to
+ * fully initialize first. */
+ if (CAMEL_IS_STORE (service)) {
+ SourceContext *context;
+
+ context = g_slice_new0 (SourceContext);
+ context->session = g_object_ref (session);
+ context->service = g_object_ref (service);
+
+ g_idle_add_full (
+ G_PRIORITY_DEFAULT_IDLE,
+ (GSourceFunc) mail_session_add_service_cb,
+ context, (GDestroyNotify) source_context_free);
+ }
+
return service;
}
@@ -1073,7 +1523,8 @@ mail_session_forward_to (CamelSession *session,
/* and send it */
info = camel_message_info_new (NULL);
- out_folder = e_mail_local_get_folder (E_MAIL_LOCAL_FOLDER_OUTBOX);
+ out_folder = e_mail_session_get_local_folder (
+ E_MAIL_SESSION (session), E_MAIL_LOCAL_FOLDER_OUTBOX);
camel_message_info_set_flags (
info, CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN);
@@ -1300,6 +1751,28 @@ e_mail_session_class_init (EMailSessionClass *class)
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_LOCAL_STORE,
+ g_param_spec_object (
+ "local-store",
+ "Local Store",
+ "Built-in local store",
+ CAMEL_TYPE_STORE,
+ 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));
}
static void
@@ -1308,11 +1781,17 @@ e_mail_session_init (EMailSession *session)
GSettings *settings;
session->priv = E_MAIL_SESSION_GET_PRIVATE (session);
- session->priv->folder_cache = mail_folder_cache_new ();
session->priv->junk_filters = g_hash_table_new (
(GHashFunc) g_str_hash, (GEqualFunc) g_str_equal);
session->priv->proxy = e_proxy_new ();
+ session->priv->local_folders =
+ g_ptr_array_new_with_free_func (
+ (GDestroyNotify) g_object_unref);
+ session->priv->local_folder_uris =
+ g_ptr_array_new_with_free_func (
+ (GDestroyNotify) g_free);
+
/* Initialize the EAccount setup. */
e_account_writable (NULL, E_ACCOUNT_SOURCE_SAVE_PASSWD);
@@ -1348,6 +1827,14 @@ e_mail_session_new (void)
NULL);
}
+EMailAccountStore *
+e_mail_session_get_account_store (EMailSession *session)
+{
+ g_return_val_if_fail (E_IS_MAIL_SESSION (session), NULL);
+
+ return session->priv->account_store;
+}
+
MailFolderCache *
e_mail_session_get_folder_cache (EMailSession *session)
{
@@ -1356,6 +1843,58 @@ e_mail_session_get_folder_cache (EMailSession *session)
return session->priv->folder_cache;
}
+CamelStore *
+e_mail_session_get_local_store (EMailSession *session)
+{
+ g_return_val_if_fail (E_IS_MAIL_SESSION (session), NULL);
+
+ return session->priv->local_store;
+}
+
+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;
+}
+
+CamelFolder *
+e_mail_session_get_local_folder (EMailSession *session,
+ EMailLocalFolder type)
+{
+ GPtrArray *local_folders;
+ CamelFolder *folder;
+
+ g_return_val_if_fail (E_IS_MAIL_SESSION (session), NULL);
+
+ local_folders = session->priv->local_folders;
+ g_return_val_if_fail (type < local_folders->len, NULL);
+
+ folder = g_ptr_array_index (local_folders, type);
+ g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL);
+
+ return folder;
+}
+
+const gchar *
+e_mail_session_get_local_folder_uri (EMailSession *session,
+ EMailLocalFolder type)
+{
+ GPtrArray *local_folder_uris;
+ const gchar *folder_uri;
+
+ g_return_val_if_fail (E_IS_MAIL_SESSION (session), NULL);
+
+ local_folder_uris = session->priv->local_folder_uris;
+ g_return_val_if_fail (type < local_folder_uris->len, NULL);
+
+ folder_uri = g_ptr_array_index (local_folder_uris, type);
+ g_return_val_if_fail (folder_uri != NULL, NULL);
+
+ return folder_uri;
+}
+
GList *
e_mail_session_get_available_junk_filters (EMailSession *session)
{
diff --git a/mail/e-mail-session.h b/mail/e-mail-session.h
index 165b335a19..e10e3c3d1f 100644
--- a/mail/e-mail-session.h
+++ b/mail/e-mail-session.h
@@ -26,6 +26,8 @@
#define E_MAIL_SESSION_H
#include <camel/camel.h>
+#include <mail/e-mail-enums.h>
+#include <mail/e-mail-account-store.h>
#include <mail/mail-folder-cache.h>
/* Standard GObject macros */
@@ -47,8 +49,15 @@
(G_TYPE_INSTANCE_GET_CLASS \
((obj), E_TYPE_MAIL_SESSION, EMailSessionClass))
+/* Built-in CamelServices */
+#define E_MAIL_SESSION_LOCAL_UID "local" /* "On This Computer" */
+#define E_MAIL_SESSION_VFOLDER_UID "vfolder" /* "Search Folders" */
+
G_BEGIN_DECLS
+/* Avoids a circular dependency. */
+typedef struct _EMailAccountStore EMailAccountStore;
+
typedef struct _EMailSession EMailSession;
typedef struct _EMailSessionClass EMailSessionClass;
typedef struct _EMailSessionPrivate EMailSessionPrivate;
@@ -64,8 +73,19 @@ struct _EMailSessionClass {
GType e_mail_session_get_type (void);
EMailSession * e_mail_session_new (void);
+EMailAccountStore *
+ e_mail_session_get_account_store
+ (EMailSession *session);
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
+ (EMailSession *session,
+ EMailLocalFolder type);
GList * e_mail_session_get_available_junk_filters
(EMailSession *session);
CamelFolder * e_mail_session_get_inbox_sync (EMailSession *session,
diff --git a/mail/e-mail-sidebar.c b/mail/e-mail-sidebar.c
index 35048f8293..9a935819c8 100644
--- a/mail/e-mail-sidebar.c
+++ b/mail/e-mail-sidebar.c
@@ -28,7 +28,6 @@
#include <string.h>
#include <camel/camel.h>
-#include "mail/e-mail-local.h"
#include "mail/em-utils.h"
#define E_MAIL_SIDEBAR_GET_PRIVATE(obj) \
@@ -338,6 +337,8 @@ mail_sidebar_check_state (EMailSidebar *sidebar)
GtkTreeIter iter;
CamelStore *store;
gchar *full_name;
+ const gchar *uid;
+ gboolean store_is_local;
gboolean allows_children = TRUE;
gboolean can_delete = TRUE;
gboolean is_junk = FALSE;
@@ -360,12 +361,12 @@ mail_sidebar_check_state (EMailSidebar *sidebar)
COL_BOOL_IS_STORE, &is_store,
COL_UINT_FLAGS, &folder_flags, -1);
+ uid = camel_service_get_uid (CAMEL_SERVICE (store));
+ store_is_local = (g_strcmp0 (uid, E_MAIL_SESSION_LOCAL_UID) == 0);
+
if (!is_store && full_name != NULL) {
- CamelStore *local_store;
guint32 folder_type;
- local_store = e_mail_local_get_store ();
-
/* Is this a virtual junk or trash folder? */
is_junk = (strcmp (full_name, CAMEL_VJUNK_NAME) == 0);
is_trash = (strcmp (full_name, CAMEL_VTRASH_NAME) == 0);
@@ -378,7 +379,7 @@ mail_sidebar_check_state (EMailSidebar *sidebar)
allows_children = !(is_junk || is_trash);
/* Don't allow deletion of special local folders. */
- if (store == local_store) {
+ if (store_is_local) {
can_delete =
(strcmp (full_name, "Drafts") != 0) &&
(strcmp (full_name, "Inbox") != 0) &&
diff --git a/mail/e-mail-store.c b/mail/e-mail-store.c
deleted file mode 100644
index 283a8608e9..0000000000
--- a/mail/e-mail-store.c
+++ /dev/null
@@ -1,500 +0,0 @@
-/*
- * e-mail-store.c
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "e-mail-store.h"
-
-#include <glib/gi18n.h>
-#include <camel/camel.h>
-#include <libedataserver/e-account.h>
-#include <libedataserver/e-account-list.h>
-
-#include "e-util/e-account-utils.h"
-
-#include "mail/e-mail-local.h"
-#include "mail/em-folder-tree-model.h"
-#include "mail/em-utils.h"
-#include "mail/mail-folder-cache.h"
-#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,
- CamelStore *store,
- CamelFolderInfo *info,
- StoreInfo *store_info);
-
-struct _StoreInfo {
- gint ref_count;
-
- CamelStore *store;
-
- /* Hold a reference to keep them alive. */
- CamelFolder *vtrash;
- CamelFolder *vjunk;
-
- AddStoreCallback callback;
-
- guint removed : 1;
-};
-
-static GHashTable *store_table;
-
-static StoreInfo *
-store_info_new (CamelStore *store)
-{
- StoreInfo *store_info;
-
- g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
-
- store_info = g_slice_new0 (StoreInfo);
- store_info->ref_count = 1;
-
- store_info->store = g_object_ref (store);
-
- /* If these are vfolders then they need to be opened now,
- * otherwise they won't keep track of all folders. */
- if (store->flags & CAMEL_STORE_VTRASH)
- store_info->vtrash =
- camel_store_get_trash_folder_sync (store, NULL, NULL);
- if (store->flags & CAMEL_STORE_VJUNK)
- store_info->vjunk =
- camel_store_get_junk_folder_sync (store, NULL, NULL);
-
- return store_info;
-}
-
-static StoreInfo *
-store_info_ref (StoreInfo *store_info)
-{
- g_return_val_if_fail (store_info != NULL, store_info);
- g_return_val_if_fail (store_info->ref_count > 0, store_info);
-
- g_atomic_int_inc (&store_info->ref_count);
-
- return store_info;
-}
-
-static void
-store_info_unref (StoreInfo *store_info)
-{
- g_return_if_fail (store_info != NULL);
- g_return_if_fail (store_info->ref_count > 0);
-
- if (g_atomic_int_dec_and_test (&store_info->ref_count)) {
-
- g_object_unref (store_info->store);
-
- if (store_info->vtrash != NULL)
- g_object_unref (store_info->vtrash);
-
- if (store_info->vjunk != NULL)
- g_object_unref (store_info->vjunk);
-
- g_slice_free (StoreInfo, store_info);
- }
-}
-
-static void
-store_table_free (StoreInfo *store_info)
-{
- store_info->removed = 1;
- store_info_unref (store_info);
-}
-
-static gboolean
-mail_store_note_store_cb (MailFolderCache *folder_cache,
- CamelStore *store,
- CamelFolderInfo *info,
- gpointer user_data)
-{
- StoreInfo *store_info = user_data;
-
- if (store_info->callback != NULL)
- store_info->callback (
- folder_cache, store, info, store_info);
-
- if (!store_info->removed) {
- /* This keeps message counters up-to-date. */
- if (store_info->vtrash != NULL)
- mail_folder_cache_note_folder (
- folder_cache, store_info->vtrash);
- if (store_info->vjunk != NULL)
- mail_folder_cache_note_folder (
- folder_cache, store_info->vjunk);
- }
-
- store_info_unref (store_info);
-
- 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,
- AddStoreCallback callback)
-{
- EMFolderTreeModel *default_model;
- MailFolderCache *folder_cache;
- StoreInfo *store_info;
-
- g_return_if_fail (store_table != NULL);
- g_return_if_fail (CAMEL_IS_STORE (store));
-
- default_model = em_folder_tree_model_get_default ();
- folder_cache = e_mail_session_get_folder_cache (session);
-
- store_info = store_info_new (store);
- store_info->callback = callback;
-
- g_hash_table_insert (store_table, store, store_info);
-
- if (special_mail_store_is_enabled (store))
- em_folder_tree_model_add_store (default_model, store);
-
- mail_folder_cache_note_store (
- folder_cache, store, NULL,
- mail_store_note_store_cb, store_info_ref (store_info));
-}
-
-static void
-mail_store_add_local_done_cb (MailFolderCache *folder_cache,
- CamelStore *store,
- CamelFolderInfo *info,
- StoreInfo *store_info)
-{
- CamelFolder *folder;
- gint ii;
-
- for (ii = 0; ii < E_MAIL_NUM_LOCAL_FOLDERS; ii++) {
- folder = e_mail_local_get_folder (ii);
- if (folder == NULL)
- continue;
- mail_folder_cache_note_folder (folder_cache, folder);
- }
-}
-
-static void
-mail_store_load_accounts (EMailSession *session,
- const gchar *data_dir)
-{
- CamelStore *local_store;
- EAccountList *account_list;
- EIterator *iter;
-
- /* Add the local store. */
-
- e_mail_local_init (session, data_dir);
- local_store = e_mail_local_get_store ();
-
- mail_store_add (
- session, local_store, (AddStoreCallback)
- mail_store_add_local_done_cb);
-
- /* Add mail accounts.. */
-
- account_list = e_get_account_list ();
-
- for (iter = e_list_get_iterator ((EList *) account_list);
- e_iterator_is_valid (iter); e_iterator_next (iter)) {
- EAccount *account;
-
- account = (EAccount *) e_iterator_get (iter);
-
- if (!account->enabled)
- continue;
-
- e_mail_store_add_by_account (session, account);
- }
-
- g_object_unref (iter);
-}
-
-void
-e_mail_store_init (EMailSession *session,
- const gchar *data_dir)
-{
- static gboolean initialized = FALSE;
-
- g_return_if_fail (E_IS_MAIL_SESSION (session));
-
- /* This function is idempotent because mail
- * migration code may need to call it early. */
- if (initialized)
- return;
-
- /* Initialize global variables. */
-
- store_table = g_hash_table_new_full (
- g_direct_hash, g_direct_equal,
- (GDestroyNotify) NULL,
- (GDestroyNotify) store_table_free);
-
- mail_store_load_accounts (session, data_dir);
-
- initialized = TRUE;
-}
-
-void
-e_mail_store_add (EMailSession *session,
- CamelStore *store)
-{
- g_return_if_fail (E_IS_MAIL_SESSION (session));
- g_return_if_fail (CAMEL_IS_STORE (store));
-
- mail_store_add (session, store, NULL);
-}
-
-CamelStore *
-e_mail_store_add_by_account (EMailSession *session,
- EAccount *account)
-{
- CamelService *service = NULL;
- CamelProvider *provider;
- CamelURL *url;
- gboolean transport_only;
- gboolean service_is_local_delivery;
- gboolean service_belongs_in_tree_model;
- GError *error = NULL;
-
- g_return_val_if_fail (E_IS_MAIL_SESSION (session), NULL);
- g_return_val_if_fail (E_IS_ACCOUNT (account), NULL);
-
- /* check whether it's transport-only accounts */
- transport_only =
- (account->source == NULL) ||
- (account->source->url == NULL) ||
- (*account->source->url == '\0');
- if (transport_only)
- goto handle_transport;
-
- /* Load the service, but don't connect. Check its provider,
- * and if this belongs in the folder tree model, add it. */
-
- url = camel_url_new (account->source->url, NULL);
- if (url != NULL) {
- service_is_local_delivery =
- em_utils_is_local_delivery_mbox_file (url);
- provider = camel_provider_get (url->protocol, NULL);
- camel_url_free (url);
- } else {
- service_is_local_delivery = FALSE;
- provider = NULL;
- }
-
- if (provider == NULL) {
- /* In case we do not have a provider here, we handle
- * the special case of having multiple mail identities
- * eg. a dummy account having just SMTP server defined */
- goto handle_transport;
- }
-
- service = camel_session_add_service (
- CAMEL_SESSION (session),
- account->uid, provider->protocol,
- CAMEL_PROVIDER_STORE, &error);
-
- if (!CAMEL_IS_STORE (service))
- goto fail;
-
- camel_service_set_display_name (service, account->name);
-
- service_belongs_in_tree_model =
- (provider->flags & CAMEL_PROVIDER_IS_STORAGE) &&
- !service_is_local_delivery;
-
- if (service_belongs_in_tree_model && store_table != NULL)
- e_mail_store_add (session, CAMEL_STORE (service));
-
-handle_transport:
-
- /* While we're at it, add the account's transport (if it has one)
- * to the CamelSession. The transport's UID is a kludge for now.
- * We take the EAccount's UID and tack on "-transport". */
-
- if (account->transport) {
- GError *transport_error = NULL;
-
- url = camel_url_new (
- account->transport->url,
- &transport_error);
-
- if (url != NULL) {
- provider = camel_provider_get (
- url->protocol, &transport_error);
- camel_url_free (url);
- } else
- provider = NULL;
-
- if (provider != NULL) {
- gchar *transport_uid;
-
- transport_uid = g_strconcat (
- account->uid, "-transport", NULL);
-
- camel_session_add_service (
- CAMEL_SESSION (session),
- transport_uid, provider->protocol,
- CAMEL_PROVIDER_TRANSPORT, &transport_error);
-
- g_free (transport_uid);
- }
-
- if (transport_error) {
- g_warning (
- "%s: Failed to add transport service: %s",
- G_STRFUNC, transport_error->message);
- g_error_free (transport_error);
- }
- }
-
- if (transport_only)
- return NULL;
-
- return CAMEL_STORE (service);
-
-fail:
- /* FIXME: Show an error dialog. */
- g_warning (
- "Couldn't get service: %s: %s", account->name,
- error ? error->message : "Not a CamelStore");
- if (error)
- g_error_free (error);
-
- return NULL;
-}
-
-void
-e_mail_store_remove (EMailSession *session,
- CamelStore *store)
-{
- MailFolderCache *folder_cache;
- EMFolderTreeModel *default_model;
-
- g_return_if_fail (E_IS_MAIL_SESSION (session));
- g_return_if_fail (CAMEL_IS_STORE (store));
- g_return_if_fail (store_table != NULL);
-
- /* Because the store table holds a reference to each store used
- * as a key in it, none of them will ever be gc'ed, meaning any
- * call to camel_session_get_{service,store} with the same URL
- * will always return the same object. So this works. */
-
- if (g_hash_table_lookup (store_table, store) == NULL)
- return;
-
- g_object_ref (store);
-
- g_hash_table_remove (store_table, store);
-
- 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 ();
- em_folder_tree_model_remove_store (default_model, store);
-
- mail_disconnect_store (store);
-
- g_object_unref (store);
-}
-
-void
-e_mail_store_remove_by_account (EMailSession *session,
- EAccount *account)
-{
- CamelService *service;
- CamelProvider *provider;
- const gchar *uid;
-
- g_return_if_fail (E_IS_MAIL_SESSION (session));
- g_return_if_fail (E_IS_ACCOUNT (account));
-
- uid = account->uid;
-
- service = camel_session_get_service (CAMEL_SESSION (session), uid);
- g_return_if_fail (CAMEL_IS_STORE (service));
-
- provider = camel_service_get_provider (service);
- g_return_if_fail (provider != NULL);
-
- if (!(provider->flags & CAMEL_PROVIDER_IS_STORAGE) || store_table == NULL)
- return;
-
- e_mail_store_remove (session, CAMEL_STORE (service));
-}
-
-void
-e_mail_store_foreach (EMailSession *session,
- GFunc func,
- gpointer user_data)
-{
- GList *list, *link;
-
- /* XXX This is a silly convenience function.
- * Could probably just get rid of it. */
-
- g_return_if_fail (E_IS_MAIL_SESSION (session));
- g_return_if_fail (func != NULL);
-
- list = camel_session_list_services (CAMEL_SESSION (session));
-
- for (link = list; link != NULL; link = g_list_next (link)) {
- CamelService *service = CAMEL_SERVICE (link->data);
-
- if (CAMEL_IS_STORE (service))
- func (service, user_data);
- }
-
- g_list_free (list);
-}
diff --git a/mail/e-mail-store.h b/mail/e-mail-store.h
deleted file mode 100644
index 5dca416e09..0000000000
--- a/mail/e-mail-store.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * e-mail-store.h
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef E_MAIL_STORE_H
-#define E_MAIL_STORE_H
-
-#include <camel/camel.h>
-#include <mail/e-mail-session.h>
-#include <libedataserver/e-account.h>
-
-G_BEGIN_DECLS
-
-void e_mail_store_init (EMailSession *session,
- const gchar *data_dir);
-void e_mail_store_add (EMailSession *session,
- CamelStore *store);
-CamelStore * e_mail_store_add_by_account (EMailSession *session,
- EAccount *account);
-void e_mail_store_remove (EMailSession *session,
- CamelStore *store);
-void e_mail_store_remove_by_account (EMailSession *session,
- EAccount *account);
-void e_mail_store_foreach (EMailSession *session,
- GFunc func,
- gpointer user_data);
-
-G_END_DECLS
-
-#endif /* E_MAIL_STORE_H */
diff --git a/mail/e-mail.h b/mail/e-mail.h
index 7c40b20947..02c169cd10 100644
--- a/mail/e-mail.h
+++ b/mail/e-mail.h
@@ -32,7 +32,6 @@
#include <mail/e-mail-label-list-store.h>
#include <mail/e-mail-label-manager.h>
#include <mail/e-mail-label-tree-view.h>
-#include <mail/e-mail-local.h>
#include <mail/e-mail-message-pane.h>
#include <mail/e-mail-migrate.h>
#include <mail/e-mail-notebook-view.h>
@@ -42,7 +41,6 @@
#include <mail/e-mail-session.h>
#include <mail/e-mail-session-utils.h>
#include <mail/e-mail-sidebar.h>
-#include <mail/e-mail-store.h>
#include <mail/e-mail-store-utils.h>
#include <mail/e-mail-tag-editor.h>
#include <mail/e-mail-view.h>
diff --git a/mail/em-account-editor.c b/mail/em-account-editor.c
index 6bd96ef299..7b84112a34 100644
--- a/mail/em-account-editor.c
+++ b/mail/em-account-editor.c
@@ -60,8 +60,6 @@
#include "e-mail-backend.h"
#include "e-mail-folder-utils.h"
#include "e-mail-junk-options.h"
-#include "e-mail-local.h"
-#include "e-mail-store.h"
#include "em-config.h"
#include "em-folder-selection-button.h"
#include "em-account-editor.h"
@@ -301,26 +299,10 @@ emae_set_original_account (EMAccountEditor *emae,
modified_account = e_account_new ();
modified_account->enabled = TRUE;
emae->priv->new_account = TRUE;
-
- e_account_set_string (
- modified_account, E_ACCOUNT_DRAFTS_FOLDER_URI,
- e_mail_local_get_folder_uri (E_MAIL_LOCAL_FOLDER_DRAFTS));
-
- e_account_set_string (
- modified_account, E_ACCOUNT_SENT_FOLDER_URI,
- e_mail_local_get_folder_uri (E_MAIL_LOCAL_FOLDER_SENT));
-
- /* encrypt to self by default */
- e_account_set_bool (modified_account, E_ACCOUNT_PGP_ENCRYPT_TO_SELF, TRUE);
- e_account_set_bool (modified_account, E_ACCOUNT_SMIME_ENCRYPT_TO_SELF, TRUE);
}
emae->priv->original_account = original_account;
emae->priv->modified_account = modified_account;
-
- g_signal_connect_swapped (
- emae->priv->modified_account, "changed",
- G_CALLBACK (emae_config_target_changed_cb), emae);
}
static void
@@ -909,6 +891,52 @@ emae_finalize (GObject *object)
}
static void
+emae_constructed (GObject *object)
+{
+ EMAccountEditor *emae;
+
+ emae = EM_ACCOUNT_EDITOR (object);
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (em_account_editor_parent_class)->constructed (object);
+
+ /* Set some defaults on the new account before we get started. */
+ if (emae->priv->new_account) {
+ EMailBackend *backend;
+ EMailSession *session;
+
+ backend = em_account_editor_get_backend (emae);
+ session = e_mail_backend_get_session (backend);
+
+ /* Pick local Drafts folder. */
+ e_account_set_string (
+ emae->priv->modified_account,
+ E_ACCOUNT_DRAFTS_FOLDER_URI,
+ e_mail_session_get_local_folder_uri (
+ session, E_MAIL_LOCAL_FOLDER_DRAFTS));
+
+ /* Pick local Sent folder. */
+ e_account_set_string (
+ emae->priv->modified_account,
+ E_ACCOUNT_SENT_FOLDER_URI,
+ e_mail_session_get_local_folder_uri (
+ session, E_MAIL_LOCAL_FOLDER_SENT));
+
+ /* Encrypt to self by default. */
+ e_account_set_bool (
+ emae->priv->modified_account,
+ E_ACCOUNT_PGP_ENCRYPT_TO_SELF, TRUE);
+ e_account_set_bool (
+ emae->priv->modified_account,
+ E_ACCOUNT_SMIME_ENCRYPT_TO_SELF, TRUE);
+ }
+
+ g_signal_connect_swapped (
+ emae->priv->modified_account, "changed",
+ G_CALLBACK (emae_config_target_changed_cb), emae);
+}
+
+static void
em_account_editor_class_init (EMAccountEditorClass *class)
{
GObjectClass *object_class;
@@ -920,6 +948,7 @@ em_account_editor_class_init (EMAccountEditorClass *class)
object_class->get_property = emae_get_property;
object_class->dispose = emae_dispose;
object_class->finalize = emae_finalize;
+ object_class->constructed = emae_constructed;
g_object_class_install_property (
object_class,
@@ -1295,15 +1324,29 @@ default_folders_clicked (GtkButton *button,
gpointer user_data)
{
EMAccountEditor *emae = user_data;
- const gchar *uri;
+ EMFolderSelectionButton *folder_button;
+ EMailBackend *backend;
+ EMailSession *session;
+ const gchar *folder_uri;
- uri = e_mail_local_get_folder_uri (E_MAIL_LOCAL_FOLDER_DRAFTS);
- em_folder_selection_button_set_folder_uri ((EMFolderSelectionButton *) emae->priv->drafts_folder_button, uri);
- emae_account_folder_changed ((EMFolderSelectionButton *) emae->priv->drafts_folder_button, emae);
+ backend = em_account_editor_get_backend (emae);
+ session = e_mail_backend_get_session (backend);
- uri = e_mail_local_get_folder_uri (E_MAIL_LOCAL_FOLDER_SENT);
- em_folder_selection_button_set_folder_uri ((EMFolderSelectionButton *) emae->priv->sent_folder_button, uri);
- emae_account_folder_changed ((EMFolderSelectionButton *) emae->priv->sent_folder_button, emae);
+ folder_button =
+ EM_FOLDER_SELECTION_BUTTON (
+ emae->priv->drafts_folder_button);
+ folder_uri = e_mail_session_get_local_folder_uri (
+ session, E_MAIL_LOCAL_FOLDER_DRAFTS);
+ em_folder_selection_button_set_folder_uri (folder_button, folder_uri);
+ emae_account_folder_changed (folder_button, emae);
+
+ folder_button =
+ EM_FOLDER_SELECTION_BUTTON (
+ emae->priv->sent_folder_button);
+ folder_uri = e_mail_session_get_local_folder_uri (
+ session, E_MAIL_LOCAL_FOLDER_SENT);
+ em_folder_selection_button_set_folder_uri (folder_button, folder_uri);
+ emae_account_folder_changed (folder_button, emae);
gtk_toggle_button_set_active (emae->priv->trash_folder_check, FALSE);
gtk_toggle_button_set_active (emae->priv->junk_folder_check, FALSE);
@@ -1805,10 +1848,12 @@ emae_account_folder (EMAccountEditor *emae,
EAccount *account;
EMFolderSelectionButton *folder;
EMailBackend *backend;
+ EMailSession *session;
const gchar *uri;
account = em_account_editor_get_modified_account (emae);
backend = em_account_editor_get_backend (emae);
+ session = e_mail_backend_get_session (backend);
folder = (EMFolderSelectionButton *) e_builder_get_widget (builder, name);
em_folder_selection_button_set_backend (folder, backend);
@@ -1817,7 +1862,7 @@ emae_account_folder (EMAccountEditor *emae,
if (uri != NULL) {
em_folder_selection_button_set_folder_uri (folder, uri);
} else {
- uri = e_mail_local_get_folder_uri (deffolder);
+ uri = e_mail_session_get_local_folder_uri (session, deffolder);
em_folder_selection_button_set_folder_uri (folder, uri);
}
@@ -5136,7 +5181,6 @@ emae_commit (EConfig *ec,
camel_url_free (url);
if (original_account != NULL) {
- d (printf ("Committing account '%s'\n", e_account_get_string (modified_account, E_ACCOUNT_NAME)));
forget_password_if_needed (original_account, modified_account, E_ACCOUNT_SOURCE_SAVE_PASSWD, E_ACCOUNT_SOURCE_URL);
forget_password_if_needed (original_account, modified_account, E_ACCOUNT_TRANSPORT_SAVE_PASSWD, E_ACCOUNT_TRANSPORT_URL);
@@ -5144,30 +5188,25 @@ emae_commit (EConfig *ec,
account = original_account;
e_account_list_change (accounts, account);
} else {
- CamelProvider *provider;
-
- d (printf ("Adding new account '%s'\n", e_account_get_string (modified_account, E_ACCOUNT_NAME)));
e_account_list_add (accounts, modified_account);
account = modified_account;
+ }
- provider = emae_get_store_provider (emae);
+ if (gtk_toggle_button_get_active (emae->priv->default_account)) {
+ EMailBackend *backend;
+ EMailSession *session;
+ EMailAccountStore *store;
+ CamelService *service;
- /* HACK: this will add the account to the folder tree.
- * We should just be listening to the account list directly for changed events */
- if (account->enabled
- && provider != NULL
- && (provider->flags & CAMEL_PROVIDER_IS_STORAGE)) {
- EMailBackend *backend;
- EMailSession *session;
-
- backend = em_account_editor_get_backend (emae);
- session = e_mail_backend_get_session (backend);
- e_mail_store_add_by_account (session, account);
- }
- }
+ backend = em_account_editor_get_backend (emae);
+ session = e_mail_backend_get_session (backend);
- if (gtk_toggle_button_get_active (emae->priv->default_account))
- e_account_list_set_default (accounts, account);
+ service = camel_session_get_service (
+ CAMEL_SESSION (session), account->uid);
+
+ store = e_mail_session_get_account_store (session);
+ e_mail_account_store_set_default_service (store, service);
+ }
e_account_list_save (accounts);
}
diff --git a/mail/em-composer-utils.c b/mail/em-composer-utils.c
index 0eceeea228..f6a938bdac 100644
--- a/mail/em-composer-utils.c
+++ b/mail/em-composer-utils.c
@@ -45,7 +45,6 @@
#include "shell/e-shell.h"
#include "e-mail-folder-utils.h"
-#include "e-mail-local.h"
#include "e-mail-session.h"
#include "e-mail-session-utils.h"
#include "em-utils.h"
@@ -74,6 +73,7 @@ typedef struct _ForwardData ForwardData;
struct _AsyncContext {
CamelMimeMessage *message;
+ EMailSession *session;
EMsgComposer *composer;
EActivity *activity;
EMailReader *reader;
@@ -98,6 +98,9 @@ async_context_free (AsyncContext *context)
if (context->message != NULL)
g_object_unref (context->message);
+ if (context->session != NULL)
+ g_object_unref (context->session);
+
if (context->composer != NULL)
g_object_unref (context->composer);
@@ -206,7 +209,8 @@ is_group_definition (const gchar *str)
}
static gboolean
-composer_presend_check_recipients (EMsgComposer *composer)
+composer_presend_check_recipients (EMsgComposer *composer,
+ EMailSession *session)
{
EDestination **recipients;
EDestination **recipients_bcc;
@@ -358,7 +362,8 @@ finished:
}
static gboolean
-composer_presend_check_account (EMsgComposer *composer)
+composer_presend_check_account (EMsgComposer *composer,
+ EMailSession *session)
{
EComposerHeaderTable *table;
EAccount *account;
@@ -377,7 +382,8 @@ composer_presend_check_account (EMsgComposer *composer)
}
static gboolean
-composer_presend_check_downloads (EMsgComposer *composer)
+composer_presend_check_downloads (EMsgComposer *composer,
+ EMailSession *session)
{
EAttachmentView *view;
EAttachmentStore *store;
@@ -396,7 +402,8 @@ composer_presend_check_downloads (EMsgComposer *composer)
}
static gboolean
-composer_presend_check_plugins (EMsgComposer *composer)
+composer_presend_check_plugins (EMsgComposer *composer,
+ EMailSession *session)
{
EMEvent *eme;
EMEventTargetComposer *target;
@@ -428,7 +435,8 @@ composer_presend_check_plugins (EMsgComposer *composer)
}
static gboolean
-composer_presend_check_subject (EMsgComposer *composer)
+composer_presend_check_subject (EMsgComposer *composer,
+ EMailSession *session)
{
EComposerHeaderTable *table;
const gchar *subject;
@@ -446,7 +454,8 @@ composer_presend_check_subject (EMsgComposer *composer)
}
static gboolean
-composer_presend_check_unwanted_html (EMsgComposer *composer)
+composer_presend_check_unwanted_html (EMsgComposer *composer,
+ EMailSession *session)
{
EDestination **recipients;
EComposerHeaderTable *table;
@@ -556,10 +565,10 @@ exit:
static void
em_utils_composer_send_cb (EMsgComposer *composer,
CamelMimeMessage *message,
- EActivity *activity)
+ EActivity *activity,
+ EMailSession *session)
{
AsyncContext *context;
- CamelSession *session;
GCancellable *cancellable;
context = g_slice_new0 (AsyncContext);
@@ -568,10 +577,9 @@ em_utils_composer_send_cb (EMsgComposer *composer,
context->activity = g_object_ref (activity);
cancellable = e_activity_get_cancellable (activity);
- session = e_msg_composer_get_session (context->composer);
e_mail_session_send_to (
- E_MAIL_SESSION (session), message,
+ session, message,
G_PRIORITY_DEFAULT, cancellable, NULL, NULL,
(GAsyncReadyCallback) composer_send_completed,
context);
@@ -593,6 +601,7 @@ composer_set_no_change (EMsgComposer *composer)
/* delete original messages from Outbox folder */
static void
manage_x_evolution_replace_outbox (EMsgComposer *composer,
+ EMailSession *session,
CamelMimeMessage *message,
GCancellable *cancellable)
{
@@ -610,7 +619,8 @@ manage_x_evolution_replace_outbox (EMsgComposer *composer,
if (!message_uid)
return;
- outbox = e_mail_local_get_folder (E_MAIL_LOCAL_FOLDER_OUTBOX);
+ outbox = e_mail_session_get_local_folder (
+ session, E_MAIL_LOCAL_FOLDER_OUTBOX);
g_return_if_fail (outbox != NULL);
camel_folder_set_message_flags (
@@ -708,7 +718,8 @@ composer_save_to_drafts_append_mail (AsyncContext *context,
CamelMessageInfo *info;
local_drafts_folder =
- e_mail_local_get_folder (E_MAIL_LOCAL_FOLDER_DRAFTS);
+ e_mail_session_get_local_folder (
+ context->session, E_MAIL_LOCAL_FOLDER_DRAFTS);
if (drafts_folder == NULL)
drafts_folder = g_object_ref (local_drafts_folder);
@@ -778,24 +789,24 @@ composer_save_to_drafts_got_folder (EMailSession *session,
static void
em_utils_composer_save_to_drafts_cb (EMsgComposer *composer,
CamelMimeMessage *message,
- EActivity *activity)
+ EActivity *activity,
+ EMailSession *session)
{
AsyncContext *context;
EComposerHeaderTable *table;
const gchar *drafts_folder_uri = NULL;
const gchar *local_drafts_folder_uri;
- CamelSession *session;
EAccount *account;
context = g_slice_new0 (AsyncContext);
context->message = g_object_ref (message);
+ context->session = g_object_ref (session);
context->composer = g_object_ref (composer);
context->activity = g_object_ref (activity);
- session = e_msg_composer_get_session (composer);
-
local_drafts_folder_uri =
- e_mail_local_get_folder_uri (E_MAIL_LOCAL_FOLDER_DRAFTS);
+ e_mail_session_get_local_folder_uri (
+ session, E_MAIL_LOCAL_FOLDER_DRAFTS);
table = e_msg_composer_get_header_table (composer);
account = e_composer_header_table_get_account (table);
@@ -816,9 +827,9 @@ em_utils_composer_save_to_drafts_cb (EMsgComposer *composer,
context->folder_uri = g_strdup (drafts_folder_uri);
e_mail_session_uri_to_folder (
- E_MAIL_SESSION (session),
- drafts_folder_uri, 0, G_PRIORITY_DEFAULT,
- cancellable, (GAsyncReadyCallback)
+ session, drafts_folder_uri, 0,
+ G_PRIORITY_DEFAULT, cancellable,
+ (GAsyncReadyCallback)
composer_save_to_drafts_got_folder, context);
}
}
@@ -851,7 +862,7 @@ composer_save_to_outbox_completed (CamelFolder *outbox_folder,
/* special processing for Outbox folder */
manage_x_evolution_replace_outbox (
- context->composer, context->message,
+ context->composer, context->session, context->message,
e_activity_get_cancellable (context->activity));
e_activity_set_state (context->activity, E_ACTIVITY_COMPLETED);
@@ -869,7 +880,8 @@ exit:
static void
em_utils_composer_save_to_outbox_cb (EMsgComposer *composer,
CamelMimeMessage *message,
- EActivity *activity)
+ EActivity *activity,
+ EMailSession *session)
{
AsyncContext *context;
CamelFolder *outbox_folder;
@@ -878,11 +890,15 @@ em_utils_composer_save_to_outbox_cb (EMsgComposer *composer,
context = g_slice_new0 (AsyncContext);
context->message = g_object_ref (message);
+ context->session = g_object_ref (session);
context->composer = g_object_ref (composer);
context->activity = g_object_ref (activity);
cancellable = e_activity_get_cancellable (activity);
- outbox_folder = e_mail_local_get_folder (E_MAIL_LOCAL_FOLDER_OUTBOX);
+
+ outbox_folder =
+ e_mail_session_get_local_folder (
+ session, E_MAIL_LOCAL_FOLDER_OUTBOX);
info = camel_message_info_new (NULL);
camel_message_info_set_flags (info, CAMEL_MESSAGE_SEEN, ~0);
@@ -900,7 +916,8 @@ static void
em_utils_composer_print_cb (EMsgComposer *composer,
GtkPrintOperationAction action,
CamelMimeMessage *message,
- EActivity *activity)
+ EActivity *activity,
+ EMailSession *session)
{
EMFormatHTMLPrint *efhp;
@@ -2719,7 +2736,7 @@ em_utils_reply_to_message (EShell *shell,
static void
post_header_clicked_cb (EComposerPostHeader *header,
- EMsgComposer *composer)
+ EMailSession *session)
{
EShell *shell;
EShellBackend *shell_backend;
@@ -2731,14 +2748,14 @@ post_header_clicked_cb (EComposerPostHeader *header,
GList *list;
/* FIXME Figure out a way to pass the mail backend in. */
- shell = e_msg_composer_get_shell (composer);
+ shell = e_shell_get_default ();
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 ();
dialog = em_folder_selector_new (
- GTK_WINDOW (composer),
+ /* FIXME GTK_WINDOW (composer) */ NULL,
E_MAIL_BACKEND (shell_backend),
model, EM_FOLDER_SELECTOR_CAN_CREATE,
_("Posting destination"),
@@ -2788,13 +2805,15 @@ exit:
* things the #EMsgComposer instance can't do itself.
**/
void
-em_configure_new_composer (EMsgComposer *composer)
+em_configure_new_composer (EMsgComposer *composer,
+ EMailSession *session)
{
EComposerHeaderTable *table;
EComposerHeaderType header_type;
EComposerHeader *header;
g_return_if_fail (E_IS_MSG_COMPOSER (composer));
+ g_return_if_fail (E_IS_MAIL_SESSION (session));
header_type = E_COMPOSER_HEADER_POST_TO;
table = e_msg_composer_get_header_table (composer);
@@ -2802,43 +2821,43 @@ em_configure_new_composer (EMsgComposer *composer)
g_signal_connect (
composer, "presend",
- G_CALLBACK (composer_presend_check_recipients), NULL);
+ G_CALLBACK (composer_presend_check_recipients), session);
g_signal_connect (
composer, "presend",
- G_CALLBACK (composer_presend_check_account), NULL);
+ G_CALLBACK (composer_presend_check_account), session);
g_signal_connect (
composer, "presend",
- G_CALLBACK (composer_presend_check_downloads), NULL);
+ G_CALLBACK (composer_presend_check_downloads), session);
g_signal_connect (
composer, "presend",
- G_CALLBACK (composer_presend_check_plugins), NULL);
+ G_CALLBACK (composer_presend_check_plugins), session);
g_signal_connect (
composer, "presend",
- G_CALLBACK (composer_presend_check_subject), NULL);
+ G_CALLBACK (composer_presend_check_subject), session);
g_signal_connect (
composer, "presend",
- G_CALLBACK (composer_presend_check_unwanted_html), NULL);
+ G_CALLBACK (composer_presend_check_unwanted_html), session);
g_signal_connect (
composer, "send",
- G_CALLBACK (em_utils_composer_send_cb), NULL);
+ G_CALLBACK (em_utils_composer_send_cb), session);
g_signal_connect (
composer, "save-to-drafts",
- G_CALLBACK (em_utils_composer_save_to_drafts_cb), NULL);
+ G_CALLBACK (em_utils_composer_save_to_drafts_cb), session);
g_signal_connect (
composer, "save-to-outbox",
- G_CALLBACK (em_utils_composer_save_to_outbox_cb), NULL);
+ G_CALLBACK (em_utils_composer_save_to_outbox_cb), session);
g_signal_connect (
composer, "print",
- G_CALLBACK (em_utils_composer_print_cb), NULL);
+ G_CALLBACK (em_utils_composer_print_cb), session);
/* Handle "Post To:" button clicks, which displays a folder tree
* widget. The composer doesn't know about folder tree widgets,
@@ -2849,5 +2868,5 @@ em_configure_new_composer (EMsgComposer *composer)
* the folder selector dialog. See the handler function. */
g_signal_connect (
header, "clicked",
- G_CALLBACK (post_header_clicked_cb), composer);
+ G_CALLBACK (post_header_clicked_cb), session);
}
diff --git a/mail/em-composer-utils.h b/mail/em-composer-utils.h
index 215e6bb2bc..093001dfd0 100644
--- a/mail/em-composer-utils.h
+++ b/mail/em-composer-utils.h
@@ -79,7 +79,8 @@ EMsgComposer * em_utils_reply_to_message (EShell *shell,
CamelInternetAddress *address);
EDestination ** em_utils_camel_address_to_destination
(CamelInternetAddress *iaddr);
-void em_configure_new_composer (EMsgComposer *composer);
+void em_configure_new_composer (EMsgComposer *composer,
+ EMailSession *session);
G_END_DECLS
diff --git a/mail/em-folder-properties.c b/mail/em-folder-properties.c
index 310aa76740..9dbffba2e2 100644
--- a/mail/em-folder-properties.c
+++ b/mail/em-folder-properties.c
@@ -34,7 +34,6 @@
#include "e-mail-backend.h"
#include "e-mail-folder-utils.h"
-#include "e-mail-local.h"
#include "mail-ops.h"
#include "mail-mt.h"
#include "mail-vfolder.h"
@@ -249,25 +248,26 @@ emfp_dialog_run (AsyncContext *context)
EMConfigTargetFolder *target;
EShellWindow *shell_window;
EShellView *shell_view;
- CamelStore *local_store;
CamelStore *parent_store;
+ CamelFolderSummary *summary;
+ gboolean store_is_local;
gboolean hide_deleted;
GSettings *settings;
const gchar *name;
+ const gchar *uid;
shell_view = context->shell_view;
shell_window = e_shell_view_get_shell_window (shell_view);
- local_store = e_mail_local_get_store ();
parent_store = camel_folder_get_parent_store (context->folder);
/* Get number of VISIBLE and DELETED messages, instead of TOTAL
* messages. VISIBLE+DELETED gives the correct count that matches
* the label below the Send & Receive button. */
- name = camel_folder_get_display_name (context->folder);
- context->total = camel_folder_summary_get_visible_count (context->folder->summary);
- context->unread = camel_folder_summary_get_unread_count (context->folder->summary);
- deleted = camel_folder_summary_get_deleted_count (context->folder->summary);
+ summary = context->folder->summary;
+ context->total = camel_folder_summary_get_visible_count (summary);
+ context->unread = camel_folder_summary_get_unread_count (summary);
+ deleted = camel_folder_summary_get_deleted_count (summary);
settings = g_settings_new ("org.gnome.evolution.mail");
hide_deleted = !g_settings_get_boolean (settings, "show-deleted");
@@ -290,7 +290,12 @@ emfp_dialog_run (AsyncContext *context)
context->total = camel_folder_summary_count (
context->folder->summary);
- if (parent_store == local_store
+ name = camel_folder_get_display_name (context->folder);
+
+ uid = camel_service_get_uid (CAMEL_SERVICE (parent_store));
+ store_is_local = (g_strcmp0 (uid, E_MAIL_SESSION_LOCAL_UID) == 0);
+
+ if (store_is_local
&& (!strcmp (name, "Drafts")
|| !strcmp (name, "Templates")
|| !strcmp (name, "Inbox")
@@ -474,7 +479,7 @@ em_folder_properties_show (EShellView *shell_view,
/* Show the Edit Rule dialog for Search Folders, but not "Unmatched".
* "Unmatched" is a special Search Folder which can't be modified. */
- if (g_strcmp0 (uid, "vfolder") == 0) {
+ if (g_strcmp0 (uid, E_MAIL_SESSION_VFOLDER_UID) == 0) {
if (g_strcmp0 (folder_name, CAMEL_UNMATCHED_NAME) != 0) {
gchar *folder_uri;
diff --git a/mail/em-folder-selection-button.c b/mail/em-folder-selection-button.c
index 1b8ef6cd71..1532e42364 100644
--- a/mail/em-folder-selection-button.c
+++ b/mail/em-folder-selection-button.c
@@ -258,6 +258,7 @@ folder_selection_button_clicked (GtkButton *button)
EMFolderSelector *selector;
EMFolderTree *folder_tree;
EMFolderTreeModel *model = NULL;
+ EMailSession *session;
GtkWidget *dialog;
GtkTreeSelection *selection;
gpointer parent;
@@ -267,9 +268,11 @@ folder_selection_button_clicked (GtkButton *button)
parent = gtk_widget_get_toplevel (GTK_WIDGET (button));
parent = gtk_widget_is_toplevel (parent) ? parent : NULL;
+ session = e_mail_backend_get_session (priv->backend);
+
if (priv->store != NULL) {
model = em_folder_tree_model_new ();
- em_folder_tree_model_set_backend (model, priv->backend);
+ em_folder_tree_model_set_session (model, session);
em_folder_tree_model_add_store (model, priv->store);
}
diff --git a/mail/em-folder-tree-model.c b/mail/em-folder-tree-model.c
index 27fa44aea4..dea9daa7ff 100644
--- a/mail/em-folder-tree-model.c
+++ b/mail/em-folder-tree-model.c
@@ -51,8 +51,6 @@
#include "em-event.h"
#include "e-mail-folder-utils.h"
-#include "e-mail-local.h"
-#include "e-mail-store.h"
#include "shell/e-shell.h"
#define EM_FOLDER_TREE_MODEL_GET_PRIVATE(obj) \
@@ -67,24 +65,20 @@ struct _EMFolderTreeModelPrivate {
* mimic the sidebar. */
GtkTreeSelection *selection; /* weak reference */
- EAccountList *accounts;
- EMailBackend *backend;
+ EMailSession *session;
+ EMailAccountStore *account_store;
/* CamelStore -> EMFolderTreeStoreInfo */
GHashTable *store_index;
/* URI -> GtkTreeRowReference */
GHashTable *uri_index;
-
- gulong account_changed_id;
- gulong account_removed_id;
- gulong account_added_id;
};
enum {
PROP_0,
PROP_SELECTION,
- PROP_BACKEND
+ PROP_SESSION
};
enum {
@@ -123,111 +117,66 @@ folder_tree_model_sort (GtkTreeModel *model,
gpointer unused)
{
EMFolderTreeModel *folder_tree_model;
- EMailBackend *backend;
gchar *aname, *bname;
- CamelStore *store;
- gboolean is_store;
+ CamelService *service_a;
+ CamelService *service_b;
+ gboolean a_is_store;
+ gboolean b_is_store;
const gchar *store_uid = NULL;
- guint32 aflags, bflags;
- guint asortorder, bsortorder;
+ guint32 flags_a, flags_b;
gint rv = -2;
folder_tree_model = EM_FOLDER_TREE_MODEL (model);
- backend = em_folder_tree_model_get_backend (folder_tree_model);
- g_return_val_if_fail (backend != NULL, -1);
gtk_tree_model_get (
model, a,
- COL_BOOL_IS_STORE, &is_store,
- COL_POINTER_CAMEL_STORE, &store,
+ COL_BOOL_IS_STORE, &a_is_store,
+ COL_POINTER_CAMEL_STORE, &service_a,
COL_STRING_DISPLAY_NAME, &aname,
- COL_UINT_FLAGS, &aflags,
- COL_UINT_SORTORDER, &asortorder,
+ COL_UINT_FLAGS, &flags_a,
-1);
gtk_tree_model_get (
model, b,
+ COL_BOOL_IS_STORE, &b_is_store,
+ COL_POINTER_CAMEL_STORE, &service_b,
COL_STRING_DISPLAY_NAME, &bname,
- COL_UINT_FLAGS, &bflags,
- COL_UINT_SORTORDER, &bsortorder,
+ COL_UINT_FLAGS, &flags_b,
-1);
- if (CAMEL_IS_SERVICE (store))
- store_uid = camel_service_get_uid (CAMEL_SERVICE (store));
+ if (CAMEL_IS_SERVICE (service_a))
+ store_uid = camel_service_get_uid (service_a);
- if (is_store) {
- EShell *shell;
- EShellBackend *shell_backend;
- EShellSettings *shell_settings;
-
- shell_backend = E_SHELL_BACKEND (backend);
- shell = e_shell_backend_get_shell (shell_backend);
- shell_settings = e_shell_get_shell_settings (shell);
-
- if (e_shell_settings_get_boolean (
- shell_settings, "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 (asortorder > bsortorder)
- rv = 1;
- else
- rv = 0;
- }
- } else if (g_strcmp0 (store_uid, "vfolder") == 0) {
+ if (a_is_store && b_is_store) {
+ rv = e_mail_account_store_compare_services (
+ folder_tree_model->priv->account_store,
+ service_a, service_b);
+
+ } else if (g_strcmp0 (store_uid, E_MAIL_SESSION_VFOLDER_UID) == 0) {
/* UNMATCHED is always last. */
if (aname && !strcmp (aname, _("UNMATCHED")))
rv = 1;
else if (bname && !strcmp (bname, _("UNMATCHED")))
rv = -1;
+
} else {
/* Inbox is always first. */
- if ((aflags & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_INBOX)
+ if ((flags_a & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_INBOX)
rv = -1;
- else if ((bflags & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_INBOX)
+ else if ((flags_b & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_INBOX)
rv = 1;
}
- if (aname == NULL) {
- if (bname == NULL)
+ if (rv == -2) {
+ if (aname != NULL && bname != NULL)
+ rv = g_utf8_collate (aname, bname);
+ else if (aname == bname)
rv = 0;
- else
+ else if (aname == NULL)
rv = -1;
- } else if (bname == NULL)
- rv = 1;
-
- if (rv == -2)
- rv = g_utf8_collate (aname, bname);
+ else
+ rv = 1;
+ }
g_free (aname);
g_free (bname);
@@ -236,175 +185,44 @@ folder_tree_model_sort (GtkTreeModel *model,
}
static void
-account_changed_cb (EAccountList *accounts,
- EAccount *account,
- EMFolderTreeModel *model)
+folder_tree_model_service_removed (EMailAccountStore *account_store,
+ CamelService *service,
+ EMFolderTreeModel *folder_tree_model)
{
- EMailBackend *backend;
- EMailSession *session;
- CamelService *service;
-
- backend = em_folder_tree_model_get_backend (model);
- session = e_mail_backend_get_session (backend);
-
- service = camel_session_get_service (
- CAMEL_SESSION (session), account->uid);
-
- if (!CAMEL_IS_STORE (service))
- return;
-
- em_folder_tree_model_remove_store (model, CAMEL_STORE (service));
-
- /* check if store needs to be added at all*/
- if (!account->enabled)
- return;
-
- em_folder_tree_model_add_store (model, CAMEL_STORE (service));
+ em_folder_tree_model_remove_store (
+ folder_tree_model, CAMEL_STORE (service));
}
static void
-account_removed_cb (EAccountList *accounts,
- EAccount *account,
- EMFolderTreeModel *model)
+folder_tree_model_service_enabled (EMailAccountStore *account_store,
+ CamelService *service,
+ EMFolderTreeModel *folder_tree_model)
{
- EMailBackend *backend;
- EMailSession *session;
- CamelService *service;
-
- backend = em_folder_tree_model_get_backend (model);
- session = e_mail_backend_get_session (backend);
-
- service = camel_session_get_service (
- CAMEL_SESSION (session), account->uid);
-
- if (!CAMEL_IS_STORE (service))
- return;
-
- em_folder_tree_model_remove_store (model, CAMEL_STORE (service));
+ em_folder_tree_model_add_store (
+ folder_tree_model, CAMEL_STORE (service));
}
-/* HACK: FIXME: the component should listen to the account object directly */
static void
-account_added_cb (EAccountList *accounts,
- EAccount *account,
- EMFolderTreeModel *model)
+folder_tree_model_service_disabled (EMailAccountStore *account_store,
+ CamelService *service,
+ EMFolderTreeModel *folder_tree_model)
{
- EMailBackend *backend;
- EMailSession *session;
-
- backend = em_folder_tree_model_get_backend (model);
- session = e_mail_backend_get_session (backend);
-
- e_mail_store_add_by_account (session, account);
+ em_folder_tree_model_remove_store (
+ folder_tree_model, CAMEL_STORE (service));
}
static void
-folder_tree_model_sort_changed (EMFolderTreeModel *tree_model)
+folder_tree_model_services_reordered (EMailAccountStore *account_store,
+ gboolean default_restored,
+ EMFolderTreeModel *folder_tree_model)
{
- GtkTreeModel *model;
-
- 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;
-
- /* this invokes also sort on a GtkTreeStore */
+ /* This forces the tree store to re-sort. */
gtk_tree_sortable_set_default_sort_func (
- GTK_TREE_SORTABLE (model),
+ GTK_TREE_SORTABLE (folder_tree_model),
folder_tree_model_sort, NULL, 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)
-{
- EMailBackend *backend;
- EMailSession *session;
- CamelService *service;
-
- backend = em_folder_tree_model_get_backend (model);
- session = e_mail_backend_get_session (backend);
-
- 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;
@@ -425,8 +243,8 @@ folder_tree_model_set_property (GObject *object,
g_value_get_object (value));
return;
- case PROP_BACKEND:
- em_folder_tree_model_set_backend (
+ case PROP_SESSION:
+ em_folder_tree_model_set_session (
EM_FOLDER_TREE_MODEL (object),
g_value_get_object (value));
return;
@@ -449,10 +267,10 @@ folder_tree_model_get_property (GObject *object,
EM_FOLDER_TREE_MODEL (object)));
return;
- case PROP_BACKEND:
+ case PROP_SESSION:
g_value_set_object (
value,
- em_folder_tree_model_get_backend (
+ em_folder_tree_model_get_session (
EM_FOLDER_TREE_MODEL (object)));
return;
}
@@ -474,26 +292,17 @@ folder_tree_model_dispose (GObject *object)
priv->selection = NULL;
}
- if (priv->backend != NULL) {
- EShell *shell;
- EShellBackend *shell_backend;
- EShellSettings *shell_settings;
-
- shell_backend = E_SHELL_BACKEND (priv->backend);
- shell = e_shell_backend_get_shell (shell_backend);
- shell_settings = e_shell_get_shell_settings (shell);
-
- g_signal_handlers_disconnect_by_func (
- priv->backend, account_sort_order_changed_cb, object);
- g_signal_handlers_disconnect_by_func (
- shell_settings, account_sort_order_changed_cb, object);
- g_signal_handlers_disconnect_by_func (
- shell_settings, enable_local_folders_changed_cb, object);
- g_signal_handlers_disconnect_by_func (
- shell_settings, enable_search_folders_changed_cb, object);
-
- g_object_unref (priv->backend);
- priv->backend = NULL;
+ if (priv->session != NULL) {
+ g_object_unref (priv->session);
+ priv->session = NULL;
+ }
+
+ if (priv->account_store != NULL) {
+ g_signal_handlers_disconnect_matched (
+ priv->account_store, G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, object);
+ g_object_unref (priv->account_store);
+ priv->account_store = NULL;
}
/* Chain up to parent's dispose() method. */
@@ -510,13 +319,6 @@ folder_tree_model_finalize (GObject *object)
g_hash_table_destroy (priv->store_index);
g_hash_table_destroy (priv->uri_index);
- g_signal_handler_disconnect (
- priv->accounts, priv->account_changed_id);
- g_signal_handler_disconnect (
- priv->accounts, priv->account_removed_id);
- g_signal_handler_disconnect (
- priv->accounts, priv->account_added_id);
-
/* Chain up to parent's finalize() method. */
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -524,8 +326,6 @@ folder_tree_model_finalize (GObject *object)
static void
folder_tree_model_constructed (GObject *object)
{
- EMFolderTreeModelPrivate *priv;
-
GType col_types[] = {
G_TYPE_STRING, /* display name */
G_TYPE_POINTER, /* store object */
@@ -542,8 +342,6 @@ folder_tree_model_constructed (GObject *object)
G_TYPE_UINT /* user's sortorder */
};
- priv = EM_FOLDER_TREE_MODEL_GET_PRIVATE (object);
-
gtk_tree_store_set_column_types (
GTK_TREE_STORE (object), NUM_COLUMNS, col_types);
gtk_tree_sortable_set_default_sort_func (
@@ -554,17 +352,6 @@ folder_tree_model_constructed (GObject *object)
GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
GTK_SORT_ASCENDING);
- priv->accounts = e_get_account_list ();
- priv->account_changed_id = g_signal_connect (
- priv->accounts, "account-changed",
- G_CALLBACK (account_changed_cb), object);
- priv->account_removed_id = g_signal_connect (
- priv->accounts, "account-removed",
- G_CALLBACK (account_removed_cb), object);
- priv->account_added_id = g_signal_connect (
- priv->accounts, "account-added",
- G_CALLBACK (account_added_cb), object);
-
/* Chain up to parent's constructed() method. */
G_OBJECT_CLASS (parent_class)->constructed (object);
}
@@ -586,12 +373,12 @@ em_folder_tree_model_class_init (EMFolderTreeModelClass *class)
g_object_class_install_property (
object_class,
- PROP_BACKEND,
+ PROP_SESSION,
g_param_spec_object (
- "backend",
+ "session",
NULL,
NULL,
- E_TYPE_MAIL_BACKEND,
+ E_TYPE_MAIL_SESSION,
G_PARAM_READWRITE));
g_object_class_install_property (
@@ -754,60 +541,63 @@ em_folder_tree_model_set_selection (EMFolderTreeModel *model,
g_object_notify (G_OBJECT (model), "selection");
}
-EMailBackend *
-em_folder_tree_model_get_backend (EMFolderTreeModel *model)
+EMailSession *
+em_folder_tree_model_get_session (EMFolderTreeModel *model)
{
g_return_val_if_fail (EM_IS_FOLDER_TREE_MODEL (model), NULL);
- return model->priv->backend;
+ return model->priv->session;
}
void
-em_folder_tree_model_set_backend (EMFolderTreeModel *model,
- EMailBackend *backend)
+em_folder_tree_model_set_session (EMFolderTreeModel *model,
+ EMailSession *session)
{
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 (session != NULL) {
+ g_return_if_fail (E_IS_MAIL_SESSION (session));
+ g_object_ref (session);
}
- if (model->priv->backend != NULL)
- g_object_unref (model->priv->backend);
+ if (model->priv->session != NULL)
+ g_object_unref (model->priv->session);
- model->priv->backend = backend;
+ model->priv->session = session;
/* FIXME Technically we should be disconnecting this signal
- * when replacing an old backend with a new backend,
+ * when replacing an old session with a new session,
* but at present this function is only called once. */
- if (backend != NULL) {
+ if (session != NULL) {
+ EMailAccountStore *account_store;
MailFolderCache *folder_cache;
- EMailSession *session;
- EShell *shell;
- EShellBackend *shell_backend;
- EShellSettings *shell_settings;
-
- shell_backend = E_SHELL_BACKEND (backend);
- shell = e_shell_backend_get_shell (shell_backend);
- shell_settings = e_shell_get_shell_settings (shell);
- session = e_mail_backend_get_session (backend);
folder_cache = e_mail_session_get_folder_cache (session);
+ account_store = e_mail_session_get_account_store (session);
- g_signal_connect_swapped (
- backend, "account-sort-order-changed",
- G_CALLBACK (account_sort_order_changed_cb), model);
+ /* Keep our own reference since we connect to its signals. */
+ g_warn_if_fail (model->priv->account_store == NULL);
+ model->priv->account_store = g_object_ref (account_store);
- 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_signal_connect (
+ account_store, "service-removed",
+ G_CALLBACK (folder_tree_model_service_removed),
+ model);
+
+ g_signal_connect (
+ account_store, "service-enabled",
+ G_CALLBACK (folder_tree_model_service_enabled),
+ model);
+
+ g_signal_connect (
+ account_store, "service-disabled",
+ G_CALLBACK (folder_tree_model_service_disabled),
+ model);
+
+ g_signal_connect (
+ account_store, "services-reordered",
+ G_CALLBACK (folder_tree_model_services_reordered),
+ model);
g_signal_connect_swapped (
folder_cache, "folder-unread-updated",
@@ -815,7 +605,7 @@ em_folder_tree_model_set_backend (EMFolderTreeModel *model,
model);
}
- g_object_notify (G_OBJECT (model), "backend");
+ g_object_notify (G_OBJECT (model), "session");
}
void
@@ -828,7 +618,6 @@ em_folder_tree_model_set_folder_info (EMFolderTreeModel *model,
GtkTreeRowReference *uri_row, *path_row;
GtkTreeStore *tree_store;
MailFolderCache *folder_cache;
- EMailBackend *backend;
EMailSession *session;
EAccount *account;
guint unread;
@@ -845,6 +634,7 @@ em_folder_tree_model_set_folder_info (EMFolderTreeModel *model,
gboolean folder_is_drafts = FALSE;
gboolean folder_is_outbox = FALSE;
gboolean folder_is_templates = FALSE;
+ gboolean store_is_local;
gchar *uri;
/* Make sure we don't already know about it. */
@@ -853,11 +643,11 @@ em_folder_tree_model_set_folder_info (EMFolderTreeModel *model,
tree_store = GTK_TREE_STORE (model);
- backend = em_folder_tree_model_get_backend (model);
- session = e_mail_backend_get_session (backend);
+ session = em_folder_tree_model_get_session (model);
folder_cache = e_mail_session_get_folder_cache (session);
uid = camel_service_get_uid (CAMEL_SERVICE (si->store));
+ store_is_local = (g_strcmp0 (uid, E_MAIL_SESSION_LOCAL_UID) == 0);
account = e_get_account_by_uid (uid);
if (!fully_loaded)
@@ -907,7 +697,7 @@ em_folder_tree_model_set_folder_info (EMFolderTreeModel *model,
flags = fi->flags;
display_name = fi->display_name;
- if (si->store == e_mail_local_get_store ()) {
+ if (store_is_local) {
if (strcmp (fi->full_name, "Drafts") == 0) {
folder_is_drafts = TRUE;
display_name = _("Drafts");
@@ -1202,7 +992,6 @@ void
em_folder_tree_model_add_store (EMFolderTreeModel *model,
CamelStore *store)
{
- EMailBackend *mail_backend;
EMFolderTreeModelStoreInfo *si;
GtkTreeRowReference *reference;
GtkTreeStore *tree_store;
@@ -1212,7 +1001,6 @@ 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));
@@ -1223,7 +1011,6 @@ em_folder_tree_model_add_store (EMFolderTreeModel *model,
service = CAMEL_SERVICE (store);
provider = camel_service_get_provider (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. */
@@ -1245,8 +1032,6 @@ em_folder_tree_model_add_store (EMFolderTreeModel *model,
if (si != NULL)
em_folder_tree_model_remove_store (model, store);
- 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 (
@@ -1257,7 +1042,6 @@ em_folder_tree_model_add_store (EMFolderTreeModel *model,
COL_BOOL_LOAD_SUBDIRS, TRUE,
COL_BOOL_IS_STORE, TRUE,
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);
diff --git a/mail/em-folder-tree-model.h b/mail/em-folder-tree-model.h
index 0ed007aa96..1bf5483367 100644
--- a/mail/em-folder-tree-model.h
+++ b/mail/em-folder-tree-model.h
@@ -26,7 +26,6 @@
#include <gtk/gtk.h>
#include <camel/camel.h>
-#include <mail/e-mail-backend.h>
#include <mail/e-mail-session.h>
/* Standard GObject macros */
@@ -73,7 +72,6 @@ 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
};
@@ -120,11 +118,11 @@ GtkTreeSelection *
void em_folder_tree_model_set_selection
(EMFolderTreeModel *model,
GtkTreeSelection *selection);
-EMailBackend * em_folder_tree_model_get_backend
+EMailSession * em_folder_tree_model_get_session
(EMFolderTreeModel *model);
-void em_folder_tree_model_set_backend
+void em_folder_tree_model_set_session
(EMFolderTreeModel *model,
- EMailBackend *backend);
+ EMailSession *session);
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 48cf6af40d..5ef1845304 100644
--- a/mail/em-folder-tree.c
+++ b/mail/em-folder-tree.c
@@ -62,9 +62,7 @@
#include "em-event.h"
#include "e-mail-folder-utils.h"
-#include "e-mail-local.h"
#include "e-mail-session.h"
-#include "e-mail-store.h"
#define d(x)
@@ -720,15 +718,17 @@ folder_tree_render_display_name (GtkTreeViewColumn *column,
GtkTreeModel *model,
GtkTreeIter *iter)
{
+ CamelService *service;
PangoWeight weight;
gboolean is_store, bold, subdirs_unread = FALSE;
gboolean editable;
guint unread;
- gchar *display;
gchar *name;
gtk_tree_model_get (
- model, iter, COL_STRING_DISPLAY_NAME, &name,
+ model, iter,
+ COL_STRING_DISPLAY_NAME, &name,
+ COL_POINTER_CAMEL_STORE, &service,
COL_BOOL_IS_STORE, &is_store,
COL_UINT_UNREAD, &unread, -1);
@@ -747,8 +747,17 @@ folder_tree_render_display_name (GtkTreeViewColumn *column,
bold = !editable && (bold || subdirs_unread);
weight = bold ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL;
+ g_object_set (renderer, "weight", weight, NULL);
+
+ if (is_store) {
+ const gchar *display_name;
+
+ display_name = camel_service_get_display_name (service);
+ g_object_set (renderer, "text", display_name, NULL);
+
+ } else if (!editable && unread > 0) {
+ gchar *name_and_unread;
- if (!is_store && !editable && unread) {
/* Translators: This is the string used for displaying the
* folder names in folder trees. The first "%s" will be
* replaced by the folder's name and "%u" will be replaced
@@ -767,16 +776,17 @@ folder_tree_render_display_name (GtkTreeViewColumn *column,
* Do not translate the "folder-display|" part. Remove it
* from your translation.
*/
- display = g_strdup_printf (
+ name_and_unread = g_strdup_printf (
C_("folder-display", "%s (%u%s)"),
name, unread, subdirs_unread ? "+" : "");
- g_free (name);
- } else
- display = name;
+ g_object_set (renderer, "text", name_and_unread, NULL);
+ g_free (name_and_unread);
- g_object_set (renderer, "text", display, "weight", weight, NULL);
+ } else {
+ g_object_set (renderer, "text", name, NULL);
+ }
- g_free (display);
+ g_free (name);
}
static void
@@ -1783,18 +1793,10 @@ em_folder_tree_new_with_model (EMailBackend *backend,
EAlertSink *alert_sink,
EMFolderTreeModel *model)
{
- EMailSession *session;
- const gchar *data_dir;
-
g_return_val_if_fail (E_IS_MAIL_BACKEND (backend), NULL);
g_return_val_if_fail (E_IS_ALERT_SINK (alert_sink), NULL);
g_return_val_if_fail (EM_IS_FOLDER_TREE_MODEL (model), NULL);
- session = e_mail_backend_get_session (backend);
- data_dir = e_shell_backend_get_data_dir (E_SHELL_BACKEND (backend));
-
- e_mail_store_init (session, data_dir);
-
return g_object_new (
EM_TYPE_FOLDER_TREE,
"alert-sink", alert_sink,
@@ -2283,7 +2285,6 @@ folder_tree_drop_target (EMFolderTree *folder_tree,
EMFolderTreePrivate *p = folder_tree->priv;
gchar *dst_full_name = NULL;
gchar *src_full_name = NULL;
- CamelStore *local;
CamelStore *dst_store;
CamelStore *src_store = NULL;
GdkAtom atom = GDK_NONE;
@@ -2292,6 +2293,7 @@ folder_tree_drop_target (EMFolderTree *folder_tree,
GtkTreeIter iter;
GList *targets;
const gchar *uid;
+ gboolean src_is_local;
gboolean src_is_vfolder;
gboolean dst_is_vfolder;
guint32 flags = 0;
@@ -2314,10 +2316,8 @@ folder_tree_drop_target (EMFolderTree *folder_tree,
COL_STRING_FULL_NAME, &dst_full_name,
COL_UINT_FLAGS, &flags, -1);
- local = e_mail_local_get_store ();
-
uid = camel_service_get_uid (CAMEL_SERVICE (dst_store));
- dst_is_vfolder = (g_strcmp0 (uid, "vfolder") == 0);
+ dst_is_vfolder = (g_strcmp0 (uid, E_MAIL_SESSION_VFOLDER_UID) == 0);
targets = gdk_drag_context_list_targets (context);
@@ -2392,13 +2392,17 @@ folder_tree_drop_target (EMFolderTree *folder_tree,
if (src_store != NULL && src_full_name != NULL) {
uid = camel_service_get_uid (CAMEL_SERVICE (src_store));
- src_is_vfolder = (g_strcmp0 (uid, "vfolder") == 0);
+
+ src_is_local =
+ (g_strcmp0 (uid, E_MAIL_SESSION_LOCAL_UID) == 0);
+ src_is_vfolder =
+ (g_strcmp0 (uid, E_MAIL_SESSION_VFOLDER_UID) == 0);
/* FIXME: this is a total hack, but i think all we can do at present */
/* Check for dragging from special folders which can't be moved/copied */
/* Don't allow moving any of the the special local folders. */
- if (src_store == local && is_special_local_folder (src_full_name)) {
+ if (src_is_local && is_special_local_folder (src_full_name)) {
GdkAtom xfolder;
/* force copy for special local folders */
diff --git a/mail/em-folder-utils.c b/mail/em-folder-utils.c
index e72b8014ad..2ac87d7efd 100644
--- a/mail/em-folder-utils.c
+++ b/mail/em-folder-utils.c
@@ -59,9 +59,7 @@
#include "em-folder-properties.h"
#include "e-mail-folder-utils.h"
-#include "e-mail-local.h"
#include "e-mail-session.h"
-#include "e-mail-store.h"
#include "e-mail-store-utils.h"
#define d(x)
@@ -339,15 +337,15 @@ emfu_copy_folder_selected (EMailBackend *backend,
EMailSession *session;
struct _copy_folder_data *cfd = data;
CamelStore *tostore = NULL;
- CamelStore *local_store;
CamelService *service;
+ gboolean store_is_local;
+ const gchar *uid;
gchar *tobase = NULL;
GError *local_error = NULL;
if (uri == NULL)
goto fail;
- local_store = e_mail_local_get_store ();
session = e_mail_backend_get_session (backend);
service = CAMEL_SERVICE (cfd->source_store);
@@ -365,7 +363,10 @@ emfu_copy_folder_selected (EMailBackend *backend,
g_return_if_fail (CAMEL_IS_STORE (service));
- if (cfd->delete && cfd->source_store == local_store &&
+ uid = camel_service_get_uid (CAMEL_SERVICE (cfd->source_store));
+ store_is_local = (g_strcmp0 (uid, E_MAIL_SESSION_LOCAL_UID) == 0);
+
+ if (cfd->delete && store_is_local &&
emfu_is_special_local_folder (cfd->source_folder_name)) {
e_mail_backend_submit_alert (
backend, "mail:no-rename-special-folder",
@@ -426,7 +427,7 @@ emfu_copy_folder_exclude (EMFolderTree *tree,
/* handles moving to/from vfolders */
uid = camel_service_get_uid (CAMEL_SERVICE (cfd->source_store));
- fromvfolder = (g_strcmp0 (uid, "vfolder") == 0);
+ fromvfolder = (g_strcmp0 (uid, E_MAIL_SESSION_VFOLDER_UID) == 0);
gtk_tree_model_get (
model, iter,
@@ -434,7 +435,7 @@ emfu_copy_folder_exclude (EMFolderTree *tree,
COL_POINTER_CAMEL_STORE, &store, -1);
uid = camel_service_get_uid (CAMEL_SERVICE (store));
- tovfolder = (g_strcmp0 (uid, "vfolder") == 0);
+ tovfolder = (g_strcmp0 (uid, E_MAIL_SESSION_VFOLDER_UID) == 0);
/* moving from vfolder to normal- not allowed */
if (fromvfolder && !tovfolder && cfd->delete)
@@ -566,9 +567,9 @@ em_folder_utils_create_folder (GtkWindow *parent,
shell_settings = e_shell_get_shell_settings (shell);
model = em_folder_tree_model_new ();
- em_folder_tree_model_set_backend (model, backend);
-
session = e_mail_backend_get_session (backend);
+ em_folder_tree_model_set_session (model, session);
+
list = camel_session_list_services (CAMEL_SESSION (session));
for (link = list; link != NULL; link = g_list_next (link)) {
@@ -587,9 +588,9 @@ em_folder_utils_create_folder (GtkWindow *parent,
continue;
uid = camel_service_get_uid (service);
- if (g_strcmp0 (uid, "local") == 0)
+ if (g_strcmp0 (uid, E_MAIL_SESSION_LOCAL_UID) == 0)
prop = "mail-enable-local-folders";
- else if (g_strcmp0 (uid, "vfolder") == 0)
+ else if (g_strcmp0 (uid, E_MAIL_SESSION_VFOLDER_UID) == 0)
prop = "mail-enable-search-folders";
if (prop && !e_shell_settings_get_boolean (shell_settings, prop))
diff --git a/mail/em-utils.c b/mail/em-utils.c
index c15f8b67b5..bfda4056be 100644
--- a/mail/em-utils.c
+++ b/mail/em-utils.c
@@ -71,7 +71,6 @@
#include "em-composer-utils.h"
#include "em-format-quote.h"
#include "e-mail-folder-utils.h"
-#include "e-mail-local.h"
#include "e-mail-session.h"
/* XXX This is a dirty hack on a dirty hack. We really need
@@ -84,8 +83,6 @@ 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)
@@ -998,17 +995,18 @@ em_utils_folder_is_templates (CamelFolder *folder)
g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE);
+ store = camel_folder_get_parent_store (folder);
+ session = camel_service_get_session (CAMEL_SERVICE (store));
+
local_templates_folder =
- e_mail_local_get_folder (E_MAIL_LOCAL_FOLDER_TEMPLATES);
+ e_mail_session_get_local_folder (
+ E_MAIL_SESSION (session), E_MAIL_LOCAL_FOLDER_TEMPLATES);
if (folder == local_templates_folder)
return TRUE;
folder_uri = e_mail_folder_uri_from_folder (folder);
- store = camel_folder_get_parent_store (folder);
- session = camel_service_get_session (CAMEL_SERVICE (store));
-
account_list = e_get_account_list ();
iterator = e_list_get_iterator (E_LIST (account_list));
@@ -1053,17 +1051,18 @@ em_utils_folder_is_drafts (CamelFolder *folder)
g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE);
+ store = camel_folder_get_parent_store (folder);
+ session = camel_service_get_session (CAMEL_SERVICE (store));
+
local_drafts_folder =
- e_mail_local_get_folder (E_MAIL_LOCAL_FOLDER_DRAFTS);
+ e_mail_session_get_local_folder (
+ E_MAIL_SESSION (session), E_MAIL_LOCAL_FOLDER_DRAFTS);
if (folder == local_drafts_folder)
return TRUE;
folder_uri = e_mail_folder_uri_from_folder (folder);
- store = camel_folder_get_parent_store (folder);
- session = camel_service_get_session (CAMEL_SERVICE (store));
-
account_list = e_get_account_list ();
iterator = e_list_get_iterator (E_LIST (account_list));
@@ -1108,17 +1107,18 @@ em_utils_folder_is_sent (CamelFolder *folder)
g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE);
+ store = camel_folder_get_parent_store (folder);
+ session = camel_service_get_session (CAMEL_SERVICE (store));
+
local_sent_folder =
- e_mail_local_get_folder (E_MAIL_LOCAL_FOLDER_SENT);
+ e_mail_session_get_local_folder (
+ E_MAIL_SESSION (session), E_MAIL_LOCAL_FOLDER_SENT);
if (folder == local_sent_folder)
return TRUE;
folder_uri = e_mail_folder_uri_from_folder (folder);
- store = camel_folder_get_parent_store (folder);
- session = camel_service_get_session (CAMEL_SERVICE (store));
-
account_list = e_get_account_list ();
iterator = e_list_get_iterator (E_LIST (account_list));
@@ -1153,12 +1153,18 @@ em_utils_folder_is_sent (CamelFolder *folder)
gboolean
em_utils_folder_is_outbox (CamelFolder *folder)
{
+ CamelStore *store;
+ CamelSession *session;
CamelFolder *local_outbox_folder;
g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE);
+ store = camel_folder_get_parent_store (folder);
+ session = camel_service_get_session (CAMEL_SERVICE (store));
+
local_outbox_folder =
- e_mail_local_get_folder (E_MAIL_LOCAL_FOLDER_OUTBOX);
+ e_mail_session_get_local_folder (
+ E_MAIL_SESSION (session), E_MAIL_LOCAL_FOLDER_OUTBOX);
return (folder == local_outbox_folder);
}
@@ -1911,8 +1917,6 @@ emu_free_mail_cache (void)
photos_cache = NULL;
G_UNLOCK (photos_cache);
-
- free_account_sort_order_cache ();
}
void
@@ -2269,169 +2273,3 @@ 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 b7e3ec6f49..0a27266d31 100644
--- a/mail/em-utils.h
+++ b/mail/em-utils.h
@@ -98,10 +98,6 @@ 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 831059910c..3f0c2200aa 100644
--- a/mail/em-vfolder-rule.c
+++ b/mail/em-vfolder-rule.c
@@ -33,7 +33,6 @@
#include "em-vfolder-context.h"
#include "em-vfolder-rule.h"
#include "mail/e-mail-folder-utils.h"
-#include "mail/e-mail-store.h"
#include "mail/em-utils.h"
#include "mail/em-folder-tree.h"
#include "mail/em-folder-selector.h"
diff --git a/mail/importers/evolution-mbox-importer.c b/mail/importers/evolution-mbox-importer.c
index 3c97bd953b..b158d606a9 100644
--- a/mail/importers/evolution-mbox-importer.c
+++ b/mail/importers/evolution-mbox-importer.c
@@ -45,8 +45,6 @@
#include "shell/e-shell-sidebar.h"
#include "mail/e-mail-backend.h"
-#include "mail/e-mail-local.h"
-#include "mail/e-mail-store.h"
#include "mail/em-folder-selection-button.h"
#include "mail/em-folder-tree-model.h"
#include "mail/em-folder-tree.h"
@@ -85,6 +83,8 @@ mbox_getwidget (EImport *ei,
{
EShell *shell;
EShellBackend *shell_backend;
+ EMailBackend *backend;
+ EMailSession *session;
GtkWindow *window;
GtkWidget *hbox, *w;
GtkLabel *label;
@@ -96,6 +96,9 @@ mbox_getwidget (EImport *ei,
shell = e_shell_get_default ();
shell_backend = e_shell_get_backend_by_name (shell, "mail");
+ backend = E_MAIL_BACKEND (shell_backend);
+ session = e_mail_backend_get_session (backend);
+
/* preselect the folder selected in a mail view */
window = e_shell_get_active_window (shell);
if (E_IS_SHELL_WINDOW (window)) {
@@ -129,7 +132,8 @@ mbox_getwidget (EImport *ei,
if (!select_uri) {
const gchar *uri;
- uri = e_mail_local_get_folder_uri (E_MAIL_LOCAL_FOLDER_INBOX);
+ uri = e_mail_session_get_local_folder_uri (
+ session, E_MAIL_LOCAL_FOLDER_INBOX);
select_uri = g_strdup (uri);
}
diff --git a/mail/importers/mail-importer.c b/mail/importers/mail-importer.c
index e28de37b3c..558359c636 100644
--- a/mail/importers/mail-importer.c
+++ b/mail/importers/mail-importer.c
@@ -41,7 +41,6 @@
#include "mail-mt.h"
#include "mail-tools.h"
-#include "e-mail-local.h"
#include "e-mail-session.h"
#include "mail-importer.h"
@@ -124,7 +123,8 @@ import_mbox_exec (struct _import_mbox_msg *m,
}
if (m->uri == NULL || m->uri[0] == 0)
- folder = e_mail_local_get_folder (E_MAIL_LOCAL_FOLDER_INBOX);
+ folder = e_mail_session_get_local_folder (
+ m->session, E_MAIL_LOCAL_FOLDER_INBOX);
else
folder = e_mail_session_uri_to_folder_sync (
m->session, m->uri, CAMEL_STORE_FOLDER_CREATE,
diff --git a/mail/mail-config.c b/mail/mail-config.c
index bbad256d2f..883612b346 100644
--- a/mail/mail-config.c
+++ b/mail/mail-config.c
@@ -34,7 +34,6 @@
#include "e-util/e-account-utils.h"
#include "e-util/e-signature-utils.h"
-#include "e-mail-local.h"
#include "e-mail-folder-utils.h"
#include "mail-config.h"
#include "mail-tools.h"
diff --git a/mail/mail-folder-cache.c b/mail/mail-folder-cache.c
index cab15c5e93..d9e3befa79 100644
--- a/mail/mail-folder-cache.c
+++ b/mail/mail-folder-cache.c
@@ -49,7 +49,6 @@
#include "em-utils.h"
#include "e-mail-folder-utils.h"
-#include "e-mail-local.h"
#include "e-mail-session.h"
#include "e-mail-store-utils.h"
@@ -62,7 +61,12 @@
/* This code is a mess, there is no reason it should be so complicated. */
+typedef struct _StoreInfo StoreInfo;
+
struct _MailFolderCachePrivate {
+ gpointer session; /* weak pointer */
+ EMailAccountStore *account_store;
+
/* source id for the ping timeout callback */
guint ping_id;
/* Store to storeinfo table, active stores */
@@ -82,6 +86,11 @@ struct _MailFolderCachePrivate {
};
enum {
+ PROP_0,
+ PROP_SESSION
+};
+
+enum {
FOLDER_AVAILABLE,
FOLDER_UNAVAILABLE,
FOLDER_DELETED,
@@ -94,7 +103,7 @@ enum {
static guint signals[LAST_SIGNAL];
struct _folder_info {
- struct _store_info *store_info; /* 'parent' link */
+ StoreInfo *store_info; /* 'parent' link */
gchar *full_name; /* full name of folder/folderinfo */
@@ -124,14 +133,26 @@ struct _folder_update {
gchar *msg_subject; /* ... and its subject. */
};
-struct _store_info {
+struct _StoreInfo {
GHashTable *folders; /* by full_name */
CamelStore *store; /* the store for these folders */
+ gboolean first_update; /* TRUE initially, then FALSE forever */
+
+ /* Hold a reference to keep them alive. */
+ CamelFolder *vjunk;
+ CamelFolder *vtrash;
/* Outstanding folderinfo requests */
GQueue folderinfo_updates;
};
+struct _update_data {
+ NoteDoneFunc done;
+ gpointer data;
+ MailFolderCache *cache;
+ GCancellable *cancellable;
+};
+
G_DEFINE_TYPE (MailFolderCache, mail_folder_cache, G_TYPE_OBJECT)
static void
@@ -147,6 +168,66 @@ free_update (struct _folder_update *up)
g_free (up);
}
+static void
+free_folder_info (struct _folder_info *mfi)
+{
+ g_free (mfi->full_name);
+ g_free (mfi);
+}
+
+static StoreInfo *
+store_info_new (CamelStore *store)
+{
+ StoreInfo *info;
+ GHashTable *folders;
+
+ folders = g_hash_table_new_full (
+ (GHashFunc) g_str_hash,
+ (GEqualFunc) g_str_equal,
+ (GDestroyNotify) NULL,
+ (GDestroyNotify) free_folder_info);
+
+ info = g_slice_new0 (StoreInfo);
+ info->folders = folders;
+ info->store = g_object_ref (store);
+ info->first_update = TRUE;
+
+ /* If these are vfolders then they need to be opened
+ * now, otherwise they won't keep track of all folders. */
+ if (store->flags & CAMEL_STORE_VJUNK)
+ info->vjunk = camel_store_get_junk_folder_sync (
+ store, NULL, NULL);
+ if (store->flags & CAMEL_STORE_VTRASH)
+ info->vtrash = camel_store_get_trash_folder_sync (
+ store, NULL, NULL);
+
+ g_queue_init (&info->folderinfo_updates);
+
+ return info;
+}
+
+static void
+store_info_free (StoreInfo *info)
+{
+ struct _update_data *ud;
+
+ while (!g_queue_is_empty (&info->folderinfo_updates)) {
+ ud = g_queue_pop_head (&info->folderinfo_updates);
+ g_cancellable_cancel (ud->cancellable);
+ }
+
+ g_hash_table_destroy (info->folders);
+ g_object_unref (info->store);
+
+ if (info->vjunk != NULL)
+ g_object_unref (info->vjunk);
+
+ if (info->vtrash != NULL)
+ g_object_unref (info->vtrash);
+
+ g_slice_free (StoreInfo, info);
+}
+
static gboolean
flush_updates_idle_cb (MailFolderCache *cache)
{
@@ -334,9 +415,10 @@ folder_changed_cb (CamelFolder *folder,
CamelFolder *local_drafts;
CamelFolder *local_outbox;
CamelFolder *local_sent;
+ CamelSession *session;
CamelStore *parent_store;
CamelMessageInfo *info;
- struct _store_info *si;
+ StoreInfo *si;
struct _folder_info *mfi;
const gchar *full_name;
gint new = 0;
@@ -346,6 +428,7 @@ folder_changed_cb (CamelFolder *folder,
full_name = camel_folder_get_full_name (folder);
parent_store = camel_folder_get_parent_store (folder);
+ session = camel_service_get_session (CAMEL_SERVICE (parent_store));
if (!last_newmail_per_folder)
last_newmail_per_folder = g_hash_table_new (g_direct_hash, g_direct_equal);
@@ -355,9 +438,12 @@ folder_changed_cb (CamelFolder *folder,
g_hash_table_lookup (last_newmail_per_folder, folder));
new_latest_received = latest_received;
- local_drafts = e_mail_local_get_folder (E_MAIL_LOCAL_FOLDER_DRAFTS);
- local_outbox = e_mail_local_get_folder (E_MAIL_LOCAL_FOLDER_OUTBOX);
- local_sent = e_mail_local_get_folder (E_MAIL_LOCAL_FOLDER_SENT);
+ local_drafts = e_mail_session_get_local_folder (
+ E_MAIL_SESSION (session), E_MAIL_LOCAL_FOLDER_DRAFTS);
+ local_outbox = e_mail_session_get_local_folder (
+ E_MAIL_SESSION (session), E_MAIL_LOCAL_FOLDER_OUTBOX);
+ local_sent = e_mail_session_get_local_folder (
+ E_MAIL_SESSION (session), E_MAIL_LOCAL_FOLDER_SENT);
if (!CAMEL_IS_VEE_FOLDER (folder)
&& folder != local_drafts
@@ -451,16 +537,9 @@ unset_folder_info (MailFolderCache *cache,
}
static void
-free_folder_info (struct _folder_info *mfi)
-{
- g_free (mfi->full_name);
- g_free (mfi);
-}
-
-static void
setup_folder (MailFolderCache *cache,
CamelFolderInfo *fi,
- struct _store_info *si)
+ StoreInfo *si)
{
struct _folder_info *mfi;
struct _folder_update *up;
@@ -493,7 +572,7 @@ setup_folder (MailFolderCache *cache,
static void
create_folders (MailFolderCache *cache,
CamelFolderInfo *fi,
- struct _store_info *si)
+ StoreInfo *si)
{
while (fi) {
setup_folder (cache, fi, si);
@@ -510,7 +589,7 @@ store_folder_subscribed_cb (CamelStore *store,
CamelFolderInfo *info,
MailFolderCache *cache)
{
- struct _store_info *si;
+ StoreInfo *si;
g_mutex_lock (cache->priv->stores_mutex);
si = g_hash_table_lookup (cache->priv->stores, store);
@@ -543,7 +622,7 @@ store_folder_unsubscribed_cb (CamelStore *store,
CamelFolderInfo *info,
MailFolderCache *cache)
{
- struct _store_info *si;
+ StoreInfo *si;
struct _folder_info *mfi;
g_mutex_lock (cache->priv->stores_mutex);
@@ -572,7 +651,7 @@ store_folder_deleted_cb (CamelStore *store,
static void
rename_folders (MailFolderCache *cache,
- struct _store_info *si,
+ StoreInfo *si,
const gchar *oldbase,
const gchar *newbase,
CamelFolderInfo *fi)
@@ -678,7 +757,7 @@ store_folder_renamed_cb (CamelStore *store,
CamelFolderInfo *info,
MailFolderCache *cache)
{
- struct _store_info *si;
+ StoreInfo *si;
g_mutex_lock (cache->priv->stores_mutex);
si = g_hash_table_lookup (cache->priv->stores, store);
@@ -703,13 +782,6 @@ store_folder_renamed_cb (CamelStore *store,
g_mutex_unlock (cache->priv->stores_mutex);
}
-struct _update_data {
- NoteDoneFunc done;
- gpointer data;
- MailFolderCache *cache;
- GCancellable *cancellable;
-};
-
static void
unset_folder_info_hash (gchar *path,
struct _folder_info *mfi,
@@ -720,11 +792,31 @@ unset_folder_info_hash (gchar *path,
}
static void
-free_folder_info_hash (gchar *path,
- struct _folder_info *mfi,
- gpointer data)
+mail_folder_cache_first_update (MailFolderCache *cache,
+ StoreInfo *info)
{
- free_folder_info (mfi);
+ EMailSession *session;
+ const gchar *uid;
+
+ session = mail_folder_cache_get_session (cache);
+ uid = camel_service_get_uid (CAMEL_SERVICE (info->store));
+
+ if (info->vjunk != NULL)
+ mail_folder_cache_note_folder (cache, info->vjunk);
+
+ if (info->vtrash != NULL)
+ mail_folder_cache_note_folder (cache, info->vtrash);
+
+ /* Some extra work for the "On This Computer" store. */
+ if (g_strcmp0 (uid, E_MAIL_SESSION_LOCAL_UID) == 0) {
+ CamelFolder *folder;
+ gint ii;
+
+ for (ii = 0; ii < E_MAIL_NUM_LOCAL_FOLDERS; ii++) {
+ folder = e_mail_session_get_local_folder (session, ii);
+ mail_folder_cache_note_folder (cache, folder);
+ }
+ }
}
static void
@@ -733,7 +825,7 @@ update_folders (CamelStore *store,
struct _update_data *ud)
{
CamelFolderInfo *fi;
- struct _store_info *si;
+ StoreInfo *si;
GError *error = NULL;
fi = camel_store_get_folder_info_finish (store, result, &error);
@@ -756,6 +848,12 @@ update_folders (CamelStore *store,
}
g_mutex_unlock (ud->cache->priv->stores_mutex);
+ /* Do some extra work for the first update. */
+ if (si != NULL && si->first_update) {
+ mail_folder_cache_first_update (ud->cache, si);
+ si->first_update = FALSE;
+ }
+
if (fi != NULL) {
gboolean free_fi = TRUE;
@@ -913,7 +1011,7 @@ struct _find_info {
static void
storeinfo_find_folder_info (CamelStore *store,
- struct _store_info *si,
+ StoreInfo *si,
struct _find_info *fi)
{
gchar *folder_name;
@@ -933,34 +1031,175 @@ storeinfo_find_folder_info (CamelStore *store,
}
static void
+mail_folder_cache_service_added (EMailAccountStore *account_store,
+ CamelService *service,
+ MailFolderCache *cache)
+{
+ mail_folder_cache_note_store (
+ cache, CAMEL_STORE (service), NULL, NULL, NULL);
+}
+
+static void
+mail_folder_cache_service_removed (EMailAccountStore *account_store,
+ CamelService *service,
+ MailFolderCache *cache)
+{
+ StoreInfo *si;
+
+ if (cache->priv->stores == NULL)
+ return;
+
+ g_mutex_lock (cache->priv->stores_mutex);
+
+ si = g_hash_table_lookup (cache->priv->stores, service);
+ if (si != NULL) {
+ g_hash_table_remove (cache->priv->stores, service);
+
+ g_signal_handlers_disconnect_matched (
+ service, G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, cache);
+
+ g_hash_table_foreach (
+ si->folders, (GHFunc)
+ unset_folder_info_hash, cache);
+
+ store_info_free (si);
+ }
+
+ g_mutex_unlock (cache->priv->stores_mutex);
+}
+
+static void
+mail_folder_cache_set_session (MailFolderCache *cache,
+ EMailSession *session)
+{
+ g_return_if_fail (E_IS_MAIL_SESSION (session));
+ g_return_if_fail (cache->priv->session == NULL);
+
+ cache->priv->session = session;
+
+ g_object_add_weak_pointer (
+ G_OBJECT (cache->priv->session),
+ &cache->priv->session);
+}
+
+static void
+mail_folder_cache_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SESSION:
+ mail_folder_cache_set_session (
+ MAIL_FOLDER_CACHE (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_folder_cache_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SESSION:
+ g_value_set_object (
+ value,
+ mail_folder_cache_get_session (
+ MAIL_FOLDER_CACHE (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_folder_cache_dispose (GObject *object)
+{
+ MailFolderCachePrivate *priv;
+
+ priv = MAIL_FOLDER_CACHE_GET_PRIVATE (object);
+
+ if (priv->session != NULL) {
+ g_object_remove_weak_pointer (
+ G_OBJECT (priv->session), &priv->session);
+ priv->session = NULL;
+ }
+
+ if (priv->account_store != NULL) {
+ g_signal_handlers_disconnect_matched (
+ priv->account_store, G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, object);
+ g_object_unref (priv->account_store);
+ priv->account_store = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (mail_folder_cache_parent_class)->dispose (object);
+}
+
+static void
mail_folder_cache_finalize (GObject *object)
{
- MailFolderCache *cache = (MailFolderCache *) object;
+ MailFolderCachePrivate *priv;
- g_hash_table_destroy (cache->priv->stores);
- g_mutex_free (cache->priv->stores_mutex);
+ priv = MAIL_FOLDER_CACHE_GET_PRIVATE (object);
- if (cache->priv->ping_id > 0) {
- g_source_remove (cache->priv->ping_id);
- cache->priv->ping_id = 0;
+ g_hash_table_destroy (priv->stores);
+ g_mutex_free (priv->stores_mutex);
+
+ if (priv->ping_id > 0) {
+ g_source_remove (priv->ping_id);
+ priv->ping_id = 0;
}
- if (cache->priv->update_id > 0) {
- g_source_remove (cache->priv->update_id);
- cache->priv->update_id = 0;
+ if (priv->update_id > 0) {
+ g_source_remove (priv->update_id);
+ priv->update_id = 0;
}
- while (!g_queue_is_empty (&cache->priv->local_folder_uris))
- g_free (g_queue_pop_head (&cache->priv->local_folder_uris));
+ while (!g_queue_is_empty (&priv->local_folder_uris))
+ g_free (g_queue_pop_head (&priv->local_folder_uris));
- while (!g_queue_is_empty (&cache->priv->remote_folder_uris))
- g_free (g_queue_pop_head (&cache->priv->remote_folder_uris));
+ while (!g_queue_is_empty (&priv->remote_folder_uris))
+ g_free (g_queue_pop_head (&priv->remote_folder_uris));
/* Chain up to parent's finalize() method. */
G_OBJECT_CLASS (mail_folder_cache_parent_class)->finalize (object);
}
static void
+mail_folder_cache_constructed (GObject *object)
+{
+ MailFolderCache *cache;
+ EMailSession *session;
+ EMailAccountStore *account_store;
+
+ cache = MAIL_FOLDER_CACHE (object);
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (mail_folder_cache_parent_class)->constructed (object);
+
+ session = mail_folder_cache_get_session (cache);
+ account_store = e_mail_session_get_account_store (session);
+
+ cache->priv->account_store = g_object_ref (account_store);
+
+ g_signal_connect (
+ account_store, "service-added",
+ G_CALLBACK (mail_folder_cache_service_added), cache);
+
+ g_signal_connect (
+ account_store, "service-removed",
+ G_CALLBACK (mail_folder_cache_service_removed), cache);
+}
+
+static void
mail_folder_cache_folder_available (MailFolderCache *cache,
CamelStore *store,
const gchar *folder_name)
@@ -1118,12 +1357,28 @@ mail_folder_cache_class_init (MailFolderCacheClass *class)
g_type_class_add_private (class, sizeof (MailFolderCachePrivate));
object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = mail_folder_cache_set_property;
+ object_class->get_property = mail_folder_cache_get_property;
+ object_class->dispose = mail_folder_cache_dispose;
object_class->finalize = mail_folder_cache_finalize;
+ object_class->constructed = mail_folder_cache_constructed;
class->folder_available = mail_folder_cache_folder_available;
class->folder_unavailable = mail_folder_cache_folder_unavailable;
class->folder_deleted = mail_folder_cache_folder_deleted;
+ g_object_class_install_property (
+ object_class,
+ PROP_SESSION,
+ g_param_spec_object (
+ "session",
+ "Session",
+ "Mail session",
+ E_TYPE_MAIL_SESSION,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
/**
* MailFolderCache::folder-available
* @store: the #CamelStore containing the folder
@@ -1274,9 +1529,21 @@ mail_folder_cache_init (MailFolderCache *cache)
}
MailFolderCache *
-mail_folder_cache_new (void)
+mail_folder_cache_new (EMailSession *session)
{
- return g_object_new (MAIL_TYPE_FOLDER_CACHE, NULL);
+ g_return_val_if_fail (E_IS_MAIL_SESSION (session), NULL);
+
+ return g_object_new (
+ MAIL_TYPE_FOLDER_CACHE,
+ "session", session, NULL);
+}
+
+EMailSession *
+mail_folder_cache_get_session (MailFolderCache *cache)
+{
+ g_return_val_if_fail (MAIL_IS_FOLDER_CACHE (cache), NULL);
+
+ return E_MAIL_SESSION (cache->priv->session);
}
/**
@@ -1294,12 +1561,12 @@ mail_folder_cache_note_store (MailFolderCache *cache,
gpointer data)
{
CamelSession *session;
- struct _store_info *si;
+ StoreInfo *si;
struct _update_data *ud;
gint hook = 0;
+ g_return_if_fail (MAIL_IS_FOLDER_CACHE (cache));
g_return_if_fail (CAMEL_IS_STORE (store));
- g_return_if_fail (mail_in_main_thread ());
session = camel_service_get_session (CAMEL_SERVICE (store));
@@ -1307,11 +1574,8 @@ mail_folder_cache_note_store (MailFolderCache *cache,
si = g_hash_table_lookup (cache->priv->stores, store);
if (si == NULL) {
- si = g_malloc0 (sizeof (*si));
- si->folders = g_hash_table_new (g_str_hash, g_str_equal);
- si->store = g_object_ref (store);
+ si = store_info_new (store);
g_hash_table_insert (cache->priv->stores, store, si);
- g_queue_init (&si->folderinfo_updates);
hook = TRUE;
}
@@ -1389,55 +1653,6 @@ mail_folder_cache_note_store (MailFolderCache *cache,
}
/**
- * mail_folder_cache_note_store_remove:
- *
- * Notify the cache that the specified @store can be removed from the cache
- */
-void
-mail_folder_cache_note_store_remove (MailFolderCache *cache,
- CamelStore *store)
-{
- struct _store_info *si;
-
- g_return_if_fail (CAMEL_IS_STORE (store));
-
- if (cache->priv->stores == NULL)
- return;
-
- d(printf("store removed!!\n"));
- g_mutex_lock (cache->priv->stores_mutex);
- si = g_hash_table_lookup (cache->priv->stores, store);
- if (si) {
- GList *link;
-
- g_hash_table_remove (cache->priv->stores, store);
-
- g_signal_handlers_disconnect_matched (
- store, G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, NULL, cache);
-
- g_hash_table_foreach (
- si->folders, (GHFunc)
- unset_folder_info_hash, cache);
-
- link = g_queue_peek_head_link (&si->folderinfo_updates);
-
- while (link != NULL) {
- struct _update_data *ud = link->data;
- g_cancellable_cancel (ud->cancellable);
- link = g_list_next (link);
- }
-
- g_object_unref (si->store);
- g_hash_table_foreach (si->folders, (GHFunc) free_folder_info_hash, NULL);
- g_hash_table_destroy (si->folders);
- g_free (si);
- }
-
- g_mutex_unlock (cache->priv->stores_mutex);
-}
-
-/**
* mail_folder_cache_note_folder:
*
* When a folder has been opened, notify it for watching. The folder must have
@@ -1449,10 +1664,13 @@ mail_folder_cache_note_folder (MailFolderCache *cache,
CamelFolder *folder)
{
CamelStore *parent_store;
- struct _store_info *si;
+ StoreInfo *si;
struct _folder_info *mfi;
const gchar *full_name;
+ g_return_if_fail (MAIL_IS_FOLDER_CACHE (cache));
+ g_return_if_fail (CAMEL_IS_FOLDER (folder));
+
full_name = camel_folder_get_full_name (folder);
parent_store = camel_folder_get_parent_store (folder);
diff --git a/mail/mail-folder-cache.h b/mail/mail-folder-cache.h
index 146ead5012..78d5fd94de 100644
--- a/mail/mail-folder-cache.h
+++ b/mail/mail-folder-cache.h
@@ -49,6 +49,9 @@
G_BEGIN_DECLS
+/* Avoid a circular dependency. */
+typedef struct _EMailSession EMailSession;
+
typedef struct _MailFolderCache MailFolderCache;
typedef struct _MailFolderCacheClass MailFolderCacheClass;
typedef struct _MailFolderCachePrivate MailFolderCachePrivate;
@@ -107,34 +110,32 @@ struct _MailFolderCacheClass {
GType mail_folder_cache_get_type (void) G_GNUC_CONST;
MailFolderCache *
- mail_folder_cache_new (void);
-void mail_folder_cache_note_store (MailFolderCache *self,
+ mail_folder_cache_new (EMailSession *session);
+EMailSession * mail_folder_cache_get_session (MailFolderCache *cache);
+void mail_folder_cache_note_store (MailFolderCache *cache,
CamelStore *store,
GCancellable *cancellable,
NoteDoneFunc done,
gpointer data);
-void mail_folder_cache_note_store_remove
- (MailFolderCache *self,
- CamelStore *store);
-void mail_folder_cache_note_folder (MailFolderCache *self,
+void mail_folder_cache_note_folder (MailFolderCache *cache,
CamelFolder *folder);
gboolean mail_folder_cache_get_folder_from_uri
- (MailFolderCache *self,
+ (MailFolderCache *cache,
const gchar *uri,
CamelFolder **folderp);
gboolean mail_folder_cache_get_folder_info_flags
- (MailFolderCache *self,
+ (MailFolderCache *cache,
CamelFolder *folder,
CamelFolderInfoFlags *flags);
gboolean mail_folder_cache_get_folder_has_children
- (MailFolderCache *self,
+ (MailFolderCache *cache,
CamelFolder *folder,
gboolean *found);
void mail_folder_cache_get_local_folder_uris
- (MailFolderCache *self,
+ (MailFolderCache *cache,
GQueue *out_queue);
void mail_folder_cache_get_remote_folder_uris
- (MailFolderCache *self,
+ (MailFolderCache *cache,
GQueue *out_queue);
G_END_DECLS
diff --git a/mail/mail-ops.c b/mail/mail-ops.c
index 24a494ddac..4ff12b3955 100644
--- a/mail/mail-ops.c
+++ b/mail/mail-ops.c
@@ -43,7 +43,6 @@
#include "mail-ops.h"
#include "mail-tools.h"
-#include "e-mail-local.h"
#include "e-mail-session.h"
#include "e-mail-session-utils.h"
@@ -213,18 +212,23 @@ fetch_mail_exec (struct _fetch_mail_msg *m,
{
struct _filter_mail_msg *fm = (struct _filter_mail_msg *) m;
CamelFolder *folder = NULL;
+ CamelService *service;
+ CamelSession *session;
CamelURL *url;
gboolean is_local_delivery;
const gchar *uid;
gint i;
- fm->destination = e_mail_local_get_folder (
- E_MAIL_LOCAL_FOLDER_LOCAL_INBOX);
+ service = CAMEL_SERVICE (m->store);
+ session = camel_service_get_session (service);
+
+ fm->destination = e_mail_session_get_local_folder (
+ E_MAIL_SESSION (session), E_MAIL_LOCAL_FOLDER_LOCAL_INBOX);
if (fm->destination == NULL)
goto fail;
g_object_ref (fm->destination);
- url = camel_service_new_camel_url (CAMEL_SERVICE (m->store));
+ url = camel_service_new_camel_url (service);
is_local_delivery = em_utils_is_local_delivery_mbox_file (url);
if (is_local_delivery) {
@@ -250,7 +254,7 @@ fetch_mail_exec (struct _fetch_mail_msg *m,
g_free (path);
g_free (url_string);
} else {
- uid = camel_service_get_uid (CAMEL_SERVICE (m->store));
+ uid = camel_service_get_uid (service);
folder = fm->source_folder =
e_mail_session_get_inbox_sync (
@@ -344,7 +348,7 @@ fail:
* there is no need to keep the connection alive forever */
if (!is_local_delivery)
em_utils_disconnect_service_sync (
- CAMEL_SERVICE (m->store), TRUE, cancellable, NULL);
+ service, TRUE, cancellable, NULL);
}
static void
@@ -670,7 +674,8 @@ mail_send_message (struct _send_queue_msg *m,
}
if (!folder) {
- folder = e_mail_local_get_folder (E_MAIL_LOCAL_FOLDER_SENT);
+ folder = e_mail_session_get_local_folder (
+ session, E_MAIL_LOCAL_FOLDER_SENT);
g_object_ref (folder);
}
@@ -683,7 +688,8 @@ mail_send_message (struct _send_queue_msg *m,
if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
goto exit;
- sent_folder = e_mail_local_get_folder (E_MAIL_LOCAL_FOLDER_SENT);
+ sent_folder = e_mail_session_get_local_folder (
+ session, E_MAIL_LOCAL_FOLDER_SENT);
if (folder != sent_folder) {
const gchar *description;
@@ -801,6 +807,7 @@ send_queue_exec (struct _send_queue_msg *m,
GCancellable *cancellable,
GError **error)
{
+ EMailSession *session;
CamelFolder *sent_folder;
GPtrArray *uids, *send_uids = NULL;
gint i, j;
@@ -808,7 +815,11 @@ send_queue_exec (struct _send_queue_msg *m,
d(printf("sending queue\n"));
- sent_folder = e_mail_local_get_folder (E_MAIL_LOCAL_FOLDER_SENT);
+ session = e_mail_backend_get_session (m->backend);
+
+ sent_folder =
+ e_mail_session_get_local_folder (
+ session, E_MAIL_LOCAL_FOLDER_SENT);
if (!(uids = camel_folder_get_uids (m->queue)))
return;
@@ -1489,19 +1500,25 @@ expunge_folder_exec (struct _sync_folder_msg *m,
GCancellable *cancellable,
GError **error)
{
+ EMailSession *session;
CamelFolder *local_inbox;
- CamelStore *local_store;
CamelStore *parent_store;
gboolean is_local_inbox_or_trash;
+ gboolean store_is_local;
gboolean success = TRUE;
+ const gchar *uid;
- local_inbox = e_mail_local_get_folder (E_MAIL_LOCAL_FOLDER_INBOX);
- is_local_inbox_or_trash = (m->folder == local_inbox);
-
- local_store = e_mail_local_get_store ();
+ session = e_mail_backend_get_session (m->backend);
parent_store = camel_folder_get_parent_store (m->folder);
+ uid = camel_service_get_uid (CAMEL_SERVICE (parent_store));
+ store_is_local = (g_strcmp0 (uid, E_MAIL_SESSION_LOCAL_UID) == 0);
+
+ local_inbox =
+ e_mail_session_get_local_folder (
+ session, E_MAIL_LOCAL_FOLDER_INBOX);
+ is_local_inbox_or_trash = (m->folder == local_inbox);
- if (!is_local_inbox_or_trash && local_store == parent_store) {
+ if (store_is_local && !is_local_inbox_or_trash) {
CamelFolder *trash;
trash = camel_store_get_trash_folder_sync (
@@ -1591,7 +1608,7 @@ empty_trash_exec (struct _empty_trash_msg *m,
return;
/* do this before expunge, to know which messages will be expunged */
- if (g_strcmp0 (uid, "local") == 0)
+ if (g_strcmp0 (uid, E_MAIL_SESSION_LOCAL_UID) == 0)
success = expunge_pop3_stores (
trash, m->backend, cancellable, error);
diff --git a/mail/mail-send-recv.c b/mail/mail-send-recv.c
index 44c5158631..36c717619b 100644
--- a/mail/mail-send-recv.c
+++ b/mail/mail-send-recv.c
@@ -36,7 +36,6 @@
#include "e-util/e-util.h"
#include "e-mail-folder-utils.h"
-#include "e-mail-local.h"
#include "e-mail-session.h"
#include "em-event.h"
#include "em-filter-rule.h"
@@ -164,10 +163,13 @@ free_send_info (struct _send_info *info)
}
static struct _send_data *
-setup_send_data (void)
+setup_send_data (EMailBackend *backend)
{
+ EMailSession *session;
struct _send_data *data;
+ session = e_mail_backend_get_session (backend);
+
if (send_data == NULL) {
send_data = data = g_malloc0 (sizeof (*data));
data->lock = g_mutex_new ();
@@ -175,8 +177,9 @@ setup_send_data (void)
g_str_hash, g_str_equal,
(GDestroyNotify) NULL,
(GDestroyNotify) free_folder_info);
- data->inbox = e_mail_local_get_folder (
- E_MAIL_LOCAL_FOLDER_LOCAL_INBOX);
+ data->inbox =
+ e_mail_session_get_local_folder (
+ session, E_MAIL_LOCAL_FOLDER_LOCAL_INBOX);
g_object_ref (data->inbox);
data->active = g_hash_table_new_full (
g_str_hash, g_str_equal,
@@ -520,7 +523,7 @@ build_dialog (GtkWindow *parent,
gtk_widget_show (scrolled_window);
/* must bet setup after send_recv_dialog as it may re-trigger send-recv button */
- data = setup_send_data ();
+ data = setup_send_data (backend);
row = 0;
iter = e_list_get_iterator ((EList *) accounts);
@@ -810,8 +813,9 @@ receive_done (gpointer data)
session = e_mail_backend_get_session (info->backend);
- local_outbox = e_mail_local_get_folder (
- E_MAIL_LOCAL_FOLDER_OUTBOX);
+ local_outbox =
+ e_mail_session_get_local_folder (
+ session, E_MAIL_LOCAL_FOLDER_OUTBOX);
service = camel_session_get_service (
CAMEL_SESSION (session),
@@ -1126,7 +1130,10 @@ send_receive (GtkWindow *parent,
accounts = e_get_account_list ();
- local_outbox = e_mail_local_get_folder (E_MAIL_LOCAL_FOLDER_OUTBOX);
+ local_outbox =
+ e_mail_session_get_local_folder (
+ session, E_MAIL_LOCAL_FOLDER_OUTBOX);
+
data = build_dialog (
parent, backend, accounts,
local_outbox, account, allow_send);
@@ -1280,11 +1287,12 @@ auto_account_changed (EAccountList *eal,
EAccount *ea,
gpointer dummy)
{
- struct _auto_data *info = g_object_get_data((GObject *)ea, "mail-autoreceive");
+ struct _auto_data *info;
- g_return_if_fail (info != NULL);
+ info = g_object_get_data (G_OBJECT (ea), "mail-autoreceive");
- auto_account_commit (info);
+ if (info != NULL)
+ auto_account_commit (info);
}
static void
@@ -1394,7 +1402,7 @@ mail_receive_account (EMailBackend *backend,
CamelURL *url;
send_info_t type = SEND_INVALID;
- data = setup_send_data ();
+ data = setup_send_data (backend);
info = g_hash_table_lookup (data->active, account->uid);
if (info != NULL)
@@ -1450,8 +1458,9 @@ mail_receive_account (EMailBackend *backend,
break;
case SEND_SEND:
/* todo, store the folder in info? */
- local_outbox = e_mail_local_get_folder (
- E_MAIL_LOCAL_FOLDER_OUTBOX);
+ local_outbox =
+ e_mail_session_get_local_folder (
+ session, E_MAIL_LOCAL_FOLDER_OUTBOX);
mail_send_queue (
info->backend,
local_outbox,
@@ -1487,7 +1496,7 @@ mail_send (EMailBackend *backend)
if (account == NULL || account->transport->url == NULL)
return;
- data = setup_send_data ();
+ data = setup_send_data (backend);
info = g_hash_table_lookup (data->active, SEND_URI_KEY);
if (info != NULL) {
info->again++;
@@ -1525,11 +1534,13 @@ mail_send (EMailBackend *backend)
g_hash_table_insert (data->active, (gpointer) SEND_URI_KEY, info);
- /* todo, store the folder in info? */
- local_outbox = e_mail_local_get_folder (E_MAIL_LOCAL_FOLDER_OUTBOX);
-
session = e_mail_backend_get_session (backend);
+ /* todo, store the folder in info? */
+ local_outbox =
+ e_mail_session_get_local_folder (
+ session, E_MAIL_LOCAL_FOLDER_OUTBOX);
+
service = camel_session_get_service (
CAMEL_SESSION (session), transport_uid);
diff --git a/mail/mail-vfolder.c b/mail/mail-vfolder.c
index b37d042077..99caa6c0ec 100644
--- a/mail/mail-vfolder.c
+++ b/mail/mail-vfolder.c
@@ -49,11 +49,6 @@
#include "mail-tools.h"
#include "mail-vfolder.h"
-#include "e-mail-local.h"
-#include "e-mail-store.h"
-
-#define VFOLDER_SERVICE_UID "vfolder"
-
#define d(x) /* (printf("%s:%s: ", G_STRLOC, G_STRFUNC), (x))*/
static EMVFolderContext *context; /* context remains open all time */
@@ -720,7 +715,7 @@ rule_changed (EFilterRule *rule,
session = e_mail_backend_get_session (backend);
service = camel_session_get_service (
- CAMEL_SESSION (session), VFOLDER_SERVICE_UID);
+ CAMEL_SESSION (session), E_MAIL_SESSION_VFOLDER_UID);
g_return_if_fail (CAMEL_IS_SERVICE (service));
/* if the folder has changed name, then add it, then remove the old manually */
@@ -820,7 +815,7 @@ context_rule_added (ERuleContext *ctx,
session = e_mail_backend_get_session (backend);
service = camel_session_get_service (
- CAMEL_SESSION (session), VFOLDER_SERVICE_UID);
+ CAMEL_SESSION (session), E_MAIL_SESSION_VFOLDER_UID);
g_return_if_fail (CAMEL_IS_SERVICE (service));
/* this always runs quickly */
@@ -853,7 +848,7 @@ context_rule_removed (ERuleContext *ctx,
session = e_mail_backend_get_session (backend);
service = camel_session_get_service (
- CAMEL_SESSION (session), VFOLDER_SERVICE_UID);
+ CAMEL_SESSION (session), E_MAIL_SESSION_VFOLDER_UID);
g_return_if_fail (CAMEL_IS_SERVICE (service));
/* TODO: remove from folder info cache? */
@@ -1008,8 +1003,7 @@ vfolder_load_storage (EMailBackend *backend)
/* lock for loading storage, it is safe to call it more than once */
G_LOCK_DEFINE_STATIC (vfolder_hash);
- CamelService *service;
- const gchar *key;
+ CamelStore *vfolder_store;
const gchar *config_dir;
gchar *user;
EFilterRule *rule;
@@ -1034,27 +1028,14 @@ vfolder_load_storage (EMailBackend *backend)
config_dir = mail_session_get_config_dir ();
session = e_mail_backend_get_session (backend);
-
- /* first, create the vfolder store, and set it up */
- service = camel_session_add_service (
- CAMEL_SESSION (session), "vfolder",
- "vfolder", CAMEL_PROVIDER_STORE, NULL);
- if (service != NULL) {
- camel_service_set_display_name (service, _("Search Folders"));
- em_utils_connect_service_sync (service, NULL, NULL);
- } else {
- g_warning("Cannot open vfolder store - no vfolders available");
- return;
- }
-
- g_return_if_fail (CAMEL_IS_STORE (service));
+ vfolder_store = e_mail_session_get_vfolder_store (session);
g_signal_connect (
- service, "folder-deleted",
+ vfolder_store, "folder-deleted",
G_CALLBACK (store_folder_deleted_cb), backend);
g_signal_connect (
- service, "folder-renamed",
+ vfolder_store, "folder-renamed",
G_CALLBACK (store_folder_renamed_cb), NULL);
/* load our rules */
@@ -1076,9 +1057,6 @@ vfolder_load_storage (EMailBackend *backend)
context, "rule_removed",
G_CALLBACK (context_rule_removed), context);
- /* load store to mail component */
- e_mail_store_add (session, CAMEL_STORE (service));
-
/* and setup the rules we have */
rule = NULL;
while ((rule = e_rule_context_next_rule ((ERuleContext *) context, rule, NULL))) {
@@ -1092,9 +1070,7 @@ vfolder_load_storage (EMailBackend *backend)
/* reenable the feature if required */
settings = g_settings_new ("org.gnome.evolution.mail");
- key = "enable-vfolders";
- if (!g_settings_get_boolean (settings, key))
- g_settings_set_boolean (settings, key, TRUE);
+ g_settings_set_boolean (settings, "enable-vfolders", TRUE);
g_object_unref (settings);
folder_cache = e_mail_session_get_folder_cache (session);