My first icalendar patch
- From: rms39 columbia edu (Russell Steinthal)
- To: calendar-list gnome org
- cc: miguel gnu org, federico helixcode com
- Subject: My first icalendar patch
- Date: Mon, 17 Jan 2000 03:46:20 -0500
Fellow gnomecal hackers:
This is the first of what I hope will be a series of patches to
gnomecal to add iCalendar support. Since this is a fairly major
architectural change, I'm going to post significant patches to
existing code to the list for review before committing, although I'll
still probably make the usual tweaks directly to CVS. (In
particular, I've tried to isolate as much of the new code as possible
to new files to try to minimize disruptions to existing code):
Anyway, this is more of a "preliminary" patch: it doesn't actually
add much (if any) iCalendar support, and should not change the
operation of gnomecal in any way. It does, however, change the format
of several key internal structures, most importantly iCalObject.
The following changes were made to iCalObject. The patch also
attempts to fix all existing references to these fields to make them
conform to the new semantics:
* The attendee field in has been changed from a list of strings to a
list of iCalPerson's (a new structure). (The field does not yet
appear to be in use.)
* The organizer field was changed from a char* to an iCalPerson*.
* The related field was changed from a list of strings to a list of
iCalRelated's (a new structure).
* New fields alarms (a list of CalendarAlarm), desc (a string), and
date_only (a boolean) were added. These are for iCal-use, and
existing code should not be affected. (The alarms list will replace
the current dalarm, palarm, malarm, and aalarm fields, but I have
not yet made those changes.)
The following is a brief summary of other changes:
* A format field was added to Calendar, and supporting code was added
to call the appropriate vCal/iCal loader in calendar_load. (Note
that a #ifdef HAVE_LIBICAL surrounds a reference to the icalendar
loader, which is not yet complete and is not included.)
* A new flag CALENDAR_USE_ICAL was added to Eskil's CalendarNewOptions
enum to tell a Calendar to use iCalendar.
* Some new pointers were added to CalendarAlarm to support the richer
semantics of iCalendar-alarms. Eventually, I want to delete the
redundant old fields, but not until the rest of the code is ready.
A formal ChangeLog entry is not included in the patch, but I will add
something appropriate before committing.
If there are objections to any of these changes, please let me know.
Otherwise, I will commit them to HEAD in the next few days. More
substantial changes are in the works...
-Russell
Index: calendar.c
===================================================================
RCS file: /cvs/gnome/gnome-pim/gncal/calendar.c,v
retrieving revision 1.51
diff -u -r1.51 calendar.c
--- calendar.c 1999/12/31 15:58:08 1.51
+++ calendar.c 2000/01/17 07:52:31
@@ -40,6 +40,10 @@
cal = g_new0 (Calendar, 1);
cal->title = g_strdup (title);
+ if (options & CALENDAR_USE_ICAL)
+ cal->format = CAL_ICAL;
+ else
+ cal->format = CAL_VCAL;
if ((calendar_day_begin == 0) || (calendar_day_end == 0))
calendar_set_day ();
@@ -315,18 +319,30 @@
}
cal->filename = g_strdup (fname);
- vcal = Parse_MIME_FromFileName (fname);
- if (!vcal)
- return "Could not load the calendar";
stat (fname, &s);
cal->file_time = s.st_mtime;
-
+
calendar_set_day ();
-
- calendar_load_from_vobject (cal, vcal);
- cleanVObject (vcal);
- cleanStrTbl ();
+
+ switch (cal->format) {
+ case CAL_VCAL:
+ vcal = Parse_MIME_FromFileName (fname);
+ if (!vcal)
+ return "Could not load the calendar";
+ calendar_load_from_vobject (cal, vcal);
+ cleanVObject (vcal);
+ cleanStrTbl ();
+ break;
+#ifdef HAVE_LIBICAL
+ case CAL_ICAL:
+ icalendar_calendar_load (cal, fname);
+ break;
+#endif
+ default:
+ return "Unknown calendar format";
+ }
+
return NULL;
}
Index: calendar.h
===================================================================
RCS file: /cvs/gnome/gnome-pim/gncal/calendar.h,v
retrieving revision 1.24
diff -u -r1.24 calendar.h
--- calendar.h 1999/12/31 15:58:08 1.24
+++ calendar.h 2000/01/17 07:52:31
@@ -5,17 +5,24 @@
BEGIN_GNOME_DECLS
+typedef enum {
+ CAL_VCAL,
+ CAL_ICAL
+} CalendarFormat;
+
typedef struct {
/* This calendar's title */
char *title;
/* backing store for this calendar object */
char *filename;
+ CalendarFormat format;
/* The list of events; todo's and journal entries */
GList *events;
GList *todo;
GList *journal;
+ GList *timezones; /* required for iCalendar */
GHashTable *event_hash;
@@ -43,7 +50,8 @@
typedef enum {
CALENDAR_INIT_NIL = 0,
- CALENDAR_INIT_ALARMS = 1 << 0
+ CALENDAR_INIT_ALARMS = 1 << 0,
+ CALENDAR_USE_ICAL = 1 << 1
} CalendarNewOptions;
Calendar *calendar_new (char *title,CalendarNewOptio
ns options);
Index: calobj.c
===================================================================
RCS file: /cvs/gnome/gnome-pim/gncal/calobj.c,v
retrieving revision 1.57
diff -u -r1.57 calobj.c
--- calobj.c 1999/11/03 02:36:31 1.57
+++ calobj.c 2000/01/17 07:52:31
@@ -82,7 +82,8 @@
ico = ical_object_new ();
ico->comment = g_strdup (comment);
- ico->organizer = g_strdup (organizer);
+ ico->organizer = g_new0 (iCalPerson, 1);
+ ico->organizer->addr = g_strdup (organizer);
ico->summary = g_strdup (summary);
ico->class = g_strdup ("PUBLIC");
ico->status = g_strdup ("NEEDS ACTION");
@@ -699,13 +700,23 @@
/* Organizer */
if (has (o, VCOrgNameProp)){
- ical->organizer = g_strdup (str_val (vo));
+ ical->organizer = g_new0 (iCalPerson, 1);
+ ical->organizer->addr = g_strdup (str_val (vo));
free (the_str);
}
/* related */
if (has (o, VCRelatedToProp)){
- ical->related = set_list (str_val (vo));
+ char *str;
+ char *s;
+ iCalRelation *rel;
+ str = str_val (vo);
+ for (s = strtok (str, ";"); s; s = strtok (NULL, ";")) {
+ rel = g_new0 (iCalRelation, 1);
+ rel->uid = g_strdup (s);
+ rel->reltype = g_strdup ("PARENT");
+ ical->related = g_list_prepend (ical->related, rel);
+ }
free (the_str);
}
@@ -849,6 +860,36 @@
}
static void
+store_rel_list (VObject *o, char *prop, GList *values)
+{
+ GList *l;
+ int len;
+ char *result, *p;
+
+ for (len = 0, l = values; l; l = l->next)
+ len += strlen (((iCalRelation*)(l->data))->uid) + 1;
+
+ result = g_malloc (len);
+
+ for (p = result, l = values; l; l = l->next) {
+ int len = strlen (((iCalRelation*)(l->data))->uid);
+
+ strcpy (p, ((iCalRelation*)(l->data))->uid);
+
+ if (l->next) {
+ p [len] = ';';
+ p += len+1;
+ } else
+ p += len;
+ }
+
+ *p = 0;
+
+ addPropValue (o, prop, result);
+ g_free (result);
+}
+
+static void
store_date_list (VObject *o, char *prop, GList *values)
{
GList *l;
@@ -996,12 +1037,12 @@
addPropValue (o, VCTranspProp, to_str (ical->transp));
/* Owenr/organizer */
- if (ical->organizer)
- addPropValue (o, VCOrgNameProp, ical->organizer);
+ if (ical->organizer && ical->organizer->addr)
+ addPropValue (o, VCOrgNameProp, ical->organizer->addr);
/* related */
if (ical->related)
- store_list (o, VCRelatedToProp, ical->related);
+ store_rel_list (o, VCRelatedToProp, ical->related);
/* attach */
for (l = ical->attach; l; l = l->next)
Index: calobj.h
===================================================================
RCS file: /cvs/gnome/gnome-pim/gncal/calobj.h,v
retrieving revision 1.26
diff -u -r1.26 calobj.h
--- calobj.h 1999/09/19 09:35:41 1.26
+++ calobj.h 2000/01/17 07:52:31
@@ -31,8 +31,15 @@
int enabled;
int count;
enum AlarmUnit units;
- char *data;
+ char *data; /* not used for iCalendar alarms */
+ /* the following pointers are used for iCalendar alarms */
+
+ char *attach; /* AUDIO, EMAIL, PROC */
+ char *desc; /* DISPLAY, EMAIL, PROC */
+ char *summary; /* EMAIL */
+ char *attendee; /* EMAIL */
+
/* Does not get saved, internally used */
time_t offset;
time_t trigger;
@@ -82,6 +89,11 @@
ICAL_TRANSPARENT
} iCalTransp;
+typedef struct {
+ char *uid;
+ char *reltype;
+} iCalRelation;
+
typedef char NotYet;
enum RecurType {
@@ -119,6 +131,28 @@
int __count;
} Recurrence;
+/*
+ NOTE: iCalPerson is used for various property values which specify
+ people (e.g. ATTENDEE, ORGANIZER, etc. Not all fields are valid
+ under RFC 2445 for all property values, but iCalPerson can store
+ them anyway. Enforcing the RFC is a job for the parser.
+*/
+
+typedef struct {
+ char *addr;
+ char *name;
+ char *role;
+ char *partstat;
+ gboolean rsvp;
+ char *cutype; /* calendar user type */
+ GList *member; /* group memberships */
+ GList *deleg_to;
+ GList *deleg_from;
+ char *sent_by;
+ char *directory;
+ GList *altrep; /* list of char* URI's */
+} iCalPerson;
+
#define IS_INFINITE(r) (r->duration == 0)
/* Flags to indicate what has changed in an object */
@@ -137,7 +171,7 @@
iCalType type;
GList *attach; /* type: one or more URIs or binary data */
- GList *attendee; /* type: CAL-ADDRESS */
+ GList *attendee; /* type: CAL-ADDRESS (list of iCalPerson)
*/
GList *categories; /* type: one or more TEXT */
char *class;
@@ -145,15 +179,17 @@
time_t completed;
time_t created;
GList *contact; /* type: one or more TEXT */
+ char *desc;
time_t dtstamp;
time_t dtstart;
- time_t dtend;
+ time_t dtend; /* also duedate for todo's */
+ gboolean date_only; /* set if the start/end times were
specified using dates, not times (internal use, not stored to disk) */
GList *exdate; /* type: one or more time_t's */
GList *exrule; /* type: one or more RECUR */
iCalGeo geo;
time_t last_mod;
char *location;
- char *organizer;
+ iCalPerson *organizer;
int percent;
int priority;
char *rstatus; /* request status for freebusy */
@@ -173,6 +209,8 @@
CalendarAlarm aalarm;
CalendarAlarm palarm;
CalendarAlarm malarm;
+
+ GList *alarms;
Recurrence *recur;
Index: eventedit.c
===================================================================
RCS file: /cvs/gnome/gnome-pim/gncal/eventedit.c,v
retrieving revision 1.61
diff -u -r1.61 eventedit.c
--- eventedit.c 1999/12/31 15:58:08 1.61
+++ eventedit.c 2000/01/17 07:52:31
@@ -826,7 +826,8 @@
l = gtk_label_new (_("Owner:"));
gtk_box_pack_start (GTK_BOX (hbox), l, FALSE, FALSE, 0);
- ee->general_owner = gtk_label_new (ee->ical->organizer ? ee->ical->
organizer: _("?"));
+ ee->general_owner = gtk_label_new (ee->ical->organizer->addr ?
+ ee->ical->organizer->addr : _("?"));
gtk_misc_set_alignment (GTK_MISC (ee->general_owner), 0.0, 0.5);
gtk_box_pack_start (GTK_BOX (hbox), ee->general_owner, TRUE, TRUE,
4);
Index: main.c
===================================================================
RCS file: /cvs/gnome/gnome-pim/gncal/main.c,v
retrieving revision 1.92
diff -u -r1.92 main.c
--- main.c 1999/12/31 15:58:08 1.92
+++ main.c 2000/01/17 07:52:31
@@ -844,7 +844,7 @@
if (object->type != ICAL_TODO)
continue;
- printf ("[%s]: %s\n", object->organizer, object->summary);
+ printf ("[%s]: %s\n", object->organizer->addr, object->summary);
}
calendar_destroy (cal);
exit (0);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]