aboutsummaryrefslogtreecommitdiffstats
path: root/calendar
diff options
context:
space:
mode:
Diffstat (limited to 'calendar')
-rw-r--r--calendar/ChangeLog11
-rw-r--r--calendar/Makefile.am14
-rw-r--r--calendar/cal-util/calobj.c55
-rw-r--r--calendar/cal-util/calobj.h47
-rw-r--r--calendar/calendar.c31
-rw-r--r--calendar/calendar.h10
-rw-r--r--calendar/calobj.c55
-rw-r--r--calendar/calobj.h47
-rw-r--r--calendar/eventedit.c3
-rw-r--r--calendar/gncal-day-view.c17
-rw-r--r--calendar/gnome-cal.c4
-rw-r--r--calendar/gui/Makefile.am14
-rw-r--r--calendar/gui/calendar.c31
-rw-r--r--calendar/gui/calendar.h10
-rw-r--r--calendar/gui/eventedit.c3
-rw-r--r--calendar/gui/gncal-day-view.c17
-rw-r--r--calendar/gui/gnome-cal.c4
-rw-r--r--calendar/gui/main.c2
-rw-r--r--calendar/main.c2
-rw-r--r--calendar/pcs/calobj.c55
-rw-r--r--calendar/pcs/calobj.h47
21 files changed, 418 insertions, 61 deletions
diff --git a/calendar/ChangeLog b/calendar/ChangeLog
index e81315c966..d71c28a186 100644
--- a/calendar/ChangeLog
+++ b/calendar/ChangeLog
@@ -1,3 +1,14 @@
+2000-02-16 Russell Steinthal <rms39@columbia.edu>
+
+ * calobj.[ch], eventedit.c, main.c: Change iCalObject.organizer
+ from char* to iCalPerson*
+
+ * calobj.[ch]: Change iCalObject.related from list of char* to
+ list of iCalRelation*; assorted related fixes
+
+ * icalendar.c: interface between libical and the gnomecal
+ internal representation
+
2000-02-11 Federico Mena Quintero <federico@helixcode.com>
* cal-client.c (cal_client_update_object): Implemented.
diff --git a/calendar/Makefile.am b/calendar/Makefile.am
index 8fab42d57c..1762bc0bf7 100644
--- a/calendar/Makefile.am
+++ b/calendar/Makefile.am
@@ -20,11 +20,19 @@ endif
bin_PROGRAMS = gnomecal tlacuache $(extra_pilot_bins)
+#if HAVE_LIBICAL
+ICAL_INCLUDEDIR = -I../libical/src/libical
+ICAL_SOURCES = icalendar.c
+ICAL_LINK_FLAGS = ../libical/src/libical/libical.a
+#endif
+
+
INCLUDES = \
-I$(includedir) \
$(GNOME_INCLUDEDIR) \
$(GNOME_CONDUIT_INCLUDEDIR) \
$(PISOCK_INCLUDEDIR) \
+ $(ICAL_INCLUDEDIR) \
-DGNOMELOCALEDIR=\""$(datadir)/locale"\"
GNOMECAL_CORBA_GENERATED = \
@@ -110,7 +118,8 @@ gnomecal_SOURCES = \
view-utils.h \
view-utils.c \
year-view.c \
- year-view.h
+ year-view.h \
+ $(ICAL_SOURCES)
calendar_pilot_sync_SOURCES = \
GnomeCal-common.c \
@@ -148,7 +157,8 @@ tlacuache_SOURCES = \
LINK_FLAGS = \
$(BONOBO_VFS_GNOME_LIBS) \
$(INTLLIBS) \
- ../libversit/libversit.la
+ ../libversit/libversit.la \
+ $(ICAL_LINK_FLAGS)
tlacuache_INCLUDES = \
$(INCLUDES) \
diff --git a/calendar/cal-util/calobj.c b/calendar/cal-util/calobj.c
index 01e90e3b50..ce0d330303 100644
--- a/calendar/cal-util/calobj.c
+++ b/calendar/cal-util/calobj.c
@@ -82,7 +82,8 @@ ical_new (char *comment, char *organizer, char *summary)
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");
@@ -705,13 +706,23 @@ ical_object_create_from_vobject (VObject *o, const char *object_name)
/* 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);
}
@@ -855,6 +866,36 @@ store_list (VObject *o, char *prop, GList *values)
}
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;
@@ -1001,13 +1042,13 @@ ical_object_to_vobject (iCalObject *ical)
/* transparency */
addPropValue (o, VCTranspProp, to_str (ical->transp));
- /* Owenr/organizer */
- if (ical->organizer)
- addPropValue (o, VCOrgNameProp, ical->organizer);
+ /* Owner/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)
diff --git a/calendar/cal-util/calobj.h b/calendar/cal-util/calobj.h
index dabbc36c2d..38d9598298 100644
--- a/calendar/cal-util/calobj.h
+++ b/calendar/cal-util/calobj.h
@@ -31,7 +31,14 @@ typedef struct {
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;
@@ -82,6 +89,11 @@ typedef enum {
ICAL_TRANSPARENT
} iCalTransp;
+typedef struct {
+ char *uid;
+ char *reltype;
+} iCalRelation;
+
typedef char NotYet;
enum RecurType {
@@ -119,6 +131,28 @@ typedef struct {
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 @@ typedef struct {
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,18 @@ typedef struct {
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 */
@@ -174,6 +211,8 @@ typedef struct {
CalendarAlarm palarm;
CalendarAlarm malarm;
+ GList *alarms;
+
Recurrence *recur;
int new;
diff --git a/calendar/calendar.c b/calendar/calendar.c
index db31ba016b..0a690f344b 100644
--- a/calendar/calendar.c
+++ b/calendar/calendar.c
@@ -40,6 +40,10 @@ calendar_new (char *title,CalendarNewOptions options)
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,31 @@ calendar_load (Calendar *cal, char *fname)
}
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
+ hi;
+ case CAL_ICAL:
+ icalendar_calendar_load (cal, fname);
+ break;
+#endif
+ default:
+ return "Unknown calendar format";
+ }
+
return NULL;
}
diff --git a/calendar/calendar.h b/calendar/calendar.h
index 858f0151ca..452281ebd1 100644
--- a/calendar/calendar.h
+++ b/calendar/calendar.h
@@ -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 struct {
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,CalendarNewOptions options);
diff --git a/calendar/calobj.c b/calendar/calobj.c
index 01e90e3b50..ce0d330303 100644
--- a/calendar/calobj.c
+++ b/calendar/calobj.c
@@ -82,7 +82,8 @@ ical_new (char *comment, char *organizer, char *summary)
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");
@@ -705,13 +706,23 @@ ical_object_create_from_vobject (VObject *o, const char *object_name)
/* 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);
}
@@ -855,6 +866,36 @@ store_list (VObject *o, char *prop, GList *values)
}
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;
@@ -1001,13 +1042,13 @@ ical_object_to_vobject (iCalObject *ical)
/* transparency */
addPropValue (o, VCTranspProp, to_str (ical->transp));
- /* Owenr/organizer */
- if (ical->organizer)
- addPropValue (o, VCOrgNameProp, ical->organizer);
+ /* Owner/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)
diff --git a/calendar/calobj.h b/calendar/calobj.h
index dabbc36c2d..38d9598298 100644
--- a/calendar/calobj.h
+++ b/calendar/calobj.h
@@ -31,7 +31,14 @@ typedef struct {
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;
@@ -82,6 +89,11 @@ typedef enum {
ICAL_TRANSPARENT
} iCalTransp;
+typedef struct {
+ char *uid;
+ char *reltype;
+} iCalRelation;
+
typedef char NotYet;
enum RecurType {
@@ -119,6 +131,28 @@ typedef struct {
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 @@ typedef struct {
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,18 @@ typedef struct {
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 */
@@ -174,6 +211,8 @@ typedef struct {
CalendarAlarm palarm;
CalendarAlarm malarm;
+ GList *alarms;
+
Recurrence *recur;
int new;
diff --git a/calendar/eventedit.c b/calendar/eventedit.c
index 31fbf11225..a3ec95da07 100644
--- a/calendar/eventedit.c
+++ b/calendar/eventedit.c
@@ -826,7 +826,8 @@ ee_init_general_page (EventEditor *ee)
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);
diff --git a/calendar/gncal-day-view.c b/calendar/gncal-day-view.c
index eafd237029..22a0859069 100644
--- a/calendar/gncal-day-view.c
+++ b/calendar/gncal-day-view.c
@@ -13,7 +13,7 @@
#include "main.h"
#include "eventedit.h"
#include "popup-menu.h"
-
+#include "quick-view.h"
#define TEXT_BORDER 2
#define MIN_INFO_WIDTH 50
@@ -152,6 +152,21 @@ gncal_day_view_button_press (GtkWidget *widget, GdkEventButton *event)
if (event->button == 1 && event->type == GDK_2BUTTON_PRESS)
gnome_calendar_dayjump (dayview->calendar, dayview->lower);
+#if 0
+ else if (event->button == 1 && event->type == GDK_BUTTON_PRESS) {
+ time_t day_begin_time, day_end_time;
+ GList *list;
+ GtkWidget *qv;
+ char date_str [256];
+
+ strftime (date_str, sizeof (date_str), _("%a %b %d %Y"),
+ localtime (&dayview->lower));
+ qv = quick_view_new (dayview->calendar, date_str, dayview->events);
+ quick_view_do_popup (QUICK_VIEW (qv), event);
+ gtk_widget_destroy (qv);
+ }
+#endif
+
return TRUE;
}
diff --git a/calendar/gnome-cal.c b/calendar/gnome-cal.c
index d54c4e98df..0e3c475fdf 100644
--- a/calendar/gnome-cal.c
+++ b/calendar/gnome-cal.c
@@ -228,7 +228,7 @@ gnome_calendar_new (char *title)
gtk_window_set_title(GTK_WINDOW(retval), title);
gcal->current_display = time_day_begin (time (NULL));
- gcal->cal = calendar_new (title,CALENDAR_INIT_ALARMS);
+ gcal->cal = calendar_new (title, CALENDAR_INIT_ALARMS);
setup_widgets (gcal);
gnome_calendar_create_corba_server (gcal);
@@ -450,6 +450,7 @@ calendar_notify (time_t activation_time, CalendarAlarm *which, void *data)
gtk_object_set_data (GTK_OBJECT (w), "beep_tag",
GINT_TO_POINTER (beep_tag));
gtk_widget_ref (w);
+ gtk_window_set_modal (GTK_WINDOW (w), FALSE);
ret = gnome_dialog_run (GNOME_DIALOG (w));
switch (ret) {
case 1:
@@ -493,6 +494,7 @@ calendar_notify (time_t activation_time, CalendarAlarm *which, void *data)
ico->summary, "'", NULL);
w = gnome_message_box_new (msg, GNOME_MESSAGE_BOX_INFO,
_("Ok"), snooze_button, NULL);
+ gtk_window_set_modal (GTK_WINDOW (w), FALSE);
ret = gnome_dialog_run (GNOME_DIALOG (w));
switch (ret) {
case 1:
diff --git a/calendar/gui/Makefile.am b/calendar/gui/Makefile.am
index 8fab42d57c..1762bc0bf7 100644
--- a/calendar/gui/Makefile.am
+++ b/calendar/gui/Makefile.am
@@ -20,11 +20,19 @@ endif
bin_PROGRAMS = gnomecal tlacuache $(extra_pilot_bins)
+#if HAVE_LIBICAL
+ICAL_INCLUDEDIR = -I../libical/src/libical
+ICAL_SOURCES = icalendar.c
+ICAL_LINK_FLAGS = ../libical/src/libical/libical.a
+#endif
+
+
INCLUDES = \
-I$(includedir) \
$(GNOME_INCLUDEDIR) \
$(GNOME_CONDUIT_INCLUDEDIR) \
$(PISOCK_INCLUDEDIR) \
+ $(ICAL_INCLUDEDIR) \
-DGNOMELOCALEDIR=\""$(datadir)/locale"\"
GNOMECAL_CORBA_GENERATED = \
@@ -110,7 +118,8 @@ gnomecal_SOURCES = \
view-utils.h \
view-utils.c \
year-view.c \
- year-view.h
+ year-view.h \
+ $(ICAL_SOURCES)
calendar_pilot_sync_SOURCES = \
GnomeCal-common.c \
@@ -148,7 +157,8 @@ tlacuache_SOURCES = \
LINK_FLAGS = \
$(BONOBO_VFS_GNOME_LIBS) \
$(INTLLIBS) \
- ../libversit/libversit.la
+ ../libversit/libversit.la \
+ $(ICAL_LINK_FLAGS)
tlacuache_INCLUDES = \
$(INCLUDES) \
diff --git a/calendar/gui/calendar.c b/calendar/gui/calendar.c
index db31ba016b..0a690f344b 100644
--- a/calendar/gui/calendar.c
+++ b/calendar/gui/calendar.c
@@ -40,6 +40,10 @@ calendar_new (char *title,CalendarNewOptions options)
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,31 @@ calendar_load (Calendar *cal, char *fname)
}
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
+ hi;
+ case CAL_ICAL:
+ icalendar_calendar_load (cal, fname);
+ break;
+#endif
+ default:
+ return "Unknown calendar format";
+ }
+
return NULL;
}
diff --git a/calendar/gui/calendar.h b/calendar/gui/calendar.h
index 858f0151ca..452281ebd1 100644
--- a/calendar/gui/calendar.h
+++ b/calendar/gui/calendar.h
@@ -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 struct {
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,CalendarNewOptions options);
diff --git a/calendar/gui/eventedit.c b/calendar/gui/eventedit.c
index 31fbf11225..a3ec95da07 100644
--- a/calendar/gui/eventedit.c
+++ b/calendar/gui/eventedit.c
@@ -826,7 +826,8 @@ ee_init_general_page (EventEditor *ee)
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);
diff --git a/calendar/gui/gncal-day-view.c b/calendar/gui/gncal-day-view.c
index eafd237029..22a0859069 100644
--- a/calendar/gui/gncal-day-view.c
+++ b/calendar/gui/gncal-day-view.c
@@ -13,7 +13,7 @@
#include "main.h"
#include "eventedit.h"
#include "popup-menu.h"
-
+#include "quick-view.h"
#define TEXT_BORDER 2
#define MIN_INFO_WIDTH 50
@@ -152,6 +152,21 @@ gncal_day_view_button_press (GtkWidget *widget, GdkEventButton *event)
if (event->button == 1 && event->type == GDK_2BUTTON_PRESS)
gnome_calendar_dayjump (dayview->calendar, dayview->lower);
+#if 0
+ else if (event->button == 1 && event->type == GDK_BUTTON_PRESS) {
+ time_t day_begin_time, day_end_time;
+ GList *list;
+ GtkWidget *qv;
+ char date_str [256];
+
+ strftime (date_str, sizeof (date_str), _("%a %b %d %Y"),
+ localtime (&dayview->lower));
+ qv = quick_view_new (dayview->calendar, date_str, dayview->events);
+ quick_view_do_popup (QUICK_VIEW (qv), event);
+ gtk_widget_destroy (qv);
+ }
+#endif
+
return TRUE;
}
diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c
index d54c4e98df..0e3c475fdf 100644
--- a/calendar/gui/gnome-cal.c
+++ b/calendar/gui/gnome-cal.c
@@ -228,7 +228,7 @@ gnome_calendar_new (char *title)
gtk_window_set_title(GTK_WINDOW(retval), title);
gcal->current_display = time_day_begin (time (NULL));
- gcal->cal = calendar_new (title,CALENDAR_INIT_ALARMS);
+ gcal->cal = calendar_new (title, CALENDAR_INIT_ALARMS);
setup_widgets (gcal);
gnome_calendar_create_corba_server (gcal);
@@ -450,6 +450,7 @@ calendar_notify (time_t activation_time, CalendarAlarm *which, void *data)
gtk_object_set_data (GTK_OBJECT (w), "beep_tag",
GINT_TO_POINTER (beep_tag));
gtk_widget_ref (w);
+ gtk_window_set_modal (GTK_WINDOW (w), FALSE);
ret = gnome_dialog_run (GNOME_DIALOG (w));
switch (ret) {
case 1:
@@ -493,6 +494,7 @@ calendar_notify (time_t activation_time, CalendarAlarm *which, void *data)
ico->summary, "'", NULL);
w = gnome_message_box_new (msg, GNOME_MESSAGE_BOX_INFO,
_("Ok"), snooze_button, NULL);
+ gtk_window_set_modal (GTK_WINDOW (w), FALSE);
ret = gnome_dialog_run (GNOME_DIALOG (w));
switch (ret) {
case 1:
diff --git a/calendar/gui/main.c b/calendar/gui/main.c
index ee4111b03e..eb1823fc6f 100644
--- a/calendar/gui/main.c
+++ b/calendar/gui/main.c
@@ -829,7 +829,7 @@ dump_todo (void)
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);
diff --git a/calendar/main.c b/calendar/main.c
index ee4111b03e..eb1823fc6f 100644
--- a/calendar/main.c
+++ b/calendar/main.c
@@ -829,7 +829,7 @@ dump_todo (void)
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);
diff --git a/calendar/pcs/calobj.c b/calendar/pcs/calobj.c
index 01e90e3b50..ce0d330303 100644
--- a/calendar/pcs/calobj.c
+++ b/calendar/pcs/calobj.c
@@ -82,7 +82,8 @@ ical_new (char *comment, char *organizer, char *summary)
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");
@@ -705,13 +706,23 @@ ical_object_create_from_vobject (VObject *o, const char *object_name)
/* 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);
}
@@ -855,6 +866,36 @@ store_list (VObject *o, char *prop, GList *values)
}
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;
@@ -1001,13 +1042,13 @@ ical_object_to_vobject (iCalObject *ical)
/* transparency */
addPropValue (o, VCTranspProp, to_str (ical->transp));
- /* Owenr/organizer */
- if (ical->organizer)
- addPropValue (o, VCOrgNameProp, ical->organizer);
+ /* Owner/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)
diff --git a/calendar/pcs/calobj.h b/calendar/pcs/calobj.h
index dabbc36c2d..38d9598298 100644
--- a/calendar/pcs/calobj.h
+++ b/calendar/pcs/calobj.h
@@ -31,7 +31,14 @@ typedef struct {
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;
@@ -82,6 +89,11 @@ typedef enum {
ICAL_TRANSPARENT
} iCalTransp;
+typedef struct {
+ char *uid;
+ char *reltype;
+} iCalRelation;
+
typedef char NotYet;
enum RecurType {
@@ -119,6 +131,28 @@ typedef struct {
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 @@ typedef struct {
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,18 @@ typedef struct {
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 */
@@ -174,6 +211,8 @@ typedef struct {
CalendarAlarm palarm;
CalendarAlarm malarm;
+ GList *alarms;
+
Recurrence *recur;
int new;