From daccfe0b40f0da7e8de96a350e99fe8c31bfd867 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 8 Oct 2013 20:53:41 -0500 Subject: add a uri-searching subtask whenever we find an appointment --- src/planner-eds.c | 198 +++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 165 insertions(+), 33 deletions(-) diff --git a/src/planner-eds.c b/src/planner-eds.c index f121a32..dd41428 100644 --- a/src/planner-eds.c +++ b/src/planner-eds.c @@ -54,16 +54,23 @@ indicator_datetime_appt_free (struct IndicatorDatetimeAppt * appt) g_date_time_unref (appt->begin); g_free (appt->color); g_free (appt->summary); + g_free (appt->url); g_slice_free (struct IndicatorDatetimeAppt, appt); } } /*** -**** my_get_appointments() helpers +**** +**** my_get_appointments() helpers +**** ***/ -struct get_appointments_task_data +/* whole-task data that all the subtasks can see */ +struct appointment_task_data { + /* a ref to the planner's cancellable */ + GCancellable * cancellable; + /* how many subtasks are still running on */ int subtask_count; @@ -74,47 +81,164 @@ struct get_appointments_task_data GHashTable * added; }; +static struct appointment_task_data * +appointment_task_data_new (GCancellable * cancellable) +{ + struct appointment_task_data * data; + + data = g_slice_new0 (struct appointment_task_data); + data->added = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + data->cancellable = g_object_ref (cancellable); + return data; +} + static void -get_appointments_task_data_free (gpointer gdata) +appointment_task_data_free (gpointer gdata) { - struct get_appointments_task_data * data = gdata; + struct appointment_task_data * data = gdata; + + g_object_unref (data->cancellable); g_hash_table_unref (data->added); - g_slice_free (struct get_appointments_task_data, data); + g_slice_free (struct appointment_task_data, data); } static void -on_all_subtasks_done (GTask * task) +appointment_task_done (GTask * task) { - struct get_appointments_task_data * data = g_task_get_task_data (task); + struct appointment_task_data * data = g_task_get_task_data (task); + g_task_return_pointer (task, data->appointments, NULL); g_object_unref (task); } -struct get_appointments_subtask_data +static void +appointment_task_decrement_subtasks (GTask * task) +{ + struct appointment_task_data * data = g_task_get_task_data (task); + + if (g_atomic_int_dec_and_test (&data->subtask_count)) + appointment_task_done (task); +} + +static void +appointment_task_increment_subtasks (GTask * task) { + struct appointment_task_data * data = g_task_get_task_data (task); + + g_atomic_int_inc (&data->subtask_count); +} + +/** +*** get-the-appointment's-uri subtasks +**/ + +struct appointment_uri_subtask_data +{ + /* The parent task */ GTask * task; - gchar * color; + /* The appointment whose uri we're looking for. + This pointer is owned by the Task and isn't reffed/unreffed by the subtask */ + struct IndicatorDatetimeAppt * appt; }; static void -on_subtask_done (gpointer gsubdata) +appointment_uri_subtask_done (struct appointment_uri_subtask_data * subdata) +{ + GTask * task = subdata->task; + + /* free the subtask data */ + g_slice_free (struct appointment_uri_subtask_data, subdata); + + appointment_task_decrement_subtasks (task); +} + +static struct appointment_uri_subtask_data * +appointment_uri_subtask_data_new (GTask * task, struct IndicatorDatetimeAppt * appt) +{ + struct appointment_uri_subtask_data * subdata; + + appointment_task_increment_subtasks (task); + + subdata = g_slice_new0 (struct appointment_uri_subtask_data); + subdata->task = task; + subdata->appt = appt; + return subdata; +} + +static void +on_appointment_uris_ready (GObject * client, + GAsyncResult * res, + gpointer gsubdata) +{ + GSList * uris; + GError * error; + struct appointment_uri_subtask_data * subdata = gsubdata; + + uris = NULL; + error = NULL; + e_cal_client_get_attachment_uris_finish (E_CAL_CLIENT(client), res, &uris, &error); + if (error != NULL) + { + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("Error getting appointment uris: %s", error->message); + + g_error_free (error); + } + else if (uris != NULL) + { + struct IndicatorDatetimeAppt * appt = subdata->appt; + appt->url = g_strdup (uris->data); /* copy the first URL */ + g_debug ("found url '%s' for appointment '%s'", appt->url, appt->summary); + e_client_util_free_string_slist (uris); + } + + appointment_uri_subtask_done (subdata); +} + +/** +*** enumerate-the-components subtasks +**/ + +/* data struct for the enumerate-components subtask */ +struct appointment_component_subtask_data { - struct get_appointments_subtask_data * subdata; + /* The parent task */ GTask * task; - struct get_appointments_task_data * data; - subdata = gsubdata; - task = subdata->task; + /* The client we're walking through. The subtask owns a ref to this */ + ECalClient * client; + + /* The appointment's color coding. The subtask owns this string */ + gchar * color; +}; + +static void +on_appointment_component_subtask_done (gpointer gsubdata) +{ + struct appointment_component_subtask_data * subdata = gsubdata; + GTask * task = subdata->task; /* free the subtask data */ g_free (subdata->color); - g_slice_free (struct get_appointments_subtask_data, subdata); + g_object_unref (subdata->client); + g_slice_free (struct appointment_component_subtask_data, subdata); - /* poke the task */ - data = g_task_get_task_data (task); - if (g_atomic_int_dec_and_test (&data->subtask_count)) - on_all_subtasks_done (task); + appointment_task_decrement_subtasks (task); +} + +static struct appointment_component_subtask_data * +appointment_component_subtask_data_new (GTask * task, ECalClient * client, const gchar * color) +{ + struct appointment_component_subtask_data * subdata; + + appointment_task_increment_subtasks (task); + + subdata = g_slice_new0 (struct appointment_component_subtask_data); + subdata->task = task; + subdata->client = g_object_ref (client); + subdata->color = g_strdup (color); + return subdata; } static gboolean @@ -124,8 +248,8 @@ my_get_appointments_foreach (ECalComponent * component, gpointer gsubdata) { const ECalComponentVType vtype = e_cal_component_get_vtype (component); - struct get_appointments_subtask_data * subdata = gsubdata; - struct get_appointments_task_data * data = g_task_get_task_data (subdata->task); + struct appointment_component_subtask_data * subdata = gsubdata; + struct appointment_task_data * data = g_task_get_task_data (subdata->task); if ((vtype == E_CAL_COMPONENT_EVENT) || (vtype == E_CAL_COMPONENT_TODO)) { @@ -145,6 +269,7 @@ my_get_appointments_foreach (ECalComponent * component, GSList * recur_list; ECalComponentText text; struct IndicatorDatetimeAppt * appt; + struct appointment_uri_subtask_data * uri_subdata; appt = g_slice_new0 (struct IndicatorDatetimeAppt); @@ -176,6 +301,15 @@ my_get_appointments_foreach (ECalComponent * component, data->appointments = g_slist_prepend (data->appointments, appt); g_hash_table_add (data->added, g_strdup(uid)); + + /* start a new subtask to get the associated URIs */ + uri_subdata = appointment_uri_subtask_data_new (subdata->task, appt); + e_cal_client_get_attachment_uris (subdata->client, + uid, + NULL, + data->cancellable, + on_appointment_uris_ready, + uri_subdata); } } @@ -197,7 +331,6 @@ my_get_appointments (IndicatorDatetimePlanner * planner, priv_t * p; const char * str; icaltimezone * default_timezone; - struct get_appointments_task_data * data; const int64_t begin = g_date_time_to_unix (begin_datetime); const int64_t end = g_date_time_to_unix (end_datetime); GTask * task; @@ -223,17 +356,18 @@ my_get_appointments (IndicatorDatetimePlanner * planner, *** walk through the sources to build the appointment list **/ - data = g_slice_new0 (struct get_appointments_task_data); - data->added = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); task = g_task_new (planner, p->cancellable, callback, user_data); - g_task_set_task_data (task, data, get_appointments_task_data_free); + g_task_set_task_data (task, + appointment_task_data_new (p->cancellable), + appointment_task_data_free); subtasks_added = FALSE; for (l=p->sources; l!=NULL; l=l->next) { ESource * source; ECalClient * client; - struct get_appointments_subtask_data * subdata; + const char * color; + struct appointment_component_subtask_data * subdata; source = l->data; client = g_object_get_qdata (l->data, source_client_quark()); @@ -243,11 +377,9 @@ my_get_appointments (IndicatorDatetimePlanner * planner, if (default_timezone != NULL) e_cal_client_set_default_timezone (client, default_timezone); - subdata = g_slice_new (struct get_appointments_subtask_data); - subdata->task = task; - subdata->color = e_source_selectable_dup_color (e_source_get_extension (source, E_SOURCE_EXTENSION_CALENDAR)); - - g_atomic_int_inc (&data->subtask_count); + /* start a new subtask to enumerate all the components in this client. */ + color = e_source_selectable_get_color (e_source_get_extension (source, E_SOURCE_EXTENSION_CALENDAR)); + subdata = appointment_component_subtask_data_new (task, client, color); subtasks_added = TRUE; e_cal_client_generate_instances (client, begin, @@ -255,11 +387,11 @@ my_get_appointments (IndicatorDatetimePlanner * planner, p->cancellable, my_get_appointments_foreach, subdata, - on_subtask_done); + on_appointment_component_subtask_done); } if (!subtasks_added) - on_all_subtasks_done (task); + appointment_task_done (task); } static GSList * -- cgit v1.2.3