[evolution] Bug #664016 - [evolution-alarm-notify] Try reconnect offline calendars



commit 5fc51b95fe98fb7a08afe58e81837d3ec09fa763
Author: Milan Crha <mcrha redhat com>
Date:   Tue Nov 15 13:51:01 2011 +0100

    Bug #664016 - [evolution-alarm-notify] Try reconnect offline calendars

 calendar/gui/alarm-notify/alarm-notify.c |   93 +++++++++++++++++++++++++++---
 calendar/gui/alarm-notify/alarm-notify.h |    3 +-
 2 files changed, 85 insertions(+), 11 deletions(-)
---
diff --git a/calendar/gui/alarm-notify/alarm-notify.c b/calendar/gui/alarm-notify/alarm-notify.c
index e612b0c..4f04974 100644
--- a/calendar/gui/alarm-notify/alarm-notify.c
+++ b/calendar/gui/alarm-notify/alarm-notify.c
@@ -51,6 +51,9 @@ struct _AlarmNotifyPrivate {
         ESourceList *source_lists[E_CAL_CLIENT_SOURCE_TYPE_LAST];
 	ESourceList *selected_calendars;
         GMutex *mutex;
+
+	GSList *offline_sources;
+	guint offline_timeout_id;
 };
 
 typedef struct {
@@ -102,6 +105,21 @@ process_removal_in_hash (const gchar *uri,
 	prd->removals = g_list_prepend (prd->removals, (gpointer) uri);
 }
 
+static gint
+find_slist_source_uri_cb (gconstpointer a, gconstpointer b)
+{
+	ESource *asource = (ESource *) a;
+	const gchar *buri = b;
+	gchar *auri;
+	gint res;
+
+	auri = e_source_get_uri (asource);
+	res = g_strcmp0 (auri, buri);
+	g_free (auri);
+
+	return res;
+}
+
 static void
 alarm_notify_list_changed_cb (ESourceList *source_list,
                               AlarmNotify *an)
@@ -141,9 +159,10 @@ alarm_notify_list_changed_cb (ESourceList *source_list,
 				continue;
 
 			uri = e_source_get_uri (source);
-			if (!g_hash_table_lookup (an->priv->uri_client_hash[source_type], uri)) {
+			if (!g_hash_table_lookup (an->priv->uri_client_hash[source_type], uri) &&
+			    !g_slist_find_custom (an->priv->offline_sources, uri, find_slist_source_uri_cb)) {
 				debug (("Adding Calendar %s", uri));
-				alarm_notify_add_calendar (an, source_type, source, FALSE);
+				alarm_notify_add_calendar (an, source_type, source);
 			}
 			g_free (uri);
 		}
@@ -196,7 +215,7 @@ alarm_notify_load_calendars (AlarmNotify *an,
 
 			uri = e_source_get_uri (source);
 			debug (("Loading Calendar %s", uri));
-			alarm_notify_add_calendar (an, source_type, source, FALSE);
+			alarm_notify_add_calendar (an, source_type, source);
 			g_free (uri);
 
 		}
@@ -224,6 +243,12 @@ alarm_notify_finalize (GObject *object)
 
 	priv = ALARM_NOTIFY_GET_PRIVATE (object);
 
+	if (priv->offline_timeout_id)
+		g_source_remove (priv->offline_timeout_id);
+	priv->offline_timeout_id = 0;
+	g_slist_free_full (priv->offline_sources, g_object_unref);
+	priv->offline_sources = NULL;
+
 	for (ii = 0; ii < E_CAL_CLIENT_SOURCE_TYPE_LAST; ii++) {
 		g_hash_table_foreach (
 			priv->uri_client_hash[ii],
@@ -350,6 +375,32 @@ alarm_notify_new (GCancellable *cancellable,
 		"application-id", APPLICATION_ID, NULL);
 }
 
+static gboolean
+try_open_offline_timeout_cb (gpointer user_data)
+{
+	AlarmNotify *an = ALARM_NOTIFY (user_data);
+	GSList *sources, *iter;
+
+	g_return_val_if_fail (an != NULL, FALSE);
+	g_return_val_if_fail (an->priv != NULL, FALSE);
+
+	sources = an->priv->offline_sources;
+	an->priv->offline_sources = NULL;
+	an->priv->offline_timeout_id = 0;
+
+	for (iter = sources; iter; iter = iter->next) {
+		ESource *source = iter->data;
+
+		alarm_notify_add_calendar (an,
+			GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (source), "source-type")),
+			source);
+	}
+
+	g_slist_free_full (sources, g_object_unref);
+
+	return FALSE;
+}
+
 static void
 client_opened_cb (GObject *source_object,
                   GAsyncResult *result,
@@ -361,11 +412,22 @@ client_opened_cb (GObject *source_object,
 	ECalClient *cal_client;
 	ECalClientSourceType source_type;
 	const gchar *uri;
+	GError *error = NULL;
+
+	e_client_utils_open_new_finish (source, result, &client, &error);
+
+	if (client == NULL) {
+		if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_REPOSITORY_OFFLINE)) {
+			if (an->priv->offline_timeout_id)
+				g_source_remove (an->priv->offline_timeout_id);
+			an->priv->offline_sources = g_slist_append (an->priv->offline_sources, g_object_ref (source));
+			an->priv->offline_timeout_id = g_timeout_add_seconds (5 * 60, try_open_offline_timeout_cb, an);
+		}
 
-	e_client_utils_open_new_finish (source, result, &client, NULL);
+		g_clear_error (&error);
 
-	if (client == NULL)
 		return;
+	}
 
 	cal_client = E_CAL_CLIENT (client);
 	source_type = e_cal_client_get_source_type (cal_client);
@@ -386,8 +448,6 @@ client_opened_cb (GObject *source_object,
  * alarm_notify_add_calendar:
  * @an: An alarm notification service.
  * @uri: URI of the calendar to load.
- * @load_afterwards: Whether this calendar should be loaded in the future
- * when the alarm daemon starts up.
  *
  * Tells the alarm notification service to load a calendar and start monitoring
  * its alarms.  It can optionally be made to save the URI of this calendar so
@@ -396,8 +456,7 @@ client_opened_cb (GObject *source_object,
 void
 alarm_notify_add_calendar (AlarmNotify *an,
                            ECalClientSourceType source_type,
-                           ESource *source,
-                           gboolean load_afterwards)
+                           ESource *source)
 {
 	AlarmNotifyPrivate *priv;
 	EClientSourceType client_source_type;
@@ -460,6 +519,8 @@ alarm_notify_add_calendar (AlarmNotify *an,
 			client_source_type = E_CLIENT_SOURCE_TYPE_LAST;
 	}
 
+	g_object_set_data (G_OBJECT (source), "source-type", GUINT_TO_POINTER (source_type));
+
 	e_client_utils_open_new (
 		source, client_source_type, TRUE, NULL,
 		e_client_utils_authenticate_handler, NULL,
@@ -477,6 +538,7 @@ alarm_notify_remove_calendar (AlarmNotify *an,
 {
 	AlarmNotifyPrivate *priv;
 	ECalClient *cal_client;
+	GSList *in_offline;
 
 	priv = an->priv;
 
@@ -487,4 +549,17 @@ alarm_notify_remove_calendar (AlarmNotify *an,
 		alarm_queue_remove_client (cal_client, FALSE);
 		g_hash_table_remove (priv->uri_client_hash[source_type], str_uri);
 	}
+
+	in_offline = g_slist_find_custom (priv->offline_sources, str_uri, find_slist_source_uri_cb);
+	if (in_offline) {
+		ESource *source = in_offline->data;
+
+		priv->offline_sources = g_slist_remove (priv->offline_sources, source);
+		if (!priv->offline_sources && priv->offline_timeout_id) {
+			g_source_remove (priv->offline_timeout_id);
+			priv->offline_timeout_id = 0;
+		}
+
+		g_object_unref (source);
+	}
 }
diff --git a/calendar/gui/alarm-notify/alarm-notify.h b/calendar/gui/alarm-notify/alarm-notify.h
index f95a4d6..b48cd5a 100644
--- a/calendar/gui/alarm-notify/alarm-notify.h
+++ b/calendar/gui/alarm-notify/alarm-notify.h
@@ -69,8 +69,7 @@ AlarmNotify *	alarm_notify_new		(GCancellable *cancellable,
 						 GError **error);
 void		alarm_notify_add_calendar	(AlarmNotify *an,
 						 ECalClientSourceType source_type,
-						 ESource *source,
-						 gboolean load_afterwards);
+						 ESource *source);
 void		alarm_notify_remove_calendar	(AlarmNotify *an,
 						 ECalClientSourceType source_type,
 						 const gchar *str_uri);



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