aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mail/Makefile.am2
-rw-r--r--mail/e-mail-backend.c408
-rw-r--r--mail/e-mail-backend.h79
-rw-r--r--modules/mail/e-mail-shell-backend.c513
-rw-r--r--modules/mail/e-mail-shell-backend.h6
5 files changed, 647 insertions, 361 deletions
diff --git a/mail/Makefile.am b/mail/Makefile.am
index 67497712ee..934a971f9b 100644
--- a/mail/Makefile.am
+++ b/mail/Makefile.am
@@ -37,6 +37,7 @@ libevolution_mail_la_CPPFLAGS = \
mailinclude_HEADERS = \
e-mail-attachment-bar.h \
+ e-mail-backend.h \
e-mail-browser.h \
e-mail-display.h \
e-mail-label-action.h \
@@ -95,6 +96,7 @@ mailinclude_HEADERS = \
libevolution_mail_la_SOURCES = \
e-mail-attachment-bar.c \
+ e-mail-backend.c \
e-mail-browser.c \
e-mail-display.c \
e-mail-label-action.c \
diff --git a/mail/e-mail-backend.c b/mail/e-mail-backend.c
new file mode 100644
index 0000000000..aa7e149f76
--- /dev/null
+++ b/mail/e-mail-backend.c
@@ -0,0 +1,408 @@
+/*
+ * e-mail-backend.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-mail-backend.h"
+
+#include <camel/camel.h>
+
+#include "e-util/e-account-utils.h"
+#include "e-util/e-alert-dialog.h"
+
+#include "shell/e-shell.h"
+
+#include "mail/e-mail-local.h"
+#include "mail/e-mail-migrate.h"
+#include "mail/e-mail-store.h"
+#include "mail/em-utils.h"
+#include "mail/mail-ops.h"
+#include "mail/mail-session.h"
+#include "mail/mail-vfolder.h"
+
+#define E_MAIL_BACKEND_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAIL_BACKEND, EMailBackendPrivate))
+
+#define QUIT_POLL_INTERVAL 1 /* seconds */
+
+struct _EMailBackendPrivate {
+ gint placeholder; /* for future expansion */
+};
+
+static gpointer parent_class;
+
+/* FIXME Kill this thing. It's a horrible hack. */
+extern gint camel_application_is_exiting;
+
+/* Callback for various asynchronous CamelStore operations where
+ * the EActivity's reference count is used as a counting semaphore. */
+static void
+mail_backend_store_operation_done_cb (CamelStore *store,
+ gpointer user_data)
+{
+ g_object_unref (E_ACTIVITY (user_data));
+}
+
+static void
+mail_backend_notify_online_cb (EShell *shell,
+ GParamSpec *pspec,
+ EMailBackend *backend)
+{
+ gboolean online;
+
+ online = e_shell_get_online (shell);
+ camel_session_set_online (session, online);
+}
+
+/* Helper for mail_backend_prepare_for_offline_cb() */
+static void
+mail_store_prepare_for_offline_cb (CamelService *service,
+ gpointer unused,
+ EActivity *activity)
+{
+ if (CAMEL_IS_DISCO_STORE (service) || CAMEL_IS_OFFLINE_STORE (service))
+ mail_store_set_offline (
+ CAMEL_STORE (service), TRUE,
+ mail_backend_store_operation_done_cb,
+ g_object_ref (activity));
+}
+
+static void
+mail_backend_prepare_for_offline_cb (EShell *shell,
+ EActivity *activity,
+ EMailBackend *backend)
+{
+ GtkWindow *window;
+ gboolean synchronize = FALSE;
+
+ window = e_shell_get_active_window (shell);
+
+ if (e_shell_get_network_available (shell))
+ synchronize = em_utils_prompt_user (
+ window, NULL, "mail:ask-quick-offline", NULL);
+
+ if (!synchronize) {
+ mail_cancel_all ();
+ camel_session_set_network_state (session, FALSE);
+ }
+
+ e_mail_store_foreach (
+ (GHFunc) mail_store_prepare_for_offline_cb, activity);
+}
+
+/* Helper for mail_backend_prepare_for_online_cb() */
+static void
+mail_store_prepare_for_online_cb (CamelService *service,
+ gpointer unused,
+ EActivity *activity)
+{
+ if (CAMEL_IS_DISCO_STORE (service) || CAMEL_IS_OFFLINE_STORE (service))
+ mail_store_set_offline (
+ CAMEL_STORE (service), FALSE,
+ mail_backend_store_operation_done_cb,
+ g_object_ref (activity));
+}
+
+static void
+mail_backend_prepare_for_online_cb (EShell *shell,
+ EActivity *activity,
+ EMailBackend *backend)
+{
+ camel_session_set_online (session, TRUE);
+
+ e_mail_store_foreach (
+ (GHFunc) mail_store_prepare_for_online_cb, activity);
+}
+
+/* Helper for mail_backend_prepare_for_quit_cb() */
+static void
+mail_backend_delete_junk (CamelStore *store,
+ gpointer unused,
+ EMailBackend *backend)
+{
+ CamelFolder *folder;
+ GPtrArray *uids;
+ guint32 flags;
+ guint32 mask;
+ guint ii;
+
+ folder = camel_store_get_junk (store, NULL);
+ if (folder == NULL)
+ return;
+
+ uids = camel_folder_get_uids (folder);
+ flags = mask = CAMEL_MESSAGE_DELETED | CAMEL_MESSAGE_SEEN;
+
+ camel_folder_freeze (folder);
+
+ for (ii = 0; ii < uids->len; ii++) {
+ const gchar *uid = uids->pdata[ii];
+ camel_folder_set_message_flags (folder, uid, flags, mask);
+ }
+
+ camel_folder_thaw (folder);
+
+ camel_folder_free_uids (folder, uids);
+}
+
+/* Helper for mail_backend_prepare_for_quit_cb() */
+static void
+mail_backend_final_sync (CamelStore *store,
+ gpointer unused,
+ gpointer user_data)
+{
+ struct {
+ EActivity *activity;
+ gboolean empty_trash;
+ } *sync_data = user_data;
+
+ /* Reffing the activity delays quitting; the reference count
+ * acts like a counting semaphore. */
+ mail_sync_store (
+ store, sync_data->empty_trash,
+ 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)
+{
+ return mail_msg_active ((guint) -1);
+}
+
+/* Helper for mail_backend_prepare_for_quit_cb() */
+static void
+mail_backend_ready_to_quit (EActivity *activity)
+{
+ mail_session_shutdown ();
+ emu_free_mail_cache ();
+
+ /* Do this last. It may terminate the process. */
+ g_object_unref (activity);
+}
+
+static void
+mail_backend_prepare_for_quit_cb (EShell *shell,
+ EActivity *activity,
+ EMailBackend *backend)
+{
+ EAccountList *account_list;
+ gboolean delete_junk;
+ gboolean empty_trash;
+
+ struct {
+ EActivity *activity;
+ gboolean empty_trash;
+ } sync_data;
+
+ delete_junk = e_mail_backend_delete_junk_policy_decision (backend);
+ empty_trash = e_mail_backend_empty_trash_policy_decision (backend);
+
+ camel_application_is_exiting = TRUE;
+
+ account_list = e_get_account_list ();
+ e_account_list_prune_proxies (account_list);
+
+ mail_vfolder_shutdown ();
+
+ if (delete_junk)
+ e_mail_store_foreach (
+ (GHFunc) mail_backend_delete_junk, backend);
+
+ sync_data.activity = activity;
+ sync_data.empty_trash = empty_trash;
+
+ e_mail_store_foreach ((GHFunc) mail_backend_final_sync, &sync_data);
+
+ /* Cancel all activities. */
+ mail_cancel_all ();
+
+ /* Now we poll until all activities are actually cancelled.
+ * Reffing the activity delays quitting; the reference count
+ * acts like a counting semaphore. */
+ if (mail_msg_active ((guint) -1))
+ g_timeout_add_seconds_full (
+ G_PRIORITY_DEFAULT, QUIT_POLL_INTERVAL,
+ (GSourceFunc) mail_backend_poll_to_quit,
+ g_object_ref (activity),
+ (GDestroyNotify) mail_backend_ready_to_quit);
+ else
+ mail_backend_ready_to_quit (g_object_ref (activity));
+}
+
+static void
+mail_backend_quit_requested_cb (EShell *shell,
+ EShellBackend *shell_backend)
+{
+ CamelFolder *folder;
+ GtkWindow *window;
+ guint32 unsent;
+ gint response;
+
+ window = e_shell_get_active_window (shell);
+
+ /* We can quit immediately if offline. */
+ if (!e_shell_get_online (shell))
+ return;
+
+ /* Check Outbox for any unsent messages. */
+
+ folder = e_mail_local_get_folder (E_MAIL_FOLDER_OUTBOX);
+ if (folder == NULL)
+ return;
+
+ if (camel_object_get (
+ folder, NULL, CAMEL_FOLDER_VISIBLE, &unsent, 0) != 0)
+ return;
+
+ if (unsent == 0)
+ return;
+
+ response = e_alert_run_dialog_for_args (
+ window, "mail:exit-unsaved", NULL);
+
+ if (response == GTK_RESPONSE_YES)
+ return;
+
+ e_shell_cancel_quit (shell);
+}
+
+static void
+mail_backend_constructed (GObject *object)
+{
+ EShell *shell;
+ EShellBackend *shell_backend;
+ const gchar *data_dir;
+
+ shell_backend = E_SHELL_BACKEND (object);
+ shell = e_shell_backend_get_shell (shell_backend);
+
+ /* This also initializes Camel, so it needs to happen early. */
+ mail_session_init (shell_backend);
+
+ g_signal_connect (
+ shell, "notify::online",
+ G_CALLBACK (mail_backend_notify_online_cb),
+ shell_backend);
+
+ g_signal_connect (
+ shell, "prepare-for-offline",
+ G_CALLBACK (mail_backend_prepare_for_offline_cb),
+ shell_backend);
+
+ g_signal_connect (
+ shell, "prepare-for-online",
+ G_CALLBACK (mail_backend_prepare_for_online_cb),
+ shell_backend);
+
+ g_signal_connect (
+ shell, "prepare-for-quit",
+ G_CALLBACK (mail_backend_prepare_for_quit_cb),
+ shell_backend);
+
+ g_signal_connect (
+ shell, "quit-requested",
+ G_CALLBACK (mail_backend_quit_requested_cb),
+ shell_backend);
+
+ mail_config_init ();
+ mail_msg_init ();
+
+ data_dir = e_shell_backend_get_data_dir (shell_backend);
+ e_mail_store_init (data_dir);
+}
+
+static void
+mail_backend_class_init (EMailBackendClass *class)
+{
+ GObjectClass *object_class;
+ EShellBackendClass *shell_backend_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EMailBackendPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->constructed = mail_backend_constructed;
+
+ shell_backend_class = E_SHELL_BACKEND_CLASS (class);
+ shell_backend_class->migrate = e_mail_migrate;
+}
+
+static void
+mail_backend_init (EMailBackend *backend)
+{
+ backend->priv = E_MAIL_BACKEND_GET_PRIVATE (backend);
+}
+
+GType
+e_mail_backend_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EMailBackendClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) mail_backend_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMailBackend),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) mail_backend_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ E_TYPE_SHELL_BACKEND, "EMailBackend", &type_info,
+ G_TYPE_FLAG_ABSTRACT);
+ }
+
+ return type;
+}
+
+gboolean
+e_mail_backend_delete_junk_policy_decision (EMailBackend *backend)
+{
+ EMailBackendClass *class;
+
+ g_return_val_if_fail (E_IS_MAIL_BACKEND (backend), FALSE);
+
+ class = E_MAIL_BACKEND_GET_CLASS (backend);
+ if (class->delete_junk_policy_decision == NULL)
+ return FALSE;
+
+ return class->delete_junk_policy_decision (backend);
+}
+
+gboolean
+e_mail_backend_empty_trash_policy_decision (EMailBackend *backend)
+{
+ EMailBackendClass *class;
+
+ g_return_val_if_fail (E_IS_MAIL_BACKEND (backend), FALSE);
+
+ class = E_MAIL_BACKEND_GET_CLASS (backend);
+ if (class->empty_trash_policy_decision == NULL)
+ return FALSE;
+
+ return class->empty_trash_policy_decision (backend);
+}
diff --git a/mail/e-mail-backend.h b/mail/e-mail-backend.h
new file mode 100644
index 0000000000..0d2dc2d0fd
--- /dev/null
+++ b/mail/e-mail-backend.h
@@ -0,0 +1,79 @@
+/*
+ * e-mail-backend.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)
+ *
+ */
+
+/* This is an abstract EShellBackend subclass that integrates
+ * with libevolution-mail. It serves as a common base class
+ * for Evolution's mail module and Anjal. */
+
+#ifndef E_MAIL_BACKEND_H
+#define E_MAIL_BACKEND_H
+
+#include <shell/e-shell-backend.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_BACKEND \
+ (e_mail_backend_get_type ())
+#define E_MAIL_BACKEND(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_BACKEND, EMailBackend))
+#define E_MAIL_BACKEND_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_BACKEND, EMailBackendClass))
+#define E_IS_MAIL_BACKEND(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_BACKEND))
+#define E_IS_MAIL_BACKEND_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_BACKEND))
+#define E_MAIL_BACKEND_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_BACKEND, EMailBackendClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailBackend EMailBackend;
+typedef struct _EMailBackendClass EMailBackendClass;
+typedef struct _EMailBackendPrivate EMailBackendPrivate;
+
+struct _EMailBackend {
+ EShellBackend parent;
+ EMailBackendPrivate *priv;
+};
+
+struct _EMailBackendClass {
+ EShellBackendClass parent_class;
+
+ /* Methods */
+ gboolean (*delete_junk_policy_decision)
+ (EMailBackend *backend);
+ gboolean (*empty_trash_policy_decision)
+ (EMailBackend *backend);
+};
+
+GType e_mail_backend_get_type (void);
+gboolean e_mail_backend_delete_junk_policy_decision
+ (EMailBackend *backend);
+gboolean e_mail_backend_empty_trash_policy_decision
+ (EMailBackend *backend);
+
+G_END_DECLS
+
+#endif /* E_MAIL_BACKEND_H */
diff --git a/modules/mail/e-mail-shell-backend.c b/modules/mail/e-mail-shell-backend.c
index 47e00b7591..b166084f5d 100644
--- a/modules/mail/e-mail-shell-backend.c
+++ b/modules/mail/e-mail-shell-backend.c
@@ -29,7 +29,6 @@
#include "e-util/e-account-utils.h"
#include "e-util/e-binding.h"
-#include "e-util/e-alert-dialog.h"
#include "e-util/e-import.h"
#include "e-util/e-util.h"
#include "shell/e-shell.h"
@@ -42,8 +41,6 @@
#include "e-mail-shell-view.h"
#include "e-mail-browser.h"
-#include "e-mail-local.h"
-#include "e-mail-migrate.h"
#include "e-mail-reader.h"
#include "e-mail-store.h"
#include "em-account-editor.h"
@@ -71,18 +68,15 @@
((obj), E_TYPE_MAIL_SHELL_BACKEND, EMailShellBackendPrivate))
#define BACKEND_NAME "mail"
-#define QUIT_POLL_INTERVAL 1 /* seconds */
struct _EMailShellBackendPrivate {
gint mail_sync_in_progress;
- guint mail_sync_timeout_source_id;
+ guint mail_sync_source_id;
};
static gpointer parent_class;
static GType mail_shell_backend_type;
-extern gint camel_application_is_exiting;
-
static void
mail_shell_backend_init_importers (void)
{
@@ -103,7 +97,7 @@ mail_shell_backend_init_importers (void)
static void
mail_shell_backend_mail_icon_cb (EShellWindow *shell_window,
- const gchar *icon_name)
+ const gchar *icon_name)
{
GtkAction *action;
@@ -249,25 +243,29 @@ static void
mail_shell_backend_sync_store_cb (CamelStore *store,
EMailShellBackend *mail_shell_backend)
{
- if (!camel_application_is_exiting) {
- mail_shell_backend->priv->mail_sync_in_progress++;
- mail_sync_store (
- store, FALSE,
- mail_shell_backend_sync_store_done_cb,
- mail_shell_backend);
- }
+ mail_shell_backend->priv->mail_sync_in_progress++;
+
+ mail_sync_store (
+ store, FALSE,
+ mail_shell_backend_sync_store_done_cb,
+ mail_shell_backend);
}
static gboolean
mail_shell_backend_mail_sync (EMailShellBackend *mail_shell_backend)
{
- if (camel_application_is_exiting)
- return FALSE;
+ EShell *shell;
+ EShellBackend *shell_backend;
- if (mail_shell_backend->priv->mail_sync_in_progress)
+ shell_backend = E_SHELL_BACKEND (mail_shell_backend);
+ shell = e_shell_backend_get_shell (shell_backend);
+
+ /* Obviously we can only sync in online mode. */
+ if (!e_shell_get_online (shell))
goto exit;
- if (session == NULL || !camel_session_is_online (session))
+ /* If a sync is still in progress, skip this round. */
+ if (mail_shell_backend->priv->mail_sync_in_progress)
goto exit;
e_mail_store_foreach (
@@ -275,18 +273,7 @@ mail_shell_backend_mail_sync (EMailShellBackend *mail_shell_backend)
mail_shell_backend);
exit:
- return !camel_application_is_exiting;
-}
-
-static void
-mail_shell_backend_notify_online_cb (EShell *shell,
- GParamSpec *pspec,
- EShellBackend *shell_backend)
-{
- gboolean online;
-
- online = e_shell_get_online (shell);
- camel_session_set_online (session, online);
+ return TRUE;
}
static void
@@ -385,309 +372,26 @@ mail_shell_backend_handle_uri_cb (EShell *shell,
return handled;
}
-/* Helper for mail_shell_backend_prepare_for_[off|on]line_cb() */
-static void
-mail_shell_store_line_transition_done_cb (CamelStore *store,
- gpointer user_data)
-{
- EActivity *activity = user_data;
-
- g_object_unref (activity);
-}
-
-/* Helper for mail_shell_backend_prepare_for_offline_cb() */
-static void
-mail_shell_store_prepare_for_offline_cb (CamelService *service,
- gpointer unused,
- EActivity *activity)
-{
- if (CAMEL_IS_DISCO_STORE (service) || CAMEL_IS_OFFLINE_STORE (service))
- mail_store_set_offline (
- CAMEL_STORE (service), TRUE,
- mail_shell_store_line_transition_done_cb,
- g_object_ref (activity));
-}
-
-static void
-mail_shell_backend_prepare_for_offline_cb (EShell *shell,
- EActivity *activity,
- EMailShellBackend *mail_shell_backend)
-{
- gboolean synchronize = FALSE;
-
- if (e_shell_get_network_available (shell))
- synchronize = em_utils_prompt_user (
- e_shell_get_active_window (shell), NULL,
- "mail:ask-quick-offline", NULL);
-
- if (!synchronize) {
- mail_cancel_all ();
- camel_session_set_network_state (session, FALSE);
- }
-
- e_mail_store_foreach (
- (GHFunc) mail_shell_store_prepare_for_offline_cb, activity);
-}
-
-/* Helper for mail_shell_backend_prepare_for_online_cb() */
-static void
-mail_shell_store_prepare_for_online_cb (CamelService *service,
- gpointer unused,
- EActivity *activity)
-{
- if (CAMEL_IS_DISCO_STORE (service) || CAMEL_IS_OFFLINE_STORE (service))
- mail_store_set_offline (
- CAMEL_STORE (service), FALSE,
- mail_shell_store_line_transition_done_cb,
- g_object_ref (activity));
-}
-
-static void
-mail_shell_backend_prepare_for_online_cb (EShell *shell,
- EActivity *activity,
- EMailShellBackend *mail_shell_backend)
-{
- camel_session_set_online (session, TRUE);
-
- e_mail_store_foreach (
- (GHFunc) mail_shell_store_prepare_for_online_cb, activity);
-}
-
-/* Helper for mail_shell_backend_prepare_for_quit_cb() */
-static void
-mail_shell_backend_empty_junk (CamelStore *store,
- gpointer opaque_store_info,
- EMailShellBackend *mail_shell_backend)
-{
- CamelFolder *folder;
- GPtrArray *uids;
- guint32 flags;
- guint32 mask;
- guint ii;
-
- folder = camel_store_get_junk (store, NULL);
- if (folder == NULL)
- return;
-
- uids = camel_folder_get_uids (folder);
- flags = mask = CAMEL_MESSAGE_DELETED | CAMEL_MESSAGE_SEEN;
-
- camel_folder_freeze (folder);
-
- for (ii = 0; ii < uids->len; ii++) {
- const gchar *uid = uids->pdata[ii];
- camel_folder_set_message_flags (folder, uid, flags, mask);
- }
-
- camel_folder_thaw (folder);
-
- camel_folder_free_uids (folder, uids);
-}
-
-/* Helper for mail_shell_backend_final_sync() */
-static void
-mail_shell_backend_final_sync_done_cb (CamelStore *store,
- gpointer user_data)
-{
- g_object_unref (E_ACTIVITY (user_data));
-}
-
-/* Helper for mail_shell_backend_prepare_for_quit_cb() */
-static void
-mail_shell_backend_final_sync (CamelStore *store,
- gpointer opaque_store_info,
- gpointer user_data)
-{
- struct {
- EActivity *activity;
- gboolean empty_trash;
- } *sync_data = user_data;
-
- /* Reffing the activity delays quitting; the reference count
- * acts like a counting semaphore. */
- mail_sync_store (
- store, sync_data->empty_trash,
- mail_shell_backend_final_sync_done_cb,
- g_object_ref (sync_data->activity));
-}
-
-/* Helper for mail_shell_backend_prepare_for_quit_cb() */
-static gboolean
-mail_shell_backend_poll_to_quit (EActivity *activity)
-{
- return mail_msg_active ((guint) -1);
-}
-
-/* Helper for mail_shell_backend_prepare_for_quit_cb() */
-static void
-mail_shell_backend_ready_to_quit (EActivity *activity)
-{
- mail_session_shutdown ();
- g_object_unref (activity);
- emu_free_mail_cache ();
-}
-
static void
mail_shell_backend_prepare_for_quit_cb (EShell *shell,
EActivity *activity,
- EMailShellBackend *mail_shell_backend)
+ EShellBackend *shell_backend)
{
- EShellSettings *shell_settings;
- EAccountList *account_list;
- GConfClient *client;
- const gchar *key;
- gboolean empty_junk;
- gboolean empty_trash;
- gint empty_date;
- gint empty_days;
- gint now;
- GError *error = NULL;
-
- struct {
- EActivity *activity;
- gboolean empty_trash;
- } sync_data;
-
- client = e_shell_get_gconf_client (shell);
- shell_settings = e_shell_get_shell_settings (shell);
-
- camel_application_is_exiting = TRUE;
- now = time (NULL) / 60 / 60 / 24;
-
- account_list = e_get_account_list ();
- e_account_list_prune_proxies (account_list);
-
- mail_vfolder_shutdown ();
-
- empty_junk = e_shell_settings_get_boolean (
- shell_settings, "mail-empty-junk-on-exit");
-
- empty_trash = e_shell_settings_get_boolean (
- shell_settings, "mail-empty-trash-on-exit");
-
- /* XXX No EShellSettings properties for these keys. */
-
- empty_date = empty_days = 0;
-
- if (empty_junk) {
- key = "/apps/evolution/mail/junk/empty_on_exit_days";
- empty_days = gconf_client_get_int (client, key, &error);
- if (error != NULL) {
- g_warning ("%s", error->message);
- g_clear_error (&error);
- empty_trash = FALSE;
- }
- }
-
- if (empty_junk) {
- key = "/apps/evolution/mail/junk/empty_date";
- empty_date = gconf_client_get_int (client, key, &error);
- if (error != NULL) {
- g_warning ("%s", error->message);
- g_clear_error (&error);
- empty_trash = FALSE;
- }
- }
-
- empty_junk &= (empty_days = 0) || (empty_date + empty_days <= now);
-
- if (empty_junk) {
- e_mail_store_foreach (
- (GHFunc) mail_shell_backend_empty_junk,
- mail_shell_backend);
-
- key = "/apps/evolution/mail/junk/empty_date";
- gconf_client_set_int (client, key, now, NULL);
- }
-
- empty_date = empty_days = 0;
-
- if (empty_trash) {
- key = "/apps/evolution/mail/trash/empty_on_exit_days";
- empty_days = gconf_client_get_int (client, key, &error);
- if (error != NULL) {
- g_warning ("%s", error->message);
- g_clear_error (&error);
- empty_trash = FALSE;
- }
- }
-
- if (empty_trash) {
- key = "/apps/evolution/mail/trash/empty_date";
- empty_date = gconf_client_get_int (client, key, &error);
- if (error != NULL) {
- g_warning ("%s", error->message);
- g_clear_error (&error);
- empty_trash = FALSE;
- }
- }
-
- empty_trash &= (empty_days == 0) || (empty_date + empty_days <= now);
-
- sync_data.activity = activity;
- sync_data.empty_trash = empty_trash;
+ EMailShellBackendPrivate *priv;
- e_mail_store_foreach (
- (GHFunc) mail_shell_backend_final_sync, &sync_data);
+ priv = E_MAIL_SHELL_BACKEND_GET_PRIVATE (shell_backend);
- if (empty_trash) {
- key = "/apps/evolution/mail/trash/empty_date";
- gconf_client_set_int (client, key, now, NULL);
+ /* Prevent a sync from starting while trying to shutdown. */
+ if (priv->mail_sync_source_id > 0) {
+ g_source_remove (priv->mail_sync_source_id);
+ priv->mail_sync_source_id = 0;
}
-
- /* Cancel all activities. */
- mail_cancel_all ();
-
- /* Now we poll until all activities are actually cancelled.
- * Reffing the activity delays quitting; the reference count
- * acts like a counting semaphore. */
- if (mail_msg_active ((guint) -1))
- g_timeout_add_seconds_full (
- G_PRIORITY_DEFAULT, QUIT_POLL_INTERVAL,
- (GSourceFunc) mail_shell_backend_poll_to_quit,
- g_object_ref (activity),
- (GDestroyNotify) mail_shell_backend_ready_to_quit);
- else
- mail_shell_backend_ready_to_quit (g_object_ref (activity));
-}
-
-static void
-mail_shell_backend_quit_requested_cb (EShell *shell,
- EShellBackend *shell_backend)
-{
- CamelFolder *folder;
- guint32 unsent;
- gint response;
-
- /* We can quit immediately if offline. */
- if (!camel_session_is_online (session))
- return;
-
- /* Check Outbox for any unsent messages. */
-
- folder = e_mail_local_get_folder (E_MAIL_FOLDER_OUTBOX);
- if (folder == NULL)
- return;
-
- if (camel_object_get (
- folder, NULL, CAMEL_FOLDER_VISIBLE, &unsent, 0) != 0)
- return;
-
- if (unsent == 0)
- return;
-
- response = e_alert_run_dialog_for_args (e_shell_get_active_window (shell), "mail:exit-unsaved", NULL);
-
- if (response == GTK_RESPONSE_YES)
- return;
-
- e_shell_cancel_quit (shell);
}
static void
mail_shell_backend_send_receive_cb (EShell *shell,
- GtkWindow *parent,
- EShellBackend *shell_backend)
+ GtkWindow *parent,
+ EShellBackend *shell_backend)
{
em_utils_clear_get_password_canceled_accounts_flag ();
mail_send_receive (parent);
@@ -695,7 +399,7 @@ mail_shell_backend_send_receive_cb (EShell *shell,
static void
mail_shell_backend_window_weak_notify_cb (EShell *shell,
- GObject *where_the_object_was)
+ GObject *where_the_object_was)
{
g_signal_handlers_disconnect_by_func (
shell, mail_shell_backend_mail_icon_cb,
@@ -704,8 +408,8 @@ mail_shell_backend_window_weak_notify_cb (EShell *shell,
static void
mail_shell_backend_window_created_cb (EShell *shell,
- GtkWindow *window,
- EShellBackend *shell_backend)
+ GtkWindow *window,
+ EShellBackend *shell_backend)
{
EShellSettings *shell_settings;
static gboolean first_time = TRUE;
@@ -838,15 +542,14 @@ mail_shell_backend_constructed (GObject *object)
EMailShellBackendPrivate *priv;
EShell *shell;
EShellBackend *shell_backend;
- const gchar *data_dir;
priv = E_MAIL_SHELL_BACKEND_GET_PRIVATE (object);
shell_backend = E_SHELL_BACKEND (object);
shell = e_shell_backend_get_shell (shell_backend);
- /* This also initializes Camel, so it needs to happen early. */
- mail_session_init (shell_backend);
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (parent_class)->constructed (object);
/* Register format types for EMFormatHook. */
em_format_hook_register_type (em_format_get_type ());
@@ -859,36 +562,16 @@ mail_shell_backend_constructed (GObject *object)
mail_shell_backend_init_importers ();
g_signal_connect (
- shell, "notify::online",
- G_CALLBACK (mail_shell_backend_notify_online_cb),
- shell_backend);
-
- g_signal_connect (
shell, "handle-uri",
G_CALLBACK (mail_shell_backend_handle_uri_cb),
shell_backend);
g_signal_connect (
- shell, "prepare-for-offline",
- G_CALLBACK (mail_shell_backend_prepare_for_offline_cb),
- shell_backend);
-
- g_signal_connect (
- shell, "prepare-for-online",
- G_CALLBACK (mail_shell_backend_prepare_for_online_cb),
- shell_backend);
-
- g_signal_connect (
shell, "prepare-for-quit",
G_CALLBACK (mail_shell_backend_prepare_for_quit_cb),
shell_backend);
g_signal_connect (
- shell, "quit-requested",
- G_CALLBACK (mail_shell_backend_quit_requested_cb),
- shell_backend);
-
- g_signal_connect (
shell, "send-receive",
G_CALLBACK (mail_shell_backend_send_receive_cb),
shell_backend);
@@ -910,12 +593,6 @@ mail_shell_backend_constructed (GObject *object)
mail_folder_cache_get_default (), "folder-changed",
G_CALLBACK (folder_changed_cb), shell);
- mail_config_init ();
- mail_msg_init ();
-
- data_dir = e_shell_backend_get_data_dir (shell_backend);
- e_mail_store_init (data_dir);
-
e_mail_shell_settings_init (shell);
/* Initialize preferences after the main loop starts so
@@ -947,17 +624,132 @@ mail_shell_backend_start (EShellBackend *shell_backend)
mail_autoreceive_init (shell_backend, session);
if (g_getenv ("CAMEL_FLUSH_CHANGES") != NULL)
- priv->mail_sync_timeout_source_id = g_timeout_add_seconds (
+ priv->mail_sync_source_id = g_timeout_add_seconds (
mail_config_get_sync_timeout (),
(GSourceFunc) mail_shell_backend_mail_sync,
shell_backend);
}
+static gboolean
+mail_shell_backend_delete_junk_policy_decision (EMailBackend *backend)
+{
+ EShell *shell;
+ EShellSettings *shell_settings;
+ GConfClient *client;
+ const gchar *key;
+ gboolean delete_junk;
+ gint empty_date;
+ gint empty_days;
+ gint now;
+ GError *error = NULL;
+
+ shell = e_shell_backend_get_shell (E_SHELL_BACKEND (backend));
+
+ client = e_shell_get_gconf_client (shell);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ now = time (NULL) / 60 / 60 / 24;
+
+ delete_junk = e_shell_settings_get_boolean (
+ shell_settings, "mail-empty-junk-on-exit");
+
+ /* XXX No EShellSettings properties for these keys. */
+
+ empty_date = empty_days = 0;
+
+ if (delete_junk) {
+ key = "/apps/evolution/mail/junk/empty_on_exit_days";
+ empty_days = gconf_client_get_int (client, key, &error);
+ if (error != NULL) {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+ }
+
+ if (delete_junk) {
+ key = "/apps/evolution/mail/junk/empty_date";
+ empty_date = gconf_client_get_int (client, key, &error);
+ if (error != NULL) {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+ }
+
+ delete_junk &= (empty_days == 0) || (empty_date + empty_days <= now);
+
+ if (delete_junk) {
+ key = "/apps/evolution/mail/junk/empty_date";
+ gconf_client_set_int (client, key, now, NULL);
+ }
+
+ return delete_junk;
+}
+
+static gboolean
+mail_shell_backend_empty_trash_policy_decision (EMailBackend *backend)
+{
+ EShell *shell;
+ EShellSettings *shell_settings;
+ GConfClient *client;
+ const gchar *key;
+ gboolean empty_trash;
+ gint empty_date;
+ gint empty_days;
+ gint now;
+ GError *error = NULL;
+
+ shell = e_shell_backend_get_shell (E_SHELL_BACKEND (backend));
+
+ client = e_shell_get_gconf_client (shell);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ now = time (NULL) / 60 / 60 / 24;
+
+ empty_trash = e_shell_settings_get_boolean (
+ shell_settings, "mail-empty-trash-on-exit");
+
+ /* XXX No EShellSettings properties for these keys. */
+
+ empty_date = empty_days = 0;
+
+ if (empty_trash) {
+ key = "/apps/evolution/mail/trash/empty_on_exit_days";
+ empty_days = gconf_client_get_int (client, key, &error);
+ if (error != NULL) {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+ }
+
+ if (empty_trash) {
+ key = "/apps/evolution/mail/trash/empty_date";
+ empty_date = gconf_client_get_int (client, key, &error);
+ if (error != NULL) {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+ }
+
+ empty_trash &= (empty_days == 0) || (empty_date + empty_days <= now);
+
+ if (empty_trash) {
+ key = "/apps/evolution/mail/trash/empty_date";
+ gconf_client_set_int (client, key, now, NULL);
+ }
+
+ return empty_trash;
+}
+
static void
mail_shell_backend_class_init (EMailShellBackendClass *class)
{
GObjectClass *object_class;
EShellBackendClass *shell_backend_class;
+ EMailBackendClass *mail_backend_class;
parent_class = g_type_class_peek_parent (class);
g_type_class_add_private (class, sizeof (EMailShellBackendPrivate));
@@ -973,7 +765,12 @@ mail_shell_backend_class_init (EMailShellBackendClass *class)
shell_backend_class->sort_order = 200;
shell_backend_class->preferences_page = "mail-accounts";
shell_backend_class->start = mail_shell_backend_start;
- shell_backend_class->migrate = e_mail_migrate;
+
+ mail_backend_class = E_MAIL_BACKEND_CLASS (class);
+ mail_backend_class->delete_junk_policy_decision =
+ mail_shell_backend_delete_junk_policy_decision;
+ mail_backend_class->empty_trash_policy_decision =
+ mail_shell_backend_empty_trash_policy_decision;
}
static void
@@ -1006,7 +803,7 @@ e_mail_shell_backend_register_type (GTypeModule *type_module)
};
mail_shell_backend_type = g_type_module_register_type (
- type_module, E_TYPE_SHELL_BACKEND,
+ type_module, E_TYPE_MAIL_BACKEND,
"EMailShellBackend", &type_info, 0);
}
diff --git a/modules/mail/e-mail-shell-backend.h b/modules/mail/e-mail-shell-backend.h
index 73ef10e75b..36f4064e68 100644
--- a/modules/mail/e-mail-shell-backend.h
+++ b/modules/mail/e-mail-shell-backend.h
@@ -22,7 +22,7 @@
#ifndef E_MAIL_SHELL_BACKEND_H
#define E_MAIL_SHELL_BACKEND_H
-#include <shell/e-shell-backend.h>
+#include <mail/e-mail-backend.h>
#include <camel/camel-folder.h>
#include <camel/camel-store.h>
@@ -55,12 +55,12 @@ typedef struct _EMailShellBackendClass EMailShellBackendClass;
typedef struct _EMailShellBackendPrivate EMailShellBackendPrivate;
struct _EMailShellBackend {
- EShellBackend parent;
+ EMailBackend parent;
EMailShellBackendPrivate *priv;
};
struct _EMailShellBackendClass {
- EShellBackendClass parent_class;
+ EMailBackendClass parent_class;
};
GType e_mail_shell_backend_get_type (void);