/* $Id$ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "GnomeCal.h" #include "calobj.h" #include "calendar.h" #include "timeutil.h" #include "calendar-conduit.h" GnomePilotConduit * conduit_get_gpilot_conduit (guint32); void conduit_destroy_gpilot_conduit (GnomePilotConduit*); typedef struct _ConduitData ConduitData; struct _ConduitData { struct AppointmentAppInfo ai; Calendar *cal; }; #define GET_DATA(c) ((ConduitData*)gtk_object_get_data(GTK_OBJECT(c),"conduit_data")) GNOME_Calendar_Repository calendar; CORBA_Environment ev; CORBA_ORB orb; static GNOME_Calendar_Repository calendar_server (void) { int n =0; calendar = goad_server_activate_with_id (NULL, "IDL:GNOME:Calendar:Repository:1.0", 0, NULL); if (calendar == 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)); return CORBA_OBJECT_NIL; } return calendar; } /* Just a stub to link with */ void calendar_notify (time_t time, CalendarAlarm *which, void *data) { } /* Code blatantly stolen from * calendar-pilot-sync.c: * * (C) 1999 International GNOME Support * * Author: * Miguel de Icaza (miguel@gnome-support.com) * */ static void update_record (PilotRecord *remote) { char *vcal_string; iCalObject *obj; int i; char *str; struct Appointment a; g_return_if_fail(remote!=NULL); unpack_Appointment(&a,remote->record,remote->length); obj = ical_new (a.note ? a.note : "", g_get_user_name (), a.description ? a.description : ""); printf ("requesting %d [%s]\n", remote->ID, a.description); vcal_string = GNOME_Calendar_Repository_get_object_by_pilot_id (calendar, remote->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 = remote->ID; obj->pilot_status = ICAL_PILOT_SYNC_NONE; printf (_("\tObject did not exist, creating a new one\n")); } else if(ev._major != CORBA_NO_EXCEPTION) { printf(_("\tError while communicating with calendar server\n")); printf("\texception id = %s\n",CORBA_exception_id(&ev)); CORBA_exception_free(&ev); ical_object_destroy (obj); return; } else { printf ("\tFound\n"); ical_object_destroy (obj); obj = ical_object_new_from_string (vcal_string); } if (obj->pilot_status == ICAL_PILOT_SYNC_MOD){ printf (_("\tObject has been modified on desktop and on the pilot, desktop takes precedence\n")); ical_object_destroy (obj); return; } /* * Begin and end */ if (a.event) { /* turn day-long events into a full day's appointment */ a.begin.tm_sec = 0; a.begin.tm_min = 0; a.begin.tm_hour = 6; a.end.tm_sec = 0; a.end.tm_min = 0; a.end.tm_hour = 10; } 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 (remote->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 (calendar, obj->uid, str, &ev); free (str); /* * Shutdown */ ical_object_destroy (obj); } static gint load_records(GnomePilotConduit *c) { char *vcalendar_string; char *error; ConduitData *cd; vcalendar_string = GNOME_Calendar_Repository_get_updated_objects (calendar, &ev); cd = GET_DATA(c); g_assert(cd!=NULL); cd->cal = calendar_new("Temporary"); error = calendar_load_from_memory(cd->cal,vcalendar_string); return 0; } static gint pre_sync(GnomePilotConduit *c, GnomePilotDBInfo *dbi) { int l; unsigned char *buf; calendar = CORBA_OBJECT_NIL; calendar = calendar_server(); if(calendar == CORBA_OBJECT_NIL) { return 0; } gtk_object_set_data(GTK_OBJECT(c),"dbinfo",dbi); load_records(c); buf = (unsigned char*)g_malloc(0xffff); if((l=dlp_ReadAppBlock(dbi->pilot_socket,dbi->db_handle,0,(unsigned char *)buf,0xffff))<0) { return 0; } unpack_AppointmentAppInfo(&(GET_DATA(c)->ai),buf,l); g_free(buf); return 1; } static gint match_record (GnomePilotConduitStandardAbs *pilot_conduit_standard_abs, LocalRecord **local, PilotRecord *remote, gpointer data) { g_return_val_if_fail(remote!=NULL,0); g_print ("in match_record\n"); *local = NULL; return 1; } static gint free_match (GnomePilotConduitStandardAbs *pilot_conduit_standard_abs, LocalRecord **local, gpointer data) { g_print ("entering free_match\n"); *local = NULL; return 0; } static gint archive_local (GnomePilotConduitStandardAbs *pilot_conduit_standard_abs, LocalRecord *local, gpointer data) { g_print ("entering archive_local\n"); return 1; } static gint archive_remote (GnomePilotConduitStandardAbs *pilot_conduit_standard_abs, LocalRecord *local, PilotRecord *remote, gpointer data) { g_print ("entering archive_remote\n"); return 1; } static gint store_remote (GnomePilotConduitStandardAbs *pilot_conduit_standard_abs, PilotRecord *remote, gpointer data) { g_print ("entering store_remote\n"); g_return_val_if_fail(remote!=NULL,0); update_record(remote); return 1; } static gint clear_status_archive_local (GnomePilotConduitStandardAbs *pilot_conduit_standard_abs, LocalRecord *local, gpointer data) { g_print ("entering clear_status_archive_local\n"); return 1; } static gint iterate (GnomePilotConduitStandardAbs *pilot_conduit_standard_abs, LocalRecord **local, gpointer data) { g_print ("entering iterate\n"); return 1; } static gint iterate_specific (GnomePilotConduitStandardAbs *pilot_conduit_standard_abs, LocalRecord **local, gint flag, gint archived, gpointer data) { g_print ("entering iterate_specific\n"); return 1; } static gint purge (GnomePilotConduitStandardAbs *pilot_conduit_standard_abs, gpointer data) { g_print ("entering purge\n"); return 1; } static gint set_status (GnomePilotConduitStandardAbs *pilot_conduit_standard_abs, LocalRecord *local, gint status, gpointer data) { g_print ("entering set_status\n"); return 0; } static gint set_archived (GnomePilotConduitStandardAbs *pilot_conduit_standard_abs, LocalRecord *local, gint archived, gpointer data) { g_print ("entering set_archived\n"); return 1; } static gint set_pilot_id (GnomePilotConduitStandardAbs *pilot_conduit_standard_abs, LocalRecord *local, guint32 ID, gpointer data) { g_print ("entering set_pilot_id\n"); return 1; } static gint compare (GnomePilotConduitStandardAbs *pilot_conduit_standard_abs, LocalRecord *local, PilotRecord *remote, gpointer data) { g_print ("entering compare\n"); return 1; } static gint compare_backup (GnomePilotConduitStandardAbs *pilot_conduit_standard_abs, LocalRecord *local, PilotRecord *remote, gpointer data) { g_print ("entering compare_backup\n"); return 1; } static gint free_transmit (GnomePilotConduitStandardAbs *pilot_conduit_standard_abs, LocalRecord *local, PilotRecord *remote, gpointer data) { g_print ("entering free_transmit\n"); return 1; } static gint delete_all (GnomePilotConduitStandardAbs *pilot_conduit_standard_abs, gpointer data) { g_print ("entering delete_all\n"); return 1; } static PilotRecord * transmit (GnomePilotConduitStandardAbs *pilot_conduit_standard_abs, LocalRecord *local, gpointer data) { g_print ("entering transmit\n"); return NULL; } GnomePilotConduit * conduit_get_gpilot_conduit (guint32 pilotId) { GtkObject *retval; ConduitCfg *cfg; ConduitData *cdata; CORBA_exception_init (&ev); retval = gnome_pilot_conduit_standard_abs_new ("DatebookDB", 0x64617465); g_assert (retval != NULL); gnome_pilot_conduit_construct(GNOME_PILOT_CONDUIT(retval),"calendar"); cfg = g_new0(ConduitCfg,1); g_assert(cfg != NULL); gtk_object_set_data(retval,"conduit_cfg",cfg); cdata = g_new0(ConduitData,1); g_assert(cdata != NULL); gtk_object_set_data(retval,"conduit_data",cdata); gtk_signal_connect (retval, "match_record", (GtkSignalFunc) match_record, NULL); gtk_signal_connect (retval, "free_match", (GtkSignalFunc) free_match, NULL); gtk_signal_connect (retval, "archive_local", (GtkSignalFunc) archive_local, NULL); gtk_signal_connect (retval, "archive_remote", (GtkSignalFunc) archive_remote, NULL); gtk_signal_connect (retval, "store_remote", (GtkSignalFunc) store_remote, NULL); gtk_signal_connect (retval, "clear_status_archive_local", (GtkSignalFunc) clear_status_archive_local, NULL); gtk_signal_connect (retval, "iterate", (GtkSignalFunc) iterate, NULL); gtk_signal_connect (retval, "iterate_specific", (GtkSignalFunc) iterate_specific, NULL); gtk_signal_connect (retval, "purge", (GtkSignalFunc) purge, NULL); gtk_signal_connect (retval, "set_status", (GtkSignalFunc) set_status, NULL); gtk_signal_connect (retval, "set_archived", (GtkSignalFunc) set_archived, NULL); gtk_signal_connect (retval, "set_pilot_id", (GtkSignalFunc) set_pilot_id, NULL); gtk_signal_connect (retval, "compare", (GtkSignalFunc) compare, NULL); gtk_signal_connect (retval, "compare_backup", (GtkSignalFunc) compare_backup, NULL); gtk_signal_connect (retval, "free_transmit", (GtkSignalFunc) free_transmit, NULL); gtk_signal_connect (retval, "delete_all", (GtkSignalFunc) delete_all, NULL); gtk_signal_connect (retval, "transmit", (GtkSignalFunc) transmit, NULL); gtk_signal_connect (retval, "pre_sync", (GtkSignalFunc) pre_sync, NULL); load_configuration(&cfg,pilotId); return GNOME_PILOT_CONDUIT (retval); } void conduit_destroy_gpilot_conduit (GnomePilotConduit *conduit) { ConduitCfg *cc; ConduitData *cd; GNOME_Calendar_Repository_done (calendar, &ev); cc = GET_CONFIG(conduit); destroy_configuration(&cc); cd = GET_DATA(conduit); if(cd->cal!=NULL) calendar_destroy(cd->cal); gtk_object_destroy (GTK_OBJECT (conduit)); }