aboutsummaryrefslogtreecommitdiff
path: root/src/planner-eds.c
diff options
context:
space:
mode:
authorCharles Kerr <charles.kerr@canonical.com>2013-10-08 20:53:41 -0500
committerCharles Kerr <charles.kerr@canonical.com>2013-10-08 20:53:41 -0500
commitdaccfe0b40f0da7e8de96a350e99fe8c31bfd867 (patch)
treece8061d7b9b3aa026a692a14209389643024e2ad /src/planner-eds.c
parent414c9ee4a5d04c7d8b1aa893ba68936c3107430b (diff)
downloadayatana-indicator-datetime-daccfe0b40f0da7e8de96a350e99fe8c31bfd867.tar.gz
ayatana-indicator-datetime-daccfe0b40f0da7e8de96a350e99fe8c31bfd867.tar.bz2
ayatana-indicator-datetime-daccfe0b40f0da7e8de96a350e99fe8c31bfd867.zip
add a uri-searching subtask whenever we find an appointment
Diffstat (limited to 'src/planner-eds.c')
-rw-r--r--src/planner-eds.c198
1 files 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 *