aboutsummaryrefslogtreecommitdiffstats
path: root/calendar/cal-client
diff options
context:
space:
mode:
Diffstat (limited to 'calendar/cal-client')
-rw-r--r--calendar/cal-client/.cvsignore2
-rw-r--r--calendar/cal-client/Makefile.am7
-rw-r--r--calendar/cal-client/cal-client-types.h26
-rw-r--r--calendar/cal-client/cal-client.c3710
-rw-r--r--calendar/cal-client/cal-client.h101
-rw-r--r--calendar/cal-client/cal-listener.c895
-rw-r--r--calendar/cal-client/cal-listener.h53
-rw-r--r--calendar/cal-client/cal-marshal.list6
-rw-r--r--calendar/cal-client/cal-query.c470
-rw-r--r--calendar/cal-client/cal-query.h37
-rw-r--r--calendar/cal-client/client-test.c155
-rw-r--r--calendar/cal-client/query-listener.c393
-rw-r--r--calendar/cal-client/query-listener.h44
13 files changed, 3611 insertions, 2288 deletions
diff --git a/calendar/cal-client/.cvsignore b/calendar/cal-client/.cvsignore
index 1537e6e01d..f2aa4f92ae 100644
--- a/calendar/cal-client/.cvsignore
+++ b/calendar/cal-client/.cvsignore
@@ -10,6 +10,8 @@ evolution-calendar.h
evolution-calendar-common.lo
evolution-calendar-skels.lo
evolution-calendar-stubs.lo
+cal-marshal.c
+cal-marshal.h
*.lo
*.la
client-test
diff --git a/calendar/cal-client/Makefile.am b/calendar/cal-client/Makefile.am
index 5e48e7db23..5f8b5a3cf1 100644
--- a/calendar/cal-client/Makefile.am
+++ b/calendar/cal-client/Makefile.am
@@ -38,6 +38,8 @@ libcal_clientincludedir = $(privincludedir)/cal-client
libcal_client_la_SOURCES = \
$(CORBA_GENERATED_C) \
cal-client-types.c \
+ cal-marshal.c \
+ cal--marshal.h \
cal-client.c \
cal-listener.c \
cal-listener.h \
@@ -72,7 +74,10 @@ client_test_LDADD = \
libcal-client.la \
$(EVOLUTION_CALENDAR_LIBS)
-BUILT_SOURCES = $(CORBA_GENERATED)
+MARSHAL_GENERATED = cal-marshal.c cal-marshal.h
+@EVO_MARSHAL_RULE@
+
+BUILT_SOURCES = $(CORBA_GENERATED) $(MARSHAL_GENERATED)
CLEANFILES = $(BUILT_SOURCES)
dist-hook:
diff --git a/calendar/cal-client/cal-client-types.h b/calendar/cal-client/cal-client-types.h
index c160a1fa94..925628337b 100644
--- a/calendar/cal-client/cal-client-types.h
+++ b/calendar/cal-client/cal-client-types.h
@@ -29,6 +29,10 @@ G_BEGIN_DECLS
+#define E_CALENDAR_ERROR e_calendar_error_quark()
+
+GQuark e_calendar_error_quark (void) G_GNUC_CONST;
+
typedef enum {
CAL_CLIENT_CHANGE_ADDED = 1 << 0,
CAL_CLIENT_CHANGE_MODIFIED = 1 << 1,
@@ -41,6 +45,28 @@ typedef struct
CalClientChangeType type;
} CalClientChange;
+typedef enum {
+ E_CALENDAR_STATUS_OK,
+ E_CALENDAR_STATUS_INVALID_ARG,
+ E_CALENDAR_STATUS_BUSY,
+ E_CALENDAR_STATUS_REPOSITORY_OFFLINE,
+ E_CALENDAR_STATUS_NO_SUCH_CALENDAR,
+ E_CALENDAR_STATUS_OBJECT_NOT_FOUND,
+ E_CALENDAR_STATUS_INVALID_OBJECT,
+ E_CALENDAR_STATUS_URI_NOT_LOADED,
+ E_CALENDAR_STATUS_URI_ALREADY_LOADED,
+ E_CALENDAR_STATUS_PERMISSION_DENIED,
+ E_CALENDAR_STATUS_CARD_NOT_FOUND,
+ E_CALENDAR_STATUS_CARD_ID_ALREADY_EXISTS,
+ E_CALENDAR_STATUS_PROTOCOL_NOT_SUPPORTED,
+ E_CALENDAR_STATUS_CANCELLED,
+ E_CALENDAR_STATUS_COULD_NOT_CANCEL,
+ E_CALENDAR_STATUS_AUTHENTICATION_FAILED,
+ E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED,
+ E_CALENDAR_STATUS_CORBA_EXCEPTION,
+ E_CALENDAR_STATUS_OTHER_ERROR
+} ECalendarStatus;
+
void cal_client_change_list_free (GList *list);
G_END_DECLS
diff --git a/calendar/cal-client/cal-client.c b/calendar/cal-client/cal-client.c
index e40d405120..95efdd6d5d 100644
--- a/calendar/cal-client/cal-client.c
+++ b/calendar/cal-client/cal-client.c
@@ -22,20 +22,39 @@
#include <config.h>
#endif
+#include <pthread.h>
#include <string.h>
#include <bonobo-activation/bonobo-activation.h>
#include <bonobo/bonobo-exception.h>
+#include <bonobo/bonobo-i18n.h>
#include <libgnome/gnome-util.h>
#include "e-util/e-component-listener.h"
#include "e-util/e-config-listener.h"
+#include "e-util/e-url.h"
+#include "e-util/e-msgport.h"
#include "cal-util/cal-util-marshal.h"
-#include "cal-client-types.h"
+#include "cal-util/timeutil.h"
#include "cal-client.h"
#include "cal-listener.h"
+#include "query-listener.h"
+typedef struct {
+ EMutex *mutex;
+ pthread_cond_t cond;
+ ECalendarStatus status;
+
+ char *uid;
+ GList *list;
+ gboolean bool;
+ char *string;
+
+ CalQuery *query;
+ QueryListener *listener;
+} ECalendarOp;
+
/* Private part of the CalClient structure */
struct _CalClientPrivate {
/* Load state to avoid multiple loads */
@@ -45,7 +64,12 @@ struct _CalClientPrivate {
* NULL if we are not loaded.
*/
char *uri;
+ CalObjType type;
+
+ ECalendarOp *current_op;
+ EMutex *mutex;
+
/* Email address associated with this calendar, or NULL */
char *cal_address;
char *alarm_email_address;
@@ -85,8 +109,6 @@ struct _CalClientPrivate {
enum {
CAL_OPENED,
CAL_SET_MODE,
- OBJ_UPDATED,
- OBJ_REMOVED,
BACKEND_ERROR,
CATEGORIES_CHANGED,
FORGET_PASSWORD,
@@ -94,10 +116,6 @@ enum {
LAST_SIGNAL
};
-static void cal_client_class_init (CalClientClass *klass);
-static void cal_client_init (CalClient *client, CalClientClass *klass);
-static void cal_client_finalize (GObject *object);
-
static void cal_client_get_object_timezones_cb (icalparameter *param,
void *data);
@@ -105,36 +123,28 @@ static guint cal_client_signals[LAST_SIGNAL];
static GObjectClass *parent_class;
+#define E_CALENDAR_CHECK_STATUS(status,error) G_STMT_START{ \
+ if ((status) == E_CALENDAR_STATUS_OK) { \
+ return TRUE; \
+ } \
+ else { \
+ const char *msg; \
+ msg = cal_client_get_error_message ((status)); \
+ g_set_error ((error), E_CALENDAR_ERROR, (status), msg, (status)); \
+ return FALSE; \
+ } }G_STMT_END
+
-/**
- * cal_client_get_type:
- *
- * Registers the #CalClient class if necessary, and returns the type ID assigned
- * to it.
- *
- * Return value: The type ID of the #CalClient class.
- **/
-GType
-cal_client_get_type (void)
+/* Error quark */
+GQuark
+e_calendar_error_quark (void)
{
- static GType cal_client_type = 0;
-
- if (!cal_client_type) {
- static GTypeInfo info = {
- sizeof (CalClientClass),
- (GBaseInitFunc) NULL,
- (GBaseFinalizeFunc) NULL,
- (GClassInitFunc) cal_client_class_init,
- NULL, NULL,
- sizeof (CalClient),
- 0,
- (GInstanceInitFunc) cal_client_init
- };
- cal_client_type = g_type_register_static (G_TYPE_OBJECT, "CalClient", &info, 0);
- }
+ static GQuark q = 0;
+ if (q == 0)
+ q = g_quark_from_static_string ("e-calendar-error-quark");
- return cal_client_type;
+ return q;
}
GType
@@ -198,118 +208,48 @@ cal_mode_enum_get_type (void)
return cal_mode_enum_type;
}
-/* Class initialization function for the calendar client */
-static void
-cal_client_class_init (CalClientClass *klass)
+/* EBookOp calls */
+
+static ECalendarOp*
+e_calendar_new_op (CalClient *client)
{
- GObjectClass *object_class;
+ ECalendarOp *op = g_new0 (ECalendarOp, 1);
- object_class = (GObjectClass *) klass;
+ op->mutex = e_mutex_new (E_MUTEX_SIMPLE);
+ pthread_cond_init (&op->cond, 0);
- parent_class = g_type_class_peek_parent (klass);
-
- cal_client_signals[CAL_OPENED] =
- g_signal_new ("cal_opened",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (CalClientClass, cal_opened),
- NULL, NULL,
- g_cclosure_marshal_VOID__ENUM,
- G_TYPE_NONE, 1,
- CAL_CLIENT_OPEN_STATUS_ENUM_TYPE);
- cal_client_signals[CAL_SET_MODE] =
- g_signal_new ("cal_set_mode",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (CalClientClass, cal_set_mode),
- NULL, NULL,
- cal_util_marshal_VOID__ENUM_ENUM,
- G_TYPE_NONE, 2,
- CAL_CLIENT_SET_MODE_STATUS_ENUM_TYPE,
- CAL_MODE_ENUM_TYPE);
- cal_client_signals[OBJ_UPDATED] =
- g_signal_new ("obj_updated",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (CalClientClass, obj_updated),
- NULL, NULL,
- g_cclosure_marshal_VOID__STRING,
- G_TYPE_NONE, 1,
- G_TYPE_STRING);
- cal_client_signals[OBJ_REMOVED] =
- g_signal_new ("obj_removed",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (CalClientClass, obj_removed),
- NULL, NULL,
- g_cclosure_marshal_VOID__STRING,
- G_TYPE_NONE, 1,
- G_TYPE_STRING);
- cal_client_signals[BACKEND_ERROR] =
- g_signal_new ("backend_error",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (CalClientClass, backend_error),
- NULL, NULL,
- g_cclosure_marshal_VOID__STRING,
- G_TYPE_NONE, 1,
- G_TYPE_STRING);
- cal_client_signals[CATEGORIES_CHANGED] =
- g_signal_new ("categories_changed",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (CalClientClass, categories_changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__POINTER,
- G_TYPE_NONE, 1,
- G_TYPE_POINTER);
- cal_client_signals[FORGET_PASSWORD] =
- g_signal_new ("forget_password",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (CalClientClass, forget_password),
- NULL, NULL,
- g_cclosure_marshal_VOID__STRING,
- G_TYPE_NONE, 1,
- G_TYPE_STRING);
- cal_client_signals[BACKEND_DIED] =
- g_signal_new ("backend_died",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (CalClientClass, backend_died),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
+ client->priv->current_op = op;
- klass->cal_opened = NULL;
- klass->obj_updated = NULL;
- klass->obj_removed = NULL;
- klass->categories_changed = NULL;
- klass->forget_password = NULL;
- klass->backend_died = NULL;
+ return op;
+}
- object_class->finalize = cal_client_finalize;
+static ECalendarOp*
+e_calendar_get_op (CalClient *client)
+{
+ if (!client->priv->current_op) {
+ g_warning (G_STRLOC ": Unexpected response");
+ return NULL;
+ }
+
+ return client->priv->current_op;
}
-/* Object initialization function for the calendar client */
static void
-cal_client_init (CalClient *client, CalClientClass *klass)
+e_calendar_free_op (ECalendarOp *op)
{
- CalClientPrivate *priv;
+ /* XXX more stuff here */
+ pthread_cond_destroy (&op->cond);
+ e_mutex_destroy (op->mutex);
+ g_free (op);
+}
- priv = g_new0 (CalClientPrivate, 1);
- client->priv = priv;
+static void
+e_calendar_remove_op (CalClient *client, ECalendarOp *op)
+{
+ if (client->priv->current_op != op)
+ g_warning (G_STRLOC ": Cannot remove op, it's not current");
- priv->load_state = CAL_CLIENT_LOAD_NOT_LOADED;
- priv->uri = NULL;
- priv->cal_address = NULL;
- priv->alarm_email_address = NULL;
- priv->ldap_attribute = NULL;
- priv->capabilities = FALSE;
- priv->factories = NULL;
- priv->timezones = g_hash_table_new (g_str_hash, g_str_equal);
- priv->default_zone = icaltimezone_get_utc_timezone ();
- priv->comp_listener = NULL;
+ client->priv->current_op = NULL;
}
/* Gets rid of the factories that a client knows about */
@@ -364,7 +304,7 @@ destroy_cal (CalClient *client)
CORBA_exception_init (&ev);
result = CORBA_Object_is_nil (priv->cal, &ev);
if (BONOBO_EX (&ev)) {
- g_message ("destroy_cal(): could not see if the "
+ g_message (G_STRLOC ": could not see if the "
"calendar client interface object was nil");
priv->cal = CORBA_OBJECT_NIL;
CORBA_exception_free (&ev);
@@ -375,19 +315,7 @@ destroy_cal (CalClient *client)
if (result)
return;
- CORBA_exception_init (&ev);
- GNOME_Evolution_Calendar_Cal_unref (priv->cal, &ev);
- if (BONOBO_EX (&ev))
- 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 (BONOBO_EX (&ev))
- g_message ("destroy_cal(): could not release the calendar client interface object");
-
- CORBA_exception_free (&ev);
+ bonobo_object_release_unref (priv->cal, NULL);
priv->cal = CORBA_OBJECT_NIL;
}
@@ -400,184 +328,541 @@ free_timezone (gpointer key, gpointer value, gpointer data)
icaltimezone_free (value, TRUE);
}
-/* Finalize handler for the calendar client */
+
+
static void
-cal_client_finalize (GObject *object)
+backend_died_cb (EComponentListener *cl, gpointer user_data)
{
- CalClient *client;
CalClientPrivate *priv;
+ CalClient *client = (CalClient *) user_data;
- g_return_if_fail (object != NULL);
- g_return_if_fail (IS_CAL_CLIENT (object));
+ g_return_if_fail (IS_CAL_CLIENT (client));
- client = CAL_CLIENT (object);
priv = client->priv;
+ priv->load_state = CAL_CLIENT_LOAD_NOT_LOADED;
+ g_signal_emit (G_OBJECT (client), cal_client_signals[BACKEND_DIED], 0);
+}
- if (priv->listener) {
- cal_listener_stop_notification (priv->listener);
- bonobo_object_unref (priv->listener);
- priv->listener = NULL;
+/* Signal handlers for the listener's signals */
+/* Handle the cal_opened notification from the listener */
+
+static void
+cal_read_only_cb (CalListener *listener, ECalendarStatus status, gboolean read_only, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
}
- if (priv->comp_listener) {
- g_signal_handlers_disconnect_matched (G_OBJECT (priv->comp_listener),
- G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, NULL,
- client);
- g_object_unref (G_OBJECT (priv->comp_listener));
- priv->comp_listener = NULL;
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+ op->bool = read_only;
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
+
+static void
+cal_cal_address_cb (CalListener *listener, ECalendarStatus status, const char *address, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
}
- destroy_factories (client);
- destroy_cal (client);
+ e_mutex_lock (op->mutex);
- priv->load_state = CAL_CLIENT_LOAD_NOT_LOADED;
+ op->status = status;
+ op->string = g_strdup (address);
- if (priv->uri) {
- g_free (priv->uri);
- priv->uri = NULL;
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
+
+static void
+cal_alarm_address_cb (CalListener *listener, ECalendarStatus status, const char *address, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
}
- if (priv->cal_address) {
- g_free (priv->cal_address);
- priv->cal_address = NULL;
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+ op->string = g_strdup (address);
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
+
+static void
+cal_ldap_attribute_cb (CalListener *listener, ECalendarStatus status, const char *attribute, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
}
- if (priv->alarm_email_address) {
- g_free (priv->alarm_email_address);
- priv->alarm_email_address = NULL;
+
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+ op->string = g_strdup (attribute);
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
+
+static void
+cal_static_capabilities_cb (CalListener *listener, ECalendarStatus status, const char *capabilities, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
}
- if (priv->ldap_attribute) {
- g_free (priv->ldap_attribute);
- priv->ldap_attribute = NULL;
+
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+ op->string = g_strdup (capabilities);
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
+
+static void
+cal_opened_cb (CalListener *listener, ECalendarStatus status, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
}
- if (priv->capabilities) {
- g_free (priv->capabilities);
- priv->capabilities = NULL;
+
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
+
+static void
+cal_removed_cb (CalListener *listener, ECalendarStatus status, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
}
- g_hash_table_foreach (priv->timezones, free_timezone, NULL);
- g_hash_table_destroy (priv->timezones);
- priv->timezones = NULL;
+ e_mutex_lock (op->mutex);
- g_free (priv);
- client->priv = NULL;
+ op->status = status;
- if (G_OBJECT_CLASS (parent_class)->finalize)
- (* G_OBJECT_CLASS (parent_class)->finalize) (object);
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
}
-
+static void
+cal_object_created_cb (CalListener *listener, ECalendarStatus status, const char *uid, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
+ }
+
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+ op->uid = g_strdup (uid);
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
static void
-backend_died_cb (EComponentListener *cl, gpointer user_data)
+cal_object_modified_cb (CalListener *listener, ECalendarStatus status, gpointer data)
{
- CalClientPrivate *priv;
- CalClient *client = (CalClient *) user_data;
+ CalClient *client = data;
+ ECalendarOp *op;
- g_return_if_fail (IS_CAL_CLIENT (client));
+ op = e_calendar_get_op (client);
- priv = client->priv;
- priv->load_state = CAL_CLIENT_LOAD_NOT_LOADED;
- g_signal_emit (G_OBJECT (client), cal_client_signals[BACKEND_DIED], 0);
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
+ }
+
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
}
-/* Signal handlers for the listener's signals */
-/* Handle the cal_opened notification from the listener */
static void
-cal_opened_cb (CalListener *listener,
- GNOME_Evolution_Calendar_Listener_OpenStatus status,
- GNOME_Evolution_Calendar_Cal cal,
- gpointer data)
+cal_object_removed_cb (CalListener *listener, ECalendarStatus status, gpointer data)
{
- CalClient *client;
- CalClientPrivate *priv;
- CORBA_Environment ev;
- GNOME_Evolution_Calendar_Cal cal_copy;
- CalClientOpenStatus client_status;
+ CalClient *client = data;
+ ECalendarOp *op;
- client = CAL_CLIENT (data);
- priv = client->priv;
+ op = e_calendar_get_op (client);
- g_assert (priv->load_state == CAL_CLIENT_LOAD_LOADING);
- g_assert (priv->uri != NULL);
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
+ }
- client_status = CAL_CLIENT_OPEN_ERROR;
+ e_mutex_lock (op->mutex);
- switch (status) {
- case GNOME_Evolution_Calendar_Listener_SUCCESS:
- CORBA_exception_init (&ev);
- cal_copy = CORBA_Object_duplicate (cal, &ev);
- if (BONOBO_EX (&ev)) {
- g_message ("cal_opened_cb(): could not duplicate the "
- "calendar client interface");
- CORBA_exception_free (&ev);
- goto error;
- }
- CORBA_exception_free (&ev);
+ op->status = status;
- priv->cal = cal_copy;
- priv->load_state = CAL_CLIENT_LOAD_LOADED;
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
- client_status = CAL_CLIENT_OPEN_SUCCESS;
+static void
+cal_alarm_discarded_cb (CalListener *listener, ECalendarStatus status, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
- /* setup component listener */
- priv->comp_listener = e_component_listener_new (priv->cal);
- g_signal_connect (G_OBJECT (priv->comp_listener), "component_died",
- G_CALLBACK (backend_died_cb), client);
- goto out;
+ op = e_calendar_get_op (client);
- case GNOME_Evolution_Calendar_Listener_ERROR:
- client_status = CAL_CLIENT_OPEN_ERROR;
- goto error;
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
+ }
- case GNOME_Evolution_Calendar_Listener_NOT_FOUND:
- client_status = CAL_CLIENT_OPEN_NOT_FOUND;
- goto error;
+ e_mutex_lock (op->mutex);
- case GNOME_Evolution_Calendar_Listener_METHOD_NOT_SUPPORTED:
- client_status = CAL_CLIENT_OPEN_METHOD_NOT_SUPPORTED;
- goto error;
+ op->status = status;
- case GNOME_Evolution_Calendar_Listener_PERMISSION_DENIED :
- client_status = CAL_CLIENT_OPEN_PERMISSION_DENIED;
- goto error;
+ pthread_cond_signal (&op->cond);
- default:
- g_assert_not_reached ();
+ e_mutex_unlock (op->mutex);
+}
+
+static void
+cal_objects_received_cb (CalListener *listener, ECalendarStatus status, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
}
- error:
+ e_mutex_lock (op->mutex);
- bonobo_object_unref (BONOBO_OBJECT (priv->listener));
- priv->listener = NULL;
+ op->status = status;
- /* We free the priv->uri and set the priv->load_state until after the
- * "cal_opened" signal has been emitted so that handlers will be able to
- * access this information.
- */
+ pthread_cond_signal (&op->cond);
- out:
+ e_mutex_unlock (op->mutex);
+}
- /* We are *not* inside a signal handler (this is just a simple callback
- * called from the listener), so there is not a temporary reference to
- * the client object. We ref() so that we can safely emit our own
- * signal and clean up.
- */
+static void
+cal_objects_sent_cb (CalListener *listener, ECalendarStatus status, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
- g_object_ref (G_OBJECT (client));
+ op = e_calendar_get_op (client);
- g_signal_emit (G_OBJECT (client), cal_client_signals[CAL_OPENED],
- 0, client_status);
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
+ }
- if (client_status != CAL_CLIENT_OPEN_SUCCESS) {
- priv->load_state = CAL_CLIENT_LOAD_NOT_LOADED;
- g_free (priv->uri);
- priv->uri = NULL;
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
+
+static void
+cal_default_object_requested_cb (CalListener *listener, ECalendarStatus status, const char *object, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
}
- g_assert (priv->load_state != CAL_CLIENT_LOAD_LOADING);
+ e_mutex_lock (op->mutex);
- g_object_unref (G_OBJECT (client));
+ op->status = status;
+ op->string = g_strdup (object);
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
+
+static void
+cal_object_requested_cb (CalListener *listener, ECalendarStatus status, const char *object, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
+ }
+
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+ op->string = g_strdup (object);
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
+
+static void
+cal_object_list_cb (CalListener *listener, ECalendarStatus status, GList *objects, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+ GList *l;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
+ }
+
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+ op->list = g_list_copy (objects);
+
+ for (l = op->list; l; l = l->next)
+ l->data = icalcomponent_new_clone (l->data);
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
+
+static void
+cal_get_timezone_cb (CalListener *listener, ECalendarStatus status, const char *object, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
+ }
+
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+ op->string = g_strdup (object);
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+
+}
+
+static void
+cal_add_timezone_cb (CalListener *listener, ECalendarStatus status, const char *tzid, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
+ }
+
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+ op->uid = g_strdup (tzid);
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+
+}
+
+static void
+cal_set_default_timezone_cb (CalListener *listener, ECalendarStatus status, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
+ }
+
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
+
+static void
+cal_get_changes_cb (CalListener *listener, ECalendarStatus status, GList *changes, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+ GList *l;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
+ }
+
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+ op->list = g_list_copy (changes);
+
+ for (l = op->list; l; l = l->next) {
+ CalClientChange *ccc = l->data, *new_ccc;
+
+ new_ccc = g_new (CalClientChange, 1);
+ new_ccc->comp = cal_component_clone (ccc->comp);
+ new_ccc->type = ccc->type;
+
+ l->data = new_ccc;
+ }
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
+
+static void
+cal_get_free_busy_cb (CalListener *listener, ECalendarStatus status, GList *freebusy, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+ GList *l;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
+ }
+
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+ op->list = g_list_copy (freebusy);
+
+ for (l = op->list; l; l = l->next)
+ l->data = cal_component_clone (l->data);
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
+
+static void
+cal_query_cb (CalListener *listener, ECalendarStatus status, GNOME_Evolution_Calendar_Query query, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
+ }
+
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+ op->query = cal_query_new (query, op->listener, client);
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
}
/* Handle the cal_set_mode notification from the listener */
@@ -624,26 +909,6 @@ cal_set_mode_cb (CalListener *listener,
g_object_unref (G_OBJECT (client));
}
-/* Handle the obj_updated signal from the listener */
-static void
-obj_updated_cb (CalListener *listener, const CORBA_char *uid, gpointer data)
-{
- CalClient *client;
-
- client = CAL_CLIENT (data);
- g_signal_emit (G_OBJECT (client), cal_client_signals[OBJ_UPDATED], 0, uid);
-}
-
-/* Handle the obj_removed signal from the listener */
-static void
-obj_removed_cb (CalListener *listener, const CORBA_char *uid, gpointer data)
-{
- CalClient *client;
-
- client = CAL_CLIENT (data);
- g_signal_emit (G_OBJECT (client), cal_client_signals[OBJ_REMOVED], 0, uid);
-}
-
/* Handle the error_occurred signal from the listener */
static void
backend_error_cb (CalListener *listener, const char *message, gpointer data)
@@ -678,97 +943,343 @@ categories_changed_cb (CalListener *listener, const GNOME_Evolution_Calendar_Str
-static GList *
-get_factories (void)
+static gboolean
+get_factories (const char *str_uri, GList **factories)
{
- GList *factories = NULL;
GNOME_Evolution_Calendar_CalFactory factory;
Bonobo_ServerInfoList *servers;
- CORBA_Environment ev;
+ EUri *uri;
+ char *query;
int i;
- CORBA_exception_init (&ev);
- servers = bonobo_activation_query ("repo_ids.has ('IDL:GNOME/Evolution/Calendar/CalFactory:1.0')", NULL, &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_message ("Cannot perform OAF query for Calendar servers.");
- CORBA_exception_free (&ev);
- return NULL;
+ /* Determine the protocol and query for factory supporting that */
+ uri = e_uri_new (str_uri);
+ if (!uri) {
+ g_warning (G_STRLOC ": Invalid uri string");
+
+ return FALSE;
}
- if (servers->_length == 0)
- g_warning ("No Calendar servers installed.");
+ query = g_strdup_printf ("repo_ids.has ('IDL:GNOME/Evolution/Calendar/CalFactory:1.0')"
+ " AND calendar:supported_protocols.has ('%s')", uri->protocol);
+
+
+ servers = bonobo_activation_query (query, NULL, NULL);
+
+ g_free (query);
+ e_uri_free (uri);
+ if (!servers) {
+ g_warning (G_STRLOC ": Unable to query for calendar factories");
+
+ return FALSE;
+ }
+
+ /* Try to activate the servers for the protocol */
for (i = 0; i < servers->_length; i++) {
const Bonobo_ServerInfo *info;
info = servers->_buffer + i;
- factory = (GNOME_Evolution_Calendar_CalFactory)
- bonobo_activation_activate_from_id (info->iid, 0, NULL, &ev);
- if (BONOBO_EX (&ev)) {
-#if 0
- g_warning ("cal_client_construct: Could not activate calendar server %s", info->iid);
- CORBA_free (servers);
- CORBA_exception_free (&ev);
- return NULL;
-#endif
- }
+ g_message (G_STRLOC ": Activating calendar factory (%s)", info->iid);
+ factory = bonobo_activation_activate_from_id (info->iid, 0, NULL, NULL);
+
+ if (factory == CORBA_OBJECT_NIL)
+ g_warning (G_STRLOC ": Could not activate calendar factory (%s)", info->iid);
else
- factories = g_list_prepend (factories, factory);
+ *factories = g_list_append (*factories, factory);
}
CORBA_free (servers);
- CORBA_exception_free (&ev);
- return factories;
+
+ return TRUE;
+}
+
+/* Object initialization function for the calendar client */
+static void
+cal_client_init (CalClient *client, CalClientClass *klass)
+{
+ CalClientPrivate *priv;
+
+ priv = g_new0 (CalClientPrivate, 1);
+ client->priv = priv;
+
+ priv->load_state = CAL_CLIENT_LOAD_NOT_LOADED;
+ priv->uri = NULL;
+ priv->mutex = e_mutex_new (E_MUTEX_REC);
+ priv->listener = cal_listener_new (cal_set_mode_cb,
+ backend_error_cb,
+ categories_changed_cb,
+ client);
+
+ priv->cal_address = NULL;
+ priv->alarm_email_address = NULL;
+ priv->ldap_attribute = NULL;
+ priv->capabilities = FALSE;
+ priv->factories = NULL;
+ priv->timezones = g_hash_table_new (g_str_hash, g_str_equal);
+ priv->default_zone = icaltimezone_get_utc_timezone ();
+ priv->comp_listener = NULL;
+
+ g_signal_connect (G_OBJECT (priv->listener), "read_only", G_CALLBACK (cal_read_only_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "cal_address", G_CALLBACK (cal_cal_address_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "alarm_address", G_CALLBACK (cal_alarm_address_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "ldap_attribute", G_CALLBACK (cal_ldap_attribute_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "static_capabilities", G_CALLBACK (cal_static_capabilities_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "open", G_CALLBACK (cal_opened_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "remove", G_CALLBACK (cal_removed_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "create_object", G_CALLBACK (cal_object_created_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "modify_object", G_CALLBACK (cal_object_modified_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "remove_object", G_CALLBACK (cal_object_removed_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "discard_alarm", G_CALLBACK (cal_alarm_discarded_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "receive_objects", G_CALLBACK (cal_objects_received_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "send_objects", G_CALLBACK (cal_objects_sent_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "default_object", G_CALLBACK (cal_default_object_requested_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "object", G_CALLBACK (cal_object_requested_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "object_list", G_CALLBACK (cal_object_list_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "get_timezone", G_CALLBACK (cal_get_timezone_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "add_timezone", G_CALLBACK (cal_add_timezone_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "set_default_timezone", G_CALLBACK (cal_set_default_timezone_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "get_changes", G_CALLBACK (cal_get_changes_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "get_free_busy", G_CALLBACK (cal_get_free_busy_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "query", G_CALLBACK (cal_query_cb), client);
+}
+
+/* Finalize handler for the calendar client */
+static void
+cal_client_finalize (GObject *object)
+{
+ CalClient *client;
+ CalClientPrivate *priv;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (IS_CAL_CLIENT (object));
+
+ client = CAL_CLIENT (object);
+ priv = client->priv;
+
+ if (priv->listener) {
+ cal_listener_stop_notification (priv->listener);
+ bonobo_object_unref (priv->listener);
+ priv->listener = NULL;
+ }
+
+ if (priv->comp_listener) {
+ g_signal_handlers_disconnect_matched (G_OBJECT (priv->comp_listener),
+ G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL,
+ client);
+ g_object_unref (G_OBJECT (priv->comp_listener));
+ priv->comp_listener = NULL;
+ }
+
+ destroy_factories (client);
+ destroy_cal (client);
+
+ priv->load_state = CAL_CLIENT_LOAD_NOT_LOADED;
+
+ if (priv->uri) {
+ g_free (priv->uri);
+ priv->uri = NULL;
+ }
+
+ if (priv->mutex) {
+ e_mutex_destroy (priv->mutex);
+ priv->mutex = NULL;
+ }
+
+ if (priv->cal_address) {
+ g_free (priv->cal_address);
+ priv->cal_address = NULL;
+ }
+ if (priv->alarm_email_address) {
+ g_free (priv->alarm_email_address);
+ priv->alarm_email_address = NULL;
+ }
+ if (priv->ldap_attribute) {
+ g_free (priv->ldap_attribute);
+ priv->ldap_attribute = NULL;
+ }
+ if (priv->capabilities) {
+ g_free (priv->capabilities);
+ priv->capabilities = NULL;
+ }
+
+ g_hash_table_foreach (priv->timezones, free_timezone, NULL);
+ g_hash_table_destroy (priv->timezones);
+ priv->timezones = NULL;
+
+ g_free (priv);
+ client->priv = NULL;
+
+ if (G_OBJECT_CLASS (parent_class)->finalize)
+ (* G_OBJECT_CLASS (parent_class)->finalize) (object);
+}
+
+/* Class initialization function for the calendar client */
+static void
+cal_client_class_init (CalClientClass *klass)
+{
+ GObjectClass *object_class;
+
+ object_class = (GObjectClass *) klass;
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ cal_client_signals[CAL_OPENED] =
+ g_signal_new ("cal_opened",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (CalClientClass, cal_opened),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__ENUM,
+ G_TYPE_NONE, 1,
+ CAL_CLIENT_OPEN_STATUS_ENUM_TYPE);
+ cal_client_signals[CAL_SET_MODE] =
+ g_signal_new ("cal_set_mode",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (CalClientClass, cal_set_mode),
+ NULL, NULL,
+ cal_util_marshal_VOID__ENUM_ENUM,
+ G_TYPE_NONE, 2,
+ CAL_CLIENT_SET_MODE_STATUS_ENUM_TYPE,
+ CAL_MODE_ENUM_TYPE);
+ cal_client_signals[BACKEND_ERROR] =
+ g_signal_new ("backend_error",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (CalClientClass, backend_error),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1,
+ G_TYPE_STRING);
+ cal_client_signals[CATEGORIES_CHANGED] =
+ g_signal_new ("categories_changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (CalClientClass, categories_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1,
+ G_TYPE_POINTER);
+ cal_client_signals[FORGET_PASSWORD] =
+ g_signal_new ("forget_password",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (CalClientClass, forget_password),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1,
+ G_TYPE_STRING);
+ cal_client_signals[BACKEND_DIED] =
+ g_signal_new ("backend_died",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (CalClientClass, backend_died),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ klass->cal_opened = NULL;
+ klass->categories_changed = NULL;
+ klass->forget_password = NULL;
+ klass->backend_died = NULL;
+
+ object_class->finalize = cal_client_finalize;
}
/**
- * cal_client_construct:
- * @client: A calendar client.
+ * cal_client_get_type:
*
- * Constructs a calendar client object by contacting all available
- * calendar factories.
+ * Registers the #CalClient class if necessary, and returns the type ID assigned
+ * to it.
*
- * Return value: The same object as the @client argument, or NULL if the
- * calendar factory could not be contacted.
+ * Return value: The type ID of the #CalClient class.
**/
-CalClient *
-cal_client_construct (CalClient *client)
+GType
+cal_client_get_type (void)
{
- CalClientPrivate *priv;
+ static GType cal_client_type = 0;
- g_return_val_if_fail (client != NULL, NULL);
- g_return_val_if_fail (IS_CAL_CLIENT (client), NULL);
+ if (!cal_client_type) {
+ static GTypeInfo info = {
+ sizeof (CalClientClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) cal_client_class_init,
+ NULL, NULL,
+ sizeof (CalClient),
+ 0,
+ (GInstanceInitFunc) cal_client_init
+ };
+ cal_client_type = g_type_register_static (G_TYPE_OBJECT, "CalClient", &info, 0);
+ }
+ return cal_client_type;
+}
+
+
+static gboolean
+fetch_corba_cal (CalClient *client, const char *str_uri, CalObjType type)
+{
+ CalClientPrivate *priv;
+ GList *f;
+ CORBA_Environment ev;
+
priv = client->priv;
- priv->factories = get_factories ();
+ g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_NOT_LOADED, FALSE);
+ g_assert (priv->uri == NULL);
- return client;
+ g_return_val_if_fail (str_uri != NULL, FALSE);
+
+ if (!get_factories (str_uri, &priv->factories))
+ return FALSE;
+
+ priv->uri = g_strdup (str_uri);
+ priv->type = type;
+
+ for (f = priv->factories; f; f = f->next) {
+ GNOME_Evolution_Calendar_Cal cal;
+
+ CORBA_exception_init (&ev);
+
+ cal = GNOME_Evolution_Calendar_CalFactory_getCal (f->data, priv->uri, priv->type,
+ BONOBO_OBJREF (priv->listener), &ev);
+ if (BONOBO_EX (&ev))
+ continue;
+
+ priv->cal = cal;
+
+ return TRUE;
+ }
+
+ return FALSE;
}
/**
* cal_client_new:
*
* Creates a new calendar client. It should be initialized by calling
- * cal_client_open_calendar().
+ * cal_client_open().
*
* Return value: A newly-created calendar client, or NULL if the client could
* not be constructed because it could not contact the calendar server.
**/
CalClient *
-cal_client_new (void)
+cal_client_new (const char *uri, CalObjType type)
{
CalClient *client;
client = g_object_new (CAL_CLIENT_TYPE, NULL);
- if (!cal_client_construct (client)) {
- g_message ("cal_client_new(): could not construct the calendar client");
- g_object_unref (G_OBJECT (client));
+ if (!fetch_corba_cal (client, uri, type)) {
+ g_object_unref (client);
+
return NULL;
}
-
+
return client;
}
@@ -800,74 +1311,8 @@ cal_client_set_auth_func (CalClient *client, CalClientAuthFunc func, gpointer da
client->priv->auth_user_data = data;
}
-static gboolean
-real_open_calendar (CalClient *client, const char *str_uri, gboolean only_if_exists, gboolean *supported)
-{
- CalClientPrivate *priv;
- GNOME_Evolution_Calendar_Listener corba_listener;
- int unsupported;
- GList *f;
- CORBA_Environment ev;
-
- priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_NOT_LOADED, FALSE);
- g_assert (priv->uri == NULL);
-
- g_return_val_if_fail (str_uri != NULL, FALSE);
-
- priv->listener = cal_listener_new (cal_opened_cb,
- cal_set_mode_cb,
- obj_updated_cb,
- obj_removed_cb,
- backend_error_cb,
- categories_changed_cb,
- client);
- if (!priv->listener) {
- g_message ("cal_client_open_calendar(): could not create the listener");
- return FALSE;
- }
-
- corba_listener = (GNOME_Evolution_Calendar_Listener) (BONOBO_OBJREF (priv->listener));
-
- priv->load_state = CAL_CLIENT_LOAD_LOADING;
- priv->uri = g_strdup (str_uri);
-
- unsupported = 0;
- for (f = priv->factories; f; f = f->next) {
- CORBA_exception_init (&ev);
-
- GNOME_Evolution_Calendar_CalFactory_open (f->data, str_uri,
- only_if_exists,
- corba_listener, &ev);
- if (!BONOBO_EX (&ev)) {
- if (supported != NULL)
- *supported = TRUE;
- return TRUE;
- }
-
- if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_CalFactory_UnsupportedMethod))
- unsupported++;
- CORBA_exception_free (&ev);
- }
-
- if (supported != NULL) {
- if (unsupported == g_list_length (priv->factories))
- *supported = FALSE;
- else
- *supported = TRUE;
- }
-
- bonobo_object_unref (BONOBO_OBJECT (priv->listener));
- priv->listener = NULL;
- priv->load_state = CAL_CLIENT_LOAD_NOT_LOADED;
- g_free (priv->uri);
- priv->uri = NULL;
-
- return FALSE;
-}
-
/**
- * cal_client_open_calendar:
+ * cal_client_open
* @client: A calendar client.
* @str_uri: URI of calendar to open.
* @only_if_exists: FALSE if the calendar should be opened even if there
@@ -882,93 +1327,167 @@ real_open_calendar (CalClient *client, const char *str_uri, gboolean only_if_exi
* Return value: TRUE on success, FALSE on failure to issue the open request.
**/
gboolean
-cal_client_open_calendar (CalClient *client, const char *str_uri, gboolean only_if_exists)
+cal_client_open (CalClient *client, gboolean only_if_exists, GError **error)
{
+ CalClientPrivate *priv;
+ CORBA_Environment ev;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
+
g_return_val_if_fail (client != NULL, FALSE);
g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
- return real_open_calendar (client, str_uri, only_if_exists, NULL);
-}
+ priv = client->priv;
+
+ e_mutex_lock (client->priv->mutex);
-static char *
-get_fall_back_uri (gboolean tasks)
-{
- if (tasks)
- return g_concat_dir_and_file (g_get_home_dir (),
- "evolution/local/"
- "Tasks/tasks.ics");
- else
- return g_concat_dir_and_file (g_get_home_dir (),
- "evolution/local/"
- "Calendar/calendar.ics");
-}
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
-static char *
-get_default_uri (gboolean tasks)
-{
- EConfigListener *db;
- char *uri;
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
+
+ CORBA_exception_init (&ev);
+
+ priv->load_state = CAL_CLIENT_LOAD_LOADING;
+
+ GNOME_Evolution_Calendar_Cal_open (priv->cal, only_if_exists, &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ g_signal_emit (G_OBJECT (client), cal_client_signals[CAL_OPENED], 0,
+ E_CALENDAR_STATUS_CORBA_EXCEPTION);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
+ }
+
+ CORBA_exception_free (&ev);
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
- db = e_config_listener_new ();
+ status = our_op->status;
- if (tasks)
- uri = e_config_listener_get_string (db, "/apps/evolution/shell/default_folders/tasks_uri");
- else
- uri = e_config_listener_get_string (db, "/apps/evolution/shell/default_folders/calendar_uri");
- g_object_unref (G_OBJECT (db));
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
- if (!uri || *uri == '\0')
- uri = get_fall_back_uri (tasks);
+ if (status == E_CALENDAR_STATUS_OK)
+ priv->load_state = CAL_CLIENT_LOAD_LOADED;
else
- uri = cal_util_expand_uri (uri, tasks);
-
- return uri;
+ priv->load_state = CAL_CLIENT_LOAD_NOT_LOADED;
+
+ g_signal_emit (G_OBJECT (client), cal_client_signals[CAL_OPENED], 0, status);
+ E_CALENDAR_CHECK_STATUS (status, error);
}
-gboolean
-cal_client_open_default_calendar (CalClient *client, gboolean only_if_exists)
+typedef struct {
+ CalClient *client;
+
+ gboolean exists;
+} CalClientAsyncData;
+
+static gboolean
+open_async (gpointer data)
{
- char *default_uri, *fall_back;
- gboolean result, supported;
+ CalClientAsyncData *ccad = data;
+ GError *error = NULL;
- g_return_val_if_fail (client != NULL, FALSE);
- g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
+ cal_client_open (ccad->client, ccad->exists, &error);
- default_uri = get_default_uri (FALSE);
- fall_back = get_fall_back_uri (FALSE);
-
- result = real_open_calendar (client, default_uri, only_if_exists, &supported);
- if (!supported && strcmp (fall_back, default_uri))
- result = real_open_calendar (client, fall_back, only_if_exists, NULL);
+ g_clear_error (&error);
- g_free (default_uri);
- g_free (fall_back);
+ g_object_unref (ccad);
+ g_free (ccad);
- return result;
+ return FALSE;
}
-gboolean
-cal_client_open_default_tasks (CalClient *client, gboolean only_if_exists)
+void
+cal_client_open_async (CalClient *client, gboolean only_if_exists)
{
- char *default_uri, *fall_back;
- gboolean result, supported;
+ CalClientAsyncData *ccad;
+
+ g_return_if_fail (client != NULL);
+ g_return_if_fail (IS_CAL_CLIENT (client));
+
+ ccad = g_new0 (CalClientAsyncData, 1);
+ ccad->client = g_object_ref (client);
+ ccad->exists = only_if_exists;
+ /* FIXME This should really spawn a new thread */
+ g_idle_add (open_async, ccad);
+}
+
+gboolean
+cal_client_remove_calendar (CalClient *client, GError **error)
+{
+ CalClientPrivate *priv;
+ CORBA_Environment ev;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
+
g_return_val_if_fail (client != NULL, FALSE);
g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
- default_uri = get_default_uri (TRUE);
- fall_back = get_fall_back_uri (TRUE);
+ priv = client->priv;
+
+ e_mutex_lock (client->priv->mutex);
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
- result = real_open_calendar (client, default_uri, only_if_exists, &supported);
- if (!supported && strcmp (fall_back, default_uri))
- result = real_open_calendar (client, fall_back, only_if_exists, NULL);
+ e_mutex_lock (our_op->mutex);
- g_free (default_uri);
- g_free (fall_back);
+ e_mutex_unlock (client->priv->mutex);
+
+
+ CORBA_exception_init (&ev);
- return result;
+ GNOME_Evolution_Calendar_Cal_remove (priv->cal, &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
+ }
+
+ CORBA_exception_free (&ev);
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
}
+#if 0
/* Builds an URI list out of a CORBA string sequence */
static GList *
build_uri_list (GNOME_Evolution_Calendar_StringSeq *seq)
@@ -981,6 +1500,7 @@ build_uri_list (GNOME_Evolution_Calendar_StringSeq *seq)
return uris;
}
+#endif
/**
* cal_client_uri_list:
@@ -993,6 +1513,7 @@ build_uri_list (GNOME_Evolution_Calendar_StringSeq *seq)
GList *
cal_client_uri_list (CalClient *client, CalMode mode)
{
+#if 0
CalClientPrivate *priv;
GNOME_Evolution_Calendar_StringSeq *uri_seq;
GList *uris = NULL;
@@ -1026,8 +1547,12 @@ cal_client_uri_list (CalClient *client, CalMode mode)
}
return uris;
+#endif
+
+ return NULL;
}
+
/**
* cal_client_get_load_state:
* @client: A calendar client.
@@ -1076,33 +1601,72 @@ cal_client_get_uri (CalClient *client)
* @client: A calendar client.
*
* Queries whether the calendar client can perform modifications
- * on the calendar or not.
+ * on the calendar or not. Whether the backend is read only or not
+ * is specified, on exit, in the @read_only argument.
*
- * Return value: TRUE if the calendar is read-only, FALSE otherwise.
+ * Return value: TRUE if the call was successful, FALSE if there was an error.
*/
gboolean
-cal_client_is_read_only (CalClient *client)
+cal_client_is_read_only (CalClient *client, gboolean *read_only, GError **error)
{
CalClientPrivate *priv;
CORBA_Environment ev;
- CORBA_boolean read_only;
-
+ ECalendarStatus status;
+ ECalendarOp *our_op;
+
g_return_val_if_fail (client != NULL, FALSE);
g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
priv = client->priv;
+
+ e_mutex_lock (client->priv->mutex);
+
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
- if (priv->load_state != CAL_CLIENT_LOAD_LOADED)
- return FALSE;
CORBA_exception_init (&ev);
- read_only = GNOME_Evolution_Calendar_Cal_isReadOnly (priv->cal, &ev);
+
+ GNOME_Evolution_Calendar_Cal_isReadOnly (priv->cal, &ev);
if (BONOBO_EX (&ev)) {
- g_message ("cal_client_is_read_only: could not call isReadOnly method");
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
}
+
CORBA_exception_free (&ev);
- return read_only;
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+ *read_only = our_op->bool;
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ return status;
}
/**
@@ -1115,119 +1679,269 @@ cal_client_is_read_only (CalClient *client)
* is loaded or being loaded, or %NULL if the client has not started a
* load request yet or the calendar has no associated email address.
**/
-const char *
-cal_client_get_cal_address (CalClient *client)
+gboolean
+cal_client_get_cal_address (CalClient *client, char **cal_address, GError **error)
{
CalClientPrivate *priv;
-
- g_return_val_if_fail (client != NULL, NULL);
- g_return_val_if_fail (IS_CAL_CLIENT (client), NULL);
+ CORBA_Environment ev;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
+
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, NULL);
+
+ e_mutex_lock (client->priv->mutex);
- if (priv->cal_address == NULL) {
- CORBA_Environment ev;
- CORBA_char *cal_address;
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
+
+
+ CORBA_exception_init (&ev);
+
+ GNOME_Evolution_Calendar_Cal_getCalAddress (priv->cal, &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
- CORBA_exception_init (&ev);
- cal_address = GNOME_Evolution_Calendar_Cal_getCalAddress (priv->cal, &ev);
- if (!BONOBO_EX (&ev)) {
- priv->cal_address = g_strdup (cal_address);
- CORBA_free (cal_address);
- }
CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
}
- return priv->cal_address;
+ CORBA_exception_free (&ev);
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+ *cal_address = our_op->string;
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
}
-const char *
-cal_client_get_alarm_email_address (CalClient *client)
+gboolean
+cal_client_get_alarm_email_address (CalClient *client, char **alarm_address, GError **error)
{
CalClientPrivate *priv;
+ CORBA_Environment ev;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
- g_return_val_if_fail (client != NULL, NULL);
- g_return_val_if_fail (IS_CAL_CLIENT (client), NULL);
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, NULL);
- if (priv->alarm_email_address == NULL) {
- CORBA_Environment ev;
- CORBA_char *email_address;
+ e_mutex_lock (client->priv->mutex);
+
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
+
+
+ CORBA_exception_init (&ev);
+
+ GNOME_Evolution_Calendar_Cal_getAlarmEmailAddress (priv->cal, &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
- CORBA_exception_init (&ev);
- email_address = GNOME_Evolution_Calendar_Cal_getAlarmEmailAddress (priv->cal, &ev);
- if (!BONOBO_EX (&ev)) {
- priv->alarm_email_address = g_strdup (email_address);
- CORBA_free (email_address);
- }
CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
}
- return priv->alarm_email_address;
+ CORBA_exception_free (&ev);
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+ *alarm_address = our_op->string;
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
}
-const char *
-cal_client_get_ldap_attribute (CalClient *client)
+gboolean
+cal_client_get_ldap_attribute (CalClient *client, char **ldap_attribute, GError **error)
{
CalClientPrivate *priv;
+ CORBA_Environment ev;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
- g_return_val_if_fail (client != NULL, NULL);
- g_return_val_if_fail (IS_CAL_CLIENT (client), NULL);
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, NULL);
- if (priv->ldap_attribute == NULL) {
- CORBA_Environment ev;
- CORBA_char *ldap_attribute;
+ e_mutex_lock (client->priv->mutex);
+
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
+
+
+ CORBA_exception_init (&ev);
+
+ GNOME_Evolution_Calendar_Cal_getLdapAttribute (priv->cal, &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
- CORBA_exception_init (&ev);
- ldap_attribute = GNOME_Evolution_Calendar_Cal_getLdapAttribute (priv->cal, &ev);
- if (!BONOBO_EX (&ev)) {
- priv->ldap_attribute = g_strdup (ldap_attribute);
- CORBA_free (ldap_attribute);
- }
CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
}
- return priv->ldap_attribute;
+ CORBA_exception_free (&ev);
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+ *ldap_attribute = our_op->string;
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
}
-static void
-load_static_capabilities (CalClient *client)
+static gboolean
+load_static_capabilities (CalClient *client, GError **error)
{
CalClientPrivate *priv;
CORBA_Environment ev;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
char *cap;
priv = client->priv;
if (priv->capabilities)
- return;
-
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
+
+ e_mutex_lock (client->priv->mutex);
+
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
+
+
CORBA_exception_init (&ev);
- cap = GNOME_Evolution_Calendar_Cal_getStaticCapabilities (priv->cal, &ev);
- if (!BONOBO_EX (&ev))
- priv->capabilities = g_strdup (cap);
- else
- priv->capabilities = g_strdup ("");
- CORBA_free (cap);
+ GNOME_Evolution_Calendar_Cal_getStaticCapabilities (priv->cal, &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
+ }
+
CORBA_exception_free (&ev);
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+ cap = our_op->string;
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
}
static gboolean
check_capability (CalClient *client, const char *cap)
{
CalClientPrivate *priv;
-
+
priv = client->priv;
- load_static_capabilities (client);
- if (strstr (priv->capabilities, cap))
+ /* FIXME Check result */
+ load_static_capabilities (client, NULL);
+ if (priv->capabilities && strstr (priv->capabilities, cap))
return TRUE;
return FALSE;
@@ -1269,15 +1983,6 @@ cal_client_get_save_schedules (CalClient *client)
return check_capability (client, CAL_STATIC_CAPABILITY_SAVE_SCHEDULES);
}
-/* Converts our representation of a calendar component type into its CORBA representation */
-static GNOME_Evolution_Calendar_CalObjType
-corba_obj_type (CalObjType type)
-{
- return (((type & CALOBJ_TYPE_EVENT) ? GNOME_Evolution_Calendar_TYPE_EVENT : 0)
- | ((type & CALOBJ_TYPE_TODO) ? GNOME_Evolution_Calendar_TYPE_TODO : 0)
- | ((type & CALOBJ_TYPE_JOURNAL) ? GNOME_Evolution_Calendar_TYPE_JOURNAL : 0));
-}
-
gboolean
cal_client_set_mode (CalClient *client, CalMode mode)
{
@@ -1302,45 +2007,6 @@ cal_client_set_mode (CalClient *client, CalMode mode)
return retval;
}
-/**
- * cal_client_get_n_objects:
- * @client: A calendar client.
- * @type: Type of objects that will be counted.
- *
- * Counts the number of calendar components of the specified @type. This can be
- * used to count how many events, to-dos, or journals there are, for example.
- *
- * Return value: Number of components.
- **/
-int
-cal_client_get_n_objects (CalClient *client, CalObjType type)
-{
- CalClientPrivate *priv;
- CORBA_Environment ev;
- int n;
- int t;
-
- g_return_val_if_fail (client != NULL, -1);
- g_return_val_if_fail (IS_CAL_CLIENT (client), -1);
-
- priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, -1);
-
- t = corba_obj_type (type);
-
- CORBA_exception_init (&ev);
- n = GNOME_Evolution_Calendar_Cal_countObjects (priv->cal, t, &ev);
-
- if (BONOBO_EX (&ev)) {
- g_message ("cal_client_get_n_objects(): could not get the number of objects");
- CORBA_exception_free (&ev);
- return -1;
- }
-
- CORBA_exception_free (&ev);
- return n;
-}
-
/* This is used in the callback which fetches all the timezones needed for an
object. */
@@ -1348,68 +2014,93 @@ typedef struct _CalClientGetTimezonesData CalClientGetTimezonesData;
struct _CalClientGetTimezonesData {
CalClient *client;
- /* This starts out at CAL_CLIENT_GET_SUCCESS. If an error occurs this
+ /* This starts out at E_CALENDAR_STATUS_OK. If an error occurs this
contains the last error. */
- CalClientGetStatus status;
+ ECalendarStatus status;
};
-CalClientGetStatus
-cal_client_get_default_object (CalClient *client, CalObjType type, icalcomponent **icalcomp)
+gboolean
+cal_client_get_default_object (CalClient *client, icalcomponent **icalcomp, GError **error)
{
CalClientPrivate *priv;
CORBA_Environment ev;
- GNOME_Evolution_Calendar_CalObj comp_str;
- CalClientGetStatus retval;
- CalClientGetTimezonesData cb_data;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
- g_return_val_if_fail (client != NULL, CAL_CLIENT_GET_NOT_FOUND);
- g_return_val_if_fail (IS_CAL_CLIENT (client), CAL_CLIENT_GET_NOT_FOUND);
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, CAL_CLIENT_GET_NOT_FOUND);
- g_return_val_if_fail (icalcomp != NULL, CAL_CLIENT_GET_NOT_FOUND);
+ e_mutex_lock (client->priv->mutex);
- retval = CAL_CLIENT_GET_NOT_FOUND;
- *icalcomp = NULL;
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
CORBA_exception_init (&ev);
- comp_str = GNOME_Evolution_Calendar_Cal_getDefaultObject (priv->cal, type, &ev);
- if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_NotFound))
- goto out;
- else if (BONOBO_EX (&ev)) {
- g_message ("cal_client_get_default_object(): could not get the object");
- goto out;
- }
+ GNOME_Evolution_Calendar_Cal_getDefaultObject (priv->cal, &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
- *icalcomp = icalparser_parse_string (comp_str);
- CORBA_free (comp_str);
+ CORBA_exception_free (&ev);
- if (!*icalcomp) {
- retval = CAL_CLIENT_GET_SYNTAX_ERROR;
- goto out;
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
}
- /* Now make sure we have all timezones needed for this object.
- We do this to try to avoid any problems caused by getting a timezone
- in the middle of other code. Any calls to ORBit result in a
- recursive call of the GTK+ main loop, which can cause problems for
- code that doesn't expect it. Currently GnomeCanvas has problems if
- we try to get a timezone in the middle of a redraw, and there is a
- resize pending, which leads to an assert failure and an abort. */
- cb_data.client = client;
- cb_data.status = CAL_CLIENT_GET_SUCCESS;
- icalcomponent_foreach_tzid (*icalcomp,
- cal_client_get_object_timezones_cb,
- &cb_data);
+ CORBA_exception_free (&ev);
- retval = cb_data.status;
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
- out:
+ status = our_op->status;
+ *icalcomp = icalparser_parse_string (our_op->string);
+ g_free (our_op->string);
- CORBA_exception_free (&ev);
- return retval;
+ if (!*icalcomp) {
+ status = E_CALENDAR_STATUS_INVALID_OBJECT;
+ } else {
+ CalClientGetTimezonesData cb_data;
+
+ /* Now make sure we have all timezones needed for this object.
+ We do this to try to avoid any problems caused by getting a timezone
+ in the middle of other code. Any calls to ORBit result in a
+ recursive call of the GTK+ main loop, which can cause problems for
+ code that doesn't expect it. Currently GnomeCanvas has problems if
+ we try to get a timezone in the middle of a redraw, and there is a
+ resize pending, which leads to an assert failure and an abort. */
+ cb_data.client = client;
+ cb_data.status = E_CALENDAR_STATUS_OK;
+ icalcomponent_foreach_tzid (*icalcomp,
+ cal_client_get_object_timezones_cb,
+ &cb_data);
+
+ status = cb_data.status;
+ }
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
}
/**
@@ -1423,64 +2114,89 @@ cal_client_get_default_object (CalClient *client, CalObjType type, icalcomponent
*
* Return value: Result code based on the status of the operation.
**/
-CalClientGetStatus
-cal_client_get_object (CalClient *client, const char *uid, icalcomponent **icalcomp)
+gboolean
+cal_client_get_object (CalClient *client, const char *uid, const char *rid, icalcomponent **icalcomp, GError **error)
{
+
CalClientPrivate *priv;
CORBA_Environment ev;
- GNOME_Evolution_Calendar_CalObj comp_str;
- CalClientGetStatus retval;
- CalClientGetTimezonesData cb_data;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
- g_return_val_if_fail (client != NULL, CAL_CLIENT_GET_NOT_FOUND);
- g_return_val_if_fail (IS_CAL_CLIENT (client), CAL_CLIENT_GET_NOT_FOUND);
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, CAL_CLIENT_GET_NOT_FOUND);
- g_return_val_if_fail (uid != NULL, CAL_CLIENT_GET_NOT_FOUND);
- g_return_val_if_fail (icalcomp != NULL, CAL_CLIENT_GET_NOT_FOUND);
+ e_mutex_lock (client->priv->mutex);
+
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
- retval = CAL_CLIENT_GET_NOT_FOUND;
- *icalcomp = NULL;
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
CORBA_exception_init (&ev);
- comp_str = GNOME_Evolution_Calendar_Cal_getObject (priv->cal, (char *) uid, &ev);
- if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_NotFound))
- goto out;
- else if (BONOBO_EX (&ev)) {
- g_message ("cal_client_get_object(): could not get the object");
- goto out;
- }
+ GNOME_Evolution_Calendar_Cal_getObject (priv->cal, uid, rid ? rid : "", &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
- *icalcomp = icalparser_parse_string (comp_str);
- CORBA_free (comp_str);
+ CORBA_exception_free (&ev);
- if (!*icalcomp) {
- retval = CAL_CLIENT_GET_SYNTAX_ERROR;
- goto out;
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
}
- /* Now make sure we have all timezones needed for this object.
- We do this to try to avoid any problems caused by getting a timezone
- in the middle of other code. Any calls to ORBit result in a
- recursive call of the GLib main loop, which can cause problems for
- code that doesn't expect it. Currently GnomeCanvas has problems if
- we try to get a timezone in the middle of a redraw, and there is a
- resize pending, which leads to an assert failure and an abort. */
- cb_data.client = client;
- cb_data.status = CAL_CLIENT_GET_SUCCESS;
- icalcomponent_foreach_tzid (*icalcomp,
- cal_client_get_object_timezones_cb,
- &cb_data);
+ CORBA_exception_free (&ev);
- retval = cb_data.status;
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
- out:
+ status = our_op->status;
+ *icalcomp = icalparser_parse_string (our_op->string);
+ g_free (our_op->string);
- CORBA_exception_free (&ev);
- return retval;
+ if (!*icalcomp) {
+ status = E_CALENDAR_STATUS_INVALID_OBJECT;
+ } else {
+ CalClientGetTimezonesData cb_data;
+
+ /* Now make sure we have all timezones needed for this object.
+ We do this to try to avoid any problems caused by getting a timezone
+ in the middle of other code. Any calls to ORBit result in a
+ recursive call of the GTK+ main loop, which can cause problems for
+ code that doesn't expect it. Currently GnomeCanvas has problems if
+ we try to get a timezone in the middle of a redraw, and there is a
+ resize pending, which leads to an assert failure and an abort. */
+ cb_data.client = client;
+ cb_data.status = E_CALENDAR_STATUS_OK;
+ icalcomponent_foreach_tzid (*icalcomp,
+ cal_client_get_object_timezones_cb,
+ &cb_data);
+
+ status = cb_data.status;
+ }
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
}
@@ -1491,106 +2207,18 @@ cal_client_get_object_timezones_cb (icalparameter *param,
CalClientGetTimezonesData *cb_data = data;
const char *tzid;
icaltimezone *zone;
- CalClientGetStatus status;
+ GError *error = NULL;
tzid = icalparameter_get_tzid (param);
if (!tzid) {
- cb_data->status = CAL_CLIENT_GET_SYNTAX_ERROR;
+ cb_data->status = E_CALENDAR_STATUS_INVALID_OBJECT;
return;
}
- status = cal_client_get_timezone (cb_data->client, tzid, &zone);
- if (status != CAL_CLIENT_GET_SUCCESS)
- cb_data->status = status;
-}
-
-
-CalClientGetStatus
-cal_client_get_timezone (CalClient *client,
- const char *tzid,
- icaltimezone **zone)
-{
- CalClientPrivate *priv;
- CORBA_Environment ev;
- GNOME_Evolution_Calendar_CalObj comp_str;
- CalClientGetStatus retval;
- icalcomponent *icalcomp;
- icaltimezone *tmp_zone;
-
- g_return_val_if_fail (client != NULL, CAL_CLIENT_GET_NOT_FOUND);
- g_return_val_if_fail (IS_CAL_CLIENT (client), CAL_CLIENT_GET_NOT_FOUND);
-
- priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED,
- CAL_CLIENT_GET_NOT_FOUND);
-
- g_return_val_if_fail (zone != NULL, CAL_CLIENT_GET_NOT_FOUND);
-
- /* If tzid is NULL or "" we return NULL, since it is a 'local time'. */
- if (!tzid || !tzid[0]) {
- *zone = NULL;
- return CAL_CLIENT_GET_SUCCESS;
- }
-
- /* If it is UTC, we return the special UTC timezone. */
- if (!strcmp (tzid, "UTC")) {
- *zone = icaltimezone_get_utc_timezone ();
- return CAL_CLIENT_GET_SUCCESS;
- }
-
- /* See if we already have it in the cache. */
- tmp_zone = g_hash_table_lookup (priv->timezones, tzid);
- if (tmp_zone) {
- *zone = tmp_zone;
- return CAL_CLIENT_GET_SUCCESS;
- }
-
- retval = CAL_CLIENT_GET_NOT_FOUND;
- *zone = NULL;
-
- /* We don't already have it, so we try to get it from the server. */
- CORBA_exception_init (&ev);
- comp_str = GNOME_Evolution_Calendar_Cal_getTimezoneObject (priv->cal, (char *) tzid, &ev);
-
- if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_NotFound))
- goto out;
- else if (BONOBO_EX (&ev)) {
- g_message ("cal_client_get_timezone(): could not get the object");
- goto out;
- }
-
- icalcomp = icalparser_parse_string (comp_str);
- CORBA_free (comp_str);
-
- if (!icalcomp) {
- retval = CAL_CLIENT_GET_SYNTAX_ERROR;
- goto out;
- }
-
- tmp_zone = icaltimezone_new ();
- if (!tmp_zone) {
- /* FIXME: Needs better error code - out of memory. Or just
- abort like GLib does? */
- retval = CAL_CLIENT_GET_NOT_FOUND;
- goto out;
- }
-
- if (!icaltimezone_set_component (tmp_zone, icalcomp)) {
- retval = CAL_CLIENT_GET_SYNTAX_ERROR;
- goto out;
- }
-
- /* Now add it to the cache, to avoid the server call in future. */
- g_hash_table_insert (priv->timezones, icaltimezone_get_tzid (tmp_zone),
- tmp_zone);
-
- *zone = tmp_zone;
- retval = CAL_CLIENT_GET_SUCCESS;
-
- out:
-
- CORBA_exception_free (&ev);
- return retval;
+ if (!cal_client_get_timezone (cb_data->client, tzid, &zone, &error))
+ cb_data->status = error->code;
+
+ g_clear_error (&error);
}
/* Resolves TZIDs for the recurrence generator. */
@@ -1599,7 +2227,6 @@ cal_client_resolve_tzid_cb (const char *tzid, gpointer data)
{
CalClient *client;
icaltimezone *zone = NULL;
- CalClientGetStatus status;
g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail (IS_CAL_CLIENT (data), NULL);
@@ -1607,219 +2234,180 @@ cal_client_resolve_tzid_cb (const char *tzid, gpointer data)
client = CAL_CLIENT (data);
/* FIXME: Handle errors. */
- status = cal_client_get_timezone (client, tzid, &zone);
+ cal_client_get_timezone (client, tzid, &zone, NULL);
return zone;
}
-
-/* Builds an UID list out of a CORBA UID sequence */
-static GList *
-build_uid_list (GNOME_Evolution_Calendar_CalObjUIDSeq *seq)
-{
- GList *uids;
- int i;
-
- uids = NULL;
-
- for (i = 0; i < seq->_length; i++)
- uids = g_list_prepend (uids, g_strdup (seq->_buffer[i]));
-
- return uids;
-}
-
-/**
- * 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. This should be
- * freed using the cal_obj_uid_list_free() function.
- **/
-GList *
-cal_client_get_uids (CalClient *client, CalObjType type)
+gboolean
+cal_client_get_changes (CalClient *client, CalObjType type, const char *change_id, GList **changes, GError **error)
{
- CalClientPrivate *priv;
CORBA_Environment ev;
- GNOME_Evolution_Calendar_CalObjUIDSeq *seq;
- int t;
- GList *uids;
+ ECalendarOp *our_op;
+ ECalendarStatus status;
- g_return_val_if_fail (client != NULL, NULL);
- g_return_val_if_fail (IS_CAL_CLIENT (client), NULL);
+ g_return_val_if_fail (client != NULL, E_CALENDAR_STATUS_INVALID_ARG);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), E_CALENDAR_STATUS_INVALID_ARG);
+ g_return_val_if_fail (change_id != NULL, E_CALENDAR_STATUS_INVALID_ARG);
- priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, NULL);
+ e_mutex_lock (client->priv->mutex);
- t = corba_obj_type (type);
-
- CORBA_exception_init (&ev);
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
- seq = GNOME_Evolution_Calendar_Cal_getUIDs (priv->cal, t, &ev);
- if (BONOBO_EX (&ev)) {
- g_message ("cal_client_get_uids(): could not get the list of UIDs");
- CORBA_exception_free (&ev);
- return NULL;
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
}
- CORBA_exception_free (&ev);
+ our_op = e_calendar_new_op (client);
- uids = build_uid_list (seq);
- CORBA_free (seq);
+ e_mutex_lock (our_op->mutex);
- return uids;
-}
+ e_mutex_unlock (client->priv->mutex);
-/* Builds a GList of CalClientChange structures from the CORBA sequence */
-static GList *
-build_change_list (GNOME_Evolution_Calendar_CalObjChangeSeq *seq)
-{
- GList *list = NULL;
- icalcomponent *icalcomp;
- int i;
+ CORBA_exception_init (&ev);
- /* Create the list in reverse order */
- for (i = 0; i < seq->_length; i++) {
- GNOME_Evolution_Calendar_CalObjChange *corba_coc;
- CalClientChange *ccc;
+ GNOME_Evolution_Calendar_Cal_getChanges (client->priv->cal, type, change_id, &ev);
- corba_coc = &seq->_buffer[i];
- ccc = g_new (CalClientChange, 1);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
- icalcomp = icalparser_parse_string (corba_coc->calobj);
- if (!icalcomp)
- continue;
+ CORBA_exception_free (&ev);
- ccc->comp = cal_component_new ();
- if (!cal_component_set_icalcomponent (ccc->comp, icalcomp)) {
- icalcomponent_free (icalcomp);
- g_object_unref (G_OBJECT (ccc->comp));
- continue;
- }
- ccc->type = corba_coc->type;
+ g_warning (G_STRLOC ": Unable to contact backend");
- list = g_list_prepend (list, ccc);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
}
+
+ CORBA_exception_free (&ev);
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
- list = g_list_reverse (list);
+ status = our_op->status;
+ *changes = our_op->list;
- return list;
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
}
-GList *
-cal_client_get_changes (CalClient *client, CalObjType type, const char *change_id)
+
+/**
+ * cal_client_get_object_list:
+ * @client:
+ * @query:
+ *
+ *
+ *
+ * Return value:
+ **/
+gboolean
+cal_client_get_object_list (CalClient *client, const char *query, GList **objects, GError **error)
{
- CalClientPrivate *priv;
CORBA_Environment ev;
- GNOME_Evolution_Calendar_CalObjChangeSeq *seq;
- int t;
- GList *changes;
+ ECalendarOp *our_op;
+ ECalendarStatus status;
- g_return_val_if_fail (client != NULL, NULL);
- g_return_val_if_fail (IS_CAL_CLIENT (client), NULL);
+ g_return_val_if_fail (client != NULL, E_CALENDAR_STATUS_INVALID_ARG);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), E_CALENDAR_STATUS_INVALID_ARG);
+ g_return_val_if_fail (query != NULL, E_CALENDAR_STATUS_INVALID_ARG);
- priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, NULL);
+ e_mutex_lock (client->priv->mutex);
- t = corba_obj_type (type);
- CORBA_exception_init (&ev);
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
- seq = GNOME_Evolution_Calendar_Cal_getChanges (priv->cal, t, change_id, &ev);
- if (BONOBO_EX (&ev)) {
- g_message ("cal_client_get_changes(): could not get the list of changes");
- CORBA_exception_free (&ev);
- return NULL;
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
}
- CORBA_exception_free (&ev);
+ our_op = e_calendar_new_op (client);
- changes = build_change_list (seq);
- CORBA_free (seq);
+ e_mutex_lock (our_op->mutex);
- return changes;
-}
+ e_mutex_unlock (client->priv->mutex);
-/* FIXME: Not used? */
-#if 0
-/* Builds a GList of CalObjInstance structures from the CORBA sequence */
-static GList *
-build_object_instance_list (GNOME_Evolution_Calendar_CalObjInstanceSeq *seq)
-{
- GList *list;
- int i;
+ CORBA_exception_init (&ev);
- /* Create the list in reverse order */
+ GNOME_Evolution_Calendar_Cal_getObjectList (client->priv->cal, query, &ev);
- list = NULL;
- for (i = 0; i < seq->_length; i++) {
- GNOME_Evolution_Calendar_CalObjInstance *corba_icoi;
- CalObjInstance *icoi;
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
- corba_icoi = &seq->_buffer[i];
- icoi = g_new (CalObjInstance, 1);
+ CORBA_exception_free (&ev);
- icoi->uid = g_strdup (corba_icoi->uid);
- icoi->start = corba_icoi->start;
- icoi->end = corba_icoi->end;
+ g_warning (G_STRLOC ": Unable to contact backend");
- list = g_list_prepend (list, icoi);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
}
+
+ CORBA_exception_free (&ev);
- list = g_list_reverse (list);
- return list;
-}
-#endif
-
-/**
- * cal_client_get_objects_in_range:
- * @client: A calendar client.
- * @type: Bitmask with types of objects to return.
- * @start: Start time for query.
- * @end: End time for query.
- *
- * Queries a calendar for the objects that occur or recur in the specified range
- * of time.
- *
- * Return value: A list of UID strings. This should be freed using the
- * cal_obj_uid_list_free() function.
- **/
-GList *
-cal_client_get_objects_in_range (CalClient *client, CalObjType type, time_t start, time_t end)
-{
- CalClientPrivate *priv;
- CORBA_Environment ev;
- GNOME_Evolution_Calendar_CalObjUIDSeq *seq;
- GList *uids;
- int t;
-
- g_return_val_if_fail (client != NULL, NULL);
- g_return_val_if_fail (IS_CAL_CLIENT (client), NULL);
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
- priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, NULL);
+ status = our_op->status;
+ *objects = our_op->list;
- g_return_val_if_fail (start != -1 && end != -1, NULL);
- g_return_val_if_fail (start <= end, NULL);
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
- CORBA_exception_init (&ev);
-
- t = corba_obj_type (type);
+ E_CALENDAR_CHECK_STATUS (status, error);
+}
- seq = GNOME_Evolution_Calendar_Cal_getObjectsInRange (priv->cal, t, start, end, &ev);
- if (BONOBO_EX (&ev)) {
- g_message ("cal_client_get_objects_in_range(): could not get the objects");
- CORBA_exception_free (&ev);
- return NULL;
+gboolean
+cal_client_get_object_list_as_comp (CalClient *client, const char *query, GList **objects, GError **error)
+{
+ GList *ical_objects = NULL;
+ GList *l;
+
+ g_return_val_if_fail (client != NULL, E_CALENDAR_STATUS_INVALID_ARG);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), E_CALENDAR_STATUS_INVALID_ARG);
+ g_return_val_if_fail (query != NULL, E_CALENDAR_STATUS_INVALID_ARG);
+ g_return_val_if_fail (objects != NULL, E_CALENDAR_STATUS_INVALID_ARG);
+
+ if (!cal_client_get_object_list (client, query, &ical_objects, error))
+ return FALSE;
+
+ *objects = NULL;
+ for (l = ical_objects; l; l = l->next) {
+ CalComponent *comp;
+
+ comp = cal_component_new ();
+ cal_component_set_icalcomponent (comp, l->data);
+ *objects = g_list_prepend (*objects, comp);
}
- CORBA_exception_free (&ev);
+
+ g_list_free (ical_objects);
- uids = build_uid_list (seq);
- CORBA_free (seq);
+ return TRUE;
+}
+
+void
+cal_client_free_object_list (GList *objects)
+{
+ GList *l;
+
+ for (l = objects; l; l = l->next)
+ icalcomponent_free (l->data);
- return uids;
+ g_list_free (objects);
}
/**
@@ -1833,57 +2421,81 @@ cal_client_get_objects_in_range (CalClient *client, CalObjType type, time_t star
*
* Returns: a GList of VFREEBUSY CalComponents
*/
-GList *
-cal_client_get_free_busy (CalClient *client, GList *users,
- time_t start, time_t end)
+gboolean
+cal_client_get_free_busy (CalClient *client, GList *users, time_t start, time_t end,
+ GList **freebusy, GError **error)
{
- CalClientPrivate *priv;
CORBA_Environment ev;
- GNOME_Evolution_Calendar_UserList *corba_list;
- GNOME_Evolution_Calendar_CalObjSeq *calobj_list;
+ ECalendarOp *our_op;
+ ECalendarStatus status;
+ GNOME_Evolution_Calendar_UserList corba_users;
GList *l;
- GList *comp_list = NULL;
- int len, i;
+ int i, len;
+
+ g_return_val_if_fail (client != NULL, E_CALENDAR_STATUS_INVALID_ARG);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), E_CALENDAR_STATUS_INVALID_ARG);
- g_return_val_if_fail (client != NULL, NULL);
- g_return_val_if_fail (IS_CAL_CLIENT (client), NULL);
+ e_mutex_lock (client->priv->mutex);
- priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, NULL);
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
- g_return_val_if_fail (start != -1 && end != -1, NULL);
- g_return_val_if_fail (start <= end, NULL);
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
/* create the CORBA user list to be passed to the backend */
len = g_list_length (users);
- corba_list = GNOME_Evolution_Calendar_UserList__alloc ();
- CORBA_sequence_set_release (corba_list, TRUE);
- corba_list->_length = len;
- corba_list->_buffer = CORBA_sequence_GNOME_Evolution_Calendar_User_allocbuf (len);
+ corba_users._length = len;
+ corba_users._buffer = CORBA_sequence_GNOME_Evolution_Calendar_User_allocbuf (len);
- for (l = g_list_first (users), i = 0; l; l = l->next, i++)
- corba_list->_buffer[i] = CORBA_string_dup ((CORBA_char *) l->data);
+ for (l = users, i = 0; l; l = l->next, i++)
+ corba_users._buffer[i] = CORBA_string_dup (l->data);
- /* call the method on the backend */
CORBA_exception_init (&ev);
- calobj_list = GNOME_Evolution_Calendar_Cal_getFreeBusy (priv->cal, corba_list,
- start, end, &ev);
- CORBA_free (corba_list);
- if (BONOBO_EX (&ev) || !calobj_list) {
- if (!BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_NotFound))
- g_message ("cal_client_get_free_busy(): could not get the objects");
+ GNOME_Evolution_Calendar_Cal_getFreeBusy (client->priv->cal, &corba_users, start, end, &ev);
+
+ CORBA_free (corba_users._buffer);
+
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
CORBA_exception_free (&ev);
- return NULL;
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
}
+
+ CORBA_exception_free (&ev);
- for (i = 0; i < calobj_list->_length; i++) {
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+
+ *freebusy = NULL;
+ for (l = our_op->list; l; l = l->next) {
CalComponent *comp;
+
icalcomponent *icalcomp;
icalcomponent_kind kind;
- icalcomp = icalparser_parse_string (calobj_list->_buffer[i]);
+ icalcomp = icalparser_parse_string (l->data);
if (!icalcomp)
continue;
@@ -1896,184 +2508,17 @@ cal_client_get_free_busy (CalClient *client, GList *users,
continue;
}
- comp_list = g_list_append (comp_list, comp);
+ *freebusy = g_list_append (*freebusy, comp);
}
else
icalcomponent_free (icalcomp);
}
- CORBA_exception_free (&ev);
- CORBA_free (calobj_list);
-
- return comp_list;
-}
-
-/* Callback used when an object is updated and we must update the copy we have */
-static void
-generate_instances_obj_updated_cb (CalClient *client, const char *uid, gpointer data)
-{
- GHashTable *uid_comp_hash;
- CalComponent *comp;
- icalcomponent *icalcomp;
- CalClientGetStatus status;
- const char *comp_uid;
-
- uid_comp_hash = data;
-
- comp = g_hash_table_lookup (uid_comp_hash, uid);
- if (!comp)
- /* OK, so we don't care about new objects that may indeed be in
- * the requested time range. We only care about the ones that
- * were returned by the first query to
- * cal_client_get_objects_in_range().
- */
- return;
-
- g_hash_table_remove (uid_comp_hash, uid);
- g_object_unref (G_OBJECT (comp));
-
- status = cal_client_get_object (client, uid, &icalcomp);
-
- switch (status) {
- case CAL_CLIENT_GET_SUCCESS:
- comp = cal_component_new ();
- if (cal_component_set_icalcomponent (comp, icalcomp)) {
- /* The hash key comes from the component's internal data */
- cal_component_get_uid (comp, &comp_uid);
- g_hash_table_insert (uid_comp_hash, (char *) comp_uid, comp);
- } else {
- g_object_unref (comp);
- icalcomponent_free (icalcomp);
- }
- break;
-
- case CAL_CLIENT_GET_NOT_FOUND:
- /* No longer in the server, too bad */
- break;
-
- case CAL_CLIENT_GET_SYNTAX_ERROR:
- g_message ("obj_updated_cb(): Syntax error when getting "
- "object `%s'; ignoring...", uid);
- break;
-
- }
-}
-
-/* Callback used when an object is removed and we must delete the copy we have */
-static void
-generate_instances_obj_removed_cb (CalClient *client, const char *uid, gpointer data)
-{
- GHashTable *uid_comp_hash;
- CalComponent *comp;
-
- uid_comp_hash = data;
-
- comp = g_hash_table_lookup (uid_comp_hash, uid);
- if (!comp)
- return;
-
- g_hash_table_remove (uid_comp_hash, uid);
- g_object_unref (G_OBJECT (comp));
-}
-
-/* Adds a component to the list; called from g_hash_table_foreach() */
-static void
-add_component (gpointer key, gpointer value, gpointer data)
-{
- CalComponent *comp;
- GList **list;
-
- comp = CAL_COMPONENT (value);
- list = data;
-
- *list = g_list_prepend (*list, comp);
-}
-
-/* Gets a list of components that recur within the specified range of time. It
- * ensures that the resulting list of CalComponent objects contains only objects
- * that are actually in the server at the time the initial
- * cal_client_get_objects_in_range() query ends.
- */
-static GList *
-get_objects_atomically (CalClient *client, CalObjType type, time_t start, time_t end)
-{
- GList *uids;
- GHashTable *uid_comp_hash;
- GList *objects;
- guint obj_updated_id;
- guint obj_removed_id;
- GList *l;
-
- uids = cal_client_get_objects_in_range (client, type, start, end);
-
- uid_comp_hash = g_hash_table_new (g_str_hash, g_str_equal);
-
- /* While we are getting the actual object data, keep track of changes */
-
- obj_updated_id = g_signal_connect (G_OBJECT (client), "obj_updated",
- G_CALLBACK (generate_instances_obj_updated_cb),
- uid_comp_hash);
-
- obj_removed_id = g_signal_connect (G_OBJECT (client), "obj_removed",
- G_CALLBACK (generate_instances_obj_removed_cb),
- uid_comp_hash);
-
- /* Get the objects */
-
- for (l = uids; l; l = l->next) {
- CalComponent *comp;
- icalcomponent *icalcomp;
- CalClientGetStatus status;
- char *uid;
- const char *comp_uid;
-
- uid = l->data;
-
- status = cal_client_get_object (client, uid, &icalcomp);
-
- switch (status) {
- case CAL_CLIENT_GET_SUCCESS:
- comp = cal_component_new ();
- if (cal_component_set_icalcomponent (comp, icalcomp)) {
- /* The hash key comes from the component's internal data
- * instead of the duped UID from the list of UIDS.
- */
- cal_component_get_uid (comp, &comp_uid);
- g_hash_table_insert (uid_comp_hash, (char *) comp_uid, comp);
- } else {
- g_object_unref (comp);
- icalcomponent_free (icalcomp);
- }
- break;
-
- case CAL_CLIENT_GET_NOT_FOUND:
- /* Object disappeared from the server, so don't log it */
- break;
-
- case CAL_CLIENT_GET_SYNTAX_ERROR:
- g_message ("get_objects_atomically(): Syntax error when getting "
- "object `%s'; ignoring...", uid);
- break;
-
- default:
- g_assert_not_reached ();
- }
- }
-
- cal_obj_uid_list_free (uids);
-
- /* Now our state is consistent with the server, so disconnect from the
- * notification signals and generate the final list of components.
- */
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
- g_signal_handler_disconnect (client, obj_updated_id);
- g_signal_handler_disconnect (client, obj_removed_id);
-
- objects = NULL;
- g_hash_table_foreach (uid_comp_hash, add_component, &objects);
- g_hash_table_destroy (uid_comp_hash);
-
- return objects;
+ E_CALENDAR_CHECK_STATUS (status, error);
}
struct comp_instance {
@@ -2127,10 +2572,8 @@ compare_comp_instance (gconstpointer a, gconstpointer b)
* @cb: Callback for each generated instance.
* @cb_data: Closure data for the callback.
*
- * Does a combination of cal_client_get_objects_in_range() and
- * cal_recur_generate_instances(). It fetches the list of objects in an atomic
- * way so that the generated instances are actually in the server at the time
- * the initial cal_client_get_objects_in_range() query ends.
+ * Does a combination of cal_client_get_object_list () and
+ * cal_recur_generate_instances().
*
* The callback function should do a g_object_ref() of the calendar component
* it gets passed if it intends to keep it around.
@@ -2144,7 +2587,8 @@ cal_client_generate_instances (CalClient *client, CalObjType type,
GList *objects;
GList *instances;
GList *l;
-
+ char *query;
+
g_return_if_fail (client != NULL);
g_return_if_fail (IS_CAL_CLIENT (client));
@@ -2156,8 +2600,13 @@ cal_client_generate_instances (CalClient *client, CalObjType type,
g_return_if_fail (cb != NULL);
/* Generate objects */
+ query = g_strdup_printf ("(occur-in-time-range? (%lu) (%lu))", start, end);
+ if (!cal_client_get_object_list (client, query, &objects, NULL)) {
+ g_free (query);
+ return;
+ }
+ g_free (query);
- objects = get_objects_atomically (client, type, start, end);
instances = NULL;
for (l = objects; l; l = l->next) {
@@ -2201,64 +2650,22 @@ cal_client_generate_instances (CalClient *client, CalObjType type,
g_list_free (instances);
}
-/* Builds a list of CalAlarmInstance structures */
-static GSList *
-build_alarm_instance_list (CalComponent *comp, GNOME_Evolution_Calendar_CalAlarmInstanceSeq *seq)
-{
- GSList *alarms;
- int i;
-
- alarms = NULL;
-
- for (i = 0; i < seq->_length; i++) {
- GNOME_Evolution_Calendar_CalAlarmInstance *corba_instance;
- CalComponentAlarm *alarm;
- const char *auid;
- CalAlarmInstance *instance;
-
- corba_instance = seq->_buffer + i;
-
- /* Since we want the in-commponent auid, we look for the alarm
- * in the component and fetch its "real" auid.
- */
-
- alarm = cal_component_get_alarm (comp, corba_instance->auid);
- if (!alarm)
- continue;
-
- auid = cal_component_alarm_get_uid (alarm);
- cal_component_alarm_free (alarm);
-
- instance = g_new (CalAlarmInstance, 1);
- instance->auid = auid;
- instance->trigger = corba_instance->trigger;
- instance->occur_start = corba_instance->occur_start;
- instance->occur_end = corba_instance->occur_end;
-
- alarms = g_slist_prepend (alarms, instance);
- }
-
- return g_slist_reverse (alarms);
-}
-
/* Builds a list of CalComponentAlarms structures */
static GSList *
-build_component_alarms_list (GNOME_Evolution_Calendar_CalComponentAlarmsSeq *seq)
+build_component_alarms_list (CalClient *client, GList *object_list, time_t start, time_t end)
{
GSList *comp_alarms;
- int i;
+ GList *l;
comp_alarms = NULL;
- for (i = 0; i < seq->_length; i++) {
- GNOME_Evolution_Calendar_CalComponentAlarms *corba_alarms;
+ for (l = object_list; l != NULL; l = l->next) {
CalComponent *comp;
CalComponentAlarms *alarms;
icalcomponent *icalcomp;
+ CalAlarmAction omit[] = {-1};
- corba_alarms = seq->_buffer + i;
-
- icalcomp = icalparser_parse_string (corba_alarms->calobj);
+ icalcomp = icalparser_parse_string (l->data);
if (!icalcomp)
continue;
@@ -2269,11 +2676,10 @@ build_component_alarms_list (GNOME_Evolution_Calendar_CalComponentAlarmsSeq *seq
continue;
}
- alarms = g_new (CalComponentAlarms, 1);
- alarms->comp = comp;
- alarms->alarms = build_alarm_instance_list (comp, &corba_alarms->alarms);
-
- comp_alarms = g_slist_prepend (comp_alarms, alarms);
+ alarms = cal_util_generate_alarms_for_comp (comp, start, end, omit, cal_client_resolve_tzid_cb,
+ icalcomp, client->priv->default_zone);
+ if (alarms)
+ comp_alarms = g_slist_prepend (comp_alarms, alarms);
}
return comp_alarms;
@@ -2297,9 +2703,9 @@ GSList *
cal_client_get_alarms_in_range (CalClient *client, time_t start, time_t end)
{
CalClientPrivate *priv;
- CORBA_Environment ev;
- GNOME_Evolution_Calendar_CalComponentAlarmsSeq *seq;
GSList *alarms;
+ char *sexp;
+ GList *object_list = NULL;
g_return_val_if_fail (client != NULL, NULL);
g_return_val_if_fail (IS_CAL_CLIENT (client), NULL);
@@ -2310,18 +2716,20 @@ cal_client_get_alarms_in_range (CalClient *client, time_t start, time_t end)
g_return_val_if_fail (start != -1 && end != -1, NULL);
g_return_val_if_fail (start <= end, NULL);
- CORBA_exception_init (&ev);
+ /* build the query string */
+ sexp = g_strdup ("(and (has-alarms? #t))");
- seq = GNOME_Evolution_Calendar_Cal_getAlarmsInRange (priv->cal, start, end, &ev);
- if (BONOBO_EX (&ev)) {
- g_message ("cal_client_get_alarms_in_range(): could not get the alarm range");
- CORBA_exception_free (&ev);
+ /* execute the query on the server */
+ if (!cal_client_get_object_list (client, sexp, &object_list, NULL)) {
+ g_free (sexp);
return NULL;
}
- CORBA_exception_free (&ev);
- alarms = build_component_alarms_list (seq);
- CORBA_free (seq);
+ alarms = build_component_alarms_list (client, object_list, start, end);
+
+ g_list_foreach (object_list, (GFunc) g_free, NULL);
+ g_list_free (object_list);
+ g_free (sexp);
return alarms;
}
@@ -2371,11 +2779,9 @@ cal_client_get_alarms_for_object (CalClient *client, const char *uid,
CalComponentAlarms **alarms)
{
CalClientPrivate *priv;
- CORBA_Environment ev;
- GNOME_Evolution_Calendar_CalComponentAlarms *corba_alarms;
- gboolean retval;
icalcomponent *icalcomp;
CalComponent *comp;
+ CalAlarmAction omit[] = {-1};
g_return_val_if_fail (client != NULL, FALSE);
g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
@@ -2389,40 +2795,23 @@ cal_client_get_alarms_for_object (CalClient *client, const char *uid,
g_return_val_if_fail (alarms != NULL, FALSE);
*alarms = NULL;
- retval = FALSE;
-
- CORBA_exception_init (&ev);
-
- corba_alarms = GNOME_Evolution_Calendar_Cal_getAlarmsForObject (priv->cal, (char *) uid,
- start, end, &ev);
- if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_NotFound))
- goto out;
- else if (BONOBO_EX (&ev)) {
- g_message ("cal_client_get_alarms_for_object(): could not get the alarm range");
- goto out;
- }
- icalcomp = icalparser_parse_string (corba_alarms->calobj);
+ if (!cal_client_get_object (client, uid, NULL, &icalcomp, NULL))
+ return FALSE;
if (!icalcomp)
- goto out;
+ return FALSE;
comp = cal_component_new ();
if (!cal_component_set_icalcomponent (comp, icalcomp)) {
icalcomponent_free (icalcomp);
g_object_unref (G_OBJECT (comp));
- goto out;
+ return FALSE;
}
- retval = TRUE;
-
- *alarms = g_new (CalComponentAlarms, 1);
- (*alarms)->comp = comp;
- (*alarms)->alarms = build_alarm_instance_list (comp, &corba_alarms->alarms);
- CORBA_free (corba_alarms);
+ *alarms = cal_util_generate_alarms_for_comp (comp, start, end, omit, cal_client_resolve_tzid_cb,
+ icalcomp, priv->default_zone);
- out:
- CORBA_exception_free (&ev);
- return retval;
+ return TRUE;
}
/**
@@ -2439,33 +2828,68 @@ cal_client_get_alarms_for_object (CalClient *client, const char *uid,
* Return value: a #CalClientResult value indicating the result of the
* operation.
*/
-CalClientResult
-cal_client_discard_alarm (CalClient *client, CalComponent *comp, const char *auid)
+gboolean
+cal_client_discard_alarm (CalClient *client, CalComponent *comp, const char *auid, GError **error)
{
CalClientPrivate *priv;
- CalClientResult retval;
CORBA_Environment ev;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
const char *uid;
-
- g_return_val_if_fail (IS_CAL_CLIENT (client), CAL_CLIENT_RESULT_NOT_FOUND);
- g_return_val_if_fail (IS_CAL_COMPONENT (comp), CAL_CLIENT_RESULT_NOT_FOUND);
- g_return_val_if_fail (auid != NULL, CAL_CLIENT_RESULT_NOT_FOUND);
+
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
priv = client->priv;
+ e_mutex_lock (client->priv->mutex);
+
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
+
cal_component_get_uid (comp, &uid);
CORBA_exception_init (&ev);
+
GNOME_Evolution_Calendar_Cal_discardAlarm (priv->cal, uid, auid, &ev);
- if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_NotFound))
- retval = CAL_CLIENT_RESULT_NOT_FOUND;
- else if (BONOBO_EX (&ev))
- retval = CAL_CLIENT_RESULT_CORBA_ERROR;
- else
- retval = CAL_CLIENT_RESULT_SUCCESS;
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
+ }
CORBA_exception_free (&ev);
- return retval;
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
}
typedef struct _ForeachTZIDCallbackData ForeachTZIDCallbackData;
@@ -2500,10 +2924,7 @@ foreach_tzid_callback (icalparameter *param, void *cbdata)
return;
if (data->include_all_timezones) {
- CalClientGetStatus status;
-
- status = cal_client_get_timezone (data->client, tzid, &zone);
- if (status != CAL_CLIENT_GET_SUCCESS) {
+ if (!cal_client_get_timezone (data->client, tzid, &zone, NULL)) {
data->success = FALSE;
return;
}
@@ -2642,163 +3063,192 @@ cal_client_get_component_as_string (CalClient *client, icalcomponent *icalcomp)
return cal_client_get_component_as_string_internal (client, icalcomp, TRUE);
}
-CalClientResult
-cal_client_update_object_with_mod (CalClient *client, CalComponent *comp, CalObjModType mod)
+gboolean
+cal_client_create_object (CalClient *client, icalcomponent *icalcomp, char **uid, GError **error)
{
CalClientPrivate *priv;
CORBA_Environment ev;
- CalClientResult retval;
- char *obj_string;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
- g_return_val_if_fail (client != NULL, CAL_CLIENT_RESULT_INVALID_OBJECT);
- g_return_val_if_fail (IS_CAL_CLIENT (client), CAL_CLIENT_RESULT_INVALID_OBJECT);
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, CAL_CLIENT_RESULT_INVALID_OBJECT);
- g_return_val_if_fail (comp != NULL, CAL_CLIENT_RESULT_INVALID_OBJECT);
+ e_mutex_lock (client->priv->mutex);
- cal_component_commit_sequence (comp);
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
- obj_string = cal_client_get_component_as_string_internal (client,
- cal_component_get_icalcomponent (comp),
- FALSE);
- if (obj_string == NULL)
- return CAL_CLIENT_RESULT_INVALID_OBJECT;
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
CORBA_exception_init (&ev);
- GNOME_Evolution_Calendar_Cal_updateObjects (priv->cal, obj_string, mod, &ev);
- g_free (obj_string);
-
- if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_InvalidObject))
- retval = CAL_CLIENT_RESULT_INVALID_OBJECT;
- else if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_NotFound))
- retval = CAL_CLIENT_RESULT_NOT_FOUND;
- else if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_PermissionDenied))
- retval = CAL_CLIENT_RESULT_PERMISSION_DENIED;
- else if (BONOBO_EX (&ev)) {
- g_message ("cal_client_update_object(): could not update the object");
- retval = CAL_CLIENT_RESULT_CORBA_ERROR;
+
+ GNOME_Evolution_Calendar_Cal_createObject (priv->cal, icalcomponent_as_ical_string (icalcomp), &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
}
- else
- retval = CAL_CLIENT_RESULT_SUCCESS;
CORBA_exception_free (&ev);
- return retval;
-}
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
-/**
- * cal_client_update_object:
- * @client: A calendar client.
- * @comp: A calendar component object.
- *
- * Asks a calendar to update a component. Any existing component with the
- * specified component's UID will be replaced. The client program should not
- * assume that the object is actually in the server's storage until it has
- * received the "obj_updated" notification signal.
- *
- * Return value: a #CalClientResult value indicating the result of the
- * operation.
- **/
-CalClientResult
-cal_client_update_object (CalClient *client, CalComponent *comp)
-{
+ status = our_op->status;
+ if (uid)
+ *uid = our_op->uid;
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
- return cal_client_update_object_with_mod (client, comp, CALOBJ_MOD_ALL);
+ E_CALENDAR_CHECK_STATUS (status, error);
}
-/**
- * cal_client_update_objects:
- * @client: A calendar client.
- * @icalcomp: A toplevel VCALENDAR libical component.
- *
- * Asks a calendar to add or update one or more components, possibly including
- * VTIMEZONE data. Any existing components with the same UIDs will be
- * replaced. The VTIMEZONE data will be compared to existing VTIMEZONEs in
- * the calendar, and the VTIMEZONEs may possibly be renamed, as well as all
- * references to them throughout the VCALENDAR.
- *
- * The client program should not assume that the objects are actually in the
- * server's storage until it has received the "obj_updated" notification
- * signal.
- *
- * Return value: a #CalClientResult value indicating the result of the
- * operation.
- **/
-CalClientResult
-cal_client_update_objects (CalClient *client, icalcomponent *icalcomp)
+gboolean
+cal_client_modify_object (CalClient *client, icalcomponent *icalcomp, CalObjModType mod, GError **error)
{
CalClientPrivate *priv;
CORBA_Environment ev;
- CalClientResult retval;
- char *obj_string;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
- g_return_val_if_fail (client != NULL, CAL_CLIENT_RESULT_INVALID_OBJECT);
- g_return_val_if_fail (IS_CAL_CLIENT (client), CAL_CLIENT_RESULT_INVALID_OBJECT);
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
+ g_return_val_if_fail (icalcomp != NULL, FALSE);
priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED,
- CAL_CLIENT_RESULT_INVALID_OBJECT);
- g_return_val_if_fail (icalcomp != NULL, CAL_CLIENT_RESULT_INVALID_OBJECT);
+ e_mutex_lock (client->priv->mutex);
- /* Libical owns this memory, using one of its temporary buffers. */
- obj_string = icalcomponent_as_ical_string (icalcomp);
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
CORBA_exception_init (&ev);
- GNOME_Evolution_Calendar_Cal_updateObjects (priv->cal, obj_string, GNOME_Evolution_Calendar_MOD_ALL, &ev);
-
- if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_InvalidObject))
- retval = CAL_CLIENT_RESULT_INVALID_OBJECT;
- else if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_NotFound))
- retval = CAL_CLIENT_RESULT_NOT_FOUND;
- else if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_PermissionDenied))
- retval = CAL_CLIENT_RESULT_PERMISSION_DENIED;
- else if (BONOBO_EX (&ev)) {
- g_message ("cal_client_update_objects(): could not update the objects");
- retval = CAL_CLIENT_RESULT_CORBA_ERROR;
+
+ GNOME_Evolution_Calendar_Cal_modifyObject (priv->cal, icalcomponent_as_ical_string (icalcomp), mod, &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
}
- else
- retval = CAL_CLIENT_RESULT_SUCCESS;
CORBA_exception_free (&ev);
- return retval;
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
}
-CalClientResult
-cal_client_remove_object_with_mod (CalClient *client, const char *uid, CalObjModType mod)
+gboolean
+cal_client_remove_object_with_mod (CalClient *client, const char *uid,
+ const char *rid, CalObjModType mod, GError **error)
{
CalClientPrivate *priv;
CORBA_Environment ev;
- CalClientResult retval;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
- g_return_val_if_fail (client != NULL, CAL_CLIENT_RESULT_INVALID_OBJECT);
- g_return_val_if_fail (IS_CAL_CLIENT (client), CAL_CLIENT_RESULT_INVALID_OBJECT);
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, CAL_CLIENT_RESULT_INVALID_OBJECT);
- g_return_val_if_fail (uid != NULL, CAL_CLIENT_RESULT_NOT_FOUND);
+ e_mutex_lock (client->priv->mutex);
+
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
+
CORBA_exception_init (&ev);
- GNOME_Evolution_Calendar_Cal_removeObject (priv->cal, (char *) uid, mod, &ev);
-
- if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_InvalidObject))
- retval = CAL_CLIENT_RESULT_INVALID_OBJECT;
- else if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_NotFound))
- retval = CAL_CLIENT_RESULT_NOT_FOUND;
- else if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_PermissionDenied))
- retval = CAL_CLIENT_RESULT_PERMISSION_DENIED;
- else if (BONOBO_EX (&ev)) {
- g_message ("cal_client_remove_object(): could not remove the object");
- retval = CAL_CLIENT_RESULT_CORBA_ERROR;
+
+ GNOME_Evolution_Calendar_Cal_removeObject (priv->cal, uid, rid ? rid : "", mod, &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
}
- else
- retval = CAL_CLIENT_RESULT_SUCCESS;
CORBA_exception_free (&ev);
- return retval;
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
}
/**
@@ -2813,69 +3263,319 @@ cal_client_remove_object_with_mod (CalClient *client, const char *uid, CalObjMod
* Return value: a #CalClientResult value indicating the result of the
* operation.
**/
-CalClientResult
-cal_client_remove_object (CalClient *client, const char *uid)
+gboolean
+cal_client_remove_object (CalClient *client, const char *uid, GError **error)
{
- return cal_client_remove_object_with_mod (client, uid, CALOBJ_MOD_ALL);
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
+
+ return cal_client_remove_object_with_mod (client, uid, NULL, CALOBJ_MOD_ALL, error);
}
-CalClientResult
-cal_client_send_object (CalClient *client, icalcomponent *icalcomp,
- icalcomponent **new_icalcomp, GList **users,
- char **error_msg)
+gboolean
+cal_client_receive_objects (CalClient *client, icalcomponent *icalcomp, GError **error)
{
CalClientPrivate *priv;
CORBA_Environment ev;
- CalClientResult retval;
- GNOME_Evolution_Calendar_UserList *user_list;
- char *obj_string;
- int i;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
+
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
+
+ priv = client->priv;
+
+ e_mutex_lock (client->priv->mutex);
+
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
+
+ CORBA_exception_init (&ev);
+
+ GNOME_Evolution_Calendar_Cal_receiveObjects (priv->cal, icalcomponent_as_ical_string (icalcomp), &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
+ }
+
+ CORBA_exception_free (&ev);
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
- g_return_val_if_fail (client != NULL, CAL_CLIENT_RESULT_INVALID_OBJECT);
- g_return_val_if_fail (IS_CAL_CLIENT (client), CAL_CLIENT_RESULT_INVALID_OBJECT);
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
+}
+
+gboolean
+cal_client_send_objects (CalClient *client, icalcomponent *icalcomp, GError **error)
+{
+ CalClientPrivate *priv;
+ CORBA_Environment ev;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
+
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED,
- CAL_CLIENT_RESULT_INVALID_OBJECT);
- g_return_val_if_fail (icalcomp != NULL, CAL_CLIENT_RESULT_INVALID_OBJECT);
+ e_mutex_lock (client->priv->mutex);
- /* Libical owns this memory, using one of its temporary buffers. */
- obj_string = icalcomponent_as_ical_string (icalcomp);
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
CORBA_exception_init (&ev);
- obj_string = GNOME_Evolution_Calendar_Cal_sendObject (priv->cal, obj_string, &user_list, &ev);
-
- if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_InvalidObject)) {
- retval = CAL_CLIENT_SEND_INVALID_OBJECT;
- } else if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_Busy)) {
- retval = CAL_CLIENT_SEND_BUSY;
- if (error_msg)
- *error_msg = g_strdup (((GNOME_Evolution_Calendar_Cal_Busy *)(CORBA_exception_value (&ev)))->errorMsg);
- } else if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_PermissionDenied)) {
- retval = CAL_CLIENT_SEND_PERMISSION_DENIED;
- } else if (BONOBO_EX (&ev)) {
- g_message ("cal_client_update_objects(): could not send the objects");
- retval = CAL_CLIENT_SEND_CORBA_ERROR;
+
+ GNOME_Evolution_Calendar_Cal_sendObjects (priv->cal, icalcomponent_as_ical_string (icalcomp), &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
+ }
+
+ CORBA_exception_free (&ev);
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
+}
+
+gboolean
+cal_client_get_timezone (CalClient *client, const char *tzid, icaltimezone **zone, GError **error)
+{
+ CalClientPrivate *priv;
+ CORBA_Environment ev;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
+ icalcomponent *icalcomp;
+
+ g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
+ g_return_val_if_fail (tzid != NULL, FALSE);
+
+ priv = client->priv;
+
+ e_mutex_lock (priv->mutex);
+
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (priv->mutex);
+
+ /* Check for well known zones and in the cache */
+ *zone = NULL;
+
+ /* If tzid is NULL or "" we return NULL, since it is a 'local time'. */
+ if (!tzid || !tzid[0]) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
+ }
+
+ /* If it is UTC, we return the special UTC timezone. */
+ if (!strcmp (tzid, "UTC")) {
+ *zone = icaltimezone_get_utc_timezone ();
} else {
- retval = CAL_CLIENT_RESULT_SUCCESS;
-
- *new_icalcomp = icalparser_parse_string (obj_string);
- CORBA_free (obj_string);
-
- if (*new_icalcomp == NULL) {
- retval = CAL_CLIENT_RESULT_INVALID_OBJECT;
- } else {
- *users = NULL;
- for (i = 0; i < user_list->_length; i++)
- *users = g_list_append (*users, g_strdup (user_list->_buffer[i]));
- CORBA_free (user_list);
- }
+ /* See if we already have it in the cache. */
+ *zone = g_hash_table_lookup (priv->timezones, tzid);
+ }
+
+ if (*zone) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
}
+ /* call the backend */
+ CORBA_exception_init (&ev);
+
+ GNOME_Evolution_Calendar_Cal_getTimezone (priv->cal, tzid, &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
+ }
+
CORBA_exception_free (&ev);
- return retval;
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+
+ icalcomp = icalparser_parse_string (our_op->string);
+ g_free (our_op->string);
+
+ /* FIXME Invalid object status? */
+ if (!icalcomp)
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OBJECT_NOT_FOUND, error);
+
+ *zone = icaltimezone_new ();
+ if (!icaltimezone_set_component (*zone, icalcomp)) {
+ icaltimezone_free (*zone, 1);
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OBJECT_NOT_FOUND, error);
+ }
+
+ /* Now add it to the cache, to avoid the server call in future. */
+ g_hash_table_insert (priv->timezones, icaltimezone_get_tzid (*zone), *zone);
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
+}
+
+/**
+ * cal_client_add_timezone
+ * @client: A calendar client.
+ * @izone: The timezone to add.
+ * @error: Placeholder for error information.
+ *
+ * Add a VTIMEZONE object to the given calendar.
+ *
+ * Returns: TRUE if successful, FALSE otherwise.
+ */
+gboolean
+cal_client_add_timezone (CalClient *client, icaltimezone *izone, GError **error)
+{
+ CalClientPrivate *priv;
+ CORBA_Environment ev;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
+ const char *tzobj;
+
+ g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
+ g_return_val_if_fail (izone != NULL, FALSE);
+
+ priv = client->priv;
+
+ e_mutex_lock (priv->mutex);
+
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (priv->mutex);
+
+ /* convert icaltimezone into a string */
+ tzobj = icalcomponent_as_ical_string (icaltimezone_get_component (izone));
+
+ /* call the backend */
+ CORBA_exception_init (&ev);
+
+ GNOME_Evolution_Calendar_Cal_addTimezone (priv->cal, tzobj, &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
+ }
+
+ CORBA_exception_free (&ev);
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
}
/**
@@ -2888,20 +3588,68 @@ cal_client_send_object (CalClient *client, icalcomponent *icalcomp,
* Return value: A query object that will emit notification signals as calendar
* components are added and removed from the query in the server.
**/
-CalQuery *
-cal_client_get_query (CalClient *client, const char *sexp)
+gboolean
+cal_client_get_query (CalClient *client, const char *sexp, CalQuery **query, GError **error)
{
- CalClientPrivate *priv;
+ CORBA_Environment ev;
+ ECalendarOp *our_op;
+ ECalendarStatus status;
- g_return_val_if_fail (client != NULL, NULL);
- g_return_val_if_fail (IS_CAL_CLIENT (client), NULL);
+ g_return_val_if_fail (client != NULL, E_CALENDAR_STATUS_INVALID_ARG);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), E_CALENDAR_STATUS_INVALID_ARG);
+ g_return_val_if_fail (query != NULL, E_CALENDAR_STATUS_INVALID_ARG);
- priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, FALSE);
+ e_mutex_lock (client->priv->mutex);
+
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
- g_return_val_if_fail (sexp != NULL, NULL);
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
+
+ CORBA_exception_init (&ev);
+
+ our_op->listener = query_listener_new ();
+ GNOME_Evolution_Calendar_Cal_getQuery (client->priv->cal, sexp, BONOBO_OBJREF (our_op->listener), &ev);
- return cal_query_new (client, priv->cal, sexp);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
+ }
+
+ CORBA_exception_free (&ev);
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+ *query = our_op->query;
+
+ bonobo_object_unref (BONOBO_OBJECT (our_op->listener));
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
}
@@ -2910,19 +3658,16 @@ cal_client_get_query (CalClient *client, const char *sexp)
DATE-TIME values into specific times. (Most of our IDL interface uses
time_t values to pass specific times from the server to the client.) */
static gboolean
-cal_client_ensure_timezone_on_server (CalClient *client, icaltimezone *zone)
+cal_client_ensure_timezone_on_server (CalClient *client, icaltimezone *zone, GError **error)
{
CalClientPrivate *priv;
- char *tzid, *obj_string;
+ char *tzid;
icaltimezone *tmp_zone;
- GString *vcal_string;
- gboolean retval = FALSE;
- icalcomponent *vtimezone_comp;
- char *vtimezone_as_string;
- CORBA_Environment ev;
priv = client->priv;
+ /* FIXME This is highly broken since there is no locking */
+
/* If the zone is NULL or UTC we don't need to do anything. */
if (!zone)
return TRUE;
@@ -2940,89 +3685,128 @@ cal_client_ensure_timezone_on_server (CalClient *client, icaltimezone *zone)
/* Now we have to send it to the server, in case it doesn't already
have it. */
-
- vcal_string = g_string_new (NULL);
- g_string_append (vcal_string,
- "BEGIN:VCALENDAR\n"
- "PRODID:-//Ximian//NONSGML Evolution Calendar//EN\n"
- "VERSION:2.0\n");
-
- /* Convert the timezone to a string and add it. */
- vtimezone_comp = icaltimezone_get_component (zone);
- if (!vtimezone_comp) {
- g_string_free (vcal_string, TRUE);
- return FALSE;
- }
-
- /* We don't need to free this string as libical owns it. */
- vtimezone_as_string = icalcomponent_as_ical_string (vtimezone_comp);
- g_string_append (vcal_string, vtimezone_as_string);
-
- g_string_append (vcal_string, "END:VCALENDAR\n");
-
- obj_string = vcal_string->str;
- g_string_free (vcal_string, FALSE);
-
- CORBA_exception_init (&ev);
- GNOME_Evolution_Calendar_Cal_updateObjects (priv->cal, obj_string, GNOME_Evolution_Calendar_MOD_ALL, &ev);
- g_free (obj_string);
-
- if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_InvalidObject))
- goto out;
- else if (BONOBO_EX (&ev)) {
- g_message ("cal_client_ensure_timezone_on_server(): could not add the timezone to the server");
- goto out;
- }
-
- retval = TRUE;
-
- out:
- CORBA_exception_free (&ev);
- return retval;
+ return cal_client_add_timezone (client, zone, error);
}
-
gboolean
-cal_client_set_default_timezone (CalClient *client, icaltimezone *zone)
+cal_client_set_default_timezone (CalClient *client, icaltimezone *zone, GError **error)
{
CalClientPrivate *priv;
- gboolean retval = FALSE;
CORBA_Environment ev;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
const char *tzid;
-
- g_return_val_if_fail (client != NULL, FALSE);
+
g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
g_return_val_if_fail (zone != NULL, FALSE);
priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED,
- FALSE);
-
/* Make sure the server has the VTIMEZONE data. */
- if (!cal_client_ensure_timezone_on_server (client, zone))
+ if (!cal_client_ensure_timezone_on_server (client, zone, error))
return FALSE;
- /* Now set the default timezone on the server. */
- CORBA_exception_init (&ev);
- tzid = icaltimezone_get_tzid (zone);
- GNOME_Evolution_Calendar_Cal_setDefaultTimezone (priv->cal,
- (char *) tzid, &ev);
+ e_mutex_lock (priv->mutex);
- if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_NotFound))
- goto out;
- else if (BONOBO_EX (&ev)) {
- g_message ("cal_client_set_default_timezone(): could not set the default timezone");
- goto out;
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
}
- retval = TRUE;
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (priv->mutex);
- priv->default_zone = zone;
+ /* FIXME Adding it to the server to change the tzid */
+ tzid = icaltimezone_get_tzid (zone);
+
+ /* call the backend */
+ CORBA_exception_init (&ev);
- out:
+ GNOME_Evolution_Calendar_Cal_setDefaultTimezone (priv->cal, tzid, &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
+ }
CORBA_exception_free (&ev);
- return retval;
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
}
+/**
+ * cal_client_get_error_message
+ * @status: A status code.
+ *
+ * Get an error message for the given status code.
+ *
+ * Returns: the error message.
+ */
+const char *
+cal_client_get_error_message (ECalendarStatus status)
+{
+ switch (status) {
+ case E_CALENDAR_STATUS_INVALID_ARG :
+ return _("Invalid argument");
+ case E_CALENDAR_STATUS_BUSY :
+ return _("Backend is busy");
+ case E_CALENDAR_STATUS_REPOSITORY_OFFLINE :
+ return _("Repository is offline");
+ case E_CALENDAR_STATUS_NO_SUCH_CALENDAR :
+ return _("No such calendar");
+ case E_CALENDAR_STATUS_OBJECT_NOT_FOUND :
+ return _("Object not found");
+ case E_CALENDAR_STATUS_INVALID_OBJECT :
+ return _("Invalid object");
+ case E_CALENDAR_STATUS_URI_NOT_LOADED :
+ return _("URI not loaded");
+ case E_CALENDAR_STATUS_URI_ALREADY_LOADED :
+ return _("URI already loaded");
+ case E_CALENDAR_STATUS_PERMISSION_DENIED :
+ return _("Permission denied");
+ case E_CALENDAR_STATUS_CARD_NOT_FOUND :
+ return _("Object not found");
+ case E_CALENDAR_STATUS_CARD_ID_ALREADY_EXISTS :
+ return _("Object ID already exists");
+ case E_CALENDAR_STATUS_PROTOCOL_NOT_SUPPORTED :
+ return _("Protocol not supported");
+ case E_CALENDAR_STATUS_CANCELLED :
+ return _("Operation has been cancelled");
+ case E_CALENDAR_STATUS_COULD_NOT_CANCEL :
+ return _("Could not cancel operation");
+ case E_CALENDAR_STATUS_AUTHENTICATION_FAILED :
+ return _("Authentication failed");
+ case E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED :
+ return _("Authentication required");
+ case E_CALENDAR_STATUS_CORBA_EXCEPTION :
+ return _("A CORBA esception has occurred");
+ case E_CALENDAR_STATUS_OTHER_ERROR :
+ return _("Unknown error");
+ }
+
+ return NULL;
+}
diff --git a/calendar/cal-client/cal-client.h b/calendar/cal-client/cal-client.h
index 961ba5d993..277522f097 100644
--- a/calendar/cal-client/cal-client.h
+++ b/calendar/cal-client/cal-client.h
@@ -25,6 +25,7 @@
#include <cal-util/cal-recur.h>
#include <cal-util/cal-util.h>
#include <cal-client/cal-query.h>
+#include "cal-client-types.h"
G_BEGIN_DECLS
@@ -37,6 +38,7 @@ G_BEGIN_DECLS
#define IS_CAL_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CAL_CLIENT_TYPE))
#define CAL_CLIENT_OPEN_STATUS_ENUM_TYPE (cal_client_open_status_enum_get_type ())
+#define CAL_CLIENT_REMOVE_STATUS_ENUM_TYPE (cal_client_remove_status_enum_get_type ())
#define CAL_CLIENT_SET_MODE_STATUS_ENUM_TYPE (cal_client_set_mode_status_enum_get_type ())
#define CAL_MODE_ENUM_TYPE (cal_mode_enum_get_type ())
@@ -76,14 +78,6 @@ typedef enum {
CAL_CLIENT_RESULT_PERMISSION_DENIED
} CalClientResult;
-typedef enum {
- CAL_CLIENT_SEND_SUCCESS,
- CAL_CLIENT_SEND_CORBA_ERROR,
- CAL_CLIENT_SEND_INVALID_OBJECT,
- CAL_CLIENT_SEND_BUSY,
- CAL_CLIENT_SEND_PERMISSION_DENIED
-} CalClientSendResult;
-
/* Whether the client is not loaded, is being loaded, or is already loaded */
typedef enum {
CAL_CLIENT_LOAD_NOT_LOADED,
@@ -104,10 +98,7 @@ struct _CalClientClass {
/* Notification signals */
void (* cal_opened) (CalClient *client, CalClientOpenStatus status);
- void (* cal_set_mode) (CalClient *client, CalClientSetModeStatus status, CalMode mode);
-
- void (* obj_updated) (CalClient *client, const char *uid);
- void (* obj_removed) (CalClient *client, const char *uid);
+ void (* cal_set_mode) (CalClient *client, CalClientSetModeStatus status, CalMode mode);
void (* backend_error) (CalClient *client, const char *message);
@@ -129,21 +120,13 @@ GType cal_client_open_status_enum_get_type (void);
GType cal_client_set_mode_status_enum_get_type (void);
GType cal_mode_enum_get_type (void);
-CalClient *cal_client_construct (CalClient *client);
-
-CalClient *cal_client_new (void);
+CalClient *cal_client_new (const char *uri, CalObjType type);
void cal_client_set_auth_func (CalClient *client, CalClientAuthFunc func, gpointer data);
-/* Sets the default timezone to use to resolve DATE and floating DATE-TIME
- values. This will typically be from the user's timezone setting. Call this
- before using any other functions. It will pass the default timezone on to
- the server. Returns TRUE on success. */
-gboolean cal_client_set_default_timezone (CalClient *client, icaltimezone *zone);
-
-gboolean cal_client_open_calendar (CalClient *client, const char *str_uri, gboolean only_if_exists);
-gboolean cal_client_open_default_calendar (CalClient *client, gboolean only_if_exists);
-gboolean cal_client_open_default_tasks (CalClient *client, gboolean only_if_exists);
+gboolean cal_client_open (CalClient *client, gboolean only_if_exists, GError **error);
+void cal_client_open_async (CalClient *client, gboolean only_if_exists);
+gboolean cal_client_remove_calendar (CalClient *client, GError **error);
GList *cal_client_uri_list (CalClient *client, CalMode mode);
@@ -151,11 +134,10 @@ CalClientLoadState cal_client_get_load_state (CalClient *client);
const char *cal_client_get_uri (CalClient *client);
-gboolean cal_client_is_read_only (CalClient *client);
-
-const char *cal_client_get_cal_address (CalClient *client);
-const char *cal_client_get_alarm_email_address (CalClient *client);
-const char *cal_client_get_ldap_attribute (CalClient *client);
+gboolean cal_client_is_read_only (CalClient *client, gboolean *read_only, GError **error);
+gboolean cal_client_get_cal_address (CalClient *client, char **cal_address, GError **error);
+gboolean cal_client_get_alarm_email_address (CalClient *client, char **alarm_address, GError **error);
+gboolean cal_client_get_ldap_attribute (CalClient *client, char **ldap_attribute, GError **error);
gboolean cal_client_get_one_alarm_only (CalClient *client);
gboolean cal_client_get_organizer_must_attend (CalClient *client);
@@ -164,28 +146,23 @@ gboolean cal_client_get_static_capability (CalClient *client, const char *cap);
gboolean cal_client_set_mode (CalClient *client, CalMode mode);
-int cal_client_get_n_objects (CalClient *client, CalObjType type);
-
-CalClientGetStatus cal_client_get_default_object (CalClient *client,
- CalObjType type,
- icalcomponent **icalcomp);
+gboolean cal_client_get_default_object (CalClient *client,
+ icalcomponent **icalcomp, GError **error);
-CalClientGetStatus cal_client_get_object (CalClient *client,
- const char *uid,
- icalcomponent **icalcomp);
+gboolean cal_client_get_object (CalClient *client,
+ const char *uid,
+ const char *rid,
+ icalcomponent **icalcomp,
+ GError **error);
-CalClientGetStatus cal_client_get_timezone (CalClient *client,
- const char *tzid,
- icaltimezone **zone);
+gboolean cal_client_get_changes (CalClient *client, CalObjType type, const char *change_id, GList **changes, GError **error);
-GList *cal_client_get_uids (CalClient *client, CalObjType type);
-GList *cal_client_get_changes (CalClient *client, CalObjType type, const char *change_id);
+gboolean cal_client_get_object_list (CalClient *client, const char *query, GList **objects, GError **error);
+gboolean cal_client_get_object_list_as_comp (CalClient *client, const char *query, GList **objects, GError **error);
+void cal_client_free_object_list (GList *objects);
-GList *cal_client_get_objects_in_range (CalClient *client, CalObjType type,
- time_t start, time_t end);
-
-GList *cal_client_get_free_busy (CalClient *client, GList *users,
- time_t start, time_t end);
+gboolean cal_client_get_free_busy (CalClient *client, GList *users, time_t start, time_t end,
+ GList **freebusy, GError **error);
void cal_client_generate_instances (CalClient *client, CalObjType type,
time_t start, time_t end,
@@ -199,24 +176,25 @@ gboolean cal_client_get_alarms_for_object (CalClient *client, const char *uid,
time_t start, time_t end,
CalComponentAlarms **alarms);
-CalClientResult cal_client_discard_alarm (CalClient *client, CalComponent *comp, const char *auid);
-
-/* Add or update a single object. When adding an object only builtin timezones
- are allowed. To use external VTIMEZONE data call update_objects() instead.*/
-CalClientResult cal_client_update_object (CalClient *client, CalComponent *comp);
-CalClientResult cal_client_update_object_with_mod (CalClient *client, CalComponent *comp, CalObjModType mod);
+gboolean cal_client_create_object (CalClient *client, icalcomponent *icalcomp, char **uid, GError **error);
+gboolean cal_client_modify_object (CalClient *client, icalcomponent *icalcomp, CalObjModType mod, GError **error);
+gboolean cal_client_remove_object (CalClient *client, const char *uid, GError **error);
+gboolean cal_client_remove_object_with_mod (CalClient *client, const char *uid, const char *rid, CalObjModType mod, GError **error);
-/* Add or update multiple objects, possibly including VTIMEZONE data. */
-CalClientResult cal_client_update_objects (CalClient *client, icalcomponent *icalcomp);
+gboolean cal_client_discard_alarm (CalClient *client, CalComponent *comp, const char *auid, GError **error);
-CalClientResult cal_client_remove_object (CalClient *client, const char *uid);
-CalClientResult cal_client_remove_object_with_mod (CalClient *client, const char *uid, CalObjModType mod);
+gboolean cal_client_receive_objects (CalClient *client, icalcomponent *icalcomp, GError **error);
+gboolean cal_client_send_objects (CalClient *client, icalcomponent *icalcomp, GError **error);
-CalClientSendResult cal_client_send_object (CalClient *client, icalcomponent *icalcomp,
- icalcomponent **new_icalcomp, GList **users,
- char **error_msg);
+gboolean cal_client_get_timezone (CalClient *client, const char *tzid, icaltimezone **zone, GError **error);
+gboolean cal_client_add_timezone (CalClient *client, icaltimezone *izone, GError **error);
+/* Sets the default timezone to use to resolve DATE and floating DATE-TIME
+ values. This will typically be from the user's timezone setting. Call this
+ before using any other functions. It will pass the default timezone on to
+ the server. Returns TRUE on success. */
+gboolean cal_client_set_default_timezone (CalClient *client, icaltimezone *zone, GError **error);
-CalQuery *cal_client_get_query (CalClient *client, const char *sexp);
+gboolean cal_client_get_query (CalClient *client, const char *sexp, CalQuery **query, GError **error);
/* Resolves TZIDs for the recurrence generator. */
icaltimezone *cal_client_resolve_tzid_cb (const char *tzid, gpointer data);
@@ -225,6 +203,7 @@ icaltimezone *cal_client_resolve_tzid_cb (const char *tzid, gpointer data);
used by the component. It also includes a 'METHOD:PUBLISH' property. */
char* cal_client_get_component_as_string (CalClient *client, icalcomponent *icalcomp);
+const char * cal_client_get_error_message (ECalendarStatus status);
diff --git a/calendar/cal-client/cal-listener.c b/calendar/cal-client/cal-listener.c
index c7beef8c97..ac04be7c07 100644
--- a/calendar/cal-client/cal-listener.c
+++ b/calendar/cal-client/cal-listener.c
@@ -19,6 +19,9 @@
*/
#include <config.h>
+
+#include <bonobo/bonobo-main.h>
+#include "cal-marshal.h"
#include "cal-listener.h"
@@ -26,10 +29,7 @@
/* Private part of the CalListener structure */
struct CalListenerPrivate {
/* Notification functions and their closure data */
- CalListenerCalOpenedFn cal_opened_fn;
CalListenerCalSetModeFn cal_set_mode_fn;
- CalListenerObjUpdatedFn obj_updated_fn;
- CalListenerObjRemovedFn obj_removed_fn;
CalListenerErrorOccurredFn error_occurred_fn;
CalListenerCategoriesChangedFn categories_changed_fn;
gpointer fn_data;
@@ -38,124 +38,178 @@ struct CalListenerPrivate {
gboolean notify : 1;
};
-
+/* Signal IDs */
+enum {
+ READ_ONLY,
+ CAL_ADDRESS,
+ ALARM_ADDRESS,
+ LDAP_ATTRIBUTE,
+ STATIC_CAPABILITIES,
+ OPEN,
+ REMOVE,
+ CREATE_OBJECT,
+ MODIFY_OBJECT,
+ REMOVE_OBJECT,
+ DISCARD_ALARM,
+ RECEIVE_OBJECTS,
+ SEND_OBJECTS,
+ DEFAULT_OBJECT,
+ OBJECT,
+ OBJECT_LIST,
+ GET_TIMEZONE,
+ ADD_TIMEZONE,
+ SET_DEFAULT_TIMEZONE,
+ GET_CHANGES,
+ GET_FREE_BUSY,
+ QUERY,
+ LAST_SIGNAL
+};
-static void cal_listener_class_init (CalListenerClass *klass);
-static void cal_listener_init (CalListener *listener, CalListenerClass *klass);
-static void cal_listener_finalize (GObject *object);
-
-static void impl_notifyCalOpened (PortableServer_Servant servant,
- GNOME_Evolution_Calendar_Listener_OpenStatus status,
- GNOME_Evolution_Calendar_Cal cal,
- CORBA_Environment *ev);
-static void impl_notifyCalSetMode (PortableServer_Servant servant,
- GNOME_Evolution_Calendar_Listener_SetModeStatus status,
- GNOME_Evolution_Calendar_CalMode mode,
- CORBA_Environment *ev);
-static void impl_notifyObjUpdated (PortableServer_Servant servant,
- const CORBA_char *uid,
- CORBA_Environment *ev);
-static void impl_notifyObjRemoved (PortableServer_Servant servant,
- const CORBA_char *uid,
- CORBA_Environment *ev);
-static void impl_notifyErrorOccurred (PortableServer_Servant servant,
- const CORBA_char *message,
- CORBA_Environment *ev);
-static void impl_notifyCategoriesChanged (PortableServer_Servant servant,
- const GNOME_Evolution_Calendar_StringSeq *categories,
- CORBA_Environment *ev);
+static guint signals[LAST_SIGNAL] = { 0 };
static BonoboObjectClass *parent_class;
-
-
-BONOBO_TYPE_FUNC_FULL (CalListener,
- GNOME_Evolution_Calendar_Listener,
- BONOBO_TYPE_OBJECT,
- cal_listener);
+static ECalendarStatus
+convert_status (const GNOME_Evolution_Calendar_CallStatus status)
+{
+ switch (status) {
+ case GNOME_Evolution_Calendar_Success:
+ return E_CALENDAR_STATUS_OK;
+ case GNOME_Evolution_Calendar_RepositoryOffline:
+ return E_CALENDAR_STATUS_REPOSITORY_OFFLINE;
+ case GNOME_Evolution_Calendar_PermissionDenied:
+ return E_CALENDAR_STATUS_PERMISSION_DENIED;
+ case GNOME_Evolution_Calendar_ObjectNotFound:
+ return E_CALENDAR_STATUS_OBJECT_NOT_FOUND;
+ case GNOME_Evolution_Calendar_InvalidObject:
+ return E_CALENDAR_STATUS_INVALID_OBJECT;
+ case GNOME_Evolution_Calendar_CardIdAlreadyExists:
+ return E_CALENDAR_STATUS_CARD_ID_ALREADY_EXISTS;
+ case GNOME_Evolution_Calendar_AuthenticationFailed:
+ return E_CALENDAR_STATUS_AUTHENTICATION_FAILED;
+ case GNOME_Evolution_Calendar_AuthenticationRequired:
+ return E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED;
+ case GNOME_Evolution_Calendar_OtherError:
+ default:
+ return E_CALENDAR_STATUS_OTHER_ERROR;
+ }
+}
-/* Class initialization function for the calendar listener */
static void
-cal_listener_class_init (CalListenerClass *klass)
+impl_notifyReadOnly (PortableServer_Servant servant,
+ GNOME_Evolution_Calendar_CallStatus status,
+ const CORBA_boolean read_only,
+ CORBA_Environment *ev)
{
- GObjectClass *object_class;
-
- object_class = (GObjectClass *) klass;
+ CalListener *listener;
+ CalListenerPrivate *priv;
- parent_class = g_type_class_peek_parent (klass);
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
- klass->epv.notifyCalOpened = impl_notifyCalOpened;
- klass->epv.notifyCalSetMode = impl_notifyCalSetMode;
- klass->epv.notifyObjUpdated = impl_notifyObjUpdated;
- klass->epv.notifyObjRemoved = impl_notifyObjRemoved;
- klass->epv.notifyErrorOccurred = impl_notifyErrorOccurred;
- klass->epv.notifyCategoriesChanged = impl_notifyCategoriesChanged;
+ if (!priv->notify)
+ return;
- object_class->finalize = cal_listener_finalize;
+ g_signal_emit (G_OBJECT (listener), signals[READ_ONLY], 0, convert_status (status), read_only);
}
-/* Object initialization function for the calendar listener */
static void
-cal_listener_init (CalListener *listener, CalListenerClass *klass)
+impl_notifyCalAddress (PortableServer_Servant servant,
+ GNOME_Evolution_Calendar_CallStatus status,
+ const CORBA_char *address,
+ CORBA_Environment *ev)
{
+ CalListener *listener;
CalListenerPrivate *priv;
- priv = g_new0 (CalListenerPrivate, 1);
- listener->priv = priv;
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
- priv->cal_opened_fn = NULL;
- priv->obj_updated_fn = NULL;
- priv->obj_removed_fn = NULL;
- priv->error_occurred_fn = NULL;
- priv->categories_changed_fn = NULL;
+ if (!priv->notify)
+ return;
- priv->notify = TRUE;
+ g_signal_emit (G_OBJECT (listener), signals[CAL_ADDRESS], 0, convert_status (status), address);
}
-/* Finalize handler for the calendar listener */
static void
-cal_listener_finalize (GObject *object)
+impl_notifyAlarmEmailAddress (PortableServer_Servant servant,
+ GNOME_Evolution_Calendar_CallStatus status,
+ const CORBA_char *address,
+ CORBA_Environment *ev)
{
CalListener *listener;
CalListenerPrivate *priv;
- g_return_if_fail (object != NULL);
- g_return_if_fail (IS_CAL_LISTENER (object));
-
- listener = CAL_LISTENER (object);
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
priv = listener->priv;
- priv->cal_opened_fn = NULL;
- priv->obj_updated_fn = NULL;
- priv->obj_removed_fn = NULL;
- priv->error_occurred_fn = NULL;
- priv->categories_changed_fn = NULL;
- priv->fn_data = NULL;
+ if (!priv->notify)
+ return;
- priv->notify = FALSE;
+ g_signal_emit (G_OBJECT (listener), signals[ALARM_ADDRESS], 0, convert_status (status), address);
+}
- g_free (priv);
- listener->priv = NULL;
+static void
+impl_notifyLDAPAttribute (PortableServer_Servant servant,
+ GNOME_Evolution_Calendar_CallStatus status,
+ const CORBA_char *ldap_attribute,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
- if (G_OBJECT_CLASS (parent_class)->finalize)
- (* G_OBJECT_CLASS (parent_class)->finalize) (object);
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+
+ if (!priv->notify)
+ return;
+
+ g_signal_emit (G_OBJECT (listener), signals[LDAP_ATTRIBUTE], 0, convert_status (status), ldap_attribute);
}
-
+static void
+impl_notifyStaticCapabilities (PortableServer_Servant servant,
+ GNOME_Evolution_Calendar_CallStatus status,
+ const CORBA_char *capabilities,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
-/* CORBA servant implementation */
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+
+ if (!priv->notify)
+ return;
+
+ g_signal_emit (G_OBJECT (listener), signals[STATIC_CAPABILITIES], 0, convert_status (status));
+}
/* ::notifyCalOpened method */
static void
impl_notifyCalOpened (PortableServer_Servant servant,
- GNOME_Evolution_Calendar_Listener_OpenStatus status,
- GNOME_Evolution_Calendar_Cal cal,
+ GNOME_Evolution_Calendar_CallStatus status,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+
+ if (!priv->notify)
+ return;
+
+ g_signal_emit (G_OBJECT (listener), signals[OPEN], 0, convert_status (status));
+}
+
+static void
+impl_notifyCalRemoved (PortableServer_Servant servant,
+ GNOME_Evolution_Calendar_CallStatus status,
CORBA_Environment *ev)
{
CalListener *listener;
CalListenerPrivate *priv;
- CORBA_Environment aev;
- GNOME_Evolution_Calendar_Cal cal_copy;
listener = CAL_LISTENER (bonobo_object_from_servant (servant));
priv = listener->priv;
@@ -163,63 +217,388 @@ impl_notifyCalOpened (PortableServer_Servant servant,
if (!priv->notify)
return;
- CORBA_exception_init (&aev);
- cal_copy = CORBA_Object_duplicate (cal, &aev);
+ g_signal_emit (G_OBJECT (listener), signals[REMOVE], 0, convert_status (status));
+}
+
+static void
+impl_notifyObjectCreated (PortableServer_Servant servant,
+ GNOME_Evolution_Calendar_CallStatus status,
+ const CORBA_char *uid,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+
+ if (!priv->notify)
+ return;
+
+ g_signal_emit (G_OBJECT (listener), signals[CREATE_OBJECT], 0, convert_status (status), uid);
+}
+
+static void
+impl_notifyObjectModified (PortableServer_Servant servant,
+ GNOME_Evolution_Calendar_CallStatus status,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
- if (aev._major != CORBA_NO_EXCEPTION) {
- g_message ("Listener_notifyCalOpened(): could not duplicate the calendar");
- CORBA_exception_free (&aev);
+ if (!priv->notify)
return;
+
+ g_signal_emit (G_OBJECT (listener), signals[MODIFY_OBJECT], 0, convert_status (status));
+}
+
+static void
+impl_notifyObjectRemoved (PortableServer_Servant servant,
+ GNOME_Evolution_Calendar_CallStatus status,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+
+ if (!priv->notify)
+ return;
+
+ g_signal_emit (G_OBJECT (listener), signals[REMOVE_OBJECT], 0, convert_status (status));
+}
+
+static void
+impl_notifyAlarmDiscarded (PortableServer_Servant servant,
+ GNOME_Evolution_Calendar_CallStatus status,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+
+ if (!priv->notify)
+ return;
+
+ g_signal_emit (G_OBJECT (listener), signals[DISCARD_ALARM], 0, convert_status (status));
+}
+
+static void
+impl_notifyObjectsReceived (PortableServer_Servant servant,
+ GNOME_Evolution_Calendar_CallStatus status,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+
+ if (!priv->notify)
+ return;
+
+ g_signal_emit (G_OBJECT (listener), signals[RECEIVE_OBJECTS], 0, convert_status (status));
+}
+
+static void
+impl_notifyObjectsSent (PortableServer_Servant servant,
+ GNOME_Evolution_Calendar_CallStatus status,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+
+ if (!priv->notify)
+ return;
+
+ g_signal_emit (G_OBJECT (listener), signals[SEND_OBJECTS], 0, convert_status (status));
+}
+
+static void
+impl_notifyDefaultObjectRequested (PortableServer_Servant servant,
+ const GNOME_Evolution_Calendar_CallStatus status,
+ const CORBA_char *object,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+
+ if (!priv->notify)
+ return;
+
+ g_signal_emit (G_OBJECT (listener), signals[DEFAULT_OBJECT], 0, convert_status (status), object);
+}
+
+static void
+impl_notifyObjectRequested (PortableServer_Servant servant,
+ const GNOME_Evolution_Calendar_CallStatus status,
+ const CORBA_char *object,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+
+ if (!priv->notify)
+ return;
+
+ g_signal_emit (G_OBJECT (listener), signals[OBJECT], 0, convert_status (status), object);
+}
+
+static GList *
+build_object_list (const GNOME_Evolution_Calendar_stringlist *seq)
+{
+ GList *list;
+ int i;
+
+ list = NULL;
+ for (i = 0; i < seq->_length; i++) {
+ icalcomponent *comp;
+
+ comp = icalcomponent_new_from_string (seq->_buffer[i]);
+ if (!comp)
+ continue;
+
+ list = g_list_prepend (list, comp);
}
- CORBA_exception_free (&aev);
- g_assert (priv->cal_opened_fn != NULL);
- (* priv->cal_opened_fn) (listener, status, cal, priv->fn_data);
+ return list;
+}
+
+static void
+impl_notifyObjectListRequested (PortableServer_Servant servant,
+ const GNOME_Evolution_Calendar_CallStatus status,
+ const GNOME_Evolution_Calendar_stringlist *objects,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+ GList *object_list, *l;
+
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+
+ if (!priv->notify)
+ return;
+
+ object_list = build_object_list (objects);
+
+ g_signal_emit (G_OBJECT (listener), signals[OBJECT_LIST], 0, convert_status (status), object_list);
+
+ for (l = object_list; l; l = l->next)
+ icalcomponent_free (l->data);
+ g_list_free (object_list);
}
-/* ::notifyCalSetMode method */
static void
-impl_notifyCalSetMode (PortableServer_Servant servant,
- GNOME_Evolution_Calendar_Listener_SetModeStatus status,
- GNOME_Evolution_Calendar_CalMode mode,
- CORBA_Environment *ev)
+impl_notifyTimezoneRequested (PortableServer_Servant servant,
+ const GNOME_Evolution_Calendar_CallStatus status,
+ const CORBA_char *object,
+ CORBA_Environment *ev)
{
CalListener *listener;
CalListenerPrivate *priv;
+
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+
+ if (!priv->notify)
+ return;
+
+ g_signal_emit (G_OBJECT (listener), signals[GET_TIMEZONE], 0, convert_status (status), object);
+}
+static void
+impl_notifyTimezoneAdded (PortableServer_Servant servant,
+ const GNOME_Evolution_Calendar_CallStatus status,
+ const CORBA_char *tzid,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+
listener = CAL_LISTENER (bonobo_object_from_servant (servant));
priv = listener->priv;
if (!priv->notify)
return;
+
+ g_signal_emit (G_OBJECT (listener), signals[ADD_TIMEZONE], 0, convert_status (status), tzid);
+}
- g_assert (priv->cal_set_mode_fn != NULL);
- (* priv->cal_set_mode_fn) (listener, status, mode, priv->fn_data);
+static void
+impl_notifyDefaultTimezoneSet (PortableServer_Servant servant,
+ const GNOME_Evolution_Calendar_CallStatus status,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+
+ if (!priv->notify)
+ return;
+
+ g_signal_emit (G_OBJECT (listener), signals[SET_DEFAULT_TIMEZONE], 0, convert_status (status));
+}
+
+static GList *
+build_change_list (const GNOME_Evolution_Calendar_CalObjChangeSeq *seq)
+{
+ GList *list = NULL;
+ icalcomponent *icalcomp;
+ int i;
+
+ /* Create the list in reverse order */
+ for (i = 0; i < seq->_length; i++) {
+ GNOME_Evolution_Calendar_CalObjChange *corba_coc;
+ CalClientChange *ccc;
+
+ corba_coc = &seq->_buffer[i];
+ ccc = g_new (CalClientChange, 1);
+
+ icalcomp = icalparser_parse_string (corba_coc->calobj);
+ if (!icalcomp)
+ continue;
+
+ ccc->comp = cal_component_new ();
+ if (!cal_component_set_icalcomponent (ccc->comp, icalcomp)) {
+ icalcomponent_free (icalcomp);
+ g_object_unref (G_OBJECT (ccc->comp));
+ continue;
+ }
+ ccc->type = corba_coc->type;
+
+ list = g_list_prepend (list, ccc);
+ }
+
+ list = g_list_reverse (list);
+
+ return list;
}
-/* ::notifyObjUpdated method */
static void
-impl_notifyObjUpdated (PortableServer_Servant servant,
- const CORBA_char *uid,
- CORBA_Environment *ev)
+impl_notifyChanges (PortableServer_Servant servant,
+ const GNOME_Evolution_Calendar_CallStatus status,
+ const GNOME_Evolution_Calendar_CalObjChangeSeq *seq,
+ CORBA_Environment *ev)
{
CalListener *listener;
CalListenerPrivate *priv;
+ GList *changes, *l;
+
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+ if (!priv->notify)
+ return;
+
+ changes = build_change_list (seq);
+
+ g_signal_emit (G_OBJECT (listener), signals[GET_CHANGES], 0, convert_status (status), changes);
+
+ for (l = changes; l; l = l->next)
+ g_free (l->data);
+ g_list_free (changes);
+}
+
+static GList *
+build_free_busy_list (const GNOME_Evolution_Calendar_CalObjSeq *seq)
+{
+ GList *list = NULL;
+ int i;
+
+ /* Create the list in reverse order */
+ for (i = 0; i < seq->_length; i++) {
+ CalComponent *comp;
+ icalcomponent *icalcomp;
+ icalcomponent_kind kind;
+
+ icalcomp = icalcomponent_new_from_string (seq->_buffer[i]);
+ if (!icalcomp)
+ continue;
+
+ kind = icalcomponent_isa (icalcomp);
+ if (kind == ICAL_VFREEBUSY_COMPONENT) {
+ comp = cal_component_new ();
+ if (!cal_component_set_icalcomponent (comp, icalcomp)) {
+ icalcomponent_free (icalcomp);
+ g_object_unref (G_OBJECT (comp));
+ continue;
+ }
+
+ list = g_list_append (list, comp);
+ } else {
+ icalcomponent_free (icalcomp);
+ }
+ }
+
+ return list;
+}
+
+static void
+impl_notifyFreeBusy (PortableServer_Servant servant,
+ const GNOME_Evolution_Calendar_CallStatus status,
+ const GNOME_Evolution_Calendar_CalObjSeq *seq,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+ GList *freebusy, *l;
+
listener = CAL_LISTENER (bonobo_object_from_servant (servant));
priv = listener->priv;
if (!priv->notify)
return;
+
+ freebusy = build_free_busy_list (seq);
+
+ g_signal_emit (G_OBJECT (listener), signals[GET_FREE_BUSY], 0, convert_status (status), freebusy);
+
+ for (l = freebusy; l; l = l->next)
+ g_free (l->data);
+ g_list_free (freebusy);
+}
- g_assert (priv->obj_updated_fn != NULL);
- (* priv->obj_updated_fn) (listener, uid, priv->fn_data);
+static void
+impl_notifyQuery (PortableServer_Servant servant,
+ const GNOME_Evolution_Calendar_CallStatus status,
+ const GNOME_Evolution_Calendar_Query query,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+
+ if (!priv->notify)
+ return;
+
+ g_signal_emit (G_OBJECT (listener), signals[QUERY], 0, convert_status (status), query);
}
-/* ::notifyObjRemoved method */
+/* ::notifyCalSetMode method */
static void
-impl_notifyObjRemoved (PortableServer_Servant servant,
- const CORBA_char *uid,
+impl_notifyCalSetMode (PortableServer_Servant servant,
+ GNOME_Evolution_Calendar_Listener_SetModeStatus status,
+ GNOME_Evolution_Calendar_CalMode mode,
CORBA_Environment *ev)
{
CalListener *listener;
@@ -231,10 +610,13 @@ impl_notifyObjRemoved (PortableServer_Servant servant,
if (!priv->notify)
return;
- g_assert (priv->obj_removed_fn != NULL);
- (* priv->obj_removed_fn) (listener, uid, priv->fn_data);
+ g_message ("notify_set_mode");
+
+ g_assert (priv->cal_set_mode_fn != NULL);
+ (* priv->cal_set_mode_fn) (listener, status, mode, priv->fn_data);
}
+
/* ::notifyErrorOccurred method */
static void
impl_notifyErrorOccurred (PortableServer_Servant servant,
@@ -250,6 +632,8 @@ impl_notifyErrorOccurred (PortableServer_Servant servant,
if (!priv->notify)
return;
+ g_message ("notify_error");
+
g_assert (priv->error_occurred_fn != NULL);
(* priv->error_occurred_fn) (listener, message, priv->fn_data);
}
@@ -269,21 +653,283 @@ impl_notifyCategoriesChanged (PortableServer_Servant servant,
if (!priv->notify)
return;
+ g_message ("notify_categories");
+
g_assert (priv->categories_changed_fn != NULL);
(* priv->categories_changed_fn) (listener, categories, priv->fn_data);
}
+/* Object initialization function for the calendar listener */
+static void
+cal_listener_init (CalListener *listener, CalListenerClass *klass)
+{
+ CalListenerPrivate *priv;
+
+ priv = g_new0 (CalListenerPrivate, 1);
+ listener->priv = priv;
+
+ priv->error_occurred_fn = NULL;
+ priv->categories_changed_fn = NULL;
+
+ priv->notify = TRUE;
+}
+
+/* Finalize handler for the calendar listener */
+static void
+cal_listener_finalize (GObject *object)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (IS_CAL_LISTENER (object));
+
+ listener = CAL_LISTENER (object);
+ priv = listener->priv;
+
+ priv->error_occurred_fn = NULL;
+ priv->categories_changed_fn = NULL;
+ priv->fn_data = NULL;
+
+ priv->notify = FALSE;
+
+ g_free (priv);
+ listener->priv = NULL;
+
+ if (G_OBJECT_CLASS (parent_class)->finalize)
+ (* G_OBJECT_CLASS (parent_class)->finalize) (object);
+}
+
+/* Class initialization function for the calendar listener */
+static void
+cal_listener_class_init (CalListenerClass *klass)
+{
+ GObjectClass *object_class;
+
+ object_class = (GObjectClass *) klass;
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ klass->epv.notifyReadOnly = impl_notifyReadOnly;
+ klass->epv.notifyCalAddress = impl_notifyCalAddress;
+ klass->epv.notifyAlarmEmailAddress = impl_notifyAlarmEmailAddress;
+ klass->epv.notifyLDAPAttribute = impl_notifyLDAPAttribute;
+ klass->epv.notifyStaticCapabilities = impl_notifyStaticCapabilities;
+ klass->epv.notifyCalOpened = impl_notifyCalOpened;
+ klass->epv.notifyCalRemoved = impl_notifyCalRemoved;
+ klass->epv.notifyObjectCreated = impl_notifyObjectCreated;
+ klass->epv.notifyObjectModified = impl_notifyObjectModified;
+ klass->epv.notifyObjectRemoved = impl_notifyObjectRemoved;
+ klass->epv.notifyAlarmDiscarded = impl_notifyAlarmDiscarded;
+ klass->epv.notifyObjectsReceived = impl_notifyObjectsReceived;
+ klass->epv.notifyObjectsSent = impl_notifyObjectsSent;
+ klass->epv.notifyDefaultObjectRequested = impl_notifyDefaultObjectRequested;
+ klass->epv.notifyObjectRequested = impl_notifyObjectRequested;
+ klass->epv.notifyObjectListRequested = impl_notifyObjectListRequested;
+ klass->epv.notifyTimezoneRequested = impl_notifyTimezoneRequested;
+ klass->epv.notifyTimezoneAdded = impl_notifyTimezoneAdded;
+ klass->epv.notifyDefaultTimezoneSet = impl_notifyDefaultTimezoneSet;
+ klass->epv.notifyChanges = impl_notifyChanges;
+ klass->epv.notifyFreeBusy = impl_notifyFreeBusy;
+ klass->epv.notifyQuery = impl_notifyQuery;
+ klass->epv.notifyCalSetMode = impl_notifyCalSetMode;
+ klass->epv.notifyErrorOccurred = impl_notifyErrorOccurred;
+ klass->epv.notifyCategoriesChanged = impl_notifyCategoriesChanged;
+
+ object_class->finalize = cal_listener_finalize;
+
+ signals[READ_ONLY] =
+ g_signal_new ("read_only",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, read_only),
+ NULL, NULL,
+ cal_marshal_VOID__INT_BOOLEAN,
+ G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_BOOLEAN);
+ signals[CAL_ADDRESS] =
+ g_signal_new ("cal_address",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, cal_address),
+ NULL, NULL,
+ cal_marshal_VOID__INT_STRING,
+ G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_STRING);
+ signals[ALARM_ADDRESS] =
+ g_signal_new ("alarm_address",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, alarm_address),
+ NULL, NULL,
+ cal_marshal_VOID__INT_STRING,
+ G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_STRING);
+ signals[LDAP_ATTRIBUTE] =
+ g_signal_new ("ldap_attribute",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, ldap_attribute),
+ NULL, NULL,
+ cal_marshal_VOID__INT_STRING,
+ G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_STRING);
+ signals[STATIC_CAPABILITIES] =
+ g_signal_new ("static_capabilities",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, static_capabilities),
+ NULL, NULL,
+ cal_marshal_VOID__INT_STRING,
+ G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_STRING);
+ signals[OPEN] =
+ g_signal_new ("open",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, open),
+ NULL, NULL,
+ cal_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
+ signals[REMOVE] =
+ g_signal_new ("remove",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, remove),
+ NULL, NULL,
+ cal_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
+ signals[CREATE_OBJECT] =
+ g_signal_new ("create_object",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, create_object),
+ NULL, NULL,
+ cal_marshal_VOID__INT_STRING,
+ G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_STRING);
+ signals[MODIFY_OBJECT] =
+ g_signal_new ("modify_object",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, modify_object),
+ NULL, NULL,
+ cal_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
+ signals[REMOVE_OBJECT] =
+ g_signal_new ("remove_object",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, remove_object),
+ NULL, NULL,
+ cal_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
+ signals[DISCARD_ALARM] =
+ g_signal_new ("discard_alarm",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, discard_alarm),
+ NULL, NULL,
+ cal_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
+ signals[RECEIVE_OBJECTS] =
+ g_signal_new ("receive_objects",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, receive_objects),
+ NULL, NULL,
+ cal_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
+ signals[SEND_OBJECTS] =
+ g_signal_new ("send_objects",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, send_objects),
+ NULL, NULL,
+ cal_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
+ signals[DEFAULT_OBJECT] =
+ g_signal_new ("default_object",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, default_object),
+ NULL, NULL,
+ cal_marshal_VOID__INT_STRING,
+ G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_STRING);
+ signals[OBJECT] =
+ g_signal_new ("object",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, object),
+ NULL, NULL,
+ cal_marshal_VOID__INT_STRING,
+ G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_STRING);
+ signals[OBJECT_LIST] =
+ g_signal_new ("object_list",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, object_list),
+ NULL, NULL,
+ cal_marshal_VOID__INT_POINTER,
+ G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_POINTER);
+ signals[GET_TIMEZONE] =
+ g_signal_new ("get_timezone",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, get_timezone),
+ NULL, NULL,
+ cal_marshal_VOID__INT_STRING,
+ G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_STRING);
+ signals[ADD_TIMEZONE] =
+ g_signal_new ("add_timezone",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, add_timezone),
+ NULL, NULL,
+ cal_marshal_VOID__INT_STRING,
+ G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_STRING);
+ signals[SET_DEFAULT_TIMEZONE] =
+ g_signal_new ("set_default_timezone",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, set_default_timezone),
+ NULL, NULL,
+ cal_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
+ signals[GET_CHANGES] =
+ g_signal_new ("get_changes",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, get_changes),
+ NULL, NULL,
+ cal_marshal_VOID__INT_POINTER,
+ G_TYPE_NONE, 1, G_TYPE_INT, G_TYPE_POINTER);
+ signals[GET_FREE_BUSY] =
+ g_signal_new ("get_free_busy",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, get_free_busy),
+ NULL, NULL,
+ cal_marshal_VOID__INT_POINTER,
+ G_TYPE_NONE, 1, G_TYPE_INT, G_TYPE_POINTER);
+ signals[QUERY] =
+ g_signal_new ("query",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, query),
+ NULL, NULL,
+ cal_marshal_VOID__INT_POINTER,
+ G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_POINTER);
+}
+
+BONOBO_TYPE_FUNC_FULL (CalListener,
+ GNOME_Evolution_Calendar_Listener,
+ BONOBO_TYPE_OBJECT,
+ cal_listener);
+
/**
* cal_listener_construct:
* @listener: A calendar listener.
* @cal_opened_fn: Function that will be called to notify that a calendar was
* opened.
- * @obj_updated_fn: Function that will be called to notify that an object in the
- * calendar was updated.
- * @obj_removed_fn: Function that will be called to notify that an object in the
- * calendar was removed.
+ * @cal_removed_fn: Function that will be called to notify that a calendar was
+ * removed
* @error_occurred_fn: Function that will be called to notify errors.
* @categories_changed_fn: Function that will be called to notify that the list
* of categories that are present in the calendar's objects has changed.
@@ -297,10 +943,7 @@ impl_notifyCategoriesChanged (PortableServer_Servant servant,
**/
CalListener *
cal_listener_construct (CalListener *listener,
- CalListenerCalOpenedFn cal_opened_fn,
CalListenerCalSetModeFn cal_set_mode_fn,
- CalListenerObjUpdatedFn obj_updated_fn,
- CalListenerObjRemovedFn obj_removed_fn,
CalListenerErrorOccurredFn error_occurred_fn,
CalListenerCategoriesChangedFn categories_changed_fn,
gpointer fn_data)
@@ -309,19 +952,13 @@ cal_listener_construct (CalListener *listener,
g_return_val_if_fail (listener != NULL, NULL);
g_return_val_if_fail (IS_CAL_LISTENER (listener), NULL);
- g_return_val_if_fail (cal_opened_fn != NULL, NULL);
g_return_val_if_fail (cal_set_mode_fn != NULL, NULL);
- g_return_val_if_fail (obj_updated_fn != NULL, NULL);
- g_return_val_if_fail (obj_removed_fn != NULL, NULL);
g_return_val_if_fail (error_occurred_fn != NULL, NULL);
g_return_val_if_fail (categories_changed_fn != NULL, NULL);
priv = listener->priv;
- priv->cal_opened_fn = cal_opened_fn;
priv->cal_set_mode_fn = cal_set_mode_fn;
- priv->obj_updated_fn = obj_updated_fn;
- priv->obj_removed_fn = obj_removed_fn;
priv->error_occurred_fn = error_occurred_fn;
priv->categories_changed_fn = categories_changed_fn;
priv->fn_data = fn_data;
@@ -333,10 +970,6 @@ cal_listener_construct (CalListener *listener,
* cal_listener_new:
* @cal_opened_fn: Function that will be called to notify that a calendar was
* opened.
- * @obj_updated_fn: Function that will be called to notify that an object in the
- * calendar was updated.
- * @obj_removed_fn: Function that will be called to notify that an object in the
- * calendar was removed.
* @error_occurred_fn: Function that will be called to notify errors.
* @categories_changed_fn: Function that will be called to notify that the list
* of categories that are present in the calendar's objects has changed.
@@ -348,28 +981,22 @@ cal_listener_construct (CalListener *listener,
* Return value: A newly-created #CalListener object.
**/
CalListener *
-cal_listener_new (CalListenerCalOpenedFn cal_opened_fn,
- CalListenerCalSetModeFn cal_set_mode_fn,
- CalListenerObjUpdatedFn obj_updated_fn,
- CalListenerObjRemovedFn obj_removed_fn,
+cal_listener_new (CalListenerCalSetModeFn cal_set_mode_fn,
CalListenerErrorOccurredFn error_occurred_fn,
CalListenerCategoriesChangedFn categories_changed_fn,
gpointer fn_data)
{
CalListener *listener;
- g_return_val_if_fail (cal_opened_fn != NULL, NULL);
- g_return_val_if_fail (obj_updated_fn != NULL, NULL);
- g_return_val_if_fail (obj_removed_fn != NULL, NULL);
g_return_val_if_fail (error_occurred_fn != NULL, NULL);
g_return_val_if_fail (categories_changed_fn != NULL, NULL);
- listener = g_object_new (CAL_LISTENER_TYPE, NULL);
+ listener = g_object_new (CAL_LISTENER_TYPE,
+ "poa", bonobo_poa_get_threaded (ORBIT_THREAD_HINT_PER_REQUEST, NULL),
+ NULL);
+
return cal_listener_construct (listener,
- cal_opened_fn,
cal_set_mode_fn,
- obj_updated_fn,
- obj_removed_fn,
error_occurred_fn,
categories_changed_fn,
fn_data);
diff --git a/calendar/cal-client/cal-listener.h b/calendar/cal-client/cal-listener.h
index d0f9a718a4..1230104999 100644
--- a/calendar/cal-client/cal-listener.h
+++ b/calendar/cal-client/cal-listener.h
@@ -23,6 +23,7 @@
#include <bonobo/bonobo-object.h>
#include "evolution-calendar.h"
+#include "cal-client-types.h"
G_BEGIN_DECLS
@@ -48,26 +49,46 @@ typedef struct {
BonoboObjectClass parent_class;
POA_GNOME_Evolution_Calendar_Listener__epv epv;
+
+ /* Signals */
+ void (*read_only) (CalListener *listener, ECalendarStatus status, gboolean read_only);
+ void (*cal_address) (CalListener *listener, ECalendarStatus status, const char *address);
+ void (*alarm_address) (CalListener *listener, ECalendarStatus status, const char *address);
+ void (*ldap_attribute) (CalListener *listener, ECalendarStatus status, const char *ldap_attribute);
+ void (*static_capabilities) (CalListener *listener, ECalendarStatus status, const char *capabilities);
+
+ void (*open) (CalListener *listener, ECalendarStatus status);
+ void (*remove) (CalListener *listener, ECalendarStatus status);
+
+ void (*create_object) (CalListener *listener, ECalendarStatus status, const char *id);
+ void (*modify_object) (CalListener *listener, ECalendarStatus status);
+ void (*remove_object) (CalListener *listener, ECalendarStatus status);
+
+ void (*discard_alarm) (CalListener *listener, ECalendarStatus status);
+
+ void (*receive_objects) (CalListener *listener, ECalendarStatus status);
+ void (*send_objects) (CalListener *listener, ECalendarStatus status);
+
+ void (*default_object) (CalListener *listener, ECalendarStatus status, const char *object);
+ void (*object) (CalListener *listener, ECalendarStatus status, const char *object);
+ void (*object_list) (CalListener *listener, ECalendarStatus status, GList **objects);
+
+ void (*get_timezone) (CalListener *listener, ECalendarStatus status, const char *object);
+ void (*add_timezone) (CalListener *listener, ECalendarStatus status, const char *tzid);
+ void (*set_default_timezone) (CalListener *listener, ECalendarStatus status, const char *tzid);
+
+ void (*get_changes) (CalListener *listener, ECalendarStatus status, GList *changes);
+ void (*get_free_busy) (CalListener *listener, ECalendarStatus status, GList *freebusy);
+
+ void (*query) (CalListener *listener, ECalendarStatus status, GNOME_Evolution_Calendar_Query query);
} CalListenerClass;
/* Notification functions */
-typedef void (* CalListenerCalOpenedFn) (CalListener *listener,
- GNOME_Evolution_Calendar_Listener_OpenStatus status,
- GNOME_Evolution_Calendar_Cal cal,
- gpointer data);
-
typedef void (* CalListenerCalSetModeFn) (CalListener *listener,
GNOME_Evolution_Calendar_Listener_SetModeStatus status,
GNOME_Evolution_Calendar_CalMode mode,
gpointer data);
-typedef void (* CalListenerObjUpdatedFn) (CalListener *listener,
- const CORBA_char *uid,
- gpointer data);
-typedef void (* CalListenerObjRemovedFn) (CalListener *listener,
- const CORBA_char *uid,
- gpointer data);
-
typedef void (* CalListenerErrorOccurredFn) (CalListener *listener,
const char *message,
gpointer data);
@@ -80,18 +101,12 @@ typedef void (* CalListenerCategoriesChangedFn) (CalListener *listener,
GType cal_listener_get_type (void);
CalListener *cal_listener_construct (CalListener *listener,
- CalListenerCalOpenedFn cal_opened_fn,
CalListenerCalSetModeFn cal_set_mode_fn,
- CalListenerObjUpdatedFn obj_updated_fn,
- CalListenerObjRemovedFn obj_removed_fn,
CalListenerErrorOccurredFn error_occurred_fn,
CalListenerCategoriesChangedFn categories_changed_fn,
gpointer fn_data);
-CalListener *cal_listener_new (CalListenerCalOpenedFn cal_opened_fn,
- CalListenerCalSetModeFn cal_set_mode_fn,
- CalListenerObjUpdatedFn obj_updated_fn,
- CalListenerObjRemovedFn obj_removed_fn,
+CalListener *cal_listener_new (CalListenerCalSetModeFn cal_set_mode_fn,
CalListenerErrorOccurredFn error_occurred_fn,
CalListenerCategoriesChangedFn categories_changed_fn,
gpointer fn_data);
diff --git a/calendar/cal-client/cal-marshal.list b/calendar/cal-client/cal-marshal.list
new file mode 100644
index 0000000000..e0ca019669
--- /dev/null
+++ b/calendar/cal-client/cal-marshal.list
@@ -0,0 +1,6 @@
+NONE:INT
+NONE:POINTER
+NONE:INT,STRING
+NONE:INT,BOOL
+NONE:INT,POINTER
+NONE:STRING,INT
diff --git a/calendar/cal-client/cal-query.c b/calendar/cal-client/cal-query.c
index 914af5db28..e77f5ad3e9 100644
--- a/calendar/cal-client/cal-query.c
+++ b/calendar/cal-client/cal-query.c
@@ -24,7 +24,8 @@
#include <string.h>
#include <bonobo/bonobo-exception.h>
-#include "cal-util/cal-util-marshal.h"
+#include "cal-marshal.h"
+#include "cal-client.h"
#include "cal-query.h"
#include "query-listener.h"
@@ -32,143 +33,88 @@
/* Private part of the CalQuery structure */
struct _CalQueryPrivate {
- /* Our query listener implementation */
- QueryListener *ql;
-
/* Handle to the query in the server */
- GNOME_Evolution_Calendar_Query corba_query;
+ GNOME_Evolution_Calendar_Query query;
+
+ /* Our query listener implementation */
+ QueryListener *listener;
/* The CalClient associated with this query */
CalClient *client;
};
-
-
-static void cal_query_class_init (CalQueryClass *klass);
-static void cal_query_init (CalQuery *query, CalQueryClass *klass);
-static void cal_query_finalize (GObject *object);
+/* Property IDs */
+enum props {
+ PROP_0,
+ PROP_QUERY,
+ PROP_LISTENER,
+ PROP_CLIENT
+};
/* Signal IDs */
enum {
- OBJ_UPDATED,
- OBJ_REMOVED,
+ OBJECTS_ADDED,
+ OBJECTS_MODIFIED,
+ OBJECTS_REMOVED,
+ QUERY_PROGRESS,
QUERY_DONE,
- EVAL_ERROR,
LAST_SIGNAL
};
-static guint query_signals[LAST_SIGNAL];
+static guint signals[LAST_SIGNAL];
static GObjectClass *parent_class;
-/**
- * cal_query_get_type:
- *
- * Registers the #CalQuery class if necessary, and returns the type ID assigned
- * to it.
- *
- * Return value: The type ID of the #CalQuery class.
- **/
-GType
-cal_query_get_type (void)
+static void
+objects_added_cb (QueryListener *listener, GList *objects, gpointer data)
{
- static GType cal_query_type = 0;
+ CalQuery *query;
- if (!cal_query_type) {
- static GTypeInfo info = {
- sizeof (CalQueryClass),
- (GBaseInitFunc) NULL,
- (GBaseFinalizeFunc) NULL,
- (GClassInitFunc) cal_query_class_init,
- NULL, NULL,
- sizeof (CalQuery),
- 0,
- (GInstanceInitFunc) cal_query_init
- };
- cal_query_type = g_type_register_static (G_TYPE_OBJECT, "CalQuery", &info, 0);
- }
+ query = CAL_QUERY (data);
- return cal_query_type;
+ g_signal_emit (G_OBJECT (query), signals[OBJECTS_ADDED], 0, objects);
}
-GType
-cal_query_done_status_enum_get_type (void)
+static void
+objects_modified_cb (QueryListener *listener, GList *objects, gpointer data)
{
- static GType cal_query_done_status_enum_type = 0;
+ CalQuery *query;
- if (!cal_query_done_status_enum_type) {
- static GEnumValue values [] = {
- { CAL_QUERY_DONE_SUCCESS, "CalQueryDoneSuccess", "success" },
- { CAL_QUERY_DONE_PARSE_ERROR, "CalQueryDoneParseError", "parse-error" },
- { -1, NULL, NULL }
- };
+ query = CAL_QUERY (data);
- cal_query_done_status_enum_type =
- g_enum_register_static ("CalQueryDoneStatusEnum", values);
- }
+ g_signal_emit (G_OBJECT (query), signals[OBJECTS_MODIFIED], 0, objects);
+}
+
+static void
+objects_removed_cb (QueryListener *listener, GList *uids, gpointer data)
+{
+ CalQuery *query;
+
+ query = CAL_QUERY (data);
- return cal_query_done_status_enum_type;
+ g_signal_emit (G_OBJECT (query), signals[OBJECTS_REMOVED], 0, uids);
}
-/* Class initialization function for the calendar query */
static void
-cal_query_class_init (CalQueryClass *klass)
+query_progress_cb (QueryListener *listener, const char *message, int percent, gpointer data)
{
- GObjectClass *object_class;
+ CalQuery *query;
- object_class = (GObjectClass *) klass;
+ query = CAL_QUERY (data);
- parent_class = g_type_class_peek_parent (klass);
+ g_signal_emit (G_OBJECT (query), signals[QUERY_PROGRESS], 0, message, percent);
+}
- query_signals[OBJ_UPDATED] =
- g_signal_new ("obj_updated",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (CalQueryClass, obj_updated),
- NULL, NULL,
- cal_util_marshal_VOID__STRING_BOOLEAN_INT_INT,
- G_TYPE_NONE, 4,
- G_TYPE_STRING,
- G_TYPE_BOOLEAN,
- G_TYPE_INT,
- G_TYPE_INT);
- query_signals[OBJ_REMOVED] =
- g_signal_new ("obj_removed",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (CalQueryClass, obj_removed),
- NULL, NULL,
- g_cclosure_marshal_VOID__STRING,
- G_TYPE_NONE, 1,
- G_TYPE_STRING);
- query_signals[QUERY_DONE] =
- g_signal_new ("query_done",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (CalQueryClass, query_done),
- NULL, NULL,
- cal_util_marshal_VOID__ENUM_STRING,
- G_TYPE_NONE, 2,
- CAL_QUERY_DONE_STATUS_ENUM_TYPE,
- G_TYPE_STRING);
- query_signals[EVAL_ERROR] =
- g_signal_new ("eval_error",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (CalQueryClass, eval_error),
- NULL, NULL,
- g_cclosure_marshal_VOID__STRING,
- G_TYPE_NONE, 1,
- G_TYPE_STRING);
+static void
+query_done_cb (QueryListener *listener, ECalendarStatus status, gpointer data)
+{
+ CalQuery *query;
- klass->obj_updated = NULL;
- klass->obj_removed = NULL;
- klass->query_done = NULL;
- klass->eval_error = NULL;
+ query = CAL_QUERY (data);
- object_class->finalize = cal_query_finalize;
+ g_signal_emit (G_OBJECT (query), signals[QUERY_DONE], 0, status);
}
/* Object initialization function for the calendar query */
@@ -180,191 +126,193 @@ cal_query_init (CalQuery *query, CalQueryClass *klass)
priv = g_new0 (CalQueryPrivate, 1);
query->priv = priv;
- priv->ql = NULL;
- priv->corba_query = CORBA_OBJECT_NIL;
+ priv->listener = NULL;
+ priv->query = CORBA_OBJECT_NIL;
}
-/* Finalize handler for the calendar query */
static void
-cal_query_finalize (GObject *object)
+cal_query_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
{
CalQuery *query;
CalQueryPrivate *priv;
-
- g_return_if_fail (object != NULL);
- g_return_if_fail (IS_CAL_QUERY (object));
-
+
query = CAL_QUERY (object);
priv = query->priv;
-
- /* The server keeps a copy of the query listener, so we must unref it */
- query_listener_stop_notification (priv->ql);
- bonobo_object_unref (BONOBO_OBJECT (priv->ql));
- priv->ql = NULL;
-
- if (priv->corba_query != CORBA_OBJECT_NIL) {
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
- bonobo_object_release_unref (priv->corba_query, &ev);
-
- if (BONOBO_EX (&ev))
- g_message ("cal_query_destroy(): Could not release/unref the query");
-
- CORBA_exception_free (&ev);
- priv->corba_query = CORBA_OBJECT_NIL;
+
+ switch (property_id) {
+ case PROP_QUERY:
+ priv->query = bonobo_object_dup_ref (g_value_get_pointer (value), NULL);
+ break;
+ case PROP_LISTENER:
+ priv->listener = bonobo_object_ref (g_value_get_pointer (value));
+
+ g_signal_connect (G_OBJECT (priv->listener), "objects_added",
+ G_CALLBACK (objects_added_cb), query);
+ g_signal_connect (G_OBJECT (priv->listener), "objects_modified",
+ G_CALLBACK (objects_modified_cb), query);
+ g_signal_connect (G_OBJECT (priv->listener), "objects_removed",
+ G_CALLBACK (objects_removed_cb), query);
+ g_signal_connect (G_OBJECT (priv->listener), "query_progress",
+ G_CALLBACK (query_progress_cb), query);
+ g_signal_connect (G_OBJECT (priv->listener), "query_done",
+ G_CALLBACK (query_done_cb), query);
+ break;
+ case PROP_CLIENT:
+ priv->client = CAL_CLIENT (g_value_dup_object (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
}
-
- g_free (priv);
- query->priv = NULL;
-
- if (G_OBJECT_CLASS (parent_class)->finalize)
- (* G_OBJECT_CLASS (parent_class)->finalize) (object);
}
-
-
-/* Callback used when an object is updated in the query */
static void
-obj_updated_cb (QueryListener *ql,
- const GNOME_Evolution_Calendar_CalObjUIDSeq *uids,
- CORBA_boolean query_in_progress,
- CORBA_long n_scanned,
- CORBA_long total,
- gpointer data)
+cal_query_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
{
CalQuery *query;
- int n;
-
- query = CAL_QUERY (data);
+ CalQueryPrivate *priv;
+
+ query = CAL_QUERY (object);
+ priv = query->priv;
- for (n = 0; n < uids->_length; n++) {
- g_signal_emit (G_OBJECT (query), query_signals[OBJ_UPDATED], 0,
- uids->_buffer[n], query_in_progress,
- (int) n_scanned, (int) total);
+ switch (property_id) {
+ case PROP_QUERY:
+ g_value_set_pointer (value, priv->query);
+ break;
+ case PROP_LISTENER:
+ g_value_set_pointer (value, priv->listener);
+ break;
+ case PROP_CLIENT:
+ g_value_set_object (value, priv->client);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
}
}
-/* Callback used when an object is removed from the query */
-static void
-obj_removed_cb (QueryListener *ql,
- const CORBA_char *uid,
- gpointer data)
-{
- CalQuery *query;
-
- query = CAL_QUERY (data);
-
- g_signal_emit (G_OBJECT (query), query_signals[OBJ_REMOVED],
- 0, uid);
-}
-/* Callback used when the query terminates */
+/* Finalize handler for the calendar query */
static void
-query_done_cb (QueryListener *ql,
- GNOME_Evolution_Calendar_QueryListener_QueryDoneStatus corba_status,
- const CORBA_char *error_str,
- gpointer data)
+cal_query_finalize (GObject *object)
{
CalQuery *query;
- CalQueryDoneStatus status;
+ CalQueryPrivate *priv;
- query = CAL_QUERY (data);
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (IS_CAL_QUERY (object));
- switch (corba_status) {
- case GNOME_Evolution_Calendar_QueryListener_SUCCESS:
- status = CAL_QUERY_DONE_SUCCESS;
- break;
+ query = CAL_QUERY (object);
+ priv = query->priv;
- case GNOME_Evolution_Calendar_QueryListener_PARSE_ERROR:
- status = CAL_QUERY_DONE_PARSE_ERROR;
- break;
+ /* The server keeps a copy of the query listener, so we must unref it */
+ g_signal_handlers_disconnect_matched (priv->listener, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, query);
+ bonobo_object_unref (BONOBO_OBJECT (priv->listener));
- default:
- g_assert_not_reached ();
- return;
- }
+ if (priv->query != CORBA_OBJECT_NIL)
+ bonobo_object_release_unref (priv->query, NULL);
- g_signal_emit (G_OBJECT (query), query_signals[QUERY_DONE], 0,
- status, error_str);
+ g_free (priv);
+
+ if (G_OBJECT_CLASS (parent_class)->finalize)
+ (* G_OBJECT_CLASS (parent_class)->finalize) (object);
}
-/* Callback used when an error occurs when evaluating the query */
+/* Class initialization function for the calendar query */
static void
-eval_error_cb (QueryListener *ql,
- const CORBA_char *error_str,
- gpointer data)
+cal_query_class_init (CalQueryClass *klass)
{
- CalQuery *query;
+ GObjectClass *object_class;
+ GParamSpec *param;
+
+ object_class = (GObjectClass *) klass;
- query = CAL_QUERY (data);
+ parent_class = g_type_class_peek_parent (klass);
+
+ object_class->set_property = cal_query_set_property;
+ object_class->get_property = cal_query_get_property;
+ object_class->finalize = cal_query_finalize;
- g_signal_emit (G_OBJECT (query), query_signals[EVAL_ERROR], 0,
- error_str);
+ param = g_param_spec_pointer ("query", NULL, NULL,
+ G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY);
+ g_object_class_install_property (object_class, PROP_QUERY, param);
+ param = g_param_spec_pointer ("listener", NULL, NULL,
+ G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY);
+ g_object_class_install_property (object_class, PROP_LISTENER, param);
+ param = g_param_spec_object ("client", NULL, NULL, CAL_CLIENT_TYPE,
+ G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY);
+ g_object_class_install_property (object_class, PROP_CLIENT, param);
+
+ signals[OBJECTS_ADDED] =
+ g_signal_new ("objects_added",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (CalQueryClass, objects_added),
+ NULL, NULL,
+ cal_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
+ signals[OBJECTS_MODIFIED] =
+ g_signal_new ("objects_modified",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (CalQueryClass, objects_modified),
+ NULL, NULL,
+ cal_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
+ signals[OBJECTS_REMOVED] =
+ g_signal_new ("objects_removed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (CalQueryClass, objects_removed),
+ NULL, NULL,
+ cal_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
+ signals[QUERY_PROGRESS] =
+ g_signal_new ("query_progress",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (CalQueryClass, query_progress),
+ NULL, NULL,
+ cal_marshal_VOID__POINTER,
+ G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_INT);
+ signals[QUERY_DONE] =
+ g_signal_new ("query_done",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (CalQueryClass, query_done),
+ NULL, NULL,
+ cal_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
}
/**
- * cal_query_construct:
- * @query: A calendar query.
- * @cal: Handle to an open calendar.
- * @sexp: S-expression that defines the query.
+ * cal_query_get_type:
*
- * Constructs a query object by issuing the query creation request to the
- * calendar server.
+ * Registers the #CalQuery class if necessary, and returns the type ID assigned
+ * to it.
*
- * Return value: The same value as @query on success, or NULL if the request
- * failed.
+ * Return value: The type ID of the #CalQuery class.
**/
-CalQuery *
-cal_query_construct (CalQuery *query,
- GNOME_Evolution_Calendar_Cal cal,
- const char *sexp)
+GType
+cal_query_get_type (void)
{
- CalQueryPrivate *priv;
- GNOME_Evolution_Calendar_QueryListener corba_ql;
- CORBA_Environment ev;
-
- g_return_val_if_fail (query != NULL, NULL);
- g_return_val_if_fail (IS_CAL_QUERY (query), NULL);
- g_return_val_if_fail (sexp != NULL, NULL);
-
- priv = query->priv;
-
- priv->ql = query_listener_new (obj_updated_cb,
- obj_removed_cb,
- query_done_cb,
- eval_error_cb,
- query);
- if (!priv->ql) {
- g_message ("cal_query_construct(): Could not create the query listener");
- return NULL;
- }
+ static GType cal_query_type = 0;
- corba_ql = BONOBO_OBJREF (priv->ql);
-
- CORBA_exception_init (&ev);
- priv->corba_query = GNOME_Evolution_Calendar_Cal_getQuery (cal, sexp, corba_ql, &ev);
-
- if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_CouldNotCreate)) {
- g_message ("cal_query_construct(): The server could not create the query");
- goto error;
- } else if (BONOBO_EX (&ev)) {
- g_message ("cal_query_construct(): Could not issue the getQuery() request");
- goto error;
+ if (!cal_query_type) {
+ static GTypeInfo info = {
+ sizeof (CalQueryClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) cal_query_class_init,
+ NULL, NULL,
+ sizeof (CalQuery),
+ 0,
+ (GInstanceInitFunc) cal_query_init
+ };
+ cal_query_type = g_type_register_static (G_TYPE_OBJECT, "CalQuery", &info, 0);
}
- CORBA_exception_free (&ev);
-
- return query;
-
- error:
-
- CORBA_exception_free (&ev);
-
- bonobo_object_unref (BONOBO_OBJECT (priv->ql));
- priv->ql = NULL;
- priv->corba_query = CORBA_OBJECT_NIL;
- return NULL;
+ return cal_query_type;
}
/**
@@ -379,20 +327,12 @@ cal_query_construct (CalQuery *query,
* Return value: A newly-created query object, or NULL if the request failed.
**/
CalQuery *
-cal_query_new (CalClient *client,
- GNOME_Evolution_Calendar_Cal cal,
- const char *sexp)
+cal_query_new (GNOME_Evolution_Calendar_Query corba_query, QueryListener *listener, CalClient *client)
{
CalQuery *query;
- query = g_object_new (CAL_QUERY_TYPE, NULL);
-
- if (!cal_query_construct (query, cal, sexp)) {
- g_object_unref (G_OBJECT (query));
- return NULL;
- }
-
- query->priv->client = client;
+ query = g_object_new (CAL_QUERY_TYPE, "query", corba_query, "listener",
+ listener, "client", client, NULL);
return query;
}
@@ -412,3 +352,23 @@ cal_query_get_client (CalQuery *query)
return query->priv->client;
}
+
+void
+cal_query_start (CalQuery *query)
+{
+ CalQueryPrivate *priv;
+ CORBA_Environment ev;
+
+ g_return_if_fail (query != NULL);
+ g_return_if_fail (IS_CAL_QUERY (query));
+
+ priv = query->priv;
+
+ CORBA_exception_init (&ev);
+
+ GNOME_Evolution_Calendar_Query_start (priv->query, &ev);
+ if (BONOBO_EX (&ev))
+ g_warning (G_STRLOC ": Unable to start query");
+
+ CORBA_exception_free (&ev);
+}
diff --git a/calendar/cal-client/cal-query.h b/calendar/cal-client/cal-query.h
index 77429035fa..05390dd12a 100644
--- a/calendar/cal-client/cal-query.h
+++ b/calendar/cal-client/cal-query.h
@@ -22,7 +22,8 @@
#define CAL_QUERY_H
#include <glib-object.h>
-
+#include "cal-client-types.h"
+#include "query-listener.h"
#include "evolution-calendar.h"
G_BEGIN_DECLS
@@ -37,14 +38,6 @@ typedef struct _CalClient CalClient;
#define IS_CAL_QUERY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CAL_QUERY_TYPE))
#define IS_CAL_QUERY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CAL_QUERY_TYPE))
-#define CAL_QUERY_DONE_STATUS_ENUM_TYPE (cal_query_done_status_enum_get_type ())
-
-/* Status values when a query terminates */
-typedef enum {
- CAL_QUERY_DONE_SUCCESS,
- CAL_QUERY_DONE_PARSE_ERROR
-} CalQueryDoneStatus;
-
typedef struct _CalQueryPrivate CalQueryPrivate;
typedef struct {
@@ -58,30 +51,18 @@ typedef struct {
GObjectClass parent_class;
/* Notification signals */
-
- void (* obj_updated) (CalQuery *query, const char *uid,
- gboolean query_in_progress, int n_scanned, int total);
- void (* obj_removed) (CalQuery *query, const char *uid);
-
- void (* query_done) (CalQuery *query, CalQueryDoneStatus status, const char *error_str);
-
- void (* eval_error) (CalQuery *query, const char *error_str);
+ void (* objects_added) (CalQuery *query, GList *objects);
+ void (* objects_modified) (CalQuery *query, GList *objects);
+ void (* objects_removed) (CalQuery *query, GList *uids);
+ void (* query_progress) (CalQuery *query, char *message, int percent);
+ void (* query_done) (CalQuery *query, ECalendarStatus status);
} CalQueryClass;
GType cal_query_get_type (void);
-GType cal_query_done_status_enum_get_type (void);
-
-CalQuery *cal_query_construct (CalQuery *query,
- GNOME_Evolution_Calendar_Cal cal,
- const char *sexp);
-
-CalQuery *cal_query_new (CalClient *client,
- GNOME_Evolution_Calendar_Cal cal,
- const char *sexp);
+CalQuery *cal_query_new (GNOME_Evolution_Calendar_Query corba_query, QueryListener *listener, CalClient *client);
CalClient *cal_query_get_client (CalQuery *query);
-
-
+void cal_query_start (CalQuery *query);
G_END_DECLS
diff --git a/calendar/cal-client/client-test.c b/calendar/cal-client/client-test.c
index cb6eed17b2..48763be50a 100644
--- a/calendar/cal-client/client-test.c
+++ b/calendar/cal-client/client-test.c
@@ -45,24 +45,37 @@ cl_printf (CalClient *client, const char *format, ...)
va_end (args);
}
-/* Dumps some interesting data from a component */
static void
-dump_component (CalComponent *comp)
+objects_added_cb (GObject *object, GList *objects, gpointer data)
{
- const char *uid;
- CalComponentText summary;
+ GList *l;
+
+ for (l = objects; l; l = l->next)
+ cl_printf (data, "Object added %s\n", icalcomponent_get_uid (l->data));
+}
- cal_component_get_uid (comp, &uid);
+static void
+objects_modified_cb (GObject *object, GList *objects, gpointer data)
+{
+ GList *l;
+
+ for (l = objects; l; l = l->next)
+ cl_printf (data, "Object modified %s\n", icalcomponent_get_uid (l->data));
+}
- printf ("UID %s\n", uid);
+static void
+objects_removed_cb (GObject *object, GList *objects, gpointer data)
+{
+ GList *l;
+
+ for (l = objects; l; l = l->next)
+ cl_printf (data, "Object removed %s\n", icalcomponent_get_uid (l->data));
+}
- cal_component_get_summary (comp, &summary);
- if (summary.value)
- printf ("\tSummary: `%s', altrep `%s'\n",
- summary.value,
- summary.altrep ? summary.altrep : "NONE");
- else
- printf ("\tNo summary\n");
+static void
+query_done_cb (GObject *object, ECalendarStatus status, gpointer data)
+{
+ cl_printf (data, "Query done\n");
}
/* Lists the UIDs of objects in a calendar, called as an idle handler */
@@ -70,47 +83,38 @@ static gboolean
list_uids (gpointer data)
{
CalClient *client;
- GList *uids;
+ GList *objects = NULL;
GList *l;
-
+
client = CAL_CLIENT (data);
- uids = cal_client_get_uids (client, CALOBJ_TYPE_ANY);
-
- cl_printf (client, "UIDs: ");
+ g_message ("Blah");
+
+ if (!cal_client_get_object_list (client, "(contains? \"any\" \"Test4\")", &objects, NULL))
+ return FALSE;
+
+ cl_printf (client, "UIDS: ");
- if (!uids)
+ if (!objects)
printf ("none\n");
else {
- for (l = uids; l; l = l->next) {
- char *uid;
+ for (l = objects; l; l = l->next) {
+ const char *uid;
- uid = l->data;
+ uid = icalcomponent_get_uid (l->data);
printf ("`%s' ", uid);
}
printf ("\n");
- for (l = uids; l; l = l->next) {
- char *uid;
- CalComponent *comp;
- CalClientGetStatus status;
-
- uid = l->data;
- status = cal_client_get_object (client, uid, &comp);
-
- if (status == CAL_CLIENT_GET_SUCCESS) {
- printf ("------------------------------\n");
- dump_component (comp);
- printf ("------------------------------\n");
- g_object_unref (comp);
- } else {
- printf ("FAILED: %d\n", status);
- }
+ for (l = objects; l; l = l->next) {
+ printf ("------------------------------\n");
+ printf ("%s", icalcomponent_as_ical_string (l->data));
+ printf ("------------------------------\n");
}
}
- cal_obj_uid_list_free (uids);
+ cal_client_free_object_list (objects);
g_object_unref (client);
@@ -121,6 +125,8 @@ list_uids (gpointer data)
static void
cal_opened_cb (CalClient *client, CalClientOpenStatus status, gpointer data)
{
+ CalQuery *query;
+
cl_printf (client, "Load/create %s\n",
((status == CAL_CLIENT_OPEN_SUCCESS) ? "success" :
(status == CAL_CLIENT_OPEN_ERROR) ? "error" :
@@ -129,40 +135,29 @@ cal_opened_cb (CalClient *client, CalClientOpenStatus status, gpointer data)
"unknown status value"));
if (status == CAL_CLIENT_OPEN_SUCCESS) {
- GList *comp_list;
-
- /* get free/busy information */
- comp_list = cal_client_get_free_busy (client, NULL, 0, time (NULL));
- if (comp_list) {
- GList *l;
-
- for (l = comp_list; l; l = l->next) {
- char *comp_str;
-
- comp_str = cal_component_get_as_string (CAL_COMPONENT (l->data));
- g_object_unref (l->data);
- cl_printf (client, "Free/Busy -> %s\n", comp_str);
- g_free (comp_str);
- }
- g_list_free (comp_list);
- }
-
+ if (!cal_client_get_query (client, "(contains? \"any\" \"Test4\")", &query, NULL))
+ g_warning (G_STRLOC ": Unable to obtain query");
+
+ g_signal_connect (G_OBJECT (query), "objects_added",
+ G_CALLBACK (objects_added_cb), client);
+ g_signal_connect (G_OBJECT (query), "objects_modified",
+ G_CALLBACK (objects_modified_cb), client);
+ g_signal_connect (G_OBJECT (query), "objects_removed",
+ G_CALLBACK (objects_removed_cb), client);
+ g_signal_connect (G_OBJECT (query), "query_done",
+ G_CALLBACK (query_done_cb), client);
+
+ cal_query_start (query);
+
g_idle_add (list_uids, client);
}
else
g_object_unref (client);
}
-/* Callback used when an object is updated */
-static void
-obj_updated_cb (CalClient *client, const char *uid, gpointer data)
-{
- cl_printf (client, "Object updated: %s\n", uid);
-}
-
/* Callback used when a client is destroyed */
static void
-client_destroy_cb (GObject *object, gpointer data)
+client_destroy_cb (gpointer data, GObject *object)
{
if (CAL_CLIENT (object) == client1)
client1 = NULL;
@@ -177,33 +172,24 @@ client_destroy_cb (GObject *object, gpointer data)
/* Creates a calendar client and tries to load the specified URI into it */
static void
-create_client (CalClient **client, const char *uri, gboolean only_if_exists)
+create_client (CalClient **client, const char *uri, CalObjType type, gboolean only_if_exists)
{
- gboolean result;
-
- *client = cal_client_new ();
+ *client = cal_client_new (uri, type);
if (!*client) {
- g_message ("create_client(): could not create the client");
+ g_message (G_STRLOC ": could not create the client");
exit (1);
}
- g_signal_connect (*client, "destroy",
- G_CALLBACK (client_destroy_cb),
- NULL);
+ g_object_weak_ref (G_OBJECT (*client), client_destroy_cb, NULL);
g_signal_connect (*client, "cal_opened",
G_CALLBACK (cal_opened_cb),
NULL);
- g_signal_connect (*client, "obj_updated",
- G_CALLBACK (obj_updated_cb),
- NULL);
printf ("Calendar loading `%s'...\n", uri);
- result = cal_client_open_calendar (*client, uri, only_if_exists);
-
- if (!result) {
- g_message ("create_client(): failure when issuing calendar open request `%s'",
+ if (!cal_client_open (*client, only_if_exists, NULL)) {
+ g_message (G_STRLOC ": failure when issuing calendar open request `%s'",
uri);
exit (1);
}
@@ -212,8 +198,6 @@ create_client (CalClient **client, const char *uri, gboolean only_if_exists)
int
main (int argc, char **argv)
{
- char *dir;
-
bindtextdomain (GETTEXT_PACKAGE, EVOLUTION_LOCALEDIR);
textdomain (GETTEXT_PACKAGE);
@@ -225,10 +209,9 @@ main (int argc, char **argv)
exit (1);
}
- dir = g_strdup_printf ("%s/evolution/local/Calendar/calendar.ics", g_get_home_dir ());
- create_client (&client1, dir, FALSE);
- g_free (dir);
- create_client (&client2, "/cvs/evolution/calendar/cal-client/test.ics", TRUE);
+ create_client (&client1, "file:///home/gnome24-evolution-new-calendar/evolution/local/Calendar",
+ CALOBJ_TYPE_EVENT, FALSE);
+// create_client (&client2, "file:///tmp/tasks", TRUE);
bonobo_main ();
return 0;
diff --git a/calendar/cal-client/query-listener.c b/calendar/cal-client/query-listener.c
index 6bd7bfc6f7..4c8cbb4fe5 100644
--- a/calendar/cal-client/query-listener.c
+++ b/calendar/cal-client/query-listener.c
@@ -22,6 +22,7 @@
#include <config.h>
#endif
+#include "cal-marshal.h"
#include "query-listener.h"
@@ -29,166 +30,164 @@
/* Private part of the QueryListener structure */
struct _QueryListenerPrivate {
- /* Callbacks for notification and their closure data */
- QueryListenerObjUpdatedFn obj_updated_fn;
- QueryListenerObjRemovedFn obj_removed_fn;
- QueryListenerQueryDoneFn query_done_fn;
- QueryListenerEvalErrorFn eval_error_fn;
- gpointer fn_data;
-
- /* Whether notification is desired */
- gboolean notify : 1;
+ int dummy;
};
-
-
-static void query_listener_class_init (QueryListenerClass *class);
-static void query_listener_init (QueryListener *ql, QueryListenerClass *class);
-static void query_listener_finalize (GObject *object);
-
-static void impl_notifyObjUpdated (PortableServer_Servant servant,
- const GNOME_Evolution_Calendar_CalObjUIDSeq *uids,
- CORBA_boolean query_in_progress,
- CORBA_long n_scanned,
- CORBA_long total,
- CORBA_Environment *ev);
-
-static void impl_notifyObjRemoved (PortableServer_Servant servant,
- const CORBA_char *uid,
- CORBA_Environment *ev);
-
-static void impl_notifyQueryDone (PortableServer_Servant servant,
- GNOME_Evolution_Calendar_QueryListener_QueryDoneStatus corba_status,
- const CORBA_char *error_str,
- CORBA_Environment *ev);
+/* Signal IDs */
+enum {
+ OBJECTS_ADDED,
+ OBJECTS_MODIFIED,
+ OBJECTS_REMOVED,
+ QUERY_PROGRESS,
+ QUERY_DONE,
+ LAST_SIGNAL
+};
-static void impl_notifyEvalError (PortableServer_Servant servant,
- const CORBA_char *error_str,
- CORBA_Environment *ev);
+static guint signals[LAST_SIGNAL] = { 0 };
static BonoboObjectClass *parent_class;
-
-
-BONOBO_TYPE_FUNC_FULL (QueryListener,
- GNOME_Evolution_Calendar_QueryListener,
- BONOBO_TYPE_OBJECT,
- query_listener);
-
-/* Class initialization function for the live search query listener */
-static void
-query_listener_class_init (QueryListenerClass *class)
+/* CORBA method implementations */
+/* FIXME This is duplicated from cal-listener.c */
+static ECalendarStatus
+convert_status (const GNOME_Evolution_Calendar_CallStatus status)
{
- GObjectClass *object_class;
+ switch (status) {
+ case GNOME_Evolution_Calendar_Success:
+ return E_CALENDAR_STATUS_OK;
+ case GNOME_Evolution_Calendar_RepositoryOffline:
+ return E_CALENDAR_STATUS_REPOSITORY_OFFLINE;
+ case GNOME_Evolution_Calendar_PermissionDenied:
+ return E_CALENDAR_STATUS_PERMISSION_DENIED;
+ case GNOME_Evolution_Calendar_ObjectNotFound:
+ return E_CALENDAR_STATUS_OBJECT_NOT_FOUND;
+ case GNOME_Evolution_Calendar_CardIdAlreadyExists:
+ return E_CALENDAR_STATUS_CARD_ID_ALREADY_EXISTS;
+ case GNOME_Evolution_Calendar_AuthenticationFailed:
+ return E_CALENDAR_STATUS_AUTHENTICATION_FAILED;
+ case GNOME_Evolution_Calendar_AuthenticationRequired:
+ return E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED;
+ case GNOME_Evolution_Calendar_OtherError:
+ default:
+ return E_CALENDAR_STATUS_OTHER_ERROR;
+ }
+}
- object_class = (GObjectClass *) class;
+/* FIXME This is duplicated from cal-listener.c */
+static GList *
+build_object_list (const GNOME_Evolution_Calendar_stringlist *seq)
+{
+ GList *list;
+ int i;
+
+ list = NULL;
+ for (i = 0; i < seq->_length; i++) {
+ icalcomponent *comp;
+
+ comp = icalcomponent_new_from_string (seq->_buffer[i]);
+ if (!comp)
+ continue;
+
+ list = g_list_prepend (list, comp);
+ }
+
+ return list;
+}
- parent_class = g_type_class_peek_parent (class);
+static GList *
+build_uid_list (const GNOME_Evolution_Calendar_CalObjUIDSeq *seq)
+{
+ GList *list;
+ int i;
- object_class->finalize = query_listener_finalize;
+ list = NULL;
+ for (i = 0; i < seq->_length; i++)
+ list = g_list_prepend (list, g_strdup (seq->_buffer[i]));
- class->epv.notifyObjUpdated = impl_notifyObjUpdated;
- class->epv.notifyObjRemoved = impl_notifyObjRemoved;
- class->epv.notifyQueryDone = impl_notifyQueryDone;
- class->epv.notifyEvalError = impl_notifyEvalError;
+ return list;
}
-/* Object initialization function for the live search query listener */
static void
-query_listener_init (QueryListener *ql, QueryListenerClass *class)
+impl_notifyObjectsAdded (PortableServer_Servant servant,
+ const GNOME_Evolution_Calendar_stringlist *objects,
+ CORBA_Environment *ev)
{
+ QueryListener *ql;
QueryListenerPrivate *priv;
+ GList *object_list, *l;
+
+ ql = QUERY_LISTENER (bonobo_object_from_servant (servant));
+ priv = ql->priv;
- priv = g_new0 (QueryListenerPrivate, 1);
- ql->priv = priv;
-
- priv->obj_updated_fn = NULL;
- priv->obj_removed_fn = NULL;
- priv->query_done_fn = NULL;
- priv->eval_error_fn = NULL;
- priv->fn_data = NULL;
+ object_list = build_object_list (objects);
+
+ g_signal_emit (G_OBJECT (ql), signals[OBJECTS_ADDED], 0, object_list);
- priv->notify = TRUE;
+ for (l = object_list; l; l = l->next)
+ icalcomponent_free (l->data);
+ g_list_free (object_list);
}
-/* Finalize handler for the live search query listener */
static void
-query_listener_finalize (GObject *object)
+impl_notifyObjectsModified (PortableServer_Servant servant,
+ const GNOME_Evolution_Calendar_stringlist *objects,
+ CORBA_Environment *ev)
{
QueryListener *ql;
QueryListenerPrivate *priv;
-
- g_return_if_fail (object != NULL);
- g_return_if_fail (IS_QUERY_LISTENER (object));
-
- ql = QUERY_LISTENER (object);
+ GList *object_list, *l;
+
+ ql = QUERY_LISTENER (bonobo_object_from_servant (servant));
priv = ql->priv;
- priv->obj_updated_fn = NULL;
- priv->obj_removed_fn = NULL;
- priv->query_done_fn = NULL;
- priv->eval_error_fn = NULL;
- priv->fn_data = NULL;
-
- priv->notify = FALSE;
+ object_list = build_object_list (objects);
+
+ g_signal_emit (G_OBJECT (ql), signals[OBJECTS_MODIFIED], 0, object_list);
- g_free (priv);
- ql->priv = NULL;
-
- if (G_OBJECT_CLASS (parent_class)->finalize)
- (* G_OBJECT_CLASS (parent_class)->finalize) (object);
+ for (l = object_list; l; l = l->next)
+ icalcomponent_free (l->data);
+ g_list_free (object_list);
}
-
-
-/* CORBA method implementations */
-
-/* ::notifyObjUpdated() method */
static void
-impl_notifyObjUpdated (PortableServer_Servant servant,
- const GNOME_Evolution_Calendar_CalObjUIDSeq *uids,
- CORBA_boolean query_in_progress,
- CORBA_long n_scanned,
- CORBA_long total,
- CORBA_Environment *ev)
+impl_notifyObjectsRemoved (PortableServer_Servant servant,
+ const GNOME_Evolution_Calendar_CalObjUIDSeq *uids,
+ CORBA_Environment *ev)
{
QueryListener *ql;
QueryListenerPrivate *priv;
-
+ GList *uid_list, *l;
+
ql = QUERY_LISTENER (bonobo_object_from_servant (servant));
priv = ql->priv;
- if (!priv->notify)
- return;
+ uid_list = build_uid_list (uids);
+
+ g_signal_emit (G_OBJECT (ql), signals[OBJECTS_REMOVED], 0, uid_list);
- g_assert (priv->obj_updated_fn != NULL);
- (* priv->obj_updated_fn) (ql, uids, query_in_progress, n_scanned, total, priv->fn_data);
+ for (l = uid_list; l; l = l->next)
+ g_free (l->data);
+ g_list_free (uid_list);
}
-/* ::notifyObjRemoved() method */
static void
-impl_notifyObjRemoved (PortableServer_Servant servant,
- const CORBA_char *uid,
- CORBA_Environment *ev)
+impl_notifyQueryProgress (PortableServer_Servant servant,
+ const CORBA_char *message,
+ const CORBA_short percent,
+ CORBA_Environment *ev)
{
QueryListener *ql;
QueryListenerPrivate *priv;
ql = QUERY_LISTENER (bonobo_object_from_servant (servant));
priv = ql->priv;
-
- if (!priv->notify)
- return;
-
- g_assert (priv->obj_removed_fn != NULL);
- (* priv->obj_removed_fn) (ql, uid, priv->fn_data);
+
+ g_signal_emit (G_OBJECT (ql), signals[QUERY_PROGRESS], 0, message, percent);
}
-/* ::notifyQueryDone() method */
static void
impl_notifyQueryDone (PortableServer_Servant servant,
- GNOME_Evolution_Calendar_QueryListener_QueryDoneStatus corba_status,
- const CORBA_char *error_str,
+ const GNOME_Evolution_Calendar_CallStatus status,
CORBA_Environment *ev)
{
QueryListener *ql;
@@ -196,126 +195,110 @@ impl_notifyQueryDone (PortableServer_Servant servant,
ql = QUERY_LISTENER (bonobo_object_from_servant (servant));
priv = ql->priv;
+
+ g_signal_emit (G_OBJECT (ql), signals[QUERY_DONE], 0, convert_status (status));
+}
- if (!priv->notify)
- return;
+/* Object initialization function for the live search query listener */
+static void
+query_listener_init (QueryListener *ql, QueryListenerClass *class)
+{
+ QueryListenerPrivate *priv;
- g_assert (priv->query_done_fn != NULL);
- (* priv->query_done_fn) (ql, corba_status, error_str, priv->fn_data);
+ priv = g_new0 (QueryListenerPrivate, 1);
+ ql->priv = priv;
}
-/* ::notifyEvalError() method */
+/* Finalize handler for the live search query listener */
static void
-impl_notifyEvalError (PortableServer_Servant servant,
- const CORBA_char *error_str,
- CORBA_Environment *ev)
+query_listener_finalize (GObject *object)
{
QueryListener *ql;
QueryListenerPrivate *priv;
- ql = QUERY_LISTENER (bonobo_object_from_servant (servant));
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (IS_QUERY_LISTENER (object));
+
+ ql = QUERY_LISTENER (object);
priv = ql->priv;
- if (!priv->notify)
- return;
+ g_free (priv);
- g_assert (priv->eval_error_fn != NULL);
- (* priv->eval_error_fn) (ql, error_str, priv->fn_data);
+ if (G_OBJECT_CLASS (parent_class)->finalize)
+ (* G_OBJECT_CLASS (parent_class)->finalize) (object);
}
-
-
-/**
- * query_listener_construct:
- * @ql: A query listener.
- * @obj_updated_fn: Callback to use when a component is updated in the query.
- * @obj_removed_fn: Callback to use when a component is removed from the query.
- * @query_done_fn: Callback to use when a query is done.
- * @eval_error_fn: Callback to use when an evaluation error happens during a query.
- * @fn_data: Closure data to pass to the callbacks.
- *
- * Constructs a query listener by setting the callbacks it will use for
- * notification from the calendar server.
- *
- * Return value: The same value as @ql.
- **/
-QueryListener *
-query_listener_construct (QueryListener *ql,
- QueryListenerObjUpdatedFn obj_updated_fn,
- QueryListenerObjRemovedFn obj_removed_fn,
- QueryListenerQueryDoneFn query_done_fn,
- QueryListenerEvalErrorFn eval_error_fn,
- gpointer fn_data)
+/* Class initialization function for the live search query listener */
+static void
+query_listener_class_init (QueryListenerClass *klass)
{
- QueryListenerPrivate *priv;
+ GObjectClass *object_class;
- g_return_val_if_fail (ql != NULL, NULL);
- g_return_val_if_fail (IS_QUERY_LISTENER (ql), NULL);
- g_return_val_if_fail (obj_updated_fn != NULL, NULL);
- g_return_val_if_fail (obj_removed_fn != NULL, NULL);
- g_return_val_if_fail (query_done_fn != NULL, NULL);
- g_return_val_if_fail (eval_error_fn != NULL, NULL);
+ object_class = (GObjectClass *) klass;
- priv = ql->priv;
+ parent_class = g_type_class_peek_parent (klass);
- priv->obj_updated_fn = obj_updated_fn;
- priv->obj_removed_fn = obj_removed_fn;
- priv->query_done_fn = query_done_fn;
- priv->eval_error_fn = eval_error_fn;
- priv->fn_data = fn_data;
+ object_class->finalize = query_listener_finalize;
- return ql;
+ klass->epv.notifyObjectsAdded = impl_notifyObjectsAdded;
+ klass->epv.notifyObjectsModified = impl_notifyObjectsModified;
+ klass->epv.notifyObjectsRemoved = impl_notifyObjectsRemoved;
+ klass->epv.notifyQueryProgress = impl_notifyQueryProgress;
+ klass->epv.notifyQueryDone = impl_notifyQueryDone;
+
+ signals[OBJECTS_ADDED] =
+ g_signal_new ("objects_added",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (QueryListenerClass, objects_added),
+ NULL, NULL,
+ cal_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
+ signals[OBJECTS_MODIFIED] =
+ g_signal_new ("objects_modified",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (QueryListenerClass, objects_modified),
+ NULL, NULL,
+ cal_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
+ signals[OBJECTS_REMOVED] =
+ g_signal_new ("objects_removed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (QueryListenerClass, objects_removed),
+ NULL, NULL,
+ cal_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
+ signals[QUERY_PROGRESS] =
+ g_signal_new ("query_progress",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (QueryListenerClass, query_progress),
+ NULL, NULL,
+ cal_marshal_VOID__POINTER,
+ G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_INT);
+ signals[QUERY_DONE] =
+ g_signal_new ("query_done",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (QueryListenerClass, query_done),
+ NULL, NULL,
+ cal_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
}
-/**
- * query_listener_new:
- * @obj_updated_fn: Callback to use when a component is updated in the query.
- * @obj_removed_fn: Callback to use when a component is removed from the query.
- * @query_done_fn: Callback to use when a query is done.
- * @eval_error_fn: Callback to use when an evaluation error happens during a query.
- * @fn_data: Closure data to pass to the callbacks.
- *
- * Creates a new query listener object.
- *
- * Return value: A newly-created query listener object.
- **/
+BONOBO_TYPE_FUNC_FULL (QueryListener,
+ GNOME_Evolution_Calendar_QueryListener,
+ BONOBO_TYPE_OBJECT,
+ query_listener);
+
QueryListener *
-query_listener_new (QueryListenerObjUpdatedFn obj_updated_fn,
- QueryListenerObjRemovedFn obj_removed_fn,
- QueryListenerQueryDoneFn query_done_fn,
- QueryListenerEvalErrorFn eval_error_fn,
- gpointer fn_data)
+query_listener_new (void)
{
QueryListener *ql;
ql = g_object_new (QUERY_LISTENER_TYPE, NULL);
- return query_listener_construct (ql,
- obj_updated_fn,
- obj_removed_fn,
- query_done_fn,
- eval_error_fn,
- fn_data);
-}
-
-/**
- * query_listener_stop_notification:
- * @ql: A query listener.
- *
- * Informs a query listener that no further notification is desired. The
- * callbacks specified when the listener was created will no longer be invoked
- * after this function is called.
- **/
-void
-query_listener_stop_notification (QueryListener *ql)
-{
- QueryListenerPrivate *priv;
-
- g_return_if_fail (ql != NULL);
- g_return_if_fail (IS_QUERY_LISTENER (ql));
-
- priv = ql->priv;
- g_return_if_fail (priv->notify != FALSE);
-
- priv->notify = FALSE;
+ return ql;
}
diff --git a/calendar/cal-client/query-listener.h b/calendar/cal-client/query-listener.h
index eeb42afc7e..6a204bbf77 100644
--- a/calendar/cal-client/query-listener.h
+++ b/calendar/cal-client/query-listener.h
@@ -22,6 +22,7 @@
#define QUERY_LISTENER_H
#include <bonobo/bonobo-object.h>
+#include "cal-client-types.h"
#include "evolution-calendar.h"
G_BEGIN_DECLS
@@ -48,47 +49,18 @@ typedef struct {
BonoboObjectClass parent_class;
POA_GNOME_Evolution_Calendar_QueryListener__epv epv;
+
+ void (*objects_added) (QueryListener *listener, GList *objects);
+ void (*objects_modified) (QueryListener *listener, GList *objects);
+ void (*objects_removed) (QueryListener *listener, GList *uids);
+ void (*query_progress) (QueryListener *listener, const char *message, int percent);
+ void (*query_done) (QueryListener *listener, ECalendarStatus status);
} QueryListenerClass;
/* Notification functions */
-typedef void (* QueryListenerObjUpdatedFn) (QueryListener *ql,
- const GNOME_Evolution_Calendar_CalObjUIDSeq *uids,
- CORBA_boolean query_in_progress,
- CORBA_long n_scanned,
- CORBA_long total,
- gpointer data);
-
-typedef void (* QueryListenerObjRemovedFn) (QueryListener *ql,
- const CORBA_char *uid,
- gpointer data);
-
-typedef void (* QueryListenerQueryDoneFn) (
- QueryListener *ql,
- GNOME_Evolution_Calendar_QueryListener_QueryDoneStatus status,
- const CORBA_char *error_str,
- gpointer data);
-
-typedef void (* QueryListenerEvalErrorFn) (QueryListener *ql,
- const CORBA_char *error_str,
- gpointer data);
-
GType query_listener_get_type (void);
-
-QueryListener *query_listener_construct (QueryListener *ql,
- QueryListenerObjUpdatedFn obj_updated_fn,
- QueryListenerObjRemovedFn obj_removed_fn,
- QueryListenerQueryDoneFn query_done_fn,
- QueryListenerEvalErrorFn eval_error_fn,
- gpointer fn_data);
-
-QueryListener *query_listener_new (QueryListenerObjUpdatedFn obj_updated_fn,
- QueryListenerObjRemovedFn obj_removed_fn,
- QueryListenerQueryDoneFn query_done_fn,
- QueryListenerEvalErrorFn eval_error_fn,
- gpointer fn_data);
-
-void query_listener_stop_notification (QueryListener *ql);
+QueryListener *query_listener_new (void);