[evolution-data-server] Bug #596095 - Open saved ESource-s for e_cal_/e_book__new_system_* calls



commit 543319f9152f16d190dd9cf0ce3a2b38b9db5f01
Author: Milan Crha <mcrha redhat com>
Date:   Thu Oct 15 21:11:52 2009 +0200

    Bug #596095 - Open saved ESource-s for e_cal_/e_book__new_system_* calls

 addressbook/libebook/e-book.c |  206 +++++++++++++++++++++++++++-------------
 calendar/libecal/e-cal.c      |  164 +++++++++++++++++++--------------
 2 files changed, 233 insertions(+), 137 deletions(-)
---
diff --git a/addressbook/libebook/e-book.c b/addressbook/libebook/e-book.c
index 7d43c8d..25f239e 100644
--- a/addressbook/libebook/e-book.c
+++ b/addressbook/libebook/e-book.c
@@ -1985,9 +1985,14 @@ e_book_set_default_source (ESource *source, GError **error)
 	if (!e_source_list_sync (sources, &err)) {
 		if (error)
 			g_propagate_error (error, err);
+
+		g_object_unref (sources);
+
 		return FALSE;
 	}
 
+	g_object_unref (sources);
+
 	return TRUE;
 }
 
@@ -2082,6 +2087,59 @@ e_book_new (ESource *source, GError **error)
 	return book;
 }
 
+/* for each known source calls check_func, which should return TRUE if the required
+   source have been found. Function returns NULL or the source on which was returned
+   TRUE by the check_func. Non-NULL pointer should be unreffed by g_object_unref. */
+static ESource *
+search_known_sources (gboolean (*check_func)(ESource *source, gpointer user_data), gpointer user_data, GError **error)
+{
+	ESourceList *sources;
+	ESource *res = NULL;
+	GSList *g;
+	GError *err = NULL;
+
+	g_return_val_if_fail (check_func != NULL, NULL);
+
+	if (!e_book_get_addressbooks (&sources, &err)) {
+		g_propagate_error (error, err);
+		return NULL;
+	}
+
+	for (g = e_source_list_peek_groups (sources); g; g = g->next) {
+		ESourceGroup *group = E_SOURCE_GROUP (g->data);
+		GSList *s;
+
+		for (s = e_source_group_peek_sources (group); s; s = s->next) {
+			ESource *source = E_SOURCE (s->data);
+
+			if (check_func (source, user_data)) {
+				res = g_object_ref (source);
+				break;
+			}
+		}
+
+		if (res)
+			break;
+	}
+
+	g_object_unref (sources);
+
+	return res;
+}
+
+static gboolean
+check_uri (ESource *source, gpointer uri)
+{
+	const gchar *suri;
+
+	g_return_val_if_fail (source != NULL, FALSE);
+	g_return_val_if_fail (uri != NULL, FALSE);
+
+	suri = e_source_peek_absolute_uri (source);
+
+	return suri && g_ascii_strcasecmp (suri, uri) == 0;
+}
+
 /**
  * e_book_new_from_uri:
  * @uri: the URI to load
@@ -2097,18 +2155,55 @@ e_book_new_from_uri (const gchar *uri, GError **error)
 {
 	ESource *source;
 	EBook *book;
+	GError *err = NULL;
 
 	e_return_error_if_fail (uri, E_BOOK_ERROR_INVALID_ARG);
 
-	source = e_source_new_with_absolute_uri ("", uri);
+	source = search_known_sources (check_uri, (gpointer) uri, &err);
+	if (err) {
+		g_propagate_error (error, err);
+		return NULL;
+	}
+
+	if (!source)
+		source = e_source_new_with_absolute_uri ("", uri);
 
-	book = e_book_new (source, error);
+	book = e_book_new (source, &err);
+	if (err)
+		g_propagate_error (error, err);
 
 	g_object_unref (source);
 
 	return book;
 }
 
+struct check_system_data
+{
+	const gchar *uri;
+	ESource *uri_source;
+};
+
+static gboolean
+check_system (ESource *source, gpointer data)
+{
+	struct check_system_data *csd = data;
+
+	g_return_val_if_fail (source != NULL, FALSE);
+	g_return_val_if_fail (data != NULL, FALSE);
+
+	if (e_source_get_property (source, "system")) {
+		return TRUE;
+	}
+
+	if (check_uri (source, (gpointer) csd->uri)) {
+		if (csd->uri_source)
+			g_object_unref (csd->uri_source);
+		csd->uri_source = g_object_ref (source);
+	}
+
+	return FALSE;
+}
+
 /**
  * e_book_new_system_addressbook:
  * @error: A #GError pointer
@@ -2122,61 +2217,58 @@ e_book_new_from_uri (const gchar *uri, GError **error)
 EBook*
 e_book_new_system_addressbook (GError **error)
 {
-	ESourceList *sources;
-	GSList *g;
 	GError *err = NULL;
 	ESource *system_source = NULL;
 	EBook *book;
+	gchar *uri, *filename;
+	struct check_system_data csd;
 
-	if (!e_book_get_addressbooks (&sources, &err)) {
-		if (error)
-			g_propagate_error (error, err);
-		return NULL;
-	}
+	filename = g_build_filename (g_get_home_dir(),
+				     ".evolution/addressbook/local/system",
+				     NULL);
+	uri = g_filename_to_uri (filename, NULL, NULL);
+	g_free (filename);
 
-	for (g = e_source_list_peek_groups (sources); g; g = g->next) {
-		ESourceGroup *group = E_SOURCE_GROUP (g->data);
-		GSList *s;
-		for (s = e_source_group_peek_sources (group); s; s = s->next) {
-			ESource *source = E_SOURCE (s->data);
+	csd.uri = uri;
+	csd.uri_source = NULL;
 
-			if (e_source_get_property (source, "system")) {
-				system_source = source;
-				break;
-			}
-		}
+	system_source = search_known_sources (check_system, &csd, &err);
+	if (err) {
+		g_propagate_error (error, err);
+		g_free (uri);
 
-		if (system_source)
-			break;
+		return NULL;
+	}
+
+	if (!system_source) {
+		system_source = csd.uri_source;
+		csd.uri_source = NULL;
 	}
 
 	if (system_source) {
 		book = e_book_new (system_source, &err);
+		g_object_unref (system_source);
+	} else {
+		book = e_book_new_from_uri (uri, &err);
 	}
-	else {
-		gchar *filename;
-		gchar *uri;
-
-		filename = g_build_filename (g_get_home_dir(),
-					     ".evolution/addressbook/local/system",
-					     NULL);
-		uri = g_filename_to_uri (filename, NULL, NULL);
 
-		g_free (filename);
+	if (csd.uri_source)
+		g_object_unref (csd.uri_source);
 
-		book = e_book_new_from_uri (uri, error);
+	g_free (uri);
 
-		g_free (uri);
-	}
+	if (err)
+		g_propagate_error (error, err);
 
-	if (!book) {
-		if (error)
-			g_propagate_error (error, err);
-	}
+	return book;
+}
 
-	g_object_unref (sources);
+static gboolean
+check_default (ESource *source, gpointer data)
+{
+	g_return_val_if_fail (source != NULL, FALSE);
 
-	return book;
+	return e_source_get_property (source, "default") != NULL;
 }
 
 /**
@@ -2192,45 +2284,25 @@ e_book_new_system_addressbook (GError **error)
 EBook*
 e_book_new_default_addressbook   (GError **error)
 {
-	ESourceList *sources;
-	GSList *g;
 	GError *err = NULL;
 	ESource *default_source = NULL;
 	EBook *book;
 
-	if (!e_book_get_addressbooks (&sources, &err)) {
-		if (error)
-			g_propagate_error (error, err);
+	default_source = search_known_sources (check_default, NULL, &err);
+	if (err) {
+		g_propagate_error (error, err);
 		return NULL;
 	}
 
-	for (g = e_source_list_peek_groups (sources); g; g = g->next) {
-		ESourceGroup *group = E_SOURCE_GROUP (g->data);
-		GSList *s;
-		for (s = e_source_group_peek_sources (group); s; s = s->next) {
-			ESource *source = E_SOURCE (s->data);
-
-			if (e_source_get_property (source, "default")) {
-				default_source = source;
-				break;
-			}
-		}
-
-		if (default_source)
-			break;
-	}
-
-	if (default_source)
+	if (default_source) {
 		book = e_book_new (default_source, &err);
-	else
+		g_object_unref (default_source);
+	} else {
 		book = e_book_new_system_addressbook (&err);
-
-	if (!book) {
-		if (error)
-			g_propagate_error (error, err);
 	}
 
-	g_object_unref (sources);
+	if (err)
+		g_propagate_error (error, err);
 
 	return book;
 }
diff --git a/calendar/libecal/e-cal.c b/calendar/libecal/e-cal.c
index 244b04c..f849038 100644
--- a/calendar/libecal/e-cal.c
+++ b/calendar/libecal/e-cal.c
@@ -777,6 +777,59 @@ e_cal_new (ESource *source, ECalSourceType type)
 	return ecal;
 }
 
+/* for each known source calls check_func, which should return TRUE if the required
+   source have been found. Function returns NULL or the source on which was returned
+   TRUE by the check_func. Non-NULL pointer should be unreffed by g_object_unref. */
+static ESource *
+search_known_sources (ECalSourceType type, gboolean (*check_func)(ESource *source, gpointer user_data), gpointer user_data, GError **error)
+{
+	ESourceList *sources;
+	ESource *res = NULL;
+	GSList *g;
+	GError *err = NULL;
+
+	g_return_val_if_fail (check_func != NULL, NULL);
+
+	if (!e_cal_get_sources (&sources, type, &err)) {
+		g_propagate_error (error, err);
+		return NULL;
+	}
+
+	for (g = e_source_list_peek_groups (sources); g; g = g->next) {
+		ESourceGroup *group = E_SOURCE_GROUP (g->data);
+		GSList *s;
+
+		for (s = e_source_group_peek_sources (group); s; s = s->next) {
+			ESource *source = E_SOURCE (s->data);
+
+			if (check_func (source, user_data)) {
+				res = g_object_ref (source);
+				break;
+			}
+		}
+
+		if (res)
+			break;
+	}
+
+	g_object_unref (sources);
+
+	return res;
+}
+
+static gboolean
+check_uri (ESource *source, gpointer uri)
+{
+	const gchar *suri;
+
+	g_return_val_if_fail (source != NULL, FALSE);
+	g_return_val_if_fail (uri != NULL, FALSE);
+
+	suri = e_source_peek_absolute_uri (source);
+
+	return suri && g_ascii_strcasecmp (suri, uri) == 0;
+}
+
 /**
  * e_cal_new_from_uri:
  * @uri: The URI pointing to the calendar to open.
@@ -794,7 +847,10 @@ e_cal_new_from_uri (const gchar *uri, ECalSourceType type)
 	ESource *source;
 	ECal *cal;
 
-	source = e_source_new_with_absolute_uri ("", uri);
+	source = search_known_sources (type, check_uri, (gpointer) uri, NULL);
+	if (!source)
+		source = e_source_new_with_absolute_uri ("", uri);
+
 	cal = e_cal_new (source, type);
 
 	g_object_unref (source);
@@ -3713,43 +3769,44 @@ e_cal_get_error_message (ECalendarStatus status)
 }
 
 static gboolean
-get_default (ECal **ecal, ESourceList *sources, ECalSourceType type, ECalAuthFunc func, gpointer data, GError **error)
+check_default (ESource *source, gpointer data)
+{
+	g_return_val_if_fail (source != NULL, FALSE);
+
+	return e_source_get_property (source, "default") != NULL;
+}
+
+/**
+ * e_cal_open_default:
+ * @ecal: A calendar client.
+ * @type: Type of the calendar.
+ * @func: Authentication function.
+ * @data: Closure data for the authentication function.
+ * @error: Placeholder for error information.
+ *
+ * Opens the default calendar.
+ *
+ * Return value: TRUE if it opened correctly, FALSE otherwise.
+ */
+gboolean
+e_cal_open_default (ECal **ecal, ECalSourceType type, ECalAuthFunc func, gpointer data, GError **error)
 {
-	GSList *g;
 	GError *err = NULL;
-	ESource *default_source = NULL;
-	gboolean rv = TRUE;
+	ESource *default_source;
+	gboolean res = TRUE;
 
-	for (g = e_source_list_peek_groups (sources); g; g = g->next) {
-		ESourceGroup *group = E_SOURCE_GROUP (g->data);
-		GSList *s;
-		for (s = e_source_group_peek_sources (group); s; s = s->next) {
-			ESource *source = E_SOURCE (s->data);
+	e_return_error_if_fail (ecal != NULL, E_CALENDAR_STATUS_INVALID_ARG);
+	*ecal = NULL;
 
-			if (e_source_get_property (source, "default")) {
-				default_source = source;
-				break;
-			}
-		}
+	default_source = search_known_sources (type, check_default, NULL, &err);
 
-		if (default_source)
-			break;
+	if (err) {
+		g_propagate_error (error, err);
+		return FALSE;
 	}
 
 	if (default_source) {
 		*ecal = e_cal_new (default_source, type);
-		if (!*ecal) {
-			g_propagate_error (error, err);
-			rv = FALSE;
-			goto done;
-		}
-
-		e_cal_set_auth_func (*ecal, func, data);
-		if (!e_cal_open (*ecal, TRUE, &err)) {
-			g_propagate_error (error, err);
-			rv = FALSE;
-			goto done;
-		}
 	} else {
 		switch (type) {
 		case E_CAL_SOURCE_TYPE_EVENT:
@@ -3764,58 +3821,25 @@ get_default (ECal **ecal, ESourceList *sources, ECalSourceType type, ECalAuthFun
 		default:
 			break;
 		}
+	}
 
-		if (!*ecal) {
-			g_propagate_error (error, err);
-			rv = FALSE;
-			goto done;
-		}
-
+	if (!*ecal) {
+		g_propagate_error (error, err);
+		res = FALSE;
+	} else {
 		e_cal_set_auth_func (*ecal, func, data);
 		if (!e_cal_open (*ecal, TRUE, &err)) {
 			g_propagate_error (error, err);
-			rv = FALSE;
-			goto done;
+			res = FALSE;
 		}
 	}
 
- done:
-	if (!rv && *ecal) {
+	if (!res && *ecal) {
 		g_object_unref (*ecal);
 		*ecal = NULL;
 	}
-	g_object_unref (sources);
-
-	return rv;
-}
-
-/**
- * e_cal_open_default:
- * @ecal: A calendar client.
- * @type: Type of the calendar.
- * @func: Authentication function.
- * @data: Closure data for the authentication function.
- * @error: Placeholder for error information.
- *
- * Opens the default calendar.
- *
- * Return value: TRUE if it opened correctly, FALSE otherwise.
- */
-gboolean
-e_cal_open_default (ECal **ecal, ECalSourceType type, ECalAuthFunc func, gpointer data, GError **error)
-{
-	ESourceList *sources;
-	GError *err = NULL;
-
-	e_return_error_if_fail (ecal != NULL, E_CALENDAR_STATUS_INVALID_ARG);
-	*ecal = NULL;
-
-	if (!e_cal_get_sources (&sources, type, &err)) {
-		g_propagate_error (error, err);
-		return FALSE;
-	}
 
-	return get_default (ecal, sources, type, func, data, error);
+	return res;
 }
 
 /**



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