aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--calendar/common/authentication.c273
-rw-r--r--calendar/common/authentication.h18
-rw-r--r--modules/addressbook/e-book-shell-backend.c7
-rw-r--r--modules/calendar/e-cal-shell-backend.c128
-rw-r--r--modules/calendar/e-cal-shell-sidebar.c126
-rw-r--r--modules/calendar/e-memo-shell-backend.c102
-rw-r--r--modules/calendar/e-memo-shell-sidebar.c126
-rw-r--r--modules/calendar/e-task-shell-backend.c99
-rw-r--r--modules/calendar/e-task-shell-sidebar.c126
9 files changed, 665 insertions, 340 deletions
diff --git a/calendar/common/authentication.c b/calendar/common/authentication.c
index 675754c5f0..b36e10a244 100644
--- a/calendar/common/authentication.c
+++ b/calendar/common/authentication.c
@@ -32,8 +32,6 @@
#include "authentication.h"
#include <libedataserver/e-url.h>
-static GHashTable *source_lists_hash = NULL;
-
static gchar *
auth_func_cb (ECal *ecal,
const gchar *prompt,
@@ -124,3 +122,274 @@ e_auth_new_cal_from_source (ESource *source, ECalSourceType type)
return cal;
}
+
+typedef struct {
+ ECal *cal;
+ GtkWindow *parent;
+ GCancellable *cancellable;
+ ECalSourceType source_type;
+ icaltimezone *default_zone;
+
+ /* Authentication Details */
+ gchar *auth_uri;
+ gchar *auth_component;
+} LoadContext;
+
+static void
+load_cal_source_context_free (LoadContext *context)
+{
+ if (context->cal != NULL)
+ g_object_unref (context->cal);
+
+ if (context->parent != NULL)
+ g_object_unref (context->parent);
+
+ if (context->cancellable != NULL)
+ g_object_unref (context->cancellable);
+
+ g_free (context->auth_uri);
+ g_free (context->auth_component);
+
+ g_slice_free (LoadContext, context);
+}
+
+static void
+load_cal_source_get_auth_details (ESource *source,
+ LoadContext *context)
+{
+ const gchar *property;
+
+ /* ECal figures out most of the details before invoking the
+ * authentication callback, but we still need a component name
+ * for e_passwords_ask_password(). */
+
+ /* auth_component */
+
+ property = e_source_get_property (source, "auth-domain");
+
+ if (property == NULL)
+ property = "Calendar";
+
+ context->auth_component = g_strdup (property);
+}
+
+static gchar *
+load_cal_source_authenticate (ECal *cal,
+ const gchar *prompt,
+ const gchar *uri,
+ LoadContext *context)
+{
+ const gchar *title;
+ gboolean remember; /* not used */
+ gchar *password;
+
+ /* Remember the URI so we don't have to reconstruct it if
+ * authentication fails and we have to forget the password. */
+ g_free (context->auth_uri);
+ context->auth_uri = g_strdup (uri);
+
+ /* XXX Dialog windows should not have titles. */
+ title = "";
+
+ password = e_passwords_get_password (context->auth_component, uri);
+
+ if (password == NULL)
+ password = e_passwords_ask_password (
+ title, context->auth_component, uri,
+ prompt, E_PASSWORDS_REMEMBER_FOREVER |
+ E_PASSWORDS_SECRET | E_PASSWORDS_ONLINE,
+ &remember, context->parent);
+
+ return password;
+}
+
+static void
+load_cal_source_thread (GSimpleAsyncResult *simple,
+ ESource *source,
+ GCancellable *cancellable)
+{
+ ECal *cal;
+ LoadContext *context;
+ GError *error = NULL;
+
+ context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ /* XXX This doesn't take a GError, it just dumps
+ * error messages to the terminal... so broken. */
+ cal = e_cal_new (source, context->source_type);
+ g_return_if_fail (cal != NULL);
+
+ if (g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_object_unref (cal);
+ g_error_free (error);
+ return;
+ }
+
+ if (!e_cal_set_default_timezone (cal, context->default_zone, &error)) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_object_unref (cal);
+ g_error_free (error);
+ return;
+ }
+
+ /* XXX Why doesn't EBook have something like this? */
+ e_cal_set_auth_func (
+ cal, (ECalAuthFunc)
+ load_cal_source_authenticate, context);
+
+try_again:
+ if (!e_cal_open (cal, FALSE, &error))
+ goto fail;
+
+ /* We should be authenticated now if we're going to be,
+ * so remove the authentication callback so it doesn't
+ * get triggered after we free the load context. */
+ e_cal_set_auth_func (cal, NULL, NULL);
+
+ if (g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_object_unref (cal);
+ g_error_free (error);
+ return;
+ }
+
+ context->cal = cal;
+
+ return;
+
+fail:
+ g_return_if_fail (error != NULL);
+
+ /* If authentication failed, forget the password and reprompt. */
+ if (g_error_matches (
+ error, E_CALENDAR_ERROR,
+ E_CALENDAR_STATUS_AUTHENTICATION_FAILED)) {
+ e_passwords_forget_password (
+ context->auth_component, context->auth_uri);
+ g_clear_error (&error);
+ goto try_again;
+
+ /* XXX Might this cause a busy loop? */
+ } else if (g_error_matches (
+ error, E_CALENDAR_ERROR, E_CALENDAR_STATUS_BUSY)) {
+ g_clear_error (&error);
+ goto try_again;
+
+ } else {
+ g_simple_async_result_set_from_error (simple, error);
+ g_object_unref (cal);
+ g_error_free (error);
+ }
+}
+
+/**
+ * e_load_cal_source_async:
+ * @source: an #ESource
+ * @source_type: the type of #ECal to load
+ * @default_zone: default time zone, or %NULL to use UTC
+ * @parent: parent window for password dialogs, or %NULL
+ * @cancellable: optional #GCancellable object, %NULL to ignore
+ * @callback: a #GAsyncReadyCallback to call when the request is satisfied
+ * @user_data: the data to pass to @callback
+ *
+ * Creates a new #ECal specified by @source and opens it, prompting the
+ * user for authentication if necessary.
+ *
+ * When the operation is finished, @callback will be called. You can
+ * then call e_load_cal_source_finish() to obtain the resulting #ECal.
+ **/
+void
+e_load_cal_source_async (ESource *source,
+ ECalSourceType source_type,
+ icaltimezone *default_zone,
+ GtkWindow *parent,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ LoadContext *context;
+
+ g_return_if_fail (E_IS_SOURCE (source));
+
+ /* Source must have a group so we can obtain its URI. */
+ g_return_if_fail (e_source_peek_group (source) != NULL);
+
+ if (parent != NULL) {
+ g_return_if_fail (GTK_IS_WINDOW (parent));
+ g_object_ref (parent);
+ }
+
+ if (cancellable != NULL) {
+ g_return_if_fail (G_IS_CANCELLABLE (cancellable));
+ g_object_ref (cancellable);
+ }
+
+ if (default_zone == NULL)
+ default_zone = icaltimezone_get_utc_timezone ();
+
+ context = g_slice_new0 (LoadContext);
+ context->parent = parent;
+ context->cancellable = cancellable;
+ context->source_type = source_type;
+ context->default_zone = default_zone;
+
+ /* Extract authentication details from the ESource before
+ * spawning the thread, since ESource is not thread-safe. */
+ load_cal_source_get_auth_details (source, context);
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (source), callback,
+ user_data, e_load_cal_source_async);
+
+ g_simple_async_result_set_op_res_gpointer (
+ simple, context, (GDestroyNotify)
+ load_cal_source_context_free);
+
+ g_simple_async_result_run_in_thread (
+ simple, (GSimpleAsyncThreadFunc) load_cal_source_thread,
+ G_PRIORITY_DEFAULT, context->cancellable);
+
+ g_object_unref (simple);
+}
+
+/**
+ * e_load_cal_source_finish:
+ * @source: an #ESource
+ * @result: a #GAsyncResult
+ * @error: return location for a #GError, or %NULL
+ *
+ * Finishes an asynchronous #ECal open operation started with
+ * e_load_cal_source_async(). If an error occurred, or the user
+ * declined to authenticate, the function will return %NULL and
+ * set @error.
+ *
+ * Returns: a ready-to-use #ECal, or %NULL on error
+ **/
+ECal *
+e_load_cal_source_finish (ESource *source,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+ LoadContext *context;
+
+ g_return_val_if_fail (E_IS_SOURCE (source), NULL);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (source),
+ e_load_cal_source_async), NULL);
+
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+
+ if (g_simple_async_result_propagate_error (simple, error))
+ return NULL;
+
+ context = g_simple_async_result_get_op_res_gpointer (simple);
+ g_return_val_if_fail (context != NULL, NULL);
+
+ return g_object_ref (context->cal);
+}
diff --git a/calendar/common/authentication.h b/calendar/common/authentication.h
index d48ca3edc2..11b2dc1dfc 100644
--- a/calendar/common/authentication.h
+++ b/calendar/common/authentication.h
@@ -21,9 +21,10 @@
*
*/
-#ifndef _AUTHENTICATION_H_
-#define _AUTHENTICATION_H_
+#ifndef AUTHENTICATION_H
+#define AUTHENTICATION_H
+#include <gtk/gtk.h>
#include <libedataserver/e-source.h>
#include <libecal/e-cal.h>
@@ -31,4 +32,15 @@ ECal *e_auth_new_cal_from_default (ECalSourceType type);
ECal *e_auth_new_cal_from_source (ESource *source, ECalSourceType type);
void e_auth_cal_forget_password (ECal *ecal);
-#endif
+void e_load_cal_source_async (ESource *source,
+ ECalSourceType source_type,
+ icaltimezone *default_zone,
+ GtkWindow *parent,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ECal * e_load_cal_source_finish (ESource *source,
+ GAsyncResult *result,
+ GError **error);
+
+#endif /* AUTHENTICATION_H */
diff --git a/modules/addressbook/e-book-shell-backend.c b/modules/addressbook/e-book-shell-backend.c
index 5036796c93..aecc93efb7 100644
--- a/modules/addressbook/e-book-shell-backend.c
+++ b/modules/addressbook/e-book-shell-backend.c
@@ -228,15 +228,13 @@ action_contact_new_cb (GtkAction *action,
/* This callback is used for both contacts and contact lists. */
- /* Dig out the EBookShellBackend's source list. */
shell = e_shell_window_get_shell (shell_window);
shell_backend = e_shell_get_backend_by_name (shell, "addressbook");
+
g_object_get (shell_backend, "source-list", &source_list, NULL);
g_return_if_fail (E_IS_SOURCE_LIST (source_list));
client = e_shell_get_gconf_client (shell);
- action_name = gtk_action_get_name (action);
-
key = "/apps/evolution/addressbook/display/primary_addressbook";
uid = gconf_client_get_string (client, key, NULL);
@@ -250,13 +248,14 @@ action_contact_new_cb (GtkAction *action,
g_return_if_fail (E_IS_SOURCE (source));
+ /* Use a callback function appropriate for the action. */
+ action_name = gtk_action_get_name (action);
if (strcmp (action_name, "contact-new") == 0)
e_load_book_source_async (
source, GTK_WINDOW (shell_window),
NULL, (GAsyncReadyCallback)
book_shell_backend_new_contact_cb,
g_object_ref (shell));
-
if (strcmp (action_name, "contact-new-list") == 0)
e_load_book_source_async (
source, GTK_WINDOW (shell_window),
diff --git a/modules/calendar/e-cal-shell-backend.c b/modules/calendar/e-cal-shell-backend.c
index 8861a82cf3..e72626304e 100644
--- a/modules/calendar/e-cal-shell-backend.c
+++ b/modules/calendar/e-cal-shell-backend.c
@@ -221,20 +221,19 @@ cal_shell_backend_ensure_sources (EShellBackend *shell_backend)
}
static void
-cal_shell_backend_new_event (ECal *cal,
- const GError *error,
+cal_shell_backend_new_event (ESource *source,
+ GAsyncResult *result,
EShell *shell,
CompEditorFlags flags,
gboolean all_day)
{
+ ECal *cal;
ECalComponent *comp;
CompEditor *editor;
/* XXX Handle errors better. */
- if (error)
- return;
-
- flags |= COMP_EDITOR_NEW_ITEM;
+ cal = e_load_cal_source_finish (source, result, NULL);
+ g_return_if_fail (E_IS_CAL (cal));
editor = event_editor_new (cal, shell, flags);
comp = cal_comp_event_new_with_current_time (cal, all_day);
@@ -244,68 +243,77 @@ cal_shell_backend_new_event (ECal *cal,
gtk_window_present (GTK_WINDOW (editor));
g_object_unref (comp);
+ g_object_unref (cal);
}
static void
-cal_shell_backend_event_new_cb (ECal *cal,
- const GError *error,
+cal_shell_backend_event_new_cb (ESource *source,
+ GAsyncResult *result,
EShell *shell)
{
- CompEditorFlags flags;
+ CompEditorFlags flags = 0;
+ gboolean all_day = FALSE;
- flags = COMP_EDITOR_USER_ORG;
- cal_shell_backend_new_event (cal, error, shell, flags, FALSE);
+ flags |= COMP_EDITOR_NEW_ITEM;
+ flags |= COMP_EDITOR_USER_ORG;
- g_object_unref (cal);
+ cal_shell_backend_new_event (source, result, shell, flags, all_day);
+
+ g_object_unref (shell);
}
static void
-cal_shell_backend_event_all_day_new_cb (ECal *cal,
- const GError *error,
+cal_shell_backend_event_all_day_new_cb (ESource *source,
+ GAsyncResult *result,
EShell *shell)
{
- CompEditorFlags flags;
+ CompEditorFlags flags = 0;
+ gboolean all_day = TRUE;
- flags = COMP_EDITOR_USER_ORG;
- cal_shell_backend_new_event (cal, error, shell, flags, TRUE);
+ flags |= COMP_EDITOR_NEW_ITEM;
+ flags |= COMP_EDITOR_USER_ORG;
- g_object_unref (cal);
+ cal_shell_backend_new_event (source, result, shell, flags, all_day);
+
+ g_object_unref (shell);
}
static void
-cal_shell_backend_event_meeting_new_cb (ECal *cal,
- const GError *error,
+cal_shell_backend_event_meeting_new_cb (ESource *source,
+ GAsyncResult *result,
EShell *shell)
{
- CompEditorFlags flags;
+ CompEditorFlags flags = 0;
+ gboolean all_day = FALSE;
- flags = COMP_EDITOR_USER_ORG | COMP_EDITOR_MEETING;
- cal_shell_backend_new_event (cal, error, shell, flags, FALSE);
+ flags |= COMP_EDITOR_NEW_ITEM;
+ flags |= COMP_EDITOR_USER_ORG;
+ flags |= COMP_EDITOR_MEETING;
- g_object_unref (cal);
+ cal_shell_backend_new_event (source, result, shell, flags, all_day);
+
+ g_object_unref (shell);
}
static void
action_event_new_cb (GtkAction *action,
EShellWindow *shell_window)
{
- ECal *cal = NULL;
- ECalSourceType source_type;
- ESourceList *source_list;
- EShellSettings *shell_settings;
- EShellView *shell_view;
EShell *shell;
- const gchar *view_name;
+ EShellView *shell_view;
+ EShellBackend *shell_backend;
+ EShellSettings *shell_settings;
+ ESource *source = NULL;
+ ESourceList *source_list;
+ ECalSourceType source_type;
const gchar *action_name;
gchar *uid;
/* With a 'calendar' active shell view pass the new appointment
* request to it, thus the event will inherit selected time from
* the view. */
- view_name = e_shell_window_get_active_view (shell_window);
- shell_view = e_shell_window_get_shell_view (shell_window, view_name);
-
- if (shell_view && g_ascii_strcasecmp (view_name, "calendar") == 0) {
+ shell_view = e_shell_window_peek_shell_view (shell_window, "calendar");
+ if (shell_view != NULL) {
EShellContent *shell_content;
GnomeCalendar *gcal;
GnomeCalendarViewType view_type;
@@ -338,48 +346,50 @@ action_event_new_cb (GtkAction *action,
shell = e_shell_window_get_shell (shell_window);
shell_settings = e_shell_get_shell_settings (shell);
+ shell_backend = e_shell_get_backend_by_name (shell, "calendar");
- if (!e_cal_get_sources (&source_list, source_type, NULL)) {
- g_warning ("Could not get calendar sources from GConf!");
- return;
- }
+ g_object_get (shell_backend, "source-list", &source_list, NULL);
+ g_return_if_fail (E_IS_SOURCE_LIST (source_list));
uid = e_shell_settings_get_string (
shell_settings, "cal-primary-calendar");
if (uid != NULL) {
- ESource *source;
-
source = e_source_list_peek_source_by_uid (source_list, uid);
- if (source != NULL)
- cal = e_auth_new_cal_from_source (source, source_type);
g_free (uid);
}
- if (cal == NULL)
- cal = e_auth_new_cal_from_default (source_type);
+ if (source == NULL)
+ source = e_source_list_peek_default_source (source_list);
- g_return_if_fail (cal != NULL);
+ g_return_if_fail (E_IS_SOURCE (source));
- /* Connect the appropriate signal handler. */
+ /* Use a callback function appropriate for the action.
+ * FIXME Need to obtain a better default time zone. */
action_name = gtk_action_get_name (action);
if (strcmp (action_name, "event-all-day-new") == 0)
- g_signal_connect (
- cal, "cal-opened-ex",
- G_CALLBACK (cal_shell_backend_event_all_day_new_cb),
- shell);
+ e_load_cal_source_async (
+ source, source_type, NULL,
+ GTK_WINDOW (shell_window),
+ NULL, (GAsyncReadyCallback)
+ cal_shell_backend_event_all_day_new_cb,
+ g_object_ref (shell));
else if (strcmp (action_name, "event-meeting-new") == 0)
- g_signal_connect (
- cal, "cal-opened-ex",
- G_CALLBACK (cal_shell_backend_event_meeting_new_cb),
- shell);
+ e_load_cal_source_async (
+ source, source_type, NULL,
+ GTK_WINDOW (shell_window),
+ NULL, (GAsyncReadyCallback)
+ cal_shell_backend_event_meeting_new_cb,
+ g_object_ref (shell));
else
- g_signal_connect (
- cal, "cal-opened-ex",
- G_CALLBACK (cal_shell_backend_event_new_cb),
- shell);
+ e_load_cal_source_async (
+ source, source_type, NULL,
+ GTK_WINDOW (shell_window),
+ NULL, (GAsyncReadyCallback)
+ cal_shell_backend_event_new_cb,
+ g_object_ref (shell));
- e_cal_open_async (cal, FALSE);
+ g_object_unref (source_list);
}
static void
diff --git a/modules/calendar/e-cal-shell-sidebar.c b/modules/calendar/e-cal-shell-sidebar.c
index 1cd4ba9619..a819d88473 100644
--- a/modules/calendar/e-cal-shell-sidebar.c
+++ b/modules/calendar/e-cal-shell-sidebar.c
@@ -59,6 +59,8 @@ struct _ECalShellSidebarPrivate {
* sometime later we update our default-client property
* which is bound by an EBinding to ECalModel. */
ECal *default_client;
+
+ GCancellable *loading_default_client;
};
enum {
@@ -241,104 +243,106 @@ cal_shell_sidebar_client_opened_cb (ECalShellSidebar *cal_shell_sidebar,
}
static void
-cal_shell_sidebar_default_opened_cb (ECalShellSidebar *cal_shell_sidebar,
- const GError *error,
- ECal *client)
+cal_shell_sidebar_default_loaded_cb (ESource *source,
+ GAsyncResult *result,
+ EShellSidebar *shell_sidebar)
{
+ ECalShellSidebarPrivate *priv;
+ EShellWindow *shell_window;
EShellView *shell_view;
- EShellSidebar *shell_sidebar;
+ ECal *client;
+ GError *error = NULL;
+
+ priv = E_CAL_SHELL_SIDEBAR_GET_PRIVATE (shell_sidebar);
- shell_sidebar = E_SHELL_SIDEBAR (cal_shell_sidebar);
shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
+ shell_window = e_shell_view_get_shell_window (shell_view);
- if (g_error_matches (error, E_CALENDAR_ERROR,
- E_CALENDAR_STATUS_AUTHENTICATION_FAILED) ||
- g_error_matches (error, E_CALENDAR_ERROR,
- E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED))
- e_auth_cal_forget_password (client);
+ client = e_load_cal_source_finish (source, result, &error);
- /* Handle errors. */
- switch (error ? error->code : E_CALENDAR_STATUS_OK) {
- case E_CALENDAR_STATUS_OK:
- break;
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ g_error_free (error);
+ goto exit;
- case E_CALENDAR_STATUS_AUTHENTICATION_FAILED:
- e_cal_open_async (client, FALSE);
- return;
+ } else if (error != NULL) {
+ e_alert_run_dialog_for_args (
+ GTK_WINDOW (shell_window),
+ "calendar:failed-open-calendar",
+ error->message, NULL);
+ g_error_free (error);
+ goto exit;
+ }
- case E_CALENDAR_STATUS_BUSY:
- return;
+ g_return_if_fail (E_IS_CAL (client));
- default:
- e_alert_run_dialog_for_args (
- GTK_WINDOW (e_shell_view_get_shell_window (shell_view)),
- "calendar:failed-open-calendar",
- error->message, NULL);
+ if (priv->default_client != NULL)
+ g_object_unref (priv->default_client);
- e_cal_shell_sidebar_remove_source (
- cal_shell_sidebar,
- e_cal_get_source (client));
- return;
- }
+ priv->default_client = client;
- g_assert (error == NULL);
+ g_object_notify (G_OBJECT (shell_sidebar), "default-client");
- g_signal_handlers_disconnect_matched (
- client, G_SIGNAL_MATCH_FUNC, 0, 0, NULL,
- cal_shell_sidebar_default_opened_cb, NULL);
-
- g_object_notify (G_OBJECT (cal_shell_sidebar), "default-client");
+exit:
+ g_object_unref (shell_sidebar);
}
static void
cal_shell_sidebar_set_default (ECalShellSidebar *cal_shell_sidebar,
ESource *source)
{
+ ECalShellSidebarPrivate *priv;
EShellView *shell_view;
+ EShellWindow *shell_window;
EShellContent *shell_content;
EShellSidebar *shell_sidebar;
ECalShellContent *cal_shell_content;
ECalSourceType source_type;
- GHashTable *client_table;
ECalModel *model;
ECal *client;
icaltimezone *timezone;
const gchar *uid;
+ priv = cal_shell_sidebar->priv;
source_type = E_CAL_SOURCE_TYPE_EVENT;
- client_table = cal_shell_sidebar->priv->client_table;
-
- uid = e_source_peek_uid (source);
- client = g_hash_table_lookup (client_table, uid);
-
- if (cal_shell_sidebar->priv->default_client != NULL)
- g_object_unref (cal_shell_sidebar->priv->default_client);
-
- if (client != NULL)
- g_object_ref (client);
- else
- client = e_auth_new_cal_from_source (source, source_type);
-
- cal_shell_sidebar->priv->default_client = client;
- g_return_if_fail (client != NULL);
-
- g_signal_connect_swapped (
- client, "cal-opened-ex",
- G_CALLBACK (cal_shell_sidebar_default_opened_cb),
- cal_shell_sidebar);
/* FIXME Sidebar should not be accessing the EShellContent.
* This probably needs to be moved to ECalShellView. */
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);
+ shell_window = e_shell_view_get_shell_window (shell_view);
cal_shell_content = E_CAL_SHELL_CONTENT (shell_content);
model = e_cal_shell_content_get_model (cal_shell_content);
timezone = e_cal_model_get_timezone (model);
- e_cal_set_default_timezone (client, timezone, NULL);
- e_cal_open_async (client, FALSE);
+ /* Cancel any unfinished previous request. */
+ if (priv->loading_default_client != NULL) {
+ g_cancellable_cancel (priv->loading_default_client);
+ g_object_unref (priv->loading_default_client);
+ priv->loading_default_client = NULL;
+ }
+
+ uid = e_source_peek_uid (source);
+ client = g_hash_table_lookup (priv->client_table, uid);
+
+ /* If we already have an open connection for
+ * this UID, we can finish immediately. */
+ if (client != NULL) {
+ if (priv->default_client != NULL)
+ g_object_unref (priv->default_client);
+ priv->default_client = g_object_ref (client);
+ g_object_notify (G_OBJECT (shell_sidebar), "default-client");
+ return;
+ }
+
+ priv->loading_default_client = g_cancellable_new ();
+
+ e_load_cal_source_async (
+ source, source_type, timezone,
+ GTK_WINDOW (shell_window), priv->loading_default_client,
+ (GAsyncReadyCallback) cal_shell_sidebar_default_loaded_cb,
+ g_object_ref (shell_sidebar));
}
static void
@@ -572,6 +576,12 @@ cal_shell_sidebar_dispose (GObject *object)
priv->default_client = NULL;
}
+ if (priv->loading_default_client != NULL) {
+ g_cancellable_cancel (priv->loading_default_client);
+ g_object_unref (priv->loading_default_client);
+ priv->loading_default_client = NULL;
+ }
+
g_hash_table_remove_all (priv->client_table);
/* Chain up to parent's dispose() method. */
diff --git a/modules/calendar/e-memo-shell-backend.c b/modules/calendar/e-memo-shell-backend.c
index 8f5bf40825..d54c32f98e 100644
--- a/modules/calendar/e-memo-shell-backend.c
+++ b/modules/calendar/e-memo-shell-backend.c
@@ -153,19 +153,18 @@ memo_shell_backend_ensure_sources (EShellBackend *shell_backend)
}
static void
-memo_shell_backend_memo_new_cb (ECal *cal,
- const GError *error,
- EShell *shell)
+memo_shell_backend_new_memo (ESource *source,
+ GAsyncResult *result,
+ EShell *shell,
+ CompEditorFlags flags)
{
+ ECal *cal;
ECalComponent *comp;
CompEditor *editor;
- CompEditorFlags flags = 0;
/* XXX Handle errors better. */
- if (error)
- return;
-
- flags |= COMP_EDITOR_NEW_ITEM;
+ cal = e_load_cal_source_finish (source, result, NULL);
+ g_return_if_fail (E_IS_CAL (cal));
comp = cal_comp_memo_new_with_defaults (cal);
cal_comp_update_time_by_active_window (comp, shell);
@@ -179,42 +178,45 @@ memo_shell_backend_memo_new_cb (ECal *cal,
}
static void
-memo_shell_backend_memo_shared_new_cb (ECal *cal,
- const GError *error,
- EShell *shell)
+memo_shell_backend_memo_new_cb (ESource *source,
+ GAsyncResult *result,
+ EShell *shell)
{
- ECalComponent *comp;
- CompEditor *editor;
CompEditorFlags flags = 0;
- /* XXX Handle errors better. */
- if (error)
- return;
+ flags |= COMP_EDITOR_NEW_ITEM;
+
+ memo_shell_backend_new_memo (source, result, shell, flags);
+
+ g_object_unref (shell);
+}
+
+static void
+memo_shell_backend_memo_shared_new_cb (ESource *source,
+ GAsyncResult *result,
+ EShell *shell)
+{
+ CompEditorFlags flags = 0;
flags |= COMP_EDITOR_NEW_ITEM;
flags |= COMP_EDITOR_IS_SHARED;
flags |= COMP_EDITOR_USER_ORG;
- comp = cal_comp_memo_new_with_defaults (cal);
- cal_comp_update_time_by_active_window (comp, shell);
- editor = memo_editor_new (cal, shell, flags);
- comp_editor_edit_comp (editor, comp);
-
- gtk_window_present (GTK_WINDOW (editor));
+ memo_shell_backend_new_memo (source, result, shell, flags);
- g_object_unref (comp);
- g_object_unref (cal);
+ g_object_unref (shell);
}
static void
action_memo_new_cb (GtkAction *action,
EShellWindow *shell_window)
{
- ECal *cal = NULL;
- ECalSourceType source_type;
- ESourceList *source_list;
- EShellSettings *shell_settings;
EShell *shell;
+ EShellBackend *shell_backend;
+ EShellSettings *shell_settings;
+ ESource *source = NULL;
+ ESourceList *source_list;
+ ECalSourceType source_type;
const gchar *action_name;
gchar *uid;
@@ -224,43 +226,43 @@ action_memo_new_cb (GtkAction *action,
shell = e_shell_window_get_shell (shell_window);
shell_settings = e_shell_get_shell_settings (shell);
+ shell_backend = e_shell_get_backend_by_name (shell, "memos");
- if (!e_cal_get_sources (&source_list, source_type, NULL)) {
- g_warning ("Could not get memo sources from GConf!");
- return;
- }
+ g_object_get (shell_backend, "source-list", &source_list, NULL);
+ g_return_if_fail (E_IS_SOURCE_LIST (source_list));
uid = e_shell_settings_get_string (
shell_settings, "cal-primary-memo-list");
if (uid != NULL) {
- ESource *source;
-
source = e_source_list_peek_source_by_uid (source_list, uid);
- if (source != NULL)
- cal = e_auth_new_cal_from_source (source, source_type);
g_free (uid);
}
- if (cal == NULL)
- cal = e_auth_new_cal_from_default (source_type);
+ if (source == NULL)
+ source = e_source_list_peek_default_source (source_list);
- g_return_if_fail (cal != NULL);
+ g_return_if_fail (E_IS_SOURCE (source));
- /* Connect the appropriate signal handler. */
+ /* Use a callback function appropriate for the action.
+ * FIXME Need to obtain a better default time zone. */
action_name = gtk_action_get_name (action);
- if (strcmp (action_name, "memo-shared-new") == 0)
- g_signal_connect (
- cal, "cal-opened-ex",
- G_CALLBACK (memo_shell_backend_memo_shared_new_cb),
- shell);
+ if (g_strcmp0 (action_name, "memo-shared-new") == 0)
+ e_load_cal_source_async (
+ source, source_type, NULL,
+ GTK_WINDOW (shell_window),
+ NULL, (GAsyncReadyCallback)
+ memo_shell_backend_memo_shared_new_cb,
+ g_object_ref (shell));
else
- g_signal_connect (
- cal, "cal-opened-ex",
- G_CALLBACK (memo_shell_backend_memo_new_cb),
- shell);
+ e_load_cal_source_async (
+ source, source_type, NULL,
+ GTK_WINDOW (shell_window),
+ NULL, (GAsyncReadyCallback)
+ memo_shell_backend_memo_new_cb,
+ g_object_ref (shell));
- e_cal_open_async (cal, FALSE);
+ g_object_unref (source_list);
}
static void
diff --git a/modules/calendar/e-memo-shell-sidebar.c b/modules/calendar/e-memo-shell-sidebar.c
index 7b4b8f71b6..f463394fbd 100644
--- a/modules/calendar/e-memo-shell-sidebar.c
+++ b/modules/calendar/e-memo-shell-sidebar.c
@@ -54,6 +54,8 @@ struct _EMemoShellSidebarPrivate {
* sometime later we update our default-client property
* which is bound by an EBinding to ECalModel. */
ECal *default_client;
+
+ GCancellable *loading_default_client;
};
enum {
@@ -235,104 +237,106 @@ memo_shell_sidebar_client_opened_cb (EMemoShellSidebar *memo_shell_sidebar,
}
static void
-memo_shell_sidebar_default_opened_cb (EMemoShellSidebar *memo_shell_sidebar,
- const GError *error,
- ECal *client)
+memo_shell_sidebar_default_loaded_cb (ESource *source,
+ GAsyncResult *result,
+ EShellSidebar *shell_sidebar)
{
+ EMemoShellSidebarPrivate *priv;
+ EShellWindow *shell_window;
EShellView *shell_view;
- EShellSidebar *shell_sidebar;
+ ECal *client;
+ GError *error = NULL;
+
+ priv = E_MEMO_SHELL_SIDEBAR_GET_PRIVATE (shell_sidebar);
- shell_sidebar = E_SHELL_SIDEBAR (memo_shell_sidebar);
shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
+ shell_window = e_shell_view_get_shell_window (shell_view);
- if (g_error_matches (error, E_CALENDAR_ERROR,
- E_CALENDAR_STATUS_AUTHENTICATION_FAILED) ||
- g_error_matches (error, E_CALENDAR_ERROR,
- E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED))
- e_auth_cal_forget_password (client);
+ client = e_load_cal_source_finish (source, result, &error);
- /* Handle errors. */
- switch (error ? error->code : E_CALENDAR_STATUS_OK) {
- case E_CALENDAR_STATUS_OK:
- break;
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ g_error_free (error);
+ goto exit;
- case E_CALENDAR_STATUS_AUTHENTICATION_FAILED:
- e_cal_open_async (client, FALSE);
- return;
+ } else if (error != NULL) {
+ e_alert_run_dialog_for_args (
+ GTK_WINDOW (shell_window),
+ "calendar:failed-open-memos",
+ error->message, NULL);
+ g_error_free (error);
+ goto exit;
+ }
- case E_CALENDAR_STATUS_BUSY:
- return;
+ g_return_if_fail (E_IS_CAL (client));
- default:
- e_alert_run_dialog_for_args (
- GTK_WINDOW (e_shell_view_get_shell_window (shell_view)),
- "calendar:failed-open-memos",
- error->message, NULL);
+ if (priv->default_client != NULL)
+ g_object_unref (priv->default_client);
- e_memo_shell_sidebar_remove_source (
- memo_shell_sidebar,
- e_cal_get_source (client));
- return;
- }
+ priv->default_client = client;
- g_assert (error == NULL);
+ g_object_notify (G_OBJECT (shell_sidebar), "default-client");
- g_signal_handlers_disconnect_matched (
- client, G_SIGNAL_MATCH_FUNC, 0, 0, NULL,
- memo_shell_sidebar_default_opened_cb, NULL);
-
- g_object_notify (G_OBJECT (memo_shell_sidebar), "default-client");
+exit:
+ g_object_unref (shell_sidebar);
}
static void
memo_shell_sidebar_set_default (EMemoShellSidebar *memo_shell_sidebar,
ESource *source)
{
+ EMemoShellSidebarPrivate *priv;
EShellView *shell_view;
+ EShellWindow *shell_window;
EShellContent *shell_content;
EShellSidebar *shell_sidebar;
EMemoShellContent *memo_shell_content;
ECalSourceType source_type;
- GHashTable *client_table;
ECalModel *model;
ECal *client;
icaltimezone *timezone;
const gchar *uid;
+ priv = memo_shell_sidebar->priv;
source_type = E_CAL_SOURCE_TYPE_JOURNAL;
- client_table = memo_shell_sidebar->priv->client_table;
-
- uid = e_source_peek_uid (source);
- client = g_hash_table_lookup (client_table, uid);
-
- if (memo_shell_sidebar->priv->default_client != NULL)
- g_object_unref (memo_shell_sidebar->priv->default_client);
-
- if (client != NULL)
- g_object_ref (client);
- else
- client = e_auth_new_cal_from_source (source, source_type);
-
- memo_shell_sidebar->priv->default_client = client;
- g_return_if_fail (client != NULL);
-
- g_signal_connect_swapped (
- client, "cal-opened-ex",
- G_CALLBACK (memo_shell_sidebar_default_opened_cb),
- memo_shell_sidebar);
/* FIXME Sidebar should not be accessing the EShellContent.
* This probably needs to be moved to EMemoShellView. */
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);
+ shell_window = e_shell_view_get_shell_window (shell_view);
memo_shell_content = E_MEMO_SHELL_CONTENT (shell_content);
model = e_memo_shell_content_get_memo_model (memo_shell_content);
timezone = e_cal_model_get_timezone (model);
- e_cal_set_default_timezone (client, timezone, NULL);
- e_cal_open_async (client, FALSE);
+ /* Cancel any unfinished previous request. */
+ if (priv->loading_default_client != NULL) {
+ g_cancellable_cancel (priv->loading_default_client);
+ g_object_unref (priv->loading_default_client);
+ priv->loading_default_client = NULL;
+ }
+
+ uid = e_source_peek_uid (source);
+ client = g_hash_table_lookup (priv->client_table, uid);
+
+ /* If we already have an open connection for
+ * this UID, we can finish immediately. */
+ if (client != NULL) {
+ if (priv->default_client != NULL)
+ g_object_unref (priv->default_client);
+ priv->default_client = g_object_ref (client);
+ g_object_notify (G_OBJECT (shell_sidebar), "default-client");
+ return;
+ }
+
+ priv->loading_default_client = g_cancellable_new ();
+
+ e_load_cal_source_async (
+ source, source_type, timezone,
+ GTK_WINDOW (shell_window), priv->loading_default_client,
+ (GAsyncReadyCallback) memo_shell_sidebar_default_loaded_cb,
+ g_object_ref (shell_sidebar));
}
static void
@@ -538,6 +542,12 @@ memo_shell_sidebar_dispose (GObject *object)
priv->default_client = NULL;
}
+ if (priv->loading_default_client != NULL) {
+ g_cancellable_cancel (priv->loading_default_client);
+ g_object_unref (priv->loading_default_client);
+ priv->loading_default_client = NULL;
+ }
+
g_hash_table_remove_all (priv->client_table);
/* Chain up to parent's dispose() method. */
diff --git a/modules/calendar/e-task-shell-backend.c b/modules/calendar/e-task-shell-backend.c
index cdd4dcc608..be085afa8d 100644
--- a/modules/calendar/e-task-shell-backend.c
+++ b/modules/calendar/e-task-shell-backend.c
@@ -153,19 +153,18 @@ task_shell_backend_ensure_sources (EShellBackend *shell_backend)
}
static void
-task_shell_backend_task_new_cb (ECal *cal,
- const GError *error,
- EShell *shell)
+task_shell_backend_new_task (ESource *source,
+ GAsyncResult *result,
+ EShell *shell,
+ CompEditorFlags flags)
{
+ ECal *cal;
ECalComponent *comp;
CompEditor *editor;
- CompEditorFlags flags = 0;
/* XXX Handle errors better. */
- if (error)
- return;
-
- flags |= COMP_EDITOR_NEW_ITEM;
+ cal = e_load_cal_source_finish (source, result, NULL);
+ g_return_if_fail (E_IS_CAL (cal));
editor = task_editor_new (cal, shell, flags);
comp = cal_comp_task_new_with_defaults (cal);
@@ -178,41 +177,45 @@ task_shell_backend_task_new_cb (ECal *cal,
}
static void
-task_shell_backend_task_assigned_new_cb (ECal *cal,
- const GError *error,
- EShell *shell)
+task_shell_backend_task_new_cb (ESource *source,
+ GAsyncResult *result,
+ EShell *shell)
{
- ECalComponent *comp;
- CompEditor *editor;
CompEditorFlags flags = 0;
- /* XXX Handle errors better. */
- if (error)
- return;
+ flags |= COMP_EDITOR_NEW_ITEM;
+
+ task_shell_backend_new_task (source, result, shell, flags);
+
+ g_object_unref (shell);
+}
+
+static void
+task_shell_backend_task_assigned_new_cb (ESource *source,
+ GAsyncResult *result,
+ EShell *shell)
+{
+ CompEditorFlags flags = 0;
flags |= COMP_EDITOR_NEW_ITEM;
flags |= COMP_EDITOR_IS_ASSIGNED;
flags |= COMP_EDITOR_USER_ORG;
- editor = task_editor_new (cal, shell, flags);
- comp = cal_comp_task_new_with_defaults (cal);
- comp_editor_edit_comp (editor, comp);
+ task_shell_backend_new_task (source, result, shell, flags);
- gtk_window_present (GTK_WINDOW (editor));
-
- g_object_unref (comp);
- g_object_unref (cal);
+ g_object_unref (shell);
}
static void
action_task_new_cb (GtkAction *action,
EShellWindow *shell_window)
{
- ECal *cal = NULL;
- ECalSourceType source_type;
- ESourceList *source_list;
- EShellSettings *shell_settings;
EShell *shell;
+ EShellBackend *shell_backend;
+ EShellSettings *shell_settings;
+ ESource *source = NULL;
+ ESourceList *source_list;
+ ECalSourceType source_type;
const gchar *action_name;
gchar *uid;
@@ -222,43 +225,43 @@ action_task_new_cb (GtkAction *action,
shell = e_shell_window_get_shell (shell_window);
shell_settings = e_shell_get_shell_settings (shell);
+ shell_backend = e_shell_get_backend_by_name (shell, "tasks");
- if (!e_cal_get_sources (&source_list, source_type, NULL)) {
- g_warning ("Could not get task sources from GConf!");
- return;
- }
+ g_object_get (shell_backend, "source-list", &source_list, NULL);
+ g_return_if_fail (E_IS_SOURCE_LIST (source_list));
uid = e_shell_settings_get_string (
shell_settings, "cal-primary-task-list");
if (uid != NULL) {
- ESource *source;
-
source = e_source_list_peek_source_by_uid (source_list, uid);
- if (source != NULL)
- cal = e_auth_new_cal_from_source (source, source_type);
g_free (uid);
}
- if (cal == NULL)
- cal = e_auth_new_cal_from_default (source_type);
+ if (source == NULL)
+ source = e_source_list_peek_default_source (source_list);
- g_return_if_fail (cal != NULL);
+ g_return_if_fail (E_IS_SOURCE (source));
- /* Connect the appropriate signal handler. */
+ /* Use a callback function appropriate for the action.
+ * FIXME Need to obtain a better default time zone. */
action_name = gtk_action_get_name (action);
if (strcmp (action_name, "task-assigned-new") == 0)
- g_signal_connect (
- cal, "cal-opened-ex",
- G_CALLBACK (task_shell_backend_task_assigned_new_cb),
- shell);
+ e_load_cal_source_async (
+ source, source_type, NULL,
+ GTK_WINDOW (shell_window),
+ NULL, (GAsyncReadyCallback)
+ task_shell_backend_task_assigned_new_cb,
+ g_object_ref (shell));
else
- g_signal_connect (
- cal, "cal-opened-ex",
- G_CALLBACK (task_shell_backend_task_new_cb),
- shell);
+ e_load_cal_source_async (
+ source, source_type, NULL,
+ GTK_WINDOW (shell_window),
+ NULL, (GAsyncReadyCallback)
+ task_shell_backend_task_new_cb,
+ g_object_ref (shell));
- e_cal_open_async (cal, FALSE);
+ g_object_unref (source_list);
}
static void
diff --git a/modules/calendar/e-task-shell-sidebar.c b/modules/calendar/e-task-shell-sidebar.c
index 8613b4eb0f..b50e463e8a 100644
--- a/modules/calendar/e-task-shell-sidebar.c
+++ b/modules/calendar/e-task-shell-sidebar.c
@@ -54,6 +54,8 @@ struct _ETaskShellSidebarPrivate {
* sometime later we update our default-client property
* which is bound by an EBinding to ECalModel. */
ECal *default_client;
+
+ GCancellable *loading_default_client;
};
enum {
@@ -235,104 +237,106 @@ task_shell_sidebar_client_opened_cb (ETaskShellSidebar *task_shell_sidebar,
}
static void
-task_shell_sidebar_default_opened_cb (ETaskShellSidebar *task_shell_sidebar,
- const GError *error,
- ECal *client)
+task_shell_sidebar_default_loaded_cb (ESource *source,
+ GAsyncResult *result,
+ EShellSidebar *shell_sidebar)
{
+ ETaskShellSidebarPrivate *priv;
+ EShellWindow *shell_window;
EShellView *shell_view;
- EShellSidebar *shell_sidebar;
+ ECal *client;
+ GError *error = NULL;
+
+ priv = E_TASK_SHELL_SIDEBAR_GET_PRIVATE (shell_sidebar);
- shell_sidebar = E_SHELL_SIDEBAR (task_shell_sidebar);
shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
+ shell_window = e_shell_view_get_shell_window (shell_view);
- if (g_error_matches (error, E_CALENDAR_ERROR,
- E_CALENDAR_STATUS_AUTHENTICATION_FAILED) ||
- g_error_matches (error, E_CALENDAR_ERROR,
- E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED))
- e_auth_cal_forget_password (client);
+ client = e_load_cal_source_finish (source, result, &error);
- /* Handle errors. */
- switch (error ? error->code : E_CALENDAR_STATUS_OK) {
- case E_CALENDAR_STATUS_OK:
- break;
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ g_error_free (error);
+ goto exit;
- case E_CALENDAR_STATUS_AUTHENTICATION_FAILED:
- e_cal_open_async (client, FALSE);
- return;
+ } else if (error != NULL) {
+ e_alert_run_dialog_for_args (
+ GTK_WINDOW (shell_window),
+ "calendar:failed-open-tasks",
+ error->message, NULL);
+ g_error_free (error);
+ goto exit;
+ }
- case E_CALENDAR_STATUS_BUSY:
- return;
+ g_return_if_fail (E_IS_CAL (client));
- default:
- e_alert_run_dialog_for_args (
- GTK_WINDOW (e_shell_view_get_shell_window (shell_view)),
- "calendar:failed-open-tasks",
- error->message, NULL);
+ if (priv->default_client != NULL)
+ g_object_unref (priv->default_client);
- e_task_shell_sidebar_remove_source (
- task_shell_sidebar,
- e_cal_get_source (client));
- return;
- }
+ priv->default_client = client;
- g_assert (error == NULL);
+ g_object_notify (G_OBJECT (shell_sidebar), "default-client");
- g_signal_handlers_disconnect_matched (
- client, G_SIGNAL_MATCH_FUNC, 0, 0, NULL,
- task_shell_sidebar_default_opened_cb, NULL);
-
- g_object_notify (G_OBJECT (task_shell_sidebar), "default-client");
+exit:
+ g_object_unref (shell_sidebar);
}
static void
task_shell_sidebar_set_default (ETaskShellSidebar *task_shell_sidebar,
ESource *source)
{
+ ETaskShellSidebarPrivate *priv;
EShellView *shell_view;
+ EShellWindow *shell_window;
EShellContent *shell_content;
EShellSidebar *shell_sidebar;
ETaskShellContent *task_shell_content;
ECalSourceType source_type;
- GHashTable *client_table;
ECalModel *model;
ECal *client;
icaltimezone *timezone;
const gchar *uid;
+ priv = task_shell_sidebar->priv;
source_type = E_CAL_SOURCE_TYPE_TODO;
- client_table = task_shell_sidebar->priv->client_table;
-
- uid = e_source_peek_uid (source);
- client = g_hash_table_lookup (client_table, uid);
-
- if (task_shell_sidebar->priv->default_client != NULL)
- g_object_unref (task_shell_sidebar->priv->default_client);
-
- if (client != NULL)
- g_object_ref (client);
- else
- client = e_auth_new_cal_from_source (source, source_type);
-
- task_shell_sidebar->priv->default_client = client;
- g_return_if_fail (client != NULL);
-
- g_signal_connect_swapped (
- client, "cal-opened-ex",
- G_CALLBACK (task_shell_sidebar_default_opened_cb),
- task_shell_sidebar);
/* FIXME Sidebar should not be accessing the EShellContent.
* This probably needs to be moved to ETaskShellView. */
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);
+ shell_window = e_shell_view_get_shell_window (shell_view);
task_shell_content = E_TASK_SHELL_CONTENT (shell_content);
model = e_task_shell_content_get_task_model (task_shell_content);
timezone = e_cal_model_get_timezone (model);
- e_cal_set_default_timezone (client, timezone, NULL);
- e_cal_open_async (client, FALSE);
+ /* Cancel any unfinished previous request. */
+ if (priv->loading_default_client != NULL) {
+ g_cancellable_cancel (priv->loading_default_client);
+ g_object_unref (priv->loading_default_client);
+ priv->loading_default_client = NULL;
+ }
+
+ uid = e_source_peek_uid (source);
+ client = g_hash_table_lookup (priv->client_table, uid);
+
+ /* If we already have an open connection for
+ * this UID, we can finish immediately. */
+ if (client != NULL) {
+ if (priv->default_client != NULL)
+ g_object_unref (priv->default_client);
+ priv->default_client = g_object_ref (client);
+ g_object_notify (G_OBJECT (shell_sidebar), "default-client");
+ return;
+ }
+
+ priv->loading_default_client = g_cancellable_new ();
+
+ e_load_cal_source_async (
+ source, source_type, timezone,
+ GTK_WINDOW (shell_window), priv->loading_default_client,
+ (GAsyncReadyCallback) task_shell_sidebar_default_loaded_cb,
+ g_object_ref (shell_sidebar));
}
static void
@@ -538,6 +542,12 @@ task_shell_sidebar_dispose (GObject *object)
priv->default_client = NULL;
}
+ if (priv->loading_default_client != NULL) {
+ g_cancellable_cancel (priv->loading_default_client);
+ g_object_unref (priv->loading_default_client);
+ priv->loading_default_client = NULL;
+ }
+
g_hash_table_remove_all (priv->client_table);
/* Chain up to parent's dispose() method. */