diff options
-rw-r--r-- | calendar/ChangeLog | 50 | ||||
-rw-r--r-- | calendar/cal-client/cal-client.c | 119 | ||||
-rw-r--r-- | calendar/cal-client/cal-client.h | 1 | ||||
-rw-r--r-- | calendar/cal-util/cal-util.h | 7 | ||||
-rw-r--r-- | calendar/cal-util/calobj.c | 2008 | ||||
-rw-r--r-- | calendar/cal-util/calobj.h | 312 | ||||
-rw-r--r-- | calendar/gui/Makefile.am | 2 | ||||
-rw-r--r-- | calendar/gui/calendar-component.c | 28 | ||||
-rw-r--r-- | calendar/gui/calendar-offline-handler.c | 267 | ||||
-rw-r--r-- | calendar/gui/calendar-offline-handler.h | 70 | ||||
-rw-r--r-- | calendar/gui/component-factory.c | 28 | ||||
-rw-r--r-- | calendar/gui/dialogs/comp-editor.c | 2 | ||||
-rw-r--r-- | calendar/gui/e-itip-control.c | 3 | ||||
-rw-r--r-- | calendar/idl/evolution-calendar.idl | 9 | ||||
-rw-r--r-- | calendar/pcs/cal-backend-file.c | 15 | ||||
-rw-r--r-- | calendar/pcs/cal-backend.c | 27 | ||||
-rw-r--r-- | calendar/pcs/cal-backend.h | 2 | ||||
-rw-r--r-- | calendar/pcs/cal-factory.c | 77 | ||||
-rw-r--r-- | calendar/pcs/cal.c | 68 |
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 (¤t); - - 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 (¤t); - 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 (¤t); - - 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"); } |