aboutsummaryrefslogtreecommitdiffstats
path: root/calendar
diff options
context:
space:
mode:
Diffstat (limited to 'calendar')
-rw-r--r--calendar/ChangeLog14
-rw-r--r--calendar/cal-util/cal-component.c173
-rw-r--r--calendar/cal-util/cal-component.h1
-rw-r--r--calendar/gui/dialogs/recurrence-page.c24
-rw-r--r--calendar/gui/itip-utils.c49
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;