[evolution-data-server/account-mgmt: 24/39] Add an ESource extension for the contacts backend.
- From: Matthew Barnes <mbarnes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server/account-mgmt: 24/39] Add an ESource extension for the contacts backend.
- Date: Wed, 7 Mar 2012 19:11:41 +0000 (UTC)
commit 448775c8d212359056380074d136377d63651fd3
Author: Matthew Barnes <mbarnes redhat com>
Date: Tue Nov 23 08:35:40 2010 -0500
Add an ESource extension for the contacts backend.
calendar/backends/contacts/Makefile.am | 4 +-
.../contacts/e-cal-backend-contacts-factory.c | 2 +
.../backends/contacts/e-cal-backend-contacts.c | 610 ++++----------------
calendar/backends/contacts/e-source-contacts.c | 139 +++++
calendar/backends/contacts/e-source-contacts.h | 70 +++
5 files changed, 317 insertions(+), 508 deletions(-)
---
diff --git a/calendar/backends/contacts/Makefile.am b/calendar/backends/contacts/Makefile.am
index b589e92..804260f 100644
--- a/calendar/backends/contacts/Makefile.am
+++ b/calendar/backends/contacts/Makefile.am
@@ -15,7 +15,9 @@ libecalbackendcontacts_la_CPPFLAGS = \
libecalbackendcontacts_la_SOURCES = \
e-cal-backend-contacts-factory.c \
e-cal-backend-contacts.c \
- e-cal-backend-contacts.h
+ e-cal-backend-contacts.h \
+ e-source-contacts.c \
+ e-source-contacts.h
libecalbackendcontacts_la_LIBADD = \
$(top_builddir)/calendar/libecal/libecal-1.2.la \
diff --git a/calendar/backends/contacts/e-cal-backend-contacts-factory.c b/calendar/backends/contacts/e-cal-backend-contacts-factory.c
index c7b06e6..2c22740 100644
--- a/calendar/backends/contacts/e-cal-backend-contacts-factory.c
+++ b/calendar/backends/contacts/e-cal-backend-contacts-factory.c
@@ -11,6 +11,7 @@
#include <libedata-cal/e-cal-backend-factory.h>
#include "e-cal-backend-contacts.h"
+#include "e-source-contacts.h"
#define FACTORY_NAME "contacts"
@@ -50,6 +51,7 @@ e_cal_backend_contacts_events_factory_init (ECalBackendFactory *factory)
G_MODULE_EXPORT void
e_module_load (GTypeModule *type_module)
{
+ e_source_contacts_type_register (type_module);
e_cal_backend_contacts_events_factory_register_type (type_module);
}
diff --git a/calendar/backends/contacts/e-cal-backend-contacts.c b/calendar/backends/contacts/e-cal-backend-contacts.c
index f595ece..b7f8fa0 100644
--- a/calendar/backends/contacts/e-cal-backend-contacts.c
+++ b/calendar/backends/contacts/e-cal-backend-contacts.c
@@ -35,7 +35,8 @@
#include <libsoup/soup.h>
#include <libedataserver/e-xml-hash-utils.h>
-#include <libedataserver/e-source-list.h>
+#include <libedataserver/e-source-registry.h>
+#include <libedataserver/e-source-address-book.h>
#include <libedataserver/e-flag.h>
#include <libecal/e-cal-recur.h>
#include <libecal/e-cal-util.h>
@@ -45,6 +46,8 @@
#include <libebook/e-book-query.h>
#include <libebook/e-contact.h>
+#include "e-source-contacts.h"
+
#define E_CAL_BACKEND_CONTACTS_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE \
((obj), E_TYPE_CAL_BACKEND_CONTACTS, ECalBackendContactsPrivate))
@@ -65,19 +68,15 @@ typedef enum
/* Private part of the ECalBackendContacts structure */
struct _ECalBackendContactsPrivate {
- ESourceList *addressbook_sources;
GHashTable *addressbooks; /* UID -> BookRecord */
- GHashTable *credentials; /* UID -> ECredentials to use in "authenticate" handler */
- gboolean loaded;
+ gboolean addressbook_loaded;
EBookClientView *book_view;
GHashTable *tracked_contacts; /* UID -> ContactRecord */
GHashTable *zones;
- EFlag *init_done_flag; /* is set, when the init thread gone */
-
/* properties related to track alarm settings for this backend */
GConfClient *conf_client;
guint notifyid1;
@@ -107,9 +106,6 @@ typedef struct _ContactRecord {
#define ANNIVERSARY_UID_EXT "-anniversary"
#define BIRTHDAY_UID_EXT "-birthday"
-#define CBC_CREDENTIALS_KEY_SOURCE_UID "cbc-source-uid"
-#define CBC_CREDENTIALS_KEY_ALREADY_USED "cbc-already-used"
-
static ECalComponent * create_birthday (ECalBackendContacts *cbc, EContact *contact);
static ECalComponent * create_anniversary (ECalBackendContacts *cbc, EContact *contact);
@@ -119,340 +115,67 @@ static void contacts_removed_cb (EBookClientView *book_view, const GSList *conta
static void e_cal_backend_contacts_add_timezone (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const gchar *tzobj, GError **perror);
static void setup_alarm (ECalBackendContacts *cbc, ECalComponent *comp);
-static gboolean
-book_client_authenticate_cb (EClient *client,
- ECredentials *credentials,
- ECalBackendContacts *cbc)
-{
- ESource *source;
- const gchar *source_uid;
- ECredentials *use_credentials;
-
- g_return_val_if_fail (client != NULL, FALSE);
- g_return_val_if_fail (credentials != NULL, FALSE);
- g_return_val_if_fail (cbc != NULL, FALSE);
-
- source = e_client_get_source (client);
-
- source_uid = e_source_peek_uid (source);
- g_return_val_if_fail (source_uid != NULL, FALSE);
-
- use_credentials = g_hash_table_lookup (cbc->priv->credentials, source_uid);
-
- if (use_credentials &&
- g_strcmp0 (e_credentials_peek (use_credentials, CBC_CREDENTIALS_KEY_ALREADY_USED), "1") != 0) {
- GSList *keys, *iter;
-
- e_credentials_clear (credentials);
- keys = e_credentials_list_keys (use_credentials);
-
- for (iter = keys; iter; iter = iter->next) {
- const gchar *key = iter->data;
-
- e_credentials_set (credentials, key, e_credentials_peek (use_credentials, key));
- }
-
- e_credentials_set (credentials, E_CREDENTIALS_KEY_FOREIGN_REQUEST, NULL);
-
- e_credentials_clear_peek (use_credentials);
- e_credentials_set (use_credentials, CBC_CREDENTIALS_KEY_ALREADY_USED, "1");
- g_slist_free (keys);
-
- return TRUE;
- }
-
- /* write properties on a copy of original credentials */
- credentials = e_credentials_new_clone (credentials);
-
- if (!e_credentials_has_key (credentials, E_CREDENTIALS_KEY_USERNAME)) {
- const gchar *username;
-
- username = e_source_get_property (source, "username");
- if (!username) {
- const gchar *auth;
-
- auth = e_source_get_property (source, "auth");
- if (g_strcmp0 (auth, "ldap/simple-binddn") == 0)
- username = e_source_get_property (source, "binddn");
- else
- username = e_source_get_property (source, "email_addr");
-
- if (!username)
- username = "";
- }
-
- e_credentials_set (credentials, E_CREDENTIALS_KEY_USERNAME, username);
-
- /* no username set on the source - deny authentication request */
- if (!e_credentials_has_key (credentials, E_CREDENTIALS_KEY_USERNAME))
- return FALSE;
- }
-
- if (!e_credentials_has_key (credentials, E_CREDENTIALS_KEY_PROMPT_KEY)) {
- gchar *prompt_key;
- SoupURI *suri;
-
- suri = soup_uri_new (e_client_get_uri (client));
- g_return_val_if_fail (suri != NULL, FALSE);
-
- soup_uri_set_user (suri, e_credentials_peek (credentials, E_CREDENTIALS_KEY_USERNAME));
- soup_uri_set_password (suri, NULL);
- soup_uri_set_fragment (suri, NULL);
-
- prompt_key = soup_uri_to_string (suri, FALSE);
- soup_uri_free (suri);
-
- e_credentials_set (credentials, E_CREDENTIALS_KEY_PROMPT_KEY, prompt_key);
-
- g_free (prompt_key);
- }
-
- if (!e_credentials_has_key (credentials, E_CREDENTIALS_KEY_PROMPT_TEXT)) {
- 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));
-
- if (reason && *reason)
- prompt = g_strdup_printf (_("Enter password for address book %s (user %s)\nReason: %s"), source_name_markup, username_markup, reason);
- else
- prompt = g_strdup_printf (_("Enter password for address book %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);
- }
-
- e_credentials_set (credentials, E_CREDENTIALS_KEY_FOREIGN_REQUEST, "1");
- e_credentials_set (credentials, CBC_CREDENTIALS_KEY_SOURCE_UID, e_source_peek_uid (source));
-
- /* this is a reprompt, set proper flags */
- if (use_credentials) {
- guint prompt_flags;
- gchar *prompt_flags_str;
-
- 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_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);
- }
-
- e_cal_backend_notify_auth_required (E_CAL_BACKEND (cbc), FALSE, credentials);
-
- /* this is a copy of original credentials */
- e_credentials_free (credentials);
-
- return FALSE;
-}
-
-static void book_client_opened_cb (EBookClient *book_client, const GError *error, ECalBackendContacts *cbc);
-
-static gpointer
-cbc_reopen_book_client_thread (gpointer user_data)
-{
- EBookClient *book_client = user_data;
- gboolean done = FALSE;
-
- while (!done) {
- done = TRUE;
-
- if (!e_client_is_opened (E_CLIENT (book_client))) {
- GError *error = NULL;
-
- if (!e_client_open_sync (E_CLIENT (book_client), TRUE, NULL, &error) || error) {
- if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_BUSY)) {
- done = FALSE;
- g_usleep (500000);
- } else
- g_warning ("%s: Failed to open book: %s", G_STRFUNC, error ? error->message : "Unknown error");
- }
-
- g_clear_error (&error);
- }
- }
-
- g_object_unref (book_client);
-
- return NULL;
-}
-
-static void
-cbc_reopen_book_client (ECalBackendContacts *cbc,
- EBookClient *book_client)
-{
- GError *error = NULL;
-
- g_return_if_fail (book_client != NULL);
-
- /* make sure signal handlers are disconnected */
- g_signal_handlers_disconnect_by_func (book_client, G_CALLBACK (book_client_authenticate_cb), cbc);
- g_signal_handlers_disconnect_by_func (book_client, G_CALLBACK (book_client_opened_cb), cbc);
-
- /* and connect them */
- g_signal_connect (book_client, "authenticate", G_CALLBACK (book_client_authenticate_cb), cbc);
- g_signal_connect (book_client, "opened", G_CALLBACK (book_client_opened_cb), cbc);
-
- g_object_ref (book_client);
- if (!g_thread_create (cbc_reopen_book_client_thread, book_client, FALSE, &error)) {
- g_object_unref (book_client);
-
- g_warning ("%s: Cannot create thread to reload source! (%s)", G_STRFUNC, error ? error->message : "Unknown error");
- g_clear_error (&error);
- }
-}
-
-static void
-book_client_opened_cb (EBookClient *book_client,
- const GError *error,
- ECalBackendContacts *cbc)
-{
- ESource *source;
- const gchar *source_uid;
- BookRecord *br = NULL;
-
- g_return_if_fail (book_client != NULL);
- g_return_if_fail (cbc != NULL);
-
- g_signal_handlers_disconnect_by_func (book_client, G_CALLBACK (book_client_authenticate_cb), cbc);
- g_signal_handlers_disconnect_by_func (book_client, G_CALLBACK (book_client_opened_cb), cbc);
-
- source = e_client_get_source (E_CLIENT (book_client));
- source_uid = e_source_peek_uid (source);
- g_return_if_fail (source_uid != NULL);
-
- if (source_uid) {
- br = g_hash_table_lookup (cbc->priv->addressbooks, source_uid);
- if (br && br->book_client != book_client)
- br = NULL;
- }
-
- if (!br)
- return;
-
- if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_AUTHENTICATION_FAILED)) {
- if (g_hash_table_lookup (cbc->priv->credentials, source_uid)) {
- cbc_reopen_book_client (cbc, br->book_client);
- }
- } else if (!error) {
- EBookQuery *query;
- EBookClientView *book_view;
- gchar *query_sexp;
- GError *error = NULL;
-
- if (br->book_view)
- g_object_unref (br->book_view);
- br->book_view = NULL;
-
- query = e_book_query_andv (
- e_book_query_orv (
- e_book_query_field_exists (E_CONTACT_FILE_AS),
- e_book_query_field_exists (E_CONTACT_FULL_NAME),
- e_book_query_field_exists (E_CONTACT_GIVEN_NAME),
- e_book_query_field_exists (E_CONTACT_NICKNAME),
- NULL),
- e_book_query_orv (
- e_book_query_field_exists (E_CONTACT_BIRTH_DATE),
- e_book_query_field_exists (E_CONTACT_ANNIVERSARY),
- NULL),
- NULL);
- query_sexp = e_book_query_to_string (query);
- e_book_query_unref (query);
-
- if (!e_book_client_get_view_sync (book_client, query_sexp, &book_view, NULL, &error))
- g_warning ("%s: Failed to get book view on '%s': %s", G_STRFUNC, e_source_peek_name (source), error ? error->message : "Unknown error");
- g_free (query_sexp);
- g_clear_error (&error);
-
- g_signal_connect (book_view, "objects-added", G_CALLBACK (contacts_added_cb), cbc);
- g_signal_connect (book_view, "objects-removed", G_CALLBACK (contacts_removed_cb), cbc);
- g_signal_connect (book_view, "objects-modified", G_CALLBACK (contacts_modified_cb), cbc);
-
- e_book_client_view_start (book_view, NULL);
-
- br->book_view = book_view;
- }
-}
-
-static void
-e_cal_backend_contacts_authenticate_user (ECalBackendSync *backend,
- GCancellable *cancellable,
- ECredentials *credentials,
- GError **error)
-{
- ECalBackendContacts *cbc;
- const gchar *source_uid;
- BookRecord *br;
-
- g_return_if_fail (backend != NULL);
- g_return_if_fail (credentials != NULL);
-
- cbc = E_CAL_BACKEND_CONTACTS (backend);
- g_return_if_fail (cbc != NULL);
-
- source_uid = e_credentials_peek (credentials, CBC_CREDENTIALS_KEY_SOURCE_UID);
- g_return_if_fail (source_uid != NULL);
-
- br = g_hash_table_lookup (cbc->priv->addressbooks, source_uid);
- if (!br || !br->book_client ||
- /* no username means user cancelled password prompt */
- !e_credentials_has_key (credentials, E_CREDENTIALS_KEY_USERNAME)) {
- g_hash_table_remove (cbc->priv->credentials, source_uid);
- return;
- }
-
- g_hash_table_insert (cbc->priv->credentials, g_strdup (source_uid), e_credentials_new_clone (credentials));
-
- cbc_reopen_book_client (cbc, br->book_client);
-}
-
/* BookRecord methods */
static BookRecord *
book_record_new (ECalBackendContacts *cbc,
ESource *source)
{
EBookClient *book_client;
+ EBookQuery *query;
+ EBookClientView *book_view;
BookRecord *br;
GError *error = NULL;
+ gchar *query_sexp;
book_client = e_book_client_new (source, &error);
- if (!book_client) {
- g_warning ("%s: Failed to create new book: %s", G_STRFUNC, error ? error->message : "Unknown error");
- g_clear_error (&error);
-
+ if (!book_client || !e_client_open_sync (E_CLIENT (book_client), TRUE, NULL, &error) || error) {
+ if (book_client)
+ g_object_unref (book_client);
+ if (error) {
+ g_warning ("%s: Failed to open book: %s", G_STRFUNC, error->message);
+ g_error_free (error);
+ }
return NULL;
}
- g_signal_connect (book_client, "authenticate", G_CALLBACK (book_client_authenticate_cb), cbc);
- g_signal_connect (book_client, "opened", G_CALLBACK (book_client_opened_cb), cbc);
+ query = e_book_query_andv (
+ e_book_query_orv (
+ e_book_query_field_exists (E_CONTACT_FILE_AS),
+ e_book_query_field_exists (E_CONTACT_FULL_NAME),
+ e_book_query_field_exists (E_CONTACT_GIVEN_NAME),
+ e_book_query_field_exists (E_CONTACT_NICKNAME),
+ NULL),
+ e_book_query_orv (
+ e_book_query_field_exists (E_CONTACT_BIRTH_DATE),
+ e_book_query_field_exists (E_CONTACT_ANNIVERSARY),
+ NULL),
+ NULL);
+ query_sexp = e_book_query_to_string (query);
+ e_book_query_unref (query);
+
+ if (!e_book_client_get_view_sync (book_client, query_sexp, &book_view, NULL, &error)) {
+ g_warning ("%s: Failed to get book view on '%s': %s", G_STRFUNC, e_source_get_display_name (source), error ? error->message : "Unknown error");
- if (!e_client_open_sync (E_CLIENT (book_client), TRUE, NULL, &error) || error) {
- g_signal_handlers_disconnect_by_func (book_client, G_CALLBACK (book_client_authenticate_cb), cbc);
- g_signal_handlers_disconnect_by_func (book_client, G_CALLBACK (book_client_opened_cb), cbc);
+ g_free (query_sexp);
g_object_unref (book_client);
- if (error) {
- g_warning ("%s: Failed to open book: %s", G_STRFUNC, error->message);
+
+ if (error)
g_error_free (error);
- }
+
return NULL;
}
+ g_free (query_sexp);
- br = g_new0 (BookRecord, 1);
+ g_signal_connect (book_view, "objects-added", G_CALLBACK (contacts_added_cb), cbc);
+ g_signal_connect (book_view, "objects-removed", G_CALLBACK (contacts_removed_cb), cbc);
+ g_signal_connect (book_view, "objects-modified", G_CALLBACK (contacts_modified_cb), cbc);
+
+ e_book_client_view_start (book_view, NULL);
+
+ br = g_new (BookRecord, 1);
br->cbc = cbc;
br->book_client = book_client;
- br->book_view = NULL;
+ br->book_view = book_view;
return br;
}
@@ -474,11 +197,8 @@ book_record_free (BookRecord *br)
if (!br)
return;
- g_signal_handlers_disconnect_by_func (br->book_client, G_CALLBACK (book_client_authenticate_cb), br->cbc);
- g_signal_handlers_disconnect_by_func (br->book_client, G_CALLBACK (book_client_opened_cb), br->cbc);
g_hash_table_foreach_remove (br->cbc->priv->tracked_contacts, remove_by_book, br->book_client);
- if (br->book_view)
- g_object_unref (br->book_view);
+ g_object_unref (br->book_view);
g_object_unref (br->book_client);
g_free (br);
@@ -599,138 +319,42 @@ contact_record_cb (gpointer key,
}
}
-static gboolean
-is_source_usable (ESource *source,
- ESourceGroup *group)
+static void
+source_added_cb (ESourceRegistry *registry,
+ ESource *source,
+ ECalBackendContacts *cbc)
{
- const gchar *base_uri;
- const gchar *prop;
+ ESourceContacts *extension;
+ const gchar *extension_name;
+ BookRecord *br;
+ const gchar *uid;
- base_uri = e_source_group_peek_base_uri (group);
- if (!base_uri)
- return FALSE;
+ extension_name = E_SOURCE_EXTENSION_CONTACTS_BACKEND;
+ extension = e_source_get_extension (source, extension_name);
- prop = e_source_get_property (source, "use-in-contacts-calendar");
+ if (extension == NULL)
+ return;
- /* the later check is for backward compatibility */
- return (prop && g_str_equal (prop, "1")) || (!prop && g_str_has_prefix (base_uri, "file://")) || (!prop && g_str_has_prefix (base_uri, "local:"));
-}
+ if (!e_source_contacts_get_include_me (extension))
+ return;
-/* SourceList callbacks */
-static void
-add_source (ECalBackendContacts *cbc,
- ESource *source)
-{
- BookRecord *br = book_record_new (cbc, source);
- const gchar *uid = e_source_peek_uid (source);
+ uid = e_source_get_uid (source);
+ br = book_record_new (cbc, source);
- if (!br)
+ if (br == NULL)
return;
g_hash_table_insert (cbc->priv->addressbooks, g_strdup (uid), br);
}
static void
-source_added_cb (ESourceGroup *group,
- ESource *source,
- gpointer user_data)
-{
- ECalBackendContacts *cbc = E_CAL_BACKEND_CONTACTS (user_data);
-
- g_return_if_fail (cbc);
-
- if (is_source_usable (source, group))
- add_source (cbc, source);
-}
-
-static void
-source_removed_cb (ESourceGroup *group,
+source_removed_cb (ESourceRegistry *registry,
ESource *source,
- gpointer user_data)
+ ECalBackendContacts *cbc)
{
- ECalBackendContacts *cbc = E_CAL_BACKEND_CONTACTS (user_data);
- const gchar *uid = e_source_peek_uid (source);
-
- g_return_if_fail (cbc);
+ const gchar *uid = e_source_get_uid (source);
g_hash_table_remove (cbc->priv->addressbooks, uid);
- g_hash_table_remove (cbc->priv->credentials, uid);
-}
-
-static void
-source_list_changed_cb (ESourceList *source_list,
- gpointer user_data)
-{
- ECalBackendContacts *cbc = E_CAL_BACKEND_CONTACTS (user_data);
- GSList *g, *s;
-
- g_return_if_fail (cbc);
-
- for (g = e_source_list_peek_groups (source_list); g; g = g->next) {
- ESourceGroup *group = E_SOURCE_GROUP (g->data);
-
- if (!group)
- continue;
-
- for (s = e_source_group_peek_sources (group); s; s = s->next) {
- ESource *source = E_SOURCE (s->data);
- const gchar *uid;
-
- if (!source)
- continue;
-
- uid = e_source_peek_uid (source);
- if (!uid)
- continue;
-
- if (is_source_usable (source, group)) {
- if (!g_hash_table_lookup (cbc->priv->addressbooks, uid))
- source_added_cb (group, source, cbc);
- } else if (g_hash_table_lookup (cbc->priv->addressbooks, uid)) {
- source_removed_cb (group, source, cbc);
- }
- }
- }
-}
-
-static void
-source_group_added_cb (ESourceList *source_list,
- ESourceGroup *group,
- gpointer user_data)
-{
- ECalBackendContacts *cbc = E_CAL_BACKEND_CONTACTS (user_data);
- GSList *i;
-
- g_return_if_fail (cbc);
-
- for (i = e_source_group_peek_sources (group); i; i = i->next) {
- ESource *source = E_SOURCE (i->data);
- source_added_cb (group, source, cbc);
- }
-
- /* Watch for future changes */
- g_signal_connect (group, "source_added", G_CALLBACK (source_added_cb), cbc);
- g_signal_connect (group, "source_removed", G_CALLBACK (source_removed_cb), cbc);
-}
-
-static void
-source_group_removed_cb (ESourceList *source_list,
- ESourceGroup *group,
- gpointer user_data)
-{
- ECalBackendContacts *cbc = E_CAL_BACKEND_CONTACTS (user_data);
- GSList *i = NULL;
-
- g_return_if_fail (cbc);
-
- /* Unload all address books from this group */
- for (i = e_source_group_peek_sources (group); i; i = i->next) {
- ESource *source = E_SOURCE (i->data);
- const gchar *uid = e_source_peek_uid (source);
-
- g_hash_table_remove (cbc->priv->addressbooks, uid);
- g_hash_table_remove (cbc->priv->credentials, uid);
- }
}
/************************************************************************************/
@@ -1316,36 +940,6 @@ e_cal_backend_contacts_notify_online_cb (ECalBackend *backend,
e_cal_backend_notify_readonly (backend, TRUE);
}
-static gpointer
-init_sources_cb (ECalBackendContacts *cbc)
-{
- ECalBackendContactsPrivate *priv;
- GSList *i;
-
- g_return_val_if_fail (cbc != NULL, NULL);
-
- priv = cbc->priv;
-
- if (!priv->addressbook_sources)
- return NULL;
-
- /* Create address books for existing sources */
- for (i = e_source_list_peek_groups (priv->addressbook_sources); i; i = i->next) {
- ESourceGroup *source_group = E_SOURCE_GROUP (i->data);
-
- source_group_added_cb (priv->addressbook_sources, source_group, cbc);
- }
-
- /* Listen for source list changes */
- g_signal_connect (priv->addressbook_sources, "changed", G_CALLBACK (source_list_changed_cb), cbc);
- g_signal_connect (priv->addressbook_sources, "group_added", G_CALLBACK (source_group_added_cb), cbc);
- g_signal_connect (priv->addressbook_sources, "group_removed", G_CALLBACK (source_group_removed_cb), cbc);
-
- e_flag_set (priv->init_done_flag);
-
- return NULL;
-}
-
static void
e_cal_backend_contacts_open (ECalBackendSync *backend,
EDataCal *cal,
@@ -1355,24 +949,11 @@ e_cal_backend_contacts_open (ECalBackendSync *backend,
{
ECalBackendContacts *cbc = E_CAL_BACKEND_CONTACTS (backend);
ECalBackendContactsPrivate *priv = cbc->priv;
- GError *error = NULL;
-
- if (priv->loaded)
- return;
-
- /* initialize addressbook sources in new thread to make this function quick as much as possible */
- if (!g_thread_create ((GThreadFunc) init_sources_cb, cbc, FALSE, &error)) {
- e_flag_set (priv->init_done_flag);
- g_warning ("%s: Cannot create thread to initialize sources! (%s)", G_STRFUNC, error ? error->message : "Unknown error");
- if (error)
- g_error_free (error);
- g_propagate_error (perror, EDC_ERROR (OtherError));
- e_cal_backend_notify_opened (E_CAL_BACKEND (backend), EDC_ERROR (OtherError));
+ if (priv->addressbook_loaded)
return;
- }
- priv->loaded = TRUE;
+ priv->addressbook_loaded = 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);
@@ -1501,21 +1082,12 @@ e_cal_backend_contacts_finalize (GObject *object)
priv = E_CAL_BACKEND_CONTACTS_GET_PRIVATE (object);
- if (priv->init_done_flag) {
- e_flag_wait (priv->init_done_flag);
- e_flag_free (priv->init_done_flag);
- priv->init_done_flag = NULL;
- }
-
if (priv->update_alarms_id) {
g_source_remove (priv->update_alarms_id);
priv->update_alarms_id = 0;
}
- if (priv->addressbook_sources)
- g_object_unref (priv->addressbook_sources);
g_hash_table_destroy (priv->addressbooks);
- g_hash_table_destroy (priv->credentials);
g_hash_table_destroy (priv->tracked_contacts);
g_hash_table_destroy (priv->zones);
if (priv->notifyid1)
@@ -1531,27 +1103,49 @@ e_cal_backend_contacts_finalize (GObject *object)
G_OBJECT_CLASS (e_cal_backend_contacts_parent_class)->finalize (object);
}
+static void
+e_cal_backend_contacts_constructed (GObject *object)
+{
+ ESourceRegistry *registry;
+ GList *list, *link;
+ const gchar *extension_name;
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (e_cal_backend_contacts_parent_class)->constructed (object);
+
+ registry = e_backend_get_registry (E_BACKEND (object));
+
+ /* Query all address book sources from the registry. */
+
+ extension_name = E_SOURCE_EXTENSION_ADDRESS_BOOK;
+ list = e_source_registry_list_sources (registry, extension_name);
+ for (link = list; link != NULL; link = g_list_next (link))
+ source_added_cb (
+ registry, E_SOURCE (link->data),
+ E_CAL_BACKEND_CONTACTS (object));
+ g_list_free (list);
+
+ g_signal_connect (
+ registry, "source-added",
+ G_CALLBACK (source_added_cb), object);
+
+ g_signal_connect (
+ registry, "source-removed",
+ G_CALLBACK (source_removed_cb), object);
+}
+
/* Object initialization function for the contacts backend */
static void
e_cal_backend_contacts_init (ECalBackendContacts *cbc)
{
cbc->priv = E_CAL_BACKEND_CONTACTS_GET_PRIVATE (cbc);
- if (!e_book_client_get_sources (&cbc->priv->addressbook_sources, NULL))
- cbc->priv->addressbook_sources = NULL;
-
cbc->priv->addressbooks = g_hash_table_new_full (
(GHashFunc) g_str_hash,
(GEqualFunc) g_str_equal,
(GDestroyNotify) g_free,
(GDestroyNotify) book_record_free);
- cbc->priv->credentials = g_hash_table_new_full (
- (GHashFunc) g_str_hash,
- (GEqualFunc) g_str_equal,
- (GDestroyNotify) g_free,
- (GDestroyNotify) e_credentials_free);
-
cbc->priv->tracked_contacts = g_hash_table_new_full (
(GHashFunc) g_str_hash,
(GEqualFunc) g_str_equal,
@@ -1564,7 +1158,6 @@ e_cal_backend_contacts_init (ECalBackendContacts *cbc)
(GDestroyNotify) g_free,
(GDestroyNotify) free_zone);
- cbc->priv->init_done_flag = e_flag_new ();
cbc->priv->conf_client = gconf_client_get_default ();
cbc->priv->notifyid1 = 0;
cbc->priv->notifyid2 = 0;
@@ -1608,6 +1201,7 @@ e_cal_backend_contacts_class_init (ECalBackendContactsClass *class)
sync_class = (ECalBackendSyncClass *) class;
object_class->finalize = e_cal_backend_contacts_finalize;
+ object_class->constructed = e_cal_backend_contacts_constructed;
sync_class->get_backend_property_sync = e_cal_backend_contacts_get_backend_property;
sync_class->open_sync = e_cal_backend_contacts_open;
@@ -1619,8 +1213,10 @@ e_cal_backend_contacts_class_init (ECalBackendContactsClass *class)
sync_class->get_object_list_sync = e_cal_backend_contacts_get_object_list;
sync_class->add_timezone_sync = e_cal_backend_contacts_add_timezone;
sync_class->get_free_busy_sync = e_cal_backend_contacts_get_free_busy;
- sync_class->authenticate_user_sync = e_cal_backend_contacts_authenticate_user;
backend_class->start_view = e_cal_backend_contacts_start_view;
backend_class->internal_get_timezone = e_cal_backend_contacts_internal_get_timezone;
+
+ /* Register our ESource extension. */
+ E_TYPE_SOURCE_CONTACTS;
}
diff --git a/calendar/backends/contacts/e-source-contacts.c b/calendar/backends/contacts/e-source-contacts.c
new file mode 100644
index 0000000..32ba589
--- /dev/null
+++ b/calendar/backends/contacts/e-source-contacts.c
@@ -0,0 +1,139 @@
+/*
+ * e-source-contacts.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <webcal://www.gnu.org/licenses/>
+ *
+ */
+
+#include "e-source-contacts.h"
+
+#define E_SOURCE_CONTACTS_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_SOURCE_CONTACTS, ESourceContactsPrivate))
+
+struct _ESourceContactsPrivate {
+ gboolean include_me;
+};
+
+enum {
+ PROP_0,
+ PROP_INCLUDE_ME
+};
+
+G_DEFINE_DYNAMIC_TYPE (
+ ESourceContacts,
+ e_source_contacts,
+ E_TYPE_SOURCE_EXTENSION)
+
+static void
+source_contacts_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_INCLUDE_ME:
+ e_source_contacts_set_include_me (
+ E_SOURCE_CONTACTS (object),
+ g_value_get_boolean (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+source_contacts_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_INCLUDE_ME:
+ g_value_set_boolean (
+ value,
+ e_source_contacts_get_include_me (
+ E_SOURCE_CONTACTS (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+e_source_contacts_class_init (ESourceContactsClass *class)
+{
+ GObjectClass *object_class;
+ ESourceExtensionClass *extension_class;
+
+ g_type_class_add_private (class, sizeof (ESourceContactsPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = source_contacts_set_property;
+ object_class->get_property = source_contacts_get_property;
+
+ extension_class = E_SOURCE_EXTENSION_CLASS (class);
+ extension_class->name = E_SOURCE_EXTENSION_CONTACTS_BACKEND;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_INCLUDE_ME,
+ g_param_spec_boolean (
+ "include-me",
+ "Include Me",
+ "Include this address book in the contacts calendar",
+ TRUE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ E_SOURCE_PARAM_SETTING));
+}
+
+static void
+e_source_contacts_class_finalize (ESourceContactsClass *class)
+{
+}
+
+static void
+e_source_contacts_init (ESourceContacts *extension)
+{
+ extension->priv = E_SOURCE_CONTACTS_GET_PRIVATE (extension);
+}
+
+void
+e_source_contacts_type_register (GTypeModule *type_module)
+{
+ /* XXX G_DEFINE_DYNAMIC_TYPE declares a static type registration
+ * function, so we have to wrap it with a public function in
+ * order to register types from a separate compilation unit. */
+ e_source_contacts_register_type (type_module);
+}
+
+gboolean
+e_source_contacts_get_include_me (ESourceContacts *extension)
+{
+ g_return_val_if_fail (E_IS_SOURCE_CONTACTS (extension), FALSE);
+
+ return extension->priv->include_me;
+}
+
+void
+e_source_contacts_set_include_me (ESourceContacts *extension,
+ gboolean include_me)
+{
+ g_return_if_fail (E_IS_SOURCE_CONTACTS (extension));
+
+ extension->priv->include_me = include_me;
+
+ g_object_notify (G_OBJECT (extension), "include-me");
+}
diff --git a/calendar/backends/contacts/e-source-contacts.h b/calendar/backends/contacts/e-source-contacts.h
new file mode 100644
index 0000000..95d9b83
--- /dev/null
+++ b/calendar/backends/contacts/e-source-contacts.h
@@ -0,0 +1,70 @@
+/*
+ * e-source-contacts.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <webcal://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef E_SOURCE_CONTACTS_H
+#define E_SOURCE_CONTACTS_H
+
+#include <libedataserver/e-source-extension.h>
+
+/* Standard GObject macros */
+#define E_TYPE_SOURCE_CONTACTS \
+ (e_source_contacts_get_type ())
+#define E_SOURCE_CONTACTS(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_SOURCE_CONTACTS, ESourceContacts))
+#define E_SOURCE_CONTACTS_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_SOURCE_CONTACTS, ESourceContactsClass))
+#define E_IS_SOURCE_CONTACTS(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_SOURCE_CONTACTS))
+#define E_IS_SOURCE_CONTACTS_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_SOURCE_CONTACTS))
+#define E_SOURCE_CONTACTS_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_SOURCE_CONTACTS, ESourceContactsClass))
+
+#define E_SOURCE_EXTENSION_CONTACTS_BACKEND "Contacts Backend"
+
+G_BEGIN_DECLS
+
+typedef struct _ESourceContacts ESourceContacts;
+typedef struct _ESourceContactsClass ESourceContactsClass;
+typedef struct _ESourceContactsPrivate ESourceContactsPrivate;
+
+struct _ESourceContacts {
+ ESourceExtension parent;
+ ESourceContactsPrivate *priv;
+};
+
+struct _ESourceContactsClass {
+ ESourceExtensionClass parent_class;
+};
+
+GType e_source_contacts_get_type (void);
+void e_source_contacts_type_register (GTypeModule *type_module);
+gboolean e_source_contacts_get_include_me
+ (ESourceContacts *extension);
+void e_source_contacts_set_include_me
+ (ESourceContacts *extension,
+ gboolean include_me);
+
+G_END_DECLS
+
+#endif /* E_SOURCE_CONTACTS_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]