~ubuntu-branches/ubuntu/maverick/evolution-data-server/maverick-proposed

« back to all changes in this revision

Viewing changes to calendar/libecal/e-cal.c

  • Committer: Bazaar Package Importer
  • Author(s): Didier Roche
  • Date: 2010-05-17 17:02:06 UTC
  • mfrom: (1.1.79 upstream) (1.6.12 experimental)
  • Revision ID: james.westby@ubuntu.com-20100517170206-4ufr52vwrhh26yh0
Tags: 2.30.1-1ubuntu1
* Merge from debian experimental. Remaining change:
  (LP: #42199, #229669, #173703, #360344, #508494)
  + debian/control:
    - add Vcs-Bzr tag
    - don't use libgnome
    - Use Breaks instead of Conflicts against evolution 2.25 and earlier.
  + debian/evolution-data-server.install,
    debian/patches/45_libcamel_providers_version.patch:
    - use the upstream versioning, not a Debian-specific one 
  + debian/libedata-book1.2-dev.install, debian/libebackend-1.2-dev.install,
    debian/libcamel1.2-dev.install, debian/libedataserverui1.2-dev.install:
    - install html documentation
  + debian/rules:
    - don't build documentation it's shipped with the tarball

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
/* Evolution calendar ecal
3
3
 *
4
4
 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
 
5
 * Copyright (C) 2009 Intel Corporation
5
6
 *
6
7
 * Authors: Federico Mena-Quintero <federico@ximian.com>
7
8
 *          Rodrigo Moya <rodrigo@novell.com>
 
9
 *          Ross Burton <ross@linux.intel.com>
8
10
 *
9
11
 * This program is free software; you can redistribute it and/or
10
12
 * modify it under the terms of version 2 of the GNU Lesser General Public
24
26
#include <config.h>
25
27
#endif
26
28
 
 
29
#include <unistd.h>
27
30
#include <pthread.h>
28
31
#include <string.h>
29
32
#include <glib/gi18n-lib.h>
30
 
#include <bonobo-activation/bonobo-activation.h>
31
 
#include <bonobo/bonobo-exception.h>
32
 
#include <bonobo/bonobo-main.h>
33
 
 
34
 
#include "libecal/e-cal-check-timezones.h"
35
 
#include "libedataserver/e-component-listener.h"
36
 
#include "libedataserver/e-flag.h"
37
 
#include "libedataserver/e-url.h"
 
33
 
 
34
#include <libical/ical.h>
 
35
#include <libedataserver/e-url.h>
 
36
 
 
37
#include <dbus/dbus-glib-lowlevel.h>
 
38
#include <dbus/dbus.h>
 
39
#include <dbus/dbus-glib.h>
 
40
#include <glib-object.h>
 
41
 
 
42
#include "e-cal-check-timezones.h"
38
43
#include "e-cal-marshal.h"
39
44
#include "e-cal-time-util.h"
40
 
#include "e-cal-listener.h"
41
 
#include "e-cal-view-listener.h"
42
45
#include "e-cal-view-private.h"
43
46
#include "e-cal.h"
44
 
 
45
 
static gboolean
46
 
open_calendar (ECal *ecal, gboolean only_if_exists, GError **error, ECalendarStatus *status, gboolean needs_auth);
47
 
 
48
 
static gboolean
49
 
get_read_only (ECal *ecal, gboolean *read_only, GError **error);
50
 
 
51
 
 
52
 
typedef struct {
53
 
        EFlag *done;
54
 
        ECalendarStatus status;
55
 
 
56
 
        gchar *uid;
57
 
        GList *list;
58
 
        GSList *slist;
59
 
        gboolean bool;
60
 
        gchar *string;
61
 
 
62
 
        gchar *op_str;
63
 
        ECalView *query;
64
 
        ECalViewListener *listener;
65
 
} ECalendarOp;
 
47
#include "e-data-cal-factory-bindings.h"
 
48
#include "e-data-cal-bindings.h"
 
49
#include <libedata-cal/e-data-cal-types.h>
 
50
 
 
51
static DBusGConnection *connection = NULL;
 
52
static DBusGProxy *factory_proxy = NULL;
 
53
 
 
54
/* guards both connection and factory_proxy */
 
55
static GStaticRecMutex connection_lock = G_STATIC_REC_MUTEX_INIT;
 
56
#define LOCK_CONN()   g_static_rec_mutex_lock (&connection_lock)
 
57
#define UNLOCK_CONN() g_static_rec_mutex_unlock (&connection_lock)
 
58
 
 
59
G_DEFINE_TYPE(ECal, e_cal, G_TYPE_OBJECT)
 
60
#define E_CAL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), E_TYPE_CAL, ECalPrivate))
 
61
 
 
62
static gboolean open_calendar (ECal *ecal, gboolean only_if_exists, GError **error, ECalendarStatus *status, gboolean needs_auth, gboolean async);
 
63
static void e_cal_dispose (GObject *object);
 
64
static void e_cal_finalize (GObject *object);
66
65
 
67
66
/* Private part of the ECal structure */
68
67
struct _ECalPrivate {
76
75
        gchar *uri;
77
76
        ECalSourceType type;
78
77
 
79
 
        ECalendarOp *current_op;
80
 
 
81
 
        GMutex *mutex;
82
 
 
83
78
        /* Email address associated with this calendar, or NULL */
84
79
        gchar *cal_address;
85
80
        gchar *alarm_email_address;
92
87
 
93
88
        gboolean read_only;
94
89
 
95
 
        /* The calendar factories we are contacting */
96
 
        GList *factories;
97
 
 
98
 
        /* Our calendar listener implementation */
99
 
        ECalListener *listener;
100
 
 
101
 
        /* The calendar ecal interface object we are contacting */
102
 
        GNOME_Evolution_Calendar_Cal cal;
 
90
        DBusGProxy *proxy;
103
91
 
104
92
        /* The authentication function */
105
93
        ECalAuthFunc auth_func;
113
101
           values. */
114
102
        icaltimezone *default_zone;
115
103
 
116
 
        /* The component listener to keep track of the lifetime of backends */
117
 
        EComponentListener *comp_listener;
118
 
 
119
104
        gchar *local_attachment_store;
120
105
};
121
106
 
172
157
       };                               }G_STMT_END
173
158
#endif
174
159
 
175
 
#define E_CALENDAR_CHECK_STATUS(status,error) G_STMT_START{             \
176
 
        if ((status) == E_CALENDAR_STATUS_OK) {                         \
 
160
#define E_CALENDAR_CHECK_STATUS(status,error)                           \
 
161
G_STMT_START{                                                           \
 
162
        if ((status) == E_CALENDAR_STATUS_OK)                           \
177
163
                return TRUE;                                            \
178
 
        }                                                               \
179
 
        else {                                                          \
180
 
                const gchar *msg;                                        \
181
 
                msg = e_cal_get_error_message ((status));          \
 
164
        else {                                                          \
 
165
                const gchar *msg;                                       \
 
166
                if (error && *error)                                    \
 
167
                        return unwrap_gerror (error);                   \
 
168
                msg = e_cal_get_error_message ((status));               \
182
169
                g_set_error ((error), E_CALENDAR_ERROR, (status), "%s", msg);   \
183
170
                return FALSE;                                           \
184
 
        }                               }G_STMT_END
 
171
        }                                                               \
 
172
} G_STMT_END
185
173
 
186
174
 
187
175
 
197
185
}
198
186
 
199
187
/**
 
188
 * If the GError is a remote error, extract the EBookStatus embedded inside.
 
189
 * Otherwise return CORBA_EXCEPTION (I know this is DBus...).
 
190
 */
 
191
static ECalendarStatus
 
192
get_status_from_error (GError *error)
 
193
{
 
194
        #define err(a,b) "org.gnome.evolution.dataserver.calendar.Cal." a, b
 
195
        static struct {
 
196
                const gchar *name;
 
197
                ECalendarStatus err_code;
 
198
        } errors[] = {
 
199
                { err ("Success",                               E_CALENDAR_STATUS_OK) },
 
200
                { err ("RepositoryOffline",                     E_CALENDAR_STATUS_REPOSITORY_OFFLINE) },
 
201
                { err ("PermissionDenied",                      E_CALENDAR_STATUS_PERMISSION_DENIED) },
 
202
                { err ("InvalidRange",                          E_CALENDAR_STATUS_OTHER_ERROR) },
 
203
                { err ("ObjectNotFound",                        E_CALENDAR_STATUS_OBJECT_NOT_FOUND) },
 
204
                { err ("InvalidObject",                         E_CALENDAR_STATUS_INVALID_OBJECT) },
 
205
                { err ("ObjectIdAlreadyExists",                 E_CALENDAR_STATUS_OBJECT_ID_ALREADY_EXISTS) },
 
206
                { err ("AuthenticationFailed",                  E_CALENDAR_STATUS_AUTHENTICATION_FAILED) },
 
207
                { err ("AuthenticationRequired",                E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED) },
 
208
                { err ("UnsupportedField",                      E_CALENDAR_STATUS_OTHER_ERROR) },
 
209
                { err ("UnsupportedMethod",                     E_CALENDAR_STATUS_OTHER_ERROR) },
 
210
                { err ("UnsupportedAuthenticationMethod",       E_CALENDAR_STATUS_OTHER_ERROR) },
 
211
                { err ("TLSNotAvailable",                       E_CALENDAR_STATUS_OTHER_ERROR) },
 
212
                { err ("NoSuchCal",                             E_CALENDAR_STATUS_NO_SUCH_CALENDAR) },
 
213
                { err ("UnknownUser",                           E_CALENDAR_STATUS_UNKNOWN_USER) },
 
214
                { err ("OfflineUnavailable",                    E_CALENDAR_STATUS_OTHER_ERROR) },
 
215
                { err ("SearchSizeLimitExceeded",               E_CALENDAR_STATUS_OTHER_ERROR) },
 
216
                { err ("SearchTimeLimitExceeded",               E_CALENDAR_STATUS_OTHER_ERROR) },
 
217
                { err ("InvalidQuery",                          E_CALENDAR_STATUS_OTHER_ERROR) },
 
218
                { err ("QueryRefused",                          E_CALENDAR_STATUS_OTHER_ERROR) },
 
219
                { err ("CouldNotCancel",                        E_CALENDAR_STATUS_COULD_NOT_CANCEL) },
 
220
                { err ("OtherError",                            E_CALENDAR_STATUS_OTHER_ERROR) },
 
221
                { err ("InvalidServerVersion",                  E_CALENDAR_STATUS_INVALID_SERVER_VERSION) }
 
222
        };
 
223
        #undef err
 
224
 
 
225
        if G_LIKELY (error == NULL)
 
226
                return Success;
 
227
 
 
228
        if (error->domain == DBUS_GERROR && error->code == DBUS_GERROR_REMOTE_EXCEPTION) {
 
229
                const gchar *name;
 
230
                gint i;
 
231
 
 
232
                name = dbus_g_error_get_name (error);
 
233
                for (i = 0; i < G_N_ELEMENTS (errors); i++) {
 
234
                        if (g_ascii_strcasecmp (errors[i].name, name) == 0)
 
235
                                return errors[i].err_code;
 
236
                }
 
237
 
 
238
                g_warning ("Unmatched error name %s", name);
 
239
                return E_CALENDAR_STATUS_OTHER_ERROR;
 
240
        } else if (error->domain == E_CALENDAR_ERROR) {
 
241
                return error->code;
 
242
        } else {
 
243
                /* In this case the error was caused by DBus */
 
244
                return E_CALENDAR_STATUS_CORBA_EXCEPTION;
 
245
        }
 
246
}
 
247
 
 
248
/**
 
249
 * If the specified GError is a remote error, then create a new error
 
250
 * representing the remote error.  If the error is anything else, then leave it
 
251
 * alone.
 
252
 */
 
253
static gboolean
 
254
unwrap_gerror(GError **error)
 
255
{
 
256
        if (*error == NULL)
 
257
                return TRUE;
 
258
        if ((*error)->domain == DBUS_GERROR && (*error)->code == DBUS_GERROR_REMOTE_EXCEPTION) {
 
259
                GError *new_error = NULL;
 
260
                gint code;
 
261
                code = get_status_from_error (*error);
 
262
                new_error = g_error_new_literal (E_CALENDAR_ERROR, code, (*error)->message);
 
263
                g_error_free (*error);
 
264
                *error = new_error;
 
265
        }
 
266
        return FALSE;
 
267
}
 
268
 
 
269
/**
200
270
 * e_cal_source_type_enum_get_type:
201
271
 *
202
272
 * Registers the #ECalSourceTypeEnum type with glib.
203
273
 *
204
 
 * Return value: the ID of the #ECalSourceTypeEnum type.
 
274
 * Returns: the ID of the #ECalSourceTypeEnum type.
205
275
 */
206
276
GType
207
277
e_cal_source_type_enum_get_type (void)
208
278
{
209
 
        static GType e_cal_source_type_enum_type = 0;
 
279
        static volatile gsize enum_type__volatile = 0;
210
280
 
211
 
        if (!e_cal_source_type_enum_type) {
 
281
        if (g_once_init_enter (&enum_type__volatile)) {
 
282
                GType enum_type;
212
283
                static GEnumValue values [] = {
213
284
                        { E_CAL_SOURCE_TYPE_EVENT, "Event", NULL},
214
285
                        { E_CAL_SOURCE_TYPE_TODO, "ToDo", NULL},
217
288
                        { -1, NULL, NULL}
218
289
                };
219
290
 
220
 
                e_cal_source_type_enum_type =
221
 
                        g_enum_register_static ("ECalSourceTypeEnum", values);
 
291
                enum_type = g_enum_register_static ("ECalSourceTypeEnum", values);
 
292
                g_once_init_leave (&enum_type__volatile, enum_type);
222
293
        }
223
294
 
224
 
        return e_cal_source_type_enum_type;
 
295
        return enum_type__volatile;
225
296
}
226
297
 
227
298
/**
229
300
 *
230
301
 * Registers the #ECalSetModeStatusEnum type with glib.
231
302
 *
232
 
 * Return value: the ID of the #ECalSetModeStatusEnum type.
 
303
 * Returns: the ID of the #ECalSetModeStatusEnum type.
233
304
 */
234
305
GType
235
306
e_cal_set_mode_status_enum_get_type (void)
236
307
{
237
 
        static GType e_cal_set_mode_status_enum_type = 0;
 
308
        static volatile gsize enum_type__volatile = 0;
238
309
 
239
 
        if (!e_cal_set_mode_status_enum_type) {
 
310
        if (g_once_init_enter (&enum_type__volatile)) {
 
311
                GType enum_type;
240
312
                static GEnumValue values [] = {
241
313
                        { E_CAL_SET_MODE_SUCCESS,          "ECalSetModeSuccess",         "success"     },
242
314
                        { E_CAL_SET_MODE_ERROR,            "ECalSetModeError",           "error"       },
243
315
                        { E_CAL_SET_MODE_NOT_SUPPORTED,    "ECalSetModeNotSupported",    "unsupported" },
244
 
                        { -1,                                   NULL,                              NULL          }
 
316
                        { -1,                                   NULL,                              NULL}
245
317
                };
246
318
 
247
 
                e_cal_set_mode_status_enum_type =
248
 
                        g_enum_register_static ("ECalSetModeStatusEnum", values);
 
319
                enum_type = g_enum_register_static ("ECalSetModeStatusEnum", values);
 
320
                g_once_init_leave (&enum_type__volatile, enum_type);
249
321
        }
250
322
 
251
 
        return e_cal_set_mode_status_enum_type;
 
323
        return enum_type__volatile;
252
324
}
253
325
 
254
326
/**
256
328
 *
257
329
 * Registers the #CalModeEnum type with glib.
258
330
 *
259
 
 * Return value: the ID of the #CalModeEnum type.
 
331
 * Returns: the ID of the #CalModeEnum type.
260
332
 */
261
333
GType
262
334
cal_mode_enum_get_type (void)
263
335
{
264
 
        static GType cal_mode_enum_type = 0;
 
336
        static volatile gsize enum_type__volatile = 0;
265
337
 
266
 
        if (!cal_mode_enum_type) {
 
338
        if (g_once_init_enter (&enum_type__volatile)) {
 
339
                GType enum_type;
267
340
                static GEnumValue values [] = {
268
341
                        { CAL_MODE_INVALID,                     "CalModeInvalid",                  "invalid" },
269
342
                        { CAL_MODE_LOCAL,                       "CalModeLocal",                    "local"   },
272
345
                        { -1,                                   NULL,                              NULL      }
273
346
                };
274
347
 
275
 
                cal_mode_enum_type = g_enum_register_static ("CalModeEnum", values);
 
348
                enum_type = g_enum_register_static ("CalModeEnum", values);
 
349
                g_once_init_leave (&enum_type__volatile, enum_type);
276
350
        }
277
351
 
278
 
        return cal_mode_enum_type;
 
352
        return enum_type__volatile;
279
353
}
280
354
 
281
 
static GNOME_Evolution_Calendar_CalObjType
 
355
static EDataCalObjType
282
356
convert_type (ECalSourceType type)
283
357
{
284
358
        switch (type) {
285
359
        case E_CAL_SOURCE_TYPE_EVENT:
286
 
                return GNOME_Evolution_Calendar_TYPE_EVENT;
 
360
                return Event;
287
361
        case E_CAL_SOURCE_TYPE_TODO:
288
 
                return GNOME_Evolution_Calendar_TYPE_TODO;
 
362
                return Todo;
289
363
        case E_CAL_SOURCE_TYPE_JOURNAL:
290
 
                return GNOME_Evolution_Calendar_TYPE_JOURNAL;
291
 
        default:
292
 
                return GNOME_Evolution_Calendar_TYPE_ANY;
293
 
        }
294
 
 
295
 
        return GNOME_Evolution_Calendar_TYPE_ANY;
296
 
}
297
 
 
298
 
/* EBookOp calls */
299
 
 
300
 
static ECalendarOp*
301
 
e_calendar_new_op (ECal *ecal, const gchar *str)
302
 
{
303
 
        ECalendarOp *op = g_new0 (ECalendarOp, 1);
304
 
 
305
 
        op->done = e_flag_new ();
306
 
 
307
 
        ecal->priv->current_op = op;
308
 
        op->op_str = g_strdup (str);
309
 
 
310
 
        return op;
311
 
}
312
 
 
313
 
static ECalendarOp*
314
 
e_calendar_get_op (ECal *ecal)
315
 
{
316
 
        if (!ecal->priv->current_op) {
317
 
                g_warning ("%s", G_STRLOC ": Unexpected response");
318
 
                return NULL;
319
 
        }
320
 
 
321
 
        return ecal->priv->current_op;
322
 
}
323
 
 
324
 
static void
325
 
e_calendar_free_op (ECalendarOp *op)
326
 
{
327
 
        /* XXX more stuff here */
328
 
        e_flag_free (op->done);
329
 
        g_free (op->op_str);
330
 
        g_free (op);
331
 
}
332
 
 
333
 
static void
334
 
e_calendar_remove_op (ECal *ecal, ECalendarOp *op)
335
 
{
336
 
        if (ecal->priv->current_op != op)
337
 
                g_warning ("%s", G_STRLOC ": Cannot remove op, it's not current");
338
 
 
339
 
        ecal->priv->current_op = NULL;
340
 
}
341
 
 
342
 
/* Gets rid of the factories that a ecal knows about */
343
 
static void
344
 
destroy_factories (ECal *ecal)
345
 
{
346
 
        ECalPrivate *priv;
347
 
        CORBA_Object factory;
348
 
        CORBA_Environment ev;
349
 
        gint result;
350
 
        GList *f;
351
 
 
352
 
        priv = ecal->priv;
353
 
 
354
 
        CORBA_exception_init (&ev);
355
 
 
356
 
        for (f = priv->factories; f; f = f->next) {
357
 
                factory = f->data;
358
 
 
359
 
                result = CORBA_Object_is_nil (factory, &ev);
360
 
                if (BONOBO_EX (&ev)) {
361
 
                        g_message ("%s", G_STRLOC ": could not see if a factory was nil");
362
 
                        CORBA_exception_free (&ev);
363
 
 
364
 
                        continue;
365
 
                }
366
 
 
367
 
                if (result)
368
 
                        continue;
369
 
 
370
 
                CORBA_Object_release (factory, &ev);
371
 
                if (BONOBO_EX (&ev)) {
372
 
                        g_message ("%s", G_STRLOC ": could not release a factory");
373
 
                        CORBA_exception_free (&ev);
374
 
                }
375
 
        }
376
 
 
377
 
        g_list_free (priv->factories);
378
 
        priv->factories = NULL;
379
 
}
380
 
 
381
 
/* Gets rid of the calendar ecal interface object that a ecal knows about */
382
 
static void
383
 
destroy_cal (ECal *ecal)
384
 
{
385
 
        ECalPrivate *priv;
386
 
        CORBA_Environment ev;
387
 
        gint result;
388
 
 
389
 
        priv = ecal->priv;
390
 
 
391
 
        CORBA_exception_init (&ev);
392
 
        result = CORBA_Object_is_nil (priv->cal, &ev);
393
 
        if (BONOBO_EX (&ev)) {
394
 
                g_message ("%s", G_STRLOC ": could not see if the "
395
 
                           "calendar ecal interface object was nil");
396
 
                priv->cal = CORBA_OBJECT_NIL;
397
 
                CORBA_exception_free (&ev);
398
 
                return;
399
 
        }
400
 
        CORBA_exception_free (&ev);
401
 
 
402
 
        if (result)
403
 
                return;
404
 
 
405
 
        bonobo_object_release_unref (priv->cal, NULL);
406
 
        priv->cal = CORBA_OBJECT_NIL;
407
 
 
408
 
}
409
 
 
410
 
static void
411
 
free_timezone (gpointer key, gpointer value, gpointer data)
412
 
{
413
 
        /* Note that the key comes from within the icaltimezone value, so we
414
 
           don't free that. */
415
 
        icaltimezone_free (value, TRUE);
416
 
}
417
 
 
418
 
 
419
 
 
420
 
static void
421
 
backend_died_cb (EComponentListener *cl, gpointer user_data)
422
 
{
423
 
        ECalPrivate *priv;
424
 
        ECal *ecal = (ECal *) user_data;
425
 
 
426
 
        priv = ecal->priv;
427
 
        priv->load_state = E_CAL_LOAD_NOT_LOADED;
428
 
        g_signal_emit (G_OBJECT (ecal), e_cal_signals[BACKEND_DIED], 0);
429
 
}
430
 
 
431
 
/* Signal handlers for the listener's signals */
432
 
/* Handle the cal_opened notification from the listener */
433
 
 
434
 
static void
435
 
cal_read_only_cb (ECalListener *listener, ECalendarStatus status, gboolean read_only, gpointer data)
436
 
{
437
 
        ECal *ecal = data;
438
 
        ECalendarOp *op;
439
 
 
440
 
        op = e_calendar_get_op (ecal);
441
 
 
442
 
        if (op == NULL || !op->bool) {
443
 
                ecal->priv->read_only = read_only;
444
 
                return;
445
 
        }
446
 
 
447
 
        op->status = status;
448
 
        op->bool = read_only;
449
 
 
450
 
        e_flag_set (op->done);
451
 
}
452
 
 
453
 
static void
454
 
cal_cal_address_cb (ECalListener *listener, ECalendarStatus status, const gchar *address, gpointer data)
455
 
{
456
 
        ECal *ecal = data;
457
 
        ECalendarOp *op;
458
 
 
459
 
        op = e_calendar_get_op (ecal);
460
 
 
461
 
        if (ecal->priv->cal_address) {
462
 
                g_free (ecal->priv->cal_address);
463
 
                ecal->priv->cal_address = NULL;
464
 
        }
465
 
 
466
 
        ecal->priv->cal_address = g_strdup (address);
467
 
 
468
 
        if (op == NULL) {
469
 
                return;
470
 
        }
471
 
 
472
 
        op->status = status;
473
 
        op->string = g_strdup (address);
474
 
 
475
 
        e_flag_set (op->done);
476
 
}
477
 
 
478
 
static void
479
 
cal_alarm_address_cb (ECalListener *listener, ECalendarStatus status, const gchar *address, gpointer data)
480
 
{
481
 
        ECal *ecal = data;
482
 
        ECalendarOp *op;
483
 
 
484
 
        op = e_calendar_get_op (ecal);
485
 
 
486
 
        if (op == NULL) {
487
 
                g_warning ("%s", G_STRLOC ": Cannot find operation ");
488
 
                return;
489
 
        }
490
 
 
491
 
        op->status = status;
492
 
        op->string = g_strdup (address);
493
 
 
494
 
        e_flag_set (op->done);
495
 
}
496
 
 
497
 
static void
498
 
cal_ldap_attribute_cb (ECalListener *listener, ECalendarStatus status, const gchar *attribute, gpointer data)
499
 
{
500
 
        ECal *ecal = data;
501
 
        ECalendarOp *op;
502
 
 
503
 
        op = e_calendar_get_op (ecal);
504
 
 
505
 
        if (op == NULL) {
506
 
                g_warning ("%s", G_STRLOC ": Cannot find operation ");
507
 
                return;
508
 
        }
509
 
 
510
 
        op->status = status;
511
 
        op->string = g_strdup (attribute);
512
 
 
513
 
        e_flag_set (op->done);
514
 
}
515
 
 
516
 
static void
517
 
cal_static_capabilities_cb (ECalListener *listener, ECalendarStatus status, const gchar *capabilities, gpointer data)
518
 
{
519
 
        ECal *ecal = data;
520
 
        ECalendarOp *op;
521
 
 
522
 
        op = e_calendar_get_op (ecal);
523
 
 
524
 
        if (op == NULL) {
525
 
                g_warning ("%s", G_STRLOC ": Cannot find operation ");
526
 
                return;
527
 
        }
528
 
 
529
 
        op->status = status;
530
 
        op->string = g_strdup (capabilities);
531
 
 
532
 
        e_flag_set (op->done);
533
 
}
534
 
 
535
 
static void
536
 
cal_opened_cb (ECalListener *listener, ECalendarStatus status, gpointer data)
537
 
{
538
 
        ECal *ecal = data;
539
 
        ECalendarOp *op;
540
 
 
541
 
        op = e_calendar_get_op (ecal);
542
 
 
543
 
        if (op == NULL) {
544
 
                g_warning ("%s", G_STRLOC ": Cannot find operation ");
545
 
                return;
546
 
        }
547
 
 
548
 
        op->status = status;
549
 
 
550
 
        e_flag_set (op->done);
551
 
}
552
 
 
553
 
static void
554
 
cal_removed_cb (ECalListener *listener, ECalendarStatus status, gpointer data)
555
 
{
556
 
        ECal *ecal = data;
557
 
        ECalendarOp *op;
558
 
 
559
 
        op = e_calendar_get_op (ecal);
560
 
 
561
 
        if (op == NULL) {
562
 
                g_warning ("%s", G_STRLOC ": Cannot find operation ");
563
 
                return;
564
 
        }
565
 
 
566
 
        op->status = status;
567
 
 
568
 
        e_flag_set (op->done);
569
 
}
570
 
 
571
 
static void
572
 
cal_object_created_cb (ECalListener *listener, ECalendarStatus status, const gchar *uid, gpointer data)
573
 
{
574
 
        ECal *ecal = data;
575
 
        ECalendarOp *op;
576
 
 
577
 
        op = e_calendar_get_op (ecal);
578
 
 
579
 
        if (op == NULL) {
580
 
                g_warning ("%s", G_STRLOC ": Cannot find operation ");
581
 
                return;
582
 
        }
583
 
 
584
 
        op->status = status;
585
 
        op->uid = g_strdup (uid);
586
 
 
587
 
        e_flag_set (op->done);
588
 
}
589
 
 
590
 
static void
591
 
cal_object_modified_cb (ECalListener *listener, ECalendarStatus status, gpointer data)
592
 
{
593
 
        ECal *ecal = data;
594
 
        ECalendarOp *op;
595
 
 
596
 
        op = e_calendar_get_op (ecal);
597
 
 
598
 
        if (op == NULL) {
599
 
                g_warning (G_STRLOC ": Cannot find operation ");
600
 
                return;
601
 
        }
602
 
 
603
 
        op->status = status;
604
 
 
605
 
        e_flag_set (op->done);
606
 
}
607
 
 
608
 
static void
609
 
cal_object_removed_cb (ECalListener *listener, ECalendarStatus status, gpointer data)
610
 
{
611
 
        ECal *ecal = data;
612
 
        ECalendarOp *op;
613
 
 
614
 
        op = e_calendar_get_op (ecal);
615
 
 
616
 
        if (op == NULL) {
617
 
                g_warning (G_STRLOC ": Cannot find operation ");
618
 
                return;
619
 
        }
620
 
 
621
 
        op->status = status;
622
 
 
623
 
        e_flag_set (op->done);
624
 
}
625
 
 
626
 
static void
627
 
cal_alarm_discarded_cb (ECalListener *listener, ECalendarStatus status, gpointer data)
628
 
{
629
 
        ECal *ecal = data;
630
 
        ECalendarOp *op;
631
 
 
632
 
        op = e_calendar_get_op (ecal);
633
 
 
634
 
        if (op == NULL) {
635
 
                g_warning (G_STRLOC ": Cannot find operation ");
636
 
                return;
637
 
        }
638
 
 
639
 
        op->status = status;
640
 
 
641
 
        e_flag_set (op->done);
642
 
}
643
 
 
644
 
static void
645
 
cal_objects_received_cb (ECalListener *listener, ECalendarStatus status, gpointer data)
646
 
{
647
 
        ECal *ecal = data;
648
 
        ECalendarOp *op;
649
 
 
650
 
        op = e_calendar_get_op (ecal);
651
 
 
652
 
        if (op == NULL) {
653
 
                g_warning (G_STRLOC ": Cannot find operation ");
654
 
                return;
655
 
        }
656
 
 
657
 
        op->status = status;
658
 
 
659
 
        e_flag_set (op->done);
660
 
}
661
 
 
662
 
static void
663
 
cal_objects_sent_cb (ECalListener *listener, ECalendarStatus status, GList *users, const gchar *object, gpointer data)
664
 
{
665
 
        ECal *ecal = data;
666
 
        ECalendarOp *op;
667
 
        GList *l;
668
 
 
669
 
        op = e_calendar_get_op (ecal);
670
 
 
671
 
        if (op == NULL) {
672
 
                g_warning (G_STRLOC ": Cannot find operation ");
673
 
                return;
674
 
        }
675
 
 
676
 
        op->status = status;
677
 
        op->list = g_list_copy (users);
678
 
        op->string = g_strdup (object);
679
 
 
680
 
        for (l = op->list; l; l = l->next)
681
 
                l->data = g_strdup (l->data);
682
 
 
683
 
        e_flag_set (op->done);
684
 
}
685
 
 
686
 
static void
687
 
cal_default_object_requested_cb (ECalListener *listener, ECalendarStatus status, const gchar *object, gpointer data)
688
 
{
689
 
        ECal *ecal = data;
690
 
        ECalendarOp *op;
691
 
 
692
 
        op = e_calendar_get_op (ecal);
693
 
 
694
 
        if (op == NULL) {
695
 
                g_warning (G_STRLOC ": Cannot find operation ");
696
 
                return;
697
 
        }
698
 
 
699
 
        op->status = status;
700
 
        op->string = g_strdup (object);
701
 
 
702
 
        e_flag_set (op->done);
703
 
}
704
 
 
705
 
static void
706
 
cal_object_requested_cb (ECalListener *listener, ECalendarStatus status, const gchar *object, gpointer data)
707
 
{
708
 
        ECal *ecal = data;
709
 
        ECalendarOp *op;
710
 
 
711
 
        op = e_calendar_get_op (ecal);
712
 
 
713
 
        if (op == NULL) {
714
 
                g_warning (G_STRLOC ": Cannot find operation ");
715
 
                return;
716
 
        }
717
 
 
718
 
        op->status = status;
719
 
        op->string = g_strdup (object);
720
 
 
721
 
        e_flag_set (op->done);
722
 
}
723
 
 
724
 
static void
725
 
cal_object_list_cb (ECalListener *listener, ECalendarStatus status, GList *objects, gpointer data)
726
 
{
727
 
        ECal *ecal = data;
728
 
        ECalendarOp *op;
729
 
        GList *l;
730
 
 
731
 
        op = e_calendar_get_op (ecal);
732
 
 
733
 
        if (op == NULL) {
734
 
                g_warning (G_STRLOC ": Cannot find operation ");
735
 
                return;
736
 
        }
737
 
 
738
 
        op->status = status;
739
 
        op->list = g_list_copy (objects);
740
 
 
741
 
        for (l = op->list; l; l = l->next)
742
 
                l->data = icalcomponent_new_clone (l->data);
743
 
 
744
 
        e_flag_set (op->done);
745
 
}
746
 
 
747
 
static void
748
 
cal_attachment_list_cb (ECalListener *listener, ECalendarStatus status, GSList *attachments, gpointer data)
749
 
{
750
 
        ECal *ecal = data;
751
 
        ECalendarOp *op;
752
 
 
753
 
        op = e_calendar_get_op (ecal);
754
 
 
755
 
        if (op == NULL) {
756
 
                g_warning (G_STRLOC ": Cannot find operation ");
757
 
                return;
758
 
        }
759
 
 
760
 
        op->status = status;
761
 
        op->slist = g_slist_copy (attachments);
762
 
 
763
 
        e_flag_set (op->done);
764
 
}
765
 
 
766
 
static void
767
 
cal_get_timezone_cb (ECalListener *listener, ECalendarStatus status, const gchar *object, gpointer data)
768
 
{
769
 
        ECal *ecal = data;
770
 
        ECalendarOp *op;
771
 
 
772
 
        op = e_calendar_get_op (ecal);
773
 
 
774
 
        if (op == NULL) {
775
 
                g_warning (G_STRLOC ": Cannot find operation ");
776
 
                return;
777
 
        }
778
 
 
779
 
        op->status = status;
780
 
        op->string = g_strdup (object);
781
 
 
782
 
        e_flag_set (op->done);
783
 
}
784
 
 
785
 
static void
786
 
cal_add_timezone_cb (ECalListener *listener, ECalendarStatus status, const gchar *tzid, gpointer data)
787
 
{
788
 
        ECal *ecal = data;
789
 
        ECalendarOp *op;
790
 
 
791
 
        op = e_calendar_get_op (ecal);
792
 
 
793
 
        if (op == NULL) {
794
 
                g_warning (G_STRLOC ": Cannot find operation ");
795
 
                return;
796
 
        }
797
 
 
798
 
        op->status = status;
799
 
        op->uid = g_strdup (tzid);
800
 
 
801
 
        e_flag_set (op->done);
802
 
}
803
 
 
804
 
static void
805
 
cal_set_default_timezone_cb (ECalListener *listener, ECalendarStatus status, gpointer data)
806
 
{
807
 
        ECal *ecal = data;
808
 
        ECalendarOp *op;
809
 
 
810
 
        op = e_calendar_get_op (ecal);
811
 
 
812
 
        if (op == NULL) {
813
 
                g_warning (G_STRLOC ": Cannot find operation ");
814
 
                return;
815
 
        }
816
 
 
817
 
        op->status = status;
818
 
 
819
 
        e_flag_set (op->done);
820
 
}
821
 
 
822
 
static void
823
 
cal_get_changes_cb (ECalListener *listener, ECalendarStatus status, GList *changes, gpointer data)
824
 
{
825
 
        ECal *ecal = data;
826
 
        ECalendarOp *op;
827
 
        GList *l;
828
 
 
829
 
        op = e_calendar_get_op (ecal);
830
 
 
831
 
        if (op == NULL) {
832
 
                g_warning (G_STRLOC ": Cannot find operation ");
833
 
                return;
834
 
        }
835
 
 
836
 
        op->status = status;
837
 
        op->list = g_list_copy (changes);
838
 
 
839
 
        for (l = op->list; l; l = l->next) {
840
 
                ECalChange *ccc = l->data, *new_ccc;
841
 
 
842
 
                new_ccc = g_new (ECalChange, 1);
843
 
                new_ccc->comp = e_cal_component_clone (ccc->comp);
844
 
                new_ccc->type = ccc->type;
845
 
 
846
 
                l->data = new_ccc;
847
 
        }
848
 
 
849
 
        e_flag_set (op->done);
850
 
}
851
 
 
852
 
static void
853
 
cal_get_free_busy_cb (ECalListener *listener, ECalendarStatus status, GList *freebusy, gpointer data)
854
 
{
855
 
        ECal *ecal = data;
856
 
        ECalendarOp *op;
857
 
        GList *l;
858
 
 
859
 
        op = e_calendar_get_op (ecal);
860
 
 
861
 
        if (op == NULL) {
862
 
                g_warning (G_STRLOC ": Cannot find operation ");
863
 
                return;
864
 
        }
865
 
 
866
 
        op->status = status;
867
 
        op->list = g_list_copy (freebusy);
868
 
 
869
 
        for (l = op->list; l; l = l->next)
870
 
                l->data = e_cal_component_clone (l->data);
871
 
 
872
 
        e_flag_set (op->done);
873
 
}
874
 
 
875
 
static void
876
 
cal_query_cb (ECalListener *listener, ECalendarStatus status, GNOME_Evolution_Calendar_CalView query, gpointer data)
877
 
{
878
 
        ECal *ecal = data;
879
 
        ECalendarOp *op;
880
 
 
881
 
        op = e_calendar_get_op (ecal);
882
 
 
883
 
        if (op == NULL) {
884
 
                g_warning (G_STRLOC ": Cannot find operation ");
885
 
                return;
886
 
        }
887
 
 
888
 
        op->status = status;
889
 
        op->query = e_cal_view_new (query, op->listener, ecal);
890
 
 
891
 
        e_flag_set (op->done);
892
 
}
893
 
 
894
 
static gboolean
895
 
reopen_with_auth (gpointer data)
896
 
{
897
 
        ECalendarStatus status;
898
 
 
899
 
        open_calendar (E_CAL (data), TRUE, NULL, &status, TRUE);
900
 
        return FALSE;
901
 
}
902
 
 
903
 
static void
904
 
auth_required_cb (ECalListener *listener, gpointer data)
905
 
{
906
 
        g_idle_add (reopen_with_auth, data);
907
 
 
908
 
}
909
 
 
910
 
/* Handle the cal_set_mode notification from the listener */
911
 
static void
912
 
cal_set_mode_cb (ECalListener *listener,
913
 
                 GNOME_Evolution_Calendar_CalListener_SetModeStatus status,
914
 
                 GNOME_Evolution_Calendar_CalMode mode,
915
 
                 gpointer data)
916
 
{
917
 
        ECal *ecal;
918
 
        ECalPrivate *priv;
919
 
        ECalSetModeStatus ecal_status;
920
 
 
921
 
        ecal = E_CAL (data);
922
 
        priv = ecal->priv;
923
 
        priv->mode = mode;
924
 
        ecal_status = E_CAL_SET_MODE_ERROR;
925
 
 
926
 
        switch (status) {
927
 
        case GNOME_Evolution_Calendar_CalListener_MODE_SET:
928
 
                ecal_status = E_CAL_SET_MODE_SUCCESS;
929
 
                break;
930
 
        case GNOME_Evolution_Calendar_CalListener_MODE_NOT_SET:
931
 
                ecal_status = E_CAL_SET_MODE_ERROR;
932
 
                break;
933
 
        case GNOME_Evolution_Calendar_CalListener_MODE_NOT_SUPPORTED:
934
 
                ecal_status = E_CAL_SET_MODE_NOT_SUPPORTED;
935
 
                break;
936
 
        default:
937
 
                g_assert_not_reached ();
938
 
        }
939
 
 
940
 
        /* We are *not* inside a signal handler (this is just a simple callback
941
 
         * called from the listener), so there is not a temporary reference to
942
 
         * the ecal object.  We ref() so that we can safely emit our own
943
 
         * signal and clean up.
944
 
         */
945
 
 
946
 
        g_object_ref (G_OBJECT (ecal));
947
 
 
948
 
        g_signal_emit (G_OBJECT (ecal), e_cal_signals[CAL_SET_MODE],
949
 
                       0, ecal_status, mode);
950
 
 
951
 
        if (ecal_status == E_CAL_SET_MODE_SUCCESS && ecal->priv->load_state == E_CAL_LOAD_LOADED) {
952
 
                /* the mode has been changed, recheck whether readonly or not */
953
 
                GError *error = NULL;
954
 
                gboolean read_only = TRUE;
955
 
 
956
 
                if (get_read_only (ecal, &read_only, &error)) {
957
 
                        priv->read_only = read_only;
958
 
                }
959
 
 
960
 
                if (error) {
961
 
                        g_warning ("%s: get_read_only failed: %s", G_STRFUNC, error->message);
962
 
                        g_error_free (error);
963
 
                }
964
 
        }
965
 
 
966
 
        g_object_unref (G_OBJECT (ecal));
967
 
}
968
 
 
969
 
typedef struct
970
 
{
971
 
        ECal *ecal;
972
 
        gchar *message;
973
 
}  ECalErrorData;
974
 
 
975
 
static gboolean
976
 
backend_error_idle_cb (gpointer data)
977
 
{
978
 
        ECalErrorData *error_data = data;
979
 
 
980
 
        g_signal_emit (G_OBJECT (error_data->ecal), e_cal_signals[BACKEND_ERROR], 0, error_data->message);
981
 
 
982
 
        g_object_unref (error_data->ecal);
983
 
        g_free (error_data->message);
984
 
        g_free (error_data);
985
 
 
986
 
        return FALSE;
987
 
}
988
 
 
989
 
/* Handle the error_occurred signal from the listener */
990
 
static void
991
 
backend_error_cb (ECalListener *listener, const gchar *message, gpointer data)
992
 
{
993
 
        ECalErrorData *error_data;
994
 
 
995
 
        error_data = g_new0 (ECalErrorData, 1);
996
 
 
997
 
        error_data->ecal = g_object_ref (data);
998
 
        error_data->message = g_strdup (message);
999
 
 
1000
 
        g_idle_add (backend_error_idle_cb, error_data);
1001
 
}
1002
 
 
1003
 
 
1004
 
 
1005
 
static gboolean
1006
 
get_factories (const gchar *str_uri, GList **factories)
1007
 
{
1008
 
        GNOME_Evolution_Calendar_CalFactory factory;
1009
 
        Bonobo_ServerInfoList *servers;
1010
 
        EUri *uri;
1011
 
        const gchar *query;
1012
 
        gint i;
1013
 
 
1014
 
        /* Determine the protocol and query for factory supporting that */
1015
 
        uri = e_uri_new (str_uri);
1016
 
        if (!uri) {
1017
 
                g_warning (G_STRLOC ": Invalid uri string");
1018
 
 
1019
 
                return FALSE;
1020
 
        }
1021
 
 
1022
 
        query = "repo_ids.has ('IDL:GNOME/Evolution/DataServer/CalFactory:" API_VERSION "')";
1023
 
 
1024
 
        servers = bonobo_activation_query (query, NULL, NULL);
1025
 
 
1026
 
        e_uri_free (uri);
1027
 
 
1028
 
        if (!servers) {
1029
 
                g_warning (G_STRLOC ": Unable to query for calendar factories");
1030
 
 
1031
 
                return FALSE;
1032
 
        }
1033
 
 
1034
 
        /* Try to activate the servers for the protocol */
1035
 
        for (i = 0; i < servers->_length; i++) {
1036
 
                const Bonobo_ServerInfo *info;
1037
 
 
1038
 
                info = servers->_buffer + i;
1039
 
 
1040
 
#if 0
1041
 
                g_message (G_STRLOC ": Activating calendar factory (%s)", info->iid);
1042
 
#endif
1043
 
                factory = bonobo_activation_activate_from_id (info->iid, 0, NULL, NULL);
1044
 
 
1045
 
                if (factory == CORBA_OBJECT_NIL)
1046
 
                        g_warning (G_STRLOC ": Could not activate calendar factory (%s)", info->iid);
1047
 
                else
1048
 
                        *factories = g_list_append (*factories, factory);
1049
 
        }
1050
 
 
1051
 
        CORBA_free (servers);
1052
 
 
1053
 
        return TRUE;
1054
 
}
1055
 
 
1056
 
/* Object initialization function for the calendar ecal */
1057
 
static void
1058
 
e_cal_init (ECal *ecal, ECalClass *klass)
1059
 
{
1060
 
        ECalPrivate *priv;
1061
 
 
1062
 
        priv = g_new0 (ECalPrivate, 1);
1063
 
        ecal->priv = priv;
 
364
                return Journal;
 
365
        default:
 
366
                return AnyType;
 
367
        }
 
368
 
 
369
        return AnyType;
 
370
}
 
371
static void
 
372
e_cal_init (ECal *ecal)
 
373
{
 
374
        ECalPrivate *priv;
 
375
 
 
376
        ecal->priv = priv = E_CAL_GET_PRIVATE (ecal);
1064
377
 
1065
378
        priv->load_state = E_CAL_LOAD_NOT_LOADED;
1066
379
        priv->uri = NULL;
1067
380
        priv->local_attachment_store = NULL;
1068
 
        priv->mutex = g_mutex_new ();
1069
 
        priv->listener = e_cal_listener_new (cal_set_mode_cb, ecal);
1070
381
 
1071
382
        priv->cal_address = NULL;
1072
383
        priv->alarm_email_address = NULL;
1073
384
        priv->ldap_attribute = NULL;
1074
 
        priv->capabilities = FALSE;
1075
 
        priv->factories = NULL;
 
385
        priv->capabilities = NULL;
 
386
        priv->proxy = NULL;
1076
387
        priv->timezones = g_hash_table_new (g_str_hash, g_str_equal);
1077
388
        priv->default_zone = icaltimezone_get_utc_timezone ();
1078
 
        priv->comp_listener = NULL;
1079
 
 
1080
 
        g_signal_connect (G_OBJECT (priv->listener), "read_only", G_CALLBACK (cal_read_only_cb), ecal);
1081
 
        g_signal_connect (G_OBJECT (priv->listener), "cal_address", G_CALLBACK (cal_cal_address_cb), ecal);
1082
 
        g_signal_connect (G_OBJECT (priv->listener), "alarm_address", G_CALLBACK (cal_alarm_address_cb), ecal);
1083
 
        g_signal_connect (G_OBJECT (priv->listener), "ldap_attribute", G_CALLBACK (cal_ldap_attribute_cb), ecal);
1084
 
        g_signal_connect (G_OBJECT (priv->listener), "static_capabilities", G_CALLBACK (cal_static_capabilities_cb), ecal);
1085
 
        g_signal_connect (G_OBJECT (priv->listener), "open", G_CALLBACK (cal_opened_cb), ecal);
1086
 
        g_signal_connect (G_OBJECT (priv->listener), "remove", G_CALLBACK (cal_removed_cb), ecal);
1087
 
        g_signal_connect (G_OBJECT (priv->listener), "create_object", G_CALLBACK (cal_object_created_cb), ecal);
1088
 
        g_signal_connect (G_OBJECT (priv->listener), "modify_object", G_CALLBACK (cal_object_modified_cb), ecal);
1089
 
        g_signal_connect (G_OBJECT (priv->listener), "remove_object", G_CALLBACK (cal_object_removed_cb), ecal);
1090
 
        g_signal_connect (G_OBJECT (priv->listener), "discard_alarm", G_CALLBACK (cal_alarm_discarded_cb), ecal);
1091
 
        g_signal_connect (G_OBJECT (priv->listener), "receive_objects", G_CALLBACK (cal_objects_received_cb), ecal);
1092
 
        g_signal_connect (G_OBJECT (priv->listener), "send_objects", G_CALLBACK (cal_objects_sent_cb), ecal);
1093
 
        g_signal_connect (G_OBJECT (priv->listener), "default_object", G_CALLBACK (cal_default_object_requested_cb), ecal);
1094
 
        g_signal_connect (G_OBJECT (priv->listener), "object", G_CALLBACK (cal_object_requested_cb), ecal);
1095
 
        g_signal_connect (G_OBJECT (priv->listener), "object_list", G_CALLBACK (cal_object_list_cb), ecal);
1096
 
        g_signal_connect (G_OBJECT (priv->listener), "attachment_list", G_CALLBACK (cal_attachment_list_cb), ecal);
1097
 
        g_signal_connect (G_OBJECT (priv->listener), "get_timezone", G_CALLBACK (cal_get_timezone_cb), ecal);
1098
 
        g_signal_connect (G_OBJECT (priv->listener), "add_timezone", G_CALLBACK (cal_add_timezone_cb), ecal);
1099
 
        g_signal_connect (G_OBJECT (priv->listener), "set_default_timezone", G_CALLBACK (cal_set_default_timezone_cb), ecal);
1100
 
        g_signal_connect (G_OBJECT (priv->listener), "get_changes", G_CALLBACK (cal_get_changes_cb), ecal);
1101
 
        g_signal_connect (G_OBJECT (priv->listener), "get_free_busy", G_CALLBACK (cal_get_free_busy_cb), ecal);
1102
 
        g_signal_connect (G_OBJECT (priv->listener), "query", G_CALLBACK (cal_query_cb), ecal);
1103
 
        g_signal_connect (G_OBJECT (priv->listener), "backend_error", G_CALLBACK (backend_error_cb), ecal);
1104
 
        g_signal_connect (G_OBJECT (priv->listener), "auth_required", G_CALLBACK (auth_required_cb), ecal);
 
389
}
 
390
 
 
391
/*
 
392
 * Called when the calendar server dies.
 
393
 */
 
394
static void
 
395
proxy_destroyed (gpointer data, GObject *object)
 
396
{
 
397
        ECal *ecal = data;
 
398
        ECalPrivate *priv;
 
399
 
 
400
        g_assert (E_IS_CAL (ecal));
 
401
 
 
402
        priv = ecal->priv;
 
403
 
 
404
        g_warning (G_STRLOC ": e-d-s proxy died");
 
405
 
 
406
        /* Ensure that everything relevant is reset */
 
407
        LOCK_CONN ();
 
408
        factory_proxy = NULL;
 
409
        priv->proxy = NULL;
 
410
        priv->load_state = E_CAL_LOAD_NOT_LOADED;
 
411
        UNLOCK_CONN ();
 
412
 
 
413
        g_signal_emit (G_OBJECT (ecal), e_cal_signals [BACKEND_DIED], 0);
 
414
}
 
415
 
 
416
/* Dispose handler for the calendar ecal */
 
417
static void
 
418
e_cal_dispose (GObject *object)
 
419
{
 
420
        ECal *ecal;
 
421
        ECalPrivate *priv;
 
422
 
 
423
        ecal = E_CAL (object);
 
424
        priv = ecal->priv;
 
425
 
 
426
        if (priv->proxy) {
 
427
                GError *error = NULL;
 
428
 
 
429
                g_object_weak_unref (G_OBJECT (priv->proxy), proxy_destroyed, ecal);
 
430
                LOCK_CONN ();
 
431
                org_gnome_evolution_dataserver_calendar_Cal_close (priv->proxy, &error);
 
432
                g_object_unref (priv->proxy);
 
433
                priv->proxy = NULL;
 
434
                UNLOCK_CONN ();
 
435
 
 
436
                if (error) {
 
437
                        g_warning ("%s: Failed to close calendar, %s\n", G_STRFUNC, error->message);
 
438
                        g_error_free (error);
 
439
                }
 
440
        }
 
441
 
 
442
        (* G_OBJECT_CLASS (parent_class)->dispose) (object);
 
443
}
 
444
 
 
445
static void
 
446
free_timezone (gpointer key, gpointer value, gpointer data)
 
447
{
 
448
        /* Note that the key comes from within the icaltimezone value, so we
 
449
           don't free that. */
 
450
        icaltimezone_free (value, TRUE);
1105
451
}
1106
452
 
1107
453
/* Finalize handler for the calendar ecal */
1117
463
        ecal = E_CAL (object);
1118
464
        priv = ecal->priv;
1119
465
 
1120
 
        if (priv->listener) {
1121
 
                e_cal_listener_stop_notification (priv->listener);
1122
 
                bonobo_object_unref (priv->listener);
1123
 
                priv->listener = NULL;
1124
 
        }
1125
 
 
1126
 
        if (priv->comp_listener) {
1127
 
                g_signal_handlers_disconnect_matched (G_OBJECT (priv->comp_listener),
1128
 
                                                      G_SIGNAL_MATCH_DATA,
1129
 
                                                      0, 0, NULL, NULL,
1130
 
                                                      ecal);
1131
 
                g_object_unref (G_OBJECT (priv->comp_listener));
1132
 
                priv->comp_listener = NULL;
1133
 
        }
1134
 
 
1135
 
        destroy_factories (ecal);
1136
 
        destroy_cal (ecal);
1137
 
 
1138
466
        priv->load_state = E_CAL_LOAD_NOT_LOADED;
1139
467
 
1140
468
        if (priv->source) {
1152
480
                priv->local_attachment_store = NULL;
1153
481
        }
1154
482
 
1155
 
        if (priv->mutex) {
1156
 
                g_mutex_free (priv->mutex);
1157
 
                priv->mutex = NULL;
1158
 
        }
1159
 
 
1160
483
        if (priv->cal_address) {
1161
484
                g_free (priv->cal_address);
1162
485
                priv->cal_address = NULL;
1178
501
        g_hash_table_destroy (priv->timezones);
1179
502
        priv->timezones = NULL;
1180
503
 
1181
 
        g_free (priv);
1182
 
        ecal->priv = NULL;
1183
 
 
1184
 
        if (G_OBJECT_CLASS (parent_class)->finalize)
1185
 
                (* G_OBJECT_CLASS (parent_class)->finalize) (object);
 
504
        (* G_OBJECT_CLASS (parent_class)->finalize) (object);
1186
505
}
1187
506
 
1188
507
/* Class initialization function for the calendar ecal */
1234
553
        klass->cal_opened = NULL;
1235
554
        klass->backend_died = NULL;
1236
555
 
 
556
        object_class->dispose = e_cal_dispose;
1237
557
        object_class->finalize = e_cal_finalize;
1238
 
}
1239
 
 
1240
 
/**
1241
 
 * e_cal_get_type:
1242
 
 *
1243
 
 * Registers the #ECal class if necessary, and returns the type ID assigned
1244
 
 * to it.
1245
 
 *
1246
 
 * Return value: The type ID of the #ECal class.
1247
 
 **/
1248
 
GType
1249
 
e_cal_get_type (void)
1250
 
{
1251
 
        static GType e_cal_type = 0;
1252
 
 
1253
 
        if (!e_cal_type) {
1254
 
                static GTypeInfo info = {
1255
 
                        sizeof (ECalClass),
1256
 
                        (GBaseInitFunc) NULL,
1257
 
                        (GBaseFinalizeFunc) NULL,
1258
 
                        (GClassInitFunc) e_cal_class_init,
1259
 
                        NULL, NULL,
1260
 
                        sizeof (ECal),
1261
 
                        0,
1262
 
                        (GInstanceInitFunc) e_cal_init
1263
 
                };
1264
 
                e_cal_type = g_type_register_static (G_TYPE_OBJECT, "ECal", &info, 0);
1265
 
        }
1266
 
 
1267
 
        return e_cal_type;
1268
 
}
1269
 
 
1270
 
static gboolean
1271
 
fetch_corba_cal (ECal *ecal, ESource *source, ECalSourceType type)
1272
 
{
1273
 
        ECalPrivate *priv;
1274
 
        GList *f;
1275
 
        CORBA_Environment ev;
1276
 
        gchar *source_xml;
1277
 
        gchar *str_uri;
1278
 
        gboolean result = FALSE;
1279
 
 
1280
 
        priv = ecal->priv;
1281
 
        g_return_val_if_fail (priv->load_state == E_CAL_LOAD_NOT_LOADED, FALSE);
1282
 
        g_assert (priv->uri == NULL);
1283
 
        g_return_val_if_fail (source != NULL, FALSE);
1284
 
 
1285
 
        str_uri = e_source_get_uri (source);
1286
 
        if (!str_uri)
1287
 
                return FALSE;
1288
 
 
1289
 
        if (!get_factories (str_uri, &priv->factories)) {
1290
 
                g_free (str_uri);
1291
 
                return FALSE;
1292
 
        }
1293
 
 
1294
 
        g_object_ref (source);
1295
 
        priv->source = source;
1296
 
 
1297
 
        priv->uri = g_strdup (str_uri);
1298
 
        priv->type = type;
1299
 
 
1300
 
        source_xml = e_source_to_standalone_xml (source);
1301
 
 
1302
 
        for (f = priv->factories; f; f = f->next) {
1303
 
                GNOME_Evolution_Calendar_Cal cal;
1304
 
 
1305
 
                CORBA_exception_init (&ev);
1306
 
 
1307
 
                cal = GNOME_Evolution_Calendar_CalFactory_getCal (f->data, source_xml, convert_type (priv->type),
1308
 
                                                                  BONOBO_OBJREF (priv->listener), &ev);
1309
 
                if (BONOBO_EX (&ev))
1310
 
                        continue;
1311
 
 
1312
 
                priv->cal = cal;
1313
 
 
1314
 
                result = TRUE;
1315
 
                break;
1316
 
        }
1317
 
 
1318
 
        g_free (str_uri);
1319
 
        g_free (source_xml);
1320
 
        return result;
 
558
 
 
559
        g_type_class_add_private (klass, sizeof (ECalPrivate));
 
560
}
 
561
 
 
562
static DBusHandlerResult
 
563
filter_dbus_msgs_cb (DBusConnection *pconnection, DBusMessage *message, gpointer user_data)
 
564
{
 
565
        if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected")) {
 
566
                DBusGConnection *conn = connection;
 
567
 
 
568
                LOCK_CONN ();
 
569
                factory_proxy = NULL;
 
570
                connection = NULL;
 
571
                UNLOCK_CONN ();
 
572
                dbus_g_connection_unref (conn);
 
573
                return DBUS_HANDLER_RESULT_HANDLED;
 
574
        }
 
575
 
 
576
        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 
577
}
 
578
 
 
579
static void
 
580
factory_proxy_destroy_cb (DBusGProxy *proxy, gpointer user_data)
 
581
{
 
582
        LOCK_CONN ();
 
583
        factory_proxy = NULL;
 
584
        UNLOCK_CONN ();
1321
585
}
1322
586
 
1323
587
/* one-time start up for libecal */
1324
 
static void
1325
 
e_cal_activate (void)
1326
 
{
1327
 
        static GStaticMutex e_cal_lock = G_STATIC_MUTEX_INIT;
1328
 
        static gboolean activated = FALSE;
1329
 
 
1330
 
        g_static_mutex_lock (&e_cal_lock);
1331
 
        if (!activated) {
1332
 
                activated = TRUE;
1333
 
 
1334
 
                if (!bonobo_is_initialized ())
1335
 
                        bonobo_init (NULL, NULL);
1336
 
        }
1337
 
        g_static_mutex_unlock (&e_cal_lock);
 
588
static gboolean
 
589
e_cal_activate(GError **error)
 
590
{
 
591
        DBusError derror;
 
592
 
 
593
        LOCK_CONN ();
 
594
        if (G_LIKELY (factory_proxy)) {
 
595
                UNLOCK_CONN ();
 
596
                return TRUE;
 
597
        }
 
598
 
 
599
        if (!connection) {
 
600
                connection = dbus_g_bus_get (DBUS_BUS_SESSION, error);
 
601
                if (!connection) {
 
602
                        UNLOCK_CONN ();
 
603
                        return FALSE;
 
604
                }
 
605
 
 
606
                dbus_connection_add_filter (dbus_g_connection_get_connection (connection), filter_dbus_msgs_cb, NULL, NULL);
 
607
        }
 
608
 
 
609
        dbus_error_init (&derror);
 
610
        if (!dbus_bus_start_service_by_name (dbus_g_connection_get_connection (connection),
 
611
                                                                                                        "org.gnome.evolution.dataserver.Calendar",
 
612
                                                                                                        0, NULL, &derror))
 
613
        {
 
614
                dbus_set_g_error (error, &derror);
 
615
                dbus_error_free (&derror);
 
616
                UNLOCK_CONN ();
 
617
                return FALSE;
 
618
        }
 
619
 
 
620
        if (!factory_proxy) {
 
621
                factory_proxy = dbus_g_proxy_new_for_name_owner (connection,
 
622
                                                        "org.gnome.evolution.dataserver.Calendar",
 
623
                                                        "/org/gnome/evolution/dataserver/calendar/CalFactory",
 
624
                                                        "org.gnome.evolution.dataserver.calendar.CalFactory",
 
625
                                                        error);
 
626
                if (!factory_proxy) {
 
627
                        UNLOCK_CONN ();
 
628
                        return FALSE;
 
629
                }
 
630
 
 
631
                g_signal_connect (factory_proxy, "destroy", G_CALLBACK (factory_proxy_destroy_cb), NULL);
 
632
        }
 
633
 
 
634
        UNLOCK_CONN ();
 
635
 
 
636
        return TRUE;
 
637
}
 
638
 
 
639
static gboolean
 
640
reopen_with_auth (gpointer data)
 
641
{
 
642
        ECalendarStatus status;
 
643
 
 
644
        open_calendar (E_CAL (data), TRUE, NULL, &status, TRUE, FALSE);
 
645
        return FALSE;
 
646
}
 
647
 
 
648
static void
 
649
auth_required_cb (DBusGProxy *proxy, ECal *cal)
 
650
{
 
651
        g_return_if_fail (E_IS_CAL (cal));
 
652
 
 
653
        g_idle_add (reopen_with_auth, (gpointer)cal);
 
654
}
 
655
 
 
656
static void
 
657
mode_cb (DBusGProxy *proxy, EDataCalMode mode, ECal *cal)
 
658
{
 
659
        g_return_if_fail (E_IS_CAL (cal));
 
660
        g_return_if_fail (mode & AnyMode);
 
661
 
 
662
        g_signal_emit (G_OBJECT (cal), e_cal_signals[CAL_SET_MODE],
 
663
                       0, E_CALENDAR_STATUS_OK, mode);
 
664
}
 
665
 
 
666
static void
 
667
readonly_cb (DBusGProxy *proxy, gboolean read_only, ECal *cal)
 
668
{
 
669
        ECalPrivate *priv;
 
670
 
 
671
        g_return_if_fail (cal && E_IS_CAL (cal));
 
672
 
 
673
        priv = cal->priv;
 
674
        priv->read_only = read_only;
 
675
}
 
676
 
 
677
/*
 
678
static void
 
679
backend_died_cb (EComponentListener *cl, gpointer user_data)
 
680
{
 
681
        ECalPrivate *priv;
 
682
        ECal *ecal = (ECal *) user_data;
 
683
 
 
684
        priv = ecal->priv;
 
685
        priv->load_state = E_CAL_LOAD_NOT_LOADED;
 
686
        g_signal_emit (G_OBJECT (ecal), e_cal_signals[BACKEND_DIED], 0);
 
687
}*/
 
688
 
 
689
typedef struct
 
690
{
 
691
        ECal *ecal;
 
692
        gchar *message;
 
693
}  ECalErrorData;
 
694
 
 
695
static gboolean
 
696
backend_error_idle_cb (gpointer data)
 
697
{
 
698
        ECalErrorData *error_data = data;
 
699
 
 
700
        g_signal_emit (G_OBJECT (error_data->ecal), e_cal_signals[BACKEND_ERROR], 0, error_data->message);
 
701
 
 
702
        g_object_unref (error_data->ecal);
 
703
        g_free (error_data->message);
 
704
        g_free (error_data);
 
705
 
 
706
        return FALSE;
 
707
}
 
708
 
 
709
/* Handle the error_occurred signal from the listener */
 
710
static void
 
711
backend_error_cb (DBusGProxy *proxy, const gchar *message, ECal *ecal)
 
712
{
 
713
        ECalErrorData *error_data;
 
714
 
 
715
        g_return_if_fail (E_IS_CAL (ecal));
 
716
 
 
717
        error_data = g_new0 (ECalErrorData, 1);
 
718
 
 
719
        error_data->ecal = g_object_ref (ecal);
 
720
        error_data->message = g_strdup (message);
 
721
 
 
722
        g_idle_add (backend_error_idle_cb, error_data);
1338
723
}
1339
724
 
1340
725
/* TODO - For now, the policy of where each backend serializes its
1426
811
 * Creates a new calendar client. This does not open the calendar itself,
1427
812
 * for that, #e_cal_open or #e_cal_open_async needs to be called.
1428
813
 *
1429
 
 * Return value: A newly-created calendar client, or NULL if the client could
 
814
 * Returns: A newly-created calendar client, or NULL if the client could
1430
815
 * not be constructed because it could not contact the calendar server.
1431
816
 **/
1432
817
ECal *
1433
818
e_cal_new (ESource *source, ECalSourceType type)
1434
819
{
1435
820
        ECal *ecal;
1436
 
 
1437
 
        e_cal_activate ();
 
821
        ECalPrivate *priv;
 
822
        gchar *path, *xml;
 
823
        GError *error = NULL;
 
824
 
 
825
        g_return_val_if_fail (source && E_IS_SOURCE (source), NULL);
 
826
        g_return_val_if_fail (type < E_CAL_SOURCE_TYPE_LAST, NULL);
 
827
 
 
828
        if (!e_cal_activate (&error)) {
 
829
                g_warning("Cannot activate ECal: %s\n", error ? error->message : "Unknown error");
 
830
                g_error_free (error);
 
831
                return NULL;
 
832
        }
1438
833
 
1439
834
        ecal = g_object_new (E_TYPE_CAL, NULL);
1440
 
 
1441
 
        if (!fetch_corba_cal (ecal, source, type)) {
 
835
        priv = ecal->priv;
 
836
 
 
837
        priv->source = g_object_ref (source);
 
838
        priv->uri = e_source_get_uri (source);
 
839
        priv->type = type;
 
840
 
 
841
        xml = e_source_to_standalone_xml (priv->source);
 
842
        LOCK_CONN ();
 
843
        if (!org_gnome_evolution_dataserver_calendar_CalFactory_get_cal (factory_proxy, xml, convert_type (priv->type), &path, &error)) {
 
844
                UNLOCK_CONN ();
 
845
                g_free (xml);
 
846
                g_warning ("Cannot get cal from factory: %s", error ? error->message : "Unknown error");
 
847
                g_error_free (error);
1442
848
                g_object_unref (ecal);
1443
 
 
1444
849
                return NULL;
1445
850
        }
 
851
        g_free (xml);
 
852
 
 
853
        priv->proxy = dbus_g_proxy_new_for_name_owner (connection,
 
854
                                                                        "org.gnome.evolution.dataserver.Calendar", path,
 
855
                                                                        "org.gnome.evolution.dataserver.calendar.Cal",
 
856
                                                                        &error);
 
857
 
 
858
        UNLOCK_CONN ();
 
859
 
 
860
        if (!priv->proxy)
 
861
                return NULL;
 
862
 
 
863
        g_object_weak_ref (G_OBJECT (priv->proxy), proxy_destroyed, ecal);
 
864
 
 
865
        dbus_g_proxy_add_signal (priv->proxy, "auth_required", G_TYPE_INVALID);
 
866
        dbus_g_proxy_connect_signal (priv->proxy, "auth_required", G_CALLBACK (auth_required_cb), ecal, NULL);
 
867
        dbus_g_proxy_add_signal (priv->proxy, "backend_error", G_TYPE_STRING, G_TYPE_INVALID);
 
868
        dbus_g_proxy_connect_signal (priv->proxy, "backend_error", G_CALLBACK (backend_error_cb), ecal, NULL);
 
869
        dbus_g_proxy_add_signal (priv->proxy, "readonly", G_TYPE_BOOLEAN, G_TYPE_INVALID);
 
870
        dbus_g_proxy_connect_signal (priv->proxy, "readonly", G_CALLBACK (readonly_cb), ecal, NULL);
 
871
        dbus_g_proxy_add_signal (priv->proxy, "mode", G_TYPE_INT, G_TYPE_INVALID);
 
872
        dbus_g_proxy_connect_signal (priv->proxy, "mode", G_CALLBACK (mode_cb), ecal, NULL);
1446
873
 
1447
874
        /* Set the local attachment store path for the calendar */
1448
875
        set_local_attachment_store (ecal);
1449
876
 
1450
 
        /* initialize component listener */
1451
 
        ecal->priv->comp_listener = e_component_listener_new ((Bonobo_Unknown) ecal->priv->cal);
1452
 
        g_signal_connect (G_OBJECT (ecal->priv->comp_listener), "component_died",
1453
 
                          G_CALLBACK (backend_died_cb), ecal);
1454
 
 
1455
877
        return ecal;
1456
878
}
1457
879
 
 
880
/* for each known source calls check_func, which should return TRUE if the required
 
881
   source have been found. Function returns NULL or the source on which was returned
 
882
   TRUE by the check_func. Non-NULL pointer should be unreffed by g_object_unref. */
 
883
static ESource *
 
884
search_known_sources (ECalSourceType type, gboolean (*check_func)(ESource *source, gpointer user_data), gpointer user_data, GError **error)
 
885
{
 
886
        ESourceList *sources;
 
887
        ESource *res = NULL;
 
888
        GSList *g;
 
889
        GError *err = NULL;
 
890
 
 
891
        g_return_val_if_fail (check_func != NULL, NULL);
 
892
 
 
893
        if (!e_cal_get_sources (&sources, type, &err)) {
 
894
                g_propagate_error (error, err);
 
895
                return NULL;
 
896
        }
 
897
 
 
898
        for (g = e_source_list_peek_groups (sources); g; g = g->next) {
 
899
                ESourceGroup *group = E_SOURCE_GROUP (g->data);
 
900
                GSList *s;
 
901
 
 
902
                for (s = e_source_group_peek_sources (group); s; s = s->next) {
 
903
                        ESource *source = E_SOURCE (s->data);
 
904
 
 
905
                        if (check_func (source, user_data)) {
 
906
                                res = g_object_ref (source);
 
907
                                break;
 
908
                        }
 
909
                }
 
910
 
 
911
                if (res)
 
912
                        break;
 
913
        }
 
914
 
 
915
        g_object_unref (sources);
 
916
 
 
917
        return res;
 
918
}
 
919
 
 
920
static gboolean
 
921
check_uri (ESource *source, gpointer uri)
 
922
{
 
923
        const gchar *suri;
 
924
 
 
925
        g_return_val_if_fail (source != NULL, FALSE);
 
926
        g_return_val_if_fail (uri != NULL, FALSE);
 
927
 
 
928
        suri = e_source_peek_absolute_uri (source);
 
929
 
 
930
        return suri && g_ascii_strcasecmp (suri, uri) == 0;
 
931
}
 
932
 
1458
933
/**
1459
934
 * e_cal_new_from_uri:
1460
935
 * @uri: The URI pointing to the calendar to open.
1463
938
 * Creates a new calendar client. This does not open the calendar itself,
1464
939
 * for that, #e_cal_open or #e_cal_open_async needs to be called.
1465
940
 *
1466
 
 * Return value: A newly-created calendar client, or NULL if the client could
 
941
 * Returns: A newly-created calendar client, or NULL if the client could
1467
942
 * not be constructed because it could not contact the calendar server.
1468
943
 **/
1469
944
ECal *
1472
947
        ESource *source;
1473
948
        ECal *cal;
1474
949
 
1475
 
        source = e_source_new_with_absolute_uri ("", uri);
 
950
        source = search_known_sources (type, check_uri, (gpointer) uri, NULL);
 
951
        if (!source)
 
952
                source = e_source_new_with_absolute_uri ("", uri);
 
953
 
1476
954
        cal = e_cal_new (source, type);
1477
955
 
1478
956
        g_object_unref (source);
1487
965
 * all Evolution installations. This does not open the calendar itself,
1488
966
 * for that, #e_cal_open or #e_cal_open_async needs to be called.
1489
967
 *
1490
 
 * Return value: A newly-created calendar client, or NULL if the client could
 
968
 * Returns: A newly-created calendar client, or NULL if the client could
1491
969
 * not be constructed.
1492
970
 */
1493
971
ECal *
1515
993
 * all Evolution installations. This does not open the tasks list itself,
1516
994
 * for that, #e_cal_open or #e_cal_open_async needs to be called.
1517
995
 *
1518
 
 * Return value: A newly-created calendar client, or NULL if the client could
 
996
 * Returns: A newly-created calendar client, or NULL if the client could
1519
997
 * not be constructed.
1520
998
 */
1521
999
ECal *
1543
1021
 * in all Evolution installations. This does not open the memos itself, for
1544
1022
 * that, #e_cal_open or #e_cal_open_async needs to be called.
1545
1023
 *
1546
 
 * Return value: A newly-created calendar client, or NULL if the client could
 
1024
 * Returns: A newly-created calendar client, or NULL if the client could
1547
1025
 * not be constructed.
1548
1026
 */
1549
1027
ECal *
1635
1113
        return euri_str;
1636
1114
}
1637
1115
 
 
1116
static void
 
1117
async_signal_idle_cb (DBusGProxy *proxy, GError *error, gpointer user_data)
 
1118
{
 
1119
        ECal *ecal;
 
1120
        ECalendarStatus status;
 
1121
 
 
1122
        ecal = E_CAL (user_data);
 
1123
 
 
1124
        g_return_if_fail (ecal && E_IS_CAL (ecal));
 
1125
 
 
1126
        if (error) {
 
1127
                status = get_status_from_error (error);
 
1128
        } else {
 
1129
                status = E_CALENDAR_STATUS_OK;
 
1130
                LOCK_CONN ();
 
1131
                org_gnome_evolution_dataserver_calendar_Cal_is_read_only (ecal->priv->proxy, NULL);
 
1132
                UNLOCK_CONN ();
 
1133
        }
 
1134
 
 
1135
        g_signal_emit (G_OBJECT (ecal), e_cal_signals[CAL_OPENED], 0, status);
 
1136
}
 
1137
 
1638
1138
static gboolean
1639
 
open_calendar (ECal *ecal, gboolean only_if_exists, GError **error, ECalendarStatus *status, gboolean needs_auth)
 
1139
open_calendar (ECal *ecal, gboolean only_if_exists, GError **error, ECalendarStatus *status, gboolean needs_auth, gboolean async)
1640
1140
{
1641
1141
        ECalPrivate *priv;
1642
 
        CORBA_Environment ev;
1643
 
        ECalendarOp *our_op;
1644
1142
        gchar *username = NULL, *auth_type = NULL, *password = NULL;
1645
 
        gboolean read_only = FALSE;
1646
1143
 
1647
1144
        e_return_error_if_fail (ecal != NULL, E_CALENDAR_STATUS_INVALID_ARG);
1648
1145
        e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
1649
 
 
1650
1146
        priv = ecal->priv;
1651
 
 
1652
 
        g_mutex_lock (ecal->priv->mutex);
 
1147
        e_return_error_if_fail (priv->proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
1653
1148
 
1654
1149
        if (!needs_auth && priv->load_state == E_CAL_LOAD_LOADED) {
1655
 
                g_mutex_unlock (ecal->priv->mutex);
1656
1150
                return TRUE;
1657
1151
        }
1658
1152
 
1659
 
        if (ecal->priv->current_op != NULL) {
1660
 
                g_mutex_unlock (ecal->priv->mutex);
1661
 
                *status = E_CALENDAR_STATUS_BUSY;
1662
 
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
1663
 
        }
1664
 
        /* start the open operation */
1665
 
        our_op = e_calendar_new_op (ecal, "open_calendar");
1666
 
 
1667
 
        g_mutex_unlock (priv->mutex);
1668
 
 
1669
1153
        /* see if the backend needs authentication */
1670
1154
        if ( (priv->mode !=  CAL_MODE_LOCAL) && e_source_get_property (priv->source, "auth")) {
1671
1155
                gchar *prompt, *key;
1674
1158
                priv->load_state = E_CAL_LOAD_AUTHENTICATING;
1675
1159
 
1676
1160
                if (priv->auth_func == NULL) {
1677
 
                        e_calendar_remove_op (ecal, our_op);
1678
 
                        e_calendar_free_op (our_op);
1679
1161
                        priv->load_state = E_CAL_LOAD_NOT_LOADED;
1680
1162
                        *status = E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED;
1681
1163
                        E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED, error);
1683
1165
 
1684
1166
                username = e_source_get_duped_property (priv->source, "username");
1685
1167
                if (!username) {
1686
 
                        e_calendar_remove_op (ecal, our_op);
1687
 
                        e_calendar_free_op (our_op);
1688
1168
                        priv->load_state = E_CAL_LOAD_NOT_LOADED;
1689
1169
                        *status = E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED;
1690
1170
                        E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED, error);
1712
1192
                g_free (auth_type);
1713
1193
 
1714
1194
                if (!key) {
1715
 
                        e_calendar_remove_op (ecal, our_op);
1716
 
                        e_calendar_free_op (our_op);
1717
1195
                        priv->load_state = E_CAL_LOAD_NOT_LOADED;
1718
1196
                        *status = E_CALENDAR_STATUS_URI_NOT_LOADED;
1719
1197
                        E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED, error);
1722
1200
                password = priv->auth_func (ecal, prompt, key, priv->auth_user_data);
1723
1201
 
1724
1202
                if (!password) {
1725
 
                        e_calendar_remove_op (ecal, our_op);
1726
 
                        e_calendar_free_op (our_op);
1727
1203
                        priv->load_state = E_CAL_LOAD_NOT_LOADED;
1728
1204
                        *status = E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED;
1729
1205
                        E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED, error);
1733
1209
                g_free (key);
1734
1210
        }
1735
1211
 
1736
 
        CORBA_exception_init (&ev);
1737
 
 
1738
1212
        priv->load_state = E_CAL_LOAD_LOADING;
1739
1213
 
1740
 
        GNOME_Evolution_Calendar_Cal_open (priv->cal, only_if_exists,
1741
 
                                           username ? username : "",
1742
 
                                           password ? password : "",
1743
 
                                           &ev);
 
1214
        *status = E_CALENDAR_STATUS_OK;
 
1215
        if (!async) {
 
1216
                LOCK_CONN ();
 
1217
                if (!org_gnome_evolution_dataserver_calendar_Cal_open (priv->proxy, only_if_exists, username ? username : "", password ? password : "", error))
 
1218
                        *status = E_CALENDAR_STATUS_CORBA_EXCEPTION;
 
1219
                UNLOCK_CONN ();
 
1220
        } else {
 
1221
                LOCK_CONN ();
 
1222
                if (!org_gnome_evolution_dataserver_calendar_Cal_open_async (priv->proxy, only_if_exists, username ? username : "", password ? password : "", async_signal_idle_cb, ecal))
 
1223
                        *status = E_CALENDAR_STATUS_CORBA_EXCEPTION;
 
1224
                UNLOCK_CONN ();
 
1225
        }
 
1226
 
1744
1227
        g_free (password);
1745
1228
        g_free (username);
1746
1229
 
1747
 
        if (BONOBO_EX (&ev)) {
1748
 
                e_calendar_remove_op (ecal, our_op);
1749
 
                e_calendar_free_op (our_op);
1750
 
 
1751
 
                CORBA_exception_free (&ev);
1752
 
 
1753
 
                g_warning (G_STRLOC ": Unable to contact backend");
1754
 
 
1755
 
                *status = E_CALENDAR_STATUS_CORBA_EXCEPTION;
1756
 
                priv->load_state = E_CAL_LOAD_NOT_LOADED;
1757
 
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
1758
 
        }
1759
 
 
1760
 
        CORBA_exception_free (&ev);
1761
 
 
1762
 
        e_flag_wait (our_op->done);
1763
 
 
1764
 
        *status = our_op->status;
1765
 
 
1766
 
        e_calendar_remove_op (ecal, our_op);
1767
 
        e_calendar_free_op (our_op);
1768
1230
        if (*status == E_CALENDAR_STATUS_OK) {
 
1231
                GError *error = NULL;
1769
1232
                priv->load_state = E_CAL_LOAD_LOADED;
1770
 
                if (get_read_only (ecal, &read_only, NULL))
1771
 
                        priv->read_only = read_only;
1772
 
        } else
 
1233
 
 
1234
                if (!async) {
 
1235
                        LOCK_CONN ();
 
1236
                        org_gnome_evolution_dataserver_calendar_Cal_is_read_only (priv->proxy, &error);
 
1237
                        UNLOCK_CONN ();
 
1238
                }
 
1239
        } else {
1773
1240
                priv->load_state = E_CAL_LOAD_NOT_LOADED;
 
1241
        }
1774
1242
 
1775
1243
        E_CALENDAR_CHECK_STATUS (*status, error);
1776
1244
}
1788
1256
 * client will emit the "cal_opened" signal when the response from the server is
1789
1257
 * received.
1790
1258
 *
1791
 
 * Return value: TRUE on success, FALSE on failure to issue the open request.
 
1259
 * Returns: TRUE on success, FALSE on failure to issue the open request.
1792
1260
 **/
1793
1261
gboolean
1794
1262
e_cal_open (ECal *ecal, gboolean only_if_exists, GError **error)
1796
1264
        ECalendarStatus status;
1797
1265
        gboolean result;
1798
1266
 
1799
 
        result = open_calendar (ecal, only_if_exists, error, &status, FALSE);
 
1267
        result = open_calendar (ecal, only_if_exists, error, &status, FALSE, FALSE);
1800
1268
        g_signal_emit (G_OBJECT (ecal), e_cal_signals[CAL_OPENED], 0, status);
1801
1269
 
1802
1270
        return result;
1803
1271
}
1804
1272
 
1805
 
typedef struct {
1806
 
        ECal *ecal;
1807
 
        gboolean exists;
1808
 
        ECalendarStatus status;
1809
 
        const gchar *auth_prompt;
1810
 
        const gchar *auth_key;
1811
 
        gchar *password;
1812
 
} ECalAsyncData;
 
1273
struct idle_async_error_reply_data
 
1274
{
 
1275
        ECal *ecal; /* ref-ed */
 
1276
        GError *error; /* cannot be NULL */
 
1277
};
1813
1278
 
1814
1279
static gboolean
1815
 
async_signal_idle_cb (gpointer data)
 
1280
idle_async_error_reply_cb (gpointer user_data)
1816
1281
{
1817
 
        ECalAsyncData *ccad = data;
1818
 
 
1819
 
        g_signal_emit (G_OBJECT (ccad->ecal), e_cal_signals[CAL_OPENED], 0, ccad->status);
1820
 
 
1821
 
        /* free memory */
1822
 
        g_object_unref (ccad->ecal);
1823
 
        g_free (ccad);
 
1282
        struct idle_async_error_reply_data *data = user_data;
 
1283
 
 
1284
        g_return_val_if_fail (data != NULL, FALSE);
 
1285
        g_return_val_if_fail (data->ecal != NULL, FALSE);
 
1286
        g_return_val_if_fail (data->error != NULL, FALSE);
 
1287
 
 
1288
        async_signal_idle_cb (NULL, data->error, data->ecal);
 
1289
 
 
1290
        g_object_unref (data->ecal);
 
1291
        g_error_free (data->error);
 
1292
        g_free (data);
1824
1293
 
1825
1294
        return FALSE;
1826
1295
}
1827
1296
 
1828
 
static gpointer
1829
 
open_async (gpointer data)
1830
 
{
1831
 
        ECalAsyncData *ccad = data;
1832
 
 
1833
 
        open_calendar (ccad->ecal, ccad->exists, NULL, &ccad->status, FALSE);
1834
 
        g_idle_add ((GSourceFunc) async_signal_idle_cb, ccad);
1835
 
 
1836
 
        return NULL;
1837
 
}
1838
 
 
1839
1297
/**
1840
1298
 * e_cal_open_async:
1841
1299
 * @ecal: A calendar client.
1853
1311
void
1854
1312
e_cal_open_async (ECal *ecal, gboolean only_if_exists)
1855
1313
{
1856
 
        ECalAsyncData *ccad;
1857
 
        GThread *thread;
 
1314
        ECalPrivate *priv;
1858
1315
        GError *error = NULL;
 
1316
        ECalendarStatus status;
 
1317
 
1859
1318
        g_return_if_fail (ecal != NULL);
1860
1319
        g_return_if_fail (E_IS_CAL (ecal));
1861
1320
 
1862
 
        switch (ecal->priv->load_state) {
 
1321
        priv = ecal->priv;
 
1322
 
 
1323
        switch (priv->load_state) {
1863
1324
        case E_CAL_LOAD_AUTHENTICATING :
1864
1325
        case E_CAL_LOAD_LOADING :
1865
1326
                g_signal_emit (G_OBJECT (ecal), e_cal_signals[CAL_OPENED], 0, E_CALENDAR_STATUS_BUSY);
1872
1333
                break;
1873
1334
        }
1874
1335
 
1875
 
        ccad = g_new0 (ECalAsyncData, 1);
1876
 
        ccad->ecal = g_object_ref (ecal);
1877
 
        ccad->exists = only_if_exists;
1878
 
 
1879
 
        /* spawn a new thread for opening the calendar */
1880
 
        thread = g_thread_create ((GThreadFunc) open_async, ccad, FALSE, &error);
1881
 
        if (!thread) {
1882
 
                g_warning (G_STRLOC ": %s", error->message);
1883
 
                g_error_free (error);
1884
 
 
1885
 
                /* notify listeners of the error */
1886
 
                g_signal_emit (G_OBJECT (ecal), e_cal_signals[CAL_OPENED], 0, E_CALENDAR_STATUS_OTHER_ERROR);
1887
 
        }
 
1336
        open_calendar (ecal, only_if_exists, &error, &status, FALSE, TRUE);
 
1337
        if (error) {
 
1338
                struct idle_async_error_reply_data *data;
 
1339
 
 
1340
                data = g_new0 (struct idle_async_error_reply_data, 1);
 
1341
                data->ecal = g_object_ref (ecal);
 
1342
                data->error = error;
 
1343
                g_idle_add (idle_async_error_reply_cb, data);
 
1344
        }
 
1345
}
 
1346
 
 
1347
/**
 
1348
 * e_cal_refresh:
 
1349
 * @ecal: A calendar client.
 
1350
 * @error: Placeholder for error information.
 
1351
 *
 
1352
 * Invokes refresh on a calendar. See @e_cal_get_refresh_supported.
 
1353
 *
 
1354
 * Returns: TRUE if calendar supports refresh and it was invoked, FALSE otherwise.
 
1355
 *
 
1356
 * Since: 2.30
 
1357
 **/
 
1358
gboolean
 
1359
e_cal_refresh (ECal *ecal, GError **error)
 
1360
{
 
1361
        ECalPrivate *priv;
 
1362
 
 
1363
        e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
 
1364
        priv = ecal->priv;
 
1365
        e_return_error_if_fail (priv->proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
 
1366
 
 
1367
        LOCK_CONN ();
 
1368
        if (!org_gnome_evolution_dataserver_calendar_Cal_refresh (priv->proxy, error)) {
 
1369
                UNLOCK_CONN ();
 
1370
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
 
1371
        }
 
1372
        UNLOCK_CONN ();
 
1373
 
 
1374
        return TRUE;
1888
1375
}
1889
1376
 
1890
1377
/**
1894
1381
 *
1895
1382
 * Removes a calendar.
1896
1383
 *
1897
 
 * Return value: TRUE if the calendar was removed, FALSE if there was an error.
 
1384
 * Returns: TRUE if the calendar was removed, FALSE if there was an error.
1898
1385
 */
1899
1386
gboolean
1900
1387
e_cal_remove (ECal *ecal, GError **error)
1901
1388
{
1902
1389
        ECalPrivate *priv;
1903
 
        CORBA_Environment ev;
1904
 
        ECalendarStatus status;
1905
 
        ECalendarOp *our_op;
1906
 
 
1907
 
        g_return_val_if_fail (ecal != NULL, FALSE);
1908
 
        g_return_val_if_fail (E_IS_CAL (ecal), FALSE);
1909
 
 
 
1390
 
 
1391
        e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
1910
1392
        priv = ecal->priv;
1911
 
 
1912
 
        g_mutex_lock (ecal->priv->mutex);
1913
 
 
1914
 
        if (ecal->priv->current_op != NULL) {
1915
 
                g_mutex_unlock (ecal->priv->mutex);
1916
 
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
1917
 
        }
1918
 
 
1919
 
        our_op = e_calendar_new_op (ecal, "cal_remove");
1920
 
 
1921
 
        g_mutex_unlock (ecal->priv->mutex);
1922
 
 
1923
 
        CORBA_exception_init (&ev);
1924
 
 
1925
 
        GNOME_Evolution_Calendar_Cal_remove (priv->cal, &ev);
1926
 
        if (BONOBO_EX (&ev)) {
1927
 
                e_calendar_remove_op (ecal, our_op);
1928
 
                e_calendar_free_op (our_op);
1929
 
 
1930
 
                CORBA_exception_free (&ev);
1931
 
 
1932
 
                g_warning (G_STRLOC ": Unable to contact backend");
1933
 
 
 
1393
        e_return_error_if_fail (priv->proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
 
1394
 
 
1395
        LOCK_CONN ();
 
1396
        if (!org_gnome_evolution_dataserver_calendar_Cal_remove (priv->proxy, error)) {
 
1397
                UNLOCK_CONN ();
1934
1398
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
1935
1399
        }
1936
 
 
1937
 
        CORBA_exception_free (&ev);
1938
 
 
1939
 
        e_flag_wait (our_op->done);
1940
 
 
1941
 
        status = our_op->status;
1942
 
 
1943
 
        e_calendar_remove_op (ecal, our_op);
1944
 
        e_calendar_free_op (our_op);
1945
 
 
1946
 
        E_CALENDAR_CHECK_STATUS (status, error);
 
1400
        UNLOCK_CONN ();
 
1401
 
 
1402
        return TRUE;
1947
1403
}
1948
1404
 
1949
1405
#if 0
1968
1424
 *
1969
1425
 * Retrieves a list of all calendar clients for the given mode.
1970
1426
 *
1971
 
 * Return value: list of uris.
 
1427
 * Returns: list of uris.
1972
1428
 */
1973
1429
GList *
1974
1430
e_cal_uri_list (ECal *ecal, CalMode mode)
1980
1436
        CORBA_Environment ev;
1981
1437
        GList *f;
1982
1438
 
1983
 
        g_return_val_if_fail (ecal != NULL, FALSE);
1984
 
        g_return_val_if_fail (E_IS_CAL (ecal), FALSE);
 
1439
        g_return_val_if_fail (ecal != NULL, NULL);
 
1440
        g_return_val_if_fail (E_IS_CAL (ecal), NULL);
1985
1441
 
1986
1442
        priv = ecal->priv;
1987
1443
 
2018
1474
 *
2019
1475
 * Gets the type of the calendar client.
2020
1476
 *
2021
 
 * Return value: an #ECalSourceType value corresponding to the type
 
1477
 * Returns: an #ECalSourceType value corresponding to the type
2022
1478
 * of the calendar client.
2023
1479
 */
2024
1480
ECalSourceType
2040
1496
 *
2041
1497
 * Queries the state of loading of a calendar client.
2042
1498
 *
2043
 
 * Return value: A #ECalLoadState value indicating whether the client has
 
1499
 * Returns: A #ECalLoadState value indicating whether the client has
2044
1500
 * not been loaded with #e_cal_open yet, whether it is being
2045
1501
 * loaded, or whether it is already loaded.
2046
1502
 **/
2062
1518
 *
2063
1519
 * Queries the source that is open in a calendar client.
2064
1520
 *
2065
 
 * Return value: The source of the calendar that is already loaded or is being
 
1521
 * Returns: The source of the calendar that is already loaded or is being
2066
1522
 * loaded, or NULL if the ecal has not started a load request yet.
2067
1523
 **/
2068
1524
ESource *
2083
1539
 *
2084
1540
 * Queries the URI that is open in a calendar client.
2085
1541
 *
2086
 
 * Return value: The URI of the calendar that is already loaded or is being
 
1542
 * Returns: The URI of the calendar that is already loaded or is being
2087
1543
 * loaded, or NULL if the client has not started a load request yet.
2088
1544
 **/
2089
1545
const gchar *
2108
1564
 * unless it specifically uses the attachments for open/sending
2109
1565
 * operations.
2110
1566
 *
2111
 
 * Return value: The URL where the attachments are serialized in the
 
1567
 * Returns: The URL where the attachments are serialized in the
2112
1568
 * local filesystem.
2113
1569
 **/
2114
1570
const gchar *
2133
1589
 * on the calendar or not. Whether the backend is read only or not
2134
1590
 * is specified, on exit, in the @read_only argument.
2135
1591
 *
2136
 
 * Return value: TRUE if the call was successful, FALSE if there was an error.
 
1592
 * Returns: TRUE if the call was successful, FALSE if there was an error.
2137
1593
 */
2138
1594
gboolean
2139
1595
e_cal_is_read_only (ECal *ecal, gboolean *read_only, GError **error)
2149
1605
        return TRUE;
2150
1606
}
2151
1607
 
2152
 
static gboolean
2153
 
get_read_only (ECal *ecal, gboolean *read_only, GError **error)
2154
 
{
2155
 
        ECalPrivate *priv;
2156
 
        CORBA_Environment ev;
2157
 
        ECalendarStatus status;
2158
 
        ECalendarOp *our_op;
2159
 
 
2160
 
        priv = ecal->priv;
2161
 
        g_mutex_lock (ecal->priv->mutex);
2162
 
 
2163
 
        if (ecal->priv->load_state != E_CAL_LOAD_LOADED) {
2164
 
                g_mutex_unlock (ecal->priv->mutex);
2165
 
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
2166
 
        }
2167
 
 
2168
 
        if (ecal->priv->current_op != NULL) {
2169
 
                g_mutex_unlock (ecal->priv->mutex);
2170
 
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
2171
 
        }
2172
 
 
2173
 
        our_op = e_calendar_new_op (ecal, "get_read_only");
2174
 
 
2175
 
        /* set it to true so that op does not emit cond signals for all notifications
2176
 
           from the backend */
2177
 
        our_op->bool = TRUE;
2178
 
 
2179
 
        g_mutex_unlock (ecal->priv->mutex);
2180
 
 
2181
 
        CORBA_exception_init (&ev);
2182
 
 
2183
 
        GNOME_Evolution_Calendar_Cal_isReadOnly (priv->cal, &ev);
2184
 
        if (BONOBO_EX (&ev)) {
2185
 
                e_calendar_remove_op (ecal, our_op);
2186
 
                e_calendar_free_op (our_op);
2187
 
 
2188
 
                CORBA_exception_free (&ev);
2189
 
 
2190
 
                g_warning (G_STRLOC ": Unable to contact backend");
2191
 
 
2192
 
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
2193
 
        }
2194
 
 
2195
 
        CORBA_exception_free (&ev);
2196
 
 
2197
 
        e_flag_wait (our_op->done);
2198
 
 
2199
 
        status = our_op->status;
2200
 
 
2201
 
        if (status == E_CALENDAR_STATUS_OK)
2202
 
                *read_only = our_op->bool;
2203
 
 
2204
 
        e_calendar_remove_op (ecal, our_op);
2205
 
        e_calendar_free_op (our_op);
2206
 
        E_CALENDAR_CHECK_STATUS (status, error);
2207
 
}
2208
 
 
2209
1608
/**
2210
1609
 * e_cal_get_cal_address:
2211
1610
 * @ecal: A calendar client.
2214
1613
 *
2215
1614
 * Queries the calendar address associated with a calendar client.
2216
1615
 *
2217
 
 * Return value: TRUE if the operation was successful, FALSE if there
 
1616
 * Returns: TRUE if the operation was successful, FALSE if there
2218
1617
 * was an error.
2219
1618
 **/
2220
1619
gboolean
2221
1620
e_cal_get_cal_address (ECal *ecal, gchar **cal_address, GError **error)
2222
1621
{
2223
1622
        ECalPrivate *priv;
2224
 
        CORBA_Environment ev;
2225
 
        ECalendarStatus status;
2226
 
        ECalendarOp *our_op;
2227
1623
 
2228
 
        if (!(ecal && E_IS_CAL (ecal)))
2229
 
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_INVALID_ARG, error);
 
1624
        e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
 
1625
        e_return_error_if_fail (cal_address != NULL, E_CALENDAR_STATUS_INVALID_ARG);
2230
1626
        priv = ecal->priv;
 
1627
        e_return_error_if_fail (priv->proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
 
1628
        *cal_address = NULL;
 
1629
 
2231
1630
        if (priv->cal_address == NULL) {
2232
 
                g_mutex_lock (ecal->priv->mutex);
2233
 
 
2234
 
                if (ecal->priv->load_state != E_CAL_LOAD_LOADED) {
2235
 
                        g_mutex_unlock (ecal->priv->mutex);
 
1631
                e_return_error_if_fail (priv->proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
 
1632
                if (priv->load_state != E_CAL_LOAD_LOADED) {
2236
1633
                        E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
2237
1634
                }
2238
1635
 
2239
 
                if (ecal->priv->current_op != NULL) {
2240
 
                        g_mutex_unlock (ecal->priv->mutex);
2241
 
                        E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
2242
 
                }
2243
 
 
2244
 
                our_op = e_calendar_new_op (ecal, "get_cal_address");
2245
 
 
2246
 
                g_mutex_unlock (ecal->priv->mutex);
2247
 
 
2248
 
                CORBA_exception_init (&ev);
2249
 
 
2250
 
                GNOME_Evolution_Calendar_Cal_getCalAddress (priv->cal, &ev);
2251
 
                if (BONOBO_EX (&ev)) {
2252
 
                        e_calendar_remove_op (ecal, our_op);
2253
 
                        e_calendar_free_op (our_op);
2254
 
 
2255
 
                        CORBA_exception_free (&ev);
2256
 
 
2257
 
                        g_warning (G_STRLOC ": Unable to contact backend");
2258
 
 
 
1636
                LOCK_CONN ();
 
1637
                if (!org_gnome_evolution_dataserver_calendar_Cal_get_cal_address (priv->proxy, cal_address, error)) {
 
1638
                        UNLOCK_CONN ();
2259
1639
                        E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
2260
1640
                }
2261
 
 
2262
 
                CORBA_exception_free (&ev);
2263
 
 
2264
 
                e_flag_wait (our_op->done);
2265
 
 
2266
 
                status = our_op->status;
2267
 
                *cal_address = our_op->string;
2268
 
                e_calendar_remove_op (ecal, our_op);
2269
 
                e_calendar_free_op (our_op);
2270
 
 
2271
 
                E_CALENDAR_CHECK_STATUS (status, error);
 
1641
                UNLOCK_CONN ();
2272
1642
        } else {
2273
1643
                *cal_address = g_strdup (priv->cal_address);
2274
 
 
2275
 
                return TRUE;
2276
1644
        }
 
1645
 
 
1646
        return TRUE;
2277
1647
}
2278
1648
 
2279
1649
/**
2284
1654
 *
2285
1655
 * Queries the address to be used for alarms in a calendar client.
2286
1656
 *
2287
 
 * Return value: TRUE if the operation was successful, FALSE if there was
 
1657
 * Returns: TRUE if the operation was successful, FALSE if there was
2288
1658
 * an error while contacting the backend.
2289
1659
 */
2290
1660
gboolean
2291
1661
e_cal_get_alarm_email_address (ECal *ecal, gchar **alarm_address, GError **error)
2292
1662
{
2293
1663
        ECalPrivate *priv;
2294
 
        CORBA_Environment ev;
2295
 
        ECalendarStatus status;
2296
 
        ECalendarOp *our_op;
2297
 
 
2298
 
        e_return_error_if_fail (ecal && E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
2299
 
 
 
1664
 
 
1665
        e_return_error_if_fail (alarm_address != NULL, E_CALENDAR_STATUS_INVALID_ARG);
 
1666
        e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
2300
1667
        priv = ecal->priv;
2301
 
 
2302
 
        g_mutex_lock (ecal->priv->mutex);
2303
 
 
2304
 
        if (ecal->priv->load_state != E_CAL_LOAD_LOADED) {
2305
 
                g_mutex_unlock (ecal->priv->mutex);
 
1668
        e_return_error_if_fail (priv->proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
 
1669
        *alarm_address = NULL;
 
1670
 
 
1671
        if (priv->load_state != E_CAL_LOAD_LOADED) {
2306
1672
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
2307
1673
        }
2308
1674
 
2309
 
        if (ecal->priv->current_op != NULL) {
2310
 
                g_mutex_unlock (ecal->priv->mutex);
2311
 
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
2312
 
        }
2313
 
 
2314
 
        our_op = e_calendar_new_op (ecal, "get_alarm_address");
2315
 
 
2316
 
        g_mutex_unlock (ecal->priv->mutex);
2317
 
 
2318
 
        CORBA_exception_init (&ev);
2319
 
 
2320
 
        GNOME_Evolution_Calendar_Cal_getAlarmEmailAddress (priv->cal, &ev);
2321
 
        if (BONOBO_EX (&ev)) {
2322
 
                e_calendar_remove_op (ecal, our_op);
2323
 
                e_calendar_free_op (our_op);
2324
 
 
2325
 
                CORBA_exception_free (&ev);
2326
 
 
2327
 
                g_warning (G_STRLOC ": Unable to contact backend");
2328
 
 
 
1675
        LOCK_CONN ();
 
1676
        if (!org_gnome_evolution_dataserver_calendar_Cal_get_alarm_email_address (priv->proxy, alarm_address, error)) {
 
1677
                UNLOCK_CONN ();
2329
1678
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
2330
1679
        }
2331
 
 
2332
 
        CORBA_exception_free (&ev);
2333
 
 
2334
 
        e_flag_wait (our_op->done);
2335
 
 
2336
 
        status = our_op->status;
2337
 
        *alarm_address = our_op->string;
2338
 
 
2339
 
        e_calendar_remove_op (ecal, our_op);
2340
 
        e_calendar_free_op (our_op);
2341
 
 
2342
 
        E_CALENDAR_CHECK_STATUS (status, error);
 
1680
        UNLOCK_CONN ();
 
1681
 
 
1682
        return TRUE;
2343
1683
}
2344
1684
 
2345
1685
/**
2350
1690
 *
2351
1691
 * Queries the LDAP attribute for a calendar client.
2352
1692
 *
2353
 
 * Return value: TRUE if the call was successful, FALSE if there was an
 
1693
 * Returns: TRUE if the call was successful, FALSE if there was an
2354
1694
 * error contacting the backend.
2355
1695
 */
2356
1696
gboolean
2357
1697
e_cal_get_ldap_attribute (ECal *ecal, gchar **ldap_attribute, GError **error)
2358
1698
{
2359
1699
        ECalPrivate *priv;
2360
 
        CORBA_Environment ev;
2361
 
        ECalendarStatus status;
2362
 
        ECalendarOp *our_op;
2363
 
 
2364
 
        e_return_error_if_fail (ecal && E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
2365
 
 
 
1700
 
 
1701
        e_return_error_if_fail (ldap_attribute != NULL, E_CALENDAR_STATUS_INVALID_ARG);
 
1702
        e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
2366
1703
        priv = ecal->priv;
2367
 
 
2368
 
        g_mutex_lock (ecal->priv->mutex);
2369
 
 
2370
 
        if (ecal->priv->load_state != E_CAL_LOAD_LOADED) {
2371
 
                g_mutex_unlock (ecal->priv->mutex);
 
1704
        e_return_error_if_fail (priv->proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
 
1705
        *ldap_attribute = NULL;
 
1706
 
 
1707
        if (priv->load_state != E_CAL_LOAD_LOADED) {
2372
1708
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
2373
1709
        }
2374
1710
 
2375
 
        if (ecal->priv->current_op != NULL) {
2376
 
                g_mutex_unlock (ecal->priv->mutex);
2377
 
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
2378
 
        }
2379
 
 
2380
 
        our_op = e_calendar_new_op (ecal, "get_ldap_attribute");
2381
 
 
2382
 
        g_mutex_unlock (ecal->priv->mutex);
2383
 
 
2384
 
        CORBA_exception_init (&ev);
2385
 
 
2386
 
        GNOME_Evolution_Calendar_Cal_getLdapAttribute (priv->cal, &ev);
2387
 
        if (BONOBO_EX (&ev)) {
2388
 
                e_calendar_remove_op (ecal, our_op);
2389
 
                e_calendar_free_op (our_op);
2390
 
 
2391
 
                CORBA_exception_free (&ev);
2392
 
 
2393
 
                g_warning (G_STRLOC ": Unable to contact backend");
2394
 
 
 
1711
        LOCK_CONN ();
 
1712
        if (!org_gnome_evolution_dataserver_calendar_Cal_get_ldap_attribute (priv->proxy, ldap_attribute, error)) {
 
1713
                UNLOCK_CONN ();
2395
1714
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
2396
1715
        }
2397
 
 
2398
 
        CORBA_exception_free (&ev);
2399
 
 
2400
 
        e_flag_wait (our_op->done);
2401
 
 
2402
 
        status = our_op->status;
2403
 
        *ldap_attribute = our_op->string;
2404
 
 
2405
 
        e_calendar_remove_op (ecal, our_op);
2406
 
        e_calendar_free_op (our_op);
2407
 
 
2408
 
        E_CALENDAR_CHECK_STATUS (status, error);
 
1716
        UNLOCK_CONN ();
 
1717
 
 
1718
        return TRUE;
2409
1719
}
2410
1720
 
2411
1721
static gboolean
2412
1722
load_static_capabilities (ECal *ecal, GError **error)
2413
1723
{
2414
1724
        ECalPrivate *priv;
2415
 
        CORBA_Environment ev;
2416
 
        ECalendarStatus status;
2417
 
        ECalendarOp *our_op;
2418
1725
 
2419
1726
        priv = ecal->priv;
 
1727
        e_return_error_if_fail (priv->proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
2420
1728
 
2421
1729
        if (priv->capabilities)
2422
1730
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
2423
1731
 
2424
 
        g_mutex_lock (ecal->priv->mutex);
2425
 
 
2426
 
        if (ecal->priv->load_state != E_CAL_LOAD_LOADED) {
2427
 
                g_mutex_unlock (ecal->priv->mutex);
 
1732
        if (priv->load_state != E_CAL_LOAD_LOADED) {
2428
1733
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
2429
1734
        }
2430
1735
 
2431
 
        if (ecal->priv->current_op != NULL) {
2432
 
                g_mutex_unlock (ecal->priv->mutex);
2433
 
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
2434
 
        }
2435
 
 
2436
 
        our_op = e_calendar_new_op (ecal, "load_static_capabilities");
2437
 
 
2438
 
        g_mutex_unlock (ecal->priv->mutex);
2439
 
 
2440
 
        CORBA_exception_init (&ev);
2441
 
 
2442
 
        GNOME_Evolution_Calendar_Cal_getStaticCapabilities (priv->cal, &ev);
2443
 
        if (BONOBO_EX (&ev)) {
2444
 
                e_calendar_remove_op (ecal, our_op);
2445
 
                e_calendar_free_op (our_op);
2446
 
 
2447
 
                CORBA_exception_free (&ev);
2448
 
 
2449
 
                g_warning (G_STRLOC ": Unable to contact backend");
2450
 
 
 
1736
        LOCK_CONN ();
 
1737
        if (!org_gnome_evolution_dataserver_calendar_Cal_get_scheduling_information (priv->proxy, &priv->capabilities, error)) {
 
1738
                UNLOCK_CONN ();
2451
1739
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
2452
1740
        }
2453
 
 
2454
 
        CORBA_exception_free (&ev);
2455
 
 
2456
 
        e_flag_wait (our_op->done);
2457
 
 
2458
 
        status = our_op->status;
2459
 
        priv->capabilities = our_op->string;
2460
 
 
2461
 
        e_calendar_remove_op (ecal, our_op);
2462
 
        e_calendar_free_op (our_op);
2463
 
 
2464
 
        E_CALENDAR_CHECK_STATUS (status, error);
 
1741
        UNLOCK_CONN ();
 
1742
 
 
1743
        return TRUE;
2465
1744
}
2466
1745
 
2467
1746
static gboolean
2485
1764
 *
2486
1765
 * Checks if a calendar supports only one alarm per component.
2487
1766
 *
2488
 
 * Return value: TRUE if the calendar allows only one alarm, FALSE otherwise.
 
1767
 * Returns: TRUE if the calendar allows only one alarm, FALSE otherwise.
2489
1768
 */
2490
1769
gboolean
2491
1770
e_cal_get_one_alarm_only (ECal *ecal)
2502
1781
 *
2503
1782
 * Checks if a calendar forces organizers of meetings to be also attendees.
2504
1783
 *
2505
 
 * Return value: TRUE if the calendar forces organizers to attend meetings,
 
1784
 * Returns: TRUE if the calendar forces organizers to attend meetings,
2506
1785
 * FALSE otherwise.
2507
1786
 */
2508
1787
gboolean
2520
1799
 *
2521
1800
 * Checks if the calendar has a master object for recurrences.
2522
1801
 *
2523
 
 * Return value: TRUE if the calendar has a master object for recurrences,
 
1802
 * Returns: TRUE if the calendar has a master object for recurrences,
2524
1803
 * FALSE otherwise.
2525
1804
 */
2526
1805
gboolean
2539
1818
 *
2540
1819
 * Queries the calendar for static capabilities.
2541
1820
 *
2542
 
 * Return value: TRUE if the capability is supported, FALSE otherwise.
 
1821
 * Returns: TRUE if the capability is supported, FALSE otherwise.
2543
1822
 */
2544
1823
gboolean
2545
1824
e_cal_get_static_capability (ECal *ecal, const gchar *cap)
2556
1835
 *
2557
1836
 * Checks whether the calendar saves schedules.
2558
1837
 *
2559
 
 * Return value: TRUE if it saves schedules, FALSE otherwise.
 
1838
 * Returns: TRUE if it saves schedules, FALSE otherwise.
2560
1839
 */
2561
1840
gboolean
2562
1841
e_cal_get_save_schedules (ECal *ecal)
2574
1853
 * Checks whether a calendar requires organizer to accept their attendance to
2575
1854
 * meetings.
2576
1855
 *
2577
 
 * Return value: TRUE if the calendar requires organizers to accept, FALSE
 
1856
 * Returns: TRUE if the calendar requires organizers to accept, FALSE
2578
1857
 * otherwise.
2579
1858
 */
2580
1859
gboolean
2587
1866
}
2588
1867
 
2589
1868
/**
 
1869
 * e_cal_get_refresh_supported:
 
1870
 * @ecal: A calendar client.
 
1871
 *
 
1872
 * Checks whether a calendar supports explicit refreshing (see @e_cal_refresh).
 
1873
 *
 
1874
 * Returns: TRUE if the calendar supports refreshing, FALSE otherwise.
 
1875
 *
 
1876
 * Since: 2.30
 
1877
 */
 
1878
gboolean
 
1879
e_cal_get_refresh_supported (ECal *ecal)
 
1880
{
 
1881
        g_return_val_if_fail (ecal != NULL, FALSE);
 
1882
        g_return_val_if_fail (E_IS_CAL (ecal), FALSE);
 
1883
 
 
1884
        return check_capability (ecal, CAL_STATIC_CAPABILITY_REFRESH_SUPPORTED);
 
1885
}
 
1886
 
 
1887
/**
2590
1888
 * e_cal_set_mode:
2591
1889
 * @ecal: A calendar client.
2592
1890
 * @mode: Mode to switch to.
2593
1891
 *
2594
1892
 * Switches online/offline mode on the calendar.
2595
1893
 *
2596
 
 * Return value: TRUE if the switch was successful, FALSE if there was an error.
 
1894
 * Returns: TRUE if the switch was successful, FALSE if there was an error.
2597
1895
 */
2598
1896
gboolean
2599
1897
e_cal_set_mode (ECal *ecal, CalMode mode)
2600
1898
{
2601
1899
        ECalPrivate *priv;
2602
 
        gboolean retval = TRUE;
2603
 
        CORBA_Environment ev;
 
1900
        GError *error = NULL;
2604
1901
 
2605
 
        g_return_val_if_fail (ecal != NULL, -1);
2606
 
        g_return_val_if_fail (E_IS_CAL (ecal), -1);
 
1902
        g_return_val_if_fail (ecal != NULL, FALSE);
 
1903
        g_return_val_if_fail (E_IS_CAL (ecal), FALSE);
 
1904
        g_return_val_if_fail (mode & CAL_MODE_ANY, FALSE);
2607
1905
 
2608
1906
        priv = ecal->priv;
2609
 
        g_return_val_if_fail (priv->load_state == E_CAL_LOAD_LOADED, -1);
2610
 
 
2611
 
        CORBA_exception_init (&ev);
2612
 
        GNOME_Evolution_Calendar_Cal_setMode (priv->cal, mode, &ev);
2613
 
 
2614
 
        if (BONOBO_EX (&ev))
2615
 
                retval = FALSE;
2616
 
 
2617
 
        CORBA_exception_free (&ev);
2618
 
 
2619
 
        return retval;
 
1907
        g_return_val_if_fail (priv->proxy, FALSE);
 
1908
        g_return_val_if_fail (priv->load_state == E_CAL_LOAD_LOADED, FALSE);
 
1909
 
 
1910
        LOCK_CONN ();
 
1911
        if (!org_gnome_evolution_dataserver_calendar_Cal_set_mode (priv->proxy, mode, &error)) {
 
1912
                UNLOCK_CONN ();
 
1913
                g_printerr ("%s: %s\n", G_STRFUNC, error ? error->message : "Unknown error");
 
1914
                g_error_free (error);
 
1915
                return FALSE;
 
1916
        }
 
1917
        UNLOCK_CONN ();
 
1918
 
 
1919
        return TRUE;
2620
1920
}
2621
1921
 
2622
1922
/* This is used in the callback which fetches all the timezones needed for an
2639
1939
 * Retrives an #icalcomponent from the backend that contains the default
2640
1940
 * values for properties needed.
2641
1941
 *
2642
 
 * Return value: TRUE if the call was successful, FALSE otherwise.
 
1942
 * Returns: TRUE if the call was successful, FALSE otherwise.
2643
1943
 */
2644
1944
gboolean
2645
1945
e_cal_get_default_object (ECal *ecal, icalcomponent **icalcomp, GError **error)
2646
1946
{
2647
1947
        ECalPrivate *priv;
2648
 
        CORBA_Environment ev;
2649
1948
        ECalendarStatus status;
2650
 
        ECalendarOp *our_op;
2651
 
 
2652
 
        e_return_error_if_fail (ecal && E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
2653
 
 
 
1949
        gchar *object;
 
1950
 
 
1951
        e_return_error_if_fail (icalcomp != NULL, E_CALENDAR_STATUS_INVALID_ARG);
 
1952
        e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
2654
1953
        priv = ecal->priv;
2655
 
 
2656
 
        g_mutex_lock (ecal->priv->mutex);
2657
 
 
2658
 
        if (ecal->priv->load_state != E_CAL_LOAD_LOADED) {
2659
 
                g_mutex_unlock (ecal->priv->mutex);
 
1954
        e_return_error_if_fail (priv->proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
 
1955
        *icalcomp = NULL;
 
1956
 
 
1957
        if (priv->load_state != E_CAL_LOAD_LOADED) {
2660
1958
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
2661
1959
        }
2662
1960
 
2663
 
        if (ecal->priv->current_op != NULL) {
2664
 
                g_mutex_unlock (ecal->priv->mutex);
2665
 
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
2666
 
        }
2667
 
 
2668
 
        our_op = e_calendar_new_op (ecal, "get_default_object");
2669
 
 
2670
 
        g_mutex_unlock (ecal->priv->mutex);
2671
 
 
2672
 
        CORBA_exception_init (&ev);
2673
 
 
2674
 
        GNOME_Evolution_Calendar_Cal_getDefaultObject (priv->cal, &ev);
2675
 
        if (BONOBO_EX (&ev)) {
2676
 
                e_calendar_remove_op (ecal, our_op);
2677
 
                e_calendar_free_op (our_op);
2678
 
 
2679
 
                CORBA_exception_free (&ev);
2680
 
 
2681
 
                g_warning (G_STRLOC ": Unable to contact backend");
2682
 
 
 
1961
        LOCK_CONN ();
 
1962
        if (!org_gnome_evolution_dataserver_calendar_Cal_get_default_object (priv->proxy, &object, error)) {
 
1963
                UNLOCK_CONN ();
2683
1964
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
2684
1965
        }
2685
 
 
2686
 
        CORBA_exception_free (&ev);
2687
 
 
2688
 
        e_flag_wait (our_op->done);
2689
 
 
2690
 
        status = our_op->status;
2691
 
        if (status != E_CALENDAR_STATUS_OK) {
2692
 
                *icalcomp = NULL;
2693
 
        } else {
2694
 
                *icalcomp = icalparser_parse_string (our_op->string);
 
1966
        UNLOCK_CONN ();
 
1967
 
 
1968
        if (object) {
 
1969
                *icalcomp = icalparser_parse_string (object);
 
1970
                g_free (object);
 
1971
 
2695
1972
                if (!(*icalcomp))
2696
1973
                        status = E_CALENDAR_STATUS_INVALID_OBJECT;
2697
 
        }
2698
 
        g_free (our_op->string);
 
1974
                else
 
1975
                        status = E_CALENDAR_STATUS_OK;
2699
1976
 
2700
 
        e_calendar_remove_op (ecal, our_op);
2701
 
        e_calendar_free_op (our_op);
 
1977
                E_CALENDAR_CHECK_STATUS (status, error);
 
1978
        } else
 
1979
                status = E_CALENDAR_STATUS_OTHER_ERROR;
2702
1980
 
2703
1981
        E_CALENDAR_CHECK_STATUS (status, error);
2704
1982
}
2714
1992
 * Queries a calendar for a calendar component object based on its unique
2715
1993
 * identifier and gets the attachments for the component.
2716
1994
 *
2717
 
 * Return value: TRUE if the call was successful, FALSE otherwise.
 
1995
 * Returns: TRUE if the call was successful, FALSE otherwise.
2718
1996
 **/
2719
1997
gboolean
2720
1998
e_cal_get_attachments_for_comp (ECal *ecal, const gchar *uid, const gchar *rid, GSList **list, GError **error)
2721
1999
{
2722
2000
        ECalPrivate *priv;
2723
 
        CORBA_Environment ev;
2724
2001
        ECalendarStatus status;
2725
 
        ECalendarOp *our_op;
2726
 
 
2727
 
        e_return_error_if_fail (ecal && E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
2728
 
 
 
2002
        gchar **list_array;
 
2003
 
 
2004
        e_return_error_if_fail (uid != NULL, E_CALENDAR_STATUS_INVALID_ARG);
 
2005
        e_return_error_if_fail (list != NULL, E_CALENDAR_STATUS_INVALID_ARG);
 
2006
        e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
2729
2007
        priv = ecal->priv;
2730
 
 
2731
 
        g_mutex_lock (ecal->priv->mutex);
2732
 
 
2733
 
        if (ecal->priv->load_state != E_CAL_LOAD_LOADED) {
2734
 
                g_mutex_unlock (ecal->priv->mutex);
 
2008
        e_return_error_if_fail (priv->proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
 
2009
        *list = NULL;
 
2010
 
 
2011
        if (priv->load_state != E_CAL_LOAD_LOADED) {
2735
2012
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
2736
2013
        }
2737
2014
 
2738
 
        if (ecal->priv->current_op != NULL) {
2739
 
                g_mutex_unlock (ecal->priv->mutex);
2740
 
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
2741
 
        }
2742
 
 
2743
 
        our_op = e_calendar_new_op (ecal, "get_attachments_for_comp");
2744
 
 
2745
 
        g_mutex_unlock (ecal->priv->mutex);
2746
 
 
2747
 
        CORBA_exception_init (&ev);
2748
 
        GNOME_Evolution_Calendar_Cal_getAttachmentList (priv->cal, uid, rid ? rid : "", &ev);
2749
 
        if (BONOBO_EX (&ev)) {
2750
 
                e_calendar_remove_op (ecal, our_op);
2751
 
                e_calendar_free_op (our_op);
2752
 
 
2753
 
                CORBA_exception_free (&ev);
2754
 
 
2755
 
                g_warning (G_STRLOC ": Unable to contact backend");
2756
 
 
 
2015
        LOCK_CONN ();
 
2016
        if (!org_gnome_evolution_dataserver_calendar_Cal_get_attachment_list (priv->proxy, uid, rid ? rid: "", &list_array, error)) {
 
2017
                UNLOCK_CONN ();
2757
2018
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
2758
2019
        }
2759
 
 
2760
 
        CORBA_exception_free (&ev);
2761
 
 
2762
 
        e_flag_wait (our_op->done);
2763
 
 
2764
 
        status = our_op->status;
2765
 
        if (status != E_CALENDAR_STATUS_OK) {
2766
 
                *list = NULL;
2767
 
        } else {
2768
 
                *list = our_op->slist;
2769
 
        }
2770
 
 
2771
 
        e_calendar_remove_op (ecal, our_op);
2772
 
        e_calendar_free_op (our_op);
 
2020
        UNLOCK_CONN ();
 
2021
 
 
2022
        if (list_array) {
 
2023
                gchar **string;
 
2024
                for (string = list_array; *string; string++) {
 
2025
                        *list = g_slist_append (*list, g_strdup (*string));
 
2026
                }
 
2027
                g_strfreev (list_array);
 
2028
                status = E_CALENDAR_STATUS_OK;
 
2029
        } else
 
2030
                status = E_CALENDAR_STATUS_OTHER_ERROR;
2773
2031
 
2774
2032
        E_CALENDAR_CHECK_STATUS (status, error);
2775
2033
}
2785
2043
 * Queries a calendar for a calendar component object based on its unique
2786
2044
 * identifier.
2787
2045
 *
2788
 
 * Return value: TRUE if the call was successful, FALSE otherwise.
 
2046
 * Returns: TRUE if the call was successful, FALSE otherwise.
2789
2047
 **/
2790
2048
gboolean
2791
2049
e_cal_get_object (ECal *ecal, const gchar *uid, const gchar *rid, icalcomponent **icalcomp, GError **error)
2792
2050
{
2793
2051
        ECalPrivate *priv;
2794
 
        CORBA_Environment ev;
2795
2052
        ECalendarStatus status;
2796
 
        ECalendarOp *our_op;
2797
 
 
2798
 
        e_return_error_if_fail (ecal && E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
2799
 
 
 
2053
        gchar *object;
 
2054
        icalcomponent *tmp_icalcomp;
 
2055
        icalcomponent_kind kind;
 
2056
 
 
2057
        e_return_error_if_fail (uid != NULL, E_CALENDAR_STATUS_INVALID_ARG);
 
2058
        e_return_error_if_fail (icalcomp != NULL, E_CALENDAR_STATUS_INVALID_ARG);
 
2059
        e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
2800
2060
        priv = ecal->priv;
2801
 
 
2802
 
        g_mutex_lock (ecal->priv->mutex);
2803
 
 
2804
 
        if (ecal->priv->load_state != E_CAL_LOAD_LOADED) {
2805
 
                g_mutex_unlock (ecal->priv->mutex);
 
2061
        e_return_error_if_fail (priv->proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
 
2062
        *icalcomp = NULL;
 
2063
 
 
2064
        if (priv->load_state != E_CAL_LOAD_LOADED) {
2806
2065
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
2807
2066
        }
2808
2067
 
2809
 
        if (ecal->priv->current_op != NULL) {
2810
 
                g_mutex_unlock (ecal->priv->mutex);
2811
 
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
2812
 
        }
2813
 
 
2814
 
        our_op = e_calendar_new_op (ecal, "get_object");
2815
 
 
2816
 
        g_mutex_unlock (ecal->priv->mutex);
2817
 
 
2818
 
        CORBA_exception_init (&ev);
2819
 
 
2820
 
        GNOME_Evolution_Calendar_Cal_getObject (priv->cal, uid, rid ? rid : "", &ev);
2821
 
        if (BONOBO_EX (&ev)) {
2822
 
                e_calendar_remove_op (ecal, our_op);
2823
 
                e_calendar_free_op (our_op);
2824
 
 
2825
 
                CORBA_exception_free (&ev);
2826
 
 
2827
 
                g_warning (G_STRLOC ": Unable to contact backend");
2828
 
 
 
2068
        LOCK_CONN ();
 
2069
        if (!org_gnome_evolution_dataserver_calendar_Cal_get_object (priv->proxy, uid, rid ? rid : "", &object, error)) {
 
2070
                UNLOCK_CONN ();
2829
2071
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
2830
2072
        }
2831
 
 
2832
 
        CORBA_exception_free (&ev);
2833
 
 
2834
 
        e_flag_wait (our_op->done);
2835
 
 
2836
 
        status = our_op->status;
2837
 
        if (status != E_CALENDAR_STATUS_OK) {
2838
 
                *icalcomp = NULL;
2839
 
        } else {
2840
 
                icalcomponent *tmp_icalcomp;
2841
 
                icalcomponent_kind kind;
2842
 
 
2843
 
                tmp_icalcomp = icalparser_parse_string (our_op->string);
2844
 
                if (!tmp_icalcomp) {
2845
 
                        status = E_CALENDAR_STATUS_INVALID_OBJECT;
2846
 
                        *icalcomp = NULL;
2847
 
                } else {
2848
 
                        kind = icalcomponent_isa (tmp_icalcomp);
2849
 
                        if ((kind == ICAL_VEVENT_COMPONENT && priv->type == E_CAL_SOURCE_TYPE_EVENT) ||
2850
 
                            (kind == ICAL_VTODO_COMPONENT && priv->type == E_CAL_SOURCE_TYPE_TODO) ||
2851
 
                            (kind == ICAL_VJOURNAL_COMPONENT && priv->type == E_CAL_SOURCE_TYPE_JOURNAL)) {
2852
 
                                *icalcomp = icalcomponent_new_clone (tmp_icalcomp);
2853
 
                        } else if (kind == ICAL_VCALENDAR_COMPONENT) {
2854
 
                                icalcomponent *subcomp = NULL;
2855
 
 
2856
 
                                switch (priv->type) {
2857
 
                                case E_CAL_SOURCE_TYPE_EVENT :
2858
 
                                        subcomp = icalcomponent_get_first_component (tmp_icalcomp, ICAL_VEVENT_COMPONENT);
2859
 
                                        break;
2860
 
                                case E_CAL_SOURCE_TYPE_TODO :
2861
 
                                        subcomp = icalcomponent_get_first_component (tmp_icalcomp, ICAL_VTODO_COMPONENT);
2862
 
                                        break;
2863
 
                                case E_CAL_SOURCE_TYPE_JOURNAL :
2864
 
                                        subcomp = icalcomponent_get_first_component (tmp_icalcomp, ICAL_VJOURNAL_COMPONENT);
2865
 
                                        break;
2866
 
                                default:
2867
 
                                        /* ignore everything else */
2868
 
                                        break;
2869
 
                                }
2870
 
 
2871
 
                                /* we are only interested in the first component */
2872
 
                                if (subcomp)
2873
 
                                        *icalcomp = icalcomponent_new_clone (subcomp);
 
2073
        UNLOCK_CONN ();
 
2074
 
 
2075
        status = E_CALENDAR_STATUS_OK;
 
2076
        tmp_icalcomp = icalparser_parse_string (object);
 
2077
        if (!tmp_icalcomp) {
 
2078
                status = E_CALENDAR_STATUS_INVALID_OBJECT;
 
2079
                *icalcomp = NULL;
 
2080
        } else {
 
2081
                kind = icalcomponent_isa (tmp_icalcomp);
 
2082
                if ((kind == ICAL_VEVENT_COMPONENT && priv->type == E_CAL_SOURCE_TYPE_EVENT) ||
 
2083
                    (kind == ICAL_VTODO_COMPONENT && priv->type == E_CAL_SOURCE_TYPE_TODO) ||
 
2084
                    (kind == ICAL_VJOURNAL_COMPONENT && priv->type == E_CAL_SOURCE_TYPE_JOURNAL)) {
 
2085
                        *icalcomp = icalcomponent_new_clone (tmp_icalcomp);
 
2086
                } else if (kind == ICAL_VCALENDAR_COMPONENT) {
 
2087
                        icalcomponent *subcomp = NULL;
 
2088
 
 
2089
                        switch (priv->type) {
 
2090
                        case E_CAL_SOURCE_TYPE_EVENT :
 
2091
                                subcomp = icalcomponent_get_first_component (tmp_icalcomp, ICAL_VEVENT_COMPONENT);
 
2092
                                break;
 
2093
                        case E_CAL_SOURCE_TYPE_TODO :
 
2094
                                subcomp = icalcomponent_get_first_component (tmp_icalcomp, ICAL_VTODO_COMPONENT);
 
2095
                                break;
 
2096
                        case E_CAL_SOURCE_TYPE_JOURNAL :
 
2097
                                subcomp = icalcomponent_get_first_component (tmp_icalcomp, ICAL_VJOURNAL_COMPONENT);
 
2098
                                break;
 
2099
                        default:
 
2100
                                /* ignore everything else */
 
2101
                                break;
2874
2102
                        }
2875
2103
 
2876
 
                        icalcomponent_free (tmp_icalcomp);
 
2104
                        /* we are only interested in the first component */
 
2105
                        if (subcomp)
 
2106
                                *icalcomp = icalcomponent_new_clone (subcomp);
2877
2107
                }
 
2108
 
 
2109
                icalcomponent_free (tmp_icalcomp);
2878
2110
        }
2879
 
        g_free (our_op->string);
2880
2111
 
2881
 
        e_calendar_remove_op (ecal, our_op);
2882
 
        e_calendar_free_op (our_op);
 
2112
        g_free (object);
2883
2113
 
2884
2114
        E_CALENDAR_CHECK_STATUS (status, error);
2885
2115
}
2895
2125
 * ID. This will return any recurring event and all its detached recurrences.
2896
2126
 * For non-recurring events, it will just return the object with that ID.
2897
2127
 *
2898
 
 * Return value: TRUE if the call was successful, FALSE otherwise.
 
2128
 * Returns: TRUE if the call was successful, FALSE otherwise.
2899
2129
 **/
2900
2130
gboolean
2901
2131
e_cal_get_objects_for_uid (ECal *ecal, const gchar *uid, GList **objects, GError **error)
2902
2132
{
2903
2133
        ECalPrivate *priv;
2904
 
        CORBA_Environment ev;
2905
2134
        ECalendarStatus status;
2906
 
        ECalendarOp *our_op;
2907
 
 
2908
 
        e_return_error_if_fail (ecal && E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
2909
 
 
 
2135
        gchar *object;
 
2136
 
 
2137
        e_return_error_if_fail (uid != NULL, E_CALENDAR_STATUS_INVALID_ARG);
 
2138
        e_return_error_if_fail (objects != NULL, E_CALENDAR_STATUS_INVALID_ARG);
 
2139
        e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
2910
2140
        priv = ecal->priv;
 
2141
        e_return_error_if_fail (priv->proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
2911
2142
        *objects = NULL;
2912
2143
 
2913
 
        g_mutex_lock (ecal->priv->mutex);
2914
 
 
2915
 
        if (ecal->priv->load_state != E_CAL_LOAD_LOADED) {
2916
 
                g_mutex_unlock (ecal->priv->mutex);
 
2144
        if (priv->load_state != E_CAL_LOAD_LOADED) {
2917
2145
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
2918
2146
        }
2919
2147
 
2920
 
        if (ecal->priv->current_op != NULL) {
2921
 
                g_mutex_unlock (ecal->priv->mutex);
2922
 
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
2923
 
        }
2924
 
 
2925
 
        our_op = e_calendar_new_op (ecal, "get_objects_for_uid");
2926
 
 
2927
 
        g_mutex_unlock (ecal->priv->mutex);
2928
 
 
2929
 
        CORBA_exception_init (&ev);
2930
 
 
2931
 
        GNOME_Evolution_Calendar_Cal_getObject (priv->cal, uid, "", &ev);
2932
 
        if (BONOBO_EX (&ev)) {
2933
 
                e_calendar_remove_op (ecal, our_op);
2934
 
                e_calendar_free_op (our_op);
2935
 
 
2936
 
                CORBA_exception_free (&ev);
2937
 
 
2938
 
                g_warning (G_STRLOC ": Unable to contact backend");
2939
 
 
 
2148
        LOCK_CONN ();
 
2149
        if (!org_gnome_evolution_dataserver_calendar_Cal_get_object (priv->proxy, uid, "", &object, error)) {
 
2150
                UNLOCK_CONN ();
2940
2151
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
2941
2152
        }
2942
 
 
2943
 
        CORBA_exception_free (&ev);
2944
 
 
2945
 
        e_flag_wait (our_op->done);
2946
 
 
2947
 
        status = our_op->status;
2948
 
        if (status != E_CALENDAR_STATUS_OK) {
2949
 
                *objects = NULL;
2950
 
        } else {
 
2153
        UNLOCK_CONN ();
 
2154
 
 
2155
        status = E_CALENDAR_STATUS_OK;
 
2156
        {
2951
2157
                icalcomponent *icalcomp;
2952
 
                icalcomponent_kind kind, kind_to_find;
2953
 
 
2954
 
                switch (priv->type) {
2955
 
                case E_CAL_SOURCE_TYPE_EVENT :
2956
 
                        kind_to_find = ICAL_VEVENT_COMPONENT;
2957
 
                        break;
2958
 
                case E_CAL_SOURCE_TYPE_TODO :
2959
 
                        kind_to_find = ICAL_VTODO_COMPONENT;
2960
 
                        break;
2961
 
                case E_CAL_SOURCE_TYPE_JOURNAL :
2962
 
                        kind_to_find = ICAL_VJOURNAL_COMPONENT;
2963
 
                        break;
2964
 
                default:
2965
 
                        /* ignore everything else */
2966
 
                        kind_to_find = ICAL_NO_COMPONENT;
2967
 
                        break;
2968
 
                }
2969
 
 
2970
 
                                icalcomp = icalparser_parse_string (our_op->string);
 
2158
                icalcomponent_kind kind;
 
2159
 
 
2160
                icalcomp = icalparser_parse_string (object);
2971
2161
                if (!icalcomp) {
2972
2162
                        status = E_CALENDAR_STATUS_INVALID_OBJECT;
2973
2163
                        *objects = NULL;
2975
2165
                        ECalComponent *comp;
2976
2166
 
2977
2167
                        kind = icalcomponent_isa (icalcomp);
2978
 
                        if (kind == kind_to_find) {
 
2168
                        if ((kind == ICAL_VEVENT_COMPONENT && priv->type == E_CAL_SOURCE_TYPE_EVENT) ||
 
2169
                            (kind == ICAL_VTODO_COMPONENT && priv->type == E_CAL_SOURCE_TYPE_TODO) ||
 
2170
                            (kind == ICAL_VJOURNAL_COMPONENT && priv->type == E_CAL_SOURCE_TYPE_JOURNAL)) {
2979
2171
                                comp = e_cal_component_new ();
2980
2172
                                e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (icalcomp));
2981
2173
                                *objects = g_list_append (NULL, comp);
2982
2174
                        } else if (kind == ICAL_VCALENDAR_COMPONENT) {
2983
2175
                                icalcomponent *subcomp;
 
2176
                                icalcomponent_kind kind_to_find;
 
2177
 
 
2178
                                switch (priv->type) {
 
2179
                                case E_CAL_SOURCE_TYPE_TODO :
 
2180
                                        kind_to_find = ICAL_VTODO_COMPONENT;
 
2181
                                        break;
 
2182
                                case E_CAL_SOURCE_TYPE_JOURNAL :
 
2183
                                        kind_to_find = ICAL_VJOURNAL_COMPONENT;
 
2184
                                        break;
 
2185
                                case E_CAL_SOURCE_TYPE_EVENT :
 
2186
                                default:
 
2187
                                        kind_to_find = ICAL_VEVENT_COMPONENT;
 
2188
                                        break;
 
2189
                                }
2984
2190
 
2985
2191
                                *objects = NULL;
2986
2192
                                subcomp = icalcomponent_get_first_component (icalcomp, kind_to_find);
2995
2201
                        icalcomponent_free (icalcomp);
2996
2202
                }
2997
2203
        }
2998
 
        g_free (our_op->string);
2999
 
 
3000
 
        e_calendar_remove_op (ecal, our_op);
3001
 
        e_calendar_free_op (our_op);
 
2204
        g_free (object);
3002
2205
 
3003
2206
        E_CALENDAR_CHECK_STATUS (status, error);
3004
2207
}
3010
2213
 *
3011
2214
 * Resolves TZIDs for the recurrence generator.
3012
2215
 *
3013
 
 * Return value: The timezone identified by the @tzid argument, or %NULL if
 
2216
 * Returns: The timezone identified by the @tzid argument, or %NULL if
3014
2217
 * it could not be found.
3015
2218
 */
3016
2219
icaltimezone*
3041
2244
 * is identified by the @change_id argument, which is used by the backend to
3042
2245
 * compute the changes done.
3043
2246
 *
3044
 
 * Return value: TRUE if the call was successful, FALSE otherwise.
 
2247
 * Returns: TRUE if the call was successful, FALSE otherwise.
3045
2248
 */
3046
2249
gboolean
3047
2250
e_cal_get_changes (ECal *ecal, const gchar *change_id, GList **changes, GError **error)
3048
2251
{
3049
 
        CORBA_Environment ev;
3050
 
        ECalendarOp *our_op;
3051
 
        ECalendarStatus status;
3052
 
 
3053
 
        e_return_error_if_fail (ecal && E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
3054
 
        e_return_error_if_fail (change_id, E_CALENDAR_STATUS_INVALID_ARG);
3055
 
 
3056
 
        g_mutex_lock (ecal->priv->mutex);
3057
 
 
3058
 
        if (ecal->priv->load_state != E_CAL_LOAD_LOADED) {
3059
 
                g_mutex_unlock (ecal->priv->mutex);
 
2252
        ECalPrivate *priv;
 
2253
        gchar **additions, **modifications, **removals;
 
2254
 
 
2255
        e_return_error_if_fail (changes != NULL, E_CALENDAR_STATUS_INVALID_ARG);
 
2256
        e_return_error_if_fail (change_id != NULL, E_CALENDAR_STATUS_INVALID_ARG);
 
2257
        e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
 
2258
        priv = ecal->priv;
 
2259
        e_return_error_if_fail (priv->proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
 
2260
        *changes = NULL;
 
2261
 
 
2262
        if (priv->load_state != E_CAL_LOAD_LOADED) {
3060
2263
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
3061
2264
        }
3062
2265
 
3063
 
        if (ecal->priv->current_op != NULL) {
3064
 
                g_mutex_unlock (ecal->priv->mutex);
3065
 
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
3066
 
        }
3067
 
 
3068
 
        our_op = e_calendar_new_op (ecal, "get_changes");
3069
 
 
3070
 
        g_mutex_unlock (ecal->priv->mutex);
3071
 
 
3072
 
        CORBA_exception_init (&ev);
3073
 
 
3074
 
        GNOME_Evolution_Calendar_Cal_getChanges (ecal->priv->cal, change_id, &ev);
3075
 
 
3076
 
        if (BONOBO_EX (&ev)) {
3077
 
                e_calendar_remove_op (ecal, our_op);
3078
 
                e_calendar_free_op (our_op);
3079
 
 
3080
 
                CORBA_exception_free (&ev);
3081
 
 
3082
 
                g_warning (G_STRLOC ": Unable to contact backend");
3083
 
 
 
2266
        LOCK_CONN ();
 
2267
        if (!org_gnome_evolution_dataserver_calendar_Cal_get_changes (priv->proxy, change_id, &additions, &modifications, &removals, error)) {
 
2268
                UNLOCK_CONN ();
3084
2269
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
3085
2270
        }
3086
 
 
3087
 
        CORBA_exception_free (&ev);
3088
 
 
3089
 
        e_flag_wait (our_op->done);
3090
 
 
3091
 
        status = our_op->status;
3092
 
        *changes = our_op->list;
3093
 
 
3094
 
        e_calendar_remove_op (ecal, our_op);
3095
 
        e_calendar_free_op (our_op);
3096
 
 
3097
 
        E_CALENDAR_CHECK_STATUS (status, error);
 
2271
        UNLOCK_CONN ();
 
2272
 
 
2273
        /* TODO: Be more elegant and split this into a function */
 
2274
        /* Mostly copied from the old e-cal-listener.c */
 
2275
        if ((additions)&&(modifications)&&(removals)) {
 
2276
                gint i;
 
2277
                gchar **list = NULL, **l;
 
2278
                ECalChangeType change_type = E_CAL_CHANGE_ADDED;
 
2279
                icalcomponent *icalcomp;
 
2280
                ECalChange *change;
 
2281
 
 
2282
                for (i = 0; i < 3; i++) {
 
2283
                        switch (i) {
 
2284
                        case 0:
 
2285
                                change_type = E_CAL_CHANGE_ADDED;
 
2286
                                list = additions;
 
2287
                                break;
 
2288
                        case 1:
 
2289
                                change_type = E_CAL_CHANGE_MODIFIED;
 
2290
                                list = modifications;
 
2291
                                break;
 
2292
                        case 2:
 
2293
                                change_type = E_CAL_CHANGE_DELETED;
 
2294
                                list = removals;
 
2295
                        }
 
2296
 
 
2297
                        for (l = list; *l; l++) {
 
2298
                                icalcomp = icalparser_parse_string (*l);
 
2299
                                if (!icalcomp)
 
2300
                                        continue;
 
2301
                                change = g_new (ECalChange, 1);
 
2302
                                change->comp = e_cal_component_new ();
 
2303
                                if (!e_cal_component_set_icalcomponent (change->comp, icalcomp)) {
 
2304
                                        icalcomponent_free (icalcomp);
 
2305
                                        g_object_unref (G_OBJECT (change->comp));
 
2306
                                        g_free (change);
 
2307
                                        continue;
 
2308
                                }
 
2309
                                change->type = change_type;
 
2310
                                *changes = g_list_append (*changes, change);
 
2311
                        }
 
2312
                }
 
2313
        }
 
2314
        else
 
2315
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OTHER_ERROR, error);
 
2316
 
 
2317
        E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
3098
2318
}
3099
2319
 
3100
2320
/**
3134
2354
 * argument, which is a list of #icalcomponent. When done, this list
3135
2355
 * should be freed by using the #e_cal_free_object_list function.
3136
2356
 *
3137
 
 * Return value: TRUE if the operation was successful, FALSE otherwise.
 
2357
 * Returns: TRUE if the operation was successful, FALSE otherwise.
3138
2358
 **/
3139
2359
gboolean
3140
2360
e_cal_get_object_list (ECal *ecal, const gchar *query, GList **objects, GError **error)
3141
2361
{
3142
 
        CORBA_Environment ev;
3143
 
        ECalendarOp *our_op;
3144
 
        ECalendarStatus status;
 
2362
        ECalPrivate *priv;
 
2363
        gchar **object_array;
3145
2364
 
3146
 
        e_return_error_if_fail (ecal && E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
 
2365
        e_return_error_if_fail (objects != NULL, E_CALENDAR_STATUS_INVALID_ARG);
3147
2366
        e_return_error_if_fail (query, E_CALENDAR_STATUS_INVALID_ARG);
3148
 
 
3149
 
        g_mutex_lock (ecal->priv->mutex);
3150
 
 
3151
 
        if (ecal->priv->load_state != E_CAL_LOAD_LOADED) {
3152
 
                g_mutex_unlock (ecal->priv->mutex);
 
2367
        e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
 
2368
        priv = ecal->priv;
 
2369
        e_return_error_if_fail (priv->proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
 
2370
        *objects = NULL;
 
2371
 
 
2372
        if (priv->load_state != E_CAL_LOAD_LOADED) {
3153
2373
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
3154
2374
        }
3155
2375
 
3156
 
        if (ecal->priv->current_op != NULL) {
3157
 
                g_mutex_unlock (ecal->priv->mutex);
3158
 
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
3159
 
        }
3160
 
 
3161
 
        our_op = e_calendar_new_op (ecal, "get_object_list");
3162
 
 
3163
 
        g_mutex_unlock (ecal->priv->mutex);
3164
 
 
3165
 
        CORBA_exception_init (&ev);
3166
 
 
3167
 
        GNOME_Evolution_Calendar_Cal_getObjectList (ecal->priv->cal, query, &ev);
3168
 
 
3169
 
        if (BONOBO_EX (&ev)) {
3170
 
                e_calendar_remove_op (ecal, our_op);
3171
 
                e_calendar_free_op (our_op);
3172
 
 
3173
 
                CORBA_exception_free (&ev);
3174
 
 
3175
 
                g_warning (G_STRLOC ": Unable to contact backend");
3176
 
 
 
2376
        LOCK_CONN ();
 
2377
        if (!org_gnome_evolution_dataserver_calendar_Cal_get_object_list (priv->proxy, query, &object_array, error)) {
 
2378
                UNLOCK_CONN ();
3177
2379
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
3178
2380
        }
3179
 
 
3180
 
        CORBA_exception_free (&ev);
3181
 
 
3182
 
        e_flag_wait (our_op->done);
3183
 
 
3184
 
        status = our_op->status;
3185
 
        *objects = our_op->list;
3186
 
 
3187
 
        e_calendar_remove_op (ecal, our_op);
3188
 
        e_calendar_free_op (our_op);
3189
 
 
3190
 
        E_CALENDAR_CHECK_STATUS (status, error);
 
2381
        UNLOCK_CONN ();
 
2382
 
 
2383
        if (object_array) {
 
2384
                icalcomponent *comp;
 
2385
                gchar **object;
 
2386
                for (object = object_array; *object; object++) {
 
2387
                        comp = icalcomponent_new_from_string (*object);
 
2388
                        if (!comp) continue;
 
2389
                        *objects = g_list_prepend (*objects, comp);
 
2390
                }
 
2391
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
 
2392
        }
 
2393
        else
 
2394
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OTHER_ERROR, error);
3191
2395
}
3192
2396
 
3193
2397
/**
3201
2405
 * by the @query argument. The objects will be returned in the @objects
3202
2406
 * argument, which is a list of #ECalComponent.
3203
2407
 *
3204
 
 * Return value: TRUE if the operation was successful, FALSE otherwise.
 
2408
 * Returns: TRUE if the operation was successful, FALSE otherwise.
3205
2409
 */
3206
2410
gboolean
3207
2411
e_cal_get_object_list_as_comp (ECal *ecal, const gchar *query, GList **objects, GError **error)
3209
2413
        GList *ical_objects = NULL;
3210
2414
        GList *l;
3211
2415
 
 
2416
        e_return_error_if_fail (objects != NULL, E_CALENDAR_STATUS_INVALID_ARG);
 
2417
        *objects = NULL;
 
2418
 
3212
2419
        e_return_error_if_fail (ecal && E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
3213
2420
        e_return_error_if_fail (query, E_CALENDAR_STATUS_INVALID_ARG);
3214
 
        e_return_error_if_fail (objects, E_CALENDAR_STATUS_INVALID_ARG);
3215
2421
 
3216
2422
        if (!e_cal_get_object_list (ecal, query, &ical_objects, error))
3217
2423
                return FALSE;
3218
2424
 
3219
 
        *objects = NULL;
3220
2425
        for (l = ical_objects; l; l = l->next) {
3221
2426
                ECalComponent *comp;
3222
2427
 
3247
2452
        g_list_free (objects);
3248
2453
}
3249
2454
 
 
2455
static GList *
 
2456
build_free_busy_list (const gchar **seq)
 
2457
{
 
2458
        GList *list = NULL;
 
2459
        gint i;
 
2460
 
 
2461
        /* Create the list in reverse order */
 
2462
        for (i = 0; seq[i]; i++) {
 
2463
                ECalComponent *comp;
 
2464
                icalcomponent *icalcomp;
 
2465
                icalcomponent_kind kind;
 
2466
 
 
2467
                icalcomp = icalcomponent_new_from_string ((gchar *)seq[i]);
 
2468
                if (!icalcomp)
 
2469
                        continue;
 
2470
 
 
2471
                kind = icalcomponent_isa (icalcomp);
 
2472
                if (kind == ICAL_VFREEBUSY_COMPONENT) {
 
2473
                        comp = e_cal_component_new ();
 
2474
                        if (!e_cal_component_set_icalcomponent (comp, icalcomp)) {
 
2475
                                icalcomponent_free (icalcomp);
 
2476
                                g_object_unref (G_OBJECT (comp));
 
2477
                                continue;
 
2478
                        }
 
2479
 
 
2480
                        list = g_list_append (list, comp);
 
2481
                } else {
 
2482
                        icalcomponent_free (icalcomp);
 
2483
                }
 
2484
        }
 
2485
 
 
2486
        return list;
 
2487
}
 
2488
 
3250
2489
/**
3251
2490
 * e_cal_get_free_busy
3252
2491
 * @ecal: A calendar client.
3264
2503
e_cal_get_free_busy (ECal *ecal, GList *users, time_t start, time_t end,
3265
2504
                     GList **freebusy, GError **error)
3266
2505
{
3267
 
        CORBA_Environment ev;
3268
 
        ECalendarOp *our_op;
3269
 
        ECalendarStatus status;
3270
 
        GNOME_Evolution_Calendar_UserList corba_users;
 
2506
        ECalPrivate *priv;
 
2507
        gchar **users_list;
 
2508
        gchar **freebusy_array;
3271
2509
        GList *l;
3272
 
        gint i, len;
3273
 
 
3274
 
        e_return_error_if_fail (ecal && E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
3275
 
 
3276
 
        g_mutex_lock (ecal->priv->mutex);
3277
 
 
3278
 
        if (ecal->priv->load_state != E_CAL_LOAD_LOADED) {
3279
 
                g_mutex_unlock (ecal->priv->mutex);
 
2510
        gint i;
 
2511
 
 
2512
        e_return_error_if_fail (users != NULL, E_CALENDAR_STATUS_INVALID_ARG);
 
2513
        e_return_error_if_fail (freebusy != NULL, E_CALENDAR_STATUS_INVALID_ARG);
 
2514
        e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
 
2515
        priv = ecal->priv;
 
2516
        e_return_error_if_fail (priv->proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
 
2517
        *freebusy = NULL;
 
2518
 
 
2519
        if (priv->load_state != E_CAL_LOAD_LOADED) {
3280
2520
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
3281
2521
        }
3282
2522
 
3283
 
        if (ecal->priv->current_op != NULL) {
3284
 
                g_mutex_unlock (ecal->priv->mutex);
3285
 
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
3286
 
        }
3287
 
 
3288
 
        our_op = e_calendar_new_op (ecal, "get_freebusy");
3289
 
 
3290
 
        g_mutex_unlock (ecal->priv->mutex);
3291
 
 
3292
 
        /* create the CORBA user list to be passed to the backend */
3293
 
        len = g_list_length (users);
3294
 
 
3295
 
        corba_users._length = len;
3296
 
        corba_users._buffer = CORBA_sequence_GNOME_Evolution_Calendar_User_allocbuf (len);
3297
 
 
 
2523
        users_list = g_new0 (gchar *, g_list_length (users) + 1);
3298
2524
        for (l = users, i = 0; l; l = l->next, i++)
3299
 
                corba_users._buffer[i] = CORBA_string_dup (l->data);
3300
 
 
3301
 
        CORBA_exception_init (&ev);
3302
 
 
3303
 
        GNOME_Evolution_Calendar_Cal_getFreeBusy (ecal->priv->cal, &corba_users, start, end, &ev);
3304
 
 
3305
 
        CORBA_free (corba_users._buffer);
3306
 
 
3307
 
        if (BONOBO_EX (&ev)) {
3308
 
                e_calendar_remove_op (ecal, our_op);
3309
 
                e_calendar_free_op (our_op);
3310
 
 
3311
 
                CORBA_exception_free (&ev);
3312
 
 
3313
 
                g_warning (G_STRLOC ": Unable to contact backend");
3314
 
 
 
2525
                users_list[i] = g_strdup (l->data);
 
2526
 
 
2527
        LOCK_CONN ();
 
2528
        if (!org_gnome_evolution_dataserver_calendar_Cal_get_free_busy (priv->proxy, (const gchar **)users_list, start, end, &freebusy_array, error)) {
 
2529
                UNLOCK_CONN ();
 
2530
                g_strfreev (users_list);
3315
2531
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
3316
2532
        }
3317
 
 
3318
 
        CORBA_exception_free (&ev);
3319
 
 
3320
 
        e_flag_wait (our_op->done);
3321
 
 
3322
 
        status = our_op->status;
3323
 
        *freebusy = our_op->list;
3324
 
 
3325
 
        e_calendar_remove_op (ecal, our_op);
3326
 
        e_calendar_free_op (our_op);
3327
 
 
3328
 
        E_CALENDAR_CHECK_STATUS (status, error);
 
2533
        UNLOCK_CONN ();
 
2534
        g_strfreev (users_list);
 
2535
 
 
2536
        if (freebusy_array) {
 
2537
                *freebusy = build_free_busy_list ((const gchar **)freebusy_array);
 
2538
                g_strfreev (freebusy_array);
 
2539
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
 
2540
        } else
 
2541
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OTHER_ERROR, error);
3329
2542
}
3330
2543
 
3331
2544
struct comp_instance {
3547
2760
                                goto try_again;
3548
2761
                        }
3549
2762
 
3550
 
                        g_message ("Failed to get recurrence objects for uid %s \n", error->message);
 
2763
                        g_message ("Failed to get recurrence objects for uid %s \n", error ? error->message : "Unknown error");
3551
2764
                        g_clear_error (&error);
3552
2765
                        return;
3553
2766
                }
3880
3093
 * Queries a calendar for the alarms that trigger in the specified range of
3881
3094
 * time.
3882
3095
 *
3883
 
 * Return value: A list of #ECalComponentAlarms structures.  This should be freed
 
3096
 * Returns: A list of #ECalComponentAlarms structures.  This should be freed
3884
3097
 * using the #e_cal_free_alarms() function, or by freeing each element
3885
3098
 * separately with #e_cal_component_alarms_free() and then freeing the list with
3886
3099
 * #g_slist_free().
3970
3183
 * Queries a calendar for the alarms of a particular object that trigger in the
3971
3184
 * specified range of time.
3972
3185
 *
3973
 
 * Return value: TRUE on success, FALSE if the object was not found.
 
3186
 * Returns: TRUE on success, FALSE if the object was not found.
3974
3187
 **/
3975
3188
gboolean
3976
3189
e_cal_get_alarms_for_object (ECal *ecal, const ECalComponentId *id,
3982
3195
        ECalComponent *comp;
3983
3196
        ECalComponentAlarmAction omit[] = {-1};
3984
3197
 
 
3198
        g_return_val_if_fail (alarms != NULL, FALSE);
 
3199
        *alarms = NULL;
 
3200
 
3985
3201
        g_return_val_if_fail (ecal != NULL, FALSE);
3986
3202
        g_return_val_if_fail (E_IS_CAL (ecal), FALSE);
3987
3203
 
3991
3207
        g_return_val_if_fail (id != NULL, FALSE);
3992
3208
        g_return_val_if_fail (start >= 0 && end >= 0, FALSE);
3993
3209
        g_return_val_if_fail (start <= end, FALSE);
3994
 
        g_return_val_if_fail (alarms != NULL, FALSE);
3995
 
 
3996
 
        *alarms = NULL;
3997
3210
 
3998
3211
        if (!e_cal_get_object (ecal, id->uid, id->rid, &icalcomp, NULL))
3999
3212
                return FALSE;
4025
3238
 * update internal information about the alarm be discarded, or, like
4026
3239
 * the file backend does, ignore the operation.
4027
3240
 *
4028
 
 * Return value: TRUE if the operation was successful, FALSE otherwise.
 
3241
 * Returns: TRUE if the operation was successful, FALSE otherwise.
4029
3242
 */
4030
3243
gboolean
4031
3244
e_cal_discard_alarm (ECal *ecal, ECalComponent *comp, const gchar *auid, GError **error)
4032
3245
{
4033
3246
        ECalPrivate *priv;
4034
 
        CORBA_Environment ev;
4035
 
        ECalendarStatus status;
4036
 
        ECalendarOp *our_op;
4037
3247
        const gchar *uid;
4038
3248
 
4039
3249
        g_return_val_if_fail (ecal != NULL, FALSE);
4040
3250
        g_return_val_if_fail (E_IS_CAL (ecal), FALSE);
4041
 
 
 
3251
        g_return_val_if_fail (comp != NULL, FALSE);
 
3252
        g_return_val_if_fail (E_IS_CAL_COMPONENT (comp), FALSE);
 
3253
        g_return_val_if_fail (auid != NULL, FALSE);
4042
3254
        priv = ecal->priv;
4043
 
 
4044
 
        g_mutex_lock (ecal->priv->mutex);
4045
 
 
4046
 
        if (ecal->priv->load_state != E_CAL_LOAD_LOADED) {
4047
 
                g_mutex_unlock (ecal->priv->mutex);
 
3255
        e_return_error_if_fail (priv->proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
 
3256
 
 
3257
        if (priv->load_state != E_CAL_LOAD_LOADED) {
4048
3258
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
4049
3259
        }
4050
3260
 
4051
 
        if (ecal->priv->current_op != NULL) {
4052
 
                g_mutex_unlock (ecal->priv->mutex);
4053
 
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
4054
 
        }
4055
 
 
4056
 
        our_op = e_calendar_new_op (ecal, "discard_alarm");
4057
 
 
4058
 
        g_mutex_unlock (ecal->priv->mutex);
4059
 
 
4060
3261
        e_cal_component_get_uid (comp, &uid);
4061
3262
 
4062
 
        CORBA_exception_init (&ev);
4063
 
 
4064
 
        GNOME_Evolution_Calendar_Cal_discardAlarm (priv->cal, uid, auid, &ev);
4065
 
        if (BONOBO_EX (&ev)) {
4066
 
                e_calendar_remove_op (ecal, our_op);
4067
 
                e_calendar_free_op (our_op);
4068
 
 
4069
 
                CORBA_exception_free (&ev);
4070
 
 
4071
 
                g_warning (G_STRLOC ": Unable to contact backend");
4072
 
 
 
3263
        LOCK_CONN ();
 
3264
        if (!org_gnome_evolution_dataserver_calendar_Cal_discard_alarm (priv->proxy, uid, auid, error)) {
 
3265
                UNLOCK_CONN ();
4073
3266
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
4074
3267
        }
4075
 
 
4076
 
        CORBA_exception_free (&ev);
4077
 
 
4078
 
        e_flag_wait (our_op->done);
4079
 
 
4080
 
        status = our_op->status;
4081
 
 
4082
 
        e_calendar_remove_op (ecal, our_op);
4083
 
        e_calendar_free_op (our_op);
4084
 
 
4085
 
        E_CALENDAR_CHECK_STATUS (status, error);
 
3268
        UNLOCK_CONN ();
 
3269
 
 
3270
        E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
4086
3271
}
4087
3272
 
4088
3273
typedef struct _ForeachTZIDCallbackData ForeachTZIDCallbackData;
4182
3367
        gint initial_vcal_string_len;
4183
3368
        ForeachTZIDCallbackData cbdata;
4184
3369
        gchar *obj_string;
4185
 
        ECalPrivate *priv;
4186
 
 
4187
 
        priv = ecal->priv;
4188
3370
 
4189
3371
        timezone_hash = g_hash_table_new (g_str_hash, g_str_equal);
4190
3372
 
4245
3427
 * Gets a calendar component as an iCalendar string, with a toplevel
4246
3428
 * VCALENDAR component and all VTIMEZONEs needed for the component.
4247
3429
 *
4248
 
 * Return value: the component as a complete iCalendar string, or NULL on
 
3430
 * Returns: the component as a complete iCalendar string, or NULL on
4249
3431
 * failure. The string should be freed after use.
4250
3432
 **/
4251
3433
gchar *
4265
3447
 * argument. Some backends would assign a specific UID to the newly created object,
4266
3448
 * in those cases that UID would be returned in the @uid argument.
4267
3449
 *
4268
 
 * Return value: TRUE if the operation was successful, FALSE otherwise.
 
3450
 * Returns: TRUE if the operation was successful, FALSE otherwise.
4269
3451
 */
4270
3452
gboolean
4271
3453
e_cal_create_object (ECal *ecal, icalcomponent *icalcomp, gchar **uid, GError **error)
4272
3454
{
4273
3455
        ECalPrivate *priv;
4274
 
        CORBA_Environment ev;
4275
 
        ECalendarStatus status;
4276
 
        ECalendarOp *our_op;
4277
 
        gchar *obj;
4278
 
 
4279
 
        e_return_error_if_fail (ecal && E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
4280
 
 
 
3456
        gchar *obj, *muid = NULL;
 
3457
 
 
3458
        e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
 
3459
        e_return_error_if_fail (icalcomp != NULL, E_CALENDAR_STATUS_INVALID_ARG);
 
3460
        e_return_error_if_fail (icalcomponent_is_valid (icalcomp), E_CALENDAR_STATUS_INVALID_ARG);
4281
3461
        priv = ecal->priv;
4282
 
 
4283
 
        g_mutex_lock (ecal->priv->mutex);
4284
 
 
4285
 
        if (ecal->priv->load_state != E_CAL_LOAD_LOADED) {
4286
 
                g_mutex_unlock (ecal->priv->mutex);
 
3462
        e_return_error_if_fail (priv->proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
 
3463
 
 
3464
        if (priv->load_state != E_CAL_LOAD_LOADED) {
4287
3465
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
4288
3466
        }
4289
3467
 
4290
 
        if (ecal->priv->current_op != NULL) {
4291
 
                g_mutex_unlock (ecal->priv->mutex);
4292
 
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
4293
 
        }
4294
 
 
4295
 
        our_op = e_calendar_new_op (ecal, "create_object");
4296
 
 
4297
 
        g_mutex_unlock (ecal->priv->mutex);
4298
 
 
4299
 
        CORBA_exception_init (&ev);
4300
 
 
4301
3468
        obj = icalcomponent_as_ical_string_r (icalcomp);
4302
 
        GNOME_Evolution_Calendar_Cal_createObject (priv->cal, obj, &ev);
4303
 
        if (BONOBO_EX (&ev)) {
4304
 
                e_calendar_remove_op (ecal, our_op);
4305
 
                e_calendar_free_op (our_op);
 
3469
        LOCK_CONN ();
 
3470
        if (!org_gnome_evolution_dataserver_calendar_Cal_create_object (priv->proxy, obj, &muid, error)) {
 
3471
                UNLOCK_CONN ();
4306
3472
                g_free (obj);
4307
 
 
4308
 
                CORBA_exception_free (&ev);
4309
 
 
4310
 
                g_warning (G_STRLOC ": Unable to contact backend");
4311
 
 
4312
3473
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
4313
3474
        }
 
3475
        UNLOCK_CONN ();
4314
3476
 
4315
3477
        g_free (obj);
4316
 
        CORBA_exception_free (&ev);
4317
 
 
4318
 
        e_flag_wait (our_op->done);
4319
 
 
4320
 
        status = our_op->status;
4321
 
        if (uid)
4322
 
        {
4323
 
                *uid = our_op->uid;
4324
 
                icalcomponent_set_uid (icalcomp, *uid);
 
3478
 
 
3479
        if (!muid) {
 
3480
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OTHER_ERROR, error);
 
3481
        } else {
 
3482
                icalcomponent_set_uid (icalcomp, muid);
 
3483
 
 
3484
                if (uid)
 
3485
                        *uid = muid;
 
3486
                else
 
3487
                        g_free (muid);
 
3488
 
 
3489
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
4325
3490
        }
4326
 
 
4327
 
        e_calendar_remove_op (ecal, our_op);
4328
 
        e_calendar_free_op (our_op);
4329
 
 
4330
 
        E_CALENDAR_CHECK_STATUS (status, error);
4331
3491
}
4332
3492
 
4333
3493
/**
4345
3505
 * or a specific set of instances (CALOBJ_MOD_THISNADPRIOR and
4346
3506
 * CALOBJ_MOD_THISANDFUTURE).
4347
3507
 *
4348
 
 * Return value: TRUE if the operation was successful, FALSE otherwise.
 
3508
 * Returns: TRUE if the operation was successful, FALSE otherwise.
4349
3509
 */
4350
3510
gboolean
4351
3511
e_cal_modify_object (ECal *ecal, icalcomponent *icalcomp, CalObjModType mod, GError **error)
4352
3512
{
4353
3513
        ECalPrivate *priv;
4354
 
        CORBA_Environment ev;
4355
 
        ECalendarStatus status;
4356
 
        ECalendarOp *our_op;
4357
3514
        gchar *obj;
4358
3515
 
4359
 
        e_return_error_if_fail (ecal && E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
 
3516
        e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
4360
3517
        e_return_error_if_fail (icalcomp, E_CALENDAR_STATUS_INVALID_ARG);
4361
 
 
 
3518
        e_return_error_if_fail (icalcomponent_is_valid (icalcomp), E_CALENDAR_STATUS_INVALID_ARG);
 
3519
        e_return_error_if_fail (mod & CALOBJ_MOD_ALL, E_CALENDAR_STATUS_INVALID_ARG);
4362
3520
        priv = ecal->priv;
4363
 
 
4364
 
        g_mutex_lock (ecal->priv->mutex);
4365
 
 
4366
 
        if (ecal->priv->load_state != E_CAL_LOAD_LOADED) {
4367
 
                g_mutex_unlock (ecal->priv->mutex);
 
3521
        e_return_error_if_fail (priv->proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
 
3522
 
 
3523
        if (priv->load_state != E_CAL_LOAD_LOADED) {
4368
3524
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
4369
3525
        }
4370
3526
 
4371
 
        if (ecal->priv->current_op != NULL) {
4372
 
                g_mutex_unlock (ecal->priv->mutex);
4373
 
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
4374
 
        }
4375
 
 
4376
 
        our_op = e_calendar_new_op (ecal, "modify_object");
4377
 
 
4378
 
        g_mutex_unlock (ecal->priv->mutex);
4379
 
 
4380
 
        CORBA_exception_init (&ev);
4381
 
 
4382
3527
        obj = icalcomponent_as_ical_string_r (icalcomp);
4383
 
        GNOME_Evolution_Calendar_Cal_modifyObject (priv->cal, obj, mod, &ev);
4384
 
        if (BONOBO_EX (&ev)) {
4385
 
                e_calendar_remove_op (ecal, our_op);
4386
 
                e_calendar_free_op (our_op);
 
3528
        LOCK_CONN ();
 
3529
        if (!org_gnome_evolution_dataserver_calendar_Cal_modify_object (priv->proxy, obj, mod, error)) {
 
3530
                UNLOCK_CONN ();
4387
3531
                g_free (obj);
4388
 
 
4389
 
                CORBA_exception_free (&ev);
4390
 
 
4391
 
                g_warning (G_STRLOC ": Unable to contact backend");
4392
 
 
4393
3532
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
4394
3533
        }
 
3534
        UNLOCK_CONN ();
4395
3535
 
4396
3536
        g_free (obj);
4397
 
        CORBA_exception_free (&ev);
4398
 
 
4399
 
        e_flag_wait (our_op->done);
4400
 
 
4401
 
        status = our_op->status;
4402
 
 
4403
 
        e_calendar_remove_op (ecal, our_op);
4404
 
        e_calendar_free_op (our_op);
4405
 
 
4406
 
        E_CALENDAR_CHECK_STATUS (status, error);
 
3537
        E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
4407
3538
}
4408
3539
 
4409
3540
/**
4423
3554
 * signal, while it will get a "obj_removed" signal when all instances
4424
3555
 * are removed.
4425
3556
 *
4426
 
 * Return value: TRUE if the operation was successful, FALSE otherwise.
 
3557
 * Returns: TRUE if the operation was successful, FALSE otherwise.
4427
3558
 */
4428
3559
gboolean
4429
3560
e_cal_remove_object_with_mod (ECal *ecal, const gchar *uid,
4430
3561
                              const gchar *rid, CalObjModType mod, GError **error)
4431
3562
{
4432
3563
        ECalPrivate *priv;
4433
 
        CORBA_Environment ev;
4434
 
        ECalendarStatus status;
4435
 
        ECalendarOp *our_op;
4436
3564
 
4437
 
        e_return_error_if_fail (ecal && E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
 
3565
        e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
4438
3566
        e_return_error_if_fail (uid, E_CALENDAR_STATUS_INVALID_ARG);
4439
 
 
 
3567
        e_return_error_if_fail (mod & CALOBJ_MOD_ALL, E_CALENDAR_STATUS_INVALID_ARG);
4440
3568
        priv = ecal->priv;
4441
 
 
4442
 
        g_mutex_lock (ecal->priv->mutex);
4443
 
 
4444
 
        if (ecal->priv->load_state != E_CAL_LOAD_LOADED) {
4445
 
                g_mutex_unlock (ecal->priv->mutex);
 
3569
        e_return_error_if_fail (priv->proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
 
3570
 
 
3571
        if (priv->load_state != E_CAL_LOAD_LOADED) {
4446
3572
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
4447
3573
        }
4448
3574
 
4449
 
        if (ecal->priv->current_op != NULL) {
4450
 
                g_mutex_unlock (ecal->priv->mutex);
4451
 
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
4452
 
        }
4453
 
 
4454
 
        our_op = e_calendar_new_op (ecal, "remove_object_with_mod");
4455
 
 
4456
 
        g_mutex_unlock (ecal->priv->mutex);
4457
 
 
4458
 
        CORBA_exception_init (&ev);
4459
 
 
4460
 
        GNOME_Evolution_Calendar_Cal_removeObject (priv->cal, uid, rid ? rid : "", mod, &ev);
4461
 
        if (BONOBO_EX (&ev)) {
4462
 
                e_calendar_remove_op (ecal, our_op);
4463
 
                e_calendar_free_op (our_op);
4464
 
 
4465
 
                CORBA_exception_free (&ev);
4466
 
 
4467
 
                g_warning (G_STRLOC ": Unable to contact backend");
4468
 
 
 
3575
        LOCK_CONN ();
 
3576
        if (!org_gnome_evolution_dataserver_calendar_Cal_remove_object (priv->proxy, uid, rid ? rid : "", mod, error)) {
 
3577
                UNLOCK_CONN ();
4469
3578
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
4470
3579
        }
4471
 
 
4472
 
        CORBA_exception_free (&ev);
4473
 
 
4474
 
        e_flag_wait (our_op->done);
4475
 
 
4476
 
        status = our_op->status;
4477
 
 
4478
 
        e_calendar_remove_op (ecal, our_op);
4479
 
        e_calendar_free_op (our_op);
4480
 
 
4481
 
        E_CALENDAR_CHECK_STATUS (status, error);
 
3580
        UNLOCK_CONN ();
 
3581
 
 
3582
        E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
4482
3583
}
4483
3584
 
4484
3585
/**
4491
3592
 * component, all clients will be notified and they will emit the "obj_removed"
4492
3593
 * signal.
4493
3594
 *
4494
 
 * Return value: %TRUE if successful, %FALSE otherwise.
 
3595
 * Returns: %TRUE if successful, %FALSE otherwise.
4495
3596
 **/
4496
3597
gboolean
4497
3598
e_cal_remove_object (ECal *ecal, const gchar *uid, GError **error)
4512
3613
 * @icalcomp argument. This is used for iTIP confirmation/cancellation
4513
3614
 * messages for scheduled meetings.
4514
3615
 *
4515
 
 * Return value: %TRUE if successful, %FALSE otherwise.
 
3616
 * Returns: %TRUE if successful, %FALSE otherwise.
4516
3617
 */
4517
3618
gboolean
4518
3619
e_cal_receive_objects (ECal *ecal, icalcomponent *icalcomp, GError **error)
4519
3620
{
4520
3621
        ECalPrivate *priv;
4521
 
        CORBA_Environment ev;
4522
 
        ECalendarStatus status;
4523
 
        ECalendarOp *our_op;
4524
 
        gchar *obj;
4525
 
 
4526
 
        e_return_error_if_fail (ecal && E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
4527
 
 
 
3622
 
 
3623
        e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
 
3624
        e_return_error_if_fail (icalcomp, E_CALENDAR_STATUS_INVALID_ARG);
 
3625
        e_return_error_if_fail (icalcomponent_is_valid (icalcomp), E_CALENDAR_STATUS_INVALID_ARG);
4528
3626
        priv = ecal->priv;
4529
 
 
4530
 
        g_mutex_lock (ecal->priv->mutex);
4531
 
 
4532
 
        if (ecal->priv->load_state != E_CAL_LOAD_LOADED) {
4533
 
                g_mutex_unlock (ecal->priv->mutex);
 
3627
        e_return_error_if_fail (priv->proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
 
3628
 
 
3629
        if (priv->load_state != E_CAL_LOAD_LOADED) {
4534
3630
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
4535
3631
        }
4536
3632
 
4537
 
        if (ecal->priv->current_op != NULL) {
4538
 
                g_mutex_unlock (ecal->priv->mutex);
4539
 
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
4540
 
        }
4541
 
 
4542
 
        our_op = e_calendar_new_op (ecal, "receive_objects");
4543
 
 
4544
 
        g_mutex_unlock (ecal->priv->mutex);
4545
 
 
4546
 
        CORBA_exception_init (&ev);
4547
 
 
4548
 
        obj = icalcomponent_as_ical_string_r (icalcomp);
4549
 
        GNOME_Evolution_Calendar_Cal_receiveObjects (priv->cal, obj, &ev);
4550
 
        if (BONOBO_EX (&ev)) {
4551
 
                e_calendar_remove_op (ecal, our_op);
4552
 
                e_calendar_free_op (our_op);
4553
 
                g_free (obj);
4554
 
 
4555
 
                CORBA_exception_free (&ev);
4556
 
 
4557
 
                g_warning (G_STRLOC ": Unable to contact backend");
4558
 
 
 
3633
        LOCK_CONN ();
 
3634
        if (!org_gnome_evolution_dataserver_calendar_Cal_receive_objects (priv->proxy, icalcomponent_as_ical_string (icalcomp), error)) {
 
3635
                UNLOCK_CONN ();
4559
3636
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
4560
3637
        }
4561
 
 
4562
 
        g_free (obj);
4563
 
        CORBA_exception_free (&ev);
4564
 
 
4565
 
        e_flag_wait (our_op->done);
4566
 
 
4567
 
        status = our_op->status;
4568
 
 
4569
 
        e_calendar_remove_op (ecal, our_op);
4570
 
        e_calendar_free_op (our_op);
4571
 
 
4572
 
        E_CALENDAR_CHECK_STATUS (status, error);
 
3638
        UNLOCK_CONN ();
 
3639
 
 
3640
        E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
4573
3641
}
4574
3642
 
4575
3643
/**
4584
3652
 * Requests a calendar backend to send meeting information to the specified list
4585
3653
 * of users.
4586
3654
 *
4587
 
 * Return value: TRUE if the operation was successful, FALSE otherwise.
 
3655
 * Returns: TRUE if the operation was successful, FALSE otherwise.
4588
3656
 */
4589
3657
gboolean
4590
3658
e_cal_send_objects (ECal *ecal, icalcomponent *icalcomp, GList **users, icalcomponent **modified_icalcomp, GError **error)
4591
3659
{
4592
3660
        ECalPrivate *priv;
4593
 
        CORBA_Environment ev;
4594
3661
        ECalendarStatus status;
4595
 
        ECalendarOp *our_op;
4596
 
        gchar *obj;
4597
 
 
4598
 
        e_return_error_if_fail (ecal && E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
4599
 
 
 
3662
        gchar **users_array;
 
3663
        gchar *object;
 
3664
 
 
3665
        e_return_error_if_fail (users != NULL, E_CALENDAR_STATUS_INVALID_ARG);
 
3666
        e_return_error_if_fail (modified_icalcomp != NULL, E_CALENDAR_STATUS_INVALID_ARG);
 
3667
        e_return_error_if_fail (icalcomp != NULL, E_CALENDAR_STATUS_INVALID_ARG);
 
3668
        e_return_error_if_fail (icalcomponent_is_valid (icalcomp), E_CALENDAR_STATUS_INVALID_ARG);
 
3669
        e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
4600
3670
        priv = ecal->priv;
4601
 
 
4602
 
        g_mutex_lock (ecal->priv->mutex);
4603
 
 
4604
 
        if (ecal->priv->load_state != E_CAL_LOAD_LOADED) {
4605
 
                g_mutex_unlock (ecal->priv->mutex);
 
3671
        e_return_error_if_fail (priv->proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
 
3672
        *users = NULL;
 
3673
        *modified_icalcomp = NULL;
 
3674
 
 
3675
        if (priv->load_state != E_CAL_LOAD_LOADED) {
4606
3676
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
4607
3677
        }
4608
3678
 
4609
 
        if (ecal->priv->current_op != NULL) {
4610
 
                g_mutex_unlock (ecal->priv->mutex);
4611
 
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
4612
 
        }
4613
 
 
4614
 
        our_op = e_calendar_new_op (ecal, "send_objects");
4615
 
 
4616
 
        g_mutex_unlock (ecal->priv->mutex);
4617
 
 
4618
 
        CORBA_exception_init (&ev);
4619
 
 
4620
 
        obj = icalcomponent_as_ical_string_r (icalcomp);
4621
 
        GNOME_Evolution_Calendar_Cal_sendObjects (priv->cal, obj, &ev);
4622
 
        if (BONOBO_EX (&ev)) {
4623
 
                e_calendar_remove_op (ecal, our_op);
4624
 
                e_calendar_free_op (our_op);
4625
 
                g_free (obj);
4626
 
 
4627
 
                CORBA_exception_free (&ev);
4628
 
 
4629
 
                g_warning (G_STRLOC ": Unable to contact backend");
4630
 
 
 
3679
        LOCK_CONN ();
 
3680
        if (!org_gnome_evolution_dataserver_calendar_Cal_send_objects (priv->proxy, icalcomponent_as_ical_string (icalcomp), &users_array, &object, error)) {
 
3681
                UNLOCK_CONN ();
4631
3682
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
4632
3683
        }
4633
 
 
4634
 
        g_free (obj);
4635
 
        CORBA_exception_free (&ev);
4636
 
 
4637
 
        e_flag_wait (our_op->done);
4638
 
 
4639
 
        status = our_op->status;
4640
 
        *users = our_op->list;
4641
 
        if (status != E_CALENDAR_STATUS_OK) {
4642
 
                *modified_icalcomp = NULL;
4643
 
                g_list_foreach (*users, (GFunc) g_free, NULL);
4644
 
                g_list_free (*users);
4645
 
                *users = NULL;
4646
 
        } else {
4647
 
                *modified_icalcomp = icalparser_parse_string (our_op->string);
4648
 
                if (!(*modified_icalcomp)) {
 
3684
        UNLOCK_CONN ();
 
3685
 
 
3686
        status = E_CALENDAR_STATUS_OK;
 
3687
        if (users_array) {
 
3688
                gchar **user;
 
3689
                *modified_icalcomp = icalparser_parse_string (object);
 
3690
                if (!(*modified_icalcomp))
4649
3691
                        status = E_CALENDAR_STATUS_INVALID_OBJECT;
4650
 
                        g_list_foreach (*users, (GFunc) g_free, NULL);
4651
 
                        g_list_free (*users);
4652
 
                        *users = NULL;
4653
 
                }
4654
 
        }
4655
 
        g_free (our_op->string);
4656
3692
 
4657
 
        e_calendar_remove_op (ecal, our_op);
4658
 
        e_calendar_free_op (our_op);
 
3693
                for (user = users_array; *user; user++)
 
3694
                        *users = g_list_append (*users, g_strdup (*user));
 
3695
                g_strfreev (users_array);
 
3696
        } else
 
3697
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OTHER_ERROR, error);
4659
3698
 
4660
3699
        E_CALENDAR_CHECK_STATUS (status, error);
4661
3700
}
4669
3708
 *
4670
3709
 * Retrieves a timezone object from the calendar backend.
4671
3710
 *
4672
 
 * Return value: TRUE if the operation was successful, FALSE otherwise.
 
3711
 * Returns: TRUE if the operation was successful, FALSE otherwise.
4673
3712
 */
4674
3713
gboolean
4675
3714
e_cal_get_timezone (ECal *ecal, const gchar *tzid, icaltimezone **zone, GError **error)
4676
3715
{
4677
3716
        ECalPrivate *priv;
4678
 
        CORBA_Environment ev;
4679
3717
        ECalendarStatus status = E_CALENDAR_STATUS_OK;
4680
 
        ECalendarOp *our_op;
4681
3718
        icalcomponent *icalcomp = NULL;
4682
 
        const gchar *systzid;
 
3719
        gchar *object;
 
3720
        const gchar *systzid = NULL;
4683
3721
 
4684
 
        e_return_error_if_fail (ecal && E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
4685
3722
        e_return_error_if_fail (zone, E_CALENDAR_STATUS_INVALID_ARG);
4686
 
 
 
3723
        e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
4687
3724
        priv = ecal->priv;
4688
 
 
4689
 
        g_mutex_lock (priv->mutex);
4690
 
 
4691
 
        if (ecal->priv->load_state != E_CAL_LOAD_LOADED) {
4692
 
                g_mutex_unlock (ecal->priv->mutex);
 
3725
        e_return_error_if_fail (priv->proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
 
3726
        *zone = NULL;
 
3727
 
 
3728
        if (priv->load_state != E_CAL_LOAD_LOADED) {
4693
3729
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
4694
3730
        }
4695
3731
 
4696
 
        if (ecal->priv->current_op != NULL) {
4697
 
                g_mutex_unlock (ecal->priv->mutex);
4698
 
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
4699
 
        }
4700
 
 
4701
 
        our_op = e_calendar_new_op (ecal, "get_timezone");
4702
 
 
4703
 
        g_mutex_unlock (priv->mutex);
4704
 
 
4705
3732
        /* Check for well known zones and in the cache */
4706
 
        *zone = NULL;
4707
 
 
4708
3733
        /* If tzid is NULL or "" we return NULL, since it is a 'local time'. */
4709
3734
        if (!tzid || !tzid[0]) {
4710
 
                e_calendar_remove_op (ecal, our_op);
4711
 
                e_calendar_free_op (our_op);
4712
 
 
4713
 
                *zone = NULL;
4714
 
 
4715
3735
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
4716
3736
        }
4717
3737
 
4724
3744
        }
4725
3745
 
4726
3746
        if (*zone) {
4727
 
                e_calendar_remove_op (ecal, our_op);
4728
 
                e_calendar_free_op (our_op);
4729
 
 
4730
3747
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
4731
3748
        }
4732
3749
 
4740
3757
        systzid = e_cal_match_tzid (tzid);
4741
3758
        if (!systzid) {
4742
3759
                /* call the backend */
4743
 
                CORBA_exception_init (&ev);
4744
 
 
4745
 
                GNOME_Evolution_Calendar_Cal_getTimezone (priv->cal, tzid, &ev);
4746
 
                if (BONOBO_EX (&ev)) {
4747
 
                        e_calendar_remove_op (ecal, our_op);
4748
 
                        e_calendar_free_op (our_op);
4749
 
 
4750
 
                        CORBA_exception_free (&ev);
4751
 
 
4752
 
                        g_warning (G_STRLOC ": Unable to contact backend");
4753
 
 
 
3760
                LOCK_CONN ();
 
3761
                if (!org_gnome_evolution_dataserver_calendar_Cal_get_timezone (priv->proxy, tzid, &object, error)) {
 
3762
                        UNLOCK_CONN ();
4754
3763
                        E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
4755
3764
                }
4756
 
 
4757
 
                CORBA_exception_free (&ev);
4758
 
 
4759
 
                e_flag_wait (our_op->done);
4760
 
 
4761
 
                status = our_op->status;
4762
 
                if (status != E_CALENDAR_STATUS_OK) {
4763
 
                        icalcomp = NULL;
4764
 
                } else {
4765
 
                        icalcomp = icalparser_parse_string (our_op->string);
4766
 
                        if (!icalcomp)
4767
 
                                status = E_CALENDAR_STATUS_INVALID_OBJECT;
4768
 
                }
4769
 
                g_free (our_op->string);
 
3765
                UNLOCK_CONN ();
 
3766
 
 
3767
                icalcomp = icalparser_parse_string (object);
 
3768
                if (!icalcomp)
 
3769
                        status = E_CALENDAR_STATUS_INVALID_OBJECT;
 
3770
                g_free (object);
4770
3771
        } else {
4771
3772
                /*
4772
3773
                 * Use built-in time zone *and* rename it:
4798
3799
        }
4799
3800
 
4800
3801
        if (!icalcomp) {
4801
 
                e_calendar_remove_op (ecal, our_op);
4802
 
                e_calendar_free_op (our_op);
4803
 
 
4804
3802
                E_CALENDAR_CHECK_STATUS (status, error);
4805
3803
        }
4806
3804
 
4807
3805
        *zone = icaltimezone_new ();
4808
3806
        if (!icaltimezone_set_component (*zone, icalcomp)) {
4809
3807
                icaltimezone_free (*zone, 1);
4810
 
 
4811
 
                e_calendar_remove_op (ecal, our_op);
4812
 
                e_calendar_free_op (our_op);
4813
 
 
4814
3808
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OBJECT_NOT_FOUND, error);
4815
3809
        }
4816
3810
 
4817
3811
        /* Now add it to the cache, to avoid the server call in future. */
4818
3812
        g_hash_table_insert (priv->timezones, (gpointer) icaltimezone_get_tzid (*zone), *zone);
4819
3813
 
4820
 
        e_calendar_remove_op (ecal, our_op);
4821
 
        e_calendar_free_op (our_op);
4822
 
 
4823
3814
        E_CALENDAR_CHECK_STATUS (status, error);
4824
3815
}
4825
3816
 
4837
3828
e_cal_add_timezone (ECal *ecal, icaltimezone *izone, GError **error)
4838
3829
{
4839
3830
        ECalPrivate *priv;
4840
 
        CORBA_Environment ev;
4841
 
        ECalendarStatus status;
4842
 
        ECalendarOp *our_op;
4843
3831
        gchar *tzobj;
4844
3832
        icalcomponent *icalcomp;
4845
3833
 
4846
 
        e_return_error_if_fail (ecal && E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
 
3834
        e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
4847
3835
        e_return_error_if_fail (izone, E_CALENDAR_STATUS_INVALID_ARG);
4848
 
 
4849
3836
        priv = ecal->priv;
4850
 
 
4851
 
        g_mutex_lock (priv->mutex);
4852
 
 
4853
 
        if (ecal->priv->load_state != E_CAL_LOAD_LOADED) {
4854
 
                g_mutex_unlock (ecal->priv->mutex);
 
3837
        e_return_error_if_fail (priv->proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
 
3838
 
 
3839
        if (priv->load_state != E_CAL_LOAD_LOADED) {
4855
3840
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
4856
3841
        }
4857
3842
 
4858
 
        if (ecal->priv->current_op != NULL) {
4859
 
                g_mutex_unlock (ecal->priv->mutex);
4860
 
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
4861
 
        }
4862
 
 
4863
 
        our_op = e_calendar_new_op (ecal, "add_timezone");
4864
 
 
4865
 
        g_mutex_unlock (priv->mutex);
4866
 
 
4867
3843
        /* Make sure we have a valid component - UTC doesn't, nor do
4868
3844
         * we really have to add it */
4869
3845
        if (izone == icaltimezone_get_utc_timezone ()) {
4870
 
                e_calendar_remove_op (ecal, our_op);
4871
 
                e_calendar_free_op (our_op);
4872
 
 
4873
3846
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
4874
3847
        }
4875
3848
 
4876
3849
        icalcomp = icaltimezone_get_component (izone);
4877
3850
        if (!icalcomp) {
4878
 
                e_calendar_remove_op (ecal, our_op);
4879
 
                e_calendar_free_op (our_op);
4880
 
 
4881
3851
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_INVALID_ARG, error);
4882
3852
        }
4883
3853
 
4885
3855
        tzobj = icalcomponent_as_ical_string_r (icalcomp);
4886
3856
 
4887
3857
        /* call the backend */
4888
 
        CORBA_exception_init (&ev);
4889
 
 
4890
 
        GNOME_Evolution_Calendar_Cal_addTimezone (priv->cal, tzobj, &ev);
4891
 
        if (BONOBO_EX (&ev)) {
4892
 
                e_calendar_remove_op (ecal, our_op);
4893
 
                e_calendar_free_op (our_op);
 
3858
        LOCK_CONN ();
 
3859
        if (!org_gnome_evolution_dataserver_calendar_Cal_add_timezone (priv->proxy, tzobj, error)) {
 
3860
                UNLOCK_CONN ();
4894
3861
                g_free (tzobj);
4895
 
 
4896
 
                CORBA_exception_free (&ev);
4897
 
 
4898
 
                g_warning (G_STRLOC ": Unable to contact backend");
4899
 
 
4900
3862
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
4901
3863
        }
 
3864
        UNLOCK_CONN ();
4902
3865
 
4903
3866
        g_free (tzobj);
4904
 
        CORBA_exception_free (&ev);
4905
 
 
4906
 
        e_flag_wait (our_op->done);
4907
 
 
4908
 
        status = our_op->status;
4909
 
 
4910
 
        e_calendar_remove_op (ecal, our_op);
4911
 
        e_calendar_free_op (our_op);
4912
 
 
4913
 
        E_CALENDAR_CHECK_STATUS (status, error);
 
3867
        E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
4914
3868
}
4915
3869
 
4916
3870
/**
4922
3876
 *
4923
3877
 * Creates a live query object from a loaded calendar.
4924
3878
 *
4925
 
 * Return value: A query object that will emit notification signals as calendar
 
3879
 * Returns: A query object that will emit notification signals as calendar
4926
3880
 * components are added and removed from the query in the server.
4927
3881
 **/
4928
3882
gboolean
4929
3883
e_cal_get_query (ECal *ecal, const gchar *sexp, ECalView **query, GError **error)
4930
3884
{
4931
 
        CORBA_Environment ev;
4932
 
        ECalendarOp *our_op;
 
3885
        ECalPrivate *priv;
4933
3886
        ECalendarStatus status;
 
3887
        gchar *query_path;
 
3888
        DBusGProxy *query_proxy;
4934
3889
 
4935
 
        e_return_error_if_fail (ecal && E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
 
3890
        e_return_error_if_fail (sexp, E_CALENDAR_STATUS_INVALID_ARG);
4936
3891
        e_return_error_if_fail (query, E_CALENDAR_STATUS_INVALID_ARG);
4937
 
 
4938
 
        g_mutex_lock (ecal->priv->mutex);
4939
 
 
4940
 
        if (ecal->priv->load_state != E_CAL_LOAD_LOADED) {
4941
 
                g_mutex_unlock (ecal->priv->mutex);
 
3892
        e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
 
3893
        priv = ecal->priv;
 
3894
        e_return_error_if_fail (priv->proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
 
3895
        *query = NULL;
 
3896
 
 
3897
        if (priv->load_state != E_CAL_LOAD_LOADED) {
4942
3898
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
4943
3899
        }
4944
3900
 
4945
 
        if (ecal->priv->current_op != NULL) {
4946
 
                g_mutex_unlock (ecal->priv->mutex);
4947
 
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
4948
 
        }
4949
 
 
4950
 
        our_op = e_calendar_new_op (ecal, "get_query");
4951
 
 
4952
 
        g_mutex_unlock (ecal->priv->mutex);
4953
 
 
4954
 
        CORBA_exception_init (&ev);
4955
 
 
4956
 
        our_op->listener = e_cal_view_listener_new ();
4957
 
        GNOME_Evolution_Calendar_Cal_getQuery (ecal->priv->cal, sexp, BONOBO_OBJREF (our_op->listener), &ev);
4958
 
 
4959
 
        if (BONOBO_EX (&ev)) {
4960
 
                e_calendar_remove_op (ecal, our_op);
4961
 
                e_calendar_free_op (our_op);
4962
 
 
4963
 
                CORBA_exception_free (&ev);
4964
 
 
4965
 
                g_warning (G_STRLOC ": Unable to contact backend");
4966
 
 
 
3901
        LOCK_CONN ();
 
3902
        if (!org_gnome_evolution_dataserver_calendar_Cal_get_query (priv->proxy, sexp, &query_path, error)) {
 
3903
                UNLOCK_CONN ();
4967
3904
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
4968
3905
        }
4969
 
 
4970
 
        CORBA_exception_free (&ev);
4971
 
 
4972
 
        e_flag_wait (our_op->done);
4973
 
 
4974
 
        status = our_op->status;
4975
 
        *query = our_op->query;
4976
 
 
4977
 
        bonobo_object_unref (BONOBO_OBJECT (our_op->listener));
4978
 
 
4979
 
        e_calendar_remove_op (ecal, our_op);
4980
 
        e_calendar_free_op (our_op);
 
3906
        UNLOCK_CONN ();
 
3907
 
 
3908
        status = E_CALENDAR_STATUS_OK;
 
3909
 
 
3910
        LOCK_CONN ();
 
3911
        query_proxy = dbus_g_proxy_new_for_name_owner (connection,
 
3912
                                                "org.gnome.evolution.dataserver.Calendar", query_path,
 
3913
                                                "org.gnome.evolution.dataserver.calendar.CalView", error);
 
3914
        UNLOCK_CONN ();
 
3915
 
 
3916
        if (!query_proxy) {
 
3917
                *query = NULL;
 
3918
                status = E_CALENDAR_STATUS_OTHER_ERROR;
 
3919
        } else {
 
3920
                *query = _e_cal_view_new (ecal, query_proxy, &connection_lock);
 
3921
        }
 
3922
 
 
3923
        g_object_unref (query_proxy);
4981
3924
 
4982
3925
        E_CALENDAR_CHECK_STATUS (status, error);
4983
3926
}
4991
3934
 * Sets the default timezone on the calendar. This should be called before opening
4992
3935
 * the calendar.
4993
3936
 *
4994
 
 * Return value: TRUE if the operation was successful, FALSE otherwise.
 
3937
 * Returns: TRUE if the operation was successful, FALSE otherwise.
4995
3938
 */
4996
3939
gboolean
4997
3940
e_cal_set_default_timezone (ECal *ecal, icaltimezone *zone, GError **error)
4998
3941
{
4999
3942
        ECalPrivate *priv;
5000
 
        CORBA_Environment ev;
5001
 
        ECalendarStatus status;
5002
 
        ECalendarOp *our_op;
5003
3943
        icalcomponent *icalcomp = NULL;
5004
3944
        gchar *tzobj;
5005
3945
 
5006
 
        e_return_error_if_fail (ecal && E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
 
3946
        e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
5007
3947
        e_return_error_if_fail (zone, E_CALENDAR_STATUS_INVALID_ARG);
5008
 
 
5009
3948
        priv = ecal->priv;
 
3949
        e_return_error_if_fail (priv->proxy, E_CALENDAR_STATUS_REPOSITORY_OFFLINE);
5010
3950
 
5011
 
        /* Don't set the same timezone multiple times */
 
3951
        /* If the same timezone is already set, we don't have to do anything. */
5012
3952
        if (priv->default_zone == zone)
5013
 
                return FALSE;
5014
 
 
5015
 
        g_mutex_lock (priv->mutex);
5016
 
 
5017
 
        if (ecal->priv->current_op != NULL) {
5018
 
                g_mutex_unlock (ecal->priv->mutex);
5019
 
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
5020
 
        }
5021
 
 
5022
 
        our_op = e_calendar_new_op (ecal, "set_default_timezone");
5023
 
 
5024
 
        g_mutex_unlock (priv->mutex);
 
3953
                return TRUE;
5025
3954
 
5026
3955
        /* FIXME Adding it to the server to change the tzid */
5027
3956
        icalcomp = icaltimezone_get_component (zone);
5028
3957
        if (!icalcomp) {
5029
 
                e_calendar_remove_op (ecal, our_op);
5030
 
                e_calendar_free_op (our_op);
5031
 
 
5032
3958
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_INVALID_ARG, error);
5033
3959
        }
5034
3960
 
5036
3962
        tzobj = icalcomponent_as_ical_string_r (icalcomp);
5037
3963
 
5038
3964
        /* call the backend */
5039
 
        CORBA_exception_init (&ev);
5040
 
 
5041
 
        GNOME_Evolution_Calendar_Cal_setDefaultTimezone (priv->cal, tzobj, &ev);
5042
 
        if (BONOBO_EX (&ev)) {
5043
 
                e_calendar_remove_op (ecal, our_op);
5044
 
                e_calendar_free_op (our_op);
 
3965
        LOCK_CONN ();
 
3966
        if (!org_gnome_evolution_dataserver_calendar_Cal_set_default_timezone (priv->proxy, tzobj, error)) {
 
3967
                UNLOCK_CONN ();
5045
3968
                g_free (tzobj);
5046
 
 
5047
 
                CORBA_exception_free (&ev);
5048
 
 
5049
 
                g_warning (G_STRLOC ": Unable to contact backend");
5050
 
 
5051
3969
                E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
5052
3970
        }
 
3971
        UNLOCK_CONN ();
5053
3972
 
5054
3973
        g_free (tzobj);
5055
 
        CORBA_exception_free (&ev);
5056
 
 
5057
 
        e_flag_wait (our_op->done);
5058
 
 
5059
 
        status = our_op->status;
5060
 
 
5061
 
        /* set the default timezone internally if successful */
5062
 
        if (our_op->status == E_CALENDAR_STATUS_OK) {
5063
 
                g_mutex_lock (priv->mutex);
5064
 
                priv->default_zone = zone;
5065
 
                g_mutex_unlock (priv->mutex);
5066
 
        }
5067
 
 
5068
 
        e_calendar_remove_op (ecal, our_op);
5069
 
        e_calendar_free_op (our_op);
5070
 
 
5071
 
        E_CALENDAR_CHECK_STATUS (status, error);
 
3974
        priv->default_zone = zone;
 
3975
 
 
3976
        E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
5072
3977
}
5073
3978
 
5074
3979
/**
5130
4035
}
5131
4036
 
5132
4037
static gboolean
5133
 
get_default (ECal **ecal, ESourceList *sources, ECalSourceType type, ECalAuthFunc func, gpointer data, GError **error)
5134
 
{
5135
 
        GSList *g;
 
4038
check_default (ESource *source, gpointer data)
 
4039
{
 
4040
        g_return_val_if_fail (source != NULL, FALSE);
 
4041
 
 
4042
        return e_source_get_property (source, "default") != NULL;
 
4043
}
 
4044
 
 
4045
/**
 
4046
 * e_cal_open_default:
 
4047
 * @ecal: A calendar client.
 
4048
 * @type: Type of the calendar.
 
4049
 * @func: Authentication function.
 
4050
 * @data: Closure data for the authentication function.
 
4051
 * @error: Placeholder for error information.
 
4052
 *
 
4053
 * Opens the default calendar.
 
4054
 *
 
4055
 * Returns: TRUE if it opened correctly, FALSE otherwise.
 
4056
 */
 
4057
gboolean
 
4058
e_cal_open_default (ECal **ecal, ECalSourceType type, ECalAuthFunc func, gpointer data, GError **error)
 
4059
{
5136
4060
        GError *err = NULL;
5137
 
        ESource *default_source = NULL;
5138
 
        gboolean rv = TRUE;
5139
 
 
5140
 
        for (g = e_source_list_peek_groups (sources); g; g = g->next) {
5141
 
                ESourceGroup *group = E_SOURCE_GROUP (g->data);
5142
 
                GSList *s;
5143
 
                for (s = e_source_group_peek_sources (group); s; s = s->next) {
5144
 
                        ESource *source = E_SOURCE (s->data);
5145
 
 
5146
 
                        if (e_source_get_property (source, "default")) {
5147
 
                                default_source = source;
5148
 
                                break;
5149
 
                        }
5150
 
                }
5151
 
 
5152
 
                if (default_source)
5153
 
                        break;
 
4061
        ESource *default_source;
 
4062
        gboolean res = TRUE;
 
4063
 
 
4064
        e_return_error_if_fail (ecal != NULL, E_CALENDAR_STATUS_INVALID_ARG);
 
4065
        *ecal = NULL;
 
4066
 
 
4067
        default_source = search_known_sources (type, check_default, NULL, &err);
 
4068
 
 
4069
        if (err) {
 
4070
                g_propagate_error (error, err);
 
4071
                return FALSE;
5154
4072
        }
5155
4073
 
5156
4074
        if (default_source) {
5157
4075
                *ecal = e_cal_new (default_source, type);
5158
 
                if (!*ecal) {
5159
 
                        g_propagate_error (error, err);
5160
 
                        rv = FALSE;
5161
 
                        goto done;
5162
 
                }
5163
 
 
5164
 
                e_cal_set_auth_func (*ecal, func, data);
5165
 
                if (!e_cal_open (*ecal, TRUE, &err)) {
5166
 
                        g_propagate_error (error, err);
5167
 
                        rv = FALSE;
5168
 
                        goto done;
5169
 
                }
5170
4076
        } else {
5171
4077
                switch (type) {
5172
4078
                case E_CAL_SOURCE_TYPE_EVENT:
5181
4087
                default:
5182
4088
                        break;
5183
4089
                }
5184
 
 
5185
 
                if (!*ecal) {
5186
 
                        g_propagate_error (error, err);
5187
 
                        rv = FALSE;
5188
 
                        goto done;
5189
 
                }
5190
 
 
 
4090
        }
 
4091
 
 
4092
        if (!*ecal) {
 
4093
                g_propagate_error (error, err);
 
4094
                res = FALSE;
 
4095
        } else {
5191
4096
                e_cal_set_auth_func (*ecal, func, data);
5192
4097
                if (!e_cal_open (*ecal, TRUE, &err)) {
5193
4098
                        g_propagate_error (error, err);
5194
 
                        rv = FALSE;
5195
 
                        goto done;
 
4099
                        res = FALSE;
5196
4100
                }
5197
4101
        }
5198
4102
 
5199
 
 done:
5200
 
        if (!rv && *ecal) {
 
4103
        if (!res && *ecal) {
5201
4104
                g_object_unref (*ecal);
5202
4105
                *ecal = NULL;
5203
4106
        }
5204
 
        g_object_unref (sources);
5205
 
 
5206
 
        return rv;
5207
 
}
5208
 
 
5209
 
/**
5210
 
 * e_cal_open_default:
5211
 
 * @ecal: A calendar client.
5212
 
 * @type: Type of the calendar.
5213
 
 * @func: Authentication function.
5214
 
 * @data: Closure data for the authentication function.
5215
 
 * @error: Placeholder for error information.
5216
 
 *
5217
 
 * Opens the default calendar.
5218
 
 *
5219
 
 * Return value: TRUE if it opened correctly, FALSE otherwise.
5220
 
 */
5221
 
gboolean
5222
 
e_cal_open_default (ECal **ecal, ECalSourceType type, ECalAuthFunc func, gpointer data, GError **error)
5223
 
{
5224
 
        ESourceList *sources;
5225
 
        GError *err = NULL;
5226
 
 
5227
 
        if (!e_cal_get_sources (&sources, type, &err)) {
5228
 
                g_propagate_error (error, err);
5229
 
                return FALSE;
5230
 
        }
5231
 
 
5232
 
        return get_default (ecal, sources, type, func, data, error);
 
4107
 
 
4108
        return res;
5233
4109
}
5234
4110
 
5235
4111
/**
5239
4115
 *
5240
4116
 * Sets a calendar as the default one.
5241
4117
 *
5242
 
 * Return value: TRUE if the operation was successful, FALSE otherwise.
 
4118
 * Returns: TRUE if the operation was successful, FALSE otherwise.
5243
4119
 */
5244
4120
gboolean
5245
4121
e_cal_set_default (ECal *ecal, GError **error)
5304
4180
 *
5305
4181
 * Sets the default source for the specified @type.
5306
4182
 *
5307
 
 * Return value: TRUE if the operation was successful, FALSE otherwise.
 
4183
 * Returns: TRUE if the operation was successful, FALSE otherwise.
5308
4184
 */
5309
4185
gboolean
5310
4186
e_cal_set_default_source (ESource *source, ECalSourceType type, GError **error)
5339
4215
 *
5340
4216
 * Gets the list of sources defined in the configuration for the given @type.
5341
4217
 *
5342
 
 * Return value: TRUE if the operation was successful, FALSE otherwise.
 
4218
 * Returns: TRUE if the operation was successful, FALSE otherwise.
5343
4219
 */
5344
4220
gboolean
5345
4221
e_cal_get_sources (ESourceList **sources, ECalSourceType type, GError **error)
5346
4222
{
 
4223
        e_return_error_if_fail (sources != NULL, E_CALENDAR_STATUS_INVALID_ARG);
 
4224
        *sources = NULL;
 
4225
 
5347
4226
        switch (type) {
5348
4227
        case E_CAL_SOURCE_TYPE_EVENT:
5349
4228
                return get_sources (sources, "/apps/evolution/calendar/sources", error);