/* fill_widgets handler for the alarm page */ static void alarm_to_dialog (Dialog *dialog) { GtkTreeModel *model; GtkTreeIter iter; gboolean valid; gboolean repeat; ECalComponentAlarmAction action; gchar *email; gint i; /* Clean the page */ clear_widgets (dialog); /* Alarm types */ model = gtk_combo_box_get_model (GTK_COMBO_BOX (dialog->action_combo)); valid = gtk_tree_model_get_iter_first (model, &iter); for (i = 0; valid && action_map[i] != -1; i++) { gtk_list_store_set ( GTK_LIST_STORE (model), &iter, 1, !e_client_check_capability (E_CLIENT (dialog->cal_client), action_map_cap[i]), -1); valid = gtk_tree_model_iter_next (model, &iter); } /* Set a default address if possible */ if (!e_client_check_capability (E_CLIENT (dialog->cal_client), CAL_STATIC_CAPABILITY_NO_EMAIL_ALARMS) && !e_cal_component_alarm_has_attendees (dialog->alarm) && e_client_get_backend_property_sync (E_CLIENT (dialog->cal_client), CAL_BACKEND_PROPERTY_ALARM_EMAIL_ADDRESS, &email, NULL, NULL)) { ECalComponentAttendee *a; GSList attendee_list; a = g_new0 (ECalComponentAttendee, 1); a->value = email; a->cutype = ICAL_CUTYPE_INDIVIDUAL; a->status = ICAL_PARTSTAT_NEEDSACTION; a->role = ICAL_ROLE_REQPARTICIPANT; attendee_list.data = a; attendee_list.next = NULL; e_cal_component_alarm_set_attendee_list (dialog->alarm, &attendee_list); g_free (email); g_free (a); } /* If we can repeat */ repeat = !e_client_check_capability (E_CLIENT (dialog->cal_client), CAL_STATIC_CAPABILITY_NO_ALARM_REPEAT); gtk_widget_set_sensitive (dialog->repeat_toggle, repeat); /* if we are editing a exiting alarm */ e_cal_component_alarm_get_action (dialog->alarm, &action); if (action) populate_widgets_from_alarm (dialog); }
/* fill_widgets handler for the alarm page */ static void alarm_to_dialog (Dialog *dialog) { GtkWidget *menu; GList *l; gboolean repeat; ECalComponentAlarmAction action; char *email; int i; /* Clean the page */ clear_widgets (dialog); /* Alarm types */ menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (dialog->action)); for (i = 0, l = GTK_MENU_SHELL (menu)->children; action_map[i] != -1; i++, l = l->next) { if (e_cal_get_static_capability (dialog->ecal, action_map_cap[i])) gtk_widget_set_sensitive (l->data, FALSE); else gtk_widget_set_sensitive (l->data, TRUE); } /* Set a default address if possible */ if (!e_cal_get_static_capability (dialog->ecal, CAL_STATIC_CAPABILITY_NO_EMAIL_ALARMS) && !e_cal_component_alarm_has_attendees (dialog->alarm) && e_cal_get_alarm_email_address (dialog->ecal, &email, NULL)) { ECalComponentAttendee *a; GSList attendee_list; a = g_new0 (ECalComponentAttendee, 1); a->value = email; attendee_list.data = a; attendee_list.next = NULL; e_cal_component_alarm_set_attendee_list (dialog->alarm, &attendee_list); g_free (email); g_free (a); } /* If we can repeat */ repeat = !e_cal_get_static_capability (dialog->ecal, CAL_STATIC_CAPABILITY_NO_ALARM_REPEAT); gtk_widget_set_sensitive (dialog->repeat_toggle, repeat); /* if we are editing a exiting alarm */ e_cal_component_alarm_get_action (dialog->alarm, &action); if (action) populate_widgets_from_alarm (dialog); }
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); } }
/* 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); }
/* 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; }