aboutsummaryrefslogtreecommitdiffstats
path: root/calendar/pcs
diff options
context:
space:
mode:
authorFederico Mena Quintero <federico@helixcode.com>2000-02-08 15:08:29 +0800
committerArturo Espinosa <unammx@src.gnome.org>2000-02-08 15:08:29 +0800
commitcc670cb2ca319599eebac658f1164dbb64d70c65 (patch)
tree55dc72c7ea1b1582158e8aa55eedb9d18a4ab4e4 /calendar/pcs
parentc02660b4081a84c9ad5749a931f5458f08f634d3 (diff)
downloadgsoc2013-evolution-cc670cb2ca319599eebac658f1164dbb64d70c65.tar.gz
gsoc2013-evolution-cc670cb2ca319599eebac658f1164dbb64d70c65.tar.zst
gsoc2013-evolution-cc670cb2ca319599eebac658f1164dbb64d70c65.zip
New struct to wrap instances of calendar objects for recurrencies and
2000-02-08 Federico Mena Quintero <federico@helixcode.com> * 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
Diffstat (limited to 'calendar/pcs')
-rw-r--r--calendar/pcs/cal-backend.c129
-rw-r--r--calendar/pcs/cal-backend.h8
-rw-r--r--calendar/pcs/cal.c58
3 files changed, 183 insertions, 12 deletions
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;
}