[evolution-data-server/account-mgmt: 20/28] Add an ESource extension for the weather backend.



commit 02392133b32f26631c7ec30364fa1ff8a031c418
Author: Matthew Barnes <mbarnes redhat com>
Date:   Tue Nov 23 17:39:27 2010 -0500

    Add an ESource extension for the weather backend.

 calendar/backends/weather/Makefile.am              |    2 +
 .../weather/e-cal-backend-weather-factory.c        |   86 ++++-----
 calendar/backends/weather/e-cal-backend-weather.c  |  145 +++++++------
 calendar/backends/weather/e-source-weather.c       |  224 ++++++++++++++++++++
 calendar/backends/weather/e-source-weather.h       |   82 +++++++
 calendar/backends/weather/e-weather-source-ccf.c   |   73 ++++---
 calendar/backends/weather/e-weather-source-ccf.h   |   31 ++-
 calendar/backends/weather/e-weather-source.c       |   17 +-
 calendar/backends/weather/e-weather-source.h       |   41 +++-
 9 files changed, 525 insertions(+), 176 deletions(-)
---
diff --git a/calendar/backends/weather/Makefile.am b/calendar/backends/weather/Makefile.am
index cd57049..c5017b1 100644
--- a/calendar/backends/weather/Makefile.am
+++ b/calendar/backends/weather/Makefile.am
@@ -20,6 +20,8 @@ libecalbackendweather_la_SOURCES =	\
 	e-cal-backend-weather-factory.h	\
 	e-cal-backend-weather.c		\
 	e-cal-backend-weather.h		\
+	e-source-weather.c		\
+	e-source-weather.h		\
 	e-weather-source.c		\
 	e-weather-source.h		\
 	e-weather-source-ccf.c		\
diff --git a/calendar/backends/weather/e-cal-backend-weather-factory.c b/calendar/backends/weather/e-cal-backend-weather-factory.c
index 6059375..b986517 100644
--- a/calendar/backends/weather/e-cal-backend-weather-factory.c
+++ b/calendar/backends/weather/e-cal-backend-weather-factory.c
@@ -26,19 +26,18 @@
 
 #include "e-cal-backend-weather-factory.h"
 #include "e-cal-backend-weather.h"
+#include "e-source-weather.h"
 
-typedef struct {
-	ECalBackendFactory parent_object;
-} ECalBackendWeatherFactory;
+typedef ECalBackendFactory ECalBackendWeatherEventsFactory;
+typedef ECalBackendFactoryClass ECalBackendWeatherEventsFactoryClass;
 
-typedef struct {
-	ECalBackendWeatherClass parent_class;
-} ECalBackendWeatherFactoryClass;
+/* Forward Declarations */
+GType e_cal_backend_weather_events_factory_get_type (void);
 
-static void
-e_cal_backend_weather_factory_instance_init (ECalBackendWeatherFactory *factory)
-{
-}
+G_DEFINE_DYNAMIC_TYPE (
+	ECalBackendWeatherEventsFactory,
+	e_cal_backend_weather_events_factory,
+	E_TYPE_CAL_BACKEND_FACTORY)
 
 static const gchar *
 _get_protocol (ECalBackendFactory *factory)
@@ -46,58 +45,45 @@ _get_protocol (ECalBackendFactory *factory)
 	return "weather";
 }
 
-static ECalBackend*
-_events_new_backend (ECalBackendFactory *factory, ESource *source)
-{
-	return g_object_new (e_cal_backend_weather_get_type (),
-			     "source", source,
-			     "kind", ICAL_VEVENT_COMPONENT,
-			     NULL);
-}
-
 static icalcomponent_kind
 _events_get_kind (ECalBackendFactory *factory)
 {
 	return ICAL_VEVENT_COMPONENT;
 }
 
+static ECalBackend *
+_events_new_backend (ECalBackendFactory *factory,
+                     ESource *source)
+{
+	return g_object_new (
+		e_cal_backend_weather_get_type (),
+		"kind", ICAL_VEVENT_COMPONENT,
+		"source", source, NULL);
+}
+
 static void
-events_backend_factory_class_init (ECalBackendWeatherFactoryClass *klass)
+e_cal_backend_weather_events_factory_class_init (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;
+	class->get_protocol = _get_protocol;
+	class->get_kind     = _events_get_kind;
+	class->new_backend  = _events_new_backend;
 }
 
-static GType
-events_backend_factory_get_type (GTypeModule *module)
+static void
+e_cal_backend_weather_events_factory_class_finalize (ECalBackendFactoryClass *class)
 {
-	GType type;
-	GTypeInfo info = {
-		sizeof (ECalBackendWeatherFactoryClass),
-		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_weather_factory_instance_init
-	};
-	type = g_type_module_register_type (module,
-					    E_TYPE_CAL_BACKEND_FACTORY,
-					    "ECalBackendWeatherEventsFactory",
-					    &info, 0);
-
-	return type;
 }
 
-static GType weather_type[1];
+static void
+e_cal_backend_weather_events_factory_init (ECalBackendFactory *factory)
+{
+}
 
 void
-eds_module_initialize (GTypeModule *module)
+eds_module_initialize (GTypeModule *type_module)
 {
-	weather_type[0] = events_backend_factory_get_type (module);
+	e_source_weather_type_register (type_module);
+	e_cal_backend_weather_events_factory_register_type (type_module);
 }
 
 void
@@ -108,6 +94,10 @@ eds_module_shutdown (void)
 void
 eds_module_list_types (const GType **types, gint *num_types)
 {
-	*types = weather_type;
-	*num_types = 1;
+	static GType weather_types[1];
+
+	weather_types[0] = e_cal_backend_weather_events_factory_get_type ();
+
+	*types = weather_types;
+	*num_types = G_N_ELEMENTS (weather_types);
 }
diff --git a/calendar/backends/weather/e-cal-backend-weather.c b/calendar/backends/weather/e-cal-backend-weather.c
index 6e62126..bf90858 100644
--- a/calendar/backends/weather/e-cal-backend-weather.c
+++ b/calendar/backends/weather/e-cal-backend-weather.c
@@ -23,9 +23,11 @@
 #include <libedata-cal/e-cal-backend-file-store.h>
 #include <libedata-cal/e-cal-backend-util.h>
 #include <libedata-cal/e-cal-backend-sexp.h>
+#include <libedataserver/e-source-refresh.h>
 #include <glib/gi18n-lib.h>
 #include <string.h>
 #include "e-cal-backend-weather.h"
+#include "e-source-weather.h"
 #include "e-weather-source.h"
 
 #define GWEATHER_I_KNOW_THIS_IS_UNSTABLE
@@ -62,7 +64,6 @@ struct _ECalBackendWeatherPrivate {
 
 	/* Reload */
 	guint reload_timeout_id;
-	guint source_changed_id;
 	guint is_loading : 1;
 
 	/* Flags */
@@ -96,20 +97,13 @@ reload_cb (ECalBackendWeather *cbw)
 }
 
 static void
-source_changed (ESource *source, ECalBackendWeather *cbw)
-{
-	/* FIXME
-	 * We should force a reload of the data when this gets called. Unfortunately,
-	 * this signal isn't getting through from evolution to the backend
-	 */
-}
-
-static void
 maybe_start_reload_timeout (ECalBackendWeather *cbw)
 {
 	ECalBackendWeatherPrivate *priv;
 	ESource *source;
-	const gchar *refresh_str;
+	ESourceRefresh *extension;
+	const gchar *extension_name;
+	guint interval_in_minutes;
 
 	priv = cbw->priv;
 
@@ -117,25 +111,21 @@ maybe_start_reload_timeout (ECalBackendWeather *cbw)
 		return;
 
 	source = e_cal_backend_get_source (E_CAL_BACKEND (cbw));
-	if (!source) {
-		g_warning ("Could not get source for ECalBackendWeather reload.");
-		return;
-	}
 
-	if (priv->source_changed_id == 0)
-		priv->source_changed_id = g_signal_connect (G_OBJECT (source),
-							    "changed",
-							    G_CALLBACK (source_changed),
-							    cbw);
+	extension_name = E_SOURCE_EXTENSION_REFRESH;
+	extension = e_source_get_extension (source, extension_name);
 
-	refresh_str = e_source_get_property (source, "refresh");
+	/* By default, reload every 4 hours. At least for CCF, the forecasts
+	 * only come out twice a day, and chances are while the NWS and similar
+	 * organizations have some serious bandwidth, they would appreciate it
+	 * if we didn't hammer their servers. */
+	interval_in_minutes =
+		e_source_refresh_get_interval_minutes (extension);
+	if (interval_in_minutes == 0)
+		interval_in_minutes = 240;
 
-	/* By default, reload every 4 hours. At least for CCF, the forecasts only come out
-	 * twice a day, and chances are while the NWS and similar organizations have some
-	 * serious bandwidth, they would appreciate it if we didn't hammer their servers
-	 */
-	priv->reload_timeout_id = g_timeout_add ((refresh_str ? atoi (refresh_str) : 240) * 60000,
-						 (GSourceFunc) reload_cb, cbw);
+	priv->reload_timeout_id = g_timeout_add_seconds (
+		interval_in_minutes * 60, (GSourceFunc) reload_cb, cbw);
 
 }
 
@@ -251,15 +241,27 @@ static gboolean
 begin_retrieval_cb (ECalBackendWeather *cbw)
 {
 	ECalBackendWeatherPrivate *priv = cbw->priv;
+	ESourceWeather *extension;
+	ESource *e_source;
 	GSource *source;
+	const gchar *extension_name;
+	const gchar *location;
+
+	/* XXX Too much overloading of the word 'source' here! */
 
 	if (priv->mode != CAL_MODE_REMOTE)
 		return TRUE;
 
 	maybe_start_reload_timeout (cbw);
 
+	e_source = e_cal_backend_get_source (E_CAL_BACKEND (cbw));
+
+	extension_name = E_SOURCE_EXTENSION_WEATHER_BACKEND;
+	extension = e_source_get_extension (e_source, extension_name);
+	location = e_source_weather_get_location (extension);
+
 	if (priv->source == NULL)
-		priv->source = e_weather_source_new (e_cal_backend_get_uri (E_CAL_BACKEND (cbw)));
+		priv->source = e_weather_source_new (location);
 
 	source = g_main_current_source ();
 
@@ -271,7 +273,9 @@ begin_retrieval_cb (ECalBackendWeather *cbw)
 
 	priv->is_loading = TRUE;
 
-	e_weather_source_parse (priv->source, (EWeatherSourceFinished) finished_retrieval_cb, cbw);
+	e_weather_source_parse (
+		priv->source, (EWeatherSourceFinished)
+		finished_retrieval_cb, cbw);
 
 	return FALSE;
 }
@@ -323,11 +327,13 @@ create_weather (ECalBackendWeather *cbw, WeatherInfo *report, gboolean is_foreca
 	GSList                    *text_list = NULL;
 	ECalComponentText         *description;
 	ESource                   *source;
-	gboolean                   metric;
-	const gchar                *tmp;
+	const gchar               *tmp;
 	time_t			   update_time;
 	icaltimezone		  *update_zone = NULL;
+	ESourceWeather            *extension;
+	const gchar               *extension_name;
 	const WeatherLocation     *location;
+	ESourceWeatherUnits        units;
 
 	g_return_val_if_fail (E_IS_CAL_BACKEND_WEATHER (cbw), NULL);
 
@@ -337,21 +343,16 @@ create_weather (ECalBackendWeather *cbw, WeatherInfo *report, gboolean is_foreca
 	priv = cbw->priv;
 
 	source = e_cal_backend_get_source (E_CAL_BACKEND (cbw));
-	tmp = e_source_get_property (source, "units");
-	if (tmp == NULL) {
-		tmp = e_source_get_property (source, "temperature");
-		if (tmp == NULL)
-			metric = FALSE;
-		else
-			metric = (strcmp (tmp, "fahrenheit") != 0);
-	} else {
-		metric = (strcmp (tmp, "metric") == 0);
-	}
 
-	if (metric)
-		weather_info_to_metric (report);
-	else
+	extension_name = E_SOURCE_EXTENSION_WEATHER_BACKEND;
+	extension = e_source_get_extension (source, extension_name);
+	units = e_source_weather_get_units (extension);
+
+	/* Prefer metric if units is invalid. */
+	if (units == E_SOURCE_WEATHER_UNITS_IMPERIAL)
 		weather_info_to_imperial (report);
+	else
+		weather_info_to_metric (report);
 
 	/* create the component and event object */
 	ical_comp = icalcomponent_new (ICAL_VEVENT_COMPONENT);
@@ -499,18 +500,25 @@ e_cal_backend_weather_open (ECalBackendSync *backend, EDataCal *cal, gboolean on
 {
 	ECalBackendWeather *cbw;
 	ECalBackendWeatherPrivate *priv;
+	ESource *source;
+	ESourceWeather *extension;
+	const gchar *extension_name;
 	const gchar *cache_dir;
-	const gchar *uri;
+	const gchar *location;
 
 	cbw = E_CAL_BACKEND_WEATHER (backend);
 	priv = cbw->priv;
 
-	uri = e_cal_backend_get_uri (E_CAL_BACKEND (backend));
+	source = e_cal_backend_get_source (E_CAL_BACKEND (backend));
 	cache_dir = e_cal_backend_get_cache_dir (E_CAL_BACKEND (backend));
 
+	extension_name = E_SOURCE_EXTENSION_WEATHER_BACKEND;
+	extension = e_source_get_extension (source, extension_name);
+	location = e_source_weather_get_location (extension);
+
 	if (priv->city)
 		g_free (priv->city);
-	priv->city = g_strdup (strrchr (uri, '/') + 1);
+	priv->city = g_strdup (strrchr (location, '/') + 1);
 
 	if (!priv->store) {
 		e_cal_backend_cache_remove (cache_dir, "cache.xml");
@@ -562,24 +570,6 @@ e_cal_backend_weather_refresh (ECalBackendSync *backend, EDataCal *cal, GError *
 }
 
 static void
-e_cal_backend_weather_remove (ECalBackendSync *backend, EDataCal *cal, GError **perror)
-{
-	ECalBackendWeather *cbw;
-	ECalBackendWeatherPrivate *priv;
-
-	cbw = E_CAL_BACKEND_WEATHER (backend);
-	priv = cbw->priv;
-
-	if (!priv->store) {
-		/* lie here a bit, but otherwise the calendar will not be removed, even it should */
-		g_print (G_STRLOC ": Doesn't have a cache?!?");
-		return;
-	}
-
-	e_cal_backend_store_remove (priv->store);
-}
-
-static void
 e_cal_backend_weather_discard_alarm (ECalBackendSync *backend, EDataCal *cal, const gchar *uid, const gchar *auid, GError **perror)
 {
 }
@@ -753,6 +743,24 @@ e_cal_backend_weather_is_loaded (ECalBackend *backend)
 	return TRUE;
 }
 
+static gboolean
+e_cal_backend_weather_remove (ECalBackend *backend,
+                              GError **error)
+{
+	ECalBackendWeather *cbw;
+	ECalBackendWeatherPrivate *priv;
+
+	cbw = E_CAL_BACKEND_WEATHER (backend);
+	priv = cbw->priv;
+
+	if (!priv->store)
+		return TRUE;
+
+	e_cal_backend_store_remove (priv->store);
+
+	return TRUE;
+}
+
 static void e_cal_backend_weather_start_query (ECalBackend *backend, EDataCalView *query)
 {
 	ECalBackendWeather *cbw;
@@ -963,7 +971,6 @@ e_cal_backend_weather_init (ECalBackendWeather *cbw)
 	cbw->priv = priv;
 
 	priv->reload_timeout_id = 0;
-	priv->source_changed_id = 0;
 	priv->begin_retrival_id = 0;
 	priv->opened = FALSE;
 	priv->source = NULL;
@@ -998,7 +1005,6 @@ e_cal_backend_weather_class_init (ECalBackendWeatherClass *class)
 	sync_class->get_static_capabilities_sync = e_cal_backend_weather_get_static_capabilities;
 	sync_class->open_sync = e_cal_backend_weather_open;
 	sync_class->refresh_sync = e_cal_backend_weather_refresh;
-	sync_class->remove_sync = e_cal_backend_weather_remove;
 	sync_class->discard_alarm_sync = e_cal_backend_weather_discard_alarm;
 	sync_class->receive_objects_sync = e_cal_backend_weather_receive_objects;
 	sync_class->get_default_object_sync = e_cal_backend_weather_get_default_object;
@@ -1008,11 +1014,16 @@ e_cal_backend_weather_class_init (ECalBackendWeatherClass *class)
 	sync_class->set_default_zone_sync = e_cal_backend_weather_set_default_zone;
 	sync_class->get_freebusy_sync = e_cal_backend_weather_get_free_busy;
 	sync_class->get_changes_sync = e_cal_backend_weather_get_changes;
+
 	backend_class->is_loaded = e_cal_backend_weather_is_loaded;
+	backend_class->remove = e_cal_backend_weather_remove;
 	backend_class->start_query = e_cal_backend_weather_start_query;
 	backend_class->get_mode = e_cal_backend_weather_get_mode;
 	backend_class->set_mode = e_cal_backend_weather_set_mode;
 
 	backend_class->internal_get_default_timezone = e_cal_backend_weather_internal_get_default_timezone;
 	backend_class->internal_get_timezone = e_cal_backend_weather_internal_get_timezone;
+
+	/* Register our ESource extension. */
+	E_TYPE_SOURCE_WEATHER;
 }
diff --git a/calendar/backends/weather/e-source-weather.c b/calendar/backends/weather/e-source-weather.c
new file mode 100644
index 0000000..7db5e99
--- /dev/null
+++ b/calendar/backends/weather/e-source-weather.c
@@ -0,0 +1,224 @@
+/*
+ * e-source-weather.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 <webcal://www.gnu.org/licenses/>
+ *
+ */
+
+#include "e-source-weather.h"
+
+#define E_SOURCE_WEATHER_GET_PRIVATE(obj) \
+	(G_TYPE_INSTANCE_GET_PRIVATE \
+	((obj), E_TYPE_SOURCE_WEATHER, ESourceWeatherPrivate))
+
+struct _ESourceWeatherPrivate {
+	ESourceWeatherUnits units;
+	gchar *location;
+};
+
+enum {
+	PROP_0,
+	PROP_LOCATION,
+	PROP_UNITS
+};
+
+static GType e_source_weather_units_type = G_TYPE_INVALID;
+
+G_DEFINE_DYNAMIC_TYPE (
+	ESourceWeather,
+	e_source_weather,
+	E_TYPE_SOURCE_EXTENSION)
+
+static void
+source_weather_set_property (GObject *object,
+                             guint property_id,
+                             const GValue *value,
+                             GParamSpec *pspec)
+{
+	switch (property_id) {
+		case PROP_LOCATION:
+			e_source_weather_set_location (
+				E_SOURCE_WEATHER (object),
+				g_value_get_string (value));
+			return;
+
+		case PROP_UNITS:
+			e_source_weather_set_units (
+				E_SOURCE_WEATHER (object),
+				g_value_get_enum (value));
+			return;
+	}
+
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+source_weather_get_property (GObject *object,
+                             guint property_id,
+                             GValue *value,
+                             GParamSpec *pspec)
+{
+	switch (property_id) {
+		case PROP_LOCATION:
+			g_value_set_string (
+				value,
+				e_source_weather_get_location (
+				E_SOURCE_WEATHER (object)));
+			return;
+
+		case PROP_UNITS:
+			g_value_set_enum (
+				value,
+				e_source_weather_get_units (
+				E_SOURCE_WEATHER (object)));
+			return;
+	}
+
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+source_weather_finalize (GObject *object)
+{
+	ESourceWeatherPrivate *priv;
+
+	priv = E_SOURCE_WEATHER_GET_PRIVATE (object);
+
+	g_free (priv->location);
+
+	/* Chain up to parent's finalize() method. */
+	G_OBJECT_CLASS (e_source_weather_parent_class)->finalize (object);
+}
+
+static void
+e_source_weather_class_init (ESourceWeatherClass *class)
+{
+	GObjectClass *object_class;
+	ESourceExtensionClass *extension_class;
+
+	g_type_class_add_private (class, sizeof (ESourceWeatherPrivate));
+
+	object_class = G_OBJECT_CLASS (class);
+	object_class->set_property = source_weather_set_property;
+	object_class->get_property = source_weather_get_property;
+	object_class->finalize = source_weather_finalize;
+
+	extension_class = E_SOURCE_EXTENSION_CLASS (class);
+	extension_class->name = E_SOURCE_EXTENSION_WEATHER_BACKEND;
+
+	g_object_class_install_property (
+		object_class,
+		PROP_LOCATION,
+		g_param_spec_string (
+			"location",
+			"Location",
+			"Weather location code",
+			NULL,
+			G_PARAM_READWRITE |
+			G_PARAM_CONSTRUCT |
+			E_SOURCE_PARAM_SETTING));
+
+	g_object_class_install_property (
+		object_class,
+		PROP_UNITS,
+		g_param_spec_enum (
+			"units",
+			"Units",
+			"Metric or imperial units",
+			E_TYPE_SOURCE_WEATHER_UNITS,
+			E_SOURCE_WEATHER_UNITS_METRIC,
+			G_PARAM_READWRITE |
+			G_PARAM_CONSTRUCT |
+			E_SOURCE_PARAM_SETTING));
+}
+
+static void
+e_source_weather_class_finalize (ESourceWeatherClass *class)
+{
+}
+
+static void
+e_source_weather_init (ESourceWeather *extension)
+{
+	extension->priv = E_SOURCE_WEATHER_GET_PRIVATE (extension);
+}
+
+void
+e_source_weather_type_register (GTypeModule *type_module)
+{
+	static const GEnumValue e_source_weather_units_values[] = {
+		{ E_SOURCE_WEATHER_UNITS_METRIC,
+		  "E_SOURCE_WEATHER_UNITS_METRIC",
+		  "metric" },
+		{ E_SOURCE_WEATHER_UNITS_IMPERIAL,
+		  "E_SOURCE_WEATHER_UNITS_IMPERIAL",
+		  "imperial" },
+		{ 0, NULL, NULL }
+	};
+
+	e_source_weather_units_type =
+		g_type_module_register_enum (
+		type_module, "ESourceWeatherUnits",
+		e_source_weather_units_values);
+
+	/* 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_weather_register_type (type_module);
+}
+
+const gchar *
+e_source_weather_get_location (ESourceWeather *extension)
+{
+	g_return_val_if_fail (E_IS_SOURCE_WEATHER (extension), NULL);
+
+	return extension->priv->location;
+}
+
+void
+e_source_weather_set_location (ESourceWeather *extension,
+                               const gchar *location)
+{
+	g_return_if_fail (E_IS_SOURCE_WEATHER (extension));
+
+	g_free (extension->priv->location);
+	extension->priv->location = g_strdup (location);
+
+	g_object_notify (G_OBJECT (extension), "location");
+}
+
+ESourceWeatherUnits
+e_source_weather_get_units (ESourceWeather *extension)
+{
+	g_return_val_if_fail (E_IS_SOURCE_WEATHER (extension), 0);
+
+	return extension->priv->units;
+}
+
+void
+e_source_weather_set_units (ESourceWeather *extension,
+                            ESourceWeatherUnits units)
+{
+	g_return_if_fail (E_IS_SOURCE_WEATHER (extension));
+
+	extension->priv->units = units;
+
+	g_object_notify (G_OBJECT (extension), "units");
+}
+
+ESourceWeatherUnits
+e_source_weather_units_get_type (void)
+{
+	return e_source_weather_units_type;
+}
diff --git a/calendar/backends/weather/e-source-weather.h b/calendar/backends/weather/e-source-weather.h
new file mode 100644
index 0000000..85bb2f3
--- /dev/null
+++ b/calendar/backends/weather/e-source-weather.h
@@ -0,0 +1,82 @@
+/*
+ * e-source-weather.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 <webcal://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef E_SOURCE_WEATHER_H
+#define E_SOURCE_WEATHER_H
+
+#include <libedataserver/e-source-extension.h>
+
+/* Standard GObject macros */
+#define E_TYPE_SOURCE_WEATHER \
+	(e_source_weather_get_type ())
+#define E_SOURCE_WEATHER(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), E_TYPE_SOURCE_WEATHER, ESourceWeather))
+#define E_SOURCE_WEATHER_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_CAST \
+	((cls), E_TYPE_SOURCE_WEATHER, ESourceWeatherClass))
+#define E_IS_SOURCE_WEATHER(obj) \
+	(G_TYPE_CHECK_INSTANCE_TYPE \
+	((obj), E_TYPE_SOURCE_WEATHER))
+#define E_IS_SOURCE_WEATHER_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_TYPE \
+	((cls), E_TYPE_SOURCE_WEATHER))
+#define E_SOURCE_WEATHER_GET_CLASS(obj) \
+	(G_TYPE_INSTANCE_GET_CLASS \
+	((obj), E_TYPE_SOURCE_WEATHER, ESourceWeatherClass))
+
+#define E_TYPE_SOURCE_WEATHER_UNITS \
+	(e_source_weather_units_get_type ())
+
+#define E_SOURCE_EXTENSION_WEATHER_BACKEND "Weather Backend"
+
+G_BEGIN_DECLS
+
+typedef struct _ESourceWeather ESourceWeather;
+typedef struct _ESourceWeatherClass ESourceWeatherClass;
+typedef struct _ESourceWeatherPrivate ESourceWeatherPrivate;
+
+struct _ESourceWeather {
+	ESourceExtension parent;
+	ESourceWeatherPrivate *priv;
+};
+
+struct _ESourceWeatherClass {
+	ESourceExtensionClass parent_class;
+};
+
+typedef enum {
+	E_SOURCE_WEATHER_UNITS_METRIC,
+	E_SOURCE_WEATHER_UNITS_IMPERIAL
+} ESourceWeatherUnits;
+
+GType		e_source_weather_get_type	(void);
+void		e_source_weather_type_register	(GTypeModule *type_module);
+const gchar *	e_source_weather_get_location	(ESourceWeather *extension);
+void		e_source_weather_set_location	(ESourceWeather *extension,
+						 const gchar *location);
+ESourceWeatherUnits
+		e_source_weather_get_units	(ESourceWeather *extension);
+void		e_source_weather_set_units	(ESourceWeather *extension,
+						 ESourceWeatherUnits units);
+
+GType		e_source_weather_units_get_type		(void);
+
+G_END_DECLS
+
+#endif /* E_SOURCE_WEATHER_H */
diff --git a/calendar/backends/weather/e-weather-source-ccf.c b/calendar/backends/weather/e-weather-source-ccf.c
index f20b802..94bd772 100644
--- a/calendar/backends/weather/e-weather-source-ccf.c
+++ b/calendar/backends/weather/e-weather-source-ccf.c
@@ -114,38 +114,6 @@ done:
 	return search.location;
 }
 
-EWeatherSource*
-e_weather_source_ccf_new (const gchar *uri)
-{
-	/* Old URI is formatted as weather://ccf/AAA[/BBB] - AAA is the 3-letter station
-	 * code for identifying the providing station (subdirectory within the crh data
-	 * repository). BBB is an optional additional station ID for the station within
-	 * the CCF file. If not present, BBB is assumed to be the same station as AAA.
-	 * But the new URI is as weather://code/name, where code is 4-letter code.
-	 * So if got the old URI, then migrate to the new one, if possible.
-	 */
-
-	WeatherLocation *wl;
-	EWeatherSourceCCF *source;
-
-	if (!uri)
-		return NULL;
-
-	if (strncmp (uri, "ccf/", 4) == 0)
-		wl = find_location (uri + 4, TRUE);
-	else
-		wl = find_location (uri, FALSE);
-
-	if (!wl)
-		return NULL;
-
-	source = E_WEATHER_SOURCE_CCF (g_object_new (e_weather_source_ccf_get_type (), NULL));
-	source->location = wl;
-	source->info = NULL;
-
-	return E_WEATHER_SOURCE (source);
-}
-
 #if 0
 static GSList*
 tokenize (gchar *buffer)
@@ -416,7 +384,9 @@ parse_done (WeatherInfo *info, gpointer data)
 }
 
 static void
-e_weather_source_ccf_parse (EWeatherSource *source, EWeatherSourceFinished done, gpointer data)
+e_weather_source_ccf_parse (EWeatherSource *source,
+                            EWeatherSourceFinished done,
+                            gpointer data)
 {
 	EWeatherSourceCCF *ccfsource = (EWeatherSourceCCF*) source;
 	WeatherPrefs prefs;
@@ -446,8 +416,7 @@ e_weather_source_ccf_class_init (EWeatherSourceCCFClass *class)
 {
 	EWeatherSourceClass *source_class;
 
-	source_class = (EWeatherSourceClass *) class;
-
+	source_class = E_WEATHER_SOURCE_CLASS (class);
 	source_class->parse = e_weather_source_ccf_parse;
 }
 
@@ -457,3 +426,37 @@ e_weather_source_ccf_init (EWeatherSourceCCF *source)
 	source->location = NULL;
 	source->info = NULL;
 }
+
+EWeatherSource *
+e_weather_source_ccf_new (const gchar *location)
+{
+	/* Old location is formatted as ccf/AAA[/BBB] - AAA is the 3-letter
+	 * station code for identifying the providing station (subdirectory
+	 * within the crh data repository). BBB is an optional additional
+	 * station ID for the station within the CCF file. If not present,
+	 * BBB is assumed to be the same station as AAA.  But the new
+	 * location is code/name, where code is 4-letter code.  So if we
+	 * got the old format, then migrate to the new one, if possible.
+	 */
+
+	WeatherLocation *wl;
+	EWeatherSourceCCF *source;
+
+	if (location == NULL)
+		return NULL;
+
+	if (strncmp (location, "ccf/", 4) == 0)
+		wl = find_location (location + 4, TRUE);
+	else
+		wl = find_location (location, FALSE);
+
+	if (wl == NULL)
+		return NULL;
+
+	source = g_object_new (E_TYPE_WEATHER_SOURCE_CCF, NULL);
+	source->location = wl;
+	source->info = NULL;
+
+	return E_WEATHER_SOURCE (source);
+}
+
diff --git a/calendar/backends/weather/e-weather-source-ccf.h b/calendar/backends/weather/e-weather-source-ccf.h
index ad697f8..e0ae161 100644
--- a/calendar/backends/weather/e-weather-source-ccf.h
+++ b/calendar/backends/weather/e-weather-source-ccf.h
@@ -30,13 +30,26 @@
 #include <libgweather/weather.h>
 #undef GWEATHER_I_KNOW_THIS_IS_UNSTABLE
 
-G_BEGIN_DECLS
+/* Standard GObject macros */
+#define E_TYPE_WEATHER_SOURCE_CCF \
+	(e_weather_source_ccf_get_type ())
+#define E_WEATHER_SOURCE_CCF(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), E_TYPE_WEATHER_SOURCE_CCF, EWeatherSourceCCF))
+#define E_WEATHER_SOURCE_CCF_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_CAST \
+	((cls), E_TYPE_WEATHER_SOURCE_CCF, EWeatherSourceCCF))
+#define E_IS_WEATHER_SOURCE_CCF(obj) \
+	(G_TYPE_CHECK_INSTANCE_TYPE \
+	((obj), E_TYPE_WEATHER_SOURCE_CCF))
+#define E_IS_WEATHER_SOURCE_CCF_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_TYPE \
+	((cls), E_TYPE_WEATHER_SOURCE_CCF))
+#define E_WEATHER_SOURCE_CCF_GET_CLASS(obj) \
+	(G_TYPE_INSTANCE_GET_CLASS \
+	((obj), E_TYPE_WEATHER_SOURCE_CCF, EWeatherSourceCCF))
 
-#define E_TYPE_WEATHER_SOURCE_CCF            (e_weather_source_ccf_get_type ())
-#define E_WEATHER_SOURCE_CCF(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_WEATHER_SOURCE_CCF, EWeatherSourceCCF))
-#define E_WEATHER_SOURCE_CCF_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_WEATHER_SOURCE_CCF, EWeatherSourceCCF))
-#define E_IS_WEATHER_SOURCE_CCF(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_WEATHER_SOURCE_CCF))
-#define E_IS_WEATHER_SOURCE_CCF_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_WEATHER_SOURCE_CCF))
+G_BEGIN_DECLS
 
 typedef struct _EWeatherSourceCCF EWeatherSourceCCF;
 typedef struct _EWeatherSourceCCFClass EWeatherSourceCCFClass;
@@ -55,9 +68,9 @@ struct _EWeatherSourceCCFClass {
 	EWeatherSourceClass parent_class;
 };
 
-EWeatherSource*	e_weather_source_ccf_new (const gchar *uri);
-GType		e_weather_source_ccf_get_type (void);
+GType		e_weather_source_ccf_get_type	(void);
+EWeatherSource *e_weather_source_ccf_new	(const gchar *location);
 
 G_END_DECLS
 
-#endif
+#endif /* E_WEATHER_SOURCE_CCF_H */
diff --git a/calendar/backends/weather/e-weather-source.c b/calendar/backends/weather/e-weather-source.c
index 539390a..3dd3431 100644
--- a/calendar/backends/weather/e-weather-source.c
+++ b/calendar/backends/weather/e-weather-source.c
@@ -26,11 +26,17 @@
 G_DEFINE_TYPE (EWeatherSource, e_weather_source, G_TYPE_OBJECT)
 
 void
-e_weather_source_parse (EWeatherSource *source, EWeatherSourceFinished done, gpointer data)
+e_weather_source_parse (EWeatherSource *source,
+                        EWeatherSourceFinished done,
+                        gpointer data)
 {
 	EWeatherSourceClass *class;
+
 	g_return_if_fail (source != NULL);
-	class = (EWeatherSourceClass*) G_OBJECT_GET_CLASS (source);
+
+	class = E_WEATHER_SOURCE_GET_CLASS (source);
+	g_return_if_fail (class->parse != NULL);
+
 	class->parse (source, done, data);
 }
 
@@ -46,9 +52,10 @@ e_weather_source_init (EWeatherSource *source)
 	/* nothing to do here */
 }
 
-EWeatherSource*	e_weather_source_new (const gchar *uri)
+EWeatherSource *
+e_weather_source_new (const gchar *location)
 {
-	const gchar *base = uri + 10; /* skip weather:// */
+	g_return_val_if_fail (location != NULL, NULL);
 
-	return e_weather_source_ccf_new (base);
+	return e_weather_source_ccf_new (location);
 }
diff --git a/calendar/backends/weather/e-weather-source.h b/calendar/backends/weather/e-weather-source.h
index 175d9fa..e36793e 100644
--- a/calendar/backends/weather/e-weather-source.h
+++ b/calendar/backends/weather/e-weather-source.h
@@ -28,6 +28,25 @@
 #include <libgweather/weather.h>
 #undef GWEATHER_I_KNOW_THIS_IS_UNSTABLE
 
+/* Standard GObject macros */
+#define E_TYPE_WEATHER_SOURCE \
+	(e_weather_source_get_type ())
+#define E_WEATHER_SOURCE(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), E_TYPE_WEATHER_SOURCE, EWeatherSource))
+#define E_WEATHER_SOURCE_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_CAST \
+	((cls), E_TYPE_WEATHER_SOURCE, EWeatherSourceClass))
+#define E_IS_WEATHER_SOURCE(obj) \
+	(G_TYPE_CHECK_INSTANCE_TYPE \
+	((obj), E_TYPE_WEATHER_SOURCE))
+#define E_IS_WEATHER_SOURCE_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_TYPE \
+	((cls), E_TYPE_WEATHER_SOURCE))
+#define E_WEATHER_SOURCE_GET_CLASS(obj) \
+	(G_TYPE_INSTANCE_GET_CLASS \
+	((obj), E_TYPE_WEATHER_SOURCE, EWeatherSourceClass))
+
 G_BEGIN_DECLS
 
 typedef enum {
@@ -60,12 +79,6 @@ typedef enum {
 
 typedef void (*EWeatherSourceFinished)(WeatherInfo *result, gpointer data);
 
-#define E_TYPE_WEATHER_SOURCE            (e_weather_source_get_type ())
-#define E_WEATHER_SOURCE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_WEATHER_SOURCE, EWeatherSource))
-#define E_WEATHER_SOURCE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_WEATHER_SOURCE, EWeatherSource))
-#define E_IS_WEATHER_SOURCE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_WEATHER_SOURCE))
-#define E_IS_WEATHER_SOURCE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_WEATHER_SOURCE))
-
 typedef struct _EWeatherSource EWeatherSource;
 typedef struct _EWeatherSourceClass EWeatherSourceClass;
 
@@ -73,7 +86,7 @@ typedef struct _EWeatherSourceClass EWeatherSourceClass;
  * All the URL fetching is handled outside of this, and all this has
  * to know how to do is parse the specific format. */
 struct _EWeatherSource {
-	GObject object;
+	GObject parent;
 };
 
 struct _EWeatherSourceClass {
@@ -81,13 +94,17 @@ struct _EWeatherSourceClass {
 
 	/* Returns a list of WeatherForecast objects containing the
 	 * data for the forecast. */
-	void (*parse)	(EWeatherSource *source, EWeatherSourceFinished done, gpointer data);
+	void		(*parse)	(EWeatherSource *source,
+					 EWeatherSourceFinished done,
+					 gpointer data);
 };
 
-EWeatherSource*	e_weather_source_new (const gchar *uri);
-GType	e_weather_source_get_type (void);
-void	e_weather_source_parse (EWeatherSource *source, EWeatherSourceFinished done, gpointer data);
+GType		e_weather_source_get_type	(void);
+EWeatherSource *e_weather_source_new		(const gchar *location);
+void		e_weather_source_parse		(EWeatherSource *source,
+						 EWeatherSourceFinished done,
+						 gpointer data);
 
 G_END_DECLS
 
-#endif
+#endif /* E_WEATHER_SOURCE_H */



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