[gnome-calendar/wip/gbsneto/alarms: 6/12] event: add support for alarms
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-calendar/wip/gbsneto/alarms: 6/12] event: add support for alarms
- Date: Wed, 6 Jul 2016 06:02:01 +0000 (UTC)
commit 1ddc690810b26c92206ae10431c17ff6970c483c
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date: Sun Jun 19 11:56:25 2016 -0300
event: add support for alarms
This commit prepares GcalEvent to handle alarms. Basically,
it is now able to load the current alarms of an event, and add
and remove alarms for them.
src/gcal-event.c | 209 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/gcal-event.h | 9 +++
2 files changed, 218 insertions(+), 0 deletions(-)
---
diff --git a/src/gcal-event.c b/src/gcal-event.c
index 9cc61a8..f2f9623 100644
--- a/src/gcal-event.c
+++ b/src/gcal-event.c
@@ -43,6 +43,9 @@ struct _GcalEvent
gboolean all_day;
+ /* A map of GcalAlarmType */
+ GHashTable *alarms;
+
ECalComponent *component;
ESource *source;
};
@@ -187,6 +190,65 @@ gcal_event_update_uid_internal (GcalEvent *self)
g_object_notify (G_OBJECT (self), "uid");
}
+static gint
+get_trigger_minutes (GcalEvent *self,
+ ECalComponentAlarm *alarm)
+{
+ ECalComponentAlarmTrigger trigger;
+ GDateTime *alarm_dt;
+ gint diff;
+
+ e_cal_component_alarm_get_trigger (alarm, &trigger);
+
+ /*
+ * We only support alarms relative to the start date, and solely
+ * ignore whetever different it may be.
+ */
+ if (trigger.type != E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START)
+ return -1;
+
+ alarm_dt = g_date_time_add_full (self->dt_start,
+ 0,
+ 0,
+ - (trigger.u.rel_duration.days + trigger.u.rel_duration.weeks * 7),
+ - trigger.u.rel_duration.hours,
+ - trigger.u.rel_duration.minutes,
+ - trigger.u.rel_duration.seconds);
+
+ diff = g_date_time_difference (self->dt_start, alarm_dt) / G_TIME_SPAN_MINUTE;
+
+ return diff;
+}
+
+static void
+load_alarms (GcalEvent *self)
+{
+ GList *alarm_uids, *l;
+
+ alarm_uids = e_cal_component_get_alarm_uids (self->component);
+
+ for (l = alarm_uids; l != NULL; l = l->next)
+ {
+ ECalComponentAlarm *alarm;
+ gint trigger_minutes;
+
+ alarm = e_cal_component_get_alarm (self->component, l->data);
+ trigger_minutes = get_trigger_minutes (self, alarm);
+
+ /* We only support a single alarm for a given time */
+ if (!g_hash_table_contains (self->alarms, GINT_TO_POINTER (trigger_minutes)))
+ {
+ g_hash_table_insert (self->alarms,
+ GINT_TO_POINTER (trigger_minutes),
+ g_strdup (e_cal_component_alarm_get_uid (alarm)));
+ }
+
+ e_cal_component_alarm_free (alarm);
+ }
+
+ cal_obj_uid_list_free (alarm_uids);
+}
+
static void
gcal_event_set_component_internal (GcalEvent *self,
ECalComponent *component)
@@ -253,6 +315,9 @@ gcal_event_set_component_internal (GcalEvent *self,
/* Setup UID */
gcal_event_update_uid_internal (self);
+ /* Load and setup the alarms */
+ load_alarms (self);
+
g_object_notify (G_OBJECT (self), "component");
g_object_notify (G_OBJECT (self), "location");
g_object_notify (G_OBJECT (self), "summary");
@@ -555,6 +620,9 @@ gcal_event_init (GcalEvent *self)
/* Default color of events */
gdk_rgba_parse (&rgba, "#ffffff");
self->color = gdk_rgba_copy (&rgba);
+
+ /* Alarms */
+ self->alarms = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
}
/**
@@ -847,6 +915,147 @@ gcal_event_has_alarms (GcalEvent *self)
}
/**
+ * gcal_event_get_alarms:
+ * @self: a #GcalEvent
+ *
+ * Retrieves the alarms available for @self.
+ *
+ * Returns: (transfer full): a #GList of #ECalComponentAlarm.
+ */
+GList*
+gcal_event_get_alarms (GcalEvent *self)
+{
+ GHashTable *tmp;
+ GList *alarm_uids, *alarms, *l;
+
+ g_return_val_if_fail (GCAL_IS_EVENT (self), NULL);
+
+ tmp = g_hash_table_new (g_direct_hash, g_direct_equal);
+ alarms = NULL;
+ alarm_uids = e_cal_component_get_alarm_uids (self->component);
+
+ for (l = alarm_uids; l != NULL; l = l->next)
+ {
+ ECalComponentAlarm *alarm;
+ gint trigger_minutes;
+
+ alarm = e_cal_component_get_alarm (self->component, l->data);
+ trigger_minutes = get_trigger_minutes (self, alarm);
+
+ /* We only support a single alarm for a given time */
+ if (!g_hash_table_contains (tmp, GINT_TO_POINTER (trigger_minutes)))
+ {
+ alarms = g_list_prepend (alarms, alarm);
+
+ g_hash_table_insert (tmp, GINT_TO_POINTER (trigger_minutes), NULL);
+ }
+ else
+ {
+ e_cal_component_alarm_free (alarm);
+ }
+ }
+
+ cal_obj_uid_list_free (alarm_uids);
+ g_hash_table_destroy (tmp);
+
+ return alarms;
+}
+
+/**
+ * gcal_event_add_alarm:
+ * @self: a #GcalEvent
+ * @type: the minutes before the start date to trigger the alarm
+ * @has_sound: whether the alarm plays a sound or not
+ *
+ * Adds an alarm to @self that triggers @type minutes before the event's
+ * start date.
+ *
+ * If there's already an alarm for @type, it'll be replaced.
+ */
+void
+gcal_event_add_alarm (GcalEvent *self,
+ guint type,
+ gboolean has_sound)
+{
+ ECalComponentAlarmTrigger trigger;
+ ECalComponentAlarmAction action;
+ ECalComponentAlarm *alarm;
+ gchar *alarm_uid;
+
+ g_return_if_fail (GCAL_IS_EVENT (self));
+
+ /* Only 1 alarm per relative time */
+ if (g_hash_table_contains (self->alarms, GINT_TO_POINTER (type)))
+ {
+ const gchar *alarm_uid;
+
+ alarm_uid = g_hash_table_lookup (self->alarms, GINT_TO_POINTER (type));
+
+ e_cal_component_remove_alarm (self->component, alarm_uid);
+ }
+
+ /* Alarm */
+ alarm = e_cal_component_alarm_new ();
+
+ /* Setup the alarm trigger */
+ trigger.type = E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START;
+
+ trigger.u.rel_duration = icaldurationtype_null_duration ();
+ trigger.u.rel_duration.is_neg = TRUE;
+ trigger.u.rel_duration.minutes = type;
+
+ e_cal_component_alarm_set_trigger (alarm, trigger);
+
+ /* Action */
+ if (has_sound)
+ action = E_CAL_COMPONENT_ALARM_AUDIO;
+ else
+ action = E_CAL_COMPONENT_ALARM_DISPLAY;
+
+ e_cal_component_alarm_set_action (alarm, action);
+
+ /* Add the alarm to the component */
+ e_cal_component_add_alarm (self->component, alarm);
+
+ /* Add to the hash table */
+ alarm_uid = g_strdup (e_cal_component_alarm_get_uid (alarm));
+
+ g_hash_table_insert (self->alarms, GINT_TO_POINTER (type), alarm_uid);
+
+ e_cal_component_alarm_free (alarm);
+}
+
+/**
+ * gcal_event_remove_alarm:
+ * @self: a #GcalEvent
+ * @type: the minutes before the start date to trigger the alarm
+ *
+ * Removes an alarm from @self that triggers @type minutes before the event's
+ * start date.
+ *
+ * If there's no alarm set for @type, nothing happens.
+ */
+void
+gcal_event_remove_alarm (GcalEvent *self,
+ guint type)
+{
+ g_return_if_fail (GCAL_IS_EVENT (self));
+
+ /* Only 1 alarm per relative time */
+ if (g_hash_table_contains (self->alarms, GINT_TO_POINTER (type)))
+ {
+ const gchar *alarm_uid;
+
+ alarm_uid = g_hash_table_lookup (self->alarms, GINT_TO_POINTER (type));
+
+ e_cal_component_remove_alarm (self->component, alarm_uid);
+
+ g_hash_table_remove (self->alarms, GINT_TO_POINTER (type));
+ }
+}
+
+
+/**
* gcal_event_get_location:
* @self: a #GcalEvent
*
diff --git a/src/gcal-event.h b/src/gcal-event.h
index f3eca91..16dc19a 100644
--- a/src/gcal-event.h
+++ b/src/gcal-event.h
@@ -62,6 +62,15 @@ void gcal_event_set_description (GcalEvent
gboolean gcal_event_has_alarms (GcalEvent *self);
+GList* gcal_event_get_alarms (GcalEvent *self);
+
+void gcal_event_add_alarm (GcalEvent *self,
+ guint type,
+ gboolean has_sound);
+
+void gcal_event_remove_alarm (GcalEvent *self,
+ guint type);
+
const gchar* gcal_event_get_location (GcalEvent *self);
void gcal_event_set_location (GcalEvent *self,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]