diff options
Diffstat (limited to 'applets/clock/calendar-sources.c')
-rw-r--r-- | applets/clock/calendar-sources.c | 658 |
1 files changed, 0 insertions, 658 deletions
diff --git a/applets/clock/calendar-sources.c b/applets/clock/calendar-sources.c deleted file mode 100644 index 721ff062..00000000 --- a/applets/clock/calendar-sources.c +++ /dev/null @@ -1,658 +0,0 @@ -/* - * Copyright (C) 2004 Free Software Foundation, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - * - * Authors: - * Mark McLoughlin <[email protected]> - * William Jon McCann <[email protected]> - * Martin Grimme <[email protected]> - * Christian Kellner <[email protected]> - */ - -#include <config.h> - -#include "calendar-sources.h" - -#include <libintl.h> -#include <string.h> -#include <mateconf/mateconf-client.h> -#define HANDLE_LIBICAL_MEMORY -#include <libecal/e-cal.h> -#include <libedataserver/e-source-list.h> -#include <libedataserverui/e-passwords.h> - -#undef CALENDAR_ENABLE_DEBUG -#include "calendar-debug.h" - -#ifndef _ -#define _(x) gettext(x) -#endif - -#ifndef N_ -#define N_(x) x -#endif - -#define CALENDAR_SOURCES_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CALENDAR_TYPE_SOURCES, CalendarSourcesPrivate)) - -#define CALENDAR_SOURCES_EVO_DIR "/apps/evolution" -#define CALENDAR_SOURCES_APPOINTMENT_SOURCES_KEY CALENDAR_SOURCES_EVO_DIR "/calendar/sources" -#define CALENDAR_SOURCES_SELECTED_APPOINTMENT_SOURCES_DIR CALENDAR_SOURCES_EVO_DIR "/calendar/display" -#define CALENDAR_SOURCES_SELECTED_APPOINTMENT_SOURCES_KEY CALENDAR_SOURCES_SELECTED_APPOINTMENT_SOURCES_DIR "/selected_calendars" -#define CALENDAR_SOURCES_TASK_SOURCES_KEY CALENDAR_SOURCES_EVO_DIR "/tasks/sources" -#define CALENDAR_SOURCES_SELECTED_TASK_SOURCES_DIR CALENDAR_SOURCES_EVO_DIR "/calendar/tasks" -#define CALENDAR_SOURCES_SELECTED_TASK_SOURCES_KEY CALENDAR_SOURCES_SELECTED_TASK_SOURCES_DIR "/selected_tasks" - -typedef struct _CalendarSourceData CalendarSourceData; - -struct _CalendarSourceData -{ - ECalSourceType source_type; - CalendarSources *sources; - guint changed_signal; - - GSList *clients; - GSList *selected_sources; - ESourceList *esource_list; - - guint selected_sources_listener; - char *selected_sources_dir; - - guint timeout_id; - - guint loaded : 1; -}; - -struct _CalendarSourcesPrivate -{ - CalendarSourceData appointment_sources; - CalendarSourceData task_sources; - - MateConfClient *mateconf_client; -}; - -static void calendar_sources_class_init (CalendarSourcesClass *klass); -static void calendar_sources_init (CalendarSources *sources); -static void calendar_sources_finalize (GObject *object); - -static void backend_died_cb (ECal *client, CalendarSourceData *source_data); -static void calendar_sources_esource_list_changed (ESourceList *source_list, - CalendarSourceData *source_data); - -enum -{ - APPOINTMENT_SOURCES_CHANGED, - TASK_SOURCES_CHANGED, - LAST_SIGNAL -}; -static guint signals [LAST_SIGNAL] = { 0, }; - -static GObjectClass *parent_class = NULL; -static CalendarSources *calendar_sources_singleton = NULL; - -GType -calendar_sources_get_type (void) -{ - static GType sources_type = 0; - - if (!sources_type) - { - static const GTypeInfo sources_info = - { - sizeof (CalendarSourcesClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) calendar_sources_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (CalendarSources), - 0, /* n_preallocs */ - (GInstanceInitFunc) calendar_sources_init, - }; - - sources_type = g_type_register_static (G_TYPE_OBJECT, - "CalendarSources", - &sources_info, 0); - } - - return sources_type; -} - -static void -calendar_sources_class_init (CalendarSourcesClass *klass) -{ - GObjectClass *gobject_class = (GObjectClass *) klass; - - parent_class = g_type_class_peek_parent (klass); - - gobject_class->finalize = calendar_sources_finalize; - - g_type_class_add_private (klass, sizeof (CalendarSourcesPrivate)); - - signals [APPOINTMENT_SOURCES_CHANGED] = - g_signal_new ("appointment-sources-changed", - G_TYPE_FROM_CLASS (gobject_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (CalendarSourcesClass, - appointment_sources_changed), - NULL, - NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, - 0); - - signals [TASK_SOURCES_CHANGED] = - g_signal_new ("task-sources-changed", - G_TYPE_FROM_CLASS (gobject_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (CalendarSourcesClass, - task_sources_changed), - NULL, - NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, - 0); -} - -static void -calendar_sources_init (CalendarSources *sources) -{ - sources->priv = CALENDAR_SOURCES_GET_PRIVATE (sources); - - sources->priv->appointment_sources.source_type = E_CAL_SOURCE_TYPE_EVENT; - sources->priv->appointment_sources.sources = sources; - sources->priv->appointment_sources.changed_signal = signals [APPOINTMENT_SOURCES_CHANGED]; - sources->priv->appointment_sources.timeout_id = 0; - - sources->priv->task_sources.source_type = E_CAL_SOURCE_TYPE_TODO; - sources->priv->task_sources.sources = sources; - sources->priv->task_sources.changed_signal = signals [TASK_SOURCES_CHANGED]; - sources->priv->task_sources.timeout_id = 0; - - sources->priv->mateconf_client = mateconf_client_get_default (); -} - -static void -calendar_sources_finalize_source_data (CalendarSources *sources, - CalendarSourceData *source_data) -{ - if (source_data->loaded) - { - GSList *l; - - if (source_data->selected_sources_dir) - { - mateconf_client_remove_dir (sources->priv->mateconf_client, - source_data->selected_sources_dir, - NULL); - - g_free (source_data->selected_sources_dir); - source_data->selected_sources_dir = NULL; - } - - if (source_data->selected_sources_listener) - { - mateconf_client_notify_remove (sources->priv->mateconf_client, - source_data->selected_sources_listener); - source_data->selected_sources_listener = 0; - } - - for (l = source_data->clients; l; l = l->next) - { - g_signal_handlers_disconnect_by_func (G_OBJECT (l->data), - G_CALLBACK (backend_died_cb), - source_data); - g_object_unref (l->data); - } - g_slist_free (source_data->clients); - source_data->clients = NULL; - - if (source_data->esource_list) - { - g_signal_handlers_disconnect_by_func (source_data->esource_list, - G_CALLBACK (calendar_sources_esource_list_changed), - source_data); - g_object_unref (source_data->esource_list); - } - source_data->esource_list = NULL; - - for (l = source_data->selected_sources; l; l = l->next) - g_free (l->data); - g_slist_free (source_data->selected_sources); - source_data->selected_sources = NULL; - - if (source_data->timeout_id != 0) - { - g_source_remove (source_data->timeout_id); - source_data->timeout_id = 0; - } - - source_data->loaded = FALSE; - } -} - -static void -calendar_sources_finalize (GObject *object) -{ - CalendarSources *sources = CALENDAR_SOURCES (object); - - calendar_sources_finalize_source_data (sources, &sources->priv->appointment_sources); - calendar_sources_finalize_source_data (sources, &sources->priv->task_sources); - - if (sources->priv->mateconf_client) - g_object_unref (sources->priv->mateconf_client); - sources->priv->mateconf_client = NULL; - - if (G_OBJECT_CLASS (parent_class)->finalize) - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -CalendarSources * -calendar_sources_get (void) -{ - gpointer singleton_location = &calendar_sources_singleton; - - if (calendar_sources_singleton) - return g_object_ref (calendar_sources_singleton); - - calendar_sources_singleton = g_object_new (CALENDAR_TYPE_SOURCES, NULL); - g_object_add_weak_pointer (G_OBJECT (calendar_sources_singleton), - singleton_location); - - return calendar_sources_singleton; -} - -static gboolean -is_source_selected (ESource *esource, - GSList *selected_sources) -{ - const char *uid; - GSList *l; - - uid = e_source_peek_uid (esource); - - for (l = selected_sources; l; l = l->next) - { - const char *source = l->data; - - if (!strcmp (source, uid)) - return TRUE; - } - - return FALSE; -} - -static char * -auth_func_cb (ECal *ecal, - const char *prompt, - const char *key, - gpointer user_data) -{ - ESource *source; - const gchar *auth_domain; - const gchar *component_name; - - source = e_cal_get_source (ecal); - auth_domain = e_source_get_property (source, "auth-domain"); - component_name = auth_domain ? auth_domain : "Calendar"; - - return e_passwords_get_password (component_name, key); -} - -/* The clients are just created here but not loaded */ -static ECal * -get_ecal_from_source (ESource *esource, - ECalSourceType source_type, - GSList *existing_clients) -{ - ECal *retval; - - if (existing_clients) - { - GSList *l; - - for (l = existing_clients; l; l = l->next) - { - ECal *client = E_CAL (l->data); - - if (e_source_equal (esource, e_cal_get_source (client))) - { - dprintf (" load_esource: found existing source ... returning that\n"); - - return g_object_ref (client); - } - } - } - - retval = e_cal_new (esource, source_type); - if (!retval) - { - g_warning ("Could not load source '%s' from '%s'\n", - e_source_peek_name (esource), - e_source_peek_relative_uri (esource)); - return NULL; - } - - e_cal_set_auth_func (retval, auth_func_cb, NULL); - - return retval; -} - -/* - Order doesn't matter - * - Can just compare object pointers since we - * re-use client connections - */ -static gboolean -compare_ecal_lists (GSList *a, - GSList *b) -{ - GSList *l; - - if (g_slist_length (a) != g_slist_length (b)) - return FALSE; - - for (l = a; l; l = l->next) - { - if (!g_slist_find (b, l->data)) - return FALSE; - } - - return TRUE; -} - -static inline void -debug_dump_selected_sources (GSList *selected_sources) -{ -#ifdef CALENDAR_ENABLE_DEBUG - GSList *l; - - dprintf ("Selected sources:\n"); - for (l = selected_sources; l; l = l->next) - { - char *source = l->data; - - dprintf (" %s\n", source); - } - dprintf ("\n"); -#endif -} - -static inline void -debug_dump_ecal_list (GSList *ecal_list) -{ -#ifdef CALENDAR_ENABLE_DEBUG - GSList *l; - - dprintf ("Loaded clients:\n"); - for (l = ecal_list; l; l = l->next) - { - ECal *client = l->data; - ESource *source = e_cal_get_source (client); - - dprintf (" %s %s %s\n", - e_source_peek_uid (source), - e_source_peek_name (source), - e_cal_get_uri (client)); - } -#endif -} - -static void -calendar_sources_load_esource_list (CalendarSourceData *source_data); - -static gboolean -backend_restart (gpointer data) -{ - CalendarSourceData *source_data = data; - - calendar_sources_load_esource_list (source_data); - - source_data->timeout_id = 0; - - return FALSE; -} - -static void -backend_died_cb (ECal *client, CalendarSourceData *source_data) -{ - const char *uristr; - - source_data->clients = g_slist_remove (source_data->clients, client); - if (g_slist_length (source_data->clients) < 1) - { - g_slist_free (source_data->clients); - source_data->clients = NULL; - } - uristr = e_cal_get_uri (client); - g_warning ("The calendar backend for %s has crashed.", uristr); - - if (source_data->timeout_id != 0) - { - g_source_remove (source_data->timeout_id); - source_data->timeout_id = 0; - } - - source_data->timeout_id = g_timeout_add_seconds (2, backend_restart, - source_data); -} - -static void -calendar_sources_load_esource_list (CalendarSourceData *source_data) -{ - GSList *clients = NULL; - GSList *groups, *l; - gboolean emit_signal = FALSE; - - g_return_if_fail (source_data->esource_list != NULL); - - debug_dump_selected_sources (source_data->selected_sources); - - dprintf ("Source groups:\n"); - groups = e_source_list_peek_groups (source_data->esource_list); - for (l = groups; l; l = l->next) - { - GSList *esources, *s; - - dprintf (" %s\n", e_source_group_peek_uid (l->data)); - dprintf (" sources:\n"); - - esources = e_source_group_peek_sources (l->data); - for (s = esources; s; s = s->next) - { - ESource *esource = E_SOURCE (s->data); - ECal *client; - - dprintf (" type = '%s' uid = '%s', name = '%s', relative uri = '%s': \n", - source_data->source_type == E_CAL_SOURCE_TYPE_EVENT ? "appointment" : "task", - e_source_peek_uid (esource), - e_source_peek_name (esource), - e_source_peek_relative_uri (esource)); - - if (is_source_selected (esource, source_data->selected_sources) && - (client = get_ecal_from_source (esource, source_data->source_type, source_data->clients))) - { - clients = g_slist_prepend (clients, client); - } - } - } - dprintf ("\n"); - - if (source_data->loaded && - !compare_ecal_lists (source_data->clients, clients)) - emit_signal = TRUE; - - for (l = source_data->clients; l; l = l->next) - { - g_signal_handlers_disconnect_by_func (G_OBJECT (l->data), - G_CALLBACK (backend_died_cb), - source_data); - - g_object_unref (l->data); - } - g_slist_free (source_data->clients); - source_data->clients = g_slist_reverse (clients); - - /* connect to backend_died after we disconnected the previous signal - * handlers. If we do it before, we'll lose some handlers (for clients that - * were already there before) */ - for (l = source_data->clients; l; l = l->next) - { - g_signal_connect (G_OBJECT (l->data), "backend_died", - G_CALLBACK (backend_died_cb), source_data); - } - - if (emit_signal) - { - dprintf ("Emitting %s-sources-changed signal\n", - source_data->source_type == E_CAL_SOURCE_TYPE_EVENT ? "appointment" : "task"); - g_signal_emit (source_data->sources, source_data->changed_signal, 0); - } - - debug_dump_ecal_list (source_data->clients); -} - -static void -calendar_sources_esource_list_changed (ESourceList *source_list, - CalendarSourceData *source_data) - -{ - dprintf ("ESourceList changed, reloading\n"); - - calendar_sources_load_esource_list (source_data); -} - -static void -calendar_sources_selected_sources_notify (MateConfClient *client, - guint cnx_id, - MateConfEntry *entry, - CalendarSourceData *source_data) -{ - GSList *l; - - if (!entry->value || - entry->value->type != MATECONF_VALUE_LIST || - mateconf_value_get_list_type (entry->value) != MATECONF_VALUE_STRING) - return; - - dprintf ("Selected sources key (%s) changed, reloading\n", entry->key); - - for (l = source_data->selected_sources; l; l = l->next) - g_free (l->data); - source_data->selected_sources = NULL; - - for (l = mateconf_value_get_list (entry->value); l; l = l->next) - { - const char *source = mateconf_value_get_string (l->data); - - source_data->selected_sources = - g_slist_prepend (source_data->selected_sources, - g_strdup (source)); - } - source_data->selected_sources = - g_slist_reverse (source_data->selected_sources); - - calendar_sources_load_esource_list (source_data); -} - -static void -calendar_sources_load_sources (CalendarSources *sources, - CalendarSourceData *source_data, - const char *sources_key, - const char *selected_sources_key, - const char *selected_sources_dir) -{ - MateConfClient *mateconf_client; - GError *error; - - dprintf ("---------------------------\n"); - dprintf ("Loading sources:\n"); - dprintf (" sources_key: %s\n", sources_key); - dprintf (" selected_sources_key: %s\n", selected_sources_key); - dprintf (" selected_sources_dir: %s\n", selected_sources_dir); - - mateconf_client = sources->priv->mateconf_client; - - error = NULL; - source_data->selected_sources = mateconf_client_get_list (mateconf_client, - selected_sources_key, - MATECONF_VALUE_STRING, - &error); - if (error) - { - g_warning ("Failed to get selected sources from '%s': %s\n", - selected_sources_key, - error->message); - g_error_free (error); - return; - } - - mateconf_client_add_dir (mateconf_client, - selected_sources_dir, - MATECONF_CLIENT_PRELOAD_NONE, - NULL); - source_data->selected_sources_dir = g_strdup (selected_sources_dir); - - source_data->selected_sources_listener = - mateconf_client_notify_add (mateconf_client, - selected_sources_dir, - (MateConfClientNotifyFunc) calendar_sources_selected_sources_notify, - source_data, NULL, NULL); - - source_data->esource_list = e_source_list_new_for_mateconf (mateconf_client, sources_key); - g_signal_connect (source_data->esource_list, "changed", - G_CALLBACK (calendar_sources_esource_list_changed), - source_data); - - calendar_sources_load_esource_list (source_data); - - source_data->loaded = TRUE; - - dprintf ("---------------------------\n"); -} - -GSList * -calendar_sources_get_appointment_sources (CalendarSources *sources) -{ - g_return_val_if_fail (CALENDAR_IS_SOURCES (sources), NULL); - - if (!sources->priv->appointment_sources.loaded) - { - calendar_sources_load_sources (sources, - &sources->priv->appointment_sources, - CALENDAR_SOURCES_APPOINTMENT_SOURCES_KEY, - CALENDAR_SOURCES_SELECTED_APPOINTMENT_SOURCES_KEY, - CALENDAR_SOURCES_SELECTED_APPOINTMENT_SOURCES_DIR); - } - - return sources->priv->appointment_sources.clients; -} - -GSList * -calendar_sources_get_task_sources (CalendarSources *sources) -{ - g_return_val_if_fail (CALENDAR_IS_SOURCES (sources), NULL); - - if (!sources->priv->task_sources.loaded) - { - calendar_sources_load_sources (sources, - &sources->priv->task_sources, - CALENDAR_SOURCES_TASK_SOURCES_KEY, - CALENDAR_SOURCES_SELECTED_TASK_SOURCES_KEY, - CALENDAR_SOURCES_SELECTED_TASK_SOURCES_DIR); - } - - return sources->priv->task_sources.clients; -} |