[evolution-data-server] EDataCalView cleanups.



commit 3693ed13e447a2a615e1709259102b5e1285d8ec
Author: Matthew Barnes <mbarnes redhat com>
Date:   Fri Oct 12 14:12:35 2012 -0400

    EDataCalView cleanups.
    
    Some minor API changes with this:
    
        e_data_cal_view_get_text() is dropped.  Instead use:
    
            sexp = e_data_cal_view_get_sexp (view);
            query = e_cal_backend_sexp_text (sexp);

 calendar/backends/caldav/e-cal-backend-caldav.c    |    7 +-
 .../backends/contacts/e-cal-backend-contacts.c     |    2 +-
 calendar/backends/file/e-cal-backend-file.c        |   13 +-
 calendar/backends/http/e-cal-backend-http.c        |    7 +-
 calendar/backends/weather/e-cal-backend-weather.c  |    2 +-
 calendar/libedata-cal/e-data-cal-view.c            |  987 ++++++++++----------
 calendar/libedata-cal/e-data-cal-view.h            |    5 +-
 .../libedata-cal/libedata-cal-sections.txt         |    4 +-
 8 files changed, 515 insertions(+), 512 deletions(-)
---
diff --git a/calendar/backends/caldav/e-cal-backend-caldav.c b/calendar/backends/caldav/e-cal-backend-caldav.c
index 9e8a84c..ff89fbe 100644
--- a/calendar/backends/caldav/e-cal-backend-caldav.c
+++ b/calendar/backends/caldav/e-cal-backend-caldav.c
@@ -4533,10 +4533,8 @@ caldav_start_view (ECalBackend *backend,
 	gboolean prunning_by_time;
 	cbdav = E_CAL_BACKEND_CALDAV (backend);
 
-	sexp_string = e_data_cal_view_get_text (query);
-	sexp = e_cal_backend_sexp_new (sexp_string);
-
-	/* FIXME:check invalid sexp */
+	sexp = e_data_cal_view_get_sexp (query);
+	sexp_string = e_cal_backend_sexp_text (sexp);
 
 	if (g_str_equal (sexp_string, "#t")) {
 		do_search = FALSE;
@@ -4564,7 +4562,6 @@ caldav_start_view (ECalBackend *backend,
 		g_object_unref (comp);
 	}
 
-	g_object_unref (sexp);
 	g_slist_free (list);
 
 	e_data_cal_view_notify_complete (query, NULL /* Success */);
diff --git a/calendar/backends/contacts/e-cal-backend-contacts.c b/calendar/backends/contacts/e-cal-backend-contacts.c
index 786b13d..486ea74 100644
--- a/calendar/backends/contacts/e-cal-backend-contacts.c
+++ b/calendar/backends/contacts/e-cal-backend-contacts.c
@@ -1260,7 +1260,7 @@ e_cal_backend_contacts_start_view (ECalBackend *backend,
 	ECalBackendSExp *sexp;
 	ContactRecordCB *cb_data;
 
-	sexp = e_data_cal_view_get_object_sexp (query);
+	sexp = e_data_cal_view_get_sexp (query);
 	if (!sexp) {
 		GError *error = EDC_ERROR (InvalidQuery);
 		e_data_cal_view_notify_complete (query, error);
diff --git a/calendar/backends/file/e-cal-backend-file.c b/calendar/backends/file/e-cal-backend-file.c
index 3e14e4d..f5fced5 100644
--- a/calendar/backends/file/e-cal-backend-file.c
+++ b/calendar/backends/file/e-cal-backend-file.c
@@ -1809,6 +1809,7 @@ e_cal_backend_file_start_view (ECalBackend *backend,
 {
 	ECalBackendFile *cbfile;
 	ECalBackendFilePrivate *priv;
+	ECalBackendSExp *sexp;
 	MatchObjectData match_data = { 0, };
 	time_t occur_start = -1, occur_end = -1;
 	gboolean prunning_by_time;
@@ -1816,15 +1817,17 @@ e_cal_backend_file_start_view (ECalBackend *backend,
 	cbfile = E_CAL_BACKEND_FILE (backend);
 	priv = cbfile->priv;
 
-	d (g_message (G_STRLOC ": Starting query (%s)", e_data_cal_view_get_text (query)));
+	sexp = e_data_cal_view_get_sexp (query);
+
+	d (g_message (G_STRLOC ": Starting query (%s)", e_cal_backend_sexp_text (sexp)));
 
 	/* try to match all currently existing objects */
 	match_data.search_needed = TRUE;
-	match_data.query = e_data_cal_view_get_text (query);
+	match_data.query = e_cal_backend_sexp_text (sexp);
 	match_data.comps_list = NULL;
 	match_data.as_string = FALSE;
 	match_data.backend = backend;
-	match_data.obj_sexp = e_data_cal_view_get_object_sexp (query);
+	match_data.obj_sexp = e_data_cal_view_get_sexp (query);
 	match_data.view = query;
 
 	if (!strcmp (match_data.query, "#t"))
@@ -1850,7 +1853,7 @@ e_cal_backend_file_start_view (ECalBackend *backend,
 				      &match_data);
 
 		e_debug_log (FALSE, E_DEBUG_LOG_DOMAIN_CAL_QUERIES,  "---;%p;QUERY-ITEMS;%s;%s;%d", query,
-			    e_data_cal_view_get_text (query), G_OBJECT_TYPE_NAME (backend),
+			    e_cal_backend_sexp_text (sexp), G_OBJECT_TYPE_NAME (backend),
 			    g_hash_table_size (priv->comp_uid_hash));
 	} else {
 		/* matches objects in new "interval tree" way */
@@ -1861,7 +1864,7 @@ e_cal_backend_file_start_view (ECalBackend *backend,
 			       &match_data);
 
 		e_debug_log (FALSE, E_DEBUG_LOG_DOMAIN_CAL_QUERIES,  "---;%p;QUERY-ITEMS;%s;%s;%d", query,
-			    e_data_cal_view_get_text (query), G_OBJECT_TYPE_NAME (backend),
+			    e_cal_backend_sexp_text (sexp), G_OBJECT_TYPE_NAME (backend),
 			    g_list_length (objs_occuring_in_tw));
 	}
 
diff --git a/calendar/backends/http/e-cal-backend-http.c b/calendar/backends/http/e-cal-backend-http.c
index 69bd679..dd54f43 100644
--- a/calendar/backends/http/e-cal-backend-http.c
+++ b/calendar/backends/http/e-cal-backend-http.c
@@ -1110,7 +1110,9 @@ e_cal_backend_http_start_view (ECalBackend *backend,
 	cbhttp = E_CAL_BACKEND_HTTP (backend);
 	priv = cbhttp->priv;
 
-	d (g_message (G_STRLOC ": Starting query (%s)", e_data_cal_view_get_text (query)));
+	cbsexp = e_data_cal_view_get_sexp (query);
+
+	d (g_message (G_STRLOC ": Starting query (%s)", e_cal_backend_sexp_text (cbsexp)));
 
 	if (!priv->store) {
 		GError *error = EDC_ERROR (NoSuchCal);
@@ -1120,8 +1122,6 @@ e_cal_backend_http_start_view (ECalBackend *backend,
 	}
 
 	/* process all components in the cache */
-	cbsexp = e_cal_backend_sexp_new (e_data_cal_view_get_text (query));
-
 	objects = NULL;
 	prunning_by_time = e_cal_backend_sexp_evaluate_occur_times (cbsexp,
 									    &occur_start,
@@ -1143,7 +1143,6 @@ e_cal_backend_http_start_view (ECalBackend *backend,
 
 	g_slist_free_full (components, g_object_unref);
 	g_slist_free (objects);
-	g_object_unref (cbsexp);
 
 	e_data_cal_view_notify_complete (query, NULL /* Success */);
 }
diff --git a/calendar/backends/weather/e-cal-backend-weather.c b/calendar/backends/weather/e-cal-backend-weather.c
index f31e3d5..2d555b2 100644
--- a/calendar/backends/weather/e-cal-backend-weather.c
+++ b/calendar/backends/weather/e-cal-backend-weather.c
@@ -710,7 +710,7 @@ e_cal_backend_weather_start_view (ECalBackend *backend,
 		return;
 	}
 
-	sexp = e_data_cal_view_get_object_sexp (query);
+	sexp = e_data_cal_view_get_sexp (query);
 	if (!sexp) {
 		error = EDC_ERROR (InvalidQuery);
 		e_data_cal_view_notify_complete (query, error);
diff --git a/calendar/libedata-cal/e-data-cal-view.c b/calendar/libedata-cal/e-data-cal-view.c
index 5c5a742..86917a9 100644
--- a/calendar/libedata-cal/e-data-cal-view.c
+++ b/calendar/libedata-cal/e-data-cal-view.c
@@ -35,10 +35,11 @@
 	(G_TYPE_INSTANCE_GET_PRIVATE \
 	((obj), E_TYPE_DATA_CAL_VIEW, EDataCalViewPrivate))
 
-static void ensure_pending_flush_timeout (EDataCalView *view);
+/* how many items can be hold in a cache, before propagated to UI */
+#define THRESHOLD_ITEMS 32
 
-#define THRESHOLD_ITEMS   32	/* how many items can be hold in a cache, before propagated to UI */
-#define THRESHOLD_SECONDS  2	/* how long to wait until notifications are propagated to UI; in seconds */
+/* how long to wait until notifications are propagated to UI; in seconds */
+#define THRESHOLD_SECONDS 2
 
 struct _EDataCalViewPrivate {
 	EGdbusCalView *gdbus_object;
@@ -69,43 +70,13 @@ struct _EDataCalViewPrivate {
 	GHashTable *fields_of_interest;
 };
 
-G_DEFINE_TYPE (EDataCalView, e_data_cal_view, G_TYPE_OBJECT);
-
-static void e_data_cal_view_dispose (GObject *object);
-static void e_data_cal_view_finalize (GObject *object);
-static void e_data_cal_view_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
-static void e_data_cal_view_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec);
-
-/* Property IDs */
-enum props {
+enum {
 	PROP_0,
 	PROP_BACKEND,
 	PROP_SEXP
 };
 
-/* Class init */
-static void
-e_data_cal_view_class_init (EDataCalViewClass *class)
-{
-	GObjectClass *object_class = G_OBJECT_CLASS (class);
-
-	g_type_class_add_private (class, sizeof (EDataCalViewPrivate));
-
-	object_class->set_property = e_data_cal_view_set_property;
-	object_class->get_property = e_data_cal_view_get_property;
-	object_class->dispose = e_data_cal_view_dispose;
-	object_class->finalize = e_data_cal_view_finalize;
-
-	g_object_class_install_property (object_class, PROP_BACKEND,
-		g_param_spec_object (
-			"backend", NULL, NULL, E_TYPE_CAL_BACKEND,
-			G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
-
-	g_object_class_install_property (object_class, PROP_SEXP,
-		g_param_spec_object (
-			"sexp", NULL, NULL, E_TYPE_CAL_BACKEND_SEXP,
-			G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
-}
+G_DEFINE_TYPE (EDataCalView, e_data_cal_view, G_TYPE_OBJECT);
 
 static guint
 str_ic_hash (gconstpointer key)
@@ -114,12 +85,11 @@ str_ic_hash (gconstpointer key)
 	const gchar *str = key;
 	gint ii;
 
-	if (!str)
+	if (str == NULL)
 		return hash;
 
-	for (ii = 0; str[ii]; ii++) {
+	for (ii = 0; str[ii] != '\0'; ii++)
 		hash = hash * 33 + g_ascii_tolower (str[ii]);
-	}
 
 	return hash;
 }
@@ -128,16 +98,17 @@ static gboolean
 str_ic_equal (gconstpointer a,
               gconstpointer b)
 {
-	const gchar *stra = a, *strb = b;
+	const gchar *stra = a;
+	const gchar *strb = b;
 	gint ii;
 
-	if (!stra && !strb)
+	if (stra == NULL && strb == NULL)
 		return TRUE;
 
-	if (!stra || !strb)
+	if (stra == NULL || strb == NULL)
 		return FALSE;
 
-	for (ii = 0; stra[ii] && strb[ii]; ii++) {
+	for (ii = 0; stra[ii] != '\0' && strb[ii] != '\0'; ii++) {
 		if (g_ascii_tolower (stra[ii]) != g_ascii_tolower (strb[ii]))
 			return FALSE;
 	}
@@ -149,6 +120,7 @@ static guint
 id_hash (gconstpointer key)
 {
 	const ECalComponentId *id = key;
+
 	return g_str_hash (id->uid) ^ (id->rid ? g_str_hash (id->rid) : 0);
 }
 
@@ -156,38 +128,11 @@ static gboolean
 id_equal (gconstpointer a,
           gconstpointer b)
 {
-	const ECalComponentId *id_a = a, *id_b = b;
-	return g_strcmp0 (id_a->uid, id_b->uid) == 0 && g_strcmp0 (id_a->rid, id_b->rid) == 0;
-}
-
-EDataCalView *
-e_data_cal_view_new (ECalBackend *backend,
-                     ECalBackendSExp *sexp)
-{
-	EDataCalView *view;
+	const ECalComponentId *id_a = a;
+	const ECalComponentId *id_b = b;
 
-	view = g_object_new (E_TYPE_DATA_CAL_VIEW, "backend", backend, "sexp", sexp, NULL);
-
-	return view;
-}
-
-/**
- * e_data_cal_view_register_gdbus_object:
- *
- * Since: 2.32
- **/
-guint
-e_data_cal_view_register_gdbus_object (EDataCalView *view,
-                                       GDBusConnection *connection,
-                                       const gchar *object_path,
-                                       GError **error)
-{
-	g_return_val_if_fail (view != NULL, 0);
-	g_return_val_if_fail (E_IS_DATA_CAL_VIEW (view), 0);
-	g_return_val_if_fail (connection != NULL, 0);
-	g_return_val_if_fail (object_path != NULL, 0);
-
-	return e_gdbus_cal_view_register_object (view->priv->gdbus_object, connection, object_path, error);
+	return (g_strcmp0 (id_a->uid, id_b->uid) == 0) &&
+		(g_strcmp0 (id_a->rid, id_b->rid) == 0);
 }
 
 static void
@@ -206,231 +151,6 @@ reset_array (GArray *array)
 	g_array_set_size (array, 0);
 }
 
-static void
-send_pending_adds (EDataCalView *view)
-{
-	EDataCalViewPrivate *priv = view->priv;
-
-	if (priv->adds->len == 0)
-		return;
-
-	e_gdbus_cal_view_emit_objects_added (view->priv->gdbus_object, (const gchar * const *) priv->adds->data);
-	reset_array (priv->adds);
-}
-
-static void
-send_pending_changes (EDataCalView *view)
-{
-	EDataCalViewPrivate *priv = view->priv;
-
-	if (priv->changes->len == 0)
-		return;
-
-	e_gdbus_cal_view_emit_objects_modified (view->priv->gdbus_object, (const gchar * const *) priv->changes->data);
-	reset_array (priv->changes);
-}
-
-static void
-send_pending_removes (EDataCalView *view)
-{
-	EDataCalViewPrivate *priv = view->priv;
-
-	if (priv->removes->len == 0)
-		return;
-
-	/* send ECalComponentIds as <uid>[\n<rid>], as encoded in notify_remove() */
-	e_gdbus_cal_view_emit_objects_removed (view->priv->gdbus_object, (const gchar * const *) priv->removes->data);
-	reset_array (priv->removes);
-}
-
-static gboolean
-pending_flush_timeout_cb (gpointer data)
-{
-	EDataCalView *view = data;
-	EDataCalViewPrivate *priv = view->priv;
-
-	g_mutex_lock (priv->pending_mutex);
-
-	priv->flush_id = 0;
-
-	send_pending_adds (view);
-	send_pending_changes (view);
-	send_pending_removes (view);
-
-	g_mutex_unlock (priv->pending_mutex);
-
-	return FALSE;
-}
-
-static void
-ensure_pending_flush_timeout (EDataCalView *view)
-{
-	EDataCalViewPrivate *priv = view->priv;
-
-	if (priv->flush_id)
-		return;
-
-	priv->flush_id = g_timeout_add (e_data_cal_view_is_completed (view) ? 10 : (THRESHOLD_SECONDS * 1000), pending_flush_timeout_cb, view);
-}
-
-static void
-notify_add (EDataCalView *view,
-            gchar *obj)
-{
-	EDataCalViewPrivate *priv = view->priv;
-	ECalComponent *comp;
-	ECalClientViewFlags flags;
-
-	send_pending_changes (view);
-	send_pending_removes (view);
-
-	/* Do not send object add notifications during initial stage */
-	flags = e_data_cal_view_get_flags (view);
-	if (priv->complete || (flags & E_CAL_CLIENT_VIEW_FLAGS_NOTIFY_INITIAL) != 0) {
-		if (priv->adds->len == THRESHOLD_ITEMS) {
-			send_pending_adds (view);
-		}
-		g_array_append_val (priv->adds, obj);
-
-		ensure_pending_flush_timeout (view);
-	}
-
-	comp = e_cal_component_new_from_string (obj);
-	g_hash_table_insert (priv->ids,
-			     e_cal_component_get_id (comp),
-			     GUINT_TO_POINTER (1));
-	g_object_unref (comp);
-}
-
-static void
-notify_add_component (EDataCalView *view,
-                      /* const */ ECalComponent *comp)
-{
-	EDataCalViewPrivate *priv = view->priv;
-	gchar               *obj;
-	ECalClientViewFlags flags;
-
-	obj = e_data_cal_view_get_component_string (view, comp);
-
-	send_pending_changes (view);
-	send_pending_removes (view);
-
-	/* Do not send component add notifications during initial stage */
-	flags = e_data_cal_view_get_flags (view);
-	if (priv->complete || (flags & E_CAL_CLIENT_VIEW_FLAGS_NOTIFY_INITIAL) != 0) {
-		if (priv->adds->len == THRESHOLD_ITEMS) {
-			send_pending_adds (view);
-		}
-		g_array_append_val (priv->adds, obj);
-
-		ensure_pending_flush_timeout (view);
-	}
-
-	g_hash_table_insert (priv->ids,
-			     e_cal_component_get_id (comp),
-			     GUINT_TO_POINTER (1));
-}
-
-static void
-notify_change (EDataCalView *view,
-               gchar *obj)
-{
-	EDataCalViewPrivate *priv = view->priv;
-
-	send_pending_adds (view);
-	send_pending_removes (view);
-
-	if (priv->changes->len == THRESHOLD_ITEMS) {
-		send_pending_changes (view);
-	}
-
-	g_array_append_val (priv->changes, obj);
-
-	ensure_pending_flush_timeout (view);
-}
-
-static void
-notify_change_component (EDataCalView *view,
-                         ECalComponent *comp)
-{
-	gchar *obj;
-
-	obj = e_data_cal_view_get_component_string (view, comp);
-
-	notify_change (view, obj);
-}
-
-static void
-notify_remove (EDataCalView *view,
-               ECalComponentId *id)
-{
-	EDataCalViewPrivate *priv = view->priv;
-	gchar *ids;
-	gchar *uid, *rid;
-	gsize uid_len, rid_len;
-
-	send_pending_adds (view);
-	send_pending_changes (view);
-
-	if (priv->removes->len == THRESHOLD_ITEMS) {
-		send_pending_removes (view);
-	}
-
-	/* store ECalComponentId as <uid>[\n<rid>] (matches D-Bus API) */
-	if (id->uid) {
-		uid = e_util_utf8_make_valid (id->uid);
-		uid_len = strlen (uid);
-	} else {
-		uid = NULL;
-		uid_len = 0;
-	}
-	if (id->rid) {
-		rid = e_util_utf8_make_valid (id->rid);
-		rid_len = strlen (rid);
-	} else {
-		rid = NULL;
-		rid_len = 0;
-	}
-	if (uid_len && !rid_len) {
-		/* shortcut */
-		ids = uid;
-		uid = NULL;
-	} else {
-		/* concatenate */
-		ids = g_malloc (uid_len + rid_len + (rid_len ? 2 : 1));
-		if (uid_len)
-			strcpy (ids, uid);
-		if (rid_len) {
-			ids[uid_len] = '\n';
-			strcpy (ids + uid_len + 1, rid);
-		}
-	}
-	g_array_append_val (priv->removes, ids);
-	g_free (uid);
-	g_free (rid);
-
-	g_hash_table_remove (priv->ids, id);
-
-	ensure_pending_flush_timeout (view);
-}
-
-static void
-notify_complete (EDataCalView *view,
-                 const GError *error)
-{
-	gchar **error_strv;
-
-	send_pending_adds (view);
-	send_pending_changes (view);
-	send_pending_removes (view);
-
-	error_strv = e_gdbus_templates_encode_error (error);
-
-	e_gdbus_cal_view_emit_complete (view->priv->gdbus_object, (const gchar * const *) error_strv);
-
-	g_strfreev (error_strv);
-}
-
 static gpointer
 calview_start_thread (gpointer data)
 {
@@ -448,17 +168,18 @@ impl_DataCalView_start (EGdbusCalView *object,
                         GDBusMethodInvocation *invocation,
                         EDataCalView *view)
 {
-	EDataCalViewPrivate *priv;
-
-	priv = view->priv;
-
-	if (!priv->started) {
+	if (!view->priv->started) {
 		GThread *thread;
 
-		priv->started = TRUE;
-		e_debug_log (FALSE, E_DEBUG_LOG_DOMAIN_CAL_QUERIES, "---;%p;VIEW-START;%s;%s", view, e_data_cal_view_get_text (view), G_OBJECT_TYPE_NAME (priv->backend));
+		view->priv->started = TRUE;
+		e_debug_log (
+			FALSE, E_DEBUG_LOG_DOMAIN_CAL_QUERIES,
+			"---;%p;VIEW-START;%s;%s", view,
+			e_cal_backend_sexp_text (view->priv->sexp),
+			G_OBJECT_TYPE_NAME (view->priv->backend));
 
-		thread = g_thread_new (NULL, calview_start_thread, g_object_ref (view));
+		thread = g_thread_new (
+			NULL, calview_start_thread, g_object_ref (view));
 		g_thread_unref (thread);
 	}
 
@@ -484,12 +205,9 @@ impl_DataCalView_stop (EGdbusCalView *object,
                        GDBusMethodInvocation *invocation,
                        EDataCalView *view)
 {
-	EDataCalViewPrivate *priv;
 	GThread *thread;
 
-	priv = view->priv;
-
-	priv->stopped = TRUE;
+	view->priv->stopped = TRUE;
 
 	thread = g_thread_new (NULL, calview_stop_thread, g_object_ref (view));
 	g_thread_unref (thread);
@@ -533,16 +251,14 @@ impl_DataCalView_set_fields_of_interest (EGdbusCalView *object,
                                          const gchar * const *in_fields_of_interest,
                                          EDataCalView *view)
 {
-	EDataCalViewPrivate *priv;
 	gint ii;
 
 	g_return_val_if_fail (in_fields_of_interest != NULL, TRUE);
 
-	priv = view->priv;
-
-	if (priv->fields_of_interest)
-		g_hash_table_destroy (priv->fields_of_interest);
-	priv->fields_of_interest = NULL;
+	if (view->priv->fields_of_interest != NULL) {
+		g_hash_table_destroy (view->priv->fields_of_interest);
+		view->priv->fields_of_interest = NULL;
+	}
 
 	for (ii = 0; in_fields_of_interest[ii]; ii++) {
 		const gchar *field = in_fields_of_interest[ii];
@@ -550,68 +266,190 @@ impl_DataCalView_set_fields_of_interest (EGdbusCalView *object,
 		if (!*field)
 			continue;
 
-		if (!priv->fields_of_interest)
-			priv->fields_of_interest = g_hash_table_new_full (str_ic_hash, str_ic_equal, g_free, NULL);
+		if (view->priv->fields_of_interest == NULL)
+			view->priv->fields_of_interest =
+				g_hash_table_new_full (
+					(GHashFunc) str_ic_hash,
+					(GEqualFunc) str_ic_equal,
+					(GDestroyNotify) g_free,
+					(GDestroyNotify) NULL);
+
+		g_hash_table_insert (
+			view->priv->fields_of_interest,
+			g_strdup (field), GINT_TO_POINTER (1));
+	}
+
+	e_gdbus_cal_view_complete_set_fields_of_interest (
+		object, invocation, NULL);
+
+	return TRUE;
+}
+
+static void
+data_cal_view_set_backend (EDataCalView *view,
+                           ECalBackend *backend)
+{
+	g_return_if_fail (E_IS_CAL_BACKEND (backend));
+	g_return_if_fail (view->priv->backend == NULL);
+
+	view->priv->backend = g_object_ref (backend);
+}
+
+static void
+data_cal_view_set_sexp (EDataCalView *view,
+                        ECalBackendSExp *sexp)
+{
+	g_return_if_fail (E_IS_CAL_BACKEND_SEXP (sexp));
+	g_return_if_fail (view->priv->sexp == NULL);
+
+	view->priv->sexp = g_object_ref (sexp);
+}
+
+static void
+data_cal_view_set_property (GObject *object,
+                            guint property_id,
+                            const GValue *value,
+                            GParamSpec *pspec)
+{
+	switch (property_id) {
+		case PROP_BACKEND:
+			data_cal_view_set_backend (
+				E_DATA_CAL_VIEW (object),
+				g_value_get_object (value));
+			return;
+
+		case PROP_SEXP:
+			data_cal_view_set_sexp (
+				E_DATA_CAL_VIEW (object),
+				g_value_get_object (value));
+			return;
+	}
+
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+data_cal_view_get_property (GObject *object,
+                            guint property_id,
+                            GValue *value,
+                            GParamSpec *pspec)
+{
+	switch (property_id) {
+		case PROP_BACKEND:
+			g_value_set_object (
+				value,
+				e_data_cal_view_get_backend (
+				E_DATA_CAL_VIEW (object)));
+			return;
+
+		case PROP_SEXP:
+			g_value_set_object (
+				value,
+				e_data_cal_view_get_sexp (
+				E_DATA_CAL_VIEW (object)));
+			return;
+	}
+
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
 
-		g_hash_table_insert (priv->fields_of_interest, g_strdup (field), GINT_TO_POINTER (1));
+static void
+data_cal_view_dispose (GObject *object)
+{
+	EDataCalViewPrivate *priv;
+
+	priv = E_DATA_CAL_VIEW_GET_PRIVATE (object);
+
+	if (priv->backend != NULL) {
+		e_cal_backend_remove_view (
+			priv->backend,
+			E_DATA_CAL_VIEW (object));
+		g_object_unref (priv->backend);
+		priv->backend = NULL;
+	}
+
+	if (priv->sexp != NULL) {
+		g_object_unref (priv->sexp);
+		priv->sexp = NULL;
+	}
+
+	g_mutex_lock (priv->pending_mutex);
+
+	if (priv->flush_id > 0) {
+		g_source_remove (priv->flush_id);
+		priv->flush_id = 0;
 	}
 
-	e_gdbus_cal_view_complete_set_fields_of_interest (object, invocation, NULL);
+	g_mutex_unlock (priv->pending_mutex);
 
-	return TRUE;
+	/* Chain up to parent's dispose() method. */
+	G_OBJECT_CLASS (e_data_cal_view_parent_class)->dispose (object);
 }
 
 static void
-e_data_cal_view_set_property (GObject *object,
-                              guint property_id,
-                              const GValue *value,
-                              GParamSpec *pspec)
+data_cal_view_finalize (GObject *object)
 {
-	EDataCalView *view;
 	EDataCalViewPrivate *priv;
 
-	view = E_DATA_CAL_VIEW (object);
-	priv = view->priv;
+	priv = E_DATA_CAL_VIEW_GET_PRIVATE (object);
 
-	switch (property_id) {
-	case PROP_BACKEND:
-		priv->backend = E_CAL_BACKEND (g_value_dup_object (value));
-		break;
-	case PROP_SEXP:
-		priv->sexp = E_CAL_BACKEND_SEXP (g_value_dup_object (value));
-		break;
-	default:
-		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
-		break;
-	}
+	reset_array (priv->adds);
+	reset_array (priv->changes);
+	reset_array (priv->removes);
+
+	g_array_free (priv->adds, TRUE);
+	g_array_free (priv->changes, TRUE);
+	g_array_free (priv->removes, TRUE);
+
+	g_hash_table_destroy (priv->ids);
+
+	if (priv->fields_of_interest != NULL)
+		g_hash_table_destroy (priv->fields_of_interest);
+
+	g_mutex_free (priv->pending_mutex);
+
+	/* Chain up to parent's finalize() method. */
+	G_OBJECT_CLASS (e_data_cal_view_parent_class)->finalize (object);
 }
 
 static void
-e_data_cal_view_get_property (GObject *object,
-                              guint property_id,
-                              GValue *value,
-                              GParamSpec *pspec)
+e_data_cal_view_class_init (EDataCalViewClass *class)
 {
-	EDataCalView *view;
-	EDataCalViewPrivate *priv;
+	GObjectClass *object_class;
 
-	view = E_DATA_CAL_VIEW (object);
-	priv = view->priv;
+	g_type_class_add_private (class, sizeof (EDataCalViewPrivate));
 
-	switch (property_id) {
-	case PROP_BACKEND:
-		g_value_set_object (value, priv->backend);
-		break;
-	case PROP_SEXP:
-		g_value_set_object (value, priv->sexp);
-		break;
-	default:
-		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
-		break;
-	}
+	object_class = G_OBJECT_CLASS (class);
+	object_class->set_property = data_cal_view_set_property;
+	object_class->get_property = data_cal_view_get_property;
+	object_class->dispose = data_cal_view_dispose;
+	object_class->finalize = data_cal_view_finalize;
+
+	g_object_class_install_property (
+		object_class,
+		PROP_BACKEND,
+		g_param_spec_object (
+			"backend",
+			"Backend",
+			"The backend being monitored",
+			E_TYPE_CAL_BACKEND,
+			G_PARAM_READWRITE |
+			G_PARAM_CONSTRUCT_ONLY |
+			G_PARAM_STATIC_STRINGS));
+
+	g_object_class_install_property (
+		object_class,
+		PROP_SEXP,
+		g_param_spec_object (
+			"sexp",
+			"S-Expression",
+			"The query expression for this view",
+			E_TYPE_CAL_BACKEND_SEXP,
+			G_PARAM_READWRITE |
+			G_PARAM_CONSTRUCT_ONLY |
+			G_PARAM_STATIC_STRINGS));
 }
 
-/* Instance init */
 static void
 e_data_cal_view_init (EDataCalView *view)
 {
@@ -660,97 +498,270 @@ e_data_cal_view_init (EDataCalView *view)
 	view->priv->flush_id = 0;
 }
 
+EDataCalView *
+e_data_cal_view_new (ECalBackend *backend,
+                     ECalBackendSExp *sexp)
+{
+	g_return_val_if_fail (E_IS_CAL_BACKEND (backend), NULL);
+	g_return_val_if_fail (E_IS_CAL_BACKEND_SEXP (sexp), NULL);
+
+	return g_object_new (
+		E_TYPE_DATA_CAL_VIEW,
+		"backend", backend, "sexp", sexp, NULL);
+}
+
+/**
+ * e_data_cal_view_register_gdbus_object:
+ *
+ * Since: 2.32
+ **/
+guint
+e_data_cal_view_register_gdbus_object (EDataCalView *view,
+                                       GDBusConnection *connection,
+                                       const gchar *object_path,
+                                       GError **error)
+{
+	g_return_val_if_fail (E_IS_DATA_CAL_VIEW (view), 0);
+	g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), 0);
+	g_return_val_if_fail (object_path != NULL, 0);
+
+	return e_gdbus_cal_view_register_object (
+		view->priv->gdbus_object, connection, object_path, error);
+}
+
 static void
-e_data_cal_view_dispose (GObject *object)
+send_pending_adds (EDataCalView *view)
 {
-	EDataCalView *view;
-	EDataCalViewPrivate *priv;
+	if (view->priv->adds->len == 0)
+		return;
 
-	g_return_if_fail (object != NULL);
-	g_return_if_fail (E_IS_DATA_CAL_VIEW (object));
+	e_gdbus_cal_view_emit_objects_added (
+		view->priv->gdbus_object,
+		(const gchar * const *) view->priv->adds->data);
+	reset_array (view->priv->adds);
+}
 
-	view = E_DATA_CAL_VIEW (object);
-	priv = view->priv;
+static void
+send_pending_changes (EDataCalView *view)
+{
+	if (view->priv->changes->len == 0)
+		return;
 
-	if (priv->backend) {
-		e_cal_backend_remove_view (priv->backend, view);
-		g_object_unref (priv->backend);
-		priv->backend = NULL;
-	}
+	e_gdbus_cal_view_emit_objects_modified (
+		view->priv->gdbus_object,
+		(const gchar * const *) view->priv->changes->data);
+	reset_array (view->priv->changes);
+}
 
-	if (priv->sexp) {
-		g_object_unref (priv->sexp);
-		priv->sexp = NULL;
+static void
+send_pending_removes (EDataCalView *view)
+{
+	if (view->priv->removes->len == 0)
+		return;
+
+	/* send ECalComponentIds as <uid>[\n<rid>], as encoded in notify_remove() */
+	e_gdbus_cal_view_emit_objects_removed (
+		view->priv->gdbus_object,
+		(const gchar * const *) view->priv->removes->data);
+	reset_array (view->priv->removes);
+}
+
+static gboolean
+pending_flush_timeout_cb (gpointer data)
+{
+	EDataCalView *view = data;
+
+	g_mutex_lock (view->priv->pending_mutex);
+
+	view->priv->flush_id = 0;
+
+	send_pending_adds (view);
+	send_pending_changes (view);
+	send_pending_removes (view);
+
+	g_mutex_unlock (view->priv->pending_mutex);
+
+	return FALSE;
+}
+
+static void
+ensure_pending_flush_timeout (EDataCalView *view)
+{
+	if (view->priv->flush_id > 0)
+		return;
+
+	if (e_data_cal_view_is_completed (view))
+		view->priv->flush_id = g_timeout_add (
+			10 /* ms */, pending_flush_timeout_cb, view);
+	else
+		view->priv->flush_id = g_timeout_add_seconds (
+			THRESHOLD_SECONDS, pending_flush_timeout_cb, view);
+}
+
+static void
+notify_add (EDataCalView *view,
+            gchar *obj)
+{
+	ECalComponent *comp;
+	ECalClientViewFlags flags;
+
+	send_pending_changes (view);
+	send_pending_removes (view);
+
+	/* Do not send object add notifications during initial stage */
+	flags = e_data_cal_view_get_flags (view);
+	if (view->priv->complete || (flags & E_CAL_CLIENT_VIEW_FLAGS_NOTIFY_INITIAL) != 0) {
+		if (view->priv->adds->len == THRESHOLD_ITEMS)
+			send_pending_adds (view);
+		g_array_append_val (view->priv->adds, obj);
+
+		ensure_pending_flush_timeout (view);
 	}
 
-	g_mutex_lock (priv->pending_mutex);
+	comp = e_cal_component_new_from_string (obj);
+	g_hash_table_insert (
+		view->priv->ids,
+		e_cal_component_get_id (comp),
+		GUINT_TO_POINTER (1));
+	g_object_unref (comp);
+}
 
-	if (priv->flush_id) {
-		g_source_remove (priv->flush_id);
-		priv->flush_id = 0;
+static void
+notify_add_component (EDataCalView *view,
+                      /* const */ ECalComponent *comp)
+{
+	ECalClientViewFlags flags;
+	gchar *obj;
+
+	obj = e_data_cal_view_get_component_string (view, comp);
+
+	send_pending_changes (view);
+	send_pending_removes (view);
+
+	/* Do not send component add notifications during initial stage */
+	flags = e_data_cal_view_get_flags (view);
+	if (view->priv->complete || (flags & E_CAL_CLIENT_VIEW_FLAGS_NOTIFY_INITIAL) != 0) {
+		if (view->priv->adds->len == THRESHOLD_ITEMS)
+			send_pending_adds (view);
+		g_array_append_val (view->priv->adds, obj);
+
+		ensure_pending_flush_timeout (view);
 	}
 
-	g_mutex_unlock (priv->pending_mutex);
+	g_hash_table_insert (
+		view->priv->ids,
+		e_cal_component_get_id (comp),
+		GUINT_TO_POINTER (1));
+}
+
+static void
+notify_change (EDataCalView *view,
+               gchar *obj)
+{
+	send_pending_adds (view);
+	send_pending_removes (view);
+
+	if (view->priv->changes->len == THRESHOLD_ITEMS)
+		send_pending_changes (view);
 
-	(* G_OBJECT_CLASS (e_data_cal_view_parent_class)->dispose) (object);
+	g_array_append_val (view->priv->changes, obj);
+
+	ensure_pending_flush_timeout (view);
 }
 
 static void
-e_data_cal_view_finalize (GObject *object)
+notify_change_component (EDataCalView *view,
+                         ECalComponent *comp)
 {
-	EDataCalView *view;
-	EDataCalViewPrivate *priv;
+	gchar *obj;
 
-	g_return_if_fail (object != NULL);
-	g_return_if_fail (E_IS_DATA_CAL_VIEW (object));
+	obj = e_data_cal_view_get_component_string (view, comp);
 
-	view = E_DATA_CAL_VIEW (object);
-	priv = view->priv;
+	notify_change (view, obj);
+}
 
-	reset_array (priv->adds);
-	reset_array (priv->changes);
-	reset_array (priv->removes);
+static void
+notify_remove (EDataCalView *view,
+               ECalComponentId *id)
+{
+	gchar *ids;
+	gchar *uid, *rid;
+	gsize uid_len, rid_len;
 
-	g_array_free (priv->adds, TRUE);
-	g_array_free (priv->changes, TRUE);
-	g_array_free (priv->removes, TRUE);
+	send_pending_adds (view);
+	send_pending_changes (view);
 
-	g_hash_table_destroy (priv->ids);
+	if (view->priv->removes->len == THRESHOLD_ITEMS)
+		send_pending_removes (view);
 
-	if (priv->fields_of_interest)
-		g_hash_table_destroy (priv->fields_of_interest);
+	/* store ECalComponentId as <uid>[\n<rid>] (matches D-Bus API) */
+	if (id->uid) {
+		uid = e_util_utf8_make_valid (id->uid);
+		uid_len = strlen (uid);
+	} else {
+		uid = NULL;
+		uid_len = 0;
+	}
+	if (id->rid) {
+		rid = e_util_utf8_make_valid (id->rid);
+		rid_len = strlen (rid);
+	} else {
+		rid = NULL;
+		rid_len = 0;
+	}
+	if (uid_len && !rid_len) {
+		/* shortcut */
+		ids = uid;
+		uid = NULL;
+	} else {
+		/* concatenate */
+		ids = g_malloc (uid_len + rid_len + (rid_len ? 2 : 1));
+		if (uid_len)
+			strcpy (ids, uid);
+		if (rid_len) {
+			ids[uid_len] = '\n';
+			strcpy (ids + uid_len + 1, rid);
+		}
+	}
+	g_array_append_val (view->priv->removes, ids);
+	g_free (uid);
+	g_free (rid);
 
-	g_mutex_free (priv->pending_mutex);
+	g_hash_table_remove (view->priv->ids, id);
 
-	(* G_OBJECT_CLASS (e_data_cal_view_parent_class)->finalize) (object);
+	ensure_pending_flush_timeout (view);
 }
 
 /**
- * e_data_cal_view_get_text:
- * @view: A #EDataCalView object.
+ * e_data_cal_view_get_backend:
+ * @view: an #EDataCalView
  *
- * Get the expression used for the given view.
+ * Gets the backend that @view is querying.
  *
- * Returns: the view expression used to search.
- */
-const gchar *
-e_data_cal_view_get_text (EDataCalView *view)
+ * Returns: The associated #ECalBackend.
+ *
+ * Since: 3.8
+ **/
+ECalBackend *
+e_data_cal_view_get_backend (EDataCalView *view)
 {
 	g_return_val_if_fail (E_IS_DATA_CAL_VIEW (view), NULL);
 
-	return e_cal_backend_sexp_text (view->priv->sexp);
+	return view->priv->backend;
 }
 
 /**
- * e_data_cal_view_get_object_sexp:
- * @view: A view object.
+ * e_data_cal_view_get_sexp:
+ * @view: an #EDataCalView
  *
  * Get the #ECalBackendSExp object used for the given view.
  *
  * Returns: The expression object used to search.
+ *
+ * Since: 3.8
  */
 ECalBackendSExp *
-e_data_cal_view_get_object_sexp (EDataCalView *view)
+e_data_cal_view_get_sexp (EDataCalView *view)
 {
 	g_return_val_if_fail (E_IS_DATA_CAL_VIEW (view), NULL);
 
@@ -759,7 +770,7 @@ e_data_cal_view_get_object_sexp (EDataCalView *view)
 
 /**
  * e_data_cal_view_object_matches:
- * @view: A view object.
+ * @view: an #EDataCalView
  * @object: Object to match.
  *
  * Compares the given @object to the regular expression used for the
@@ -771,20 +782,16 @@ gboolean
 e_data_cal_view_object_matches (EDataCalView *view,
                                 const gchar *object)
 {
-	EDataCalViewPrivate *priv;
-
-	g_return_val_if_fail (view != NULL, FALSE);
 	g_return_val_if_fail (E_IS_DATA_CAL_VIEW (view), FALSE);
 	g_return_val_if_fail (object != NULL, FALSE);
 
-	priv = view->priv;
-
-	return e_cal_backend_sexp_match_object (priv->sexp, object, priv->backend);
+	return e_cal_backend_sexp_match_object (
+		view->priv->sexp, object, view->priv->backend);
 }
 
 /**
  * e_data_cal_view_component_matches:
- * @view: A view object.
+ * @view: an #EDataCalView
  * @component: the #ECalComponent object to match.
  *
  * Compares the given @component to the regular expression used for the
@@ -798,20 +805,16 @@ gboolean
 e_data_cal_view_component_matches (EDataCalView *view,
                                    ECalComponent *component)
 {
-	EDataCalViewPrivate *priv;
-
-	g_return_val_if_fail (view != NULL, FALSE);
 	g_return_val_if_fail (E_IS_DATA_CAL_VIEW (view), FALSE);
 	g_return_val_if_fail (E_IS_CAL_COMPONENT (component), FALSE);
 
-	priv = view->priv;
-
-	return e_cal_backend_sexp_match_comp (priv->sexp, component, priv->backend);
+	return e_cal_backend_sexp_match_comp (
+		view->priv->sexp, component, view->priv->backend);
 }
 
 /**
  * e_data_cal_view_is_started:
- * @view: A view object.
+ * @view: an #EDataCalView
  *
  * Checks whether the given view has already been started.
  *
@@ -827,7 +830,7 @@ e_data_cal_view_is_started (EDataCalView *view)
 
 /**
  * e_data_cal_view_is_stopped:
- * @view: A view object.
+ * @view: an #EDataCalView
  *
  * Checks whether the given view has been stopped.
  *
@@ -845,7 +848,7 @@ e_data_cal_view_is_stopped (EDataCalView *view)
 
 /**
  * e_data_cal_view_is_completed:
- * @view: A view object.
+ * @view: an #EDataCalView
  *
  * Checks whether the given view is already completed. Being completed means the initial
  * matching of objects have been finished, not that no more notifications about
@@ -866,7 +869,7 @@ e_data_cal_view_is_completed (EDataCalView *view)
 
 /**
  * e_data_cal_view_get_fields_of_interest:
- * @view: A view object.
+ * @view: an #EDataCalView
  *
  * Returns: Hash table of field names which the listener is interested in.
  * Backends can return fully populated objects, but the listener advertised
@@ -888,7 +891,7 @@ e_data_cal_view_get_fields_of_interest (EDataCalView *view)
 
 /**
  * e_data_cal_view_get_flags:
- * @view: A view object.
+ * @view: an #EDataCalView
  *
  * Gets the #ECalClientViewFlags that control the behaviour of @view.
  *
@@ -981,7 +984,7 @@ filter_component (icalcomponent *icomponent,
 
 /**
  * e_data_cal_view_get_component_string:
- * @view: A view object.
+ * @view: an #EDataCalView
  * @component: The #ECalComponent to get the string for.
  *
  * This function is similar to e_cal_component_get_as_string() except
@@ -995,10 +998,10 @@ filter_component (icalcomponent *icomponent,
  */
 gchar *
 e_data_cal_view_get_component_string (EDataCalView *view,
-                                      /* const */ ECalComponent *component)
+                                      ECalComponent *component)
 {
 	g_return_val_if_fail (E_IS_DATA_CAL_VIEW (view), NULL);
-	g_return_val_if_fail (component != NULL, NULL);
+	g_return_val_if_fail (E_IS_CAL_COMPONENT (component), NULL);
 
 	if (view->priv->fields_of_interest) {
 		GString *string = g_string_new ("");
@@ -1015,7 +1018,7 @@ e_data_cal_view_get_component_string (EDataCalView *view,
 
 /**
  * e_data_cal_view_notify_components_added:
- * @view: A view object.
+ * @view: an #EDataCalView
  * @ecalcomponents: List of #ECalComponent-s that have been added.
  *
  * Notifies all view listeners of the addition of a list of components.
@@ -1031,16 +1034,14 @@ void
 e_data_cal_view_notify_components_added (EDataCalView *view,
                                          const GSList *ecalcomponents)
 {
-	EDataCalViewPrivate *priv;
 	const GSList *l;
 
-	g_return_if_fail (view && E_IS_DATA_CAL_VIEW (view));
-	priv = view->priv;
+	g_return_if_fail (E_IS_DATA_CAL_VIEW (view));
 
 	if (ecalcomponents == NULL)
 		return;
 
-	g_mutex_lock (priv->pending_mutex);
+	g_mutex_lock (view->priv->pending_mutex);
 
 	for (l = ecalcomponents; l; l = l->next) {
 		ECalComponent *comp = l->data;
@@ -1050,12 +1051,12 @@ e_data_cal_view_notify_components_added (EDataCalView *view,
 		notify_add_component (view, comp);
 	}
 
-	g_mutex_unlock (priv->pending_mutex);
+	g_mutex_unlock (view->priv->pending_mutex);
 }
 
 /**
  * e_data_cal_view_notify_components_added_1:
- * @view: A view object.
+ * @view: an #EDataCalView
  * @component: The #ECalComponent that has been added.
  *
  * Notifies all the view listeners of the addition of a single object.
@@ -1069,12 +1070,12 @@ e_data_cal_view_notify_components_added (EDataCalView *view,
  */
 void
 e_data_cal_view_notify_components_added_1 (EDataCalView *view,
-                                           /* const */ ECalComponent *component)
+                                           ECalComponent *component)
 {
 	GSList l = {NULL,};
 
 	g_return_if_fail (E_IS_DATA_CAL_VIEW (view));
-	g_return_if_fail (component != NULL);
+	g_return_if_fail (E_IS_CAL_COMPONENT (component));
 
 	l.data = (gpointer) component;
 	e_data_cal_view_notify_components_added (view, &l);
@@ -1082,7 +1083,7 @@ e_data_cal_view_notify_components_added_1 (EDataCalView *view,
 
 /**
  * e_data_cal_view_notify_components_modified:
- * @view: A view object.
+ * @view: an #EDataCalView
  * @ecalcomponents: List of modified #ECalComponent-s.
  *
  * Notifies all view listeners of the modification of a list of components.
@@ -1098,16 +1099,14 @@ void
 e_data_cal_view_notify_components_modified (EDataCalView *view,
                                             const GSList *ecalcomponents)
 {
-	EDataCalViewPrivate *priv;
 	const GSList *l;
 
-	g_return_if_fail (view && E_IS_DATA_CAL_VIEW (view));
-	priv = view->priv;
+	g_return_if_fail (E_IS_DATA_CAL_VIEW (view));
 
 	if (ecalcomponents == NULL)
 		return;
 
-	g_mutex_lock (priv->pending_mutex);
+	g_mutex_lock (view->priv->pending_mutex);
 
 	for (l = ecalcomponents; l; l = l->next) {
 		ECalComponent *comp = l->data;
@@ -1117,12 +1116,12 @@ e_data_cal_view_notify_components_modified (EDataCalView *view,
 		notify_change_component (view, comp);
 	}
 
-	g_mutex_unlock (priv->pending_mutex);
+	g_mutex_unlock (view->priv->pending_mutex);
 }
 
 /**
  * e_data_cal_view_notify_components_modified_1:
- * @view: A view object.
+ * @view: an #EDataCalView
  * @component: The modified #ECalComponent.
  *
  * Notifies all view listeners of the modification of @component.
@@ -1136,12 +1135,12 @@ e_data_cal_view_notify_components_modified (EDataCalView *view,
  */
 void
 e_data_cal_view_notify_components_modified_1 (EDataCalView *view,
-                                              /* const */ ECalComponent *component)
+                                              ECalComponent *component)
 {
 	GSList l = {NULL,};
 
 	g_return_if_fail (E_IS_DATA_CAL_VIEW (view));
-	g_return_if_fail (component != NULL);
+	g_return_if_fail (E_IS_CAL_COMPONENT (component));
 
 	l.data = (gpointer) component;
 	e_data_cal_view_notify_components_modified (view, &l);
@@ -1149,7 +1148,7 @@ e_data_cal_view_notify_components_modified_1 (EDataCalView *view,
 
 /**
  * e_data_cal_view_notify_objects_added:
- * @view: A view object.
+ * @view: an #EDataCalView
  * @objects: List of objects that have been added.
  *
  * Notifies all view listeners of the addition of a list of objects.
@@ -1161,27 +1160,25 @@ void
 e_data_cal_view_notify_objects_added (EDataCalView *view,
                                       const GSList *objects)
 {
-	EDataCalViewPrivate *priv;
 	const GSList *l;
 
-	g_return_if_fail (view && E_IS_DATA_CAL_VIEW (view));
-	priv = view->priv;
+	g_return_if_fail (E_IS_DATA_CAL_VIEW (view));
 
 	if (objects == NULL)
 		return;
 
-	g_mutex_lock (priv->pending_mutex);
+	g_mutex_lock (view->priv->pending_mutex);
 
 	for (l = objects; l; l = l->next) {
 		notify_add (view, e_util_utf8_make_valid (l->data));
 	}
 
-	g_mutex_unlock (priv->pending_mutex);
+	g_mutex_unlock (view->priv->pending_mutex);
 }
 
 /**
  * e_data_cal_view_notify_objects_added_1:
- * @view: A view object.
+ * @view: an #EDataCalView
  * @object: The object that has been added.
  *
  * Notifies all the view listeners of the addition of a single object.
@@ -1195,8 +1192,8 @@ e_data_cal_view_notify_objects_added_1 (EDataCalView *view,
 {
 	GSList l = {NULL,};
 
-	g_return_if_fail (view && E_IS_DATA_CAL_VIEW (view));
-	g_return_if_fail (object);
+	g_return_if_fail (E_IS_DATA_CAL_VIEW (view));
+	g_return_if_fail (object != NULL);
 
 	l.data = (gpointer) object;
 	e_data_cal_view_notify_objects_added (view, &l);
@@ -1204,7 +1201,7 @@ e_data_cal_view_notify_objects_added_1 (EDataCalView *view,
 
 /**
  * e_data_cal_view_notify_objects_modified:
- * @view: A view object.
+ * @view: an #EDataCalView
  * @objects: List of modified objects.
  *
  * Notifies all view listeners of the modification of a list of objects.
@@ -1216,28 +1213,26 @@ void
 e_data_cal_view_notify_objects_modified (EDataCalView *view,
                                          const GSList *objects)
 {
-	EDataCalViewPrivate *priv;
 	const GSList *l;
 
-	g_return_if_fail (view && E_IS_DATA_CAL_VIEW (view));
-	priv = view->priv;
+	g_return_if_fail (E_IS_DATA_CAL_VIEW (view));
 
 	if (objects == NULL)
 		return;
 
-	g_mutex_lock (priv->pending_mutex);
+	g_mutex_lock (view->priv->pending_mutex);
 
 	for (l = objects; l; l = l->next) {
 		/* TODO: send add/remove/change as relevant, based on ->ids */
 		notify_change (view, e_util_utf8_make_valid (l->data));
 	}
 
-	g_mutex_unlock (priv->pending_mutex);
+	g_mutex_unlock (view->priv->pending_mutex);
 }
 
 /**
  * e_data_cal_view_notify_objects_modified_1:
- * @view: A view object.
+ * @view: an #EDataCalView
  * @object: The modified object.
  *
  * Notifies all view listeners of the modification of a single object.
@@ -1251,8 +1246,8 @@ e_data_cal_view_notify_objects_modified_1 (EDataCalView *view,
 {
 	GSList l = {NULL,};
 
-	g_return_if_fail (view && E_IS_DATA_CAL_VIEW (view));
-	g_return_if_fail (object);
+	g_return_if_fail (E_IS_DATA_CAL_VIEW (view));
+	g_return_if_fail (object != NULL);
 
 	l.data = (gpointer) object;
 	e_data_cal_view_notify_objects_modified (view, &l);
@@ -1260,7 +1255,7 @@ e_data_cal_view_notify_objects_modified_1 (EDataCalView *view,
 
 /**
  * e_data_cal_view_notify_objects_removed:
- * @view: A view object.
+ * @view: an #EDataCalView
  * @ids: List of IDs for the objects that have been removed.
  *
  * Notifies all view listener of the removal of a list of objects.
@@ -1269,29 +1264,27 @@ void
 e_data_cal_view_notify_objects_removed (EDataCalView *view,
                                         const GSList *ids)
 {
-	EDataCalViewPrivate *priv;
 	const GSList *l;
 
-	g_return_if_fail (view && E_IS_DATA_CAL_VIEW (view));
-	priv = view->priv;
+	g_return_if_fail (E_IS_DATA_CAL_VIEW (view));
 
 	if (ids == NULL)
 		return;
 
-	g_mutex_lock (priv->pending_mutex);
+	g_mutex_lock (view->priv->pending_mutex);
 
 	for (l = ids; l; l = l->next) {
 		ECalComponentId *id = l->data;
-		if (g_hash_table_lookup (priv->ids, id))
+		if (g_hash_table_lookup (view->priv->ids, id))
 		    notify_remove (view, id);
 	}
 
-	g_mutex_unlock (priv->pending_mutex);
+	g_mutex_unlock (view->priv->pending_mutex);
 }
 
 /**
  * e_data_cal_view_notify_objects_removed_1:
- * @view: A view object.
+ * @view: an #EDataCalView
  * @id: ID of the removed object.
  *
  * Notifies all view listener of the removal of a single object.
@@ -1302,8 +1295,8 @@ e_data_cal_view_notify_objects_removed_1 (EDataCalView *view,
 {
 	GSList l = {NULL,};
 
-	g_return_if_fail (view && E_IS_DATA_CAL_VIEW (view));
-	g_return_if_fail (id);
+	g_return_if_fail (E_IS_DATA_CAL_VIEW (view));
+	g_return_if_fail (id != NULL);
 
 	l.data = (gpointer) id;
 	e_data_cal_view_notify_objects_removed (view, &l);
@@ -1311,7 +1304,7 @@ e_data_cal_view_notify_objects_removed_1 (EDataCalView *view,
 
 /**
  * e_data_cal_view_notify_progress:
- * @view: A view object.
+ * @view: an #EDataCalView
  * @percent: Percentage completed.
  * @message: Progress message to send to listeners.
  *
@@ -1322,23 +1315,23 @@ e_data_cal_view_notify_progress (EDataCalView *view,
                                  gint percent,
                                  const gchar *message)
 {
-	EDataCalViewPrivate *priv;
 	gchar *gdbus_message = NULL;
 
-	g_return_if_fail (view && E_IS_DATA_CAL_VIEW (view));
-	priv = view->priv;
+	g_return_if_fail (E_IS_DATA_CAL_VIEW (view));
 
-	if (!priv->started || priv->stopped)
+	if (!view->priv->started || view->priv->stopped)
 		return;
 
-	e_gdbus_cal_view_emit_progress (view->priv->gdbus_object, percent, e_util_ensure_gdbus_string (message, &gdbus_message));
+	e_gdbus_cal_view_emit_progress (
+		view->priv->gdbus_object, percent,
+		e_util_ensure_gdbus_string (message, &gdbus_message));
 
 	g_free (gdbus_message);
 }
 
 /**
  * e_data_cal_view_notify_complete:
- * @view: A view object.
+ * @view: an #EDataCalView
  * @error: View completion error, if any.
  *
  * Notifies all view listeners of the completion of the view, including a
@@ -1350,19 +1343,29 @@ void
 e_data_cal_view_notify_complete (EDataCalView *view,
                                  const GError *error)
 {
-	EDataCalViewPrivate *priv;
+	gchar **error_strv;
 
-	g_return_if_fail (view && E_IS_DATA_CAL_VIEW (view));
-	priv = view->priv;
+	g_return_if_fail (E_IS_DATA_CAL_VIEW (view));
 
-	if (!priv->started || priv->stopped)
+	if (!view->priv->started || view->priv->stopped)
 		return;
 
-	g_mutex_lock (priv->pending_mutex);
+	g_mutex_lock (view->priv->pending_mutex);
+
+	view->priv->complete = TRUE;
+
+	send_pending_adds (view);
+	send_pending_changes (view);
+	send_pending_removes (view);
+
+	error_strv = e_gdbus_templates_encode_error (error);
 
-	priv->complete = TRUE;
+	e_gdbus_cal_view_emit_complete (
+		view->priv->gdbus_object,
+		(const gchar * const *) error_strv);
 
-	notify_complete (view, error);
+	g_strfreev (error_strv);
 
-	g_mutex_unlock (priv->pending_mutex);
+	g_mutex_unlock (view->priv->pending_mutex);
 }
+
diff --git a/calendar/libedata-cal/e-data-cal-view.h b/calendar/libedata-cal/e-data-cal-view.h
index 945b891..d04e71c 100644
--- a/calendar/libedata-cal/e-data-cal-view.h
+++ b/calendar/libedata-cal/e-data-cal-view.h
@@ -72,9 +72,10 @@ guint		e_data_cal_view_register_gdbus_object
 						 GDBusConnection *connection,
 						 const gchar *object_path,
 						 GError **error);
-const gchar *	e_data_cal_view_get_text	(EDataCalView *view);
+struct _ECalBackend *
+		e_data_cal_view_get_backend	(EDataCalView *view);
 struct _ECalBackendSExp *
-		e_data_cal_view_get_object_sexp	(EDataCalView *view);
+		e_data_cal_view_get_sexp	(EDataCalView *view);
 gboolean	e_data_cal_view_object_matches	(EDataCalView *view,
 						 const gchar *object);
 gboolean	e_data_cal_view_component_matches
diff --git a/docs/reference/calendar/libedata-cal/libedata-cal-sections.txt b/docs/reference/calendar/libedata-cal/libedata-cal-sections.txt
index 0c679ab..4fff930 100644
--- a/docs/reference/calendar/libedata-cal/libedata-cal-sections.txt
+++ b/docs/reference/calendar/libedata-cal/libedata-cal-sections.txt
@@ -340,8 +340,8 @@ e_data_cal_factory_get_type
 <TITLE>EDataCalView</TITLE>
 e_data_cal_view_new
 e_data_cal_view_register_gdbus_object
-e_data_cal_view_get_text
-e_data_cal_view_get_object_sexp
+e_data_cal_view_get_backend
+e_data_cal_view_get_sexp
 e_data_cal_view_object_matches
 e_data_cal_view_component_matches
 e_data_cal_view_is_started



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]