aboutsummaryrefslogtreecommitdiffstats
path: root/modules/mail/e-mail-shell-backend.c
diff options
context:
space:
mode:
Diffstat (limited to 'modules/mail/e-mail-shell-backend.c')
-rw-r--r--modules/mail/e-mail-shell-backend.c513
1 files changed, 155 insertions, 358 deletions
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);
}