[evolution-kolab/ek-wip-porting] ECalBackendKolab: implemented online/offline state switching
- From: Christian Hilberg <chilberg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-kolab/ek-wip-porting] ECalBackendKolab: implemented online/offline state switching
- Date: Fri, 16 Mar 2012 19:14:33 +0000 (UTC)
commit d82fc1d1983aa3e24b09777a4597fc9309f64349
Author: Christian Hilberg <hilberg kernelconcepts de>
Date: Fri Mar 16 20:13:40 2012 +0100
ECalBackendKolab: implemented online/offline state switching
* implemented state switching (offline, online)
* state is set initially according to the
E-D-S status
* state can subsequently be toggled by the
online state button in Evolution
src/calendar/e-cal-backend-kolab.c | 247 +++++++++++++++++++++++++++++++++---
1 files changed, 226 insertions(+), 21 deletions(-)
---
diff --git a/src/calendar/e-cal-backend-kolab.c b/src/calendar/e-cal-backend-kolab.c
index 5b8f7f6..7f27f1f 100644
--- a/src/calendar/e-cal-backend-kolab.c
+++ b/src/calendar/e-cal-backend-kolab.c
@@ -71,20 +71,125 @@ typedef struct {
/* Private part of the ECalBackendKolab structure */
typedef struct _ECalBackendKolabPrivate ECalBackendKolabPrivate;
struct _ECalBackendKolabPrivate {
- GHashTable *koma_table;
- CalMode cal_mode;
- KolabMailAccess *cal_koma;
- ECalBackendCache *cal_cache;
- gchar *user_email;
- ECalComponent *default_zone;
- ECalSourceType source_type;
- gboolean already_opened;
- gchar * cal_uri;
+ GHashTable *koma_table;
+ CalMode cal_mode;
+ KolabMailAccess *cal_koma;
+ ECalBackendCache *cal_cache;
+ gchar *user_email;
+ ECalComponent *default_zone;
+ ECalSourceType source_type;
+ gboolean already_opened;
+ gchar *cal_uri;
+ GError *mode_switch_err;
};
/*----------------------------------------------------------------------------*/
/* internal statics */
+static void
+cal_backend_kolab_signal_online_cb (GObject *object)
+{
+ EBackend *backend = NULL;
+ ECalBackendKolab *self = NULL;
+ ECalBackendKolabPrivate *priv = NULL;
+ gboolean online = FALSE;
+ gboolean ok = FALSE;
+
+ g_return_if_fail (E_IS_CAL_BACKEND_KOLAB (object));
+
+ backend = E_BACKEND (object);
+ self = E_CAL_BACKEND_KOLAB (object);
+ priv = E_CAL_BACKEND_KOLAB_PRIVATE (self);
+
+ online = e_backend_get_online (backend);
+
+ g_debug ("%s()[%u] backend mode: %i",
+ __func__, __LINE__, online);
+
+ /* FIXME
+ *
+ * This callback is for online state notifications only.
+ * Doing I/O, which can fail, is the wrong thing to do
+ * here since we do not have a proper way to let the user
+ * cancel the I/O. Getting KolabMailAccess online can hang.
+ * Thus, cancellation would be needed.
+ *
+ * e_backend_get_online (backend) could be called in the
+ * "other" operations and the KolabMailAccess state changed
+ * if needed, Problem: KolabMailAccess online/offline state
+ * change involves synchronization with the server, which
+ * may take long time and is not expected by the user if
+ * they e.g. just add a contact or event.
+ *
+ * For now, we'll leave the cancellation issue aside
+ * (we could not have cancelled in 2.30 either), but
+ * at least bind a GError to our backend object, if we
+ * have one. We can then propagate this error in the
+ * first "other" operation the user triggers.
+ *
+ * It has been supposed by upstream to use a global static
+ * GCancellable for the cancellation issue, but it will
+ * not help us here since the Evolution online/offline
+ * toggle button does not seem to expect heavy I/O to
+ * be triggered. Our local GCancellabe would need transfer
+ * to Evo and be registered there so the online/offline
+ * switching in evo-kolab could be cancelled from the
+ * frontend. Moreover, there is no telling how long a
+ * synchronization run with the Kolab server may take,
+ * so we also cannot set a sensible timeout here.
+ *
+ */
+
+ if (priv->mode_switch_err != NULL) {
+ g_warning ("%s()[%u]: Online mode switching error pending (%s)",
+ __func__, __LINE__, priv->mode_switch_err->message);
+ g_error_free (priv->mode_switch_err);
+ priv->mode_switch_err = NULL;
+ }
+ ok = kolab_util_backend_deploy_mode_by_backend (priv->cal_koma,
+ online,
+ NULL, /* GCancellable (see above )*/
+ &(priv->mode_switch_err));
+ if (priv->mode_switch_err) {
+ g_warning ("%s()[%u]: Online mode switching error pending (%s)",
+ __func__, __LINE__, priv->mode_switch_err->message);
+ }
+
+ if (ok) {
+ e_cal_backend_notify_online (E_CAL_BACKEND (self), online);
+ }
+}
+
+static gboolean
+cal_backend_kolab_notify_open (ECalBackendKolab *self,
+ GError **err)
+{
+ ECalBackend *cbackend = NULL;
+ ECalBackendKolabPrivate *priv = NULL;
+ KolabMailAccessOpmodeID tmp_mode = KOLAB_MAIL_ACCESS_OPMODE_INVAL;
+ GError *tmp_err = NULL;
+
+ g_assert (E_IS_CAL_BACKEND_KOLAB (self));
+ g_return_val_if_fail (err == NULL || *err == NULL, FALSE);
+
+ priv = E_CAL_BACKEND_KOLAB_PRIVATE (self);
+ cbackend = E_CAL_BACKEND (self);
+
+ tmp_mode = kolab_mail_access_get_opmode (priv->cal_koma, &tmp_err);
+ if (tmp_err != NULL) {
+ g_propagate_error (err, tmp_err);
+ return FALSE;
+ }
+ e_cal_backend_notify_online (cbackend,
+ tmp_mode = KOLAB_MAIL_ACCESS_OPMODE_ONLINE ? TRUE : FALSE);
+ e_cal_backend_notify_opened (cbackend, NULL);
+
+ return TRUE;
+}
+
+/*----------------------------------------------------------------------------*/
+/* class functions */
+
/**
* e_cal_backend_kolab_open:
* @backend: An ECalBackendSync object.
@@ -110,7 +215,6 @@ e_cal_backend_kolab_open (ECalBackendSync *backend,
KolabSettingsHandler *ksettings = NULL;
KolabMailAccess *tmp_koma = NULL;
KolabSyncStrategyID sync_value = KOLAB_SYNC_STRATEGY_DEFAULT;
- KolabMailAccessOpmodeID tmp_mode = KOLAB_MAIL_ACCESS_OPMODE_INVAL;
icalcomponent_kind icalkind = ICAL_VEVENT_COMPONENT;
gchar *sourcename = NULL;
gchar *servername = NULL;
@@ -118,8 +222,9 @@ e_cal_backend_kolab_open (ECalBackendSync *backend,
gchar *user_at_server = NULL;
gchar *tmp_key = NULL;
const gchar *prop_str = NULL;
- GError *tmp_err = NULL;
+ gboolean online = FALSE;
gboolean ok = FALSE;
+ GError *tmp_err = NULL;
g_return_if_fail (error == NULL || *error == NULL);
e_return_data_cal_error_if_fail (E_IS_CAL_BACKEND_KOLAB (backend), InvalidArg);
@@ -209,6 +314,8 @@ e_cal_backend_kolab_open (ECalBackendSync *backend,
sync_value = kolab_util_misc_sync_value_from_property (prop_str);
sourcename = kolab_util_backend_get_relative_path_from_uri (priv->cal_uri);
+ /* Check whether we have a KolabMailAccess (KoMA) instance already */
+
user_at_server = g_strdup_printf ("%s %s",
username, servername);
@@ -217,7 +324,9 @@ e_cal_backend_kolab_open (ECalBackendSync *backend,
(gpointer *) &tmp_key,
(gpointer *) &tmp_koma);
if (ok) {
- /* There is already a KoMA instance for $servername. Use it and return */
+ /* There already is a KoMA instance for user_at_server.
+ * Use it and return
+ */
g_object_ref (tmp_koma);
priv->cal_koma = tmp_koma;
g_free (servername);
@@ -231,7 +340,29 @@ e_cal_backend_kolab_open (ECalBackendSync *backend,
NULL,
sourcename,
&sync_value);
- goto notifications;
+ g_object_unref (ksettings);
+ /* We should have received authentication data (password)
+ * at this point, since it was requested and stored when
+ * the KolabMailAccess object was initially created.
+ * We can just skip the AuthenticationRequested part here
+ * and move along...
+ */
+ online = e_backend_get_online (E_BACKEND (backend));
+ ok = kolab_util_backend_deploy_mode_by_backend (priv->cal_koma,
+ online,
+ cancellable,
+ &tmp_err);
+ if (! ok) {
+ kolab_util_calendar_err_to_edb_err (error, tmp_err, __func__, __LINE__);
+ g_error_free (tmp_err);
+ return;
+ }
+ ok = cal_backend_kolab_notify_open (self, &tmp_err);
+ if (! ok) {
+ kolab_util_calendar_err_to_edb_err (error, tmp_err, __func__, __LINE__);
+ g_error_free (tmp_err);
+ }
+ return;
}
/* Nope, we need to setup a new KoMA instance and a settings handler */
@@ -307,12 +438,15 @@ e_cal_backend_kolab_open (ECalBackendSync *backend,
*/
priv->user_email = g_strdup (user_at_server);
- notifications:
+ /* If we are here (just created a fresh KolabMailAccess),
+ * we did not yet receive authentication data. Though we
+ * do not need it if we want to stay in offline mode, once
+ * we're asked to go online, we'll need the credentials
+ * (password in our case) anyway, so we can just request
+ * it once the book gets opened.
+ */
+ e_cal_backend_notify_auth_required (E_CAL_BACKEND (self), TRUE, NULL);
priv->already_opened = TRUE;
-#if 0 /* FIXME */
- e_cal_backend_kolab_set_mode (E_CAL_BACKEND (backend),
- priv->cal_mode);
-#endif
}
static void
@@ -449,6 +583,7 @@ e_cal_backend_kolab_get_backend_property (ECalBackendSync *backend,
return processed;
}
+#if 0 /* probably not needed */
static gboolean
e_cal_backend_kolab_set_backend_property (ECalBackendSync *backend,
EDataCal *cal,
@@ -474,6 +609,7 @@ e_cal_backend_kolab_set_backend_property (ECalBackendSync *backend,
return FALSE;
}
+#endif
/**
* e_cal_backend_kolab_get_object:
@@ -1463,6 +1599,13 @@ e_cal_backend_kolab_authenticate_user (ECalBackendSync *backend,
{
ECalBackendKolab *self = NULL;
ECalBackendKolabPrivate *priv = NULL;
+ KolabSettingsHandler *ksettings = NULL;
+ const gchar *cred_user = NULL;
+ const gchar *cred_pwd = NULL;
+ const gchar *kset_user = NULL;
+ gboolean online = FALSE;
+ gboolean ok = FALSE;
+ GError *tmp_err = NULL;
g_return_if_fail (error == NULL || *error == NULL);
e_return_data_cal_error_if_fail (E_IS_CAL_BACKEND_KOLAB (backend), InvalidArg);
@@ -1472,7 +1615,56 @@ e_cal_backend_kolab_authenticate_user (ECalBackendSync *backend,
self = E_CAL_BACKEND_KOLAB (backend);
priv = E_CAL_BACKEND_KOLAB_PRIVATE (self);
- g_error ("%s: FIXME implement me", __func__);
+ g_debug ("%s()[%u] called.", __func__, __LINE__);
+
+ ksettings = kolab_mail_access_get_settings_handler (priv->cal_koma);
+
+ /* warn about a possible inconsistency in user names */
+ kset_user = kolab_settings_handler_get_char_field (ksettings,
+ KOLAB_SETTINGS_HANDLER_CHAR_FIELD_KOLAB_USER_NAME,
+ &tmp_err);
+ if (tmp_err != NULL) {
+ g_object_unref (ksettings);
+ kolab_util_calendar_err_to_edb_err (error, tmp_err, __func__, __LINE__);
+ g_error_free (tmp_err);
+ return;
+ }
+ cred_user = e_credentials_peek (credentials,
+ E_CREDENTIALS_KEY_USERNAME);
+ if (g_strcmp0 (kset_user, cred_user) != 0) {
+ g_warning ("%s()[%u] username from argument and username in "
+ "KolabSettingsHandler do not match: %s vs. %s",
+ __func__, __LINE__, cred_user, kset_user);
+ }
+
+ cred_pwd = e_credentials_peek (credentials,
+ E_CREDENTIALS_KEY_PASSWORD);
+
+ kolab_util_backend_prepare_settings (ksettings,
+ NULL,
+ NULL,
+ NULL,
+ cred_pwd,
+ NULL,
+ NULL);
+ g_object_unref (ksettings);
+
+ online = e_backend_get_online (E_BACKEND (backend));
+ ok = kolab_util_backend_deploy_mode_by_backend (priv->cal_koma,
+ online,
+ cancellable,
+ &tmp_err);
+ if (! ok) {
+ kolab_util_calendar_err_to_edb_err (error, tmp_err, __func__, __LINE__);
+ g_error_free (tmp_err);
+ return;
+ }
+
+ ok = cal_backend_kolab_notify_open (self, &tmp_err);
+ if (! ok) {
+ kolab_util_calendar_err_to_edb_err (error, tmp_err, __func__, __LINE__);
+ g_error_free (tmp_err);
+ }
}
/**
@@ -1495,7 +1687,8 @@ e_cal_backend_kolab_start_view (ECalBackend *backend,
self = E_CAL_BACKEND_KOLAB (backend);
priv = E_CAL_BACKEND_KOLAB_PRIVATE (self);
- g_error ("%s: FIXME implement me", __func__);
+ g_warning ("%s: FIXME implement me", __func__);
+ e_data_cal_view_notify_complete (view, NULL);
#if 0 /* FIXME old */
query = e_data_cal_view_get_text (cal_view);
@@ -1567,7 +1760,8 @@ e_cal_backend_kolab_stop_view (ECalBackend *backend,
self = E_CAL_BACKEND_KOLAB (backend);
priv = E_CAL_BACKEND_KOLAB_PRIVATE (self);
- g_error ("%s: FIXME implement me", __func__);
+ g_warning ("%s: FIXME implement me", __func__);
+ e_data_cal_view_notify_complete (view, NULL);
}
static void
@@ -1610,6 +1804,9 @@ e_cal_backend_kolab_init (ECalBackendKolab *backend)
priv->source_type = 0;
priv->already_opened = FALSE;
priv->cal_uri = NULL;
+ priv->mode_switch_err = NULL;
+
+ g_signal_connect (E_BACKEND (backend), "notify::online", G_CALLBACK (cal_backend_kolab_signal_online_cb), NULL);
} /* e_cal_backend_kolab_init () */
static void
@@ -1652,6 +1849,12 @@ e_cal_backend_kolab_finalize (GObject *object)
if (priv->cal_uri != NULL)
g_free (priv->cal_uri);
+ if (priv->mode_switch_err != NULL) {
+ g_warning ("%s()[%u]: %s",
+ __func__, __LINE__, priv->mode_switch_err->message);
+ g_error_free (priv->mode_switch_err);
+ }
+
G_OBJECT_CLASS (e_cal_backend_kolab_parent_class)->finalize (object);
} /* e_book_backend_kolab_finalize () */
@@ -1683,7 +1886,9 @@ e_cal_backend_kolab_class_init (ECalBackendKolabClass *klass)
sync_class->remove_sync = e_cal_backend_kolab_remove;
sync_class->refresh_sync = e_cal_backend_kolab_refresh;
sync_class->get_backend_property_sync = e_cal_backend_kolab_get_backend_property;
+#if 0 /* probably not needed */
sync_class->set_backend_property_sync = e_cal_backend_kolab_set_backend_property;
+#endif
sync_class->get_object_sync = e_cal_backend_kolab_get_object;
sync_class->get_object_list_sync = e_cal_backend_kolab_get_object_list;
sync_class->get_free_busy_sync = e_cal_backend_kolab_get_free_busy;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]