[evolution-data-server/openismus-work-master: 4/9] Handle fields-of-interest for the UID field in the file backend.
- From: Tristan Van Berkom <tvb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server/openismus-work-master: 4/9] Handle fields-of-interest for the UID field in the file backend.
- Date: Mon, 25 Jul 2011 20:55:58 +0000 (UTC)
commit eb226464c13cf505aad01e93e871dcaf892ef8ad
Author: Tristan Van Berkom <tristan van berkom gmail com>
Date: Sun Jun 26 12:05:54 2011 -0400
Handle fields-of-interest for the UID field in the file backend.
This patch modifies the local file addressbook backend to notify
with shallow vcards bearing only the UID if
e_book_client_view_set_fields_of_interest() has been called with
only the UID field requested.
Additionally, the patch adds a filtering algorithm in
e_book_backend_notify_update() to automatically filter vcard
notifications in response to a client adding or modifying a contact.
addressbook/backends/file/e-book-backend-file.c | 58 ++++++++++++++++++++--
addressbook/libedata-book/e-book-backend.c | 57 +++++++++++++++++++++-
2 files changed, 106 insertions(+), 9 deletions(-)
---
diff --git a/addressbook/backends/file/e-book-backend-file.c b/addressbook/backends/file/e-book-backend-file.c
index 596c829..773b758 100644
--- a/addressbook/backends/file/e-book-backend-file.c
+++ b/addressbook/backends/file/e-book-backend-file.c
@@ -633,6 +633,46 @@ get_closure (EDataBookView *book_view)
return g_object_get_data (G_OBJECT (book_view), "EBookBackendFile.BookView::closure");
}
+static void
+notify_update_vcard (EDataBookView *book_view,
+ gboolean uid_only,
+ gboolean prefiltered,
+ const gchar *id,
+ const gchar *vcard)
+{
+ gchar *final_vcard;
+
+ if (uid_only) {
+ /* Create a shallow version of the contacts for views that are
+ * only interested in the uid. */
+ EContact *shallow = e_contact_new ();
+
+ e_contact_set (shallow, E_CONTACT_UID, id);
+ final_vcard = e_vcard_to_string (E_VCARD (shallow), EVC_FORMAT_VCARD_30);
+ g_object_unref (shallow);
+ } else {
+ final_vcard = g_strdup (vcard);
+ }
+
+ if (prefiltered)
+ e_data_book_view_notify_update_prefiltered_vcard (book_view, id, final_vcard);
+ else
+ e_data_book_view_notify_update_vcard (book_view, final_vcard);
+}
+
+static gboolean
+view_wants_uid_only (EDataBookView *book_view)
+{
+ GHashTable *fields = e_data_book_view_get_fields_of_interest (book_view);
+
+ if (fields &&
+ g_hash_table_size (fields) == 1 &&
+ g_hash_table_lookup (fields, e_contact_field_name (E_CONTACT_UID)))
+ return TRUE;
+
+ return FALSE;
+}
+
static gpointer
book_view_thread (gpointer data)
{
@@ -643,7 +683,7 @@ book_view_thread (gpointer data)
DB *db;
DBT id_dbt, vcard_dbt;
gint db_error;
- gboolean allcontacts;
+ gboolean allcontacts, uid_only;
g_return_val_if_fail (E_IS_DATA_BOOK_VIEW (data), NULL);
@@ -672,6 +712,9 @@ book_view_thread (gpointer data)
allcontacts = FALSE;
}
+ /* Check if the view only wants UID in the fields-of-interest */
+ uid_only = view_wants_uid_only (book_view);
+
d(printf ("signalling parent thread\n"));
e_flag_set (closure->running);
@@ -689,6 +732,11 @@ book_view_thread (gpointer data)
if (!e_flag_is_set (closure->running))
break;
+ if (uid_only) {
+ notify_update_vcard (book_view, uid_only, TRUE, id, NULL);
+ continue;
+ }
+
string_to_dbt (id, &id_dbt);
memset (&vcard_dbt, 0, sizeof (vcard_dbt));
vcard_dbt.flags = DB_DBT_MALLOC;
@@ -696,7 +744,7 @@ book_view_thread (gpointer data)
db_error = db->get (db, NULL, &id_dbt, &vcard_dbt, 0);
if (db_error == 0) {
- e_data_book_view_notify_update_prefiltered_vcard (book_view, id, vcard_dbt.data);
+ notify_update_vcard (book_view, uid_only, TRUE, id, vcard_dbt.data);
}
else {
g_warning (G_STRLOC ": db->get failed with %s", db_strerror (db_error));
@@ -724,10 +772,8 @@ book_view_thread (gpointer data)
/* don't include the version in the list of cards */
if (strcmp (id_dbt.data, E_BOOK_BACKEND_FILE_VERSION_NAME)) {
- if (allcontacts)
- e_data_book_view_notify_update_prefiltered_vcard (book_view, id_dbt.data, vcard_dbt.data);
- else
- e_data_book_view_notify_update_vcard (book_view, vcard_dbt.data);
+ notify_update_vcard (book_view, uid_only, allcontacts,
+ id_dbt.data, vcard_dbt.data);
} else {
g_free (vcard_dbt.data);
}
diff --git a/addressbook/libedata-book/e-book-backend.c b/addressbook/libedata-book/e-book-backend.c
index 358f489..8850106 100644
--- a/addressbook/libedata-book/e-book-backend.c
+++ b/addressbook/libedata-book/e-book-backend.c
@@ -804,7 +804,9 @@ e_book_backend_remove_client (EBookBackend *backend,
* @callback returns %FALSE to stop further processing.
**/
void
-e_book_backend_foreach_view (EBookBackend *backend, gboolean (* callback) (EDataBookView *view, gpointer user_data), gpointer user_data)
+e_book_backend_foreach_view (EBookBackend *backend,
+ gboolean (* callback) (EDataBookView *view, gpointer user_data),
+ gpointer user_data)
{
const GSList *views;
EDataBookView *view;
@@ -1026,10 +1028,59 @@ e_book_backend_sync (EBookBackend *backend)
+
+typedef struct {
+ EContact *contact;
+ EContact *shallow;
+} FilterContactData;
+
+static void
+foreach_filter_contact (const gchar *field,
+ gpointer present,
+ FilterContactData *data)
+{
+ GList *attributes;
+ EContactField field_id;
+
+ field_id = e_contact_field_id (field);
+ attributes = e_contact_get_attributes (data->contact, field_id);
+
+ if (attributes)
+ e_contact_set_attributes (data->shallow, field_id, attributes);
+
+ g_list_foreach (attributes, (GFunc)e_vcard_attribute_free, NULL);
+ g_list_free (attributes);
+}
+
static gboolean
-view_notify_update (EDataBookView *view, gpointer contact)
+view_notify_update (EDataBookView *view, gpointer data)
{
- e_data_book_view_notify_update (view, contact);
+ EContact *contact = data;
+ GHashTable *fields;
+
+ fields = e_data_book_view_get_fields_of_interest (view);
+ if (fields && g_hash_table_size (fields) > 0) {
+ FilterContactData data = { 0, };
+ EContact *shallow = e_contact_new ();
+ gchar *vcard;
+
+
+ /* Set the UID unconditionally */
+ e_contact_set (shallow, E_CONTACT_UID, e_contact_get_const (contact, E_CONTACT_UID));
+
+ /* Transfer any attributes for the fields-of-interest */
+ data.contact = contact;
+ data.shallow = shallow;
+ g_hash_table_foreach (fields, (GHFunc)foreach_filter_contact, &data);
+
+ vcard = e_vcard_to_string (E_VCARD (shallow), EVC_FORMAT_VCARD_30);
+ g_object_unref (shallow);
+
+ /* Notify with a stripped vcard holding only the fields-of-interest */
+ e_data_book_view_notify_update_vcard (view, vcard);
+ } else {
+ e_data_book_view_notify_update (view, contact);
+ }
return TRUE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]