diff options
Diffstat (limited to 'modules/calendar/e-memo-shell-sidebar.c')
-rw-r--r-- | modules/calendar/e-memo-shell-sidebar.c | 95 |
1 files changed, 83 insertions, 12 deletions
diff --git a/modules/calendar/e-memo-shell-sidebar.c b/modules/calendar/e-memo-shell-sidebar.c index 213179cc3a..01806199bb 100644 --- a/modules/calendar/e-memo-shell-sidebar.c +++ b/modules/calendar/e-memo-shell-sidebar.c @@ -55,6 +55,7 @@ struct _EMemoShellSidebarPrivate { ECalClient *default_client; GCancellable *loading_default_client; + GCancellable *loading_clients; }; enum { @@ -176,6 +177,28 @@ memo_shell_sidebar_retrieve_capabilies_cb (GObject *source_object, GAsyncResult memo_shell_sidebar_emit_status_message (memo_shell_sidebar, NULL); } +static gboolean memo_shell_sidebar_retry_open_timeout_cb (gpointer user_data); + +struct RetryOpenData +{ + EClient *client; + EMemoShellSidebar *memo_shell_sidebar; + GCancellable *cancellable; +}; + +static void +free_retry_open_data (gpointer data) +{ + struct RetryOpenData *rod = data; + + if (!rod) + return; + + g_object_unref (rod->client); + g_object_unref (rod->cancellable); + g_free (rod); +} + static void memo_shell_sidebar_client_opened_cb (GObject *source_object, GAsyncResult *result, gpointer user_data) { @@ -186,22 +209,43 @@ memo_shell_sidebar_client_opened_cb (GObject *source_object, GAsyncResult *resul EShellSidebar *shell_sidebar; GError *error = NULL; - shell_sidebar = E_SHELL_SIDEBAR (memo_shell_sidebar); - shell_view = e_shell_sidebar_get_shell_view (shell_sidebar); - shell_content = e_shell_view_get_shell_content (shell_view); - e_client_open_finish (E_CLIENT (client), result, &error); + if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED) || + g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + g_clear_error (&error); + return; + } + if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_AUTHENTICATION_FAILED) || g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_AUTHENTICATION_REQUIRED)) e_client_utils_forget_password (E_CLIENT (client)); if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_AUTHENTICATION_FAILED)) { - e_client_open (E_CLIENT (client), FALSE, NULL, memo_shell_sidebar_client_opened_cb, user_data); + e_client_open (E_CLIENT (client), FALSE, memo_shell_sidebar->priv->loading_clients, memo_shell_sidebar_client_opened_cb, user_data); + g_clear_error (&error); + return; + } + + if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_BUSY)) { + struct RetryOpenData *rod; + + rod = g_new0 (struct RetryOpenData, 1); + rod->client = g_object_ref (client); + rod->memo_shell_sidebar = memo_shell_sidebar; + rod->cancellable = g_object_ref (memo_shell_sidebar->priv->loading_clients); + + /* postpone for 1/2 of a second, backend is busy now */ + g_timeout_add_full (G_PRIORITY_DEFAULT, 500, memo_shell_sidebar_retry_open_timeout_cb, rod, free_retry_open_data); + g_clear_error (&error); return; } + shell_sidebar = E_SHELL_SIDEBAR (memo_shell_sidebar); + shell_view = e_shell_sidebar_get_shell_view (shell_sidebar); + shell_content = e_shell_view_get_shell_content (shell_view); + /* Handle errors. */ switch ((error && error->domain == E_CLIENT_ERROR) ? error->code : -1) { case -1: @@ -240,6 +284,24 @@ memo_shell_sidebar_client_opened_cb (GObject *source_object, GAsyncResult *resul e_client_retrieve_capabilities (E_CLIENT (client), NULL, memo_shell_sidebar_retrieve_capabilies_cb, memo_shell_sidebar); } +static gboolean +memo_shell_sidebar_retry_open_timeout_cb (gpointer user_data) +{ + struct RetryOpenData *rod = user_data; + + g_return_val_if_fail (rod != NULL, FALSE); + g_return_val_if_fail (rod->client != NULL, FALSE); + g_return_val_if_fail (rod->memo_shell_sidebar != NULL, FALSE); + g_return_val_if_fail (rod->cancellable != NULL, FALSE); + + if (g_cancellable_is_cancelled (rod->cancellable)) + return FALSE; + + e_client_open (rod->client, FALSE, rod->memo_shell_sidebar->priv->loading_clients, memo_shell_sidebar_client_opened_cb, rod->memo_shell_sidebar); + + return FALSE; +} + static void memo_shell_sidebar_default_loaded_cb (GObject *source_object, GAsyncResult *result, gpointer user_data) { @@ -254,11 +316,6 @@ memo_shell_sidebar_default_loaded_cb (GObject *source_object, GAsyncResult *resu priv = E_MEMO_SHELL_SIDEBAR (shell_sidebar)->priv; - shell_view = e_shell_sidebar_get_shell_view (shell_sidebar); - shell_content = e_shell_view_get_shell_content (shell_view); - memo_shell_content = E_MEMO_SHELL_CONTENT (shell_content); - model = e_memo_shell_content_get_memo_model (memo_shell_content); - if (!e_client_utils_open_new_finish (E_SOURCE (source_object), result, &client, &error)) client = NULL; @@ -266,7 +323,14 @@ memo_shell_sidebar_default_loaded_cb (GObject *source_object, GAsyncResult *resu g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED)) { g_error_free (error); goto exit; - } else if (error != NULL) { + } + + shell_view = e_shell_sidebar_get_shell_view (shell_sidebar); + shell_content = e_shell_view_get_shell_content (shell_view); + memo_shell_content = E_MEMO_SHELL_CONTENT (shell_content); + model = e_memo_shell_content_get_memo_model (memo_shell_content); + + if (error != NULL) { e_alert_submit ( E_ALERT_SINK (shell_content), "calendar:failed-open-memos", @@ -527,6 +591,12 @@ memo_shell_sidebar_dispose (GObject *object) priv->loading_default_client = NULL; } + if (priv->loading_clients != NULL) { + g_cancellable_cancel (priv->loading_clients); + g_object_unref (priv->loading_clients); + priv->loading_clients = NULL; + } + g_hash_table_remove_all (priv->client_table); /* Chain up to parent's dispose() method. */ @@ -760,6 +830,7 @@ memo_shell_sidebar_init (EMemoShellSidebar *memo_shell_sidebar) EMemoShellSidebarPrivate); memo_shell_sidebar->priv->client_table = client_table; + memo_shell_sidebar->priv->loading_clients = g_cancellable_new (); /* Postpone widget construction until we have a shell view. */ } @@ -914,7 +985,7 @@ e_memo_shell_sidebar_add_source (EMemoShellSidebar *memo_shell_sidebar, timezone = e_cal_model_get_timezone (model); e_cal_client_set_default_timezone (client, timezone); - e_client_open (E_CLIENT (client), FALSE, NULL, memo_shell_sidebar_client_opened_cb, memo_shell_sidebar); + e_client_open (E_CLIENT (client), FALSE, memo_shell_sidebar->priv->loading_clients, memo_shell_sidebar_client_opened_cb, memo_shell_sidebar); } void |