aboutsummaryrefslogtreecommitdiff
path: root/src/planner-eds.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/planner-eds.c')
-rw-r--r--src/planner-eds.c219
1 files changed, 164 insertions, 55 deletions
diff --git a/src/planner-eds.c b/src/planner-eds.c
index f121a32..876fdfc 100644
--- a/src/planner-eds.c
+++ b/src/planner-eds.c
@@ -43,78 +43,180 @@ G_DEFINE_QUARK ("source-client", source_client)
/***
****
+**** my_get_appointments() helpers
+****
***/
-void
-indicator_datetime_appt_free (struct IndicatorDatetimeAppt * appt)
+/* whole-task data that all the subtasks can see */
+struct appointment_task_data
{
- if (appt != NULL)
- {
- g_date_time_unref (appt->end);
- g_date_time_unref (appt->begin);
- g_free (appt->color);
- g_free (appt->summary);
- g_slice_free (struct IndicatorDatetimeAppt, appt);
- }
-}
-
-/***
-**** my_get_appointments() helpers
-***/
+ /* a ref to the planner's cancellable */
+ GCancellable * cancellable;
-struct get_appointments_task_data
-{
/* how many subtasks are still running on */
int subtask_count;
/* the list of appointments to be returned */
GSList * appointments;
-
- /* ensure that recurring events don't get multiple IndicatorDatetimeAppts */
- 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->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;
- g_hash_table_unref (data->added);
- g_slice_free (struct get_appointments_task_data, data);
+ struct appointment_task_data * data = gdata;
+
+ g_object_unref (data->cancellable);
+
+ 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)
{
- struct get_appointments_subtask_data * subdata;
+ 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
+{
+ /* 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 +226,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))
{
@@ -136,7 +238,6 @@ my_get_appointments_foreach (ECalComponent * component,
e_cal_component_get_status (component, &status);
if ((uid != NULL) &&
- (!g_hash_table_contains (data->added, uid)) &&
(status != ICAL_STATUS_COMPLETED) &&
(status != ICAL_STATUS_CANCELLED))
{
@@ -145,6 +246,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);
@@ -169,13 +271,22 @@ my_get_appointments_foreach (ECalComponent * component,
appt->color = g_strdup (subdata->color);
appt->is_event = vtype == E_CAL_COMPONENT_EVENT;
appt->summary = g_strdup (text.value);
+ appt->uid = g_strdup (uid);
alarm_uids = e_cal_component_get_alarm_uids (component);
appt->has_alarms = alarm_uids != NULL;
cal_obj_uid_list_free (alarm_uids);
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 +308,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 +333,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 +354,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 +364,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 *
@@ -270,7 +379,7 @@ my_get_appointments_finish (IndicatorDatetimePlanner * self G_GNUC_UNUSED,
return g_task_propagate_pointer (G_TASK(res), error);
}
-gboolean
+static gboolean
my_is_configured (IndicatorDatetimePlanner * planner)
{
IndicatorDatetimePlannerEds * self;