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
This commit is contained in:
committed by
Arturo Espinosa
parent
c02660b408
commit
cc670cb2ca
@ -1,3 +1,36 @@
|
||||
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.
|
||||
|
||||
2000-02-04 Federico Mena Quintero <federico@helixcode.com>
|
||||
|
||||
* cal-backend.c (get_calendar_base_vobject): New function to
|
||||
|
||||
@ -62,6 +62,8 @@ gnomecal_SOURCES = \
|
||||
cal-client.h \
|
||||
cal-listener.c \
|
||||
cal-listener.h \
|
||||
cal-util.c \
|
||||
cal-util.h \
|
||||
calendar.c \
|
||||
calendar.h \
|
||||
calendar-conduit.h \
|
||||
@ -134,6 +136,8 @@ tlacuache_SOURCES = \
|
||||
cal-common.h \
|
||||
cal-factory.c \
|
||||
cal-factory.h \
|
||||
cal-util.c \
|
||||
cal-util.h \
|
||||
calobj.c \
|
||||
calobj.h \
|
||||
job.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 buf;
|
||||
return retval;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -471,3 +471,57 @@ cal_client_get_object (CalClient *client, const char *uid)
|
||||
CORBA_exception_free (&ev);
|
||||
return retval;
|
||||
}
|
||||
|
||||
GList *
|
||||
cal_client_get_events_in_range (CalClient *client, time_t start, time_t end)
|
||||
{
|
||||
CalClientPrivate *priv;
|
||||
CORBA_Environment ev;
|
||||
Evolution_Calendar_CalObjInstanceSeq *seq;
|
||||
GList *elist;
|
||||
int i;
|
||||
|
||||
g_return_val_if_fail (client != NULL, NULL);
|
||||
g_return_val_if_fail (IS_CAL_CLIENT (client), NULL);
|
||||
|
||||
priv = client->priv;
|
||||
g_return_val_if_fail (priv->load_state == LOAD_STATE_LOADED, NULL);
|
||||
|
||||
g_return_val_if_fail (start != -1 && end != -1, NULL);
|
||||
g_return_val_if_fail (start <= end, NULL);
|
||||
|
||||
priv = client->priv;
|
||||
|
||||
CORBA_exception_init (&ev);
|
||||
|
||||
seq = Evolution_Calendar_Cal_get_events_in_range (priv->cal, start, end, &ev);
|
||||
if (ev._major != CORBA_NO_EXCEPTION) {
|
||||
g_message ("cal_client_get_events_in_range(): could not get the event range");
|
||||
CORBA_exception_free (&ev);
|
||||
return NULL;
|
||||
}
|
||||
CORBA_exception_free (&ev);
|
||||
|
||||
/* Create the list in reverse order */
|
||||
|
||||
elist = NULL;
|
||||
|
||||
for (i = 0; i < seq->_length; i++) {
|
||||
Evolution_Calendar_CalObjInstance *corba_icoi;
|
||||
CalObjInstance *icoi;
|
||||
|
||||
corba_icoi = &seq->_buffer[i];
|
||||
icoi = g_new (CalObjInstance, 1);
|
||||
|
||||
icoi->calobj = g_strdup (corba_icoi->calobj);
|
||||
icoi->start = corba_icoi->start;
|
||||
icoi->end = corba_icoi->end;
|
||||
|
||||
elist = g_list_prepend (elist, icoi);
|
||||
}
|
||||
|
||||
CORBA_free (seq);
|
||||
elist = g_list_reverse (elist);
|
||||
|
||||
return elist;
|
||||
}
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
|
||||
#include <libgnome/gnome-defs.h>
|
||||
#include <gtk/gtkobject.h>
|
||||
#include "cal-util.h"
|
||||
|
||||
BEGIN_GNOME_DECLS
|
||||
|
||||
@ -73,6 +74,8 @@ gboolean cal_client_load_calendar (CalClient *client, const char *str_uri);
|
||||
|
||||
char *cal_client_get_object (CalClient *client, const char *uid);
|
||||
|
||||
GList *cal_client_get_events_in_range (CalClient *client, time_t start, time_t end);
|
||||
|
||||
|
||||
|
||||
END_GNOME_DECLS
|
||||
|
||||
@ -471,3 +471,57 @@ cal_client_get_object (CalClient *client, const char *uid)
|
||||
CORBA_exception_free (&ev);
|
||||
return retval;
|
||||
}
|
||||
|
||||
GList *
|
||||
cal_client_get_events_in_range (CalClient *client, time_t start, time_t end)
|
||||
{
|
||||
CalClientPrivate *priv;
|
||||
CORBA_Environment ev;
|
||||
Evolution_Calendar_CalObjInstanceSeq *seq;
|
||||
GList *elist;
|
||||
int i;
|
||||
|
||||
g_return_val_if_fail (client != NULL, NULL);
|
||||
g_return_val_if_fail (IS_CAL_CLIENT (client), NULL);
|
||||
|
||||
priv = client->priv;
|
||||
g_return_val_if_fail (priv->load_state == LOAD_STATE_LOADED, NULL);
|
||||
|
||||
g_return_val_if_fail (start != -1 && end != -1, NULL);
|
||||
g_return_val_if_fail (start <= end, NULL);
|
||||
|
||||
priv = client->priv;
|
||||
|
||||
CORBA_exception_init (&ev);
|
||||
|
||||
seq = Evolution_Calendar_Cal_get_events_in_range (priv->cal, start, end, &ev);
|
||||
if (ev._major != CORBA_NO_EXCEPTION) {
|
||||
g_message ("cal_client_get_events_in_range(): could not get the event range");
|
||||
CORBA_exception_free (&ev);
|
||||
return NULL;
|
||||
}
|
||||
CORBA_exception_free (&ev);
|
||||
|
||||
/* Create the list in reverse order */
|
||||
|
||||
elist = NULL;
|
||||
|
||||
for (i = 0; i < seq->_length; i++) {
|
||||
Evolution_Calendar_CalObjInstance *corba_icoi;
|
||||
CalObjInstance *icoi;
|
||||
|
||||
corba_icoi = &seq->_buffer[i];
|
||||
icoi = g_new (CalObjInstance, 1);
|
||||
|
||||
icoi->calobj = g_strdup (corba_icoi->calobj);
|
||||
icoi->start = corba_icoi->start;
|
||||
icoi->end = corba_icoi->end;
|
||||
|
||||
elist = g_list_prepend (elist, icoi);
|
||||
}
|
||||
|
||||
CORBA_free (seq);
|
||||
elist = g_list_reverse (elist);
|
||||
|
||||
return elist;
|
||||
}
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
|
||||
#include <libgnome/gnome-defs.h>
|
||||
#include <gtk/gtkobject.h>
|
||||
#include "cal-util.h"
|
||||
|
||||
BEGIN_GNOME_DECLS
|
||||
|
||||
@ -73,6 +74,8 @@ gboolean cal_client_load_calendar (CalClient *client, const char *str_uri);
|
||||
|
||||
char *cal_client_get_object (CalClient *client, const char *uid);
|
||||
|
||||
GList *cal_client_get_events_in_range (CalClient *client, time_t start, time_t end);
|
||||
|
||||
|
||||
|
||||
END_GNOME_DECLS
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -295,7 +295,7 @@ cal_repo_get_updated_objects (PortableServer_Servant servant,
|
||||
}
|
||||
str = calendar_get_as_vcal_string (dirty_cal);
|
||||
res = CORBA_string_dup (str);
|
||||
g_free (str);
|
||||
free (str); /* calendar_get_as_vcal_string() uses writeMemVObject(), which uses realloc() */
|
||||
calendar_destroy (dirty_cal);
|
||||
|
||||
return res;
|
||||
|
||||
@ -23,11 +23,29 @@ module Calendar {
|
||||
/* An unique identifier for a calendar object */
|
||||
typedef string CalObjUID;
|
||||
|
||||
/* Used to store a time_t */
|
||||
typedef unsigned long Time_t;
|
||||
|
||||
/* An instance of a calendar object that actually occurs. These are
|
||||
* "virtual" objects in that they are used to represent instances of
|
||||
* recurring events and alarms. "Real" objects just contain the
|
||||
* information required to figure out the times at which they recur or
|
||||
* trigger.
|
||||
*/
|
||||
struct CalObjInstance {
|
||||
CalObj calobj;
|
||||
Time_t start;
|
||||
Time_t end;
|
||||
};
|
||||
|
||||
typedef sequence<CalObjInstance> CalObjInstanceSeq;
|
||||
|
||||
interface Listener;
|
||||
|
||||
/* Calendar client interface */
|
||||
interface Cal : Bonobo::Unknown {
|
||||
exception NotFound {};
|
||||
exception InvalidRange {};
|
||||
|
||||
/* A calendar is identified by its URI */
|
||||
readonly attribute string uri;
|
||||
@ -35,6 +53,10 @@ module Calendar {
|
||||
/* Gets an object based on its URI */
|
||||
CalObj get_object (in CalObjUID uid)
|
||||
raises (NotFound);
|
||||
|
||||
/* Gets the events that occur or recur in the specified time range */
|
||||
CalObjInstanceSeq get_events_in_range (in Time_t start, in Time_t end)
|
||||
raises (InvalidRange);
|
||||
};
|
||||
|
||||
/* Listener for changes in a calendar */
|
||||
|
||||
@ -62,6 +62,8 @@ gnomecal_SOURCES = \
|
||||
cal-client.h \
|
||||
cal-listener.c \
|
||||
cal-listener.h \
|
||||
cal-util.c \
|
||||
cal-util.h \
|
||||
calendar.c \
|
||||
calendar.h \
|
||||
calendar-conduit.h \
|
||||
@ -134,6 +136,8 @@ tlacuache_SOURCES = \
|
||||
cal-common.h \
|
||||
cal-factory.c \
|
||||
cal-factory.h \
|
||||
cal-util.c \
|
||||
cal-util.h \
|
||||
calobj.c \
|
||||
calobj.h \
|
||||
job.c \
|
||||
|
||||
@ -295,7 +295,7 @@ cal_repo_get_updated_objects (PortableServer_Servant servant,
|
||||
}
|
||||
str = calendar_get_as_vcal_string (dirty_cal);
|
||||
res = CORBA_string_dup (str);
|
||||
g_free (str);
|
||||
free (str); /* calendar_get_as_vcal_string() uses writeMemVObject(), which uses realloc() */
|
||||
calendar_destroy (dirty_cal);
|
||||
|
||||
return res;
|
||||
|
||||
@ -23,11 +23,29 @@ module Calendar {
|
||||
/* An unique identifier for a calendar object */
|
||||
typedef string CalObjUID;
|
||||
|
||||
/* Used to store a time_t */
|
||||
typedef unsigned long Time_t;
|
||||
|
||||
/* An instance of a calendar object that actually occurs. These are
|
||||
* "virtual" objects in that they are used to represent instances of
|
||||
* recurring events and alarms. "Real" objects just contain the
|
||||
* information required to figure out the times at which they recur or
|
||||
* trigger.
|
||||
*/
|
||||
struct CalObjInstance {
|
||||
CalObj calobj;
|
||||
Time_t start;
|
||||
Time_t end;
|
||||
};
|
||||
|
||||
typedef sequence<CalObjInstance> CalObjInstanceSeq;
|
||||
|
||||
interface Listener;
|
||||
|
||||
/* Calendar client interface */
|
||||
interface Cal : Bonobo::Unknown {
|
||||
exception NotFound {};
|
||||
exception InvalidRange {};
|
||||
|
||||
/* A calendar is identified by its URI */
|
||||
readonly attribute string uri;
|
||||
@ -35,6 +53,10 @@ module Calendar {
|
||||
/* Gets an object based on its URI */
|
||||
CalObj get_object (in CalObjUID uid)
|
||||
raises (NotFound);
|
||||
|
||||
/* Gets the events that occur or recur in the specified time range */
|
||||
CalObjInstanceSeq get_events_in_range (in Time_t start, in Time_t end)
|
||||
raises (InvalidRange);
|
||||
};
|
||||
|
||||
/* Listener for changes in a calendar */
|
||||
|
||||
@ -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 buf;
|
||||
return retval;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user