aboutsummaryrefslogtreecommitdiffstats
path: root/addressbook/backend/pas/pas-book-view.c
diff options
context:
space:
mode:
authorEttore Perazzoli <ettore@src.gnome.org>2003-10-22 02:49:34 +0800
committerEttore Perazzoli <ettore@src.gnome.org>2003-10-22 02:49:34 +0800
commit653cfffc0e00dfb59b36813c1b45c53d3f773c65 (patch)
tree9b486d5e383ec1391d60973d9cc548be0ef6d9d5 /addressbook/backend/pas/pas-book-view.c
parent0fb08f3ff81575a4749d851404233f34252dd2f2 (diff)
downloadgsoc2013-evolution-653cfffc0e00dfb59b36813c1b45c53d3f773c65.tar
gsoc2013-evolution-653cfffc0e00dfb59b36813c1b45c53d3f773c65.tar.gz
gsoc2013-evolution-653cfffc0e00dfb59b36813c1b45c53d3f773c65.tar.bz2
gsoc2013-evolution-653cfffc0e00dfb59b36813c1b45c53d3f773c65.tar.lz
gsoc2013-evolution-653cfffc0e00dfb59b36813c1b45c53d3f773c65.tar.xz
gsoc2013-evolution-653cfffc0e00dfb59b36813c1b45c53d3f773c65.tar.zst
gsoc2013-evolution-653cfffc0e00dfb59b36813c1b45c53d3f773c65.zip
Merge new-ui-branch to the trunk.
svn path=/trunk/; revision=22965
Diffstat (limited to 'addressbook/backend/pas/pas-book-view.c')
-rw-r--r--addressbook/backend/pas/pas-book-view.c362
1 files changed, 270 insertions, 92 deletions
diff --git a/addressbook/backend/pas/pas-book-view.c b/addressbook/backend/pas/pas-book-view.c
index fce4173f0f..712997d258 100644
--- a/addressbook/backend/pas/pas-book-view.c
+++ b/addressbook/backend/pas/pas-book-view.c
@@ -6,158 +6,266 @@
*/
#include <config.h>
+#include <string.h>
#include <glib.h>
#include <bonobo/bonobo-main.h>
+#include "pas-backend.h"
+#include "pas-backend-card-sexp.h"
#include "pas-book-view.h"
static BonoboObjectClass *pas_book_view_parent_class;
struct _PASBookViewPrivate {
GNOME_Evolution_Addressbook_BookViewListener listener;
+
+#define INITIAL_THRESHOLD 20
+ GMutex *pending_mutex;
+
+ CORBA_sequence_GNOME_Evolution_Addressbook_VCard adds;
+ int next_threshold;
+ int threshold_max;
+
+ CORBA_sequence_GNOME_Evolution_Addressbook_VCard changes;
+ CORBA_sequence_GNOME_Evolution_Addressbook_ContactId removes;
+
+ PASBackend *backend;
+ char *card_query;
+ PASBackendCardSExp *card_sexp;
+ GHashTable *ids;
};
-/**
- * pas_book_view_notify_change:
- */
-void
-pas_book_view_notify_change (PASBookView *book_view,
- const GList *cards)
+static void
+send_pending_adds (PASBookView *book_view, gboolean reset)
{
CORBA_Environment ev;
- gint i, length;
- CORBA_sequence_GNOME_Evolution_Addressbook_VCard card_sequence;
+ CORBA_sequence_GNOME_Evolution_Addressbook_VCard *adds;
+
+ adds = &book_view->priv->adds;
+ if (adds->_length == 0)
+ return;
- length = g_list_length((GList *) cards);
+ CORBA_exception_init (&ev);
- card_sequence._buffer = CORBA_sequence_GNOME_Evolution_Addressbook_VCard_allocbuf(length);
- card_sequence._maximum = length;
- card_sequence._length = length;
+ GNOME_Evolution_Addressbook_BookViewListener_notifyContactsAdded (
+ book_view->priv->listener, adds, &ev);
- for ( i = 0; cards; cards = g_list_next(cards), i++ ) {
- card_sequence._buffer[i] = CORBA_string_dup((char *) cards->data);
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_warning ("send_pending_adds: Exception signaling BookViewListener!\n");
}
+ CORBA_exception_free (&ev);
+
+ CORBA_free (adds->_buffer);
+ adds->_buffer = NULL;
+ adds->_maximum = 0;
+ adds->_length = 0;
+
+ if (reset)
+ book_view->priv->next_threshold = INITIAL_THRESHOLD;
+}
+
+static void
+send_pending_changes (PASBookView *book_view)
+{
+ CORBA_Environment ev;
+ CORBA_sequence_GNOME_Evolution_Addressbook_VCard *changes;
+
+ changes = &book_view->priv->changes;
+ if (changes->_length == 0)
+ return;
+
CORBA_exception_init (&ev);
- GNOME_Evolution_Addressbook_BookViewListener_notifyCardChanged (
- book_view->priv->listener, &card_sequence, &ev);
+ GNOME_Evolution_Addressbook_BookViewListener_notifyContactsChanged (
+ book_view->priv->listener, changes, &ev);
if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("pas_book_view_notify_change: Exception signaling BookViewListener!\n");
+ g_warning ("send_pending_changes: Exception signaling BookViewListener!\n");
}
CORBA_exception_free (&ev);
- CORBA_free(card_sequence._buffer);
+ CORBA_free (changes->_buffer);
+ changes->_buffer = NULL;
+ changes->_maximum = 0;
+ changes->_length = 0;
}
-void
-pas_book_view_notify_change_1 (PASBookView *book_view,
- const char *card)
+static void
+send_pending_removes (PASBookView *book_view)
{
- GList *list = g_list_append(NULL, (char *) card);
- pas_book_view_notify_change(book_view, list);
- g_list_free(list);
+ CORBA_Environment ev;
+ CORBA_sequence_GNOME_Evolution_Addressbook_VCard *removes;
+
+ removes = &book_view->priv->removes;
+ if (removes->_length == 0)
+ return;
+
+ CORBA_exception_init (&ev);
+
+ GNOME_Evolution_Addressbook_BookViewListener_notifyContactsRemoved (
+ book_view->priv->listener, removes, &ev);
+
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_warning ("send_pending_removes: Exception signaling BookViewListener!\n");
+ }
+
+ CORBA_exception_free (&ev);
+
+ CORBA_free (removes->_buffer);
+ removes->_buffer = NULL;
+ removes->_maximum = 0;
+ removes->_length = 0;
}
-/**
- * pas_book_view_notify_remove:
- */
-void
-pas_book_view_notify_remove_1 (PASBookView *book_view,
- const char *id)
+#define MAKE_REALLOC(type) \
+static void \
+CORBA_sequence_ ## type ## _realloc (CORBA_sequence_ ## type *seq, \
+ CORBA_unsigned_long new_max) \
+{ \
+ type *new_buf; \
+ \
+ new_buf = CORBA_sequence_ ## type ## _allocbuf (new_max); \
+ memcpy (new_buf, seq->_buffer, seq->_maximum * sizeof (type)); \
+ CORBA_free (seq->_buffer); \
+ seq->_buffer = new_buf; \
+ seq->_maximum = new_max; \
+}
+
+MAKE_REALLOC (GNOME_Evolution_Addressbook_VCard)
+MAKE_REALLOC (GNOME_Evolution_Addressbook_ContactId)
+
+static void
+notify_change (PASBookView *book_view, const char *vcard)
{
- GList *ids = NULL;
+ CORBA_sequence_GNOME_Evolution_Addressbook_VCard *changes;
+
+ send_pending_adds (book_view, TRUE);
+ send_pending_removes (book_view);
- ids = g_list_prepend (ids, (char*)id);
+ changes = &book_view->priv->changes;
- pas_book_view_notify_remove (book_view, ids);
+ if (changes->_length == changes->_maximum) {
+ CORBA_sequence_GNOME_Evolution_Addressbook_VCard_realloc (
+ changes, 2 * (changes->_maximum + 1));
+ }
- g_list_free (ids);
+ changes->_buffer[changes->_length++] = CORBA_string_dup (vcard);
}
-void
-pas_book_view_notify_remove (PASBookView *book_view,
- const GList *ids)
+static void
+notify_remove (PASBookView *book_view, const char *id)
{
- GNOME_Evolution_Addressbook_CardIdList idlist;
- CORBA_Environment ev;
- const GList *l;
- int num_ids, i;
+ CORBA_sequence_GNOME_Evolution_Addressbook_ContactId *removes;
- CORBA_exception_init (&ev);
+ send_pending_adds (book_view, TRUE);
+ send_pending_changes (book_view);
- num_ids = g_list_length ((GList*)ids);
- idlist._buffer = CORBA_sequence_GNOME_Evolution_Addressbook_CardId_allocbuf (num_ids);
- idlist._maximum = num_ids;
- idlist._length = num_ids;
+ removes = &book_view->priv->removes;
- for (l = ids, i = 0; l; l=l->next, i ++) {
- idlist._buffer[i] = CORBA_string_dup (l->data);
+ if (removes->_length == removes->_maximum) {
+ CORBA_sequence_GNOME_Evolution_Addressbook_ContactId_realloc (
+ removes, 2 * (removes->_maximum + 1));
}
- GNOME_Evolution_Addressbook_BookViewListener_notifyCardsRemoved (
- book_view->priv->listener, &idlist, &ev);
+ removes->_buffer[removes->_length++] = CORBA_string_dup (id);
+ g_hash_table_remove (book_view->priv->ids, id);
+}
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("pas_book_view_notify_remove: Exception signaling BookViewListener!\n");
- }
+static void
+notify_add (PASBookView *book_view, const char *id, const char *vcard)
+{
+ CORBA_sequence_GNOME_Evolution_Addressbook_VCard *adds;
+ PASBookViewPrivate *priv = book_view->priv;
- CORBA_free(idlist._buffer);
+ send_pending_changes (book_view);
+ send_pending_removes (book_view);
- CORBA_exception_free (&ev);
+ adds = &priv->adds;
+
+ if (adds->_length == adds->_maximum) {
+ send_pending_adds (book_view, FALSE);
+
+ adds->_buffer = CORBA_sequence_GNOME_Evolution_Addressbook_VCard_allocbuf (priv->next_threshold);
+ adds->_maximum = priv->next_threshold;
+
+ if (priv->next_threshold < priv->threshold_max) {
+ priv->next_threshold = MIN (2 * priv->next_threshold,
+ priv->threshold_max);
+ }
+ }
+
+ adds->_buffer[adds->_length++] = CORBA_string_dup (vcard);
+ g_hash_table_insert (book_view->priv->ids, g_strdup (id),
+ GUINT_TO_POINTER (1));
}
/**
- * pas_book_view_notify_add:
+ * pas_book_view_notify_update:
*/
void
-pas_book_view_notify_add (PASBookView *book_view,
- const GList *cards)
+pas_book_view_notify_update (PASBookView *book_view,
+ EContact *contact)
{
- CORBA_Environment ev;
- gint i, length;
- CORBA_sequence_GNOME_Evolution_Addressbook_VCard card_sequence;
+ gboolean currently_in_view, want_in_view;
+ const char *id;
+ char *vcard;
- length = g_list_length((GList *)cards);
+ g_mutex_lock (book_view->priv->pending_mutex);
- card_sequence._buffer = CORBA_sequence_GNOME_Evolution_Addressbook_VCard_allocbuf(length);
- card_sequence._maximum = length;
- card_sequence._length = length;
+ id = e_contact_get_const (contact, E_CONTACT_UID);
- for ( i = 0; cards; cards = g_list_next(cards), i++ ) {
- card_sequence._buffer[i] = CORBA_string_dup((char *) cards->data);
- }
+ currently_in_view =
+ g_hash_table_lookup (book_view->priv->ids, id) != NULL;
+ want_in_view = pas_backend_card_sexp_match_contact (
+ book_view->priv->card_sexp, contact);
- CORBA_exception_init (&ev);
+ if (want_in_view) {
+ vcard = e_vcard_to_string (E_VCARD (contact),
+ EVC_FORMAT_VCARD_30);
- GNOME_Evolution_Addressbook_BookViewListener_notifyCardAdded (
- book_view->priv->listener, &card_sequence, &ev);
+ if (currently_in_view)
+ notify_change (book_view, vcard);
+ else
+ notify_add (book_view, id, vcard);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("pas_book_view_notify_add: Exception signaling BookViewListener!\n");
+ g_free (vcard);
+ } else {
+ if (currently_in_view)
+ pas_book_view_notify_remove (book_view, id);
+ /* else nothing; we're removing a card that wasn't there */
}
- CORBA_exception_free (&ev);
-
- CORBA_free(card_sequence._buffer);
+ g_mutex_unlock (book_view->priv->pending_mutex);
}
+/**
+ * pas_book_view_notify_remove:
+ */
void
-pas_book_view_notify_add_1 (PASBookView *book_view,
- const char *card)
+pas_book_view_notify_remove (PASBookView *book_view,
+ const char *id)
{
- GList *list = g_list_append(NULL, (char *) card);
- pas_book_view_notify_add(book_view, list);
- g_list_free(list);
+ g_mutex_lock (book_view->priv->pending_mutex);
+ notify_remove (book_view, id);
+ g_mutex_unlock (book_view->priv->pending_mutex);
}
+
void
pas_book_view_notify_complete (PASBookView *book_view,
- GNOME_Evolution_Addressbook_BookViewListener_CallStatus status)
+ GNOME_Evolution_Addressbook_CallStatus status)
{
CORBA_Environment ev;
+ g_mutex_lock (book_view->priv->pending_mutex);
+
+ send_pending_adds (book_view, TRUE);
+ send_pending_changes (book_view);
+ send_pending_removes (book_view);
+
+ g_mutex_unlock (book_view->priv->pending_mutex);
+
CORBA_exception_init (&ev);
GNOME_Evolution_Addressbook_BookViewListener_notifySequenceComplete (
@@ -178,8 +286,8 @@ pas_book_view_notify_status_message (PASBookView *book_view,
CORBA_exception_init (&ev);
- GNOME_Evolution_Addressbook_BookViewListener_notifyStatusMessage (
- book_view->priv->listener, message, &ev);
+ GNOME_Evolution_Addressbook_BookViewListener_notifyProgress (
+ book_view->priv->listener, message, 0, &ev);
if (ev._major != CORBA_NO_EXCEPTION) {
g_warning ("pas_book_view_notify_status_message: Exception signaling BookViewListener!\n");
@@ -190,7 +298,10 @@ pas_book_view_notify_status_message (PASBookView *book_view,
static void
pas_book_view_construct (PASBookView *book_view,
- GNOME_Evolution_Addressbook_BookViewListener listener)
+ PASBackend *backend,
+ GNOME_Evolution_Addressbook_BookViewListener listener,
+ const char *card_query,
+ PASBackendCardSExp *card_sexp)
{
PASBookViewPrivate *priv;
CORBA_Environment ev;
@@ -202,29 +313,70 @@ pas_book_view_construct (PASBookView *book_view,
CORBA_exception_init (&ev);
- bonobo_object_dup_ref (listener, &ev);
+ priv->listener = CORBA_Object_duplicate (listener, &ev);
if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning("Unable to duplicate & ref listener object in pas-book-view.c\n");
+ g_warning("Unable to duplicate listener object in pas-book-view.c\n");
CORBA_exception_free (&ev);
return;
}
CORBA_exception_free (&ev);
- priv->listener = listener;
+ priv->backend = backend;
+ priv->card_query = g_strdup (card_query);
+ priv->card_sexp = card_sexp;
+}
+
+/**
+ * pas_book_view_new:
+ */
+static void
+impl_GNOME_Evolution_Addressbook_BookView_start (PortableServer_Servant servant,
+ CORBA_Environment *ev)
+{
+ PASBookView *view = PAS_BOOK_VIEW (bonobo_object (servant));
+
+ pas_backend_start_book_view (pas_book_view_get_backend (view), view);
+}
+
+/**
+ * pas_book_view_get_card_query
+ */
+const char*
+pas_book_view_get_card_query (PASBookView *book_view)
+{
+ return book_view->priv->card_query;
+}
+
+/**
+ * pas_book_view_get_card_sexp
+ */
+PASBackendCardSExp*
+pas_book_view_get_card_sexp (PASBookView *book_view)
+{
+ return book_view->priv->card_sexp;
+}
+
+PASBackend*
+pas_book_view_get_backend (PASBookView *book_view)
+{
+ return book_view->priv->backend;
}
/**
* pas_book_view_new:
*/
PASBookView *
-pas_book_view_new (GNOME_Evolution_Addressbook_BookViewListener listener)
+pas_book_view_new (PASBackend *backend,
+ GNOME_Evolution_Addressbook_BookViewListener listener,
+ const char *card_query,
+ PASBackendCardSExp *card_sexp)
{
PASBookView *book_view;
book_view = g_object_new (PAS_TYPE_BOOK_VIEW, NULL);
- pas_book_view_construct (book_view, listener);
+ pas_book_view_construct (book_view, backend, listener, card_query, card_sexp);
return book_view;
}
@@ -237,6 +389,19 @@ pas_book_view_dispose (GObject *object)
if (book_view->priv) {
bonobo_object_release_unref (book_view->priv->listener, NULL);
+ if (book_view->priv->adds._buffer)
+ CORBA_free (book_view->priv->adds._buffer);
+ if (book_view->priv->changes._buffer)
+ CORBA_free (book_view->priv->changes._buffer);
+ if (book_view->priv->removes._buffer)
+ CORBA_free (book_view->priv->removes._buffer);
+
+ g_free (book_view->priv->card_query);
+ g_object_unref (book_view->priv->card_sexp);
+
+ g_mutex_free (book_view->priv->pending_mutex);
+ book_view->priv->pending_mutex = NULL;
+
g_free (book_view->priv);
book_view->priv = NULL;
}
@@ -249,17 +414,30 @@ static void
pas_book_view_class_init (PASBookViewClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ POA_GNOME_Evolution_Addressbook_BookView__epv *epv;
pas_book_view_parent_class = g_type_class_peek_parent (klass);
object_class->dispose = pas_book_view_dispose;
+
+ epv = &klass->epv;
+
+ epv->start = impl_GNOME_Evolution_Addressbook_BookView_start;
+
}
static void
pas_book_view_init (PASBookView *book_view)
{
- book_view->priv = g_new0 (PASBookViewPrivate, 1);
- book_view->priv->listener = CORBA_OBJECT_NIL;
+ book_view->priv = g_new0 (PASBookViewPrivate, 1);
+
+ book_view->priv->pending_mutex = g_mutex_new();
+
+ book_view->priv->next_threshold = INITIAL_THRESHOLD;
+ book_view->priv->threshold_max = 3000;
+
+ book_view->priv->ids = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, NULL);
}
BONOBO_TYPE_FUNC_FULL (