~ubuntu-branches/ubuntu/oneiric/almanah/oneiric

« back to all changes in this revision

Viewing changes to src/event-factories/calendar-sources.c

  • Committer: Bazaar Package Importer
  • Author(s): Stefan Ebner
  • Date: 2009-05-16 15:49:21 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20090516154921-2uhvlj8btb4qygmd
Tags: 0.6.1-0ubuntu1
* New upstream release (LP: #368078)
* debian/control:
  - Bump Standards-Version to 3.8.1
  - Add intltool, libedataserver1.2-dev, libedataserverui1.2-dev, 
    libecal1.2-dev, libcryptui-dev as build dependency
  - Remove build dependency on autotools-dev and chrpath
* debian/{control/compat/rules}: Move to mimalistic dh7 style
* Update debian/watch
* Update copyright information

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2004 Free Software Foundation, Inc.
 
3
 *
 
4
 * This program is free software; you can redistribute it and/or
 
5
 * modify it under the terms of the GNU General Public License as
 
6
 * published by the Free Software Foundation; either version 2 of the
 
7
 * License, or (at your option) any later version.
 
8
 *
 
9
 * This program is distributed in the hope that it will be useful, but
 
10
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
12
 * General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU General Public License
 
15
 * along with this program; if not, write to the Free Software
 
16
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 
17
 * 02111-1307, USA.
 
18
 *
 
19
 * Authors:
 
20
 *     Mark McLoughlin  <mark@skynet.ie>
 
21
 *     William Jon McCann  <mccann@jhu.edu>
 
22
 *     Martin Grimme  <martin@pycage.de>
 
23
 *     Christian Kellner  <gicmo@xatom.net>
 
24
 */
 
25
 
 
26
#include <config.h>
 
27
 
 
28
#include "calendar-sources.h"
 
29
 
 
30
#include <libintl.h>
 
31
#include <string.h>
 
32
#include <gconf/gconf-client.h>
 
33
#define HANDLE_LIBICAL_MEMORY
 
34
#include <libecal/e-cal.h>
 
35
#include <libedataserver/e-source-list.h>
 
36
#include <libedataserverui/e-passwords.h>
 
37
 
 
38
#undef CALENDAR_ENABLE_DEBUG
 
39
#include "calendar-debug.h"
 
40
 
 
41
#ifndef _
 
42
#define _(x) gettext(x)
 
43
#endif
 
44
 
 
45
#ifndef N_
 
46
#define N_(x) x
 
47
#endif
 
48
 
 
49
#define CALENDAR_SOURCES_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CALENDAR_TYPE_SOURCES, CalendarSourcesPrivate))
 
50
 
 
51
#define CALENDAR_SOURCES_EVO_DIR                          "/apps/evolution"
 
52
#define CALENDAR_SOURCES_APPOINTMENT_SOURCES_KEY          CALENDAR_SOURCES_EVO_DIR "/calendar/sources"
 
53
#define CALENDAR_SOURCES_SELECTED_APPOINTMENT_SOURCES_DIR CALENDAR_SOURCES_EVO_DIR "/calendar/display"
 
54
#define CALENDAR_SOURCES_SELECTED_APPOINTMENT_SOURCES_KEY CALENDAR_SOURCES_SELECTED_APPOINTMENT_SOURCES_DIR "/selected_calendars"
 
55
#define CALENDAR_SOURCES_TASK_SOURCES_KEY                 CALENDAR_SOURCES_EVO_DIR "/tasks/sources"
 
56
#define CALENDAR_SOURCES_SELECTED_TASK_SOURCES_DIR        CALENDAR_SOURCES_EVO_DIR "/calendar/tasks"
 
57
#define CALENDAR_SOURCES_SELECTED_TASK_SOURCES_KEY        CALENDAR_SOURCES_SELECTED_TASK_SOURCES_DIR "/selected_tasks"
 
58
 
 
59
typedef struct _CalendarSourceData CalendarSourceData;
 
60
 
 
61
struct _CalendarSourceData
 
62
{
 
63
  ECalSourceType   source_type;
 
64
  CalendarSources *sources;
 
65
  guint            changed_signal;
 
66
 
 
67
  GSList          *clients;
 
68
  GSList          *selected_sources;
 
69
  ESourceList     *esource_list;
 
70
 
 
71
  guint            selected_sources_listener;
 
72
  char            *selected_sources_dir;
 
73
 
 
74
  guint            timeout_id;
 
75
 
 
76
  guint            loaded : 1;
 
77
};
 
78
 
 
79
struct _CalendarSourcesPrivate
 
80
{
 
81
  CalendarSourceData  appointment_sources;
 
82
  CalendarSourceData  task_sources;
 
83
 
 
84
  GConfClient        *gconf_client;
 
85
};
 
86
 
 
87
static void calendar_sources_class_init (CalendarSourcesClass *klass);
 
88
static void calendar_sources_init       (CalendarSources      *sources);
 
89
static void calendar_sources_finalize   (GObject             *object);
 
90
 
 
91
static void backend_died_cb (ECal *client, CalendarSourceData *source_data);
 
92
static void calendar_sources_esource_list_changed (ESourceList        *source_list,
 
93
                                                   CalendarSourceData *source_data);
 
94
 
 
95
enum
 
96
{
 
97
  APPOINTMENT_SOURCES_CHANGED,
 
98
  TASK_SOURCES_CHANGED,
 
99
  LAST_SIGNAL
 
100
};
 
101
static guint signals [LAST_SIGNAL] = { 0, };
 
102
 
 
103
static GObjectClass    *parent_class = NULL;
 
104
static CalendarSources *calendar_sources_singleton = NULL;
 
105
 
 
106
GType
 
107
calendar_sources_get_type (void)
 
108
{
 
109
  static GType sources_type = 0;
 
110
  
 
111
  if (!sources_type)
 
112
    {
 
113
      static const GTypeInfo sources_info =
 
114
      {
 
115
        sizeof (CalendarSourcesClass),
 
116
        NULL,           /* base_init */
 
117
        NULL,           /* base_finalize */
 
118
        (GClassInitFunc) calendar_sources_class_init,
 
119
        NULL,           /* class_finalize */
 
120
        NULL,           /* class_data */
 
121
        sizeof (CalendarSources),
 
122
        0,              /* n_preallocs */
 
123
        (GInstanceInitFunc) calendar_sources_init,
 
124
      };
 
125
      
 
126
      sources_type = g_type_register_static (G_TYPE_OBJECT,
 
127
                                             "CalendarSources",
 
128
                                             &sources_info, 0);
 
129
    }
 
130
  
 
131
  return sources_type;
 
132
}
 
133
 
 
134
static void
 
135
calendar_sources_class_init (CalendarSourcesClass *klass)
 
136
{
 
137
  GObjectClass *gobject_class = (GObjectClass *) klass;
 
138
 
 
139
  parent_class = g_type_class_peek_parent (klass);
 
140
 
 
141
  gobject_class->finalize = calendar_sources_finalize;
 
142
 
 
143
  g_type_class_add_private (klass, sizeof (CalendarSourcesPrivate));
 
144
 
 
145
  signals [APPOINTMENT_SOURCES_CHANGED] =
 
146
    g_signal_new ("appointment-sources-changed",
 
147
                  G_TYPE_FROM_CLASS (gobject_class),
 
148
                  G_SIGNAL_RUN_LAST,
 
149
                  G_STRUCT_OFFSET (CalendarSourcesClass,
 
150
                                   appointment_sources_changed),
 
151
                  NULL,
 
152
                  NULL,
 
153
                  g_cclosure_marshal_VOID__VOID,
 
154
                  G_TYPE_NONE,
 
155
                  0);
 
156
 
 
157
  signals [TASK_SOURCES_CHANGED] =
 
158
    g_signal_new ("task-sources-changed",
 
159
                  G_TYPE_FROM_CLASS (gobject_class),
 
160
                  G_SIGNAL_RUN_LAST,
 
161
                  G_STRUCT_OFFSET (CalendarSourcesClass,
 
162
                                   task_sources_changed),
 
163
                  NULL,
 
164
                  NULL,
 
165
                  g_cclosure_marshal_VOID__VOID,
 
166
                  G_TYPE_NONE,
 
167
                  0);
 
168
}
 
169
 
 
170
static void
 
171
calendar_sources_init (CalendarSources *sources)
 
172
{
 
173
  sources->priv = CALENDAR_SOURCES_GET_PRIVATE (sources);
 
174
 
 
175
  sources->priv->appointment_sources.source_type    = E_CAL_SOURCE_TYPE_EVENT;
 
176
  sources->priv->appointment_sources.sources        = sources;
 
177
  sources->priv->appointment_sources.changed_signal = signals [APPOINTMENT_SOURCES_CHANGED];
 
178
  sources->priv->appointment_sources.timeout_id     = 0;
 
179
 
 
180
  sources->priv->task_sources.source_type    = E_CAL_SOURCE_TYPE_TODO;
 
181
  sources->priv->task_sources.sources        = sources;
 
182
  sources->priv->task_sources.changed_signal = signals [TASK_SOURCES_CHANGED];
 
183
  sources->priv->task_sources.timeout_id     = 0;
 
184
 
 
185
  sources->priv->gconf_client = gconf_client_get_default ();
 
186
}
 
187
 
 
188
static void
 
189
calendar_sources_finalize_source_data (CalendarSources    *sources,
 
190
                                       CalendarSourceData *source_data)
 
191
{
 
192
  if (source_data->loaded)
 
193
    {
 
194
      GSList *l;
 
195
 
 
196
      if (source_data->selected_sources_dir)
 
197
        {
 
198
          gconf_client_remove_dir (sources->priv->gconf_client,
 
199
                                   source_data->selected_sources_dir,
 
200
                                   NULL);
 
201
 
 
202
          g_free (source_data->selected_sources_dir);
 
203
          source_data->selected_sources_dir = NULL;
 
204
        }
 
205
 
 
206
      if (source_data->selected_sources_listener)
 
207
        {
 
208
          gconf_client_notify_remove (sources->priv->gconf_client,
 
209
                                      source_data->selected_sources_listener);
 
210
          source_data->selected_sources_listener = 0;
 
211
        }
 
212
 
 
213
      for (l = source_data->clients; l; l = l->next)
 
214
        {
 
215
          g_signal_handlers_disconnect_by_func (G_OBJECT (l->data),
 
216
                                                G_CALLBACK (backend_died_cb),
 
217
                                                source_data);
 
218
          g_object_unref (l->data);
 
219
        }
 
220
      g_slist_free (source_data->clients);
 
221
      source_data->clients = NULL;
 
222
 
 
223
      if (source_data->esource_list)
 
224
        {
 
225
          g_signal_handlers_disconnect_by_func (source_data->esource_list,
 
226
                                                G_CALLBACK (calendar_sources_esource_list_changed),
 
227
                                                source_data);
 
228
          g_object_unref (source_data->esource_list);
 
229
        }
 
230
      source_data->esource_list = NULL;
 
231
 
 
232
      for (l = source_data->selected_sources; l; l = l->next)
 
233
        g_free (l->data);
 
234
      g_slist_free (source_data->selected_sources);
 
235
      source_data->selected_sources = NULL;
 
236
 
 
237
      if (source_data->timeout_id != 0)
 
238
        {
 
239
          g_source_remove (source_data->timeout_id);
 
240
          source_data->timeout_id = 0;
 
241
        }
 
242
 
 
243
      source_data->loaded = FALSE;
 
244
    }
 
245
}
 
246
 
 
247
static void
 
248
calendar_sources_finalize (GObject *object)
 
249
{
 
250
  CalendarSources *sources = CALENDAR_SOURCES (object);
 
251
 
 
252
  calendar_sources_finalize_source_data (sources, &sources->priv->appointment_sources);
 
253
  calendar_sources_finalize_source_data (sources, &sources->priv->task_sources);
 
254
 
 
255
  if (sources->priv->gconf_client)
 
256
    g_object_unref (sources->priv->gconf_client);
 
257
  sources->priv->gconf_client = NULL;
 
258
 
 
259
  if (G_OBJECT_CLASS (parent_class)->finalize)
 
260
    G_OBJECT_CLASS (parent_class)->finalize (object);
 
261
}
 
262
 
 
263
CalendarSources *
 
264
calendar_sources_get (void)
 
265
{
 
266
  gpointer singleton_location = &calendar_sources_singleton;
 
267
 
 
268
  if (calendar_sources_singleton)
 
269
    return g_object_ref (calendar_sources_singleton);
 
270
 
 
271
  calendar_sources_singleton = g_object_new (CALENDAR_TYPE_SOURCES, NULL);
 
272
  g_object_add_weak_pointer (G_OBJECT (calendar_sources_singleton),
 
273
                             singleton_location);
 
274
 
 
275
  return calendar_sources_singleton;
 
276
}
 
277
 
 
278
static gboolean
 
279
is_source_selected (ESource *esource,
 
280
                    GSList  *selected_sources)
 
281
{
 
282
  const char *uid;
 
283
  GSList     *l;
 
284
 
 
285
  uid = e_source_peek_uid (esource);
 
286
 
 
287
  for (l = selected_sources; l; l = l->next)
 
288
    {
 
289
      const char *source = l->data;
 
290
 
 
291
      if (!strcmp (source, uid))
 
292
        return TRUE;
 
293
    }
 
294
 
 
295
  return FALSE;
 
296
}
 
297
 
 
298
static char *
 
299
auth_func_cb (ECal       *ecal,
 
300
              const char *prompt,
 
301
              const char *key,
 
302
              gpointer    user_data)
 
303
{
 
304
        ESource *source;
 
305
        const gchar *auth_domain;
 
306
        const gchar *component_name;
 
307
 
 
308
        source = e_cal_get_source (ecal);
 
309
        auth_domain = e_source_get_property (source, "auth-domain");
 
310
        component_name = auth_domain ? auth_domain : "Calendar";
 
311
 
 
312
        return e_passwords_get_password (component_name, key);
 
313
}
 
314
 
 
315
/* The clients are just created here but not loaded */
 
316
static ECal *
 
317
get_ecal_from_source (ESource        *esource,
 
318
                      ECalSourceType  source_type,
 
319
                      GSList         *existing_clients)
 
320
{
 
321
  ECal *retval;
 
322
 
 
323
  if (existing_clients)
 
324
    {
 
325
      GSList *l;
 
326
 
 
327
      for (l = existing_clients; l; l = l->next)
 
328
        {
 
329
          ECal *client = E_CAL (l->data);
 
330
 
 
331
          if (e_source_equal (esource, e_cal_get_source (client)))
 
332
            {
 
333
              dprintf ("        load_esource: found existing source ... returning that\n");
 
334
 
 
335
              return g_object_ref (client);
 
336
            }
 
337
        }
 
338
    }
 
339
 
 
340
  retval = e_cal_new (esource, source_type);
 
341
  if (!retval)
 
342
    {
 
343
      g_warning ("Could not load source '%s' from '%s'\n",
 
344
                 e_source_peek_name (esource),
 
345
                 e_source_peek_relative_uri (esource));
 
346
      return NULL;
 
347
    }
 
348
 
 
349
  e_cal_set_auth_func (retval, auth_func_cb, NULL);
 
350
 
 
351
  return retval;
 
352
}
 
353
 
 
354
/* - Order doesn't matter
 
355
 * - Can just compare object pointers since we
 
356
 *   re-use client connections
 
357
 */
 
358
static gboolean
 
359
compare_ecal_lists (GSList *a,
 
360
                    GSList *b)
 
361
{
 
362
  GSList *l;
 
363
 
 
364
  if (g_slist_length (a) != g_slist_length (b))
 
365
    return FALSE;
 
366
 
 
367
  for (l = a; l; l = l->next)
 
368
    {
 
369
      if (!g_slist_find (b, l->data))
 
370
        return FALSE;
 
371
    }
 
372
 
 
373
  return TRUE;
 
374
}
 
375
 
 
376
static inline void
 
377
debug_dump_selected_sources (GSList *selected_sources)
 
378
{
 
379
#ifdef CALENDAR_ENABLE_DEBUG
 
380
  GSList *l;
 
381
 
 
382
  dprintf ("Selected sources:\n");
 
383
  for (l = selected_sources; l; l = l->next)
 
384
    {
 
385
      char *source = l->data;
 
386
 
 
387
      dprintf ("  %s\n", source);
 
388
    }
 
389
  dprintf ("\n");
 
390
#endif
 
391
}
 
392
 
 
393
static inline void
 
394
debug_dump_ecal_list (GSList *ecal_list)
 
395
{
 
396
#ifdef CALENDAR_ENABLE_DEBUG
 
397
  GSList *l;
 
398
 
 
399
  dprintf ("Loaded clients:\n");
 
400
  for (l = ecal_list; l; l = l->next)
 
401
    {
 
402
      ECal    *client = l->data;
 
403
      ESource *source = e_cal_get_source (client);
 
404
 
 
405
      dprintf ("  %s %s %s\n",
 
406
               e_source_peek_uid (source),
 
407
               e_source_peek_name (source),
 
408
               e_cal_get_uri (client));
 
409
    }
 
410
#endif
 
411
}
 
412
 
 
413
static void
 
414
calendar_sources_load_esource_list (CalendarSourceData *source_data);
 
415
 
 
416
static gboolean
 
417
backend_restart (gpointer data)
 
418
{
 
419
  CalendarSourceData *source_data = data;
 
420
 
 
421
  calendar_sources_load_esource_list (source_data);
 
422
 
 
423
  source_data->timeout_id = 0;
 
424
    
 
425
  return FALSE;
 
426
}
 
427
 
 
428
static void
 
429
backend_died_cb (ECal *client, CalendarSourceData *source_data)
 
430
{
 
431
  const char *uristr;
 
432
 
 
433
  source_data->clients = g_slist_remove (source_data->clients, client);
 
434
  if (g_slist_length (source_data->clients) < 1) 
 
435
    {
 
436
      g_slist_free (source_data->clients);
 
437
      source_data->clients = NULL;
 
438
    }
 
439
  uristr = e_cal_get_uri (client);
 
440
  g_warning ("The calendar backend for %s has crashed.", uristr);
 
441
 
 
442
  if (source_data->timeout_id != 0)
 
443
    {
 
444
      g_source_remove (source_data->timeout_id);
 
445
      source_data->timeout_id = 0;
 
446
    }
 
447
 
 
448
  source_data->timeout_id = g_timeout_add_seconds (2, backend_restart,
 
449
                                                   source_data);
 
450
}
 
451
 
 
452
static void
 
453
calendar_sources_load_esource_list (CalendarSourceData *source_data)
 
454
{
 
455
  GSList  *clients = NULL;
 
456
  GSList  *groups, *l;
 
457
  gboolean emit_signal = FALSE;
 
458
 
 
459
  g_return_if_fail (source_data->esource_list != NULL);
 
460
 
 
461
  debug_dump_selected_sources (source_data->selected_sources);
 
462
 
 
463
  dprintf ("Source groups:\n");
 
464
  groups = e_source_list_peek_groups (source_data->esource_list);
 
465
  for (l = groups; l; l = l->next)
 
466
    {
 
467
      GSList *esources, *s;
 
468
 
 
469
      dprintf ("  %s\n", e_source_group_peek_uid (l->data));
 
470
      dprintf ("    sources:\n");
 
471
 
 
472
      esources = e_source_group_peek_sources (l->data);
 
473
      for (s = esources; s; s = s->next)
 
474
        {
 
475
          ESource *esource = E_SOURCE (s->data);
 
476
          ECal    *client;
 
477
 
 
478
          dprintf ("      type = '%s' uid = '%s', name = '%s', relative uri = '%s': \n",
 
479
                   source_data->source_type == E_CAL_SOURCE_TYPE_EVENT ? "appointment" : "task",
 
480
                   e_source_peek_uid (esource),
 
481
                   e_source_peek_name (esource),
 
482
                   e_source_peek_relative_uri (esource));
 
483
 
 
484
          if (is_source_selected (esource, source_data->selected_sources) &&
 
485
              (client = get_ecal_from_source (esource, source_data->source_type, source_data->clients)))
 
486
            {
 
487
              clients = g_slist_prepend (clients, client);
 
488
            }
 
489
        }
 
490
    }
 
491
  dprintf ("\n");
 
492
 
 
493
  if (source_data->loaded && 
 
494
      !compare_ecal_lists (source_data->clients, clients))
 
495
    emit_signal = TRUE;
 
496
 
 
497
  for (l = source_data->clients; l; l = l->next)
 
498
    {
 
499
      g_signal_handlers_disconnect_by_func (G_OBJECT (l->data),
 
500
                                            G_CALLBACK (backend_died_cb),
 
501
                                            source_data);
 
502
 
 
503
      g_object_unref (l->data);
 
504
    }
 
505
  g_slist_free (source_data->clients);
 
506
  source_data->clients = g_slist_reverse (clients);
 
507
 
 
508
  /* connect to backend_died after we disconnected the previous signal
 
509
   * handlers. If we do it before, we'll lose some handlers (for clients that
 
510
   * were already there before) */
 
511
  for (l = source_data->clients; l; l = l->next)
 
512
    {
 
513
      g_signal_connect (G_OBJECT (l->data), "backend_died",
 
514
                        G_CALLBACK (backend_died_cb), source_data);
 
515
    }
 
516
 
 
517
  if (emit_signal) 
 
518
    {
 
519
      dprintf ("Emitting %s-sources-changed signal\n",
 
520
               source_data->source_type == E_CAL_SOURCE_TYPE_EVENT ? "appointment" : "task");
 
521
      g_signal_emit (source_data->sources, source_data->changed_signal, 0);
 
522
    }
 
523
 
 
524
  debug_dump_ecal_list (source_data->clients);
 
525
}
 
526
 
 
527
static void
 
528
calendar_sources_esource_list_changed (ESourceList        *source_list,
 
529
                                       CalendarSourceData *source_data)
 
530
                                       
 
531
{
 
532
  dprintf ("ESourceList changed, reloading\n");
 
533
 
 
534
  calendar_sources_load_esource_list (source_data);
 
535
}
 
536
 
 
537
static void
 
538
calendar_sources_selected_sources_notify (GConfClient        *client,
 
539
                                          guint               cnx_id,
 
540
                                          GConfEntry         *entry,
 
541
                                          CalendarSourceData *source_data)
 
542
{
 
543
  GSList *l;
 
544
 
 
545
  if (!entry->value ||
 
546
      entry->value->type != GCONF_VALUE_LIST ||
 
547
      gconf_value_get_list_type (entry->value) != GCONF_VALUE_STRING)
 
548
    return;
 
549
 
 
550
  dprintf ("Selected sources key (%s) changed, reloading\n", entry->key);
 
551
 
 
552
  for (l = source_data->selected_sources; l; l = l->next)
 
553
    g_free (l->data);
 
554
  source_data->selected_sources = NULL;
 
555
 
 
556
  for (l = gconf_value_get_list (entry->value); l; l = l->next)
 
557
    {
 
558
      const char *source = gconf_value_get_string (l->data);
 
559
 
 
560
      source_data->selected_sources = 
 
561
        g_slist_prepend (source_data->selected_sources,
 
562
                         g_strdup (source));
 
563
    }
 
564
  source_data->selected_sources =
 
565
    g_slist_reverse (source_data->selected_sources);
 
566
 
 
567
  calendar_sources_load_esource_list (source_data);
 
568
}
 
569
 
 
570
static void
 
571
calendar_sources_load_sources (CalendarSources    *sources,
 
572
                               CalendarSourceData *source_data,
 
573
                               const char         *sources_key,
 
574
                               const char         *selected_sources_key,
 
575
                               const char         *selected_sources_dir)
 
576
{
 
577
  GConfClient *gconf_client;
 
578
  GError      *error;
 
579
 
 
580
  dprintf ("---------------------------\n");
 
581
  dprintf ("Loading sources:\n");
 
582
  dprintf ("  sources_key: %s\n", sources_key);
 
583
  dprintf ("  selected_sources_key: %s\n", selected_sources_key);
 
584
  dprintf ("  selected_sources_dir: %s\n", selected_sources_dir);
 
585
 
 
586
  gconf_client = sources->priv->gconf_client;
 
587
 
 
588
  error = NULL;
 
589
  source_data->selected_sources = gconf_client_get_list (gconf_client,
 
590
                                                         selected_sources_key,
 
591
                                                         GCONF_VALUE_STRING,
 
592
                                                         &error);
 
593
  if (error)
 
594
    {
 
595
      g_warning ("Failed to get selected sources from '%s': %s\n",
 
596
                 selected_sources_key,
 
597
                 error->message);
 
598
      g_error_free (error);
 
599
      return;
 
600
    }
 
601
 
 
602
  gconf_client_add_dir (gconf_client,
 
603
                        selected_sources_dir,
 
604
                        GCONF_CLIENT_PRELOAD_NONE,
 
605
                        NULL);
 
606
  source_data->selected_sources_dir = g_strdup (selected_sources_dir);
 
607
 
 
608
  source_data->selected_sources_listener =
 
609
    gconf_client_notify_add (gconf_client,
 
610
                             selected_sources_dir,
 
611
                             (GConfClientNotifyFunc) calendar_sources_selected_sources_notify,
 
612
                             source_data, NULL, NULL);
 
613
 
 
614
  source_data->esource_list = e_source_list_new_for_gconf (gconf_client, sources_key);
 
615
  g_signal_connect (source_data->esource_list, "changed",
 
616
                    G_CALLBACK (calendar_sources_esource_list_changed),
 
617
                    source_data);
 
618
 
 
619
  calendar_sources_load_esource_list (source_data);
 
620
 
 
621
  source_data->loaded = TRUE;
 
622
 
 
623
  dprintf ("---------------------------\n");
 
624
}
 
625
 
 
626
GSList *
 
627
calendar_sources_get_appointment_sources (CalendarSources *sources)
 
628
{
 
629
  g_return_val_if_fail (CALENDAR_IS_SOURCES (sources), NULL);
 
630
 
 
631
  if (!sources->priv->appointment_sources.loaded)
 
632
    {
 
633
      calendar_sources_load_sources (sources,
 
634
                                     &sources->priv->appointment_sources,
 
635
                                     CALENDAR_SOURCES_APPOINTMENT_SOURCES_KEY,
 
636
                                     CALENDAR_SOURCES_SELECTED_APPOINTMENT_SOURCES_KEY,
 
637
                                     CALENDAR_SOURCES_SELECTED_APPOINTMENT_SOURCES_DIR);
 
638
    }
 
639
  
 
640
  return sources->priv->appointment_sources.clients;
 
641
}
 
642
 
 
643
GSList *
 
644
calendar_sources_get_task_sources (CalendarSources *sources)
 
645
{
 
646
  g_return_val_if_fail (CALENDAR_IS_SOURCES (sources), NULL);
 
647
 
 
648
  if (!sources->priv->task_sources.loaded)
 
649
    {
 
650
      calendar_sources_load_sources (sources,
 
651
                                     &sources->priv->task_sources,
 
652
                                     CALENDAR_SOURCES_TASK_SOURCES_KEY,
 
653
                                     CALENDAR_SOURCES_SELECTED_TASK_SOURCES_KEY,
 
654
                                     CALENDAR_SOURCES_SELECTED_TASK_SOURCES_DIR);
 
655
    }
 
656
 
 
657
  return sources->priv->task_sources.clients;
 
658
}