/* Evolution calendar client interface object * * Copyright (C) 2000 Helix Code, Inc. * * Author: Federico Mena-Quintero * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #include #include "cal.h" #include "cal-backend.h" /* Private part of the Cal structure */ typedef struct { /* Our backend */ CalBackend *backend; /* Listener on the client we notify */ Evolution_Calendar_Listener listener; } CalPrivate; static void cal_class_init (CalClass *class); static void cal_init (Cal *cal); static void cal_destroy (GtkObject *object); static POA_Evolution_Calendar_Cal__vepv cal_vepv; static BonoboObjectClass *parent_class; /** * cal_get_type: * @void: * * Registers the #Cal class if necessary, and returns the type ID associated to * it. * * Return value: The type ID of the #Cal class. **/ GtkType cal_get_type (void) { static GtkType cal_type = 0; if (!cal_type) { static const GtkTypeInfo cal_info = { "Cal", sizeof (Cal), sizeof (CalClass), (GtkClassInitFunc) cal_class_init, (GtkObjectInitFunc) cal_init, NULL, /* reserved_1 */ NULL, /* reserved_2 */ (GtkClassInitFunc) NULL }; cal_type = gtk_type_unique (BONOBO_OBJECT_TYPE, &cal_info); } return cal_type; } /* CORBA class initialzation function for the calendar */ static void init_cal_corba_class (void) { cal_vepv.Bonobo_Unknown_epv = bonobo_object_get_epv (); cal_vepv.Evolution_Calendar_Cal_epv = cal_get_epv (); } /* Class initialization function for the calendar */ static void cal_class_init (CalClass *class) { GtkObjectClass *object_class; object_class = (GtkObjectClass *) class; parent_class = gtk_type_class (BONOBO_OBJECT_TYPE); object_class->destroy = cal_destroy; init_cal_corba_class (); } /* Object initialization function for the calendar */ static void cal_init (Cal *cal) { CalPrivate *priv; priv = g_new0 (CalPrivate, 1); cal->priv = priv; priv->listener = CORBA_OBJECT_NIL; } /* Destroy handler for the calendar */ static void cal_destroy (GtkObject *object) { Cal *cal; CalPrivate *priv; CORBA_Environment ev; g_return_if_fail (object != NULL); g_return_if_fail (IS_CAL (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) g_message ("cal_destroy(): could not release the listener"); CORBA_exception_free (&ev); g_free (priv); if (GTK_OBJECT_CLASS (parent_class)->destroy) (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); } /* CORBA servant implementation */ /* Cal::get_uri method */ static CORBA_char * Cal_get_uri (PortableServer_Servant servant, CORBA_Environment *ev) { Cal *cal; CalPrivate *priv; GnomeVFSURI *uri; char *str_uri; CORBA_char *str_uri_copy; cal = CAL (bonobo_object_from_servant (servant)); priv = cal->priv; uri = cal_backend_get_uri (priv->backend); str_uri = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_NONE); str_uri_copy = CORBA_string_dup (str_uri); g_free (str_uri); return str_uri_copy; } /* Cal::get_object method */ static Evolution_Calendar_CalObj Cal_get_object (PortableServer_Servant servant, const Evolution_Calendar_CalObjUID uid, CORBA_Environment *ev) { Cal *cal; CalPrivate *priv; char *calobj; cal = CAL (bonobo_object_from_servant (servant)); priv = cal->priv; calobj = cal_backend_get_object (priv->backend, uid); if (calobj) { CORBA_char *calobj_copy; calobj_copy = CORBA_string_dup (calobj); g_free (calobj); return calobj_copy; } else { CORBA_exception_set (ev, CORBA_USER_EXCEPTION, ex_Evolution_Calendar_Cal_NotFound, NULL); return NULL; } } /* Cal::get_uids method */ static Evolution_Calendar_CalObjUIDSeq * Cal_get_uids (PortableServer_Servant servant, const Evolution_Calendar_CalObjType type, CORBA_Environment *ev) { Cal *cal; CalPrivate *priv; GList *uids, *l; Evolution_Calendar_CalObjUIDSeq *seq; int t; int n, i; cal = CAL (bonobo_object_from_servant (servant)); priv = cal->priv; /* Translate the CORBA flags to our own flags */ t = (((type & Evolution_Calendar_TYPE_EVENT) ? CALOBJ_TYPE_EVENT : 0) | ((type & Evolution_Calendar_TYPE_TODO) ? CALOBJ_TYPE_TODO : 0) | ((type & Evolution_Calendar_TYPE_JOURNAL) ? CALOBJ_TYPE_JOURNAL : 0) | ((type & Evolution_Calendar_TYPE_OTHER) ? CALOBJ_TYPE_OTHER : 0) | ((type & Evolution_Calendar_TYPE_ANY) ? CALOBJ_TYPE_ANY : 0)); uids = cal_backend_get_uids (priv->backend, t); n = g_list_length (uids); seq = Evolution_Calendar_CalObjUIDSeq__alloc (); CORBA_sequence_set_release (seq, TRUE); seq->_length = n; seq->_buffer = CORBA_sequence_Evolution_Calendar_CalObjUID_allocbuf (n); /* Fill the sequence */ for (i = 0, l = uids; l; i++, l = l->next) { char *uid; uid = l->data; seq->_buffer[i] = CORBA_string_dup (uid); } /* Done */ cal_obj_uid_list_free (uids); return seq; } /* Cal::get_events_in_range method */ static Evolution_Calendar_CalObjInstanceSeq * Cal_get_events_in_range (PortableServer_Servant servant, const Evolution_Calendar_Time_t start, const Evolution_Calendar_Time_t end, CORBA_Environment *ev) { Cal *cal; CalPrivate *priv; time_t t_start, t_end; Evolution_Calendar_CalObjInstanceSeq *seq; GList *elist, *l; int n, i; cal = CAL (bonobo_object_from_servant (servant)); priv = cal->priv; t_start = (time_t) start; t_end = (time_t) end; if (t_start > t_end || t_start == -1 || t_end == -1) { CORBA_exception_set (ev, CORBA_USER_EXCEPTION, ex_Evolution_Calendar_Cal_InvalidRange, NULL); return NULL; } /* Figure out the list and allocate the sequence */ elist = cal_backend_get_events_in_range (priv->backend, t_start, t_end); n = g_list_length (elist); seq = Evolution_Calendar_CalObjInstanceSeq__alloc (); CORBA_sequence_set_release (seq, TRUE); seq->_length = n; seq->_buffer = CORBA_sequence_Evolution_Calendar_CalObjInstance_allocbuf (n); /* Fill the sequence */ for (i = 0, l = elist; l; i++, l = l->next) { CalObjInstance *icoi; Evolution_Calendar_CalObjInstance *corba_icoi; icoi = l->data; corba_icoi = &seq->_buffer[i]; corba_icoi->uid = CORBA_string_dup (icoi->uid); corba_icoi->calobj = CORBA_string_dup (icoi->calobj); corba_icoi->start = icoi->start; corba_icoi->end = icoi->end; } /* Done */ cal_obj_instance_list_free (elist); return seq; } /* Cal::update_object method */ static void Cal_update_object (PortableServer_Servant servant, const Evolution_Calendar_CalObjUID uid, const Evolution_Calendar_CalObj calobj, CORBA_Environment *ev) { Cal *cal; CalPrivate *priv; cal = CAL (bonobo_object_from_servant (servant)); priv = cal->priv; if (!cal_backend_update_object (priv->backend, uid, calobj)) CORBA_exception_set (ev, CORBA_USER_EXCEPTION, ex_Evolution_Calendar_Cal_InvalidObject, NULL); } /** * cal_get_epv: * @void: * * Creates an EPV for the Cal CORBA class. * * Return value: A newly-allocated EPV. **/ POA_Evolution_Calendar_Cal__epv * cal_get_epv (void) { POA_Evolution_Calendar_Cal__epv *epv; epv = g_new0 (POA_Evolution_Calendar_Cal__epv, 1); epv->_get_uri = Cal_get_uri; epv->get_object = Cal_get_object; epv->get_uids = Cal_get_uids; epv->get_events_in_range = Cal_get_events_in_range; epv->update_object = Cal_update_object; return epv; } /** * cal_construct: * @cal: A calendar client interface. * @corba_cal: CORBA object for the calendar. * @backend: Calendar backend that this @cal presents an interface to. * @listener: Calendar listener for notification. * * Constructs a calendar client interface object by binding the corresponding * CORBA object to it. The calendar interface is bound to the specified * @backend, and will notify the @listener about changes to the calendar. * * Return value: The same object as the @cal argument. **/ Cal * cal_construct (Cal *cal, Evolution_Calendar_Cal corba_cal, CalBackend *backend, Evolution_Calendar_Listener listener) { CalPrivate *priv; CORBA_Environment ev; g_return_val_if_fail (cal != NULL, NULL); g_return_val_if_fail (IS_CAL (cal), NULL); g_return_val_if_fail (backend != NULL, NULL); g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL); priv = cal->priv; CORBA_exception_init (&ev); priv->listener = CORBA_Object_duplicate (listener, &ev); if (ev._major != CORBA_NO_EXCEPTION) { g_message ("cal_construct: could not duplicate the listener"); priv->listener = CORBA_OBJECT_NIL; CORBA_exception_free (&ev); return NULL; } CORBA_exception_free (&ev); priv->backend = backend; bonobo_object_construct (BONOBO_OBJECT (cal), corba_cal); return cal; } /** * cal_corba_object_create: * @object: #BonoboObject that will wrap the CORBA object. * * Creates and activates the CORBA object that is wrapped by the specified * calendar client interface @object. * * Return value: An activated object reference or #CORBA_OBJECT_NIL in case of * failure. **/ Evolution_Calendar_Cal cal_corba_object_create (BonoboObject *object) { POA_Evolution_Calendar_Cal *servant; CORBA_Environment ev; g_return_val_if_fail (object != NULL, CORBA_OBJECT_NIL); g_return_val_if_fail (IS_CAL (object), CORBA_OBJECT_NIL); servant = (POA_Evolution_Calendar_Cal *) g_new0 (BonoboObjectServant, 1); servant->vepv = &cal_vepv; CORBA_exception_init (&ev); POA_Evolution_Calendar_Cal__init ((PortableServer_Servant) servant, &ev); if (ev._major != CORBA_NO_EXCEPTION) { g_message ("cal_corba_object_create(): could not init the servant"); g_free (servant); CORBA_exception_free (&ev); return CORBA_OBJECT_NIL; } CORBA_exception_free (&ev); return (Evolution_Calendar_Cal) bonobo_object_activate_servant (object, servant); } /** * cal_new: * @backend: A calendar backend. * @listener: A calendar listener. * * Creates a new calendar client interface object and binds it to the specified * @backend and @listener objects. * * Return value: A newly-created #Cal calendar client interface object, or NULL * if its corresponding CORBA object could not be created. **/ Cal * cal_new (CalBackend *backend, Evolution_Calendar_Listener listener) { Cal *cal, *retval; Evolution_Calendar_Cal corba_cal; CORBA_Environment ev; gboolean ret; g_return_val_if_fail (backend != NULL, NULL); g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL); cal = CAL (gtk_type_new (CAL_TYPE)); corba_cal = cal_corba_object_create (BONOBO_OBJECT (cal)); CORBA_exception_init (&ev); ret = CORBA_Object_is_nil ((CORBA_Object) corba_cal, &ev); if (ev._major != CORBA_NO_EXCEPTION || ret) { g_message ("cal_new(): could not create the CORBA object"); bonobo_object_unref (BONOBO_OBJECT (cal)); CORBA_exception_free (&ev); return NULL; } CORBA_exception_free (&ev); retval = cal_construct (cal, corba_cal, backend, listener); if (!retval) { g_message ("cal_new(): could not construct the calendar client interface"); bonobo_object_unref (BONOBO_OBJECT (cal)); return NULL; } return retval; } /** * cal_notify_update: * @cal: A calendar client interface. * @uid: UID of object that was updated. * * Notifies a listener attached to a calendar client interface object about an * update to a calendar object. **/ void cal_notify_update (Cal *cal, const char *uid) { CalPrivate *priv; CORBA_Environment ev; g_return_if_fail (cal != NULL); g_return_if_fail (IS_CAL (cal)); g_return_if_fail (uid != NULL); priv = cal->priv; g_return_if_fail (priv->listener != CORBA_OBJECT_NIL); CORBA_exception_init (&ev); Evolution_Calendar_Listener_obj_updated (priv->listener, uid, &ev); if (ev._major != CORBA_NO_EXCEPTION) g_message ("cal_notify_update(): could not notify the listener " "about an updated object"); CORBA_exception_free (&ev); }