From ae28ea4621c9ced08524548ca67a5297c284ce01 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Mon, 2 May 2011 21:01:48 -0400 Subject: EMailShellView: Open the selected folder ourselves. This one's a little involved: - EMailShellView now obtains a CamelFolder itself in response to EMFolderTree::folder-selected signals. Uses EActivity to do so. - Revise EMFolderTree::folder-selected signal arguments to be more useful: emit a CamelStore object instead of a folder URI. - Also revise EMFolderTree::folder-activiated signal arguments the same way while we're at it. - Remove the "folder_uri" argument from e_mail_reader_set_folder(). If you have a CamelFolder object you can obtain the URI string by calling camel_folder_get_uri(). --- modules/mail/e-mail-shell-backend.c | 2 +- modules/mail/e-mail-shell-content.c | 5 +- modules/mail/e-mail-shell-view-private.c | 119 +++++++++++++++++++++++++++---- modules/mail/e-mail-shell-view-private.h | 3 + modules/mail/e-mail-shell-view.c | 22 ++---- 5 files changed, 119 insertions(+), 32 deletions(-) (limited to 'modules') diff --git a/modules/mail/e-mail-shell-backend.c b/modules/mail/e-mail-shell-backend.c index 1de34a97ed..609e483083 100644 --- a/modules/mail/e-mail-shell-backend.c +++ b/modules/mail/e-mail-shell-backend.c @@ -315,7 +315,7 @@ mail_shell_backend_handle_email_uri_cb (gchar *folder_uri, /* FIXME Should pass in the shell module. */ browser = e_mail_browser_new (backend); e_mail_reader_set_folder ( - E_MAIL_READER (browser), folder, folder_uri); + E_MAIL_READER (browser), folder); e_mail_reader_set_message (E_MAIL_READER (browser), uid); gtk_widget_show (browser); } diff --git a/modules/mail/e-mail-shell-content.c b/modules/mail/e-mail-shell-content.c index c3b6cf978b..57d1663434 100644 --- a/modules/mail/e-mail-shell-content.c +++ b/modules/mail/e-mail-shell-content.c @@ -361,8 +361,7 @@ mail_shell_content_get_window (EMailReader *reader) static void mail_shell_content_set_folder (EMailReader *reader, - CamelFolder *folder, - const gchar *folder_uri) + CamelFolder *folder) { EMailShellContentPrivate *priv; @@ -372,7 +371,7 @@ mail_shell_content_set_folder (EMailReader *reader, * also implements the EMailReader interface. */ reader = E_MAIL_READER (priv->mail_view); - return e_mail_reader_set_folder (reader, folder, folder_uri); + return e_mail_reader_set_folder (reader, folder); } static void diff --git a/modules/mail/e-mail-shell-view-private.c b/modules/mail/e-mail-shell-view-private.c index ac13439eb6..c67dc76773 100644 --- a/modules/mail/e-mail-shell-view-private.c +++ b/modules/mail/e-mail-shell-view-private.c @@ -26,36 +26,125 @@ #include "e-util/e-util-private.h" +typedef struct _AsyncContext AsyncContext; + +struct _AsyncContext { + EActivity *activity; + EMailReader *reader; + EShellView *shell_view; +}; + +static void +async_context_free (AsyncContext *context) +{ + if (context->activity != NULL) + g_object_unref (context->activity); + + if (context->reader != NULL) + g_object_unref (context->reader); + + if (context->shell_view != NULL) + g_object_unref (context->shell_view); + + g_slice_free (AsyncContext, context); +} + +static void +mail_shell_view_got_folder_cb (CamelStore *store, + GAsyncResult *result, + AsyncContext *context) +{ + EAlertSink *alert_sink; + CamelFolder *folder; + GError *error = NULL; + + alert_sink = e_activity_get_alert_sink (context->activity); + + folder = camel_store_get_folder_finish (store, result, &error); + + /* Ignore cancellations. */ + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + g_warn_if_fail (folder == NULL); + async_context_free (context); + g_error_free (error); + return; + + } else if (error != NULL) { + g_warn_if_fail (folder == NULL); + e_alert_submit ( + alert_sink, "folder-open", + error->message, NULL); + async_context_free (context); + g_error_free (error); + return; + } + + e_mail_reader_set_folder (context->reader, folder); + e_shell_view_update_actions (context->shell_view); + + g_object_unref (folder); + + async_context_free (context); +} + static void mail_shell_view_folder_tree_selected_cb (EMailShellView *mail_shell_view, - const gchar *full_name, - const gchar *uri, - guint32 flags, + CamelStore *store, + const gchar *folder_name, + CamelFolderInfoFlags flags, EMFolderTree *folder_tree) { EMailShellContent *mail_shell_content; + EShellBackend *shell_backend; EShellView *shell_view; EMailReader *reader; EMailView *mail_view; - gboolean folder_selected; + GCancellable *cancellable; + EAlertSink *alert_sink; + AsyncContext *context; shell_view = E_SHELL_VIEW (mail_shell_view); + shell_backend = e_shell_view_get_shell_backend (shell_view); mail_shell_content = mail_shell_view->priv->mail_shell_content; mail_view = e_mail_shell_content_get_mail_view (mail_shell_content); reader = E_MAIL_READER (mail_view); - folder_selected = - !(flags & CAMEL_FOLDER_NOSELECT) && - full_name != NULL; + /* Cancel any unfinished open folder operations. */ + if (mail_shell_view->priv->opening_folder != NULL) { + g_cancellable_cancel (mail_shell_view->priv->opening_folder); + mail_shell_view->priv->opening_folder = NULL; + } - if (folder_selected) - e_mail_reader_set_folder_uri (reader, uri); - else - e_mail_reader_set_folder (reader, NULL, NULL); + /* If we are to clear the message list, do so immediately. */ + if ((flags & CAMEL_FOLDER_NOSELECT) || folder_name == NULL) { + e_mail_reader_set_folder (reader, NULL); + e_shell_view_update_actions (shell_view); + return; + } - e_shell_view_update_actions (shell_view); + g_warn_if_fail (CAMEL_IS_STORE (store)); + + /* Open the selected folder asynchronously. */ + + context = g_slice_new0 (AsyncContext); + context->activity = e_activity_new (); + context->reader = g_object_ref (reader); + context->shell_view = g_object_ref (shell_view); + + alert_sink = E_ALERT_SINK (mail_shell_content); + e_activity_set_alert_sink (context->activity, alert_sink); + + cancellable = camel_operation_new (); + e_activity_set_cancellable (context->activity, cancellable); + mail_shell_view->priv->opening_folder = cancellable; + + e_shell_backend_add_activity (shell_backend, context->activity); + + camel_store_get_folder ( + store, folder_name, 0, G_PRIORITY_DEFAULT, cancellable, + (GAsyncReadyCallback) mail_shell_view_got_folder_cb, context); } static gboolean @@ -748,6 +837,12 @@ e_mail_shell_view_private_dispose (EMailShellView *mail_shell_view) for (ii = 0; ii < MAIL_NUM_SEARCH_RULES; ii++) DISPOSE (priv->search_rules[ii]); + if (priv->opening_folder != NULL) { + g_cancellable_cancel (priv->opening_folder); + g_object_unref (priv->opening_folder); + priv->opening_folder = NULL; + } + if (priv->search_account_all != NULL) { g_object_unref (priv->search_account_all); priv->search_account_all = NULL; diff --git a/modules/mail/e-mail-shell-view-private.h b/modules/mail/e-mail-shell-view-private.h index ac460a7b40..01097056b0 100644 --- a/modules/mail/e-mail-shell-view-private.h +++ b/modules/mail/e-mail-shell-view-private.h @@ -149,6 +149,9 @@ struct _EMailShellViewPrivate { /* EShell::prepare-for-quit */ gulong prepare_for_quit_handler_id; + /* For opening the selected folder. */ + GCancellable *opening_folder; + /* Search folders for interactive search. */ CamelVeeFolder *search_account_all; CamelVeeFolder *search_account_current; diff --git a/modules/mail/e-mail-shell-view.c b/modules/mail/e-mail-shell-view.c index 4af7de5a1b..0b0f13e5d3 100644 --- a/modules/mail/e-mail-shell-view.c +++ b/modules/mail/e-mail-shell-view.c @@ -116,8 +116,7 @@ mail_shell_view_setup_search_results_folder (CamelFolder *folder, static void mail_shell_view_show_search_results_folder (EMailShellView *mail_shell_view, - CamelFolder *folder, - const gchar *folder_uri) + CamelFolder *folder) { EMailShellContent *mail_shell_content; GtkWidget *message_list; @@ -132,7 +131,7 @@ mail_shell_view_show_search_results_folder (EMailShellView *mail_shell_view, message_list_freeze (MESSAGE_LIST (message_list)); - e_mail_reader_set_folder (reader, folder, folder_uri); + e_mail_reader_set_folder (reader, folder); e_tree_set_state (E_TREE (message_list), SEARCH_RESULTS_STATE); message_list_thaw (MESSAGE_LIST (message_list)); @@ -240,7 +239,6 @@ mail_shell_view_execute_search (EShellView *shell_view) gchar *query; gchar *temp; gchar *tag; - gchar *uri; const gchar *use_tag; gint value; @@ -519,9 +517,7 @@ all_accounts: * folder URI and let the asynchronous callbacks run * after we've already kicked off the search. */ folder = em_folder_tree_get_selected_folder (folder_tree); - uri = em_folder_tree_get_selected_uri (folder_tree); - e_mail_reader_set_folder (reader, folder, uri); - g_free (uri); + e_mail_reader_set_folder (reader, folder); gtk_widget_set_sensitive (GTK_WIDGET (combo_box), TRUE); @@ -606,11 +602,9 @@ all_accounts: CAMEL_FOLDER (search_folder), list, priv->search_account_cancel); - folder_uri = camel_folder_get_uri (CAMEL_FOLDER (search_folder)); - mail_shell_view_show_search_results_folder ( E_MAIL_SHELL_VIEW (shell_view), - CAMEL_FOLDER (search_folder), folder_uri); + CAMEL_FOLDER (search_folder)); goto execute; @@ -639,9 +633,7 @@ current_account: * folder URI and let the asynchronous callbacks run * after we've already kicked off the search. */ folder = em_folder_tree_get_selected_folder (folder_tree); - uri = em_folder_tree_get_selected_uri (folder_tree); - e_mail_reader_set_folder (reader, folder, uri); - g_free (uri); + e_mail_reader_set_folder (reader, folder); gtk_widget_set_sensitive (GTK_WIDGET (combo_box), TRUE); @@ -758,11 +750,9 @@ current_account: CAMEL_FOLDER (search_folder), list, priv->search_account_cancel); - folder_uri = camel_folder_get_uri (CAMEL_FOLDER (search_folder)); - mail_shell_view_show_search_results_folder ( E_MAIL_SHELL_VIEW (shell_view), - CAMEL_FOLDER (search_folder), folder_uri); + CAMEL_FOLDER (search_folder)); execute: -- cgit