static void populate_widgets_from_alarm (Dialog *dialog) { ECalComponentAlarmTrigger *trigger; ECalComponentAlarmAction *action; action = g_new0 (ECalComponentAlarmAction, 1); e_cal_component_alarm_get_action (dialog->alarm, action); g_return_if_fail ( action != NULL ); trigger = g_new0 (ECalComponentAlarmTrigger, 1); e_cal_component_alarm_get_trigger (dialog->alarm, trigger); g_return_if_fail ( trigger != NULL ); if (*action == E_CAL_COMPONENT_ALARM_NONE) return; gtk_window_set_title (GTK_WINDOW (dialog->toplevel),_("Edit Reminder")); /* Alarm Types */ switch (trigger->type) { case E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START: e_dialog_combo_box_set (dialog->time_combo, E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START, time_map); break; case E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_END: e_dialog_combo_box_set (dialog->time_combo, E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_END, time_map); break; default: g_warning ("%s: Unexpected alarm type (%d)", G_STRLOC, trigger->type); } switch (trigger->u.rel_duration.is_neg) { case 1: e_dialog_combo_box_set (dialog->relative_combo, BEFORE, relative_map); break; case 0: e_dialog_combo_box_set (dialog->relative_combo, AFTER, relative_map); break; } if (trigger->u.rel_duration.days) { e_dialog_combo_box_set (dialog->value_units_combo, DAYS, value_map); gtk_spin_button_set_value ( GTK_SPIN_BUTTON (dialog->interval_value), trigger->u.rel_duration.days); } else if (trigger->u.rel_duration.hours) { e_dialog_combo_box_set (dialog->value_units_combo, HOURS, value_map); gtk_spin_button_set_value ( GTK_SPIN_BUTTON (dialog->interval_value), trigger->u.rel_duration.hours); } else if (trigger->u.rel_duration.minutes) { e_dialog_combo_box_set (dialog->value_units_combo, MINUTES, value_map); gtk_spin_button_set_value ( GTK_SPIN_BUTTON (dialog->interval_value), trigger->u.rel_duration.minutes); } else { e_dialog_combo_box_set (dialog->value_units_combo, MINUTES, value_map); gtk_spin_button_set_value ( GTK_SPIN_BUTTON (dialog->interval_value), 0); } /* Repeat options */ alarm_to_repeat_widgets (dialog, dialog->alarm); /* Alarm options */ e_dialog_combo_box_set (dialog->action_combo, *action, action_map); action_changed_cb (dialog->action_combo, dialog); switch (*action) { case E_CAL_COMPONENT_ALARM_AUDIO: alarm_to_aalarm_widgets (dialog, dialog->alarm); break; case E_CAL_COMPONENT_ALARM_DISPLAY: alarm_to_dalarm_widgets (dialog, dialog->alarm); break; case E_CAL_COMPONENT_ALARM_EMAIL: alarm_to_malarm_widgets (dialog, dialog->alarm); break; case E_CAL_COMPONENT_ALARM_PROCEDURE: alarm_to_palarm_widgets (dialog, dialog->alarm); break; default: g_warning ("%s: Unexpected alarm action (%d)", G_STRLOC, *action); } }
/* Callback used from cal_recur_generate_instances(); generates triggers for all * of a component's RELATIVE alarms. */ static gboolean add_alarm_occurrences_cb (ECalComponent *comp, time_t start, time_t end, gpointer data) { struct alarm_occurrence_data *aod; GList *l; aod = data; for (l = aod->alarm_uids; l; l = l->next) { const gchar *auid; ECalComponentAlarm *alarm; ECalComponentAlarmAction action; ECalComponentAlarmTrigger trigger; ECalComponentAlarmRepeat repeat; struct icaldurationtype *dur; time_t dur_time; time_t occur_time, trigger_time; gint i; auid = l->data; alarm = e_cal_component_get_alarm (comp, auid); g_return_val_if_fail (alarm != NULL, FALSE); e_cal_component_alarm_get_action (alarm, &action); e_cal_component_alarm_get_trigger (alarm, &trigger); e_cal_component_alarm_get_repeat (alarm, &repeat); e_cal_component_alarm_free (alarm); for (i = 0; aod->omit[i] != -1; i++) { if (aod->omit[i] == action) break; } if (aod->omit[i] != -1) continue; if (trigger.type != E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START && trigger.type != E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_END) continue; dur = &trigger.u.rel_duration; dur_time = icaldurationtype_as_int (*dur); if (trigger.type == E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START) occur_time = start; else occur_time = end; /* If dur->is_neg is true then dur_time will already be * negative. So we do not need to test for dur->is_neg here; we * can simply add the dur_time value to the occur_time and get * the correct result. */ trigger_time = occur_time + dur_time; /* Add repeating alarms */ if (repeat.repetitions != 0) { gint i; time_t repeat_time; repeat_time = icaldurationtype_as_int (repeat.duration); for (i = 0; i < repeat.repetitions; i++) { time_t t; t = trigger_time + (i + 1) * repeat_time; if (t >= aod->start && t < aod->end) add_trigger (aod, auid, t, start, end); } } /* Add the trigger itself */ if (trigger_time >= aod->start && trigger_time < aod->end) add_trigger (aod, auid, trigger_time, start, end); } return TRUE; }
/* Generates the absolute triggers for a component */ static void generate_absolute_triggers (ECalComponent *comp, struct alarm_occurrence_data *aod, ECalRecurResolveTimezoneFn resolve_tzid, gpointer user_data, icaltimezone *default_timezone) { GList *l; ECalComponentDateTime dt_start, dt_end; e_cal_component_get_dtstart (comp, &dt_start); e_cal_component_get_dtend (comp, &dt_end); for (l = aod->alarm_uids; l; l = l->next) { const gchar *auid; ECalComponentAlarm *alarm; ECalComponentAlarmAction action; ECalComponentAlarmRepeat repeat; ECalComponentAlarmTrigger trigger; time_t abs_time; time_t occur_start, occur_end; icaltimezone *zone; gint i; auid = l->data; alarm = e_cal_component_get_alarm (comp, auid); g_return_if_fail (alarm != NULL); e_cal_component_alarm_get_action (alarm, &action); e_cal_component_alarm_get_trigger (alarm, &trigger); e_cal_component_alarm_get_repeat (alarm, &repeat); e_cal_component_alarm_free (alarm); for (i = 0; aod->omit[i] != -1; i++) { if (aod->omit[i] == action) break; } if (aod->omit[i] != -1) continue; if (trigger.type != E_CAL_COMPONENT_ALARM_TRIGGER_ABSOLUTE) continue; /* Absolute triggers are always in UTC; * see RFC 2445 section 4.8.6.3 */ zone = icaltimezone_get_utc_timezone (); abs_time = icaltime_as_timet_with_zone (trigger.u.abs_time, zone); /* No particular occurrence, so just use the times from the * component */ if (dt_start.value) { if (dt_start.tzid && !dt_start.value->is_date) zone = (* resolve_tzid) (dt_start.tzid, user_data); else zone = default_timezone; occur_start = icaltime_as_timet_with_zone ( *dt_start.value, zone); } else occur_start = -1; if (dt_end.value) { if (dt_end.tzid && !dt_end.value->is_date) zone = (* resolve_tzid) (dt_end.tzid, user_data); else zone = default_timezone; occur_end = icaltime_as_timet_with_zone (*dt_end.value, zone); } else occur_end = -1; /* Add repeating alarms */ if (repeat.repetitions != 0) { gint i; time_t repeat_time; repeat_time = icaldurationtype_as_int (repeat.duration); for (i = 0; i < repeat.repetitions; i++) { time_t t; t = abs_time + (i + 1) * repeat_time; if (t >= aod->start && t < aod->end) add_trigger ( aod, auid, t, occur_start, occur_end); } } /* Add the trigger itself */ if (abs_time >= aod->start && abs_time < aod->end) add_trigger (aod, auid, abs_time, occur_start, occur_end); } e_cal_component_free_datetime (&dt_start); e_cal_component_free_datetime (&dt_end); }
/* Computes the range of time in which recurrences should be generated for a * component in order to compute alarm trigger times. */ static void compute_alarm_range (ECalComponent *comp, GList *alarm_uids, time_t start, time_t end, time_t *alarm_start, time_t *alarm_end) { GList *l; time_t repeat_time; *alarm_start = start; *alarm_end = end; repeat_time = 0; for (l = alarm_uids; l; l = l->next) { const gchar *auid; ECalComponentAlarm *alarm; ECalComponentAlarmTrigger trigger; struct icaldurationtype *dur; time_t dur_time; ECalComponentAlarmRepeat repeat; auid = l->data; alarm = e_cal_component_get_alarm (comp, auid); g_return_if_fail (alarm != NULL); e_cal_component_alarm_get_trigger (alarm, &trigger); e_cal_component_alarm_get_repeat (alarm, &repeat); e_cal_component_alarm_free (alarm); switch (trigger.type) { case E_CAL_COMPONENT_ALARM_TRIGGER_NONE: case E_CAL_COMPONENT_ALARM_TRIGGER_ABSOLUTE: break; case E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START: case E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_END: dur = &trigger.u.rel_duration; dur_time = icaldurationtype_as_int (*dur); if (repeat.repetitions != 0) { gint rdur; rdur = repeat.repetitions * icaldurationtype_as_int (repeat.duration); repeat_time = MAX (repeat_time, rdur); } if (dur->is_neg) /* If the duration is negative then dur_time * will be negative as well; that is why we * subtract to expand the range. */ *alarm_end = MAX (*alarm_end, end - dur_time); else *alarm_start = MIN (*alarm_start, start - dur_time); break; default: g_return_if_reached (); } } *alarm_start -= repeat_time; g_warn_if_fail (*alarm_start <= *alarm_end); }