[evolution-data-server/eclient] Changing logic of backend opening phase in favor of e_client_utils_open_new()
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server/eclient] Changing logic of backend opening phase in favor of e_client_utils_open_new()
- Date: Fri, 20 May 2011 12:43:42 +0000 (UTC)
commit bfee384189eaffd4f3af32bbefb3ae8b45893fac
Author: Milan Crha <mcrha redhat com>
Date: Fri May 20 14:42:11 2011 +0200
Changing logic of backend opening phase in favor of e_client_utils_open_new()
addressbook/backends/file/e-book-backend-file.c | 6 +-
.../backends/google/e-book-backend-google.c | 43 ++-
.../backends/groupwise/e-book-backend-groupwise.c | 35 +-
addressbook/backends/ldap/e-book-backend-ldap.c | 86 ++---
addressbook/backends/vcf/e-book-backend-vcf.c | 6 +-
.../backends/webdav/e-book-backend-webdav.c | 24 +-
addressbook/libebook/e-book-client-view.c | 6 +-
addressbook/libebook/e-book-client.c | 20 +-
addressbook/libebook/e-book-view.c | 4 +-
addressbook/libebook/e-book.c | 1 +
addressbook/libedata-book/e-book-backend-sync.c | 11 +-
addressbook/libedata-book/e-book-backend-sync.h | 6 +-
addressbook/libedata-book/e-book-backend.c | 271 ++++++++++---
addressbook/libedata-book/e-book-backend.h | 17 +-
addressbook/libedata-book/e-data-book-factory.c | 12 +-
addressbook/libedata-book/e-data-book-types.h | 1 +
addressbook/libedata-book/e-data-book-view.c | 2 +-
addressbook/libedata-book/e-data-book.c | 85 +++--
addressbook/libedata-book/e-data-book.h | 8 +-
addressbook/libegdbus/e-gdbus-book-view.c | 44 --
addressbook/libegdbus/e-gdbus-book-view.h | 3 -
addressbook/libegdbus/e-gdbus-book.c | 62 ++--
addressbook/libegdbus/e-gdbus-book.h | 17 +-
calendar/backends/caldav/e-cal-backend-caldav.c | 12 +-
.../backends/contacts/e-cal-backend-contacts.c | 3 +-
calendar/backends/file/e-cal-backend-file.c | 10 +-
.../backends/groupwise/e-cal-backend-groupwise.c | 27 +-
calendar/backends/http/e-cal-backend-http.c | 29 +-
calendar/backends/weather/e-cal-backend-weather.c | 6 +-
calendar/libecal/e-cal-client-view.c | 6 +-
calendar/libecal/e-cal-client.c | 20 +-
calendar/libecal/e-cal-view.c | 4 +-
calendar/libecal/e-cal.c | 1 +
calendar/libedata-cal/e-cal-backend-sync.c | 12 +-
calendar/libedata-cal/e-cal-backend-sync.h | 6 +-
calendar/libedata-cal/e-cal-backend.c | 296 ++++++++++++---
calendar/libedata-cal/e-cal-backend.h | 17 +-
calendar/libedata-cal/e-data-cal-factory.c | 12 +-
calendar/libedata-cal/e-data-cal-types.h | 1 +
calendar/libedata-cal/e-data-cal-view.c | 2 +-
calendar/libedata-cal/e-data-cal.c | 85 +++--
calendar/libedata-cal/e-data-cal.h | 2 +-
calendar/libegdbus/e-gdbus-cal-view.c | 44 --
calendar/libegdbus/e-gdbus-cal-view.h | 3 -
calendar/libegdbus/e-gdbus-cal.c | 62 ++--
calendar/libegdbus/e-gdbus-cal.h | 17 +-
libedataserver/e-client-private.h | 1 +
libedataserver/e-client.c | 73 +++-
libedataserver/e-client.h | 4 +-
libedataserver/e-credentials.h | 1 +
libedataserver/e-gdbus-templates.c | 47 +++
libedataserver/e-gdbus-templates.h | 15 +-
libedataserverui/e-client-utils.c | 365 +++++++++++++++++-
libedataserverui/e-client-utils.h | 8 +-
tests/libebook/client/client-test-utils.c | 3 +-
tests/libebook/client/test-client-examine.c | 10 +-
tests/libecal/client/test-client-examine.c | 4 +-
tests/libedataserverui/Makefile.am | 5 +
tests/libedataserverui/test-client-examine-auth.c | 418 ++++++++++++++++++++
59 files changed, 1796 insertions(+), 605 deletions(-)
---
diff --git a/addressbook/backends/file/e-book-backend-file.c b/addressbook/backends/file/e-book-backend-file.c
index ca7cccf..65ca8c3 100644
--- a/addressbook/backends/file/e-book-backend-file.c
+++ b/addressbook/backends/file/e-book-backend-file.c
@@ -741,7 +741,6 @@ e_book_backend_file_extract_path_from_source (ESource *source)
static void
e_book_backend_file_authenticate_user (EBookBackendSync *backend,
- EDataBook *book,
GCancellable *cancellable,
ECredentials *credentials,
GError **perror)
@@ -1102,10 +1101,9 @@ e_book_backend_file_open (EBookBackendSync *backend,
}
}
- e_book_backend_set_is_loaded (E_BOOK_BACKEND (backend), TRUE);
- e_book_backend_set_is_readonly (E_BOOK_BACKEND (backend), readonly);
e_book_backend_notify_online (E_BOOK_BACKEND (backend), TRUE);
e_book_backend_notify_readonly (E_BOOK_BACKEND (backend), readonly);
+ e_book_backend_notify_opened (E_BOOK_BACKEND (backend), NULL /* Success */);
}
static gboolean
@@ -1212,7 +1210,7 @@ e_book_backend_file_get_backend_property (EBookBackendSync *backend, EDataBook *
static void
e_book_backend_file_set_online (EBookBackend *backend, gboolean is_online)
{
- if (e_book_backend_is_loaded (backend))
+ if (e_book_backend_is_opened (backend))
e_book_backend_notify_online (backend, TRUE);
}
diff --git a/addressbook/backends/google/e-book-backend-google.c b/addressbook/backends/google/e-book-backend-google.c
index f922651..5216f3c 100644
--- a/addressbook/backends/google/e-book-backend-google.c
+++ b/addressbook/backends/google/e-book-backend-google.c
@@ -1207,7 +1207,7 @@ e_book_backend_google_start_book_view (EBookBackend *backend, EDataBookView *boo
if (cache_needs_update (backend, NULL)) {
if (!priv->service || !gdata_service_is_authenticated (priv->service)) {
/* We need authorization first */
- e_book_backend_notify_auth_required (backend, NULL);
+ e_book_backend_notify_auth_required (backend, TRUE, NULL);
} else {
/* Update in an idle function, so that this call doesn't block */
priv->idle_id = g_idle_add ((GSourceFunc) on_refresh_idle, backend);
@@ -1270,7 +1270,6 @@ proxy_settings_changed (EProxy *proxy, EBookBackend *backend)
typedef struct {
EBookBackend *backend;
- EDataBook *book;
guint32 opid;
} AuthenticateUserData;
@@ -1291,37 +1290,37 @@ authenticate_user_cb (GDataService *service, GAsyncResult *result, AuthenticateU
finish_operation (data->backend, data->opid);
e_book_backend_notify_readonly (data->backend, gdata_error ? TRUE : FALSE);
- e_data_book_respond_authenticate_user (data->book, data->opid, book_error);
+ e_book_backend_notify_opened (data->backend, book_error);
- g_object_unref (data->book);
g_object_unref (data->backend);
g_slice_free (AuthenticateUserData, data);
}
static void
-e_book_backend_google_authenticate_user (EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable, ECredentials *credentials)
+e_book_backend_google_authenticate_user (EBookBackend *backend, GCancellable *cancellable, ECredentials *credentials)
{
EBookBackendGooglePrivate *priv = E_BOOK_BACKEND_GOOGLE (backend)->priv;
AuthenticateUserData *data;
+ guint32 opid;
__debug__ (G_STRFUNC);
if (!priv->is_online) {
e_book_backend_notify_readonly (backend, TRUE);
e_book_backend_notify_online (backend, FALSE);
- e_data_book_respond_authenticate_user (book, opid, EDB_ERROR (SUCCESS));
+ e_book_backend_notify_opened (backend, EDB_ERROR (SUCCESS));
return;
}
if (priv->service && gdata_service_is_authenticated (priv->service)) {
g_warning ("Connection to Google already established.");
e_book_backend_notify_readonly (backend, FALSE);
- e_data_book_respond_authenticate_user (book, opid, NULL);
+ e_book_backend_notify_opened (backend, NULL);
return;
}
if (!credentials || !e_credentials_has_key (credentials, E_CREDENTIALS_KEY_USERNAME) || !e_credentials_has_key (credentials, E_CREDENTIALS_KEY_PASSWORD)) {
- e_data_book_respond_authenticate_user (book, opid, EDB_ERROR (AUTHENTICATION_FAILED));
+ e_book_backend_notify_opened (backend, EDB_ERROR (AUTHENTICATION_REQUIRED));
return;
}
@@ -1337,10 +1336,13 @@ e_book_backend_google_authenticate_user (EBookBackend *backend, EDataBook *book,
g_signal_connect (priv->proxy, "changed", G_CALLBACK (proxy_settings_changed), backend);
}
+ opid = -1;
+ while (g_hash_table_lookup (priv->cancellables, GUINT_TO_POINTER (opid)))
+ opid--;
+
/* Authenticate with the server asynchronously */
data = g_slice_new (AuthenticateUserData);
data->backend = g_object_ref (backend);
- data->book = g_object_ref (book);
data->opid = opid;
cancellable = start_operation (backend, opid, cancellable, _("Authenticating with the serverâ?¦"));
@@ -1367,7 +1369,7 @@ e_book_backend_google_open (EBookBackend *backend, EDataBook *book, guint opid,
__debug__ (G_STRFUNC);
if (priv->cancellables) {
- e_data_book_respond_open (book, opid, EDB_ERROR_EX (OTHER_ERROR, "Source already loaded!"));
+ e_book_backend_respond_opened (backend, book, opid, EDB_ERROR_EX (OTHER_ERROR, "Source already loaded!"));
return;
}
@@ -1405,15 +1407,15 @@ e_book_backend_google_open (EBookBackend *backend, EDataBook *book, guint opid,
}
/* Set up ready to be interacted with */
- e_book_backend_set_is_loaded (backend, TRUE);
- e_book_backend_set_is_readonly (backend, TRUE);
e_book_backend_notify_online (backend, priv->is_online);
e_book_backend_notify_readonly (backend, TRUE);
if (priv->is_online) {
/* We're going online, so we need to authenticate and create the service and proxy.
* This is done in e_book_backend_google_authenticate_user() when it gets the authentication data. */
- e_book_backend_notify_auth_required (backend, NULL);
+ e_book_backend_notify_auth_required (backend, TRUE, NULL);
+ } else {
+ e_book_backend_notify_opened (backend, NULL /* Success */);
}
e_data_book_respond_open (book, opid, NULL /* Success */);
@@ -1570,6 +1572,9 @@ google_cancel_all_operations (EBookBackend *backend)
__debug__ (G_STRFUNC);
+ if (!priv->cancellables)
+ return;
+
/* Cancel all active operations */
g_hash_table_iter_init (&iter, priv->cancellables);
while (g_hash_table_iter_next (&iter, &opid_ptr, (gpointer *) &cancellable)) {
@@ -1590,10 +1595,10 @@ e_book_backend_google_set_online (EBookBackend *backend, gboolean is_online)
e_book_backend_notify_online (backend, is_online);
- if (is_online) {
+ if (is_online && e_book_backend_is_opened (backend)) {
/* Going online, so we need to re-authenticate and re-create the service and proxy.
* This is done in e_book_backend_google_authenticate_user() when it gets the authentication data. */
- e_book_backend_notify_auth_required (backend, NULL);
+ e_book_backend_notify_auth_required (backend, TRUE, NULL);
} else {
/* Going offline, so cancel all running operations */
google_cancel_all_operations (backend);
@@ -1653,9 +1658,11 @@ e_book_backend_google_finalize (GObject *object)
__debug__ (G_STRFUNC);
- g_hash_table_destroy (priv->groups_by_id);
- g_hash_table_destroy (priv->groups_by_name);
- g_hash_table_destroy (priv->cancellables);
+ if (priv->cancellables) {
+ g_hash_table_destroy (priv->groups_by_id);
+ g_hash_table_destroy (priv->groups_by_name);
+ g_hash_table_destroy (priv->cancellables);
+ }
G_OBJECT_CLASS (e_book_backend_google_parent_class)->finalize (object);
}
diff --git a/addressbook/backends/groupwise/e-book-backend-groupwise.c b/addressbook/backends/groupwise/e-book-backend-groupwise.c
index 3ab40fc..414f970 100644
--- a/addressbook/backends/groupwise/e-book-backend-groupwise.c
+++ b/addressbook/backends/groupwise/e-book-backend-groupwise.c
@@ -3130,8 +3130,6 @@ update_address_book_cache (gpointer data)
static void
e_book_backend_groupwise_authenticate_user (EBookBackend *backend,
- EDataBook *book,
- guint32 opid,
GCancellable *cancellable,
ECredentials *credentials)
{
@@ -3163,13 +3161,13 @@ e_book_backend_groupwise_authenticate_user (EBookBackend *backend,
e_book_backend_notify_readonly (backend, TRUE);
e_book_backend_notify_online (backend, FALSE);
- e_data_book_respond_authenticate_user (book, opid, EDB_ERROR (SUCCESS));
+ e_book_backend_notify_opened (backend, NULL /* Success */);
return;
}
if (priv->cnc) { /*we have already authenticated to server */
printf("already authenticated\n");
- e_data_book_respond_authenticate_user (book, opid, EDB_ERROR (SUCCESS));
+ e_book_backend_notify_opened (backend, NULL /* Success */);
return;
}
@@ -3182,9 +3180,9 @@ e_book_backend_groupwise_authenticate_user (EBookBackend *backend,
if (!E_IS_GW_CONNECTION (priv->cnc)) {
if (error.status == E_GW_CONNECTION_STATUS_INVALID_PASSWORD)
- e_data_book_respond_authenticate_user (book, opid, EDB_ERROR (AUTHENTICATION_FAILED));
+ e_book_backend_notify_opened (backend, EDB_ERROR (AUTHENTICATION_FAILED));
else
- e_data_book_respond_authenticate_user (book, opid, EDB_ERROR_FAILED_STATUS (OTHER_ERROR, error.status));
+ e_book_backend_notify_opened (backend, EDB_ERROR_FAILED_STATUS (OTHER_ERROR, error.status));
return;
}
@@ -3198,7 +3196,7 @@ e_book_backend_groupwise_authenticate_user (EBookBackend *backend,
status = e_gw_connection_create_book (priv->cnc, priv->book_name, &id);
is_writable = TRUE;
if (status != E_GW_CONNECTION_STATUS_OK ) {
- e_data_book_respond_authenticate_user (book, opid, EDB_ERROR_FAILED_STATUS (OTHER_ERROR, status));
+ e_book_backend_notify_opened (backend, EDB_ERROR_FAILED_STATUS (OTHER_ERROR, status));
return;
}
}
@@ -3206,18 +3204,17 @@ e_book_backend_groupwise_authenticate_user (EBookBackend *backend,
if (id != NULL) {
priv->container_id = g_strdup (id);
g_free (id);
- e_book_backend_set_is_readonly (backend, !is_writable);
e_book_backend_notify_readonly (backend, !is_writable);
e_book_backend_notify_online (backend, TRUE);
priv->is_readonly = !is_writable;
e_gw_connection_get_categories (priv->cnc, &priv->categories_by_id, &priv->categories_by_name);
- if (!e_gw_connection_get_version (priv->cnc))
- e_data_book_respond_authenticate_user (book, opid, EDB_ERROR (INVALID_SERVER_VERSION));
- else
- e_data_book_respond_authenticate_user (book, opid, EDB_ERROR (SUCCESS));
+ /* if (!e_gw_connection_get_version (priv->cnc))
+ / * error means failure, thus do not send this further * /
+ e_book_backend_notify_opened (backend, EDB_ERROR (INVALID_SERVER_VERSION));
+ else */
+ e_book_backend_notify_opened (backend, EDB_ERROR (SUCCESS));
} else {
- e_book_backend_set_is_loaded (backend, FALSE);
- e_data_book_respond_authenticate_user (book, opid, EDB_ERROR (NO_SUCH_BOOK));
+ e_book_backend_notify_opened (backend, EDB_ERROR (NO_SUCH_BOOK));
}
/* initialize summary file */
@@ -3228,7 +3225,7 @@ e_book_backend_groupwise_authenticate_user (EBookBackend *backend,
SUMMARY_FLUSH_TIMEOUT);
if (!ebgw->priv->file_db) {
- e_data_book_respond_authenticate_user (book, opid, EDB_ERROR (OTHER_ERROR));
+ e_book_backend_notify_opened (backend, EDB_ERROR (OTHER_ERROR));
return;
}
if (e_book_backend_db_cache_is_populated (ebgw->priv->file_db)) {
@@ -3496,8 +3493,6 @@ e_book_backend_groupwise_open (EBookBackend *backend,
priv->use_ssl = g_strdup (use_ssl);
priv->only_if_exists = only_if_exists;
- e_book_backend_set_is_loaded (E_BOOK_BACKEND (backend), TRUE);
- e_book_backend_set_is_readonly (E_BOOK_BACKEND (backend), TRUE);
e_book_backend_notify_readonly (backend, TRUE);
e_book_backend_notify_online (backend, priv->is_online);
@@ -3523,6 +3518,8 @@ e_book_backend_groupwise_open (EBookBackend *backend,
}*/
e_data_book_respond_open (book, opid, NULL /* Success */);
+ if (!priv->is_online)
+ e_book_backend_notify_opened (backend, NULL /* Success */);
}
static void
@@ -3611,7 +3608,7 @@ e_book_backend_groupwise_set_online (EBookBackend *backend, gboolean is_online)
printf ("\ne_book_backend_groupwise_set_mode...\n");
bg = E_BOOK_BACKEND_GROUPWISE (backend);
bg->priv->is_online = is_online;
- if (e_book_backend_is_loaded (backend)) {
+ if (e_book_backend_is_opened (backend)) {
if (!is_online) {
e_book_backend_notify_readonly (backend, TRUE);
e_book_backend_notify_online (backend, FALSE);
@@ -3622,7 +3619,7 @@ e_book_backend_groupwise_set_online (EBookBackend *backend, gboolean is_online)
} else {
e_book_backend_notify_readonly (backend, bg->priv->is_readonly);
e_book_backend_notify_online (backend, TRUE);
- e_book_backend_notify_auth_required (backend, NULL);
+ e_book_backend_notify_auth_required (backend, TRUE, NULL);
}
}
}
diff --git a/addressbook/backends/ldap/e-book-backend-ldap.c b/addressbook/backends/ldap/e-book-backend-ldap.c
index fe68f79..8d2e740 100644
--- a/addressbook/backends/ldap/e-book-backend-ldap.c
+++ b/addressbook/backends/ldap/e-book-backend-ldap.c
@@ -976,7 +976,6 @@ e_book_backend_ldap_connect (EBookBackendLDAP *bl)
if (ldap_error == LDAP_SUCCESS
|| ldap_error == LDAP_PARTIAL_RESULTS
|| LDAP_NAME_ERROR (ldap_error)) {
- e_book_backend_set_is_loaded (E_BOOK_BACKEND (bl), TRUE);
blpriv->connected = TRUE;
g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
@@ -996,7 +995,7 @@ e_book_backend_ldap_connect (EBookBackendLDAP *bl)
}
return EDB_ERROR (SUCCESS);
} else if (ldap_error == LDAP_UNWILLING_TO_PERFORM) {
- e_book_backend_notify_auth_required (E_BOOK_BACKEND (bl), NULL);
+ e_book_backend_notify_auth_required (E_BOOK_BACKEND (bl), TRUE, NULL);
g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
return EDB_ERROR (AUTHENTICATION_REQUIRED);
} else {
@@ -4729,8 +4728,6 @@ generate_cache (EBookBackendLDAP *book_backend_ldap)
static void
e_book_backend_ldap_authenticate_user (EBookBackend *backend,
- EDataBook *book,
- guint32 opid,
GCancellable *cancellable,
ECredentials *credentials)
{
@@ -4747,16 +4744,14 @@ e_book_backend_ldap_authenticate_user (EBookBackend *backend,
if (!bl->priv->is_online) {
e_book_backend_notify_readonly (backend, TRUE);
e_book_backend_notify_online (backend, FALSE);
- e_data_book_respond_authenticate_user (book,
- opid,
- EDB_ERROR (SUCCESS));
+ e_book_backend_notify_opened (backend, EDB_ERROR (SUCCESS));
g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
return;
}
if (bl->priv->connected) {
/* other client connected meanwhile, report success and return */
- e_data_book_respond_authenticate_user (book, opid, EDB_ERROR (SUCCESS));
+ e_book_backend_notify_opened (backend, EDB_ERROR (SUCCESS));
g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
return;
}
@@ -4786,9 +4781,7 @@ e_book_backend_ldap_authenticate_user (EBookBackend *backend,
if (!e) {
g_warning ("Failed to get the DN for %s", user);
ldap_msgfree (res);
- e_data_book_respond_authenticate_user (book,
- opid,
- EDB_ERROR (AUTHENTICATION_FAILED));
+ e_book_backend_notify_opened (backend, EDB_ERROR (AUTHENTICATION_FAILED));
return;
}
@@ -4800,11 +4793,8 @@ e_book_backend_ldap_authenticate_user (EBookBackend *backend,
ldap_memfree (entry_dn);
ldap_msgfree (res);
- }
- else {
- e_data_book_respond_authenticate_user (book,
- opid,
- EDB_ERROR (PERMISSION_DENIED));
+ } else {
+ e_book_backend_notify_opened (backend, EDB_ERROR (PERMISSION_DENIED));
return;
}
}
@@ -4829,7 +4819,7 @@ e_book_backend_ldap_authenticate_user (EBookBackend *backend,
error = e_book_backend_ldap_connect (bl);
if (error) {
- e_data_book_respond_authenticate_user (book, opid, error);
+ e_book_backend_notify_opened (backend, error);
return;
}
}
@@ -4851,9 +4841,7 @@ e_book_backend_ldap_authenticate_user (EBookBackend *backend,
}
- e_data_book_respond_authenticate_user (book,
- opid,
- ldap_error_to_response (ldap_error));
+ e_book_backend_notify_opened (backend, ldap_error_to_response (ldap_error));
}
#ifdef ENABLE_SASL_BINDS
else if (!g_ascii_strncasecmp (auth_method, SASL_PREFIX, strlen (SASL_PREFIX))) {
@@ -4866,7 +4854,7 @@ e_book_backend_ldap_authenticate_user (EBookBackend *backend,
error = e_book_backend_ldap_connect (bl);
if (error) {
- e_data_book_respond_authenticate_user (book, opid, error);
+ e_book_backend_notify_opened (backend, error);
return;
}
}
@@ -4880,24 +4868,17 @@ e_book_backend_ldap_authenticate_user (EBookBackend *backend,
g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
if (ldap_error == LDAP_NOT_SUPPORTED)
- e_data_book_respond_authenticate_user (book,
- opid,
- EDB_ERROR (UNSUPPORTED_AUTHENTICATION_METHOD));
+ e_book_backend_notify_opened (backend, EDB_ERROR (UNSUPPORTED_AUTHENTICATION_METHOD));
else
- e_data_book_respond_authenticate_user (book,
- opid,
- ldap_error_to_response (ldap_error));
+ e_book_backend_notify_opened (backend, ldap_error_to_response (ldap_error));
}
#endif
else {
- e_data_book_respond_authenticate_user (book,
- opid,
- EDB_ERROR (UNSUPPORTED_AUTHENTICATION_METHOD));
+ e_book_backend_notify_opened (backend, EDB_ERROR (UNSUPPORTED_AUTHENTICATION_METHOD));
return;
}
if (ldap_error == LDAP_SUCCESS) {
- e_book_backend_set_is_readonly (backend, FALSE);
e_book_backend_notify_readonly (backend, FALSE);
/* force a requery on the root dse since some ldap
@@ -4915,8 +4896,6 @@ e_book_backend_ldap_authenticate_user (EBookBackend *backend,
g_warning ("Failed to perform root dse query after authenticating, (ldap_error 0x%02x)", ldap_error);
}
- e_data_book_report_readonly (book, FALSE);
-
if (bl->priv->marked_for_offline && bl->priv->cache)
generate_cache (bl);
}
@@ -5018,7 +4997,7 @@ e_book_backend_ldap_open (EBookBackend *backend,
if (enable_debug)
printf ("%s ... failed to parse the ldap URI %s\n", G_STRFUNC, uri);
g_free (uri);
- e_data_book_respond_open (book, opid, EDB_ERROR_EX (OTHER_ERROR, "Failed to parse LDAP URI"));
+ e_book_backend_respond_opened (backend, book, opid, EDB_ERROR_EX (OTHER_ERROR, "Failed to parse LDAP URI"));
return;
}
@@ -5036,26 +5015,23 @@ e_book_backend_ldap_open (EBookBackend *backend,
if (!bl->priv->is_online) {
/* Offline */
- e_book_backend_set_is_loaded (backend, TRUE);
- e_book_backend_set_is_readonly (backend, TRUE);
e_book_backend_notify_readonly (backend, TRUE);
e_book_backend_notify_online (backend, FALSE);
if (!bl->priv->marked_for_offline) {
- e_data_book_respond_open (book, opid, EDB_ERROR (OFFLINE_UNAVAILABLE));
+ e_book_backend_respond_opened (backend, book, opid, EDB_ERROR (OFFLINE_UNAVAILABLE));
return;
}
#if 0
if (!e_book_backend_cache_is_populated (bl->priv->cache)) {
- e_data_book_respond_open (book, opid, EDB_ERROR (OFFLINE_UNAVAILABLE));
+ e_book_backend_respond_opened (backend, book, opid, EDB_ERROR (OFFLINE_UNAVAILABLE));
return;
}
#endif
- e_data_book_respond_open (book, opid, NULL /* Success */);
+ e_book_backend_respond_opened (backend, book, opid, NULL /* Success */);
return;
} else {
- e_book_backend_set_is_readonly (backend, FALSE);
e_book_backend_notify_readonly (backend, FALSE);
e_book_backend_notify_online (backend, TRUE);
}
@@ -5068,10 +5044,11 @@ e_book_backend_ldap_open (EBookBackend *backend,
if (enable_debug)
printf ("%s ... skipping anonymous bind, because auth required\n", G_STRFUNC);
- if (!e_book_backend_is_loaded (backend))
- e_book_backend_notify_auth_required (backend, NULL);
- e_book_backend_set_is_loaded (backend, TRUE);
- e_data_book_respond_open (book, opid, NULL /* Success */);
+ if (!e_book_backend_is_opened (backend))
+ e_book_backend_notify_auth_required (backend, TRUE, NULL);
+ else
+ e_book_backend_notify_opened (backend, NULL);
+ e_book_backend_respond_opened (backend, book, opid, NULL /* Success */);
return;
}
@@ -5080,12 +5057,12 @@ e_book_backend_ldap_open (EBookBackend *backend,
if (err) {
if (enable_debug)
printf ("%s ... failed to connect to server \n", G_STRFUNC);
- e_data_book_respond_open (book, opid, err);
+ e_book_backend_respond_opened (backend, book, opid, err);
return;
}
- if (auth_required && !e_book_backend_is_loaded (backend)) {
- e_book_backend_notify_auth_required (E_BOOK_BACKEND (bl), NULL);
+ if (auth_required && !e_book_backend_is_opened (backend)) {
+ e_book_backend_notify_auth_required (E_BOOK_BACKEND (bl), TRUE, NULL);
e_data_book_respond_open (book, opid, NULL /* Success */);
return;
}
@@ -5093,7 +5070,7 @@ e_book_backend_ldap_open (EBookBackend *backend,
if (bl->priv->marked_for_offline)
generate_cache (bl);
- e_data_book_respond_open (book, opid, NULL /* Success */);
+ e_book_backend_respond_opened (backend, book, opid, NULL /* Success */);
}
static void
@@ -5217,7 +5194,6 @@ e_book_backend_ldap_set_online (EBookBackend *backend, gboolean is_online)
if (!is_online) {
/* Go offline */
- e_book_backend_set_is_readonly (backend, TRUE);
e_book_backend_notify_readonly (backend, TRUE);
e_book_backend_notify_online (backend, FALSE);
@@ -5233,21 +5209,20 @@ e_book_backend_ldap_set_online (EBookBackend *backend, gboolean is_online)
bl->priv->connected = FALSE;
#if 0
- if (e_book_backend_is_loaded (backend))
+ if (e_book_backend_is_opened (backend))
start_views (backend);
#endif
} else {
/* Go online */
- e_book_backend_set_is_readonly (backend, FALSE);
e_book_backend_notify_readonly (backend, FALSE);
e_book_backend_notify_online (backend, TRUE);
- if (e_book_backend_is_loaded (backend)) {
+ if (e_book_backend_is_opened (backend)) {
GError *error;
error = e_book_backend_ldap_connect (bl);
- e_book_backend_notify_auth_required (backend, NULL);
+ e_book_backend_notify_auth_required (backend, TRUE, NULL);
if (error)
g_error_free (error);
@@ -5329,6 +5304,11 @@ e_book_backend_ldap_dispose (GObject *object)
bl->priv->summary = NULL;
}
+ if (bl->priv->cache) {
+ g_object_unref (bl->priv->cache);
+ bl->priv->cache = NULL;
+ }
+
g_free (bl->priv->ldap_host);
g_free (bl->priv->ldap_rootdn);
g_free (bl->priv->ldap_search_filter);
diff --git a/addressbook/backends/vcf/e-book-backend-vcf.c b/addressbook/backends/vcf/e-book-backend-vcf.c
index a06bf00..ea235db 100644
--- a/addressbook/backends/vcf/e-book-backend-vcf.c
+++ b/addressbook/backends/vcf/e-book-backend-vcf.c
@@ -541,7 +541,6 @@ e_book_backend_vcf_extract_path_from_uri (const gchar *uri)
static void
e_book_backend_vcf_authenticate_user (EBookBackendSync *backend,
- EDataBook *book,
GCancellable *cancellable,
ECredentials *credentials,
GError **perror)
@@ -628,10 +627,9 @@ e_book_backend_vcf_open (EBookBackendSync *backend,
load_file (bvcf, fd);
- e_book_backend_set_is_loaded (E_BOOK_BACKEND (backend), TRUE);
- e_book_backend_set_is_readonly (E_BOOK_BACKEND (backend), readonly);
e_book_backend_notify_readonly (E_BOOK_BACKEND (backend), readonly);
e_book_backend_notify_online (E_BOOK_BACKEND (backend), TRUE);
+ e_book_backend_notify_opened (E_BOOK_BACKEND (backend), NULL);
g_free (uri);
}
@@ -671,7 +669,7 @@ e_book_backend_vcf_get_backend_property (EBookBackendSync *backend, EDataBook *b
static void
e_book_backend_vcf_set_online (EBookBackend *backend, gboolean is_online)
{
- if (e_book_backend_is_loaded (backend))
+ if (e_book_backend_is_opened (backend))
e_book_backend_notify_online (backend, TRUE);
}
diff --git a/addressbook/backends/webdav/e-book-backend-webdav.c b/addressbook/backends/webdav/e-book-backend-webdav.c
index 7c04eb4..14086e3 100644
--- a/addressbook/backends/webdav/e-book-backend-webdav.c
+++ b/addressbook/backends/webdav/e-book-backend-webdav.c
@@ -1094,7 +1094,7 @@ e_book_backend_webdav_get_contact_list (EBookBackend *backend, EDataBook *book,
}
static void
-e_book_backend_webdav_authenticate_user (EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable, ECredentials *credentials)
+e_book_backend_webdav_authenticate_user (EBookBackend *backend, GCancellable *cancellable, ECredentials *credentials)
{
EBookBackendWebdav *webdav = E_BOOK_BACKEND_WEBDAV (backend);
EBookBackendWebdavPrivate *priv = webdav->priv;
@@ -1116,9 +1116,9 @@ e_book_backend_webdav_authenticate_user (EBookBackend *backend, EDataBook *book,
e_credentials_util_safe_free_string (priv->password);
priv->password = NULL;
- e_data_book_respond_authenticate_user (book, opid, EDB_ERROR (AUTHENTICATION_FAILED));
+ e_book_backend_notify_opened (backend, EDB_ERROR (AUTHENTICATION_FAILED));
} else {
- e_data_book_respond_authenticate_user (book, opid, EDB_ERROR (SUCCESS));
+ e_book_backend_notify_opened (backend, EDB_ERROR (SUCCESS));
}
}
@@ -1176,7 +1176,7 @@ e_book_backend_webdav_open (EBookBackend *backend, EDataBook *book, guint opid,
uri = e_source_get_uri (source);
if (uri == NULL) {
- e_data_book_respond_open (book, opid, EDB_ERROR_EX (OTHER_ERROR, "No uri given for addressbook"));
+ e_book_backend_respond_opened (backend, book, opid, EDB_ERROR_EX (OTHER_ERROR, "No uri given for addressbook"));
return;
}
@@ -1184,7 +1184,7 @@ e_book_backend_webdav_open (EBookBackend *backend, EDataBook *book, guint opid,
g_free (uri);
if (!suri) {
- e_data_book_respond_open (book, opid, EDB_ERROR_EX (OTHER_ERROR, "Invalid uri given for addressbook"));
+ e_book_backend_respond_opened (backend, book, opid, EDB_ERROR_EX (OTHER_ERROR, "Invalid uri given for addressbook"));
return;
}
@@ -1194,14 +1194,14 @@ e_book_backend_webdav_open (EBookBackend *backend, EDataBook *book, guint opid,
if (!priv->is_online && !priv->marked_for_offline ) {
soup_uri_free (suri);
- e_data_book_respond_open (book, opid, EDB_ERROR (OFFLINE_UNAVAILABLE));
+ e_book_backend_respond_opened (backend, book, opid, EDB_ERROR (OFFLINE_UNAVAILABLE));
return;
}
if (!suri->scheme || !g_str_equal (suri->scheme, "webdav")) {
/* the book is not for us */
soup_uri_free (suri);
- e_data_book_respond_open (book, opid, EDB_ERROR_EX (OTHER_ERROR, "Not a webdav uri"));
+ e_book_backend_respond_opened (backend, book, opid, EDB_ERROR_EX (OTHER_ERROR, "Not a webdav uri"));
return;
}
@@ -1242,7 +1242,7 @@ e_book_backend_webdav_open (EBookBackend *backend, EDataBook *book, guint opid,
priv->uri = soup_uri_to_string (suri, FALSE);
if (!priv->uri) {
soup_uri_free (suri);
- e_data_book_respond_open (book, opid, EDB_ERROR_EX (OTHER_ERROR, "Cannot transform SoupURI to string"));
+ e_book_backend_respond_opened (backend, book, opid, EDB_ERROR_EX (OTHER_ERROR, "Cannot transform SoupURI to string"));
return;
}
@@ -1261,10 +1261,8 @@ e_book_backend_webdav_open (EBookBackend *backend, EDataBook *book, guint opid,
proxy_settings_changed (priv->proxy, priv);
webdav_debug_setup (priv->session);
- e_book_backend_notify_auth_required (backend, NULL);
- e_book_backend_set_is_loaded (backend, TRUE);
+ e_book_backend_notify_auth_required (backend, TRUE, NULL);
e_book_backend_notify_online (backend, TRUE);
- e_book_backend_set_is_readonly (backend, FALSE);
e_book_backend_notify_readonly (backend, FALSE);
soup_uri_free (suri);
@@ -1286,15 +1284,13 @@ e_book_backend_webdav_set_online (EBookBackend *backend, gboolean is_online)
webdav->priv->is_online = is_online;
/* set_mode is called before the backend is loaded */
- if (!e_book_backend_is_loaded (backend))
+ if (!e_book_backend_is_opened (backend))
return;
if (!is_online) {
- e_book_backend_set_is_readonly (backend, TRUE);
e_book_backend_notify_readonly (backend, TRUE);
e_book_backend_notify_online (backend, FALSE);
} else {
- e_book_backend_set_is_readonly (backend, FALSE);
e_book_backend_notify_readonly (backend, FALSE);
e_book_backend_notify_online (backend, TRUE);
}
diff --git a/addressbook/libebook/e-book-client-view.c b/addressbook/libebook/e-book-client-view.c
index 86ce7d7..28ecd89 100644
--- a/addressbook/libebook/e-book-client-view.c
+++ b/addressbook/libebook/e-book-client-view.c
@@ -126,12 +126,12 @@ progress_cb (EGdbusBookView *object, guint percent, const gchar *message, EBookC
static void
complete_cb (EGdbusBookView *object, const gchar * const *in_error_strv, EBookClientView *view)
{
- GError *error;
+ GError *error = NULL;
if (!view->priv->running)
return;
- error = e_gdbus_book_view_decode_error (in_error_strv);
+ g_return_if_fail (e_gdbus_templates_decode_error (in_error_strv, &error));
g_signal_emit (view, signals[COMPLETE], 0, error);
@@ -256,7 +256,7 @@ e_book_client_view_stop (EBookClientView *view, GError **error)
*
* Client can instruct server to which fields it is interested in only, thus
* the server can return less data over the wire. The server can still return
- * complete objects, this is just a hint to it that the listef fields will
+ * complete objects, this is just a hint to it that the listed fields will
* be used only. The UID field is returned always. Initial views has no restriction,
* and using %NULL for @only_fields will unset any previous changes.
**/
diff --git a/addressbook/libebook/e-book-client.c b/addressbook/libebook/e-book-client.c
index 3fa86b8..c8fea3b 100644
--- a/addressbook/libebook/e-book-client.c
+++ b/addressbook/libebook/e-book-client.c
@@ -63,7 +63,7 @@ G_DEFINE_TYPE (EBookClient, e_book_client, E_TYPE_CLIENT)
* Use e_client_util_parse_comma_strings() to parse returned string value
* into a #GSList.
*
- * See also: @CLIENT_BACKEND_PROPERTY_LOADED,
+ * See also: @CLIENT_BACKEND_PROPERTY_OPENED, @CLIENT_BACKEND_PROPERTY_OPENING,
* @CLIENT_BACKEND_PROPERTY_ONLINE, @CLIENT_BACKEND_PROPERTY_READONLY
* @CLIENT_BACKEND_PROPERTY_CACHE_DIR, @CLIENT_BACKEND_PROPERTY_CAPABILITIES
**/
@@ -124,6 +124,7 @@ unwrap_dbus_error (GError *error, GError **client_error)
{ err ("OfflineUnavailable", E_BOOK_CLIENT_ERROR_OFFLINE_UNAVAILABLE) },
{ err ("NoSpace", E_BOOK_CLIENT_ERROR_NO_SPACE) }
}, cl_errors[] = {
+ { err ("Busy", E_CLIENT_ERROR_BUSY) },
{ err ("RepositoryOffline", E_CLIENT_ERROR_REPOSITORY_OFFLINE) },
{ err ("PermissionDenied", E_CLIENT_ERROR_PERMISSION_DENIED) },
{ err ("AuthenticationFailed", E_CLIENT_ERROR_AUTHENTICATION_FAILED) },
@@ -364,6 +365,22 @@ auth_required_cb (EGdbusBook *object, const gchar * const *credentials_strv, EBo
e_credentials_free (credentials);
}
+static void
+opened_cb (EGdbusBook *object, const gchar * const *error_strv, EBookClient *client)
+{
+ GError *error = NULL;
+
+ g_return_if_fail (client != NULL);
+ g_return_if_fail (E_IS_BOOK_CLIENT (client));
+ g_return_if_fail (error_strv != NULL);
+ g_return_if_fail (e_gdbus_templates_decode_error (error_strv, &error));
+
+ e_client_emit_opened (E_CLIENT (client), error);
+
+ if (error)
+ g_error_free (error);
+}
+
/**
* e_book_client_new:
* @source: An #ESource pointer
@@ -463,6 +480,7 @@ e_book_client_new (ESource *source, GError **error)
g_signal_connect (client->priv->gdbus_book, "readonly", G_CALLBACK (readonly_cb), client);
g_signal_connect (client->priv->gdbus_book, "online", G_CALLBACK (online_cb), client);
g_signal_connect (client->priv->gdbus_book, "auth-required", G_CALLBACK (auth_required_cb), client);
+ g_signal_connect (client->priv->gdbus_book, "opened", G_CALLBACK (opened_cb), client);
return client;
}
diff --git a/addressbook/libebook/e-book-view.c b/addressbook/libebook/e-book-view.c
index dd88218..877a069 100644
--- a/addressbook/libebook/e-book-view.c
+++ b/addressbook/libebook/e-book-view.c
@@ -124,13 +124,13 @@ progress_cb (EGdbusBookView *object, guint percent, const gchar *message, EBookV
static void
complete_cb (EGdbusBookView *object, const gchar * const *in_error_strv, EBookView *book_view)
{
- GError *error;
+ GError *error = NULL;
EBookViewStatus bv_status = E_BOOK_VIEW_ERROR_OTHER_ERROR;
if (!book_view->priv->running)
return;
- error = e_gdbus_book_view_decode_error (in_error_strv);
+ g_return_if_fail (e_gdbus_templates_decode_error (in_error_strv, &error));
switch (error ? error->code : E_DATA_BOOK_STATUS_SUCCESS) {
case E_DATA_BOOK_STATUS_SUCCESS:
diff --git a/addressbook/libebook/e-book.c b/addressbook/libebook/e-book.c
index a94106e..7969d2b 100644
--- a/addressbook/libebook/e-book.c
+++ b/addressbook/libebook/e-book.c
@@ -3632,6 +3632,7 @@ get_status_from_error (GError *error)
EBookStatus err_code;
} errors[] = {
{ err ("Success", E_BOOK_ERROR_OK) },
+ { err ("Busy", E_BOOK_ERROR_BUSY) },
{ err ("RepositoryOffline", E_BOOK_ERROR_REPOSITORY_OFFLINE) },
{ err ("PermissionDenied", E_BOOK_ERROR_PERMISSION_DENIED) },
{ err ("ContactNotFound", E_BOOK_ERROR_CONTACT_NOT_FOUND) },
diff --git a/addressbook/libedata-book/e-book-backend-sync.c b/addressbook/libedata-book/e-book-backend-sync.c
index ce3072d..340636c 100644
--- a/addressbook/libedata-book/e-book-backend-sync.c
+++ b/addressbook/libedata-book/e-book-backend-sync.c
@@ -285,7 +285,6 @@ e_book_backend_sync_get_contact_list (EBookBackendSync *backend,
/**
* e_book_backend_sync_authenticate_user:
* @backend: an #EBookBackendSync
- * @book: an #EDataBook
* @cancellable: a #GCancellable for the operation
* @credentials: an #ECredentials to authenticate with
* @error: #GError to set, when something fails
@@ -294,17 +293,15 @@ e_book_backend_sync_get_contact_list (EBookBackendSync *backend,
**/
void
e_book_backend_sync_authenticate_user (EBookBackendSync *backend,
- EDataBook *book,
GCancellable *cancellable,
ECredentials *credentials,
GError **error)
{
e_return_data_book_error_if_fail (E_IS_BOOK_BACKEND_SYNC (backend), E_DATA_BOOK_STATUS_INVALID_ARG);
- e_return_data_book_error_if_fail (E_IS_DATA_BOOK (book), E_DATA_BOOK_STATUS_INVALID_ARG);
e_return_data_book_error_if_fail (credentials, E_DATA_BOOK_STATUS_INVALID_ARG);
e_return_data_book_error_if_fail (E_BOOK_BACKEND_SYNC_GET_CLASS (backend)->authenticate_user_sync, E_DATA_BOOK_STATUS_NOT_SUPPORTED);
- (* E_BOOK_BACKEND_SYNC_GET_CLASS (backend)->authenticate_user_sync) (backend, book, cancellable, credentials, error);
+ (* E_BOOK_BACKEND_SYNC_GET_CLASS (backend)->authenticate_user_sync) (backend, cancellable, credentials, error);
}
static void
@@ -453,16 +450,14 @@ book_backend_get_contact_list (EBookBackend *backend,
static void
book_backend_authenticate_user (EBookBackend *backend,
- EDataBook *book,
- guint32 opid,
GCancellable *cancellable,
ECredentials *credentials)
{
GError *error = NULL;
- e_book_backend_sync_authenticate_user (E_BOOK_BACKEND_SYNC (backend), book, cancellable, credentials, &error);
+ e_book_backend_sync_authenticate_user (E_BOOK_BACKEND_SYNC (backend), cancellable, credentials, &error);
- e_data_book_respond_authenticate_user (book, opid, error);
+ e_book_backend_notify_opened (backend, error);
}
static gboolean
diff --git a/addressbook/libedata-book/e-book-backend-sync.h b/addressbook/libedata-book/e-book-backend-sync.h
index a50f24f..e944052 100644
--- a/addressbook/libedata-book/e-book-backend-sync.h
+++ b/addressbook/libedata-book/e-book-backend-sync.h
@@ -30,7 +30,6 @@ struct _EBookBackendSyncClass {
/* Virtual methods */
void (*open_sync) (EBookBackendSync *backend, EDataBook *book, GCancellable *cancellable, gboolean only_if_exists, GError **error);
- void (*authenticate_user_sync) (EBookBackendSync *backend, EDataBook *book, GCancellable *cancellable, ECredentials *credentials, GError **error);
void (*remove_sync) (EBookBackendSync *backend, EDataBook *book, GCancellable *cancellable, GError **error);
gboolean (*get_backend_property_sync) (EBookBackendSync *backend, EDataBook *book, GCancellable *cancellable, const gchar *prop_name, gchar **prop_value, GError **error);
gboolean (*set_backend_property_sync) (EBookBackendSync *backend, EDataBook *book, GCancellable *cancellable, const gchar *prop_name, const gchar *prop_value, GError **error);
@@ -39,6 +38,8 @@ struct _EBookBackendSyncClass {
void (*modify_contact_sync) (EBookBackendSync *backend, EDataBook *book, GCancellable *cancellable, const gchar *vcard, EContact **contact, GError **error);
void (*get_contact_sync) (EBookBackendSync *backend, EDataBook *book, GCancellable *cancellable, const gchar *id, gchar **vcard, GError **error);
void (*get_contact_list_sync) (EBookBackendSync *backend, EDataBook *book, GCancellable *cancellable, const gchar *query, GSList **contacts, GError **error);
+
+ void (*authenticate_user_sync) (EBookBackendSync *backend, GCancellable *cancellable, ECredentials *credentials, GError **error);
};
GType e_book_backend_sync_get_type (void);
@@ -46,7 +47,6 @@ GType e_book_backend_sync_get_type (void);
gboolean e_book_backend_sync_construct (EBookBackendSync *backend);
void e_book_backend_sync_open (EBookBackendSync *backend, EDataBook *book, GCancellable *cancellable, gboolean only_if_exists, GError **error);
-void e_book_backend_sync_authenticate_user (EBookBackendSync *backend, EDataBook *book, GCancellable *cancellable, ECredentials *credentials, GError **error);
void e_book_backend_sync_remove (EBookBackendSync *backend, EDataBook *book, GCancellable *cancellable, GError **error);
gboolean e_book_backend_sync_get_backend_property(EBookBackendSync *backend, EDataBook *book, GCancellable *cancellable, const gchar *prop_name, gchar **prop_value, GError **error);
gboolean e_book_backend_sync_set_backend_property(EBookBackendSync *backend, EDataBook *book, GCancellable *cancellable, const gchar *prop_name, const gchar *prop_value, GError **error);
@@ -56,6 +56,8 @@ void e_book_backend_sync_modify_contact (EBookBackendSync *backend, EDataBook *
void e_book_backend_sync_get_contact (EBookBackendSync *backend, EDataBook *book, GCancellable *cancellable, const gchar *id, gchar **vcard, GError **error);
void e_book_backend_sync_get_contact_list (EBookBackendSync *backend, EDataBook *book, GCancellable *cancellable, const gchar *query, GSList **contacts, GError **error);
+void e_book_backend_sync_authenticate_user (EBookBackendSync *backend, GCancellable *cancellable, ECredentials *credentials, GError **error);
+
G_END_DECLS
#endif /* __E_BOOK_BACKEND_SYNC_H__ */
diff --git a/addressbook/libedata-book/e-book-backend.c b/addressbook/libedata-book/e-book-backend.c
index 54b5cd9..d261be4 100644
--- a/addressbook/libedata-book/e-book-backend.c
+++ b/addressbook/libedata-book/e-book-backend.c
@@ -16,12 +16,14 @@
#include "e-data-book.h"
#include "e-book-backend.h"
+#define EDB_OPENING_ERROR e_data_book_create_error (E_DATA_BOOK_STATUS_BUSY, _("Cannot process, book backend is opening"))
+
struct _EBookBackendPrivate {
GMutex *clients_mutex;
GSList *clients;
ESource *source;
- gboolean loaded, readonly, removed, online;
+ gboolean opening, opened, readonly, removed, online;
GMutex *views_mutex;
GSList *views;
@@ -77,8 +79,10 @@ book_backend_get_backend_property (EBookBackend *backend, EDataBook *book, guint
g_return_if_fail (book != NULL);
g_return_if_fail (prop_name != NULL);
- if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_LOADED)) {
- e_data_book_respond_get_backend_property (book, opid, NULL, e_book_backend_is_loaded (backend) ? "TRUE" : "FALSE");
+ if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_OPENED)) {
+ e_data_book_respond_get_backend_property (book, opid, NULL, e_book_backend_is_opened (backend) ? "TRUE" : "FALSE");
+ } else if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_OPENING)) {
+ e_data_book_respond_get_backend_property (book, opid, NULL, e_book_backend_is_opening (backend) ? "TRUE" : "FALSE");
} else if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_ONLINE)) {
e_data_book_respond_get_backend_property (book, opid, NULL, e_book_backend_is_online (backend) ? "TRUE" : "FALSE");
} else if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_READONLY)) {
@@ -292,8 +296,51 @@ e_book_backend_get_source (EBookBackend *backend)
* @only_if_exists: %TRUE to prevent the creation of a new book
*
* Executes an 'open' request specified by @opid on @book
- * using @backend.
- * This might be finished with e_data_book_respond_open().
+ * using @backend. This call might be finished
+ * with e_data_book_respond_open() or e_book_backend_respond_opened(),
+ * though the overall opening phase finishes only after call
+ * of e_book_backend_notify_opened() after which call the backend
+ * is either fully opened (including authentication against (remote)
+ * server/storage) or an error was encountered during this opening phase.
+ * 'opened' and 'opening' properties are updated automatically.
+ * The backend refuses all other operations until the opening phase is finished.
+ *
+ * The e_book_backend_notify_opened() is called either from this function
+ * or from e_book_backend_authenticate_user(), or after necessary steps
+ * initiated by these two functions.
+ *
+ * The opening phase usually works like this:
+ * 1) client requests open for the backend
+ * 2) server receives this request and calls e_book_backend_open() - the opening phase begun
+ * 3) either the backend is opened during this call, and notifies client
+ * with e_book_backend_notify_opened() about that. This is usually
+ * for local backends; their opening phase is finished
+ * 4) or the backend requires authentication, thus it notifies client
+ * about that with e_book_backend_notify_auth_required() and is
+ * waiting for credentials, which will be received from client
+ * by e_book_backend_authenticate_user() call. Backend's opening
+ * phase is still running in this case, thus it doesn't call
+ * e_book_backend_notify_opened() within e_book_backend_open() call.
+ * 5) when backend receives credentials in e_book_backend_authenticate_user()
+ * then it tries to authenticate against a server/storage with them
+ * and only after it knows result of the authentication, whether user
+ * was or wasn't authenticated, it notifies client with the result
+ * by e_book_backend_notify_opened() and it's opening phase is
+ * finished now. If there was no error returned then the backend is
+ * considered opened, otherwise it's considered closed. Use AuthenticationFailed
+ * error when the given credentials were rejected by the server/store, which
+ * will result in a re-prompt on the client side, otherwise use AuthenticationRequired
+ * if there was anything wrong with the given credentials. Set error's
+ * message to a reason for a re-prompt, it'll be shown to a user.
+ * 6) client checks error returned from e_book_backend_notify_opened() and
+ * reprompts for a password if it was AuthenticationFailed. Otherwise
+ * considers backend opened based on the error presence (no error means success).
+ *
+ * In any case, the call of e_book_backend_open() should be always finished
+ * with e_data_book_respond_open(), which has no influence on the opening phase,
+ * or alternatively with e_book_backend_respond_opened(). Never use authentication
+ * errors in e_data_book_respond_open() to notify the client the authentication is
+ * required, there is e_book_backend_notify_auth_required() for this.
**/
void
e_book_backend_open (EBookBackend *backend,
@@ -305,15 +352,25 @@ e_book_backend_open (EBookBackend *backend,
g_return_if_fail (E_IS_BOOK_BACKEND (backend));
g_return_if_fail (E_IS_DATA_BOOK (book));
- if (backend->priv->loaded) {
+ g_mutex_lock (backend->priv->clients_mutex);
+
+ if (e_book_backend_is_opened (backend)) {
+ g_mutex_unlock (backend->priv->clients_mutex);
+
e_data_book_report_readonly (book, backend->priv->readonly);
e_data_book_report_online (book, backend->priv->online);
- e_data_book_respond_open (book, opid, NULL);
+ e_book_backend_respond_opened (backend, book, opid, NULL);
+ } else if (e_book_backend_is_opening (backend)) {
+ g_mutex_unlock (backend->priv->clients_mutex);
+
+ e_data_book_respond_open (book, opid, EDB_OPENING_ERROR);
} else {
ESource *source = e_data_book_get_source (book);
- g_return_if_fail (E_IS_BOOK_BACKEND (backend));
+ backend->priv->opening = TRUE;
+ g_mutex_unlock (backend->priv->clients_mutex);
+
g_return_if_fail (source != NULL);
/* Subclasses may need to call e_book_backend_get_cache_dir() in
@@ -349,7 +406,10 @@ e_book_backend_remove (EBookBackend *backend,
g_return_if_fail (E_IS_DATA_BOOK (book));
g_return_if_fail (E_BOOK_BACKEND_GET_CLASS (backend)->remove);
- (* E_BOOK_BACKEND_GET_CLASS (backend)->remove) (backend, book, opid, cancellable);
+ if (e_book_backend_is_opening (backend))
+ e_data_book_respond_remove (book, opid, EDB_OPENING_ERROR);
+ else
+ (* E_BOOK_BACKEND_GET_CLASS (backend)->remove) (backend, book, opid, cancellable);
}
/**
@@ -376,7 +436,10 @@ e_book_backend_create_contact (EBookBackend *backend,
g_return_if_fail (vcard);
g_return_if_fail (E_BOOK_BACKEND_GET_CLASS (backend)->create_contact);
- (* E_BOOK_BACKEND_GET_CLASS (backend)->create_contact) (backend, book, opid, cancellable, vcard);
+ if (e_book_backend_is_opening (backend))
+ e_data_book_respond_create (book, opid, EDB_OPENING_ERROR, NULL);
+ else
+ (* E_BOOK_BACKEND_GET_CLASS (backend)->create_contact) (backend, book, opid, cancellable, vcard);
}
/**
@@ -403,7 +466,10 @@ e_book_backend_remove_contacts (EBookBackend *backend,
g_return_if_fail (id_list);
g_return_if_fail (E_BOOK_BACKEND_GET_CLASS (backend)->remove_contacts);
- (* E_BOOK_BACKEND_GET_CLASS (backend)->remove_contacts) (backend, book, opid, cancellable, id_list);
+ if (e_book_backend_is_opening (backend))
+ e_data_book_respond_remove_contacts (book, opid, EDB_OPENING_ERROR, NULL);
+ else
+ (* E_BOOK_BACKEND_GET_CLASS (backend)->remove_contacts) (backend, book, opid, cancellable, id_list);
}
/**
@@ -430,7 +496,10 @@ e_book_backend_modify_contact (EBookBackend *backend,
g_return_if_fail (vcard);
g_return_if_fail (E_BOOK_BACKEND_GET_CLASS (backend)->modify_contact);
- (* E_BOOK_BACKEND_GET_CLASS (backend)->modify_contact) (backend, book, opid, cancellable, vcard);
+ if (e_book_backend_is_opening (backend))
+ e_data_book_respond_modify (book, opid, EDB_OPENING_ERROR, NULL);
+ else
+ (* E_BOOK_BACKEND_GET_CLASS (backend)->modify_contact) (backend, book, opid, cancellable, vcard);
}
/**
@@ -457,7 +526,10 @@ e_book_backend_get_contact (EBookBackend *backend,
g_return_if_fail (id);
g_return_if_fail (E_BOOK_BACKEND_GET_CLASS (backend)->get_contact);
- (* E_BOOK_BACKEND_GET_CLASS (backend)->get_contact) (backend, book, opid, cancellable, id);
+ if (e_book_backend_is_opening (backend))
+ e_data_book_respond_get_contact (book, opid, EDB_OPENING_ERROR, NULL);
+ else
+ (* E_BOOK_BACKEND_GET_CLASS (backend)->get_contact) (backend, book, opid, cancellable, id);
}
/**
@@ -484,7 +556,10 @@ e_book_backend_get_contact_list (EBookBackend *backend,
g_return_if_fail (query);
g_return_if_fail (E_BOOK_BACKEND_GET_CLASS (backend)->get_contact_list);
- (* E_BOOK_BACKEND_GET_CLASS (backend)->get_contact_list) (backend, book, opid, cancellable, query);
+ if (e_book_backend_is_opening (backend))
+ e_data_book_respond_get_contact_list (book, opid, EDB_OPENING_ERROR, NULL);
+ else
+ (* E_BOOK_BACKEND_GET_CLASS (backend)->get_contact_list) (backend, book, opid, cancellable, query);
}
/**
@@ -528,28 +603,32 @@ e_book_backend_stop_book_view (EBookBackend *backend,
/**
* e_book_backend_authenticate_user:
* @backend: an #EBookBackend
- * @book: an #EDataBook
- * @opid: the ID to use for this operation
* @cancellable: a #GCancellable for the operation
* @credentials: #ECredentials to use for authentication
*
- * Executes an 'authenticate' request specified by @opid on @book
- * using @backend.
- * This might be finished with e_data_book_respond_authenticate_user().
+ * Notifies @backend about @credentials provided by user to use
+ * for authentication. This notification is usually called during
+ * opening phase as a response to e_book_backend_notify_auth_required()
+ * on the client side and it results in setting property 'opening' to %TRUE
+ * unless the backend is already opened. This function finishes opening
+ * phase, thus it should be finished with e_book_backend_notify_opened().
+ *
+ * See information at e_book_backend_open() for more details
+ * how the opening phase works.
**/
void
e_book_backend_authenticate_user (EBookBackend *backend,
- EDataBook *book,
- guint32 opid,
GCancellable *cancellable,
ECredentials *credentials)
{
g_return_if_fail (E_IS_BOOK_BACKEND (backend));
- g_return_if_fail (E_IS_DATA_BOOK (book));
g_return_if_fail (credentials != NULL);
g_return_if_fail (E_BOOK_BACKEND_GET_CLASS (backend)->authenticate_user);
- (* E_BOOK_BACKEND_GET_CLASS (backend)->authenticate_user) (backend, book, opid, cancellable, credentials);
+ if (backend->priv->opened)
+ backend->priv->opening = TRUE;
+
+ (* E_BOOK_BACKEND_GET_CLASS (backend)->authenticate_user) (backend, cancellable, credentials);
}
static void
@@ -748,7 +827,7 @@ e_book_backend_set_backend_property (EBookBackend *backend, EDataBook *book, gui
*
* Checks if @backend's storage is online.
*
- * Returns: %TRUE if loaded, %FALSE otherwise.
+ * Returns: %TRUE if online, %FALSE otherwise.
**/
gboolean
e_book_backend_is_online (EBookBackend *backend)
@@ -759,36 +838,43 @@ e_book_backend_is_online (EBookBackend *backend)
}
/**
- * e_book_backend_is_loaded:
+ * e_book_backend_is_opened:
* @backend: an #EBookBackend
*
- * Checks if @backend's storage has been opened and the backend
- * itself is ready for accessing.
+ * Checks if @backend's storage has been opened (and
+ * authenticated, if necessary) and the backend itself
+ * is ready for accessing. This property is changed automatically
+ * within call of e_book_backend_notify_opened().
*
- * Returns: %TRUE if loaded, %FALSE otherwise.
+ * Returns: %TRUE if fully opened, %FALSE otherwise.
**/
gboolean
-e_book_backend_is_loaded (EBookBackend *backend)
+e_book_backend_is_opened (EBookBackend *backend)
{
g_return_val_if_fail (E_IS_BOOK_BACKEND (backend), FALSE);
- return backend->priv->loaded;
+ return backend->priv->opened;
}
/**
- * e_book_backend_set_is_loaded:
+ * e_book_backend_is_opening:
* @backend: an #EBookBackend
- * @is_loaded: A flag indicating whether the backend is loaded
*
- * Sets the flag indicating whether @backend is loaded to @is_loaded.
- * Meant to be used by backend implementations.
+ * Checks if @backend is processing its opening phase, which
+ * includes everything since the e_book_backend_open() call,
+ * through authentication, up to e_book_backend_notify_opened().
+ * This property is managed automatically and the backend deny
+ * every operation except of cancel and authenticate_user while
+ * it is being opening.
+ *
+ * Returns: %TRUE if opening phase is in the effect, %FALSE otherwise.
**/
-void
-e_book_backend_set_is_loaded (EBookBackend *backend, gboolean is_loaded)
+gboolean
+e_book_backend_is_opening (EBookBackend *backend)
{
- g_return_if_fail (E_IS_BOOK_BACKEND (backend));
+ g_return_val_if_fail (E_IS_BOOK_BACKEND (backend), FALSE);
- backend->priv->loaded = is_loaded;
+ return backend->priv->opening;
}
/**
@@ -808,22 +894,6 @@ e_book_backend_is_readonly (EBookBackend *backend)
}
/**
- * e_book_backend_set_is_readonly:
- * @backend: an #EBookBackend
- * @is_readonly: A flag indicating whether the backend is readonly
- *
- * Sets the flag indicating whether @backend is readonly to @is_readonly.
- * Meant to be used by backend implementations.
- **/
-void
-e_book_backend_set_is_readonly (EBookBackend *backend, gboolean is_readonly)
-{
- g_return_if_fail (E_IS_BOOK_BACKEND (backend));
-
- backend->priv->readonly = is_readonly;
-}
-
-/**
* e_book_backend_is_removed:
* @backend: an #EBookBackend
*
@@ -1047,15 +1117,27 @@ e_book_backend_notify_online (EBookBackend *backend, gboolean is_online)
/**
* e_book_backend_notify_auth_required:
* @backend: an #EBookBackend
+ * @is_self: Use %TRUE to indicate the authentication is required
+ * for the @backend, otheriwse the authentication is for any
+ * other source. Having @credentials %NULL means @is_self
+ * automatically.
* @credentials: an #ECredentials that contains extra information for
* a source for which authentication is requested.
- * This parameter can be NULL to indicate "for this book".
+ * This parameter can be %NULL to indicate "for this book".
*
* Notifies clients that @backend requires authentication in order to
- * connect. Means to be used by backend implementations.
+ * connect. This function call does not influence 'opening', but
+ * influences 'opened' property, which is set to %FALSE when @is_self
+ * is %TRUE or @credentials is %NULL. Opening phase is finished
+ * by e_book_backend_notify_opened() if this is requested for @backend.
+ *
+ * See e_book_backend_open() for a description how the whole opening
+ * phase works.
+ *
+ * Meant to be used by backend implementations.
**/
void
-e_book_backend_notify_auth_required (EBookBackend *backend, const ECredentials *credentials)
+e_book_backend_notify_auth_required (EBookBackend *backend, gboolean is_self, const ECredentials *credentials)
{
EBookBackendPrivate *priv;
GSList *clients;
@@ -1063,7 +1145,82 @@ e_book_backend_notify_auth_required (EBookBackend *backend, const ECredentials *
priv = backend->priv;
g_mutex_lock (priv->clients_mutex);
+ if (is_self || !credentials)
+ priv->opened = FALSE;
+
for (clients = priv->clients; clients != NULL; clients = g_slist_next (clients))
e_data_book_report_auth_required (E_DATA_BOOK (clients->data), credentials);
+
g_mutex_unlock (priv->clients_mutex);
}
+
+/**
+ * e_book_backend_notify_opened:
+ * @backend: an #EBookBackend
+ * @error: a #GError corresponding to the error encountered during
+ * the opening phase. Use %NULL for success. The @error is freed
+ * automatically if not %NULL.
+ *
+ * Notifies clients that @backend finished its opening phase.
+ * See e_book_backend_open() for more information how the opening
+ * phase works. Calling this function changes 'opening' property,
+ * same as 'opened'. 'opening' is set to %FALSE and the backend
+ * is considered 'opened' only if the @error is %NULL.
+ *
+ * See also: e_book_backend_respond_opened()
+ *
+ * Note: The @error is freed automatically if not %NULL.
+ *
+ * Meant to be used by backend implementations.
+ **/
+void
+e_book_backend_notify_opened (EBookBackend *backend, GError *error)
+{
+ EBookBackendPrivate *priv;
+ GSList *clients;
+
+ priv = backend->priv;
+ g_mutex_lock (priv->clients_mutex);
+
+ priv->opening = FALSE;
+ priv->opened = error == NULL;
+
+ for (clients = priv->clients; clients != NULL; clients = g_slist_next (clients))
+ e_data_book_report_opened (E_DATA_BOOK (clients->data), error);
+
+ g_mutex_unlock (priv->clients_mutex);
+
+ if (error)
+ g_error_free (error);
+}
+
+/**
+ * e_book_backend_respond_opened:
+ * @backend: an #EBookBackend
+ * @book: an #EDataBook
+ * @opid: an operation ID
+ * @error: result error; can be %NULL, if it isn't then it's automatically freed
+ *
+ * This is a replacement for e_data_book_respond_open() for cases where
+ * the finish of 'open' method call also finishes backend opening phase.
+ * This function covers calling of both e_data_book_respond_open() and
+ * e_book_backend_notify_opened() with the same @error.
+ *
+ * See e_book_backend_open() for more details how the opening phase works.
+ **/
+void
+e_book_backend_respond_opened (EBookBackend *backend, EDataBook *book, guint32 opid, GError *error)
+{
+ GError *copy = NULL;
+
+ g_return_if_fail (backend != NULL);
+ g_return_if_fail (E_IS_BOOK_BACKEND (backend));
+ g_return_if_fail (book != NULL);
+ g_return_if_fail (opid != 0);
+
+ if (error)
+ copy = g_error_copy (error);
+
+ e_data_book_respond_open (book, opid, error);
+ e_book_backend_notify_opened (backend, copy);
+}
diff --git a/addressbook/libedata-book/e-book-backend.h b/addressbook/libedata-book/e-book-backend.h
index cd7ec1c..752b381 100644
--- a/addressbook/libedata-book/e-book-backend.h
+++ b/addressbook/libedata-book/e-book-backend.h
@@ -41,7 +41,8 @@ G_BEGIN_DECLS
#define E_IS_BOOK_BACKEND_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_TYPE_BOOK_BACKEND))
#define E_BOOK_BACKEND_GET_CLASS(k) (G_TYPE_INSTANCE_GET_CLASS ((k), E_TYPE_BOOK_BACKEND, EBookBackendClass))
-#define CLIENT_BACKEND_PROPERTY_LOADED "loaded"
+#define CLIENT_BACKEND_PROPERTY_OPENED "opened"
+#define CLIENT_BACKEND_PROPERTY_OPENING "opening"
#define CLIENT_BACKEND_PROPERTY_ONLINE "online"
#define CLIENT_BACKEND_PROPERTY_READONLY "readonly"
#define CLIENT_BACKEND_PROPERTY_CACHE_DIR "cache-dir"
@@ -65,9 +66,9 @@ struct _EBookBackendClass {
void (* set_backend_property) (EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable, const gchar *prop_name, const gchar *prop_value);
void (* open) (EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable, gboolean only_if_exists);
- void (* authenticate_user) (EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable, ECredentials *credentials);
void (* remove) (EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable);
void (* set_online) (EBookBackend *backend, gboolean is_online);
+ void (* authenticate_user) (EBookBackend *backend, GCancellable *cancellable, ECredentials *credentials);
void (* create_contact) (EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable, const gchar *vcard);
void (* remove_contacts) (EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable, const GSList *id_list);
@@ -94,16 +95,17 @@ gboolean e_book_backend_add_client (EBookBackend *backend, EDataBook *book);
void e_book_backend_remove_client (EBookBackend *backend, EDataBook *book);
gboolean e_book_backend_is_online (EBookBackend *backend);
-gboolean e_book_backend_is_loaded (EBookBackend *backend);
+gboolean e_book_backend_is_opened (EBookBackend *backend);
+gboolean e_book_backend_is_opening (EBookBackend *backend);
gboolean e_book_backend_is_readonly (EBookBackend *backend);
gboolean e_book_backend_is_removed (EBookBackend *backend);
void e_book_backend_set_online (EBookBackend *backend, gboolean is_online);
+void e_book_backend_authenticate_user(EBookBackend *backend, GCancellable *cancellable, ECredentials *credentials);
void e_book_backend_get_backend_property (EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable, const gchar *prop_name);
void e_book_backend_set_backend_property (EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable, const gchar *prop_name, const gchar *prop_value);
void e_book_backend_open (EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable, gboolean only_if_exists);
-void e_book_backend_authenticate_user(EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable, ECredentials *credentials);
void e_book_backend_remove (EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable);
void e_book_backend_create_contact (EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable, const gchar *vcard);
void e_book_backend_remove_contacts (EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable, const GSList *id_list);
@@ -124,15 +126,16 @@ void e_book_backend_notify_complete (EBookBackend *backend);
void e_book_backend_notify_error (EBookBackend *backend, const gchar *message);
void e_book_backend_notify_readonly (EBookBackend *backend, gboolean is_readonly);
void e_book_backend_notify_online (EBookBackend *backend, gboolean is_online);
-void e_book_backend_notify_auth_required (EBookBackend *backend, const ECredentials *credentials);
+void e_book_backend_notify_auth_required (EBookBackend *backend, gboolean is_self, const ECredentials *credentials);
+void e_book_backend_notify_opened (EBookBackend *backend, GError *error);
void e_book_backend_sync (EBookBackend *backend);
/* protected functions for subclasses */
-void e_book_backend_set_is_loaded (EBookBackend *backend, gboolean is_loaded);
-void e_book_backend_set_is_readonly (EBookBackend *backend, gboolean is_readonly);
void e_book_backend_set_is_removed (EBookBackend *backend, gboolean is_removed);
+void e_book_backend_respond_opened (EBookBackend *backend, EDataBook *book, guint32 opid, GError *error);
+
G_END_DECLS
#endif /* __E_BOOK_BACKEND_H__ */
diff --git a/addressbook/libedata-book/e-data-book-factory.c b/addressbook/libedata-book/e-data-book-factory.c
index f70a586..9fcceb6 100644
--- a/addressbook/libedata-book/e-data-book-factory.c
+++ b/addressbook/libedata-book/e-data-book-factory.c
@@ -313,12 +313,6 @@ impl_BookFactory_getBook (EGdbusBookFactory *object, GDBusMethodInvocation *invo
return TRUE;
}
- /* Remove a pending exit */
- if (priv->exit_timeout) {
- g_source_remove (priv->exit_timeout);
- priv->exit_timeout = 0;
- }
-
g_mutex_lock (priv->backends_lock);
source = e_source_new_from_standalone_xml (in_source);
@@ -382,6 +376,12 @@ impl_BookFactory_getBook (EGdbusBookFactory *object, GDBusMethodInvocation *invo
return TRUE;
}
+ /* Remove a pending exit */
+ if (priv->exit_timeout) {
+ g_source_remove (priv->exit_timeout);
+ priv->exit_timeout = 0;
+ }
+
path = construct_book_factory_path ();
book = e_data_book_new (backend, source);
g_hash_table_insert (priv->books, g_strdup (path), book);
diff --git a/addressbook/libedata-book/e-data-book-types.h b/addressbook/libedata-book/e-data-book-types.h
index cf608dc..5434815 100644
--- a/addressbook/libedata-book/e-data-book-types.h
+++ b/addressbook/libedata-book/e-data-book-types.h
@@ -46,6 +46,7 @@ typedef struct _EDataBookClass EDataBookClass;
typedef enum {
E_DATA_BOOK_STATUS_SUCCESS,
+ E_DATA_BOOK_STATUS_BUSY,
E_DATA_BOOK_STATUS_REPOSITORY_OFFLINE,
E_DATA_BOOK_STATUS_PERMISSION_DENIED,
E_DATA_BOOK_STATUS_CONTACT_NOT_FOUND,
diff --git a/addressbook/libedata-book/e-data-book-view.c b/addressbook/libedata-book/e-data-book-view.c
index 358adaa..685d784 100644
--- a/addressbook/libedata-book/e-data-book-view.c
+++ b/addressbook/libedata-book/e-data-book-view.c
@@ -541,7 +541,7 @@ e_data_book_view_notify_complete (EDataBookView *book_view, const GError *error)
g_mutex_unlock (priv->pending_mutex);
- strv_error = e_gdbus_book_view_encode_error (error);
+ strv_error = e_gdbus_templates_encode_error (error);
e_gdbus_book_view_emit_complete (priv->gdbus_object, (const gchar * const *) strv_error);
g_strfreev (strv_error);
}
diff --git a/addressbook/libedata-book/e-data-book.c b/addressbook/libedata-book/e-data-book.c
index 9fd618a..29f1a5b 100644
--- a/addressbook/libedata-book/e-data-book.c
+++ b/addressbook/libedata-book/e-data-book.c
@@ -137,10 +137,6 @@ operation_thread (gpointer data, gpointer user_data)
case OP_OPEN:
e_book_backend_open (backend, op->book, op->id, op->cancellable, op->d.only_if_exists);
break;
- case OP_AUTHENTICATE:
- e_book_backend_authenticate_user (backend, op->book, op->id, op->cancellable, op->d.credentials);
- e_credentials_free (op->d.credentials);
- break;
case OP_ADD_CONTACT:
e_book_backend_create_contact (backend, op->book, op->id, op->cancellable, op->d.vcard);
g_free (op->d.vcard);
@@ -215,6 +211,10 @@ operation_thread (gpointer data, gpointer user_data)
}
g_free (op->d.query);
break;
+ case OP_AUTHENTICATE:
+ e_book_backend_authenticate_user (backend, op->cancellable, op->d.credentials);
+ e_credentials_free (op->d.credentials);
+ break;
case OP_CANCEL_OPERATION:
g_static_rec_mutex_lock (&op->book->priv->pending_ops_lock);
@@ -285,6 +285,7 @@ e_data_book_status_to_string (EDataBookStatus status)
const gchar *msg;
} statuses[] = {
{ E_DATA_BOOK_STATUS_SUCCESS, N_("Success") },
+ { E_DATA_BOOK_STATUS_BUSY, N_("Backend is busy") },
{ E_DATA_BOOK_STATUS_REPOSITORY_OFFLINE, N_("Repository offline") },
{ E_DATA_BOOK_STATUS_PERMISSION_DENIED, N_("Permission denied") },
{ E_DATA_BOOK_STATUS_CONTACT_NOT_FOUND, N_("Contact not found") },
@@ -326,6 +327,7 @@ e_data_book_error_quark (void)
static const GDBusErrorEntry entries[] = {
{ E_DATA_BOOK_STATUS_SUCCESS, ERR_PREFIX "Success" },
+ { E_DATA_BOOK_STATUS_BUSY, ERR_PREFIX "Busy" },
{ E_DATA_BOOK_STATUS_REPOSITORY_OFFLINE, ERR_PREFIX "RepositoryOffline" },
{ E_DATA_BOOK_STATUS_PERMISSION_DENIED, ERR_PREFIX "PermissionDenied" },
{ E_DATA_BOOK_STATUS_CONTACT_NOT_FOUND, ERR_PREFIX "ContactNotFound" },
@@ -541,28 +543,6 @@ impl_Book_getContactList (EGdbusBook *object, GDBusMethodInvocation *invocation,
}
static gboolean
-impl_Book_authenticateUser (EGdbusBook *object, GDBusMethodInvocation *invocation, const gchar * const *in_credentials, EDataBook *book)
-{
- OperationData *op;
-
- if (in_credentials == NULL) {
- GError *error = e_data_book_create_error (E_DATA_BOOK_STATUS_INVALID_ARG, NULL);
- /* Translators: This is prefix to a detailed error message */
- data_book_return_error (invocation, error, _("Cannot authenticate user: "));
- g_error_free (error);
- return TRUE;
- }
-
- op = op_new (OP_AUTHENTICATE, book);
- op->d.credentials = e_credentials_new_strv (in_credentials);
-
- e_gdbus_book_complete_authenticate_user (book->priv->gdbus_object, invocation, op->id);
- e_operation_pool_push (ops_pool, op);
-
- return TRUE;
-}
-
-static gboolean
impl_Book_addContact (EGdbusBook *object, GDBusMethodInvocation *invocation, const gchar *in_vcard, EDataBook *book)
{
OperationData *op;
@@ -678,6 +658,28 @@ impl_Book_getBookView (EGdbusBook *object, GDBusMethodInvocation *invocation, co
}
static gboolean
+impl_Book_authenticateUser (EGdbusBook *object, GDBusMethodInvocation *invocation, const gchar * const *in_credentials, EDataBook *book)
+{
+ OperationData *op;
+
+ if (in_credentials == NULL) {
+ GError *error = e_data_book_create_error (E_DATA_BOOK_STATUS_INVALID_ARG, NULL);
+ /* Translators: This is prefix to a detailed error message */
+ data_book_return_error (invocation, error, _("Cannot authenticate user: "));
+ g_error_free (error);
+ return TRUE;
+ }
+
+ op = op_new (OP_AUTHENTICATE, book);
+ op->d.credentials = e_credentials_new_strv (in_credentials);
+
+ e_gdbus_book_complete_authenticate_user (book->priv->gdbus_object, invocation, NULL);
+ e_operation_pool_push (ops_pool, op);
+
+ return TRUE;
+}
+
+static gboolean
impl_Book_cancelOperation (EGdbusBook *object, GDBusMethodInvocation *invocation, guint in_opid, EDataBook *book)
{
OperationData *op;
@@ -824,20 +826,6 @@ e_data_book_respond_get_contact_list (EDataBook *book, guint32 opid, GError *err
}
void
-e_data_book_respond_authenticate_user (EDataBook *book, guint32 opid, GError *error)
-{
- op_complete (book, opid);
-
- /* Translators: This is prefix to a detailed error message */
- g_prefix_error (&error, "%s", _("Cannot authenticate user: "));
-
- e_gdbus_book_emit_authenticate_user_done (book->priv->gdbus_object, opid, error);
-
- if (error)
- g_error_free (error);
-}
-
-void
e_data_book_respond_create (EDataBook *book, guint32 opid, GError *error, const EContact *contact)
{
gchar *gdbus_uid = NULL;
@@ -946,6 +934,23 @@ e_data_book_report_auth_required (EDataBook *book, const ECredentials *credentia
g_strfreev (strv);
}
+/* Reports to associated client that opening phase of the book is finished.
+ error being NULL means successfully, otherwise reports an error which happened
+ during opening phase. By opening phase is meant a process including successfull
+ authentication to the server/storage.
+*/
+void
+e_data_book_report_opened (EDataBook *book, const GError *error)
+{
+ gchar **strv_error;
+
+ strv_error = e_gdbus_templates_encode_error (error);
+
+ e_gdbus_book_emit_opened (book->priv->gdbus_object, (const gchar * const *) strv_error);
+
+ g_strfreev (strv_error);
+}
+
/**
* e_data_book_register_gdbus_object:
*
diff --git a/addressbook/libedata-book/e-data-book.h b/addressbook/libedata-book/e-data-book.h
index 1c7ea9c..465a2ba 100644
--- a/addressbook/libedata-book/e-data-book.h
+++ b/addressbook/libedata-book/e-data-book.h
@@ -20,8 +20,8 @@
* Author: Ross Burton <ross linux intel com>
*/
-#ifndef __E_DATA_BOOK_H__
-#define __E_DATA_BOOK_H__
+#ifndef E_DATA_BOOK_H
+#define E_DATA_BOOK_H
#include <glib-object.h>
#include <gio/gio.h>
@@ -140,7 +140,6 @@ void e_data_book_respond_set_backend_property (EDataBook *book, guint32 opid, G
void e_data_book_respond_create (EDataBook *book, guint32 opid, GError *error, const EContact *contact);
void e_data_book_respond_remove_contacts (EDataBook *book, guint32 opid, GError *error, const GSList *ids);
void e_data_book_respond_modify (EDataBook *book, guint32 opid, GError *error, const EContact *contact);
-void e_data_book_respond_authenticate_user (EDataBook *book, guint32 opid, GError *error);
void e_data_book_respond_get_contact (EDataBook *book, guint32 opid, GError *error, const gchar *vcard);
void e_data_book_respond_get_contact_list (EDataBook *book, guint32 opid, GError *error, const GSList *cards);
@@ -148,9 +147,10 @@ void e_data_book_report_error (EDataBook *book, const gchar *message);
void e_data_book_report_readonly (EDataBook *book, gboolean readonly);
void e_data_book_report_online (EDataBook *book, gboolean is_online);
void e_data_book_report_auth_required (EDataBook *book, const ECredentials *credentials);
+void e_data_book_report_opened (EDataBook *book, const GError *error);
gchar * e_data_book_string_slist_to_comma_string (const GSList *strings);
G_END_DECLS
-#endif /* __E_DATA_BOOK_H__ */
+#endif /* E_DATA_BOOK_H */
diff --git a/addressbook/libegdbus/e-gdbus-book-view.c b/addressbook/libegdbus/e-gdbus-book-view.c
index f8ff514..dfa40a5 100644
--- a/addressbook/libegdbus/e-gdbus-book-view.c
+++ b/addressbook/libegdbus/e-gdbus-book-view.c
@@ -210,50 +210,6 @@ e_gdbus_book_view_emit_progress (EGdbusBookView *object, guint arg_percent, cons
g_signal_emit (object, signals[__PROGRESS_SIGNAL], 0, arg_percent, arg_message);
}
-/* free returned pointer with g_strfreev() */
-gchar **
-e_gdbus_book_view_encode_error (const GError *in_error)
-{
- gchar **strv;
-
- strv = g_new0 (gchar *, 3);
-
- if (!in_error) {
- strv[0] = g_strdup ("");
- strv[1] = g_strdup ("");
- } else {
- gchar *dbus_error_name = g_dbus_error_encode_gerror (in_error);
-
- strv[0] = e_util_utf8_make_valid (dbus_error_name ? dbus_error_name : "");
- strv[1] = e_util_utf8_make_valid (in_error->message);
-
- g_free (dbus_error_name);
- }
-
- return strv;
-}
-
-/* free returned pointer with g_error_free(), of not NULL */
-GError *
-e_gdbus_book_view_decode_error (const gchar * const *in_strv)
-{
- GError *error = NULL;
- const gchar *error_name, *error_message;
-
- g_return_val_if_fail (in_strv != NULL, NULL);
- g_return_val_if_fail (in_strv[0] != NULL, NULL);
- g_return_val_if_fail (in_strv[1] != NULL, NULL);
- g_return_val_if_fail (in_strv[2] == NULL, NULL);
-
- error_name = in_strv[0];
- error_message = in_strv[1];
-
- if (error_name && *error_name && error_message)
- error = g_dbus_error_new_for_dbus_error (error_name, error_message);
-
- return error;
-}
-
void
e_gdbus_book_view_emit_complete (EGdbusBookView *object, const gchar * const *arg_error)
{
diff --git a/addressbook/libegdbus/e-gdbus-book-view.h b/addressbook/libegdbus/e-gdbus-book-view.h
index 719bcbd..e959afd 100644
--- a/addressbook/libegdbus/e-gdbus-book-view.h
+++ b/addressbook/libegdbus/e-gdbus-book-view.h
@@ -148,9 +148,6 @@ void e_gdbus_book_view_emit_objects_modified (EGdbusBookView *object, const gcha
void e_gdbus_book_view_emit_objects_removed (EGdbusBookView *object, const gchar * const *arg_uids);
void e_gdbus_book_view_emit_progress (EGdbusBookView *object, guint arg_percent, const gchar *arg_message);
-
-gchar **e_gdbus_book_view_encode_error (const GError *in_error);
-GError *e_gdbus_book_view_decode_error (const gchar * const *in_strv);
void e_gdbus_book_view_emit_complete (EGdbusBookView *object, const gchar * const *arg_error);
G_END_DECLS
diff --git a/addressbook/libegdbus/e-gdbus-book.c b/addressbook/libegdbus/e-gdbus-book.c
index 97b39c9..a3dbcd1 100644
--- a/addressbook/libegdbus/e-gdbus-book.c
+++ b/addressbook/libegdbus/e-gdbus-book.c
@@ -39,10 +39,9 @@ enum
__READONLY_SIGNAL,
__ONLINE_SIGNAL,
__AUTH_REQUIRED_SIGNAL,
+ __OPENED_SIGNAL,
__OPEN_METHOD,
__OPEN_DONE_SIGNAL,
- __AUTHENTICATE_USER_METHOD,
- __AUTHENTICATE_USER_DONE_SIGNAL,
__REMOVE_METHOD,
__REMOVE_DONE_SIGNAL,
__GET_CONTACT_METHOD,
@@ -61,6 +60,7 @@ enum
__SET_BACKEND_PROPERTY_DONE_SIGNAL,
__GET_VIEW_METHOD,
__GET_VIEW_DONE_SIGNAL,
+ __AUTHENTICATE_USER_METHOD,
__CANCEL_OPERATION_METHOD,
__CANCEL_ALL_METHOD,
__CLOSE_METHOD,
@@ -113,9 +113,9 @@ E_DECLARE_GDBUS_SIGNAL_EMISSION_HOOK_STRING (GDBUS_BOOK_INTERFACE_NAME, backend
E_DECLARE_GDBUS_SIGNAL_EMISSION_HOOK_BOOLEAN (GDBUS_BOOK_INTERFACE_NAME, readonly)
E_DECLARE_GDBUS_SIGNAL_EMISSION_HOOK_BOOLEAN (GDBUS_BOOK_INTERFACE_NAME, online)
E_DECLARE_GDBUS_SIGNAL_EMISSION_HOOK_STRV (GDBUS_BOOK_INTERFACE_NAME, auth_required)
+E_DECLARE_GDBUS_SIGNAL_EMISSION_HOOK_STRV (GDBUS_BOOK_INTERFACE_NAME, opened)
E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_VOID (GDBUS_BOOK_INTERFACE_NAME, open)
-E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_VOID (GDBUS_BOOK_INTERFACE_NAME, authenticate_user)
E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_VOID (GDBUS_BOOK_INTERFACE_NAME, remove)
E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_STRING (GDBUS_BOOK_INTERFACE_NAME, get_contact)
E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_STRV (GDBUS_BOOK_INTERFACE_NAME, get_contact_list)
@@ -140,10 +140,10 @@ e_gdbus_book_default_init (EGdbusBookIface *iface)
E_INIT_GDBUS_SIGNAL_BOOLEAN (EGdbusBookIface, "readonly", readonly, __READONLY_SIGNAL)
E_INIT_GDBUS_SIGNAL_BOOLEAN (EGdbusBookIface, "online", online, __ONLINE_SIGNAL)
E_INIT_GDBUS_SIGNAL_STRV (EGdbusBookIface, "auth_required", auth_required, __AUTH_REQUIRED_SIGNAL)
+ E_INIT_GDBUS_SIGNAL_STRV (EGdbusBookIface, "opened", opened, __OPENED_SIGNAL)
/* GObject signals definitions for D-Bus methods: */
E_INIT_GDBUS_METHOD_ASYNC_BOOLEAN__VOID (EGdbusBookIface, "open", open, __OPEN_METHOD, __OPEN_DONE_SIGNAL)
- E_INIT_GDBUS_METHOD_ASYNC_STRV__VOID (EGdbusBookIface, "authenticateUser", authenticate_user, __AUTHENTICATE_USER_METHOD, __AUTHENTICATE_USER_DONE_SIGNAL)
E_INIT_GDBUS_METHOD_ASYNC_VOID__VOID (EGdbusBookIface, "remove", remove, __REMOVE_METHOD, __REMOVE_DONE_SIGNAL)
E_INIT_GDBUS_METHOD_ASYNC_STRING__STRING(EGdbusBookIface, "getContact", get_contact, __GET_CONTACT_METHOD, __GET_CONTACT_DONE_SIGNAL)
E_INIT_GDBUS_METHOD_ASYNC_STRING__STRV (EGdbusBookIface, "getContactList", get_contact_list, __GET_CONTACT_LIST_METHOD, __GET_CONTACT_LIST_DONE_SIGNAL)
@@ -153,6 +153,7 @@ e_gdbus_book_default_init (EGdbusBookIface *iface)
E_INIT_GDBUS_METHOD_ASYNC_STRING__STRING(EGdbusBookIface, "getBackendProperty", get_backend_property, __GET_BACKEND_PROPERTY_METHOD, __GET_BACKEND_PROPERTY_DONE_SIGNAL)
E_INIT_GDBUS_METHOD_ASYNC_STRV__VOID (EGdbusBookIface, "setBackendProperty", set_backend_property, __SET_BACKEND_PROPERTY_METHOD, __SET_BACKEND_PROPERTY_DONE_SIGNAL)
E_INIT_GDBUS_METHOD_ASYNC_STRING__STRING(EGdbusBookIface, "getView", get_view, __GET_VIEW_METHOD, __GET_VIEW_DONE_SIGNAL)
+ E_INIT_GDBUS_METHOD_STRV (EGdbusBookIface, "authenticateUser", authenticate_user, __AUTHENTICATE_USER_METHOD)
E_INIT_GDBUS_METHOD_UINT (EGdbusBookIface, "cancelOperation", cancel_operation, __CANCEL_OPERATION_METHOD)
E_INIT_GDBUS_METHOD_VOID (EGdbusBookIface, "cancelAll", cancel_all, __CANCEL_ALL_METHOD)
E_INIT_GDBUS_METHOD_VOID (EGdbusBookIface, "close", close, __CLOSE_METHOD)
@@ -179,26 +180,6 @@ e_gdbus_book_call_open_sync (GDBusProxy *proxy, gboolean in_only_if_exists, GCan
}
void
-e_gdbus_book_call_authenticate_user (GDBusProxy *proxy, const gchar * const *in_credentials, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
-{
- e_gdbus_proxy_call_strv ("authenticateUser", e_gdbus_book_call_authenticate_user, E_GDBUS_ASYNC_OP_KEEPER (proxy), in_credentials, cancellable, callback, user_data);
-}
-
-gboolean
-e_gdbus_book_call_authenticate_user_finish (GDBusProxy *proxy, GAsyncResult *result, GError **error)
-{
- return e_gdbus_proxy_finish_call_void (E_GDBUS_ASYNC_OP_KEEPER (proxy), result, error, e_gdbus_book_call_authenticate_user);
-}
-
-gboolean
-e_gdbus_book_call_authenticate_user_sync (GDBusProxy *proxy, const gchar * const *in_credentials, GCancellable *cancellable, GError **error)
-{
- return e_gdbus_proxy_call_sync_strv__void (proxy, in_credentials, cancellable, error,
- e_gdbus_book_call_authenticate_user,
- e_gdbus_book_call_authenticate_user_finish);
-}
-
-void
e_gdbus_book_call_remove (GDBusProxy *proxy, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
{
e_gdbus_proxy_call_void ("remove", e_gdbus_book_call_remove, E_GDBUS_ASYNC_OP_KEEPER (proxy), cancellable, callback, user_data);
@@ -410,6 +391,24 @@ e_gdbus_book_call_get_view_sync (GDBusProxy *proxy, const gchar *in_query, gchar
}
void
+e_gdbus_book_call_authenticate_user (GDBusProxy *proxy, const gchar * const *in_credentials, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
+{
+ e_gdbus_proxy_method_call_strv ("authenticateUser", proxy, in_credentials, cancellable, callback, user_data);
+}
+
+gboolean
+e_gdbus_book_call_authenticate_user_finish (GDBusProxy *proxy, GAsyncResult *result, GError **error)
+{
+ return e_gdbus_proxy_method_call_finish_void (proxy, result, error);
+}
+
+gboolean
+e_gdbus_book_call_authenticate_user_sync (GDBusProxy *proxy, const gchar * const *in_credentials, GCancellable *cancellable, GError **error)
+{
+ return e_gdbus_proxy_method_call_sync_strv__void ("authenticateUser", proxy, in_credentials, cancellable, error);
+}
+
+void
e_gdbus_book_call_cancel_operation (GDBusProxy *proxy, guint in_opid, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
{
e_gdbus_proxy_method_call_uint ("cancelOperation", proxy, in_opid, cancellable, callback, user_data);
@@ -478,7 +477,6 @@ e_gdbus_book_emit_ ## _mname ## _done (EGdbusBook *object, guint arg_opid, const
}
DECLARE_EMIT_DONE_SIGNAL_0 (open, __OPEN_DONE_SIGNAL)
-DECLARE_EMIT_DONE_SIGNAL_0 (authenticate_user, __AUTHENTICATE_USER_DONE_SIGNAL)
DECLARE_EMIT_DONE_SIGNAL_0 (remove, __REMOVE_DONE_SIGNAL)
DECLARE_EMIT_DONE_SIGNAL_1 (get_contact, __GET_CONTACT_DONE_SIGNAL, const gchar *)
DECLARE_EMIT_DONE_SIGNAL_1 (get_contact_list, __GET_CONTACT_LIST_DONE_SIGNAL, const gchar * const *)
@@ -516,13 +514,19 @@ e_gdbus_book_emit_auth_required (EGdbusBook *object, const gchar * const *arg_cr
g_signal_emit (object, signals[__AUTH_REQUIRED_SIGNAL], 0, arg_credentials);
}
+void
+e_gdbus_book_emit_opened (EGdbusBook *object, const gchar * const *arg_error)
+{
+ g_signal_emit (object, signals[__OPENED_SIGNAL], 0, arg_error);
+}
+
E_DECLARE_GDBUS_NOTIFY_SIGNAL_1 (book, backend_error, message, "s")
E_DECLARE_GDBUS_NOTIFY_SIGNAL_1 (book, readonly, is_readonly, "b")
E_DECLARE_GDBUS_NOTIFY_SIGNAL_1 (book, online, is_online, "b")
E_DECLARE_GDBUS_NOTIFY_SIGNAL_1 (book, auth_required, credentials, "as")
+E_DECLARE_GDBUS_NOTIFY_SIGNAL_1 (book, opened, error, "as")
E_DECLARE_GDBUS_ASYNC_METHOD_1 (book, open, only_if_exists, "b")
-E_DECLARE_GDBUS_ASYNC_METHOD_1 (book, authenticateUser, credentials, "as")
E_DECLARE_GDBUS_ASYNC_METHOD_0 (book, remove)
E_DECLARE_GDBUS_ASYNC_METHOD_1_WITH_RETURN (book, getContact, uid, "s", vcard, "s")
E_DECLARE_GDBUS_ASYNC_METHOD_1_WITH_RETURN (book, getContactList, query, "s", vcards, "as")
@@ -533,6 +537,7 @@ E_DECLARE_GDBUS_ASYNC_METHOD_1_WITH_RETURN (book, getBackendProperty, prop_name,
E_DECLARE_GDBUS_ASYNC_METHOD_1 (book, setBackendProperty, prop_name_value, "as")
E_DECLARE_GDBUS_ASYNC_METHOD_1_WITH_RETURN (book, getView, query, "s", view, "s")
+E_DECLARE_GDBUS_SYNC_METHOD_1 (book, authenticateUser, credentials, "as")
E_DECLARE_GDBUS_SYNC_METHOD_1 (book, cancelOperation, opid, "u")
E_DECLARE_GDBUS_SYNC_METHOD_0 (book, cancelAll)
E_DECLARE_GDBUS_SYNC_METHOD_0 (book, close)
@@ -540,7 +545,6 @@ E_DECLARE_GDBUS_SYNC_METHOD_0 (book, close)
static const GDBusMethodInfo * const e_gdbus_book_method_info_pointers[] =
{
&E_DECLARED_GDBUS_METHOD_INFO_NAME (book, open),
- &E_DECLARED_GDBUS_METHOD_INFO_NAME (book, authenticateUser),
&E_DECLARED_GDBUS_METHOD_INFO_NAME (book, remove),
&E_DECLARED_GDBUS_METHOD_INFO_NAME (book, getContact),
&E_DECLARED_GDBUS_METHOD_INFO_NAME (book, getContactList),
@@ -550,6 +554,7 @@ static const GDBusMethodInfo * const e_gdbus_book_method_info_pointers[] =
&E_DECLARED_GDBUS_METHOD_INFO_NAME (book, getBackendProperty),
&E_DECLARED_GDBUS_METHOD_INFO_NAME (book, setBackendProperty),
&E_DECLARED_GDBUS_METHOD_INFO_NAME (book, getView),
+ &E_DECLARED_GDBUS_METHOD_INFO_NAME (book, authenticateUser),
&E_DECLARED_GDBUS_METHOD_INFO_NAME (book, cancelOperation),
&E_DECLARED_GDBUS_METHOD_INFO_NAME (book, cancelAll),
&E_DECLARED_GDBUS_METHOD_INFO_NAME (book, close),
@@ -562,9 +567,9 @@ static const GDBusSignalInfo * const e_gdbus_book_signal_info_pointers[] =
&E_DECLARED_GDBUS_SIGNAL_INFO_NAME (book, readonly),
&E_DECLARED_GDBUS_SIGNAL_INFO_NAME (book, online),
&E_DECLARED_GDBUS_SIGNAL_INFO_NAME (book, auth_required),
+ &E_DECLARED_GDBUS_SIGNAL_INFO_NAME (book, opened),
&E_DECLARED_GDBUS_SIGNAL_INFO_NAME (book, open_done),
- &E_DECLARED_GDBUS_SIGNAL_INFO_NAME (book, authenticateUser_done),
&E_DECLARED_GDBUS_SIGNAL_INFO_NAME (book, remove_done),
&E_DECLARED_GDBUS_SIGNAL_INFO_NAME (book, getContact_done),
&E_DECLARED_GDBUS_SIGNAL_INFO_NAME (book, getContactList_done),
@@ -769,7 +774,6 @@ e_gdbus_book_proxy_init (EGdbusBookProxy *proxy)
proxy->priv->pending_ops = e_gdbus_async_op_keeper_create_pending_ops (E_GDBUS_ASYNC_OP_KEEPER (proxy));
E_GDBUS_CONNECT_METHOD_DONE_SIGNAL_VOID (open);
- E_GDBUS_CONNECT_METHOD_DONE_SIGNAL_VOID (authenticate_user);
E_GDBUS_CONNECT_METHOD_DONE_SIGNAL_VOID (remove);
E_GDBUS_CONNECT_METHOD_DONE_SIGNAL_STRING (get_contact);
E_GDBUS_CONNECT_METHOD_DONE_SIGNAL_STRV (get_contact_list);
diff --git a/addressbook/libegdbus/e-gdbus-book.h b/addressbook/libegdbus/e-gdbus-book.h
index 6223cce..0249539 100644
--- a/addressbook/libegdbus/e-gdbus-book.h
+++ b/addressbook/libegdbus/e-gdbus-book.h
@@ -116,14 +116,12 @@ struct _EGdbusBookIface
void (*readonly) (EGdbusBook *object, gboolean arg_is_readonly);
void (*online) (EGdbusBook *object, gboolean arg_is_online);
void (*auth_required) (EGdbusBook *object, const gchar * const *arg_credentials);
+ void (*opened) (EGdbusBook *object, const gchar * const *arg_error);
/* Signal handlers for handling D-Bus method calls: */
gboolean (*handle_open) (EGdbusBook *object, GDBusMethodInvocation *invocation, gboolean in_only_if_exists);
void (*open_done) (EGdbusBook *object, guint arg_opid, const GError *arg_error);
- gboolean (*handle_authenticate_user) (EGdbusBook *object, GDBusMethodInvocation *invocation, const gchar * const *in_credentials);
- void (*authenticate_user_done) (EGdbusBook *object, guint arg_opid, const GError *arg_error);
-
gboolean (*handle_remove) (EGdbusBook *object, GDBusMethodInvocation *invocation);
void (*remove_done) (EGdbusBook *object, guint arg_opid, const GError *arg_error);
@@ -151,6 +149,7 @@ struct _EGdbusBookIface
gboolean (*handle_get_view) (EGdbusBook *object, GDBusMethodInvocation *invocation, const gchar *in_query);
void (*get_view_done) (EGdbusBook *object, guint arg_opid, const GError *arg_error, gchar **out_view);
+ gboolean (*handle_authenticate_user) (EGdbusBook *object, GDBusMethodInvocation *invocation, const gchar * const *in_credentials);
gboolean (*handle_cancel_operation) (EGdbusBook *object, GDBusMethodInvocation *invocation, guint in_opid);
gboolean (*handle_cancel_all) (EGdbusBook *object, GDBusMethodInvocation *invocation);
gboolean (*handle_close) (EGdbusBook *object, GDBusMethodInvocation *invocation);
@@ -164,10 +163,6 @@ void e_gdbus_book_call_open (GDBusProxy *proxy, gboolean in_only_if_exists, GCa
gboolean e_gdbus_book_call_open_finish (GDBusProxy *proxy, GAsyncResult *result, GError **error);
gboolean e_gdbus_book_call_open_sync (GDBusProxy *proxy, gboolean in_only_if_exists, GCancellable *cancellable, GError **error);
-void e_gdbus_book_call_authenticate_user (GDBusProxy *proxy, const gchar * const *in_credentials, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
-gboolean e_gdbus_book_call_authenticate_user_finish (GDBusProxy *proxy, GAsyncResult *result, GError **error);
-gboolean e_gdbus_book_call_authenticate_user_sync (GDBusProxy *proxy, const gchar * const *in_credentials, GCancellable *cancellable, GError **error);
-
void e_gdbus_book_call_remove (GDBusProxy *proxy, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
gboolean e_gdbus_book_call_remove_finish (GDBusProxy *proxy, GAsyncResult *result, GError **error);
gboolean e_gdbus_book_call_remove_sync (GDBusProxy *proxy, GCancellable *cancellable, GError **error);
@@ -206,6 +201,10 @@ void e_gdbus_book_call_get_view (GDBusProxy *proxy, const gchar *in_query, GCan
gboolean e_gdbus_book_call_get_view_finish (GDBusProxy *proxy, GAsyncResult *result, gchar **out_view_path, GError **error);
gboolean e_gdbus_book_call_get_view_sync (GDBusProxy *proxy, const gchar *in_query, gchar **out_view_path, GCancellable *cancellable, GError **error);
+void e_gdbus_book_call_authenticate_user (GDBusProxy *proxy, const gchar * const *in_credentials, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
+gboolean e_gdbus_book_call_authenticate_user_finish (GDBusProxy *proxy, GAsyncResult *result, GError **error);
+gboolean e_gdbus_book_call_authenticate_user_sync (GDBusProxy *proxy, const gchar * const *in_credentials, GCancellable *cancellable, GError **error);
+
void e_gdbus_book_call_cancel_operation (GDBusProxy *proxy, guint in_opid, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
gboolean e_gdbus_book_call_cancel_operation_finish (GDBusProxy *proxy, GAsyncResult *result, GError **error);
gboolean e_gdbus_book_call_cancel_operation_sync (GDBusProxy *proxy, guint in_opid, GCancellable *cancellable, GError **error);
@@ -220,7 +219,6 @@ gboolean e_gdbus_book_call_close_sync (GDBusProxy *proxy, GCancellable *cancella
/* D-Bus Methods Completion Helpers */
#define e_gdbus_book_complete_open e_gdbus_complete_async_method
-#define e_gdbus_book_complete_authenticate_user e_gdbus_complete_async_method
#define e_gdbus_book_complete_remove e_gdbus_complete_async_method
#define e_gdbus_book_complete_get_contact e_gdbus_complete_async_method
#define e_gdbus_book_complete_get_contact_list e_gdbus_complete_async_method
@@ -230,12 +228,12 @@ gboolean e_gdbus_book_call_close_sync (GDBusProxy *proxy, GCancellable *cancella
#define e_gdbus_book_complete_get_backend_property e_gdbus_complete_async_method
#define e_gdbus_book_complete_set_backend_property e_gdbus_complete_async_method
#define e_gdbus_book_complete_get_view e_gdbus_complete_async_method
+#define e_gdbus_book_complete_authenticate_user e_gdbus_complete_sync_method_void
#define e_gdbus_book_complete_cancel_operation e_gdbus_complete_sync_method_void
#define e_gdbus_book_complete_cancel_all e_gdbus_complete_sync_method_void
#define e_gdbus_book_complete_close e_gdbus_complete_sync_method_void
void e_gdbus_book_emit_open_done (EGdbusBook *object, guint arg_opid, const GError *arg_error);
-void e_gdbus_book_emit_authenticate_user_done (EGdbusBook *object, guint arg_opid, const GError *arg_error);
void e_gdbus_book_emit_remove_done (EGdbusBook *object, guint arg_opid, const GError *arg_error);
void e_gdbus_book_emit_get_contact_done (EGdbusBook *object, guint arg_opid, const GError *arg_error, const gchar *out_vcard);
void e_gdbus_book_emit_get_contact_list_done (EGdbusBook *object, guint arg_opid, const GError *arg_error, const gchar * const *out_vcards);
@@ -251,6 +249,7 @@ void e_gdbus_book_emit_backend_error (EGdbusBook *object, const gchar *arg_messa
void e_gdbus_book_emit_readonly (EGdbusBook *object, gboolean arg_is_readonly);
void e_gdbus_book_emit_online (EGdbusBook *object, gboolean arg_is_online);
void e_gdbus_book_emit_auth_required (EGdbusBook *object, const gchar * const *arg_credentials);
+void e_gdbus_book_emit_opened (EGdbusBook *object, const gchar * const *arg_error);
G_END_DECLS
diff --git a/calendar/backends/caldav/e-cal-backend-caldav.c b/calendar/backends/caldav/e-cal-backend-caldav.c
index 20020a7..0eca575 100644
--- a/calendar/backends/caldav/e-cal-backend-caldav.c
+++ b/calendar/backends/caldav/e-cal-backend-caldav.c
@@ -2485,16 +2485,18 @@ caldav_do_open (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellab
if (g_error_matches (local_error, E_DATA_CAL_ERROR, AuthenticationRequired) || g_error_matches (local_error, E_DATA_CAL_ERROR, AuthenticationFailed)) {
g_clear_error (&local_error);
- e_cal_backend_notify_auth_required (E_CAL_BACKEND (cbdav), priv->credentials);
+ e_cal_backend_notify_auth_required (E_CAL_BACKEND (cbdav), TRUE, priv->credentials);
+ } else {
+ e_cal_backend_notify_opened (E_CAL_BACKEND (backend), NULL);
}
if (local_error)
g_propagate_error (perror, local_error);
} else {
priv->read_only = TRUE;
+ e_cal_backend_notify_opened (E_CAL_BACKEND (backend), NULL);
}
- e_cal_backend_set_is_loaded (E_CAL_BACKEND (backend), priv->loaded);
e_cal_backend_notify_readonly (E_CAL_BACKEND (backend), priv->read_only);
e_cal_backend_notify_online (E_CAL_BACKEND (backend), priv->is_online);
@@ -2502,7 +2504,7 @@ caldav_do_open (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellab
}
static void
-caldav_authenticate_user (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, ECredentials *credentials, GError **error)
+caldav_authenticate_user (ECalBackendSync *backend, GCancellable *cancellable, ECredentials *credentials, GError **error)
{
ECalBackendCalDAV *cbdav;
ECalBackendCalDAVPrivate *priv;
@@ -2517,7 +2519,7 @@ caldav_authenticate_user (ECalBackendSync *backend, EDataCal *cal, GCancellable
if (!credentials || !e_credentials_has_key (credentials, E_CREDENTIALS_KEY_USERNAME)) {
g_mutex_unlock (priv->busy_lock);
- g_propagate_error (error, EDC_ERROR (AuthenticationFailed));
+ g_propagate_error (error, EDC_ERROR (AuthenticationRequired));
return;
}
@@ -2592,8 +2594,6 @@ caldav_remove (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellabl
g_cond_wait (priv->slave_gone_cond, priv->busy_lock);
}
- e_cal_backend_set_is_loaded (E_CAL_BACKEND (backend), priv->loaded);
-
g_mutex_unlock (priv->busy_lock);
}
diff --git a/calendar/backends/contacts/e-cal-backend-contacts.c b/calendar/backends/contacts/e-cal-backend-contacts.c
index 42052e3..366a229 100644
--- a/calendar/backends/contacts/e-cal-backend-contacts.c
+++ b/calendar/backends/contacts/e-cal-backend-contacts.c
@@ -978,13 +978,14 @@ e_cal_backend_contacts_open (ECalBackendSync *backend, EDataCal *cal, GCancellab
g_error_free (error);
g_propagate_error (perror, EDC_ERROR (OtherError));
+ e_cal_backend_notify_opened (E_CAL_BACKEND (backend), EDC_ERROR (OtherError));
return;
}
priv->addressbook_loaded = TRUE;
- e_cal_backend_set_is_loaded (E_CAL_BACKEND (backend), TRUE);
e_cal_backend_notify_readonly (E_CAL_BACKEND (backend), TRUE);
e_cal_backend_notify_online (E_CAL_BACKEND (backend), TRUE);
+ e_cal_backend_notify_opened (E_CAL_BACKEND (backend), NULL);
}
/* Add_timezone handler for the file backend */
diff --git a/calendar/backends/file/e-cal-backend-file.c b/calendar/backends/file/e-cal-backend-file.c
index b1189ee..956862a 100644
--- a/calendar/backends/file/e-cal-backend-file.c
+++ b/calendar/backends/file/e-cal-backend-file.c
@@ -983,8 +983,6 @@ open_cal (ECalBackendFile *cbfile, const gchar *uristr, GError **perror)
scan_vcalendar (cbfile);
prepare_refresh_data (cbfile);
-
- e_cal_backend_set_is_loaded (E_CAL_BACKEND (cbfile), TRUE);
}
typedef struct
@@ -1141,8 +1139,6 @@ reload_cal (ECalBackendFile *cbfile, const gchar *uristr, GError **perror)
/* Free old data */
free_calendar_components (comp_uid_hash_old, icalcomp_old);
-
- e_cal_backend_set_is_loaded (E_CAL_BACKEND (cbfile), TRUE);
}
static void
@@ -1179,8 +1175,6 @@ create_cal (ECalBackendFile *cbfile, const gchar *uristr, GError **perror)
g_free (priv->custom_file);
priv->custom_file = g_strdup (uristr);
prepare_refresh_data (cbfile);
-
- e_cal_backend_set_is_loaded (E_CAL_BACKEND (cbfile), TRUE);
}
static gchar *
@@ -1290,7 +1284,9 @@ e_cal_backend_file_open (ECalBackendSync *backend, EDataCal *cal, GCancellable *
e_cal_backend_notify_online (E_CAL_BACKEND (backend), TRUE);
if (err)
- g_propagate_error (perror, err);
+ g_propagate_error (perror, g_error_copy (err));
+
+ e_cal_backend_notify_opened (E_CAL_BACKEND (backend), err);
}
static void
diff --git a/calendar/backends/groupwise/e-cal-backend-groupwise.c b/calendar/backends/groupwise/e-cal-backend-groupwise.c
index 413ffe0..3f54c05 100644
--- a/calendar/backends/groupwise/e-cal-backend-groupwise.c
+++ b/calendar/backends/groupwise/e-cal-backend-groupwise.c
@@ -1150,7 +1150,6 @@ connect_to_server (ECalBackendGroupwise *cbgw, GError **perror)
}
e_cal_backend_store_load (priv->store);
- e_cal_backend_set_is_loaded (E_CAL_BACKEND (backend), TRUE);
/* spawn a new thread for opening the calendar */
thread = g_thread_create ((GThreadFunc) cache_init, cbgw, FALSE, &error);
@@ -1378,6 +1377,7 @@ e_cal_backend_groupwise_open (ECalBackendSync *backend, EDataCal *cal, GCancella
if (!display_contents || !g_str_equal (display_contents, "1")) {
PRIV_UNLOCK (priv);
g_propagate_error (perror, EDC_ERROR (RepositoryOffline));
+ e_cal_backend_notify_opened (E_CAL_BACKEND (backend), EDC_ERROR (RepositoryOffline));
return;
}
@@ -1388,26 +1388,35 @@ e_cal_backend_groupwise_open (ECalBackendSync *backend, EDataCal *cal, GCancella
if (!priv->store) {
PRIV_UNLOCK (priv);
g_propagate_error (perror, EDC_ERROR_EX (OtherError, _("Could not create cache file")));
+ e_cal_backend_notify_opened (E_CAL_BACKEND (backend), EDC_ERROR_EX (OtherError, _("Could not create cache file")));
return;
}
}
e_cal_backend_store_load (priv->store);
- e_cal_backend_set_is_loaded (E_CAL_BACKEND (backend), TRUE);
+ e_cal_backend_notify_opened (E_CAL_BACKEND (backend), NULL);
PRIV_UNLOCK (priv);
return;
}
- if (priv->credentials)
- connect_to_server (cbgw, perror);
- else
- e_cal_backend_notify_auth_required (E_CAL_BACKEND (cbgw), priv->credentials);
+ if (priv->credentials) {
+ GError *local_error = NULL;
+
+ connect_to_server (cbgw, &local_error);
+
+ if (!local_error)
+ e_cal_backend_notify_opened (E_CAL_BACKEND (backend), NULL);
+ else
+ g_propagate_error (perror, local_error);
+ } else {
+ e_cal_backend_notify_auth_required (E_CAL_BACKEND (cbgw), TRUE, priv->credentials);
+ }
PRIV_UNLOCK (priv);
}
static void
-e_cal_backend_groupwise_authenticate_user (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, ECredentials *credentials, GError **error)
+e_cal_backend_groupwise_authenticate_user (ECalBackendSync *backend, GCancellable *cancellable, ECredentials *credentials, GError **error)
{
ECalBackendGroupwise *cbgw;
ECalBackendGroupwisePrivate *priv;
@@ -1474,8 +1483,8 @@ e_cal_backend_groupwise_set_online (ECalBackend *backend, gboolean is_online)
priv->read_only = FALSE;
e_cal_backend_notify_online (backend, priv->is_online);
e_cal_backend_notify_readonly (backend, priv->read_only);
- if (e_cal_backend_is_loaded (backend))
- e_cal_backend_notify_auth_required (backend, priv->credentials);
+ if (e_cal_backend_is_opened (backend))
+ e_cal_backend_notify_auth_required (backend, TRUE, priv->credentials);
} else {
/* FIXME: make sure we update the cache before closing the connection */
in_offline (cbgw);
diff --git a/calendar/backends/http/e-cal-backend-http.c b/calendar/backends/http/e-cal-backend-http.c
index 41becd9..b187587 100644
--- a/calendar/backends/http/e-cal-backend-http.c
+++ b/calendar/backends/http/e-cal-backend-http.c
@@ -414,7 +414,7 @@ retrieval_done (SoupSession *session, SoupMessage *msg, ECalBackendHttp *cbhttp)
if (!priv->opened) {
if (msg->status_code == 401 || msg->status_code == 403) {
priv->requires_auth = TRUE;
- e_cal_backend_notify_auth_required (E_CAL_BACKEND (cbhttp), priv->credentials);
+ e_cal_backend_notify_auth_required (E_CAL_BACKEND (cbhttp), TRUE, priv->credentials);
return;
} else
e_cal_backend_notify_error (E_CAL_BACKEND (cbhttp),
@@ -730,8 +730,10 @@ e_cal_backend_http_open (ECalBackendSync *backend, EDataCal *cal, GCancellable *
priv = cbhttp->priv;
/* already opened, thus can skip all this initialization */
- if (priv->opened)
+ if (priv->opened) {
+ e_cal_backend_notify_opened (E_CAL_BACKEND (backend), NULL);
return;
+ }
source = e_cal_backend_get_source (E_CAL_BACKEND (backend));
@@ -756,26 +758,31 @@ e_cal_backend_http_open (ECalBackendSync *backend, EDataCal *cal, GCancellable *
if (!priv->store) {
g_propagate_error (perror, EDC_ERROR_EX (OtherError, _("Could not create cache file")));
+ e_cal_backend_notify_opened (E_CAL_BACKEND (backend), EDC_ERROR_EX (OtherError, _("Could not create cache file")));
return;
}
}
- e_cal_backend_set_is_loaded (E_CAL_BACKEND (backend), TRUE);
e_cal_backend_notify_readonly (E_CAL_BACKEND (backend), TRUE);
e_cal_backend_notify_online (E_CAL_BACKEND (backend), priv->is_online);
if (priv->is_online) {
- if (e_source_get_property (source, "auth"))
- e_cal_backend_notify_auth_required (E_CAL_BACKEND (cbhttp), priv->credentials);
- else if (priv->requires_auth && perror && !*perror)
+ if (e_source_get_property (source, "auth")) {
+ e_cal_backend_notify_auth_required (E_CAL_BACKEND (cbhttp), TRUE, priv->credentials);
+ } else if (priv->requires_auth && perror && !*perror) {
g_propagate_error (perror, EDC_ERROR (AuthenticationRequired));
- else
+ e_cal_backend_notify_opened (E_CAL_BACKEND (backend), EDC_ERROR (AuthenticationRequired));
+ } else {
+ e_cal_backend_notify_opened (E_CAL_BACKEND (backend), NULL);
g_idle_add ((GSourceFunc) begin_retrieval_cb, cbhttp);
+ }
+ } else {
+ e_cal_backend_notify_opened (E_CAL_BACKEND (backend), NULL);
}
}
static void
-e_cal_backend_http_authenticate_user (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, ECredentials *credentials, GError **error)
+e_cal_backend_http_authenticate_user (ECalBackendSync *backend, GCancellable *cancellable, ECredentials *credentials, GError **error)
{
ECalBackendHttp *cbhttp;
ECalBackendHttpPrivate *priv;
@@ -784,7 +791,7 @@ e_cal_backend_http_authenticate_user (ECalBackendSync *backend, EDataCal *cal, G
priv = cbhttp->priv;
if (priv->credentials && credentials && e_credentials_equal_keys (priv->credentials, credentials, E_CREDENTIALS_KEY_USERNAME, E_CREDENTIALS_KEY_PASSWORD, NULL)) {
- g_propagate_error (error, EDC_ERROR (AuthenticationFailed));
+ g_propagate_error (error, EDC_ERROR (AuthenticationRequired));
return;
}
@@ -792,7 +799,7 @@ e_cal_backend_http_authenticate_user (ECalBackendSync *backend, EDataCal *cal, G
priv->credentials = NULL;
if (!credentials || !e_credentials_has_key (credentials, E_CREDENTIALS_KEY_USERNAME)) {
- g_propagate_error (error, EDC_ERROR (AuthenticationFailed));
+ g_propagate_error (error, EDC_ERROR (AuthenticationRequired));
return;
}
@@ -848,7 +855,7 @@ e_cal_backend_http_set_online (ECalBackend *backend, gboolean is_online)
cbhttp = E_CAL_BACKEND_HTTP (backend);
priv = cbhttp->priv;
- loaded = e_cal_backend_is_loaded (backend);
+ loaded = e_cal_backend_is_opened (backend);
if ((priv->is_online ? 1 : 0) != (is_online ? 1 : 0)) {
priv->is_online = is_online;
diff --git a/calendar/backends/weather/e-cal-backend-weather.c b/calendar/backends/weather/e-cal-backend-weather.c
index 98657ef..a17cb94 100644
--- a/calendar/backends/weather/e-cal-backend-weather.c
+++ b/calendar/backends/weather/e-cal-backend-weather.c
@@ -514,7 +514,7 @@ e_cal_backend_weather_open (ECalBackendSync *backend, EDataCal *cal, GCancellabl
/* do we require to load this new store */
e_cal_backend_store_load (priv->store);
- e_cal_backend_set_is_loaded (E_CAL_BACKEND (backend), TRUE);
+ e_cal_backend_notify_opened (E_CAL_BACKEND (backend), NULL);
if (!priv->is_online)
return;
@@ -523,7 +523,7 @@ e_cal_backend_weather_open (ECalBackendSync *backend, EDataCal *cal, GCancellabl
priv->begin_retrival_id = g_idle_add ((GSourceFunc) begin_retrieval_cb, cbw);
}
- e_cal_backend_set_is_loaded (E_CAL_BACKEND (backend), TRUE);
+ e_cal_backend_notify_opened (E_CAL_BACKEND (backend), NULL);
}
static void
@@ -740,7 +740,7 @@ e_cal_backend_weather_set_online (ECalBackend *backend, gboolean is_online)
cbw = E_CAL_BACKEND_WEATHER (backend);
priv = cbw->priv;
- loaded = e_cal_backend_is_loaded (backend);
+ loaded = e_cal_backend_is_opened (backend);
if ((priv->is_online ? 1: 0) != (is_online ? 1 : 0)) {
priv->is_online = is_online;
diff --git a/calendar/libecal/e-cal-client-view.c b/calendar/libecal/e-cal-client-view.c
index 1ffb0ff..8a56e76 100644
--- a/calendar/libecal/e-cal-client-view.c
+++ b/calendar/libecal/e-cal-client-view.c
@@ -182,14 +182,14 @@ progress_cb (EGdbusCalView *gdbus_calview, guint percent, const gchar *message,
static void
complete_cb (EGdbusCalView *gdbus_calview, const gchar * const *arg_error, ECalClientView *view)
{
- GError *error;
+ GError *error = NULL;
g_return_if_fail (E_IS_CAL_CLIENT_VIEW (view));
if (!view->priv->running)
return;
- error = e_gdbus_cal_view_decode_error (arg_error);
+ g_return_if_fail (e_gdbus_templates_decode_error (arg_error, &error));
g_signal_emit (G_OBJECT (view), signals[COMPLETE], 0, error);
@@ -493,7 +493,7 @@ e_cal_client_view_stop (ECalClientView *view, GError **error)
*
* Client can instruct server to which fields it is interested in only, thus
* the server can return less data over the wire. The server can still return
- * complete objects, this is just a hint to it that the listef fields will
+ * complete objects, this is just a hint to it that the listed fields will
* be used only. The UID/RID fields are returned always. Initial views has
* no restriction, and using %NULL for @only_fields will unset any previous
* changes.
diff --git a/calendar/libecal/e-cal-client.c b/calendar/libecal/e-cal-client.c
index 3cb33f1..9b5c47a 100644
--- a/calendar/libecal/e-cal-client.c
+++ b/calendar/libecal/e-cal-client.c
@@ -76,7 +76,7 @@ G_DEFINE_TYPE (ECalClient, e_cal_client, E_TYPE_CLIENT)
* Preferred way of retrieving this property is by
* calling e_cal_client_get_default_object().
*
- * See also: @CLIENT_BACKEND_PROPERTY_LOADED,
+ * See also: @CLIENT_BACKEND_PROPERTY_OPENED, @CLIENT_BACKEND_PROPERTY_OPENING,
* @CLIENT_BACKEND_PROPERTY_ONLINE, @CLIENT_BACKEND_PROPERTY_READONLY
* @CLIENT_BACKEND_PROPERTY_CACHE_DIR, @CLIENT_BACKEND_PROPERTY_CAPABILITIES
**/
@@ -157,6 +157,7 @@ unwrap_dbus_error (GError *error, GError **client_error)
{ err ("NoSuchCal", E_CAL_CLIENT_ERROR_NO_SUCH_CALENDAR) },
{ err ("UnknownUser", E_CAL_CLIENT_ERROR_UNKNOWN_USER) },
}, cl_errors[] = {
+ { err ("Busy", E_CLIENT_ERROR_BUSY) },
{ err ("InvalidArg", E_CLIENT_ERROR_INVALID_ARG) },
{ err ("RepositoryOffline", E_CLIENT_ERROR_REPOSITORY_OFFLINE) },
{ err ("PermissionDenied", E_CLIENT_ERROR_PERMISSION_DENIED) },
@@ -403,6 +404,22 @@ auth_required_cb (EGdbusCal *object, const gchar * const *credentials_strv, ECal
}
static void
+opened_cb (EGdbusCal *object, const gchar * const *error_strv, ECalClient *client)
+{
+ GError *error = NULL;
+
+ g_return_if_fail (client != NULL);
+ g_return_if_fail (E_IS_CAL_CLIENT (client));
+ g_return_if_fail (error_strv != NULL);
+ g_return_if_fail (e_gdbus_templates_decode_error (error_strv, &error));
+
+ e_client_emit_opened (E_CLIENT (client), error);
+
+ if (error)
+ g_error_free (error);
+}
+
+static void
free_busy_data_cb (EGdbusCal *object, const gchar * const *free_busy_strv, ECalClient *client)
{
GSList *ecalcomps = NULL;
@@ -570,6 +587,7 @@ e_cal_client_new (ESource *source, ECalClientSourceType source_type, GError **er
g_signal_connect (client->priv->gdbus_cal, "readonly", G_CALLBACK (readonly_cb), client);
g_signal_connect (client->priv->gdbus_cal, "online", G_CALLBACK (online_cb), client);
g_signal_connect (client->priv->gdbus_cal, "auth-required", G_CALLBACK (auth_required_cb), client);
+ g_signal_connect (client->priv->gdbus_cal, "opened", G_CALLBACK (opened_cb), client);
g_signal_connect (client->priv->gdbus_cal, "free-busy-data", G_CALLBACK (free_busy_data_cb), client);
return client;
diff --git a/calendar/libecal/e-cal-view.c b/calendar/libecal/e-cal-view.c
index 3302198..a7dcd22 100644
--- a/calendar/libecal/e-cal-view.c
+++ b/calendar/libecal/e-cal-view.c
@@ -165,11 +165,11 @@ progress_cb (EGdbusCalView *gdbus_calview, guint percent, const gchar *message,
static void
complete_cb (EGdbusCalView *gdbus_calview, const gchar * const *arg_error, ECalView *view)
{
- GError *error;
+ GError *error = NULL;
g_return_if_fail (E_IS_CAL_VIEW (view));
- error = e_gdbus_cal_view_decode_error (arg_error);
+ g_return_if_fail (e_gdbus_templates_decode_error (arg_error, &error));
#ifndef E_CAL_DISABLE_DEPRECATED
g_signal_emit (G_OBJECT (view), signals[VIEW_DONE], 0, error ? error->code : 0);
diff --git a/calendar/libecal/e-cal.c b/calendar/libecal/e-cal.c
index 9a2d37c..7d70e98 100644
--- a/calendar/libecal/e-cal.c
+++ b/calendar/libecal/e-cal.c
@@ -230,6 +230,7 @@ get_status_from_error (const GError *error)
ECalendarStatus err_code;
} errors[] = {
{ err ("Success", E_CALENDAR_STATUS_OK) },
+ { err ("Busy", E_CALENDAR_STATUS_BUSY) },
{ err ("RepositoryOffline", E_CALENDAR_STATUS_REPOSITORY_OFFLINE) },
{ err ("PermissionDenied", E_CALENDAR_STATUS_PERMISSION_DENIED) },
{ err ("InvalidRange", E_CALENDAR_STATUS_OTHER_ERROR) },
diff --git a/calendar/libedata-cal/e-cal-backend-sync.c b/calendar/libedata-cal/e-cal-backend-sync.c
index b214c4a..5c06864 100644
--- a/calendar/libedata-cal/e-cal-backend-sync.c
+++ b/calendar/libedata-cal/e-cal-backend-sync.c
@@ -81,7 +81,6 @@ e_cal_backend_sync_open (ECalBackendSync *backend, EDataCal *cal, GCancellable *
/**
* e_cal_backend_sync_authenticate_user:
* @backend: an #ECalBackendSync
- * @cal: an #EDataCal
* @cancellable: a #GCancellable for the operation
* @credentials: an #ECredentials to authenticate with
* @error: #GError to set, when something fails
@@ -89,13 +88,12 @@ e_cal_backend_sync_open (ECalBackendSync *backend, EDataCal *cal, GCancellable *
* Authenticates @backend with given @credentials.
**/
void
-e_cal_backend_sync_authenticate_user (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, ECredentials *credentials, GError **error)
+e_cal_backend_sync_authenticate_user (ECalBackendSync *backend, GCancellable *cancellable, ECredentials *credentials, GError **error)
{
e_return_data_cal_error_if_fail (E_IS_CAL_BACKEND_SYNC (backend), InvalidArg);
- e_return_data_cal_error_if_fail (E_IS_DATA_CAL (cal), InvalidArg);
e_return_data_cal_error_if_fail (credentials, InvalidArg);
- LOCK_WRAPPER (authenticate_user_sync, (backend, cal, cancellable, credentials, error));
+ LOCK_WRAPPER (authenticate_user_sync, (backend, cancellable, credentials, error));
}
/**
@@ -498,13 +496,13 @@ cal_backend_open (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellabl
}
static void
-cal_backend_authenticate_user (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellable *cancellable, ECredentials *credentials)
+cal_backend_authenticate_user (ECalBackend *backend, GCancellable *cancellable, ECredentials *credentials)
{
GError *error = NULL;
- e_cal_backend_sync_authenticate_user (E_CAL_BACKEND_SYNC (backend), cal, cancellable, credentials, &error);
+ e_cal_backend_sync_authenticate_user (E_CAL_BACKEND_SYNC (backend), cancellable, credentials, &error);
- e_data_cal_respond_authenticate_user (cal, opid, error);
+ e_cal_backend_notify_opened (backend, error);
}
static void
diff --git a/calendar/libedata-cal/e-cal-backend-sync.h b/calendar/libedata-cal/e-cal-backend-sync.h
index 17f6cca..a77dc87 100644
--- a/calendar/libedata-cal/e-cal-backend-sync.h
+++ b/calendar/libedata-cal/e-cal-backend-sync.h
@@ -32,7 +32,6 @@ struct _ECalBackendSyncClass {
/* Virtual methods */
void (* open_sync) (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, gboolean only_if_exists, GError **error);
- void (* authenticate_user_sync) (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, ECredentials *credentials, GError **error);
void (* remove_sync) (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, GError **error);
void (* refresh_sync) (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, GError **error);
@@ -50,6 +49,8 @@ struct _ECalBackendSyncClass {
void (* discard_alarm_sync) (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const gchar *uid, const gchar *rid, const gchar *auid, GError **error);
void (* get_timezone_sync) (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const gchar *tzid, gchar **tzobject, GError **error);
void (* add_timezone_sync) (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const gchar *tzobject, GError **error);
+
+ void (* authenticate_user_sync) (ECalBackendSync *backend, GCancellable *cancellable, ECredentials *credentials, GError **error);
};
GType e_cal_backend_sync_get_type (void);
@@ -57,7 +58,6 @@ GType e_cal_backend_sync_get_type (void);
void e_cal_backend_sync_set_lock (ECalBackendSync *backend, gboolean lock);
void e_cal_backend_sync_open (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, gboolean only_if_exists, GError **error);
-void e_cal_backend_sync_authenticate_user (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, ECredentials *credentials, GError **error);
void e_cal_backend_sync_remove (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, GError **error);
void e_cal_backend_sync_refresh (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, GError **error);
gboolean e_cal_backend_sync_get_backend_property(ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const gchar *prop_name, gchar **prop_value, GError **error);
@@ -75,6 +75,8 @@ void e_cal_backend_sync_discard_alarm (ECalBackendSync *backend, EDataCal *cal,
void e_cal_backend_sync_get_timezone (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const gchar *tzid, gchar **tzobject, GError **error);
void e_cal_backend_sync_add_timezone (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const gchar *tzobject, GError **error);
+void e_cal_backend_sync_authenticate_user (ECalBackendSync *backend, GCancellable *cancellable, ECredentials *credentials, GError **error);
+
G_END_DECLS
#endif /* __E_CAL_BACKEND_SYNC_H__ */
diff --git a/calendar/libedata-cal/e-cal-backend.c b/calendar/libedata-cal/e-cal-backend.c
index 7823d58..3349770 100644
--- a/calendar/libedata-cal/e-cal-backend.c
+++ b/calendar/libedata-cal/e-cal-backend.c
@@ -31,6 +31,7 @@
#include "e-cal-backend-cache.h"
#define EDC_ERROR(_code) e_data_cal_create_error (_code, NULL)
+#define EDC_OPENING_ERROR e_data_cal_create_error (Busy, _("Cannot process, calendar backend is opening"))
/* Private part of the CalBackend structure */
struct _ECalBackendPrivate {
@@ -39,7 +40,7 @@ struct _ECalBackendPrivate {
/* The kind of components for this backend */
icalcomponent_kind kind;
- gboolean loaded, readonly, removed, online;
+ gboolean opening, opened, readonly, removed, online;
/* URI, from source. This is cached, since we return const. */
gchar *uri;
@@ -192,8 +193,10 @@ cal_backend_get_backend_property (ECalBackend *backend, EDataCal *cal, guint32 o
g_return_if_fail (cal != NULL);
g_return_if_fail (prop_name != NULL);
- if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_LOADED)) {
- e_data_cal_respond_get_backend_property (cal, opid, NULL, e_cal_backend_is_loaded (backend) ? "TRUE" : "FALSE");
+ if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_OPENED)) {
+ e_data_cal_respond_get_backend_property (cal, opid, NULL, e_cal_backend_is_opened (backend) ? "TRUE" : "FALSE");
+ } else if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_OPENING)) {
+ e_data_cal_respond_get_backend_property (cal, opid, NULL, e_cal_backend_is_opening (backend) ? "TRUE" : "FALSE");
} else if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_ONLINE)) {
e_data_cal_respond_get_backend_property (cal, opid, NULL, e_cal_backend_is_online (backend) ? "TRUE" : "FALSE");
} else if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_READONLY)) {
@@ -399,7 +402,6 @@ e_cal_backend_init (ECalBackend *backend)
backend->priv->views = NULL;
backend->priv->views_mutex = g_mutex_new ();
- backend->priv->loaded = FALSE;
backend->priv->readonly = TRUE;
backend->priv->online = FALSE;
}
@@ -468,32 +470,43 @@ e_cal_backend_is_online (ECalBackend *backend)
}
/**
- * e_cal_backend_is_loaded:
+ * e_cal_backend_is_opened:
* @backend: an #ECalBackend
*
- * Returns: Whether is backend already loaded.
+ * Checks if @backend's storage has been opened (and
+ * authenticated, if necessary) and the backend itself
+ * is ready for accessing. This property is changed automatically
+ * within call of e_cal_backend_notify_opened().
+ *
+ * Returns: %TRUE if fully opened, %FALSE otherwise.
**/
gboolean
-e_cal_backend_is_loaded (ECalBackend *backend)
+e_cal_backend_is_opened (ECalBackend *backend)
{
g_return_val_if_fail (E_IS_CAL_BACKEND (backend), FALSE);
- return backend->priv->loaded;
+ return backend->priv->opened;
}
/**
- * e_cal_backend_set_is_loaded:
+ * e_cal_backend_is_opening::
* @backend: an #ECalBackend
*
- * Stores value for e_cal_backend_is_loaded().
- * Meant to be used by backend implementations.
+ * Checks if @backend is processing its opening phase, which
+ * includes everything since the e_cal_backend_open() call,
+ * through authentication, up to e_cal_backend_notify_opened().
+ * This property is managed automatically and the backend deny
+ * every operation except of cancel and authenticate_user while
+ * it is being opening.
+ *
+ * Returns: %TRUE if opening phase is in the effect, %FALSE otherwise.
**/
-void
-e_cal_backend_set_is_loaded (ECalBackend *backend, gboolean is_loaded)
+gboolean
+e_cal_backend_is_opening (ECalBackend *backend)
{
- g_return_if_fail (E_IS_CAL_BACKEND (backend));
+ g_return_val_if_fail (E_IS_CAL_BACKEND (backend), FALSE);
- backend->priv->loaded = is_loaded;
+ return backend->priv->opening;
}
/**
@@ -840,7 +853,50 @@ e_cal_backend_set_online (ECalBackend *backend, gboolean is_online)
* does not exist.
*
* Opens a calendar backend with data from a calendar stored at the specified URI.
- * This might be finished with e_data_cal_respond_open().
+ * This might be finished with e_data_cal_respond_open() or e_cal_backend_respond_opened(),
+ * though the overall opening phase finishes only after call
+ * of e_cal_backend_notify_opened() after which call the backend
+ * is either fully opened (including authentication against (remote)
+ * server/storage) or an error was encountered during this opening phase.
+ * 'opened' and 'opening' properties are updated automatically.
+ * The backend refuses all other operations until the opening phase is finished.
+ *
+ * The e_cal_backend_notify_opened() is called either from this function
+ * or from e_cal_backend_authenticate_user(), or after necessary steps
+ * initiated by these two functions.
+ *
+ * The opening phase usually works like this:
+ * 1) client requests open for the backend
+ * 2) server receives this request and calls e_cal_backend_open() - the opening phase begun
+ * 3) either the backend is opened during this call, and notifies client
+ * with e_cal_backend_notify_opened() about that. This is usually
+ * for local backends; their opening phase is finished
+ * 4) or the backend requires authentication, thus it notifies client
+ * about that with e_cal_backend_notify_auth_required() and is
+ * waiting for credentials, which will be received from client
+ * by e_cal_backend_authenticate_user() call. Backend's opening
+ * phase is still running in this case, thus it doesn't call
+ * e_cal_backend_notify_opened() within e_cal_backend_open() call.
+ * 5) when backend receives credentials in e_cal_backend_authenticate_user()
+ * then it tries to authenticate against a server/storage with them
+ * and only after it knows result of the authentication, whether user
+ * was or wasn't authenticated, it notifies client with the result
+ * by e_cal_backend_notify_opened() and it's opening phase is
+ * finished now. If there was no error returned then the backend is
+ * considered opened, otherwise it's considered closed. Use AuthenticationFailed
+ * error when the given credentials were rejected by the server/store, which
+ * will result in a re-prompt on the client side, otherwise use AuthenticationRequired
+ * if there was anything wrong with the given credentials. Set error's
+ * message to a reason for a re-prompt, it'll be shown to a user.
+ * 6) client checks error returned from e_cal_backend_notify_opened() and
+ * reprompts for a password if it was AuthenticationFailed. Otherwise
+ * considers backend opened based on the error presence (no error means success).
+ *
+ * In any case, the call of e_cal_backend_open() should be always finished
+ * with e_data_cal_respond_open(), which has no influence on the opening phase,
+ * or alternatively with e_cal_backend_respond_opened(). Never use authentication
+ * errors in e_data_cal_respond_open() to notify the client the authentication is
+ * required, there is e_cal_backend_notify_auth_required() for this.
**/
void
e_cal_backend_open (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellable *cancellable, gboolean only_if_exists)
@@ -849,35 +905,56 @@ e_cal_backend_open (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancella
g_return_if_fail (E_IS_CAL_BACKEND (backend));
g_return_if_fail (E_CAL_BACKEND_GET_CLASS (backend)->open != NULL);
- (* E_CAL_BACKEND_GET_CLASS (backend)->open) (backend, cal, opid, cancellable, only_if_exists);
+ g_mutex_lock (backend->priv->clients_mutex);
+
+ if (e_cal_backend_is_opened (backend)) {
+ g_mutex_unlock (backend->priv->clients_mutex);
+
+ e_data_cal_report_readonly (cal, backend->priv->readonly);
+ e_data_cal_report_online (cal, backend->priv->online);
+
+ e_cal_backend_respond_opened (backend, cal, opid, NULL);
+ } else if (e_cal_backend_is_opening (backend)) {
+ g_mutex_unlock (backend->priv->clients_mutex);
+
+ e_data_cal_respond_open (cal, opid, EDC_OPENING_ERROR);
+ } else {
+ backend->priv->opening = TRUE;
+ g_mutex_unlock (backend->priv->clients_mutex);
+
+ (* E_CAL_BACKEND_GET_CLASS (backend)->open) (backend, cal, opid, cancellable, only_if_exists);
+ }
}
/**
* e_cal_backend_authenticate_user:
* @backend: an #ECalBackend
- * @cal: an #EDataCal
- * @opid: the ID to use for this operation
* @cancellable: a #GCancellable for the operation
- * @opid: the ID to use for this operation
* @credentials: #ECredentials to use for authentication
*
- * Executes an 'authenticate' request specified by @opid on @cal
- * using @backend.
- * This might be finished with e_data_cal_respond_authenticate_user().
+ * Notifies @backend about @credentials provided by user to use
+ * for authentication. This notification is usually called during
+ * opening phase as a response to e_cal_backend_notify_auth_required()
+ * on the client side and it results in setting property 'opening' to %TRUE
+ * unless the backend is already opened. This function finishes opening
+ * phase, thus it should be finished with e_cal_backend_notify_opened().
+ *
+ * See information at e_cal_backend_open() for more details
+ * how the opening phase works.
**/
void
e_cal_backend_authenticate_user (ECalBackend *backend,
- EDataCal *cal,
- guint32 opid,
GCancellable *cancellable,
ECredentials *credentials)
{
g_return_if_fail (E_IS_CAL_BACKEND (backend));
- g_return_if_fail (E_IS_DATA_CAL (cal));
g_return_if_fail (credentials != NULL);
g_return_if_fail (E_CAL_BACKEND_GET_CLASS (backend)->authenticate_user);
- (* E_CAL_BACKEND_GET_CLASS (backend)->authenticate_user) (backend, cal, opid, cancellable, credentials);
+ if (!e_cal_backend_is_opened (backend))
+ backend->priv->opening = TRUE;
+
+ (* E_CAL_BACKEND_GET_CLASS (backend)->authenticate_user) (backend, cancellable, credentials);
}
/**
@@ -897,7 +974,10 @@ e_cal_backend_remove (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancel
g_return_if_fail (E_IS_CAL_BACKEND (backend));
g_return_if_fail (E_CAL_BACKEND_GET_CLASS (backend)->remove != NULL);
- (* E_CAL_BACKEND_GET_CLASS (backend)->remove) (backend, cal, opid, cancellable);
+ if (e_cal_backend_is_opening (backend))
+ e_data_cal_respond_remove (cal, opid, EDC_OPENING_ERROR);
+ else
+ (* E_CAL_BACKEND_GET_CLASS (backend)->remove) (backend, cal, opid, cancellable);
}
/**
@@ -919,7 +999,10 @@ e_cal_backend_refresh (ECalBackend *backend, EDataCal *cal, guint32 opid, GCance
g_return_if_fail (E_IS_CAL_BACKEND (backend));
g_return_if_fail (E_CAL_BACKEND_GET_CLASS (backend)->refresh != NULL);
- (* E_CAL_BACKEND_GET_CLASS (backend)->refresh) (backend, cal, opid, cancellable);
+ if (e_cal_backend_is_opening (backend))
+ e_data_cal_respond_refresh (cal, opid, EDC_OPENING_ERROR);
+ else
+ (* E_CAL_BACKEND_GET_CLASS (backend)->refresh) (backend, cal, opid, cancellable);
}
/**
@@ -943,7 +1026,10 @@ e_cal_backend_get_object (ECalBackend *backend, EDataCal *cal, guint32 opid, GCa
g_return_if_fail (uid != NULL);
g_return_if_fail (E_CAL_BACKEND_GET_CLASS (backend)->get_object != NULL);
- (* E_CAL_BACKEND_GET_CLASS (backend)->get_object) (backend, cal, opid, cancellable, uid, rid);
+ if (e_cal_backend_is_opening (backend))
+ e_data_cal_respond_get_object (cal, opid, EDC_OPENING_ERROR, NULL);
+ else
+ (* E_CAL_BACKEND_GET_CLASS (backend)->get_object) (backend, cal, opid, cancellable, uid, rid);
}
/**
@@ -964,7 +1050,10 @@ e_cal_backend_get_object_list (ECalBackend *backend, EDataCal *cal, guint32 opid
g_return_if_fail (E_IS_CAL_BACKEND (backend));
g_return_if_fail (E_CAL_BACKEND_GET_CLASS (backend)->get_object_list != NULL);
- (* E_CAL_BACKEND_GET_CLASS (backend)->get_object_list) (backend, cal, opid, cancellable, sexp);
+ if (e_cal_backend_is_opening (backend))
+ e_data_cal_respond_get_object_list (cal, opid, EDC_OPENING_ERROR, NULL);
+ else
+ (* E_CAL_BACKEND_GET_CLASS (backend)->get_object_list) (backend, cal, opid, cancellable, sexp);
}
/**
@@ -990,7 +1079,10 @@ e_cal_backend_get_free_busy (ECalBackend *backend, EDataCal *cal, guint32 opid,
g_return_if_fail (start <= end);
g_return_if_fail (E_CAL_BACKEND_GET_CLASS (backend)->get_free_busy != NULL);
- (* E_CAL_BACKEND_GET_CLASS (backend)->get_free_busy) (backend, cal, opid, cancellable, users, start, end);
+ if (e_cal_backend_is_opening (backend))
+ e_data_cal_respond_get_free_busy (cal, opid, EDC_OPENING_ERROR);
+ else
+ (* E_CAL_BACKEND_GET_CLASS (backend)->get_free_busy) (backend, cal, opid, cancellable, users, start, end);
}
/**
@@ -1011,7 +1103,9 @@ e_cal_backend_create_object (ECalBackend *backend, EDataCal *cal, guint32 opid,
g_return_if_fail (E_IS_CAL_BACKEND (backend));
g_return_if_fail (calobj != NULL);
- if (E_CAL_BACKEND_GET_CLASS (backend)->create_object)
+ if (e_cal_backend_is_opening (backend))
+ e_data_cal_respond_create_object (cal, opid, EDC_OPENING_ERROR, NULL, NULL);
+ else if (E_CAL_BACKEND_GET_CLASS (backend)->create_object)
(* E_CAL_BACKEND_GET_CLASS (backend)->create_object) (backend, cal, opid, cancellable, calobj);
else
e_data_cal_respond_create_object (cal, opid, EDC_ERROR (UnsupportedMethod), NULL, NULL);
@@ -1036,7 +1130,9 @@ e_cal_backend_modify_object (ECalBackend *backend, EDataCal *cal, guint32 opid,
g_return_if_fail (E_IS_CAL_BACKEND (backend));
g_return_if_fail (calobj != NULL);
- if (E_CAL_BACKEND_GET_CLASS (backend)->modify_object)
+ if (e_cal_backend_is_opening (backend))
+ e_data_cal_respond_modify_object (cal, opid, EDC_OPENING_ERROR, NULL, NULL);
+ else if (E_CAL_BACKEND_GET_CLASS (backend)->modify_object)
(* E_CAL_BACKEND_GET_CLASS (backend)->modify_object) (backend, cal, opid, cancellable, calobj, mod);
else
e_data_cal_respond_modify_object (cal, opid, EDC_ERROR (UnsupportedMethod), NULL, NULL);
@@ -1064,7 +1160,10 @@ e_cal_backend_remove_object (ECalBackend *backend, EDataCal *cal, guint32 opid,
g_return_if_fail (uid != NULL);
g_return_if_fail (E_CAL_BACKEND_GET_CLASS (backend)->remove_object != NULL);
- (* E_CAL_BACKEND_GET_CLASS (backend)->remove_object) (backend, cal, opid, cancellable, uid, rid, mod);
+ if (e_cal_backend_is_opening (backend))
+ e_data_cal_respond_remove_object (cal, opid, EDC_OPENING_ERROR, NULL, NULL, NULL);
+ else
+ (* E_CAL_BACKEND_GET_CLASS (backend)->remove_object) (backend, cal, opid, cancellable, uid, rid, mod);
}
/**
@@ -1086,7 +1185,10 @@ e_cal_backend_receive_objects (ECalBackend *backend, EDataCal *cal, guint32 opid
g_return_if_fail (calobj != NULL);
g_return_if_fail (E_CAL_BACKEND_GET_CLASS (backend)->receive_objects != NULL);
- (* E_CAL_BACKEND_GET_CLASS (backend)->receive_objects) (backend, cal, opid, cancellable, calobj);
+ if (e_cal_backend_is_opening (backend))
+ e_data_cal_respond_receive_objects (cal, opid, EDC_OPENING_ERROR);
+ else
+ (* E_CAL_BACKEND_GET_CLASS (backend)->receive_objects) (backend, cal, opid, cancellable, calobj);
}
/**
@@ -1108,7 +1210,10 @@ e_cal_backend_send_objects (ECalBackend *backend, EDataCal *cal, guint32 opid, G
g_return_if_fail (calobj != NULL);
g_return_if_fail (E_CAL_BACKEND_GET_CLASS (backend)->send_objects != NULL);
- (* E_CAL_BACKEND_GET_CLASS (backend)->send_objects) (backend, cal, opid, cancellable, calobj);
+ if (e_cal_backend_is_opening (backend))
+ e_data_cal_respond_send_objects (cal, opid, EDC_OPENING_ERROR, NULL, NULL);
+ else
+ (* E_CAL_BACKEND_GET_CLASS (backend)->send_objects) (backend, cal, opid, cancellable, calobj);
}
/**
@@ -1132,7 +1237,10 @@ e_cal_backend_get_attachment_uris (ECalBackend *backend, EDataCal *cal, guint32
g_return_if_fail (uid != NULL);
g_return_if_fail (E_CAL_BACKEND_GET_CLASS (backend)->get_attachment_uris != NULL);
- (* E_CAL_BACKEND_GET_CLASS (backend)->get_attachment_uris) (backend, cal, opid, cancellable, uid, rid);
+ if (e_cal_backend_is_opening (backend))
+ e_data_cal_respond_get_attachment_uris (cal, opid, EDC_OPENING_ERROR, NULL);
+ else
+ (* E_CAL_BACKEND_GET_CLASS (backend)->get_attachment_uris) (backend, cal, opid, cancellable, uid, rid);
}
/**
@@ -1157,12 +1265,12 @@ e_cal_backend_discard_alarm (ECalBackend *backend, EDataCal *cal, guint32 opid,
g_return_if_fail (uid != NULL);
g_return_if_fail (auid != NULL);
- if (!E_CAL_BACKEND_GET_CLASS (backend)->discard_alarm) {
+ if (e_cal_backend_is_opening (backend))
+ e_data_cal_respond_discard_alarm (cal, opid, EDC_OPENING_ERROR);
+ else if (E_CAL_BACKEND_GET_CLASS (backend)->discard_alarm)
+ (* E_CAL_BACKEND_GET_CLASS (backend)->discard_alarm) (backend, cal, opid, cancellable, uid, rid, auid);
+ else
e_data_cal_respond_discard_alarm (cal, opid, e_data_cal_create_error (NotSupported, NULL));
- return;
- }
-
- (* E_CAL_BACKEND_GET_CLASS (backend)->discard_alarm) (backend, cal, opid, cancellable, uid, rid, auid);
}
/**
@@ -1186,7 +1294,10 @@ e_cal_backend_get_timezone (ECalBackend *backend, EDataCal *cal, guint32 opid, G
g_return_if_fail (tzid != NULL);
g_return_if_fail (E_CAL_BACKEND_GET_CLASS (backend)->get_timezone != NULL);
- (* E_CAL_BACKEND_GET_CLASS (backend)->get_timezone) (backend, cal, opid, cancellable, tzid);
+ if (e_cal_backend_is_opening (backend))
+ e_data_cal_respond_get_timezone (cal, opid, EDC_OPENING_ERROR, NULL);
+ else
+ (* E_CAL_BACKEND_GET_CLASS (backend)->get_timezone) (backend, cal, opid, cancellable, tzid);
}
/**
@@ -1207,7 +1318,10 @@ e_cal_backend_add_timezone (ECalBackend *backend, EDataCal *cal, guint32 opid, G
g_return_if_fail (tzobject != NULL);
g_return_if_fail (E_CAL_BACKEND_GET_CLASS (backend)->add_timezone != NULL);
- (* E_CAL_BACKEND_GET_CLASS (backend)->add_timezone) (backend, cal, opid, cancellable, tzobject);
+ if (e_cal_backend_is_opening (backend))
+ e_data_cal_respond_add_timezone (cal, opid, EDC_OPENING_ERROR);
+ else
+ (* E_CAL_BACKEND_GET_CLASS (backend)->add_timezone) (backend, cal, opid, cancellable, tzobject);
}
/**
@@ -1555,15 +1669,27 @@ e_cal_backend_notify_online (ECalBackend *backend, gboolean is_online)
/**
* e_cal_backend_notify_auth_required:
* @backend: an #ECalBackend
+ * @is_self: Use %TRUE to indicate the authentication is required
+ * for the @backend, otheriwse the authentication is for any
+ * other source. Having @credentials %NULL means @is_self
+ * automatically.
* @credentials: an #ECredentials that contains extra information for
* a source for which authentication is requested.
* This parameter can be NULL to indicate "for this calendar".
*
* Notifies clients that @backend requires authentication in order to
- * connect. Means to be used by backend implementations.
+ * connect. This function call does not influence 'opening', but
+ * influences 'opened' property, which is set to %FALSE when @is_self
+ * is %TRUE or @credentials is %NULL. Opening phase is finished
+ * by e_cal_backend_notify_opened() if this is requested for @backend.
+ *
+ * See e_cal_backend_open() for a description how the whole opening
+ * phase works.
+ *
+ * Meant to be used by backend implementations.
**/
void
-e_cal_backend_notify_auth_required (ECalBackend *backend, const ECredentials *credentials)
+e_cal_backend_notify_auth_required (ECalBackend *backend, gboolean is_self, const ECredentials *credentials)
{
ECalBackendPrivate *priv;
GSList *clients;
@@ -1571,12 +1697,15 @@ e_cal_backend_notify_auth_required (ECalBackend *backend, const ECredentials *cr
priv = backend->priv;
if (priv->notification_proxy) {
- e_cal_backend_notify_auth_required (priv->notification_proxy, credentials);
+ e_cal_backend_notify_auth_required (priv->notification_proxy, is_self, credentials);
return;
}
g_mutex_lock (priv->clients_mutex);
+ if (is_self || !credentials)
+ priv->opened = FALSE;
+
for (clients = priv->clients; clients != NULL; clients = g_slist_next (clients))
e_data_cal_report_auth_required (E_DATA_CAL (clients->data), credentials);
@@ -1584,6 +1713,77 @@ e_cal_backend_notify_auth_required (ECalBackend *backend, const ECredentials *cr
}
/**
+ * e_cal_backend_notify_opened:
+ * @backend: an #ECalBackend
+ * @error: a #GError corresponding to the error encountered during
+ * the opening phase. Use %NULL for success. The @error is freed
+ * automatically if not %NULL.
+ *
+ * Notifies clients that @backend finished its opening phase.
+ * See e_cal_backend_open() for more information how the opening
+ * phase works. Calling this function changes 'opening' property,
+ * same as 'opened'. 'opening' is set to %FALSE and the backend
+ * is considered 'opened' only if the @error is %NULL.
+ *
+ * See also: e_cal_backend_respond_opened()
+ *
+ * Note: The @error is freed automatically if not %NULL.
+ *
+ * Meant to be used by backend implementations.
+ **/
+void
+e_cal_backend_notify_opened (ECalBackend *backend, GError *error)
+{
+ ECalBackendPrivate *priv;
+ GSList *clients;
+
+ priv = backend->priv;
+ g_mutex_lock (priv->clients_mutex);
+
+ priv->opening = FALSE;
+ priv->opened = error == NULL;
+
+ for (clients = priv->clients; clients != NULL; clients = g_slist_next (clients))
+ e_data_cal_report_opened (E_DATA_CAL (clients->data), error);
+
+ g_mutex_unlock (priv->clients_mutex);
+
+ if (error)
+ g_error_free (error);
+}
+
+/**
+ * e_cal_backend_respond_opened:
+ * @backend: an #ECalBackend
+ * @cal: an #EDataCal
+ * @opid: an operation ID
+ * @error: result error; can be %NULL, if it isn't then it's automatically freed
+ *
+ * This is a replacement for e_data_cal_respond_open() for cases where
+ * the finish of 'open' method call also finishes backend opening phase.
+ * This function covers calling of both e_data_cal_respond_open() and
+ * e_cal_backend_notify_opened() with the same @error.
+ *
+ * See e_cal_backend_open() for more details how the opening phase works.
+ **/
+void
+e_cal_backend_respond_opened (ECalBackend *backend, EDataCal *cal, guint32 opid, GError *error)
+{
+ GError *copy = NULL;
+
+ g_return_if_fail (backend != NULL);
+ g_return_if_fail (E_IS_CAL_BACKEND (backend));
+ g_return_if_fail (cal != NULL);
+ g_return_if_fail (opid != 0);
+
+ if (error)
+ copy = g_error_copy (error);
+
+ e_data_cal_respond_open (cal, opid, error);
+ e_cal_backend_notify_opened (backend, copy);
+}
+
+/**
* e_cal_backend_empty_cache:
* @backend: an #ECalBackend
* @cache: Backend's cache to empty.
diff --git a/calendar/libedata-cal/e-cal-backend.h b/calendar/libedata-cal/e-cal-backend.h
index 5b33152..360c4e4 100644
--- a/calendar/libedata-cal/e-cal-backend.h
+++ b/calendar/libedata-cal/e-cal-backend.h
@@ -43,7 +43,8 @@ G_BEGIN_DECLS
#define E_IS_CAL_BACKEND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_CAL_BACKEND))
#define E_CAL_BACKEND_GET_CLASS(obj) (E_CAL_BACKEND_CLASS (G_OBJECT_GET_CLASS (obj)))
-#define CLIENT_BACKEND_PROPERTY_LOADED "loaded"
+#define CLIENT_BACKEND_PROPERTY_OPENED "opened"
+#define CLIENT_BACKEND_PROPERTY_OPENING "opening"
#define CLIENT_BACKEND_PROPERTY_ONLINE "online"
#define CLIENT_BACKEND_PROPERTY_READONLY "readonly"
#define CLIENT_BACKEND_PROPERTY_CACHE_DIR "cache-dir"
@@ -70,9 +71,9 @@ struct _ECalBackendClass {
void (* set_backend_property) (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellable *cancellable, const gchar *prop_name, const gchar *prop_value);
void (* open) (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellable *cancellable, gboolean only_if_exists);
- void (* authenticate_user) (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellable *cancellable, ECredentials *credentials);
void (* remove) (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellable *cancellable);
void (* set_online) (ECalBackend *backend, gboolean is_online);
+ void (* authenticate_user) (ECalBackend *backend, GCancellable *cancellable, ECredentials *credentials);
void (* refresh) (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellable *cancellable);
void (* get_object) (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellable *cancellable, const gchar *uid, const gchar *rid);
@@ -104,7 +105,8 @@ ESource * e_cal_backend_get_source (ECalBackend *backend);
const gchar * e_cal_backend_get_uri (ECalBackend *backend);
icalcomponent_kind e_cal_backend_get_kind (ECalBackend *backend);
gboolean e_cal_backend_is_online (ECalBackend *backend);
-gboolean e_cal_backend_is_loaded (ECalBackend *backend);
+gboolean e_cal_backend_is_opened (ECalBackend *backend);
+gboolean e_cal_backend_is_opening (ECalBackend *backend);
gboolean e_cal_backend_is_readonly (ECalBackend *backend);
gboolean e_cal_backend_is_removed (ECalBackend *backend);
@@ -124,8 +126,9 @@ void e_cal_backend_get_backend_property (ECalBackend *backend, EDataCal *cal, g
void e_cal_backend_set_backend_property (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellable *cancellable, const gchar *prop_name, const gchar *prop_value);
void e_cal_backend_set_online (ECalBackend *backend, gboolean is_online);
+void e_cal_backend_authenticate_user (ECalBackend *backend, GCancellable *cancellable, ECredentials *credentials);
+
void e_cal_backend_open (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellable *cancellable, gboolean only_if_exists);
-void e_cal_backend_authenticate_user (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellable *cancellable, ECredentials *credentials);
void e_cal_backend_remove (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellable *cancellable);
void e_cal_backend_refresh (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellable *cancellable);
void e_cal_backend_get_object (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellable *cancellable, const gchar *uid, const gchar *rid);
@@ -154,14 +157,16 @@ void e_cal_backend_notify_objects_removed (ECalBackend *backend, EDataCalView *
void e_cal_backend_notify_error (ECalBackend *backend, const gchar *message);
void e_cal_backend_notify_readonly (ECalBackend *backend, gboolean is_readonly);
void e_cal_backend_notify_online (ECalBackend *backend, gboolean is_online);
-void e_cal_backend_notify_auth_required (ECalBackend *backend, const ECredentials *credentials);
+void e_cal_backend_notify_auth_required (ECalBackend *backend, gboolean is_self, const ECredentials *credentials);
+void e_cal_backend_notify_opened (ECalBackend *backend, GError *error);
void e_cal_backend_empty_cache (ECalBackend *backend, struct _ECalBackendCache *cache);
/* protected functions for subclasses */
-void e_cal_backend_set_is_loaded (ECalBackend *backend, gboolean is_loaded);
void e_cal_backend_set_is_removed (ECalBackend *backend, gboolean is_removed);
+void e_cal_backend_respond_opened (ECalBackend *backend, EDataCal *cal, guint32 opid, GError *error);
+
G_END_DECLS
#endif
diff --git a/calendar/libedata-cal/e-data-cal-factory.c b/calendar/libedata-cal/e-data-cal-factory.c
index 15bc734..e43b452 100644
--- a/calendar/libedata-cal/e-data-cal-factory.c
+++ b/calendar/libedata-cal/e-data-cal-factory.c
@@ -353,12 +353,6 @@ impl_CalFactory_getCal (EGdbusCalFactory *object, GDBusMethodInvocation *invocat
gchar *source_xml = NULL;
guint type = 0;
- /* Remove a pending exit */
- if (priv->exit_timeout) {
- g_source_remove (priv->exit_timeout);
- priv->exit_timeout = 0;
- }
-
if (!e_gdbus_cal_factory_decode_get_cal (in_source_type, &source_xml, &type)) {
error = g_error_new (E_DATA_CAL_ERROR, NoSuchCal, _("Invalid call"));
g_dbus_method_invocation_return_gerror (invocation, error);
@@ -497,6 +491,12 @@ impl_CalFactory_getCal (EGdbusCalFactory *object, GDBusMethodInvocation *invocat
update_source_in_backend (backend, source);
}
+ /* Remove a pending exit */
+ if (priv->exit_timeout) {
+ g_source_remove (priv->exit_timeout);
+ priv->exit_timeout = 0;
+ }
+
calendar = e_data_cal_new (backend, source);
e_cal_backend_add_client (backend, calendar);
diff --git a/calendar/libedata-cal/e-data-cal-types.h b/calendar/libedata-cal/e-data-cal-types.h
index e2b47ed..d4f75f4 100644
--- a/calendar/libedata-cal/e-data-cal-types.h
+++ b/calendar/libedata-cal/e-data-cal-types.h
@@ -6,6 +6,7 @@ G_BEGIN_DECLS
typedef enum {
Success,
+ Busy,
RepositoryOffline,
PermissionDenied,
InvalidRange,
diff --git a/calendar/libedata-cal/e-data-cal-view.c b/calendar/libedata-cal/e-data-cal-view.c
index 0fb7d52..3a9ea41 100644
--- a/calendar/libedata-cal/e-data-cal-view.c
+++ b/calendar/libedata-cal/e-data-cal-view.c
@@ -335,7 +335,7 @@ notify_complete (EDataCalView *view, const GError *error)
send_pending_changes (view);
send_pending_removes (view);
- error_strv = e_gdbus_cal_view_encode_error (error);
+ error_strv = e_gdbus_templates_encode_error (error);
e_gdbus_cal_view_emit_complete (view->priv->gdbus_object, (const gchar * const *) error_strv);
diff --git a/calendar/libedata-cal/e-data-cal.c b/calendar/libedata-cal/e-data-cal.c
index c8f8292..8f32133 100644
--- a/calendar/libedata-cal/e-data-cal.c
+++ b/calendar/libedata-cal/e-data-cal.c
@@ -178,10 +178,6 @@ operation_thread (gpointer data, gpointer user_data)
case OP_OPEN:
e_cal_backend_open (backend, op->cal, op->id, op->cancellable, op->d.only_if_exists);
break;
- case OP_AUTHENTICATE:
- e_cal_backend_authenticate_user (backend, op->cal, op->id, op->cancellable, op->d.credentials);
- e_credentials_free (op->d.credentials);
- break;
case OP_REMOVE:
e_cal_backend_remove (backend, op->cal, op->id, op->cancellable);
break;
@@ -298,6 +294,10 @@ operation_thread (gpointer data, gpointer user_data)
e_cal_backend_add_timezone (backend, op->cal, op->id, op->cancellable, op->d.tzobject);
g_free (op->d.tzobject);
break;
+ case OP_AUTHENTICATE:
+ e_cal_backend_authenticate_user (backend, op->cancellable, op->d.credentials);
+ e_credentials_free (op->d.credentials);
+ break;
case OP_CANCEL_OPERATION:
g_static_rec_mutex_lock (&op->cal->priv->pending_ops_lock);
@@ -362,6 +362,7 @@ e_data_cal_error_quark (void)
static const GDBusErrorEntry entries[] = {
{ Success, ERR_PREFIX "Success" },
+ { Busy, ERR_PREFIX "Busy" },
{ RepositoryOffline, ERR_PREFIX "RepositoryOffline" },
{ PermissionDenied, ERR_PREFIX "PermissionDenied" },
{ InvalidRange, ERR_PREFIX "InvalidRange" },
@@ -411,6 +412,7 @@ e_data_cal_status_to_string (EDataCalCallStatus status)
const gchar *msg;
} statuses[] = {
{ Success, N_("Success") },
+ { Busy, N_("Backend is busy") },
{ RepositoryOffline, N_("Repository offline") },
{ PermissionDenied, N_("Permission denied") },
{ InvalidRange, N_("Invalid range") },
@@ -569,28 +571,6 @@ impl_Cal_open (EGdbusCal *object, GDBusMethodInvocation *invocation, gboolean in
}
static gboolean
-impl_Cal_authenticateUser (EGdbusCal *object, GDBusMethodInvocation *invocation, const gchar * const *in_credentials, EDataCal *cal)
-{
- OperationData *op;
-
- if (in_credentials == NULL) {
- GError *error = e_data_cal_create_error (InvalidArg, NULL);
- /* Translators: This is prefix to a detailed error message */
- data_cal_return_error (invocation, error, _("Cannot authenticate user: "));
- g_error_free (error);
- return TRUE;
- }
-
- op = op_new (OP_AUTHENTICATE, cal);
- op->d.credentials = e_credentials_new_strv (in_credentials);
-
- e_gdbus_cal_complete_authenticate_user (cal->priv->gdbus_object, invocation, op->id);
- e_operation_pool_push (ops_pool, op);
-
- return TRUE;
-}
-
-static gboolean
impl_Cal_remove (EGdbusCal *object, GDBusMethodInvocation *invocation, EDataCal *cal)
{
OperationData *op;
@@ -835,6 +815,28 @@ impl_Cal_addTimezone (EGdbusCal *object, GDBusMethodInvocation *invocation, cons
}
static gboolean
+impl_Cal_authenticateUser (EGdbusCal *object, GDBusMethodInvocation *invocation, const gchar * const *in_credentials, EDataCal *cal)
+{
+ OperationData *op;
+
+ if (in_credentials == NULL) {
+ GError *error = e_data_cal_create_error (InvalidArg, NULL);
+ /* Translators: This is prefix to a detailed error message */
+ data_cal_return_error (invocation, error, _("Cannot authenticate user: "));
+ g_error_free (error);
+ return TRUE;
+ }
+
+ op = op_new (OP_AUTHENTICATE, cal);
+ op->d.credentials = e_credentials_new_strv (in_credentials);
+
+ e_gdbus_cal_complete_authenticate_user (cal->priv->gdbus_object, invocation, NULL);
+ e_operation_pool_push (ops_pool, op);
+
+ return TRUE;
+}
+
+static gboolean
impl_Cal_cancelOperation (EGdbusCal *object, GDBusMethodInvocation *invocation, guint in_opid, EDataCal *cal)
{
OperationData *op;
@@ -913,20 +915,6 @@ e_data_cal_respond_open (EDataCal *cal, guint32 opid, GError *error)
g_error_free (error);
}
-void
-e_data_cal_respond_authenticate_user (EDataCal *cal, guint32 opid, GError *error)
-{
- op_complete (cal, opid);
-
- /* Translators: This is prefix to a detailed error message */
- g_prefix_error (&error, "%s", _("Cannot authenticate user: "));
-
- e_gdbus_cal_emit_authenticate_user_done (cal->priv->gdbus_object, opid, error);
-
- if (error)
- g_error_free (error);
-}
-
/**
* e_data_cal_respond_remove:
* @cal: A calendar client interface.
@@ -1391,6 +1379,23 @@ e_data_cal_report_auth_required (EDataCal *cal, const ECredentials *credentials)
g_strfreev (strv);
}
+/* Reports to associated client that opening phase of the cal is finished.
+ error being NULL means successfully, otherwise reports an error which happened
+ during opening phase. By opening phase is meant a process including successfull
+ authentication to the server/storage.
+*/
+void
+e_data_cal_report_opened (EDataCal *cal, const GError *error)
+{
+ gchar **strv_error;
+
+ strv_error = e_gdbus_templates_encode_error (error);
+
+ e_gdbus_cal_emit_opened (cal->priv->gdbus_object, (const gchar * const *) strv_error);
+
+ g_strfreev (strv_error);
+}
+
void
e_data_cal_report_free_busy_data (EDataCal *cal, const GSList *freebusy)
{
diff --git a/calendar/libedata-cal/e-data-cal.h b/calendar/libedata-cal/e-data-cal.h
index 3a538ef..9d8b553 100644
--- a/calendar/libedata-cal/e-data-cal.h
+++ b/calendar/libedata-cal/e-data-cal.h
@@ -131,7 +131,6 @@ ESource * e_data_cal_get_source (EDataCal *cal);
guint e_data_cal_register_gdbus_object (EDataCal *cal, GDBusConnection *connection, const gchar *object_path, GError **error);
void e_data_cal_respond_open (EDataCal *cal, guint32 opid, GError *error);
-void e_data_cal_respond_authenticate_user (EDataCal *cal, guint32 opid, GError *error);
void e_data_cal_respond_remove (EDataCal *cal, guint32 opid, GError *error);
void e_data_cal_respond_refresh (EDataCal *cal, guint32 opid, GError *error);
void e_data_cal_respond_get_backend_property (EDataCal *cal, guint32 opid, GError *error, const gchar *prop_value);
@@ -154,6 +153,7 @@ void e_data_cal_report_error (EDataCal *cal, const gchar *message);
void e_data_cal_report_readonly (EDataCal *cal, gboolean is_readonly);
void e_data_cal_report_online (EDataCal *cal, gboolean is_online);
void e_data_cal_report_auth_required (EDataCal *cal, const ECredentials *credentials);
+void e_data_cal_report_opened (EDataCal *cal, const GError *error);
void e_data_cal_report_free_busy_data (EDataCal *cal, const GSList *freebusy);
G_END_DECLS
diff --git a/calendar/libegdbus/e-gdbus-cal-view.c b/calendar/libegdbus/e-gdbus-cal-view.c
index 1497a98..be0eb1c 100644
--- a/calendar/libegdbus/e-gdbus-cal-view.c
+++ b/calendar/libegdbus/e-gdbus-cal-view.c
@@ -210,50 +210,6 @@ e_gdbus_cal_view_emit_progress (EGdbusCalView *object, guint arg_percent, const
g_signal_emit (object, signals[__PROGRESS_SIGNAL], 0, arg_percent, arg_message);
}
-/* free returned pointer with g_strfreev() */
-gchar **
-e_gdbus_cal_view_encode_error (const GError *in_error)
-{
- gchar **strv;
-
- strv = g_new0 (gchar *, 3);
-
- if (!in_error) {
- strv[0] = g_strdup ("");
- strv[1] = g_strdup ("");
- } else {
- gchar *dbus_error_name = g_dbus_error_encode_gerror (in_error);
-
- strv[0] = e_util_utf8_make_valid (dbus_error_name ? dbus_error_name : "");
- strv[1] = e_util_utf8_make_valid (in_error->message);
-
- g_free (dbus_error_name);
- }
-
- return strv;
-}
-
-/* free returned pointer with g_error_free(), of not NULL */
-GError *
-e_gdbus_cal_view_decode_error (const gchar * const *in_strv)
-{
- GError *error = NULL;
- const gchar *error_name, *error_message;
-
- g_return_val_if_fail (in_strv != NULL, NULL);
- g_return_val_if_fail (in_strv[0] != NULL, NULL);
- g_return_val_if_fail (in_strv[1] != NULL, NULL);
- g_return_val_if_fail (in_strv[2] == NULL, NULL);
-
- error_name = in_strv[0];
- error_message = in_strv[1];
-
- if (error_name && *error_name && error_message)
- error = g_dbus_error_new_for_dbus_error (error_name, error_message);
-
- return error;
-}
-
void
e_gdbus_cal_view_emit_complete (EGdbusCalView *object, const gchar * const *arg_error)
{
diff --git a/calendar/libegdbus/e-gdbus-cal-view.h b/calendar/libegdbus/e-gdbus-cal-view.h
index c5a646c..fa2751b 100644
--- a/calendar/libegdbus/e-gdbus-cal-view.h
+++ b/calendar/libegdbus/e-gdbus-cal-view.h
@@ -140,9 +140,6 @@ void e_gdbus_cal_view_emit_objects_modified (EGdbusCalView *object, const gchar
void e_gdbus_cal_view_emit_objects_removed (EGdbusCalView *object, const gchar * const *arg_uids);
void e_gdbus_cal_view_emit_progress (EGdbusCalView *object, guint arg_percent, const gchar *arg_message);
-
-gchar **e_gdbus_cal_view_encode_error (const GError *in_error);
-GError *e_gdbus_cal_view_decode_error (const gchar * const *in_strv);
void e_gdbus_cal_view_emit_complete (EGdbusCalView *object, const gchar * const *arg_error);
G_END_DECLS
diff --git a/calendar/libegdbus/e-gdbus-cal.c b/calendar/libegdbus/e-gdbus-cal.c
index 54a89e0..3604be0 100644
--- a/calendar/libegdbus/e-gdbus-cal.c
+++ b/calendar/libegdbus/e-gdbus-cal.c
@@ -40,11 +40,10 @@ enum
__READONLY_SIGNAL,
__ONLINE_SIGNAL,
__AUTH_REQUIRED_SIGNAL,
+ __OPENED_SIGNAL,
__FREE_BUSY_DATA_SIGNAL,
__OPEN_METHOD,
__OPEN_DONE_SIGNAL,
- __AUTHENTICATE_USER_METHOD,
- __AUTHENTICATE_USER_DONE_SIGNAL,
__REMOVE_METHOD,
__REMOVE_DONE_SIGNAL,
__REFRESH_METHOD,
@@ -79,6 +78,7 @@ enum
__GET_TIMEZONE_DONE_SIGNAL,
__ADD_TIMEZONE_METHOD,
__ADD_TIMEZONE_DONE_SIGNAL,
+ __AUTHENTICATE_USER_METHOD,
__CANCEL_OPERATION_METHOD,
__CANCEL_ALL_METHOD,
__CLOSE_METHOD,
@@ -131,10 +131,10 @@ E_DECLARE_GDBUS_SIGNAL_EMISSION_HOOK_STRING (GDBUS_CAL_INTERFACE_NAME, backend_
E_DECLARE_GDBUS_SIGNAL_EMISSION_HOOK_BOOLEAN (GDBUS_CAL_INTERFACE_NAME, readonly)
E_DECLARE_GDBUS_SIGNAL_EMISSION_HOOK_BOOLEAN (GDBUS_CAL_INTERFACE_NAME, online)
E_DECLARE_GDBUS_SIGNAL_EMISSION_HOOK_STRV (GDBUS_CAL_INTERFACE_NAME, auth_required)
+E_DECLARE_GDBUS_SIGNAL_EMISSION_HOOK_STRV (GDBUS_CAL_INTERFACE_NAME, opened)
E_DECLARE_GDBUS_SIGNAL_EMISSION_HOOK_STRV (GDBUS_CAL_INTERFACE_NAME, free_busy_data)
E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_VOID (GDBUS_CAL_INTERFACE_NAME, open)
-E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_VOID (GDBUS_CAL_INTERFACE_NAME, authenticate_user)
E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_VOID (GDBUS_CAL_INTERFACE_NAME, remove)
E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_VOID (GDBUS_CAL_INTERFACE_NAME, refresh)
E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_STRING (GDBUS_CAL_INTERFACE_NAME, get_backend_property)
@@ -167,11 +167,11 @@ e_gdbus_cal_default_init (EGdbusCalIface *iface)
E_INIT_GDBUS_SIGNAL_BOOLEAN (EGdbusCalIface, "readonly", readonly, __READONLY_SIGNAL)
E_INIT_GDBUS_SIGNAL_BOOLEAN (EGdbusCalIface, "online", online, __ONLINE_SIGNAL)
E_INIT_GDBUS_SIGNAL_STRV (EGdbusCalIface, "auth_required", auth_required, __AUTH_REQUIRED_SIGNAL)
+ E_INIT_GDBUS_SIGNAL_STRV (EGdbusCalIface, "opened", opened, __OPENED_SIGNAL)
E_INIT_GDBUS_SIGNAL_STRV (EGdbusCalIface, "free_busy_data", free_busy_data, __FREE_BUSY_DATA_SIGNAL)
/* GObject signals definitions for D-Bus methods: */
E_INIT_GDBUS_METHOD_ASYNC_BOOLEAN__VOID (EGdbusCalIface, "open", open, __OPEN_METHOD, __OPEN_DONE_SIGNAL)
- E_INIT_GDBUS_METHOD_ASYNC_STRV__VOID (EGdbusCalIface, "authenticateUser", authenticate_user, __AUTHENTICATE_USER_METHOD, __AUTHENTICATE_USER_DONE_SIGNAL)
E_INIT_GDBUS_METHOD_ASYNC_VOID__VOID (EGdbusCalIface, "remove", remove, __REMOVE_METHOD, __REMOVE_DONE_SIGNAL)
E_INIT_GDBUS_METHOD_ASYNC_VOID__VOID (EGdbusCalIface, "refresh", refresh, __REFRESH_METHOD, __REFRESH_DONE_SIGNAL)
E_INIT_GDBUS_METHOD_ASYNC_STRING__STRING(EGdbusCalIface, "getBackendProperty", get_backend_property, __GET_BACKEND_PROPERTY_METHOD, __GET_BACKEND_PROPERTY_DONE_SIGNAL)
@@ -189,6 +189,7 @@ e_gdbus_cal_default_init (EGdbusCalIface *iface)
E_INIT_GDBUS_METHOD_ASYNC_STRING__STRING(EGdbusCalIface, "getView", get_view, __GET_VIEW_METHOD, __GET_VIEW_DONE_SIGNAL)
E_INIT_GDBUS_METHOD_ASYNC_STRING__STRING(EGdbusCalIface, "getTimezone", get_timezone, __GET_TIMEZONE_METHOD, __GET_TIMEZONE_DONE_SIGNAL)
E_INIT_GDBUS_METHOD_ASYNC_STRING__VOID (EGdbusCalIface, "addTimezone", add_timezone, __ADD_TIMEZONE_METHOD, __ADD_TIMEZONE_DONE_SIGNAL)
+ E_INIT_GDBUS_METHOD_STRV (EGdbusCalIface, "authenticateUser", authenticate_user, __AUTHENTICATE_USER_METHOD)
E_INIT_GDBUS_METHOD_UINT (EGdbusCalIface, "cancelOperation", cancel_operation, __CANCEL_OPERATION_METHOD)
E_INIT_GDBUS_METHOD_VOID (EGdbusCalIface, "cancelAll", cancel_all, __CANCEL_ALL_METHOD)
E_INIT_GDBUS_METHOD_VOID (EGdbusCalIface, "close", close, __CLOSE_METHOD)
@@ -244,26 +245,6 @@ e_gdbus_cal_call_open_sync (GDBusProxy *proxy, gboolean in_only_if_exists, GCanc
}
void
-e_gdbus_cal_call_authenticate_user (GDBusProxy *proxy, const gchar * const *in_credentials, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
-{
- e_gdbus_proxy_call_strv ("authenticateUser", e_gdbus_cal_call_authenticate_user, E_GDBUS_ASYNC_OP_KEEPER (proxy), in_credentials, cancellable, callback, user_data);
-}
-
-gboolean
-e_gdbus_cal_call_authenticate_user_finish (GDBusProxy *proxy, GAsyncResult *result, GError **error)
-{
- return e_gdbus_proxy_finish_call_void (E_GDBUS_ASYNC_OP_KEEPER (proxy), result, error, e_gdbus_cal_call_authenticate_user);
-}
-
-gboolean
-e_gdbus_cal_call_authenticate_user_sync (GDBusProxy *proxy, const gchar * const *in_credentials, GCancellable *cancellable, GError **error)
-{
- return e_gdbus_proxy_call_sync_strv__void (proxy, in_credentials, cancellable, error,
- e_gdbus_cal_call_authenticate_user,
- e_gdbus_cal_call_authenticate_user_finish);
-}
-
-void
e_gdbus_cal_call_remove (GDBusProxy *proxy, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
{
e_gdbus_proxy_call_void ("remove", e_gdbus_cal_call_remove, E_GDBUS_ASYNC_OP_KEEPER (proxy), cancellable, callback, user_data);
@@ -841,6 +822,24 @@ e_gdbus_cal_call_add_timezone_sync (GDBusProxy *proxy, const gchar *in_tzobject,
}
void
+e_gdbus_cal_call_authenticate_user (GDBusProxy *proxy, const gchar * const *in_credentials, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
+{
+ e_gdbus_proxy_method_call_strv ("authenticateUser", proxy, in_credentials, cancellable, callback, user_data);
+}
+
+gboolean
+e_gdbus_cal_call_authenticate_user_finish (GDBusProxy *proxy, GAsyncResult *result, GError **error)
+{
+ return e_gdbus_proxy_method_call_finish_void (proxy, result, error);
+}
+
+gboolean
+e_gdbus_cal_call_authenticate_user_sync (GDBusProxy *proxy, const gchar * const *in_credentials, GCancellable *cancellable, GError **error)
+{
+ return e_gdbus_proxy_method_call_sync_strv__void ("authenticateUser", proxy, in_credentials, cancellable, error);
+}
+
+void
e_gdbus_cal_call_cancel_operation (GDBusProxy *proxy, guint in_opid, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
{
e_gdbus_proxy_method_call_uint ("cancelOperation", proxy, in_opid, cancellable, callback, user_data);
@@ -909,7 +908,6 @@ e_gdbus_cal_emit_ ## _mname ## _done (EGdbusCal *object, guint arg_opid, const G
}
DECLARE_EMIT_DONE_SIGNAL_0 (open, __OPEN_DONE_SIGNAL)
-DECLARE_EMIT_DONE_SIGNAL_0 (authenticate_user, __AUTHENTICATE_USER_DONE_SIGNAL)
DECLARE_EMIT_DONE_SIGNAL_0 (remove, __REMOVE_DONE_SIGNAL)
DECLARE_EMIT_DONE_SIGNAL_0 (refresh, __REFRESH_DONE_SIGNAL)
DECLARE_EMIT_DONE_SIGNAL_1 (get_backend_property, __GET_BACKEND_PROPERTY_DONE_SIGNAL, const gchar *)
@@ -956,6 +954,12 @@ e_gdbus_cal_emit_auth_required (EGdbusCal *object, const gchar * const *arg_cred
}
void
+e_gdbus_cal_emit_opened (EGdbusCal *object, const gchar * const *arg_error)
+{
+ g_signal_emit (object, signals[__OPENED_SIGNAL], 0, arg_error);
+}
+
+void
e_gdbus_cal_emit_free_busy_data (EGdbusCal *object, const gchar * const *arg_free_busy)
{
g_signal_emit (object, signals[__FREE_BUSY_DATA_SIGNAL], 0, arg_free_busy);
@@ -965,10 +969,10 @@ E_DECLARE_GDBUS_NOTIFY_SIGNAL_1 (cal, backend_error, message, "s")
E_DECLARE_GDBUS_NOTIFY_SIGNAL_1 (cal, readonly, is_readonly, "b")
E_DECLARE_GDBUS_NOTIFY_SIGNAL_1 (cal, online, is_online, "b")
E_DECLARE_GDBUS_NOTIFY_SIGNAL_1 (cal, auth_required, credentials, "as")
+E_DECLARE_GDBUS_NOTIFY_SIGNAL_1 (cal, opened, error, "as")
E_DECLARE_GDBUS_NOTIFY_SIGNAL_1 (cal, free_busy_data, free_busy_data, "as")
E_DECLARE_GDBUS_ASYNC_METHOD_1 (cal, open, only_if_exists, "b")
-E_DECLARE_GDBUS_ASYNC_METHOD_1 (cal, authenticateUser, credentials, "as")
E_DECLARE_GDBUS_ASYNC_METHOD_0 (cal, remove)
E_DECLARE_GDBUS_ASYNC_METHOD_0 (cal, refresh)
E_DECLARE_GDBUS_ASYNC_METHOD_1_WITH_RETURN (cal, getBackendProperty, propname, "s", propvalue, "s")
@@ -987,6 +991,7 @@ E_DECLARE_GDBUS_ASYNC_METHOD_1_WITH_RETURN (cal, getView, sexp, "s", view_path,
E_DECLARE_GDBUS_ASYNC_METHOD_1_WITH_RETURN (cal, getTimezone, tzid, "s", tzobject, "s")
E_DECLARE_GDBUS_ASYNC_METHOD_1 (cal, addTimezone, tzobject, "s")
+E_DECLARE_GDBUS_SYNC_METHOD_1 (cal, authenticateUser, credentials, "as")
E_DECLARE_GDBUS_SYNC_METHOD_1 (cal, cancelOperation, opid, "u")
E_DECLARE_GDBUS_SYNC_METHOD_0 (cal, cancelAll)
E_DECLARE_GDBUS_SYNC_METHOD_0 (cal, close)
@@ -994,7 +999,6 @@ E_DECLARE_GDBUS_SYNC_METHOD_0 (cal, close)
static const GDBusMethodInfo * const e_gdbus_cal_method_info_pointers[] =
{
&E_DECLARED_GDBUS_METHOD_INFO_NAME (cal, open),
- &E_DECLARED_GDBUS_METHOD_INFO_NAME (cal, authenticateUser),
&E_DECLARED_GDBUS_METHOD_INFO_NAME (cal, remove),
&E_DECLARED_GDBUS_METHOD_INFO_NAME (cal, refresh),
&E_DECLARED_GDBUS_METHOD_INFO_NAME (cal, getBackendProperty),
@@ -1012,6 +1016,7 @@ static const GDBusMethodInfo * const e_gdbus_cal_method_info_pointers[] =
&E_DECLARED_GDBUS_METHOD_INFO_NAME (cal, getView),
&E_DECLARED_GDBUS_METHOD_INFO_NAME (cal, getTimezone),
&E_DECLARED_GDBUS_METHOD_INFO_NAME (cal, addTimezone),
+ &E_DECLARED_GDBUS_METHOD_INFO_NAME (cal, authenticateUser),
&E_DECLARED_GDBUS_METHOD_INFO_NAME (cal, cancelOperation),
&E_DECLARED_GDBUS_METHOD_INFO_NAME (cal, cancelAll),
&E_DECLARED_GDBUS_METHOD_INFO_NAME (cal, close),
@@ -1024,10 +1029,10 @@ static const GDBusSignalInfo * const e_gdbus_cal_signal_info_pointers[] =
&E_DECLARED_GDBUS_SIGNAL_INFO_NAME (cal, readonly),
&E_DECLARED_GDBUS_SIGNAL_INFO_NAME (cal, online),
&E_DECLARED_GDBUS_SIGNAL_INFO_NAME (cal, auth_required),
+ &E_DECLARED_GDBUS_SIGNAL_INFO_NAME (cal, opened),
&E_DECLARED_GDBUS_SIGNAL_INFO_NAME (cal, free_busy_data),
&E_DECLARED_GDBUS_SIGNAL_INFO_NAME (cal, open_done),
- &E_DECLARED_GDBUS_SIGNAL_INFO_NAME (cal, authenticateUser_done),
&E_DECLARED_GDBUS_SIGNAL_INFO_NAME (cal, remove_done),
&E_DECLARED_GDBUS_SIGNAL_INFO_NAME (cal, refresh_done),
&E_DECLARED_GDBUS_SIGNAL_INFO_NAME (cal, getBackendProperty_done),
@@ -1251,7 +1256,6 @@ e_gdbus_cal_proxy_init (EGdbusCalProxy *proxy)
proxy->priv->pending_ops = e_gdbus_async_op_keeper_create_pending_ops (E_GDBUS_ASYNC_OP_KEEPER (proxy));
E_GDBUS_CONNECT_METHOD_DONE_SIGNAL_VOID (open);
- E_GDBUS_CONNECT_METHOD_DONE_SIGNAL_VOID (authenticate_user);
E_GDBUS_CONNECT_METHOD_DONE_SIGNAL_VOID (remove);
E_GDBUS_CONNECT_METHOD_DONE_SIGNAL_VOID (refresh);
E_GDBUS_CONNECT_METHOD_DONE_SIGNAL_STRING (get_backend_property);
diff --git a/calendar/libegdbus/e-gdbus-cal.h b/calendar/libegdbus/e-gdbus-cal.h
index 79bbb90..21e2c7d 100644
--- a/calendar/libegdbus/e-gdbus-cal.h
+++ b/calendar/libegdbus/e-gdbus-cal.h
@@ -107,15 +107,13 @@ struct _EGdbusCalIface
void (*readonly) (EGdbusCal *object, gboolean arg_is_readonly);
void (*online) (EGdbusCal *object, gboolean arg_is_online);
void (*auth_required) (EGdbusCal *object, const gchar * const *arg_credentials);
+ void (*opened) (EGdbusCal *object, const gchar * const *arg_error);
void (*free_busy_data) (EGdbusCal *object, const gchar * const *arg_free_busy);
/* Signal handlers for handling D-Bus method calls: */
gboolean (*handle_open) (EGdbusCal *object, GDBusMethodInvocation *invocation, gboolean in_only_if_exists);
void (*open_done) (EGdbusCal *object, guint arg_opid, const GError *arg_error);
- gboolean (*handle_authenticate_user) (EGdbusCal *object, GDBusMethodInvocation *invocation, const gchar * const *in_credentials);
- void (*authenticate_user_done) (EGdbusCal *object, guint arg_opid, const GError *arg_error);
-
gboolean (*handle_remove) (EGdbusCal *object, GDBusMethodInvocation *invocation);
void (*remove_done) (EGdbusCal *object, guint arg_opid, const GError *arg_error);
@@ -167,6 +165,7 @@ struct _EGdbusCalIface
gboolean (*handle_add_timezone) (EGdbusCal *object, GDBusMethodInvocation *invocation, const gchar *in_tzobject);
void (*add_timezone_done) (EGdbusCal *object, guint arg_opid, const GError *arg_error);
+ gboolean (*handle_authenticate_user) (EGdbusCal *object, GDBusMethodInvocation *invocation, const gchar * const *in_credentials);
gboolean (*handle_cancel_operation) (EGdbusCal *object, GDBusMethodInvocation *invocation, guint in_opid);
gboolean (*handle_cancel_all) (EGdbusCal *object, GDBusMethodInvocation *invocation);
gboolean (*handle_close) (EGdbusCal *object, GDBusMethodInvocation *invocation);
@@ -177,10 +176,6 @@ void e_gdbus_cal_call_open (GDBusProxy *proxy, gboolean in_only_if_exists, G
gboolean e_gdbus_cal_call_open_finish (GDBusProxy *proxy, GAsyncResult *result, GError **error);
gboolean e_gdbus_cal_call_open_sync (GDBusProxy *proxy, gboolean in_only_if_exists, GCancellable *cancellable, GError **error);
-void e_gdbus_cal_call_authenticate_user (GDBusProxy *proxy, const gchar * const *in_credentials, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
-gboolean e_gdbus_cal_call_authenticate_user_finish (GDBusProxy *proxy, GAsyncResult *result, GError **error);
-gboolean e_gdbus_cal_call_authenticate_user_sync (GDBusProxy *proxy, const gchar * const *in_credentials, GCancellable *cancellable, GError **error);
-
void e_gdbus_cal_call_remove (GDBusProxy *proxy, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
gboolean e_gdbus_cal_call_remove_finish (GDBusProxy *proxy, GAsyncResult *result, GError **error);
gboolean e_gdbus_cal_call_remove_sync (GDBusProxy *proxy, GCancellable *cancellable, GError **error);
@@ -265,6 +260,10 @@ void e_gdbus_cal_call_add_timezone (GDBusProxy *proxy, const gchar *in_tzobje
gboolean e_gdbus_cal_call_add_timezone_finish (GDBusProxy *proxy, GAsyncResult *result, GError **error);
gboolean e_gdbus_cal_call_add_timezone_sync (GDBusProxy *proxy, const gchar *in_tzobject, GCancellable *cancellable, GError **error);
+void e_gdbus_cal_call_authenticate_user (GDBusProxy *proxy, const gchar * const *in_credentials, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
+gboolean e_gdbus_cal_call_authenticate_user_finish (GDBusProxy *proxy, GAsyncResult *result, GError **error);
+gboolean e_gdbus_cal_call_authenticate_user_sync (GDBusProxy *proxy, const gchar * const *in_credentials, GCancellable *cancellable, GError **error);
+
void e_gdbus_cal_call_cancel_operation (GDBusProxy *proxy, guint in_opid, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
gboolean e_gdbus_cal_call_cancel_operation_finish (GDBusProxy *proxy, GAsyncResult *result, GError **error);
gboolean e_gdbus_cal_call_cancel_operation_sync (GDBusProxy *proxy, guint in_opid, GCancellable *cancellable, GError **error);
@@ -279,7 +278,6 @@ gboolean e_gdbus_cal_call_close_sync (GDBusProxy *proxy, GCancellable *cancell
/* D-Bus Methods Completion Helpers */
#define e_gdbus_cal_complete_open e_gdbus_complete_async_method
-#define e_gdbus_cal_complete_authenticate_user e_gdbus_complete_async_method
#define e_gdbus_cal_complete_remove e_gdbus_complete_async_method
#define e_gdbus_cal_complete_refresh e_gdbus_complete_async_method
#define e_gdbus_cal_complete_get_backend_property e_gdbus_complete_async_method
@@ -297,12 +295,12 @@ gboolean e_gdbus_cal_call_close_sync (GDBusProxy *proxy, GCancellable *cancell
#define e_gdbus_cal_complete_get_view e_gdbus_complete_async_method
#define e_gdbus_cal_complete_get_timezone e_gdbus_complete_async_method
#define e_gdbus_cal_complete_add_timezone e_gdbus_complete_async_method
+#define e_gdbus_cal_complete_authenticate_user e_gdbus_complete_sync_method_void
#define e_gdbus_cal_complete_cancel_operation e_gdbus_complete_sync_method_void
#define e_gdbus_cal_complete_cancel_all e_gdbus_complete_sync_method_void
#define e_gdbus_cal_complete_close e_gdbus_complete_sync_method_void
void e_gdbus_cal_emit_open_done (EGdbusCal *object, guint arg_opid, const GError *arg_error);
-void e_gdbus_cal_emit_authenticate_user_done (EGdbusCal *object, guint arg_opid, const GError *arg_error);
void e_gdbus_cal_emit_remove_done (EGdbusCal *object, guint arg_opid, const GError *arg_error);
void e_gdbus_cal_emit_refresh_done (EGdbusCal *object, guint arg_opid, const GError *arg_error);
void e_gdbus_cal_emit_get_backend_property_done (EGdbusCal *object, guint arg_opid, const GError *arg_error, const gchar *out_prop_value);
@@ -327,6 +325,7 @@ void e_gdbus_cal_emit_backend_error (EGdbusCal *object, const gchar *arg_message
void e_gdbus_cal_emit_readonly (EGdbusCal *object, gboolean arg_is_readonly);
void e_gdbus_cal_emit_online (EGdbusCal *object, gint arg_is_online);
void e_gdbus_cal_emit_auth_required (EGdbusCal *object, const gchar * const *arg_credentials);
+void e_gdbus_cal_emit_opened (EGdbusCal *object, const gchar * const *arg_error);
void e_gdbus_cal_emit_free_busy_data (EGdbusCal *object, const gchar * const *arg_free_busy);
G_END_DECLS
diff --git a/libedataserver/e-client-private.h b/libedataserver/e-client-private.h
index d32522d..71091bf 100644
--- a/libedataserver/e-client-private.h
+++ b/libedataserver/e-client-private.h
@@ -40,6 +40,7 @@ void e_client_unregister_op (EClient *client, guint32 opid);
void e_client_process_authentication (EClient *client, const ECredentials *credentials);
gboolean e_client_emit_authenticate (EClient *client, ECredentials *credentials);
+void e_client_emit_opened (EClient *client, const GError *error);
void e_client_emit_backend_error (EClient *client, const gchar *error_msg);
void e_client_emit_backend_died (EClient *client);
diff --git a/libedataserver/e-client.c b/libedataserver/e-client.c
index 4e11710..1479a13 100644
--- a/libedataserver/e-client.c
+++ b/libedataserver/e-client.c
@@ -61,6 +61,7 @@ enum {
enum {
AUTHENTICATE,
+ OPENED,
BACKEND_ERROR,
BACKEND_DIED,
LAST_SIGNAL
@@ -73,8 +74,10 @@ G_DEFINE_ABSTRACT_TYPE (EClient, e_client, G_TYPE_OBJECT)
/**
* Well-known client backend properties, which are common for each #EClient:
- * @CLIENT_BACKEND_PROPERTY_LOADED: Is set to "TRUE" or "FALSE" depending
- * on the backend's loaded state.
+ * @CLIENT_BACKEND_PROPERTY_OPENED: Is set to "TRUE" or "FALSE" depending
+ * whether the backend is fully opened.
+ * @CLIENT_BACKEND_PROPERTY_OPENING: Is set to "TRUE" or "FALSE" depending
+ * whether the backend is processing its opening phase.
* @CLIENT_BACKEND_PROPERTY_ONLINE: Is set to "TRUE" or "FALSE" depending
* on the backend's loaded state. See also e_client_is_online().
* @CLIENT_BACKEND_PROPERTY_READONLY: Is set to "TRUE" or "FALSE" depending
@@ -325,6 +328,17 @@ e_client_class_init (EClientClass *klass)
G_TYPE_BOOLEAN, 1,
G_TYPE_POINTER);
+ signals[OPENED] = g_signal_new (
+ "opened",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EClientClass, opened),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE, 1,
+ G_TYPE_ERROR);
+
+
signals[BACKEND_ERROR] = g_signal_new (
"backend-error",
G_OBJECT_CLASS_TYPE (klass),
@@ -370,8 +384,15 @@ client_operation_thread (gpointer data, gpointer user_data)
switch (op_data->op) {
case E_CLIENT_OP_AUTHENTICATE:
- if (e_client_emit_authenticate (op_data->client, op_data->d.credentials))
+ if (e_client_emit_authenticate (op_data->client, op_data->d.credentials)) {
client_handle_authentication (op_data->client, op_data->d.credentials);
+ } else {
+ GError *error;
+
+ error = g_error_new_literal (E_CLIENT_ERROR, E_CLIENT_ERROR_AUTHENTICATION_REQUIRED, e_client_error_to_string (E_CLIENT_ERROR_AUTHENTICATION_REQUIRED));
+ e_client_emit_opened (op_data->client, error);
+ g_error_free (error);
+ }
e_credentials_free (op_data->d.credentials);
break;
}
@@ -643,9 +664,13 @@ e_client_set_online (EClient *client, gboolean is_online)
* e_client_is_opened:
* @client: an #EClient
*
- * Check if this @client has been opened.
+ * Check if this @client is fully opened. This includes
+ * everything from e_client_open() call up to the authentication,
+ * if required by a backend. Client cannot do any other operation
+ * during the opening phase except of authenticate or cancel it.
+ * Every other operation results in an %E_CLIENT_ERROR_BUSY error.
*
- * Returns: %TRUE if this @client has been opened, otherwise %FALSE.
+ * Returns: %TRUE if this @client is fully opened, otherwise %FALSE.
*
* Since: 3.2.
**/
@@ -831,6 +856,28 @@ e_client_emit_authenticate (EClient *client, ECredentials *credentials)
}
void
+e_client_emit_opened (EClient *client, const GError *dbus_error)
+{
+ GError *local_error = NULL;
+
+ g_return_if_fail (client != NULL);
+ g_return_if_fail (E_IS_CLIENT (client));
+ g_return_if_fail (client->priv != NULL);
+
+ client->priv->opened = dbus_error == NULL;
+
+ if (dbus_error) {
+ local_error = g_error_copy (dbus_error);
+ e_client_unwrap_dbus_error (client, local_error, &local_error);
+ }
+
+ g_signal_emit (client, signals[OPENED], 0, local_error);
+
+ if (local_error)
+ g_error_free (local_error);
+}
+
+void
e_client_emit_backend_error (EClient *client, const gchar *error_msg)
{
g_return_if_fail (client != NULL);
@@ -1084,7 +1131,6 @@ gboolean
e_client_open_finish (EClient *client, GAsyncResult *result, GError **error)
{
EClientClass *klass;
- gboolean res;
g_return_val_if_fail (client != NULL, FALSE);
g_return_val_if_fail (E_IS_CLIENT (client), FALSE);
@@ -1094,11 +1140,7 @@ e_client_open_finish (EClient *client, GAsyncResult *result, GError **error)
g_return_val_if_fail (klass != NULL, FALSE);
g_return_val_if_fail (klass->open_finish != NULL, FALSE);
- res = klass->open_finish (client, result, error);
-
- client->priv->opened = res;
-
- return res;
+ return klass->open_finish (client, result, error);
}
/**
@@ -1118,17 +1160,12 @@ gboolean
e_client_open_sync (EClient *client, gboolean only_if_exists, GCancellable *cancellable, GError **error)
{
EClientClass *klass;
- gboolean res;
klass = E_CLIENT_GET_CLASS (client);
g_return_val_if_fail (klass != NULL, FALSE);
g_return_val_if_fail (klass->open_sync != NULL, FALSE);
- res = klass->open_sync (client, only_if_exists, cancellable, error);
-
- client->priv->opened = res;
-
- return res;
+ return klass->open_sync (client, only_if_exists, cancellable, error);
}
/**
@@ -1663,6 +1700,8 @@ e_client_util_unwrap_dbus_error (GError *dbus_error, GError **client_error, cons
return TRUE;
}
}
+
+ g_free (name);
}
}
diff --git a/libedataserver/e-client.h b/libedataserver/e-client.h
index b2ece72..5db9afb 100644
--- a/libedataserver/e-client.h
+++ b/libedataserver/e-client.h
@@ -36,7 +36,8 @@
#define E_IS_CLIENT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_TYPE_CLIENT))
#define E_CLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), E_TYPE_CLIENT, EClientClass))
-#define CLIENT_BACKEND_PROPERTY_LOADED "loaded"
+#define CLIENT_BACKEND_PROPERTY_OPENED "opened"
+#define CLIENT_BACKEND_PROPERTY_OPENING "opening"
#define CLIENT_BACKEND_PROPERTY_ONLINE "online"
#define CLIENT_BACKEND_PROPERTY_READONLY "readonly"
#define CLIENT_BACKEND_PROPERTY_CACHE_DIR "cache-dir"
@@ -103,6 +104,7 @@ struct _EClientClass {
/* signals */
gboolean (* authenticate) (EClient *client, ECredentials *credentials);
+ void (* opened) (EClient *client, const GError *error);
void (* backend_error) (EClient *client, const gchar *error_msg);
void (* backend_died) (EClient *client);
};
diff --git a/libedataserver/e-credentials.h b/libedataserver/e-credentials.h
index 223e344..06b0f26 100644
--- a/libedataserver/e-credentials.h
+++ b/libedataserver/e-credentials.h
@@ -39,6 +39,7 @@ typedef struct _ECredentials
#define E_CREDENTIALS_KEY_AUTH_DOMAIN "auth-domain"
#define E_CREDENTIALS_KEY_PROMPT_TITLE "prompt-title"
#define E_CREDENTIALS_KEY_PROMPT_TEXT "prompt-text"
+#define E_CREDENTIALS_KEY_PROMPT_REASON "prompt-reason"
#define E_CREDENTIALS_KEY_PROMPT_KEY "prompt-key"
#define E_CREDENTIALS_KEY_PROMPT_FLAGS "prompt-flags"
diff --git a/libedataserver/e-gdbus-templates.c b/libedataserver/e-gdbus-templates.c
index bf0f01c..3d8b450 100644
--- a/libedataserver/e-gdbus-templates.c
+++ b/libedataserver/e-gdbus-templates.c
@@ -1661,3 +1661,50 @@ e_gdbus_proxy_method_call_sync_strv__string (const gchar *method_name, GDBusProx
{
return proxy_method_call_sync (method_name, E_GDBUS_TYPE_STRV, in_strv, E_GDBUS_TYPE_STRING, out_string, proxy, cancellable, error);
}
+
+/* free returned pointer with g_strfreev() */
+gchar **
+e_gdbus_templates_encode_error (const GError *in_error)
+{
+ gchar **strv;
+
+ strv = g_new0 (gchar *, 3);
+
+ if (!in_error) {
+ strv[0] = g_strdup ("");
+ strv[1] = g_strdup ("");
+ } else {
+ gchar *dbus_error_name = g_dbus_error_encode_gerror (in_error);
+
+ strv[0] = e_util_utf8_make_valid (dbus_error_name ? dbus_error_name : "");
+ strv[1] = e_util_utf8_make_valid (in_error->message);
+
+ g_free (dbus_error_name);
+ }
+
+ return strv;
+}
+
+/* free *out_error with g_error_free(), if not NULL */
+gboolean
+e_gdbus_templates_decode_error (const gchar * const *in_strv, GError **out_error)
+{
+ const gchar *error_name, *error_message;
+
+ g_return_val_if_fail (out_error != NULL, FALSE);
+
+ *out_error = NULL;
+
+ g_return_val_if_fail (in_strv != NULL, FALSE);
+ g_return_val_if_fail (in_strv[0] != NULL, FALSE);
+ g_return_val_if_fail (in_strv[1] != NULL, FALSE);
+ g_return_val_if_fail (in_strv[2] == NULL, FALSE);
+
+ error_name = in_strv[0];
+ error_message = in_strv[1];
+
+ if (error_name && *error_name && error_message)
+ *out_error = g_dbus_error_new_for_dbus_error (error_name, error_message);
+
+ return TRUE;
+}
diff --git a/libedataserver/e-gdbus-templates.h b/libedataserver/e-gdbus-templates.h
index bedb51e..ce32798 100644
--- a/libedataserver/e-gdbus-templates.h
+++ b/libedataserver/e-gdbus-templates.h
@@ -163,17 +163,17 @@ enum {
(GDBusAnnotationInfo **) NULL, \
};
-#define E_DECLARE_GDBUS_SYNC_METHOD_0(_where, _name) \
- static const GDBusMethodInfo e_gdbus_ ## _where ## _method_ ## _name = \
+#define E_DECLARE_GDBUS_SYNC_METHOD_0(_where, _mname) \
+ static const GDBusMethodInfo e_gdbus_ ## _where ## _method_ ## _mname = \
{ \
-1, \
- (gchar *) # _name, \
+ (gchar *) # _mname, \
(GDBusArgInfo **) NULL, \
(GDBusArgInfo **) NULL, \
(GDBusAnnotationInfo **) NULL, \
};
-#define E_DECLARE_GDBUS_SYNC_METHOD_1(_where, _name, _p1_name, _p1_type) \
+#define E_DECLARE_GDBUS_SYNC_METHOD_1(_where, _mname, _p1_name, _p1_type) \
E_DECLARE_GDBUS_ARG (_where, _mname, method_in, _p1_name, _p1_type) \
\
static const GDBusArgInfo * const e_gdbus_ ## _where ## _method_in_arg_pointers_ ## _mname[] = \
@@ -182,10 +182,10 @@ enum {
NULL \
}; \
\
- static const GDBusMethodInfo e_gdbus_ ## _where ## _method_ ## _name = \
+ static const GDBusMethodInfo e_gdbus_ ## _where ## _method_ ## _mname = \
{ \
-1, \
- (gchar *) # _name, \
+ (gchar *) # _mname, \
(GDBusArgInfo **) &e_gdbus_ ## _where ## _method_in_arg_pointers_ ## _mname, \
(GDBusArgInfo **) NULL, \
(GDBusAnnotationInfo **) NULL, \
@@ -742,6 +742,9 @@ gboolean e_gdbus_proxy_method_call_sync_uint__void (const gchar *method_name, GD
gboolean e_gdbus_proxy_method_call_sync_string__string (const gchar *method_name, GDBusProxy *proxy, const gchar *in_string, gchar **out_string, GCancellable *cancellable, GError **error);
gboolean e_gdbus_proxy_method_call_sync_strv__string (const gchar *method_name, GDBusProxy *proxy, const gchar * const *in_strv, gchar **out_string, GCancellable *cancellable, GError **error);
+gchar ** e_gdbus_templates_encode_error (const GError *in_error);
+gboolean e_gdbus_templates_decode_error (const gchar * const *in_strv, GError **out_error);
+
G_END_DECLS
#endif /* E_GDBUS_TEMPLATES_H */
diff --git a/libedataserverui/e-client-utils.c b/libedataserverui/e-client-utils.c
index d7ad96a..032ee5e 100644
--- a/libedataserverui/e-client-utils.c
+++ b/libedataserverui/e-client-utils.c
@@ -264,6 +264,357 @@ e_client_utils_get_sources (ESourceList **sources, EClientSourceType source_type
return res;
}
+typedef struct _EClientUtilsAsyncOpData
+{
+ EClientUtilsAuthenticateHandler auth_handler;
+ gpointer auth_handler_user_data;
+ GAsyncReadyCallback async_cb;
+ gpointer async_cb_user_data;
+ GCancellable *cancellable;
+ EClient *client;
+ ECredentials *used_credentials;
+ gboolean open_finished;
+ GError *opened_cb_error;
+} EClientUtilsAsyncOpData;
+
+static void
+free_client_utils_async_op_data (EClientUtilsAsyncOpData *async_data)
+{
+ g_return_if_fail (async_data != NULL);
+ g_return_if_fail (async_data->cancellable != NULL);
+ g_return_if_fail (async_data->client != NULL);
+
+ g_signal_handlers_disconnect_matched (async_data->cancellable, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, async_data);
+ g_signal_handlers_disconnect_matched (async_data->client, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, async_data);
+
+ if (async_data->used_credentials)
+ e_credentials_free (async_data->used_credentials);
+ if (async_data->opened_cb_error)
+ g_error_free (async_data->opened_cb_error);
+ g_object_unref (async_data->cancellable);
+ g_object_unref (async_data->client);
+ g_free (async_data);
+}
+
+static gboolean
+complete_async_op_in_idle_cb (gpointer user_data)
+{
+ GSimpleAsyncResult *simple = user_data;
+ gint run_main_depth;
+
+ g_return_val_if_fail (simple != NULL, FALSE);
+
+ run_main_depth = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (simple), "run-main-depth"));
+ if (run_main_depth < 1)
+ run_main_depth = 1;
+
+ /* do not receive in higher level than was initially run */
+ if (g_main_depth () > run_main_depth) {
+ return TRUE;
+ }
+
+ g_simple_async_result_complete (simple);
+ g_object_unref (simple);
+
+ return FALSE;
+}
+
+#define return_async_error_if_fail(expr, async_cb, async_cb_user_data, source_tag) G_STMT_START { \
+ if (G_LIKELY ((expr))) { } else { \
+ GError *error; \
+ \
+ error = g_error_new (E_CLIENT_ERROR, E_CLIENT_ERROR_INVALID_ARG, \
+ "%s: assertion '%s' failed", G_STRFUNC, #expr); \
+ \
+ return_async_error (error, async_cb, async_cb_user_data, source_tag); \
+ g_error_free (error); \
+ return; \
+ } \
+ } G_STMT_END
+
+static void
+return_async_error (const GError *error, GAsyncReadyCallback async_cb, gpointer async_cb_user_data, gpointer source_tag)
+{
+ GSimpleAsyncResult *simple;
+
+ g_return_if_fail (error != NULL);
+ g_return_if_fail (source_tag != NULL);
+
+ simple = g_simple_async_result_new (NULL, async_cb, async_cb_user_data, source_tag);
+ g_simple_async_result_set_from_error (simple, error);
+
+ g_object_set_data (G_OBJECT (simple), "run-main-depth", GINT_TO_POINTER (g_main_depth ()));
+ g_idle_add (complete_async_op_in_idle_cb, simple);
+}
+
+static void
+client_utils_open_new_done (EClientUtilsAsyncOpData *async_data)
+{
+ GSimpleAsyncResult *simple;
+
+ g_return_if_fail (async_data != NULL);
+ g_return_if_fail (async_data->client != NULL);
+
+ /* keep the initial auth_handler connected directly, thus it will be able
+ to answer any later authentication requests, for reconnection, for example
+ */
+ if (async_data->auth_handler)
+ g_signal_connect (async_data->client, "authenticate", G_CALLBACK (async_data->auth_handler), async_data->auth_handler_user_data);
+
+ simple = g_simple_async_result_new (NULL, async_data->async_cb, async_data->async_cb_user_data, e_client_utils_open_new);
+ g_simple_async_result_set_op_res_gpointer (simple, g_object_ref (async_data->client), g_object_unref);
+
+ g_object_set_data (G_OBJECT (simple), "run-main-depth", GINT_TO_POINTER (g_main_depth ()));
+ g_idle_add (complete_async_op_in_idle_cb, simple);
+
+ free_client_utils_async_op_data (async_data);
+}
+
+static void
+client_utils_open_new_cancelled_cb (GCancellable *cancellable, EClientUtilsAsyncOpData *async_data)
+{
+ GError *error = NULL;
+
+ g_return_if_fail (cancellable != NULL);
+ g_return_if_fail (async_data != NULL);
+ g_return_if_fail (async_data->cancellable == cancellable);
+ g_return_if_fail (g_cancellable_set_error_if_cancelled (cancellable, &error));
+
+ return_async_error (error, async_data->async_cb, async_data->async_cb_user_data, e_client_utils_open_new);
+ free_client_utils_async_op_data (async_data);
+ g_error_free (error);
+}
+
+static void
+finish_or_retry_open (EClientUtilsAsyncOpData *async_data, const GError *error)
+{
+ g_return_if_fail (async_data != NULL);
+
+ if (async_data->auth_handler && error && g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_AUTHENTICATION_FAILED)) {
+ if (async_data->used_credentials) {
+ const gchar *auth_domain, *prompt_key;
+
+ auth_domain = e_credentials_peek (async_data->used_credentials, E_CREDENTIALS_KEY_AUTH_DOMAIN);
+ prompt_key = e_credentials_peek (async_data->used_credentials, E_CREDENTIALS_KEY_PROMPT_KEY);
+
+ /* make sure the old password is forgotten when authentication failed */
+ if (auth_domain && prompt_key)
+ e_passwords_forget_password (auth_domain, prompt_key);
+
+ e_credentials_set (async_data->used_credentials, E_CREDENTIALS_KEY_PROMPT_REASON, error->message);
+ }
+
+ e_client_process_authentication (async_data->client, async_data->used_credentials);
+ } else if (error) {
+ return_async_error (error, async_data->async_cb, async_data->async_cb_user_data, e_client_utils_open_new);
+ free_client_utils_async_op_data (async_data);
+ } else {
+ client_utils_open_new_done (async_data);
+ }
+}
+
+static void
+client_utils_opened_cb (EClient *client, const GError *error, EClientUtilsAsyncOpData *async_data)
+{
+ g_return_if_fail (client != NULL);
+ g_return_if_fail (async_data != NULL);
+ g_return_if_fail (client == async_data->client);
+
+ if (!async_data->open_finished) {
+ /* there can happen that the "opened" signal is received
+ before the e_client_open() is finished, thus keep detailed
+ error for later use, if any */
+ if (error)
+ async_data->opened_cb_error = g_error_copy (error);
+ } else {
+ finish_or_retry_open (async_data, error);
+ }
+}
+
+static void
+client_utils_open_new_async_cb (GObject *source_object, GAsyncResult *result, gpointer user_data)
+{
+ EClientUtilsAsyncOpData *async_data = user_data;
+ GError *error = NULL;
+
+ g_return_if_fail (source_object != NULL);
+ g_return_if_fail (result != NULL);
+ g_return_if_fail (async_data != NULL);
+ g_return_if_fail (async_data->async_cb != NULL);
+ g_return_if_fail (async_data->client == E_CLIENT (source_object));
+
+ async_data->open_finished = TRUE;
+
+ if (!e_client_open_finish (E_CLIENT (source_object), result, &error)
+ || g_cancellable_set_error_if_cancelled (async_data->cancellable, &error)) {
+ finish_or_retry_open (async_data, error);
+ g_error_free (error);
+ return;
+ }
+
+ if (async_data->opened_cb_error) {
+ finish_or_retry_open (async_data, async_data->opened_cb_error);
+ return;
+ }
+
+ if (e_client_is_opened (async_data->client)) {
+ client_utils_open_new_done (async_data);
+ return;
+ }
+
+ /* wait for 'opened' signal, which is received in client_utils_opened_cb */
+ g_signal_connect (async_data->cancellable, "cancelled", G_CALLBACK (client_utils_open_new_cancelled_cb), async_data);
+}
+
+static gboolean
+client_utils_open_new_auth_cb (EClient *client, ECredentials *credentials, gpointer user_data)
+{
+ EClientUtilsAsyncOpData *async_data = user_data;
+ gboolean handled;
+
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (async_data != NULL, FALSE);
+ g_return_val_if_fail (async_data->auth_handler != NULL, FALSE);
+
+ if (async_data->used_credentials) {
+ const gchar *reason = e_credentials_peek (async_data->used_credentials, E_CREDENTIALS_KEY_PROMPT_REASON);
+
+ if (reason) {
+ e_credentials_set (credentials, E_CREDENTIALS_KEY_PROMPT_TEXT, NULL);
+ e_credentials_set (credentials, E_CREDENTIALS_KEY_PROMPT_REASON, reason);
+ }
+ }
+
+ handled = async_data->auth_handler (client, credentials, async_data->auth_handler_user_data);
+
+ if (handled && credentials) {
+ if (async_data->used_credentials) {
+ gchar *prompt_flags_str;
+ guint prompt_flags = 0;
+
+ e_credentials_free (async_data->used_credentials);
+
+ prompt_flags_str = e_credentials_get (credentials, E_CREDENTIALS_KEY_PROMPT_FLAGS);
+ if (prompt_flags_str) {
+ prompt_flags = e_credentials_util_string_to_prompt_flags (prompt_flags_str);
+ g_free (prompt_flags_str);
+ } else {
+ prompt_flags = E_CREDENTIALS_PROMPT_FLAG_REMEMBER_FOREVER
+ | E_CREDENTIALS_PROMPT_FLAG_SECRET
+ | E_CREDENTIALS_PROMPT_FLAG_ONLINE;
+ }
+
+ prompt_flags |= E_CREDENTIALS_PROMPT_FLAG_REPROMPT;
+
+ prompt_flags_str = e_credentials_util_prompt_flags_to_string (prompt_flags);
+ e_credentials_set (credentials, E_CREDENTIALS_KEY_PROMPT_FLAGS, prompt_flags_str);
+ g_free (prompt_flags_str);
+ }
+
+ async_data->used_credentials = e_credentials_new_clone (credentials);
+ }
+
+ return handled;
+}
+
+/**
+ * e_client_utils_open_new:
+ * @source: an #ESource to be opened
+ * @source_type: an #EClientSourceType of the @source
+ * @only_if_exists: if %TRUE, fail if this client doesn't already exist, otherwise create it first
+ * @auth_handler: authentication handler, to be used; the e_client_utils_authenticate_handler() is usually sufficient
+ * @auth_handler_user_data: user data for @auth_handler function
+ * @cancellable: a #GCancellable; can be %NULL
+ * @async_cb: callback to call when a result is ready
+ * @async_cb_user_data: user data for the @async_cb
+ *
+ * Begins asynchronous opening of a new #EClient corresponding
+ * to the @source of type @source_type. The resulting #EClient
+ * is fully opened and authenticated client, ready to be used.
+ * This call is finished by e_client_utils_open_new_finish()
+ * from the @async_cb.
+ *
+ * Note: the @auth_handler, and its @auth_handler_user_data,
+ * should be valid through whole live of returned #EClient.
+ *
+ * Since: 3.2
+ **/
+void
+e_client_utils_open_new (ESource *source, EClientSourceType source_type, gboolean only_if_exists,
+ EClientUtilsAuthenticateHandler auth_handler, gpointer auth_handler_user_data,
+ GCancellable *cancellable, GAsyncReadyCallback async_cb, gpointer async_cb_user_data)
+{
+ EClient *client;
+ GError *error = NULL;
+ EClientUtilsAsyncOpData *async_data;
+
+ g_return_if_fail (async_cb != NULL);
+ return_async_error_if_fail (source != NULL, async_cb, async_cb_user_data, e_client_utils_open_new);
+ return_async_error_if_fail (E_IS_SOURCE (source), async_cb, async_cb_user_data, e_client_utils_open_new);
+
+ client = e_client_utils_new (source, source_type, &error);
+ if (!client) {
+ return_async_error (error, async_cb, async_cb_user_data, e_client_utils_open_new);
+ g_error_free (error);
+ return;
+ }
+
+ async_data = g_new0 (EClientUtilsAsyncOpData, 1);
+ async_data->auth_handler = auth_handler;
+ async_data->auth_handler_user_data = auth_handler_user_data;
+ async_data->async_cb = async_cb;
+ async_data->async_cb_user_data = async_cb_user_data;
+ async_data->client = client;
+ async_data->open_finished = FALSE;
+ if (cancellable)
+ async_data->cancellable = g_object_ref (cancellable);
+ else
+ async_data->cancellable = g_cancellable_new ();
+
+ if (auth_handler)
+ g_signal_connect (client, "authenticate", G_CALLBACK (client_utils_open_new_auth_cb), async_data);
+
+
+ /* wait till backend notifies about its opened state */
+ g_signal_connect (client, "opened", G_CALLBACK (client_utils_opened_cb), async_data);
+
+ e_client_open (client, only_if_exists, async_data->cancellable, client_utils_open_new_async_cb, async_data);
+}
+
+/**
+ * e_client_utils_open_new_finish:
+ * @result: a #GAsyncResult
+ * @client: (out): Return value for an #EClient.
+ * @error: (out): a #GError to set an error, if any
+ *
+ * Finishes previous call of e_client_utils_open_new() and
+ * sets @client to a fully opened and authenticated #EClient.
+ * This @client, if not NULL, should be freed with g_object_unref().
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 3.2
+ **/
+gboolean
+e_client_utils_open_new_finish (GAsyncResult *result, EClient **client, GError **error)
+{
+ GSimpleAsyncResult *simple;
+
+ g_return_val_if_fail (result != NULL, FALSE);
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (g_simple_async_result_is_valid (result, NULL, e_client_utils_open_new), FALSE);
+
+ *client = NULL;
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+
+ if (g_simple_async_result_propagate_error (simple, error))
+ return FALSE;
+
+ *client = g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
+
+ return *client != NULL;
+}
+
/* This function is suitable as a handler for EClient::authenticate signal.
It takes care of all the password prompt and such and returns TRUE if
credentials (password) were provided. Thus just connect it to that signal
@@ -298,18 +649,24 @@ e_client_utils_authenticate_handler (EClient *client, ECredentials *credentials,
e_credentials_set (credentials, E_CREDENTIALS_KEY_AUTH_DOMAIN, is_book ? E_CREDENTIALS_AUTH_DOMAIN_ADDRESSBOOK : E_CREDENTIALS_AUTH_DOMAIN_CALENDAR);
if (!e_credentials_has_key (credentials, E_CREDENTIALS_KEY_PROMPT_TEXT)) {
- gchar *prompt;
+ gchar *prompt, *reason;
gchar *username_markup, *source_name_markup;
+ reason = e_credentials_get (credentials, E_CREDENTIALS_KEY_PROMPT_REASON);
username_markup = g_markup_printf_escaped ("<b>%s</b>", e_credentials_peek (credentials, E_CREDENTIALS_KEY_USERNAME));
source_name_markup = g_markup_printf_escaped ("<b>%s</b>", e_source_peek_name (source));
- prompt = g_strdup_printf (_("Enter password for %s (user %s)"), source_name_markup, username_markup);
+
+ if (reason && *reason)
+ prompt = g_strdup_printf (_("Enter password for %s (user %s)\nReason: %s"), source_name_markup, username_markup, reason);
+ else
+ prompt = g_strdup_printf (_("Enter password for %s (user %s)"), source_name_markup, username_markup);
e_credentials_set (credentials, E_CREDENTIALS_KEY_PROMPT_TEXT, prompt);
g_free (username_markup);
g_free (source_name_markup);
+ g_free (reason);
g_free (prompt);
}
@@ -373,7 +730,9 @@ e_credentials_authenticate_helper (ECredentials *credentials, GtkWindow *parent,
if (e_credentials_has_key (credentials, E_CREDENTIALS_KEY_PROMPT_FLAGS)) {
prompt_flags = e_credentials_util_string_to_prompt_flags (e_credentials_peek (credentials, E_CREDENTIALS_KEY_PROMPT_FLAGS));
} else {
- prompt_flags = E_CREDENTIALS_PROMPT_FLAG_SECRET | E_CREDENTIALS_PROMPT_FLAG_ONLINE;
+ prompt_flags = E_CREDENTIALS_PROMPT_FLAG_REMEMBER_FOREVER
+ | E_CREDENTIALS_PROMPT_FLAG_SECRET
+ | E_CREDENTIALS_PROMPT_FLAG_ONLINE;
}
if (!remember_password) {
diff --git a/libedataserverui/e-client-utils.h b/libedataserverui/e-client-utils.h
index b97c9c0..b6a189f 100644
--- a/libedataserverui/e-client-utils.h
+++ b/libedataserverui/e-client-utils.h
@@ -33,7 +33,8 @@ typedef enum {
E_CLIENT_SOURCE_TYPE_CONTACTS,
E_CLIENT_SOURCE_TYPE_EVENTS,
E_CLIENT_SOURCE_TYPE_MEMOS,
- E_CLIENT_SOURCE_TYPE_TASKS
+ E_CLIENT_SOURCE_TYPE_TASKS,
+ E_CLIENT_SOURCE_TYPE_LAST
} EClientSourceType;
typedef gboolean (* EClientUtilsAuthenticateHandler) (EClient *client, ECredentials *credentials, gpointer user_data);
@@ -47,6 +48,11 @@ gboolean e_client_utils_set_default (EClient *client, EClientSourceType source_
gboolean e_client_utils_set_default_source (ESource *source, EClientSourceType source_type, GError **error);
gboolean e_client_utils_get_sources (ESourceList **sources, EClientSourceType source_type, GError **error);
+void e_client_utils_open_new (ESource *source, EClientSourceType source_type, gboolean only_if_exists,
+ EClientUtilsAuthenticateHandler auth_handler, gpointer auth_handler_user_data,
+ GCancellable *cancellable, GAsyncReadyCallback async_cb, gpointer async_cb_user_data);
+gboolean e_client_utils_open_new_finish (GAsyncResult *result, EClient **client, GError **error);
+
gboolean e_client_utils_authenticate_handler (EClient *client, ECredentials *credentials, gpointer unused_user_data);
gboolean e_credentials_authenticate_helper (ECredentials *credentials, GtkWindow *parent, gboolean *remember_password);
diff --git a/tests/libebook/client/client-test-utils.c b/tests/libebook/client/client-test-utils.c
index 6a7004e..13acd6a 100644
--- a/tests/libebook/client/client-test-utils.c
+++ b/tests/libebook/client/client-test-utils.c
@@ -294,9 +294,8 @@ foreach_configured_source_async_next (gpointer *foreach_async_data, ESource **so
do {
async_data->current_group = async_data->current_group->next;
- if (async_data->current_group) {
+ if (async_data->current_group)
async_data->current_source = e_source_group_peek_sources (async_data->current_group->data);
- }
} while (async_data->current_group && !async_data->current_source);
if (async_data->current_source) {
diff --git a/tests/libebook/client/test-client-examine.c b/tests/libebook/client/test-client-examine.c
index 731eb9f..687c74a 100644
--- a/tests/libebook/client/test-client-examine.c
+++ b/tests/libebook/client/test-client-examine.c
@@ -14,7 +14,8 @@ get_known_prop_names (void)
{
GSList *prop_names = NULL;
- prop_names = g_slist_append (prop_names, (gpointer) CLIENT_BACKEND_PROPERTY_LOADED);
+ prop_names = g_slist_append (prop_names, (gpointer) CLIENT_BACKEND_PROPERTY_OPENED);
+ prop_names = g_slist_append (prop_names, (gpointer) CLIENT_BACKEND_PROPERTY_OPENING);
prop_names = g_slist_append (prop_names, (gpointer) CLIENT_BACKEND_PROPERTY_ONLINE);
prop_names = g_slist_append (prop_names, (gpointer) CLIENT_BACKEND_PROPERTY_READONLY);
prop_names = g_slist_append (prop_names, (gpointer) CLIENT_BACKEND_PROPERTY_CACHE_DIR);
@@ -87,6 +88,7 @@ print_values (const ExtraValues *evals, EClient *client)
g_print ("\treadonly:%s\n", e_client_is_readonly (client) ? "yes" : "no");
g_print ("\tonline:%s\n", e_client_is_online (client) ? "yes" : "no");
+ g_print ("\topened:%s\n", e_client_is_opened (client) ? "yes" : "no");
g_print ("\tcapabilities: ");
values = e_client_get_capabilities (client);
if (!values) {
@@ -360,8 +362,6 @@ in_main_thread_idle_cb (gpointer unused)
{
g_print ("* run in main thread with mainloop running\n");
foreach_configured_source (check_source_sync);
- foreach_configured_source (check_source_sync);
- foreach_configured_source (check_source_sync);
g_print ("---------------------------------------------------------\n\n");
g_print ("* run in main thread async\n");
@@ -377,8 +377,6 @@ worker_thread (gpointer unused)
{
g_print ("* run in dedicated thread with mainloop running\n");
foreach_configured_source (check_source_sync);
- foreach_configured_source (check_source_sync);
- foreach_configured_source (check_source_sync);
g_print ("---------------------------------------------------------\n\n");
g_idle_add (in_main_thread_idle_cb, NULL);
@@ -393,8 +391,6 @@ main (gint argc, gchar **argv)
g_print ("* run in main thread without mainloop\n");
foreach_configured_source (check_source_sync);
- foreach_configured_source (check_source_sync);
- foreach_configured_source (check_source_sync);
g_print ("---------------------------------------------------------\n\n");
start_in_thread_with_main_loop (worker_thread, NULL);
diff --git a/tests/libecal/client/test-client-examine.c b/tests/libecal/client/test-client-examine.c
index 0d994be..3a1298e 100644
--- a/tests/libecal/client/test-client-examine.c
+++ b/tests/libecal/client/test-client-examine.c
@@ -14,7 +14,8 @@ get_known_prop_names (void)
{
GSList *prop_names = NULL;
- prop_names = g_slist_append (prop_names, (gpointer) CLIENT_BACKEND_PROPERTY_LOADED);
+ prop_names = g_slist_append (prop_names, (gpointer) CLIENT_BACKEND_PROPERTY_OPENED);
+ prop_names = g_slist_append (prop_names, (gpointer) CLIENT_BACKEND_PROPERTY_OPENING);
prop_names = g_slist_append (prop_names, (gpointer) CLIENT_BACKEND_PROPERTY_ONLINE);
prop_names = g_slist_append (prop_names, (gpointer) CLIENT_BACKEND_PROPERTY_READONLY);
prop_names = g_slist_append (prop_names, (gpointer) CLIENT_BACKEND_PROPERTY_CACHE_DIR);
@@ -108,6 +109,7 @@ print_values (const ExtraValues *evals, EClient *client)
g_print ("\treadonly:%s\n", e_client_is_readonly (client) ? "yes" : "no");
g_print ("\tonline:%s\n", e_client_is_online (client) ? "yes" : "no");
+ g_print ("\topened:%s\n", e_client_is_opened (client) ? "yes" : "no");
g_print ("\tcache dir: %s%s%s\n", evals->cache_dir ? "'" : "", evals->cache_dir ? evals->cache_dir : "none", evals->cache_dir ? "'" : "");
g_print ("\tcapabilities: ");
values = e_client_get_capabilities (client);
diff --git a/tests/libedataserverui/Makefile.am b/tests/libedataserverui/Makefile.am
index 4473a07..4603dff 100644
--- a/tests/libedataserverui/Makefile.am
+++ b/tests/libedataserverui/Makefile.am
@@ -1,5 +1,6 @@
noinst_PROGRAMS = \
test-category-completion \
+ test-client-examine-auth \
test-source-combo-box \
test-source-selector \
test-contact-store \
@@ -27,6 +28,10 @@ test_category_completion_CPPFLAGS = $(TEST_EDATASERVERUI_CPPFLAGS)
test_category_completion_SOURCES = test-category-completion.c
test_category_completion_LDADD = $(TEST_EDATASERVERUI_LDFLAGS)
+test_client_examine_auth_CPPFLAGS = $(TEST_EDATASERVERUI_CPPFLAGS)
+test_client_examine_auth_SOURCES = test-client-examine-auth.c
+test_client_examine_auth_LDADD = $(TEST_EDATASERVERUI_LDFLAGS)
+
test_source_selector_CPPFLAGS = $(TEST_EDATASERVERUI_CPPFLAGS)
test_source_selector_SOURCES = test-source-selector.c
test_source_selector_LDADD = $(TEST_EDATASERVERUI_LDFLAGS)
diff --git a/tests/libedataserverui/test-client-examine-auth.c b/tests/libedataserverui/test-client-examine-auth.c
new file mode 100644
index 0000000..d63f4d5
--- /dev/null
+++ b/tests/libedataserverui/test-client-examine-auth.c
@@ -0,0 +1,418 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+#include <glib.h>
+
+#include <libedataserver/e-source-group.h>
+#include <libedataserverui/e-client-utils.h>
+#include <libedataserverui/e-passwords.h>
+
+static void stop_main_loop (gint stop_result);
+static void report_error (const gchar *operation, GError **error);
+static gpointer foreach_configured_source_async_start (ESource **source);
+static gboolean foreach_configured_source_async_next (gpointer *foreach_async_data, ESource **source);
+static gboolean foreach_async (void);
+
+static gint running_async = 0;
+static EClientSourceType source_type = E_CLIENT_SOURCE_TYPE_CONTACTS;
+
+static GSList *
+get_known_prop_names (void)
+{
+ GSList *prop_names = NULL;
+
+ prop_names = g_slist_append (prop_names, (gpointer) CLIENT_BACKEND_PROPERTY_OPENED);
+ prop_names = g_slist_append (prop_names, (gpointer) CLIENT_BACKEND_PROPERTY_OPENING);
+ prop_names = g_slist_append (prop_names, (gpointer) CLIENT_BACKEND_PROPERTY_ONLINE);
+ prop_names = g_slist_append (prop_names, (gpointer) CLIENT_BACKEND_PROPERTY_READONLY);
+ prop_names = g_slist_append (prop_names, (gpointer) CLIENT_BACKEND_PROPERTY_CACHE_DIR);
+ prop_names = g_slist_append (prop_names, (gpointer) CLIENT_BACKEND_PROPERTY_CAPABILITIES);
+
+ return prop_names;
+}
+
+typedef struct _ExtraValues {
+ gpointer async_data;
+
+ GSList *todo_prop_names;
+ GHashTable *retrieved_props;
+} ExtraValues;
+
+static void
+extra_values_free (ExtraValues *evals)
+{
+ if (!evals)
+ return;
+
+ g_slist_free (evals->todo_prop_names);
+ g_hash_table_destroy (evals->retrieved_props);
+ g_free (evals);
+}
+
+static void
+print_each_property (gpointer prop_name, gpointer prop_value, gpointer user_data)
+{
+ g_return_if_fail (prop_name != NULL);
+
+ if (prop_value == NULL) {
+ g_print ("\t %s: NULL\n", (const gchar *) prop_name);
+ return;
+ }
+
+ g_print ("\t %s: ", (const gchar *) prop_name);
+
+ if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_CAPABILITIES)) {
+ GSList *values = e_client_util_parse_comma_strings (prop_value), *v;
+
+
+ for (v = values; v; v = v->next) {
+ if (v != values)
+ g_print (", ");
+
+ g_print ("'%s'", (const gchar *) v->data);
+ }
+
+ e_client_util_free_string_slist (values);
+ } else {
+ g_print ("'%s'", (const gchar *) prop_value);
+ }
+
+ g_print ("\n");
+}
+
+static void
+print_values (const ExtraValues *evals, EClient *client)
+{
+ const GSList *values;
+
+ g_return_if_fail (evals != NULL);
+
+ g_print ("\treadonly:%s\n", e_client_is_readonly (client) ? "yes" : "no");
+ g_print ("\tonline:%s\n", e_client_is_online (client) ? "yes" : "no");
+ g_print ("\topened:%s\n", e_client_is_opened (client) ? "yes" : "no");
+ g_print ("\tcapabilities: ");
+ values = e_client_get_capabilities (client);
+ if (!values) {
+ g_print ("NULL");
+ } else {
+ while (values) {
+ const gchar *cap = values->data;
+
+ g_print ("'%s'", cap);
+ if (!e_client_check_capability (client, cap))
+ g_print (" (not found in EClient)");
+
+ values = values->next;
+
+ if (values)
+ g_print (", ");
+ }
+ }
+ g_print ("\n");
+
+ g_print ("\tbackend properties:\n");
+ g_hash_table_foreach (evals->retrieved_props, print_each_property, NULL);
+}
+
+static void
+identify_source (ESource *source)
+{
+ const gchar *name, *uri;
+ gchar *abs_uri = NULL;
+
+ g_return_if_fail (source != NULL);
+
+ name = e_source_peek_name (source);
+ if (!name)
+ name = "Unknown name";
+
+ uri = e_source_peek_absolute_uri (source);
+ if (!uri) {
+ abs_uri = e_source_build_absolute_uri (source);
+ uri = abs_uri;
+ }
+ if (!uri)
+ uri = e_source_peek_relative_uri (source);
+ if (!uri)
+ uri = "Unknown uri";
+
+ g_print ("\n Checking source '%s' (%s)\n", name, uri);
+
+ g_free (abs_uri);
+}
+
+static void client_opened_async (GObject *source_object, GAsyncResult *result, gpointer async_data);
+
+static void
+continue_next_source (gpointer async_data)
+{
+ ESource *source = NULL;
+
+ g_return_if_fail (async_data != NULL);
+
+ while (async_data && foreach_configured_source_async_next (&async_data, &source)) {
+ identify_source (source);
+ e_client_utils_open_new (source, source_type, TRUE,
+ e_client_utils_authenticate_handler, NULL,
+ NULL, client_opened_async, async_data);
+ break;
+ }
+
+ if (!async_data) {
+ running_async--;
+ if (!running_async) {
+ while (source_type++, source_type < E_CLIENT_SOURCE_TYPE_LAST) {
+ if (foreach_async ())
+ return;
+ }
+
+ stop_main_loop (0);
+ }
+ }
+}
+
+static void
+client_got_backend_property_async (GObject *source_object, GAsyncResult *result, gpointer user_data)
+{
+ ExtraValues *evals = user_data;
+ gchar *prop_value = NULL;
+ GError *error = NULL;
+ EClient *client;
+
+ g_return_if_fail (source_object != NULL);
+ g_return_if_fail (E_IS_CLIENT (source_object));
+ g_return_if_fail (evals != NULL);
+
+ client = E_CLIENT (source_object);
+
+ if (!e_client_get_backend_property_finish (client, result, &prop_value, &error)) {
+ report_error ("get backend property finish", &error);
+ }
+
+ g_hash_table_insert (evals->retrieved_props, evals->todo_prop_names->data, prop_value);
+ evals->todo_prop_names = g_slist_remove (evals->todo_prop_names, evals->todo_prop_names->data);
+
+ if (!evals->todo_prop_names) {
+ /* to cache them, as it can be fetched with idle as well */
+ e_client_get_capabilities (client);
+
+ print_values (evals, client);
+
+ g_object_unref (source_object);
+
+ continue_next_source (evals->async_data);
+ extra_values_free (evals);
+ } else {
+ e_client_get_backend_property (client, evals->todo_prop_names->data, NULL, client_got_backend_property_async, evals);
+ }
+}
+
+static void
+client_set_backend_property_async (GObject *source_object, GAsyncResult *result, gpointer user_data)
+{
+ ExtraValues *evals = user_data;
+ GError *error = NULL;
+ EClient *client;
+
+ g_return_if_fail (source_object != NULL);
+ g_return_if_fail (E_IS_CLIENT (source_object));
+ g_return_if_fail (evals != NULL);
+
+ client = E_CLIENT (source_object);
+
+ if (!e_client_set_backend_property_finish (client, result, &error)) {
+ /* it may fail on the set_backend_property */
+ g_clear_error (&error);
+ } else {
+ g_printerr (" Might fail on set_backend_property, but reported success\n");
+ }
+
+ e_client_get_backend_property (client, evals->todo_prop_names->data, NULL, client_got_backend_property_async, evals);
+}
+
+static void
+client_opened_async (GObject *source_object, GAsyncResult *result, gpointer async_data)
+{
+ ExtraValues *evals;
+ GError *error = NULL;
+ EClient *client = NULL;
+
+ g_return_if_fail (source_object == NULL);
+ g_return_if_fail (async_data != NULL);
+
+ if (!e_client_utils_open_new_finish (result, &client, &error)) {
+ report_error ("client utils open new finish", &error);
+ continue_next_source (async_data);
+ return;
+ }
+
+ evals = g_new0 (ExtraValues, 1);
+ evals->async_data = async_data;
+ evals->todo_prop_names = get_known_prop_names ();
+ evals->retrieved_props = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
+
+ e_client_set_backend_property (client, "*unknown*property*", "*value*", NULL, client_set_backend_property_async, evals);
+}
+
+static gboolean
+foreach_async (void)
+{
+ gpointer async_data;
+ ESource *source = NULL;
+
+ async_data = foreach_configured_source_async_start (&source);
+ if (!async_data) {
+ stop_main_loop (1);
+ return FALSE;
+ }
+
+ running_async++;
+
+ identify_source (source);
+ e_client_utils_open_new (source, source_type, TRUE,
+ e_client_utils_authenticate_handler, NULL,
+ NULL, client_opened_async, async_data);
+
+ return TRUE;
+}
+
+static gboolean
+in_main_thread_idle_cb (gpointer unused)
+{
+ if (!foreach_async ())
+ return FALSE;
+
+ return FALSE;
+}
+
+static GMainLoop *loop = NULL;
+static gint main_stop_result = 0;
+
+static void
+stop_main_loop (gint stop_result)
+{
+ g_return_if_fail (loop != NULL);
+
+ main_stop_result = stop_result;
+ g_main_loop_quit (loop);
+}
+
+static gint
+get_main_loop_stop_result (void)
+{
+ return main_stop_result;
+}
+
+struct ForeachConfiguredData
+{
+ ESourceList *source_list;
+ GSList *current_group;
+ GSList *current_source;
+};
+
+static gpointer
+foreach_configured_source_async_start (ESource **source)
+{
+ struct ForeachConfiguredData *async_data;
+ ESourceList *source_list = NULL;
+ GError *error = NULL;
+
+ g_return_val_if_fail (source != NULL, NULL);
+
+ if (!e_client_utils_get_sources (&source_list, source_type, &error)) {
+ report_error ("get sources", &error);
+ return NULL;
+ }
+
+ g_return_val_if_fail (source_list != NULL, NULL);
+
+ async_data = g_new0 (struct ForeachConfiguredData, 1);
+ async_data->source_list = source_list;
+ async_data->current_group = e_source_list_peek_groups (source_list);
+ if (!async_data->current_group) {
+ gpointer ad = async_data;
+
+ foreach_configured_source_async_next (&ad, source);
+ return ad;
+ }
+
+ async_data->current_source = e_source_group_peek_sources (async_data->current_group->data);
+ if (!async_data->current_source) {
+ gpointer ad = async_data;
+
+ if (foreach_configured_source_async_next (&ad, source))
+ return ad;
+
+ return NULL;
+ }
+
+ *source = async_data->current_source->data;
+
+ return async_data;
+}
+
+static gboolean
+foreach_configured_source_async_next (gpointer *foreach_async_data, ESource **source)
+{
+ struct ForeachConfiguredData *async_data;
+
+ g_return_val_if_fail (foreach_async_data != NULL, FALSE);
+ g_return_val_if_fail (source != NULL, FALSE);
+
+ async_data = *foreach_async_data;
+ g_return_val_if_fail (async_data != NULL, FALSE);
+ g_return_val_if_fail (async_data->source_list != NULL, FALSE);
+ g_return_val_if_fail (async_data->current_group != NULL, FALSE);
+
+ if (async_data->current_source)
+ async_data->current_source = async_data->current_source->next;
+ if (async_data->current_source) {
+ *source = async_data->current_source->data;
+ return TRUE;
+ }
+
+ do {
+ async_data->current_group = async_data->current_group->next;
+ if (async_data->current_group)
+ async_data->current_source = e_source_group_peek_sources (async_data->current_group->data);
+ } while (async_data->current_group && !async_data->current_source);
+
+ if (async_data->current_source) {
+ *source = async_data->current_source->data;
+ return TRUE;
+ }
+
+ g_object_unref (async_data->source_list);
+ g_free (async_data);
+
+ *foreach_async_data = NULL;
+
+ return FALSE;
+}
+
+static void
+report_error (const gchar *operation, GError **error)
+{
+ g_return_if_fail (operation != NULL);
+
+ g_printerr ("Failed to %s: %s\n", operation, (error && *error) ? (*error)->message : "Unknown error");
+
+ g_clear_error (error);
+}
+
+gint
+main (gint argc, gchar **argv)
+{
+ g_type_init ();
+ g_thread_init (NULL);
+ gtk_init (&argc, &argv);
+
+ e_passwords_init ();
+
+ g_idle_add (in_main_thread_idle_cb, NULL);
+
+ loop = g_main_loop_new (NULL, FALSE);
+ g_main_loop_run (loop);
+ g_main_loop_unref (loop);
+
+ return get_main_loop_stop_result ();
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]