aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--calendar/ChangeLog50
-rw-r--r--calendar/cal-client/cal-client.c119
-rw-r--r--calendar/cal-client/cal-client.h1
-rw-r--r--calendar/cal-util/cal-util.h7
-rw-r--r--calendar/cal-util/calobj.c2008
-rw-r--r--calendar/cal-util/calobj.h312
-rw-r--r--calendar/gui/Makefile.am2
-rw-r--r--calendar/gui/calendar-component.c28
-rw-r--r--calendar/gui/calendar-offline-handler.c267
-rw-r--r--calendar/gui/calendar-offline-handler.h70
-rw-r--r--calendar/gui/component-factory.c28
-rw-r--r--calendar/gui/dialogs/comp-editor.c2
-rw-r--r--calendar/gui/e-itip-control.c3
-rw-r--r--calendar/idl/evolution-calendar.idl9
-rw-r--r--calendar/pcs/cal-backend-file.c15
-rw-r--r--calendar/pcs/cal-backend.c27
-rw-r--r--calendar/pcs/cal-backend.h2
-rw-r--r--calendar/pcs/cal-factory.c77
-rw-r--r--calendar/pcs/cal.c68
19 files changed, 643 insertions, 2452 deletions
diff --git a/calendar/ChangeLog b/calendar/ChangeLog
index 91b4e948f4..e25a1f1778 100644
--- a/calendar/ChangeLog
+++ b/calendar/ChangeLog
@@ -1,3 +1,53 @@
+2001-09-25 JP Rosevear <jpr@ximian.com>
+
+ * pcs/cal.c: use bonobo-exception stuff to clean code
+
+ * pcs/cal-factory.c (add_uri): add uri to the list if the type
+ matches
+ (impl_CalFactory_uriList): implement uriList method
+
+ * pcs/cal-backend.h: new virtual function member
+
+ * pcs/cal-backend.c (cal_backend_is_remote): call virtual function
+
+ * pcs/cal-backend-file.c (cal_backend_file_class_init): override
+ virtual function
+ (cal_backend_file_is_remote): new virtual function, always return
+ FALSE
+
+ * idl/evolution-calendar.idl: uriList factory call, with flags for
+ types to get
+
+ * gui/dialogs/comp-editor.c (comp_editor_destroy): cast to remove
+ warning
+
+ * gui/e-itip-control.c (write_label_piece): kill warnings by take
+ const char *
+
+ * gui/component-factory.c (create_object): aggregate offline
+ interface
+
+ * gui/Makefile.am: compile new files
+
+ * calobj.[hc]: Remove obsolete files
+
+ * cal-util/cal-util.h: enum URI types for uriList call
+
+ * cal-client/cal-client.c (build_uri_list): build list from string
+ sequence
+ (cal_client_uri_list): factory call to get uri list
+
+ * cal-client/cal-client.h: new proto
+
+ * cal-client/cal-client.c: use bonobo exception stuff to clean
+ code
+
+ * gui/calendar-offline-handler.[hc]: Start some skeleton routines
+ for online/offline handling
+
+ * pcs/cal-factory.c (launch_backend_for_uri): use accessor and
+ remove FIXME
+
2001-09-23 JP Rosevear <jpr@ximian.com>
* gui/e-itip-control.c (set_date_label): base text on component
diff --git a/calendar/cal-client/cal-client.c b/calendar/cal-client/cal-client.c
index e0a37159f5..78d31eeab6 100644
--- a/calendar/cal-client/cal-client.c
+++ b/calendar/cal-client/cal-client.c
@@ -25,6 +25,7 @@
#include <gtk/gtksignal.h>
#include <liboaf/liboaf.h>
+#include <bonobo/bonobo-exception.h>
#include "cal-client-types.h"
#include "cal-client.h"
@@ -240,7 +241,7 @@ destroy_factory (CalClient *client)
CORBA_exception_init (&ev);
result = CORBA_Object_is_nil (priv->factory, &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
+ if (BONOBO_EX (&ev)) {
g_message ("destroy_factory(): could not see if the factory was nil");
priv->factory = CORBA_OBJECT_NIL;
CORBA_exception_free (&ev);
@@ -253,7 +254,7 @@ destroy_factory (CalClient *client)
CORBA_exception_init (&ev);
CORBA_Object_release (priv->factory, &ev);
- if (ev._major != CORBA_NO_EXCEPTION)
+ if (BONOBO_EX (&ev))
g_message ("destroy_factory(): could not release the factory");
CORBA_exception_free (&ev);
@@ -272,7 +273,7 @@ destroy_cal (CalClient *client)
CORBA_exception_init (&ev);
result = CORBA_Object_is_nil (priv->cal, &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
+ if (BONOBO_EX (&ev)) {
g_message ("destroy_cal(): could not see if the "
"calendar client interface object was nil");
priv->cal = CORBA_OBJECT_NIL;
@@ -286,14 +287,14 @@ destroy_cal (CalClient *client)
CORBA_exception_init (&ev);
GNOME_Evolution_Calendar_Cal_unref (priv->cal, &ev);
- if (ev._major != CORBA_NO_EXCEPTION)
+ if (BONOBO_EX (&ev))
g_message ("destroy_cal(): could not unref the calendar client interface object");
CORBA_exception_free (&ev);
CORBA_exception_init (&ev);
CORBA_Object_release (priv->cal, &ev);
- if (ev._major != CORBA_NO_EXCEPTION)
+ if (BONOBO_EX (&ev))
g_message ("destroy_cal(): could not release the calendar client interface object");
CORBA_exception_free (&ev);
@@ -353,7 +354,6 @@ cal_client_destroy (GtkObject *object)
/* Signal handlers for the listener's signals */
-
/* Handle the cal_opened notification from the listener */
static void
cal_opened_cb (CalListener *listener,
@@ -379,7 +379,7 @@ cal_opened_cb (CalListener *listener,
case GNOME_Evolution_Calendar_Listener_SUCCESS:
CORBA_exception_init (&ev);
cal_copy = CORBA_Object_duplicate (cal, &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
+ if (BONOBO_EX (&ev)) {
g_message ("cal_opened_cb(): could not duplicate the "
"calendar client interface");
CORBA_exception_free (&ev);
@@ -485,6 +485,7 @@ categories_changed_cb (CalListener *listener, const GNOME_Evolution_Calendar_Str
g_ptr_array_free (cats, TRUE);
}
+
/* Handle the get_password signal from the Wombatclient */
static gchar *
client_get_password_cb (WombatClient *w_client,
@@ -549,7 +550,7 @@ cal_client_construct (CalClient *client)
"OAFIID:GNOME_Evolution_Wombat_CalendarFactory",
0, NULL, &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
+ if (BONOBO_EX (&ev)) {
g_message ("cal_client_construct(): Could not activate the calendar factory");
CORBA_exception_free (&ev);
return NULL;
@@ -558,7 +559,7 @@ cal_client_construct (CalClient *client)
CORBA_exception_init (&ev);
factory_copy = CORBA_Object_duplicate (factory, &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
+ if (BONOBO_EX (&ev)) {
g_message ("cal_client_construct(): could not duplicate the calendar factory");
CORBA_exception_free (&ev);
return NULL;
@@ -666,8 +667,7 @@ cal_client_open_calendar (CalClient *client, const char *str_uri, gboolean only_
bonobo_object_add_interface (BONOBO_OBJECT (priv->listener),
BONOBO_OBJECT (priv->w_client));
- corba_listener = (GNOME_Evolution_Calendar_Listener) bonobo_object_corba_objref (
- BONOBO_OBJECT (priv->listener));
+ corba_listener = (GNOME_Evolution_Calendar_Listener) (BONOBO_OBJREF (priv->listener));
CORBA_exception_init (&ev);
@@ -677,7 +677,7 @@ cal_client_open_calendar (CalClient *client, const char *str_uri, gboolean only_
GNOME_Evolution_Calendar_CalFactory_open (priv->factory, str_uri, only_if_exists,
corba_listener, &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
+ if (BONOBO_EX (&ev)) {
CORBA_exception_free (&ev);
g_message ("cal_client_open_calendar(): open request failed");
@@ -694,6 +694,54 @@ cal_client_open_calendar (CalClient *client, const char *str_uri, gboolean only_
return TRUE;
}
+/* Builds an URI list out of a CORBA string sequence */
+static GList *
+build_uri_list (GNOME_Evolution_Calendar_StringSeq *seq)
+{
+ GList *uris = NULL;
+ int i;
+
+ for (i = 0; i < seq->_length; i++)
+ uris = g_list_prepend (uris, g_strdup (seq->_buffer[i]));
+
+ return uris;
+}
+
+/**
+ * cal_client_uri_list:
+ * @client: A calendar client
+ * @type: type of uri's to get
+ *
+ *
+ * Return value: A list of URI's open on the wombat
+ **/
+GList *
+cal_client_uri_list (CalClient *client, CalUriType type)
+{
+ CalClientPrivate *priv;
+ GNOME_Evolution_Calendar_StringSeq *uri_seq;
+ GList *uris = NULL;
+ CORBA_Environment ev;
+
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
+
+ priv = client->priv;
+
+ CORBA_exception_init (&ev);
+
+ uri_seq = GNOME_Evolution_Calendar_CalFactory_uriList (priv->factory, type, &ev);
+
+ if (BONOBO_EX (&ev))
+ g_message ("cal_client_uri_list(): request failed");
+ else
+ uris = build_uri_list (uri_seq);
+
+ CORBA_exception_free (&ev);
+
+ return uris;
+}
+
/**
* cal_client_get_load_state:
* @client: A calendar client.
@@ -775,7 +823,7 @@ cal_client_get_n_objects (CalClient *client, CalObjType type)
CORBA_exception_init (&ev);
n = GNOME_Evolution_Calendar_Cal_countObjects (priv->cal, t, &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
+ if (BONOBO_EX (&ev)) {
g_message ("cal_client_get_n_objects(): could not get the number of objects");
CORBA_exception_free (&ev);
return -1;
@@ -834,10 +882,9 @@ cal_client_get_object (CalClient *client, const char *uid, CalComponent **comp)
CORBA_exception_init (&ev);
comp_str = GNOME_Evolution_Calendar_Cal_getObject (priv->cal, (char *) uid, &ev);
- if (ev._major == CORBA_USER_EXCEPTION
- && strcmp (CORBA_exception_id (&ev), ex_GNOME_Evolution_Calendar_Cal_NotFound) == 0)
+ if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_NotFound))
goto out;
- else if (ev._major != CORBA_NO_EXCEPTION) {
+ else if (BONOBO_EX (&ev)) {
g_message ("cal_client_get_object(): could not get the object");
goto out;
}
@@ -950,10 +997,9 @@ cal_client_get_timezone (CalClient *client,
CORBA_exception_init (&ev);
comp_str = GNOME_Evolution_Calendar_Cal_getTimezoneObject (priv->cal, (char *) tzid, &ev);
- if (ev._major == CORBA_USER_EXCEPTION
- && strcmp (CORBA_exception_id (&ev), ex_GNOME_Evolution_Calendar_Cal_NotFound) == 0)
+ if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_NotFound))
goto out;
- else if (ev._major != CORBA_NO_EXCEPTION) {
+ else if (BONOBO_EX (&ev)) {
g_message ("cal_client_get_timezone(): could not get the object");
goto out;
}
@@ -1058,7 +1104,7 @@ cal_client_get_uids (CalClient *client, CalObjType type)
CORBA_exception_init (&ev);
seq = GNOME_Evolution_Calendar_Cal_getUIDs (priv->cal, t, &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
+ if (BONOBO_EX (&ev)) {
g_message ("cal_client_get_uids(): could not get the list of UIDs");
CORBA_exception_free (&ev);
return NULL;
@@ -1127,7 +1173,7 @@ cal_client_get_changes (CalClient *client, CalObjType type, const char *change_i
CORBA_exception_init (&ev);
seq = GNOME_Evolution_Calendar_Cal_getChanges (priv->cal, t, change_id, &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
+ if (BONOBO_EX (&ev)) {
g_message ("cal_client_get_changes(): could not get the list of changes");
CORBA_exception_free (&ev);
return NULL;
@@ -1208,7 +1254,7 @@ cal_client_get_objects_in_range (CalClient *client, CalObjType type, time_t star
t = corba_obj_type (type);
seq = GNOME_Evolution_Calendar_Cal_getObjectsInRange (priv->cal, t, start, end, &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
+ if (BONOBO_EX (&ev)) {
g_message ("cal_client_get_objects_in_range(): could not get the objects");
CORBA_exception_free (&ev);
return NULL;
@@ -1270,7 +1316,7 @@ cal_client_get_free_busy (CalClient *client, GList *users,
calobj_list = GNOME_Evolution_Calendar_Cal_getFreeBusy (priv->cal, corba_list,
start, end, &ev);
CORBA_free (corba_list);
- if (ev._major != CORBA_NO_EXCEPTION || !calobj_list) {
+ if (BONOBO_EX (&ev) || !calobj_list) {
g_message ("cal_client_get_free_busy(): could not get the objects");
CORBA_exception_free (&ev);
return NULL;
@@ -1696,7 +1742,7 @@ cal_client_get_alarms_in_range (CalClient *client, time_t start, time_t end)
CORBA_exception_init (&ev);
seq = GNOME_Evolution_Calendar_Cal_getAlarmsInRange (priv->cal, start, end, &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
+ if (BONOBO_EX (&ev)) {
g_message ("cal_client_get_alarms_in_range(): could not get the alarm range");
CORBA_exception_free (&ev);
return NULL;
@@ -1778,10 +1824,9 @@ cal_client_get_alarms_for_object (CalClient *client, const char *uid,
corba_alarms = GNOME_Evolution_Calendar_Cal_getAlarmsForObject (priv->cal, (char *) uid,
start, end, &ev);
- if (ev._major == CORBA_USER_EXCEPTION
- && strcmp (CORBA_exception_id (&ev), ex_GNOME_Evolution_Calendar_Cal_NotFound) == 0)
+ if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_NotFound))
goto out;
- else if (ev._major != CORBA_NO_EXCEPTION) {
+ else if (BONOBO_EX (&ev)) {
g_message ("cal_client_get_alarms_for_object(): could not get the alarm range");
goto out;
}
@@ -1975,11 +2020,10 @@ cal_client_update_object (CalClient *client, CalComponent *comp)
CORBA_exception_init (&ev);
GNOME_Evolution_Calendar_Cal_updateObjects (priv->cal, obj_string, &ev);
g_free (obj_string);
-
- if (ev._major == CORBA_USER_EXCEPTION &&
- strcmp (CORBA_exception_id (&ev), ex_GNOME_Evolution_Calendar_Cal_InvalidObject) == 0)
- goto out;
- else if (ev._major != CORBA_NO_EXCEPTION) {
+
+ if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_InvalidObject))
+ goto out;
+ else if (BONOBO_EX (&ev)) {
g_message ("cal_client_update_object(): could not update the object");
goto out;
}
@@ -2033,11 +2077,9 @@ cal_client_update_objects (CalClient *client, icalcomponent *icalcomp)
CORBA_exception_init (&ev);
GNOME_Evolution_Calendar_Cal_updateObjects (priv->cal, obj_string, &ev);
- if (ev._major == CORBA_USER_EXCEPTION &&
- strcmp (CORBA_exception_id (&ev),
- ex_GNOME_Evolution_Calendar_Cal_InvalidObject) == 0)
+ if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_InvalidObject))
goto out;
- else if (ev._major != CORBA_NO_EXCEPTION) {
+ else if (BONOBO_EX (&ev)) {
g_message ("cal_client_update_objects(): could not update the objects");
goto out;
}
@@ -2085,10 +2127,9 @@ cal_client_remove_object (CalClient *client, const char *uid)
CORBA_exception_init (&ev);
GNOME_Evolution_Calendar_Cal_removeObject (priv->cal, (char *) uid, &ev);
- if (ev._major == CORBA_USER_EXCEPTION &&
- strcmp (CORBA_exception_id (&ev), ex_GNOME_Evolution_Calendar_Cal_NotFound) == 0)
+ if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_NotFound))
goto out;
- else if (ev._major != CORBA_NO_EXCEPTION) {
+ else if (BONOBO_EX (&ev)) {
g_message ("cal_client_remove_object(): could not remove the object");
goto out;
}
diff --git a/calendar/cal-client/cal-client.h b/calendar/cal-client/cal-client.h
index 315f05e054..4237563dc7 100644
--- a/calendar/cal-client/cal-client.h
+++ b/calendar/cal-client/cal-client.h
@@ -101,6 +101,7 @@ CalClient *cal_client_new (void);
void cal_client_set_auth_func (CalClient *client, CalClientAuthFunc func, gpointer data);
gboolean cal_client_open_calendar (CalClient *client, const char *str_uri, gboolean only_if_exists);
+GList *cal_client_uri_list (CalClient *client, CalUriType type);
CalClientLoadState cal_client_get_load_state (CalClient *client);
diff --git a/calendar/cal-util/cal-util.h b/calendar/cal-util/cal-util.h
index 943f048d35..2cf7fcee8f 100644
--- a/calendar/cal-util/cal-util.h
+++ b/calendar/cal-util/cal-util.h
@@ -53,6 +53,13 @@ typedef enum {
CALOBJ_TYPE_ANY = 0x07
} CalObjType;
+/* Used for uri list */
+typedef enum {
+ CALURI_TYPE_LOCAL = 1 << 0,
+ CALURI_TYPE_REMOTE = 1 << 1,
+ CALURI_TYPE_ANY = 0x07
+} CalUriType;
+
void cal_obj_uid_list_free (GList *list);
icalcomponent *cal_util_new_top_level (void);
diff --git a/calendar/cal-util/calobj.c b/calendar/cal-util/calobj.c
deleted file mode 100644
index 4ffd180c15..0000000000
--- a/calendar/cal-util/calobj.c
+++ /dev/null
@@ -1,2008 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Calendar objects implementations.
- * Copyright (C) 1998 the Free Software Foundation
- *
- * Authors:
- * Miguel de Icaza (miguel@gnu.org)
- * Federico Mena (quartic@gimp.org)
- */
-#include <config.h>
-#include <string.h>
-#include <glib.h>
-#include <ctype.h>
-#include <unistd.h>
-#include <time.h>
-#include "calobj.h"
-#include "timeutil.h"
-#include "libversit/vcc.h"
-#include "icalendar-save.h"
-#include "icalendar.h"
-
-
-
-/* VCalendar product ID */
-#define PRODID "-//Ximian//NONSGML Evolution Calendar//EN"
-
-static gint compare_exdates (gconstpointer a, gconstpointer b);
-static void ical_object_normalize_summary (iCalObject *ico);
-static void list_free (GList *list);
-
-
-
-char *
-ical_gen_uid (void)
-{
- static char *hostname;
- time_t t = time (NULL);
- static int serial;
-
- if (!hostname){
- char buffer [128];
-
- if ((gethostname (buffer, sizeof (buffer)-1) == 0) &&
- (buffer [0] != 0))
- hostname = g_strdup (buffer);
- else
- hostname = g_strdup ("localhost");
- }
-
- return g_strdup_printf (
- "%s-%d-%d-%d-%d@%s",
- isodate_from_time_t (t),
- getpid (),
- getgid (),
- getppid (),
- serial++,
- hostname);
-}
-
-iCalObject *
-ical_object_new (void)
-{
- iCalObject *ico;
-
- ico = g_new0 (iCalObject, 1);
-
- ico->seq = -1;
- ico->dtstamp = time (NULL);
- ico->uid = ical_gen_uid ();
-
- ico->pilot_id = 0;
- ico->pilot_status = ICAL_PILOT_SYNC_MOD;
-
- ico->ref_count = 1;
-
- return ico;
-}
-
-iCalObject *
-ical_new (char *comment, char *organizer, char *summary)
-{
- iCalObject *ico;
-
- ico = ical_object_new ();
-
- ico->comment = g_strdup (comment);
- 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");
-
- ico->dalarm.type = ALARM_DISPLAY;
- ico->palarm.type = ALARM_PROGRAM;
- ico->malarm.type = ALARM_MAIL;
- ico->aalarm.type = ALARM_AUDIO;
-
- ical_object_normalize_summary (ico);
-
- return ico;
-}
-
-
-void
-ical_object_ref (iCalObject *ico)
-{
- ico->ref_count++;
-}
-
-
-#define free_if_defined(x) if (x){ g_free (x); x = 0; }
-#define lfree_if_defined(x) if (x){ list_free (x); x = 0; }
-static void
-ical_object_destroy (iCalObject *ico)
-{
- /* Regular strings */
- free_if_defined (ico->comment);
- free_if_defined (ico->organizer);
- free_if_defined (ico->summary);
- free_if_defined (ico->uid);
- free_if_defined (ico->status);
- free_if_defined (ico->class);
- free_if_defined (ico->url);
- free_if_defined (ico->recur);
-
- /* Lists */
- lfree_if_defined (ico->exdate);
- lfree_if_defined (ico->categories);
- lfree_if_defined (ico->resources);
- lfree_if_defined (ico->related);
- lfree_if_defined (ico->attach);
-
- /* Alarms */
- g_free (ico->dalarm.data);
- g_free (ico->palarm.data);
- g_free (ico->malarm.data);
- g_free (ico->aalarm.data);
-
- g_free (ico);
-}
-
-void
-ical_object_unref (iCalObject *ico)
-{
- ico->ref_count--;
- if (ico->ref_count == 0)
- ical_object_destroy (ico);
-}
-
-
-static void
-my_free (gpointer data, gpointer user_dat_ignored)
-{
- g_free (data);
-}
-
-static void
-list_free (GList *list)
-{
- g_list_foreach (list, my_free, 0);
- g_list_free (list);
-}
-
-/* This resets any recurrence rules of the iCalObject. */
-void
-ical_object_reset_recurrence (iCalObject *ico)
-{
- free_if_defined (ico->recur);
- lfree_if_defined (ico->exdate);
-}
-
-static GList *
-set_list (char *str)
-{
- GList *list = 0;
- char *s;
-
- for (s = strtok (str, ";"); s; s = strtok (NULL, ";"))
- list = g_list_prepend (list, g_strdup (s));
-
- return list;
-}
-
-static GList *
-set_date_list (char *str)
-{
- GList *list = 0;
- char *s;
-
- for (s = strtok (str, ";,"); s; s = strtok (NULL, ";,")){
- time_t *t = g_new (time_t, 1);
-
- while (*s && isspace (*s))
- s++;
- *t = time_from_isodate (s);
- list = g_list_prepend (list, t);
- }
- return list;
-}
-
-void
-ical_object_add_exdate (iCalObject *o, time_t t)
-{
- time_t *pt = g_new (time_t, 1);
-
- *pt = t;
- o->exdate = g_list_prepend (o->exdate, pt);
-}
-
-static void
-ignore_space(char **str)
-{
- while (**str && isspace (**str))
- (*str)++;
-}
-
-static void
-skip_numbers (char **str)
-{
- while (**str){
- ignore_space (str);
- if (!isdigit (**str))
- return;
- while (**str && isdigit (**str))
- (*str)++;
- }
-}
-
-static void
-weekdaylist (iCalObject *o, char **str)
-{
- int i;
- struct {
- char first_letter, second_letter;
- int index;
- } days [] = {
- { 'S', 'U', 0 },
- { 'M', 'O', 1 },
- { 'T', 'U', 2 },
- { 'W', 'E', 3 },
- { 'T', 'H', 4 },
- { 'F', 'R', 5 },
- { 'S', 'A', 6 }
- };
-
- ignore_space (str);
- do {
- for (i = 0; i < 7; i++){
- if (**str == days [i].first_letter && *(*str+1) == days [i].second_letter){
- o->recur->weekday |= 1 << i;
- *str += 2;
- if (**str == ' ')
- (*str)++;
- }
- }
- } while (isalpha ((unsigned char) **str));
-
- if (o->recur->weekday == 0){
- struct tm tm = *localtime (&o->dtstart);
-
- o->recur->weekday = 1 << tm.tm_wday;
- }
-}
-
-static void
-weekdaynum (iCalObject *o, char **str)
-{
- int i;
- struct {
- char first_letter, second_letter;
- int index;
- } days [] = {
- { 'S', 'U', 0 },
- { 'M', 'O', 1 },
- { 'T', 'U', 2 },
- { 'W', 'E', 3 },
- { 'T', 'H', 4 },
- { 'F', 'R', 5 },
- { 'S', 'A', 6 }
- };
-
- ignore_space (str);
- do {
- for (i = 0; i < 7; i++){
- if (**str == days [i].first_letter && *(*str+1) == days [i].second_letter){
- o->recur->weekday = i;
- *str += 2;
- if (**str == ' ')
- (*str)++;
- }
- }
- } while (isalpha ((unsigned char) **str));
-}
-
-static void
-ocurrencelist (iCalObject *o, char **str)
-{
- char *p;
-
- ignore_space (str);
- p = *str;
- if (!isdigit (*p))
- return;
-
- if (!(*p >= '1' && *p <= '5'))
- return;
-
- if (!(*(p+1) == '+' || *(p+1) == '-'))
- return;
-
- o->recur->u.month_pos = (*p-'0') * (*(p+1) == '+' ? 1 : -1);
- *str += 2;
-}
-
-#if 0
-
-static void
-daynumber (iCalObject *o, char **str)
-{
- int val = 0;
- char *p = *str;
-
- ignore_space (str);
- if (strcmp (p, "LD")){
- o->recur->u.month_day = DAY_LASTDAY;
- *str += 2;
- return;
- }
-
- if (!(isdigit (*p)))
- return;
-
- while (**str && isdigit (**str)){
- val = val * 10 + (**str - '0');
- (*str)++;
- }
-
- if (**str == '+')
- (*str)++;
-
- if (**str == '-')
- val *= -1;
- o->recur->u.month_day = val;
-}
-
-#endif
-
-static void
-daynumberlist (iCalObject *o, char **str)
-{
- int first = 0;
- int val = 0;
-
- ignore_space (str);
-
- while (**str){
- if (!isdigit (**str))
- return;
- while (**str && isdigit (**str)){
- val = 10 * val + (**str - '0');
- (*str)++;
- }
- if (!first){
- /*
- * Some broken applications set this to zero
- */
- if (val == 0){
- struct tm day = *localtime (&o->dtstart);
-
- val = day.tm_mday;
- }
- o->recur->u.month_day = val;
- first = 1;
- val = 0;
- }
- }
-}
-
-static void
-load_recur_weekly (iCalObject *o, char **str)
-{
- weekdaylist (o, str);
-}
-
-static void
-load_recur_monthly_pos (iCalObject *o, char **str)
-{
- ocurrencelist (o, str);
- weekdaynum (o, str);
-}
-
-static void
-load_recur_monthly_day (iCalObject *o, char **str)
-{
- daynumberlist (o, str);
-}
-
-static void
-load_recur_yearly_month (iCalObject *o, char **str)
-{
- /* Skip as we do not support multiple months and we do expect
- * the dtstart to agree with the value on this field
- */
- skip_numbers (str);
-}
-
-static void
-load_recur_yearly_day (iCalObject *o, char **str)
-{
- /* Skip as we do not support multiple days and we do expect
- * the dtstart to agree with the value on this field
- *
- * FIXME: we should support every-n-years
- */
- skip_numbers (str);
-}
-
-static void
-duration (iCalObject *o, char **str)
-{
- unsigned int duration = 0;
-
- ignore_space (str);
- if (**str != '#')
- return;
- (*str)++;
- while (**str && isdigit (**str)){
- duration = duration * 10 + (**str - '0');
- (*str)++;
- }
- o->recur->duration = duration;
-}
-
-static void
-enddate (iCalObject *o, char **str)
-{
- ignore_space (str);
- if (isdigit (**str)){
- o->recur->_enddate = time_from_isodate (*str);
- *str += 16;
- }
-}
-
-static int
-load_recurrence (iCalObject *o, char *str)
-{
- enum RecurType type;
- int interval = 0;
-
- type = -1;
- switch (*str++){
- case 'D':
- type = RECUR_DAILY;
- break;
-
- case 'W':
- type = RECUR_WEEKLY;
- break;
-
- case 'M':
- if (*str == 'P')
- type = RECUR_MONTHLY_BY_POS;
- else if (*str == 'D')
- type = RECUR_MONTHLY_BY_DAY;
- str++;
- break;
-
- case 'Y':
- if (*str == 'M')
- type = RECUR_YEARLY_BY_MONTH;
- else if (*str == 'D')
- type = RECUR_YEARLY_BY_DAY;
- str++;
- break;
- }
- if (type == -1)
- return 0;
-
- o->recur = g_new0 (Recurrence, 1);
- o->recur->type = type;
- ignore_space (&str);
-
- /* Get the interval */
- for (;*str && isdigit (*str);str++)
- interval = interval * 10 + (*str-'0');
-
- if (interval == 0)
- interval = 1;
-
- o->recur->interval = interval;
-
- /* this is the default per the spec */
- o->recur->duration = 2;
-
- ignore_space (&str);
-
- switch (type){
- case RECUR_DAILY:
- break;
- case RECUR_WEEKLY:
- load_recur_weekly (o, &str);
- break;
- case RECUR_MONTHLY_BY_POS:
- load_recur_monthly_pos (o, &str);
- break;
- case RECUR_MONTHLY_BY_DAY:
- load_recur_monthly_day (o, &str);
- break;
- case RECUR_YEARLY_BY_MONTH:
- load_recur_yearly_month (o, &str);
- break;
- case RECUR_YEARLY_BY_DAY:
- load_recur_yearly_day (o, &str);
- break;
- default:
- g_warning ("Unimplemented recurrence type %d", (int) type);
- break;
- }
- duration (o, &str);
- enddate (o, &str);
-
- /* Compute the enddate */
- if (o->recur->_enddate == 0){
- if (o->recur->duration != 0){
- ical_object_compute_end (o);
- } else
- o->recur->enddate = 0;
- } else {
- o->recur->enddate = o->recur->_enddate;
- }
- return 1;
-}
-
-#define is_a_prop_of(obj,prop) isAPropertyOf (obj,prop)
-#define str_val(obj) the_str = fakeCString (vObjectUStringZValue (obj))
-#define has(obj,prop) (vo = isAPropertyOf (obj, prop))
-
-/*
- * FIXME: This is loosing precission. Enhanec the thresholds
- */
-#define HOURS(n) (n*(60*60))
-
-static void
-setup_alarm_at (iCalObject *ico, CalendarAlarm *alarm, char *iso_time, VObject *vo)
-{
- time_t alarm_time = time_from_isodate (iso_time);
- time_t base = ico->dtstart;
- int d = difftime (base, alarm_time);
- VObject *a;
- char *the_str;
-
- alarm->enabled = 1;
- if (d > HOURS (2)){
- if (d > HOURS (48)){
- alarm->count = d / HOURS (24);
- alarm->units = ALARM_DAYS;
- } else {
- alarm->count = d / (60*60);
- alarm->units = ALARM_HOURS;
- }
- } else {
- alarm->count = d / 60;
- alarm->units = ALARM_MINUTES;
- }
-
- if ((a = is_a_prop_of (vo, VCSnoozeTimeProp))){
- alarm->snooze_secs = isodiff_to_secs (str_val (a));
- free (the_str);
- }
-
- if ((a = is_a_prop_of (vo, VCRepeatCountProp))){
- alarm->snooze_repeat = atoi (str_val (a));
- free (the_str);
- }
-}
-
-/*
- * Duplicates an iCalObject. Implementation is a grand hack.
- * If you need the new ICalObject to have a new uid, free the current one,
- * and call ical_gen_uid() to generate a new one.
- */
-iCalObject *
-ical_object_duplicate (iCalObject *o)
-{
- VObject *vo;
- iCalObject *new;
-
- vo = ical_object_to_vobject (o);
- switch (o->type){
- case ICAL_EVENT:
- new = ical_object_create_from_vobject (vo, VCEventProp);
- break;
- case ICAL_TODO:
- new = ical_object_create_from_vobject (vo, VCTodoProp);
- break;
- default:
- new = NULL;
- }
-
- cleanVObject (vo);
- return new;
-}
-
-/* FIXME: we need to load the recurrence properties */
-iCalObject *
-ical_object_create_from_vobject (VObject *o, const char *object_name)
-{
- time_t now = time (NULL);
- iCalObject *ical;
- VObject *vo, *a;
- VObjectIterator i;
- char *the_str;
-
- ical = g_new0 (iCalObject, 1);
-
- if (strcmp (object_name, VCEventProp) == 0)
- ical->type = ICAL_EVENT;
- else if (strcmp (object_name, VCTodoProp) == 0)
- ical->type = ICAL_TODO;
- else {
- g_free (ical);
- return 0;
- }
-
- ical->ref_count = 1;
-
- /* uid */
- if (has (o, VCUniqueStringProp)){
- ical->uid = g_strdup (str_val (vo));
- free (the_str);
- } else {
- ical->uid = ical_gen_uid ();
- }
-
- /* seq */
- if (has (o, VCSequenceProp)){
- ical->seq = atoi (str_val (vo));
- free (the_str);
- } else
- ical->seq = 0;
-
- /* dtstart */
- if (has (o, VCDTstartProp)){
- ical->dtstart = time_from_isodate (str_val (vo));
- free (the_str);
- } else
- ical->dtstart = 0;
-
- /* dtend */
- ical->dtend = 0; /* default value */
- if (ical->type == ICAL_EVENT){
- if (has (o, VCDTendProp)){
- ical->dtend = time_from_isodate (str_val (vo));
- free (the_str);
- }
- } else if (ical->type == ICAL_TODO){
- if (has (o, VCDueProp)){
- ical->dtend = time_from_isodate (str_val (vo));
- free (the_str);
- }
- }
-
- /* dcreated */
- if (has (o, VCDCreatedProp)){
- ical->created = time_from_isodate (str_val (vo));
- free (the_str);
- }
-
- /* completed */
- if (has (o, VCCompletedProp)){
- ical->completed = time_from_isodate (str_val (vo));
- free (the_str);
- }
-
- /* last_mod */
- if (has (o, VCLastModifiedProp)){
- ical->last_mod = time_from_isodate (str_val (vo));
- free (the_str);
- } else
- ical->last_mod = now;
-
- /* exdate */
- if (has (o, VCExpDateProp)){
- ical->exdate = set_date_list (str_val (vo));
- free (the_str);
- }
-
- /* description/comment */
- if (has (o, VCDescriptionProp)){
- ical->comment = g_strdup (str_val (vo));
- free (the_str);
- }
-
- /* summary */
- if (has (o, VCSummaryProp)){
- ical->summary = g_strdup (str_val (vo));
- free (the_str);
-
- /* Convert any CR/LF/CRLF sequences in the summary field to
- spaces so we just have a one-line field. */
- ical_object_normalize_summary (ical);
- } else
- ical->summary = g_strdup ("");
-
- /* status */
- if (has (o, VCStatusProp)){
- ical->status = g_strdup (str_val (vo));
- free (the_str);
- } else
- ical->status = g_strdup ("NEEDS ACTION");
-
- if (has (o, VCClassProp)){
- ical->class = g_strdup (str_val (vo));
- free (the_str);
- } else
- ical->class = g_strdup ("PUBLIC");
-
- /* categories */
- if (has (o, VCCategoriesProp)){
- ical->categories = set_list (str_val (vo));
- free (the_str);
- }
-
- /* resources */
- if (has (o, VCResourcesProp)){
- ical->resources = set_list (str_val (vo));
- free (the_str);
- }
-
- /* priority */
- if (has (o, VCPriorityProp)){
- ical->priority = atoi (str_val (vo));
- free (the_str);
- }
-
- /* tranparency */
- if (has (o, VCTranspProp)){
- ical->transp = atoi (str_val (vo)) ? ICAL_TRANSPARENT : ICAL_OPAQUE;
- free (the_str);
- }
-
- /* Organizer */
- if (has (o, VCOrgNameProp)){
- ical->organizer = g_new0 (iCalPerson, 1);
- ical->organizer->addr = g_strdup (str_val (vo));
- free (the_str);
- }
-
- /* related */
- if (has (o, VCRelatedToProp)){
- 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);
- }
-
- /* attach */
- initPropIterator (&i, o);
- while (moreIteration (&i)){
- vo = nextVObject (&i);
- if (strcmp (vObjectName (vo), VCAttachProp) == 0){
- ical->attach = g_list_prepend (ical->attach, g_strdup (str_val (vo)));
- free (the_str);
- }
- }
-
- /* url */
- if (has (o, VCURLProp)){
- /* There seems to be a problem with the URL property. For some
- reason an empty property gets saved, vObjectUStringZValue
- returns NULL and fakeCString crashes. So we check for NULL.
- */
- const wchar_t *zval;
-
- zval = vObjectUStringZValue (o);
- if (zval) {
- the_str = fakeCString (zval);
- ical->url = g_strdup (the_str);
- free (the_str);
- }
- }
-
- /* dalarm */
- ical->dalarm.type = ALARM_DISPLAY;
- ical->dalarm.enabled = 0;
- if (has (o, VCDAlarmProp)){
- if ((a = is_a_prop_of (vo, VCRunTimeProp))){
- setup_alarm_at (ical, &ical->dalarm, str_val (a), vo);
- free (the_str);
- }
- }
-
- /* aalarm */
- ical->aalarm.type = ALARM_AUDIO;
- ical->aalarm.enabled = 0;
- if (has (o, VCAAlarmProp)){
- if ((a = is_a_prop_of (vo, VCRunTimeProp))){
- setup_alarm_at (ical, &ical->aalarm, str_val (a), vo);
- free (the_str);
- }
- }
-
- /* palarm */
- ical->palarm.type = ALARM_PROGRAM;
- ical->palarm.enabled = 0;
- if (has (o, VCPAlarmProp)){
- ical->palarm.type = ALARM_PROGRAM;
- if ((a = is_a_prop_of (vo, VCRunTimeProp))){
- setup_alarm_at (ical, &ical->palarm, str_val (a), vo);
- free (the_str);
-
- if ((a = is_a_prop_of (vo, VCProcedureNameProp))){
- ical->palarm.data = g_strdup (str_val (a));
- free (the_str);
- } else
- ical->palarm.data = g_strdup ("");
- }
- }
-
- /* malarm */
- ical->malarm.type = ALARM_MAIL;
- ical->malarm.enabled = 0;
- if (has (o, VCMAlarmProp)){
- ical->malarm.type = ALARM_MAIL;
- if ((a = is_a_prop_of (vo, VCRunTimeProp))){
- setup_alarm_at (ical, &ical->malarm, str_val (a), vo);
- free (the_str);
-
- if ((a = is_a_prop_of (vo, VCEmailAddressProp))){
- ical->malarm.data = g_strdup (str_val (a));
- free (the_str);
- } else
- ical->malarm.data = g_strdup ("");
- }
- }
-
- /* rrule */
- if (has (o, VCRRuleProp)){
- if (!load_recurrence (ical, str_val (vo))) {
- ical_object_unref (ical);
- return NULL;
- }
- free (the_str);
- }
-
- /*
- * Pilot
- */
- if (has (o, XPilotIdProp)){
- ical->pilot_id = atoi (str_val (vo));
- free (the_str);
- } else
- ical->pilot_id = 0;
-
- if (has (o, XPilotStatusProp)){
- ical->pilot_status = atoi (str_val (vo));
- free (the_str);
- } else
- ical->pilot_status = ICAL_PILOT_SYNC_MOD;
-
- return ical;
-}
-
-static char *
-to_str (int num)
-{
- static char buf [40];
-
- sprintf (buf, "%d", num);
- return buf;
-}
-
-/*
- * stores a GList in the property.
- */
-static void
-store_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 (l->data) + 1;
-
- result = g_malloc (len);
-
- for (p = result, l = values; l; l = l->next) {
- int len = strlen (l->data);
-
- strcpy (p, l->data);
-
- if (l->next) {
- p [len] = ';';
- p += len+1;
- } else
- p += len;
- }
-
- *p = 0;
-
- addPropValue (o, prop, result);
- g_free (result);
-}
-
-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;
- int size, len;
- char *s, *p;
-
- size = g_list_length (values);
- s = p = g_malloc ((size * 17 + 1) * sizeof (char));
-
- for (l = values; l; l = l->next){
- strcpy (s, isodate_from_time_t (*(time_t *)l->data));
- len = strlen (s);
- s [len] = ',';
- s += len + 1;
- }
- s--;
- *s = 0;
- addPropValue (o, prop, p);
- g_free (p);
-}
-
-static char *recur_type_name [] = { "D", "W", "MP", "MD", "YM", "YD" };
-static char *recur_day_list [] = { "SU", "MO", "TU","WE", "TH", "FR", "SA" };
-static char *alarm_names [] = { VCMAlarmProp, VCPAlarmProp, VCDAlarmProp, VCAAlarmProp };
-
-static VObject *
-save_alarm (VObject *o, CalendarAlarm *alarm, iCalObject *ical)
-{
- VObject *alarm_object;
- struct tm tm;
- time_t alarm_time;
-
- if (!alarm->enabled)
- return NULL;
- tm = *localtime (&ical->dtstart);
- switch (alarm->units){
- case ALARM_MINUTES:
- tm.tm_min -= alarm->count;
- break;
-
- case ALARM_HOURS:
- tm.tm_hour -= alarm->count;
- break;
-
- case ALARM_DAYS:
- tm.tm_mday -= alarm->count;
- break;
- }
-
- alarm_time = mktime (&tm);
- alarm_object = addProp (o, alarm_names [alarm->type]);
- addPropValue (alarm_object, VCRunTimeProp, isodate_from_time_t (alarm_time));
-
- if (alarm->snooze_secs)
- addPropValue (alarm_object, VCSnoozeTimeProp, isodiff_from_secs (alarm->snooze_secs));
- else
- addPropValue (alarm_object, VCSnoozeTimeProp, "");
-
- if (alarm->snooze_repeat){
- char buf [20];
-
- sprintf (buf, "%d", alarm->snooze_repeat);
- addPropValue (alarm_object, VCRepeatCountProp, buf);
- } else
- addPropValue (alarm_object, VCRepeatCountProp, "");
- return alarm_object;
-}
-
-VObject *
-ical_object_to_vobject (iCalObject *ical)
-{
- VObject *o, *alarm, *s;
- GList *l;
-
- if (ical->type == ICAL_EVENT)
- o = newVObject (VCEventProp);
- else
- o = newVObject (VCTodoProp);
-
- /* uid */
- if (ical->uid)
- addPropValue (o, VCUniqueStringProp, ical->uid);
-
- /* seq */
- addPropValue (o, VCSequenceProp, to_str (ical->seq));
-
- /* dtstart */
- addPropValue (o, VCDTstartProp, isodate_from_time_t (ical->dtstart));
-
- /* dtend */
- if (ical->type == ICAL_EVENT){
- addPropValue (o, VCDTendProp, isodate_from_time_t (ical->dtend));
- } else if (ical->type == ICAL_TODO){
- addPropValue (o, VCDueProp, isodate_from_time_t (ical->dtend));
- }
-
- /* dcreated */
- addPropValue (o, VCDCreatedProp, isodate_from_time_t (ical->created));
-
- /* completed */
- if (ical->completed)
- addPropValue (o, VCDTendProp, isodate_from_time_t (ical->completed));
-
- /* last_mod */
- addPropValue (o, VCLastModifiedProp, isodate_from_time_t (ical->last_mod));
-
- /* exdate */
- if (ical->exdate)
- store_date_list (o, VCExpDateProp, ical->exdate);
-
- /* description/comment */
- if (ical->comment && strlen (ical->comment)){
- s = addPropValue (o, VCDescriptionProp, ical->comment);
- if (strchr (ical->comment, '\n'))
- addProp (s, VCQuotedPrintableProp);
- }
-
- /* summary */
- if (ical->summary && strlen (ical->summary)) {
- s = addPropValue (o, VCSummaryProp, ical->summary);
- if (strchr (ical->summary, '\n'))
- addProp (s, VCQuotedPrintableProp);
- }
-
- /* status */
- addPropValue (o, VCStatusProp, ical->status);
-
- /* class */
- addPropValue (o, VCClassProp, ical->class);
-
- /* categories */
- if (ical->categories)
- store_list (o, VCCategoriesProp, ical->categories);
-
- /* resources */
- if (ical->resources)
- store_list (o, VCCategoriesProp, ical->resources);
-
- /* priority */
- addPropValue (o, VCPriorityProp, to_str (ical->priority));
-
- /* transparency */
- addPropValue (o, VCTranspProp, to_str (ical->transp));
-
- /* Owner/organizer */
- if (ical->organizer && ical->organizer->addr)
- addPropValue (o, VCOrgNameProp, ical->organizer->addr);
-
- /* related */
- if (ical->related)
- store_rel_list (o, VCRelatedToProp, ical->related);
-
- /* attach */
- for (l = ical->attach; l; l = l->next)
- addPropValue (o, VCAttachProp, l->data);
-
- /* url */
- if (ical->url)
- addPropValue (o, VCURLProp, ical->url);
-
- if (ical->recur){
- char result [256];
- char buffer [80];
- int i;
-
- sprintf (result, "%s%d ", recur_type_name [ical->recur->type], ical->recur->interval);
- switch (ical->recur->type){
- case RECUR_DAILY:
- break;
-
- case RECUR_WEEKLY:
- for (i = 0; i < 7; i++){
- if (ical->recur->weekday & (1 << i)){
- sprintf (buffer, "%s ", recur_day_list [i]);
- strcat (result, buffer);
- }
- }
- break;
-
- case RECUR_MONTHLY_BY_POS: {
- int nega = ical->recur->u.month_pos < 0;
-
- sprintf (buffer, "%d%s ", nega ? -ical->recur->u.month_pos : ical->recur->u.month_pos,
- nega ? "-" : "+");
- strcat (result, buffer);
- /* the gui is set up for a single day, not a set here in this case */
- sprintf (buffer, "%s ", recur_day_list [ical->recur->weekday]);
- strcat (result, buffer);
- }
- break;
-
- case RECUR_MONTHLY_BY_DAY:
- sprintf (buffer, "%d ", ical->recur->u.month_pos);
- strcat (result, buffer);
- break;
-
- case RECUR_YEARLY_BY_MONTH:
- break;
-
- case RECUR_YEARLY_BY_DAY:
- break;
- }
- if (ical->recur->_enddate == 0)
- sprintf (buffer, "#%d ",ical->recur->duration);
- else
- sprintf (buffer, "%s ", isodate_from_time_t (ical->recur->_enddate));
- strcat (result, buffer);
- addPropValue (o, VCRRuleProp, result);
- }
-
- save_alarm (o, &ical->aalarm, ical);
- save_alarm (o, &ical->dalarm, ical);
-
- if ((alarm = save_alarm (o, &ical->palarm, ical)))
- addPropValue (alarm, VCProcedureNameProp, ical->palarm.data);
- if ((alarm = save_alarm (o, &ical->malarm, ical)))
- addPropValue (alarm, VCEmailAddressProp, ical->malarm.data);
-
- /* Pilot */
- {
- char buffer [20];
-
- sprintf (buffer, "%d", ical->pilot_id);
- addPropValue (o, XPilotIdProp, buffer);
- sprintf (buffer, "%d", ical->pilot_status);
- addPropValue (o, XPilotStatusProp, buffer);
- }
-
- return o;
-}
-
-void
-ical_foreach (GList *events, calendarfn fn, void *closure)
-{
- for (; events; events = events->next){
- iCalObject *ical = events->data;
-
- (*fn) (ical, ical->dtstart, ical->dtend, closure);
- }
-}
-
-static int
-is_date_in_list (GList *list, struct tm *date)
-{
- struct tm tm;
-
- for (; list; list = list->next){
- time_t *timep = list->data;
-
- tm = *localtime (timep);
- if (date->tm_mday == tm.tm_mday &&
- date->tm_mon == tm.tm_mon &&
- date->tm_year == tm.tm_year){
- return 1;
- }
- }
- return 0;
-}
-
-/* Generates an event instance based on the reference time */
-static gboolean
-generate (iCalObject *ico, time_t reference, calendarfn cb, void *closure)
-{
- time_t offset;
- struct tm tm_start, ref;
- time_t start, end;
-
- offset = ico->dtend - ico->dtstart;
-
- tm_start = *localtime (&ico->dtstart);
- ref = *localtime (&reference);
-
- tm_start.tm_mday = ref.tm_mday;
- tm_start.tm_mon = ref.tm_mon;
- tm_start.tm_year = ref.tm_year;
-
- start = mktime (&tm_start);
- if (start == -1) {
- g_message ("generate(): Produced invalid start date!");
- return FALSE;
- }
-
- end = start + offset;
-
-#if 0
- /* FIXME: I think this is not needed, since we are offsetting by full day values,
- * and the times should remain the same --- if you have a daily appointment
- * at 18:00, it is always at 18:00 even during daylight savings.
- *
- * However, what should happen on the exact change-of-savings day with
- * appointments in the early morning hours?
- */
-
- if (ref.tm_isdst > tm_start.tm_isdst) {
- tm_start.tm_hour--;
- tm_end.tm_hour--;
- } else if (ref.tm_isdst < tm_start.tm_isdst) {
- tm_start.tm_hour++;
- tm_end.tm_hour++;
- }
-#endif
-
- if (ico->exdate && is_date_in_list (ico->exdate, &tm_start))
- return TRUE;
-
- return (*cb) (ico, start, end, closure);
-}
-
-int
-ical_object_get_first_weekday (int weekday_mask)
-{
- int i;
-
- for (i = 0; i < 7; i++)
- if (weekday_mask & (1 << i))
- return i;
-
- return -1;
-}
-
-#define time_in_range(t, a, b) ((t >= a) && (b ? (t < b) : 1))
-#define recur_in_range(t, r) (r->enddate ? (t < r->enddate) : 1)
-
-/*
- * Generate every possible event. Invokes the callback routine for
- * every occurrence of the event in the [START, END] time interval.
- *
- * If END is zero, the event is generated forever.
- * The callback routine is expected to return 0 when no further event
- * generation is requested.
- */
-void
-ical_object_generate_events (iCalObject *ico, time_t start, time_t end, calendarfn cb, void *closure)
-{
- time_t current;
- int first_week_day;
-
- /* If there is no recurrence, just check ranges */
-
- if (!ico->recur) {
- if ((end && (ico->dtstart < end) && (ico->dtend > start))
- || ((end == 0) && (ico->dtend > start))) {
- /* The new calendar views expect the times to not be
- clipped, so they can show that it continues past
- the end of the viewable area. */
-#if 0
- time_t ev_s, ev_e;
-
- /* Clip range */
-
- ev_s = MAX (ico->dtstart, start);
- ev_e = MIN (ico->dtend, end);
-
- (* cb) (ico, ev_s, ev_e, closure);
-#else
- (* cb) (ico, ico->dtstart, ico->dtend, closure);
-#endif
- }
- return;
- }
-
- /* The event has a recurrence rule -- check that we will generate at least one instance */
-
- if (end != 0) {
- if (ico->dtstart > end)
- return;
-
- if (!IS_INFINITE (ico->recur) && (ico->recur->enddate < start))
- return;
- }
-
- /* Generate the instances */
-
- current = ico->dtstart;
-
- switch (ico->recur->type) {
- case RECUR_DAILY:
- do {
- if (time_in_range (current, start, end) && recur_in_range (current, ico->recur))
- if (!generate (ico, current, cb, closure))
- return;
-
- /* Advance */
-
- current = time_add_day (current, ico->recur->interval);
-
- if (current == -1) {
- g_warning ("RECUR_DAILY: time_add_day() returned invalid time");
- return;
- }
- } while ((current < end) || (end == 0));
-
- break;
-
- case RECUR_WEEKLY:
- do {
- struct tm tm;
-
- tm = *localtime (&current);
-
- if (time_in_range (current, start, end) && recur_in_range (current, ico->recur)) {
- /* Weekdays to recur on are specified as a bitmask */
- if (ico->recur->weekday & (1 << tm.tm_wday)) {
- if (!generate (ico, current, cb, closure))
- return;
- }
- }
-
- /* Advance by day for scanning the week or by interval at week end */
-
- if (tm.tm_wday == 6)
- current = time_add_day (current, (ico->recur->interval - 1) * 7 + 1);
- else
- current = time_add_day (current, 1);
-
- if (current == -1) {
- g_warning ("RECUR_WEEKLY: time_add_day() returned invalid time\n");
- return;
- }
- } while (current < end || (end == 0));
-
- break;
-
- case RECUR_MONTHLY_BY_POS:
- /* FIXME: We only deal with positives now */
- if (ico->recur->u.month_pos < 0) {
- g_warning ("RECUR_MONTHLY_BY_POS does not support negative positions yet");
- return;
- }
-
- if (ico->recur->u.month_pos == 0)
- return;
-
- first_week_day = /* ical_object_get_first_weekday (ico->recur->weekday); */
- ico->recur->weekday; /* the i/f only lets you choose a single day of the week! */
-
- /* This should not happen, but take it into account */
- if (first_week_day == -1) {
- g_warning ("ical_object_get_first_weekday() returned -1");
- return;
- }
-
- do {
- struct tm tm;
- time_t t;
- int week_day_start;
-
- tm = *localtime (&current);
- tm.tm_mday = 1;
- t = mktime (&tm);
- tm = *localtime (&t);
- week_day_start = tm.tm_wday;
-
- tm.tm_mday = (7 * (ico->recur->u.month_pos - ((week_day_start <= first_week_day ) ? 1 : 0))
- - (week_day_start - first_week_day) + 1);
- if( tm.tm_mday > 31 )
- {
- tm.tm_mday = 1;
- tm.tm_mon += ico->recur->interval;
- current = mktime (&tm);
- continue;
- }
-
- switch( tm.tm_mon )
- {
- case 3:
- case 5:
- case 8:
- case 10:
- if( tm.tm_mday > 30 )
- {
- tm.tm_mday = 1;
- tm.tm_mon += ico->recur->interval;
- current = mktime (&tm);
- continue;
- }
- break;
- case 1:
- if( ((tm.tm_year+1900)%4) == 0
- && ((tm.tm_year+1900)%400) != 100
- && ((tm.tm_year+1900)%400) != 200
- && ((tm.tm_year+1900)%400) != 300 )
- {
-
- if( tm.tm_mday > 29 )
- {
- tm.tm_mday = 1;
- tm.tm_mon += ico->recur->interval;
- current = mktime (&tm);
- continue;
- }
- }
- else
- {
- if( tm.tm_mday > 28 )
- {
- tm.tm_mday = 1;
- tm.tm_mon += ico->recur->interval;
- current = mktime (&tm);
- continue;
- }
- }
- break;
- }
-
- t = mktime (&tm);
-
- if (time_in_range (t, start, end) && recur_in_range (current, ico->recur))
- if (!generate (ico, t, cb, closure))
- return;
-
- /* Advance by the appropriate number of months */
-
- current = mktime (&tm);
-
- tm.tm_mday = 1;
- tm.tm_mon += ico->recur->interval;
- current = mktime (&tm);
-
- if (current == -1) {
- g_warning ("RECUR_MONTHLY_BY_DAY: mktime error\n");
- return;
- }
- } while ((current < end) || (end == 0));
-
- break;
-
- case RECUR_MONTHLY_BY_DAY:
- do {
- struct tm tm;
- time_t t;
- int p;
-
- tm = *localtime (&current);
-
- p = tm.tm_mday;
- tm.tm_mday = ico->recur->u.month_day;
- t = mktime (&tm);
- if (time_in_range (t, start, end) && recur_in_range (current, ico->recur))
- if (!generate (ico, t, cb, closure))
- return;
-
- /* Advance by the appropriate number of months */
-
- tm.tm_mday = p;
- tm.tm_mon += ico->recur->interval;
- current = mktime (&tm);
-
- if (current == -1) {
- g_warning ("RECUR_MONTHLY_BY_DAY: mktime error\n");
- return;
- }
- } while (current < end || (end == 0));
-
- break;
-
- case RECUR_YEARLY_BY_MONTH:
- case RECUR_YEARLY_BY_DAY:
- do {
- if (time_in_range (current, start, end) && recur_in_range (current, ico->recur))
- if (!generate (ico, current, cb, closure))
- return;
-
- /* Advance */
-
- current = time_add_year (current, ico->recur->interval);
- } while (current < end || (end == 0));
-
- break;
-
- default:
- g_assert_not_reached ();
- }
-}
-
-static int
-duration_callback (iCalObject *ico, time_t start, time_t end, void *closure)
-{
- int *count = closure;
- struct tm tm;
-
- tm = *localtime (&start);
-
- (*count)++;
- if (ico->recur->duration == *count) {
- ico->recur->enddate = time_day_end (end);
- return 0;
- }
- return 1;
-}
-
-/* Computes ico->recur->enddate from ico->recur->duration */
-void
-ical_object_compute_end (iCalObject *ico)
-{
- int count = 0;
-
- g_return_if_fail (ico->recur != NULL);
-
- ico->recur->_enddate = 0;
- ico->recur->enddate = 0;
- ical_object_generate_events (ico, ico->dtstart, 0, duration_callback, &count);
-}
-
-int
-alarm_compute_offset (CalendarAlarm *a)
-{
- if (!a->enabled)
- return -1;
- switch (a->units){
- case ALARM_MINUTES:
- a->offset = a->count * 60;
- break;
- case ALARM_HOURS:
- a->offset = a->count * 3600;
- break;
- case ALARM_DAYS:
- a->offset = a->count * 24 * 3600;
- }
- return a->offset;
-}
-
-
-/**
- * ical_object_find_in_string:
- * @uid: Unique identifier of the sought object.
- * @vcalobj: String representation of a complete calendar object.
- * @ico: The resulting #iCalObject is stored here.
- *
- * Parses a complete vCalendar object string and tries to find the calendar
- * object that matches the specified @uid. If found, it stores the resulting
- * #iCalObject in the @ico parameter.
- *
- * Return value: A result code depending on whether the parse and search were
- * successful.
- **/
-CalObjFindStatus
-ical_object_find_in_string (const char *uid, const char *vcalobj, iCalObject **ico)
-{
-#if 0
- icalcomponent* comp = NULL;
- icalcomponent *subcomp;
- iCalObject *ical;
-
- g_return_val_if_fail (vcalobj != NULL, CAL_OBJ_FIND_NOT_FOUND);
-
- comp = icalparser_parse_string (vcalobj);
-
- if (!comp) {
- printf ("CAL_OBJ_FIND_SYNTAX_ERROR #1\n");
- return CAL_OBJ_FIND_SYNTAX_ERROR;
- }
-
- subcomp = icalcomponent_get_first_component (comp,
- ICAL_ANY_COMPONENT);
- if (!subcomp) {
- printf ("CAL_OBJ_FIND_SYNTAX_ERROR #2\n");
- return CAL_OBJ_FIND_SYNTAX_ERROR;
- }
-
- while (subcomp) {
- ical = ical_object_create_from_icalcomponent (subcomp);
- if (ical->type != ICAL_EVENT &&
- ical->type != ICAL_TODO &&
- ical->type != ICAL_JOURNAL) {
- g_warning ("Skipping unsupported iCalendar component");
- } else {
- if (strcasecmp (ical->uid, uid) == 0) {
- (*ico) = ical;
- (*ico)->ref_count = 1;
- printf ("CAL_OBJ_FIND_SUCCESS\n");
-
- printf ("ical_object_find_in_string:\n");
- printf ("-----------------------------------------------------\n");
- dump_icalobject (*ico);
- printf ("-----------------------------------------------------\n");
-
-
- return CAL_OBJ_FIND_SUCCESS;
- }
- }
- subcomp = icalcomponent_get_next_component (comp,
- ICAL_ANY_COMPONENT);
- }
-
- printf ("CAL_OBJ_FIND_NOT_FOUND\n");
- return CAL_OBJ_FIND_NOT_FOUND;
-
-#else /* 1 */
- VObject *vcal;
- VObjectIterator i;
- CalObjFindStatus status;
-
- g_return_val_if_fail (uid != NULL, CAL_OBJ_FIND_SYNTAX_ERROR);
- g_return_val_if_fail (vcalobj != NULL, CAL_OBJ_FIND_SYNTAX_ERROR);
- g_return_val_if_fail (ico != NULL, CAL_OBJ_FIND_SYNTAX_ERROR);
-
- *ico = NULL;
- status = CAL_OBJ_FIND_NOT_FOUND;
-
- vcal = Parse_MIME (vcalobj, strlen (vcalobj));
-
- if (!vcal)
- return CAL_OBJ_FIND_SYNTAX_ERROR;
-
- initPropIterator (&i, vcal);
-
- while (moreIteration (&i)) {
- VObject *vobj;
- VObject *uid_prop;
- char *the_str;
-
- vobj = nextVObject (&i);
-
- uid_prop = isAPropertyOf (vobj, VCUniqueStringProp);
- if (!uid_prop)
- continue;
-
- /* str_val() sets the_str to the string representation of the
- * property.
- */
- str_val (uid_prop);
-
- if (strcmp (the_str, uid) == 0) {
- const char *object_name;
-
- object_name = vObjectName (vobj);
- *ico = ical_object_create_from_vobject (vobj, object_name);
-
- if (*ico)
- status = CAL_OBJ_FIND_SUCCESS;
- }
-
- free (the_str);
-
- if (status == CAL_OBJ_FIND_SUCCESS)
- break;
- }
-
- cleanVObject (vcal);
- cleanStrTbl ();
-
- return status;
-#endif /* 1 */
-}
-
-
-#if 1
-/* Creates a VObject with the base information of a calendar */
-static VObject *
-get_calendar_base_vobject (void)
-{
- VObject *vobj;
- time_t now;
- struct tm tm;
-
- /* We call localtime for the side effect of setting tzname */
-
- now = time (NULL);
- tm = *localtime (&now);
-
- vobj = newVObject (VCCalProp);
-
- addPropValue (vobj, VCProdIdProp, PRODID);
-
-#if defined (HAVE_TM_ZONE)
- addPropValue (vobj, VCTimeZoneProp, tm.tm_zone);
-#elif defined (HAVE_TZNAME)
- addPropValue (vobj, VCTimeZoneProp, tzname[0]);
-#endif
-
- /* Per the vCalendar spec, this must be "1.0" */
- addPropValue (vobj, VCVersionProp, "1.0");
-
- return vobj;
-}
-#endif /* 0 */
-
-/**
- * ical_object_to_string:
- * @ico: A calendar object.
- *
- * Converts a vCalendar object to its string representation. It is wrapped
- * inside a complete VCALENDAR object because other auxiliary information such
- * as timezones may appear there.
- *
- * Return value: String representation of the object.
- **/
-char *
-ical_object_to_string (iCalObject *ico)
-{
-#if 0
- icalcomponent *top = icalcomponent_new (ICAL_VCALENDAR_COMPONENT);
- char *out_cal_string;
- icalcomponent *comp;
-
- printf ("ical_object_to_string:\n");
- printf ("-----------------------------------------------------\n");
- dump_icalobject (ico);
- printf ("-----------------------------------------------------\n");
-
- comp = icalcomponent_create_from_ical_object (ico);
- icalcomponent_add_component (top, comp);
- out_cal_string = icalcomponent_as_ical_string (top);
- return g_strdup (out_cal_string);
-
-#else /* 1 */
- VObject *vcalobj, *vobj;
- char *buf, *gbuf;
-
- vcalobj = get_calendar_base_vobject ();
- vobj = ical_object_to_vobject (ico);
- addVObjectProp (vcalobj, vobj);
-
- buf = writeMemVObject (NULL, NULL, vcalobj);
-
- cleanVObject (vcalobj);
- cleanStrTbl ();
-
- /* We have to g_strdup() it because libversit uses malloc()/realloc(),
- * and we want clients to be able to use g_free(). Sigh.
- */
- gbuf = g_strdup (buf);
- free (buf);
-
- return gbuf;
-#endif /* 1 */
-}
-
-
-/**
- * ical_object_compare_dates:
- * @ico1: A calendar event.
- * @ico2: A calendar event to compare with @ico1.
- *
- * Returns TRUE if the dates of both objects match, including any recurrence
- * rules. Both calendar objects must have a type of ICAL_EVENT.
- *
- * Return value: TRUE if both calendar objects have the same dates.
- **/
-gboolean
-ical_object_compare_dates (iCalObject *ico1,
- iCalObject *ico2)
-{
- Recurrence *recur1, *recur2;
- gint num_exdates;
- GList *elem1, *elem2;
- time_t *time1, *time2;
-
- g_return_val_if_fail (ico1 != NULL, FALSE);
- g_return_val_if_fail (ico2 != NULL, FALSE);
- g_return_val_if_fail (ico1->type == ICAL_EVENT, FALSE);
- g_return_val_if_fail (ico2->type == ICAL_EVENT, FALSE);
-
- /* First check the base dates. */
- if (ico1->dtstart != ico2->dtstart
- || ico1->dtend != ico2->dtend)
- return FALSE;
-
- recur1 = ico1->recur;
- recur2 = ico2->recur;
-
- /* If the event doesn't recur, we already know it matches. */
- if (!recur1 && !recur2)
- return TRUE;
-
- /* Check that both recur. */
- if (!(recur1 && recur2))
- return FALSE;
-
- /* Now we need to see if the recurrence rules are the same. */
- if (recur1->type != recur2->type
- || recur1->interval != recur2->interval
- || recur1->enddate != recur2->enddate
- || recur1->weekday != recur2->weekday
- || recur1->duration != recur2->duration
- || recur1->_enddate != recur2->_enddate
- || recur1->__count != recur2->__count)
- return FALSE;
-
- switch (recur1->type) {
- case RECUR_MONTHLY_BY_POS:
- if (recur1->u.month_pos != recur2->u.month_pos)
- return FALSE;
- break;
- case RECUR_MONTHLY_BY_DAY:
- if (recur1->u.month_day != recur2->u.month_day)
- return FALSE;
- break;
- default:
- break;
- }
-
- /* Now check if the excluded dates match. */
- num_exdates = g_list_length (ico1->exdate);
- if (g_list_length (ico2->exdate) != num_exdates)
- return FALSE;
- if (num_exdates == 0)
- return TRUE;
-
- ico1->exdate = g_list_sort (ico1->exdate, compare_exdates);
- ico2->exdate = g_list_sort (ico2->exdate, compare_exdates);
-
- elem1 = ico1->exdate;
- elem2 = ico2->exdate;
- while (elem1) {
- time1 = (time_t*) elem1->data;
- time2 = (time_t*) elem2->data;
-
- if (*time1 != *time2)
- return FALSE;
-
- elem1 = elem1->next;
- elem2 = elem2->next;
- }
-
- return TRUE;
-}
-
-
-static gint
-compare_exdates (gconstpointer a, gconstpointer b)
-{
- const time_t *ca = a, *cb = b;
- time_t diff = *ca - *cb;
- return (diff < 0) ? -1 : (diff > 0) ? 1 : 0;
-}
-
-
-/* Converts any CR/LF sequences in the summary field to spaces so we just
- have a one-line field. The iCalObjects summary field is changed. */
-static void
-ical_object_normalize_summary (iCalObject *ico)
-{
- gchar *src, *dest, ch;
- gboolean just_output_space = FALSE;
-
- src = dest = ico->summary;
- while ((ch = *src++)) {
- if (ch == '\n' || ch == '\r') {
- /* We only output 1 space for each sequence of CR & LF
- characters. */
- if (!just_output_space) {
- *dest++ = ' ';
- just_output_space = TRUE;
- }
- } else {
- *dest++ = ch;
- just_output_space = FALSE;
- }
- }
- *dest = '\0';
-}
-
-
-void dump_icalobject (iCalObject *ico)
-{
- if (!ico) {
- printf ("<<NULL>>\n");
- return;
- }
-
- printf ("type ");
- switch (ico->type) {
- case ICAL_EVENT: printf ("event"); break;
- case ICAL_TODO: printf ("todo"); break;
- case ICAL_JOURNAL: printf ("journal"); break;
- case ICAL_FBREQUEST: printf ("fbrequest"); break;
- case ICAL_FBREPLY: printf ("fbreply"); break;
- case ICAL_BUSYTIME: printf ("busytime"); break;
- case ICAL_TIMEZONE: printf ("timezone"); break;
- }
- printf ("\n");
-
- printf ("attach-length %d\n", g_list_length (ico->attach));
-
- printf ("attendee-length %d\n", g_list_length (ico->attendee));
-
- printf ("catagories-length %d\n", g_list_length (ico->categories));
-
- printf ("class '%s'\n", ico->class ? ico->class : "NULL");
-
- printf ("comment '%s'\n", ico->comment ? ico->comment : "NULL");
-
- printf ("completed %ld=%s",
- ico->completed, ctime (&ico->completed));
-
- printf ("created %ld=%s", ico->created, ctime (&ico->created));
-
- printf ("contact-length %d\n", g_list_length (ico->contact));
-
- printf ("desc '%s'\n", ico->desc ? ico->desc : "NULL");
-
- printf ("dtstamp %ld=%s", ico->dtstamp, ctime (&ico->dtstamp));
-
- printf ("dtstart %ld=%s", ico->dtstart, ctime (&ico->dtstart));
-
- printf ("dtend %ld=%s", ico->dtend, ctime (&ico->dtend));
-
- printf ("date_only %d\n", ico->date_only);
-
- printf ("exdate-length %d\n", g_list_length (ico->exdate));
-
- printf ("exrule-length %d\n", g_list_length (ico->exrule));
-
- printf ("iCalGeo %d %f %f\n",
- ico->geo.valid, ico->geo.latitude, ico->geo.longitude);
-
- printf ("last_mod %ld=%s", ico->last_mod, ctime (&ico->last_mod));
-
- printf ("location '%s'\n", ico->location ? ico->location : "NULL");
-
- printf ("organizer %p\n", ico->organizer);
-
- printf ("percent %d\n", ico->percent);
-
- printf ("priority %d\n", ico->priority);
-
- printf ("rstatus '%s'\n", ico->rstatus ? ico->rstatus : "NULL");
-
- printf ("related-length %d\n", g_list_length (ico->related));
-
- printf ("resources-length %d\n", g_list_length (ico->resources));
-
- printf ("rdate-length %d\n", g_list_length (ico->rdate));
-
- printf ("rrule-length %d\n", g_list_length (ico->rrule));
-
- printf ("seq %d\n", ico->seq);
-
- printf ("status '%s'\n", ico->status ? ico->status : "NULL");
-
- printf ("summary '%s'\n", ico->summary ? ico->summary : "NULL");
-
- printf ("transp ");
- switch (ico->transp) {
- case ICAL_OPAQUE: printf ("opaque"); break;
- case ICAL_TRANSPARENT: printf ("transparent"); break;
- }
- printf ("\n");
-
- printf ("uid '%s'\n", ico->uid ? ico->uid : "NULL");
-
- printf ("url '%s'\n", ico->url ? ico->url : "NULL");
-
- printf ("recurid %ld=%s", ico->recurid, ctime (&ico->recurid));
-
- printf ("dalarm %d\n", ico->dalarm.enabled);
-
- printf ("aalarm %d\n", ico->aalarm.enabled);
-
- printf ("palarm %d\n", ico->palarm.enabled);
-
- printf ("malarm %d\n", ico->malarm.enabled);
-
- printf ("alarms-length %d\n", g_list_length (ico->alarms));
-
- printf ("recur %p\n", ico->recur);
-
- printf ("new %d\n", ico->new);
-
- printf ("user_data %p\n", ico->user_data);
-
- printf ("ref_count %d\n", ico->ref_count);
-}
diff --git a/calendar/cal-util/calobj.h b/calendar/cal-util/calobj.h
deleted file mode 100644
index 3caef945e2..0000000000
--- a/calendar/cal-util/calobj.h
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * Internal representation of a Calendar object. This is modeled after the
- * iCalendar/vCalendar specificiation
- *
- * Authors: Miguel de Icaza (miguel@gnu.org)
- * Federico Mena (quartic@gimp.org).
- */
-#ifndef CALOBJ_H
-#define CALOBJ_H
-
-#include <libgnome/libgnome.h>
-#include "libversit/vcc.h"
-
-BEGIN_GNOME_DECLS
-
-/* Alarm types */
-enum AlarmType {
- ALARM_MAIL,
- ALARM_PROGRAM,
- ALARM_DISPLAY,
- ALARM_AUDIO
-};
-
-/* Whether the alarm should trigger N mins/hours/days before its due time */
-enum AlarmUnit {
- ALARM_MINUTES,
- ALARM_HOURS,
- ALARM_DAYS
-};
-
-/* Field identifiers for the iCalObject structure. These are also used to
- identify columns in ECalendarTable, so be careful when reordering them. */
-typedef enum {
- ICAL_OBJECT_FIELD_COMMENT,
- ICAL_OBJECT_FIELD_COMPLETED,
- ICAL_OBJECT_FIELD_CREATED,
- ICAL_OBJECT_FIELD_DESCRIPTION,
- ICAL_OBJECT_FIELD_DTSTAMP,
- ICAL_OBJECT_FIELD_DTSTART,
- ICAL_OBJECT_FIELD_DTEND,
- ICAL_OBJECT_FIELD_GEO,
- ICAL_OBJECT_FIELD_LAST_MOD,
- ICAL_OBJECT_FIELD_LOCATION,
- ICAL_OBJECT_FIELD_ORGANIZER,
- ICAL_OBJECT_FIELD_PERCENT,
- ICAL_OBJECT_FIELD_PRIORITY,
- ICAL_OBJECT_FIELD_SUMMARY,
- ICAL_OBJECT_FIELD_URL,
- ICAL_OBJECT_FIELD_HAS_ALARMS, /* not a real field */
- ICAL_OBJECT_FIELD_ICON, /* not a real field */
- ICAL_OBJECT_FIELD_COMPLETE, /* not a real field */
- ICAL_OBJECT_FIELD_RECURRING, /* not a real field */
- ICAL_OBJECT_FIELD_OVERDUE, /* not a real field */
- ICAL_OBJECT_FIELD_COLOR, /* not a real field */
- ICAL_OBJECT_FIELD_NUM_FIELDS
-} iCalObjectField;
-
-typedef struct {
- enum AlarmType type;
- int enabled;
- int count;
- enum AlarmUnit units;
- 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;
-
- int snooze_secs;
- int snooze_repeat;
-
- /* Widgets */
- void *w_count; /* A GtkEntry */
- void *w_enabled; /* A GtkChecButton */
- void *w_timesel; /* A GtkMenu */
- void *w_entry; /* A GnomeEntryFile/GtkEntry for PROGRAM/MAIL */
- void *w_label;
-} CalendarAlarm;
-
-/* Calendar object type */
-typedef enum {
- ICAL_EVENT,
- ICAL_TODO,
- ICAL_JOURNAL,
- ICAL_FBREQUEST,
- ICAL_FBREPLY,
- ICAL_BUSYTIME,
- ICAL_TIMEZONE
-} iCalType;
-
-/* For keys that might contain binary or text/binary */
-typedef struct {
- char *data;
- int len;
-} iCalValue;
-
-typedef enum {
- ICAL_PILOT_SYNC_NONE = 0,
- ICAL_PILOT_SYNC_MOD = 1,
- ICAL_PILOT_SYNC_DEL = 3
-} iCalPilotState;
-
-typedef struct {
- int valid; /* true if the Geography was specified */
- double latitude;
- double longitude;
-} iCalGeo;
-
-typedef enum {
- ICAL_OPAQUE,
- ICAL_TRANSPARENT
-} iCalTransp;
-
-typedef struct {
- char *uid;
- char *reltype;
-} iCalRelation;
-
-typedef char NotYet;
-
-enum RecurType {
- RECUR_DAILY,
- RECUR_WEEKLY,
- RECUR_MONTHLY_BY_POS,
- RECUR_MONTHLY_BY_DAY,
- RECUR_YEARLY_BY_MONTH,
- RECUR_YEARLY_BY_DAY,
-};
-
-#define DAY_LASTDAY 10000
-
-typedef struct {
- enum RecurType type;
-
- int interval;
-
- /* Used for recur computation */
- time_t enddate; /* If the value is zero, it is an infinite event
- * otherwise, it is either the _enddate value (if
- * this is what got specified) or it is our computed
- * ending date (computed from the duration item).
- */
-
- int weekday;
-
- union {
- int month_pos;
- int month_day;
- } u;
-
- int duration;
- time_t _enddate; /* As found on the vCalendar file */
- 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 */
-typedef enum {
- CHANGE_NEW = 1 << 0, /* new object */
- CHANGE_SUMMARY = 1 << 1, /* summary */
- CHANGE_DATES = 1 << 2, /* dtstart / dtend */
- CHANGE_ALL = CHANGE_SUMMARY | CHANGE_DATES
-} CalObjectChange;
-
-/*
- * This describes an iCalendar object, note that we never store durations, instead we
- * always compute the end time computed from the start + duration.
- */
-typedef struct {
- iCalType type;
-
- GList *attach; /* type: one or more URIs or binary data */
- GList *attendee; /* type: CAL-ADDRESS (list of iCalPerson) */
- GList *categories; /* type: one or more TEXT */
- char *class;
-
- char *comment; /* we collapse one or more TEXTs into one */
- time_t completed;
- time_t created;
- GList *contact; /* type: one or more TEXT */
- char *desc;
- time_t dtstamp;
- time_t dtstart;
- 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;
- iCalPerson *organizer;
- int percent;
- int priority;
- char *rstatus; /* request status for freebusy */
- GList *related; /* type: one or more TEXT */
- GList *resources; /* type: one or more TEXT */
- GList *rdate; /* type: one or more recurrence date */
- GList *rrule; /* type: one or more recurrence rules */
- int seq;
- char *status;
- char *summary;
- iCalTransp transp;
- char *uid;
- char *url;
- time_t recurid;
-
- CalendarAlarm dalarm;
- CalendarAlarm aalarm;
- CalendarAlarm palarm;
- CalendarAlarm malarm;
-
- GList *alarms;
-
- Recurrence *recur;
-
- int new;
- void *user_data; /* Generic data pointer */
-
- /* Pilot */
- iCalPilotState pilot_status; /* Status information */
- guint32 pilot_id; /* Pilot ID */
-
- guint ref_count;
-} iCalObject;
-
-/* The callback for the recurrence generator */
-typedef int (*calendarfn) (iCalObject *, time_t, time_t, void *);
-
-iCalObject *ical_new (char *comment, char *organizer, char *summary);
-iCalObject *ical_object_new (void);
-
-void ical_object_ref (iCalObject *ico);
-void ical_object_unref (iCalObject *ico);
-
-iCalObject *ical_object_create_from_vobject (VObject *obj, const char *object_name);
-VObject *ical_object_to_vobject (iCalObject *ical);
-iCalObject *ical_object_duplicate (iCalObject *o);
-void ical_foreach (GList *events, calendarfn fn, void *closure);
-void ical_object_generate_events (iCalObject *ico, time_t start, time_t end, calendarfn cb, void *closure);
-void ical_object_add_exdate (iCalObject *o, time_t t);
-
-/* Computes the enddate field of the recurrence based on the duration */
-void ical_object_compute_end (iCalObject *ico);
-
-typedef enum {
- CAL_OBJ_FIND_SUCCESS,
- CAL_OBJ_FIND_SYNTAX_ERROR,
- CAL_OBJ_FIND_NOT_FOUND
-} CalObjFindStatus;
-
-CalObjFindStatus ical_object_find_in_string (const char *uid, const char *vcalobj, iCalObject **ico);
-
-char *ical_object_to_string (iCalObject *ico);
-
-
-/* Returns the first toggled day in a weekday mask -- we do this because we do not support multiple
- * days on a monthly-by-pos recurrence. If no days are toggled, it returns -1.
- */
-int ical_object_get_first_weekday (int weekday_mask);
-
-/* Returns the number of seconds configured to trigger the alarm in advance to an event */
-int alarm_compute_offset (CalendarAlarm *a);
-
-
-/* Returns TRUE if the dates of both objects match, including any recurrence
- rules. */
-gboolean ical_object_compare_dates (iCalObject *ico1, iCalObject *ico2);
-
-/* Generates a new uid for a calendar object. Should be g_free'd eventually. */
-char *ical_gen_uid (void);
-
-/* This resets any recurrence rules of the iCalObject. */
-void ical_object_reset_recurrence (iCalObject *ico);
-
-
-void dump_icalobject (iCalObject *ico);
-
-END_GNOME_DECLS
-
-#endif
-
diff --git a/calendar/gui/Makefile.am b/calendar/gui/Makefile.am
index 06134d5485..c598bc2150 100644
--- a/calendar/gui/Makefile.am
+++ b/calendar/gui/Makefile.am
@@ -72,6 +72,8 @@ evolution_calendar_SOURCES = \
calendar-commands.h \
calendar-model.c \
calendar-model.h \
+ calendar-offline-handler.c \
+ calendar-offline-handler.h \
calendar-view.c \
calendar-view.h \
calendar-view-factory.c \
diff --git a/calendar/gui/calendar-component.c b/calendar/gui/calendar-component.c
index 574a700e76..e13a3f8a50 100644
--- a/calendar/gui/calendar-component.c
+++ b/calendar/gui/calendar-component.c
@@ -34,6 +34,7 @@
#include <bonobo/bonobo-generic-factory.h>
#include <bonobo/bonobo-context.h>
#include "evolution-shell-component.h"
+#include "calendar-offline-handler.h"
#include "component-factory.h"
#include "tasks-control-factory.h"
#include "control-factory.h"
@@ -544,18 +545,6 @@ sc_user_create_new_item_cb (EvolutionShellComponent *shell_component,
g_assert_not_reached ();
}
-#if 0
-static void
-destroy_cb (EvolutionShellComponent *shell_component,
- gpointer user_data)
-{
- shells = g_list_remove (shells, shell_component);
-
- if (g_list_length (shells) == 0)
- gtk_main_quit ();
-}
-#endif
-
/* The factory function. */
@@ -563,7 +552,8 @@ static BonoboObject *
create_object (void)
{
EvolutionShellComponent *shell_component;
-
+ CalendarOfflineHandler *offline_handler;
+
shell_component = evolution_shell_component_new (folder_types,
NULL,
create_view,
@@ -574,18 +564,16 @@ create_object (void)
NULL, /* get_dnd_selection_fn */
NULL /* closure */);
+ /* Offline handler */
+ offline_handler = calendar_offline_handler_new ();
+ bonobo_object_add_interface (BONOBO_OBJECT (shell_component),
+ BONOBO_OBJECT (offline_handler));
+
gtk_signal_connect (GTK_OBJECT (shell_component), "owner_set",
GTK_SIGNAL_FUNC (owner_set_cb), NULL);
gtk_signal_connect (GTK_OBJECT (shell_component), "owner_unset",
GTK_SIGNAL_FUNC (owner_unset_cb), NULL);
-#if 0
- gtk_signal_connect (GTK_OBJECT (shell_component), "destroy",
- GTK_SIGNAL_FUNC (destroy_cb), NULL);
-
- shells = g_list_append (shells, shell_component);
-#endif
-
/* User creatable items */
evolution_shell_component_add_user_creatable_item (shell_component,
diff --git a/calendar/gui/calendar-offline-handler.c b/calendar/gui/calendar-offline-handler.c
new file mode 100644
index 0000000000..e57ba042ee
--- /dev/null
+++ b/calendar/gui/calendar-offline-handler.c
@@ -0,0 +1,267 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* calendar-offline-handler.c
+ *
+ * Copyright (C) 2001 Ximian, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ * Ettore Perazzoli <ettore@ximian.com>
+ * Dan Winship <danw@ximian.com>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtk/gtkmain.h>
+#include <bonobo/bonobo-exception.h>
+#include <libgnomevfs/gnome-vfs-types.h>
+#include <libgnomevfs/gnome-vfs-uri.h>
+#include <gal/util/e-util.h>
+#include <cal-client/cal-client.h>
+#include "calendar-offline-handler.h"
+
+#define PARENT_TYPE bonobo_x_object_get_type ()
+static BonoboXObjectClass *parent_class = NULL;
+
+struct _CalendarOfflineHandlerPrivate {
+ CalClient *client;
+
+ GNOME_Evolution_OfflineProgressListener listener_interface;
+
+ gboolean is_offline;
+};
+
+static void
+add_connection (gpointer data, gpointer user_data)
+{
+ GnomeVFSURI *uri = gnome_vfs_uri_new (data);
+ GNOME_Evolution_ConnectionList *list = user_data;
+
+ g_return_if_fail (uri != NULL);
+
+ list->_buffer[list->_length].hostName
+ = CORBA_string_dup (gnome_vfs_uri_get_host_name (uri));
+ list->_buffer[list->_length].type
+ = CORBA_string_dup (gnome_vfs_uri_get_scheme (uri));
+ list->_length++;
+
+ gnome_vfs_uri_unref (uri);
+}
+
+static GNOME_Evolution_ConnectionList *
+create_connection_list (GList *uris)
+{
+ GNOME_Evolution_ConnectionList *list;
+
+ list = GNOME_Evolution_ConnectionList__alloc ();
+ list->_length = 0;
+ list->_maximum = g_list_length (uris);
+ list->_buffer = CORBA_sequence_GNOME_Evolution_Connection_allocbuf (list->_maximum);
+
+ g_list_foreach (uris, add_connection, list);
+
+ return list;
+}
+
+/* GNOME::Evolution::Offline methods. */
+static CORBA_boolean
+impl__get_isOffline (PortableServer_Servant servant,
+ CORBA_Environment *ev)
+{
+ CalendarOfflineHandler *offline_handler;
+ CalendarOfflineHandlerPrivate *priv;
+
+ offline_handler = CALENDAR_OFFLINE_HANDLER (bonobo_object_from_servant (servant));
+ priv = offline_handler->priv;
+
+ return priv->is_offline;
+}
+
+static void
+impl_prepareForOffline (PortableServer_Servant servant,
+ GNOME_Evolution_ConnectionList **active_connection_list,
+ CORBA_Environment *ev)
+{
+ CalendarOfflineHandler *offline_handler;
+ CalendarOfflineHandlerPrivate *priv;
+ GList *uris;
+
+ offline_handler = CALENDAR_OFFLINE_HANDLER (bonobo_object_from_servant (servant));
+ priv = offline_handler->priv;
+
+ uris = cal_client_uri_list (priv->client, CALURI_TYPE_REMOTE);
+
+ *active_connection_list = create_connection_list (uris);
+}
+
+static void
+update_offline (CalendarOfflineHandler *offline_handler)
+{
+ CalendarOfflineHandlerPrivate *priv;
+ GNOME_Evolution_ConnectionList *connection_list;
+ CORBA_Environment ev;
+
+ priv = offline_handler->priv;
+
+#if 0
+ connection_list = create_connection_list ();
+
+ CORBA_exception_init (&ev);
+
+ GNOME_Evolution_OfflineProgressListener_updateProgress (priv->listener_interface,
+ connection_list, &ev);
+
+ if (BONOBO_EX (&ev))
+ g_warning ("Error updating offline progress");
+
+ CORBA_exception_free (&ev);
+#endif
+}
+
+static void
+backend_cal_opened (CalClient *client, CalClientOpenStatus status, gpointer data)
+{
+ CalendarOfflineHandler *offline_handler = data;
+
+ if (status != CAL_CLIENT_OPEN_SUCCESS) {
+ update_offline (offline_handler);
+ gtk_object_unref (GTK_OBJECT (client));
+ return;
+ }
+}
+
+static void
+backend_go_offline (gpointer data, gpointer user_data)
+{
+ CalendarOfflineHandler *offline_handler = user_data;
+ char *uri = data;
+ CalClient *client;
+ gboolean success;
+
+ client = cal_client_new ();
+ success = cal_client_open_calendar (client, uri, TRUE);
+ if (!success) {
+ update_offline (offline_handler);
+ gtk_object_unref (GTK_OBJECT (client));
+ return;
+ }
+
+ gtk_signal_connect (GTK_OBJECT (client), "cal_opened",
+ backend_cal_opened, offline_handler);
+}
+
+static void
+impl_goOffline (PortableServer_Servant servant,
+ const GNOME_Evolution_OfflineProgressListener progress_listener,
+ CORBA_Environment *ev)
+{
+ CalendarOfflineHandler *offline_handler;
+ CalendarOfflineHandlerPrivate *priv;
+ GList *uris;
+
+ offline_handler = CALENDAR_OFFLINE_HANDLER (bonobo_object_from_servant (servant));
+ priv = offline_handler->priv;
+
+ /* To update the status */
+ priv->listener_interface = CORBA_Object_duplicate (progress_listener, ev);
+
+ uris = cal_client_uri_list (priv->client, CALURI_TYPE_REMOTE);
+
+ g_list_foreach (uris, backend_go_offline, offline_handler);
+}
+
+static void
+impl_goOnline (PortableServer_Servant servant,
+ CORBA_Environment *ev)
+{
+ CalendarOfflineHandler *offline_handler;
+ CalendarOfflineHandlerPrivate *priv;
+
+ offline_handler = CALENDAR_OFFLINE_HANDLER (bonobo_object_from_servant (servant));
+ priv = offline_handler->priv;
+}
+
+/* GtkObject methods. */
+
+static void
+impl_destroy (GtkObject *object)
+{
+ CalendarOfflineHandler *offline_handler;
+ CalendarOfflineHandlerPrivate *priv;
+
+ offline_handler = CALENDAR_OFFLINE_HANDLER (object);
+ priv = offline_handler->priv;
+
+ if (priv->listener_interface != CORBA_OBJECT_NIL) {
+ CORBA_Environment ev;
+
+ CORBA_exception_init (&ev);
+ CORBA_Object_release (priv->listener_interface, &ev);
+ CORBA_exception_free (&ev);
+ }
+
+ g_free (priv);
+
+ if (GTK_OBJECT_CLASS (parent_class)->destroy != NULL)
+ (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+/* GTK+ type initialization. */
+
+static void
+calendar_offline_handler_class_init (CalendarOfflineHandlerClass *klass)
+{
+ GtkObjectClass *object_class;
+ POA_GNOME_Evolution_Offline__epv *epv;
+
+ object_class = GTK_OBJECT_CLASS (klass);
+ object_class->destroy = impl_destroy;
+
+ epv = & klass->epv;
+ epv->_get_isOffline = impl__get_isOffline;
+ epv->prepareForOffline = impl_prepareForOffline;
+ epv->goOffline = impl_goOffline;
+ epv->goOnline = impl_goOnline;
+
+ parent_class = gtk_type_class (PARENT_TYPE);
+}
+
+static void
+calendar_offline_handler_init (CalendarOfflineHandler *offline_handler)
+{
+ CalendarOfflineHandlerPrivate *priv;
+
+ priv = g_new (CalendarOfflineHandlerPrivate, 1);
+ offline_handler->priv = priv;
+
+ priv->client = cal_client_new ();
+ priv->listener_interface = CORBA_OBJECT_NIL;
+ priv->is_offline = FALSE;
+}
+
+CalendarOfflineHandler *
+calendar_offline_handler_new (void)
+{
+ CalendarOfflineHandler *new;
+
+ new = gtk_type_new (calendar_offline_handler_get_type ());
+
+ return new;
+}
+
+BONOBO_X_TYPE_FUNC_FULL (CalendarOfflineHandler, GNOME_Evolution_Offline, PARENT_TYPE, calendar_offline_handler);
diff --git a/calendar/gui/calendar-offline-handler.h b/calendar/gui/calendar-offline-handler.h
new file mode 100644
index 0000000000..e1becb1979
--- /dev/null
+++ b/calendar/gui/calendar-offline-handler.h
@@ -0,0 +1,70 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* calendar-offline-handler.h
+ *
+ * Copyright (C) 2001 Ximian, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Ettore Perazzoli <ettore@ximian.com>
+ */
+
+#ifndef _CALENDAR_OFFLINE_HANDLER_H_
+#define _CALENDAR_OFFLINE_HANDLER_H_
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <bonobo/bonobo-xobject.h>
+#include "Evolution.h"
+
+#ifdef __cplusplus
+extern "C" {
+#pragma }
+#endif /* __cplusplus */
+
+#define CALENDAR_TYPE_OFFLINE_HANDLER (calendar_offline_handler_get_type ())
+#define CALENDAR_OFFLINE_HANDLER(obj) (GTK_CHECK_CAST ((obj), CALENDAR_TYPE_OFFLINE_HANDLER, CalendarOfflineHandler))
+#define CALENDAR_OFFLINE_HANDLER_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), CALENDAR_TYPE_OFFLINE_HANDLER, CalendarOfflineHandlerClass))
+#define CALENDAR_IS_OFFLINE_HANDLER(obj) (GTK_CHECK_TYPE ((obj), CALENDAR_TYPE_OFFLINE_HANDLER))
+#define CALENDAR_IS_OFFLINE_HANDLER_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), CALENDAR_TYPE_OFFLINE_HANDLER))
+
+
+typedef struct _CalendarOfflineHandler CalendarOfflineHandler;
+typedef struct _CalendarOfflineHandlerPrivate CalendarOfflineHandlerPrivate;
+typedef struct _CalendarOfflineHandlerClass CalendarOfflineHandlerClass;
+
+struct _CalendarOfflineHandler {
+ BonoboXObject parent;
+
+ CalendarOfflineHandlerPrivate *priv;
+};
+
+struct _CalendarOfflineHandlerClass {
+ BonoboXObjectClass parent_class;
+
+ POA_GNOME_Evolution_Offline__epv epv;
+};
+
+
+GtkType calendar_offline_handler_get_type (void);
+CalendarOfflineHandler *calendar_offline_handler_new (void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _CALENDAR_OFFLINE_HANDLER_H_ */
diff --git a/calendar/gui/component-factory.c b/calendar/gui/component-factory.c
index 574a700e76..e13a3f8a50 100644
--- a/calendar/gui/component-factory.c
+++ b/calendar/gui/component-factory.c
@@ -34,6 +34,7 @@
#include <bonobo/bonobo-generic-factory.h>
#include <bonobo/bonobo-context.h>
#include "evolution-shell-component.h"
+#include "calendar-offline-handler.h"
#include "component-factory.h"
#include "tasks-control-factory.h"
#include "control-factory.h"
@@ -544,18 +545,6 @@ sc_user_create_new_item_cb (EvolutionShellComponent *shell_component,
g_assert_not_reached ();
}
-#if 0
-static void
-destroy_cb (EvolutionShellComponent *shell_component,
- gpointer user_data)
-{
- shells = g_list_remove (shells, shell_component);
-
- if (g_list_length (shells) == 0)
- gtk_main_quit ();
-}
-#endif
-
/* The factory function. */
@@ -563,7 +552,8 @@ static BonoboObject *
create_object (void)
{
EvolutionShellComponent *shell_component;
-
+ CalendarOfflineHandler *offline_handler;
+
shell_component = evolution_shell_component_new (folder_types,
NULL,
create_view,
@@ -574,18 +564,16 @@ create_object (void)
NULL, /* get_dnd_selection_fn */
NULL /* closure */);
+ /* Offline handler */
+ offline_handler = calendar_offline_handler_new ();
+ bonobo_object_add_interface (BONOBO_OBJECT (shell_component),
+ BONOBO_OBJECT (offline_handler));
+
gtk_signal_connect (GTK_OBJECT (shell_component), "owner_set",
GTK_SIGNAL_FUNC (owner_set_cb), NULL);
gtk_signal_connect (GTK_OBJECT (shell_component), "owner_unset",
GTK_SIGNAL_FUNC (owner_unset_cb), NULL);
-#if 0
- gtk_signal_connect (GTK_OBJECT (shell_component), "destroy",
- GTK_SIGNAL_FUNC (destroy_cb), NULL);
-
- shells = g_list_append (shells, shell_component);
-#endif
-
/* User creatable items */
evolution_shell_component_add_user_creatable_item (shell_component,
diff --git a/calendar/gui/dialogs/comp-editor.c b/calendar/gui/dialogs/comp-editor.c
index 1b114d9ecf..f88c6d2de6 100644
--- a/calendar/gui/dialogs/comp-editor.c
+++ b/calendar/gui/dialogs/comp-editor.c
@@ -254,7 +254,7 @@ comp_editor_destroy (GtkObject *object)
}
if (priv->comp) {
- gtk_object_unref (priv->comp);
+ gtk_object_unref (GTK_OBJECT (priv->comp));
priv->comp = NULL;
}
diff --git a/calendar/gui/e-itip-control.c b/calendar/gui/e-itip-control.c
index 426abd83e0..5b42b75a4b 100644
--- a/calendar/gui/e-itip-control.c
+++ b/calendar/gui/e-itip-control.c
@@ -428,7 +428,7 @@ set_button_status (EItipControl *itip)
}
static void
-write_label_piece (time_t t, char *buffer, int size, char *stext, char *etext)
+write_label_piece (time_t t, char *buffer, int size, const char *stext, const char *etext)
{
struct tm *tmp_tm;
int len;
@@ -1220,7 +1220,6 @@ static void
send_freebusy (EItipControl *itip)
{
EItipControlPrivate *priv;
- CalComponent *comp;
CalComponentDateTime datetime;
time_t start, end;
GtkWidget *dialog;
diff --git a/calendar/idl/evolution-calendar.idl b/calendar/idl/evolution-calendar.idl
index b3158dc487..be378a017a 100644
--- a/calendar/idl/evolution-calendar.idl
+++ b/calendar/idl/evolution-calendar.idl
@@ -48,6 +48,12 @@ module Calendar {
const CalObjType TYPE_JOURNAL = 1 << 2;
const CalObjType TYPE_ANY = 0x07;
+ /* Flags for getting URI sequences */
+ typedef long UriType;
+ const UriType URI_LOCAL = 1 << 0;
+ const UriType URI_REMOTE = 1 << 1;
+ const UriType URI_ANY = 0x07;
+
/* Types of object changes made */
typedef long CalObjChangeType;
const CalObjChangeType ADDED = 1 << 0;
@@ -268,6 +274,9 @@ module Calendar {
/* Open a calendar from an URI */
void open (in string uri, in boolean only_if_exists, in Listener listener)
raises (NilListener);
+
+ /* List of open URI's */
+ StringSeq uriList (in UriType type);
};
/* Interface to the alarm notification service */
diff --git a/calendar/pcs/cal-backend-file.c b/calendar/pcs/cal-backend-file.c
index 7407b6b7c0..a1e679b1c0 100644
--- a/calendar/pcs/cal-backend-file.c
+++ b/calendar/pcs/cal-backend-file.c
@@ -90,6 +90,7 @@ static GnomeVFSURI *cal_backend_file_get_uri (CalBackend *backend);
static CalBackendOpenStatus cal_backend_file_open (CalBackend *backend, GnomeVFSURI *uri,
gboolean only_if_exists);
static gboolean cal_backend_file_is_loaded (CalBackend *backend);
+static gboolean cal_backend_file_is_remote (CalBackend *backend);
static int cal_backend_file_get_n_objects (CalBackend *backend, CalObjType type);
static char *cal_backend_file_get_object (CalBackend *backend, const char *uid);
@@ -169,6 +170,7 @@ cal_backend_file_class_init (CalBackendFileClass *class)
backend_class->get_uri = cal_backend_file_get_uri;
backend_class->open = cal_backend_file_open;
backend_class->is_loaded = cal_backend_file_is_loaded;
+ backend_class->is_remote = cal_backend_file_is_remote;
backend_class->get_n_objects = cal_backend_file_get_n_objects;
backend_class->get_object = cal_backend_file_get_object;
backend_class->get_object_component = cal_backend_file_get_object_component;
@@ -878,6 +880,19 @@ cal_backend_file_is_loaded (CalBackend *backend)
return (priv->icalcomp != NULL);
}
+/* is_remote handler for the file backend */
+static gboolean
+cal_backend_file_is_remote (CalBackend *backend)
+{
+ CalBackendFile *cbfile;
+ CalBackendFilePrivate *priv;
+
+ cbfile = CAL_BACKEND_FILE (backend);
+ priv = cbfile->priv;
+
+ return FALSE;
+}
+
/* Get_n_objects handler for the file backend */
static int
cal_backend_file_get_n_objects (CalBackend *backend, CalObjType type)
diff --git a/calendar/pcs/cal-backend.c b/calendar/pcs/cal-backend.c
index 20f3a74ee1..296af0e8a3 100644
--- a/calendar/pcs/cal-backend.c
+++ b/calendar/pcs/cal-backend.c
@@ -144,6 +144,7 @@ cal_backend_class_init (CalBackendClass *class)
class->get_uri = NULL;
class->open = NULL;
class->is_loaded = NULL;
+ class->is_remote = NULL;
class->get_n_objects = NULL;
class->get_object = NULL;
class->get_object_component = NULL;
@@ -278,7 +279,8 @@ cal_backend_open (CalBackend *backend, GnomeVFSURI *uri, gboolean only_if_exists
*
* Queries whether a calendar backend has been loaded yet.
*
- * Return value: TRUE if the backend has been loaded with data, FALSE otherwise.
+ * Return value: TRUE if the backend has been loaded with data, FALSE
+ * otherwise.
**/
gboolean
cal_backend_is_loaded (CalBackend *backend)
@@ -295,6 +297,29 @@ cal_backend_is_loaded (CalBackend *backend)
}
/**
+ * cal_backend_is_remote:
+ * @backend: A calendar backend.
+ *
+ * Queries whether a calendar backend is connected remotely.
+ *
+ * Return value: TRUE if the backend is connected remotely, FALSE
+ * otherwise.
+ **/
+gboolean
+cal_backend_is_remote (CalBackend *backend)
+{
+ gboolean result;
+
+ g_return_val_if_fail (backend != NULL, FALSE);
+ g_return_val_if_fail (IS_CAL_BACKEND (backend), FALSE);
+
+ g_assert (CLASS (backend)->is_remote != NULL);
+ result = (* CLASS (backend)->is_remote) (backend);
+
+ return result;
+}
+
+/**
* cal_backend_get_n_objects:
* @backend: A calendar backend.
* @type: Types of objects that will be included in the count.
diff --git a/calendar/pcs/cal-backend.h b/calendar/pcs/cal-backend.h
index 1864a08f73..32617f94ae 100644
--- a/calendar/pcs/cal-backend.h
+++ b/calendar/pcs/cal-backend.h
@@ -81,6 +81,7 @@ struct _CalBackendClass {
gboolean only_if_exists);
gboolean (* is_loaded) (CalBackend *backend);
+ gboolean (* is_remote) (CalBackend *backend);
/* General object acquirement and information related virtual methods */
int (* get_n_objects) (CalBackend *backend, CalObjType type);
@@ -122,6 +123,7 @@ CalBackendOpenStatus cal_backend_open (CalBackend *backend, GnomeVFSURI *uri,
gboolean only_if_exists);
gboolean cal_backend_is_loaded (CalBackend *backend);
+gboolean cal_backend_is_remote (CalBackend *backend);
int cal_backend_get_n_objects (CalBackend *backend, CalObjType type);
diff --git a/calendar/pcs/cal-factory.c b/calendar/pcs/cal-factory.c
index 00f6d8b6da..458279b65f 100644
--- a/calendar/pcs/cal-factory.c
+++ b/calendar/pcs/cal-factory.c
@@ -25,6 +25,7 @@
#include <stdio.h>
#include <gtk/gtksignal.h>
#include <liboaf/liboaf.h>
+#include "evolution-calendar.h"
#include "cal.h"
#include "cal-backend.h"
#include "cal-factory.h"
@@ -50,6 +51,13 @@ struct _CalFactoryPrivate {
guint registered : 1;
};
+typedef struct
+{
+ CalFactory *factory;
+ GNOME_Evolution_Calendar_UriType type;
+ GNOME_Evolution_Calendar_StringSeq *list;
+} CalFactoryUriData;
+
/* Signal IDs */
enum SIGNALS {
LAST_CALENDAR_GONE,
@@ -162,15 +170,13 @@ static CalBackend *
launch_backend_for_uri (CalFactory *factory, GnomeVFSURI *uri, GNOME_Evolution_Calendar_Listener listener)
{
CalFactoryPrivate *priv;
- char *method;
+ const char *method;
GtkType *type;
CalBackend *backend;
priv = factory->priv;
- /* FIXME: add an accessor function to gnome-vfs */
- method = uri->method_string;
-
+ method = gnome_vfs_uri_get_scheme (uri);
type = g_hash_table_lookup (priv->methods, method);
if (!type) {
@@ -301,6 +307,41 @@ add_calendar_client (CalFactory *factory, CalBackend *backend, GNOME_Evolution_C
CORBA_exception_free (&ev);
}
+/* Add a uri to a string list */
+static void
+add_uri (gpointer key, gpointer value, gpointer data)
+{
+ CalFactoryUriData *cfud = data;
+ CalFactory *factory = cfud->factory;
+ GNOME_Evolution_Calendar_StringSeq *list = cfud->list;
+ GNOME_Evolution_Calendar_UriType type = cfud->type;
+ char *uri_string = key;
+ CalBackend *backend;
+ GnomeVFSURI *uri;
+
+ switch (type) {
+ case GNOME_Evolution_Calendar_URI_LOCAL:
+ uri = gnome_vfs_uri_new_private (uri_string, TRUE, TRUE, TRUE);
+ backend = lookup_backend (factory, uri);
+ gnome_vfs_uri_unref (uri);
+ if (backend == NULL && cal_backend_is_remote (backend))
+ return;
+ break;
+ case GNOME_Evolution_Calendar_URI_REMOTE:
+ uri = gnome_vfs_uri_new_private (uri_string, TRUE, TRUE, TRUE);
+ backend = lookup_backend (factory, uri);
+ gnome_vfs_uri_unref (uri);
+ if (backend == NULL && !cal_backend_is_remote (backend))
+ return;
+ break;
+ case GNOME_Evolution_Calendar_URI_ANY:
+ break;
+ }
+
+ list->_buffer[list->_length] = CORBA_string_dup (uri_string);
+ list->_length++;
+}
+
/* Job data */
typedef struct {
CalFactory *factory;
@@ -427,6 +468,33 @@ impl_CalFactory_open (PortableServer_Servant servant,
job_add (open_fn, jd);
}
+static GNOME_Evolution_Calendar_StringSeq *
+impl_CalFactory_uriList (PortableServer_Servant servant,
+ GNOME_Evolution_Calendar_UriType type,
+ CORBA_Environment *ev)
+{
+ CalFactory *factory;
+ CalFactoryPrivate *priv;
+ CalFactoryUriData cfud;
+ GNOME_Evolution_Calendar_StringSeq *list;
+
+ factory = CAL_FACTORY (bonobo_object_from_servant (servant));
+ priv = factory->priv;
+
+ list = GNOME_Evolution_Calendar_StringSeq__alloc ();
+ list->_length = 0;
+ list->_maximum = g_hash_table_size (priv->backends);
+ list->_buffer = CORBA_sequence_CORBA_string_allocbuf (list->_maximum);
+
+ cfud.factory = factory;
+ cfud.type = type;
+ cfud.list = list;
+ g_hash_table_foreach (priv->backends, add_uri, &cfud);
+
+ return list;
+
+}
+
/**
@@ -508,6 +576,7 @@ cal_factory_class_init (CalFactoryClass *klass)
/* Epv methods */
epv->open = impl_CalFactory_open;
+ epv->uriList = impl_CalFactory_uriList;
}
/* Object initialization function for the calendar factory */
diff --git a/calendar/pcs/cal.c b/calendar/pcs/cal.c
index 9532e8265a..481019bcb8 100644
--- a/calendar/pcs/cal.c
+++ b/calendar/pcs/cal.c
@@ -23,6 +23,7 @@
#include <config.h>
#include <ical.h>
+#include <bonobo/bonobo-exception.h>
#include "cal.h"
#include "query.h"
#include "wombat.h"
@@ -118,9 +119,8 @@ impl_Cal_get_object (PortableServer_Servant servant,
g_free (calobj);
return calobj_copy;
} else {
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_GNOME_Evolution_Calendar_Cal_NotFound,
- NULL);
+ bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_NotFound);
+
return NULL;
}
}
@@ -218,9 +218,7 @@ impl_Cal_get_objects_in_range (PortableServer_Servant servant,
t_end = (time_t) end;
if (t_start > t_end || t_start == -1 || t_end == -1) {
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_GNOME_Evolution_Calendar_Cal_InvalidRange,
- NULL);
+ bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_InvalidRange);
return NULL;
}
@@ -254,9 +252,7 @@ impl_Cal_get_free_busy (PortableServer_Servant servant,
t_end = (time_t) end;
if (t_start > t_end || t_start == -1 || t_end == -1) {
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_GNOME_Evolution_Calendar_Cal_InvalidRange,
- NULL);
+ bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_InvalidRange);
return NULL;
}
@@ -295,9 +291,7 @@ impl_Cal_get_free_busy (PortableServer_Servant servant,
return seq;
}
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_GNOME_Evolution_Calendar_Cal_NotFound,
- NULL);
+ bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_NotFound);
return NULL;
}
@@ -323,9 +317,7 @@ impl_Cal_get_alarms_in_range (PortableServer_Servant servant,
seq = cal_backend_get_alarms_in_range (priv->backend, t_start, t_end, &valid_range);
if (!valid_range) {
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_GNOME_Evolution_Calendar_Cal_InvalidRange,
- NULL);
+ bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_InvalidRange);
return NULL;
}
@@ -359,15 +351,11 @@ impl_Cal_get_alarms_for_object (PortableServer_Servant servant,
return alarms;
case CAL_BACKEND_GET_ALARMS_NOT_FOUND:
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_GNOME_Evolution_Calendar_Cal_NotFound,
- NULL);
+ bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_NotFound);
return NULL;
case CAL_BACKEND_GET_ALARMS_INVALID_RANGE:
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_GNOME_Evolution_Calendar_Cal_InvalidRange,
- NULL);
+ bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_InvalidRange);
return NULL;
default:
@@ -389,9 +377,7 @@ impl_Cal_update_objects (PortableServer_Servant servant,
priv = cal->priv;
if (!cal_backend_update_objects (priv->backend, calobj))
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_GNOME_Evolution_Calendar_Cal_InvalidObject,
- NULL);
+ bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_InvalidObject);
}
/* Cal::remove_object method */
@@ -407,9 +393,7 @@ impl_Cal_remove_object (PortableServer_Servant servant,
priv = cal->priv;
if (!cal_backend_remove_object (priv->backend, uid))
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_GNOME_Evolution_Calendar_Cal_NotFound,
- NULL);
+ bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_NotFound);
}
/* Cal::getQuery implementation */
@@ -430,20 +414,16 @@ impl_Cal_get_query (PortableServer_Servant servant,
query = query_new (priv->backend, ql, sexp);
if (!query) {
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_GNOME_Evolution_Calendar_Cal_CouldNotCreate,
- NULL);
+ bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_CouldNotCreate);
return CORBA_OBJECT_NIL;
}
CORBA_exception_init (&ev2);
query_copy = CORBA_Object_duplicate (BONOBO_OBJREF (query), &ev2);
- if (ev2._major != CORBA_NO_EXCEPTION) {
+ if (BONOBO_EX (&ev2)) {
CORBA_exception_free (&ev2);
g_message ("Cal_get_query(): Could not duplicate the query reference");
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_GNOME_Evolution_Calendar_Cal_CouldNotCreate,
- NULL);
+ bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_CouldNotCreate);
return CORBA_OBJECT_NIL;
}
@@ -474,9 +454,7 @@ impl_Cal_get_timezone_object (PortableServer_Servant servant,
g_free (calobj);
return calobj_copy;
} else {
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_GNOME_Evolution_Calendar_Cal_NotFound,
- NULL);
+ bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_NotFound);
return NULL;
}
}
@@ -511,7 +489,7 @@ cal_construct (Cal *cal,
CORBA_exception_init (&ev);
priv->listener = CORBA_Object_duplicate (listener, &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
+ if (BONOBO_EX (&ev)) {
g_message ("cal_construct: could not duplicate the listener");
priv->listener = CORBA_OBJECT_NIL;
CORBA_exception_free (&ev);
@@ -523,7 +501,7 @@ cal_construct (Cal *cal,
priv->listener,
"IDL:GNOME/Evolution/WombatClient:1.0",
&ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
+ if (BONOBO_EX (&ev)) {
g_message ("cal_construct: could not get the WombatClient interface");
priv->wombat_client = CORBA_OBJECT_NIL;
}
@@ -584,7 +562,7 @@ cal_destroy (GtkObject *object)
CORBA_exception_init (&ev);
bonobo_object_release_unref (priv->listener, &ev);
- if (ev._major != CORBA_NO_EXCEPTION)
+ if (BONOBO_EX (&ev))
g_message ("cal_destroy(): could not release the listener");
priv->listener = NULL;
@@ -665,7 +643,7 @@ cal_notify_update (Cal *cal, const char *uid)
CORBA_exception_init (&ev);
GNOME_Evolution_Calendar_Listener_notifyObjUpdated (priv->listener, (char *) uid, &ev);
- if (ev._major != CORBA_NO_EXCEPTION)
+ if (BONOBO_EX (&ev))
g_message ("cal_notify_update(): could not notify the listener "
"about an updated object");
@@ -696,7 +674,7 @@ cal_notify_remove (Cal *cal, const char *uid)
CORBA_exception_init (&ev);
GNOME_Evolution_Calendar_Listener_notifyObjRemoved (priv->listener, (char *) uid, &ev);
- if (ev._major != CORBA_NO_EXCEPTION)
+ if (BONOBO_EX (&ev))
g_message ("cal_notify_remove(): could not notify the listener "
"about a removed object");
@@ -727,7 +705,7 @@ cal_notify_categories_changed (Cal *cal, GNOME_Evolution_Calendar_StringSeq *cat
CORBA_exception_init (&ev);
GNOME_Evolution_Calendar_Listener_notifyCategoriesChanged (priv->listener, categories, &ev);
- if (ev._major != CORBA_NO_EXCEPTION)
+ if (BONOBO_EX (&ev))
g_message ("cal_notify_categories_changed(): Could not notify the listener "
"about the current set of categories");
@@ -765,7 +743,7 @@ cal_get_password (Cal *cal, const char *prompt, const char *key)
(const CORBA_char *) prompt,
(const CORBA_char *) key,
&ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
+ if (BONOBO_EX (&ev)) {
g_message ("cal_get_password: could not get password from associated WombatClient");
CORBA_exception_free (&ev);
return NULL;
@@ -804,7 +782,7 @@ cal_forget_password (Cal *cal, const char *key)
(const CORBA_char *) key,
&ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
+ if (BONOBO_EX (&ev)) {
g_message ("cal_forget_password: could not notify WombatClient about "
"password to be forgotten");
}