aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiguel de Icaza <miguel@gnu.org>1999-07-28 16:41:12 +0800
committerArturo Espinosa <unammx@src.gnome.org>1999-07-28 16:41:12 +0800
commite49e9cc1755266dade86ce33662ceff466f5ca07 (patch)
tree9c26f2dea9902aef6d691d70ddeee07293cba176
parent81207158058c5f5e4315e3b66f92a46aec64e5ae (diff)
downloadgsoc2013-evolution-e49e9cc1755266dade86ce33662ceff466f5ca07.tar
gsoc2013-evolution-e49e9cc1755266dade86ce33662ceff466f5ca07.tar.gz
gsoc2013-evolution-e49e9cc1755266dade86ce33662ceff466f5ca07.tar.bz2
gsoc2013-evolution-e49e9cc1755266dade86ce33662ceff466f5ca07.tar.lz
gsoc2013-evolution-e49e9cc1755266dade86ce33662ceff466f5ca07.tar.xz
gsoc2013-evolution-e49e9cc1755266dade86ce33662ceff466f5ca07.tar.zst
gsoc2013-evolution-e49e9cc1755266dade86ce33662ceff466f5ca07.zip
New file. Implements PalmPilot syncronization with the Gnome Calendar.
1999-07-28 Miguel de Icaza <miguel@gnu.org> * calendar-pilot-sync.c: New file. Implements PalmPilot syncronization with the Gnome Calendar. 1999-07-27 Miguel de Icaza <miguel@gnu.org> * calobj.c (ical_object_new_from_string): New function. Creates an iCalObject from a vCalendar string that is supposed to contain only one vEvent. * calendar.c: (calendar_save): Split this routine in two. * gnome-cal.c (gnome_calendar_new): Create the corba server here. * main.c: Include gnorba.h, and corba-cal-factory.h here (close_cmd): Kill the calendar server on shutdown. * calobj.c (load_recur_yearly_day): Added a fixme comment. WE need to handle intervals in the years. * calendar.c (calendar_object_find_in_list, calendar_object_find, calendar_object_find_todo, calendar_object_find_event): New functions for looking up information. * main.c (gnome_calendar_locate): New function. * corba-cal.c (calendar_create_object): New file. Implements the corba server. * calendar.c (calendar_object_changed): Flag pilot-status as changed. * calobj.c (ical_object_to_vobject): Save pilot information for syncing. (ical_object_create_from_vobject): Load syncing information for pilot. Do it in a way compatible with KOrganizer. 1999-07-26 Miguel de Icaza <miguel@gnu.org> * calobj.c (ical_object_create_from_vobject): Generate unique IDs on Vevents we load that lack it. WE need this for the old gnome calendar generated files (ie, before now :-). svn path=/trunk/; revision=1038
-rw-r--r--calendar/ChangeLog45
-rw-r--r--calendar/Makefile.am48
-rw-r--r--calendar/TODO5
-rw-r--r--calendar/cal-util/calobj.c62
-rw-r--r--calendar/cal-util/calobj.h11
-rw-r--r--calendar/calendar-pilot-sync.c360
-rw-r--r--calendar/calendar.c139
-rw-r--r--calendar/calendar.h11
-rw-r--r--calendar/calobj.c62
-rw-r--r--calendar/calobj.h11
-rw-r--r--calendar/gnome-cal.c2
-rw-r--r--calendar/gnome-cal.h2
-rw-r--r--calendar/gui/Makefile.am48
-rw-r--r--calendar/gui/calendar-pilot-sync.c360
-rw-r--r--calendar/gui/calendar.c139
-rw-r--r--calendar/gui/calendar.h11
-rw-r--r--calendar/gui/gnome-cal.c2
-rw-r--r--calendar/gui/gnome-cal.h2
-rw-r--r--calendar/gui/main.c49
-rw-r--r--calendar/gui/main.h3
-rw-r--r--calendar/main.c49
-rw-r--r--calendar/main.h3
-rw-r--r--calendar/pcs/calobj.c62
-rw-r--r--calendar/pcs/calobj.h11
24 files changed, 1461 insertions, 36 deletions
diff --git a/calendar/ChangeLog b/calendar/ChangeLog
index 9dac365862..8d7fed8098 100644
--- a/calendar/ChangeLog
+++ b/calendar/ChangeLog
@@ -1,3 +1,48 @@
+1999-07-28 Miguel de Icaza <miguel@gnu.org>
+
+ * calendar-pilot-sync.c: New file. Implements PalmPilot
+ syncronization with the Gnome Calendar.
+
+1999-07-27 Miguel de Icaza <miguel@gnu.org>
+
+ * calobj.c (ical_object_new_from_string): New function. Creates
+ an iCalObject from a vCalendar string that is supposed to contain
+ only one vEvent.
+
+ * calendar.c:
+ (calendar_save): Split this routine in two.
+
+ * gnome-cal.c (gnome_calendar_new): Create the corba server here.
+
+ * main.c: Include gnorba.h, and corba-cal-factory.h here
+ (close_cmd): Kill the calendar server on shutdown.
+
+ * calobj.c (load_recur_yearly_day): Added a fixme comment. WE
+ need to handle intervals in the years.
+
+ * calendar.c (calendar_object_find_in_list, calendar_object_find,
+ calendar_object_find_todo, calendar_object_find_event): New
+ functions for looking up information.
+
+ * main.c (gnome_calendar_locate): New function.
+
+ * corba-cal.c (calendar_create_object): New file. Implements the
+ corba server.
+
+ * calendar.c (calendar_object_changed): Flag pilot-status as changed.
+
+ * calobj.c (ical_object_to_vobject): Save pilot information for syncing.
+ (ical_object_create_from_vobject): Load syncing information for
+ pilot. Do it in a way compatible with KOrganizer.
+
+1999-07-26 Miguel de Icaza <miguel@gnu.org>
+
+ * calobj.c (ical_object_create_from_vobject): Generate unique IDs
+ on Vevents we load that lack it. WE need this for the old
+ gnome calendar generated files (ie, before now :-).
+
+ Required to sync with the Palm
+
1999-07-26 Miguel de Icaza <miguel@gnu.org>
* calobj.c (ical_object_create_from_vobject): Generate unique IDs
diff --git a/calendar/Makefile.am b/calendar/Makefile.am
index 151ce8d64b..e4fa401aad 100644
--- a/calendar/Makefile.am
+++ b/calendar/Makefile.am
@@ -1,17 +1,36 @@
SUBDIRS = doc
+idldir = $(datadir)/idl
+idl_DATA = GnomeCal.idl
+
+gnorbadir = $(sysconfdir)/CORBA/servers
+gnorba_DATA = gnomecal.gnorba
+
help_base = $(datadir)/gnome/help/cal
-CFLAGS += -Wall
+CFLAGS += -Wall -Wunused -Wpointer-arith -Wmissing-declarations
INCLUDES = \
-I$(includedir) \
$(GNOME_INCLUDEDIR) \
-DGNOMELOCALEDIR=\""$(datadir)/locale"\"
-bin_PROGRAMS = gnomecal
+bin_PROGRAMS = gnomecal calendar-pilot-sync
+
+GNOMECAL_CORBA_GENERATED = \
+ GnomeCal.h \
+ GnomeCal.c \
+ GnomeCal-common.c \
+ GnomeCal-skels.c \
+ GnomeCal-stubs.c
+
+$(GNOMECAL_CORBA_GENERATED): GnomeCal.idl
+ orbit-idl GnomeCal.idl
gnomecal_SOURCES = \
+ GnomeCal-common.c \
+ GnomeCal-skels.c \
+ GnomeCal.h \
alarm.c \
alarm.h \
calendar.c \
@@ -21,6 +40,10 @@ gnomecal_SOURCES = \
eventedit.c \
eventedit.h \
getdate.y \
+ corba-cal.c \
+ corba-cal.h \
+ corba-cal-factory.c \
+ corba-cal-factory.h \
gncal-day-panel.c \
gncal-day-panel.h \
gncal-day-view.c \
@@ -57,11 +80,28 @@ gnomecal_SOURCES = \
year-view.c \
year-view.h
+calendar_pilot_sync_SOURCES = \
+ GnomeCal-common.c \
+ GnomeCal-stubs.c \
+ alarm.c \
+ calendar-pilot-sync.c \
+ calobj.c \
+ calobj.h \
+ calendar.c \
+ calendar.h \
+ timeutil.c \
+ timeutil.h
+
LINK_FLAGS = \
$(GNOME_LIBDIR) \
$(GNOMEGNORBA_LIBS) \
$(INTLLIBS) ../libversit/libversit.a
+PILOT_LIBS = -lpisock
+
+calendar_pilot_sync_LDADD = \
+ $(PILOT_LIBS) \
+ $(LINK_FLAGS)
#gncal_LDADD = $(LINK_FLAGS)
@@ -70,7 +110,9 @@ gnomecal_LDADD = $(LINK_FLAGS)
EXTRA_DIST = \
gncal.desktop \
bell.xpm \
- recur.xpm
+ recur.xpm \
+ $(idl_DATA) \
+ $(gnorba_DATA)
Productivitydir = $(datadir)/gnome/apps/Applications
diff --git a/calendar/TODO b/calendar/TODO
index 5271b15909..bb964e908d 100644
--- a/calendar/TODO
+++ b/calendar/TODO
@@ -1,3 +1,8 @@
+Pilot:
+
+* Better support for untimed events (we have none now).
+* Add syncing from Desktop to Pilot.
+
BUGS:
- Recurrence end date is wrong. An event that repeats daily will not
diff --git a/calendar/cal-util/calobj.c b/calendar/cal-util/calobj.c
index 2618470808..08c8d8c63a 100644
--- a/calendar/cal-util/calobj.c
+++ b/calendar/cal-util/calobj.c
@@ -47,6 +47,9 @@ ical_object_new (void)
ico->seq = -1;
ico->dtstamp = time (NULL);
ico->uid = ical_gen_uid ();
+
+ ico->pilot_id = 0;
+ ico->pilot_status = ICAL_PILOT_SYNC_MOD;
return ico;
}
@@ -372,6 +375,8 @@ 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);
}
@@ -782,6 +787,22 @@ ical_object_create_from_vobject (VObject *o, const char *object_name)
}
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;
}
@@ -1047,6 +1068,17 @@ ical_object_to_vobject (iCalObject *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;
}
@@ -1426,3 +1458,33 @@ alarm_compute_offset (CalendarAlarm *a)
}
return a->offset;
}
+
+iCalObject *
+ical_object_new_from_string (const char *vcal_string)
+{
+ iCalObject *ical = NULL;
+ VObject *cal, *event;
+ VObjectIterator i;
+ char *object_name;
+
+ cal = Parse_MIME (vcal_string, strlen (vcal_string));
+
+ initPropIterator (&i, cal);
+
+ while (moreIteration (&i)){
+ event = nextVObject (&i);
+
+ object_name = vObjectName (event);
+
+ if (strcmp (object_name, VCEventProp) == 0){
+ ical = ical_object_create_from_vobject (event, object_name);
+ break;
+ }
+ }
+
+ cleanVObject (cal);
+ cleanStrTbl ();
+
+ return ical;
+}
+
diff --git a/calendar/cal-util/calobj.h b/calendar/cal-util/calobj.h
index 9532b1325f..07ba3f1cc7 100644
--- a/calendar/cal-util/calobj.h
+++ b/calendar/cal-util/calobj.h
@@ -65,6 +65,12 @@ typedef struct {
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;
@@ -172,6 +178,10 @@ typedef struct {
int new;
void *user_data; /* Generic data pointer */
+
+ /* Pilot */
+ int pilot_status; /* Status information */
+ int pilot_id; /* Pilot ID */
} iCalObject;
/* The callback for the recurrence generator */
@@ -179,6 +189,7 @@ typedef int (*calendarfn) (iCalObject *, time_t, time_t, void *);
iCalObject *ical_new (char *comment, char *organizer, char *summary);
iCalObject *ical_object_new (void);
+iCalObject *ical_object_new_from_string (const char *vcalendar_string);
void ical_object_destroy (iCalObject *ico);
iCalObject *ical_object_create_from_vobject (VObject *obj, const char *object_name);
VObject *ical_object_to_vobject (iCalObject *ical);
diff --git a/calendar/calendar-pilot-sync.c b/calendar/calendar-pilot-sync.c
new file mode 100644
index 0000000000..6ed92d540a
--- /dev/null
+++ b/calendar/calendar-pilot-sync.c
@@ -0,0 +1,360 @@
+/*
+ * calendar-pilot-sync.c:
+ *
+ * (C) 1999 International GNOME Support
+ *
+ * Author:
+ * Miguel de Icaza (miguel@gnome-support.com)
+ *
+ */
+#include <config.h>
+#include <gnome.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libgnorba/gnome-factory.h>
+#include <libgnorba/gnorba.h>
+#include "calobj.h"
+#include "calendar.h"
+#include "timeutil.h"
+#include "GnomeCal.h"
+#include "pi-source.h"
+#include "pi-socket.h"
+#include "pi-datebook.h"
+#include "pi-dlp.h"
+
+/* the CORBA ORB */
+CORBA_ORB orb;
+
+/* The default port to communicate with */
+char *pilot_port = "/dev/pilot";
+
+CORBA_Environment ev;
+
+struct pi_sockaddr addr;
+
+const struct poptOption calendar_sync_options [] = {
+ { "pilot", 0, POPT_ARG_STRING, &pilot_port, 0,
+ N_("Specifies the port on which the Pilot is"), N_("PORT") },
+ { NULL, '\0', 0, NULL, 0 }
+};
+
+static int
+setup_connection (void)
+{
+ int socket;
+ int ret, news;
+
+ if (!(socket = pi_socket(PI_AF_SLP, PI_SOCK_STREAM, PI_PF_PADP)))
+ g_error (_("Can not create Pilot socket\n"));
+
+ addr.pi_family = PI_AF_SLP;
+ strncpy ((void *) &addr.pi_device, pilot_port, sizeof (addr.pi_device));
+
+ ret = pi_bind (socket, (struct sockaddr *)&addr, sizeof (addr));
+ if (ret == -1)
+ g_error (_("Can not bind to device %s\n"), pilot_port);
+
+ if (pi_listen (socket, 1) == -1)
+ g_error (_("Failed to get a connection from the Pilot device"));
+
+ if ((news = pi_accept (socket, 0, 0)) == -1)
+ g_error (_("pi_accept failed"));
+
+ return news;
+}
+
+static GNOME_Calendar_Repository
+locate_calendar_server (void)
+{
+ GNOME_Calendar_Repository repo;
+ GNOME_stringlist list;
+
+ repo = goad_server_activate_with_id (
+ NULL, "IDL:GNOME:Calendar:Repository:1.0",
+ 0, NULL);
+
+ if (repo == CORBA_OBJECT_NIL)
+ g_error ("Can not communicate with GnomeCalendar server");
+
+ if (ev._major != CORBA_NO_EXCEPTION){
+ printf ("Exception: %s\n", CORBA_exception_id (&ev));
+ abort ();
+ }
+
+ return repo;
+}
+
+static void
+delete_record (GNOME_Calendar_Repository repo, int id)
+{
+ char *uid;
+
+ uid = GNOME_Calendar_Repository_get_id_from_pilot_id (repo, id, &ev);
+
+ /* The record was already deleted */
+ if (ev._major != CORBA_NO_EXCEPTION)
+ return;
+
+ GNOME_Calendar_Repository_delete_object (repo, uid, &ev);
+ CORBA_free (uid);
+}
+
+static void
+update_record (GNOME_Calendar_Repository repo, int id, struct Appointment *a, int attr)
+{
+ char *vcal_string;
+ iCalObject *obj;
+ int i;
+ char *str;
+
+ obj = ical_new (a->note ? a->note : "",
+ g_get_user_name (),
+ a->description ? a->description : "");
+
+ vcal_string = GNOME_Calendar_Repository_get_object_by_pilot_id (repo, id, &ev);
+
+ if (ev._major == CORBA_USER_EXCEPTION){
+ time_t now = time (NULL);
+
+ obj->created = now;
+ obj->last_mod = now;
+ obj->priority = 0;
+ obj->transp = 0;
+ obj->related = NULL;
+ obj->pilot_id = id;
+ obj->pilot_status = ICAL_PILOT_SYNC_NONE;
+ printf (_("Object did not exist, creating a new one"));
+ } else
+ obj = ical_object_new_from_string (vcal_string);
+
+ if (obj->pilot_status == ICAL_PILOT_SYNC_MOD){
+ printf (_("Object has been modified on desktop and on the pilot, desktop takes precedence"));
+ ical_object_destroy (obj);
+ return;
+ }
+
+ /*
+ * Begin and end
+ */
+ obj->dtstart = mktime (&a->begin);
+ obj->dtend = mktime (&a->end);
+
+ /* Special case: daily repetitions are converted to a multi-day event */
+ if (a->repeatType == repeatDaily){
+ time_t newt = time_add_day (obj->dtend, a->repeatFrequency);
+
+ obj->dtend = newt;
+ }
+
+ /*
+ * Alarm
+ */
+ if (a->alarm){
+ obj->aalarm.type = ALARM_AUDIO;
+ obj->aalarm.enabled = 1;
+ obj->aalarm.count = a->advance;
+
+ switch (a->advanceUnits){
+ case advMinutes:
+ obj->aalarm.units = ALARM_MINUTES;
+ break;
+
+ case advHours:
+ obj->aalarm.units = ALARM_HOURS;
+ break;
+
+ case advDays:
+ obj->aalarm.units = ALARM_DAYS;
+ break;
+ default:
+ }
+ }
+
+ /*
+ * Recurrence
+ */
+ if (a->repeatFrequency && a->repeatType != repeatDaily){
+ obj->recur = g_new0 (Recurrence, 1);
+
+ switch (a->repeatType){
+ case repeatDaily:
+ /*
+ * In the Pilot daily repetitions are actually
+ * multi-day events
+ */
+ g_warning ("Should not have got here");
+ break;
+
+ case repeatMonthlyByDate:
+ obj->recur->type = RECUR_MONTHLY_BY_DAY;
+ obj->recur->u.month_day = a->repeatFrequency;
+ break;
+
+ case repeatWeekly:
+ {
+ int wd;
+
+ obj->recur->type = RECUR_WEEKLY;
+ for (wd = 0; wd < 7; wd++)
+ if (a->repeatDays [wd])
+ obj->recur->weekday |= 1 << wd;
+
+ if (obj->recur->weekday == 0){
+ struct tm *tm = localtime (&obj->dtstart);
+
+ obj->recur->weekday = 1 << tm->tm_wday;
+ }
+ break;
+ }
+
+ case repeatMonthlyByDay:
+ obj->recur->type = RECUR_MONTHLY_BY_POS;
+ obj->recur->u.month_pos = a->repeatFrequency;
+ obj->recur->weekday = (a->repeatDay / 7);
+ break;
+
+ case repeatYearly:
+ obj->recur->type = RECUR_YEARLY_BY_DAY;
+ break;
+
+ default:
+ g_warning ("Unhandled repeate case");
+ }
+
+ if (a->repeatForever)
+ obj->recur->duration = 0;
+ else
+ obj->recur->_enddate = mktime (&a->repeatEnd);
+ }
+
+ /*
+ * Load exception dates
+ */
+ obj->exdate = NULL;
+ for (i = 0; i < a->exceptions; i++){
+ time_t *t = g_new (time_t, 1);
+
+ *t = mktime (&(a->exception [i]));
+ obj->exdate = g_list_prepend (obj->exdate, t);
+ }
+
+ g_free (obj->class);
+
+ if (attr & dlpRecAttrSecret)
+ obj->class = g_strdup ("PRIVATE");
+ else
+ obj->class = g_strdup ("PUBLIC");
+
+ /*
+ * Now, convert the in memory iCalObject to a full vCalendar we can send
+ */
+ str = calendar_string_from_object (obj);
+
+ GNOME_Calendar_Repository_update_object (repo, obj->uid, str, &ev);
+
+ free (str);
+
+ /*
+ * Shutdown
+ */
+ ical_object_destroy (obj);
+}
+
+static void
+sync_pilot (GNOME_Calendar_Repository repo, int pilot_fd)
+{
+ struct PilotUser user_info;
+ int db,record;
+ unsigned char buffer [65536];
+
+ printf (_("Syncing with the pilot..."));
+ dlp_ReadUserInfo (pilot_fd, &user_info);
+
+ /* This informs the user of the progress on the Pilot */
+ dlp_OpenConduit (pilot_fd);
+
+ if (dlp_OpenDB (pilot_fd, 0, 0x80 | 0x40, "DatebookDB", &db) < 0){
+ g_warning (_("Could not open DatebookDB on the Pilot"));
+ dlp_AddSyncLogEntry (pilot_fd, _("Unable to open DatebookDB"));
+ pi_close (pilot_fd);
+ exit (1);
+ }
+
+ /*
+ * 1. Pull all the records from the Pilot, and make any updates
+ * required on the desktop side
+ */
+ for (record = 0;; record++){
+ struct Appointment a;
+ int rec_len, attr, size;
+ recordid_t id;
+
+ rec_len = dlp_ReadRecordByIndex (pilot_fd, db, record, buffer, &id, &size, &attr, 0);
+
+ if (rec_len < 0)
+ break;
+
+ printf ("processing record %d\n", record);
+ unpack_Appointment (&a, buffer, rec_len);
+
+ /* If the object was deleted, remove it from the database */
+ if (attr & dlpRecAttrDeleted){
+ delete_record (repo, id);
+ continue;
+ }
+
+ if (attr & dlpRecAttrDirty){
+ printf ("updating record\n");
+ update_record (repo, id, &a, attr);
+ }
+
+ free_Appointment (&a);
+ }
+ /*
+ * 2. Pull all the records from the Calendar, and move any new items
+ * to the pilot
+ */
+ dlp_CloseDB (pilot_fd, db);
+ dlp_AddSyncLogEntry (pilot_fd, _("Synced DateBook from Pilot to GnomeCal"));
+ pi_close (pilot_fd);
+}
+
+int
+main (int argc, char *argv [])
+{
+ int link;
+ GNOME_Calendar_Repository repository;
+
+ CORBA_exception_init (&ev);
+ orb = gnome_CORBA_init_with_popt_table (
+ "calendar-pilot-sync", VERSION, &argc, argv,
+ calendar_sync_options, 0, NULL, 0, &ev);
+
+ printf ("Please, press HotSync button on the palm...");
+ fflush (stdout);
+ link = setup_connection ();
+ printf ("Connected\n");
+
+ printf ("Launching GnomeCal...");
+ fflush (stdout);
+ repository = locate_calendar_server ();
+ printf ("Done\n");
+
+ printf ("Syncing...\n");
+ sync_pilot (repository, link);
+ printf ("Done Syncing\n");
+
+ GNOME_Calendar_Repository_done (repository, &ev);
+
+ CORBA_exception_free (&ev);
+
+ return 0;
+}
+
+/* Just a stub to link with */
+void
+calendar_notify (time_t time, CalendarAlarm *which, void *data)
+{
+}
+
diff --git a/calendar/calendar.c b/calendar/calendar.c
index ff7ae8ee5d..b67f875fdc 100644
--- a/calendar/calendar.c
+++ b/calendar/calendar.c
@@ -4,7 +4,7 @@
* This keeps track of a given calendar. Eventually this will abtract everything
* related to getting calendars/saving calendars locally or to a remote Calendar Service
*
- * Copyright (C) 1998 the Free Software Foundation
+ * Copyright (C) 1998, 1999 the Free Software Foundation
*
* Authors:
* Miguel de Icaza (miguel@gnu.org)
@@ -323,18 +323,14 @@ calendar_load (Calendar *cal, char *fname)
return NULL;
}
-void
-calendar_save (Calendar *cal, char *fname)
+static VObject *
+vcalendar_create_from_calendar (Calendar *cal)
{
VObject *vcal;
GList *l;
time_t now = time (NULL);
- struct stat s;
struct tm *tm;
- if (fname == NULL)
- fname = cal->filename;
-
/* WE call localtime for the side effect of setting tzname */
tm = localtime (&now);
@@ -366,6 +362,19 @@ calendar_save (Calendar *cal, char *fname)
addVObjectProp (vcal, obj);
}
+ return vcal;
+}
+
+void
+calendar_save (Calendar *cal, char *fname)
+{
+ VObject *vcal;
+ struct stat s;
+
+ if (fname == NULL)
+ fname = cal->filename;
+
+ vcal = vcalendar_create_from_calendar (cal);
if (g_file_exists (fname)){
char *backup_name = g_strconcat (fname, "~", NULL);
@@ -375,6 +384,7 @@ calendar_save (Calendar *cal, char *fname)
rename (fname, backup_name);
g_free (backup_name);
}
+
writeVObjectToFile (fname, vcal);
stat (fname, &s);
@@ -384,6 +394,23 @@ calendar_save (Calendar *cal, char *fname)
cleanStrTbl ();
}
+char *
+calendar_get_as_vcal_string (Calendar *cal)
+{
+ VObject *vcal;
+ char *result;
+
+ g_return_val_if_fail (cal != NULL, NULL);
+
+ vcal = vcalendar_create_from_calendar (cal);
+ result = writeMemVObject (NULL, 0, vcal);
+
+ cleanVObject (vcal);
+ cleanStrTbl ();
+
+ return result;
+}
+
static gint
calendar_object_compare_by_start (gconstpointer a, gconstpointer b)
{
@@ -440,6 +467,8 @@ calendar_object_changed (Calendar *cal, iCalObject *obj, int flags)
while (alarm_kill (obj))
;
ical_object_try_alarms (obj);
+
+ obj->pilot_status = ICAL_PILOT_SYNC_MOD;
}
static void
@@ -466,3 +495,99 @@ calendar_init_alarms (Calendar *cal)
alarm_add (&day_change_alarm, calendar_day_change, cal);
}
+static iCalObject *
+calendar_object_find_in_list (Calendar *cal, GList *list, const char *uid)
+{
+ GList *l;
+
+ for (l = list; l; l = l->next){
+ iCalObject *obj = l->data;
+
+ if (strcmp (obj->uid, uid) == 0)
+ return obj;
+ }
+
+ return NULL;
+}
+
+iCalObject *
+calendar_object_find_event (Calendar *cal, const char *uid)
+{
+ g_return_val_if_fail (cal != NULL, NULL);
+ g_return_val_if_fail (uid != NULL, NULL);
+
+ return calendar_object_find_in_list (cal, cal->events, uid);
+}
+
+iCalObject *
+calendar_object_find_todo (Calendar *cal, const char *uid)
+{
+ g_return_val_if_fail (cal != NULL, NULL);
+ g_return_val_if_fail (uid != NULL, NULL);
+
+ return calendar_object_find_in_list (cal, cal->todo, uid);
+}
+
+iCalObject *
+calendar_object_find (Calendar *cal, const char *uid)
+{
+ iCalObject *obj;
+
+ g_return_val_if_fail (cal != NULL, NULL);
+ g_return_val_if_fail (uid != NULL, NULL);
+
+ obj = calendar_object_find_in_list (cal, cal->todo, uid);
+
+ if (obj == NULL)
+ obj = calendar_object_find_in_list (cal, cal->events, uid);
+
+ return obj;
+}
+
+iCalObject *
+calendar_object_find_by_pilot (Calendar *cal, int pilot_id)
+{
+ GList *l;
+
+ g_return_val_if_fail (cal != NULL, NULL);
+
+ for (l = cal->events; l; l = l->next){
+ iCalObject *obj = l->data;
+
+ if (obj->pilot_id == pilot_id)
+ return obj;
+ }
+
+ for (l = cal->todo; l; l = l->next){
+ iCalObject *obj = l->data;
+
+ if (obj->pilot_id == pilot_id)
+ return obj;
+ }
+
+ return NULL;
+}
+
+/*
+ * calendar_string_from_object:
+ *
+ * Returns the iCalObject @object armored around a vCalendar
+ * object as a string.
+ */
+char *
+calendar_string_from_object (iCalObject *object)
+{
+ Calendar *cal;
+ char *str;
+
+ g_return_val_if_fail (object != NULL, NULL);
+
+ cal = calendar_new ("Temporal");
+ calendar_add_object (cal, object);
+ str = calendar_get_as_vcal_string (cal);
+ calendar_remove_object (cal, object);
+
+ calendar_destroy (cal);
+
+ return str;
+}
diff --git a/calendar/calendar.h b/calendar/calendar.h
index 8dc0c517c3..2ea2753057 100644
--- a/calendar/calendar.h
+++ b/calendar/calendar.h
@@ -26,6 +26,8 @@ typedef struct {
/* If the calendar was last modified */
int modified;
void *temp;
+
+ void *corba_server;
} Calendar;
/* This is only used by the calendar_get_events_in_range routine to get
@@ -38,6 +40,9 @@ typedef struct {
} CalendarObject;
Calendar *calendar_new (char *title);
+char *calendar_get_as_vcal_string (Calendar *cal);
+char *calendar_string_from_object (iCalObject *object);
+
char *calendar_load (Calendar *cal, char *fname);
void calendar_save (Calendar *cal, char *fname);
void calendar_add_object (Calendar *cal, iCalObject *obj);
@@ -63,6 +68,12 @@ void calendar_destroy_event_list (GList *l);
void calendar_object_changed (Calendar *cal, iCalObject *obj, int flags);
void calendar_notify (time_t time, CalendarAlarm *which, void *data);
+
+iCalObject *calendar_object_find_event (Calendar *cal, const char *uid);
+iCalObject *calendar_object_find_todo (Calendar *cal, const char *uid);
+iCalObject *calendar_object_find (Calendar *cal, const char *uid);
+iCalObject *calendar_object_find_by_pilot (Calendar *cal, int pilot_id);
+
END_GNOME_DECLS
#endif
diff --git a/calendar/calobj.c b/calendar/calobj.c
index 2618470808..08c8d8c63a 100644
--- a/calendar/calobj.c
+++ b/calendar/calobj.c
@@ -47,6 +47,9 @@ ical_object_new (void)
ico->seq = -1;
ico->dtstamp = time (NULL);
ico->uid = ical_gen_uid ();
+
+ ico->pilot_id = 0;
+ ico->pilot_status = ICAL_PILOT_SYNC_MOD;
return ico;
}
@@ -372,6 +375,8 @@ 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);
}
@@ -782,6 +787,22 @@ ical_object_create_from_vobject (VObject *o, const char *object_name)
}
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;
}
@@ -1047,6 +1068,17 @@ ical_object_to_vobject (iCalObject *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;
}
@@ -1426,3 +1458,33 @@ alarm_compute_offset (CalendarAlarm *a)
}
return a->offset;
}
+
+iCalObject *
+ical_object_new_from_string (const char *vcal_string)
+{
+ iCalObject *ical = NULL;
+ VObject *cal, *event;
+ VObjectIterator i;
+ char *object_name;
+
+ cal = Parse_MIME (vcal_string, strlen (vcal_string));
+
+ initPropIterator (&i, cal);
+
+ while (moreIteration (&i)){
+ event = nextVObject (&i);
+
+ object_name = vObjectName (event);
+
+ if (strcmp (object_name, VCEventProp) == 0){
+ ical = ical_object_create_from_vobject (event, object_name);
+ break;
+ }
+ }
+
+ cleanVObject (cal);
+ cleanStrTbl ();
+
+ return ical;
+}
+
diff --git a/calendar/calobj.h b/calendar/calobj.h
index 9532b1325f..07ba3f1cc7 100644
--- a/calendar/calobj.h
+++ b/calendar/calobj.h
@@ -65,6 +65,12 @@ typedef struct {
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;
@@ -172,6 +178,10 @@ typedef struct {
int new;
void *user_data; /* Generic data pointer */
+
+ /* Pilot */
+ int pilot_status; /* Status information */
+ int pilot_id; /* Pilot ID */
} iCalObject;
/* The callback for the recurrence generator */
@@ -179,6 +189,7 @@ typedef int (*calendarfn) (iCalObject *, time_t, time_t, void *);
iCalObject *ical_new (char *comment, char *organizer, char *summary);
iCalObject *ical_object_new (void);
+iCalObject *ical_object_new_from_string (const char *vcalendar_string);
void ical_object_destroy (iCalObject *ico);
iCalObject *ical_object_create_from_vobject (VObject *obj, const char *object_name);
VObject *ical_object_to_vobject (iCalObject *ical);
diff --git a/calendar/gnome-cal.c b/calendar/gnome-cal.c
index 86900dd343..1b6c80e236 100644
--- a/calendar/gnome-cal.c
+++ b/calendar/gnome-cal.c
@@ -226,6 +226,8 @@ gnome_calendar_new (char *title)
gcal->current_display = time_day_begin (time (NULL));
gcal->cal = calendar_new (title);
setup_widgets (gcal);
+ gnome_calendar_create_corba_server (gcal);
+
return retval;
}
diff --git a/calendar/gnome-cal.h b/calendar/gnome-cal.h
index ae4e5292da..da53f29882 100644
--- a/calendar/gnome-cal.h
+++ b/calendar/gnome-cal.h
@@ -63,6 +63,8 @@ void gnome_calendar_object_changed (GnomeCalendar *gcal,
iCalObject *obj,
int flags);
+GnomeCalendar *gnome_calendar_locate (const char *pathname);
+
/* Notifies the calendar that the time format has changed and it must update all its views */
void gnome_calendar_time_format_changed (GnomeCalendar *gcal);
diff --git a/calendar/gui/Makefile.am b/calendar/gui/Makefile.am
index 151ce8d64b..e4fa401aad 100644
--- a/calendar/gui/Makefile.am
+++ b/calendar/gui/Makefile.am
@@ -1,17 +1,36 @@
SUBDIRS = doc
+idldir = $(datadir)/idl
+idl_DATA = GnomeCal.idl
+
+gnorbadir = $(sysconfdir)/CORBA/servers
+gnorba_DATA = gnomecal.gnorba
+
help_base = $(datadir)/gnome/help/cal
-CFLAGS += -Wall
+CFLAGS += -Wall -Wunused -Wpointer-arith -Wmissing-declarations
INCLUDES = \
-I$(includedir) \
$(GNOME_INCLUDEDIR) \
-DGNOMELOCALEDIR=\""$(datadir)/locale"\"
-bin_PROGRAMS = gnomecal
+bin_PROGRAMS = gnomecal calendar-pilot-sync
+
+GNOMECAL_CORBA_GENERATED = \
+ GnomeCal.h \
+ GnomeCal.c \
+ GnomeCal-common.c \
+ GnomeCal-skels.c \
+ GnomeCal-stubs.c
+
+$(GNOMECAL_CORBA_GENERATED): GnomeCal.idl
+ orbit-idl GnomeCal.idl
gnomecal_SOURCES = \
+ GnomeCal-common.c \
+ GnomeCal-skels.c \
+ GnomeCal.h \
alarm.c \
alarm.h \
calendar.c \
@@ -21,6 +40,10 @@ gnomecal_SOURCES = \
eventedit.c \
eventedit.h \
getdate.y \
+ corba-cal.c \
+ corba-cal.h \
+ corba-cal-factory.c \
+ corba-cal-factory.h \
gncal-day-panel.c \
gncal-day-panel.h \
gncal-day-view.c \
@@ -57,11 +80,28 @@ gnomecal_SOURCES = \
year-view.c \
year-view.h
+calendar_pilot_sync_SOURCES = \
+ GnomeCal-common.c \
+ GnomeCal-stubs.c \
+ alarm.c \
+ calendar-pilot-sync.c \
+ calobj.c \
+ calobj.h \
+ calendar.c \
+ calendar.h \
+ timeutil.c \
+ timeutil.h
+
LINK_FLAGS = \
$(GNOME_LIBDIR) \
$(GNOMEGNORBA_LIBS) \
$(INTLLIBS) ../libversit/libversit.a
+PILOT_LIBS = -lpisock
+
+calendar_pilot_sync_LDADD = \
+ $(PILOT_LIBS) \
+ $(LINK_FLAGS)
#gncal_LDADD = $(LINK_FLAGS)
@@ -70,7 +110,9 @@ gnomecal_LDADD = $(LINK_FLAGS)
EXTRA_DIST = \
gncal.desktop \
bell.xpm \
- recur.xpm
+ recur.xpm \
+ $(idl_DATA) \
+ $(gnorba_DATA)
Productivitydir = $(datadir)/gnome/apps/Applications
diff --git a/calendar/gui/calendar-pilot-sync.c b/calendar/gui/calendar-pilot-sync.c
new file mode 100644
index 0000000000..6ed92d540a
--- /dev/null
+++ b/calendar/gui/calendar-pilot-sync.c
@@ -0,0 +1,360 @@
+/*
+ * calendar-pilot-sync.c:
+ *
+ * (C) 1999 International GNOME Support
+ *
+ * Author:
+ * Miguel de Icaza (miguel@gnome-support.com)
+ *
+ */
+#include <config.h>
+#include <gnome.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libgnorba/gnome-factory.h>
+#include <libgnorba/gnorba.h>
+#include "calobj.h"
+#include "calendar.h"
+#include "timeutil.h"
+#include "GnomeCal.h"
+#include "pi-source.h"
+#include "pi-socket.h"
+#include "pi-datebook.h"
+#include "pi-dlp.h"
+
+/* the CORBA ORB */
+CORBA_ORB orb;
+
+/* The default port to communicate with */
+char *pilot_port = "/dev/pilot";
+
+CORBA_Environment ev;
+
+struct pi_sockaddr addr;
+
+const struct poptOption calendar_sync_options [] = {
+ { "pilot", 0, POPT_ARG_STRING, &pilot_port, 0,
+ N_("Specifies the port on which the Pilot is"), N_("PORT") },
+ { NULL, '\0', 0, NULL, 0 }
+};
+
+static int
+setup_connection (void)
+{
+ int socket;
+ int ret, news;
+
+ if (!(socket = pi_socket(PI_AF_SLP, PI_SOCK_STREAM, PI_PF_PADP)))
+ g_error (_("Can not create Pilot socket\n"));
+
+ addr.pi_family = PI_AF_SLP;
+ strncpy ((void *) &addr.pi_device, pilot_port, sizeof (addr.pi_device));
+
+ ret = pi_bind (socket, (struct sockaddr *)&addr, sizeof (addr));
+ if (ret == -1)
+ g_error (_("Can not bind to device %s\n"), pilot_port);
+
+ if (pi_listen (socket, 1) == -1)
+ g_error (_("Failed to get a connection from the Pilot device"));
+
+ if ((news = pi_accept (socket, 0, 0)) == -1)
+ g_error (_("pi_accept failed"));
+
+ return news;
+}
+
+static GNOME_Calendar_Repository
+locate_calendar_server (void)
+{
+ GNOME_Calendar_Repository repo;
+ GNOME_stringlist list;
+
+ repo = goad_server_activate_with_id (
+ NULL, "IDL:GNOME:Calendar:Repository:1.0",
+ 0, NULL);
+
+ if (repo == CORBA_OBJECT_NIL)
+ g_error ("Can not communicate with GnomeCalendar server");
+
+ if (ev._major != CORBA_NO_EXCEPTION){
+ printf ("Exception: %s\n", CORBA_exception_id (&ev));
+ abort ();
+ }
+
+ return repo;
+}
+
+static void
+delete_record (GNOME_Calendar_Repository repo, int id)
+{
+ char *uid;
+
+ uid = GNOME_Calendar_Repository_get_id_from_pilot_id (repo, id, &ev);
+
+ /* The record was already deleted */
+ if (ev._major != CORBA_NO_EXCEPTION)
+ return;
+
+ GNOME_Calendar_Repository_delete_object (repo, uid, &ev);
+ CORBA_free (uid);
+}
+
+static void
+update_record (GNOME_Calendar_Repository repo, int id, struct Appointment *a, int attr)
+{
+ char *vcal_string;
+ iCalObject *obj;
+ int i;
+ char *str;
+
+ obj = ical_new (a->note ? a->note : "",
+ g_get_user_name (),
+ a->description ? a->description : "");
+
+ vcal_string = GNOME_Calendar_Repository_get_object_by_pilot_id (repo, id, &ev);
+
+ if (ev._major == CORBA_USER_EXCEPTION){
+ time_t now = time (NULL);
+
+ obj->created = now;
+ obj->last_mod = now;
+ obj->priority = 0;
+ obj->transp = 0;
+ obj->related = NULL;
+ obj->pilot_id = id;
+ obj->pilot_status = ICAL_PILOT_SYNC_NONE;
+ printf (_("Object did not exist, creating a new one"));
+ } else
+ obj = ical_object_new_from_string (vcal_string);
+
+ if (obj->pilot_status == ICAL_PILOT_SYNC_MOD){
+ printf (_("Object has been modified on desktop and on the pilot, desktop takes precedence"));
+ ical_object_destroy (obj);
+ return;
+ }
+
+ /*
+ * Begin and end
+ */
+ obj->dtstart = mktime (&a->begin);
+ obj->dtend = mktime (&a->end);
+
+ /* Special case: daily repetitions are converted to a multi-day event */
+ if (a->repeatType == repeatDaily){
+ time_t newt = time_add_day (obj->dtend, a->repeatFrequency);
+
+ obj->dtend = newt;
+ }
+
+ /*
+ * Alarm
+ */
+ if (a->alarm){
+ obj->aalarm.type = ALARM_AUDIO;
+ obj->aalarm.enabled = 1;
+ obj->aalarm.count = a->advance;
+
+ switch (a->advanceUnits){
+ case advMinutes:
+ obj->aalarm.units = ALARM_MINUTES;
+ break;
+
+ case advHours:
+ obj->aalarm.units = ALARM_HOURS;
+ break;
+
+ case advDays:
+ obj->aalarm.units = ALARM_DAYS;
+ break;
+ default:
+ }
+ }
+
+ /*
+ * Recurrence
+ */
+ if (a->repeatFrequency && a->repeatType != repeatDaily){
+ obj->recur = g_new0 (Recurrence, 1);
+
+ switch (a->repeatType){
+ case repeatDaily:
+ /*
+ * In the Pilot daily repetitions are actually
+ * multi-day events
+ */
+ g_warning ("Should not have got here");
+ break;
+
+ case repeatMonthlyByDate:
+ obj->recur->type = RECUR_MONTHLY_BY_DAY;
+ obj->recur->u.month_day = a->repeatFrequency;
+ break;
+
+ case repeatWeekly:
+ {
+ int wd;
+
+ obj->recur->type = RECUR_WEEKLY;
+ for (wd = 0; wd < 7; wd++)
+ if (a->repeatDays [wd])
+ obj->recur->weekday |= 1 << wd;
+
+ if (obj->recur->weekday == 0){
+ struct tm *tm = localtime (&obj->dtstart);
+
+ obj->recur->weekday = 1 << tm->tm_wday;
+ }
+ break;
+ }
+
+ case repeatMonthlyByDay:
+ obj->recur->type = RECUR_MONTHLY_BY_POS;
+ obj->recur->u.month_pos = a->repeatFrequency;
+ obj->recur->weekday = (a->repeatDay / 7);
+ break;
+
+ case repeatYearly:
+ obj->recur->type = RECUR_YEARLY_BY_DAY;
+ break;
+
+ default:
+ g_warning ("Unhandled repeate case");
+ }
+
+ if (a->repeatForever)
+ obj->recur->duration = 0;
+ else
+ obj->recur->_enddate = mktime (&a->repeatEnd);
+ }
+
+ /*
+ * Load exception dates
+ */
+ obj->exdate = NULL;
+ for (i = 0; i < a->exceptions; i++){
+ time_t *t = g_new (time_t, 1);
+
+ *t = mktime (&(a->exception [i]));
+ obj->exdate = g_list_prepend (obj->exdate, t);
+ }
+
+ g_free (obj->class);
+
+ if (attr & dlpRecAttrSecret)
+ obj->class = g_strdup ("PRIVATE");
+ else
+ obj->class = g_strdup ("PUBLIC");
+
+ /*
+ * Now, convert the in memory iCalObject to a full vCalendar we can send
+ */
+ str = calendar_string_from_object (obj);
+
+ GNOME_Calendar_Repository_update_object (repo, obj->uid, str, &ev);
+
+ free (str);
+
+ /*
+ * Shutdown
+ */
+ ical_object_destroy (obj);
+}
+
+static void
+sync_pilot (GNOME_Calendar_Repository repo, int pilot_fd)
+{
+ struct PilotUser user_info;
+ int db,record;
+ unsigned char buffer [65536];
+
+ printf (_("Syncing with the pilot..."));
+ dlp_ReadUserInfo (pilot_fd, &user_info);
+
+ /* This informs the user of the progress on the Pilot */
+ dlp_OpenConduit (pilot_fd);
+
+ if (dlp_OpenDB (pilot_fd, 0, 0x80 | 0x40, "DatebookDB", &db) < 0){
+ g_warning (_("Could not open DatebookDB on the Pilot"));
+ dlp_AddSyncLogEntry (pilot_fd, _("Unable to open DatebookDB"));
+ pi_close (pilot_fd);
+ exit (1);
+ }
+
+ /*
+ * 1. Pull all the records from the Pilot, and make any updates
+ * required on the desktop side
+ */
+ for (record = 0;; record++){
+ struct Appointment a;
+ int rec_len, attr, size;
+ recordid_t id;
+
+ rec_len = dlp_ReadRecordByIndex (pilot_fd, db, record, buffer, &id, &size, &attr, 0);
+
+ if (rec_len < 0)
+ break;
+
+ printf ("processing record %d\n", record);
+ unpack_Appointment (&a, buffer, rec_len);
+
+ /* If the object was deleted, remove it from the database */
+ if (attr & dlpRecAttrDeleted){
+ delete_record (repo, id);
+ continue;
+ }
+
+ if (attr & dlpRecAttrDirty){
+ printf ("updating record\n");
+ update_record (repo, id, &a, attr);
+ }
+
+ free_Appointment (&a);
+ }
+ /*
+ * 2. Pull all the records from the Calendar, and move any new items
+ * to the pilot
+ */
+ dlp_CloseDB (pilot_fd, db);
+ dlp_AddSyncLogEntry (pilot_fd, _("Synced DateBook from Pilot to GnomeCal"));
+ pi_close (pilot_fd);
+}
+
+int
+main (int argc, char *argv [])
+{
+ int link;
+ GNOME_Calendar_Repository repository;
+
+ CORBA_exception_init (&ev);
+ orb = gnome_CORBA_init_with_popt_table (
+ "calendar-pilot-sync", VERSION, &argc, argv,
+ calendar_sync_options, 0, NULL, 0, &ev);
+
+ printf ("Please, press HotSync button on the palm...");
+ fflush (stdout);
+ link = setup_connection ();
+ printf ("Connected\n");
+
+ printf ("Launching GnomeCal...");
+ fflush (stdout);
+ repository = locate_calendar_server ();
+ printf ("Done\n");
+
+ printf ("Syncing...\n");
+ sync_pilot (repository, link);
+ printf ("Done Syncing\n");
+
+ GNOME_Calendar_Repository_done (repository, &ev);
+
+ CORBA_exception_free (&ev);
+
+ return 0;
+}
+
+/* Just a stub to link with */
+void
+calendar_notify (time_t time, CalendarAlarm *which, void *data)
+{
+}
+
diff --git a/calendar/gui/calendar.c b/calendar/gui/calendar.c
index ff7ae8ee5d..b67f875fdc 100644
--- a/calendar/gui/calendar.c
+++ b/calendar/gui/calendar.c
@@ -4,7 +4,7 @@
* This keeps track of a given calendar. Eventually this will abtract everything
* related to getting calendars/saving calendars locally or to a remote Calendar Service
*
- * Copyright (C) 1998 the Free Software Foundation
+ * Copyright (C) 1998, 1999 the Free Software Foundation
*
* Authors:
* Miguel de Icaza (miguel@gnu.org)
@@ -323,18 +323,14 @@ calendar_load (Calendar *cal, char *fname)
return NULL;
}
-void
-calendar_save (Calendar *cal, char *fname)
+static VObject *
+vcalendar_create_from_calendar (Calendar *cal)
{
VObject *vcal;
GList *l;
time_t now = time (NULL);
- struct stat s;
struct tm *tm;
- if (fname == NULL)
- fname = cal->filename;
-
/* WE call localtime for the side effect of setting tzname */
tm = localtime (&now);
@@ -366,6 +362,19 @@ calendar_save (Calendar *cal, char *fname)
addVObjectProp (vcal, obj);
}
+ return vcal;
+}
+
+void
+calendar_save (Calendar *cal, char *fname)
+{
+ VObject *vcal;
+ struct stat s;
+
+ if (fname == NULL)
+ fname = cal->filename;
+
+ vcal = vcalendar_create_from_calendar (cal);
if (g_file_exists (fname)){
char *backup_name = g_strconcat (fname, "~", NULL);
@@ -375,6 +384,7 @@ calendar_save (Calendar *cal, char *fname)
rename (fname, backup_name);
g_free (backup_name);
}
+
writeVObjectToFile (fname, vcal);
stat (fname, &s);
@@ -384,6 +394,23 @@ calendar_save (Calendar *cal, char *fname)
cleanStrTbl ();
}
+char *
+calendar_get_as_vcal_string (Calendar *cal)
+{
+ VObject *vcal;
+ char *result;
+
+ g_return_val_if_fail (cal != NULL, NULL);
+
+ vcal = vcalendar_create_from_calendar (cal);
+ result = writeMemVObject (NULL, 0, vcal);
+
+ cleanVObject (vcal);
+ cleanStrTbl ();
+
+ return result;
+}
+
static gint
calendar_object_compare_by_start (gconstpointer a, gconstpointer b)
{
@@ -440,6 +467,8 @@ calendar_object_changed (Calendar *cal, iCalObject *obj, int flags)
while (alarm_kill (obj))
;
ical_object_try_alarms (obj);
+
+ obj->pilot_status = ICAL_PILOT_SYNC_MOD;
}
static void
@@ -466,3 +495,99 @@ calendar_init_alarms (Calendar *cal)
alarm_add (&day_change_alarm, calendar_day_change, cal);
}
+static iCalObject *
+calendar_object_find_in_list (Calendar *cal, GList *list, const char *uid)
+{
+ GList *l;
+
+ for (l = list; l; l = l->next){
+ iCalObject *obj = l->data;
+
+ if (strcmp (obj->uid, uid) == 0)
+ return obj;
+ }
+
+ return NULL;
+}
+
+iCalObject *
+calendar_object_find_event (Calendar *cal, const char *uid)
+{
+ g_return_val_if_fail (cal != NULL, NULL);
+ g_return_val_if_fail (uid != NULL, NULL);
+
+ return calendar_object_find_in_list (cal, cal->events, uid);
+}
+
+iCalObject *
+calendar_object_find_todo (Calendar *cal, const char *uid)
+{
+ g_return_val_if_fail (cal != NULL, NULL);
+ g_return_val_if_fail (uid != NULL, NULL);
+
+ return calendar_object_find_in_list (cal, cal->todo, uid);
+}
+
+iCalObject *
+calendar_object_find (Calendar *cal, const char *uid)
+{
+ iCalObject *obj;
+
+ g_return_val_if_fail (cal != NULL, NULL);
+ g_return_val_if_fail (uid != NULL, NULL);
+
+ obj = calendar_object_find_in_list (cal, cal->todo, uid);
+
+ if (obj == NULL)
+ obj = calendar_object_find_in_list (cal, cal->events, uid);
+
+ return obj;
+}
+
+iCalObject *
+calendar_object_find_by_pilot (Calendar *cal, int pilot_id)
+{
+ GList *l;
+
+ g_return_val_if_fail (cal != NULL, NULL);
+
+ for (l = cal->events; l; l = l->next){
+ iCalObject *obj = l->data;
+
+ if (obj->pilot_id == pilot_id)
+ return obj;
+ }
+
+ for (l = cal->todo; l; l = l->next){
+ iCalObject *obj = l->data;
+
+ if (obj->pilot_id == pilot_id)
+ return obj;
+ }
+
+ return NULL;
+}
+
+/*
+ * calendar_string_from_object:
+ *
+ * Returns the iCalObject @object armored around a vCalendar
+ * object as a string.
+ */
+char *
+calendar_string_from_object (iCalObject *object)
+{
+ Calendar *cal;
+ char *str;
+
+ g_return_val_if_fail (object != NULL, NULL);
+
+ cal = calendar_new ("Temporal");
+ calendar_add_object (cal, object);
+ str = calendar_get_as_vcal_string (cal);
+ calendar_remove_object (cal, object);
+
+ calendar_destroy (cal);
+
+ return str;
+}
diff --git a/calendar/gui/calendar.h b/calendar/gui/calendar.h
index 8dc0c517c3..2ea2753057 100644
--- a/calendar/gui/calendar.h
+++ b/calendar/gui/calendar.h
@@ -26,6 +26,8 @@ typedef struct {
/* If the calendar was last modified */
int modified;
void *temp;
+
+ void *corba_server;
} Calendar;
/* This is only used by the calendar_get_events_in_range routine to get
@@ -38,6 +40,9 @@ typedef struct {
} CalendarObject;
Calendar *calendar_new (char *title);
+char *calendar_get_as_vcal_string (Calendar *cal);
+char *calendar_string_from_object (iCalObject *object);
+
char *calendar_load (Calendar *cal, char *fname);
void calendar_save (Calendar *cal, char *fname);
void calendar_add_object (Calendar *cal, iCalObject *obj);
@@ -63,6 +68,12 @@ void calendar_destroy_event_list (GList *l);
void calendar_object_changed (Calendar *cal, iCalObject *obj, int flags);
void calendar_notify (time_t time, CalendarAlarm *which, void *data);
+
+iCalObject *calendar_object_find_event (Calendar *cal, const char *uid);
+iCalObject *calendar_object_find_todo (Calendar *cal, const char *uid);
+iCalObject *calendar_object_find (Calendar *cal, const char *uid);
+iCalObject *calendar_object_find_by_pilot (Calendar *cal, int pilot_id);
+
END_GNOME_DECLS
#endif
diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c
index 86900dd343..1b6c80e236 100644
--- a/calendar/gui/gnome-cal.c
+++ b/calendar/gui/gnome-cal.c
@@ -226,6 +226,8 @@ gnome_calendar_new (char *title)
gcal->current_display = time_day_begin (time (NULL));
gcal->cal = calendar_new (title);
setup_widgets (gcal);
+ gnome_calendar_create_corba_server (gcal);
+
return retval;
}
diff --git a/calendar/gui/gnome-cal.h b/calendar/gui/gnome-cal.h
index ae4e5292da..da53f29882 100644
--- a/calendar/gui/gnome-cal.h
+++ b/calendar/gui/gnome-cal.h
@@ -63,6 +63,8 @@ void gnome_calendar_object_changed (GnomeCalendar *gcal,
iCalObject *obj,
int flags);
+GnomeCalendar *gnome_calendar_locate (const char *pathname);
+
/* Notifies the calendar that the time format has changed and it must update all its views */
void gnome_calendar_time_format_changed (GnomeCalendar *gcal);
diff --git a/calendar/gui/main.c b/calendar/gui/main.c
index 2167d026f3..7a1888898b 100644
--- a/calendar/gui/main.c
+++ b/calendar/gui/main.c
@@ -9,6 +9,7 @@
#include <config.h>
#include <gnome.h>
+#include <libgnorba/gnorba.h>
#include <pwd.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -20,7 +21,7 @@
#include "gnome-cal.h"
#include "main.h"
#include "timeutil.h"
-
+#include "corba-cal-factory.h"
#define COOKIE_USER_HOME_DIR ((char *) -1)
@@ -66,8 +67,6 @@ int active_calendars = 0;
/* A list of all of the calendars started */
GList *all_calendars = NULL;
-static void new_calendar (char *full_name, char *calendar_file, char *geometry, char *view, gboolean hidden);
-
/* For dumping part of a calendar */
static time_t from_t, to_t;
@@ -203,10 +202,29 @@ display_objedit_today (GtkWidget *widget, GnomeCalendar *gcal)
gtk_widget_show (ee);
}
+GnomeCalendar *
+gnome_calendar_locate (const char *pathname)
+{
+ GList *l;
+
+ if (pathname == NULL || pathname [0] == 0)
+ pathname = user_calendar_file;
+
+ for (l = all_calendars; l; l = l->next){
+ GnomeCalendar *gcal = l->data;
+
+ if (strcmp (gcal->cal->filename, pathname) == 0){
+ return gcal;
+ }
+ }
+ return NULL;
+}
+
static void
close_cmd (GtkWidget *widget, GnomeCalendar *gcal)
{
all_calendars = g_list_remove (all_calendars, gcal);
+
if (gcal->cal->modified){
if (!gcal->cal->filename)
save_calendar_cmd (widget, gcal);
@@ -217,8 +235,10 @@ close_cmd (GtkWidget *widget, GnomeCalendar *gcal)
gtk_widget_destroy (GTK_WIDGET (gcal));
active_calendars--;
- if (active_calendars == 0)
+ if (active_calendars == 0){
+ unregister_calendar_services ();
gtk_main_quit ();
+ }
}
void
@@ -551,7 +571,7 @@ calendar_close_event (GtkWidget *widget, GdkEvent *event, GnomeCalendar *gcal)
return TRUE;
}
-static void
+GnomeCalendar *
new_calendar (char *full_name, char *calendar_file, char *geometry, char *page, gboolean hidden)
{
GtkWidget *toplevel;
@@ -559,7 +579,8 @@ new_calendar (char *full_name, char *calendar_file, char *geometry, char *page,
int xpos, ypos, width, height;
/* i18n: This "%s%s" indicates possession. Languages where the order is
- the inverse should translate it to "%2$s%1$s". */
+ * the inverse should translate it to "%2$s%1$s".
+ */
g_snprintf(title, 128, _("%s%s"), full_name, _("'s calendar"));
toplevel = gnome_calendar_new (title);
@@ -606,6 +627,8 @@ new_calendar (char *full_name, char *calendar_file, char *geometry, char *page,
}
gtk_widget_show (toplevel);
+
+ return GNOME_CALENDAR (toplevel);
}
static void
@@ -839,13 +862,23 @@ int
main(int argc, char *argv[])
{
GnomeClient *client;
+ CORBA_Environment ev;
bindtextdomain (PACKAGE, GNOMELOCALEDIR);
textdomain (PACKAGE);
- gnome_init_with_popt_table ("calendar", VERSION, argc, argv,
- options, 0, NULL);
+ CORBA_exception_init (&ev);
+
+ gnome_CORBA_init_with_popt_table (
+ "calendar", VERSION, &argc, argv,
+ options, 0, NULL, GNORBA_INIT_SERVER_FUNC, &ev);
+ orb = gnome_CORBA_ORB ();
+ poa = (PortableServer_POA)CORBA_ORB_resolve_initial_references (orb, "RootPOA", &ev);
+ if (ev._major == CORBA_NO_EXCEPTION){
+ init_corba_server ();
+ }
+
if (show_events)
dump_events ();
if (show_todo)
diff --git a/calendar/gui/main.h b/calendar/gui/main.h
index 96ffcaf33d..584ce2e83c 100644
--- a/calendar/gui/main.h
+++ b/calendar/gui/main.h
@@ -75,4 +75,7 @@ char *color_spec_from_prop (ColorProp propnum);
void save_default_calendar (GnomeCalendar *gcal);
+GnomeCalendar *new_calendar (char *full_name, char *calendar_file,
+ char *geometry, char *page, gboolean hidden);
+
#endif
diff --git a/calendar/main.c b/calendar/main.c
index 2167d026f3..7a1888898b 100644
--- a/calendar/main.c
+++ b/calendar/main.c
@@ -9,6 +9,7 @@
#include <config.h>
#include <gnome.h>
+#include <libgnorba/gnorba.h>
#include <pwd.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -20,7 +21,7 @@
#include "gnome-cal.h"
#include "main.h"
#include "timeutil.h"
-
+#include "corba-cal-factory.h"
#define COOKIE_USER_HOME_DIR ((char *) -1)
@@ -66,8 +67,6 @@ int active_calendars = 0;
/* A list of all of the calendars started */
GList *all_calendars = NULL;
-static void new_calendar (char *full_name, char *calendar_file, char *geometry, char *view, gboolean hidden);
-
/* For dumping part of a calendar */
static time_t from_t, to_t;
@@ -203,10 +202,29 @@ display_objedit_today (GtkWidget *widget, GnomeCalendar *gcal)
gtk_widget_show (ee);
}
+GnomeCalendar *
+gnome_calendar_locate (const char *pathname)
+{
+ GList *l;
+
+ if (pathname == NULL || pathname [0] == 0)
+ pathname = user_calendar_file;
+
+ for (l = all_calendars; l; l = l->next){
+ GnomeCalendar *gcal = l->data;
+
+ if (strcmp (gcal->cal->filename, pathname) == 0){
+ return gcal;
+ }
+ }
+ return NULL;
+}
+
static void
close_cmd (GtkWidget *widget, GnomeCalendar *gcal)
{
all_calendars = g_list_remove (all_calendars, gcal);
+
if (gcal->cal->modified){
if (!gcal->cal->filename)
save_calendar_cmd (widget, gcal);
@@ -217,8 +235,10 @@ close_cmd (GtkWidget *widget, GnomeCalendar *gcal)
gtk_widget_destroy (GTK_WIDGET (gcal));
active_calendars--;
- if (active_calendars == 0)
+ if (active_calendars == 0){
+ unregister_calendar_services ();
gtk_main_quit ();
+ }
}
void
@@ -551,7 +571,7 @@ calendar_close_event (GtkWidget *widget, GdkEvent *event, GnomeCalendar *gcal)
return TRUE;
}
-static void
+GnomeCalendar *
new_calendar (char *full_name, char *calendar_file, char *geometry, char *page, gboolean hidden)
{
GtkWidget *toplevel;
@@ -559,7 +579,8 @@ new_calendar (char *full_name, char *calendar_file, char *geometry, char *page,
int xpos, ypos, width, height;
/* i18n: This "%s%s" indicates possession. Languages where the order is
- the inverse should translate it to "%2$s%1$s". */
+ * the inverse should translate it to "%2$s%1$s".
+ */
g_snprintf(title, 128, _("%s%s"), full_name, _("'s calendar"));
toplevel = gnome_calendar_new (title);
@@ -606,6 +627,8 @@ new_calendar (char *full_name, char *calendar_file, char *geometry, char *page,
}
gtk_widget_show (toplevel);
+
+ return GNOME_CALENDAR (toplevel);
}
static void
@@ -839,13 +862,23 @@ int
main(int argc, char *argv[])
{
GnomeClient *client;
+ CORBA_Environment ev;
bindtextdomain (PACKAGE, GNOMELOCALEDIR);
textdomain (PACKAGE);
- gnome_init_with_popt_table ("calendar", VERSION, argc, argv,
- options, 0, NULL);
+ CORBA_exception_init (&ev);
+
+ gnome_CORBA_init_with_popt_table (
+ "calendar", VERSION, &argc, argv,
+ options, 0, NULL, GNORBA_INIT_SERVER_FUNC, &ev);
+ orb = gnome_CORBA_ORB ();
+ poa = (PortableServer_POA)CORBA_ORB_resolve_initial_references (orb, "RootPOA", &ev);
+ if (ev._major == CORBA_NO_EXCEPTION){
+ init_corba_server ();
+ }
+
if (show_events)
dump_events ();
if (show_todo)
diff --git a/calendar/main.h b/calendar/main.h
index 96ffcaf33d..584ce2e83c 100644
--- a/calendar/main.h
+++ b/calendar/main.h
@@ -75,4 +75,7 @@ char *color_spec_from_prop (ColorProp propnum);
void save_default_calendar (GnomeCalendar *gcal);
+GnomeCalendar *new_calendar (char *full_name, char *calendar_file,
+ char *geometry, char *page, gboolean hidden);
+
#endif
diff --git a/calendar/pcs/calobj.c b/calendar/pcs/calobj.c
index 2618470808..08c8d8c63a 100644
--- a/calendar/pcs/calobj.c
+++ b/calendar/pcs/calobj.c
@@ -47,6 +47,9 @@ ical_object_new (void)
ico->seq = -1;
ico->dtstamp = time (NULL);
ico->uid = ical_gen_uid ();
+
+ ico->pilot_id = 0;
+ ico->pilot_status = ICAL_PILOT_SYNC_MOD;
return ico;
}
@@ -372,6 +375,8 @@ 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);
}
@@ -782,6 +787,22 @@ ical_object_create_from_vobject (VObject *o, const char *object_name)
}
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;
}
@@ -1047,6 +1068,17 @@ ical_object_to_vobject (iCalObject *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;
}
@@ -1426,3 +1458,33 @@ alarm_compute_offset (CalendarAlarm *a)
}
return a->offset;
}
+
+iCalObject *
+ical_object_new_from_string (const char *vcal_string)
+{
+ iCalObject *ical = NULL;
+ VObject *cal, *event;
+ VObjectIterator i;
+ char *object_name;
+
+ cal = Parse_MIME (vcal_string, strlen (vcal_string));
+
+ initPropIterator (&i, cal);
+
+ while (moreIteration (&i)){
+ event = nextVObject (&i);
+
+ object_name = vObjectName (event);
+
+ if (strcmp (object_name, VCEventProp) == 0){
+ ical = ical_object_create_from_vobject (event, object_name);
+ break;
+ }
+ }
+
+ cleanVObject (cal);
+ cleanStrTbl ();
+
+ return ical;
+}
+
diff --git a/calendar/pcs/calobj.h b/calendar/pcs/calobj.h
index 9532b1325f..07ba3f1cc7 100644
--- a/calendar/pcs/calobj.h
+++ b/calendar/pcs/calobj.h
@@ -65,6 +65,12 @@ typedef struct {
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;
@@ -172,6 +178,10 @@ typedef struct {
int new;
void *user_data; /* Generic data pointer */
+
+ /* Pilot */
+ int pilot_status; /* Status information */
+ int pilot_id; /* Pilot ID */
} iCalObject;
/* The callback for the recurrence generator */
@@ -179,6 +189,7 @@ typedef int (*calendarfn) (iCalObject *, time_t, time_t, void *);
iCalObject *ical_new (char *comment, char *organizer, char *summary);
iCalObject *ical_object_new (void);
+iCalObject *ical_object_new_from_string (const char *vcalendar_string);
void ical_object_destroy (iCalObject *ico);
iCalObject *ical_object_create_from_vobject (VObject *obj, const char *object_name);
VObject *ical_object_to_vobject (iCalObject *ical);