Re: [evolution-patches] patch for #59904 (calendar)
- From: Rodrigo Moya <rodrigo novell com>
- To: JP Rosevear <jpr novell com>
- Cc: Evolution Patches <evolution-patches lists ximian com>
- Subject: Re: [evolution-patches] patch for #59904 (calendar)
- Date: Thu, 26 Aug 2004 00:48:08 +0200
On Wed, 2004-08-25 at 13:17 -0400, JP Rosevear wrote:
> On Fri, 2004-08-13 at 14:06 +0200, Rodrigo Moya wrote:
> > On Tue, 2004-08-03 at 14:36 +0200, Rodrigo Moya wrote:
> > > This makes ECal use a cache of queries, so that we don't have to run
> > > them over and over again. I've seen a lot of speed improvements in the
> > > local calendars, not that much in the DVD movies file (mentioned in the
> > > bug), so I'm still looking at fixing that, but this should make things
> > > much quicker for most users
> > >
> > here is a much better patch, with the cache in the backends, so that
> > they are really shared between calendar clients.
>
> The patch is malformed.
>
ugh, not sure what's happening lately with my patches :) Here's a new
one
--
Rodrigo Moya <rodrigo novell com>
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution-data-server/calendar/ChangeLog,v
retrieving revision 1.321
diff -u -p -r1.321 ChangeLog
--- ChangeLog 25 Aug 2004 14:38:14 -0000 1.321
+++ ChangeLog 25 Aug 2004 22:47:17 -0000
@@ -1,3 +1,36 @@
+2004-08-25 Rodrigo Moya <rodrigo novell com>
+
+ Fixes #59904
+
+ * libecal/e-cal-component.[ch] (e_cal_component_new_from_string): new
+ function to avoid repeating the same code over and over.
+
+ * libedata-cal/e-data-cal-view.c: changed to keep a list of listeners,
+ not only one.
+ (listener_died_cb): remove the listener from the list of listeners.
+ (impl_EDataCalView_start): see if the query has already been started,
+ and if so, just notify correctly the listeners we need to notify.
+ (e_data_cal_view_init): create hash table for storing the objects we
+ have matching the live query.
+ (e_data_cal_view_set_property): add correctly the listeners to the list.
+ (e_data_cal_view_get_property): return always the first listener.
+ (e_data_cal_view_finalize): free all listeners and cached objects.
+ (add_object_to_cache, remove_object_from_cache):
+ new functions to manage the matched objects cache.
+ (e_data_cal_view_notify_objects_added,
+ e_data_cal_view_notify_objects_modified): add objects to our private
+ cache, and notify all listeners, now that we might have more than one.
+ (e_data_cal_view_notify_objects_removed,
+ e_data_cal_view_notify_progress, e_data_cal_view_notify_done): notify
+ all listeners.
+ (e_data_cal_view_add_listener): new function.
+
+ * libedata-cal/e-data-cal.c: keep a cache of all queries.
+ (impl_Cal_getQuery): first look in the cache of queries. And when
+ creating a new query, add it to the cache.
+ (e_data_cal_finalize): destroy the live queries hash table.
+ (e_data_cal_init): create live queries hash table.
+
2004-08-25 Frederic Crozat <fcrozat mandrakesoft com>
* libecal/e-cal.c: (e_cal_set_default_timezone):
@@ -9,7 +42,7 @@
(populate_cache): Used a static mutex to avoid the
the simulataneous calls from calendar and tasks to
ReadCursorRequest which crashes the server.
-
+
2004-08-24 Sivaiah Nallagatla <snallagatla novell com>
* backends/groupwise/e-cal-backend-groupwise.c
Index: libecal/e-cal-component.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/calendar/libecal/e-cal-component.c,v
retrieving revision 1.9
diff -u -p -r1.9 e-cal-component.c
--- libecal/e-cal-component.c 16 Jul 2004 14:29:20 -0000 1.9
+++ libecal/e-cal-component.c 25 Aug 2004 22:47:19 -0000
@@ -437,6 +437,38 @@ e_cal_component_new (void)
}
/**
+ * e_cal_component_new_from_string:
+ * @calobj: A string representation of an iCalendar component.
+ *
+ * Creates a new calendar component object from the given string.
+ *
+ * Return value: A calendar component representing the given iCalendar string on
+ * success, NULL if there was an error.
+ **/
+ECalComponent *
+e_cal_component_new_from_string (const char *calobj)
+{
+ ECalComponent *comp;
+ icalcomponent *icalcomp;
+
+ g_return_val_if_fail (calobj != NULL, NULL);
+
+ icalcomp = icalparser_parse_string (calobj);
+ if (!icalcomp)
+ return NULL;
+
+ comp = e_cal_component_new ();
+ if (!e_cal_component_set_icalcomponent (comp, icalcomp)) {
+ icalcomponent_free (icalcomp);
+ g_object_unref (comp);
+
+ return NULL;
+ }
+
+ return comp;
+}
+
+/**
* e_cal_component_clone:
* @comp: A calendar component object.
*
Index: libecal/e-cal-component.h
===================================================================
RCS file: /cvs/gnome/evolution-data-server/calendar/libecal/e-cal-component.h,v
retrieving revision 1.4
diff -u -p -r1.4 e-cal-component.h
--- libecal/e-cal-component.h 13 Jan 2004 13:14:58 -0000 1.4
+++ libecal/e-cal-component.h 25 Aug 2004 22:47:19 -0000
@@ -200,6 +200,8 @@ char *e_cal_component_gen_uid (void);
ECalComponent *e_cal_component_new (void);
+ECalComponent *e_cal_component_new_from_string (const char *calobj);
+
ECalComponent *e_cal_component_clone (ECalComponent *comp);
void e_cal_component_set_new_vtype (ECalComponent *comp, ECalComponentVType type);
Index: libedata-cal/e-data-cal-view.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/calendar/libedata-cal/e-data-cal-view.c,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 e-data-cal-view.c
--- libedata-cal/e-data-cal-view.c 3 Nov 2003 18:24:02 -0000 1.1.1.1
+++ libedata-cal/e-data-cal-view.c 25 Aug 2004 22:47:20 -0000
@@ -22,6 +22,7 @@
#include <config.h>
#endif
+#include <string.h>
#include <glib.h>
#include <bonobo/bonobo-exception.h>
#include <libedataserver/e-component-listener.h>
@@ -30,14 +31,27 @@
+typedef struct {
+ GNOME_Evolution_Calendar_CalViewListener listener;
+ EComponentListener *component_listener;
+
+ gboolean notified_start;
+ gboolean notified_done;
+} ListenerData;
+
/* Private part of the Query structure */
struct _EDataCalViewPrivate {
/* The backend we are monitoring */
ECalBackend *backend;
+ gboolean started;
+ gboolean done;
+ GNOME_Evolution_Calendar_CallStatus done_status;
+
+ GHashTable *matched_objects;
+
/* The listener we report to */
- GNOME_Evolution_Calendar_CalViewListener listener;
- EComponentListener *component_listener;
+ GList *listeners;
/* Sexp that defines the query */
ECalBackendSExp *sexp;
@@ -69,18 +83,132 @@ enum props {
static void
+add_object_to_cache (EDataCalView *query, const char *calobj)
+{
+ ECalComponent *comp;
+ char *real_uid;
+ const char *uid;
+ EDataCalViewPrivate *priv;
+
+ priv = query->priv;
+
+ comp = e_cal_component_new_from_string (calobj);
+ if (!comp)
+ return;
+
+ e_cal_component_get_uid (comp, &uid);
+ if (!uid || !*uid) {
+ g_object_unref (comp);
+ return;
+ }
+
+ if (e_cal_component_is_instance (comp))
+ real_uid = g_strdup_printf ("%s %s", uid, e_cal_component_get_recurid_as_string (comp));
+ else
+ real_uid = g_strdup (uid);
+
+ if (g_hash_table_lookup (priv->matched_objects, real_uid))
+ g_hash_table_replace (priv->matched_objects, real_uid, g_strdup (calobj));
+ else
+ g_hash_table_insert (priv->matched_objects, real_uid, g_strdup (calobj));
+
+ /* free memory */
+ g_object_unref (comp);
+}
+
+static gboolean
+uncache_with_uid_cb (gpointer key, gpointer value, gpointer user_data)
+{
+ ECalComponent *comp;
+ const char *this_uid;
+ char *uid, *object;
+
+ uid = user_data;
+ object = value;
+
+ comp = e_cal_component_new_from_string (object);
+ if (comp) {
+ e_cal_component_get_uid (comp, &this_uid);
+ if (this_uid && *this_uid && !strcmp (uid, this_uid)) {
+ g_object_unref (comp);
+ return TRUE;
+ }
+
+ g_object_unref (comp);
+ }
+
+ return FALSE;
+}
+
+static void
+remove_object_from_cache (EDataCalView *query, const char *uid)
+{
+ EDataCalViewPrivate *priv;
+
+ priv = query->priv;
+
+ g_hash_table_foreach_remove (priv->matched_objects, (GHRFunc) uncache_with_uid_cb, (gpointer) uid);
+}
+
+static void
listener_died_cb (EComponentListener *cl, gpointer data)
{
EDataCalView *query = QUERY (data);
EDataCalViewPrivate *priv;
+ GList *l;
priv = query->priv;
- g_object_unref (priv->component_listener);
- priv->component_listener = NULL;
+ for (l = priv->listeners; l != NULL; l = l->next) {
+ ListenerData *ld = l->data;
+
+ if (ld->component_listener == cl) {
+ g_object_unref (ld->component_listener);
+ ld->component_listener = NULL;
- bonobo_object_release_unref (priv->listener, NULL);
- priv->listener = NULL;
+ bonobo_object_release_unref (ld->listener, NULL);
+ ld->listener = NULL;
+
+ priv->listeners = g_list_remove_link (priv->listeners, l);
+ g_list_free (l);
+ g_free (ld);
+ break;
+ }
+ }
+}
+
+static void
+notify_matched_object_cb (gpointer key, gpointer value, gpointer user_data)
+{
+ char *uid, *object;
+ EDataCalView *query;
+ EDataCalViewPrivate *priv;
+ GList *l;
+
+ uid = key;
+ object = value;
+ query = user_data;
+ priv = query->priv;
+
+ for (l = priv->listeners; l != NULL; l = l->next) {
+ ListenerData *ld = l->data;
+
+ if (!ld->notified_start) {
+ GNOME_Evolution_Calendar_stringlist obj_list;
+ CORBA_Environment ev;
+
+ obj_list._buffer = GNOME_Evolution_Calendar_stringlist_allocbuf (1);
+ obj_list._maximum = 1;
+ obj_list._length = 1;
+ obj_list._buffer[0] = CORBA_string_dup (object);
+
+ CORBA_exception_init (&ev);
+ GNOME_Evolution_Calendar_CalViewListener_notifyObjectsAdded (ld->listener, &obj_list, &ev);
+ CORBA_exception_free (&ev);
+
+ CORBA_free (obj_list._buffer);
+ }
+ }
}
static void
@@ -88,11 +216,46 @@ impl_EDataCalView_start (PortableServer_
{
EDataCalView *query;
EDataCalViewPrivate *priv;
+ GList *l;
query = QUERY (bonobo_object_from_servant (servant));
priv = query->priv;
- e_cal_backend_start_query (priv->backend, query);
+ if (priv->started) {
+ g_warning (G_STRLOC ": Query already started, notifying matched objects");
+ g_hash_table_foreach (priv->matched_objects, (GHFunc) notify_matched_object_cb, query);
+
+ /* notify all listeners correctly if the query is already done */
+ for (l = priv->listeners; l != NULL; l = l->next) {
+ ListenerData *ld = l->data;
+
+ if (!ld->notified_start) {
+ ld->notified_start = TRUE;
+
+ if (priv->done && !ld->notified_done) {
+ CORBA_Environment ev;
+
+ ld->notified_done = TRUE;
+
+ g_warning (G_STRLOC ": Query already done before, notifying new listener");
+ CORBA_exception_init (&ev);
+ GNOME_Evolution_Calendar_CalViewListener_notifyQueryDone (
+ ld->listener, priv->done_status, &ev);
+ CORBA_exception_free (&ev);
+ }
+ }
+ }
+ } else {
+ g_warning (G_STRLOC ": Starting new query");
+ priv->started = TRUE;
+ e_cal_backend_start_query (priv->backend, query);
+
+ for (l = priv->listeners; l != NULL; l = l->next) {
+ ListenerData *ld = l->data;
+
+ ld->notified_start = TRUE;
+ }
+ }
}
static void
@@ -100,7 +263,6 @@ e_data_cal_view_set_property (GObject *o
{
EDataCalView *query;
EDataCalViewPrivate *priv;
- CORBA_Environment ev;
query = QUERY (object);
priv = query->priv;
@@ -110,13 +272,7 @@ e_data_cal_view_set_property (GObject *o
priv->backend = E_CAL_BACKEND (g_value_dup_object (value));
break;
case PROP_LISTENER:
- CORBA_exception_init (&ev);
- priv->listener = CORBA_Object_duplicate (g_value_get_pointer (value), &ev);
- CORBA_exception_free (&ev);
-
- priv->component_listener = e_component_listener_new (priv->listener);
- g_signal_connect (G_OBJECT (priv->component_listener), "component_died",
- G_CALLBACK (listener_died_cb), query);
+ e_data_cal_view_add_listener (query, g_value_get_pointer (value));
break;
case PROP_SEXP:
priv->sexp = E_CAL_BACKEND_SEXP (g_value_dup_object (value));
@@ -140,7 +296,13 @@ e_data_cal_view_get_property (GObject *o
case PROP_BACKEND:
g_value_set_object (value, priv->backend);
case PROP_LISTENER:
- g_value_set_pointer (value, priv->listener);
+
+ if (priv->listeners) {
+ ListenerData *ld;
+
+ ld = priv->listeners->data;
+ g_value_set_pointer (value, ld->listener);
+ }
break;
case PROP_SEXP:
g_value_set_object (value, priv->sexp);
@@ -190,8 +352,11 @@ e_data_cal_view_init (EDataCalView *quer
query->priv = priv;
priv->backend = NULL;
- priv->listener = NULL;
- priv->component_listener = NULL;
+ priv->started = FALSE;
+ priv->done = FALSE;
+ priv->done_status = GNOME_Evolution_Calendar_Success;
+ priv->matched_objects = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+ priv->listeners = NULL;
priv->sexp = NULL;
}
@@ -211,11 +376,19 @@ e_data_cal_view_finalize (GObject *objec
if (priv->backend)
g_object_unref (priv->backend);
- if (priv->listener != NULL)
- bonobo_object_release_unref (priv->listener, NULL);
+ while (priv->listeners) {
+ ListenerData *ld = priv->listeners->data;
+
+ if (ld->listener)
+ bonobo_object_release_unref (ld->listener, NULL);
+ if (ld->component_listener)
+ g_object_unref (ld->component_listener);
+ priv->listeners = g_list_remove (priv->listeners, ld);
+ g_free (ld);
+ }
- if (priv->component_listener != NULL)
- g_object_unref (priv->component_listener);
+ if (priv->matched_objects)
+ g_hash_table_destroy (priv->matched_objects);
if (priv->sexp)
g_object_unref (priv->sexp);
@@ -238,8 +411,8 @@ e_data_cal_view_finalize (GObject *objec
**/
EDataCalView *
e_data_cal_view_new (ECalBackend *backend,
- GNOME_Evolution_Calendar_CalViewListener ql,
- ECalBackendSExp *sexp)
+ GNOME_Evolution_Calendar_CalViewListener ql,
+ ECalBackendSExp *sexp)
{
EDataCalView *query;
@@ -250,6 +423,40 @@ e_data_cal_view_new (ECalBackend *backen
}
/**
+ * e_data_cal_view_add_listener:
+ * @query: A #EDataCalView object.
+ * @ql: A CORBA query listener to add to the list of listeners.
+ *
+ * Adds the given CORBA listener to a #EDataCalView object. This makes the view
+ * object notify that listener when notifying the other listeners already attached
+ * to the view.
+ */
+void
+e_data_cal_view_add_listener (EDataCalView *query, GNOME_Evolution_Calendar_CalViewListener ql)
+{
+ ListenerData *ld;
+ EDataCalViewPrivate *priv;
+ CORBA_Environment ev;
+
+ g_return_if_fail (IS_QUERY (query));
+ g_return_if_fail (ql != CORBA_OBJECT_NIL);
+
+ priv = query->priv;
+
+ ld = g_new0 (ListenerData, 1);
+
+ CORBA_exception_init (&ev);
+ ld->listener = CORBA_Object_duplicate (ql, &ev);
+ CORBA_exception_free (&ev);
+
+ ld->component_listener = e_component_listener_new (ld->listener);
+ g_signal_connect (G_OBJECT (ld->component_listener), "component_died",
+ G_CALLBACK (listener_died_cb), query);
+
+ priv->listeners = g_list_prepend (priv->listeners, ld);
+}
+
+/**
* e_data_cal_view_get_sexp
* @query: A #EDataCalView object.
*
@@ -300,26 +507,33 @@ e_data_cal_view_notify_objects_added (ED
g_return_if_fail (IS_QUERY (query));
priv = query->priv;
- g_return_if_fail (priv->listener != CORBA_OBJECT_NIL);
-
- CORBA_exception_init (&ev);
+ g_return_if_fail (priv->listeners != CORBA_OBJECT_NIL);
num_objs = g_list_length ((GList*)objects);
obj_list._buffer = GNOME_Evolution_Calendar_stringlist_allocbuf (num_objs);
obj_list._maximum = num_objs;
obj_list._length = num_objs;
- for (l = objects, i = 0; l; l = l->next, i++)
+ for (l = objects, i = 0; l; l = l->next, i++) {
obj_list._buffer[i] = CORBA_string_dup (l->data);
- GNOME_Evolution_Calendar_CalViewListener_notifyObjectsAdded (priv->listener, &obj_list, &ev);
+ /* update our cache */
+ add_object_to_cache (query, l->data);
+ }
- CORBA_free (obj_list._buffer);
+ for (l = priv->listeners; l != NULL; l = l->next) {
+ ListenerData *ld = l->data;
- if (BONOBO_EX (&ev))
- g_warning (G_STRLOC ": could not notify the listener of object addition");
+ CORBA_exception_init (&ev);
- CORBA_exception_free (&ev);
+ GNOME_Evolution_Calendar_CalViewListener_notifyObjectsAdded (ld->listener, &obj_list, &ev);
+ if (BONOBO_EX (&ev))
+ g_warning (G_STRLOC ": could not notify the listener of object addition");
+
+ CORBA_exception_free (&ev);
+ }
+
+ CORBA_free (obj_list._buffer);
}
void
@@ -332,7 +546,7 @@ e_data_cal_view_notify_objects_added_1 (
g_return_if_fail (IS_QUERY (query));
priv = query->priv;
- g_return_if_fail (priv->listener != CORBA_OBJECT_NIL);
+ g_return_if_fail (priv->listeners != CORBA_OBJECT_NIL);
objects.next = objects.prev = NULL;
objects.data = (gpointer)object;
@@ -353,26 +567,33 @@ e_data_cal_view_notify_objects_modified
g_return_if_fail (IS_QUERY (query));
priv = query->priv;
- g_return_if_fail (priv->listener != CORBA_OBJECT_NIL);
-
- CORBA_exception_init (&ev);
+ g_return_if_fail (priv->listeners != CORBA_OBJECT_NIL);
num_objs = g_list_length ((GList*)objects);
obj_list._buffer = GNOME_Evolution_Calendar_stringlist_allocbuf (num_objs);
obj_list._maximum = num_objs;
obj_list._length = num_objs;
- for (l = objects, i = 0; l; l = l->next, i++)
+ for (l = objects, i = 0; l; l = l->next, i++) {
obj_list._buffer[i] = CORBA_string_dup (l->data);
- GNOME_Evolution_Calendar_CalViewListener_notifyObjectsModified (priv->listener, &obj_list, &ev);
+ /* update our cache */
+ add_object_to_cache (query, l->data);
+ }
- CORBA_free (obj_list._buffer);
+ for (l = priv->listeners; l != NULL; l = l->next) {
+ ListenerData *ld = l->data;
- if (BONOBO_EX (&ev))
- g_warning (G_STRLOC ": could not notify the listener of object modification");
+ CORBA_exception_init (&ev);
- CORBA_exception_free (&ev);
+ GNOME_Evolution_Calendar_CalViewListener_notifyObjectsModified (ld->listener, &obj_list, &ev);
+ if (BONOBO_EX (&ev))
+ g_warning (G_STRLOC ": could not notify the listener of object modification");
+
+ CORBA_exception_free (&ev);
+ }
+
+ CORBA_free (obj_list._buffer);
}
void
@@ -385,7 +606,7 @@ e_data_cal_view_notify_objects_modified_
g_return_if_fail (IS_QUERY (query));
priv = query->priv;
- g_return_if_fail (priv->listener != CORBA_OBJECT_NIL);
+ g_return_if_fail (priv->listeners != CORBA_OBJECT_NIL);
objects.next = objects.prev = NULL;
objects.data = (gpointer)object;
@@ -406,9 +627,7 @@ e_data_cal_view_notify_objects_removed (
g_return_if_fail (IS_QUERY (query));
priv = query->priv;
- g_return_if_fail (priv->listener != CORBA_OBJECT_NIL);
-
- CORBA_exception_init (&ev);
+ g_return_if_fail (priv->listeners != CORBA_OBJECT_NIL);
num_uids = g_list_length ((GList*)uids);
uid_list._buffer = GNOME_Evolution_Calendar_CalObjUIDSeq_allocbuf (num_uids);
@@ -418,15 +637,19 @@ e_data_cal_view_notify_objects_removed (
for (l = uids, i = 0; l; l = l->next, i ++)
uid_list._buffer[i] = CORBA_string_dup (l->data);
- GNOME_Evolution_Calendar_CalViewListener_notifyObjectsRemoved (priv->listener, &uid_list, &ev);
+ for (l = priv->listeners; l != NULL; l = l->next) {
+ ListenerData *ld = l->data;
- CORBA_free (uid_list._buffer);
+ CORBA_exception_init (&ev);
- if (BONOBO_EX (&ev))
- g_warning (G_STRLOC ": could not notify the listener of object removal");
+ GNOME_Evolution_Calendar_CalViewListener_notifyObjectsRemoved (ld->listener, &uid_list, &ev);
+ if (BONOBO_EX (&ev))
+ g_warning (G_STRLOC ": could not notify the listener of object removal");
+ CORBA_exception_free (&ev);
+ }
- CORBA_exception_free (&ev);
+ CORBA_free (uid_list._buffer);
}
void
@@ -439,7 +662,7 @@ e_data_cal_view_notify_objects_removed_1
g_return_if_fail (IS_QUERY (query));
priv = query->priv;
- g_return_if_fail (priv->listener != CORBA_OBJECT_NIL);
+ g_return_if_fail (priv->listeners != CORBA_OBJECT_NIL);
uids.next = uids.prev = NULL;
uids.data = (gpointer)uid;
@@ -452,21 +675,25 @@ e_data_cal_view_notify_progress (EDataCa
{
EDataCalViewPrivate *priv;
CORBA_Environment ev;
+ GList *l;
g_return_if_fail (query != NULL);
g_return_if_fail (IS_QUERY (query));
priv = query->priv;
- g_return_if_fail (priv->listener != CORBA_OBJECT_NIL);
-
- CORBA_exception_init (&ev);
+ g_return_if_fail (priv->listeners != CORBA_OBJECT_NIL);
- GNOME_Evolution_Calendar_CalViewListener_notifyQueryProgress (priv->listener, message, percent, &ev);
+ for (l = priv->listeners; l != NULL; l = l->next) {
+ ListenerData *ld = l->data;
- if (BONOBO_EX (&ev))
- g_warning (G_STRLOC ": could not notify the listener of query progress");
+ CORBA_exception_init (&ev);
- CORBA_exception_free (&ev);
+ GNOME_Evolution_Calendar_CalViewListener_notifyQueryProgress (ld->listener, message, percent, &ev);
+ if (BONOBO_EX (&ev))
+ g_warning (G_STRLOC ": could not notify the listener of query progress");
+
+ CORBA_exception_free (&ev);
+ }
}
void
@@ -474,19 +701,26 @@ e_data_cal_view_notify_done (EDataCalVie
{
EDataCalViewPrivate *priv;
CORBA_Environment ev;
+ GList *l;
g_return_if_fail (query != NULL);
g_return_if_fail (IS_QUERY (query));
priv = query->priv;
- g_return_if_fail (priv->listener != CORBA_OBJECT_NIL);
-
- CORBA_exception_init (&ev);
+ g_return_if_fail (priv->listeners != CORBA_OBJECT_NIL);
- GNOME_Evolution_Calendar_CalViewListener_notifyQueryDone (priv->listener, status, &ev);
+ priv->done = TRUE;
+ priv->done_status = status;
- if (BONOBO_EX (&ev))
- g_warning (G_STRLOC ": could not notify the listener of query completion");
+ for (l = priv->listeners; l != NULL; l = l->next) {
+ ListenerData *ld = l->data;
- CORBA_exception_free (&ev);
+ CORBA_exception_init (&ev);
+
+ GNOME_Evolution_Calendar_CalViewListener_notifyQueryDone (ld->listener, status, &ev);
+ if (BONOBO_EX (&ev))
+ g_warning (G_STRLOC ": could not notify the listener of query completion");
+
+ CORBA_exception_free (&ev);
+ }
}
Index: libedata-cal/e-data-cal-view.h
===================================================================
RCS file: /cvs/gnome/evolution-data-server/calendar/libedata-cal/e-data-cal-view.h,v
retrieving revision 1.3
diff -u -p -r1.3 e-data-cal-view.h
--- libedata-cal/e-data-cal-view.h 6 Nov 2003 00:33:17 -0000 1.3
+++ libedata-cal/e-data-cal-view.h 25 Aug 2004 22:47:20 -0000
@@ -52,29 +52,30 @@ struct _EDataCalViewClass {
};
GType e_data_cal_view_get_type (void);
-EDataCalView *e_data_cal_view_new (ECalBackend *backend,
- GNOME_Evolution_Calendar_CalViewListener ql,
- ECalBackendSExp *sexp);
+EDataCalView *e_data_cal_view_new (ECalBackend *backend,
+ GNOME_Evolution_Calendar_CalViewListener ql,
+ ECalBackendSExp *sexp);
+void e_data_cal_view_add_listener (EDataCalView *query, GNOME_Evolution_Calendar_CalViewListener ql);
const char *e_data_cal_view_get_text (EDataCalView *query);
-ECalBackendSExp *e_data_cal_view_get_object_sexp (EDataCalView *query);
-gboolean e_data_cal_view_object_matches (EDataCalView *query, const char *object);
+ECalBackendSExp *e_data_cal_view_get_object_sexp (EDataCalView *query);
+gboolean e_data_cal_view_object_matches (EDataCalView *query, const char *object);
void e_data_cal_view_notify_objects_added (EDataCalView *query,
- const GList *objects);
+ const GList *objects);
void e_data_cal_view_notify_objects_added_1 (EDataCalView *query,
- const char *object);
+ const char *object);
void e_data_cal_view_notify_objects_modified (EDataCalView *query,
- const GList *objects);
+ const GList *objects);
void e_data_cal_view_notify_objects_modified_1 (EDataCalView *query,
- const char *object);
+ const char *object);
void e_data_cal_view_notify_objects_removed (EDataCalView *query,
- const GList *uids);
+ const GList *uids);
void e_data_cal_view_notify_objects_removed_1 (EDataCalView *query,
- const char *uid);
+ const char *uid);
void e_data_cal_view_notify_progress (EDataCalView *query,
- const char *message,
- int percent);
+ const char *message,
+ int percent);
void e_data_cal_view_notify_done (EDataCalView *query,
- GNOME_Evolution_Calendar_CallStatus status);
+ GNOME_Evolution_Calendar_CallStatus status);
G_END_DECLS
Index: libedata-cal/e-data-cal.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/calendar/libedata-cal/e-data-cal.c,v
retrieving revision 1.8
diff -u -p -r1.8 e-data-cal.c
--- libedata-cal/e-data-cal.c 23 Apr 2004 20:24:19 -0000 1.8
+++ libedata-cal/e-data-cal.c 25 Aug 2004 22:47:20 -0000
@@ -41,6 +41,9 @@ struct _EDataCalPrivate {
/* Listener on the client we notify */
GNOME_Evolution_Calendar_CalListener listener;
+
+ /* Cache of live queries */
+ GHashTable *live_queries;
};
/* Cal::get_uri method */
@@ -368,8 +371,16 @@ impl_Cal_getQuery (PortableServer_Servan
cal = E_DATA_CAL (bonobo_object_from_servant (servant));
priv = cal->priv;
+ /* first see if we already have the query in the cache */
+ query = g_hash_table_lookup (priv->live_queries, sexp);
+ if (query) {
+ e_data_cal_view_add_listener (query, ql);
+ e_data_cal_notify_query (cal, GNOME_Evolution_Calendar_Success, query);
+ return;
+ }
+
/* we handle this entirely here, since it doesn't require any
- backend involvement now that we have pas_book_view_start to
+ backend involvement now that we have e_cal_view_start to
actually kick off the search. */
obj_sexp = e_cal_backend_sexp_new (sexp);
@@ -387,11 +398,10 @@ impl_Cal_getQuery (PortableServer_Servan
return;
}
+ g_hash_table_insert (priv->live_queries, g_strdup (sexp), query);
e_cal_backend_add_query (priv->backend, query);
e_data_cal_notify_query (cal, GNOME_Evolution_Calendar_Success, query);
-
- g_object_unref (query);
}
@@ -538,7 +548,7 @@ e_data_cal_get_listener (EDataCal *cal)
/* Destroy handler for the calendar */
static void
-cal_finalize (GObject *object)
+e_data_cal_finalize (GObject *object)
{
EDataCal *cal;
EDataCalPrivate *priv;
@@ -560,6 +570,9 @@ cal_finalize (GObject *object)
priv->listener = NULL;
CORBA_exception_free (&ev);
+ g_hash_table_destroy (priv->live_queries);
+ priv->live_queries = NULL;
+
g_free (priv);
if (G_OBJECT_CLASS (parent_class)->finalize)
@@ -578,7 +591,7 @@ e_data_cal_class_init (EDataCalClass *kl
parent_class = g_type_class_peek_parent (klass);
/* Class method overrides */
- object_class->finalize = cal_finalize;
+ object_class->finalize = e_data_cal_finalize;
/* Epv methods */
epv->_get_uri = impl_Cal_get_uri;
@@ -618,6 +631,9 @@ e_data_cal_init (EDataCal *cal, EDataCal
cal->priv = priv;
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);
}
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]