From cc670cb2ca319599eebac658f1164dbb64d70c65 Mon Sep 17 00:00:00 2001 From: Federico Mena Quintero Date: Tue, 8 Feb 2000 07:08:29 +0000 Subject: New struct to wrap instances of calendar objects for recurrencies and 2000-02-08 Federico Mena Quintero * evolution-calendar.idl (CalObjInstance): New struct to wrap instances of calendar objects for recurrencies and alarms. (Cal::get_events_in_range): New method to get ocurring and recurring events by time range. * cal-backend.c (cal_backend_get_events_in_range): New function to get a list of event instances in a time range. (string_from_ical_object): New internal function. (cal_backend_get_object): Use string_from_ical_object() instead of doing everything ourselves. (cal_backend_get_events_in_range): New function to get a list of the events that occur or recur in a specified time range. * cal-client.c (cal_client_get_events_in_range): Implemented client-side function. * cal-util.h: * cal-util.c: New files with utilities and types common to the client and server parts. (CalObjInstance): New structure to hold an instance of an actual occurrence, recurrence, or alarm trigger of a calendar object. (cal_obj_instance_list_free): New function to free a list of calendar object instances. * cal.c (Cal_get_events_in_range): Implemented new method. * corba-cal.c (cal_repo_get_updated_objects): Free `str' with free(), not g_free(), since calendar_get_as_vcal_string() uses writeMemVObject(), which uses realloc(). Fixed in gnome-pim as well. svn path=/trunk/; revision=1693 --- calendar/pcs/cal-backend.c | 129 +++++++++++++++++++++++++++++++++++++++++---- calendar/pcs/cal-backend.h | 8 ++- calendar/pcs/cal.c | 58 ++++++++++++++++++++ 3 files changed, 183 insertions(+), 12 deletions(-) (limited to 'calendar/pcs') diff --git a/calendar/pcs/cal-backend.c b/calendar/pcs/cal-backend.c index 72315e3882..2039c9c400 100644 --- a/calendar/pcs/cal-backend.c +++ b/calendar/pcs/cal-backend.c @@ -299,6 +299,30 @@ get_calendar_base_vobject (CalBackend *backend) return vobj; } +/* Builds the string representation of a complete calendar object wrapping the + * specified object --- a complete calendar is needed because of the timezone + * information. The return value must be freed with free(), not g_free(), since + * the internal implementation calls writeMemVObject() from libversit, which + * uses realloc() to allocate this string. + */ +static char * +string_from_ical_object (CalBackend *backend, iCalObject *ico) +{ + VObject *vcalobj, *vobj; + char *buf; + + vcalobj = get_calendar_base_vobject (backend); + vobj = ical_object_to_vobject (ico); + addVObjectProp (vcalobj, vobj); + + buf = writeMemVObject (NULL, NULL, vcalobj); + + cleanVObject (vcalobj); + cleanStrTbl (); + + return buf; +} + /** @@ -467,8 +491,7 @@ cal_backend_get_object (CalBackend *backend, const char *uid) { CalBackendPrivate *priv; iCalObject *ico; - VObject *vcalobj, *vobj; - char *buf; + char *buf, *retval; g_return_val_if_fail (backend != NULL, NULL); g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL); @@ -480,19 +503,105 @@ cal_backend_get_object (CalBackend *backend, const char *uid) g_assert (priv->object_hash != NULL); - ico = g_hash_table_lookup (priv->objec_hash, uid); + ico = g_hash_table_lookup (priv->object_hash, uid); if (!ico) return NULL; - vcalobj = get_calendar_base_vobject (backend); - vobj = ical_object_to_vobject (ico); - addVObjectProp (vcalobj, vobj); + /* string_from_ical_object() uses writeMemVObject(), which uses + * realloc(), so we must free its result with free() instead of + * g_free(). We take a copy of the result so that callers can use the + * normal glib function to free it. + */ - buf = writeMemVObject (NULL, NULL, vcalobj); + buf = string_from_ical_object (backend, ico); + retval = g_strdup (buf); + free (buf); - cleanVObject (vcalobj); - cleanStrTbl (); + return retval; +} - return buf; +struct build_event_list_closure { + CalBackend *backend; + GList *event_list; +}; + +/* Builds a sorted list of event object instances. Used as a callback from + * ical_object_generate_events(). + */ +static int +build_event_list (iCalObject *ico, time_t start, time_t end, void *data) +{ + CalObjInstance *icoi; + struct build_event_list_closure *c; + + c = data; + + icoi = g_new (CalObjInstance, 1); + icoi->calobj = string_from_ical_object (c->backend, ico); + icoi->start = start; + icoi->end = end; + + c->event_list = g_list_prepend (c->event_list, icoi); + + return TRUE; +} + +/* Compares two CalObjInstance structures by their start times. Called from + * g_list_sort(). + */ +static gint +compare_instance_func (gconstpointer a, gconstpointer b) +{ + const CalObjInstance *ca, *cb; + time_t diff; + + ca = a; + cb = b; + + diff = ca->start - cb->start; + return (diff < 0) ? -1 : (diff > 0) ? 1 : 0; +} + +/** + * cal_backend_get_events_in_range: + * @backend: A calendar backend. + * @start: Start time for query. + * @end: End time for query. + * + * Builds a sorted list of calendar event object instances that occur or recur + * within the specified time range. Each object instance contains the object + * itself and the start/end times at which it occurs or recurs. + * + * Return value: A list of calendar event object instances, sorted by their + * start times. + **/ +GList * +cal_backend_get_events_in_range (CalBackend *backend, time_t start, time_t end) +{ + CalBackendPrivate *priv; + struct build_event_list_closure c; + GList *l; + + g_return_val_if_fail (backend != NULL, NULL); + g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL); + + priv = backend->priv; + g_return_val_if_fail (priv->loaded, NULL); + + g_return_val_if_fail (start != -1 && end != -1, NULL); + g_return_val_if_fail (start <= end, NULL); + + c.backend = backend; + c.event_list = NULL; + + for (l = priv->events; l; l = l->next) { + iCalObject *ico; + + ico = l->data; + ical_object_generate_events (ico, start, end, build_event_list, &c); + } + + c.event_list = g_list_sort (c.event_list, compare_instance_func); + return c.event_list; } diff --git a/calendar/pcs/cal-backend.h b/calendar/pcs/cal-backend.h index e972cbd59e..aa54a3339d 100644 --- a/calendar/pcs/cal-backend.h +++ b/calendar/pcs/cal-backend.h @@ -27,6 +27,7 @@ #include "evolution-calendar.h" #include "cal-common.h" #include "cal.h" +#include "cal-util.h" BEGIN_GNOME_DECLS @@ -39,9 +40,10 @@ BEGIN_GNOME_DECLS #define IS_CAL_BACKEND(obj) (GTK_CHECK_TYPE ((obj), CAL_BACKEND_TYPE)) #define IS_CAL_BACKEND_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), CAL_BACKEND_TYPE)) +/* Load status values */ typedef enum { - CAL_BACKEND_LOAD_SUCCESS, /* Loading OK */ - CAL_BACKEND_LOAD_ERROR /* We need better error reporting in libversit */ + CAL_BACKEND_LOAD_SUCCESS, /* Loading OK */ + CAL_BACKEND_LOAD_ERROR /* We need better error reporting in libversit */ } CalBackendLoadStatus; struct _CalBackend { @@ -68,6 +70,8 @@ CalBackendLoadStatus cal_backend_load (CalBackend *backend, GnomeVFSURI *uri); char *cal_backend_get_object (CalBackend *backend, const char *uid); +GList *cal_backend_get_events_in_range (CalBackend *backend, time_t start, time_t end); + END_GNOME_DECLS diff --git a/calendar/pcs/cal.c b/calendar/pcs/cal.c index 1ce1d91716..664d9ef416 100644 --- a/calendar/pcs/cal.c +++ b/calendar/pcs/cal.c @@ -196,6 +196,63 @@ Cal_get_object (PortableServer_Servant servant, } } +/* Cal::get_events_in_range method */ +static Evolution_Calendar_CalObjInstanceSeq * +Cal_get_events_in_range (PortableServer_Servant servant, + const Evolution_Calendar_Time_t start, + const Evolution_Calendar_Time_t end, + CORBA_Environment *ev) +{ + Cal *cal; + CalPrivate *priv; + time_t t_start, t_end; + Evolution_Calendar_CalObjInstanceSeq *seq; + GList *elist, *l; + int n, i; + + cal = CAL (bonobo_object_from_servant (servant)); + priv = cal->priv; + + t_start = (time_t) start; + t_end = (time_t) end; + + if (t_start > t_end || t_start == -1 || t_end == -1) { + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Evolution_Calendar_Cal_InvalidRange, + NULL); + return NULL; + } + + /* Figure out the list and allocate the sequence */ + + elist = cal_backend_get_events_in_range (priv->backend, t_start, t_end); + n = g_list_length (elist); + + seq = Evolution_Calendar_CalObjInstanceSeq__alloc (); + seq->_length = n; + seq->_buffer = CORBA_sequence_Evolution_Calendar_CalObjInstance_allocbuf (n); + + /* Fill the sequence */ + + for (i = 0, l = elist; i < n; i++, l = l->next) { + CalObjInstance *icoi; + Evolution_Calendar_CalObjInstance *corba_icoi; + + icoi = l->data; + corba_icoi = &seq->_buffer[i]; + + corba_icoi->calobj = CORBA_string_dup (icoi->calobj); + corba_icoi->start = icoi->start; + corba_icoi->end = icoi->end; + } + + /* Done */ + + cal_obj_instance_list_free (elist); + + return seq; +} + /** * cal_get_epv: * @void: @@ -212,6 +269,7 @@ cal_get_epv (void) epv = g_new0 (POA_Evolution_Calendar_Cal__epv, 1); epv->_get_uri = Cal_get_uri; epv->get_object = Cal_get_object; + epv->get_events_in_range = Cal_get_events_in_range; return epv; } -- cgit v1.2.3