aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFederico Mena Quintero <federico@helixcode.com>2000-02-11 19:08:08 +0800
committerArturo Espinosa <unammx@src.gnome.org>2000-02-11 19:08:08 +0800
commitd8fbc4fc0c01d174f04e8f2370131a5240764f4b (patch)
treed530001f5c312790457e2cd55585dd46eac32085
parentdb6312e2549c63372546af84fce3ce41b7c3f48d (diff)
downloadgsoc2013-evolution-d8fbc4fc0c01d174f04e8f2370131a5240764f4b.tar
gsoc2013-evolution-d8fbc4fc0c01d174f04e8f2370131a5240764f4b.tar.gz
gsoc2013-evolution-d8fbc4fc0c01d174f04e8f2370131a5240764f4b.tar.bz2
gsoc2013-evolution-d8fbc4fc0c01d174f04e8f2370131a5240764f4b.tar.lz
gsoc2013-evolution-d8fbc4fc0c01d174f04e8f2370131a5240764f4b.tar.xz
gsoc2013-evolution-d8fbc4fc0c01d174f04e8f2370131a5240764f4b.tar.zst
gsoc2013-evolution-d8fbc4fc0c01d174f04e8f2370131a5240764f4b.zip
Connect to the Cal's destroy signal. (cal_backend_remove_cal): Killed
2000-02-10 Federico Mena Quintero <federico@helixcode.com> * 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 <federico@helixcode.com> * 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
-rw-r--r--calendar/ChangeLog174
-rw-r--r--calendar/Makefile.am28
-rw-r--r--calendar/cal-backend.c182
-rw-r--r--calendar/cal-backend.h2
-rw-r--r--calendar/cal-client.c201
-rw-r--r--calendar/cal-client.h4
-rw-r--r--calendar/cal-client/cal-client.c201
-rw-r--r--calendar/cal-client/cal-client.h4
-rw-r--r--calendar/cal-client/cal-listener.c6
-rw-r--r--calendar/cal-client/cal-listener.h3
-rw-r--r--calendar/cal-client/client-test.c148
-rw-r--r--calendar/cal-factory.c159
-rw-r--r--calendar/cal-listener.c6
-rw-r--r--calendar/cal-listener.h3
-rw-r--r--calendar/cal-util/calobj.c2
-rw-r--r--calendar/cal.c2
-rw-r--r--calendar/calobj.c2
-rw-r--r--calendar/evolution-calendar.idl7
-rw-r--r--calendar/gui/Makefile.am28
-rw-r--r--calendar/gui/test2.vcf133
-rw-r--r--calendar/html-month.c110
-rw-r--r--calendar/idl/evolution-calendar.idl7
-rw-r--r--calendar/pcs/cal-backend.c182
-rw-r--r--calendar/pcs/cal-backend.h2
-rw-r--r--calendar/pcs/cal-factory.c159
-rw-r--r--calendar/pcs/cal.c2
-rw-r--r--calendar/pcs/calobj.c2
-rw-r--r--calendar/pcs/tlacuache.c2
-rw-r--r--calendar/pcs/tlacuache.gnorba4
-rw-r--r--calendar/test2.vcf133
-rw-r--r--calendar/tl-test.c148
-rw-r--r--calendar/tlacuache.c2
-rw-r--r--calendar/tlacuache.gnorba4
33 files changed, 1696 insertions, 356 deletions
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 <federico@helixcode.com>
+
+ * 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 <federico@helixcode.com>
+
+ * 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 <federico@helixcode.com>
* evolution-calendar.idl (Cal): Added get_uids() method to get a
@@ -325,13 +425,13 @@
2000-01-08 Vadim Strizhevsky <vadim@optonline.net>
- * 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 <deity@eskil.dk>
- * 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 <deity@eskil.dk>
* calendar-conduit.c (pre_sync): Writes some warning
@@ -465,7 +565,7 @@
1999-11-12 Eskil Heyn Olsen <deity@eskil.dk>
* 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 <rms39@columbia.edu>
@@ -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 <rms39@columbia.edu>
* calendar.c (calendar_day_change): Add call to
calendar_init_alarms() to schedule another day change alarm.
-
+
1999-11-09 Eskil Heyn Olsen <deity@eskil.dk>
* 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 <deity@eskil.dk>
-
+
* *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 <miguel@gnu.org>
* 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 <stric@ing.umu.se>
@@ -686,7 +786,7 @@
1999-07-30 Miguel de Icaza <miguel@gnu.org>
- * month-view.c (month_view_init): Release points here.
+ * month-view.c (month_view_init): Release points here.
1999-08-02 Peter Teichman <pat4@acpub.duke.edu>
@@ -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 <miguel@nuclecu.unam.mx>
* 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 <miguel@nuclecu.unam.mx>
@@ -1073,7 +1173,7 @@
1999-02-23 Miguel de Icaza <miguel@nuclecu.unam.mx>
* 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 <sipan@mit.edu>
* 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 <sipan@mit.edu>
* main.c: Use N_() macro for color settings labels in
color_props structure.
-
+
1999-02-15 Federico Mena Quintero <federico@nuclecu.unam.mx>
* 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 <stric@ing.umu.se>
@@ -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 <miguel@nuclecu.unam.mx>
* 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 <miguel@nuclecu.unam.mx>
- * 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 <miguel@nuclecu.unam.mx>
- * eventedit.c (ee_rp_init_exceptions): Update GtkClist usage.
+ * eventedit.c (ee_rp_init_exceptions): Update GtkClist usage.
1998-11-23 Andrew T. Veliath <andrewtv@usa.net>
@@ -1319,7 +1419,7 @@
1998-11-23 Herbert V. Riedel <hvr@hvrlab.ml.org>
- * 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 <config.h>
+#include <gtk/gtksignal.h>
#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.
*/
@@ -475,13 +548,46 @@ cal_backend_load (CalBackend *backend, GnomeVFSURI *uri)
}
/**
+ * 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);
@@ -426,12 +520,46 @@ cal_client_load_calendar (CalClient *client, const char *str_uri)
}
/**
+ * 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);
@@ -426,12 +520,46 @@ cal_client_load_calendar (CalClient *client, const char *str_uri)
}
/**
+ * 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 <config.h>
+#include <libgnorba/gnorba.h>
+#include <bonobo.h>
+#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 <config.h>
-#include <gnome.h>
-#include <pwd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <string.h>
-#include <ctype.h>
-#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,
- "<html>\n"
- " <head>\n"
- " <title>%s</title>\n"
- " </head>\n"
- " <body>\n",
- gcal->cal->title);
-}
-
-static void
-make_html_footer (GString *s)
-{
- g_string_sprintf (s, "</html>");
-}
-
-static void
-make_days_headers (GString *s)
-{
- g_string_append (s,
- "<p><table border=1>\n"
- "<tr>\n"
- " <td></td>\n"
- " <td>MONDAY</td>\n"
- " <td>TUESDAY</td>\n"
- " <td>WEDNESDAY</td>\n"
- " <td>THURSDAY</td>\n"
- " <td>FRIDAY</td>\n"
- "</tr>\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 <config.h>
+#include <gtk/gtksignal.h>
#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.
*/
@@ -475,13 +548,46 @@ cal_backend_load (CalBackend *backend, GnomeVFSURI *uri)
}
/**
+ * 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 <config.h>
+#include <libgnorba/gnorba.h>
+#include <bonobo.h>
+#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