diff options
-rw-r--r-- | mail/Makefile.am | 2 | ||||
-rw-r--r-- | mail/e-mail-backend.c | 40 | ||||
-rw-r--r-- | mail/e-mail-store-utils.c | 190 | ||||
-rw-r--r-- | mail/e-mail-store-utils.h | 47 | ||||
-rw-r--r-- | mail/e-mail.h | 1 | ||||
-rw-r--r-- | mail/em-folder-tree-model.c | 2 | ||||
-rw-r--r-- | mail/mail-folder-cache.c | 23 | ||||
-rw-r--r-- | mail/mail-ops.c | 179 | ||||
-rw-r--r-- | mail/mail-ops.h | 8 |
9 files changed, 277 insertions, 215 deletions
diff --git a/mail/Makefile.am b/mail/Makefile.am index eb7ef84ecb..a88a7c889a 100644 --- a/mail/Makefile.am +++ b/mail/Makefile.am @@ -69,6 +69,7 @@ mailinclude_HEADERS = \ e-mail-session-utils.h \ e-mail-sidebar.h \ e-mail-store.h \ + e-mail-store-utils.h \ e-mail-tag-editor.h \ em-account-editor.h \ em-composer-utils.h \ @@ -141,6 +142,7 @@ libevolution_mail_la_SOURCES = \ e-mail-session-utils.c \ e-mail-sidebar.c \ e-mail-store.c \ + e-mail-store-utils.c \ e-mail-tag-editor.c \ em-account-editor.c \ em-composer-utils.c \ diff --git a/mail/e-mail-backend.c b/mail/e-mail-backend.c index ce227f8c27..36b244d8d4 100644 --- a/mail/e-mail-backend.c +++ b/mail/e-mail-backend.c @@ -38,6 +38,7 @@ #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" #include "mail/em-utils.h" @@ -86,9 +87,14 @@ mail_shell_backend_get_config_dir (EShellBackend *backend) * the EActivity's reference count is used as a counting semaphore. */ static void mail_backend_store_operation_done_cb (CamelStore *store, - gpointer user_data) + GAsyncResult *result, + EActivity *activity) { - g_object_unref (E_ACTIVITY (user_data)); + /* FIXME Not checking result for error. To fix this, we need + * separate callbacks to call different finish functions + * and then submit an EAlert on error. */ + + g_object_unref (activity); } /* Helper for mail_backend_prepare_for_offline_cb() */ @@ -97,11 +103,11 @@ 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)); + /* 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 @@ -136,11 +142,11 @@ 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)); + /* 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)); } static void @@ -200,11 +206,11 @@ mail_backend_final_sync (CamelStore *store, 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, + /* 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)); } diff --git a/mail/e-mail-store-utils.c b/mail/e-mail-store-utils.c new file mode 100644 index 0000000000..57304f926d --- /dev/null +++ b/mail/e-mail-store-utils.c @@ -0,0 +1,190 @@ +/* + * e-mail-store-utils.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-store-utils.h" + +#include <config.h> +#include <glib/gi18n-lib.h> + +typedef struct _AsyncContext AsyncContext; + +static void +mail_store_go_offline_thread (GSimpleAsyncResult *simple, + CamelStore *store, + GCancellable *cancellable) +{ + CamelService *service; + gchar *service_name; + GError *error = NULL; + + service = CAMEL_SERVICE (store); + + service_name = camel_service_get_name (service, TRUE); + camel_operation_push_message ( + cancellable, _("Disconnecting from '%s'"), service_name); + g_free (service_name); + + if (CAMEL_IS_DISCO_STORE (store)) { + CamelDiscoStore *disco_store; + + disco_store = CAMEL_DISCO_STORE (store); + + if (camel_disco_store_can_work_offline (disco_store)) + camel_disco_store_set_status ( + disco_store, CAMEL_DISCO_STORE_OFFLINE, + cancellable, &error); + else + camel_service_disconnect_sync (service, TRUE, &error); + + } else if (CAMEL_IS_OFFLINE_STORE (store)) { + CamelOfflineStore *offline_store; + + offline_store = CAMEL_OFFLINE_STORE (store); + + camel_offline_store_set_online_sync ( + offline_store, FALSE, cancellable, &error); + + } else + camel_service_disconnect_sync (service, TRUE, &error); + + if (error != NULL) { + g_simple_async_result_set_from_error (simple, error); + g_error_free (error); + } + + camel_operation_pop_message (cancellable); +} + +void +e_mail_store_go_offline (CamelStore *store, + gint io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *simple; + + g_return_if_fail (CAMEL_IS_STORE (store)); + + /* Cancel any pending connect first so the set_offline_op + * thread won't get queued behind a hung connect op. */ + camel_service_cancel_connect (CAMEL_SERVICE (store)); + + simple = g_simple_async_result_new ( + G_OBJECT (store), callback, + user_data, e_mail_store_go_offline); + + g_simple_async_result_run_in_thread ( + simple, (GSimpleAsyncThreadFunc) + mail_store_go_offline_thread, + io_priority, cancellable); + + g_object_unref (simple); +} + +gboolean +e_mail_store_go_offline_finish (CamelStore *store, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail ( + g_simple_async_result_is_valid ( + result, G_OBJECT (store), e_mail_store_go_offline), FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + + /* Assume success unless a GError is set. */ + return !g_simple_async_result_propagate_error (simple, error); +} + +static void +mail_store_go_online_thread (GSimpleAsyncResult *simple, + CamelStore *store, + GCancellable *cancellable) +{ + CamelService *service; + gchar *service_name; + GError *error = NULL; + + service = CAMEL_SERVICE (store); + + service_name = camel_service_get_name (service, TRUE); + camel_operation_push_message ( + cancellable, _("Reconnecting to '%s'"), service_name); + g_free (service_name); + + if (CAMEL_IS_DISCO_STORE (store)) + camel_disco_store_set_status ( + CAMEL_DISCO_STORE (store), + CAMEL_DISCO_STORE_ONLINE, + cancellable, &error); + + else if (CAMEL_IS_OFFLINE_STORE (store)) + camel_offline_store_set_online_sync ( + CAMEL_OFFLINE_STORE (store), + TRUE, cancellable, &error); + + if (error != NULL) { + g_simple_async_result_set_from_error (simple, error); + g_error_free (error); + } + + camel_operation_pop_message (cancellable); +} + +void +e_mail_store_go_online (CamelStore *store, + gint io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *simple; + + g_return_if_fail (CAMEL_IS_STORE (store)); + + simple = g_simple_async_result_new ( + G_OBJECT (store), callback, + user_data, e_mail_store_go_online); + + g_simple_async_result_run_in_thread ( + simple, (GSimpleAsyncThreadFunc) + mail_store_go_online_thread, + io_priority, cancellable); + + g_object_unref (simple); +} + +gboolean +e_mail_store_go_online_finish (CamelStore *store, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail ( + g_simple_async_result_is_valid ( + result, G_OBJECT (store), e_mail_store_go_online), FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + + /* Assume success unless a GError is set. */ + return !g_simple_async_result_propagate_error (simple, error); +} diff --git a/mail/e-mail-store-utils.h b/mail/e-mail-store-utils.h new file mode 100644 index 0000000000..daf7a98412 --- /dev/null +++ b/mail/e-mail-store-utils.h @@ -0,0 +1,47 @@ +/* + * e-mail-store-utils.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_STORE_UTILS_H +#define E_MAIL_STORE_UTILS_H + +/* CamelStore wrappers with Evolution-specific policies. */ + +#include <camel/camel.h> + +G_BEGIN_DECLS + +void e_mail_store_go_offline (CamelStore *store, + gint io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean e_mail_store_go_offline_finish (CamelStore *store, + GAsyncResult *result, + GError **error); +void e_mail_store_go_online (CamelStore *store, + gint io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean e_mail_store_go_online_finish (CamelStore *store, + GAsyncResult *result, + GError **error); + +G_END_DECLS + +#endif /* E_MAIL_STORE_UTILS_H */ diff --git a/mail/e-mail.h b/mail/e-mail.h index 4e40ac370b..aa19737785 100644 --- a/mail/e-mail.h +++ b/mail/e-mail.h @@ -44,6 +44,7 @@ #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-folder-tree-model.c b/mail/em-folder-tree-model.c index ac147c43fd..f1f69a7276 100644 --- a/mail/em-folder-tree-model.c +++ b/mail/em-folder-tree-model.c @@ -749,8 +749,6 @@ em_folder_tree_model_set_folder_info (EMFolderTreeModel *model, g_object_unref (folder); } - /* TODO Maybe this should be handled by mail_get_folderinfo - * (except em-folder-tree doesn't use it, duh) */ flags = fi->flags; name = fi->name; if (si->store == e_mail_local_get_store ()) { diff --git a/mail/mail-folder-cache.c b/mail/mail-folder-cache.c index 8b19da4879..8b3f3d2c24 100644 --- a/mail/mail-folder-cache.c +++ b/mail/mail-folder-cache.c @@ -52,6 +52,7 @@ #include "em-utils.h" #include "e-mail-local.h" #include "e-mail-session.h" +#include "e-mail-store-utils.h" #define w(x) #define d(x) @@ -856,9 +857,11 @@ ping_cb (MailFolderCache *self) } static void -store_online_cb (CamelStore *store, gpointer data) +store_go_online_cb (CamelStore *store, + GAsyncResult *result, + struct _update_data *ud) { - struct _update_data *ud = data; + /* FIXME Not checking result for error. */ g_mutex_lock (ud->cache->priv->stores_mutex); @@ -1101,10 +1104,8 @@ mail_folder_cache_note_store (MailFolderCache *self, si = g_malloc0 (sizeof (*si)); si->folders = g_hash_table_new (g_str_hash, g_str_equal); si->folders_uri = g_hash_table_new ( - CAMEL_STORE_CLASS ( - CAMEL_OBJECT_GET_CLASS (store))->hash_folder_name, - CAMEL_STORE_CLASS ( - CAMEL_OBJECT_GET_CLASS (store))->compare_folder_name); + CAMEL_STORE_GET_CLASS (store)->hash_folder_name, + CAMEL_STORE_GET_CLASS (store)->compare_folder_name); si->store = g_object_ref (store); g_hash_table_insert (self->priv->stores, store, si); g_queue_init (&si->folderinfo_updates); @@ -1124,8 +1125,9 @@ mail_folder_cache_note_store (MailFolderCache *self, if (camel_session_get_online (session) && camel_disco_store_status (CAMEL_DISCO_STORE (store)) == CAMEL_DISCO_STORE_OFFLINE) { - /* Note: we use the 'id' here, even though its not the right id, its still ok */ - ud->id = mail_store_set_offline (store, FALSE, store_online_cb, ud); + e_mail_store_go_online ( + store, G_PRIORITY_DEFAULT, cancellable, + (GAsyncReadyCallback) store_go_online_cb, ud); } else { goto normal_setup; } @@ -1133,8 +1135,9 @@ mail_folder_cache_note_store (MailFolderCache *self, if (camel_session_get_online (session) && !camel_offline_store_get_online ( CAMEL_OFFLINE_STORE (store))) { - /* Note: we use the 'id' here, even though its not the right id, its still ok */ - ud->id = mail_store_set_offline (store, FALSE, store_online_cb, ud); + e_mail_store_go_online ( + store, G_PRIORITY_DEFAULT, cancellable, + (GAsyncReadyCallback) store_go_online_cb, ud); } else { goto normal_setup; } diff --git a/mail/mail-ops.c b/mail/mail-ops.c index ce219ed372..d10473606b 100644 --- a/mail/mail-ops.c +++ b/mail/mail-ops.c @@ -2351,91 +2351,7 @@ mail_save_messages (CamelFolder *folder, GPtrArray *uids, const gchar *path, return id; } -/* ** PREPARE OFFLINE ***************************************************** */ - -struct _prep_offline_msg { - MailMsg base; - - EMailSession *session; - GCancellable *cancel; - gchar *uri; - void (*done)(const gchar *uri, gpointer data); - gpointer data; -}; - -static void -prep_offline_exec (struct _prep_offline_msg *m, - GCancellable *cancellable, - GError **error) -{ - CamelFolder *folder; - - folder = e_mail_session_uri_to_folder_sync ( - m->session, m->uri, 0, - cancellable, error); - if (folder) { - if (CAMEL_IS_DISCO_FOLDER (folder)) { - camel_disco_folder_prepare_for_offline ( - CAMEL_DISCO_FOLDER (folder), - "(match-all)", m->cancel, error); - } else if (CAMEL_IS_OFFLINE_FOLDER (folder)) { - camel_offline_folder_downsync_sync ( - CAMEL_OFFLINE_FOLDER (folder), - "(match-all)", m->cancel, error); - } - /* prepare_for_offline should do this? */ - /* of course it should all be atomic, but ... */ - /* FIXME Not passing a GCancellable here. */ - camel_folder_synchronize_sync (folder, FALSE, NULL, NULL); - g_object_unref (folder); - } -} - -static void -prep_offline_done (struct _prep_offline_msg *m) -{ - if (m->done) - m->done (m->uri, m->data); -} - -static void -prep_offline_free (struct _prep_offline_msg *m) -{ - g_object_unref (m->session); - if (m->cancel) - g_object_unref (m->cancel); - g_free (m->uri); -} - -static MailMsgInfo prep_offline_info = { - sizeof (struct _prep_offline_msg), - (MailMsgDescFunc) NULL, /* DO NOT CHANGE THIS, IT MUST BE NULL FOR CANCELLATION TO WORK */ - (MailMsgExecFunc) prep_offline_exec, - (MailMsgDoneFunc) prep_offline_done, - (MailMsgFreeFunc) prep_offline_free -}; - -void -mail_prep_offline (EMailSession *session, - const gchar *uri, - CamelOperation *cancel, - void (*done)(const gchar *, gpointer data), - gpointer data) -{ - struct _prep_offline_msg *m; - - m = mail_msg_new (&prep_offline_info); - m->session = g_object_ref (session); - if (G_IS_CANCELLABLE (cancel)) - m->cancel = g_object_ref (cancel); - m->uri = g_strdup (uri); - m->data = data; - m->done = done; - - mail_msg_slow_ordered_push (m); -} - -/* ** GO OFFLINE ***************************************************** */ +/* ** Prepare OFFLINE ***************************************************** */ struct _set_offline_msg { MailMsg base; @@ -2447,99 +2363,6 @@ struct _set_offline_msg { }; static gchar * -set_offline_desc (struct _set_offline_msg *m) -{ - gchar *service_name = camel_service_get_name (CAMEL_SERVICE (m->store), TRUE); - gchar *msg; - - msg = g_strdup_printf (m->offline ? _("Disconnecting from '%s'") : _("Reconnecting to '%s'"), - service_name); - g_free (service_name); - return msg; -} - -static void -set_offline_exec (struct _set_offline_msg *m, - GCancellable *cancellable, - GError **error) -{ - if (CAMEL_IS_DISCO_STORE (m->store)) { - if (!m->offline) { - camel_disco_store_set_status ( - CAMEL_DISCO_STORE (m->store), - CAMEL_DISCO_STORE_ONLINE, - cancellable, error); - return; - } else if (camel_disco_store_can_work_offline (CAMEL_DISCO_STORE (m->store))) { - camel_disco_store_set_status ( - CAMEL_DISCO_STORE (m->store), - CAMEL_DISCO_STORE_OFFLINE, - cancellable, error); - return; - } - } else if (CAMEL_IS_OFFLINE_STORE (m->store)) { - camel_offline_store_set_online_sync ( - CAMEL_OFFLINE_STORE (m->store), - !m->offline, cancellable, error); - return; - } - - if (m->offline) - camel_service_disconnect_sync ( - CAMEL_SERVICE (m->store), TRUE, error); -} - -static void -set_offline_done (struct _set_offline_msg *m) -{ - if (m->done) - m->done (m->store, m->data); -} - -static void -set_offline_free (struct _set_offline_msg *m) -{ - g_object_unref (m->store); -} - -static MailMsgInfo set_offline_info = { - sizeof (struct _set_offline_msg), - (MailMsgDescFunc) set_offline_desc, - (MailMsgExecFunc) set_offline_exec, - (MailMsgDoneFunc) set_offline_done, - (MailMsgFreeFunc) set_offline_free -}; - -gint -mail_store_set_offline (CamelStore *store, gboolean offline, - void (*done)(CamelStore *, gpointer data), - gpointer data) -{ - struct _set_offline_msg *m; - gint id; - - /* Cancel any pending connect first so the set_offline_op - * thread won't get queued behind a hung connect op. - */ - if (offline) - camel_service_cancel_connect (CAMEL_SERVICE (store)); - - m = mail_msg_new (&set_offline_info); - m->store = store; - g_object_ref (store); - m->offline = offline; - m->data = data; - m->done = done; - - id = m->base.seq; - mail_msg_unordered_push (m); - - return id; -} - -/* ** Prepare OFFLINE ***************************************************** */ - -static gchar * prepare_offline_desc (struct _set_offline_msg *m) { gchar *service_name = camel_service_get_name (CAMEL_SERVICE (m->store), TRUE); diff --git a/mail/mail-ops.h b/mail/mail-ops.h index 751ac9de93..ea9e9f7d0b 100644 --- a/mail/mail-ops.h +++ b/mail/mail-ops.h @@ -162,14 +162,6 @@ void mail_filter_folder (EMailSession *session, gboolean notify); /* Work Offline */ -void mail_prep_offline (EMailSession *session, - const gchar *uri, - CamelOperation *cancel, - void (*done)(const gchar *, gpointer data), - gpointer data); -gint mail_store_set_offline (CamelStore *store, gboolean offline, - void (*done)(CamelStore *, gpointer data), - gpointer data); gint mail_store_prepare_offline (CamelStore *store); /* filter driver execute shell command async callback */ |