From ebed1366e5d62a4fd0912abe2c725f31e8901444 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Wed, 8 Dec 2010 14:48:06 -0500 Subject: Adapt AlarmNotify to the new ESource API. --- calendar/alarm-notify/alarm-notify.c | 437 +++++++---------------------------- 1 file changed, 87 insertions(+), 350 deletions(-) (limited to 'calendar/alarm-notify/alarm-notify.c') diff --git a/calendar/alarm-notify/alarm-notify.c b/calendar/alarm-notify/alarm-notify.c index 2c14196a68..3af3a206a7 100644 --- a/calendar/alarm-notify/alarm-notify.c +++ b/calendar/alarm-notify/alarm-notify.c @@ -27,9 +27,11 @@ #include #include #include -#include #include -#include +#include +#include +#include +#include #include #include "alarm.h" @@ -44,24 +46,11 @@ #define APPLICATION_ID "org.gnome.EvolutionAlarmNotify" struct _AlarmNotifyPrivate { - /* Mapping from EUri's to LoadedClient structures */ - /* FIXME do we need per source type uri hashes? or perhaps we - * just need to hash based on source */ - GHashTable *uri_client_hash[E_CAL_CLIENT_SOURCE_TYPE_LAST]; - ESourceList *source_lists[E_CAL_CLIENT_SOURCE_TYPE_LAST]; - ESourceList *selected_calendars; - GMutex *mutex; - - GSList *offline_sources; - guint offline_timeout_id; + ESourceRegistry *registry; + GHashTable *clients; + GMutex *mutex; }; -typedef struct { - AlarmNotify *an; - ESourceList *source_list; - GList *removals; -} ProcessRemovalsData; - /* Forward Declarations */ static void alarm_notify_initable_init (GInitableIface *interface); @@ -71,206 +60,55 @@ G_DEFINE_TYPE_WITH_CODE ( G_TYPE_INITABLE, alarm_notify_initable_init)) static void -process_removal_in_hash (const gchar *uri, - gpointer value, - ProcessRemovalsData *prd) -{ - GSList *groups, *sources, *p, *q; - gboolean found = FALSE; - - /* search the list of selected calendars */ - groups = e_source_list_peek_groups (prd->source_list); - for (p = groups; p != NULL; p = p->next) { - ESourceGroup *group = E_SOURCE_GROUP (p->data); - - sources = e_source_group_peek_sources (group); - for (q = sources; q != NULL; q = q->next) { - ESource *source = E_SOURCE (q->data); - gchar *source_uri; - const gchar *completion = e_source_get_property (source, "alarm"); - - source_uri = e_source_get_uri (source); - if (strcmp (source_uri, uri) == 0) - if (!completion || !g_ascii_strcasecmp (completion, "true")) - found = TRUE; - - g_free (source_uri); - - if (found) - return; - } - } - - /* not found, so list it for removal */ - prd->removals = g_list_prepend (prd->removals, (gpointer) uri); -} - -static gint -find_slist_source_uri_cb (gconstpointer a, - gconstpointer b) +alarm_notify_load_calendars (AlarmNotify *an) { - ESource *asource = (ESource *) a; - const gchar *buri = b; - gchar *auri; - gint res; - - auri = e_source_get_uri (asource); - res = g_strcmp0 (auri, buri); - g_free (auri); + GList *list, *iter; - return res; -} - -static void -alarm_notify_list_changed_cb (ESourceList *source_list, - AlarmNotify *an) -{ - GSList *groups, *sources, *p, *q; - ECalClientSourceType source_type = E_CAL_CLIENT_SOURCE_TYPE_LAST; - ProcessRemovalsData prd; - GList *l; - gint i; - - g_signal_handlers_block_by_func ( - source_list, alarm_notify_list_changed_cb, an); - - /* Figure out the source type */ - for (i = 0; i < E_CAL_CLIENT_SOURCE_TYPE_LAST; i++) { - if (source_list == an->priv->source_lists[i]) { - source_type = i; - break; - } - } - if (source_type == E_CAL_CLIENT_SOURCE_TYPE_LAST) - return; + /* Add all available ESources. alarm_notify_add_calendar() will + * discard the ones we're not interested in (mail accounts, etc.). */ - /* process the additions */ - groups = e_source_list_peek_groups (source_list); - for (p = groups; p != NULL; p = p->next) { - ESourceGroup *group = E_SOURCE_GROUP (p->data); - - sources = e_source_group_peek_sources (group); - for (q = sources; q != NULL; q = q->next) { - ESource *source = E_SOURCE (q->data); - gchar *uri; - const gchar *alarm; - - alarm = e_source_get_property (source, "alarm"); - - if (alarm && (!g_ascii_strcasecmp (alarm, "false") || - !g_ascii_strcasecmp (alarm, "never"))) - continue; - - uri = e_source_get_uri (source); - if (!g_hash_table_lookup ( - an->priv->uri_client_hash[source_type], uri) && - !g_slist_find_custom ( - an->priv->offline_sources, uri, - find_slist_source_uri_cb)) { - debug (("Adding Calendar %s", uri)); - alarm_notify_add_calendar (an, source_type, source); - } - g_free (uri); - } - } + list = e_source_registry_list_sources (an->priv->registry, NULL); - /* process the removals */ - prd.an = an; - prd.source_list = an->priv->source_lists[source_type]; - prd.removals = NULL; - g_hash_table_foreach ( - an->priv->uri_client_hash[source_type], - (GHFunc) process_removal_in_hash, &prd); - - for (l = prd.removals; l; l = l->next) { - debug (("Removing Calendar %s", (gchar *)l->data)); - alarm_notify_remove_calendar (an, source_type, l->data); - } - g_list_free (prd.removals); - g_signal_handlers_unblock_by_func ( - source_list, alarm_notify_list_changed_cb, an); + for (iter = list; iter != NULL; iter = g_list_next (iter)) + alarm_notify_add_calendar (an, E_SOURCE (iter->data)); + g_list_free_full (list, (GDestroyNotify) g_object_unref); } static void -alarm_notify_load_calendars (AlarmNotify *an, - ECalClientSourceType source_type) +alarm_notify_dispose (GObject *object) { - ESourceList *source_list; - GSList *groups, *sources, *p, *q; - - if (!e_cal_client_get_sources (&source_list, source_type, NULL)) { - debug (("Cannont get sources")); - an->priv->source_lists[source_type] = NULL; - - return; - } - - groups = e_source_list_peek_groups (source_list); - for (p = groups; p != NULL; p = p->next) { - ESourceGroup *group = E_SOURCE_GROUP (p->data); - - sources = e_source_group_peek_sources (group); - for (q = sources; q != NULL; q = q->next) { - ESource *source = E_SOURCE (q->data); - gchar *uri; - const gchar *alarm; - - alarm = e_source_get_property (source, "alarm"); - - if (alarm && ( - !g_ascii_strcasecmp (alarm, "false") || - !g_ascii_strcasecmp (alarm, "never"))) - continue; + AlarmNotifyPrivate *priv; + GHashTableIter iter; + gpointer client; - uri = e_source_get_uri (source); - debug (("Loading Calendar %s", uri)); - alarm_notify_add_calendar (an, source_type, source); - g_free (uri); + priv = ALARM_NOTIFY_GET_PRIVATE (object); - } + if (priv->registry != NULL) { + g_object_unref (priv->registry); + priv->registry = NULL; } - e_source_list_sync (source_list, NULL); - g_signal_connect_object ( - source_list, "changed", - G_CALLBACK (alarm_notify_list_changed_cb), an, 0); - an->priv->source_lists[source_type] = source_list; -} + g_hash_table_iter_init (&iter, priv->clients); + while (g_hash_table_iter_next (&iter, NULL, &client)) + alarm_queue_remove_client (client, TRUE); -static void -alarm_notify_dequeue_client (gpointer key, - ECalClient *client) -{ - alarm_queue_remove_client (client, TRUE); + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (alarm_notify_parent_class)->dispose (object); } static void alarm_notify_finalize (GObject *object) { AlarmNotifyPrivate *priv; - gint ii; priv = ALARM_NOTIFY_GET_PRIVATE (object); - if (priv->offline_timeout_id) - g_source_remove (priv->offline_timeout_id); - priv->offline_timeout_id = 0; - g_slist_free_full (priv->offline_sources, g_object_unref); - priv->offline_sources = NULL; - - for (ii = 0; ii < E_CAL_CLIENT_SOURCE_TYPE_LAST; ii++) { - g_hash_table_foreach ( - priv->uri_client_hash[ii], - (GHFunc) alarm_notify_dequeue_client, NULL); - g_hash_table_destroy (priv->uri_client_hash[ii]); - } + g_hash_table_destroy (priv->clients); alarm_queue_done (); alarm_done (); - e_passwords_shutdown (); - g_mutex_free (priv->mutex); /* Chain up to parent's finalize() method. */ @@ -314,8 +152,23 @@ alarm_notify_initable (GInitable *initable, GCancellable *cancellable, GError **error) { - /* XXX Just return TRUE for now. We'll have use for this soon. */ - return TRUE; + AlarmNotify *an = ALARM_NOTIFY (initable); + + an->priv->registry = e_source_registry_new_sync (cancellable, error); + + if (an->priv->registry != NULL) { + alarm_notify_load_calendars (an); + + g_signal_connect_swapped ( + an->priv->registry, "source-added", + G_CALLBACK (alarm_notify_add_calendar), an); + + g_signal_connect_swapped ( + an->priv->registry, "source-removed", + G_CALLBACK (alarm_notify_remove_calendar), an); + } + + return (an->priv->registry != NULL); } static void @@ -327,6 +180,7 @@ alarm_notify_class_init (AlarmNotifyClass *class) g_type_class_add_private (class, sizeof (AlarmNotifyPrivate)); object_class = G_OBJECT_CLASS (class); + object_class->dispose = alarm_notify_dispose; object_class->finalize = alarm_notify_finalize; application_class = G_APPLICATION_CLASS (class); @@ -344,29 +198,16 @@ alarm_notify_initable_init (GInitableIface *interface) static void alarm_notify_init (AlarmNotify *an) { - gint ii; - an->priv = ALARM_NOTIFY_GET_PRIVATE (an); an->priv->mutex = g_mutex_new (); - an->priv->selected_calendars = config_data_get_calendars ( - "/apps/evolution/calendar/sources"); - for (ii = 0; ii < E_CAL_CLIENT_SOURCE_TYPE_LAST; ii++) - an->priv->uri_client_hash[ii] = g_hash_table_new_full ( - g_str_hash, g_str_equal, - (GDestroyNotify) g_free, - (GDestroyNotify) g_object_unref); + an->priv->clients = g_hash_table_new_full ( + (GHashFunc) e_source_hash, + (GEqualFunc) e_source_equal, + (GDestroyNotify) g_object_unref, + (GDestroyNotify) g_object_unref); alarm_queue_init (an); - - for (ii = 0; ii < E_CAL_CLIENT_SOURCE_TYPE_LAST; ii++) - alarm_notify_load_calendars (an, ii); -} - -ESourceList * -alarm_notify_get_selected_calendars (AlarmNotify *an) -{ - return an->priv->selected_calendars; } /** @@ -385,32 +226,6 @@ alarm_notify_new (GCancellable *cancellable, "application-id", APPLICATION_ID, NULL); } -static gboolean -try_open_offline_timeout_cb (gpointer user_data) -{ - AlarmNotify *an = ALARM_NOTIFY (user_data); - GSList *sources, *iter; - - g_return_val_if_fail (an != NULL, FALSE); - g_return_val_if_fail (an->priv != NULL, FALSE); - - sources = an->priv->offline_sources; - an->priv->offline_sources = NULL; - an->priv->offline_timeout_id = 0; - - for (iter = sources; iter; iter = iter->next) { - ESource *source = iter->data; - - alarm_notify_add_calendar (an, - GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (source), "source-type")), - source); - } - - g_slist_free_full (sources, g_object_unref); - - return FALSE; -} - static void client_opened_cb (GObject *source_object, GAsyncResult *result, @@ -420,36 +235,17 @@ client_opened_cb (GObject *source_object, AlarmNotify *an = ALARM_NOTIFY (user_data); EClient *client = NULL; ECalClient *cal_client; - ECalClientSourceType source_type; - const gchar *uri; - GError *error = NULL; - - e_client_utils_open_new_finish (source, result, &client, &error); - - if (client == NULL) { - if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_REPOSITORY_OFFLINE)) { - if (an->priv->offline_timeout_id) - g_source_remove (an->priv->offline_timeout_id); - an->priv->offline_sources = g_slist_append ( - an->priv->offline_sources, - g_object_ref (source)); - an->priv->offline_timeout_id = - g_timeout_add_seconds ( - 5 * 60, try_open_offline_timeout_cb, an); - } - - g_clear_error (&error); - return; - } + e_client_utils_open_new_finish (source, result, &client, NULL); - cal_client = E_CAL_CLIENT (client); - source_type = e_cal_client_get_source_type (cal_client); - uri = e_client_get_uri (client); + if (client == NULL) + return; g_hash_table_insert ( - an->priv->uri_client_hash[source_type], - g_strdup (uri), cal_client); + an->priv->clients, + g_object_ref (source), client); + + cal_client = E_CAL_CLIENT (client); /* to resolve floating DATE-TIME properly */ e_cal_client_set_default_timezone ( @@ -460,123 +256,64 @@ client_opened_cb (GObject *source_object, /** * alarm_notify_add_calendar: - * @an: An alarm notification service. - * @uri: URI of the calendar to load. + * @an: an #AlarmNotify + * @source: the #ESource to create an #ECal from * - * Tells the alarm notification service to load a calendar and start monitoring - * its alarms. It can optionally be made to save the URI of this calendar so - * that it can be loaded in the future when the alarm daemon starts up. + * Tells the alarm notification service to load a calendar and start + * monitoring its alarms. **/ void alarm_notify_add_calendar (AlarmNotify *an, - ECalClientSourceType source_type, ESource *source) { - AlarmNotifyPrivate *priv; EClientSourceType client_source_type; - EUri *e_uri; - gchar *str_uri; - gchar *pass_key; - g_return_if_fail (an != NULL); - g_return_if_fail (IS_ALARM_NOTIFY (an)); + const gchar *extension_name; - /* Make sure the key used in for getting password is - * properly generated for all types of backends. */ - priv = an->priv; - str_uri = e_source_get_uri (source); - e_uri = e_uri_new (str_uri); - if (e_source_get_property (source, "auth-type")) - pass_key = e_uri_to_string (e_uri, FALSE); - else - pass_key = g_strdup (str_uri); - e_uri_free (e_uri); + g_return_if_fail (IS_ALARM_NOTIFY (an)); g_mutex_lock (an->priv->mutex); - /* See if we already know about this uri */ - if (g_hash_table_lookup (priv->uri_client_hash[source_type], str_uri)) { + + /* Check if we already know about this ESource. */ + if (g_hash_table_lookup (an->priv->clients, source) != NULL) { g_mutex_unlock (an->priv->mutex); - g_free (str_uri); - g_free (pass_key); return; } - /* If loading of this requires password and password is not - * currently availble in e-password session, skip this source - * loading. We do not really want to prompt for auth from - * the alarm dameon. */ - - if (e_source_get_property (source, "auth")) { - - if (!e_passwords_get_password (NULL, pass_key)) { - g_mutex_unlock (an->priv->mutex); - g_free (str_uri); - g_free (pass_key); + /* Check if this is an ESource we're interested in. */ + if (e_source_has_extension (source, E_SOURCE_EXTENSION_CALENDAR)) + client_source_type = E_CLIENT_SOURCE_TYPE_EVENTS; + else if (e_source_has_extension (source, E_SOURCE_EXTENSION_MEMO_LIST)) + client_source_type = E_CLIENT_SOURCE_TYPE_MEMOS; + else if (e_source_has_extension (source, E_SOURCE_EXTENSION_TASK_LIST)) + client_source_type = E_CLIENT_SOURCE_TYPE_TASKS; + else + return; + /* Check if alarms are even wanted on this ESource. */ + extension_name = E_SOURCE_EXTENSION_ALARMS; + if (e_source_has_extension (source, extension_name)) { + ESourceAlarms *extension; + extension = e_source_get_extension (source, extension_name); + if (!e_source_alarms_get_include_me (extension)) return; - } } - debug (("%s - Calendar Open Async... %p", str_uri, source)); - - switch (source_type) { - case E_CAL_CLIENT_SOURCE_TYPE_EVENTS: - client_source_type = E_CLIENT_SOURCE_TYPE_EVENTS; - break; - case E_CAL_CLIENT_SOURCE_TYPE_TASKS: - client_source_type = E_CLIENT_SOURCE_TYPE_TASKS; - break; - case E_CAL_CLIENT_SOURCE_TYPE_MEMOS: - client_source_type = E_CLIENT_SOURCE_TYPE_MEMOS; - break; - default: - g_warn_if_reached (); - client_source_type = E_CLIENT_SOURCE_TYPE_LAST; - } - - g_object_set_data ( - G_OBJECT (source), "source-type", - GUINT_TO_POINTER (source_type)); - e_client_utils_open_new ( source, client_source_type, TRUE, NULL, - e_client_utils_authenticate_handler, NULL, client_opened_cb, an); - g_free (str_uri); - g_free (pass_key); g_mutex_unlock (an->priv->mutex); } void alarm_notify_remove_calendar (AlarmNotify *an, - ECalClientSourceType source_type, - const gchar *str_uri) + ESource *source) { - AlarmNotifyPrivate *priv; ECalClient *cal_client; - GSList *in_offline; - - priv = an->priv; - cal_client = g_hash_table_lookup ( - priv->uri_client_hash[source_type], str_uri); - if (cal_client) { - debug (("Removing Client %p", cal_client)); + cal_client = g_hash_table_lookup (an->priv->clients, source); + if (cal_client != NULL) { alarm_queue_remove_client (cal_client, FALSE); - g_hash_table_remove (priv->uri_client_hash[source_type], str_uri); - } - - in_offline = g_slist_find_custom ( - priv->offline_sources, str_uri, find_slist_source_uri_cb); - if (in_offline) { - ESource *source = in_offline->data; - - priv->offline_sources = g_slist_remove (priv->offline_sources, source); - if (!priv->offline_sources && priv->offline_timeout_id) { - g_source_remove (priv->offline_timeout_id); - priv->offline_timeout_id = 0; - } - - g_object_unref (source); + g_hash_table_remove (an->priv->clients, source); } } -- cgit v1.2.3