From f00e9367382fb81cdb4b689f96645357f122b051 Mon Sep 17 00:00:00 2001 From: Federico Mena Quintero Date: Wed, 16 May 2001 23:38:58 +0000 Subject: Split the event and task editors into different objects for the separate 2001-05-16 Federico Mena Quintero Split the event and task editors into different objects for the separate pages; this way they can be shared by both editors. * gui/dialogs/editor-page.[ch]: New abstract class for a page in a calendar component editor. * gui/dialogs/event-page.[ch]: Main page of an event editor. * gui/dialogs/alarm-page.[ch]: Alarm page of a calendar component editor. * gui/dialogs/recurrence-page.[ch]: Recurrence page of a calendar component editor. * gui/dialogs/event-page.c (event_page_fill_widgets): Eeek, this was missing a bunch of break statements. (event_page_fill_component): Use a temporary variable rather than allocating a struct icaltimetype. * gui/dialogs/alarm-page.c (get_alarm_string): Do not use fixed-size buffers. (alarm_page_fill_widgets): Use cal_obj_uid_list_free(). (append_reminder): Now the list stores the plain CalComponentAlarm structures in the row data. We do *NOT* want to be frobbing the component's data directly. Rather, we clone the alarms from the component and maintain them on our own. (alarm_page_fill_component): Clone the alarms before adding them to the component so that we maintain the invariant that the alarm structures in the list did *not* come from the component. * cal-util/cal-component.c (cal_component_add_alarm): Added documentation. (cal_component_remove_alarm): Added documentation. (cal_component_remove_alarm): Do a lookup in our hash table of alarms instead of scanning the whole component. (CalComponentAlarm): Removed the `parent' field, since it was unused. (cal_component_free_alarm_uids): Removed function, since cal_component_get_alarm_uids() is documented so that the user will know that he must use cal_obj_uid_list_free(). (cal_component_alarm_clone): New function. svn path=/trunk/; revision=9861 --- calendar/gui/dialogs/recurrence-page.c | 900 +++++++++++++++++++++++++++++++++ 1 file changed, 900 insertions(+) create mode 100644 calendar/gui/dialogs/recurrence-page.c (limited to 'calendar/gui/dialogs/recurrence-page.c') diff --git a/calendar/gui/dialogs/recurrence-page.c b/calendar/gui/dialogs/recurrence-page.c new file mode 100644 index 0000000000..0b0eace9cf --- /dev/null +++ b/calendar/gui/dialogs/recurrence-page.c @@ -0,0 +1,900 @@ +/* Evolution calendar - Recurrence page of the calendar component dialogs + * + * Copyright (C) 2001 Ximian, Inc. + * + * Authors: Federico Mena-Quintero + * Miguel de Icaza + * Seth Alves + * JP Rosevear + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include "e-util/e-dialog-widgets.h" +#include "recurrence-page.h" + + + +/* Private part of the RecurrencePage structure */ +struct _RecurrencePagePrivate { + /* Glade XML data */ + GladeXML *xml; + + /* Widgets from the Glade file */ + + GtkWidget *main; + + GtkWidget *summary; + GtkWidget *starting_date; + + GtkWidget *none; + GtkWidget *simple; + GtkWidget *custom; + + GtkWidget *params; + GtkWidget *interval_value; + GtkWidget *interval_unit; + GtkWidget *special; + GtkWidget *ending_menu; + GtkWidget *ending_special; + GtkWidget *custom_warning_bin; + + /* For weekly recurrences, created by hand */ + GtkWidget *weekday_picker; + guint8 weekday_day_mask; + guint8 weekday_blocked_day_mask; + + /* For monthly recurrences, created by hand */ + GtkWidget *month_index_spin; + int month_index; + + GtkWidget *month_day_menu; + enum month_day_options month_day; + + /* For ending date, created by hand */ + GtkWidget *ending_date_edit; + time_t ending_date; + + /* For ending count of occurrences, created by hand */ + GtkWidget *ending_count_spin; + int ending_count; + + /* More widgets from the Glade file */ + + GtkWidget *exception_date; + GtkWidget *exception_list; + GtkWidget *exception_add; + GtkWidget *exception_modify; + GtkWidget *exception_delete; + + GtkWidget *preview_bin; + + /* For the recurrence preview, the actual widget */ + GtkWidget *preview_calendar; +}; + + + +static void recurrence_page_class_init (RecurrencePageClass *class); +static void recurrence_page_init (RecurrencePage *rpage); +static void recurrence_page_destroy (RecurrencePage *rpage); + +static GtkWidget *recurrence_page_get_widget (EditorPage *page); +static void recurrence_page_fill_widgets (EditorPage *page, CalComponent *comp); +static void recurrence_page_fill_component (EditorPage *page, CalComponent *comp); +static void recurrence_page_set_summary (EditorPage *page, const char *summary); +static char *recurrence_page_get_summary (EditorPage *page); +static void recurrence_page_set_dtstart (EditorPage *page, time_t start); + +static EditorPageClass *parent_class = NULL; + + + +/** + * recurrence_page_get_type: + * + * Registers the #RecurrencePage class if necessary, and returns the type ID + * associated to it. + * + * Return value: The type ID of the #RecurrencePage class. + **/ +GtkType +recurrence_page_get_type (void) +{ + static GtkType recurrence_page_type; + + if (!recurrence_page_type) { + static const GtkTypeInfo recurrence_page_info = { + "RecurrencePage", + sizeof (RecurrencePage), + sizeof (RecurrencePageClass), + (GtkClassInitFunc) recurrence_page_class_init, + (GtkObjectInitFunc) recurrence_page_init, + NULL, /* reserved_1 */ + NULL, /* reserved_2 */ + (GtkClassInitFunc) NULL + }; + + recurrence_page_type = gtk_type_unique (EDITOR_PAGE_TYPE, &recurrence_page_info); + } + + return recurrence_page_type; +} + +/* Class initialization function for the recurrence page */ +static void +recurrence_page_class_init (RecurrencePageClass *class) +{ + EditorPageClass *editor_page_class; + GtkObjectClass *object_class; + + editor_page_class = (EditorPageClass *) class; + object_class = (GtkObjectClass *) class; + + parent_class = gtk_type_class (EDITOR_PAGE_TYPE); + + editor_page_class->get_widget = recurrence_page_get_widget; + editor_page_class->fill_widgets = recurrence_page_fill_widgets; + editor_page_class->fill_component = recurrence_page_fill_component; + editor_page_class->set_summary = recurrence_page_set_summary; + editor_page_class->get_summary = recurrence_page_get_summary; + editor_page_class->set_dtstart = recurrence_page_set_dtstart; + + object_class->destroy = recurrence_page_destroy; +} + +/* Object initialization function for the recurrence page */ +static void +recurrence_page_init (RecurrencePage *rpage) +{ + RecurrencePagePrivate *priv; + + priv = g_new0 (RecurrencePagePrivate, 1); + rpage->priv = priv; + + priv->xml = NULL; + + priv->main = NULL; + priv->summary = NULL; + priv->starting_date = NULL; + priv->none = NULL; + priv->simple = NULL; + priv->custom = NULL; + priv->params = NULL; + priv->interval_value = NULL; + priv->interval_unit = NULL; + priv->special = NULL; + priv->ending_menu = NULL; + priv->ending_special = NULL; + priv->custom_warning_bin = NULL; + priv->weekday_picker = NULL; + priv->month_index_spin = NULL; + priv->month_day_menu = NULL; + priv->ending_date_edit = NULL; + priv->ending_count_spin = NULL; + priv->exception_date = NULL; + priv->exception_list = NULL; + priv->exception_add = NULL; + priv->exception_modify = NULL; + priv->exception_delete = NULL; + priv->preview_bin = NULL; + priv->preview_calendar = NULL; +} + +/* Frees the rows and the row data in the exceptions GtkCList */ +static void +free_exception_clist_data (RecurrencePage *rpage) +{ + RecurrencePagePrivate *priv; + GtkCList *clist; + int i; + + priv = rpage->priv; + + clist = GTK_CLIST (priv->exception_list); + + for (i = 0; i < clist->rows; i++) { + gpointer data; + + data = gtk_clist_get_row_data (clist, i); + g_free (data); + gtk_clist_set_row_data (clist, i, NULL); + } + + gtk_clist_clear (clist); +} + +/* Destroy handler for the recurrence page */ +static void +recurrence_page_destroy (GtkObject *object) +{ + RecurrencePage *rpage; + RecurrencePagePrivate *priv; + + g_return_if_fail (object != NULL); + g_return_if_fail (IS_RECURRENCE_PAGE (object)); + + rpage = RECURRENCE_PAGE (object); + priv = rpage->priv; + + if (priv->xml) { + gtk_object_unref (GTK_OBJECT (priv->xml)); + priv->xml = NULL; + } + + free_exception_clist_data (rpage); + + g_free (priv); + rpage->priv = NULL; + + if (GTK_OBJECT_CLASS (parent_class)->destroy) + (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); +} + + + +/* get_widget handler for the recurrence page */ +static GtkWidget * +recurrence_page_get_widget (EditorPage *page) +{ + RecurrencePage *rpage; + RecurrencePagePrivate *priv; + + rpage = RECURRENCE_PAGE (page); + priv = rpage->priv; + + return priv->main; +} + +/* Fills the widgets with default values */ +static void +clear_widgets (RecurrencePage *rpage) +{ + RecurrencePagePrivate *priv; + + priv = rpage->priv; + + priv->weekday_day_mask = 0; + + priv->month_index = 1; + priv->month_day = MONTH_DAY_NTH; + + gtk_signal_handler_block_by_data (GTK_OBJECT (priv->none), rpage); + gtk_signal_handler_block_by_data (GTK_OBJECT (priv->simple), rpage); + gtk_signal_handler_block_by_data (GTK_OBJECT (priv->custom), rpage); + e_dialog_radio_set (priv->none, RECUR_NONE, type_map); + gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->none), rpage); + gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->simple), rpage); + gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->custom), rpage); + + adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (priv->interval_value)); + gtk_signal_handler_block_by_data (GTK_OBJECT (adj), rpage); + e_dialog_spin_set (priv->interval_value, 1); + gtk_signal_handler_unblock_by_data (GTK_OBJECT (adj), rpage); + + menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->interval_unit)); + gtk_signal_handler_block_by_data (GTK_OBJECT (menu), rpage); + e_dialog_option_menu_set (priv->interval_unit, ICAL_DAILY_RECURRENCE, freq_map); + gtk_signal_handler_unblock_by_data (GTK_OBJECT (menu), rpage); + + priv->ending_date = time (NULL); + priv->ending_count = 1; + + menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->ending_menu)); + gtk_signal_handler_block_by_data (GTK_OBJECT (menu), rpage); + e_dialog_option_menu_set (priv->ending_menu, ENDING_FOREVER, ending_types_map); + gtk_signal_handler_unblock_by_data (GTK_OBJECT (menu), rpage); + + /* Exceptions list */ + free_exception_clist_data (GTK_CLIST (priv->exception_list)); +} + +/* Builds a static string out of an exception date */ +static char * +get_exception_string (time_t t) +{ + static char buf[256]; + + strftime (buf, sizeof (buf), _("%a %b %d %Y"), localtime (&t)); + return buf; +} + +/* Appends an exception date to the list */ +static void +append_exception (RecurrencePage *rpage, time_t t) +{ + RecurrencePagePrivate *priv; + time_t *tt; + char *c[1]; + int i; + GtkCList *clist; + + priv = rpage->priv; + + tt = g_new (time_t, 1); + *tt = t; + + clist = GTK_CLIST (priv->exception_list); + + gtk_signal_handler_block_by_data (GTK_OBJECT (clist), rpage); + + c[0] = get_exception_string (t); + i = gtk_clist_append (clist, c); + + gtk_clist_set_row_data (clist, i, tt); + + gtk_clist_select_row (clist, i, 0); + gtk_signal_handler_unblock_by_data (GTK_OBJECT (clist), rpage); + + e_date_edit_set_time (E_DATE_EDIT (priv->exception_date), t); + + gtk_widget_set_sensitive (priv->exception_modify, TRUE); + gtk_widget_set_sensitive (priv->exception_delete, TRUE); +} + +/* Fills in the exception widgets with the data from the calendar component */ +static void +fill_exception_widgets (RecurrencePage *rpage, CalComponent *comp) +{ + RecurrencePagePrivate *priv; + GSList *list, *l; + gboolean added; + + priv = rpage->priv; + + cal_component_get_exdate_list (comp, &list); + + added = FALSE; + + for (l = list; l; l = l->next) { + CalComponentDateTime *cdt; + time_t ext; + + added = TRUE; + + cdt = l->data; + ext = icaltime_as_timet (*cdt->value); + append_exception (rpage, ext); + } + + cal_component_free_exdate_list (list); + + if (added) + gtk_clist_select_row (GTK_CLIST (priv->exception_list), 0, 0); +} + +/* Computes a weekday mask for the start day of a calendar component, for use in + * a WeekdayPicker widget. + */ +static guint8 +get_start_weekday_mask (CalComponent *comp) +{ + CalComponentDateTime dt; + guint8 retval; + + cal_component_get_dtstart (comp, &dt); + + if (dt.value) { + time_t t; + struct tm tm; + + t = icaltime_as_timet (*dt.value); + tm = *localtime (&t); + + retval = 0x1 << tm.tm_wday; + } else + retval = 0; + + cal_component_free_datetime (&dt); + + return retval; +} + +/* Sets some sane defaults for the data sources for the recurrence special + * widgets, even if they will not be used immediately. + */ +static void +set_special_defaults (RecurrencePage *rpage) +{ + RecurrencePagePrivate *priv; + guint8 mask; + + priv = rpage->priv; + + mask = get_start_weekday_mask (priv->comp); + + priv->weekday_day_mask = mask; + priv->weekday_blocked_day_mask = mask; +} + +/* Sensitizes the recurrence widgets based on the state of the recurrence type + * radio group. + */ +static void +sensitize_recur_widgets (RecurrencePage *rpage) +{ + RecurrencePagePrivate *priv; + enum recur_type type; + GtkWidget *label; + + priv = rpage->priv; + + type = e_dialog_radio_get (priv->none, type_map); + + if (GTK_BIN (priv->custom_warning_bin)->child) + gtk_widget_destroy (GTK_BIN (priv->custom_warning_bin)->child); + + switch (type) { + case RECUR_NONE: + gtk_widget_set_sensitive (priv->params, FALSE); + gtk_widget_show (priv->params); + gtk_widget_hide (priv->custom_warning_bin); + break; + + case RECUR_SIMPLE: + gtk_widget_set_sensitive (priv->params, TRUE); + gtk_widget_show (priv->params); + gtk_widget_hide (priv->custom_warning_bin); + break; + + case RECUR_CUSTOM: + gtk_widget_set_sensitive (priv->params, FALSE); + gtk_widget_hide (priv->params); + + label = gtk_label_new (_("This appointment contains recurrences that Evolution " + "cannot edit.")); + gtk_container_add (GTK_CONTAINER (priv->custom_warning_bin), label); + gtk_widget_show_all (priv->custom_warning_bin); + break; + + default: + g_assert_not_reached (); + } +} + +/* Re-tags the recurrence preview calendar based on the current information of + * the widgets in the recurrence page. + */ +static void +preview_recur (RecurrencePage *rpage) +{ + RecurrencePagePrivate *priv; + CalComponent *comp; + CalComponentDateTime cdt; + GSList *l; + + priv = rpage->priv; + g_assert (priv->comp != NULL); + + /* Create a scratch component with the start/end and + * recurrence/excepttion information from the one we are editing. + */ + + comp = cal_component_new (); + cal_component_set_new_vtype (comp, CAL_COMPONENT_EVENT); + + cal_component_get_dtstart (priv->comp, &cdt); + cal_component_set_dtstart (comp, &cdt); + cal_component_free_datetime (&cdt); + + cal_component_get_dtend (priv->comp, &cdt); + cal_component_set_dtend (comp, &cdt); + cal_component_free_datetime (&cdt); + + cal_component_get_exdate_list (priv->comp, &l); + cal_component_set_exdate_list (comp, l); + cal_component_free_exdate_list (l); + + cal_component_get_exrule_list (priv->comp, &l); + cal_component_set_exrule_list (comp, l); + cal_component_free_recur_list (l); + + cal_component_get_rdate_list (priv->comp, &l); + cal_component_set_rdate_list (comp, l); + cal_component_free_period_list (l); + + cal_component_get_rrule_list (priv->comp, &l); + cal_component_set_rrule_list (comp, l); + cal_component_free_recur_list (l); + + recur_to_comp_object (rpage, comp); + + tag_calendar_by_comp (E_CALENDAR (priv->preview_calendar), comp); + gtk_object_unref (GTK_OBJECT (comp)); +} + +/* fill_widgets handler for the recurrence page. This function is particularly + * tricky because it has to discriminate between recurrences we support for + * editing and the ones we don't. We only support at most one recurrence rule; + * no rdates or exrules (exdates are handled just fine elsewhere). + */ +static void +recurrence_page_fill_widgets (EditorPage *page, CalComponent *comp) +{ + RecurrencePage *rpage; + RecurrencePagePrivate *priv; + GSList *rrule_list; + int len; + struct icalrecurrencetype *r; + int n_by_second, n_by_minute, n_by_hour; + int n_by_day, n_by_month_day, n_by_year_day; + int n_by_week_no, n_by_month, n_by_set_pos; + GtkWidget *menu; + GtkAdjustment *adj; + + rpage = RECURRENCE_PAGE (page); + priv = rpage->priv; + + clear_widgets (rpage); + + fill_exception_widgets (rpage, comp); + + /* Set up defaults for the special widgets */ + set_special_defaults (rpage); + + /* No recurrences? */ + + if (!cal_component_has_rdates (comp) + && !cal_component_has_rrules (comp) + && !cal_component_has_exrules (comp)) { + gtk_signal_handler_block_by_data (GTK_OBJECT (priv->none), rpage); + gtk_signal_handler_block_by_data (GTK_OBJECT (priv->simple), rpage); + gtk_signal_handler_block_by_data (GTK_OBJECT (priv->custom), rpage); + e_dialog_radio_set (priv->none, RECUR_NONE, type_map); + gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->none), rpage); + gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->simple), rpage); + gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->custom), rpage); + + gtk_widget_set_sensitive (priv->custom, FALSE); + + sensitize_recur_widgets (rpage); + preview_recur (rpage); + return; + } + + /* See if it is a custom set we don't support */ + + cal_component_get_rrule_list (comp, &rrule_list); + len = g_slist_length (rrule_list); + if (len > 1 + || cal_component_has_rdates (comp) + || cal_component_has_exrules (comp)) + goto custom; + + /* Down to one rule, so test that one */ + + g_assert (len == 1); + r = rrule_list->data; + + /* Any funky frequency? */ + + if (r->freq == ICAL_SECONDLY_RECURRENCE + || r->freq == ICAL_MINUTELY_RECURRENCE + || r->freq == ICAL_HOURLY_RECURRENCE) + goto custom; + + /* Any funky shit? */ + +#define N_HAS_BY(field) (count_by_xxx (field, sizeof (field) / sizeof (field[0]))) + + n_by_second = N_HAS_BY (r->by_second); + n_by_minute = N_HAS_BY (r->by_minute); + n_by_hour = N_HAS_BY (r->by_hour); + n_by_day = N_HAS_BY (r->by_day); + n_by_month_day = N_HAS_BY (r->by_month_day); + n_by_year_day = N_HAS_BY (r->by_year_day); + n_by_week_no = N_HAS_BY (r->by_week_no); + n_by_month = N_HAS_BY (r->by_month); + n_by_set_pos = N_HAS_BY (r->by_set_pos); + + if (n_by_second != 0 + || n_by_minute != 0 + || n_by_hour != 0) + goto custom; + + /* Filter the funky shit based on the frequency; if there is nothing + * weird we can actually set the widgets. + */ + + switch (r->freq) { + case ICAL_DAILY_RECURRENCE: + if (n_by_day != 0 + || n_by_month_day != 0 + || n_by_year_day != 0 + || n_by_week_no != 0 + || n_by_month != 0 + || n_by_set_pos != 0) + goto custom; + + menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->interval_unit)); + gtk_signal_handler_block_by_data (GTK_OBJECT (menu), rpage); + e_dialog_option_menu_set (priv->interval_unit, ICAL_DAILY_RECURRENCE, freq_map); + gtk_signal_handler_unblock_by_data (GTK_OBJECT (menu), rpage); + break; + + case ICAL_WEEKLY_RECURRENCE: { + int i; + guint8 day_mask; + + if (n_by_month_day != 0 + || n_by_year_day != 0 + || n_by_week_no != 0 + || n_by_month != 0 + || n_by_set_pos != 0) + goto custom; + + day_mask = 0; + + for (i = 0; i < 8 && r->by_day[i] != ICAL_RECURRENCE_ARRAY_MAX; i++) { + enum icalrecurrencetype_weekday weekday; + int pos; + + weekday = icalrecurrencetype_day_day_of_week (r->by_day[i]); + pos = icalrecurrencetype_day_position (r->by_day[i]); + + if (pos != 0) + goto custom; + + switch (weekday) { + case ICAL_SUNDAY_WEEKDAY: + day_mask |= 1 << 0; + break; + + case ICAL_MONDAY_WEEKDAY: + day_mask |= 1 << 1; + break; + + case ICAL_TUESDAY_WEEKDAY: + day_mask |= 1 << 2; + break; + + case ICAL_WEDNESDAY_WEEKDAY: + day_mask |= 1 << 3; + break; + + case ICAL_THURSDAY_WEEKDAY: + day_mask |= 1 << 4; + break; + + case ICAL_FRIDAY_WEEKDAY: + day_mask |= 1 << 5; + break; + + case ICAL_SATURDAY_WEEKDAY: + day_mask |= 1 << 6; + break; + + default: + break; + } + } + + priv->weekday_day_mask = day_mask; + + menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->interval_unit)); + gtk_signal_handler_block_by_data (GTK_OBJECT (menu), rpage); + e_dialog_option_menu_set (priv->interval_unit, ICAL_WEEKLY_RECURRENCE, freq_map); + gtk_signal_handler_unblock_by_data (GTK_OBJECT (menu), rpage); + break; + } + + case ICAL_MONTHLY_RECURRENCE: + if (n_by_year_day != 0 + || n_by_week_no != 0 + || n_by_month != 0 + || n_by_set_pos != 0) + goto custom; + + if (n_by_month_day == 1) { + int nth; + + nth = r->by_month_day[0]; + if (nth < 1) + goto custom; + + priv->month_index = nth; + priv->month_day = MONTH_DAY_NTH; + } else if (n_by_day == 1) { + enum icalrecurrencetype_weekday weekday; + int pos; + enum month_day_options month_day; + + weekday = icalrecurrencetype_day_day_of_week (r->by_day[0]); + pos = icalrecurrencetype_day_position (r->by_day[0]); + + if (pos < 1) + goto custom; + + switch (weekday) { + case ICAL_MONDAY_WEEKDAY: + month_day = MONTH_DAY_MON; + break; + + case ICAL_TUESDAY_WEEKDAY: + month_day = MONTH_DAY_TUE; + break; + + case ICAL_WEDNESDAY_WEEKDAY: + month_day = MONTH_DAY_WED; + break; + + case ICAL_THURSDAY_WEEKDAY: + month_day = MONTH_DAY_THU; + break; + + case ICAL_FRIDAY_WEEKDAY: + month_day = MONTH_DAY_FRI; + break; + + case ICAL_SATURDAY_WEEKDAY: + month_day = MONTH_DAY_SAT; + break; + + case ICAL_SUNDAY_WEEKDAY: + month_day = MONTH_DAY_SUN; + break; + + default: + goto custom; + } + + priv->month_index = pos; + priv->month_day = month_day; + } else + goto custom; + + menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->interval_unit)); + gtk_signal_handler_block_by_data (GTK_OBJECT (menu), rpage); + e_dialog_option_menu_set (priv->interval_unit, ICAL_MONTHLY_RECURRENCE, freq_map); + gtk_signal_handler_unblock_by_data (GTK_OBJECT (menu), rpage); + break; + + case ICAL_YEARLY_RECURRENCE: + if (n_by_day != 0 + || n_by_month_day != 0 + || n_by_year_day != 0 + || n_by_week_no != 0 + || n_by_month != 0 + || n_by_set_pos != 0) + goto custom; + + menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->interval_unit)); + gtk_signal_handler_block_by_data (GTK_OBJECT (menu), rpage); + e_dialog_option_menu_set (priv->interval_unit, ICAL_YEARLY_RECURRENCE, freq_map); + gtk_signal_handler_unblock_by_data (GTK_OBJECT (menu), rpage); + break; + + default: + goto custom; + } + + /* If we got here it means it is a simple recurrence */ + + gtk_signal_handler_block_by_data (GTK_OBJECT (priv->none), rpage); + gtk_signal_handler_block_by_data (GTK_OBJECT (priv->simple), rpage); + gtk_signal_handler_block_by_data (GTK_OBJECT (priv->custom), rpage); + e_dialog_radio_set (priv->simple, RECUR_SIMPLE, type_map); + gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->none), rpage); + gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->simple), rpage); + gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->custom), rpage); + + gtk_widget_set_sensitive (priv->custom, FALSE); + + sensitize_recur_widgets (rpage); + make_recurrence_special (rpage); + + adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (priv->interval_value)); + gtk_signal_handler_block_by_data (GTK_OBJECT (adj), rpage); + e_dialog_spin_set (priv->interval_value, r->interval); + gtk_signal_handler_unblock_by_data (GTK_OBJECT (adj), rpage); + + fill_ending_date (rpage, r); + + goto out; + + custom: + + gtk_signal_handler_block_by_data (GTK_OBJECT (priv->none), rpage); + gtk_signal_handler_block_by_data (GTK_OBJECT (priv->simple), rpage); + gtk_signal_handler_block_by_data (GTK_OBJECT (priv->custom), rpage); + e_dialog_radio_set (priv->custom, RECUR_CUSTOM, type_map); + gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->none), rpage); + gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->simple), rpage); + gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->custom), rpage); + + gtk_widget_set_sensitive (priv->custom, TRUE); + sensitize_recur_widgets (rpage); + + out: + + cal_component_free_recur_list (rrule_list); + preview_recur (rpage); +} + + + +/* Gets the widgets from the XML file and returns if they are all available. */ +static gboolean +get_widgets (RecurrencePage *rpage) +{ + RecurrencePagePrivate *priv; + GtkWidget *toplevel; + + priv = rpage->priv; + +#define GW(name) glade_xml_get_widget (priv->xml, name) + + toplevel = GW ("recurrence-toplevel"); + priv->main = GW ("recurrence-page"); + if (!(toplevel && priv->main)) + return NULL; + + gtk_widget_ref (priv->main); + gtk_widget_unparent (priv->main); + gtk_widget_destroy (toplevel); + + priv->summary = GW ("summary"); + priv->starting_date = GW ("starting-date"); + + priv->none = GW ("none"); + priv->simple = GW ("simple"); + priv->custom = GW ("custom"); + priv->params = GW ("params"); + + priv->interval_value = GW ("interval-value"); + priv->interval_unit = GW ("interval-unit"); + priv->special = GW ("special"); + priv->ending_menu = GW ("ending-menu"); + priv->ending_special = GW ("ending-special"); + priv->custom_warning_bin = GW ("custom-warning-bin"); + + priv->exception_date = GW ("exception-date"); + priv->exception_list = GW ("exception-list"); + priv->exception_add = GW ("exception-add"); + priv->exception_modify = GW ("exception-modify"); + priv->exception_delete = GW ("exception-delete"); + + priv->preview_bin = GW ("preview-bin"); + +#undef GW + + return (priv->summary + && priv->starting_date + && priv->none + && priv->simple + && priv->custom + && priv->params + && priv->interval_value + && priv->interval_unit + && priv->special + && priv->ending_menu + && priv->ending_special + && priv->custom_warning_bin + && priv->exception_date + && priv->exception_list + && priv->exception_add + && priv->exception_modify + && priv->exception_delete + && priv->preview_bin); +} -- cgit v1.2.3