aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMilan Crha <mcrha@redhat.com>2011-06-27 21:23:31 +0800
committerMilan Crha <mcrha@redhat.com>2011-06-27 21:23:31 +0800
commit05933ef483635b84514eb285d4d839b87c3b3afb (patch)
tree0d35dc4b36755651a1652c7131e485e40bd08602
parent46eec90c098d5b239035568ae5c25ae9127a8373 (diff)
downloadgsoc2013-evolution-05933ef483635b84514eb285d4d839b87c3b3afb.tar
gsoc2013-evolution-05933ef483635b84514eb285d4d839b87c3b3afb.tar.gz
gsoc2013-evolution-05933ef483635b84514eb285d4d839b87c3b3afb.tar.bz2
gsoc2013-evolution-05933ef483635b84514eb285d4d839b87c3b3afb.tar.lz
gsoc2013-evolution-05933ef483635b84514eb285d4d839b87c3b3afb.tar.xz
gsoc2013-evolution-05933ef483635b84514eb285d4d839b87c3b3afb.tar.zst
gsoc2013-evolution-05933ef483635b84514eb285d4d839b87c3b3afb.zip
Keep opening EClient-s till they report busy error
-rw-r--r--calendar/gui/e-cal-model.c72
-rw-r--r--calendar/gui/gnome-cal.c6
-rw-r--r--calendar/gui/gnome-cal.h1
-rw-r--r--modules/calendar/e-cal-shell-content.c1
-rw-r--r--modules/calendar/e-cal-shell-sidebar.c96
-rw-r--r--modules/calendar/e-memo-shell-sidebar.c95
-rw-r--r--modules/calendar/e-task-shell-sidebar.c95
7 files changed, 320 insertions, 46 deletions
diff --git a/calendar/gui/e-cal-model.c b/calendar/gui/e-cal-model.c
index 9778d3e452..2b4aac732d 100644
--- a/calendar/gui/e-cal-model.c
+++ b/calendar/gui/e-cal-model.c
@@ -114,6 +114,8 @@ struct _ECalModelPrivate {
GSList *notify_removed;
GMutex *notify_lock;
+
+ GCancellable *loading_clients;
};
static gint ecm_column_count (ETableModel *etm);
@@ -377,6 +379,12 @@ cal_model_dispose (GObject *object)
priv = E_CAL_MODEL (object)->priv;
+ if (priv->loading_clients) {
+ g_cancellable_cancel (priv->loading_clients);
+ g_object_unref (priv->loading_clients);
+ priv->loading_clients = NULL;
+ }
+
if (priv->clients) {
while (priv->clients != NULL) {
ECalModelClient *client_data = (ECalModelClient *) priv->clients->data;
@@ -701,6 +709,8 @@ e_cal_model_init (ECalModel *model)
model->priv->notify_modified = NULL;
model->priv->notify_removed = NULL;
model->priv->notify_lock = g_mutex_new ();
+
+ model->priv->loading_clients = g_cancellable_new ();
}
/* ETableModel methods */
@@ -2582,6 +2592,28 @@ cal_model_retrieve_capabilies_cb (GObject *source_object, GAsyncResult *result,
update_e_cal_view_for_client (model, client_data);
}
+struct RetryOpenData
+{
+ EClient *client;
+ ECalModel *model;
+ 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 gboolean cal_model_retry_open_timeout_cb (gpointer user_data);
+
static void
client_opened_cb (GObject *source_object, GAsyncResult *result, gpointer user_data)
{
@@ -2591,6 +2623,28 @@ client_opened_cb (GObject *source_object, GAsyncResult *result, gpointer user_da
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_error_free (error);
+ return;
+ }
+
+ if (error && 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->model = model;
+ rod->cancellable = g_object_ref (model->priv->loading_clients);
+
+ /* postpone for 1/2 of a second, backend is busy now */
+ g_timeout_add_full (G_PRIORITY_DEFAULT, 500, cal_model_retry_open_timeout_cb, rod, free_retry_open_data);
+
+ g_error_free (error);
+
+ return;
+ }
+
if (error) {
e_cal_model_remove_client (model, client);
g_debug ("%s: Failed to open '%s': %s", G_STRFUNC, e_client_get_uri (E_CLIENT (client)), error->message);
@@ -2600,7 +2654,21 @@ client_opened_cb (GObject *source_object, GAsyncResult *result, gpointer user_da
}
/* to have them ready for later use */
- e_client_retrieve_capabilities (E_CLIENT (client), NULL, cal_model_retrieve_capabilies_cb, model);
+ e_client_retrieve_capabilities (E_CLIENT (client), model->priv->loading_clients, cal_model_retrieve_capabilies_cb, model);
+}
+
+static gboolean
+cal_model_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->model != NULL, FALSE);
+
+ e_client_open (rod->client, TRUE, rod->cancellable, client_opened_cb, rod->model);
+
+ return FALSE;
}
static ECalModelClient *
@@ -2649,7 +2717,7 @@ add_new_client (ECalModel *model, ECalClient *client, gboolean do_query)
e_cal_client_set_default_timezone (client, e_cal_model_get_timezone (model));
- e_client_open (E_CLIENT (client), TRUE, NULL, client_opened_cb, model);
+ e_client_open (E_CLIENT (client), TRUE, model->priv->loading_clients, client_opened_cb, model);
}
return client_data;
diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c
index 78721bf214..4bb430c018 100644
--- a/calendar/gui/gnome-cal.c
+++ b/calendar/gui/gnome-cal.c
@@ -1510,12 +1510,6 @@ gnome_calendar_finalize (GObject *object)
G_OBJECT_CLASS (gnome_calendar_parent_class)->finalize (object);
}
-void
-gnome_calendar_dispose (GnomeCalendar *gcal)
-{
- g_object_run_dispose (G_OBJECT (gcal));
-}
-
static void
notify_selected_time_changed (GnomeCalendar *gcal)
{
diff --git a/calendar/gui/gnome-cal.h b/calendar/gui/gnome-cal.h
index 6657b8efe3..58130399f4 100644
--- a/calendar/gui/gnome-cal.h
+++ b/calendar/gui/gnome-cal.h
@@ -113,7 +113,6 @@ struct _GnomeCalendarClass {
GType gnome_calendar_get_type (void);
GtkWidget * gnome_calendar_new (void);
-void gnome_calendar_dispose (GnomeCalendar *gcal);
ECalendar * gnome_calendar_get_date_navigator
(GnomeCalendar *gcal);
void gnome_calendar_set_date_navigator
diff --git a/modules/calendar/e-cal-shell-content.c b/modules/calendar/e-cal-shell-content.c
index e85f9201cc..b4297b9fcd 100644
--- a/modules/calendar/e-cal-shell-content.c
+++ b/modules/calendar/e-cal-shell-content.c
@@ -279,7 +279,6 @@ cal_shell_content_dispose (GObject *object)
}
if (priv->calendar != NULL) {
- gnome_calendar_dispose (GNOME_CALENDAR (priv->calendar));
g_object_unref (priv->calendar);
priv->calendar = NULL;
}
diff --git a/modules/calendar/e-cal-shell-sidebar.c b/modules/calendar/e-cal-shell-sidebar.c
index e33a7dcd06..efa233e019 100644
--- a/modules/calendar/e-cal-shell-sidebar.c
+++ b/modules/calendar/e-cal-shell-sidebar.c
@@ -59,6 +59,7 @@ struct _ECalShellSidebarPrivate {
ECalClient *default_client;
GCancellable *loading_default_client;
+ GCancellable *loading_clients;
};
enum {
@@ -181,6 +182,28 @@ cal_shell_sidebar_retrieve_capabilies_cb (GObject *source_object, GAsyncResult *
cal_shell_sidebar_emit_status_message (cal_shell_sidebar, NULL);
}
+static gboolean cal_shell_sidebar_retry_open_timeout_cb (gpointer user_data);
+
+struct RetryOpenData
+{
+ EClient *client;
+ ECalShellSidebar *cal_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
cal_shell_sidebar_client_opened_cb (GObject *source_object, GAsyncResult *result, gpointer user_data)
{
@@ -191,22 +214,44 @@ cal_shell_sidebar_client_opened_cb (GObject *source_object, GAsyncResult *result
EShellSidebar *shell_sidebar;
GError *error = NULL;
- shell_sidebar = E_SHELL_SIDEBAR (cal_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, cal_shell_sidebar_client_opened_cb, user_data);
+ e_client_open (E_CLIENT (client), FALSE, cal_shell_sidebar->priv->loading_clients, cal_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->cal_shell_sidebar = cal_shell_sidebar;
+ rod->cancellable = g_object_ref (cal_shell_sidebar->priv->loading_clients);
+
+ /* postpone for 1/2 of a second, backend is busy now */
+ g_timeout_add_full (G_PRIORITY_DEFAULT, 500, cal_shell_sidebar_retry_open_timeout_cb, rod, free_retry_open_data);
+
+ g_clear_error (&error);
+ return;
+ }
+
+ shell_sidebar = E_SHELL_SIDEBAR (cal_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:
@@ -245,6 +290,24 @@ cal_shell_sidebar_client_opened_cb (GObject *source_object, GAsyncResult *result
e_client_retrieve_capabilities (E_CLIENT (client), NULL, cal_shell_sidebar_retrieve_capabilies_cb, cal_shell_sidebar);
}
+static gboolean
+cal_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->cal_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->cal_shell_sidebar->priv->loading_clients, cal_shell_sidebar_client_opened_cb, rod->cal_shell_sidebar);
+
+ return FALSE;
+}
+
static void
cal_shell_sidebar_default_loaded_cb (GObject *source_object, GAsyncResult *result, gpointer user_data)
{
@@ -259,11 +322,6 @@ cal_shell_sidebar_default_loaded_cb (GObject *source_object, GAsyncResult *resul
priv = E_CAL_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);
- cal_shell_content = E_CAL_SHELL_CONTENT (shell_content);
- model = e_cal_shell_content_get_model (cal_shell_content);
-
if (!e_client_utils_open_new_finish (E_SOURCE (source_object), result, &client, &error))
client = NULL;
@@ -271,7 +329,14 @@ cal_shell_sidebar_default_loaded_cb (GObject *source_object, GAsyncResult *resul
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);
+ cal_shell_content = E_CAL_SHELL_CONTENT (shell_content);
+ model = e_cal_shell_content_get_model (cal_shell_content);
+
+ if (error != NULL) {
e_alert_submit (
E_ALERT_SINK (shell_content),
"calendar:failed-open-calendar",
@@ -560,6 +625,12 @@ cal_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. */
@@ -864,6 +935,7 @@ cal_shell_sidebar_init (ECalShellSidebar *cal_shell_sidebar)
ECalShellSidebarPrivate);
cal_shell_sidebar->priv->client_table = client_table;
+ cal_shell_sidebar->priv->loading_clients = g_cancellable_new ();
/* Postpone widget construction until we have a shell view. */
}
@@ -1027,7 +1099,7 @@ e_cal_shell_sidebar_add_source (ECalShellSidebar *cal_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, cal_shell_sidebar_client_opened_cb, cal_shell_sidebar);
+ e_client_open (E_CLIENT (client), FALSE, cal_shell_sidebar->priv->loading_clients, cal_shell_sidebar_client_opened_cb, cal_shell_sidebar);
}
void
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
diff --git a/modules/calendar/e-task-shell-sidebar.c b/modules/calendar/e-task-shell-sidebar.c
index 04d2c25342..dbb1ba9014 100644
--- a/modules/calendar/e-task-shell-sidebar.c
+++ b/modules/calendar/e-task-shell-sidebar.c
@@ -55,6 +55,7 @@ struct _ETaskShellSidebarPrivate {
ECalClient *default_client;
GCancellable *loading_default_client;
+ GCancellable *loading_clients;
};
enum {
@@ -176,6 +177,28 @@ task_shell_sidebar_retrieve_capabilies_cb (GObject *source_object, GAsyncResult
task_shell_sidebar_emit_status_message (task_shell_sidebar, NULL);
}
+static gboolean task_shell_sidebar_retry_open_timeout_cb (gpointer user_data);
+
+struct RetryOpenData
+{
+ EClient *client;
+ ETaskShellSidebar *task_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
task_shell_sidebar_client_opened_cb (GObject *source_object, GAsyncResult *result, gpointer user_data)
{
@@ -186,22 +209,43 @@ task_shell_sidebar_client_opened_cb (GObject *source_object, GAsyncResult *resul
EShellSidebar *shell_sidebar;
GError *error = NULL;
- shell_sidebar = E_SHELL_SIDEBAR (task_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, task_shell_sidebar_client_opened_cb, user_data);
+ e_client_open (E_CLIENT (client), FALSE, task_shell_sidebar->priv->loading_clients, task_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->task_shell_sidebar = task_shell_sidebar;
+ rod->cancellable = g_object_ref (task_shell_sidebar->priv->loading_clients);
+
+ /* postpone for 1/2 of a second, backend is busy now */
+ g_timeout_add_full (G_PRIORITY_DEFAULT, 500, task_shell_sidebar_retry_open_timeout_cb, rod, free_retry_open_data);
+
g_clear_error (&error);
return;
}
+ shell_sidebar = E_SHELL_SIDEBAR (task_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 @@ task_shell_sidebar_client_opened_cb (GObject *source_object, GAsyncResult *resul
e_client_retrieve_capabilities (E_CLIENT (client), NULL, task_shell_sidebar_retrieve_capabilies_cb, task_shell_sidebar);
}
+static gboolean
+task_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->task_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->task_shell_sidebar->priv->loading_clients, task_shell_sidebar_client_opened_cb, rod->task_shell_sidebar);
+
+ return FALSE;
+}
+
static void
task_shell_sidebar_default_loaded_cb (GObject *source_object, GAsyncResult *result, gpointer user_data)
{
@@ -254,11 +316,6 @@ task_shell_sidebar_default_loaded_cb (GObject *source_object, GAsyncResult *resu
priv = E_TASK_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);
- task_shell_content = E_TASK_SHELL_CONTENT (shell_content);
- model = e_task_shell_content_get_task_model (task_shell_content);
-
if (!e_client_utils_open_new_finish (E_SOURCE (source_object), result, &client, &error))
client = NULL;
@@ -266,7 +323,14 @@ task_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);
+ task_shell_content = E_TASK_SHELL_CONTENT (shell_content);
+ model = e_task_shell_content_get_task_model (task_shell_content);
+
+ if (error != NULL) {
e_alert_submit (
E_ALERT_SINK (shell_content),
"calendar:failed-open-tasks",
@@ -527,6 +591,12 @@ task_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 @@ task_shell_sidebar_init (ETaskShellSidebar *task_shell_sidebar)
ETaskShellSidebarPrivate);
task_shell_sidebar->priv->client_table = client_table;
+ task_shell_sidebar->priv->loading_clients = g_cancellable_new ();
/* Postpone widget construction until we have a shell view. */
}
@@ -914,7 +985,7 @@ e_task_shell_sidebar_add_source (ETaskShellSidebar *task_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, task_shell_sidebar_client_opened_cb, task_shell_sidebar);
+ e_client_open (E_CLIENT (client), FALSE, task_shell_sidebar->priv->loading_clients, task_shell_sidebar_client_opened_cb, task_shell_sidebar);
}
void