[evolution-data-server/account-mgmt: 15/26] Add an ESource extension for the file backend.



commit 77f166a6f21c8e059116fa31f0b83676ce032827
Author: Matthew Barnes <mbarnes redhat com>
Date:   Sat Nov 20 17:15:39 2010 -0500

    Add an ESource extension for the file backend.

 calendar/backends/file/Makefile.am                 |    9 +-
 .../backends/file/e-cal-backend-file-factory.c     |  216 ++++++++----------
 calendar/backends/file/e-cal-backend-file.c        |  217 ++++++++++-------
 calendar/backends/file/e-source-local.c            |  248 ++++++++++++++++++++
 calendar/backends/file/e-source-local.h            |   79 +++++++
 5 files changed, 558 insertions(+), 211 deletions(-)
---
diff --git a/calendar/backends/file/Makefile.am b/calendar/backends/file/Makefile.am
index fe79080..952d60e 100644
--- a/calendar/backends/file/Makefile.am
+++ b/calendar/backends/file/Makefile.am
@@ -21,7 +21,9 @@ libecalbackendfile_la_SOURCES =		\
 	e-cal-backend-file-todos.c	\
 	e-cal-backend-file-todos.h	\
 	e-cal-backend-file.c		\
-	e-cal-backend-file.h
+	e-cal-backend-file.h		\
+	e-source-local.c		\
+	e-source-local.h
 
 libecalbackendfile_la_LIBADD =						\
 	$(top_builddir)/calendar/libecal/libecal-1.2.la			\
@@ -32,7 +34,10 @@ libecalbackendfile_la_LIBADD =						\
 libecalbackendfile_la_LDFLAGS =		\
 	-module -avoid-version $(NO_UNDEFINED)
 
-test_interval_searches_SOURCES = e-cal-backend-file.c
+test_interval_searches_SOURCES =	\
+	e-cal-backend-file.c		\
+	e-source-local.c		\
+	e-source-local.h
 
 test_interval_searches_LDADD = \
 	$(top_builddir)/calendar/libecal/libecal-1.2.la			\
diff --git a/calendar/backends/file/e-cal-backend-file-factory.c b/calendar/backends/file/e-cal-backend-file-factory.c
index 00fbe4f..c53a364 100644
--- a/calendar/backends/file/e-cal-backend-file-factory.c
+++ b/calendar/backends/file/e-cal-backend-file-factory.c
@@ -17,19 +17,36 @@
 #include "e-cal-backend-file-events.h"
 #include "e-cal-backend-file-journal.h"
 #include "e-cal-backend-file-todos.h"
+#include "e-source-local.h"
 
-typedef struct {
-	ECalBackendFactory            parent_object;
-} ECalBackendFileFactory;
+typedef ECalBackendFactory ECalBackendFileEventsFactory;
+typedef ECalBackendFactoryClass ECalBackendFileEventsFactoryClass;
 
-typedef struct {
-	ECalBackendFactoryClass parent_class;
-} ECalBackendFileFactoryClass;
+typedef ECalBackendFactory ECalBackendFileJournalFactory;
+typedef ECalBackendFactoryClass ECalBackendFileJournalFactoryClass;
 
-static void
-e_cal_backend_file_factory_instance_init (ECalBackendFileFactory *factory)
-{
-}
+typedef ECalBackendFactory ECalBackendFileTodosFactory;
+typedef ECalBackendFactoryClass ECalBackendFileTodosFactoryClass;
+
+/* Forward Declarations */
+GType e_cal_backend_file_events_factory_get_type (void);
+GType e_cal_backend_file_journal_factory_get_type (void);
+GType e_cal_backend_file_todos_factory_get_type (void);
+
+G_DEFINE_DYNAMIC_TYPE (
+	ECalBackendFileEventsFactory,
+	e_cal_backend_file_events_factory,
+	E_TYPE_CAL_BACKEND_FACTORY)
+
+G_DEFINE_DYNAMIC_TYPE (
+	ECalBackendFileJournalFactory,
+	e_cal_backend_file_journal_factory,
+	E_TYPE_CAL_BACKEND_FACTORY)
+
+G_DEFINE_DYNAMIC_TYPE (
+	ECalBackendFileTodosFactory,
+	e_cal_backend_file_todos_factory,
+	E_TYPE_CAL_BACKEND_FACTORY)
 
 static const gchar *
 _get_protocol (ECalBackendFactory *factory)
@@ -37,28 +54,20 @@ _get_protocol (ECalBackendFactory *factory)
 	return "local";
 }
 
-static ECalBackend*
-_todos_new_backend (ECalBackendFactory *factory, ESource *source)
-{
-	return g_object_new (e_cal_backend_file_todos_get_type (),
-			     "source", source,
-			     "kind", ICAL_VTODO_COMPONENT,
-			     NULL);
-}
-
 static icalcomponent_kind
-_todos_get_kind (ECalBackendFactory *factory)
+_events_get_kind (ECalBackendFactory *factory)
 {
-	return ICAL_VTODO_COMPONENT;
+	return ICAL_VEVENT_COMPONENT;
 }
 
-static ECalBackend*
-_journal_new_backend (ECalBackendFactory *factory, ESource *source)
+static ECalBackend *
+_events_new_backend (ECalBackendFactory *factory,
+                     ESource *source)
 {
-	return g_object_new (e_cal_backend_file_journal_get_type (),
-			     "source", source,
-			     "kind", ICAL_VJOURNAL_COMPONENT,
-			     NULL);
+	return g_object_new (
+		e_cal_backend_file_events_get_type (),
+		"kind", ICAL_VEVENT_COMPONENT,
+		"source", source, NULL);
 }
 
 static icalcomponent_kind
@@ -67,130 +76,93 @@ _journal_get_kind (ECalBackendFactory *factory)
 	return ICAL_VJOURNAL_COMPONENT;
 }
 
-static ECalBackend*
-_events_new_backend (ECalBackendFactory *factory, ESource *source)
+static ECalBackend *
+_journal_new_backend (ECalBackendFactory *factory,
+                      ESource *source)
 {
-	return g_object_new (e_cal_backend_file_events_get_type (),
-			     "source", source,
-			     "kind", ICAL_VEVENT_COMPONENT,
-			     NULL);
+	return g_object_new (
+		e_cal_backend_file_journal_get_type (),
+		"kind", ICAL_VJOURNAL_COMPONENT,
+		"source", source, NULL);
 }
 
 static icalcomponent_kind
-_events_get_kind (ECalBackendFactory *factory)
+_todos_get_kind (ECalBackendFactory *factory)
 {
-	return ICAL_VEVENT_COMPONENT;
+	return ICAL_VTODO_COMPONENT;
 }
 
-static void
-todos_backend_factory_class_init (ECalBackendFileFactoryClass *klass)
+static ECalBackend *
+_todos_new_backend (ECalBackendFactory *factory,
+                    ESource *source)
 {
-	E_CAL_BACKEND_FACTORY_CLASS (klass)->get_protocol = _get_protocol;
-	E_CAL_BACKEND_FACTORY_CLASS (klass)->get_kind     = _todos_get_kind;
-	E_CAL_BACKEND_FACTORY_CLASS (klass)->new_backend  = _todos_new_backend;
+	return g_object_new (
+		e_cal_backend_file_todos_get_type (),
+		"kind", ICAL_VTODO_COMPONENT,
+		"source", source, NULL);
 }
 
 static void
-journal_backend_factory_class_init (ECalBackendFileFactoryClass *klass)
+e_cal_backend_file_events_factory_class_init (ECalBackendFactoryClass *class)
 {
-	E_CAL_BACKEND_FACTORY_CLASS (klass)->get_protocol = _get_protocol;
-	E_CAL_BACKEND_FACTORY_CLASS (klass)->get_kind     = _journal_get_kind;
-	E_CAL_BACKEND_FACTORY_CLASS (klass)->new_backend  = _journal_new_backend;
+	class->get_protocol = _get_protocol;
+	class->get_kind     = _events_get_kind;
+	class->new_backend  = _events_new_backend;
 }
 
 static void
-events_backend_factory_class_init (ECalBackendFileFactoryClass *klass)
+e_cal_backend_file_events_factory_class_finalize (ECalBackendFactoryClass *class)
 {
-	E_CAL_BACKEND_FACTORY_CLASS (klass)->get_protocol = _get_protocol;
-	E_CAL_BACKEND_FACTORY_CLASS (klass)->get_kind     = _events_get_kind;
-	E_CAL_BACKEND_FACTORY_CLASS (klass)->new_backend  = _events_new_backend;
 }
 
-static GType
-events_backend_factory_get_type (GTypeModule *module)
+static void
+e_cal_backend_file_events_factory_init (ECalBackendFactory *factory)
 {
-	GType type;
-
-	GTypeInfo info = {
-		sizeof (ECalBackendFileFactoryClass),
-		NULL, /* base_class_init */
-		NULL, /* base_class_finalize */
-		(GClassInitFunc)  events_backend_factory_class_init,
-		NULL, /* class_finalize */
-		NULL, /* class_data */
-		sizeof (ECalBackend),
-		0,    /* n_preallocs */
-		(GInstanceInitFunc) e_cal_backend_file_factory_instance_init
-	};
-
-	type = g_type_module_register_type (module,
-					    E_TYPE_CAL_BACKEND_FACTORY,
-					    "ECalBackendFileEventsFactory",
-					    &info, 0);
-
-	return type;
 }
 
-static GType
-journal_backend_factory_get_type (GTypeModule *module)
+static void
+e_cal_backend_file_journal_factory_class_init (ECalBackendFactoryClass *class)
 {
-	GType type;
-
-	GTypeInfo info = {
-		sizeof (ECalBackendFileFactoryClass),
-		NULL, /* base_class_init */
-		NULL, /* base_class_finalize */
-		(GClassInitFunc)  journal_backend_factory_class_init,
-		NULL, /* class_finalize */
-		NULL, /* class_data */
-		sizeof (ECalBackend),
-		0,    /* n_preallocs */
-		(GInstanceInitFunc) e_cal_backend_file_factory_instance_init
-	};
-
-	type = g_type_module_register_type (module,
-					    E_TYPE_CAL_BACKEND_FACTORY,
-					    "ECalBackendFileJournalFactory",
-					    &info, 0);
-
-	return type;
+	class->get_protocol = _get_protocol;
+	class->get_kind     = _journal_get_kind;
+	class->new_backend  = _journal_new_backend;
 }
 
-static GType
-todos_backend_factory_get_type (GTypeModule *module)
+static void
+e_cal_backend_file_journal_factory_class_finalize (ECalBackendFactoryClass *class)
 {
-	GType type;
-
-	GTypeInfo info = {
-		sizeof (ECalBackendFileFactoryClass),
-		NULL, /* base_class_init */
-		NULL, /* base_class_finalize */
-		(GClassInitFunc)  todos_backend_factory_class_init,
-		NULL, /* class_finalize */
-		NULL, /* class_data */
-		sizeof (ECalBackend),
-		0,    /* n_preallocs */
-		(GInstanceInitFunc) e_cal_backend_file_factory_instance_init
-	};
+}
 
-	type = g_type_module_register_type (module,
-					    E_TYPE_CAL_BACKEND_FACTORY,
-					    "ECalBackendFileTodosFactory",
-					    &info, 0);
+static void
+e_cal_backend_file_journal_factory_init (ECalBackendFactory *factory)
+{
+}
 
-	return type;
+static void
+e_cal_backend_file_todos_factory_class_init (ECalBackendFactoryClass *class)
+{
+	class->get_protocol = _get_protocol;
+	class->get_kind     = _todos_get_kind;
+	class->new_backend  = _todos_new_backend;
 }
 
-
+static void
+e_cal_backend_file_todos_factory_class_finalize (ECalBackendFactoryClass *class)
+{
+}
 
-static GType file_types[3];
+static void
+e_cal_backend_file_todos_factory_init (ECalBackendFactory *factory)
+{
+}
 
 void
-eds_module_initialize (GTypeModule *module)
+eds_module_initialize (GTypeModule *type_module)
 {
-	file_types[0] = todos_backend_factory_get_type (module);
-	file_types[1] = events_backend_factory_get_type (module);
-	file_types[2] = journal_backend_factory_get_type (module);
+	e_source_local_type_register (type_module);
+	e_cal_backend_file_events_factory_register_type (type_module);
+	e_cal_backend_file_journal_factory_register_type (type_module);
+	e_cal_backend_file_todos_factory_register_type (type_module);
 }
 
 void
@@ -201,6 +173,12 @@ eds_module_shutdown   (void)
 void
 eds_module_list_types (const GType **types, gint *num_types)
 {
+	static GType file_types[3];
+
+	file_types[0] = e_cal_backend_file_events_factory_get_type ();
+	file_types[1] = e_cal_backend_file_journal_factory_get_type ();
+	file_types[2] = e_cal_backend_file_todos_factory_get_type ();
+
 	*types = file_types;
-	*num_types = 3;
+	*num_types = G_N_ELEMENTS (file_types);
 }
diff --git a/calendar/backends/file/e-cal-backend-file.c b/calendar/backends/file/e-cal-backend-file.c
index 5c65598..2b24a54 100644
--- a/calendar/backends/file/e-cal-backend-file.c
+++ b/calendar/backends/file/e-cal-backend-file.c
@@ -36,6 +36,7 @@
 #include "libedataserver/e-data-server-util.h"
 #include "libedataserver/e-xml-hash-utils.h"
 #include "libedataserver/e-debug-log.h"
+#include "libedataserver/e-source-refresh.h"
 #include <libecal/e-cal-recur.h>
 #include <libecal/e-cal-time-util.h>
 #include <libecal/e-cal-util.h>
@@ -44,6 +45,7 @@
 #include <libedata-cal/e-cal-backend-sexp.h>
 #include <libedata-cal/e-cal-backend-intervaltree.h>
 #include "e-cal-backend-file-events.h"
+#include "e-source-local.h"
 
 #ifndef O_BINARY
 #define O_BINARY 0
@@ -751,7 +753,10 @@ uri_to_path (ECalBackend *backend)
 	ECalBackendFile *cbfile;
 	ECalBackendFilePrivate *priv;
 	ESource *source;
+	ESourceLocal *local_extension;
+	const gchar *extension_name;
 	const gchar *cache_dir;
+	const gchar *custom_file;
 	gchar *filename = NULL;
 
 	cbfile = E_CAL_BACKEND_FILE (backend);
@@ -760,13 +765,13 @@ uri_to_path (ECalBackend *backend)
 	cache_dir = e_cal_backend_get_cache_dir (backend);
 
 	source = e_cal_backend_get_source (backend);
-	if (source && e_source_get_property (source, "custom-file")) {
-		const gchar *property;
 
-		/* custom-uri is with a filename already */
-		property = e_source_get_property (source, "custom-file");
-		filename = g_strdup (property);
-	}
+	extension_name = E_SOURCE_EXTENSION_LOCAL_BACKEND;
+	local_extension = e_source_get_extension (source, extension_name);
+
+	custom_file = e_source_local_get_custom_file (local_extension);
+	if (custom_file != NULL && *custom_file != '\0')
+		filename = g_strdup (custom_file);
 
 	if (filename == NULL)
 		filename = g_build_filename (cache_dir, priv->file_name, NULL);
@@ -870,7 +875,11 @@ prepare_refresh_data (ECalBackendFile *cbfile)
 {
 	ECalBackendFilePrivate *priv;
 	ESource *source;
-	const gchar *value;
+	ESourceLocal *local_extension;
+	ESourceRefresh *refresh_extension;
+	const gchar *custom_file;
+	const gchar *extension_name;
+	const gchar *refresh_type;
 
 	g_return_if_fail (cbfile != NULL);
 
@@ -882,28 +891,42 @@ prepare_refresh_data (ECalBackendFile *cbfile)
 	priv->refresh_skip = 0;
 
 	source = e_cal_backend_get_source (E_CAL_BACKEND (cbfile));
-	value = e_source_get_property (source, "refresh-type");
-	if (e_source_get_property (source, "custom-file") && value && *value && !value[1]) {
+
+	extension_name = E_SOURCE_EXTENSION_LOCAL_BACKEND;
+	local_extension = e_source_get_extension (source, extension_name);
+
+	extension_name = E_SOURCE_EXTENSION_REFRESH;
+	refresh_extension = e_source_get_extension (source, extension_name);
+
+	custom_file = e_source_local_get_custom_file (local_extension);
+	refresh_type = e_source_local_get_refresh_type (local_extension);
+
+	if (custom_file != NULL && *custom_file != '\0') {
 		GFile *file;
 		GError *error = NULL;
 
-		switch (*value) {
-		case '1': /* on file change */
+		/* file monitor */
+		if (g_strcmp0 (refresh_type, E_SOURCE_LOCAL_REFRESH_TYPE_MONITOR) == 0) {
 			file = g_file_new_for_path (priv->custom_file);
-			priv->refresh_monitor = g_file_monitor_file (file, G_FILE_MONITOR_WATCH_MOUNTS, NULL, &error);
-			if (file)
-				g_object_unref (file);
+			priv->refresh_monitor = g_file_monitor_file (
+				file, G_FILE_MONITOR_WATCH_MOUNTS, NULL, &error);
+			g_object_unref (file);
+
 			if (priv->refresh_monitor)
-				g_signal_connect (G_OBJECT (priv->refresh_monitor), "changed", G_CALLBACK (custom_file_changed), priv);
-			break;
-		case '2': /* on refresh timeout */
-			value = e_source_get_property (source, "refresh");
-			if (value && atoi (value) > 0) {
-				priv->refresh_timeout_id = g_timeout_add_seconds (60 * atoi (value), (GSourceFunc) check_refresh_calendar_timeout, priv);
-			}
-			break;
-		default:
-			break;
+				g_signal_connect (
+					priv->refresh_monitor, "changed",
+					G_CALLBACK (custom_file_changed), priv);
+		}
+
+		/* refresh interval */
+		if (g_strcmp0 (refresh_type, E_SOURCE_LOCAL_REFRESH_TYPE_INTERVAL) == 0) {
+			guint interval;
+
+			interval = e_source_refresh_get_interval (refresh_extension);
+			if (interval > 0)
+				priv->refresh_timeout_id = g_timeout_add_seconds (
+					60 * interval, (GSourceFunc)
+					check_refresh_calendar_timeout, priv);
 		}
 	}
 
@@ -1298,37 +1321,41 @@ add_timezone (icalcomponent *icalcomp, icaltimezone *tzone)
 static void
 source_changed_cb (ESource *source, ECalBackend *backend)
 {
-	const gchar *value;
+	ECalBackendFile *cbfile;
+	ESourceLocal *local_extension;
+	const gchar *extension_name;
+	const gchar *custom_file;
+	gboolean writable;
+	gboolean read_only;
 
 	g_return_if_fail (source != NULL);
-	g_return_if_fail (backend != NULL);
 	g_return_if_fail (E_IS_CAL_BACKEND (backend));
 
-	value = e_source_get_property (source, "custom-file");
-	if (value && *value) {
-		ECalBackendFile *cbfile;
-		gboolean forced_readonly;
+	cbfile = E_CAL_BACKEND_FILE (backend);
 
-		cbfile = E_CAL_BACKEND_FILE (backend);
-		g_return_if_fail (cbfile != NULL);
+	extension_name = E_SOURCE_EXTENSION_LOCAL_BACKEND;
+	local_extension = e_source_get_extension (source, extension_name);
 
-		value = e_source_get_property (source, "custom-file-readonly");
-		forced_readonly = value && g_str_equal (value, "1");
+	custom_file = e_source_local_get_custom_file (local_extension);
+	if (custom_file == NULL || *custom_file == '\0')
+		return;
 
-		if ((forced_readonly != FALSE) != (cbfile->priv->read_only != FALSE)) {
-			cbfile->priv->read_only = forced_readonly;
-			if (!forced_readonly) {
-				gchar *str_uri = get_uri_string (backend);
+	writable = e_source_local_get_custom_file_writable (local_extension);
+	read_only = !writable;
 
-				g_return_if_fail (str_uri != NULL);
+	if (read_only != cbfile->priv->read_only) {
+		cbfile->priv->read_only = read_only;
+		if (writable) {
+			gchar *str_uri = get_uri_string (backend);
 
-				cbfile->priv->read_only = g_access (str_uri, W_OK) != 0;
+			g_return_if_fail (str_uri != NULL);
 
-				g_free (str_uri);
-			}
+			cbfile->priv->read_only = g_access (str_uri, W_OK) != 0;
 
-			e_cal_backend_notify_readonly (backend, cbfile->priv->read_only);
+			g_free (str_uri);
 		}
+
+		e_cal_backend_notify_readonly (backend, cbfile->priv->read_only);
 	}
 }
 
@@ -1372,14 +1399,21 @@ e_cal_backend_file_open (ECalBackendSync *backend, EDataCal *cal, gboolean only_
 
 	if (!err) {
 		if (!priv->read_only) {
-			ESource *source = e_cal_backend_get_source (E_CAL_BACKEND (backend));
+			ESource *source;
+			ESourceLocal *local_extension;
+			const gchar *extension_name;
 
-			if (source) {
-				g_signal_connect (source, "changed", G_CALLBACK (source_changed_cb), backend);
+			source = e_cal_backend_get_source (E_CAL_BACKEND (backend));
 
-				if (e_source_get_property (source, "custom-file-readonly") && g_str_equal (e_source_get_property (source, "custom-file-readonly"), "1"))
-					priv->read_only = TRUE;
-			}
+			extension_name = E_SOURCE_EXTENSION_LOCAL_BACKEND;
+			local_extension = e_source_get_extension (source, extension_name);
+
+			g_signal_connect (
+				source, "changed",
+				G_CALLBACK (source_changed_cb), backend);
+
+			if (!e_source_local_get_custom_file_writable (local_extension))
+				priv->read_only = TRUE;
 		}
 
 		if (priv->default_zone && add_timezone (priv->icalcomp, priv->default_zone)) {
@@ -1396,8 +1430,22 @@ e_cal_backend_file_open (ECalBackendSync *backend, EDataCal *cal, gboolean only_
 		g_propagate_error (perror, err);
 }
 
-static void
-e_cal_backend_file_remove (ECalBackendSync *backend, EDataCal *cal, GError **perror)
+/* is_loaded handler for the file backend */
+static gboolean
+e_cal_backend_file_is_loaded (ECalBackend *backend)
+{
+	ECalBackendFile *cbfile;
+	ECalBackendFilePrivate *priv;
+
+	cbfile = E_CAL_BACKEND_FILE (backend);
+	priv = cbfile->priv;
+
+	return (priv->icalcomp != NULL);
+}
+
+static gboolean
+e_cal_backend_file_remove (ECalBackend *backend,
+                           GError **error)
 {
 	ECalBackendFile *cbfile;
 	ECalBackendFilePrivate *priv;
@@ -1405,7 +1453,8 @@ e_cal_backend_file_remove (ECalBackendSync *backend, EDataCal *cal, GError **per
         gchar *full_path = NULL;
 	const gchar *fname;
 	GDir *dir = NULL;
-	GError *error = NULL, *err = NULL;
+	GError *local_error = NULL;
+	GError *err = NULL;
 
 	cbfile = E_CAL_BACKEND_FILE (backend);
 	priv = cbfile->priv;
@@ -1424,9 +1473,10 @@ e_cal_backend_file_remove (ECalBackendSync *backend, EDataCal *cal, GError **per
 
 	/* remove all files in the directory */
 	dirname = g_path_get_dirname (str_uri);
-	dir = g_dir_open (dirname, 0, &error);
+	dir = g_dir_open (dirname, 0, &local_error);
 	if (!dir) {
-		err = e_data_cal_create_error (PermissionDenied, error ? error->message : NULL);
+		err = e_data_cal_create_error (
+			PermissionDenied, local_error->message);
                 goto done;
 	}
 
@@ -1456,27 +1506,15 @@ e_cal_backend_file_remove (ECalBackendSync *backend, EDataCal *cal, GError **per
 
         g_static_rec_mutex_unlock (&priv->idle_save_rmutex);
 
-	/* lie here a bit, but otherwise the calendar will not be removed, even it should */
-	if (err) {
-		g_print (G_STRLOC ": %s", err->message);
-		g_error_free (err);
-	}
+	if (local_error)
+		g_error_free (local_error);
 
-	if (error)
-		g_error_free (error);
-}
-
-/* is_loaded handler for the file backend */
-static gboolean
-e_cal_backend_file_is_loaded (ECalBackend *backend)
-{
-	ECalBackendFile *cbfile;
-	ECalBackendFilePrivate *priv;
-
-	cbfile = E_CAL_BACKEND_FILE (backend);
-	priv = cbfile->priv;
+	if (err != NULL) {
+		g_propagate_error (error, err);
+		return FALSE;
+	}
 
-	return (priv->icalcomp != NULL);
+	return TRUE;
 }
 
 /* is_remote handler for the file backend */
@@ -3236,10 +3274,9 @@ cal_backend_file_constructed (GObject *object)
 	ECalBackend *backend;
 	ESource *source;
 	icalcomponent_kind kind;
-	const gchar *source_dir;
 	const gchar *user_data_dir;
 	const gchar *component_type;
-	gchar *mangled_source_dir;
+	const gchar *uid;
 	gchar *filename;
 
 	user_data_dir = e_get_user_data_dir ();
@@ -3252,6 +3289,7 @@ cal_backend_file_constructed (GObject *object)
 	backend = E_CAL_BACKEND (object);
 	kind = e_cal_backend_get_kind (backend);
 	source = e_cal_backend_get_source (backend);
+	uid = e_source_get_uid (source);
 
 	switch (kind) {
 		case ICAL_VEVENT_COMPONENT:
@@ -3269,20 +3307,9 @@ cal_backend_file_constructed (GObject *object)
 			break;
 	}
 
-	source_dir = e_source_peek_relative_uri (source);
-	if (!source_dir || !g_str_equal (source_dir, "system"))
-		source_dir = e_source_peek_uid (source);
-
-	/* Mangle the URI to not contain invalid characters. */
-	mangled_source_dir = g_strdelimit (g_strdup (source_dir), ":/", '_');
-
-	filename = g_build_filename (
-		user_data_dir, component_type, mangled_source_dir, NULL);
-
+	filename = g_build_filename (user_data_dir, component_type, uid, NULL);
 	e_cal_backend_set_cache_dir (backend, filename);
-
 	g_free (filename);
-	g_free (mangled_source_dir);
 }
 
 /* Class initialization function for the file backend */
@@ -3309,7 +3336,6 @@ e_cal_backend_file_class_init (ECalBackendFileClass *class)
 	sync_class->get_ldap_attribute_sync = e_cal_backend_file_get_ldap_attribute;
 	sync_class->get_static_capabilities_sync = e_cal_backend_file_get_static_capabilities;
 	sync_class->open_sync = e_cal_backend_file_open;
-	sync_class->remove_sync = e_cal_backend_file_remove;
 	sync_class->create_object_sync = e_cal_backend_file_create_object;
 	sync_class->modify_object_sync = e_cal_backend_file_modify_object;
 	sync_class->remove_object_sync = e_cal_backend_file_remove_object;
@@ -3326,12 +3352,16 @@ e_cal_backend_file_class_init (ECalBackendFileClass *class)
 	sync_class->get_changes_sync = e_cal_backend_file_get_changes;
 
 	backend_class->is_loaded = e_cal_backend_file_is_loaded;
+	backend_class->remove = e_cal_backend_file_remove;
 	backend_class->start_query = e_cal_backend_file_start_query;
 	backend_class->get_mode = e_cal_backend_file_get_mode;
 	backend_class->set_mode = e_cal_backend_file_set_mode;
 
 	backend_class->internal_get_default_timezone = e_cal_backend_file_internal_get_default_timezone;
 	backend_class->internal_get_timezone = e_cal_backend_file_internal_get_timezone;
+
+	/* Register our ESource extension. */
+	E_TYPE_SOURCE_LOCAL;
 }
 
 void
@@ -3394,9 +3424,16 @@ e_cal_backend_file_reload (ECalBackendFile *cbfile, GError **perror)
 	g_free (str_uri);
 
 	if (!err && !priv->read_only) {
-		ESource *source = e_cal_backend_get_source (E_CAL_BACKEND (cbfile));
+		ESource *source;
+		ESourceLocal *local_extension;
+		const gchar *extension_name;
+
+		source = e_cal_backend_get_source (E_CAL_BACKEND (cbfile));
+
+		extension_name = E_SOURCE_EXTENSION_LOCAL_BACKEND;
+		local_extension = e_source_get_extension (source, extension_name);
 
-		if (source && e_source_get_property (source, "custom-file-readonly") && g_str_equal (e_source_get_property (source, "custom-file-readonly"), "1"))
+		if (!e_source_local_get_custom_file_writable (local_extension))
 			priv->read_only = TRUE;
 	}
   done:
diff --git a/calendar/backends/file/e-source-local.c b/calendar/backends/file/e-source-local.c
new file mode 100644
index 0000000..f9763d4
--- /dev/null
+++ b/calendar/backends/file/e-source-local.c
@@ -0,0 +1,248 @@
+/*
+ * e-source-local.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "e-source-local.h"
+
+#define E_SOURCE_LOCAL_GET_PRIVATE(obj) \
+	(G_TYPE_INSTANCE_GET_PRIVATE \
+	((obj), E_TYPE_SOURCE_LOCAL, ESourceLocalPrivate))
+
+struct _ESourceLocalPrivate {
+	gchar *custom_file;
+	gboolean custom_file_writable;
+	gchar *refresh_type;
+};
+
+enum {
+	PROP_0,
+	PROP_CUSTOM_FILE,
+	PROP_CUSTOM_FILE_WRITABLE,
+	PROP_REFRESH_TYPE
+};
+
+G_DEFINE_DYNAMIC_TYPE (
+	ESourceLocal,
+	e_source_local,
+	E_TYPE_SOURCE_EXTENSION)
+
+static void
+source_local_set_property (GObject *object,
+                           guint property_id,
+                           const GValue *value,
+                           GParamSpec *pspec)
+{
+	switch (property_id) {
+		case PROP_CUSTOM_FILE:
+			e_source_local_set_custom_file (
+				E_SOURCE_LOCAL (object),
+				g_value_get_string (value));
+			return;
+
+		case PROP_CUSTOM_FILE_WRITABLE:
+			e_source_local_set_custom_file_writable (
+				E_SOURCE_LOCAL (object),
+				g_value_get_boolean (value));
+			return;
+
+		case PROP_REFRESH_TYPE:
+			e_source_local_set_refresh_type (
+				E_SOURCE_LOCAL (object),
+				g_value_get_string (value));
+			return;
+	}
+
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+source_local_get_property (GObject *object,
+                           guint property_id,
+                           GValue *value,
+                           GParamSpec *pspec)
+{
+	switch (property_id) {
+		case PROP_CUSTOM_FILE:
+			g_value_set_string (
+				value,
+				e_source_local_get_custom_file (
+				E_SOURCE_LOCAL (object)));
+			return;
+
+		case PROP_CUSTOM_FILE_WRITABLE:
+			g_value_set_boolean (
+				value,
+				e_source_local_get_custom_file_writable (
+				E_SOURCE_LOCAL (object)));
+			return;
+
+		case PROP_REFRESH_TYPE:
+			g_value_set_string (
+				value,
+				e_source_local_get_refresh_type (
+				E_SOURCE_LOCAL (object)));
+			return;
+	}
+
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+source_local_finalize (GObject *object)
+{
+	ESourceLocalPrivate *priv;
+
+	priv = E_SOURCE_LOCAL_GET_PRIVATE (object);
+
+	g_free (priv->custom_file);
+	g_free (priv->refresh_type);
+
+	/* Chain up to parent's finalize() method. */
+	G_OBJECT_CLASS (e_source_local_parent_class)->finalize (object);
+}
+
+static void
+e_source_local_class_init (ESourceLocalClass *class)
+{
+	GObjectClass *object_class;
+	ESourceExtensionClass *extension_class;
+
+	g_type_class_add_private (class, sizeof (ESourceLocalPrivate));
+
+	object_class = G_OBJECT_CLASS (class);
+	object_class->set_property = source_local_set_property;
+	object_class->get_property = source_local_get_property;
+	object_class->finalize = source_local_finalize;
+
+	extension_class = E_SOURCE_EXTENSION_CLASS (class);
+	extension_class->name = E_SOURCE_EXTENSION_LOCAL_BACKEND;
+
+	g_object_class_install_property (
+		object_class,
+		PROP_CUSTOM_FILE,
+		g_param_spec_string (
+			"custom-file",
+			"Custom File",
+			"Custom file path",
+			NULL,
+			G_PARAM_READWRITE |
+			G_PARAM_CONSTRUCT |
+			E_SOURCE_PARAM_SETTING));
+
+	g_object_class_install_property (
+		object_class,
+		PROP_CUSTOM_FILE_WRITABLE,
+		g_param_spec_boolean (
+			"custom-file-writable",
+			"Custom File Writable",
+			"Whether the custom file can be changed",
+			FALSE,
+			G_PARAM_READWRITE |
+			G_PARAM_CONSTRUCT |
+			E_SOURCE_PARAM_SETTING));
+
+	g_object_class_install_property (
+		object_class,
+		PROP_REFRESH_TYPE,
+		g_param_spec_string (
+			"refresh-type",
+			"Refresh Type",
+			"Custom file refresh type",
+			"monitor",
+			G_PARAM_READWRITE |
+			G_PARAM_CONSTRUCT |
+			E_SOURCE_PARAM_SETTING));
+}
+
+static void
+e_source_local_class_finalize (ESourceLocalClass *class)
+{
+}
+
+static void
+e_source_local_init (ESourceLocal *extension)
+{
+	extension->priv = E_SOURCE_LOCAL_GET_PRIVATE (extension);
+}
+
+void
+e_source_local_type_register (GTypeModule *type_module)
+{
+	/* XXX G_DEFINE_DYNAMIC_TYPE declares a static type registration
+	 *     function, so we have to wrap it with a public function in
+	 *     order to register types from a separate compilation unit. */
+	e_source_local_register_type (type_module);
+}
+
+const gchar *
+e_source_local_get_custom_file (ESourceLocal *extension)
+{
+	g_return_val_if_fail (E_IS_SOURCE_LOCAL (extension), NULL);
+
+	return extension->priv->custom_file;
+}
+
+void
+e_source_local_set_custom_file (ESourceLocal *extension,
+                                const gchar *custom_file)
+{
+	g_return_if_fail (E_IS_SOURCE_LOCAL (extension));
+
+	g_free (extension->priv->custom_file);
+	extension->priv->custom_file = g_strdup (custom_file);
+
+	g_object_notify (G_OBJECT (extension), "custom-file");
+}
+
+gboolean
+e_source_local_get_custom_file_writable (ESourceLocal *extension)
+{
+	g_return_val_if_fail (E_IS_SOURCE_LOCAL (extension), FALSE);
+
+	return extension->priv->custom_file_writable;
+}
+
+void
+e_source_local_set_custom_file_writable (ESourceLocal *extension,
+                                         gboolean custom_file_writable)
+{
+	g_return_if_fail (E_IS_SOURCE_LOCAL (extension));
+
+	extension->priv->custom_file_writable = custom_file_writable;
+
+	g_object_notify (G_OBJECT (extension), "custom-file-writable");
+}
+
+const gchar *
+e_source_local_get_refresh_type (ESourceLocal *extension)
+{
+	g_return_val_if_fail (E_IS_SOURCE_LOCAL (extension), FALSE);
+
+	return extension->priv->refresh_type;
+}
+
+void
+e_source_local_set_refresh_type (ESourceLocal *extension,
+                                 const gchar *refresh_type)
+{
+	g_return_if_fail (E_IS_SOURCE_LOCAL (extension));
+
+	g_free (extension->priv->refresh_type);
+	extension->priv->refresh_type = g_strdup (refresh_type);
+
+	g_object_notify (G_OBJECT (extension), "refresh-type");
+}
diff --git a/calendar/backends/file/e-source-local.h b/calendar/backends/file/e-source-local.h
new file mode 100644
index 0000000..6d7d4f0
--- /dev/null
+++ b/calendar/backends/file/e-source-local.h
@@ -0,0 +1,79 @@
+/*
+ * e-source-local.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef E_SOURCE_LOCAL_H
+#define E_SOURCE_LOCAL_H
+
+#include <libedataserver/e-source-extension.h>
+
+/* Standard GObject macros */
+#define E_TYPE_SOURCE_LOCAL \
+	(e_source_local_get_type ())
+#define E_SOURCE_LOCAL(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), E_TYPE_SOURCE_LOCAL, ESourceLocal))
+#define E_SOURCE_LOCAL_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_CAST \
+	((cls), E_TYPE_SOURCE_LOCAL, ESourceLocalClass))
+#define E_IS_SOURCE_LOCAL(obj) \
+	(G_TYPE_CHECK_INSTANCE_TYPE \
+	((obj), E_TYPE_SOURCE_LOCAL))
+#define E_IS_SOURCE_LOCAL_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_TYPE \
+	((cls), E_TYPE_SOURCE_LOCAL))
+#define E_SOURCE_LOCAL_GET_CLASS(obj) \
+	(G_TYPE_INSTANCE_GET_CLASS \
+	((obj), E_TYPE_SOURCE_LOCAL, ESourceLocalClass))
+
+#define E_SOURCE_EXTENSION_LOCAL_BACKEND "Local Backend"
+
+#define E_SOURCE_LOCAL_REFRESH_TYPE_INTERVAL "interval"
+#define E_SOURCE_LOCAL_REFRESH_TYPE_MONITOR  "monitor"
+
+G_BEGIN_DECLS
+
+typedef struct _ESourceLocal ESourceLocal;
+typedef struct _ESourceLocalClass ESourceLocalClass;
+typedef struct _ESourceLocalPrivate ESourceLocalPrivate;
+
+struct _ESourceLocal {
+	ESourceExtension parent;
+	ESourceLocalPrivate *priv;
+};
+
+struct _ESourceLocalClass {
+	ESourceExtensionClass parent_class;
+};
+
+GType		e_source_local_get_type		(void);
+void		e_source_local_type_register	(GTypeModule *type_module);
+const gchar *	e_source_local_get_custom_file	(ESourceLocal *extension);
+void		e_source_local_set_custom_file	(ESourceLocal *extension,
+						 const gchar *custom_file);
+gboolean	e_source_local_get_custom_file_writable
+						(ESourceLocal *extension);
+void		e_source_local_set_custom_file_writable
+						(ESourceLocal *extension,
+						 gboolean custom_file_writable);
+const gchar *	e_source_local_get_refresh_type	(ESourceLocal *extension);
+void		e_source_local_set_refresh_type	(ESourceLocal *extension,
+						 const gchar *refresh_type);
+
+G_END_DECLS
+
+#endif /* E_SOURCE_LOCAL_H */



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