evolution-data-server r8638 - in trunk/calendar: . libedata-cal



Author: mcrha
Date: Wed Apr 16 13:41:35 2008
New Revision: 8638
URL: http://svn.gnome.org/viewvc/evolution-data-server?rev=8638&view=rev

Log:
2008-04-16  Milan Crha  <mcrha redhat com>

	** Fix for bug #524324

	* libedata-cal/e-data-cal-view.h: (struct _EDataCalViewClass):
	* libedata-cal/e-data-cal-view.c: (e_data_cal_view_class_init): 
	New signal "last_listener_gone" to indicate noone is using the query.
	* libedata-cal/e-data-cal-view.c: (listener_died_cb): Emit the signal.
	* libedata-cal/e-data-cal-view.c: (e_data_cal_view_set_property):
	Increase the reference counter for the backend property.
	* libedata-cal/e-cal-backend.h: (e_cal_backend_remove_query):
	* libedata-cal/e-cal-backend.c: (e_cal_backend_remove_query):
	Pair function to e_cal_backend_add_query.
	* libedata-cal/e-data-cal.c: (disconnect_query),
	(query_last_listener_gone_cb): New helper functions to properly
	disconnect/remove queries without listeners.
	* libedata-cal/e-data-cal.c: (impl_Cal_getQuery):
	Listen to "last_listener_gone" signal on new query.
	* libedata-cal/e-data-cal.c: (e_data_cal_finalize):
	Disconnect queries properly, before destroying the hash table.
	* libedata-cal/e-cal-backend.c: (e_cal_backend_init):
	* libedata-cal/e-data-cal.c: (e_data_cal_init):
	Use bonobo_object_ref/unref for EDataCalView objects.



Modified:
   trunk/calendar/ChangeLog
   trunk/calendar/libedata-cal/e-cal-backend.c
   trunk/calendar/libedata-cal/e-cal-backend.h
   trunk/calendar/libedata-cal/e-data-cal-view.c
   trunk/calendar/libedata-cal/e-data-cal-view.h
   trunk/calendar/libedata-cal/e-data-cal.c

Modified: trunk/calendar/libedata-cal/e-cal-backend.c
==============================================================================
--- trunk/calendar/libedata-cal/e-cal-backend.c	(original)
+++ trunk/calendar/libedata-cal/e-cal-backend.c	Wed Apr 16 13:41:35 2008
@@ -279,7 +279,7 @@
 	priv->clients_mutex = g_mutex_new ();
 
 	/* FIXME bonobo_object_ref/unref? */
-	priv->queries = e_list_new((EListCopyFunc) g_object_ref, (EListFreeFunc) g_object_unref, NULL);
+	priv->queries = e_list_new ((EListCopyFunc) bonobo_object_ref, (EListFreeFunc) bonobo_object_unref, NULL);
 	priv->queries_mutex = g_mutex_new ();
 }
 
@@ -498,6 +498,25 @@
 	return backend->priv->queries;
 }
 
+/**
+ * e_cal_backend_remove_query
+ * @backend: An #ECalBackend object.
+ * @query: An #EDataCalView object, previously added with @ref e_cal_backend_add_query.
+ *
+ * Removes query from the list of live queries for the backend.
+ **/
+void
+e_cal_backend_remove_query (ECalBackend *backend, EDataCalView *query)
+{
+	g_return_if_fail (backend != NULL);
+	g_return_if_fail (E_IS_CAL_BACKEND (backend));
+
+	g_mutex_lock (backend->priv->queries_mutex);
+
+	e_list_remove (backend->priv->queries, query);
+
+	g_mutex_unlock (backend->priv->queries_mutex);
+}
 
 /**
  * e_cal_backend_get_cal_address:

Modified: trunk/calendar/libedata-cal/e-cal-backend.h
==============================================================================
--- trunk/calendar/libedata-cal/e-cal-backend.h	(original)
+++ trunk/calendar/libedata-cal/e-cal-backend.h	Wed Apr 16 13:41:35 2008
@@ -123,6 +123,7 @@
 
 void e_cal_backend_add_query (ECalBackend *backend, EDataCalView *query);
 EList *e_cal_backend_get_queries (ECalBackend *backend);
+void e_cal_backend_remove_query (ECalBackend *backend, EDataCalView *query);
 
 void e_cal_backend_is_read_only (ECalBackend *backend, EDataCal *cal);
 void e_cal_backend_get_cal_address (ECalBackend *backend, EDataCal *cal);

Modified: trunk/calendar/libedata-cal/e-data-cal-view.c
==============================================================================
--- trunk/calendar/libedata-cal/e-data-cal-view.c	(original)
+++ trunk/calendar/libedata-cal/e-data-cal-view.c	Wed Apr 16 13:41:35 2008
@@ -81,6 +81,13 @@
 	PROP_SEXP
 };
 
+/* Signal IDs */
+enum {
+	LAST_LISTENER_GONE,
+	LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
 
 static void
 add_object_to_cache (EDataCalView *query, const char *calobj)
@@ -184,6 +191,10 @@
 			priv->listeners = g_list_remove_link (priv->listeners, l);
 			g_list_free (l);
 			g_free (ld);
+
+			if (priv->listeners == NULL)
+				g_signal_emit (query, signals[LAST_LISTENER_GONE], 0);
+
 			break;
 		}
 	}
@@ -277,7 +288,7 @@
 
 	switch (property_id) {
 	case PROP_BACKEND:
-		priv->backend = E_CAL_BACKEND (g_value_get_object (value));
+		priv->backend = g_object_ref (E_CAL_BACKEND (g_value_get_object (value)));
 		break;
 	case PROP_LISTENER:
 		e_data_cal_view_add_listener (query, g_value_get_pointer (value));
@@ -348,6 +359,17 @@
 	param =  g_param_spec_object ("sexp", NULL, NULL, E_TYPE_CAL_BACKEND_SEXP,
 				      G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY);
 	g_object_class_install_property (object_class, PROP_SEXP, param);
+
+	signals[LAST_LISTENER_GONE] =
+		g_signal_new ("last_listener_gone",
+			      G_TYPE_FROM_CLASS (klass),
+			      G_SIGNAL_RUN_FIRST,
+			      G_STRUCT_OFFSET (EDataCalViewClass, last_listener_gone),
+			      NULL, NULL,
+			      g_cclosure_marshal_VOID__VOID,
+			      G_TYPE_NONE, 0);
+
+	klass->last_listener_gone = NULL;
 }
 
 /* Object initialization function for the live search query */

Modified: trunk/calendar/libedata-cal/e-data-cal-view.h
==============================================================================
--- trunk/calendar/libedata-cal/e-data-cal-view.h	(original)
+++ trunk/calendar/libedata-cal/e-data-cal-view.h	Wed Apr 16 13:41:35 2008
@@ -49,6 +49,9 @@
 	BonoboObjectClass parent_class;
 
 	POA_GNOME_Evolution_Calendar_CalView__epv epv;
+
+	/* Notification signals */
+	void (* last_listener_gone) (EDataCalView *query);
 };
 
 GType                 e_data_cal_view_get_type (void);

Modified: trunk/calendar/libedata-cal/e-data-cal.c
==============================================================================
--- trunk/calendar/libedata-cal/e-data-cal.c	(original)
+++ trunk/calendar/libedata-cal/e-data-cal.c	Wed Apr 16 13:41:35 2008
@@ -384,6 +384,26 @@
 	e_cal_backend_send_objects (priv->backend, cal, calobj);
 }
 
+static void
+disconnect_query (gpointer key, EDataCalView *query, EDataCal *cal)
+{
+	g_signal_handlers_disconnect_matched (query, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, cal);
+	e_cal_backend_remove_query (cal->priv->backend, query);
+}
+
+static void
+query_last_listener_gone_cb (EDataCalView *query, EDataCal *cal)
+{
+	EDataCalPrivate *priv;
+
+	g_return_if_fail (cal != NULL);
+
+	priv = cal->priv;
+
+	disconnect_query (NULL, query, cal);
+	g_hash_table_remove (priv->live_queries, e_data_cal_view_get_text (query));
+}
+
 /* Cal::getQuery implementation */
 static void
 impl_Cal_getQuery (PortableServer_Servant servant,
@@ -427,6 +447,8 @@
 		return;
 	}
 
+	g_signal_connect (query, "last_listener_gone", G_CALLBACK (query_last_listener_gone_cb), cal);
+
 	g_hash_table_insert (priv->live_queries, g_strdup (sexp), query);
 	e_cal_backend_add_query (priv->backend, query);
 
@@ -614,6 +636,7 @@
 	priv->listener = NULL;
 	CORBA_exception_free (&ev);
 
+	g_hash_table_foreach (priv->live_queries, (GHFunc) disconnect_query, cal);
 	g_hash_table_destroy (priv->live_queries);
 	priv->live_queries = NULL;
 
@@ -665,7 +688,6 @@
 	epv->getQuery = impl_Cal_getQuery;
 }
 
-
 /* Object initialization function for the calendar */
 static void
 e_data_cal_init (EDataCal *cal, EDataCalClass *klass)
@@ -678,7 +700,7 @@
 	priv->listener = CORBA_OBJECT_NIL;
 	priv->live_queries = g_hash_table_new_full (g_str_hash, g_str_equal,
 						    (GDestroyNotify) g_free,
-						    (GDestroyNotify) g_object_unref);
+						    (GDestroyNotify) bonobo_object_unref);
 }
 
 BONOBO_TYPE_FUNC_FULL (EDataCal, GNOME_Evolution_Calendar_Cal, PARENT_TYPE, e_data_cal);



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