char weekday_labels[7][32];
char month_labels[12][32];
long weekstart = 0;
+ icalproperty *rrule = NULL;
+ struct icalrecurrencetype recur;
+
+ char *tabnames[3];
+ tabnames[0] = _("Event");
+ tabnames[1] = _("Attendees");
+ tabnames[2] = _("Recurrence");
get_pref_long("weekstart", &weekstart, 17);
if (weekstart > 6) weekstart = 0;
if (supplied_vevent != NULL) {
vevent = supplied_vevent;
+
+ /* Convert all timestamps to UTC to make them easier to process. */
+ ical_dezonify(vevent);
+
/*
* If we're looking at a fully encapsulated VCALENDAR
* rather than a VEVENT component, attempt to use the first
wprintf("<INPUT TYPE=\"hidden\" NAME=\"day\" VALUE=\"%s\">\n",
bstr("day"));
- char *tabnames[] = {
- _("Event"),
- _("Attendees"),
- _("Recurrence")
- };
tabbed_dialog(3, tabnames);
begin_tab(0, 3);
/* Recurrence tab */
begin_tab(2, 3);
- icalproperty *rrule = NULL;
- struct icalrecurrencetype recur;
rrule = icalcomponent_get_first_property(vevent, ICAL_RRULE_PROPERTY);
if (rrule) {
wprintf("<table border=0 cellspacing=\"10\" width=100%%>\n");
- /* Table row displaying raw RRULE data, FIXME remove when finished */
- if (rrule) {
- wprintf("<tr><td><b>");
- wprintf("Raw data");
- wprintf("</b></td><td>");
- wprintf("<tt>%s</tt>", icalrecurrencetype_as_string(&recur));
- wprintf("</td></tr>\n");
- }
-
char *frequency_units[] = {
_("seconds"),
_("minutes"),
wprintf("<div id=\"monthday_selector\">"); /* begin 'monthday_selector' div */
wprintf("<input type=\"radio\" name=\"rrmonthtype\" id=\"rrmonthtype_mday\" "
+ "value=\"rrmonthtype_mday\" "
"%s onChange=\"RecurrenceShowHide();\">",
((which_rrmonthtype_is_preselected == 0) ? "checked" : "")
);
- char mdaybox[256];
- int rrmday = 1; /* FIXME default to same as event start */
- int rrmweek = 1; /* FIXME default to same as event start */
- int rrmweekday = 1; /* FIXME default to same as event start */
+ int rrmday = t_start.day;
+ int rrmweekday = icaltime_day_of_week(t_start) - 1;
+
+ /* Figure out what week of the month we're in */
+ icaltimetype day1 = t_start;
+ day1.day = 1;
+ int weekbase = icaltime_week_number(day1);
+ int rrmweek = icaltime_week_number(t_start) - weekbase + 1;
+
+ /* Are we going by day of the month or week/day? */
if (recur.by_month_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
which_rrmonthtype_is_preselected = 0;
rrmweekday = icalrecurrencetype_day_day_of_week(recur.by_day[0]) - 1;
}
- snprintf(mdaybox, sizeof mdaybox,
- "<input type=\"text\" name=\"rrmday\" id=\"rrmday\" maxlength=\"2\" size=\"2\" "
- "value=\"%d\">", rrmday);
- wprintf(_("on day %s of the month"), mdaybox);
+ wprintf(_("on day %s%d%s of the month"), "<span id=\"rrmday\">", rrmday, "</span>");
wprintf("<br />\n");
wprintf("<input type=\"radio\" name=\"rrmonthtype\" id=\"rrmonthtype_wday\" "
+ "value=\"rrmonthtype_wday\" "
"%s onChange=\"RecurrenceShowHide();\">",
((which_rrmonthtype_is_preselected == 1) ? "checked" : "")
);
wprintf("</div>\n"); /* end 'monthday_selector' div */
- int rrymweek = 1; /* FIXME default to same as event start */
- int rrymweekday = 1; /* FIXME default to same as event start */
- int rrymonth = 1; /* FIXME default to same as event start */
-
+ int rrymweek = rrmweek;
+ int rrymweekday = rrmweekday;
+ int rrymonth = t_start.month;
int which_rryeartype_is_preselected = 0;
if ( (recur.by_day[0] != ICAL_RECURRENCE_ARRAY_MAX)
wprintf("<div id=\"yearday_selector\">"); /* begin 'yearday_selector' div */
wprintf("<input type=\"radio\" name=\"rryeartype\" id=\"rryeartype_ymday\" "
+ "value=\"rryeartype_ymday\" "
"%s onChange=\"RecurrenceShowHide();\">",
((which_rryeartype_is_preselected == 0) ? "checked" : "")
);
wprintf("<span id=\"ymday\">%s</span><br />", _("year on this date"));
wprintf("<input type=\"radio\" name=\"rryeartype\" id=\"rryeartype_ywday\" "
+ "value=\"rryeartype_ywday\" "
"%s onChange=\"RecurrenceShowHide();\">",
((which_rryeartype_is_preselected == 1) ? "checked" : "")
);
wprintf("</b></td><td>\n");
wprintf("<input type=\"radio\" name=\"rrend\" id=\"rrend_none\" "
+ "value=\"rrend_none\" "
"%s onChange=\"RecurrenceShowHide();\">",
((which_rrend_is_preselected == 0) ? "checked" : "")
);
wprintf("%s<br />\n", _("No ending date"));
wprintf("<input type=\"radio\" name=\"rrend\" id=\"rrend_count\" "
+ "value=\"rrend_count\" "
"%s onChange=\"RecurrenceShowHide();\">",
((which_rrend_is_preselected == 1) ? "checked" : "")
);
wprintf("<br />\n");
wprintf("<input type=\"radio\" name=\"rrend\" id=\"rrend_until\" "
+ "value=\"rrend_until\" "
"%s onChange=\"RecurrenceShowHide();\">",
((which_rrend_is_preselected == 2) ? "checked" : "")
);
if (supplied_vevent != NULL) {
vevent = supplied_vevent;
+
+ /* Convert all timestamps to UTC to make them easier to process. */
+ ical_dezonify(vevent);
+
/*
* If we're looking at a fully encapsulated VCALENDAR
* rather than a VEVENT component, attempt to use the first
icaltime_from_webform(&event_start, "dtstart");
}
- /*
- * The following odd-looking snippet of code looks like it
- * takes some unnecessary steps. It is done this way because
- * libical incorrectly turns an "all day event" into a normal
- * event starting at midnight (i.e. it serializes as date/time
- * instead of just date) unless icalvalue_new_date() is used.
- * So we force it, if this is an all day event.
- */
prop = icalproperty_new_dtstart(event_start);
+
if (all_day_event) {
+ /* Force it to serialize as a date-only rather than date/time */
icalproperty_set_value(prop, icalvalue_new_date(event_start));
}
);
}
+ /* recurrence rules -- begin */
+
+ /* remove any existing rule */
+ while (prop = icalcomponent_get_first_property(vevent, ICAL_RRULE_PROPERTY), prop != NULL) {
+ icalcomponent_remove_property(vevent, prop);
+ icalproperty_free(prop);
+ }
+
+ if (yesbstr("is_recur")) {
+ struct icalrecurrencetype recur;
+ icalrecurrencetype_clear(&recur);
+
+ recur.interval = atoi(bstr("interval"));
+ recur.freq = atoi(bstr("freq"));
+
+ switch(recur.freq) {
+
+ /* These can't happen; they're disabled. */
+ case ICAL_SECONDLY_RECURRENCE:
+ break;
+ case ICAL_MINUTELY_RECURRENCE:
+ break;
+ case ICAL_HOURLY_RECURRENCE:
+ break;
+
+ /* Daily is valid but there are no further inputs. */
+ case ICAL_DAILY_RECURRENCE:
+ break;
+
+ /* These are the real options. */
+
+ case ICAL_WEEKLY_RECURRENCE:
+ j=0;
+ for (i=0; i<7; ++i) {
+ snprintf(buf, sizeof buf, "weekday%d", i);
+ if (YESBSTR(buf)) recur.by_day[j++] =
+ icalrecurrencetype_day_day_of_week(i+1);
+ }
+ recur.by_day[j++] = ICAL_RECURRENCE_ARRAY_MAX;
+ break;
+
+ case ICAL_MONTHLY_RECURRENCE:
+ if (!strcasecmp(bstr("rrmonthtype"), "rrmonthtype_mday")) {
+ recur.by_month_day[0] = event_start.day;
+ recur.by_month_day[1] = ICAL_RECURRENCE_ARRAY_MAX;
+ }
+ else if (!strcasecmp(bstr("rrmonthtype"), "rrmonthtype_wday")) {
+ recur.by_day[0] = (atoi(bstr("rrmweek")) * 8)
+ + atoi(bstr("rrmweekday")) + 1;
+ recur.by_day[1] = ICAL_RECURRENCE_ARRAY_MAX;
+ }
+ break;
+
+ case ICAL_YEARLY_RECURRENCE:
+ if (!strcasecmp(bstr("rryeartype"), "rryeartype_ymday")) {
+ /* no further action is needed here */
+ }
+ else if (!strcasecmp(bstr("rryeartype"), "rryeartype_ywday")) {
+ recur.by_month[0] = atoi(bstr("rrymonth"));
+ recur.by_month[1] = ICAL_RECURRENCE_ARRAY_MAX;
+ recur.by_day[0] = (atoi(bstr("rrymweek")) * 8)
+ + atoi(bstr("rrymweekday")) + 1;
+ recur.by_day[1] = ICAL_RECURRENCE_ARRAY_MAX;
+ }
+ break;
+
+ /* This one can't happen either. */
+ case ICAL_NO_RECURRENCE:
+ break;
+ }
+
+ if (!strcasecmp(bstr("rrend"), "rrend_count")) {
+ recur.count = atoi(bstr("rrcount"));
+ }
+ else if (!strcasecmp(bstr("rrend"), "rrend_until")) {
+ icaltime_from_webform_dateonly(&recur.until, "rruntil");
+ }
+
+ icalcomponent_add_property(vevent, icalproperty_new_rrule(recur));
+ }
+
+ /* recurrence rules -- end */
+
/* See if transparency is indicated */
if (havebstr("transp")) {
if (!strcasecmp(bstr("transp"), "opaque")) {
/* First, strip out the parenthesized partstats. */
strcpy(form_attendees, bstr("attendees"));
- stripout(form_attendees, '(', ')');
+ do {
+ i = strlen(form_attendees);
+ stripout(form_attendees, '(', ')');
+ j = strlen(form_attendees);
+ } while (i != j);
/* Next, change any commas to newlines, because we want newline-separated attendees. */
j = strlen(form_attendees);
/* If this was a save or delete, go back to the calendar view. */
if (!havebstr("check_button")) {
- readloop("readfwd");
+ readloop(readfwd);
}
}