aboutsummaryrefslogtreecommitdiffstats
path: root/calendar/cal-client
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 /calendar/cal-client
parentdb6312e2549c63372546af84fce3ce41b7c3f48d (diff)
downloadgsoc2013-evolution-d8fbc4fc0c01d174f04e8f2370131a5240764f4b.tar.gz
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
Diffstat (limited to 'calendar/cal-client')
-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
5 files changed, 324 insertions, 38 deletions
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;
+}