From d8fbc4fc0c01d174f04e8f2370131a5240764f4b Mon Sep 17 00:00:00 2001 From: Federico Mena Quintero Date: Fri, 11 Feb 2000 11:08:08 +0000 Subject: Connect to the Cal's destroy signal. (cal_backend_remove_cal): Killed 2000-02-10 Federico Mena Quintero * cal-backend.c (cal_backend_add_cal): Connect to the Cal's destroy signal. (cal_backend_remove_cal): Killed function now that removal of Cal objects is done in their destroy callback. (cal_destroy_cb): New callback to remove a Cal from the backend's list of clients. Also, the backend destroys itself when there are no more clients connected to it. (save): New placeholder function to save a backend. (destroy): New function to destroy a backend's data. (cal_backend_destroy): Save the calendar and destroy it. * cal.c (cal_destroy): Reset the priv->backend to NULL. * cal-factory.c (add_calendar_client): There is no need to call cal_backend_remove_cal(); we can now just destroy the Cal object. (create_fn): Make sure we always unref the URI. (load_fn): Move the URI unref to the end of the function for safety. * cal-factory.c (add_calendar_client): Unref the Cal only if notification of the listener was unsuccessful. Otherwise, the calendar user agent (Listener side) keeps the reference. * tl-test.c (list_uids): Free the calobj. * cal-client.c (cal_loaded_cb): Use bonobo_object_unref() to get rid of the listener. (load_or_create): Likewise. (destroy_factory): New function to get rid of the factory. (destroy_listener): New function to get rid of the listener. (destroy_cal): New function to get rid of the calendar client interface object. (cal_client_destroy): Free all resources. (cal_client_get_object): CORBA_free() the calobj string. Boy, I love memprof. * cal-listener.c (cal_listener_destroy): Reset the priv->cal to CORBA_OBJECT_NIL. * cal-backend.c (cal_backend_remove_cal): Do not unref the Cal, since the calendar user agent owns it. (cal_backend_add_cal): Do not ref the Cal, since the calendar user agent owns it. * cal-factory.c (add_calendar_client): Use bonobo_object_unref() to get rid of the calendar client interface object. * calobj.c (ical_object_create_from_vobject): Duplicate the default "PUBLIC" string. 2000-02-09 Federico Mena Quintero * cal-factory.c (cal_factory_load): Added documentation comment. (load_fn): Do not print a message if the backend could not be loaded due to a non-fatal error. (queue_load_create_job): Moved the stuff from cal_factory_load() to here. Now this function serves to queue load or create requests. (cal_factory_load): Use queue_load_create_job(). (cal_factory_create): Implemented; use queue_load_create_job(). (create_fn): New job handler for creating new calendars. (create_backend): New function to create a new backend with a new calendar. (add_backend): New helper function to add backends to the factory's hash table. (load_backend): Use add_backend() instead of adding the backend by ourselves. * cal-client.c (load_or_create): Moved the functionality from cal_client_load_calendar() to here, and added an option to create a new calendar instead of loading an existing one. (cal_client_load_calendar): Use load_or_create(). (cal_client_create_calendar): Implemented. * cal-backend.c (cal_backend_create): Implemented. * evolution-calendar.idl (LoadStatus): Added an IN_USE error for create requests. * cal-listener.h (CalListenerLoadStatus): Added CAL_LISTENER_LOAD_IN_USE. * cal-listener.c (Listener_cal_loaded): Convert the IN_USE error. * cal-client.h (CalClientLoadStatus): Added CAL_CLIENT_LOAD_IN_USE. * cal-client.c (cal_loaded_cb): Handle CAL_LISTENER_LOAD_IN_USE. * tl-test.c: New test program for the calendar client side; it also exercises the server side by sending commands to it. * Makefile.am: Added the tl-test program. * tlacuache.gnorba: Updated. * tlacuache.c (create_cal_factory): Use the right GOAD id. * cal-client.c (cal_client_construct): Use the right GOAD id. svn path=/trunk/; revision=1732 --- calendar/ChangeLog | 174 ++++++++++++++++++++++++------- calendar/Makefile.am | 28 ++++- calendar/cal-backend.c | 182 +++++++++++++++++++++++++------- calendar/cal-backend.h | 2 + calendar/cal-client.c | 201 +++++++++++++++++++++++++++++------- calendar/cal-client.h | 4 +- calendar/cal-client/cal-client.c | 201 +++++++++++++++++++++++++++++------- calendar/cal-client/cal-client.h | 4 +- calendar/cal-client/cal-listener.c | 6 ++ calendar/cal-client/cal-listener.h | 3 +- calendar/cal-client/client-test.c | 148 ++++++++++++++++++++++++++ calendar/cal-factory.c | 159 ++++++++++++++++++++++++---- calendar/cal-listener.c | 6 ++ calendar/cal-listener.h | 3 +- calendar/cal-util/calobj.c | 2 +- calendar/cal.c | 2 + calendar/calobj.c | 2 +- calendar/evolution-calendar.idl | 7 +- calendar/gui/Makefile.am | 28 ++++- calendar/gui/test2.vcf | 133 ++++++++++++++++++++++++ calendar/html-month.c | 110 -------------------- calendar/idl/evolution-calendar.idl | 7 +- calendar/pcs/cal-backend.c | 182 +++++++++++++++++++++++++------- calendar/pcs/cal-backend.h | 2 + calendar/pcs/cal-factory.c | 159 ++++++++++++++++++++++++---- calendar/pcs/cal.c | 2 + calendar/pcs/calobj.c | 2 +- calendar/pcs/tlacuache.c | 2 +- calendar/pcs/tlacuache.gnorba | 4 +- calendar/test2.vcf | 133 ++++++++++++++++++++++++ calendar/tl-test.c | 148 ++++++++++++++++++++++++++ calendar/tlacuache.c | 2 +- calendar/tlacuache.gnorba | 4 +- 33 files changed, 1696 insertions(+), 356 deletions(-) create mode 100644 calendar/cal-client/client-test.c create mode 100644 calendar/gui/test2.vcf delete mode 100644 calendar/html-month.c create mode 100644 calendar/test2.vcf create mode 100644 calendar/tl-test.c diff --git a/calendar/ChangeLog b/calendar/ChangeLog index 7c210ad656..2982d7d689 100644 --- a/calendar/ChangeLog +++ b/calendar/ChangeLog @@ -1,3 +1,103 @@ +2000-02-10 Federico Mena Quintero + + * cal-backend.c (cal_backend_add_cal): Connect to the Cal's + destroy signal. + (cal_backend_remove_cal): Killed function now that removal of Cal + objects is done in their destroy callback. + (cal_destroy_cb): New callback to remove a Cal from the backend's + list of clients. Also, the backend destroys itself when there are + no more clients connected to it. + (save): New placeholder function to save a backend. + (destroy): New function to destroy a backend's data. + (cal_backend_destroy): Save the calendar and destroy it. + + * cal.c (cal_destroy): Reset the priv->backend to NULL. + + * cal-factory.c (add_calendar_client): There is no need to call + cal_backend_remove_cal(); we can now just destroy the Cal object. + (create_fn): Make sure we always unref the URI. + (load_fn): Move the URI unref to the end of the function for + safety. + + * cal-factory.c (add_calendar_client): Unref the Cal only if + notification of the listener was unsuccessful. Otherwise, the + calendar user agent (Listener side) keeps the reference. + + * tl-test.c (list_uids): Free the calobj. + + * cal-client.c (cal_loaded_cb): Use bonobo_object_unref() to get + rid of the listener. + (load_or_create): Likewise. + (destroy_factory): New function to get rid of the factory. + (destroy_listener): New function to get rid of the listener. + (destroy_cal): New function to get rid of the calendar client + interface object. + (cal_client_destroy): Free all resources. + (cal_client_get_object): CORBA_free() the calobj string. Boy, I + love memprof. + + * cal-listener.c (cal_listener_destroy): Reset the priv->cal to + CORBA_OBJECT_NIL. + + * cal-backend.c (cal_backend_remove_cal): Do not unref the Cal, + since the calendar user agent owns it. + (cal_backend_add_cal): Do not ref the Cal, since the calendar user + agent owns it. + + * cal-factory.c (add_calendar_client): Use bonobo_object_unref() + to get rid of the calendar client interface object. + + * calobj.c (ical_object_create_from_vobject): Duplicate the + default "PUBLIC" string. + +2000-02-09 Federico Mena Quintero + + * cal-factory.c (cal_factory_load): Added documentation comment. + (load_fn): Do not print a message if the backend could not be + loaded due to a non-fatal error. + (queue_load_create_job): Moved the stuff from cal_factory_load() + to here. Now this function serves to queue load or create + requests. + (cal_factory_load): Use queue_load_create_job(). + (cal_factory_create): Implemented; use queue_load_create_job(). + (create_fn): New job handler for creating new calendars. + (create_backend): New function to create a new backend with a new + calendar. + (add_backend): New helper function to add backends to the + factory's hash table. + (load_backend): Use add_backend() instead of adding the backend by + ourselves. + + * cal-client.c (load_or_create): Moved the functionality from + cal_client_load_calendar() to here, and added an option to create + a new calendar instead of loading an existing one. + (cal_client_load_calendar): Use load_or_create(). + (cal_client_create_calendar): Implemented. + + * cal-backend.c (cal_backend_create): Implemented. + + * evolution-calendar.idl (LoadStatus): Added an IN_USE error for + create requests. + + * cal-listener.h (CalListenerLoadStatus): Added CAL_LISTENER_LOAD_IN_USE. + + * cal-listener.c (Listener_cal_loaded): Convert the IN_USE error. + + * cal-client.h (CalClientLoadStatus): Added CAL_CLIENT_LOAD_IN_USE. + + * cal-client.c (cal_loaded_cb): Handle CAL_LISTENER_LOAD_IN_USE. + + * tl-test.c: New test program for the calendar client side; it + also exercises the server side by sending commands to it. + + * Makefile.am: Added the tl-test program. + + * tlacuache.gnorba: Updated. + + * tlacuache.c (create_cal_factory): Use the right GOAD id. + + * cal-client.c (cal_client_construct): Use the right GOAD id. + 2000-02-08 Federico Mena Quintero * evolution-calendar.idl (Cal): Added get_uids() method to get a @@ -325,13 +425,13 @@ 2000-01-08 Vadim Strizhevsky - * calendar-conduit-control-applet.c: Added pilotID argument to + * calendar-conduit-control-applet.c: Added pilotID argument to gpilotd_conduit_mgmt_new. 2000-01-05 Eskil Heyn Olsen - * GnomeCal.idl: Added an argument to get_number_of_objects, so you + * GnomeCal.idl: Added an argument to get_number_of_objects, so you can choose which state the object should have (any/new/modified/...). Will also add one to choose type (event/journal etc). @@ -357,7 +457,7 @@ (ee_rp_init_ending_date): And subtracts 86400 secs when about to redisplay the box. - * calendar.h: Added an argument to calendar_new, to enable certain + * calendar.h: Added an argument to calendar_new, to enable certain features, such as initing alarms or nor. * calendar.c (calendar_new): Implemented support for the @@ -451,7 +551,7 @@ * Merged todo list coloring patch from stable * Added myself to AUTHORS, about box (per Miguel) - + 1999-11-22 Eskil Heyn Olsen * calendar-conduit.c (pre_sync): Writes some warning @@ -465,7 +565,7 @@ 1999-11-12 Eskil Heyn Olsen * Makefile.am (extra_pilot_bins): Fixed the if then else problem, - using solution suggested by James Henstridge, appears to be caused + using solution suggested by James Henstridge, appears to be caused by a (by now fixed) bug in my automake. 1999-11-12 Russell Steinthal @@ -478,13 +578,13 @@ * eventedit.c: Give some static functions external linkage so they can be used elsewhere (make_spin_button); add some prototypes to - appease gcc. + appease gcc. 1999-11-11 Russell Steinthal * calendar.c (calendar_day_change): Add call to calendar_init_alarms() to schedule another day change alarm. - + 1999-11-09 Eskil Heyn Olsen * calendar-conduit.c: Enabled debug output. Sets a g_log_domain, @@ -572,9 +672,9 @@ * calendar-conduit.c: more _free calls, vamped the noise on output. 1999-10-06 Eskil Olsen - + * *conduit*[ch]: checks return values from gpilotd_init/connect. - + * calender.c (vcalendar_create_from_calendar): removed a set of cleanVObject cleanStrTbl, since the freed memory that the function returned. @@ -613,12 +713,12 @@ * corba-cal.c: the g_free that was commented out since glib said was a duplicate free, was supposed to be a free. - + * GnomeCal.idl/corba-cal.c: added a get_object_id_list and a get_objects_by_id_list. Latter is not done. * calendar-conduit.c: rewrote the way the conduit iterates over - records. It no longers fetches all entries (since that didn't work + records. It no longers fetches all entries (since that didn't work with more then 285 entries. It now fetches the id list, and gets each record. (will be using get_objects_by_id_list to get records in amounts of 10 or so later, to reduce amount of corba calls). @@ -652,7 +752,7 @@ * doc/C/gnomecal.sgml: Merge from gnome-pim-1-0. Synced with newest user-guide. - + 1999-09-01 Miguel de Icaza * eventedit.c (ee_create_buttons): Make the OK button the default @@ -665,10 +765,10 @@ (calendar_add_object): Ditto. Closes bug #676 - + * main.c (save_calendar_cmd): Fix problem in which we warned the user about the calendar being modified the first time the calendar - was used. + was used. 1999-08-22 Tomas Ogren @@ -686,7 +786,7 @@ 1999-07-30 Miguel de Icaza - * month-view.c (month_view_init): Release points here. + * month-view.c (month_view_init): Release points here. 1999-08-02 Peter Teichman @@ -732,10 +832,10 @@ (calendar_object_find_event): Use the hash table here. * main.c (save_calendar_cmd): The object is already destroyed by - gnome_dialog_run. + gnome_dialog_run. * calendar-pilot-sync.c (sync_object_to_pilot): Do not turn - archived bit on. + archived bit on. * calobj.c (ical_gen_uid): Use the hostname, not the domain name. (ical_gen_uid): Add a serial number. Isodates can be small. @@ -754,7 +854,7 @@ * calendar-pilot-sync.c: New file. Implements PalmPilot syncronization with the Gnome Calendar. - + * calobj.c (ical_object_new_from_string): New function. Creates an iCalObject from a vCalendar string that is supposed to contain only one vEvent. @@ -938,11 +1038,11 @@ 1999-04-16 Miguel de Icaza * gncal-todo.c (edit_activated): Kill all grabs from the CList - before running the new dialog box. + before running the new dialog box. This fixes the problem of button-3/Edit on the todo item blocking the GUI (actually, the main window responds, but not the todo - window). + window). 1999-04-08 Miguel de Icaza @@ -1073,7 +1173,7 @@ 1999-02-23 Miguel de Icaza * calobj.c (ical_object_to_vobject): Save the owner/organizer of - the event. + the event. (ical_object_create_from_vobject): Load the owner/organizer of the event. * gncal-full-day.c (delete_occurance): Assign child to data (fixes @@ -1083,7 +1183,7 @@ * calendar.c: According to configured values, use either tm.tm_zone or tzname. In last case, also declare it extern. - + * prop.c: langinfo.h not available everywhere. Wrapped. BTW, works fine without it. @@ -1095,17 +1195,17 @@ 1999-02-17 Sergey Panov * gnome-month-item.c,gnome-month-item.h,goto.c,mark.h, - month-view.c,prop.c,quick-view.c,year-view.c: will define + month-view.c,prop.c,quick-view.c,year-view.c: will define fonts via fontset. Friendlier to locales that use iso8859-[^1] and koi8-r encodings. Does not solve problem for Asian languiges --- better solution is needed (e.g. standart GNOME fontstyles - defined in gtkrc). - + defined in gtkrc). + 1999-02-16 Sergey Panov * main.c: Use N_() macro for color settings labels in color_props structure. - + 1999-02-15 Federico Mena Quintero * goto.c (goto_dialog): Indentation fixes. @@ -1120,11 +1220,11 @@ * main.c (save_default_calendar): New function. Saves the calendar if it is the user's default calendar - * gncal-full-day.c (unrecur_appointment): - * gncal-day-panel.c (day_view_range_activated): - * eventedit.c (ee_ok): + * gncal-full-day.c (unrecur_appointment): + * gncal-day-panel.c (day_view_range_activated): + * eventedit.c (ee_ok): * gncal-todo.c (ok_button): Added autosave for the default - calendar. + calendar. 1999-02-09 Tomas Ogren @@ -1174,7 +1274,7 @@ routine. Now it can split the text in lines and fit as many events as possible. (nicetime): Return strings without spaces at the beginning. - + * gncal-day-view.c (gncal_day_view_expose): Move clip-clear operation here. @@ -1227,7 +1327,7 @@ 1999-01-27 Miguel de Icaza * main.c (save_calendar_cmd): Warn if the calendar file has - changed. + changed. * calendar.c (calendar_load, calendar_save): Keep track of the modification time for the calendar file. @@ -1284,8 +1384,8 @@ Rewrote the old and broken alarm system. It never actually worked properly. Now it works properly, and I figured a nice way to get the Audio alarm do something nicer (it is now like an alarm - clock :-). - + clock :-). + * gnome-cal.c (calendar_notify): Now we take a CalendarAlarm to actually distinguish which alarm was triggered. @@ -1303,13 +1403,13 @@ 1998-12-09 Miguel de Icaza - * gncal-todo.c (simple_todo_editor): Use gnome_dialog_set_parent. + * gncal-todo.c (simple_todo_editor): Use gnome_dialog_set_parent. * goto.c (goto_dialog): ditto * prop.c (properties): ditto. 1998-11-23 Miguel de Icaza - * eventedit.c (ee_rp_init_exceptions): Update GtkClist usage. + * eventedit.c (ee_rp_init_exceptions): Update GtkClist usage. 1998-11-23 Andrew T. Veliath @@ -1319,7 +1419,7 @@ 1998-11-23 Herbert V. Riedel - * eventedit.c: use GPOINTER_TO_INT + * eventedit.c: use GPOINTER_TO_INT * gncal-todo.c: same. diff --git a/calendar/Makefile.am b/calendar/Makefile.am index 23bc461141..8fab42d57c 100644 --- a/calendar/Makefile.am +++ b/calendar/Makefile.am @@ -42,17 +42,17 @@ corba-cal.h \ corba-cal-factory.c \ corba-cal-factory.h: GnomeCal.h -GNOME_CALENDAR_CORBA_GENERATED = \ +EVOLUTION_CALENDAR_CORBA_GENERATED = \ evolution-calendar.h \ evolution-calendar-common.c \ evolution-calendar-skels.c \ evolution-calendar-stubs.c -$(GNOME_CALENDAR_CORBA_GENERATED): evolution-calendar.idl +$(EVOLUTION_CALENDAR_CORBA_GENERATED): evolution-calendar.idl orbit-idl -I`$(GNOME_CONFIG) --datadir`/idl $(srcdir)/evolution-calendar.idl gnomecal_SOURCES = \ - $(GNOME_CALENDAR_CORBA_GENERATED) \ + $(EVOLUTION_CALENDAR_CORBA_GENERATED) \ GnomeCal-common.c \ GnomeCal-skels.c \ GnomeCal.h \ @@ -125,7 +125,7 @@ calendar_pilot_sync_SOURCES = \ timeutil.h tlacuache_SOURCES = \ - $(GNOME_CALENDAR_CORBA_GENERATED) \ + $(EVOLUTION_CALENDAR_CORBA_GENERATED) \ alarm.c \ alarm.h \ cal.c \ @@ -162,6 +162,26 @@ calendar_pilot_sync_LDADD = \ $(PISOCK_LIBDIR) $(PISOCK_LIBS) \ $(LINK_FLAGS) +noinst_PROGRAMS = tl-test + +tl_test_SOURCES = \ + $(EVOLUTION_CALENDAR_CORBA_GENERATED) \ + cal-client.c \ + cal-client.h \ + cal-listener.c \ + cal-listener.h \ + cal-util.c \ + cal-util.h \ + tl-test.c + +tl_test_INCLUDES = \ + $(INCLUDES) \ + -DG_LOG_DOMAIN=\"tl-test\" + +tl_test_LDADD = \ + $(BONOBO_VFS_GNOME_LIBS) \ + ../libversit/libversit.la + if HAVE_GNOME_PILOT #calendar_conduit calendar_conduitsdir=$(libdir)/gnome-pilot/conduits diff --git a/calendar/cal-backend.c b/calendar/cal-backend.c index 17148cb048..18ed6a6c86 100644 --- a/calendar/cal-backend.c +++ b/calendar/cal-backend.c @@ -20,6 +20,7 @@ */ #include +#include #include "cal-backend.h" #include "calobj.h" #include "../libversit/vcc.h" @@ -36,7 +37,7 @@ typedef struct { /* URI where the calendar data is stored */ GnomeVFSURI *uri; - /* List of Cal client interface objects, each with its listener */ + /* List of Cal objects with their listeners */ GList *clients; /* All the iCalObject structures in the calendar, hashed by UID. The @@ -119,6 +120,55 @@ cal_backend_init (CalBackend *backend) backend->priv = priv; } +/* Saves a calendar */ +static void +save (CalBackend *backend) +{ + /* FIXME */ +} + +/* g_hash_table_foreach() callback to destroy an iCalObject */ +static void +free_ical_object (gpointer key, gpointer value, gpointer data) +{ + iCalObject *ico; + + ico = value; + ical_object_destroy (ico); +} + +/* Destroys a backend's data */ +static void +destroy (CalBackend *backend) +{ + CalBackendPrivate *priv; + + priv = backend->priv; + + if (priv->uri) { + gnome_vfs_uri_unref (priv->uri); + priv->uri = NULL; + } + + g_assert (priv->clients == NULL); + + if (priv->object_hash) { + g_hash_table_foreach (priv->object_hash, free_ical_object, NULL); + g_hash_table_destroy (priv->object_hash); + priv->object_hash = NULL; + } + + g_list_free (priv->events); + g_list_free (priv->todos); + g_list_free (priv->journals); + + priv->events = NULL; + priv->todos = NULL; + priv->journals = NULL; + + priv->loaded = FALSE; +} + /* Destroy handler for the calendar backend */ static void cal_backend_destroy (GtkObject *object) @@ -132,7 +182,10 @@ cal_backend_destroy (GtkObject *object) backend = CAL_BACKEND (object); priv = backend->priv; - /* FIXME: free stuff */ + if (priv->loaded) + save (backend); + + destroy (backend); g_free (priv); @@ -265,6 +318,11 @@ load_from_vobject (CalBackend *backend, VObject *vobject) ical = ical_object_create_from_vobject (this, object_name); + /* FIXME: some broken files may have duplicated UIDs. This is + * Bad(tm). Deal with it by creating new UIDs for them and + * spitting some messages to the console. + */ + if (ical) add_object (backend, ical); } @@ -364,45 +422,57 @@ cal_backend_get_uri (CalBackend *backend) return priv->uri; } -/** - * cal_backend_add_cal: - * @backend: A calendar backend. - * @cal: A calendar client interface object. - * - * Adds a calendar client interface object to a calendar @backend. The calendar - * backend must already have a loaded calendar. - **/ -void -cal_backend_add_cal (CalBackend *backend, Cal *cal) +/* Callback used when a Cal is destroyed */ +static void +cal_destroy_cb (GtkObject *object, gpointer data) { + Cal *cal; + Cal *lcal; + CalBackend *backend; CalBackendPrivate *priv; + GList *l; - g_return_if_fail (backend != NULL); - g_return_if_fail (IS_CAL_BACKEND (backend)); + cal = CAL (object); + backend = CAL_BACKEND (data); priv = backend->priv; - g_return_if_fail (priv->loaded); - g_return_if_fail (cal != NULL); - g_return_if_fail (IS_CAL (cal)); + /* Find the cal in the list of clients */ - gtk_object_ref (GTK_OBJECT (cal)); - priv->clients = g_list_prepend (priv->clients, cal); + for (l = priv->clients; l; l = l->next) { + lcal = CAL (l->data); + + if (lcal == cal) + break; + } + + g_assert (l != NULL); + + /* Disconnect */ + + priv->clients = g_list_remove_link (priv->clients, l); + g_list_free_1 (l); + + /* When all clients go away, the backend can go away, too. Commit + * suicide here. + */ + + if (!priv->clients) + gtk_object_unref (GTK_OBJECT (backend)); } /** - * cal_backend_remove_cal: + * cal_backend_add_cal: * @backend: A calendar backend. * @cal: A calendar client interface object. - * - * Removes a calendar client interface object from a calendar backend. The - * calendar backend must already have a loaded calendar. + * + * Adds a calendar client interface object to a calendar @backend. The calendar + * backend must already have a loaded calendar. **/ void -cal_backend_remove_cal (CalBackend *backend, Cal *cal) +cal_backend_add_cal (CalBackend *backend, Cal *cal) { CalBackendPrivate *priv; - GList *l; g_return_if_fail (backend != NULL); g_return_if_fail (IS_CAL_BACKEND (backend)); @@ -413,13 +483,15 @@ cal_backend_remove_cal (CalBackend *backend, Cal *cal) g_return_if_fail (cal != NULL); g_return_if_fail (IS_CAL (cal)); - l = g_list_find (priv->clients, cal); - if (!l) - return; + /* We do not keep a reference to the Cal since the calendar user agent + * owns it. + */ + + gtk_signal_connect (GTK_OBJECT (cal), "destroy", + GTK_SIGNAL_FUNC (cal_destroy_cb), + backend); - gtk_object_unref (GTK_OBJECT (cal)); - priv->clients = g_list_remove_link (priv->clients, l); - g_list_free_1 (l); + priv->clients = g_list_prepend (priv->clients, cal); } /** @@ -441,11 +513,12 @@ cal_backend_load (CalBackend *backend, GnomeVFSURI *uri) g_return_val_if_fail (backend != NULL, CAL_BACKEND_LOAD_ERROR); g_return_val_if_fail (IS_CAL_BACKEND (backend), CAL_BACKEND_LOAD_ERROR); - g_return_val_if_fail (uri != NULL, CAL_BACKEND_LOAD_ERROR); priv = backend->priv; g_return_val_if_fail (!priv->loaded, CAL_BACKEND_LOAD_ERROR); + g_return_val_if_fail (uri != NULL, CAL_BACKEND_LOAD_ERROR); + /* FIXME: this looks rather bad; maybe we should check for local files * and fail if they are remote. */ @@ -474,14 +547,47 @@ cal_backend_load (CalBackend *backend, GnomeVFSURI *uri) return CAL_BACKEND_LOAD_SUCCESS; } +/** + * cal_backend_create: + * @backend: A calendar backend. + * @uri: URI that will contain the calendar data. + * + * Creates a new empty calendar in a calendar backend. + **/ +void +cal_backend_create (CalBackend *backend, GnomeVFSURI *uri) +{ + CalBackendPrivate *priv; + + g_return_if_fail (backend != NULL); + g_return_if_fail (IS_CAL_BACKEND (backend)); + + priv = backend->priv; + g_return_if_fail (!priv->loaded); + + g_return_if_fail (uri != NULL); + + /* Create the new calendar information */ + + g_assert (priv->object_hash == NULL); + priv->object_hash = g_hash_table_new (g_str_hash, g_str_equal); + + /* Done */ + + gnome_vfs_uri_ref (uri); + + priv->uri = uri; + priv->loaded = TRUE; +} + /** * cal_backend_get_object: * @backend: A calendar backend. * @uid: Unique identifier for a calendar object. - * + * * Queries a calendar backend for a calendar object based on its unique * identifier. - * + * * Return value: The string representation of a complete calendar wrapping the * the sought object, or NULL if no object had the specified UID. A complete * calendar is returned because you also need the timezone data. @@ -560,10 +666,10 @@ build_uids_list (gpointer key, gpointer value, gpointer data) * cal_backend_get_uids: * @backend: A calendar backend. * @type: Bitmask with types of objects to return. - * + * * Builds a list of unique identifiers corresponding to calendar objects whose * type matches one of the types specified in the @type flags. - * + * * Return value: A list of strings that are the sought UIDs. **/ GList * @@ -639,11 +745,11 @@ compare_instance_func (gconstpointer a, gconstpointer b) * @backend: A calendar backend. * @start: Start time for query. * @end: End time for query. - * + * * Builds a sorted list of calendar event object instances that occur or recur * within the specified time range. Each object instance contains the object * itself and the start/end times at which it occurs or recurs. - * + * * Return value: A list of calendar event object instances, sorted by their * start times. **/ diff --git a/calendar/cal-backend.h b/calendar/cal-backend.h index 55c414d5f7..41b2b9186d 100644 --- a/calendar/cal-backend.h +++ b/calendar/cal-backend.h @@ -68,6 +68,8 @@ void cal_backend_remove_cal (CalBackend *backend, Cal *cal); CalBackendLoadStatus cal_backend_load (CalBackend *backend, GnomeVFSURI *uri); +void cal_backend_create (CalBackend *backend, GnomeVFSURI *uri); + char *cal_backend_get_object (CalBackend *backend, const char *uid); GList *cal_backend_get_uids (CalBackend *backend, CalObjType type); diff --git a/calendar/cal-client.c b/calendar/cal-client.c index edf2aa0a12..aa8cdcf50c 100644 --- a/calendar/cal-client.c +++ b/calendar/cal-client.c @@ -163,6 +163,94 @@ cal_client_init (CalClient *client) priv->load_state = LOAD_STATE_NOT_LOADED; } +/* Gets rid of the factory that a client knows about */ +static void +destroy_factory (CalClient *client) +{ + CalClientPrivate *priv; + CORBA_Environment ev; + int result; + + priv = client->priv; + + CORBA_exception_init (&ev); + result = CORBA_Object_is_nil (priv->factory, &ev); + if (ev._major != CORBA_NO_EXCEPTION) { + g_message ("destroy_factory(): could not see if the factory was nil"); + priv->factory = CORBA_OBJECT_NIL; + CORBA_exception_free (&ev); + return; + } + CORBA_exception_free (&ev); + + if (result) + return; + + CORBA_exception_init (&ev); + CORBA_Object_release (priv->factory, &ev); + if (ev._major != CORBA_NO_EXCEPTION) + g_message ("destroy_factory(): could not release the factory"); + + CORBA_exception_free (&ev); + priv->factory = CORBA_OBJECT_NIL; +} + +/* Gets rid of the listener that a client knows about */ +static void +destroy_listener (CalClient *client) +{ + CalClientPrivate *priv; + + priv = client->priv; + + if (!priv->listener) + return; + + bonobo_object_unref (BONOBO_OBJECT (priv->listener)); + priv->listener = NULL; +} + +/* Gets rid of the calendar client interface object that a client knows about */ +static void +destroy_cal (CalClient *client) +{ + CalClientPrivate *priv; + CORBA_Environment ev; + int result; + + priv = client->priv; + + CORBA_exception_init (&ev); + result = CORBA_Object_is_nil (priv->cal, &ev); + if (ev._major != CORBA_NO_EXCEPTION) { + g_message ("destroy_cal(): could not see if the " + "calendar client interface object was nil"); + priv->cal = CORBA_OBJECT_NIL; + CORBA_exception_free (&ev); + return; + } + CORBA_exception_free (&ev); + + if (result) + return; + + CORBA_exception_init (&ev); + Evolution_Calendar_Cal_unref (priv->cal, &ev); + if (ev._major != CORBA_NO_EXCEPTION) + g_message ("destroy_cal(): could not unref the calendar client interface object"); + + CORBA_exception_free (&ev); + + CORBA_exception_init (&ev); + CORBA_Object_release (priv->cal, &ev); + if (ev._major != CORBA_NO_EXCEPTION) + g_message ("destroy_cal(): could not release the calendar client interface object"); + + CORBA_exception_free (&ev); + priv->cal = CORBA_OBJECT_NIL; + +} + /* Destroy handler for the calendar client */ static void cal_client_destroy (GtkObject *object) @@ -176,7 +264,11 @@ cal_client_destroy (GtkObject *object) client = CAL_CLIENT (object); priv = client->priv; - /* FIXME */ + destroy_factory (client); + destroy_listener (client); + destroy_cal (client); + + priv->load_state = LOAD_STATE_NOT_LOADED; g_free (priv); @@ -199,12 +291,15 @@ cal_loaded_cb (CalListener *listener, CalClientPrivate *priv; CORBA_Environment ev; Evolution_Calendar_Cal cal_copy; + CalClientLoadStatus client_status; client = CAL_CLIENT (data); priv = client->priv; g_assert (priv->load_state == LOAD_STATE_LOADING); + client_status = CAL_CLIENT_LOAD_ERROR; + switch (status) { case CAL_LISTENER_LOAD_SUCCESS: CORBA_exception_init (&ev); @@ -219,11 +314,15 @@ cal_loaded_cb (CalListener *listener, priv->cal = cal_copy; priv->load_state = LOAD_STATE_LOADED; - gtk_signal_emit (GTK_OBJECT (client), cal_client_signals[CAL_LOADED], - CAL_CLIENT_LOAD_SUCCESS); + client_status = CAL_CLIENT_LOAD_SUCCESS; goto out; case CAL_LISTENER_LOAD_ERROR: + client_status = CAL_CLIENT_LOAD_ERROR; + goto error; + + case CAL_LISTENER_LOAD_IN_USE: + client_status = CAL_CLIENT_LOAD_IN_USE; goto error; default: @@ -232,15 +331,16 @@ cal_loaded_cb (CalListener *listener, error: - gtk_object_unref (GTK_OBJECT (priv->listener)); + bonobo_object_unref (BONOBO_OBJECT (priv->listener)); priv->listener = NULL; priv->load_state = LOAD_STATE_NOT_LOADED; - gtk_signal_emit (GTK_OBJECT (client), cal_client_signals[CAL_LOADED], - CAL_CLIENT_LOAD_ERROR); - out: + g_assert (priv->load_state != LOAD_STATE_LOADING); + + gtk_signal_emit (GTK_OBJECT (client), cal_client_signals[CAL_LOADED], + client_status); } /* Handle the obj_added signal from the listener */ @@ -278,10 +378,10 @@ obj_changed_cb (CalListener *listener, const Evolution_Calendar_CalObjUID uid, g /** * cal_client_construct: * @client: A calendar client. - * + * * Constructs a calendar client object by contacting the calendar factory of the * calendar server. - * + * * Return value: The same object as the @client argument, or NULL if the * calendar factory could not be contacted. **/ @@ -300,7 +400,7 @@ cal_client_construct (CalClient *client) factory = (Evolution_Calendar_CalFactory) goad_server_activate_with_id ( NULL, - "calendar:cal-factory", + "evolution:calendar-factory", GOAD_ACTIVATE_REMOTE, NULL); @@ -335,11 +435,11 @@ cal_client_construct (CalClient *client) /** * cal_client_new: - * @void: - * + * @void: + * * Creates a new calendar client. It should be initialized by calling * cal_client_load_calendar() or cal_client_create_calendar(). - * + * * Return value: A newly-created calendar client, or NULL if the client could * not be constructed because it could not contact the calendar server. **/ @@ -359,19 +459,9 @@ cal_client_new (void) return client; } -/** - * cal_client_load_calendar: - * @client: A calendar client. - * @str_uri: URI of calendar to load. - * - * Makes a calendar client initiate a request to load a calendar. The calendar - * client will emit the "cal_loaded" signal when the response from the server is - * received. - * - * Return value: TRUE on success, FALSE on failure to issue the load request. - **/ -gboolean -cal_client_load_calendar (CalClient *client, const char *str_uri) +/* Issues a load or create request */ +static gboolean +load_or_create (CalClient *client, const char *str_uri, gboolean load) { CalClientPrivate *priv; Evolution_Calendar_Listener corba_listener; @@ -387,7 +477,7 @@ cal_client_load_calendar (CalClient *client, const char *str_uri) priv->listener = cal_listener_new (); if (!priv->listener) { - g_message ("cal_client_load_calendar(): could not create the listener"); + g_message ("load_or_create(): could not create the listener"); return FALSE; } @@ -410,11 +500,15 @@ cal_client_load_calendar (CalClient *client, const char *str_uri) CORBA_exception_init (&ev); priv->load_state = LOAD_STATE_LOADING; - Evolution_Calendar_CalFactory_load (priv->factory, str_uri, corba_listener, &ev); + + if (load) + Evolution_Calendar_CalFactory_load (priv->factory, str_uri, corba_listener, &ev); + else + Evolution_Calendar_CalFactory_create (priv->factory, str_uri, corba_listener, &ev); if (ev._major != CORBA_NO_EXCEPTION) { - g_message ("cal_client_load_calendar(): load request failed"); - gtk_object_unref (GTK_OBJECT (priv->listener)); + g_message ("load_or_create(): load/create request failed"); + bonobo_object_unref (BONOBO_OBJECT (priv->listener)); priv->listener = NULL; priv->load_state = LOAD_STATE_NOT_LOADED; CORBA_exception_free (&ev); @@ -425,13 +519,47 @@ cal_client_load_calendar (CalClient *client, const char *str_uri) return TRUE; } +/** + * cal_client_load_calendar: + * @client: A calendar client. + * @str_uri: URI of calendar to load. + * + * Makes a calendar client initiate a request to load a calendar. The calendar + * client will emit the "cal_loaded" signal when the response from the server is + * received. + * + * Return value: TRUE on success, FALSE on failure to issue the load request. + **/ +gboolean +cal_client_load_calendar (CalClient *client, const char *str_uri) +{ + return load_or_create (client, str_uri, TRUE); +} + +/** + * cal_client_create_calendar: + * @client: A calendar client. + * @str_uri: URI that will contain the calendar data. + * + * Makes a calendar client initiate a request to create a new calendar. The + * calendar client will emit the "cal_loaded" signal when the response from the + * server is received. + * + * Return value: TRUE on success, FALSE on failure to issue the create request. + **/ +gboolean +cal_client_create_calendar (CalClient *client, const char *str_uri) +{ + return load_or_create (client, str_uri, FALSE); +} + /** * cal_client_get_object: * @client: A calendar client. * @uid: Unique identifier for a calendar object. - * + * * Queries a calendar for a calendar object based on its unique identifier. - * + * * Return value: The string representation of a complete calendar wrapping the * sought object, or NULL if no object had the specified UID. A complete * calendar is returned because you also need the timezone data. @@ -466,6 +594,7 @@ cal_client_get_object (CalClient *client, const char *uid) } retval = g_strdup (calobj); + CORBA_free (calobj); out: CORBA_exception_free (&ev); @@ -476,10 +605,10 @@ cal_client_get_object (CalClient *client, const char *uid) * cal_client_get_uids: * @client: A calendar client. * @type: Bitmask with types of objects to return. - * + * * Queries a calendar for a list of unique identifiers corresponding to calendar * objects whose type matches one of the types specified in the @type flags. - * + * * Return value: A list of strings that are the sought UIDs. **/ GList * @@ -530,10 +659,10 @@ cal_client_get_uids (CalClient *client, CalObjType type) * @client: A calendar client. * @start: Start time for query. * @end: End time for query. - * + * * Queries a calendar for the events that occur or recur in the specified range * of time. - * + * * Return value: A list of #CalObjInstance structures. **/ GList * diff --git a/calendar/cal-client.h b/calendar/cal-client.h index 738d013f35..0c4c3e4406 100644 --- a/calendar/cal-client.h +++ b/calendar/cal-client.h @@ -42,7 +42,8 @@ typedef struct _CalClientClass CalClientClass; /* Load status for the cal_loaded signal */ typedef enum { CAL_CLIENT_LOAD_SUCCESS, - CAL_CLIENT_LOAD_ERROR + CAL_CLIENT_LOAD_ERROR, + CAL_CLIENT_LOAD_IN_USE } CalClientLoadStatus; struct _CalClient { @@ -71,6 +72,7 @@ CalClient *cal_client_construct (CalClient *client); CalClient *cal_client_new (void); gboolean cal_client_load_calendar (CalClient *client, const char *str_uri); +gboolean cal_client_create_calendar (CalClient *client, const char *str_uri); char *cal_client_get_object (CalClient *client, const char *uid); diff --git a/calendar/cal-client/cal-client.c b/calendar/cal-client/cal-client.c index edf2aa0a12..aa8cdcf50c 100644 --- a/calendar/cal-client/cal-client.c +++ b/calendar/cal-client/cal-client.c @@ -163,6 +163,94 @@ cal_client_init (CalClient *client) priv->load_state = LOAD_STATE_NOT_LOADED; } +/* Gets rid of the factory that a client knows about */ +static void +destroy_factory (CalClient *client) +{ + CalClientPrivate *priv; + CORBA_Environment ev; + int result; + + priv = client->priv; + + CORBA_exception_init (&ev); + result = CORBA_Object_is_nil (priv->factory, &ev); + if (ev._major != CORBA_NO_EXCEPTION) { + g_message ("destroy_factory(): could not see if the factory was nil"); + priv->factory = CORBA_OBJECT_NIL; + CORBA_exception_free (&ev); + return; + } + CORBA_exception_free (&ev); + + if (result) + return; + + CORBA_exception_init (&ev); + CORBA_Object_release (priv->factory, &ev); + if (ev._major != CORBA_NO_EXCEPTION) + g_message ("destroy_factory(): could not release the factory"); + + CORBA_exception_free (&ev); + priv->factory = CORBA_OBJECT_NIL; +} + +/* Gets rid of the listener that a client knows about */ +static void +destroy_listener (CalClient *client) +{ + CalClientPrivate *priv; + + priv = client->priv; + + if (!priv->listener) + return; + + bonobo_object_unref (BONOBO_OBJECT (priv->listener)); + priv->listener = NULL; +} + +/* Gets rid of the calendar client interface object that a client knows about */ +static void +destroy_cal (CalClient *client) +{ + CalClientPrivate *priv; + CORBA_Environment ev; + int result; + + priv = client->priv; + + CORBA_exception_init (&ev); + result = CORBA_Object_is_nil (priv->cal, &ev); + if (ev._major != CORBA_NO_EXCEPTION) { + g_message ("destroy_cal(): could not see if the " + "calendar client interface object was nil"); + priv->cal = CORBA_OBJECT_NIL; + CORBA_exception_free (&ev); + return; + } + CORBA_exception_free (&ev); + + if (result) + return; + + CORBA_exception_init (&ev); + Evolution_Calendar_Cal_unref (priv->cal, &ev); + if (ev._major != CORBA_NO_EXCEPTION) + g_message ("destroy_cal(): could not unref the calendar client interface object"); + + CORBA_exception_free (&ev); + + CORBA_exception_init (&ev); + CORBA_Object_release (priv->cal, &ev); + if (ev._major != CORBA_NO_EXCEPTION) + g_message ("destroy_cal(): could not release the calendar client interface object"); + + CORBA_exception_free (&ev); + priv->cal = CORBA_OBJECT_NIL; + +} + /* Destroy handler for the calendar client */ static void cal_client_destroy (GtkObject *object) @@ -176,7 +264,11 @@ cal_client_destroy (GtkObject *object) client = CAL_CLIENT (object); priv = client->priv; - /* FIXME */ + destroy_factory (client); + destroy_listener (client); + destroy_cal (client); + + priv->load_state = LOAD_STATE_NOT_LOADED; g_free (priv); @@ -199,12 +291,15 @@ cal_loaded_cb (CalListener *listener, CalClientPrivate *priv; CORBA_Environment ev; Evolution_Calendar_Cal cal_copy; + CalClientLoadStatus client_status; client = CAL_CLIENT (data); priv = client->priv; g_assert (priv->load_state == LOAD_STATE_LOADING); + client_status = CAL_CLIENT_LOAD_ERROR; + switch (status) { case CAL_LISTENER_LOAD_SUCCESS: CORBA_exception_init (&ev); @@ -219,11 +314,15 @@ cal_loaded_cb (CalListener *listener, priv->cal = cal_copy; priv->load_state = LOAD_STATE_LOADED; - gtk_signal_emit (GTK_OBJECT (client), cal_client_signals[CAL_LOADED], - CAL_CLIENT_LOAD_SUCCESS); + client_status = CAL_CLIENT_LOAD_SUCCESS; goto out; case CAL_LISTENER_LOAD_ERROR: + client_status = CAL_CLIENT_LOAD_ERROR; + goto error; + + case CAL_LISTENER_LOAD_IN_USE: + client_status = CAL_CLIENT_LOAD_IN_USE; goto error; default: @@ -232,15 +331,16 @@ cal_loaded_cb (CalListener *listener, error: - gtk_object_unref (GTK_OBJECT (priv->listener)); + bonobo_object_unref (BONOBO_OBJECT (priv->listener)); priv->listener = NULL; priv->load_state = LOAD_STATE_NOT_LOADED; - gtk_signal_emit (GTK_OBJECT (client), cal_client_signals[CAL_LOADED], - CAL_CLIENT_LOAD_ERROR); - out: + g_assert (priv->load_state != LOAD_STATE_LOADING); + + gtk_signal_emit (GTK_OBJECT (client), cal_client_signals[CAL_LOADED], + client_status); } /* Handle the obj_added signal from the listener */ @@ -278,10 +378,10 @@ obj_changed_cb (CalListener *listener, const Evolution_Calendar_CalObjUID uid, g /** * cal_client_construct: * @client: A calendar client. - * + * * Constructs a calendar client object by contacting the calendar factory of the * calendar server. - * + * * Return value: The same object as the @client argument, or NULL if the * calendar factory could not be contacted. **/ @@ -300,7 +400,7 @@ cal_client_construct (CalClient *client) factory = (Evolution_Calendar_CalFactory) goad_server_activate_with_id ( NULL, - "calendar:cal-factory", + "evolution:calendar-factory", GOAD_ACTIVATE_REMOTE, NULL); @@ -335,11 +435,11 @@ cal_client_construct (CalClient *client) /** * cal_client_new: - * @void: - * + * @void: + * * Creates a new calendar client. It should be initialized by calling * cal_client_load_calendar() or cal_client_create_calendar(). - * + * * Return value: A newly-created calendar client, or NULL if the client could * not be constructed because it could not contact the calendar server. **/ @@ -359,19 +459,9 @@ cal_client_new (void) return client; } -/** - * cal_client_load_calendar: - * @client: A calendar client. - * @str_uri: URI of calendar to load. - * - * Makes a calendar client initiate a request to load a calendar. The calendar - * client will emit the "cal_loaded" signal when the response from the server is - * received. - * - * Return value: TRUE on success, FALSE on failure to issue the load request. - **/ -gboolean -cal_client_load_calendar (CalClient *client, const char *str_uri) +/* Issues a load or create request */ +static gboolean +load_or_create (CalClient *client, const char *str_uri, gboolean load) { CalClientPrivate *priv; Evolution_Calendar_Listener corba_listener; @@ -387,7 +477,7 @@ cal_client_load_calendar (CalClient *client, const char *str_uri) priv->listener = cal_listener_new (); if (!priv->listener) { - g_message ("cal_client_load_calendar(): could not create the listener"); + g_message ("load_or_create(): could not create the listener"); return FALSE; } @@ -410,11 +500,15 @@ cal_client_load_calendar (CalClient *client, const char *str_uri) CORBA_exception_init (&ev); priv->load_state = LOAD_STATE_LOADING; - Evolution_Calendar_CalFactory_load (priv->factory, str_uri, corba_listener, &ev); + + if (load) + Evolution_Calendar_CalFactory_load (priv->factory, str_uri, corba_listener, &ev); + else + Evolution_Calendar_CalFactory_create (priv->factory, str_uri, corba_listener, &ev); if (ev._major != CORBA_NO_EXCEPTION) { - g_message ("cal_client_load_calendar(): load request failed"); - gtk_object_unref (GTK_OBJECT (priv->listener)); + g_message ("load_or_create(): load/create request failed"); + bonobo_object_unref (BONOBO_OBJECT (priv->listener)); priv->listener = NULL; priv->load_state = LOAD_STATE_NOT_LOADED; CORBA_exception_free (&ev); @@ -425,13 +519,47 @@ cal_client_load_calendar (CalClient *client, const char *str_uri) return TRUE; } +/** + * cal_client_load_calendar: + * @client: A calendar client. + * @str_uri: URI of calendar to load. + * + * Makes a calendar client initiate a request to load a calendar. The calendar + * client will emit the "cal_loaded" signal when the response from the server is + * received. + * + * Return value: TRUE on success, FALSE on failure to issue the load request. + **/ +gboolean +cal_client_load_calendar (CalClient *client, const char *str_uri) +{ + return load_or_create (client, str_uri, TRUE); +} + +/** + * cal_client_create_calendar: + * @client: A calendar client. + * @str_uri: URI that will contain the calendar data. + * + * Makes a calendar client initiate a request to create a new calendar. The + * calendar client will emit the "cal_loaded" signal when the response from the + * server is received. + * + * Return value: TRUE on success, FALSE on failure to issue the create request. + **/ +gboolean +cal_client_create_calendar (CalClient *client, const char *str_uri) +{ + return load_or_create (client, str_uri, FALSE); +} + /** * cal_client_get_object: * @client: A calendar client. * @uid: Unique identifier for a calendar object. - * + * * Queries a calendar for a calendar object based on its unique identifier. - * + * * Return value: The string representation of a complete calendar wrapping the * sought object, or NULL if no object had the specified UID. A complete * calendar is returned because you also need the timezone data. @@ -466,6 +594,7 @@ cal_client_get_object (CalClient *client, const char *uid) } retval = g_strdup (calobj); + CORBA_free (calobj); out: CORBA_exception_free (&ev); @@ -476,10 +605,10 @@ cal_client_get_object (CalClient *client, const char *uid) * cal_client_get_uids: * @client: A calendar client. * @type: Bitmask with types of objects to return. - * + * * Queries a calendar for a list of unique identifiers corresponding to calendar * objects whose type matches one of the types specified in the @type flags. - * + * * Return value: A list of strings that are the sought UIDs. **/ GList * @@ -530,10 +659,10 @@ cal_client_get_uids (CalClient *client, CalObjType type) * @client: A calendar client. * @start: Start time for query. * @end: End time for query. - * + * * Queries a calendar for the events that occur or recur in the specified range * of time. - * + * * Return value: A list of #CalObjInstance structures. **/ GList * diff --git a/calendar/cal-client/cal-client.h b/calendar/cal-client/cal-client.h index 738d013f35..0c4c3e4406 100644 --- a/calendar/cal-client/cal-client.h +++ b/calendar/cal-client/cal-client.h @@ -42,7 +42,8 @@ typedef struct _CalClientClass CalClientClass; /* Load status for the cal_loaded signal */ typedef enum { CAL_CLIENT_LOAD_SUCCESS, - CAL_CLIENT_LOAD_ERROR + CAL_CLIENT_LOAD_ERROR, + CAL_CLIENT_LOAD_IN_USE } CalClientLoadStatus; struct _CalClient { @@ -71,6 +72,7 @@ CalClient *cal_client_construct (CalClient *client); CalClient *cal_client_new (void); gboolean cal_client_load_calendar (CalClient *client, const char *str_uri); +gboolean cal_client_create_calendar (CalClient *client, const char *str_uri); char *cal_client_get_object (CalClient *client, const char *uid); diff --git a/calendar/cal-client/cal-listener.c b/calendar/cal-client/cal-listener.c index fee7e96024..32024d04f5 100644 --- a/calendar/cal-client/cal-listener.c +++ b/calendar/cal-client/cal-listener.c @@ -187,6 +187,8 @@ cal_listener_destroy (GtkObject *object) if (ev._major != CORBA_NO_EXCEPTION) g_message ("cal_listener_destroy(): could not release the calendar"); + + priv->cal = CORBA_OBJECT_NIL; } CORBA_exception_free (&ev); @@ -257,6 +259,10 @@ Listener_cal_loaded (PortableServer_Servant servant, load_status = CAL_LISTENER_LOAD_ERROR; break; + case Evolution_Calendar_Listener_IN_USE: + load_status = CAL_LISTENER_LOAD_IN_USE; + break; + default: load_status = CAL_LISTENER_LOAD_ERROR; /* keep gcc happy */ g_assert_not_reached (); diff --git a/calendar/cal-client/cal-listener.h b/calendar/cal-client/cal-listener.h index 8988148f34..52b934e774 100644 --- a/calendar/cal-client/cal-listener.h +++ b/calendar/cal-client/cal-listener.h @@ -43,7 +43,8 @@ typedef struct _CalListenerClass CalListenerClass; /* Load status for the cal_loaded signal. We need better error reporting. */ typedef enum { CAL_LISTENER_LOAD_SUCCESS, - CAL_LISTENER_LOAD_ERROR + CAL_LISTENER_LOAD_ERROR, + CAL_LISTENER_LOAD_IN_USE } CalListenerLoadStatus; struct _CalListener { diff --git a/calendar/cal-client/client-test.c b/calendar/cal-client/client-test.c new file mode 100644 index 0000000000..bebaa42d87 --- /dev/null +++ b/calendar/cal-client/client-test.c @@ -0,0 +1,148 @@ +#include +#include +#include +#include "cal-client.h" + +static CalClient *client1; +static CalClient *client2; + +/* Prints a message with a client identifier */ +static void +cl_printf (CalClient *client, const char *format, ...) +{ + va_list args; + + va_start (args, format); + printf ("Client %s: ", + client == client1 ? "1" : + client == client2 ? "2" : + "UNKNOWN"); + vprintf (format, args); + va_end (args); +} + +/* Lists the UIDs of objects in a calendar, called as an idle handler */ +static gboolean +list_uids (gpointer data) +{ + CalClient *client; + GList *uids; + GList *l; + + client = CAL_CLIENT (data); + + uids = cal_client_get_uids (client, CALOBJ_TYPE_ANY); + + cl_printf (client, "UIDs: "); + + if (!uids) + printf ("none\n"); + else { + for (l = uids; l; l = l->next) { + char *uid; + + uid = l->data; + printf ("`%s' ", uid); + } + + printf ("\n"); + + for (l = uids; l; l = l->next) { + char *uid; + char *calobj; + + uid = l->data; + calobj = cal_client_get_object (client, uid); + + printf ("------------------------------\n%s", calobj); + printf ("------------------------------\n"); + + g_free (calobj); + } + } + + cal_obj_uid_list_free (uids); + + gtk_object_unref (GTK_OBJECT (client)); + + return FALSE; +} + +/* Callback used when a calendar is loaded */ +static void +cal_loaded (CalClient *client, CalClientLoadStatus status, gpointer data) +{ + cl_printf (client, "Load/create %s\n", + ((status == CAL_CLIENT_LOAD_SUCCESS) ? "success" : + (status == CAL_CLIENT_LOAD_ERROR) ? "error" : + (status == CAL_CLIENT_LOAD_IN_USE) ? "in use" : + "unknown status value")); + + if (status == CAL_CLIENT_LOAD_SUCCESS) + g_idle_add (list_uids, client); + else + gtk_object_unref (GTK_OBJECT (client)); +} + +/* Creates a calendar client and tries to load the specified URI into it */ +static CalClient * +create_client (const char *uri, gboolean load) +{ + CalClient *client; + gboolean result; + + client = cal_client_new (); + if (!client) { + g_message ("create_client(): could not create the client"); + exit (1); + } + + gtk_signal_connect (GTK_OBJECT (client), "cal_loaded", + GTK_SIGNAL_FUNC (cal_loaded), + NULL); + + printf ("Calendar loading `%s'...\n", uri); + + if (load) + result = cal_client_load_calendar (client, uri); + else + result = cal_client_create_calendar (client, uri); + + if (!result) { + g_message ("create_client(): failure when issuing calendar load/create request `%s'", + uri); + exit (1); + } + + return client; +} + +int +main (int argc, char **argv) +{ + CORBA_Environment ev; + + bindtextdomain (PACKAGE, GNOMELOCALEDIR); + textdomain (PACKAGE); + + CORBA_exception_init (&ev); + gnome_CORBA_init ("tl-test", VERSION, &argc, argv, 0, &ev); + if (ev._major != CORBA_NO_EXCEPTION) { + g_message ("main(): could not initialize the ORB"); + CORBA_exception_free (&ev); + exit (1); + } + CORBA_exception_free (&ev); + + if (!bonobo_init (CORBA_OBJECT_NIL, CORBA_OBJECT_NIL, CORBA_OBJECT_NIL)) { + g_message ("main(): could not initialize Bonobo"); + exit (1); + } + + client1 = create_client ("/cvs/evolution/calendar/test2.vcf", TRUE); + client2 = create_client ("/cvs/evolution/calendar/test2.vcf", FALSE); + + bonobo_main (); + + return 0; +} diff --git a/calendar/cal-factory.c b/calendar/cal-factory.c index d5b79ef423..14b7ac9cb6 100644 --- a/calendar/cal-factory.c +++ b/calendar/cal-factory.c @@ -244,9 +244,24 @@ lookup_backend (CalFactory *factory, GnomeVFSURI *uri) return backend; } +/* Adds a backend to the calendar factory's hash table */ +static void +add_backend (CalFactory *factory, GnomeVFSURI *uri, CalBackend *backend) +{ + CalFactoryPrivate *priv; + + priv = factory->priv; + + gnome_vfs_uri_ref (uri); + g_hash_table_insert (priv->backends, uri, backend); + /* FIXME: connect to destroy on the backend and remove it from + * the hash table when it dies. + */ +} + /* Loads a calendar backend and puts it in the factory's backend hash table */ static CalBackend * -load_backend (CalFactory *factory, GnomeVFSURI *uri, Evolution_Calendar_Listener listener) +load_backend (CalFactory *factory, GnomeVFSURI *uri) { CalFactoryPrivate *priv; CalBackend *backend; @@ -264,9 +279,7 @@ load_backend (CalFactory *factory, GnomeVFSURI *uri, Evolution_Calendar_Listener switch (status) { case CAL_BACKEND_LOAD_SUCCESS: - gnome_vfs_uri_ref (uri); - g_hash_table_insert (priv->backends, uri, backend); - + add_backend (factory, uri, backend); return backend; case CAL_BACKEND_LOAD_ERROR: @@ -279,6 +292,27 @@ load_backend (CalFactory *factory, GnomeVFSURI *uri, Evolution_Calendar_Listener } } +/* Creates a calendar backend and puts it in the factory's backend hash table */ +static CalBackend * +create_backend (CalFactory *factory, GnomeVFSURI *uri) +{ + CalFactoryPrivate *priv; + CalBackend *backend; + + priv = factory->priv; + + backend = cal_backend_new (); + if (!backend) { + g_message ("create_backend(): could not create the backend"); + return NULL; + } + + cal_backend_create (backend, uri); + add_backend (factory, uri, backend); + + return backend; +} + /* Adds a listener to a calendar backend by creating a calendar client interface * object. */ @@ -314,10 +348,8 @@ add_calendar_client (CalFactory *factory, CalBackend *backend, Evolution_Calenda if (ev._major != CORBA_NO_EXCEPTION) { g_message ("add_calendar_client(): could not notify the listener"); - cal_backend_remove_cal (backend, cal); + bonobo_object_unref (BONOBO_OBJECT (cal)); } - - gtk_object_unref (GTK_OBJECT (cal)); } /* Job handler for the load calendar command */ @@ -342,15 +374,14 @@ load_fn (gpointer data) listener = jd->listener; g_free (jd); + /* Look up the backend and create it if needed */ + backend = lookup_backend (factory, uri); if (!backend) - backend = load_backend (factory, uri, listener); - - gnome_vfs_uri_unref (uri); + backend = load_backend (factory, uri); if (!backend) { - g_message ("load_fn(): could not load the backend"); CORBA_exception_init (&ev); Evolution_Calendar_Listener_cal_loaded (listener, Evolution_Calendar_Listener_ERROR, @@ -368,6 +399,8 @@ load_fn (gpointer data) out: + gnome_vfs_uri_unref (uri); + CORBA_exception_init (&ev); CORBA_Object_release (listener, &ev); @@ -377,6 +410,78 @@ load_fn (gpointer data) CORBA_exception_free (&ev); } +/* Job handler for the create calendar command */ +static void +create_fn (gpointer data) +{ + LoadCreateJobData *jd; + CalFactory *factory; + GnomeVFSURI *uri; + Evolution_Calendar_Listener listener; + CalBackend *backend; + CORBA_Environment ev; + + jd = data; + factory = jd->factory; + + uri = gnome_vfs_uri_new (jd->uri); + g_free (jd->uri); + + factory = jd->factory; + listener = jd->listener; + g_free (jd); + + /* Check that the backend is not in use */ + + backend = lookup_backend (factory, uri); + + if (backend) { + CORBA_exception_init (&ev); + Evolution_Calendar_Listener_cal_loaded (listener, + Evolution_Calendar_Listener_IN_USE, + CORBA_OBJECT_NIL, + &ev); + + if (ev._major != CORBA_NO_EXCEPTION) + g_message ("create_fn(): could not notify the listener"); + + CORBA_exception_free (&ev); + goto out; + } + + /* Create the backend */ + + backend = create_backend (factory, uri); + + if (!backend) { + CORBA_exception_init (&ev); + Evolution_Calendar_Listener_cal_loaded (listener, + Evolution_Calendar_Listener_ERROR, + CORBA_OBJECT_NIL, + &ev); + + if (ev._major != CORBA_NO_EXCEPTION) + g_message ("create_fn(): could not notify the listener"); + + CORBA_exception_free (&ev); + goto out; + } + + add_calendar_client (factory, backend, listener); + + out: + + gnome_vfs_uri_unref (uri); + + CORBA_exception_init (&ev); + CORBA_Object_release (listener, &ev); + + if (ev._major != CORBA_NO_EXCEPTION) + g_message ("create_fn(): could not release the listener"); + + CORBA_exception_free (&ev); +} + /** @@ -470,8 +575,10 @@ cal_factory_new (void) return cal_factory_construct (factory, corba_factory); } -void -cal_factory_load (CalFactory *factory, const char *uri, Evolution_Calendar_Listener listener) +/* Queues a load or create request */ +static void +queue_load_create_job (CalFactory *factory, const char *uri, Evolution_Calendar_Listener listener, + JobFunc func) { LoadCreateJobData *jd; CORBA_Environment ev; @@ -481,21 +588,21 @@ cal_factory_load (CalFactory *factory, const char *uri, Evolution_Calendar_Liste CORBA_exception_init (&ev); result = CORBA_Object_is_nil (listener, &ev); if (ev._major != CORBA_NO_EXCEPTION) { - g_message ("cal_factory_load(): could not see if the listener was NIL"); + g_message ("queue_load_create_job(): could not see if the listener was NIL"); CORBA_exception_free (&ev); return; } CORBA_exception_free (&ev); if (result) { - g_message ("cal_factory_load(): cannot operate on a NIL listener!"); + g_message ("queue_load_create_job(): cannot operate on a NIL listener!"); return; } listener_copy = CORBA_Object_duplicate (listener, &ev); if (ev._major != CORBA_NO_EXCEPTION) { - g_message ("cal_factory_load(): could not duplicate the listener"); + g_message ("queue_load_create_job(): could not duplicate the listener"); CORBA_exception_free (&ev); return; } @@ -507,11 +614,27 @@ cal_factory_load (CalFactory *factory, const char *uri, Evolution_Calendar_Liste jd->uri = g_strdup (uri); jd->listener = listener_copy; - job_add (load_fn, jd); + job_add (func, jd); +} + +/** + * cal_factory_load: + * @factory: A calendar factory. + * @uri: URI of calendar to load. + * @listener: Listener for notification of the load result. + * + * Initiates a load request in a calendar factory. A calendar will be loaded + * asynchronously and the result code will be reported to the specified + * listener. + **/ +void +cal_factory_load (CalFactory *factory, const char *uri, Evolution_Calendar_Listener listener) +{ + queue_load_create_job (factory, uri, listener, load_fn); } void cal_factory_create (CalFactory *factory, const char *uri, Evolution_Calendar_Listener listener) { - /* FIXME */ + queue_load_create_job (factory, uri, listener, create_fn); } diff --git a/calendar/cal-listener.c b/calendar/cal-listener.c index fee7e96024..32024d04f5 100644 --- a/calendar/cal-listener.c +++ b/calendar/cal-listener.c @@ -187,6 +187,8 @@ cal_listener_destroy (GtkObject *object) if (ev._major != CORBA_NO_EXCEPTION) g_message ("cal_listener_destroy(): could not release the calendar"); + + priv->cal = CORBA_OBJECT_NIL; } CORBA_exception_free (&ev); @@ -257,6 +259,10 @@ Listener_cal_loaded (PortableServer_Servant servant, load_status = CAL_LISTENER_LOAD_ERROR; break; + case Evolution_Calendar_Listener_IN_USE: + load_status = CAL_LISTENER_LOAD_IN_USE; + break; + default: load_status = CAL_LISTENER_LOAD_ERROR; /* keep gcc happy */ g_assert_not_reached (); diff --git a/calendar/cal-listener.h b/calendar/cal-listener.h index 8988148f34..52b934e774 100644 --- a/calendar/cal-listener.h +++ b/calendar/cal-listener.h @@ -43,7 +43,8 @@ typedef struct _CalListenerClass CalListenerClass; /* Load status for the cal_loaded signal. We need better error reporting. */ typedef enum { CAL_LISTENER_LOAD_SUCCESS, - CAL_LISTENER_LOAD_ERROR + CAL_LISTENER_LOAD_ERROR, + CAL_LISTENER_LOAD_IN_USE } CalListenerLoadStatus; struct _CalListener { diff --git a/calendar/cal-util/calobj.c b/calendar/cal-util/calobj.c index 8d3e68edcc..01e90e3b50 100644 --- a/calendar/cal-util/calobj.c +++ b/calendar/cal-util/calobj.c @@ -677,7 +677,7 @@ ical_object_create_from_vobject (VObject *o, const char *object_name) ical->class = g_strdup (str_val (vo)); free (the_str); } else - ical->class = "PUBLIC"; + ical->class = g_strdup ("PUBLIC"); /* categories */ if (has (o, VCCategoriesProp)){ diff --git a/calendar/cal.c b/calendar/cal.c index 74badc7013..358f08167d 100644 --- a/calendar/cal.c +++ b/calendar/cal.c @@ -127,6 +127,8 @@ cal_destroy (GtkObject *object) cal = CAL (object); priv = cal->priv; + priv->backend = NULL; + CORBA_exception_init (&ev); CORBA_Object_release (priv->listener, &ev); if (ev._major != CORBA_NO_EXCEPTION) diff --git a/calendar/calobj.c b/calendar/calobj.c index 8d3e68edcc..01e90e3b50 100644 --- a/calendar/calobj.c +++ b/calendar/calobj.c @@ -677,7 +677,7 @@ ical_object_create_from_vobject (VObject *o, const char *object_name) ical->class = g_strdup (str_val (vo)); free (the_str); } else - ical->class = "PUBLIC"; + ical->class = g_strdup ("PUBLIC"); /* categories */ if (has (o, VCCategoriesProp)){ diff --git a/calendar/evolution-calendar.idl b/calendar/evolution-calendar.idl index d2ada802d5..d4b87e9825 100644 --- a/calendar/evolution-calendar.idl +++ b/calendar/evolution-calendar.idl @@ -78,8 +78,11 @@ module Calendar { interface Listener : Bonobo::Unknown { /* Return status when loading a calendar; we need better error reporting */ enum LoadStatus { - SUCCESS, - ERROR + SUCCESS, /* All OK */ + ERROR, /* Generic error */ + IN_USE /* Requested create while a calendar + * with the same URI was in use. + */ }; /* Called from a CalFactory when a calendar is initially loaded diff --git a/calendar/gui/Makefile.am b/calendar/gui/Makefile.am index 23bc461141..8fab42d57c 100644 --- a/calendar/gui/Makefile.am +++ b/calendar/gui/Makefile.am @@ -42,17 +42,17 @@ corba-cal.h \ corba-cal-factory.c \ corba-cal-factory.h: GnomeCal.h -GNOME_CALENDAR_CORBA_GENERATED = \ +EVOLUTION_CALENDAR_CORBA_GENERATED = \ evolution-calendar.h \ evolution-calendar-common.c \ evolution-calendar-skels.c \ evolution-calendar-stubs.c -$(GNOME_CALENDAR_CORBA_GENERATED): evolution-calendar.idl +$(EVOLUTION_CALENDAR_CORBA_GENERATED): evolution-calendar.idl orbit-idl -I`$(GNOME_CONFIG) --datadir`/idl $(srcdir)/evolution-calendar.idl gnomecal_SOURCES = \ - $(GNOME_CALENDAR_CORBA_GENERATED) \ + $(EVOLUTION_CALENDAR_CORBA_GENERATED) \ GnomeCal-common.c \ GnomeCal-skels.c \ GnomeCal.h \ @@ -125,7 +125,7 @@ calendar_pilot_sync_SOURCES = \ timeutil.h tlacuache_SOURCES = \ - $(GNOME_CALENDAR_CORBA_GENERATED) \ + $(EVOLUTION_CALENDAR_CORBA_GENERATED) \ alarm.c \ alarm.h \ cal.c \ @@ -162,6 +162,26 @@ calendar_pilot_sync_LDADD = \ $(PISOCK_LIBDIR) $(PISOCK_LIBS) \ $(LINK_FLAGS) +noinst_PROGRAMS = tl-test + +tl_test_SOURCES = \ + $(EVOLUTION_CALENDAR_CORBA_GENERATED) \ + cal-client.c \ + cal-client.h \ + cal-listener.c \ + cal-listener.h \ + cal-util.c \ + cal-util.h \ + tl-test.c + +tl_test_INCLUDES = \ + $(INCLUDES) \ + -DG_LOG_DOMAIN=\"tl-test\" + +tl_test_LDADD = \ + $(BONOBO_VFS_GNOME_LIBS) \ + ../libversit/libversit.la + if HAVE_GNOME_PILOT #calendar_conduit calendar_conduitsdir=$(libdir)/gnome-pilot/conduits diff --git a/calendar/gui/test2.vcf b/calendar/gui/test2.vcf new file mode 100644 index 0000000000..6446507989 --- /dev/null +++ b/calendar/gui/test2.vcf @@ -0,0 +1,133 @@ +BEGIN:VCALENDAR +PRODID:-//GNOME//NONSGML GnomeCalendar//EN +TZ:MST +VERSION:0.13 +BEGIN:VEVENT +UID:KOrganizer - 8469308861 +SEQUENCE:1 +DTSTART:19980601T150000 +DTEND:19980601T150000 +DCREATED:19980402T023558 +LAST-MODIFIED:19980402T023558 +SUMMARY:Cada dos dias de 06/01 al 07/01 +STATUS:NEEDS ACTION +CLASS:PUBLIC +PRIORITY:0 +TRANSP:0 +RELATED-TO:0 +RRULE:D2 19980701T140000 +END:VEVENT + +BEGIN:VEVENT +UID:KOrganizer - 8469308862 +SEQUENCE:1 +DTSTART:19980501T140000 +DTEND:19980501T140000 +DCREATED:19980402T023558 +LAST-MODIFIED:19980402T023558 +SUMMARY:5 dias. +STATUS:NEEDS ACTION +CLASS:PUBLIC +PRIORITY:0 +TRANSP:0 +RELATED-TO:0 +RRULE:D1 #5 +END:VEVENT + +BEGIN:VEVENT +UID:KOrganizer - 8469308863 +SEQUENCE:1 +DTSTART:19980501T140000 +DTEND:19980501T150000 +DCREATED:19980402T023558 +LAST-MODIFIED:19980429T004635 +SUMMARY:Diariamente de 05/01 al 06/01 +STATUS:NEEDS ACTION +CLASS:PRIVATE +PRIORITY:0 +TRANSP:0 +RELATED-TO:0 +RRULE:D1 19980601T000000 +END:VEVENT + +BEGIN:VEVENT +UID:KOrganizer - 18042893834 +SEQUENCE:1 +DTSTART:19980415T010000 +DTEND:19980415T013000 +DCREATED:19980402T023552 +LAST-MODIFIED:19980330T225948 +SUMMARY:Diario durante 5 dias +STATUS:NEEDS ACTION +CLASS:PUBLIC +PRIORITY:0 +TRANSP:0 +RELATED-TO:0 +RRULE:D1 #5 +END:VEVENT + +BEGIN:VEVENT +UID:KOrganizer - 18042893835 +SEQUENCE:1 +DTSTART:19980415T010000 +DTEND:19980415T013000 +DCREATED:19980402T023552 +LAST-MODIFIED:19980330T225948 +SUMMARY:Diario durante 5 dias +STATUS:NEEDS ACTION +CLASS:PUBLIC +PRIORITY:0 +TRANSP:0 +RELATED-TO:0 +RRULE:D1 #5 +END:VEVENT + +BEGIN:VTODO +UID:KOrganizer - 8469308866 +SEQUENCE:1 +DTSTART:19980415T140000 +DUE:19691231T180000 +DCREATED:19980402T023558 +LAST-MODIFIED:19980402T023558 +SUMMARY:Normal +STATUS:NEEDS ACTION +CLASS:PUBLIC +PRIORITY:0 +TRANSP:0 +RELATED-TO:0 +END:VTODO + +BEGIN:VTODO +UID:KOrganizer - 18042893837 +SEQUENCE:1 +DTSTART:19980415T120000 +DUE:19691231T180000 +DCREATED:19980402T023552 +LAST-MODIFIED:19980330T225948 +SUMMARY:Semanal -- 4 semanas +STATUS:NEEDS ACTION +CLASS:PUBLIC +PRIORITY:0 +TRANSP:0 +RELATED-TO:0 +RRULE:W1 WE #4 +END:VTODO + +BEGIN:VTODO +UID:KOrganizer - 18042893838 +SEQUENCE:1 +DTSTART:19980415T003000 +DUE:19691231T180000 +DCREATED:19980402T023552 +LAST-MODIFIED:19980330T225948 +SUMMARY:Semana: Mi, Ju, Vi, Dom (10 veces) +STATUS:NEEDS ACTION +CLASS:PUBLIC +PRIORITY:0 +TRANSP:0 +RELATED-TO:0 +RRULE:W1 SU WE TH FR #10 +END:VTODO + +END:VCALENDAR + diff --git a/calendar/html-month.c b/calendar/html-month.c deleted file mode 100644 index 9d4af13c33..0000000000 --- a/calendar/html-month.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Creates an HTML rendering for this month - * Copyright (C) 1999 the Free Software Foundation - * - * Authors: - * Miguel de Icaza (miguel@kernel.org) - */ -#include -#include -#include -#include -#include -#include -#include -#include "calendar.h" -#include "alarm.h" -#include "eventedit.h" -#include "gnome-cal.h" -#include "main.h" -#include "timeutil.h" - -static void -make_html_header (GnomeCalendar *gcal, GString *s) -{ - g_string_sprintf (s, - "\n" - " \n" - " %s\n" - " \n" - " \n", - gcal->cal->title); -} - -static void -make_html_footer (GString *s) -{ - g_string_sprintf (s, ""); -} - -static void -make_days_headers (GString *s) -{ - g_string_append (s, - "

\n" - "\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "\n"); -} - -static void -make_days (GnomeCalendar *gcal, GString *s) -{ - struct tm tm, month; - time_t month_start; - int day; - time_t now = time (NULL); - - make_days_headers (s); - tm = *localtime (&now); - tm.tm_hour = 0; - tm.tm_min = 0; - tm.tm_sec = 0; - tm.tm_mday = 1; - month_start = mktime (&tm); - month = *localtime (&month_start); - - for (day = 0; day < month.tm_mday; day++){ - - } -#if 0 - day = 0; - for (y = 0; y < 5; y++){ - for (x = 0; x < 7; x++){ - if (month.tm_mday < day - } - } -#endif -} - -void -make_month_html (GnomeCalendar *gcal, char *output) -{ - FILE *f; - GString *s; - - g_return_if_fail (gcal != NULL); - g_return_if_fail (GNOME_IS_CALENDAR (gcal)); - - f = fopen (output, "w"); - if (!f){ - g_warning ("Add nice error message here"); - return; - } - - s = g_string_new (""); - - make_html_header (gcal, s); - make_days (gcal, s); - make_html_footer (s); - - fwrite (s->str, strlen (s->str), 1, f); - - g_string_free (s, TRUE); - fclose (f); -} diff --git a/calendar/idl/evolution-calendar.idl b/calendar/idl/evolution-calendar.idl index d2ada802d5..d4b87e9825 100644 --- a/calendar/idl/evolution-calendar.idl +++ b/calendar/idl/evolution-calendar.idl @@ -78,8 +78,11 @@ module Calendar { interface Listener : Bonobo::Unknown { /* Return status when loading a calendar; we need better error reporting */ enum LoadStatus { - SUCCESS, - ERROR + SUCCESS, /* All OK */ + ERROR, /* Generic error */ + IN_USE /* Requested create while a calendar + * with the same URI was in use. + */ }; /* Called from a CalFactory when a calendar is initially loaded diff --git a/calendar/pcs/cal-backend.c b/calendar/pcs/cal-backend.c index 17148cb048..18ed6a6c86 100644 --- a/calendar/pcs/cal-backend.c +++ b/calendar/pcs/cal-backend.c @@ -20,6 +20,7 @@ */ #include +#include #include "cal-backend.h" #include "calobj.h" #include "../libversit/vcc.h" @@ -36,7 +37,7 @@ typedef struct { /* URI where the calendar data is stored */ GnomeVFSURI *uri; - /* List of Cal client interface objects, each with its listener */ + /* List of Cal objects with their listeners */ GList *clients; /* All the iCalObject structures in the calendar, hashed by UID. The @@ -119,6 +120,55 @@ cal_backend_init (CalBackend *backend) backend->priv = priv; } +/* Saves a calendar */ +static void +save (CalBackend *backend) +{ + /* FIXME */ +} + +/* g_hash_table_foreach() callback to destroy an iCalObject */ +static void +free_ical_object (gpointer key, gpointer value, gpointer data) +{ + iCalObject *ico; + + ico = value; + ical_object_destroy (ico); +} + +/* Destroys a backend's data */ +static void +destroy (CalBackend *backend) +{ + CalBackendPrivate *priv; + + priv = backend->priv; + + if (priv->uri) { + gnome_vfs_uri_unref (priv->uri); + priv->uri = NULL; + } + + g_assert (priv->clients == NULL); + + if (priv->object_hash) { + g_hash_table_foreach (priv->object_hash, free_ical_object, NULL); + g_hash_table_destroy (priv->object_hash); + priv->object_hash = NULL; + } + + g_list_free (priv->events); + g_list_free (priv->todos); + g_list_free (priv->journals); + + priv->events = NULL; + priv->todos = NULL; + priv->journals = NULL; + + priv->loaded = FALSE; +} + /* Destroy handler for the calendar backend */ static void cal_backend_destroy (GtkObject *object) @@ -132,7 +182,10 @@ cal_backend_destroy (GtkObject *object) backend = CAL_BACKEND (object); priv = backend->priv; - /* FIXME: free stuff */ + if (priv->loaded) + save (backend); + + destroy (backend); g_free (priv); @@ -265,6 +318,11 @@ load_from_vobject (CalBackend *backend, VObject *vobject) ical = ical_object_create_from_vobject (this, object_name); + /* FIXME: some broken files may have duplicated UIDs. This is + * Bad(tm). Deal with it by creating new UIDs for them and + * spitting some messages to the console. + */ + if (ical) add_object (backend, ical); } @@ -364,45 +422,57 @@ cal_backend_get_uri (CalBackend *backend) return priv->uri; } -/** - * cal_backend_add_cal: - * @backend: A calendar backend. - * @cal: A calendar client interface object. - * - * Adds a calendar client interface object to a calendar @backend. The calendar - * backend must already have a loaded calendar. - **/ -void -cal_backend_add_cal (CalBackend *backend, Cal *cal) +/* Callback used when a Cal is destroyed */ +static void +cal_destroy_cb (GtkObject *object, gpointer data) { + Cal *cal; + Cal *lcal; + CalBackend *backend; CalBackendPrivate *priv; + GList *l; - g_return_if_fail (backend != NULL); - g_return_if_fail (IS_CAL_BACKEND (backend)); + cal = CAL (object); + backend = CAL_BACKEND (data); priv = backend->priv; - g_return_if_fail (priv->loaded); - g_return_if_fail (cal != NULL); - g_return_if_fail (IS_CAL (cal)); + /* Find the cal in the list of clients */ - gtk_object_ref (GTK_OBJECT (cal)); - priv->clients = g_list_prepend (priv->clients, cal); + for (l = priv->clients; l; l = l->next) { + lcal = CAL (l->data); + + if (lcal == cal) + break; + } + + g_assert (l != NULL); + + /* Disconnect */ + + priv->clients = g_list_remove_link (priv->clients, l); + g_list_free_1 (l); + + /* When all clients go away, the backend can go away, too. Commit + * suicide here. + */ + + if (!priv->clients) + gtk_object_unref (GTK_OBJECT (backend)); } /** - * cal_backend_remove_cal: + * cal_backend_add_cal: * @backend: A calendar backend. * @cal: A calendar client interface object. - * - * Removes a calendar client interface object from a calendar backend. The - * calendar backend must already have a loaded calendar. + * + * Adds a calendar client interface object to a calendar @backend. The calendar + * backend must already have a loaded calendar. **/ void -cal_backend_remove_cal (CalBackend *backend, Cal *cal) +cal_backend_add_cal (CalBackend *backend, Cal *cal) { CalBackendPrivate *priv; - GList *l; g_return_if_fail (backend != NULL); g_return_if_fail (IS_CAL_BACKEND (backend)); @@ -413,13 +483,15 @@ cal_backend_remove_cal (CalBackend *backend, Cal *cal) g_return_if_fail (cal != NULL); g_return_if_fail (IS_CAL (cal)); - l = g_list_find (priv->clients, cal); - if (!l) - return; + /* We do not keep a reference to the Cal since the calendar user agent + * owns it. + */ + + gtk_signal_connect (GTK_OBJECT (cal), "destroy", + GTK_SIGNAL_FUNC (cal_destroy_cb), + backend); - gtk_object_unref (GTK_OBJECT (cal)); - priv->clients = g_list_remove_link (priv->clients, l); - g_list_free_1 (l); + priv->clients = g_list_prepend (priv->clients, cal); } /** @@ -441,11 +513,12 @@ cal_backend_load (CalBackend *backend, GnomeVFSURI *uri) g_return_val_if_fail (backend != NULL, CAL_BACKEND_LOAD_ERROR); g_return_val_if_fail (IS_CAL_BACKEND (backend), CAL_BACKEND_LOAD_ERROR); - g_return_val_if_fail (uri != NULL, CAL_BACKEND_LOAD_ERROR); priv = backend->priv; g_return_val_if_fail (!priv->loaded, CAL_BACKEND_LOAD_ERROR); + g_return_val_if_fail (uri != NULL, CAL_BACKEND_LOAD_ERROR); + /* FIXME: this looks rather bad; maybe we should check for local files * and fail if they are remote. */ @@ -474,14 +547,47 @@ cal_backend_load (CalBackend *backend, GnomeVFSURI *uri) return CAL_BACKEND_LOAD_SUCCESS; } +/** + * cal_backend_create: + * @backend: A calendar backend. + * @uri: URI that will contain the calendar data. + * + * Creates a new empty calendar in a calendar backend. + **/ +void +cal_backend_create (CalBackend *backend, GnomeVFSURI *uri) +{ + CalBackendPrivate *priv; + + g_return_if_fail (backend != NULL); + g_return_if_fail (IS_CAL_BACKEND (backend)); + + priv = backend->priv; + g_return_if_fail (!priv->loaded); + + g_return_if_fail (uri != NULL); + + /* Create the new calendar information */ + + g_assert (priv->object_hash == NULL); + priv->object_hash = g_hash_table_new (g_str_hash, g_str_equal); + + /* Done */ + + gnome_vfs_uri_ref (uri); + + priv->uri = uri; + priv->loaded = TRUE; +} + /** * cal_backend_get_object: * @backend: A calendar backend. * @uid: Unique identifier for a calendar object. - * + * * Queries a calendar backend for a calendar object based on its unique * identifier. - * + * * Return value: The string representation of a complete calendar wrapping the * the sought object, or NULL if no object had the specified UID. A complete * calendar is returned because you also need the timezone data. @@ -560,10 +666,10 @@ build_uids_list (gpointer key, gpointer value, gpointer data) * cal_backend_get_uids: * @backend: A calendar backend. * @type: Bitmask with types of objects to return. - * + * * Builds a list of unique identifiers corresponding to calendar objects whose * type matches one of the types specified in the @type flags. - * + * * Return value: A list of strings that are the sought UIDs. **/ GList * @@ -639,11 +745,11 @@ compare_instance_func (gconstpointer a, gconstpointer b) * @backend: A calendar backend. * @start: Start time for query. * @end: End time for query. - * + * * Builds a sorted list of calendar event object instances that occur or recur * within the specified time range. Each object instance contains the object * itself and the start/end times at which it occurs or recurs. - * + * * Return value: A list of calendar event object instances, sorted by their * start times. **/ diff --git a/calendar/pcs/cal-backend.h b/calendar/pcs/cal-backend.h index 55c414d5f7..41b2b9186d 100644 --- a/calendar/pcs/cal-backend.h +++ b/calendar/pcs/cal-backend.h @@ -68,6 +68,8 @@ void cal_backend_remove_cal (CalBackend *backend, Cal *cal); CalBackendLoadStatus cal_backend_load (CalBackend *backend, GnomeVFSURI *uri); +void cal_backend_create (CalBackend *backend, GnomeVFSURI *uri); + char *cal_backend_get_object (CalBackend *backend, const char *uid); GList *cal_backend_get_uids (CalBackend *backend, CalObjType type); diff --git a/calendar/pcs/cal-factory.c b/calendar/pcs/cal-factory.c index d5b79ef423..14b7ac9cb6 100644 --- a/calendar/pcs/cal-factory.c +++ b/calendar/pcs/cal-factory.c @@ -244,9 +244,24 @@ lookup_backend (CalFactory *factory, GnomeVFSURI *uri) return backend; } +/* Adds a backend to the calendar factory's hash table */ +static void +add_backend (CalFactory *factory, GnomeVFSURI *uri, CalBackend *backend) +{ + CalFactoryPrivate *priv; + + priv = factory->priv; + + gnome_vfs_uri_ref (uri); + g_hash_table_insert (priv->backends, uri, backend); + /* FIXME: connect to destroy on the backend and remove it from + * the hash table when it dies. + */ +} + /* Loads a calendar backend and puts it in the factory's backend hash table */ static CalBackend * -load_backend (CalFactory *factory, GnomeVFSURI *uri, Evolution_Calendar_Listener listener) +load_backend (CalFactory *factory, GnomeVFSURI *uri) { CalFactoryPrivate *priv; CalBackend *backend; @@ -264,9 +279,7 @@ load_backend (CalFactory *factory, GnomeVFSURI *uri, Evolution_Calendar_Listener switch (status) { case CAL_BACKEND_LOAD_SUCCESS: - gnome_vfs_uri_ref (uri); - g_hash_table_insert (priv->backends, uri, backend); - + add_backend (factory, uri, backend); return backend; case CAL_BACKEND_LOAD_ERROR: @@ -279,6 +292,27 @@ load_backend (CalFactory *factory, GnomeVFSURI *uri, Evolution_Calendar_Listener } } +/* Creates a calendar backend and puts it in the factory's backend hash table */ +static CalBackend * +create_backend (CalFactory *factory, GnomeVFSURI *uri) +{ + CalFactoryPrivate *priv; + CalBackend *backend; + + priv = factory->priv; + + backend = cal_backend_new (); + if (!backend) { + g_message ("create_backend(): could not create the backend"); + return NULL; + } + + cal_backend_create (backend, uri); + add_backend (factory, uri, backend); + + return backend; +} + /* Adds a listener to a calendar backend by creating a calendar client interface * object. */ @@ -314,10 +348,8 @@ add_calendar_client (CalFactory *factory, CalBackend *backend, Evolution_Calenda if (ev._major != CORBA_NO_EXCEPTION) { g_message ("add_calendar_client(): could not notify the listener"); - cal_backend_remove_cal (backend, cal); + bonobo_object_unref (BONOBO_OBJECT (cal)); } - - gtk_object_unref (GTK_OBJECT (cal)); } /* Job handler for the load calendar command */ @@ -342,15 +374,14 @@ load_fn (gpointer data) listener = jd->listener; g_free (jd); + /* Look up the backend and create it if needed */ + backend = lookup_backend (factory, uri); if (!backend) - backend = load_backend (factory, uri, listener); - - gnome_vfs_uri_unref (uri); + backend = load_backend (factory, uri); if (!backend) { - g_message ("load_fn(): could not load the backend"); CORBA_exception_init (&ev); Evolution_Calendar_Listener_cal_loaded (listener, Evolution_Calendar_Listener_ERROR, @@ -368,6 +399,8 @@ load_fn (gpointer data) out: + gnome_vfs_uri_unref (uri); + CORBA_exception_init (&ev); CORBA_Object_release (listener, &ev); @@ -377,6 +410,78 @@ load_fn (gpointer data) CORBA_exception_free (&ev); } +/* Job handler for the create calendar command */ +static void +create_fn (gpointer data) +{ + LoadCreateJobData *jd; + CalFactory *factory; + GnomeVFSURI *uri; + Evolution_Calendar_Listener listener; + CalBackend *backend; + CORBA_Environment ev; + + jd = data; + factory = jd->factory; + + uri = gnome_vfs_uri_new (jd->uri); + g_free (jd->uri); + + factory = jd->factory; + listener = jd->listener; + g_free (jd); + + /* Check that the backend is not in use */ + + backend = lookup_backend (factory, uri); + + if (backend) { + CORBA_exception_init (&ev); + Evolution_Calendar_Listener_cal_loaded (listener, + Evolution_Calendar_Listener_IN_USE, + CORBA_OBJECT_NIL, + &ev); + + if (ev._major != CORBA_NO_EXCEPTION) + g_message ("create_fn(): could not notify the listener"); + + CORBA_exception_free (&ev); + goto out; + } + + /* Create the backend */ + + backend = create_backend (factory, uri); + + if (!backend) { + CORBA_exception_init (&ev); + Evolution_Calendar_Listener_cal_loaded (listener, + Evolution_Calendar_Listener_ERROR, + CORBA_OBJECT_NIL, + &ev); + + if (ev._major != CORBA_NO_EXCEPTION) + g_message ("create_fn(): could not notify the listener"); + + CORBA_exception_free (&ev); + goto out; + } + + add_calendar_client (factory, backend, listener); + + out: + + gnome_vfs_uri_unref (uri); + + CORBA_exception_init (&ev); + CORBA_Object_release (listener, &ev); + + if (ev._major != CORBA_NO_EXCEPTION) + g_message ("create_fn(): could not release the listener"); + + CORBA_exception_free (&ev); +} + /** @@ -470,8 +575,10 @@ cal_factory_new (void) return cal_factory_construct (factory, corba_factory); } -void -cal_factory_load (CalFactory *factory, const char *uri, Evolution_Calendar_Listener listener) +/* Queues a load or create request */ +static void +queue_load_create_job (CalFactory *factory, const char *uri, Evolution_Calendar_Listener listener, + JobFunc func) { LoadCreateJobData *jd; CORBA_Environment ev; @@ -481,21 +588,21 @@ cal_factory_load (CalFactory *factory, const char *uri, Evolution_Calendar_Liste CORBA_exception_init (&ev); result = CORBA_Object_is_nil (listener, &ev); if (ev._major != CORBA_NO_EXCEPTION) { - g_message ("cal_factory_load(): could not see if the listener was NIL"); + g_message ("queue_load_create_job(): could not see if the listener was NIL"); CORBA_exception_free (&ev); return; } CORBA_exception_free (&ev); if (result) { - g_message ("cal_factory_load(): cannot operate on a NIL listener!"); + g_message ("queue_load_create_job(): cannot operate on a NIL listener!"); return; } listener_copy = CORBA_Object_duplicate (listener, &ev); if (ev._major != CORBA_NO_EXCEPTION) { - g_message ("cal_factory_load(): could not duplicate the listener"); + g_message ("queue_load_create_job(): could not duplicate the listener"); CORBA_exception_free (&ev); return; } @@ -507,11 +614,27 @@ cal_factory_load (CalFactory *factory, const char *uri, Evolution_Calendar_Liste jd->uri = g_strdup (uri); jd->listener = listener_copy; - job_add (load_fn, jd); + job_add (func, jd); +} + +/** + * cal_factory_load: + * @factory: A calendar factory. + * @uri: URI of calendar to load. + * @listener: Listener for notification of the load result. + * + * Initiates a load request in a calendar factory. A calendar will be loaded + * asynchronously and the result code will be reported to the specified + * listener. + **/ +void +cal_factory_load (CalFactory *factory, const char *uri, Evolution_Calendar_Listener listener) +{ + queue_load_create_job (factory, uri, listener, load_fn); } void cal_factory_create (CalFactory *factory, const char *uri, Evolution_Calendar_Listener listener) { - /* FIXME */ + queue_load_create_job (factory, uri, listener, create_fn); } diff --git a/calendar/pcs/cal.c b/calendar/pcs/cal.c index 74badc7013..358f08167d 100644 --- a/calendar/pcs/cal.c +++ b/calendar/pcs/cal.c @@ -127,6 +127,8 @@ cal_destroy (GtkObject *object) cal = CAL (object); priv = cal->priv; + priv->backend = NULL; + CORBA_exception_init (&ev); CORBA_Object_release (priv->listener, &ev); if (ev._major != CORBA_NO_EXCEPTION) diff --git a/calendar/pcs/calobj.c b/calendar/pcs/calobj.c index 8d3e68edcc..01e90e3b50 100644 --- a/calendar/pcs/calobj.c +++ b/calendar/pcs/calobj.c @@ -677,7 +677,7 @@ ical_object_create_from_vobject (VObject *o, const char *object_name) ical->class = g_strdup (str_val (vo)); free (the_str); } else - ical->class = "PUBLIC"; + ical->class = g_strdup ("PUBLIC"); /* categories */ if (has (o, VCCategoriesProp)){ diff --git a/calendar/pcs/tlacuache.c b/calendar/pcs/tlacuache.c index b11b5030d8..602cbfbe27 100644 --- a/calendar/pcs/tlacuache.c +++ b/calendar/pcs/tlacuache.c @@ -73,7 +73,7 @@ create_cal_factory (void) CORBA_exception_init (&ev); result = goad_server_register (CORBA_OBJECT_NIL, object, - "calendar:cal-factory", + "evolution:calendar-factory", "object", &ev); diff --git a/calendar/pcs/tlacuache.gnorba b/calendar/pcs/tlacuache.gnorba index acf2289229..da0f4ed552 100644 --- a/calendar/pcs/tlacuache.gnorba +++ b/calendar/pcs/tlacuache.gnorba @@ -1,5 +1,5 @@ -[calendar:cal-factory] +[evolution:calendar-factory] type=exe -repo_id=IDL:GNOME/Calendar/CalFactory:1.0 +repo_id=IDL:Evolution/Calendar/CalFactory:1.0 description=Calendar factory for the Personal Calendar Server location_info=tlacuache diff --git a/calendar/test2.vcf b/calendar/test2.vcf new file mode 100644 index 0000000000..6446507989 --- /dev/null +++ b/calendar/test2.vcf @@ -0,0 +1,133 @@ +BEGIN:VCALENDAR +PRODID:-//GNOME//NONSGML GnomeCalendar//EN +TZ:MST +VERSION:0.13 +BEGIN:VEVENT +UID:KOrganizer - 8469308861 +SEQUENCE:1 +DTSTART:19980601T150000 +DTEND:19980601T150000 +DCREATED:19980402T023558 +LAST-MODIFIED:19980402T023558 +SUMMARY:Cada dos dias de 06/01 al 07/01 +STATUS:NEEDS ACTION +CLASS:PUBLIC +PRIORITY:0 +TRANSP:0 +RELATED-TO:0 +RRULE:D2 19980701T140000 +END:VEVENT + +BEGIN:VEVENT +UID:KOrganizer - 8469308862 +SEQUENCE:1 +DTSTART:19980501T140000 +DTEND:19980501T140000 +DCREATED:19980402T023558 +LAST-MODIFIED:19980402T023558 +SUMMARY:5 dias. +STATUS:NEEDS ACTION +CLASS:PUBLIC +PRIORITY:0 +TRANSP:0 +RELATED-TO:0 +RRULE:D1 #5 +END:VEVENT + +BEGIN:VEVENT +UID:KOrganizer - 8469308863 +SEQUENCE:1 +DTSTART:19980501T140000 +DTEND:19980501T150000 +DCREATED:19980402T023558 +LAST-MODIFIED:19980429T004635 +SUMMARY:Diariamente de 05/01 al 06/01 +STATUS:NEEDS ACTION +CLASS:PRIVATE +PRIORITY:0 +TRANSP:0 +RELATED-TO:0 +RRULE:D1 19980601T000000 +END:VEVENT + +BEGIN:VEVENT +UID:KOrganizer - 18042893834 +SEQUENCE:1 +DTSTART:19980415T010000 +DTEND:19980415T013000 +DCREATED:19980402T023552 +LAST-MODIFIED:19980330T225948 +SUMMARY:Diario durante 5 dias +STATUS:NEEDS ACTION +CLASS:PUBLIC +PRIORITY:0 +TRANSP:0 +RELATED-TO:0 +RRULE:D1 #5 +END:VEVENT + +BEGIN:VEVENT +UID:KOrganizer - 18042893835 +SEQUENCE:1 +DTSTART:19980415T010000 +DTEND:19980415T013000 +DCREATED:19980402T023552 +LAST-MODIFIED:19980330T225948 +SUMMARY:Diario durante 5 dias +STATUS:NEEDS ACTION +CLASS:PUBLIC +PRIORITY:0 +TRANSP:0 +RELATED-TO:0 +RRULE:D1 #5 +END:VEVENT + +BEGIN:VTODO +UID:KOrganizer - 8469308866 +SEQUENCE:1 +DTSTART:19980415T140000 +DUE:19691231T180000 +DCREATED:19980402T023558 +LAST-MODIFIED:19980402T023558 +SUMMARY:Normal +STATUS:NEEDS ACTION +CLASS:PUBLIC +PRIORITY:0 +TRANSP:0 +RELATED-TO:0 +END:VTODO + +BEGIN:VTODO +UID:KOrganizer - 18042893837 +SEQUENCE:1 +DTSTART:19980415T120000 +DUE:19691231T180000 +DCREATED:19980402T023552 +LAST-MODIFIED:19980330T225948 +SUMMARY:Semanal -- 4 semanas +STATUS:NEEDS ACTION +CLASS:PUBLIC +PRIORITY:0 +TRANSP:0 +RELATED-TO:0 +RRULE:W1 WE #4 +END:VTODO + +BEGIN:VTODO +UID:KOrganizer - 18042893838 +SEQUENCE:1 +DTSTART:19980415T003000 +DUE:19691231T180000 +DCREATED:19980402T023552 +LAST-MODIFIED:19980330T225948 +SUMMARY:Semana: Mi, Ju, Vi, Dom (10 veces) +STATUS:NEEDS ACTION +CLASS:PUBLIC +PRIORITY:0 +TRANSP:0 +RELATED-TO:0 +RRULE:W1 SU WE TH FR #10 +END:VTODO + +END:VCALENDAR + diff --git a/calendar/tl-test.c b/calendar/tl-test.c new file mode 100644 index 0000000000..bebaa42d87 --- /dev/null +++ b/calendar/tl-test.c @@ -0,0 +1,148 @@ +#include +#include +#include +#include "cal-client.h" + +static CalClient *client1; +static CalClient *client2; + +/* Prints a message with a client identifier */ +static void +cl_printf (CalClient *client, const char *format, ...) +{ + va_list args; + + va_start (args, format); + printf ("Client %s: ", + client == client1 ? "1" : + client == client2 ? "2" : + "UNKNOWN"); + vprintf (format, args); + va_end (args); +} + +/* Lists the UIDs of objects in a calendar, called as an idle handler */ +static gboolean +list_uids (gpointer data) +{ + CalClient *client; + GList *uids; + GList *l; + + client = CAL_CLIENT (data); + + uids = cal_client_get_uids (client, CALOBJ_TYPE_ANY); + + cl_printf (client, "UIDs: "); + + if (!uids) + printf ("none\n"); + else { + for (l = uids; l; l = l->next) { + char *uid; + + uid = l->data; + printf ("`%s' ", uid); + } + + printf ("\n"); + + for (l = uids; l; l = l->next) { + char *uid; + char *calobj; + + uid = l->data; + calobj = cal_client_get_object (client, uid); + + printf ("------------------------------\n%s", calobj); + printf ("------------------------------\n"); + + g_free (calobj); + } + } + + cal_obj_uid_list_free (uids); + + gtk_object_unref (GTK_OBJECT (client)); + + return FALSE; +} + +/* Callback used when a calendar is loaded */ +static void +cal_loaded (CalClient *client, CalClientLoadStatus status, gpointer data) +{ + cl_printf (client, "Load/create %s\n", + ((status == CAL_CLIENT_LOAD_SUCCESS) ? "success" : + (status == CAL_CLIENT_LOAD_ERROR) ? "error" : + (status == CAL_CLIENT_LOAD_IN_USE) ? "in use" : + "unknown status value")); + + if (status == CAL_CLIENT_LOAD_SUCCESS) + g_idle_add (list_uids, client); + else + gtk_object_unref (GTK_OBJECT (client)); +} + +/* Creates a calendar client and tries to load the specified URI into it */ +static CalClient * +create_client (const char *uri, gboolean load) +{ + CalClient *client; + gboolean result; + + client = cal_client_new (); + if (!client) { + g_message ("create_client(): could not create the client"); + exit (1); + } + + gtk_signal_connect (GTK_OBJECT (client), "cal_loaded", + GTK_SIGNAL_FUNC (cal_loaded), + NULL); + + printf ("Calendar loading `%s'...\n", uri); + + if (load) + result = cal_client_load_calendar (client, uri); + else + result = cal_client_create_calendar (client, uri); + + if (!result) { + g_message ("create_client(): failure when issuing calendar load/create request `%s'", + uri); + exit (1); + } + + return client; +} + +int +main (int argc, char **argv) +{ + CORBA_Environment ev; + + bindtextdomain (PACKAGE, GNOMELOCALEDIR); + textdomain (PACKAGE); + + CORBA_exception_init (&ev); + gnome_CORBA_init ("tl-test", VERSION, &argc, argv, 0, &ev); + if (ev._major != CORBA_NO_EXCEPTION) { + g_message ("main(): could not initialize the ORB"); + CORBA_exception_free (&ev); + exit (1); + } + CORBA_exception_free (&ev); + + if (!bonobo_init (CORBA_OBJECT_NIL, CORBA_OBJECT_NIL, CORBA_OBJECT_NIL)) { + g_message ("main(): could not initialize Bonobo"); + exit (1); + } + + client1 = create_client ("/cvs/evolution/calendar/test2.vcf", TRUE); + client2 = create_client ("/cvs/evolution/calendar/test2.vcf", FALSE); + + bonobo_main (); + + return 0; +} diff --git a/calendar/tlacuache.c b/calendar/tlacuache.c index b11b5030d8..602cbfbe27 100644 --- a/calendar/tlacuache.c +++ b/calendar/tlacuache.c @@ -73,7 +73,7 @@ create_cal_factory (void) CORBA_exception_init (&ev); result = goad_server_register (CORBA_OBJECT_NIL, object, - "calendar:cal-factory", + "evolution:calendar-factory", "object", &ev); diff --git a/calendar/tlacuache.gnorba b/calendar/tlacuache.gnorba index acf2289229..da0f4ed552 100644 --- a/calendar/tlacuache.gnorba +++ b/calendar/tlacuache.gnorba @@ -1,5 +1,5 @@ -[calendar:cal-factory] +[evolution:calendar-factory] type=exe -repo_id=IDL:GNOME/Calendar/CalFactory:1.0 +repo_id=IDL:Evolution/Calendar/CalFactory:1.0 description=Calendar factory for the Personal Calendar Server location_info=tlacuache -- cgit v1.2.3
MONDAYTUESDAYWEDNESDAYTHURSDAYFRIDAY