diff options
Diffstat (limited to 'calendar/conduits/todo')
-rw-r--r-- | calendar/conduits/todo/todo-conduit-control-applet.c | 265 | ||||
-rw-r--r-- | calendar/conduits/todo/todo-conduit.c | 1106 | ||||
-rw-r--r-- | calendar/conduits/todo/todo-conduit.h | 101 |
3 files changed, 1167 insertions, 305 deletions
diff --git a/calendar/conduits/todo/todo-conduit-control-applet.c b/calendar/conduits/todo/todo-conduit-control-applet.c index c37f75144a..f1a852fa0b 100644 --- a/calendar/conduits/todo/todo-conduit-control-applet.c +++ b/calendar/conduits/todo/todo-conduit-control-applet.c @@ -1,4 +1,7 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* Control applet ("capplet") for the gnome-pilot todo conduit, */ +/* based on */ +/* gpilotd control applet ('capplet') for use with the GNOME control center */ #include <pwd.h> #include <sys/types.h> @@ -14,6 +17,7 @@ #include "todo-conduit.h" + /* tell changes callbacks to ignore changes or not */ static gboolean ignore_changes=FALSE; @@ -28,85 +32,109 @@ GtkWidget *dialogWindow=NULL; gboolean activated,org_activation_state; GnomePilotConduitManagement *conduit; GnomePilotConduitConfig *conduit_config; -ConduitCfg *origState = NULL; -ConduitCfg *curState = NULL; +GCalConduitCfg *origState = NULL; +GCalConduitCfg *curState = NULL; -static void doTrySettings(GtkWidget *widget, ConduitCfg *conduitCfg); -static void doRevertSettings(GtkWidget *widget, ConduitCfg *conduitCfg); -static void doSaveSettings(GtkWidget *widget, ConduitCfg *conduitCfg); +static void doTrySettings(GtkWidget *widget, GCalConduitCfg *GCalConduitCfg); +static void doRevertSettings(GtkWidget *widget, GCalConduitCfg *GCalConduitCfg); +static void doSaveSettings(GtkWidget *widget, GCalConduitCfg *GCalConduitCfg); -static void readStateCfg(GtkWidget *w); -static void setStateCfg(GtkWidget *w); +//static void readStateCfg (GtkWidget *w, GCalConduitCfg *c); +static void setStateCfg (GtkWidget *w, GCalConduitCfg *c); gint pilotId; CORBA_Environment ev; static GnomePilotClient *gpc; -#if 0 -static void -load_configuration(ConduitCfg **c, - guint32 pilotId) -{ - g_assert(c!=NULL); - *c = g_new0(ConduitCfg,1); - (*c)->pilotId = pilotId; -} -#endif /* 0 */ -#if 0 +/* This array must be in the same order as enumerations + in GnomePilotConduitSyncType as they are used as index. + Custom type implies Disabled state. +*/ +static gchar* sync_options[] ={ N_("Disabled"), + N_("Synchronize"), + N_("Copy From Pilot"), + N_("Copy To Pilot"), + N_("Merge From Pilot"), + N_("Merge To Pilot")}; +#define SYNC_OPTIONS_COUNT 6 + + + + +/* Saves the configuration data. */ static void -save_configuration(ConduitCfg *c) +gcalconduit_save_configuration(GCalConduitCfg *c) { - g_return_if_fail(c!=NULL); -} -#endif /* 0 */ + gchar prefix[256]; + g_snprintf(prefix,255,"/gnome-pilot.d/todo-conduit/Pilot_%u/",c->pilotId); -static ConduitCfg* -dupe_configuration(ConduitCfg *c) { - ConduitCfg *retval; + gnome_config_push_prefix(prefix); + gnome_config_set_bool ("open_secret", c->open_secret); + gnome_config_pop_prefix(); + + gnome_config_sync(); + gnome_config_drop_all(); +} + +/* Creates a duplicate of the configuration data */ +static GCalConduitCfg* +gcalconduit_dupe_configuration(GCalConduitCfg *c) { + GCalConduitCfg *retval; g_return_val_if_fail(c!=NULL,NULL); - retval = g_new0(ConduitCfg,1); + retval = g_new0(GCalConduitCfg,1); + retval->sync_type = c->sync_type; + retval->open_secret = c->open_secret; retval->pilotId = c->pilotId; return retval; } -#if 0 -/** this method frees all data from the conduit config */ -static void -destroy_configuration(ConduitCfg **c) + +static void +doTrySettings(GtkWidget *widget, GCalConduitCfg *c) { - g_return_if_fail(c!=NULL); - g_return_if_fail(*c!=NULL); - g_free(*c); - *c = NULL; + /* + readStateCfg (cfgStateWindow, curState); + if (activated) + gnome_pilot_conduit_config_enable (conduit_config, GnomePilotConduitSyncTypeCustom); + else + gnome_pilot_conduit_config_disable (conduit_config); + */ + + if (c->sync_type!=GnomePilotConduitSyncTypeCustom) + gnome_pilot_conduit_config_enable_with_first_sync (conduit_config, + c->sync_type, + c->sync_type, + TRUE); + else + gnome_pilot_conduit_config_disable (conduit_config); + + gcalconduit_save_configuration (c); } -#endif /* 0 */ + static void -doTrySettings(GtkWidget *widget, ConduitCfg *conduitCfg) +doSaveSettings(GtkWidget *widget, GCalConduitCfg *GCalConduitCfg) { - readStateCfg(cfgStateWindow); - if(activated) - gnome_pilot_conduit_config_enable(conduit_config,GnomePilotConduitSyncTypeCustom); - else - gnome_pilot_conduit_config_disable(conduit_config); + doTrySettings(widget, GCalConduitCfg); + gcalconduit_save_configuration(GCalConduitCfg); } + static void -doSaveSettings(GtkWidget *widget, ConduitCfg *conduitCfg) +doCancelSettings(GtkWidget *widget, GCalConduitCfg *c) { - doTrySettings(widget, conduitCfg); - save_configuration(conduitCfg); + doSaveSettings (widget, c); } static void -doRevertSettings(GtkWidget *widget, ConduitCfg *conduitCfg) +doRevertSettings(GtkWidget *widget, GCalConduitCfg *GCalConduitCfg) { activated = org_activation_state; - setStateCfg(cfgStateWindow); + setStateCfg (cfgStateWindow, curState); } static void @@ -115,77 +143,110 @@ about_cb (GtkWidget *widget, gpointer data) GtkWidget *about; const gchar *authors[] = {_("Eskil Heyn Olsen <deity@eskil.dk>"),NULL}; - about = gnome_about_new(_("Gpilotd todo conduit"), VERSION, - _("(C) 1998 the Free Software Foundation"), - authors, - _("Configuration utility for the todo conduit.\n"), - _("gnome-unknown.xpm")); + about = gnome_about_new (_("Gpilotd todo conduit"), VERSION, + _("(C) 1998 the Free Software Foundation"), + authors, + _("Configuration utility for the todo conduit.\n"), + _("gnome-unknown.xpm")); gtk_widget_show (about); return; } -static void toggled_cb(GtkWidget *widget, gpointer data) { - if(!ignore_changes) { - /* gtk_widget_set_sensitive(cfgOptionsWindow,GTK_TOGGLE_BUTTON(widget)->active); */ - capplet_widget_state_changed(CAPPLET_WIDGET(capplet), TRUE); + +/* called by the sync_type GtkOptionMenu */ +static void +sync_action_selection(GtkMenuShell *widget, gpointer unused) +{ + if (!ignore_changes) { + capplet_widget_state_changed(CAPPLET_WIDGET (capplet), TRUE); } } + +/* called by the sync_type GtkOptionMenu */ +static void +activate_sync_type(GtkMenuItem *widget, gpointer data) +{ + curState->sync_type = GPOINTER_TO_INT(data); + if(!ignore_changes) + capplet_widget_state_changed(CAPPLET_WIDGET(capplet), TRUE); +} + + static GtkWidget *createStateCfgWindow(void) { GtkWidget *vbox, *table; GtkWidget *label; - GtkWidget *button; - + GtkWidget *optionMenu,*menuItem; + GtkMenu *menu; + gint i; + vbox = gtk_vbox_new(FALSE, GNOME_PAD); - table = gtk_table_new(2, 2, FALSE); - gtk_table_set_row_spacings(GTK_TABLE(table), 4); - gtk_table_set_col_spacings(GTK_TABLE(table), 10); + table = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, GNOME_PAD); - label = gtk_label_new(_("Enabled")); - gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 1,2); + label = gtk_label_new(_("Synchronize Action")); + gtk_box_pack_start(GTK_BOX(table), label, FALSE, FALSE, GNOME_PAD); + + optionMenu=gtk_option_menu_new(); + gtk_object_set_data(GTK_OBJECT(vbox), "conduit_state", optionMenu); + menu = GTK_MENU(gtk_menu_new()); + + for (i=0; i<SYNC_OPTIONS_COUNT;i++) { + sync_options[i]=_(sync_options[i]); + menuItem = gtk_menu_item_new_with_label(sync_options[i]); + gtk_widget_show(menuItem); + gtk_signal_connect(GTK_OBJECT(menuItem),"activate", + GTK_SIGNAL_FUNC(activate_sync_type), + GINT_TO_POINTER(i)); + gtk_menu_append(menu,menuItem); + } - button = gtk_check_button_new(); - gtk_object_set_data(GTK_OBJECT(vbox), "conduit_on_off", button); - gtk_signal_connect(GTK_OBJECT(button), "toggled", - GTK_SIGNAL_FUNC(toggled_cb), + gtk_option_menu_set_menu(GTK_OPTION_MENU(optionMenu),GTK_WIDGET(menu)); + gtk_signal_connect(GTK_OBJECT(menu), "selection-done", + GTK_SIGNAL_FUNC(sync_action_selection), NULL); - gtk_table_attach_defaults(GTK_TABLE(table), button, 1, 2, 1,2); - + + gtk_box_pack_start(GTK_BOX(table), optionMenu, FALSE, FALSE, 0); + return vbox; } + static void -setStateCfg(GtkWidget *cfg) +setStateCfg (GtkWidget *w, GCalConduitCfg *c) { - GtkWidget *button; - - button = gtk_object_get_data(GTK_OBJECT(cfg), "conduit_on_off"); - - g_assert(button!=NULL); - + GtkOptionMenu *optionMenu; + GtkMenu *menu; + + optionMenu = gtk_object_get_data (GTK_OBJECT(w), "conduit_state"); + g_assert (optionMenu != NULL); + menu = GTK_MENU (gtk_option_menu_get_menu (optionMenu)); + ignore_changes = TRUE; - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button),activated); - /* gtk_widget_set_sensitive(cfgOptionsWindow,GTK_TOGGLE_BUTTON(button)->active); */ + /* Here were are relying on the items in menu being the same + order as in GnomePilotConduitSyncType. */ + gtk_option_menu_set_history (optionMenu, (int) c->sync_type); ignore_changes = FALSE; } +#if 0 static void -readStateCfg(GtkWidget *cfg) +readStateCfg (GtkWidget *w, GCalConduitCfg *c) { + /* GtkWidget *button; - button = gtk_object_get_data(GTK_OBJECT(cfg), "conduit_on_off"); - g_assert(button!=NULL); - activated = GTK_TOGGLE_BUTTON(button)->active; + */ } +#endif /* 0 */ + static void pilot_capplet_setup(void) @@ -210,15 +271,18 @@ pilot_capplet_setup(void) GTK_SIGNAL_FUNC(doRevertSettings), curState); gtk_signal_connect(GTK_OBJECT(capplet), "ok", GTK_SIGNAL_FUNC(doSaveSettings), curState); + gtk_signal_connect(GTK_OBJECT(capplet), "cancel", + GTK_SIGNAL_FUNC(doCancelSettings), curState); gtk_signal_connect(GTK_OBJECT(capplet), "help", GTK_SIGNAL_FUNC(about_cb), NULL); - setStateCfg(cfgStateWindow); + setStateCfg (cfgStateWindow, curState); - gtk_widget_show_all(capplet); + gtk_widget_show_all (capplet); } + static void run_error_dialog(gchar *mesg,...) { @@ -232,6 +296,7 @@ run_error_dialog(gchar *mesg,...) va_end(ap); } + static gint get_pilot_id_from_gpilotd() { @@ -278,18 +343,17 @@ get_pilot_id_from_gpilotd() } } + int -main( int argc, char *argv[] ) +main (int argc, char *argv[]) { - /* - bindtextdomain (PACKAGE, GNOMELOCALEDIR); - textdomain (PACKAGE); - */ + g_log_set_always_fatal (G_LOG_LEVEL_ERROR | + G_LOG_LEVEL_CRITICAL | + G_LOG_LEVEL_WARNING); /* we're a capplet */ gnome_capplet_init ("todo conduit control applet", NULL, argc, argv, - NULL, - 0, NULL); + NULL, 0, NULL); gpc = gnome_pilot_client_new(); @@ -298,17 +362,20 @@ main( int argc, char *argv[] ) if(!pilotId) return -1; /* put all code to set things up in here */ - load_configuration(&origState,pilotId); - curState = dupe_configuration(origState); + gcalconduit_load_configuration (&origState, pilotId); - /* put all code to set things up in here */ - conduit = gnome_pilot_conduit_management_new ("todo_conduit", - GNOME_PILOT_CONDUIT_MGMT_ID); - if (conduit==NULL) return -1; - conduit_config = gnome_pilot_conduit_config_new(conduit,pilotId); - org_activation_state = activated = gnome_pilot_conduit_config_is_enabled(conduit_config,NULL); + conduit = gnome_pilot_conduit_management_new ("todo_conduit", GNOME_PILOT_CONDUIT_MGMT_ID); + if (conduit == NULL) return -1; + conduit_config = gnome_pilot_conduit_config_new (conduit, pilotId); + org_activation_state = gnome_pilot_conduit_config_is_enabled (conduit_config, + &origState->sync_type); + activated = org_activation_state; + + //gpilotd_conduit_mgmt_get_sync_type (conduit, pilotId, &origState->sync_type); + + curState = gcalconduit_dupe_configuration(origState); - pilot_capplet_setup(); + pilot_capplet_setup (); /* done setting up, now run main loop */ diff --git a/calendar/conduits/todo/todo-conduit.c b/calendar/conduits/todo/todo-conduit.c index 6c76fc626d..7884e0ccce 100644 --- a/calendar/conduits/todo/todo-conduit.c +++ b/calendar/conduits/todo/todo-conduit.c @@ -1,246 +1,1010 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* $Id$ */ - -#include <glib.h> -#include <gnome.h> - -#include <pi-source.h> -#include <pi-socket.h> -#include <pi-file.h> -#include <pi-dlp.h> -#include <pi-version.h> +#include <config.h> #include <sys/stat.h> -#include <sys/types.h> #include <utime.h> #include <unistd.h> #include <pwd.h> #include <signal.h> #include <errno.h> + +#include <cal-client/cal-client.h> +#include <cal-util/calobj.h> +#include <cal-util/timeutil.h> +#include <pi-source.h> +#include <pi-socket.h> +#include <pi-file.h> +#include <pi-dlp.h> +#include <libgnorba/gnorba.h> +#include <libgnorba/gnome-factory.h> +#include <pi-version.h> #include <gpilotd/gnome-pilot-conduit.h> #include <gpilotd/gnome-pilot-conduit-standard-abs.h> +#include <todo-conduit.h> + +//#include "GnomeCal.h" + +GnomePilotConduit * conduit_get_gpilot_conduit (guint32); +void conduit_destroy_gpilot_conduit (GnomePilotConduit*); +void local_record_from_icalobject (GCalLocalRecord *local, iCalObject *obj); + +#define CONDUIT_VERSION "0.8.11" +#ifdef G_LOG_DOMAIN +#undef G_LOG_DOMAIN +#endif +#define G_LOG_DOMAIN "todoconduit" + +#define DEBUG_CALCONDUIT 1 +/* #undef DEBUG_CALCONDUIT */ + +#ifdef DEBUG_CALCONDUIT +#define show_exception(e) g_warning ("Exception: %s\n", CORBA_exception_id (e)) +#define LOG(e...) g_log(G_LOG_DOMAIN,G_LOG_LEVEL_MESSAGE, e) +#else +#define show_exception(e) +#define LOG(e...) +#endif + +#define WARN(e...) g_log(G_LOG_DOMAIN,G_LOG_LEVEL_WARNING, e) +#define INFO(e...) g_log(G_LOG_DOMAIN,G_LOG_LEVEL_MESSAGE, e) + +#define catch_ret_val(_env,ret) \ + if (_env._major != CORBA_NO_EXCEPTION) { \ + g_log(G_LOG_DOMAIN,G_LOG_LEVEL_MESSAGE,"%s:%d: Caught exception",__FILE__,__LINE__); \ + g_warning ("Exception: %s\n", CORBA_exception_id (&(_env))); \ + CORBA_exception_free(&(_env)); \ + return ret; \ + } + + + + +/* Destroys any data allocated by gcalconduit_load_configuration + and deallocates the given configuration. */ +static void +gcalconduit_destroy_configuration(GCalConduitCfg **c) +{ + g_return_if_fail(c!=NULL); + g_return_if_fail(*c!=NULL); + g_free(*c); + *c = NULL; +} + + +/* Given a GCalConduitContxt*, allocates the structure */ +static void +gcalconduit_new_context(GCalConduitContext **ctxt, + GCalConduitCfg *c) +{ + *ctxt = g_new0(GCalConduitContext,1); + g_assert(ctxt!=NULL); + (*ctxt)->cfg = c; + CORBA_exception_init (&((*ctxt)->ev)); +} + + +/* Destroys any data allocated by gcalconduit_new_context + and deallocates its data. */ +static void +gcalconduit_destroy_context(GCalConduitContext **ctxt) +{ + g_return_if_fail(ctxt!=NULL); + g_return_if_fail(*ctxt!=NULL); +/* + if ((*ctxt)->cfg!=NULL) + gcalconduit_destroy_configuration(&((*ctxt)->cfg)); +*/ + g_free(*ctxt); + *ctxt = NULL; +} + + +static void +gnome_calendar_load_cb (GtkWidget *cal_client, + CalClientLoadStatus status, + GCalConduitContext *ctxt) +{ + CalClient *client = CAL_CLIENT (cal_client); + + printf ("entering gnome_calendar_load_cb, tried=%d\n", + ctxt->calendar_load_tried); + + if (status == CAL_CLIENT_LOAD_SUCCESS) { + ctxt->calendar_load_success = TRUE; + printf (" success\n"); + gtk_main_quit (); /* end the sub event loop */ + } else { + if (ctxt->calendar_load_tried) { + printf ("load and create of calendar failed\n"); + gtk_main_quit (); /* end the sub event loop */ + return; + } + + cal_client_create_calendar (client, ctxt->calendar_file); + ctxt->calendar_load_tried = 1; + } +} + + + + + +static int +start_calendar_server (GnomePilotConduitStandardAbs *conduit, + GCalConduitContext *ctxt) +{ + + g_return_val_if_fail(conduit!=NULL,-2); + g_return_val_if_fail(ctxt!=NULL,-2); + + ctxt->client = cal_client_new (); + + /* FIX ME */ + ctxt->calendar_file = g_concat_dir_and_file (g_get_home_dir (), + "evolution/local/Calendar/calendar.vcf"); + + gtk_signal_connect (GTK_OBJECT (ctxt->client), "cal_loaded", + gnome_calendar_load_cb, ctxt); + + printf ("calling cal_client_load_calendar\n"); + cal_client_load_calendar (ctxt->client, ctxt->calendar_file); + + /* run a sub event loop to turn cal-client's async load + notification into a synchronous call */ + gtk_main (); + + if (ctxt->calendar_load_success) + return 0; + + return -1; +} + + +#if 0 +/* Just a stub to link with */ +void calendar_notify (time_t time, CalendarAlarm *which, void *data); +void calendar_notify (time_t time, CalendarAlarm *which, void *data) { } +#endif /* 0 */ + + +static GSList * +get_calendar_objects(GnomePilotConduitStandardAbs *conduit, + gboolean *status, + GCalConduitContext *ctxt) +{ + GList *uids; + GSList *result = NULL; + + g_return_val_if_fail (conduit != NULL, NULL); + g_return_val_if_fail (ctxt != NULL, NULL); + + uids = cal_client_get_uids (ctxt->client, CALOBJ_TYPE_TODO); + + printf ("got %d todo entries from cal server\n", g_list_length (uids)); -#include "todo-conduit.h" + if (status != NULL) + (*status) = TRUE; + + if (! uids) + INFO ("No entries found"); + else { + GList *c; + for (c=uids; c; c=c->next) + result = g_slist_prepend (result, (gchar *) c->data); + /* FIX ME free uids */ + } + + return result; +} + + +static void +local_record_from_ical_uid (GCalLocalRecord *local, + char *uid, + GCalConduitContext *ctxt) +{ + iCalObject *obj; + CalClientGetStatus status; + + g_assert(local!=NULL); + + status = cal_client_get_object (ctxt->client, uid, &obj); + + if (status == CAL_CLIENT_GET_SUCCESS) + local_record_from_icalobject(local,obj); + else + INFO ("Object did not exist"); +} + + +/* + * converts a iCalObject to a GCalLocalRecord + */ + +void +local_record_from_icalobject(GCalLocalRecord *local, + iCalObject *obj) +{ + g_return_if_fail(local!=NULL); + g_return_if_fail(obj!=NULL); + + local->ical = obj; + local->local.ID = local->ical->pilot_id; +/* + LOG ("local->Id = %ld [%s], status = %d", + local->local.ID,obj->summary,local->ical->pilot_status); +*/ + switch(local->ical->pilot_status) { + case ICAL_PILOT_SYNC_NONE: + local->local.attr = GnomePilotRecordNothing; + break; + case ICAL_PILOT_SYNC_MOD: + local->local.attr = GnomePilotRecordModified; + break; + case ICAL_PILOT_SYNC_DEL: + local->local.attr = GnomePilotRecordDeleted; + break; + } + + /* Records without a pilot_id are new */ + if(local->local.ID == 0) + local->local.attr = GnomePilotRecordNew; + + local->local.secret = 0; + if(obj->class!=NULL) + if(strcmp(obj->class,"PRIVATE")==0) + local->local.secret = 1; + + local->local.archived = 0; +} + + +/* + * Given a PilotRecord, find the matching record in + * the calendar repository. If no match, return NULL + */ +static GCalLocalRecord * +find_record_in_repository(GnomePilotConduitStandardAbs *conduit, + PilotRecord *remote, + GCalConduitContext *ctxt) +{ + char *uid = NULL; + GCalLocalRecord *loc; + CalClientGetStatus status; + iCalObject *obj; + + g_return_val_if_fail(conduit!=NULL,NULL); + g_return_val_if_fail(remote!=NULL,NULL); + + LOG ("requesting %ld", remote->ID); + + + status = cal_client_get_uid_by_pilot_id (ctxt->client, remote->ID, &uid); + + if (status == CAL_CLIENT_GET_SUCCESS) { + status = cal_client_get_object (ctxt->client, uid, &obj); + if (status == CAL_CLIENT_GET_SUCCESS) { + LOG ("Found"); + loc = g_new0(GCalLocalRecord,1); + /* memory allocated in new_from_string is freed in free_match */ + local_record_from_icalobject (loc, obj); + return loc; + } + } + + INFO ("Object did not exist"); + return NULL; +} -GnomePilotConduit *conduit_get_gpilot_conduit (guint32 pilotId); -void conduit_destroy_gpilot_conduit (GnomePilotConduit *conduit); +/* + * updates an given iCalObject in the repository + */ +static void +update_calendar_entry_in_repository(GnomePilotConduitStandardAbs *conduit, + iCalObject *obj, + GCalConduitContext *ctxt) +{ + gboolean success; + + g_return_if_fail(conduit!=NULL); + g_return_if_fail(obj!=NULL); + + success = cal_client_update_object (ctxt->client, obj); +} + + +static iCalObject * +ical_from_remote_record(GnomePilotConduitStandardAbs *conduit, + PilotRecord *remote, + iCalObject *in_obj) +{ + iCalObject *obj; + struct ToDo todo; + time_t now; + + now = time (NULL); + + g_return_val_if_fail(remote!=NULL,NULL); + memset (&todo, 0, sizeof (struct ToDo)); + unpack_ToDo (&todo, remote->record, remote->length); + + if (in_obj == NULL) + obj = ical_new (todo.note ? todo.note : "", + g_get_user_name (), + todo.description ? todo.description : ""); + else + obj = in_obj; + + if (todo.note) { + g_free (obj->comment); + obj->comment = g_strdup (todo.note); + } + if (todo.description) { + g_free (obj->summary); + obj->summary = g_strdup (todo.description); + } + + obj->type = ICAL_TODO; + obj->new = TRUE; + 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; + + /* + * Begin and end + */ + + obj->dtend = mktime (& todo.due); + + if (todo.complete) + obj->completed = now-5; /* FIX ME */ + + printf ("[%s] from pilot, complete=%d/%ld\n", + todo.description, + todo.complete, + obj->completed); + + obj->priority = todo.priority; + + g_free (obj->class); + + if (remote->attr & dlpRecAttrSecret) + obj->class = g_strdup ("PRIVATE"); + else + obj->class = g_strdup ("PUBLIC"); + + free_ToDo(&todo); + + return obj; +} + + +/* Code blatantly stolen from + * calendar-pilot-sync.c: + * + * (C) 1999 International GNOME Support + * + * Author: + * Miguel de Icaza (miguel@gnome-support.com) + * + */ static gint -load_records(GnomePilotConduit *c) +update_record (GnomePilotConduitStandardAbs *conduit, + PilotRecord *remote, + GCalConduitContext *ctxt) { + iCalObject *obj; + struct ToDo todo; + CalClientGetStatus status; + char *uid; + + g_return_val_if_fail(remote!=NULL,-1); + + memset (&todo, 0, sizeof (struct ToDo)); + unpack_ToDo (&todo, remote->record, remote->length); + + LOG ("requesting %ld [%s]", remote->ID, todo.description); + printf ("requesting %ld [%s]\n", remote->ID, todo.description); + + status = cal_client_get_uid_by_pilot_id(ctxt->client, remote->ID, &uid); + if (status == CAL_CLIENT_GET_SUCCESS) + status = cal_client_get_object (ctxt->client, uid, &obj); + + if (status != CAL_CLIENT_GET_SUCCESS) { + time_t now = time (NULL); + + LOG ("Object did not exist, creating a new one"); + printf ("Object did not exist, creating a new one\n"); + + obj = ical_new (todo.note ? todo.note : "", + g_get_user_name (), + todo.description ? todo.description : ""); + + obj->type = ICAL_TODO; + obj->new = TRUE; + 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; + } else { + iCalObject *new_obj; + LOG ("Found"); + printf ("Found\n"); + new_obj = ical_from_remote_record (conduit, remote, obj); + obj = new_obj; + } + + /* update record on server */ + + update_calendar_entry_in_repository (conduit, obj, ctxt); + cal_client_update_pilot_id (ctxt->client, obj->uid, obj->pilot_id, + ICAL_PILOT_SYNC_NONE); + + /* + * Shutdown + */ + ical_object_unref (obj); + free_ToDo(&todo); + return 0; } +static void +check_for_slow_setting (GnomePilotConduit *c, GCalConduitContext *ctxt) +{ + GList *uids; + unsigned long int entry_number; + + uids = cal_client_get_uids (ctxt->client, CALOBJ_TYPE_TODO); + + entry_number = g_list_length (uids); -static gint -pre_sync(GnomePilotConduit *c, GnomePilotDBInfo *dbi) + LOG (_("Calendar holds %ld todo entries"), entry_number); + /* If the local base is empty, do a slow sync */ + if (entry_number == 0) { + GnomePilotConduitStandard *conduit; + conduit = GNOME_PILOT_CONDUIT_STANDARD (c); + gnome_pilot_conduit_standard_set_slow (conduit); + } +} + +static gint +pre_sync (GnomePilotConduit *c, + GnomePilotDBInfo *dbi, + GCalConduitContext *ctxt) { int l; unsigned char *buf; + GnomePilotConduitStandardAbs *conduit; + /* gint num_records; */ + //GList *uids; + + /* + g_log_set_always_fatal (G_LOG_LEVEL_ERROR | + G_LOG_LEVEL_CRITICAL | + G_LOG_LEVEL_WARNING); + */ + + + conduit = GNOME_PILOT_CONDUIT_STANDARD_ABS(c); + + g_message ("GnomeCal Conduit v.%s",CONDUIT_VERSION); + + ctxt->client = NULL; + + if (start_calendar_server (GNOME_PILOT_CONDUIT_STANDARD_ABS(c), ctxt) != 0) { + WARN(_("Could not start gnomecal server")); + gnome_pilot_conduit_error(GNOME_PILOT_CONDUIT(c), + _("Could not start gnomecal server")); + return -1; + } + + +#if 0 + /* Set the counters for the progress bar crap */ + num_records = GNOME_Calendar_Repository_get_number_of_objects (ctxt->calendar, GNOME_Calendar_Repository_ANY, &(ctxt->ev)); + + catch_ret_val (ctxt->ev, -1); + gnome_pilot_conduit_standard_abs_set_num_local_records(GNOME_PILOT_CONDUIT_STANDARD_ABS(c), num_records); + num_records = GNOME_Calendar_Repository_get_number_of_objects (ctxt->calendar, GNOME_Calendar_Repository_MODIFIED, &(ctxt->ev)); + catch_ret_val (ctxt->ev, -1); + gnome_pilot_conduit_standard_abs_set_num_updated_local_records(GNOME_PILOT_CONDUIT_STANDARD_ABS(c), num_records); + num_records = GNOME_Calendar_Repository_get_number_of_objects (ctxt->calendar, GNOME_Calendar_Repository_NEW, &(ctxt->ev)); + catch_ret_val (ctxt->ev, -1); + gnome_pilot_conduit_standard_abs_set_num_new_local_records(GNOME_PILOT_CONDUIT_STANDARD_ABS(c), num_records); + num_records = GNOME_Calendar_Repository_get_number_of_objects (ctxt->calendar, GNOME_Calendar_Repository_DELETED, &(ctxt->ev)); + catch_ret_val (ctxt->ev, -1); + gnome_pilot_conduit_standard_abs_set_num_deleted_local_records(GNOME_PILOT_CONDUIT_STANDARD_ABS(c), num_records); +#endif /* 0 */ gtk_object_set_data(GTK_OBJECT(c),"dbinfo",dbi); - load_records(c); + /* 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) { + if((l=dlp_ReadAppBlock(dbi->pilot_socket,dbi->db_handle,0,(unsigned char *)buf,0xffff)) < 0) { + WARN(_("Could not read pilot's DateBook application block")); + WARN("dlp_ReadAppBlock(...) = %d",l); + gnome_pilot_conduit_error(GNOME_PILOT_CONDUIT(c), + _("Could not read pilot's DateBook application block")); return -1; } - unpack_ToDoAppInfo(&(GET_DATA(c)->ai),buf,l); + unpack_ToDoAppInfo(&(ctxt->ai),buf,l); g_free(buf); - return 0; -} - + check_for_slow_setting(c,ctxt); -#if 0 -static gint -post_sync(GnomePilotConduit *c) { return 0; } -#endif /* 0 */ +/** + * Find (if possible) the local record which matches + * the given PilotRecord. + * if successfull, return non-zero and set *local to + * a non-null value (the located local record), + * otherwise return 0 and set *local = NULL; + */ static gint -match_record (GnomePilotConduitStandardAbs *pilot_conduit_standard_abs, - LocalRecord **local, +match_record (GnomePilotConduitStandardAbs *conduit, + GCalLocalRecord **local, PilotRecord *remote, - gpointer data) + GCalConduitContext *ctxt) { - g_print ("in match_record\n"); + LOG ("in match_record"); + + g_return_val_if_fail(local!=NULL,-1); + g_return_val_if_fail(remote!=NULL,-1); + + *local = find_record_in_repository(conduit,remote,ctxt); + + if (*local==NULL) return -1; return 0; } - +/** + * Free the data allocated by a previous match_record call. + * If successfull, return non-zero and ser *local=NULL, otherwise + * return 0. + */ static gint -free_match (GnomePilotConduitStandardAbs *pilot_conduit_standard_abs, - LocalRecord **local, - gpointer data) +free_match (GnomePilotConduitStandardAbs *conduit, + GCalLocalRecord **local, + GCalConduitContext *ctxt) { - g_print ("entering free_match\n"); - *local = NULL; + LOG ("entering free_match"); + + g_return_val_if_fail(local!=NULL,-1); + g_return_val_if_fail(*local!=NULL,-1); + ical_object_unref (GCAL_LOCALRECORD(*local)->ical); + g_free(*local); + + *local = NULL; return 0; } - +/* + Move to archive and set status to Nothing + */ static gint -archive_local (GnomePilotConduitStandardAbs *pilot_conduit_standard_abs, - LocalRecord *local, - gpointer data) +archive_local (GnomePilotConduitStandardAbs *conduit, + GCalLocalRecord *local, + GCalConduitContext *ctxt) { - g_print ("entering archive_local\n"); - return 1; + LOG ("entering archive_local"); -} + g_return_val_if_fail(local!=NULL,-1); + return -1; +} +/* + Store in archive and set status to Nothing + */ static gint -archive_remote (GnomePilotConduitStandardAbs *pilot_conduit_standard_abs, - LocalRecord *local, +archive_remote (GnomePilotConduitStandardAbs *conduit, + GCalLocalRecord *local, PilotRecord *remote, - gpointer data) + GCalConduitContext *ctxt) { - g_print ("entering archive_remote\n"); - return 1; -} + LOG ("entering archive_remote"); + //g_return_val_if_fail(remote!=NULL,-1); + //g_return_val_if_fail(local!=NULL,-1); + return -1; +} + +/* + Store and set status to Nothing + */ static gint -store_remote (GnomePilotConduitStandardAbs *pilot_conduit_standard_abs, +store_remote (GnomePilotConduitStandardAbs *conduit, PilotRecord *remote, - gpointer data) + GCalConduitContext *ctxt) { - g_print ("entering store_remote\n"); - g_print ("Rec:%s:\nLength:%d\n", remote->record, remote->length); - return 1; -} + LOG ("entering store_remote"); + g_return_val_if_fail(remote!=NULL,-1); + remote->attr = GnomePilotRecordNothing; + + return update_record(conduit,remote,ctxt); +} static gint -clear_status_archive_local (GnomePilotConduitStandardAbs *pilot_conduit_standard_abs, - LocalRecord *local, - gpointer data) +clear_status_archive_local (GnomePilotConduitStandardAbs *conduit, + GCalLocalRecord *local, + GCalConduitContext *ctxt) { - g_print ("entering clear_status_archive_local\n"); - return 1; -} + LOG ("entering clear_status_archive_local"); + g_return_val_if_fail(local!=NULL,-1); + + return -1; +} static gint -iterate (GnomePilotConduitStandardAbs *pilot_conduit_standard_abs, - LocalRecord **local, - gpointer data) +iterate (GnomePilotConduitStandardAbs *conduit, + GCalLocalRecord **local, + GCalConduitContext *ctxt) { - g_print ("entering iterate\n"); - return 1; + static GSList *events,*iterator; + static int hest; + + g_return_val_if_fail(local!=NULL,-1); + + if(*local==NULL) { + LOG ("beginning iteration"); + + events = get_calendar_objects(conduit,NULL,ctxt); + hest = 0; + + if(events!=NULL) { + LOG ("iterating over %d records", g_slist_length (events)); + *local = g_new0(GCalLocalRecord,1); + + local_record_from_ical_uid(*local,(gchar*)events->data,ctxt); + iterator = events; + } else { + LOG ("no events"); + (*local) = NULL; + } + } else { + /* printf ("continuing iteration\n"); */ + hest++; + if(g_slist_next(iterator)==NULL) { + GSList *l; + + LOG ("ending"); + /** free stuff allocated for iteration */ + g_free((*local)); + + LOG ("iterated over %d records", hest); + for(l=events;l;l=l->next) + g_free(l->data); + + g_slist_free(events); + + /* ends iteration */ + (*local) = NULL; + return 0; + } else { + iterator = g_slist_next(iterator); + local_record_from_ical_uid(*local,(gchar*)(iterator->data),ctxt); + } + } + return 1; } static gint -iterate_specific (GnomePilotConduitStandardAbs *pilot_conduit_standard_abs, - LocalRecord **local, +iterate_specific (GnomePilotConduitStandardAbs *conduit, + GCalLocalRecord **local, gint flag, gint archived, - gpointer data) + GCalConduitContext *ctxt) { - g_print ("entering iterate_specific\n"); - return 1; -} +#ifdef DEBUG_CALCONDUIT + { + gchar *tmp; + switch (flag) { + case GnomePilotRecordNothing: tmp = g_strdup("RecordNothing"); break; + case GnomePilotRecordModified: tmp = g_strdup("RecordModified"); break; + case GnomePilotRecordNew: tmp = g_strdup("RecordNew"); break; + default: tmp = g_strdup_printf("0x%x",flag); break; + } + printf ("entering iterate_specific(flag = %s)\n", tmp); + g_free(tmp); + } +#endif + g_return_val_if_fail(local!=NULL,-1); + /* iterate until a record meets the criteria */ + while(gnome_pilot_conduit_standard_abs_iterate(conduit,(LocalRecord**)local)) { + if((*local)==NULL) break; + if(archived && ((*local)->local.archived==archived)) break; + if(((*local)->local.attr == flag)) break; + } + + return (*local)==NULL?0:1; +} static gint -purge (GnomePilotConduitStandardAbs *pilot_conduit_standard_abs, - gpointer data) +purge (GnomePilotConduitStandardAbs *conduit, + GCalConduitContext *ctxt) { - g_print ("entering purge\n"); - return 1; + LOG ("entering purge"); + + /* HEST, gem posterne her */ + + return -1; } static gint -set_status (GnomePilotConduitStandardAbs *pilot_conduit_standard_abs, - LocalRecord *local, +set_status (GnomePilotConduitStandardAbs *conduit, + GCalLocalRecord *local, gint status, - gpointer data) + GCalConduitContext *ctxt) { - g_print ("entering set_status\n"); - return 1; -} + gboolean success; + LOG ("entering set_status(status=%d)",status); + + g_return_val_if_fail(local!=NULL,-1); + + g_assert(local->ical!=NULL); + + local->local.attr = status; + switch(status) { + case GnomePilotRecordPending: + case GnomePilotRecordNothing: + local->ical->pilot_status = ICAL_PILOT_SYNC_NONE; + break; + case GnomePilotRecordDeleted: + break; + case GnomePilotRecordNew: + case GnomePilotRecordModified: + local->ical->pilot_status = ICAL_PILOT_SYNC_MOD; + break; + } + + if (status == GnomePilotRecordDeleted) { + success = cal_client_remove_object (ctxt->client, local->ical->uid); + } else { + success = cal_client_update_object (ctxt->client, local->ical); + cal_client_update_pilot_id (ctxt->client, local->ical->uid, + local->local.ID, + local->ical->pilot_status); + } + if (! success) { + WARN (_("Error while communicating with calendar server")); + } + + return 0; +} static gint -set_archived (GnomePilotConduitStandardAbs *pilot_conduit_standard_abs, - LocalRecord *local, +set_archived (GnomePilotConduitStandardAbs *conduit, + GCalLocalRecord *local, gint archived, - gpointer data) + GCalConduitContext *ctxt) { - g_print ("entering set_archived\n"); - return 1; -} + LOG ("entering set_archived"); + g_return_val_if_fail(local!=NULL,-1); + g_assert(local->ical!=NULL); + + local->local.archived = archived; + update_calendar_entry_in_repository(conduit,local->ical,ctxt); + /* FIXME: This should move the entry into a speciel + calendar file, eg. Archive, or (by config option), simply + delete it */ + return 0; +} static gint -set_pilot_id (GnomePilotConduitStandardAbs *pilot_conduit_standard_abs, - LocalRecord *local, +set_pilot_id (GnomePilotConduitStandardAbs *conduit, + GCalLocalRecord *local, guint32 ID, - gpointer data) + GCalConduitContext *ctxt) { - g_print ("entering set_pilot_id\n"); - return 1; -} + LOG ("entering set_pilot_id(id=%d)",ID); + + g_return_val_if_fail(local!=NULL,-1); + g_assert(local->ical!=NULL); + local->local.ID = ID; + local->ical->pilot_id = ID; + + cal_client_update_pilot_id (ctxt->client, + local->ical->uid, + local->local.ID, + local->ical->pilot_status); + + return 0; +} static gint -compare (GnomePilotConduitStandardAbs *pilot_conduit_standard_abs, - LocalRecord *local, - PilotRecord *remote, - gpointer data) +transmit (GnomePilotConduitStandardAbs *conduit, + GCalLocalRecord *local, + PilotRecord **remote, + GCalConduitContext *ctxt) { - g_print ("entering compare\n"); - return 1; -} + PilotRecord *p; + + LOG ("entering transmit"); + + g_return_val_if_fail(local!=NULL,-1); + g_return_val_if_fail(remote!=NULL,-1); + g_assert(local->ical!=NULL); + + p = g_new0(PilotRecord,1); + + p->ID = local->local.ID; + p->attr = local->local.attr; + p->archived = local->local.archived; + p->secret = local->local.secret; + + local->todo = g_new0(struct ToDo,1); + local->todo->indefinite = 0; /* FIX ME */ + local->todo->due = *localtime (&local->ical->dtend); + local->todo->priority = local->ical->priority; + + if (local->ical->completed > 0) + local->todo->complete = 1; /* FIX ME */ + + /* STOP: don't replace these with g_strdup, since free_ToDo + uses free to deallocte */ + local->todo->description = + local->ical->summary==NULL?NULL:strdup(local->ical->summary); + local->todo->note = + local->ical->comment==NULL?NULL:strdup(local->ical->comment); + + printf ("transmitting todo to pilot [%s] complete=%d/%ld\n", + local->ical->summary==NULL?"NULL":local->ical->summary, + local->todo->complete, local->ical->completed); + + /* Generate pilot record structure */ + p->record = g_new0(char,0xffff); + p->length = pack_ToDo(local->todo,p->record,0xffff); + + *remote = p; + + return 0; +} static gint -compare_backup (GnomePilotConduitStandardAbs *pilot_conduit_standard_abs, - LocalRecord *local, - PilotRecord *remote, - gpointer data) +free_transmit (GnomePilotConduitStandardAbs *conduit, + GCalLocalRecord *local, + PilotRecord **remote, + GCalConduitContext *ctxt) { - g_print ("entering compare_backup\n"); - return 1; -} + LOG ("entering free_transmit"); + g_return_val_if_fail(local!=NULL,-1); + g_return_val_if_fail(remote!=NULL,-1); + + free_ToDo(local->todo); + g_free((*remote)->record); + *remote = NULL; + return 0; +} static gint -free_transmit (GnomePilotConduitStandardAbs *pilot_conduit_standard_abs, - LocalRecord *local, - PilotRecord *remote, - gpointer data) +compare (GnomePilotConduitStandardAbs *conduit, + GCalLocalRecord *local, + PilotRecord *remote, + GCalConduitContext *ctxt) { - g_print ("entering free_transmit\n"); - return 1; -} + /* used by the quick compare */ + PilotRecord *remoteOfLocal; + int err; + int retval; + + g_message ("entering compare"); + printf ("entering compare\n"); + + g_return_val_if_fail (local!=NULL,-1); + g_return_val_if_fail (remote!=NULL,-1); + err = transmit(conduit,local,&remoteOfLocal,ctxt); + if (err != 0) return err; + + retval = 0; + if (remote->length == remoteOfLocal->length) { + if (memcmp(remoteOfLocal->record,remote->record,remote->length)!=0) { + g_message("compare failed on contents"); + printf ("compare failed on contents\n"); + retval = 1; + + /* debug spew */ + { + struct ToDo foolocal; + struct ToDo fooremote; + + unpack_ToDo (&foolocal, + remoteOfLocal->record, + remoteOfLocal->length); + unpack_ToDo (&fooremote, + remote->record, + remote->length); + + printf (" local:[%d %ld %d %d '%s' '%s']\n", + foolocal.indefinite, + mktime (& foolocal.due), + foolocal.priority, + foolocal.complete, + foolocal.description, + foolocal.note); + + printf ("remote:[%d %ld %d %d '%s' '%s']\n", + fooremote.indefinite, + mktime (& fooremote.due), + fooremote.priority, + fooremote.complete, + fooremote.description, + fooremote.note); + } + } + } else { + g_message("compare failed on length"); + printf("compare failed on length\n"); + retval = 1; + } + + free_transmit(conduit,local,&remoteOfLocal,ctxt); + return retval; +} static gint -delete_all (GnomePilotConduitStandardAbs *pilot_conduit_standard_abs, - gpointer data) +compare_backup (GnomePilotConduitStandardAbs *conduit, + GCalLocalRecord *local, + PilotRecord *remote, + GCalConduitContext *ctxt) { - g_print ("entering delete_all\n"); - return 1; + LOG ("entering compare_backup"); + + g_return_val_if_fail(local!=NULL,-1); + g_return_val_if_fail(remote!=NULL,-1); + + return -1; } -static PilotRecord * -transmit (GnomePilotConduitStandardAbs *pilot_conduit_standard_abs, - LocalRecord *local, - gpointer data) +static gint +delete_all (GnomePilotConduitStandardAbs *conduit, + GCalConduitContext *ctxt) { - g_print ("entering transmit\n"); - return NULL; + GSList *events,*it; + gboolean error; + gboolean success; + + events = get_calendar_objects(conduit,&error,ctxt); + + if (error == FALSE) return -1; + for (it=events; it; it = g_slist_next (it)) { + success = cal_client_remove_object (ctxt->client, it->data); + + if (!success) + INFO ("Object did not exist"); + + g_free (it->data); + } + + g_slist_free (events); + return -1; } @@ -248,55 +1012,61 @@ GnomePilotConduit * conduit_get_gpilot_conduit (guint32 pilotId) { GtkObject *retval; - ConduitCfg *cfg; - ConduitData *cdata; + GCalConduitCfg *cfg; + GCalConduitContext *ctxt; - g_print ("creating our new conduit\n"); - retval = gnome_pilot_conduit_standard_abs_new ("TodoDB", 0x0); + printf ("in todo's conduit_get_gpilot_conduit\n"); + + retval = gnome_pilot_conduit_standard_abs_new ("ToDoDB", 0x746F646F); g_assert (retval != NULL); - gnome_pilot_conduit_construct(GNOME_PILOT_CONDUIT(retval),"todo"); - - 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); - /* gtk_signal_connect (retval, "post_sync", (GtkSignalFunc) post_sync, NULL); */ - - load_configuration(&cfg,pilotId); + gnome_pilot_conduit_construct(GNOME_PILOT_CONDUIT(retval),"ToDoConduit"); + + gcalconduit_load_configuration(&cfg,pilotId); + gtk_object_set_data(retval,"todoconduit_cfg",cfg); + + gcalconduit_new_context(&ctxt,cfg); + gtk_object_set_data(GTK_OBJECT(retval),"todoconduit_context",ctxt); + + gtk_signal_connect (retval, "match_record", (GtkSignalFunc) match_record, ctxt); + gtk_signal_connect (retval, "free_match", (GtkSignalFunc) free_match, ctxt); + gtk_signal_connect (retval, "archive_local", (GtkSignalFunc) archive_local, ctxt); + gtk_signal_connect (retval, "archive_remote", (GtkSignalFunc) archive_remote, ctxt); + gtk_signal_connect (retval, "store_remote", (GtkSignalFunc) store_remote, ctxt); + gtk_signal_connect (retval, "clear_status_archive_local", (GtkSignalFunc) clear_status_archive_local, ctxt); + gtk_signal_connect (retval, "iterate", (GtkSignalFunc) iterate, ctxt); + gtk_signal_connect (retval, "iterate_specific", (GtkSignalFunc) iterate_specific, ctxt); + gtk_signal_connect (retval, "purge", (GtkSignalFunc) purge, ctxt); + gtk_signal_connect (retval, "set_status", (GtkSignalFunc) set_status, ctxt); + gtk_signal_connect (retval, "set_archived", (GtkSignalFunc) set_archived, ctxt); + gtk_signal_connect (retval, "set_pilot_id", (GtkSignalFunc) set_pilot_id, ctxt); + gtk_signal_connect (retval, "compare", (GtkSignalFunc) compare, ctxt); + gtk_signal_connect (retval, "compare_backup", (GtkSignalFunc) compare_backup, ctxt); + gtk_signal_connect (retval, "free_transmit", (GtkSignalFunc) free_transmit, ctxt); + gtk_signal_connect (retval, "delete_all", (GtkSignalFunc) delete_all, ctxt); + gtk_signal_connect (retval, "transmit", (GtkSignalFunc) transmit, ctxt); + gtk_signal_connect (retval, "pre_sync", (GtkSignalFunc) pre_sync, ctxt); return GNOME_PILOT_CONDUIT (retval); } - void conduit_destroy_gpilot_conduit (GnomePilotConduit *conduit) -{ - ConduitCfg *cc; - cc = GET_CONFIG(conduit); - destroy_configuration(&cc); - gtk_object_destroy (GTK_OBJECT (conduit)); -} +{ + GCalConduitCfg *cc; + GCalConduitContext *ctxt; + + cc = GET_GCALCONFIG(conduit); + ctxt = GET_GCALCONTEXT(conduit); + + if (ctxt->client != NULL) { + gtk_object_unref (GTK_OBJECT (ctxt->client)); + //pi_close (ctxt->link); + //GNOME_Calendar_Repository_done (ctxt->calendar, &(ctxt->ev)); + } + + gcalconduit_destroy_configuration (&cc); + gcalconduit_destroy_context (&ctxt); + gtk_object_destroy (GTK_OBJECT (conduit)); +} diff --git a/calendar/conduits/todo/todo-conduit.h b/calendar/conduits/todo/todo-conduit.h index 083064d3c1..05b9c00d18 100644 --- a/calendar/conduits/todo/todo-conduit.h +++ b/calendar/conduits/todo/todo-conduit.h @@ -1,5 +1,4 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* $Id$ */ #ifndef __TODO_CONDUIT_H__ #define __TODO_CONDUIT_H__ @@ -7,56 +6,82 @@ #include <sys/types.h> #include <fcntl.h> #include <unistd.h> -#include <pi-todo.h> #include <gnome.h> +#include <pi-todo.h> +#include <gpilotd/gnome-pilot-conduit.h> +#include <gpilotd/gnome-pilot-conduit-standard-abs.h> +#include <cal-client/cal-client.h> +#include <cal-util/calobj.h> +#include <cal-util/timeutil.h> + +#ifdef USING_OAF +#include <liboaf/liboaf.h> +#else +#include <libgnorba/gnorba.h> +#endif + + +/* This is the local record structure for the GnomeCal conduit. */ +typedef struct _GCalLocalRecord GCalLocalRecord; +struct _GCalLocalRecord { + /* The stuff from gnome-pilot-conduit-standard-abs.h + Must be first in the structure, or instances of this + structure cannot be used by gnome-pilot-conduit-standard-abs. + */ + LocalRecord local; + /* The corresponding iCal object, as found by GnomeCal. */ + iCalObject *ical; + /* pilot-link todo structure, used for implementing Transmit. */ + struct ToDo *todo; +}; +#define GCAL_LOCALRECORD(s) ((GCalLocalRecord*)(s)) -typedef struct _ConduitCfg ConduitCfg; - -struct _ConduitCfg { +/* This is the configuration of the GnomeCal conduit. */ +typedef struct _GCalConduitCfg GCalConduitCfg; +struct _GCalConduitCfg { gboolean open_secret; guint32 pilotId; + GnomePilotConduitSyncType sync_type; /* only used by capplet */ }; +#define GET_GCALCONFIG(c) ((GCalConduitCfg*)gtk_object_get_data(GTK_OBJECT(c),"todoconduit_cfg")) -#define GET_CONFIG(c) ((ConduitCfg*)gtk_object_get_data(GTK_OBJECT(c),"conduit_cfg")) - -typedef struct _ConduitData ConduitData; - -struct _ConduitData { +/* This is the context for all the GnomeCal conduit methods. */ +typedef struct _GCalConduitContext GCalConduitContext; +struct _GCalConduitContext { struct ToDoAppInfo ai; + GCalConduitCfg *cfg; + CalClient *client; + CORBA_Environment ev; + CORBA_ORB orb; + gboolean calendar_load_tried; + gboolean calendar_load_success; + + char *calendar_file; }; - -#define GET_DATA(c) ((ConduitData*)gtk_object_get_data(GTK_OBJECT(c),"conduit_data")) - -static void load_configuration(ConduitCfg **c,guint32 pilotId) { +#define GET_GCALCONTEXT(c) ((GCalConduitContext*)gtk_object_get_data(GTK_OBJECT(c),"todoconduit_context")) + + +/* Given a GCalConduitCfg*, allocates the structure and + loads the configuration data for the given pilot. + this is defined in the header file because it is used by + both todo-conduit and todo-conduit-control-applet, + and we don't want to export any symbols we don't have to. */ +static void +gcalconduit_load_configuration(GCalConduitCfg **c, + guint32 pilotId) +{ gchar prefix[256]; - g_snprintf(prefix,255,"/gnome-pilot.d/todod-conduit/Pilot_%u/",pilotId); - - *c = g_new0(ConduitCfg,1); + g_snprintf(prefix,255,"/gnome-pilot.d/todo-conduit/Pilot_%u/",pilotId); + + *c = g_new0(GCalConduitCfg,1); + g_assert(*c != NULL); gnome_config_push_prefix(prefix); - (*c)->open_secret = gnome_config_get_bool("open secret=FALSE"); + (*c)->open_secret = gnome_config_get_bool("open_secret=FALSE"); + (*c)->sync_type = GnomePilotConduitSyncTypeCustom; /* set in capplets main */ gnome_config_pop_prefix(); - + (*c)->pilotId = pilotId; } -static void save_configuration(ConduitCfg *c) { - gchar prefix[256]; - - g_snprintf(prefix,255,"/gnome-pilot.d/todo-conduit/Pilot_%u/",c->pilotId); - - gnome_config_push_prefix(prefix); - gnome_config_set_bool("open secret",c->open_secret); - gnome_config_pop_prefix(); - - gnome_config_sync(); - gnome_config_drop_all(); -} - -static void destroy_configuration(ConduitCfg **c) { - g_return_if_fail(c!=NULL); - g_return_if_fail(*c!=NULL); - g_free(*c); - *c = NULL; -} #endif __TODO_CONDUIT_H__ |