[evolution-data-server] Bug #494394 - Update backend's ESource on its change immediately
- From: Milan Crha <mcrha src gnome org>
- To: svn-commits-list gnome org
- Subject: [evolution-data-server] Bug #494394 - Update backend's ESource on its change immediately
- Date: Fri, 12 Jun 2009 09:50:15 -0400 (EDT)
commit 1fc363176806463ba89492c405f9198776a494b4
Author: Milan Crha <mcrha redhat com>
Date: Fri Jun 12 15:48:01 2009 +0200
Bug #494394 - Update backend's ESource on its change immediately
calendar/backends/http/e-cal-backend-http.c | 71 +++++++++++++-
calendar/libedata-cal/e-cal-backend-cache.h | 5 +-
calendar/libedata-cal/e-cal-backend.c | 85 ++++++++++++++++-
calendar/libedata-cal/e-cal-backend.h | 4 +
calendar/libedata-cal/e-data-cal-factory.c | 141 ++++++++++++++++++++++++---
libedataserver/e-source.c | 17 +++-
6 files changed, 299 insertions(+), 24 deletions(-)
---
diff --git a/calendar/backends/http/e-cal-backend-http.c b/calendar/backends/http/e-cal-backend-http.c
index 61d0e57..4d64b31 100644
--- a/calendar/backends/http/e-cal-backend-http.c
+++ b/calendar/backends/http/e-cal-backend-http.c
@@ -41,6 +41,8 @@
/* Private part of the ECalBackendHttp structure */
struct _ECalBackendHttpPrivate {
+ /* signal handler id for source's 'changed' signal */
+ gulong source_changed_id;
/* URI to get remote calendar data from */
gchar *uri;
@@ -97,6 +99,13 @@ e_cal_backend_http_dispose (GObject *object)
g_free (priv->username);
g_free (priv->password);
+ priv->username = NULL;
+ priv->password = NULL;
+
+ if (priv->source_changed_id) {
+ g_signal_handler_disconnect (e_cal_backend_get_source (E_CAL_BACKEND (cbhttp)), priv->source_changed_id);
+ priv->source_changed_id = 0;
+ }
if (G_OBJECT_CLASS (parent_class)->dispose)
(* G_OBJECT_CLASS (parent_class)->dispose) (object);
@@ -250,6 +259,12 @@ retrieval_done (SoupSession *session, SoupMessage *msg, ECalBackendHttp *cbhttp)
priv->is_loading = FALSE;
d(g_message ("Retrieval done.\n"));
+ if (!priv->uri) {
+ /* uri changed meanwhile, retrieve again */
+ begin_retrieval_cb (cbhttp);
+ return;
+ }
+
/* Handle redirection ourselves */
if (SOUP_STATUS_IS_REDIRECTION (msg->status_code)) {
newuri = soup_message_headers_get (msg->response_headers,
@@ -278,6 +293,8 @@ retrieval_done (SoupSession *session, SoupMessage *msg, ECalBackendHttp *cbhttp)
e_cal_backend_notify_error (E_CAL_BACKEND (cbhttp),
soup_status_get_phrase (msg->status_code));
}
+
+ e_cal_backend_empty_cache (E_CAL_BACKEND (cbhttp), priv->cache);
return;
}
@@ -287,6 +304,7 @@ retrieval_done (SoupSession *session, SoupMessage *msg, ECalBackendHttp *cbhttp)
if (!icalcomp) {
if (!priv->opened)
e_cal_backend_notify_error (E_CAL_BACKEND (cbhttp), _("Bad file format."));
+ e_cal_backend_empty_cache (E_CAL_BACKEND (cbhttp), priv->cache);
return;
}
@@ -294,6 +312,7 @@ retrieval_done (SoupSession *session, SoupMessage *msg, ECalBackendHttp *cbhttp)
if (!priv->opened)
e_cal_backend_notify_error (E_CAL_BACKEND (cbhttp), _("Not a calendar."));
icalcomponent_free (icalcomp);
+ e_cal_backend_empty_cache (E_CAL_BACKEND (cbhttp), priv->cache);
return;
}
@@ -414,7 +433,7 @@ begin_retrieval_cb (ECalBackendHttp *cbhttp)
priv = cbhttp->priv;
if (priv->mode != CAL_MODE_REMOTE)
- return TRUE;
+ return FALSE;
maybe_start_reload_timeout (cbhttp);
@@ -459,6 +478,7 @@ begin_retrieval_cb (ECalBackendHttp *cbhttp)
soup_message = soup_message_new (SOUP_METHOD_GET, priv->uri);
if (soup_message == NULL) {
priv->is_loading = FALSE;
+ e_cal_backend_empty_cache (E_CAL_BACKEND (cbhttp), priv->cache);
return FALSE;
}
@@ -517,6 +537,37 @@ maybe_start_reload_timeout (ECalBackendHttp *cbhttp)
(GSourceFunc) reload_cb, cbhttp);
}
+static void
+source_changed_cb (ESource *source, ECalBackendHttp *cbhttp)
+{
+ ECalBackendHttpPrivate *priv;
+
+ g_return_if_fail (cbhttp != NULL);
+ g_return_if_fail (cbhttp->priv != NULL);
+
+ priv = cbhttp->priv;
+
+ if (priv->uri) {
+ ESource *source = e_cal_backend_get_source (E_CAL_BACKEND (cbhttp));
+ const gchar *secure_prop = e_source_get_property (source, "use_ssl");
+ gchar *new_uri;
+
+ new_uri = webcal_to_http_method (e_cal_backend_get_uri (E_CAL_BACKEND (cbhttp)),
+ (secure_prop && g_str_equal(secure_prop, "1")));
+
+ if (new_uri && !g_str_equal (priv->uri, new_uri)) {
+ /* uri changed, do reload some time soon */
+ g_free (priv->uri);
+ priv->uri = NULL;
+
+ if (!priv->is_loading)
+ g_idle_add ((GSourceFunc) begin_retrieval_cb, cbhttp);
+ }
+
+ g_free (new_uri);
+ }
+}
+
/* Open handler for the file backend */
static ECalBackendSyncStatus
e_cal_backend_http_open (ECalBackendSync *backend, EDataCal *cal, gboolean only_if_exists,
@@ -525,11 +576,21 @@ e_cal_backend_http_open (ECalBackendSync *backend, EDataCal *cal, gboolean only_
ECalBackendHttp *cbhttp;
ECalBackendHttpPrivate *priv;
ESource *source;
+ gchar *tmp;
cbhttp = E_CAL_BACKEND_HTTP (backend);
priv = cbhttp->priv;
source = e_cal_backend_get_source (E_CAL_BACKEND (backend));
+ if (priv->source_changed_id == 0) {
+ priv->source_changed_id = g_signal_connect (source, "changed", G_CALLBACK (source_changed_cb), cbhttp);
+ }
+
+ /* always read uri again */
+ tmp = priv->uri;
+ priv->uri = NULL;
+ g_free (tmp);
+
if (e_source_get_property (source, "auth") != NULL) {
if ((username == NULL || password == NULL)) {
return GNOME_Evolution_Calendar_AuthenticationRequired;
@@ -565,13 +626,13 @@ e_cal_backend_http_open (ECalBackendSync *backend, EDataCal *cal, gboolean only_
if (priv->default_zone) {
e_cal_backend_cache_put_default_timezone (priv->cache, priv->default_zone);
}
+ }
- if (priv->mode == CAL_MODE_LOCAL)
- return GNOME_Evolution_Calendar_Success;
+ if (priv->mode == CAL_MODE_LOCAL)
+ return GNOME_Evolution_Calendar_Success;
- g_idle_add ((GSourceFunc) begin_retrieval_cb, cbhttp);
- }
+ g_idle_add ((GSourceFunc) begin_retrieval_cb, cbhttp);
return GNOME_Evolution_Calendar_Success;
}
diff --git a/calendar/libedata-cal/e-cal-backend-cache.h b/calendar/libedata-cal/e-cal-backend-cache.h
index 725a22e..15c694a 100644
--- a/calendar/libedata-cal/e-cal-backend-cache.h
+++ b/calendar/libedata-cal/e-cal-backend-cache.h
@@ -34,12 +34,13 @@ G_BEGIN_DECLS
#define E_IS_CAL_BACKEND_CACHE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_CAL_BACKEND_CACHE))
#define E_IS_CAL_BACKEND_CACHE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_CAL_BACKEND_CACHE))
+typedef struct _ECalBackendCache ECalBackendCache;
typedef struct _ECalBackendCachePrivate ECalBackendCachePrivate;
-typedef struct {
+struct _ECalBackendCache {
EFileCache parent;
ECalBackendCachePrivate *priv;
-} ECalBackendCache;
+};
typedef struct {
EFileCacheClass parent_class;
diff --git a/calendar/libedata-cal/e-cal-backend.c b/calendar/libedata-cal/e-cal-backend.c
index 7bc19c0..1d9345e 100644
--- a/calendar/libedata-cal/e-cal-backend.c
+++ b/calendar/libedata-cal/e-cal-backend.c
@@ -27,6 +27,7 @@
#include <libxml/xmlmemory.h>
#include "e-cal-backend.h"
+#include "e-cal-backend-cache.h"
@@ -36,6 +37,8 @@ G_DEFINE_TYPE (ECalBackend, e_cal_backend, G_TYPE_OBJECT)
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;
@@ -86,6 +89,29 @@ 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)
{
ECalBackend *backend;
@@ -99,9 +125,16 @@ e_cal_backend_set_property (GObject *object, guint property_id, const GValue *va
{
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)
+ 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);
@@ -275,6 +308,10 @@ e_cal_backend_finalize (GObject *object)
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);
@@ -1456,3 +1493,49 @@ e_cal_backend_notify_error (ECalBackend *backend, const gchar *message)
for (l = priv->clients; l; l = l->next)
e_data_cal_notify_error (l->data, message);
}
+
+/**
+ * e_cal_backend_empty_cache:
+ * @backend: A calendar backend.
+ * @cache: Backend's cache to empty.
+ *
+ * Empties backend's cache with all notifications and so on, thus all listening
+ * will know there is nothing in this backend.
+ **/
+void
+e_cal_backend_empty_cache (ECalBackend *backend, ECalBackendCache *cache)
+{
+ GList *comps_in_cache;
+
+ g_return_if_fail (backend != NULL);
+ g_return_if_fail (E_IS_CAL_BACKEND (backend));
+
+ if (!cache)
+ return;
+
+ g_return_if_fail (E_IS_CAL_BACKEND_CACHE (cache));
+
+ e_file_cache_freeze_changes (E_FILE_CACHE (cache));
+
+ for (comps_in_cache = e_cal_backend_cache_get_components (cache);
+ comps_in_cache;
+ comps_in_cache = comps_in_cache->next) {
+ gchar *comp_str;
+ ECalComponentId *id;
+ ECalComponent *comp = comps_in_cache->data;
+
+ id = e_cal_component_get_id (comp);
+ comp_str = e_cal_component_get_as_string (comp);
+
+ e_cal_backend_cache_remove_component (cache, id->uid, id->rid);
+ e_cal_backend_notify_object_removed (backend, id, comp_str, NULL);
+
+ g_free (comp_str);
+ e_cal_component_free_id (id);
+ g_object_unref (comp);
+ }
+
+ g_list_free (comps_in_cache);
+
+ e_file_cache_thaw_changes (E_FILE_CACHE (cache));
+}
diff --git a/calendar/libedata-cal/e-cal-backend.h b/calendar/libedata-cal/e-cal-backend.h
index dd5c857..ea1fc81 100644
--- a/calendar/libedata-cal/e-cal-backend.h
+++ b/calendar/libedata-cal/e-cal-backend.h
@@ -44,6 +44,8 @@ G_BEGIN_DECLS
#define E_IS_CAL_BACKEND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_CAL_BACKEND))
#define E_CAL_BACKEND_GET_CLASS(obj) (E_CAL_BACKEND_CLASS (G_OBJECT_GET_CLASS (obj)))
+struct _ECalBackendCache;
+
typedef struct _ECalBackendPrivate ECalBackendPrivate;
struct _ECalBackend {
@@ -188,6 +190,8 @@ void e_cal_backend_notify_objects_added (ECalBackend *backend, EDataCalView *que
void e_cal_backend_notify_objects_removed (ECalBackend *backend, EDataCalView *query, const GList *ids);
void e_cal_backend_notify_objects_modified (ECalBackend *backend, EDataCalView *query, const GList *objects);
+void e_cal_backend_empty_cache (ECalBackend *backend, struct _ECalBackendCache *cache);
+
G_END_DECLS
#endif
diff --git a/calendar/libedata-cal/e-data-cal-factory.c b/calendar/libedata-cal/e-data-cal-factory.c
index 2c4da5b..090c323 100644
--- a/calendar/libedata-cal/e-data-cal-factory.c
+++ b/calendar/libedata-cal/e-data-cal-factory.c
@@ -25,7 +25,9 @@
#include <bonobo/bonobo-main.h>
#include "libedataserver/e-url.h"
#include "libedataserver/e-source.h"
+#include "libedataserver/e-source-list.h"
#include "libebackend/e-data-server-module.h"
+#include "libecal/e-cal.h"
#include "e-cal-backend.h"
#include "e-data-cal.h"
#include "e-data-cal-factory.h"
@@ -52,6 +54,12 @@ struct _EDataCalFactoryPrivate {
guint registered : 1;
gint mode;
+
+ /* this is for notifications of source changes */
+ ESourceList *lists[E_CAL_SOURCE_TYPE_LAST];
+
+ /* backends divided by their type */
+ GSList *backends_by_type[E_CAL_SOURCE_TYPE_LAST];
};
/* Signal IDs */
@@ -79,6 +87,74 @@ calobjtype_to_icalkind (const GNOME_Evolution_Calendar_CalObjType type)
return ICAL_NO_COMPONENT;
}
+static ECalSourceType
+icalkind_to_ecalsourcetype (const icalcomponent_kind kind)
+{
+ switch (kind) {
+ case ICAL_VEVENT_COMPONENT:
+ return E_CAL_SOURCE_TYPE_EVENT;
+ case ICAL_VTODO_COMPONENT:
+ return E_CAL_SOURCE_TYPE_TODO;
+ case ICAL_VJOURNAL_COMPONENT:
+ return E_CAL_SOURCE_TYPE_JOURNAL;
+ default:
+ break;
+ }
+
+ return E_CAL_SOURCE_TYPE_LAST;
+}
+
+static void
+update_source_in_backend (ECalBackend *backend, ESource *updated_source)
+{
+ xmlNodePtr xml;
+
+ g_return_if_fail (backend != NULL);
+ g_return_if_fail (updated_source != NULL);
+
+ xml = xmlNewNode (NULL, (const xmlChar *)"dummy");
+ e_source_dump_to_xml_node (updated_source, xml);
+ e_source_update_from_xml_node (e_cal_backend_get_source (backend), xml->children, NULL);
+ xmlFreeNode (xml);
+}
+
+static void
+source_list_changed_cb (ESourceList *list, EDataCalFactory *factory)
+{
+ EDataCalFactoryPrivate *priv;
+ gint i;
+
+ g_return_if_fail (list != NULL);
+ g_return_if_fail (factory != NULL);
+ g_return_if_fail (E_IS_DATA_CAL_FACTORY (factory));
+
+ priv = factory->priv;
+
+ g_mutex_lock (priv->backends_mutex);
+
+ for (i = 0; i < E_CAL_SOURCE_TYPE_LAST; i++) {
+ if (list == priv->lists[i]) {
+ GSList *l;
+
+ for (l = priv->backends_by_type [i]; l; l = l->next) {
+ ECalBackend *backend = l->data;
+ ESource *source, *list_source;
+
+ source = e_cal_backend_get_source (backend);
+ list_source = e_source_list_peek_source_by_uid (priv->lists[i], e_source_peek_uid (source));
+
+ if (list_source) {
+ update_source_in_backend (backend, list_source);
+ }
+ }
+
+ break;
+ }
+ }
+
+ g_mutex_unlock (priv->backends_mutex);
+}
+
static ECalBackendFactory*
get_backend_factory (GHashTable *methods, const gchar *method, icalcomponent_kind kind)
{
@@ -103,8 +179,9 @@ backend_last_client_gone_cb (ECalBackend *backend, gpointer data)
EDataCalFactory *factory;
EDataCalFactoryPrivate *priv;
ECalBackend *ret_backend;
- const gchar *uristr;
- gchar *uri;
+ ECalSourceType st;
+ ESource *source;
+ gchar *uid_type_string;
gboolean last_calendar;
fprintf (stderr, "backend_last_client_gone_cb() called!\n");
@@ -114,18 +191,23 @@ backend_last_client_gone_cb (ECalBackend *backend, gpointer data)
/* Remove the backend from the hash table */
- uristr = e_cal_backend_get_uri (backend);
- g_assert (uristr != NULL);
- uri = g_strdup_printf("%s:%d", uristr, (gint)e_cal_backend_get_kind(backend));
+ source = e_cal_backend_get_source (backend);
+ g_assert (source != NULL);
+ uid_type_string = g_strdup_printf ("%s:%d", e_source_peek_uid (source), (gint)e_cal_backend_get_kind (backend));
g_mutex_lock (priv->backends_mutex);
- ret_backend = g_hash_table_lookup (factory->priv->backends, uri);
+ st = icalkind_to_ecalsourcetype (e_cal_backend_get_kind (backend));
+ if (st != E_CAL_SOURCE_TYPE_LAST && priv->backends_by_type [st]) {
+ priv->backends_by_type [st] = g_slist_remove (priv->backends_by_type [st], backend);
+ }
+
+ ret_backend = g_hash_table_lookup (priv->backends, uid_type_string);
g_assert (ret_backend != NULL);
g_assert (ret_backend == backend);
- g_hash_table_remove (priv->backends, uri);
- g_free(uri);
+ g_hash_table_remove (priv->backends, uid_type_string);
+ g_free (uid_type_string);
g_signal_handlers_disconnect_matched (backend, G_SIGNAL_MATCH_DATA,
0, 0, NULL, NULL, data);
@@ -157,7 +239,7 @@ impl_CalFactory_getCal (PortableServer_Servant servant,
ESource *source;
gchar *str_uri;
EUri *uri;
- gchar *uri_type_string;
+ gchar *uid_type_string;
factory = E_DATA_CAL_FACTORY (bonobo_object_from_servant (servant));
priv = factory->priv;
@@ -186,22 +268,24 @@ impl_CalFactory_getCal (PortableServer_Servant servant,
return CORBA_OBJECT_NIL;
}
- uri_type_string = g_strdup_printf ("%s:%d", str_uri, (gint)calobjtype_to_icalkind (type));
- g_free(str_uri);
+ g_free (str_uri);
+ uid_type_string = g_strdup_printf ("%s:%d", e_source_peek_uid (source), (gint)calobjtype_to_icalkind (type));
/* Find the associated backend factory (if any) */
backend_factory = get_backend_factory (priv->methods, uri->protocol, calobjtype_to_icalkind (type));
if (!backend_factory) {
/* FIXME Distinguish between method and kind failures? */
bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_CalFactory_UnsupportedMethod);
- goto cleanup;
+ goto cleanup2;
}
g_mutex_lock (priv->backends_mutex);
/* Look for an existing backend */
- backend = g_hash_table_lookup (factory->priv->backends, uri_type_string);
+ backend = g_hash_table_lookup (factory->priv->backends, uid_type_string);
if (!backend) {
+ ECalSourceType st;
+
/* There was no existing backend, create a new one */
if (E_IS_CAL_BACKEND_LOADER_FACTORY (backend_factory)) {
backend = E_CAL_BACKEND_LOADER_FACTORY_GET_CLASS (backend_factory)->new_backend_with_protocol ((ECalBackendLoaderFactory *)backend_factory,
@@ -215,12 +299,25 @@ impl_CalFactory_getCal (PortableServer_Servant servant,
goto cleanup;
}
+ st = icalkind_to_ecalsourcetype (e_cal_backend_get_kind (backend));
+ if (st != E_CAL_SOURCE_TYPE_LAST) {
+ if (!priv->lists[st] && e_cal_get_sources (&(priv->lists[st]), st, NULL)) {
+ g_signal_connect (priv->lists[st], "changed", G_CALLBACK (source_list_changed_cb), factory);
+ }
+
+ if (priv->lists[st])
+ priv->backends_by_type[st] = g_slist_prepend (priv->backends_by_type[st], backend);
+ }
+
/* Track the backend */
- g_hash_table_insert (priv->backends, g_strdup (uri_type_string), backend);
+ g_hash_table_insert (priv->backends, g_strdup (uid_type_string), backend);
g_signal_connect (G_OBJECT (backend), "last_client_gone",
G_CALLBACK (backend_last_client_gone_cb),
factory);
+ } else if (!e_source_equal (source, e_cal_backend_get_source (backend))) {
+ /* source changed, update it in a backend */
+ update_source_in_backend (backend, source);
}
/* Create the corba calendar */
@@ -241,8 +338,9 @@ impl_CalFactory_getCal (PortableServer_Servant servant,
before e_cal_backend_finalize() is called from the
backend_last_client_gone_cb(), for details see bug 506457. */
g_mutex_unlock (priv->backends_mutex);
+ cleanup2:
e_uri_free (uri);
- g_free (uri_type_string);
+ g_free (uid_type_string);
g_object_unref (source);
return ret_cal;
@@ -276,6 +374,7 @@ e_data_cal_factory_finalize (GObject *object)
{
EDataCalFactory *factory;
EDataCalFactoryPrivate *priv;
+ gint i;
g_return_if_fail (object != NULL);
g_return_if_fail (E_IS_DATA_CAL_FACTORY (object));
@@ -297,6 +396,18 @@ e_data_cal_factory_finalize (GObject *object)
}
g_free (priv->iid);
+ for (i = 0; i < E_CAL_SOURCE_TYPE_LAST; i++) {
+ if (priv->lists[i]) {
+ g_object_unref (priv->lists[i]);
+ priv->lists[i] = NULL;
+ }
+
+ if (priv->backends_by_type[i]) {
+ g_slist_free (priv->backends_by_type[i]);
+ priv->backends_by_type[i] = NULL;
+ }
+ }
+
g_free (priv);
factory->priv = NULL;
diff --git a/libedataserver/e-source.c b/libedataserver/e-source.c
index bdb1f57..21c1113 100644
--- a/libedataserver/e-source.c
+++ b/libedataserver/e-source.c
@@ -310,11 +310,26 @@ e_source_update_from_xml_node (ESource *source,
if (source->priv->name == NULL
|| strcmp ((gchar *)name, source->priv->name) != 0
|| source->priv->relative_uri == NULL
- || relative_uri != NULL
+ || relative_uri == NULL
|| strcmp ((gchar *)relative_uri, source->priv->relative_uri) != 0) {
g_free (source->priv->name);
source->priv->name = g_strdup ((gchar *)name);
+ if (source->priv->group) {
+ /* reset the absolute uri to NULL to be regenerated when asked for */
+ g_free (source->priv->absolute_uri);
+ source->priv->absolute_uri = NULL;
+ } else if (source->priv->absolute_uri &&
+ source->priv->relative_uri &&
+ g_str_has_suffix (source->priv->absolute_uri, source->priv->relative_uri)) {
+ gchar *tmp = source->priv->absolute_uri;
+
+ tmp [strlen (tmp) - strlen (source->priv->relative_uri)] = 0;
+ source->priv->absolute_uri = g_strconcat (tmp, (gchar *)relative_uri, NULL);
+
+ g_free (tmp);
+ }
+
g_free (source->priv->relative_uri);
source->priv->relative_uri = g_strdup ((gchar *)relative_uri);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]