[evolution-data-server/treitter-factory-refactor] Rebase the Calendar factory code upon the general classes.



commit 897fa9ebfb71b8a77ac8ee264fde59577db2898f
Author: Travis Reitter <treitter gmail com>
Date:   Tue Jan 26 09:47:50 2010 -0800

    Rebase the Calendar factory code upon the general classes.

 addressbook/libedata-book/e-book-backend.c    |    4 -
 calendar/libedata-cal/e-cal-backend-factory.c |   50 ++---
 calendar/libedata-cal/e-cal-backend-factory.h |   21 +-
 calendar/libedata-cal/e-cal-backend-sexp.c    |   33 +--
 calendar/libedata-cal/e-cal-backend-sexp.h    |    9 +-
 calendar/libedata-cal/e-cal-backend.c         |  368 ++++++++-----------------
 calendar/libedata-cal/e-cal-backend.h         |   11 +-
 calendar/libedata-cal/e-data-cal-view.c       |  179 ++++--------
 calendar/libedata-cal/e-data-cal-view.h       |    8 +-
 calendar/libedata-cal/e-data-cal.c            |  124 +++++----
 calendar/libedata-cal/e-data-cal.h            |    7 +-
 libebackend/e-backend.c                       |  296 +++++++++++++-------
 libebackend/e-backend.h                       |   73 ++----
 13 files changed, 506 insertions(+), 677 deletions(-)
---
diff --git a/addressbook/libedata-book/e-book-backend.c b/addressbook/libedata-book/e-book-backend.c
index 609b943..99a9b69 100644
--- a/addressbook/libedata-book/e-book-backend.c
+++ b/addressbook/libedata-book/e-book-backend.c
@@ -996,12 +996,8 @@ e_book_backend_class_init (EBookBackendClass *klass)
 	object_class->dispose = e_book_backend_dispose;
 
 	/* XXX: do some ugly casting to avoid breaking API */
-	parent_class->stop_view = (void (*)(EBackend*, EDataView*)) e_book_backend_stop_book_view;
-	parent_class->remove = (void (*)(EBackend*, EData*, guint32)) e_book_backend_remove;
-	parent_class->get_static_capabilities = (gchar* (*)(EBackend*)) e_book_backend_get_static_capabilities;
 	parent_class->set_mode = (void (*)(EBackend*, EDataMode)) e_book_backend_set_mode_from_data_mode;
 	parent_class->add_client = (gboolean (*)(EBackend*, EData*)) e_book_backend_add_client;
 	parent_class->remove_client = (void (*)(EBackend*, EData*)) e_book_backend_remove_client;
 	parent_class->is_loaded = (gboolean (*)(EBackend*)) e_book_backend_is_loaded;
-	parent_class->get_changes = (void (*)(EBackend*, EData*, guint32, const gchar *)) e_book_backend_get_changes;
 }
diff --git a/calendar/libedata-cal/e-cal-backend-factory.c b/calendar/libedata-cal/e-cal-backend-factory.c
index 2bb1aaf..a1b6b4c 100644
--- a/calendar/libedata-cal/e-cal-backend-factory.c
+++ b/calendar/libedata-cal/e-cal-backend-factory.c
@@ -12,42 +12,11 @@
 #endif
 
 #include <string.h>
+#include <libebackend/e-backend-factory.h>
 
 #include "e-cal-backend-factory.h"
 
-static void
-e_cal_backend_factory_instance_init (ECalBackendFactory *factory)
-{
-}
-
-static void
-e_cal_backend_factory_class_init (ECalBackendFactoryClass *klass)
-{
-}
-
-GType
-e_cal_backend_factory_get_type (void)
-{
-	static GType type = 0;
-
-	if (! type) {
-		GTypeInfo info = {
-			sizeof (ECalBackendFactoryClass),
-			NULL, /* base_class_init */
-			NULL, /* base_class_finalize */
-			(GClassInitFunc)  e_cal_backend_factory_class_init,
-			NULL, /* class_finalize */
-			NULL, /* class_data */
-			sizeof (ECalBackend),
-			0,    /* n_preallocs */
-			(GInstanceInitFunc) e_cal_backend_factory_instance_init
-		};
-
-		type = g_type_register_static (G_TYPE_OBJECT, "ECalBackendFactory", &info, 0);
-	}
-
-	return type;
-}
+G_DEFINE_TYPE (ECalBackendFactory, e_cal_backend_factory, E_TYPE_BACKEND_FACTORY);
 
 /**
  * e_cal_backend_factory_get_kind:
@@ -97,3 +66,18 @@ e_cal_backend_factory_new_backend (ECalBackendFactory *factory, ESource *source)
 
 	return E_CAL_BACKEND_FACTORY_GET_CLASS (factory)->new_backend (factory, source);
 }
+
+static void
+e_cal_backend_factory_init (ECalBackendFactory *factory)
+{
+}
+
+static void
+e_cal_backend_factory_class_init (ECalBackendFactoryClass *klass)
+{
+	EBackendFactoryClass *parent_class = E_BACKEND_FACTORY_CLASS (klass);
+
+	/* XXX: do some ugly casting to avoid breaking API */
+	parent_class->get_protocol = (const char* (*)(EBackendFactory*)) e_cal_backend_factory_get_protocol;
+	parent_class->new_backend = (EBackend* (*)(EBackendFactory*)) e_cal_backend_factory_new_backend;
+}
diff --git a/calendar/libedata-cal/e-cal-backend-factory.h b/calendar/libedata-cal/e-cal-backend-factory.h
index c572750..d424cc4 100644
--- a/calendar/libedata-cal/e-cal-backend-factory.h
+++ b/calendar/libedata-cal/e-cal-backend-factory.h
@@ -24,6 +24,7 @@
 #define _E_CAL_BACKEND_FACTORY_H_
 
 #include <glib-object.h>
+#include <libebackend/e-backend-factory.h>
 #include "e-cal-backend.h"
 
 G_BEGIN_DECLS
@@ -38,22 +39,24 @@ G_BEGIN_DECLS
 typedef struct _ECalBackendFactoryPrivate ECalBackendFactoryPrivate;
 
 typedef struct {
-	GObject            parent_object;
+	EBackend	parent_object;
 } ECalBackendFactory;
 
 typedef struct {
-	GObjectClass parent_class;
+	EBackendClass	parent_class;
 
-	icalcomponent_kind (*get_kind)     (ECalBackendFactory *factory);
-	const gchar *        (*get_protocol) (ECalBackendFactory *factory);
-	ECalBackend*       (*new_backend)  (ECalBackendFactory *factory, ESource *source);
+	icalcomponent_kind	(*get_kind)	(ECalBackendFactory *factory);
+	const gchar*		(*get_protocol)	(ECalBackendFactory *factory);
+	ECalBackend*		(*new_backend)	(ECalBackendFactory *factory,
+						 ESource            *source);
 } ECalBackendFactoryClass;
 
-GType               e_cal_backend_factory_get_type              (void);
+GType			e_cal_backend_factory_get_type		(void);
 
-icalcomponent_kind  e_cal_backend_factory_get_kind              (ECalBackendFactory *factory);
-const gchar *         e_cal_backend_factory_get_protocol          (ECalBackendFactory *factory);
-ECalBackend*        e_cal_backend_factory_new_backend           (ECalBackendFactory *factory, ESource *source);
+icalcomponent_kind	e_cal_backend_factory_get_kind		(ECalBackendFactory *factory);
+const gchar*		e_cal_backend_factory_get_protocol	(ECalBackendFactory *factory);
+ECalBackend*		e_cal_backend_factory_new_backend	(ECalBackendFactory *factory,
+								 ESource            *source);
 
 G_END_DECLS
 
diff --git a/calendar/libedata-cal/e-cal-backend-sexp.c b/calendar/libedata-cal/e-cal-backend-sexp.c
index 4d84c7b..7834d48 100644
--- a/calendar/libedata-cal/e-cal-backend-sexp.c
+++ b/calendar/libedata-cal/e-cal-backend-sexp.c
@@ -47,6 +47,8 @@ struct _SearchContext {
 
 static ESExpResult *func_is_completed (ESExp *esexp, gint argc, ESExpResult **argv, gpointer data);
 
+G_DEFINE_TYPE (ECalBackendSExp, e_cal_backend_sexp, E_TYPE_BACKEND_SEXP);
+
 /**
  * e_cal_backend_sexp_func_time_now:
  * @esexp: An #ESExp object.
@@ -1444,34 +1446,3 @@ e_cal_backend_sexp_init (ECalBackendSExp *sexp)
 	sexp->priv = priv;
 	priv->search_context = g_new (SearchContext, 1);
 }
-
-/**
- * e_cal_backend_sexp_get_type:
- *
- * Registers the #ECalBackendSExp class if needed.
- *
- * Return value: The unique identifier of the class.
- */
-GType
-e_cal_backend_sexp_get_type (void)
-{
-	static GType type = 0;
-
-	if (! type) {
-		GTypeInfo info = {
-			sizeof (ECalBackendSExpClass),
-			NULL, /* base_class_init */
-			NULL, /* base_class_finalize */
-			(GClassInitFunc)  e_cal_backend_sexp_class_init,
-			NULL, /* class_finalize */
-			NULL, /* class_data */
-			sizeof (ECalBackendSExp),
-			0,    /* n_preallocs */
-			(GInstanceInitFunc) e_cal_backend_sexp_init
-		};
-
-		type = g_type_register_static (G_TYPE_OBJECT, "ECalBackendSExp", &info, 0);
-	}
-
-	return type;
-}
diff --git a/calendar/libedata-cal/e-cal-backend-sexp.h b/calendar/libedata-cal/e-cal-backend-sexp.h
index e25e7b6..8b7025d 100644
--- a/calendar/libedata-cal/e-cal-backend-sexp.h
+++ b/calendar/libedata-cal/e-cal-backend-sexp.h
@@ -28,7 +28,9 @@
 #include <glib-object.h>
 #include <libecal/e-cal-component.h>
 #include <libedata-cal/e-cal-backend.h>
-#include "libedataserver/e-sexp.h"
+#include <libedataserver/e-sexp.h>
+#include <libebackend/e-data-types.h>
+#include <libebackend/e-backend-sexp.h>
 
 G_BEGIN_DECLS
 
@@ -42,13 +44,12 @@ G_BEGIN_DECLS
 typedef struct _ECalBackendSExpPrivate ECalBackendSExpPrivate;
 
 struct _ECalBackendSExp {
-	GObject parent_object;
-
+	EBackendSExp parent_object;
 	ECalBackendSExpPrivate *priv;
 };
 
 struct _ECalBackendSExpClass {
-	GObjectClass parent_class;
+	EBackendSExpClass parent_class;
 };
 
 GType            e_cal_backend_sexp_get_type     (void);
diff --git a/calendar/libedata-cal/e-cal-backend.c b/calendar/libedata-cal/e-cal-backend.c
index cc2d36c..81f99dc 100644
--- a/calendar/libedata-cal/e-cal-backend.c
+++ b/calendar/libedata-cal/e-cal-backend.c
@@ -26,33 +26,18 @@
 #include <libxml/parserInternals.h>
 #include <libxml/xmlmemory.h>
 
+#include <libebackend/e-backend.h>
+#include <libebackend/e-data-view.h>
 #include "e-cal-backend.h"
 #include "e-cal-backend-cache.h"
 
-
-
-G_DEFINE_TYPE (ECalBackend, e_cal_backend, G_TYPE_OBJECT);
+G_DEFINE_TYPE (ECalBackend, e_cal_backend, E_TYPE_BACKEND);
 
 /* Private part of the CalBackend structure */
 struct _ECalBackendPrivate {
-	/* The source for this backend */
-	ESource *source;
-	/* signal handler ID for source's 'changed' signal */
-	gulong source_changed_id;
-
-	/* URI, from source. This is cached, since we return const. */
-	gchar *uri;
-
 	/* The kind of components for this backend */
 	icalcomponent_kind kind;
 
-	/* List of Cal objects */
-	GMutex *clients_mutex;
-	GList *clients;
-
-	GMutex *queries_mutex;
-	EList *queries;
-
 	/* ECalBackend to pass notifications on to */
 	ECalBackend *notification_proxy;
 
@@ -70,8 +55,6 @@ struct _ECalBackendPrivate {
 /* Property IDs */
 enum props {
 	PROP_0,
-	PROP_SOURCE,
-	PROP_URI,
 	PROP_KIND
 };
 
@@ -84,33 +67,6 @@ enum {
 };
 static guint e_cal_backend_signals[LAST_SIGNAL];
 
-static void e_cal_backend_finalize (GObject *object);
-
-
-
-static void
-source_changed_cb (ESource *source, ECalBackend *backend)
-{
-	ECalBackendPrivate *priv;
-	gchar *suri;
-
-	g_return_if_fail (source != NULL);
-	g_return_if_fail (backend != NULL);
-	g_return_if_fail (E_IS_CAL_BACKEND (backend));
-
-	priv = backend->priv;
-	g_return_if_fail (priv != NULL);
-	g_return_if_fail (priv->source == source);
-
-	suri = e_source_get_uri (priv->source);
-	if (!priv->uri || (suri && !g_str_equal (priv->uri, suri))) {
-		g_free (priv->uri);
-		priv->uri = suri;
-	} else {
-		g_free (suri);
-	}
-}
-
 static void
 e_cal_backend_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
 {
@@ -121,39 +77,6 @@ e_cal_backend_set_property (GObject *object, guint property_id, const GValue *va
 	priv = backend->priv;
 
 	switch (property_id) {
-	case PROP_SOURCE:
-		{
-			ESource *new_source;
-
-			if (priv->source_changed_id && priv->source) {
-				g_signal_handler_disconnect (priv->source, priv->source_changed_id);
-				priv->source_changed_id = 0;
-			}
-
-			new_source = g_value_get_object (value);
-			if (new_source) {
-				g_object_ref (new_source);
-				priv->source_changed_id = g_signal_connect (new_source, "changed", G_CALLBACK (source_changed_cb), backend);
-			}
-
-			if (priv->source)
-				g_object_unref (priv->source);
-
-			priv->source = new_source;
-
-			/* Cache the URI */
-			if (new_source) {
-				g_free (priv->uri);
-				priv->uri = e_source_get_uri (priv->source);
-			}
-		}
-		break;
-	case PROP_URI:
-		if (!priv->source) {
-			g_free (priv->uri);
-			priv->uri = g_value_dup_string (value);
-		}
-		break;
 	case PROP_KIND:
 		priv->kind = g_value_get_ulong (value);
 		break;
@@ -173,12 +96,6 @@ e_cal_backend_get_property (GObject *object, guint property_id, GValue *value, G
 	priv = backend->priv;
 
 	switch (property_id) {
-	case PROP_SOURCE:
-		g_value_set_object (value, e_cal_backend_get_source (backend));
-		break;
-	case PROP_URI:
-		g_value_set_string (value, e_cal_backend_get_uri (backend));
-		break;
 	case PROP_KIND:
 		g_value_set_ulong (value, e_cal_backend_get_kind (backend));
 		break;
@@ -188,27 +105,50 @@ e_cal_backend_get_property (GObject *object, guint property_id, GValue *value, G
 	}
 }
 
+static void
+e_cal_backend_set_mode_from_data_mode (ECalBackend *backend,
+				       EDataMode    mode)
+{
+	CalMode real_mode = CAL_MODE_ANY;
+
+	g_return_if_fail (E_IS_CAL_BACKEND (backend));
+
+	switch (mode) {
+		case E_DATA_MODE_LOCAL:
+			real_mode = CAL_MODE_LOCAL;
+			break;
+		case E_DATA_MODE_REMOTE:
+			real_mode = CAL_MODE_REMOTE;
+			break;
+		case E_DATA_MODE_ANY:
+			real_mode = CAL_MODE_ANY;
+			break;
+		default:
+			g_warning (G_STRLOC ": unsupported EDataMode: %d; using 'any'", mode);
+	}
+
+	e_cal_backend_set_mode (backend, real_mode);
+}
+
 /* Class initialization function for the calendar backend */
 static void
-e_cal_backend_class_init (ECalBackendClass *class)
+e_cal_backend_class_init (ECalBackendClass *klass)
 {
 	GObjectClass *object_class;
+	EBackendClass *parent_class;
+
+	parent_class = E_BACKEND_CLASS (klass);
 
-	object_class = (GObjectClass *) class;
+	object_class = (GObjectClass *) klass;
 
 	object_class->set_property = e_cal_backend_set_property;
 	object_class->get_property = e_cal_backend_get_property;
-	object_class->finalize = e_cal_backend_finalize;
 
-	g_object_class_install_property (object_class, PROP_SOURCE,
-					 g_param_spec_object ("source", NULL, NULL, E_TYPE_SOURCE,
-							      G_PARAM_READABLE | G_PARAM_WRITABLE
-							      | G_PARAM_CONSTRUCT_ONLY));
-
-	g_object_class_install_property (object_class, PROP_URI,
-					 g_param_spec_string ("uri", NULL, NULL, "",
-							      G_PARAM_READABLE | G_PARAM_WRITABLE
-							      | G_PARAM_CONSTRUCT_ONLY));
+        /* XXX: do some ugly casting to avoid breaking API */
+        parent_class->set_mode = (void (*)(EBackend*, EDataMode)) e_cal_backend_set_mode_from_data_mode;
+        parent_class->add_client = (gboolean (*)(EBackend*, EData*)) e_cal_backend_add_client;
+        parent_class->remove_client = (void (*)(EBackend*, EData*)) e_cal_backend_remove_client;
+        parent_class->is_loaded = (gboolean (*)(EBackend*)) e_cal_backend_is_loaded;
 
 	g_object_class_install_property (object_class, PROP_KIND,
 					 g_param_spec_ulong ("kind", NULL, NULL,
@@ -217,16 +157,10 @@ e_cal_backend_class_init (ECalBackendClass *class)
 							     G_PARAM_READABLE | G_PARAM_WRITABLE
 							     | G_PARAM_CONSTRUCT_ONLY));
 	e_cal_backend_signals[LAST_CLIENT_GONE] =
-		g_signal_new ("last_client_gone",
-			      G_TYPE_FROM_CLASS (class),
-			      G_SIGNAL_RUN_FIRST,
-			      G_STRUCT_OFFSET (ECalBackendClass, last_client_gone),
-			      NULL, NULL,
-			      g_cclosure_marshal_VOID__VOID,
-			      G_TYPE_NONE, 0);
+		g_signal_lookup ("last_client_gone", E_TYPE_BACKEND);
 	e_cal_backend_signals[OPENED] =
 		g_signal_new ("opened",
-			      G_TYPE_FROM_CLASS (class),
+			      G_TYPE_FROM_CLASS (klass),
 			      G_SIGNAL_RUN_FIRST,
 			      G_STRUCT_OFFSET (ECalBackendClass, opened),
 			      NULL, NULL,
@@ -235,7 +169,7 @@ e_cal_backend_class_init (ECalBackendClass *class)
 			      G_TYPE_INT);
 	e_cal_backend_signals[REMOVED] =
 		g_signal_new ("removed",
-			      G_TYPE_FROM_CLASS (class),
+			      G_TYPE_FROM_CLASS (klass),
 			      G_SIGNAL_RUN_FIRST,
 			      G_STRUCT_OFFSET (ECalBackendClass, removed),
 			      NULL, NULL,
@@ -243,35 +177,7 @@ e_cal_backend_class_init (ECalBackendClass *class)
 			      G_TYPE_NONE, 1,
 			      G_TYPE_INT);
 
-	class->last_client_gone = NULL;
-	class->opened = NULL;
-	class->obj_updated = NULL;
-
-	class->get_cal_address = NULL;
-	class->get_alarm_email_address = NULL;
-	class->get_static_capabilities = NULL;
-	class->open = NULL;
-	class->is_loaded = NULL;
-	class->is_read_only = NULL;
-	class->start_query = NULL;
-	class->get_mode = NULL;
-	class->set_mode = NULL;
-	class->get_object = NULL;
-	class->get_default_object = NULL;
-	class->get_object_list = NULL;
-	class->get_free_busy = NULL;
-	class->get_changes = NULL;
-	class->discard_alarm = NULL;
-	class->create_object = NULL;
-	class->modify_object = NULL;
-	class->remove_object = NULL;
-	class->receive_objects = NULL;
-	class->send_objects = NULL;
-	class->get_timezone = NULL;
-	class->add_timezone = NULL;
-	class->set_default_timezone = NULL;
-
-	g_type_class_add_private (class, sizeof (ECalBackendPrivate));
+	g_type_class_add_private (klass, sizeof (ECalBackendPrivate));
 }
 
 /* Object initialization func for the calendar backend */
@@ -283,41 +189,9 @@ e_cal_backend_init (ECalBackend *backend)
 	priv = E_CAL_BACKEND_GET_PRIVATE (backend);
 	backend->priv = priv;
 
-	priv->clients = NULL;
-	priv->clients_mutex = g_mutex_new ();
 	priv->last_percent_notified = 0;
-
-	priv->queries = e_list_new((EListCopyFunc) g_object_ref, (EListFreeFunc) g_object_unref, NULL);
-	priv->queries_mutex = g_mutex_new ();
-}
-
-static void
-e_cal_backend_finalize (GObject *object)
-{
-	ECalBackend *backend = (ECalBackend *)object;
-	ECalBackendPrivate *priv;
-
-	priv = backend->priv;
-
-	g_assert (priv->clients == NULL);
-
-	g_object_unref (priv->queries);
-
-	g_mutex_free (priv->clients_mutex);
-	g_mutex_free (priv->queries_mutex);
-
-	g_free (priv->uri);
-	if (priv->source_changed_id && priv->source) {
-		g_signal_handler_disconnect (priv->source, priv->source_changed_id);
-		priv->source_changed_id = 0;
-	}
-	g_object_unref (priv->source);
-
-	G_OBJECT_CLASS (e_cal_backend_parent_class)->finalize (object);
 }
 
-
-
 /**
  * e_cal_backend_get_source:
  * @backend: An #ECalBackend object.
@@ -329,14 +203,10 @@ e_cal_backend_finalize (GObject *object)
 ESource *
 e_cal_backend_get_source (ECalBackend *backend)
 {
-	ECalBackendPrivate *priv;
-
 	g_return_val_if_fail (backend != NULL, NULL);
 	g_return_val_if_fail (E_IS_CAL_BACKEND (backend), NULL);
 
-	priv = backend->priv;
-
-	return priv->source;
+	return e_backend_get_source (E_BACKEND (backend));
 }
 
 /**
@@ -351,14 +221,10 @@ e_cal_backend_get_source (ECalBackend *backend)
 const gchar *
 e_cal_backend_get_uri (ECalBackend *backend)
 {
-	ECalBackendPrivate *priv;
-
 	g_return_val_if_fail (backend != NULL, NULL);
 	g_return_val_if_fail (E_IS_CAL_BACKEND (backend), NULL);
 
-	priv = backend->priv;
-
-	return priv->uri;
+	return e_backend_get_uri (E_BACKEND (backend));
 }
 
 /**
@@ -382,12 +248,6 @@ e_cal_backend_get_kind (ECalBackend *backend)
 	return priv->kind;
 }
 
-static void
-last_client_gone (ECalBackend *backend)
-{
-	g_signal_emit (backend, e_cal_backend_signals[LAST_CLIENT_GONE], 0);
-}
-
 /**
  * e_cal_backend_add_client:
  * @backend: An ECalBackend object.
@@ -399,27 +259,7 @@ last_client_gone (ECalBackend *backend)
 void
 e_cal_backend_add_client (ECalBackend *backend, EDataCal *cal)
 {
-	ECalBackendPrivate *priv;
-
-	g_return_if_fail (backend != NULL);
-	g_return_if_fail (E_IS_CAL_BACKEND (backend));
-	g_return_if_fail (cal != NULL);
-	g_return_if_fail (E_IS_DATA_CAL (cal));
-
-	priv = backend->priv;
-
-	/* TODO: Implement this? */
-#if 0
-	bonobo_object_set_immortal (BONOBO_OBJECT (cal), TRUE);
-
-	g_object_weak_ref (G_OBJECT (cal), cal_destroy_cb, backend);
-
-	ORBit_small_listen_for_broken (e_data_cal_get_listener (cal), G_CALLBACK (listener_died_cb), cal);
-#endif
-
-	g_mutex_lock (priv->clients_mutex);
-	priv->clients = g_list_append (priv->clients, cal);
-	g_mutex_unlock (priv->clients_mutex);
+	e_backend_add_client (E_BACKEND (backend), E_DATA (cal));
 }
 
 /**
@@ -432,28 +272,7 @@ e_cal_backend_add_client (ECalBackend *backend, EDataCal *cal)
 void
 e_cal_backend_remove_client (ECalBackend *backend, EDataCal *cal)
 {
-	ECalBackendPrivate *priv;
-
-	/* XXX this needs a bit more thinking wrt the mutex - we
-	   should be holding it when we check to see if clients is
-	   NULL */
-	g_return_if_fail (backend != NULL);
-	g_return_if_fail (E_IS_CAL_BACKEND (backend));
-	g_return_if_fail (cal != NULL);
-	g_return_if_fail (E_IS_DATA_CAL (cal));
-
-	priv = backend->priv;
-
-	/* Disconnect */
-	g_mutex_lock (priv->clients_mutex);
-	priv->clients = g_list_remove (priv->clients, cal);
-	g_mutex_unlock (priv->clients_mutex);
-
-	/* When all clients go away, notify the parent factory about it so that
-	 * it may decide whether to kill the backend or not.
-	 */
-	if (!priv->clients)
-		last_client_gone (backend);
+	e_backend_remove_client (E_BACKEND (backend), E_DATA (cal));
 }
 
 /**
@@ -468,14 +287,10 @@ e_cal_backend_remove_client (ECalBackend *backend, EDataCal *cal)
 void
 e_cal_backend_add_query (ECalBackend *backend, EDataCalView *query)
 {
-	g_return_if_fail (backend != NULL);
 	g_return_if_fail (E_IS_CAL_BACKEND (backend));
+	g_return_if_fail (E_IS_DATA_CAL_VIEW (query));
 
-	g_mutex_lock (backend->priv->queries_mutex);
-
-	e_list_append (backend->priv->queries, query);
-
-	g_mutex_unlock (backend->priv->queries_mutex);
+	e_backend_add_view (E_BACKEND (backend), E_DATA_VIEW (query));
 }
 
 /**
@@ -489,10 +304,9 @@ e_cal_backend_add_query (ECalBackend *backend, EDataCalView *query)
 EList *
 e_cal_backend_get_queries (ECalBackend *backend)
 {
-	g_return_val_if_fail (backend != NULL, NULL);
 	g_return_val_if_fail (E_IS_CAL_BACKEND (backend), NULL);
 
-	return backend->priv->queries;
+	return e_backend_get_views (E_BACKEND (backend));
 }
 
 /**
@@ -505,14 +319,9 @@ e_cal_backend_get_queries (ECalBackend *backend)
 void
 e_cal_backend_remove_query (ECalBackend *backend, EDataCalView *query)
 {
-	g_return_if_fail (backend != NULL);
 	g_return_if_fail (E_IS_CAL_BACKEND (backend));
 
-	g_mutex_lock (backend->priv->queries_mutex);
-
-	e_list_remove (backend->priv->queries, query);
-
-	g_mutex_unlock (backend->priv->queries_mutex);
+	e_backend_remove_view (E_BACKEND (backend), E_DATA_VIEW (query));
 }
 
 /**
@@ -537,6 +346,7 @@ e_cal_backend_notify_readonly (ECalBackend *backend, gboolean read_only)
 {
 	ECalBackendPrivate *priv;
 	GList *l;
+	GMutex *mutex;
 
 	priv = backend->priv;
 
@@ -544,8 +354,14 @@ e_cal_backend_notify_readonly (ECalBackend *backend, gboolean read_only)
 		e_cal_backend_notify_readonly (priv->notification_proxy, read_only);
 		return;
 	}
-	for (l = priv->clients; l; l = l->next)
+
+	mutex = e_backend_get_clients_mutex (E_BACKEND (backend));
+	g_mutex_lock (mutex);
+
+	for (l = e_backend_get_clients (E_BACKEND (backend)); l; l = l->next)
 		e_data_cal_notify_read_only (l->data, GNOME_Evolution_Calendar_Success, read_only);
+
+	g_mutex_unlock (mutex);
 }
 
 void
@@ -553,11 +369,17 @@ e_cal_backend_notify_cal_address (ECalBackend *backend, EServerMethodContext con
 {
 	ECalBackendPrivate *priv;
 	GList *l;
+	GMutex *mutex;
 
 	priv = backend->priv;
 
-	for (l = priv->clients; l; l = l->next)
+	mutex = e_backend_get_clients_mutex (E_BACKEND (backend));
+	g_mutex_lock (mutex);
+
+	for (l = e_backend_get_clients (E_BACKEND (backend)); l; l = l->next)
 		e_data_cal_notify_cal_address (l->data, context, GNOME_Evolution_Calendar_Success, address);
+
+	g_mutex_unlock (mutex);
 }
 
 /**
@@ -1161,6 +983,7 @@ e_cal_backend_notify_object_created (ECalBackend *backend, const gchar *calobj)
 	EList *queries;
 	EIterator *iter;
 	EDataCalView *query;
+	GMutex *mutex;
 
 	priv = backend->priv;
 
@@ -1169,6 +992,9 @@ e_cal_backend_notify_object_created (ECalBackend *backend, const gchar *calobj)
 		return;
 	}
 
+	mutex = e_backend_get_views_mutex (E_BACKEND (backend));
+	g_mutex_lock (mutex);
+
 	queries = e_cal_backend_get_queries (backend);
 	iter = e_list_get_iterator (queries);
 
@@ -1183,6 +1009,9 @@ e_cal_backend_notify_object_created (ECalBackend *backend, const gchar *calobj)
 		e_iterator_next (iter);
 	}
 	g_object_unref (iter);
+	g_object_unref (queries);
+
+	g_mutex_unlock (mutex);
 }
 
 static void
@@ -1245,6 +1074,7 @@ e_cal_backend_notify_view_progress (ECalBackend *backend, const gchar *message,
 	EList *queries;
 	EIterator *iter;
 	EDataCalView *query;
+	GMutex *mutex;
 
 	priv = backend->priv;
 
@@ -1258,6 +1088,9 @@ e_cal_backend_notify_view_progress (ECalBackend *backend, const gchar *message,
 		return;
 	}
 
+	mutex = e_backend_get_views_mutex (E_BACKEND (backend));
+	g_mutex_lock (mutex);
+
 	queries = e_cal_backend_get_queries (backend);
 	iter = e_list_get_iterator (queries);
 
@@ -1273,6 +1106,9 @@ e_cal_backend_notify_view_progress (ECalBackend *backend, const gchar *message,
 		e_iterator_next (iter);
 	}
 	g_object_unref (iter);
+	g_object_unref (queries);
+
+	g_mutex_unlock (mutex);
 }
 
 /**
@@ -1289,6 +1125,7 @@ e_cal_backend_notify_view_done (ECalBackend *backend, GNOME_Evolution_Calendar_C
 	EList *queries;
 	EIterator *iter;
 	EDataCalView *query;
+	GMutex *mutex;
 
 	priv = backend->priv;
 
@@ -1297,6 +1134,9 @@ e_cal_backend_notify_view_done (ECalBackend *backend, GNOME_Evolution_Calendar_C
 		return;
 	}
 
+	mutex = e_backend_get_views_mutex (E_BACKEND (backend));
+	g_mutex_lock (mutex);
+
 	queries = e_cal_backend_get_queries (backend);
 	iter = e_list_get_iterator (queries);
 
@@ -1312,6 +1152,9 @@ e_cal_backend_notify_view_done (ECalBackend *backend, GNOME_Evolution_Calendar_C
 		e_iterator_next (iter);
 	}
 	g_object_unref (iter);
+	g_object_unref (queries);
+
+	g_mutex_unlock (mutex);
 }
 
 /**
@@ -1334,6 +1177,7 @@ e_cal_backend_notify_object_modified (ECalBackend *backend,
 	EList *queries;
 	EIterator *iter;
 	EDataCalView *query;
+	GMutex *mutex;
 
 	priv = backend->priv;
 
@@ -1342,6 +1186,9 @@ e_cal_backend_notify_object_modified (ECalBackend *backend,
 		return;
 	}
 
+	mutex = e_backend_get_views_mutex (E_BACKEND (backend));
+	g_mutex_lock (mutex);
+
 	queries = e_cal_backend_get_queries (backend);
 	iter = e_list_get_iterator (queries);
 
@@ -1355,6 +1202,9 @@ e_cal_backend_notify_object_modified (ECalBackend *backend,
 		e_iterator_next (iter);
 	}
 	g_object_unref (iter);
+	g_object_unref (queries);
+
+	g_mutex_unlock (mutex);
 }
 
 /**
@@ -1380,6 +1230,7 @@ e_cal_backend_notify_object_removed (ECalBackend *backend, const ECalComponentId
 	EList *queries;
 	EIterator *iter;
 	EDataCalView *query;
+	GMutex *mutex;
 
 	priv = backend->priv;
 
@@ -1388,6 +1239,9 @@ e_cal_backend_notify_object_removed (ECalBackend *backend, const ECalComponentId
 		return;
 	}
 
+	mutex = e_backend_get_views_mutex (E_BACKEND (backend));
+	g_mutex_lock (mutex);
+
 	queries = e_cal_backend_get_queries (backend);
 	iter = e_list_get_iterator (queries);
 
@@ -1409,6 +1263,9 @@ e_cal_backend_notify_object_removed (ECalBackend *backend, const ECalComponentId
 		e_iterator_next (iter);
 	}
 	g_object_unref (iter);
+	g_object_unref (queries);
+
+	g_mutex_unlock (mutex);
 }
 
 void
@@ -1445,14 +1302,20 @@ e_cal_backend_notify_mode (ECalBackend *backend,
 {
 	ECalBackendPrivate *priv = backend->priv;
 	GList *l;
+	GMutex *mutex;
 
 	if (priv->notification_proxy) {
 		e_cal_backend_notify_mode (priv->notification_proxy, status, mode);
 		return;
 	}
 
-	for (l = priv->clients; l; l = l->next)
+	mutex = e_backend_get_clients_mutex (E_BACKEND (backend));
+	g_mutex_lock (mutex);
+
+	for (l = e_backend_get_clients (E_BACKEND (backend)); l; l = l->next)
 		e_data_cal_notify_mode (l->data, status, mode);
+
+	g_mutex_unlock (mutex);
 }
 
 /**
@@ -1465,11 +1328,16 @@ e_cal_backend_notify_mode (ECalBackend *backend,
 void
 e_cal_backend_notify_auth_required (ECalBackend *backend)
 {
-        ECalBackendPrivate *priv = backend->priv;
         GList *l;
+	GMutex *mutex;
+
+	mutex = e_backend_get_clients_mutex (E_BACKEND (backend));
+	g_mutex_lock (mutex);
 
-        for (l = priv->clients; l; l = l->next)
+	for (l = e_backend_get_clients (E_BACKEND (backend)); l; l = l->next)
                 e_data_cal_notify_auth_required (l->data);
+
+	g_mutex_unlock (mutex);
 }
 
 /**
@@ -1484,14 +1352,20 @@ e_cal_backend_notify_error (ECalBackend *backend, const gchar *message)
 {
 	ECalBackendPrivate *priv = backend->priv;
 	GList *l;
+	GMutex *mutex;
 
 	if (priv->notification_proxy) {
 		e_cal_backend_notify_error (priv->notification_proxy, message);
 		return;
 	}
 
-	for (l = priv->clients; l; l = l->next)
+	mutex = e_backend_get_clients_mutex (E_BACKEND (backend));
+	g_mutex_lock (mutex);
+
+	for (l = e_backend_get_clients (E_BACKEND (backend)); l; l = l->next)
 		e_data_cal_notify_error (l->data, message);
+
+	g_mutex_unlock (mutex);
 }
 
 /**
diff --git a/calendar/libedata-cal/e-cal-backend.h b/calendar/libedata-cal/e-cal-backend.h
index a10077e..f215255 100644
--- a/calendar/libedata-cal/e-cal-backend.h
+++ b/calendar/libedata-cal/e-cal-backend.h
@@ -23,8 +23,9 @@
 #ifndef E_CAL_BACKEND_H
 #define E_CAL_BACKEND_H
 
-#include "libedataserver/e-list.h"
-#include "libedataserver/e-source.h"
+#include <libedataserver/e-list.h>
+#include <libedataserver/e-source.h>
+#include <libebackend/e-backend.h>
 #include <libecal/e-cal-util.h>
 #include <libecal/e-cal-component.h>
 #include "e-data-cal-common.h"
@@ -34,8 +35,6 @@
 
 G_BEGIN_DECLS
 
-
-
 #define E_TYPE_CAL_BACKEND            (e_cal_backend_get_type ())
 #define E_CAL_BACKEND(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_CAL_BACKEND, ECalBackend))
 #define E_CAL_BACKEND_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_CAL_BACKEND,		\
@@ -49,13 +48,13 @@ struct _ECalBackendCache;
 typedef struct _ECalBackendPrivate ECalBackendPrivate;
 
 struct _ECalBackend {
-	GObject object;
+	EBackend object;
 
 	ECalBackendPrivate *priv;
 };
 
 struct _ECalBackendClass {
-	GObjectClass parent_class;
+	EBackendClass parent_class;
 
 	/* Notification signals */
 	void (* last_client_gone) (ECalBackend *backend);
diff --git a/calendar/libedata-cal/e-data-cal-view.c b/calendar/libedata-cal/e-data-cal-view.c
index 14174f5..0120fc8 100644
--- a/calendar/libedata-cal/e-data-cal-view.c
+++ b/calendar/libedata-cal/e-data-cal-view.c
@@ -32,6 +32,7 @@
 #include <dbus/dbus-glib.h>
 #include <glib-object.h>
 
+#include <libebackend/e-data-view.h>
 #include "e-cal-backend-sexp.h"
 #include "e-data-cal-view.h"
 #include "e-data-cal-marshal.h"
@@ -44,39 +45,21 @@ static gboolean impl_EDataCalView_start (EDataCalView *query, GError **error);
 #define THRESHOLD 32
 
 struct _EDataCalViewPrivate {
-	/* The backend we are monitoring */
-	ECalBackend *backend;
-
 	gboolean started;
 	gboolean done;
 	EDataCalCallStatus done_status;
 
-	/* Sexp that defines the query */
-	ECalBackendSExp *sexp;
-
 	GArray *adds;
 	GArray *changes;
 	GArray *removes;
 
 	GHashTable *ids;
-
-	gchar *path;
 };
 
-G_DEFINE_TYPE (EDataCalView, e_data_cal_view, G_TYPE_OBJECT);
+G_DEFINE_TYPE (EDataCalView, e_data_cal_view, E_TYPE_DATA_VIEW);
 #define E_DATA_CAL_VIEW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), E_DATA_CAL_VIEW_TYPE, EDataCalViewPrivate))
 
-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 {
-	PROP_0,
-	PROP_BACKEND,
-	PROP_SEXP
-};
 
 /* Signals */
 enum {
@@ -90,26 +73,24 @@ enum {
 
 static guint signals[LAST_SIGNAL] = { 0 };
 
+static void
+e_data_cal_view_stop_if_running (EDataCalView *query)
+{
+	/* Nothing for us to do here */
+}
+
 /* Class init */
 static void
 e_data_cal_view_class_init (EDataCalViewClass *klass)
 {
-	GParamSpec *param;
 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	EDataViewClass *parent_class = E_DATA_VIEW_CLASS (klass);
 
 	g_type_class_add_private (klass, 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;
 
-	param =  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_BACKEND, param);
-	param =  g_param_spec_object ("sexp", NULL, NULL, E_TYPE_CAL_BACKEND_SEXP,
-				      G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY);
-	g_object_class_install_property (object_class, PROP_SEXP, param);
+	parent_class->stop_if_running = (void (*)(EDataView*)) e_data_cal_view_stop_if_running;
 
         signals[OBJECTS_ADDED] =
           g_signal_new ("objects-added",
@@ -176,12 +157,10 @@ e_data_cal_view_init (EDataCalView *view)
 
 	view->priv = priv;
 
-	priv->backend = NULL;
 	priv->started = FALSE;
 	priv->done = FALSE;
 	priv->done_status = Success;
 	priv->started = FALSE;
-	priv->sexp = NULL;
 
 	priv->adds = g_array_sized_new (TRUE, TRUE, sizeof (gchar *), THRESHOLD);
 	priv->changes = g_array_sized_new (TRUE, TRUE, sizeof (gchar *), THRESHOLD);
@@ -191,15 +170,22 @@ e_data_cal_view_init (EDataCalView *view)
 }
 
 EDataCalView *
-e_data_cal_view_new (ECalBackend *backend,
-		     const gchar *path, ECalBackendSExp *sexp)
+e_data_cal_view_new (ECalBackend     *backend,
+		     const gchar     *path,
+		     ECalBackendSExp *sexp)
 {
 	EDataCalView *query;
 
-	query = g_object_new (E_DATA_CAL_VIEW_TYPE, "backend", backend, "sexp", sexp, NULL);
-	query->priv->path = g_strdup (path);
-
-	dbus_g_connection_register_g_object (connection, path, G_OBJECT (query));
+	/* XXX: ideally we would pass an EDataCal for "data" here and remove the
+	 * "backend" property from EDataView, since it can be derived from the
+	 * "data" value (but it would require another argument to this function,
+	 * breaking API stability) */
+	query = g_object_new (E_DATA_CAL_VIEW_TYPE,
+			"data", NULL,
+			"dbus-path", path,
+			"backend", backend,
+			"sexp", sexp,
+			NULL);
 
 	return query;
 }
@@ -209,7 +195,7 @@ e_data_cal_view_get_dbus_path (EDataCalView *view)
 {
 	g_return_val_if_fail (E_IS_DATA_CAL_VIEW (view), NULL);
 
-	return view->priv->path;
+	return e_data_view_get_dbus_path (E_DATA_VIEW (view));
 }
 
 static void
@@ -334,82 +320,13 @@ impl_EDataCalView_start (EDataCalView *query, GError **error)
 
 	if (!priv->started) {
 		priv->started = TRUE;
-		e_cal_backend_start_query (priv->backend, query);
+		e_cal_backend_start_query (e_data_cal_view_get_backend (query), query);
 	}
 
 	return TRUE;
 }
 
 static void
-e_data_cal_view_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
-{
-	EDataCalView *query;
-	EDataCalViewPrivate *priv;
-
-	query = QUERY (object);
-	priv = query->priv;
-
-	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;
-	}
-}
-
-static void
-e_data_cal_view_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
-{
-	EDataCalView *query;
-	EDataCalViewPrivate *priv;
-
-	query = QUERY (object);
-	priv = query->priv;
-
-	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;
-	}
-}
-
-static void
-e_data_cal_view_dispose (GObject *object)
-{
-	EDataCalView *query;
-	EDataCalViewPrivate *priv;
-
-	g_return_if_fail (object != NULL);
-	g_return_if_fail (IS_QUERY (object));
-
-	query = QUERY (object);
-	priv = query->priv;
-
-	if (priv->backend) {
-		g_object_unref (priv->backend);
-		priv->backend = NULL;
-	}
-
-	if (priv->sexp) {
-		g_object_unref (priv->sexp);
-		priv->sexp = NULL;
-	}
-
-	(* G_OBJECT_CLASS (e_data_cal_view_parent_class)->dispose) (object);
-}
-
-static void
 e_data_cal_view_finalize (GObject *object)
 {
 	EDataCalView *query;
@@ -423,25 +340,23 @@ e_data_cal_view_finalize (GObject *object)
 
 	g_hash_table_destroy (priv->ids);
 
-	g_free (priv->path);
-
 	(* G_OBJECT_CLASS (e_data_cal_view_parent_class)->finalize) (object);
 }
 
 /**
- * e_data_cal_view_get_text:
- * @query: A #EDataCalView object.
+ * e_data_cal_view_get_backend:
+ * @query: A query object.
  *
- * Get the expression used for the given query.
+ * Get the #ECalBackend object used for the given query.
  *
- * Return value: the query expression used to search.
+ * Return value: The #ECalBackend backend.
  */
-const gchar *
-e_data_cal_view_get_text (EDataCalView *query)
+ECalBackend *
+e_data_cal_view_get_backend (EDataCalView *query)
 {
 	g_return_val_if_fail (IS_QUERY (query), NULL);
 
-	return e_cal_backend_sexp_text (query->priv->sexp);
+	return E_CAL_BACKEND (e_data_view_get_backend (E_DATA_VIEW (query)));
 }
 
 /**
@@ -457,7 +372,27 @@ e_data_cal_view_get_object_sexp (EDataCalView *query)
 {
 	g_return_val_if_fail (IS_QUERY (query), NULL);
 
-	return query->priv->sexp;
+	return E_CAL_BACKEND_SEXP (e_data_view_get_sexp (E_DATA_VIEW (query)));
+}
+
+/**
+ * e_data_cal_view_get_text:
+ * @query: A #EDataCalView object.
+ *
+ * Get the expression used for the given query.
+ *
+ * Return value: the query expression used to search.
+ */
+const gchar *
+e_data_cal_view_get_text (EDataCalView *query)
+{
+	ECalBackendSExp *sexp;
+
+	g_return_val_if_fail (IS_QUERY (query), NULL);
+
+	sexp = e_data_cal_view_get_object_sexp (query);
+
+	return e_cal_backend_sexp_text (sexp);
 }
 
 /**
@@ -473,15 +408,17 @@ e_data_cal_view_get_object_sexp (EDataCalView *query)
 gboolean
 e_data_cal_view_object_matches (EDataCalView *query, const gchar *object)
 {
-	EDataCalViewPrivate *priv;
+	ECalBackend *backend;
+	ECalBackendSExp *sexp;
 
 	g_return_val_if_fail (query != NULL, FALSE);
 	g_return_val_if_fail (IS_QUERY (query), FALSE);
 	g_return_val_if_fail (object != NULL, FALSE);
 
-	priv = query->priv;
+	backend = e_data_cal_view_get_backend (query);
+	sexp = e_data_cal_view_get_object_sexp (query);
 
-	return e_cal_backend_sexp_match_object (priv->sexp, object, priv->backend);
+	return e_cal_backend_sexp_match_object (sexp, object, backend);
 }
 
 /**
diff --git a/calendar/libedata-cal/e-data-cal-view.h b/calendar/libedata-cal/e-data-cal-view.h
index 911b4f0..08a2362 100644
--- a/calendar/libedata-cal/e-data-cal-view.h
+++ b/calendar/libedata-cal/e-data-cal-view.h
@@ -27,11 +27,10 @@
 #include <libedata-cal/e-data-cal-common.h>
 #include <libedata-cal/e-cal-backend-sexp.h>
 #include <libedata-cal/e-data-cal-types.h>
+#include <libebackend/e-data-view.h>
 
 G_BEGIN_DECLS
 
-
-
 #define E_DATA_CAL_VIEW_TYPE            (e_data_cal_view_get_type ())
 #define E_DATA_CAL_VIEW(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_DATA_CAL_VIEW_TYPE, EDataCalView))
 #define E_DATA_CAL_VIEW_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), E_DATA_CAL_VIEW_TYPE, EDataCalViewClass))
@@ -43,12 +42,12 @@ G_BEGIN_DECLS
 typedef struct _EDataCalViewPrivate EDataCalViewPrivate;
 
 struct _EDataCalView {
-	GObject parent;
+	EDataView parent;
 	EDataCalViewPrivate *priv;
 };
 
 struct _EDataCalViewClass {
-	GObjectClass parent_class;
+	EDataViewClass parent_class;
 };
 
 GType                 e_data_cal_view_get_type (void);
@@ -56,6 +55,7 @@ EDataCalView         *e_data_cal_view_new (ECalBackend *backend, const gchar *pa
 
 const gchar * e_data_cal_view_get_dbus_path (EDataCalView *view);
 
+ECalBackend*		e_data_cal_view_get_backend (EDataCalView *query);
 const gchar           *e_data_cal_view_get_text (EDataCalView *query);
 ECalBackendSExp      *e_data_cal_view_get_object_sexp (EDataCalView *query);
 gboolean              e_data_cal_view_object_matches (EDataCalView *query, const gchar *object);
diff --git a/calendar/libedata-cal/e-data-cal.c b/calendar/libedata-cal/e-data-cal.c
index 86f0066..ffc8ea5 100644
--- a/calendar/libedata-cal/e-data-cal.c
+++ b/calendar/libedata-cal/e-data-cal.c
@@ -33,6 +33,7 @@
 #include <dbus/dbus.h>
 #include <dbus/dbus-glib.h>
 #include <glib-object.h>
+#include <libebackend/e-data.h>
 
 #include "e-data-cal.h"
 #include "e-data-cal-enumtypes.h"
@@ -80,14 +81,11 @@ enum
 
 static guint signals[LAST_SIGNAL] = { 0 };
 
-G_DEFINE_TYPE (EDataCal, e_data_cal, G_TYPE_OBJECT);
+G_DEFINE_TYPE (EDataCal, e_data_cal, E_TYPE_DATA);
 
 #define E_DATA_CAL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), E_TYPE_DATA_CAL, EDataCalPrivate))
 
 struct _EDataCalPrivate {
-	ECalBackend *backend;
-	ESource *source;
-	GHashTable *live_queries;
 };
 
 /* Create the EDataCal error quark */
@@ -100,22 +98,32 @@ e_data_cal_error_quark (void)
   return quark;
 }
 
+ECalBackend*
+e_data_cal_get_backend (EDataCal *cal)
+{
+	g_return_val_if_fail (E_IS_DATA_CAL (cal), NULL);
+
+	return E_CAL_BACKEND (e_data_get_backend (E_DATA (cal)));
+}
+
+ESource*
+e_data_cal_get_source (EDataCal *cal)
+{
+	g_return_val_if_fail (E_IS_DATA_CAL (cal), NULL);
+
+	return e_data_get_source (E_DATA (cal));
+}
+
 /* Class init */
 static void
 e_data_cal_class_init (EDataCalClass *e_data_cal_class)
 {
-	/* TODO: finalise dispose */
+	EDataClass *data_class = E_DATA_CLASS (e_data_cal_class);
 
-	g_type_class_add_private (e_data_cal_class, sizeof (EDataCalPrivate));
+	data_class->get_backend = (EBackend* (*)(EData*)) e_data_cal_get_backend;
+	data_class->get_source =  (ESource* (*)(EData*)) e_data_cal_get_source;
 
-	signals[AUTH_REQUIRED] =
-	  g_signal_new ("auth-required",
-						G_OBJECT_CLASS_TYPE (e_data_cal_class),
-						G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
-						0,
-						NULL, NULL,
-						g_cclosure_marshal_VOID__VOID,
-						G_TYPE_NONE, 0);
+	signals[AUTH_REQUIRED] = g_signal_lookup ("auth-required", E_TYPE_DATA);
 	signals[BACKEND_ERROR] =
 	  g_signal_new ("backend-error",
 						G_OBJECT_CLASS_TYPE (e_data_cal_class),
@@ -150,36 +158,26 @@ e_data_cal_class_init (EDataCalClass *e_data_cal_class)
 static void
 e_data_cal_init (EDataCal *ecal)
 {
-	ecal->priv = E_DATA_CAL_GET_PRIVATE (ecal);
 }
 
 EDataCal *
 e_data_cal_new (ECalBackend *backend, ESource *source)
 {
 	EDataCal *cal;
-	cal = g_object_new (E_TYPE_DATA_CAL, NULL);
-	cal->priv->backend = backend;
-	cal->priv->source = source;
-	return cal;
-}
 
-ESource*
-e_data_cal_get_source (EDataCal *cal)
-{
-  return cal->priv->source;
-}
+	cal = g_object_new (E_TYPE_DATA_CAL, "backend", backend, "source", source, NULL);
 
-ECalBackend*
-e_data_cal_get_backend (EDataCal *cal)
-{
-  return cal->priv->backend;
+	return cal;
 }
 
 /* EDataCal::getUri method */
 static void
 impl_Cal_get_uri (EDataCal *cal, DBusGMethodInvocation *context)
 {
-	dbus_g_method_return (context, g_strdup (e_cal_backend_get_uri (cal->priv->backend)));
+	gchar *uri;
+
+	uri = g_strdup (e_cal_backend_get_uri (e_data_cal_get_backend (cal)));
+	dbus_g_method_return (context, uri);
 }
 
 /* EDataCal::open method */
@@ -189,14 +187,14 @@ impl_Cal_open (EDataCal *cal,
 	       gchar *username,
 	       gchar *password, DBusGMethodInvocation *context)
 {
-	e_cal_backend_open (cal->priv->backend, cal, context, only_if_exists, username, password);
+	e_cal_backend_open (e_data_cal_get_backend (cal), cal, context, only_if_exists, username, password);
 }
 
 /* EDataCal::close method */
 static gboolean
 impl_Cal_close (EDataCal *cal, GError **error)
 {
-	e_cal_backend_remove_client (cal->priv->backend, cal);
+	e_cal_backend_remove_client (e_data_cal_get_backend (cal), cal);
 	g_object_unref (cal);
 	return TRUE;
 }
@@ -205,21 +203,21 @@ impl_Cal_close (EDataCal *cal, GError **error)
 static void
 impl_Cal_refresh (EDataCal *cal, DBusGMethodInvocation *context)
 {
-	e_cal_backend_refresh (cal->priv->backend, cal, context);
+	e_cal_backend_refresh (e_data_cal_get_backend (cal), cal, context);
 }
 
 /* EDataCal::remove method */
 static void
 impl_Cal_remove (EDataCal *cal, DBusGMethodInvocation *context)
 {
-	e_cal_backend_remove (cal->priv->backend, cal, context);
+	e_cal_backend_remove (e_data_cal_get_backend (cal), cal, context);
 }
 
 /* EDataCal::isReadOnly method */
 static void
 impl_Cal_isReadOnly (EDataCal *cal, DBusGMethodInvocation *context)
 {
-	e_cal_backend_is_read_only (cal->priv->backend, cal);
+	e_cal_backend_is_read_only (e_data_cal_get_backend (cal), cal);
 	dbus_g_method_return (context);
 }
 
@@ -227,28 +225,28 @@ impl_Cal_isReadOnly (EDataCal *cal, DBusGMethodInvocation *context)
 static void
 impl_Cal_getCalAddress (EDataCal *cal, DBusGMethodInvocation *context)
 {
-	e_cal_backend_get_cal_address (cal->priv->backend, cal, context);
+	e_cal_backend_get_cal_address (e_data_cal_get_backend (cal), cal, context);
 }
 
 /* EDataCal::getAlarmEmailAddress method */
 static void
 impl_Cal_getAlarmEmailAddress (EDataCal *cal, DBusGMethodInvocation *context)
 {
-	e_cal_backend_get_alarm_email_address (cal->priv->backend, cal, context);
+	e_cal_backend_get_alarm_email_address (e_data_cal_get_backend (cal), cal, context);
 }
 
 /* EDataCal::getLdapAttribute method */
 static void
 impl_Cal_getLdapAttribute (EDataCal *cal, DBusGMethodInvocation *context)
 {
-	e_cal_backend_get_ldap_attribute (cal->priv->backend, cal, context);
+	e_cal_backend_get_ldap_attribute (e_data_cal_get_backend (cal), cal, context);
 }
 
 /* EDataCal::getSchedulingInformation method */
 static void
 impl_Cal_getStaticCapabilities (EDataCal *cal, DBusGMethodInvocation *context)
 {
-	e_cal_backend_get_static_capabilities (cal->priv->backend, cal, context);
+	e_cal_backend_get_static_capabilities (e_data_cal_get_backend (cal), cal, context);
 }
 
 /* EDataCal::setMode method */
@@ -257,7 +255,7 @@ impl_Cal_setMode (EDataCal *cal,
 		  EDataCalMode mode,
 		  DBusGMethodInvocation *context)
 {
-	e_cal_backend_set_mode (cal->priv->backend, mode);
+	e_cal_backend_set_mode (e_data_cal_get_backend (cal), mode);
 	dbus_g_method_return (context);
 }
 
@@ -265,7 +263,7 @@ impl_Cal_setMode (EDataCal *cal,
 static void
 impl_Cal_getDefaultObject (EDataCal *cal, DBusGMethodInvocation *context)
 {
-	e_cal_backend_get_default_object (cal->priv->backend, cal, context);
+	e_cal_backend_get_default_object (e_data_cal_get_backend (cal), cal, context);
 }
 
 /* EDataCal::getObject method */
@@ -275,7 +273,7 @@ impl_Cal_getObject (EDataCal *cal,
 		    const gchar *rid,
 		    DBusGMethodInvocation *context)
 {
-	e_cal_backend_get_object (cal->priv->backend, cal, context, uid, rid);
+	e_cal_backend_get_object (e_data_cal_get_backend (cal), cal, context, uid, rid);
 }
 
 /* EDataCal::getObjectList method */
@@ -284,7 +282,7 @@ impl_Cal_getObjectList (EDataCal *cal,
 			const gchar *sexp,
 			DBusGMethodInvocation *context)
 {
-		e_cal_backend_get_object_list (cal->priv->backend, cal, context, sexp);
+		e_cal_backend_get_object_list (e_data_cal_get_backend (cal), cal, context, sexp);
 }
 
 /* EDataCal::getChanges method */
@@ -293,7 +291,7 @@ impl_Cal_getChanges (EDataCal *cal,
 		     const gchar *change_id,
 		     DBusGMethodInvocation *context)
 {
-       e_cal_backend_get_changes (cal->priv->backend, cal, context, change_id);
+       e_cal_backend_get_changes (e_data_cal_get_backend (cal), cal, context, change_id);
 }
 
 /* EDataCal::getFreeBusy method */
@@ -314,7 +312,7 @@ impl_Cal_getFreeBusy (EDataCal *cal,
 	}
 
 	/* call the backend's get_free_busy method */
-	e_cal_backend_get_free_busy (cal->priv->backend, cal, context, users, (time_t)start, (time_t)end);
+	e_cal_backend_get_free_busy (e_data_cal_get_backend (cal), cal, context, users, (time_t)start, (time_t)end);
 }
 
 /* EDataCal::discardAlarm method */
@@ -324,7 +322,7 @@ impl_Cal_discardAlarm (EDataCal *cal,
 		       const gchar *auid,
 		       DBusGMethodInvocation *context)
 {
-	e_cal_backend_discard_alarm (cal->priv->backend, cal, context, uid, auid);
+	e_cal_backend_discard_alarm (e_data_cal_get_backend (cal), cal, context, uid, auid);
 }
 
 /* EDataCal::createObject method */
@@ -333,7 +331,7 @@ impl_Cal_createObject (EDataCal *cal,
 		       const gchar *calobj,
 		       DBusGMethodInvocation *context)
 {
-	e_cal_backend_create_object (cal->priv->backend, cal, context, calobj);
+	e_cal_backend_create_object (e_data_cal_get_backend (cal), cal, context, calobj);
 }
 
 /* EDataCal::modifyObject method */
@@ -343,7 +341,7 @@ impl_Cal_modifyObject (EDataCal *cal,
 		       const EDataCalObjModType mod,
 		       DBusGMethodInvocation *context)
 {
-	e_cal_backend_modify_object (cal->priv->backend, cal, context, calobj, mod);
+	e_cal_backend_modify_object (e_data_cal_get_backend (cal), cal, context, calobj, mod);
 }
 
 /* EDataCal::removeObject method */
@@ -357,7 +355,7 @@ impl_Cal_removeObject (EDataCal *cal,
 	if (rid[0] == '\0')
 		rid = NULL;
 
-	e_cal_backend_remove_object (cal->priv->backend, cal, context, uid, rid, mod);
+	e_cal_backend_remove_object (e_data_cal_get_backend (cal), cal, context, uid, rid, mod);
 }
 
 /* EDataCal::receiveObjects method */
@@ -366,7 +364,7 @@ impl_Cal_receiveObjects (EDataCal *cal,
 			 const gchar *calobj,
 			 DBusGMethodInvocation *context)
 {
-	e_cal_backend_receive_objects (cal->priv->backend, cal, context, calobj);
+	e_cal_backend_receive_objects (e_data_cal_get_backend (cal), cal, context, calobj);
 }
 
 /* EDataCal::sendObjects method */
@@ -375,7 +373,7 @@ impl_Cal_sendObjects (EDataCal *cal,
 		      const gchar *calobj,
 		      DBusGMethodInvocation *context)
 {
-	e_cal_backend_send_objects (cal->priv->backend, cal, context, calobj);
+	e_cal_backend_send_objects (e_data_cal_get_backend (cal), cal, context, calobj);
 }
 
 /* EDataCal::getAttachmentList method */
@@ -385,7 +383,7 @@ impl_Cal_getAttachmentList (EDataCal *cal,
                    gchar *rid,
                    DBusGMethodInvocation *context)
 {
-	e_cal_backend_get_attachment_list (cal->priv->backend, cal, context, uid, rid);
+	e_cal_backend_get_attachment_list (e_data_cal_get_backend (cal), cal, context, uid, rid);
 }
 
 /* Function to get a new EDataCalView path, used by getQuery below */
@@ -417,14 +415,14 @@ impl_Cal_getQuery (EDataCal *cal,
 	}
 
 	path = construct_calview_path ();
-	query = e_data_cal_view_new (cal->priv->backend, path, obj_sexp);
+	query = e_data_cal_view_new (e_data_cal_get_backend (cal), path, obj_sexp);
 	if (!query) {
 		g_object_unref (obj_sexp);
 		e_data_cal_notify_query (cal, context, OtherError, NULL);
 		return;
 	}
 
-	e_cal_backend_add_query (cal->priv->backend, query);
+	e_cal_backend_add_query (e_data_cal_get_backend (cal), query);
 
 	e_data_cal_notify_query (cal, context, Success, path);
 
@@ -437,7 +435,7 @@ impl_Cal_getTimezone (EDataCal *cal,
 		      const gchar *tzid,
 		      DBusGMethodInvocation *context)
 {
-	e_cal_backend_get_timezone (cal->priv->backend, cal, context, tzid);
+	e_cal_backend_get_timezone (e_data_cal_get_backend (cal), cal, context, tzid);
 }
 
 /* EDataCal::addTimezone method */
@@ -446,7 +444,7 @@ impl_Cal_addTimezone (EDataCal *cal,
 		      const gchar *tz,
 		      DBusGMethodInvocation *context)
 {
-	e_cal_backend_add_timezone (cal->priv->backend, cal, context, tz);
+	e_cal_backend_add_timezone (e_data_cal_get_backend (cal), cal, context, tz);
 }
 
 /* EDataCal::setDefaultTimezone method */
@@ -455,9 +453,13 @@ impl_Cal_setDefaultTimezone (EDataCal *cal,
 			     const gchar *tz,
 			     DBusGMethodInvocation *context)
 {
-	e_cal_backend_set_default_zone (cal->priv->backend, cal, context, tz);
+	e_cal_backend_set_default_zone (e_data_cal_get_backend (cal), cal, context, tz);
 }
 
+/* XXX: this would be better as a (static) handler for a signal on ECalBackend
+ * that announces it's read-only (or even better, writable; it's best to assume
+ * least capability until told otherwise). This would be an incompatible break,
+ * though, since it changes the required conventions for any dependent code */
 /**
  * e_data_cal_notify_read_only:
  * @cal: A calendar client interface.
@@ -614,7 +616,7 @@ e_data_cal_notify_object_created (EDataCal *cal, EServerMethodContext context, E
 	if (status != Success) {
 		dbus_g_method_return_error (method, g_error_new (E_DATA_CAL_ERROR, status, _("Cannot create calendar object")));
 	} else {
-		e_cal_backend_notify_object_created (cal->priv->backend, object);
+		e_cal_backend_notify_object_created (e_data_cal_get_backend (cal), object);
 		dbus_g_method_return (method, uid ? uid : "");
 	}
 }
@@ -636,7 +638,7 @@ e_data_cal_notify_object_modified (EDataCal *cal, EServerMethodContext context,
 	if (status != Success) {
 		dbus_g_method_return_error (method, g_error_new (E_DATA_CAL_ERROR, status, _("Cannot modify calender object")));
 	} else {
-		e_cal_backend_notify_object_modified (cal->priv->backend, old_object, object);
+		e_cal_backend_notify_object_modified (e_data_cal_get_backend (cal), old_object, object);
 		dbus_g_method_return (method);
 	}
 }
@@ -660,7 +662,7 @@ e_data_cal_notify_object_removed (EDataCal *cal, EServerMethodContext context, E
 	if (status != Success) {
 		dbus_g_method_return_error (method, g_error_new (E_DATA_CAL_ERROR, status, _("Cannot remove calendar object")));
 	} else {
-		e_cal_backend_notify_object_removed (cal->priv->backend, id, old_object, object);
+		e_cal_backend_notify_object_removed (e_data_cal_get_backend (cal), id, old_object, object);
 		dbus_g_method_return (method);
 	}
 }
@@ -1015,7 +1017,7 @@ e_data_cal_notify_auth_required (EDataCal *cal)
 	g_return_if_fail (cal != NULL);
 	g_return_if_fail (E_IS_DATA_CAL (cal));
 
-	g_signal_emit (cal, signals[AUTH_REQUIRED], 0);
+	e_data_notify_auth_required (E_DATA (cal));
 }
 
 /**
diff --git a/calendar/libedata-cal/e-data-cal.h b/calendar/libedata-cal/e-data-cal.h
index 4cd5f1a..ebee9f4 100644
--- a/calendar/libedata-cal/e-data-cal.h
+++ b/calendar/libedata-cal/e-data-cal.h
@@ -25,14 +25,13 @@
 
 #include <glib-object.h>
 #include <dbus/dbus-glib.h>
+#include <libebackend/e-data.h>
 #include <libedata-cal/e-data-cal-common.h>
 #include <libedata-cal/e-data-cal-view.h>
 #include <libedata-cal/e-data-cal-types.h>
 
 G_BEGIN_DECLS
 
-
-
 #define E_TYPE_DATA_CAL            (e_data_cal_get_type ())
 #define E_DATA_CAL(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_DATA_CAL, EDataCal))
 #define E_DATA_CAL_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_DATA_CAL, EDataCalClass))
@@ -45,12 +44,12 @@ GQuark e_data_cal_error_quark (void);
 typedef struct _EDataCalPrivate EDataCalPrivate;
 
 struct _EDataCal {
-	GObject parent;
+	EData parent;
 	EDataCalPrivate *priv;
 };
 
 struct _EDataCalClass {
-	GObjectClass parent_class;
+	EDataClass parent_class;
 };
 
 GType e_data_cal_get_type (void);
diff --git a/libebackend/e-backend.c b/libebackend/e-backend.c
index 0eb50bc..738f1a1 100644
--- a/libebackend/e-backend.c
+++ b/libebackend/e-backend.c
@@ -39,6 +39,21 @@ struct _EBackendPrivate {
 
 	GMutex *views_mutex;
 	EList *views;
+
+	/* signal handler ID for source's 'changed' signal */
+	gulong source_changed_id;
+
+	/* URI, from source. This is cached, since we return const. */
+	gchar *uri;
+};
+
+#define E_BACKEND_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), E_TYPE_BACKEND, EBackendPrivate))
+
+/* Property IDs */
+enum props {
+        PROP_0,
+        PROP_SOURCE,
+        PROP_URI,
 };
 
 /* Signal IDs */
@@ -69,6 +84,29 @@ e_backend_get_source (EBackend *backend)
 	return backend->priv->source;
 }
 
+static void
+source_changed_cb (ESource  *source,
+		   EBackend *backend)
+{
+	EBackendPrivate *priv;
+	gchar *suri;
+
+	g_return_if_fail (source != NULL);
+	g_return_if_fail (E_IS_BACKEND (backend));
+
+	priv = backend->priv;
+	g_return_if_fail (priv != NULL);
+	g_return_if_fail (e_backend_get_source (backend) == source);
+
+	suri = e_source_get_uri (e_backend_get_source (backend));
+	if (!priv->uri || (suri && !g_str_equal (priv->uri, suri))) {
+		g_free (priv->uri);
+		priv->uri = suri;
+	} else {
+		g_free (suri);
+	}
+}
+
 /**
  * e_backend_set_source:
  * @backend: An #EBackend.
@@ -82,87 +120,65 @@ void
 e_backend_set_source (EBackend *backend,
 		      ESource  *source)
 {
-	g_return_if_fail (E_IS_BACKEND (backend));
-	g_return_if_fail (E_IS_SOURCE (source));
-
-	if (backend->priv->source)
-		g_object_unref (backend->priv->source);
-
-	backend->priv->source = g_object_ref (backend);
-}
+	EBackendPrivate *priv;
 
-/**
- * e_book_backend_stop_view:
- * @backend: an #EBackend
- * @view: the #EDataView to stop
- *
- * Stops running the query specified by @view, emitting
- * no more signals.
- **/
-void
-e_backend_stop_view (EBackend  *backend,
-		     EDataView *view)
-{
-	EBackendClass *klass;
+	g_return_if_fail (E_IS_BACKEND (backend));
+	g_return_if_fail (E_IS_SOURCE (source) || !source);
 
 	g_return_if_fail (E_IS_BACKEND (backend));
 
-	klass = E_BACKEND_GET_CLASS (backend);
+	priv = backend->priv;
+	if (priv->source_changed_id && priv->source) {
+		g_signal_handler_disconnect (priv->source, priv->source_changed_id);
+		priv->source_changed_id = 0;
+	}
+
+	if (priv->source)
+		g_object_unref (priv->source);
 
-	g_assert (klass->stop_view);
+	if (source) {
+		priv->source = g_object_ref (source);
+		priv->source_changed_id = g_signal_connect (source, "changed", G_CALLBACK (source_changed_cb), backend);
 
-	return klass->stop_view (backend, view);
+		/* Cache the URI */
+		g_free (priv->uri);
+		priv->uri = e_source_get_uri (priv->source);
+	}
 }
 
 /**
- * e_backend_remove:
- * @backend: an #EBackend
- * @data: an #EData
- * @opid: the ID to use for this operation
+ * e_backend_get_uri:
+ * @backend: An #EBackend.
+ *
+ * Gets the URI of the source that @backend is serving.
  *
- * Executes a 'remove' request to remove all of @backend's data,
- * specified by @opid on @data.
+ * Return value: uri for the backend.
  **/
-void
-e_backend_remove (EBackend *backend,
-		  EData    *data,
-		  guint32   opid)
+const gchar*
+e_backend_get_uri (EBackend *backend)
 {
-	EBackendClass *klass;
-
-	g_return_if_fail (E_IS_BACKEND (backend));
-	g_return_if_fail (E_IS_DATA (data));
-
-	klass = E_BACKEND_GET_CLASS (data);
-
-	g_assert (klass->remove);
+	g_return_val_if_fail (E_IS_BACKEND (backend), NULL);
 
-	klass->remove (backend, data, opid);
+	return backend->priv->uri;
 }
 
 /**
- * e_backend_get_changes:
- * @backend: an #EBackend
- * @data: an #EData
- * @opid: the ID to use for this operation
- * @change_id: the ID of the changeset
+ * e_backend_set_uri:
+ * @backend: An #EBackend.
+ * @uri: The URI of the source @backend is using.
  *
- * Executes a 'get changes' request specified by @opid on @data
- * using @backend.
+ * Sets the source that @backend is serving.
  **/
 void
-e_backend_get_changes (EBackend    *backend,
-		       EData       *data,
-		       guint32      opid,
-		       const gchar *change_id)
+e_backend_set_uri (EBackend    *backend,
+		   const gchar *uri)
 {
 	g_return_if_fail (E_IS_BACKEND (backend));
-	g_return_if_fail (E_IS_DATA (data));
-	g_return_if_fail (change_id);
 
-	g_assert (E_BACKEND_GET_CLASS (backend)->get_changes);
-
-	(* E_BACKEND_GET_CLASS (backend)->get_changes) (backend, data, opid, change_id);
+	if (!backend->priv->source) {
+		g_free (backend->priv->uri);
+		backend->priv->uri = g_strdup (uri);
+	}
 }
 
 static void
@@ -172,10 +188,29 @@ last_client_gone (EBackend *backend)
 }
 
 /**
+ * e_backend_get_views_mutex:
+ * @backend: an #EBackend
+ *
+ * Returns the #GMutex used to regulate access of the vies list and the
+ * views themselves. The mutex is owned by @backend.
+ **/
+GMutex*
+e_backend_get_views_mutex (EBackend *backend)
+{
+	g_return_val_if_fail (E_IS_BACKEND (backend), NULL);
+
+	return backend->priv->views_mutex;
+}
+
+/**
  * e_backend_get_views:
  * @backend: an #EBackend
  *
- * Gets the list of #EDataView views running on this backend.
+ * Gets the list of #EDataView views running on this backend. This list (but not
+ * its members) must be g_object_unref()'d when you're done with it.
+ *
+ * Be sure to also lock and unlock the mutex from @e_backend_get_views_mutex()
+ * as appropriate when using this list of views.
  *
  * Return value: An #EList of #EDataView objects.
  **/
@@ -199,10 +234,11 @@ e_backend_add_view (EBackend  *backend,
 		    EDataView *view)
 {
 	g_return_if_fail (E_IS_BACKEND (backend));
+	g_return_if_fail (E_IS_DATA_VIEW (view));
 
 	g_mutex_lock (backend->priv->views_mutex);
 
-	e_list_append (backend->priv->views, view);
+	e_list_append (backend->priv->views, g_object_ref (view));
 
 	g_mutex_unlock (backend->priv->views_mutex);
 }
@@ -219,6 +255,7 @@ e_backend_remove_view (EBackend  *backend,
 		       EDataView *view)
 {
 	g_return_if_fail (E_IS_BACKEND (backend));
+	g_return_if_fail (E_IS_DATA_VIEW (view));
 
 	g_mutex_lock (backend->priv->views_mutex);
 
@@ -317,28 +354,6 @@ e_backend_get_clients_mutex (EBackend *backend)
 }
 
 /**
- * e_backend_get_static_capabilities:
- * @backend: an #EBackend
- *
- * Gets the capabilities offered by this @backend.
- *
- * Return value: A string listing the capabilities.
- **/
-gchar *
-e_backend_get_static_capabilities (EBackend *backend)
-{
-	EBackendClass *klass;
-
-	g_return_val_if_fail (E_IS_BACKEND (backend), NULL);
-
-	klass = E_BACKEND_GET_CLASS (backend);
-
-	g_assert (klass->get_static_capabilities);
-
-	return klass->get_static_capabilities (backend);
-}
-
-/**
  * e_backend_is_loaded:
  * @backend: an #EBackend
  *
@@ -397,6 +412,8 @@ e_backend_notify_auth_required (EBackend *backend)
 	EBackendPrivate *priv;
 	GList *clients;
 
+	g_return_if_fail (E_IS_BACKEND (backend));
+
 	priv = backend->priv;
 	g_mutex_lock (priv->clients_mutex);
 
@@ -406,46 +423,101 @@ e_backend_notify_auth_required (EBackend *backend)
 }
 
 static void
+e_backend_get_property (GObject      *object,
+			guint         property_id,
+			GValue       *value,
+			GParamSpec   *pspec)
+{
+        EBackend *backend;
+        EBackendPrivate *priv;
+
+        backend = E_BACKEND (object);
+        priv = backend->priv;
+
+        switch (property_id) {
+        case PROP_SOURCE:
+                g_value_set_object (value, e_backend_get_source (backend));
+                break;
+        case PROP_URI:
+                g_value_set_string (value, e_backend_get_uri (backend));
+                break;
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                break;
+        }
+}
+
+static void
+e_backend_set_property (GObject      *object,
+			guint         property_id,
+			const GValue *value,
+			GParamSpec   *pspec)
+{
+	EBackend *backend;
+	EBackendPrivate *priv;
+
+	backend = E_BACKEND (object);
+	priv = backend->priv;
+
+	switch (property_id) {
+	case PROP_SOURCE:
+		e_backend_set_source (backend, g_value_get_object (value));
+		break;
+	case PROP_URI:
+		e_backend_set_uri (backend, g_value_get_string (value));
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+		break;
+	}
+}
+
+static void
 e_backend_init (EBackend *backend)
 {
 	EBackendPrivate *priv;
 
-	priv          = g_new0 (EBackendPrivate, 1);
-	priv->clients = NULL;
-	priv->source = NULL;
-	priv->views   = e_list_new((EListCopyFunc) NULL, (EListFreeFunc) NULL, NULL);
+	priv = E_BACKEND_GET_PRIVATE (backend);
+	backend->priv = priv;
+
+	priv->views = e_list_new((EListCopyFunc) NULL, (EListFreeFunc) g_object_unref, NULL);
 	priv->open_mutex = g_mutex_new ();
 	priv->clients_mutex = g_mutex_new ();
 	priv->views_mutex = g_mutex_new ();
-
-	backend->priv = priv;
 }
 
 static void
 e_backend_dispose (GObject *object)
 {
 	EBackend *backend;
+	EBackendPrivate *priv;
 
 	backend = E_BACKEND (object);
+	priv = backend->priv;
 
-	if (backend->priv) {
-		g_list_free (backend->priv->clients);
+	if (priv) {
+		g_assert (priv->clients == NULL);
 
-		if (backend->priv->views) {
-			g_object_unref (backend->priv->views);
-			backend->priv->views = NULL;
+		if (priv->views) {
+			g_object_unref (priv->views);
+			priv->views = NULL;
 		}
 
-		if (backend->priv->source) {
-			g_object_unref (backend->priv->source);
-			backend->priv->source = NULL;
+		if (priv->source_changed_id && priv->source) {
+			g_signal_handler_disconnect (priv->source, priv->source_changed_id);
+			priv->source_changed_id = 0;
 		}
 
-		g_mutex_free (backend->priv->open_mutex);
-		g_mutex_free (backend->priv->clients_mutex);
-		g_mutex_free (backend->priv->views_mutex);
+		if (priv->source) {
+			g_object_unref (priv->source);
+			priv->source = NULL;
+		}
+
+		g_mutex_free (priv->open_mutex);
+		g_mutex_free (priv->clients_mutex);
+		g_mutex_free (priv->views_mutex);
 
-		g_free (backend->priv);
+		g_free (priv);
 		backend->priv = NULL;
 	}
 
@@ -462,6 +534,26 @@ e_backend_class_init (EBackendClass *klass)
 	object_class = (GObjectClass *) klass;
 
 	object_class->dispose = e_backend_dispose;
+	object_class->get_property = e_backend_get_property;
+	object_class->set_property = e_backend_set_property;
+
+	g_object_class_install_property
+		(object_class, PROP_SOURCE,
+		 g_param_spec_object
+			("source",
+			 NULL,
+			 NULL,
+			 E_TYPE_SOURCE,
+			 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+	g_object_class_install_property
+		(object_class, PROP_URI,
+		 g_param_spec_string
+			("uri",
+			 NULL,
+			 NULL,
+			 "",
+			 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
 	e_backend_signals[LAST_CLIENT_GONE] =
 		g_signal_new ("last_client_gone",
@@ -471,4 +563,6 @@ e_backend_class_init (EBackendClass *klass)
 			      NULL, NULL,
 			      g_cclosure_marshal_VOID__VOID,
 			      G_TYPE_NONE, 0);
+
+	g_type_class_add_private (klass, sizeof (EBackendPrivate));
 }
diff --git a/libebackend/e-backend.h b/libebackend/e-backend.h
index f50942b..a24c38d 100644
--- a/libebackend/e-backend.h
+++ b/libebackend/e-backend.h
@@ -53,20 +53,6 @@ struct _EBackend {
 struct _EBackendClass {
 	GObjectClass parent_class;
 
-/* XXX: eCal equiv is start_query */
-	/* FIXME: this could be genericized
-	void (*start_view) (EBackend *backend,
-			EDataView *view);
-			*/
-	void		(*stop_view)			(EBackend  *backend,
-							 EDataView *view);
-
-	void		(*remove)			(EBackend  *backend,
-							 EData     *data,
-							 guint32    opid);
-
-        gchar *		(*get_static_capabilities)	(EBackend  *backend);
-
 	void		(*set_mode)			(EBackend  *backend,
 							 EDataMode  mode);
 
@@ -78,11 +64,6 @@ struct _EBackendClass {
 
 	gboolean	(*is_loaded)			(EBackend  *backend);
 
-	void		(*get_changes)			(EBackend    *backend,
-							 EData       *data,
-							 guint32      opid,
-							 const gchar *change_id);
-
 	/* Notification signals */
 	void (* last_client_gone) (EBackend *backend);
 
@@ -100,50 +81,38 @@ ESource*	e_backend_get_source		(EBackend *backend);
 void		e_backend_set_source		(EBackend *backend,
 						 ESource  *source);
 
-/* XXX: ecal equiv: add_query */
-void		e_backend_add_view		(EBackend           *backend,
-						 EDataView          *view);
-/* XXX: ecal equiv: remove_query */
-void		e_backend_remove_view		(EBackend           *backend,
-						 EDataView          *view);
-
-EList*		e_backend_get_views		(EBackend           *backend);
-
-void		e_backend_notify_auth_required	(EBackend           *backend);
+const gchar*	e_backend_get_uri		(EBackend *backend);
 
+void		e_backend_set_uri		(EBackend    *backend,
+						 const gchar *uri);
 
-void		e_backend_remove			(EBackend  *backend,
-							 EData     *data,
-							 guint32    opid);
-
-gchar*		e_backend_get_static_capabilities	(EBackend  *backend);
-
-void		e_backend_set_mode			(EBackend  *backend,
-							 EDataMode  mode);
+/* XXX: ecal equiv: add_query */
+void		e_backend_add_view		(EBackend  *backend,
+						 EDataView *view);
+/* XXX: ecal equiv: remove_query */
+void		e_backend_remove_view		(EBackend  *backend,
+						 EDataView *view);
 
-gboolean	e_backend_add_client			(EBackend  *backend,
-							 EData     *data);
+GMutex*		e_backend_get_views_mutex	(EBackend  *backend);
 
-void		e_backend_remove_client			(EBackend  *backend,
-							 EData     *data);
+EList*		e_backend_get_views		(EBackend  *backend);
 
-GList*		e_backend_get_clients			(EBackend  *backend);
+void		e_backend_notify_auth_required	(EBackend  *backend);
 
-GMutex*		e_backend_get_clients_mutex		(EBackend  *backend);
+void		e_backend_set_mode		(EBackend  *backend,
+						 EDataMode  mode);
 
-gboolean	e_backend_is_loaded			(EBackend  *backend);
+gboolean	e_backend_add_client		(EBackend  *backend,
+						 EData     *data);
 
-void		e_backend_get_changes			(EBackend    *backend,
-							 EData       *data,
-							 guint32      opid,
-							 const gchar *change_id);
+void		e_backend_remove_client		(EBackend  *backend,
+						 EData     *data);
 
-void		e_backend_notify_writable		(EBackend *backend, gboolean is_writable);
+GList*		e_backend_get_clients		(EBackend  *backend);
 
-void		e_backend_notify_connection_status	(EBackend *backend, gboolean is_online);
+GMutex*		e_backend_get_clients_mutex	(EBackend  *backend);
 
-void		e_backend_stop_view			(EBackend  *backend,
-							 EDataView *view);
+gboolean	e_backend_is_loaded		(EBackend  *backend);
 
 /* FIXME: these could be genericized a bit */
 #if 0



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