diff options
Diffstat (limited to 'calendar')
-rw-r--r-- | calendar/ChangeLog | 14 | ||||
-rw-r--r-- | calendar/cal-util/cal-component.c | 173 | ||||
-rw-r--r-- | calendar/cal-util/cal-component.h | 1 | ||||
-rw-r--r-- | calendar/gui/dialogs/recurrence-page.c | 24 | ||||
-rw-r--r-- | calendar/gui/itip-utils.c | 49 |
5 files changed, 259 insertions, 2 deletions
diff --git a/calendar/ChangeLog b/calendar/ChangeLog index 5cfd140042..71e7b02556 100644 --- a/calendar/ChangeLog +++ b/calendar/ChangeLog @@ -1,3 +1,17 @@ +2002-10-17 JP Rosevear <jpr@ximian.com> + + * gui/dialogs/recurrence-page.c (fill_ending_date): if the value + is a datetime, convert it to a date + + * gui/itip-utils.c (comp_compliant): convert an UNTIL date value + to a datetime value + + * cal-util/cal-component.c (cal_component_has_simple_recurrence): + check to see if the component recurrences meet our definition of + "simple" + + * cal-util/cal-component.h: new proto + 2002-10-17 Rodrigo Moya <rodrigo@ximian.com> * gui/dialogs/recurrence-page.c (fill_component): changed to have a diff --git a/calendar/cal-util/cal-component.c b/calendar/cal-util/cal-component.c index b91d4b26ad..197ba81a21 100644 --- a/calendar/cal-util/cal-component.c +++ b/calendar/cal-util/cal-component.c @@ -3422,6 +3422,179 @@ cal_component_has_recurrences (CalComponent *comp) return cal_component_has_rdates (comp) || cal_component_has_rrules (comp); } +/* Counts the elements in the by_xxx fields of an icalrecurrencetype */ +static int +count_by_xxx (short *field, int max_elements) +{ + int i; + + for (i = 0; i < max_elements; i++) + if (field[i] == ICAL_RECURRENCE_ARRAY_MAX) + break; + + return i; +} + +gboolean +cal_component_has_simple_recurrence (CalComponent *comp) +{ + GSList *rrule_list; + 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; + int len, i; + gboolean simple = FALSE; + + if (!cal_component_has_recurrences (comp)) + return TRUE; + + 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 cleanup; + + /* Down to one rule, so test that one */ + r = rrule_list->data; + + /* Any funky frequency? */ + if (r->freq == ICAL_SECONDLY_RECURRENCE + || r->freq == ICAL_MINUTELY_RECURRENCE + || r->freq == ICAL_HOURLY_RECURRENCE) + goto cleanup; + + /* Any funky BY_* */ +#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 cleanup; + + 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 cleanup; + + simple = TRUE; + break; + + case ICAL_WEEKLY_RECURRENCE: + 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 cleanup; + + for (i = 0; i < 8 && r->by_day[i] != ICAL_RECURRENCE_ARRAY_MAX; i++) { + int pos; + pos = icalrecurrencetype_day_position (r->by_day[i]); + + if (pos != 0) + goto cleanup; + } + + simple = TRUE; + break; + + case ICAL_MONTHLY_RECURRENCE: + if (n_by_year_day != 0 + || n_by_week_no != 0 + || n_by_month != 0 + || n_by_set_pos > 1) + goto cleanup; + + if (n_by_month_day == 1) { + int nth; + + if (n_by_set_pos != 0) + goto cleanup; + + nth = r->by_month_day[0]; + if (nth < 1 && nth != -1) + goto cleanup; + + simple = TRUE; + + } else if (n_by_day == 1) { + enum icalrecurrencetype_weekday weekday; + int pos; + + /* Outlook 2000 uses BYDAY=TU;BYSETPOS=2, and will not + accept BYDAY=2TU. So we now use the same as Outlook + by default. */ + + weekday = icalrecurrencetype_day_day_of_week (r->by_day[0]); + pos = icalrecurrencetype_day_position (r->by_day[0]); + + if (pos == 0) { + if (n_by_set_pos != 1) + goto cleanup; + pos = r->by_set_pos[0]; + } else if (pos < 0) { + goto cleanup; + } + + switch (weekday) { + case ICAL_MONDAY_WEEKDAY: + case ICAL_TUESDAY_WEEKDAY: + case ICAL_WEDNESDAY_WEEKDAY: + case ICAL_THURSDAY_WEEKDAY: + case ICAL_FRIDAY_WEEKDAY: + case ICAL_SATURDAY_WEEKDAY: + case ICAL_SUNDAY_WEEKDAY: + break; + + default: + goto cleanup; + } + } else { + goto cleanup; + } + + simple = TRUE; + 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 cleanup; + + simple = TRUE; + break; + + default: + goto cleanup; + } + + cleanup: + cal_component_free_recur_list (rrule_list); + + return simple; +} + /** * cal_component_get_sequence: * @comp: A calendar component object. diff --git a/calendar/cal-util/cal-component.h b/calendar/cal-util/cal-component.h index 3e9c505b46..0c0579c48e 100644 --- a/calendar/cal-util/cal-component.h +++ b/calendar/cal-util/cal-component.h @@ -296,6 +296,7 @@ void cal_component_set_rrule_list (CalComponent *comp, GSList *recur_list); gboolean cal_component_has_rrules (CalComponent *comp); gboolean cal_component_has_recurrences (CalComponent *comp); +gboolean cal_component_has_simple_recurrence (CalComponent *comp); void cal_component_get_sequence (CalComponent *comp, int **sequence); void cal_component_set_sequence (CalComponent *comp, int *sequence); diff --git a/calendar/gui/dialogs/recurrence-page.c b/calendar/gui/dialogs/recurrence-page.c index f587c6dbcb..3fb07a0559 100644 --- a/calendar/gui/dialogs/recurrence-page.c +++ b/calendar/gui/dialogs/recurrence-page.c @@ -1534,6 +1534,30 @@ fill_ending_date (RecurrencePage *rpage, struct icalrecurrencetype *r) } else { /* Ending date */ + if (!r->until.is_date) { + CalClient *client = COMP_EDITOR_PAGE (rpage)->client; + CalComponentDateTime dt; + icaltimezone *from_zone, *to_zone; + + cal_component_get_dtstart (priv->comp, &dt); + + if (dt.value->is_date) + to_zone = icaltimezone_get_builtin_timezone (calendar_config_get_timezone ()); + else if (dt.tzid == NULL) + to_zone = icaltimezone_get_utc_timezone (); + else + cal_client_get_timezone (client, dt.tzid, &to_zone); + from_zone = icaltimezone_get_utc_timezone (); + + icaltimezone_convert_time (&r->until, from_zone, to_zone); + + r->until.hour = 0; + r->until.minute = 0; + r->until.second = 0; + r->until.is_date = TRUE; + r->until.is_utc = FALSE; + } + priv->ending_date_tt = r->until; e_dialog_option_menu_set (priv->ending_menu, ENDING_UNTIL, diff --git a/calendar/gui/itip-utils.c b/calendar/gui/itip-utils.c index 224d8b9d52..b3e18422af 100644 --- a/calendar/gui/itip-utils.c +++ b/calendar/gui/itip-utils.c @@ -818,7 +818,7 @@ comp_minimal (CalComponent *comp, gboolean attendee) } static CalComponent * -comp_compliant (CalComponentItipMethod method, CalComponent *comp) +comp_compliant (CalComponentItipMethod method, CalComponent *comp, CalClient *client, icalcomponent *zones) { CalComponent *clone, *temp_clone; struct icaltimetype itt; @@ -828,6 +828,51 @@ comp_compliant (CalComponentItipMethod method, CalComponent *comp) icaltimezone_get_utc_timezone ()); cal_component_set_dtstamp (clone, &itt); + /* Make UNTIL date a datetime in a simple recurrence */ + if (cal_component_has_recurrences (clone) + && cal_component_has_simple_recurrence (clone)) { + GSList *rrule_list; + struct icalrecurrencetype *r; + + cal_component_get_rrule_list (clone, &rrule_list); + r = rrule_list->data; + + if (!icaltime_is_null_time (r->until) && r->until.is_date) { + CalComponentDateTime dt; + icaltimezone *from_zone = NULL, *to_zone; + + cal_component_get_dtstart (clone, &dt); + + if (dt.value->is_date) { + from_zone = icaltimezone_get_builtin_timezone (calendar_config_get_timezone ()); + } else if (dt.tzid == NULL) { + from_zone = icaltimezone_get_utc_timezone (); + } else { + if (zones != NULL) + from_zone = icalcomponent_get_timezone (zones, dt.tzid); + if (from_zone == NULL) + from_zone = icaltimezone_get_builtin_timezone_from_tzid (dt.tzid); + if (from_zone == NULL && client != NULL) + cal_client_get_timezone (client, dt.tzid, &from_zone); + } + + to_zone = icaltimezone_get_utc_timezone (); + + r->until.hour = dt.value->hour; + r->until.minute = dt.value->minute; + r->until.second = dt.value->second; + r->until.is_date = FALSE; + + icaltimezone_convert_time (&r->until, from_zone, to_zone); + r->until.is_utc = TRUE; + + cal_component_set_rrule_list (clone, rrule_list); + cal_component_abort_sequence (clone); + } + + cal_component_free_recur_list (rrule_list); + } + /* We delete incoming alarms anyhow, and this helps with outlook */ cal_component_remove_all_alarms (clone); @@ -904,7 +949,7 @@ itip_send_comp (CalComponentItipMethod method, CalComponent *send_comp, } /* Tidy up the comp */ - comp = comp_compliant (method, send_comp); + comp = comp_compliant (method, send_comp, client, zones); if (comp == NULL) goto cleanup; |