commit 99dbb43554f5ac30fc3f83012ec9f4e625d3c2b2
Author: Tristan Van Berkom <tristan.van.berkom@gmail.com>
Date:   Fri Jun 24 18:25:24 2011 -0400

    Added e_book_client_view_set_flags()
    
    This commit adds a EBookClientViewFlags to EBookClientView with
    an initial flag value E_BOOK_CLIENT_VIEW_FLAGS_NOTIFY_INITIAL
    to control whether the initial contact notifications are sent.
    The default is to send notifications, if the flag is unset then
    only future notifications are issued.

diff --git a/addressbook/libebook/e-book-client-view.c b/addressbook/libebook/e-book-client-view.c
index 00f5aba..22dd217 100644
--- a/addressbook/libebook/e-book-client-view.c
+++ b/addressbook/libebook/e-book-client-view.c
@@ -266,6 +266,40 @@ e_book_client_view_stop (EBookClientView *view,
 }
 
 /**
+ * e_book_client_view_set_flags:
+ * @view: an #EBookClientView
+ * @flags: the #EBookClientViewFlags for @view.
+ * @error: a return location for a #GError, or %NULL.
+ *
+ * Sets the @flags which control the behaviour of @view.
+ *
+ * Since: 3.4
+ */
+void
+e_book_client_view_set_flags (EBookClientView      *view,
+			      EBookClientViewFlags  flags, 
+			      GError              **error)
+{
+	EBookClientViewPrivate *priv;
+
+	g_return_if_fail (view != NULL);
+	g_return_if_fail (E_IS_BOOK_CLIENT_VIEW (view));
+
+	priv = view->priv;
+
+	if (priv->gdbus_bookview) {
+		GError *local_error = NULL;
+
+		e_gdbus_book_view_call_set_flags_sync (priv->gdbus_bookview, flags, NULL, &local_error);
+
+		e_client_unwrap_dbus_error (E_CLIENT (priv->client), local_error, error);
+	} else {
+		g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_DBUS_ERROR,
+				     "Cannot set flags on view, D-Bus proxy gone");
+	}
+}
+
+/**
  * e_book_client_view_set_fields_of_interest:
  * @view: An #EBookClientView object
  * @fields_of_interest: (element-type utf8): List of field names in which the client is interested
diff --git a/addressbook/libebook/e-book-client-view.h b/addressbook/libebook/e-book-client-view.h
index 60d58a6..94df3cd 100644
--- a/addressbook/libebook/e-book-client-view.h
+++ b/addressbook/libebook/e-book-client-view.h
@@ -38,6 +38,25 @@ typedef struct _EBookClientViewPrivate EBookClientViewPrivate;
 
 struct _EBookClient;  /* Forward reference */
 
+
+/**
+ * EBookClientViewFlags:
+ * @E_BOOK_CLIENT_VIEW_FLAGS_NONE:           Symbolic value for no flags
+ * @E_BOOK_CLIENT_VIEW_FLAGS_NOTIFY_INITIAL: If this flag is set then all contacts matching the
+ *                                           view's query will be sent as notifications when starting
+ *                                           the view, otherwise only future changes will be reported.
+ *                                           The default for a #EBookClientView is %TRUE.
+ *
+ * Flags that control the behaviour of an #EBookClientView.
+ *
+ * Since: 3.4
+ */
+typedef enum {
+	E_BOOK_CLIENT_VIEW_FLAGS_NONE           = 0,
+	E_BOOK_CLIENT_VIEW_FLAGS_NOTIFY_INITIAL = (1 << 0),
+} EBookClientViewFlags;
+
+
 struct _EBookClientView {
 	GObject     parent;
 	/*< private >*/
@@ -64,6 +83,7 @@ gboolean		e_book_client_view_is_running		(EBookClientView *view);
 void			e_book_client_view_set_fields_of_interest (EBookClientView *view, const GSList *fields_of_interest, GError **error);
 void			e_book_client_view_start		(EBookClientView *view, GError **error);
 void			e_book_client_view_stop			(EBookClientView *view, GError **error);
+void                    e_book_client_view_set_flags            (EBookClientView *view, EBookClientViewFlags  flags, GError **error);
 
 G_END_DECLS
 
diff --git a/addressbook/libedata-book/e-data-book-view.c b/addressbook/libedata-book/e-data-book-view.c
index 3c5ed80..6d0c545 100644
--- a/addressbook/libedata-book/e-data-book-view.c
+++ b/addressbook/libedata-book/e-data-book-view.c
@@ -47,8 +47,10 @@ struct _EDataBookViewPrivate {
 
 	gchar * card_query;
 	EBookBackendSExp *card_sexp;
+	EBookClientViewFlags flags;
 
 	gboolean running;
+	gboolean complete;
 	GMutex *pending_mutex;
 
 	GArray *adds;
@@ -150,6 +152,7 @@ book_destroyed_cb (gpointer data,
 	if (priv->running) {
 		e_book_backend_stop_book_view (priv->backend, view);
 		priv->running = FALSE;
+		priv->complete = FALSE;
 	}
 }
 
@@ -278,25 +281,34 @@ notify_add (EDataBookView *view,
             const gchar *id,
             const gchar *vcard)
 {
+	EBookClientViewFlags flags;
 	EDataBookViewPrivate *priv = view->priv;
 	gchar *utf8_vcard, *utf8_id;
 
 	send_pending_changes (view);
 	send_pending_removes (view);
 
-	if (priv->adds->len == THRESHOLD_ITEMS * 2) {
-		send_pending_adds (view);
-	}
-
-	utf8_vcard = e_util_utf8_make_valid (vcard);
 	utf8_id = e_util_utf8_make_valid (id);
 
-	g_array_append_val (priv->adds, utf8_vcard);
-	g_array_append_val (priv->adds, utf8_id);
-	g_hash_table_insert (priv->ids, g_strdup (utf8_id),
-			     GUINT_TO_POINTER (1));
+	/* Do not send contact add notifications during initial stage */
+	flags = e_data_book_view_get_flags (view);
+	if (priv->complete || (flags & E_BOOK_CLIENT_VIEW_FLAGS_NOTIFY_INITIAL) != 0) {
+		gchar *utf8_id_copy = g_strdup (utf8_id);
 
-	ensure_pending_flush_timeout (view);
+		if (priv->adds->len == THRESHOLD_ITEMS) {
+			send_pending_adds (view);
+		}
+
+		utf8_vcard = e_util_utf8_make_valid (vcard);
+
+		g_array_append_val (priv->adds, utf8_vcard);
+		g_array_append_val (priv->adds, utf8_id_copy);
+
+		ensure_pending_flush_timeout (view);
+	}
+
+	g_hash_table_insert (priv->ids, utf8_id,
+			     GUINT_TO_POINTER (1));
 }
 
 static gboolean
@@ -550,6 +562,8 @@ e_data_book_view_notify_complete (EDataBookView *book_view,
 
 	if (!priv->running)
 		return;
+	/* View is complete */
+	priv->complete = TRUE;
 
 	g_mutex_lock (priv->pending_mutex);
 
@@ -628,6 +642,7 @@ bookview_idle_start (gpointer data)
 	EDataBookView *book_view = data;
 
 	book_view->priv->running = TRUE;
+	book_view->priv->complete = FALSE;
 	book_view->priv->idle_id = 0;
 
 	e_book_backend_start_book_view (book_view->priv->backend, book_view);
@@ -655,6 +670,7 @@ bookview_idle_stop (gpointer data)
 	e_book_backend_stop_book_view (book_view->priv->backend, book_view);
 
 	book_view->priv->running = FALSE;
+	book_view->priv->complete = FALSE;
 	book_view->priv->idle_id = 0;
 
 	return FALSE;
@@ -676,6 +692,19 @@ impl_DataBookView_stop (EGdbusBookView *object,
 }
 
 static gboolean
+impl_DataBookView_setFlags (EGdbusBookView        *object, 
+			    GDBusMethodInvocation *invocation, 
+			    EBookClientViewFlags   flags, 
+			    EDataBookView         *book_view)
+{
+	book_view->priv->flags = flags;
+
+	e_gdbus_book_view_complete_set_flags (object, invocation, NULL);
+
+	return TRUE;
+}
+
+static gboolean
 impl_DataBookView_dispose (EGdbusBookView *object,
                            GDBusMethodInvocation *invocation,
                            EDataBookView *book_view)
@@ -698,14 +727,18 @@ e_data_book_view_init (EDataBookView *book_view)
 
 	book_view->priv = priv;
 
+	priv->flags = E_BOOK_CLIENT_VIEW_FLAGS_NOTIFY_INITIAL;
+
 	priv->gdbus_object = e_gdbus_book_view_stub_new ();
 	g_signal_connect (priv->gdbus_object, "handle-start", G_CALLBACK (impl_DataBookView_start), book_view);
 	g_signal_connect (priv->gdbus_object, "handle-stop", G_CALLBACK (impl_DataBookView_stop), book_view);
+	g_signal_connect (priv->gdbus_object, "handle-set-flags", G_CALLBACK (impl_DataBookView_setFlags), book_view);
 	g_signal_connect (priv->gdbus_object, "handle-dispose", G_CALLBACK (impl_DataBookView_dispose), book_view);
 	g_signal_connect (priv->gdbus_object, "handle-set-fields-of-interest", G_CALLBACK (impl_DataBookView_set_fields_of_interest), book_view);
 
 	priv->fields_of_interest = NULL;
 	priv->running = FALSE;
+	priv->complete = FALSE;
 	priv->pending_mutex = g_mutex_new ();
 
 	/* THRESHOLD_ITEMS * 2 because we store UID and vcard */
@@ -833,6 +866,24 @@ e_data_book_view_get_backend (EDataBookView *book_view)
 }
 
 /**
+ * e_data_book_view_get_flags:
+ * @book_view: an #EDataBookView
+ *
+ * Gets the #EBookClientViewFlags that control the behaviour of @book_view.
+ *
+ * Returns: the flags for @book_view.
+ *
+ * Since: 3.4
+ **/
+EBookClientViewFlags
+e_data_book_view_get_flags (EDataBookView *book_view)
+{
+	g_return_val_if_fail (E_IS_DATA_BOOK_VIEW (book_view), 0);
+
+	return book_view->priv->flags;
+}
+
+/**
  * e_data_book_view_get_fields_of_interest:
  * @view: A view object.
  *
diff --git a/addressbook/libedata-book/e-data-book-view.h b/addressbook/libedata-book/e-data-book-view.h
index 405754f..7f6b6d1 100644
--- a/addressbook/libedata-book/e-data-book-view.h
+++ b/addressbook/libedata-book/e-data-book-view.h
@@ -26,6 +26,7 @@
 
 #include <gio/gio.h>
 #include <libebook/e-contact.h>
+#include <libebook/e-book-client-view.h>
 #include <libedata-book/e-data-book-types.h>
 #include <libedata-book/e-book-backend.h>
 #include <libedata-book/e-book-backend-sexp.h>
@@ -57,6 +58,7 @@ guint			e_data_book_view_register_gdbus_object	(EDataBookView *query, GDBusConne
 const gchar *		e_data_book_view_get_card_query		(EDataBookView *book_view);
 EBookBackendSExp *	e_data_book_view_get_card_sexp		(EDataBookView *book_view);
 EBookBackend *		e_data_book_view_get_backend		(EDataBookView *book_view);
+EBookClientViewFlags    e_data_book_view_get_flags              (EDataBookView *book_view);
 void			e_data_book_view_notify_update		(EDataBookView *book_view, const EContact *contact);
 
 void			e_data_book_view_notify_update_vcard	(EDataBookView *book_view, const gchar *id, const gchar *vcard);
diff --git a/addressbook/libegdbus/e-gdbus-book-view.c b/addressbook/libegdbus/e-gdbus-book-view.c
index 46824e2..50cf677 100644
--- a/addressbook/libegdbus/e-gdbus-book-view.c
+++ b/addressbook/libegdbus/e-gdbus-book-view.c
@@ -42,6 +42,7 @@ enum
 	__COMPLETE_SIGNAL,
 	__START_METHOD,
 	__STOP_METHOD,
+	__SET_FLAGS_METHOD,
 	__DISPOSE_METHOD,
 	__SET_FIELDS_OF_INTEREST_METHOD,
 	__LAST_SIGNAL
@@ -112,9 +113,10 @@ e_gdbus_book_view_default_init (EGdbusBookViewIface *iface)
 	E_INIT_GDBUS_SIGNAL_STRV	(EGdbusBookViewIface, "complete",		complete, __COMPLETE_SIGNAL)
 
 	/* GObject signals definitions for D-Bus methods: */
-	E_INIT_GDBUS_METHOD_VOID	(EGdbusBookViewIface, "start",			start, __START_METHOD)
-	E_INIT_GDBUS_METHOD_VOID	(EGdbusBookViewIface, "stop",			stop, __STOP_METHOD)
-	E_INIT_GDBUS_METHOD_VOID	(EGdbusBookViewIface, "dispose",		dispose, __DISPOSE_METHOD)
+	E_INIT_GDBUS_METHOD_VOID	(EGdbusBookViewIface, "start",		        start, __START_METHOD)
+	E_INIT_GDBUS_METHOD_VOID	(EGdbusBookViewIface, "stop",		        stop, __STOP_METHOD)
+	E_INIT_GDBUS_METHOD_UINT	(EGdbusBookViewIface, "set_flags",	        set_flags, __SET_FLAGS_METHOD)
+	E_INIT_GDBUS_METHOD_VOID	(EGdbusBookViewIface, "dispose",	        dispose, __DISPOSE_METHOD)
 	E_INIT_GDBUS_METHOD_STRV	(EGdbusBookViewIface, "set_fields_of_interest",	set_fields_of_interest, __SET_FIELDS_OF_INTEREST_METHOD)
 }
 
@@ -169,10 +171,37 @@ e_gdbus_book_view_call_stop_sync (GDBusProxy *proxy,
 }
 
 void
+e_gdbus_book_view_call_set_flags (GDBusProxy *proxy,
+				  guint in_flags,
+				  GCancellable *cancellable,
+				  GAsyncReadyCallback callback,
+				  gpointer user_data)
+{
+        e_gdbus_proxy_method_call_uint ("set_flags", proxy, in_flags, cancellable, callback, user_data);
+}
+
+gboolean
+e_gdbus_book_view_call_set_flags_finish (GDBusProxy *proxy,
+					 GAsyncResult *result,
+					 GError **error)
+{
+	return e_gdbus_proxy_method_call_finish_void (proxy, result, error);
+}
+
+gboolean
+e_gdbus_book_view_call_set_flags_sync (GDBusProxy *proxy,
+				       guint in_flags,
+				       GCancellable *cancellable,
+				       GError **error)
+{
+	return e_gdbus_proxy_method_call_sync_uint__void ("set_flags", proxy, in_flags, cancellable, error);
+}
+
+void
 e_gdbus_book_view_call_dispose (GDBusProxy *proxy,
-                                GCancellable *cancellable,
-                                GAsyncReadyCallback callback,
-                                gpointer user_data)
+				GCancellable *cancellable,
+				GAsyncReadyCallback callback,
+				gpointer user_data)
 {
 	e_gdbus_proxy_method_call_void ("dispose", proxy, cancellable, callback, user_data);
 }
@@ -268,12 +297,14 @@ E_DECLARE_GDBUS_SYNC_METHOD_0 (book_view,
                                stop)
 E_DECLARE_GDBUS_SYNC_METHOD_0 (book_view,
                                dispose)
+E_DECLARE_GDBUS_SYNC_METHOD_1 (book_view, set_flags, flags, "u")
 E_DECLARE_GDBUS_SYNC_METHOD_1	(book_view, set_fields_of_interest, fields_of_interest, "as")
 
 static const GDBusMethodInfo * const e_gdbus_book_view_method_info_pointers[] =
 {
 	&E_DECLARED_GDBUS_METHOD_INFO_NAME (book_view, start),
 	&E_DECLARED_GDBUS_METHOD_INFO_NAME (book_view, stop),
+	&E_DECLARED_GDBUS_METHOD_INFO_NAME (book_view, set_flags),
 	&E_DECLARED_GDBUS_METHOD_INFO_NAME (book_view, dispose),
 	&E_DECLARED_GDBUS_METHOD_INFO_NAME (book_view, set_fields_of_interest),
 	NULL
diff --git a/addressbook/libegdbus/e-gdbus-book-view.h b/addressbook/libegdbus/e-gdbus-book-view.h
index a271eea..56e8965 100644
--- a/addressbook/libegdbus/e-gdbus-book-view.h
+++ b/addressbook/libegdbus/e-gdbus-book-view.h
@@ -114,6 +114,7 @@ struct _EGdbusBookViewIface
 	/* Signal handlers for handling D-Bus method calls: */
 	gboolean (*handle_start)		(EGdbusBookView *object, GDBusMethodInvocation *invocation);
 	gboolean (*handle_stop)			(EGdbusBookView *object, GDBusMethodInvocation *invocation);
+        gboolean (*handle_set_flags)            (EGdbusBookView *object, GDBusMethodInvocation *invocation, guint in_flags);
 	gboolean (*handle_dispose)		(EGdbusBookView *object, GDBusMethodInvocation *invocation);
 	gboolean (*handle_set_fields_of_interest)(EGdbusBookView *object, GDBusMethodInvocation *invocation, const gchar * const *in_only_fields);
 };
@@ -127,6 +128,19 @@ void		e_gdbus_book_view_call_stop		(GDBusProxy *proxy, GCancellable *cancellable
 gboolean	e_gdbus_book_view_call_stop_finish	(GDBusProxy *proxy, GAsyncResult *result, GError **error);
 gboolean	e_gdbus_book_view_call_stop_sync	(GDBusProxy *proxy, GCancellable *cancellable, GError **error);
 
+void            e_gdbus_book_view_call_set_flags        (GDBusProxy         *proxy, 
+							 guint               in_flags,
+							 GCancellable       *cancellable,
+							 GAsyncReadyCallback callback,
+							 gpointer            user_data);
+gboolean        e_gdbus_book_view_call_set_flags_finish (GDBusProxy         *proxy,
+							 GAsyncResult       *res,
+							 GError            **error);
+gboolean        e_gdbus_book_view_call_set_flags_sync   (GDBusProxy         *proxy,
+							 guint               in_flags,
+							 GCancellable       *cancellable,
+							 GError            **error);
+
 void		e_gdbus_book_view_call_dispose		(GDBusProxy *proxy, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
 gboolean	e_gdbus_book_view_call_dispose_finish	(GDBusProxy *proxy, GAsyncResult *result, GError **error);
 gboolean	e_gdbus_book_view_call_dispose_sync	(GDBusProxy *proxy, GCancellable *cancellable, GError **error);
@@ -138,6 +152,7 @@ gboolean	e_gdbus_book_view_call_set_fields_of_interest_sync	(GDBusProxy *proxy,
 /* D-Bus Methods Completion Helpers */
 #define e_gdbus_book_view_complete_start			e_gdbus_complete_sync_method_void
 #define e_gdbus_book_view_complete_stop				e_gdbus_complete_sync_method_void
+#define e_gdbus_book_view_complete_set_flags			e_gdbus_complete_sync_method_void
 #define e_gdbus_book_view_complete_dispose			e_gdbus_complete_sync_method_void
 #define e_gdbus_book_view_complete_set_fields_of_interest	e_gdbus_complete_sync_method_void
 
diff --git a/configure.ac b/configure.ac
index 076902a..c13ca48 100644
--- a/configure.ac
+++ b/configure.ac
@@ -58,7 +58,7 @@ EDS_MICRO_VERSION=eds_micro_version
 dnl ******************************
 dnl D-Bus versioning
 dnl ******************************
-ADDRESS_BOOK_DBUS_SERVICE_NAME="org.gnome.evolution.dataserver.AddressBook2"
+ADDRESS_BOOK_DBUS_SERVICE_NAME="org.gnome.evolution.dataserver.AddressBook3"
 CALENDAR_DBUS_SERVICE_NAME="org.gnome.evolution.dataserver.Calendar1"
 
 AC_DEFINE_UNQUOTED(
@@ -93,7 +93,7 @@ LIBEDATACAL_CURRENT=14
 LIBEDATACAL_REVISION=0
 LIBEDATACAL_AGE=0
 
-LIBEDATABOOK_CURRENT=12
+LIBEDATABOOK_CURRENT=13
 LIBEDATABOOK_REVISION=0
 LIBEDATABOOK_AGE=0
 
