#include "webcit.h"
#include "webserver.h"
+#include "calendar.h"
/*
* Display an event by itself (for editing)
* msgnum reference on the citserver
*/
void display_edit_individual_event(icalcomponent *supplied_vevent, long msgnum, char *from,
- int unread, struct calview *calv)
+ int unread, calview *calv)
{
icalcomponent *vevent;
icalproperty *p;
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("SEQUENCE == %d<br />\n", sequence);
*************************************************************/
- wprintf("<FORM NAME=\"EventForm\" METHOD=\"POST\" action=\"save_event\">\n");
+ wprintf("<form name=\"EventForm\" method=\"POST\" action=\"save_event\">\n");
wprintf("<input type=\"hidden\" name=\"nonce\" value=\"%d\">\n", WC->nonce);
wprintf("<INPUT TYPE=\"hidden\" NAME=\"msgnum\" VALUE=\"%ld\">\n",
wprintf("<INPUT TYPE=\"hidden\" NAME=\"day\" VALUE=\"%s\">\n",
bstr("day"));
- char *tabnames[] = {
- _("Event"),
- _("Attendees"),
- _("Recurrence")
- };
tabbed_dialog(3, tabnames);
begin_tab(0, 3);
wprintf("</TD></TR>\n");
- /*
- * If this is an all-day-event, set the end time to be identical to
- * the start time (the hour/minute/second will be set to midnight).
- * Otherwise extract or create it.
- */
wprintf("<TR><TD><B>");
wprintf(_("End"));
wprintf("</B></TD><TD id=\"dtendcell\">\n");
- if (t_start.is_date) {
- t_end = t_start;
+ p = icalcomponent_get_first_property(vevent,
+ ICAL_DTEND_PROPERTY);
+ if (p != NULL) {
+ t_end = icalproperty_get_dtend(p);
+
+ /*
+ * If this is an all-day-event, the end time is set to real end
+ * day + 1, so we have to adjust accordingly.
+ */
+ if (t_start.is_date) {
+ icaltime_adjust(&t_end, -1, 0, 0, 0);
+ }
}
else {
- p = icalcomponent_get_first_property(vevent,
- ICAL_DTEND_PROPERTY);
- if (p != NULL) {
- t_end = icalproperty_get_dtend(p);
+ if (created_new_vevent == 1) {
+ /* set default duration */
+ if (t_start.is_date) {
+ /*
+ * If this is an all-day-event, set the end time to be identical to
+ * the start time (the hour/minute/second will be set to midnight).
+ */
+ t_end = t_start;
+ }
+ else {
+ /*
+ * If this is not an all-day event and there is no
+ * end time specified, make the default one hour
+ * from the start time.
+ */
+ t_end = t_start;
+ t_end.hour += 1;
+ t_end.second = 0;
+ t_end = icaltime_normalize(t_end);
+ /* t_end = icaltime_from_timet(now, 0); */
+ }
}
else {
/*
- * If this is not an all-day event and there is no
- * end time specified, make the default one hour
- * from the start time.
+ * If an existing event has no end date/time this is
+ * supposed to mean end = start.
*/
t_end = t_start;
- t_end.hour += 1;
- t_end.second = 0;
- t_end = icaltime_normalize(t_end);
- /* t_end = icaltime_from_timet(now, 0); */
}
}
display_icaltimetype_as_webform(&t_end, "dtend", 0);
wprintf(_("Notes"));
wprintf("</B></TD><TD>\n"
"<TEXTAREA NAME=\"description\" wrap=soft "
- "ROWS=5 COLS=80 WIDTH=80>\n"
+ "ROWS=5 COLS=72 WIDTH=72>\n"
);
p = icalcomponent_get_first_property(vevent, ICAL_DESCRIPTION_PROPERTY);
if (p != NULL) {
*/
if (icalcomponent_get_first_property(vevent, ICAL_ORGANIZER_PROPERTY)
== NULL) {
- sprintf(organizer_string, "MAILTO:%s", WC->cs_inet_email);
+ sprintf(organizer_string, "MAILTO:%s", ChrPtr(WC->cs_inet_email));
icalcomponent_add_property(vevent,
icalproperty_new_organizer(organizer_string)
);
wprintf("</TD><TD>"
"<TEXTAREA %s NAME=\"attendees\" id=\"attendees_box\" wrap=soft "
- "ROWS=3 COLS=80 WIDTH=80>\n",
+ "onchange=\"EnableOrDisableCheckButton();\" "
+ "onKeyPress=\"EnableOrDisableCheckButton();\" "
+ "ROWS=10 COLS=72 WIDTH=72>\n",
(organizer_is_me ? "" : "DISABLED ")
);
i = 0;
/* 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"),
((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\" "
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)
- && (recur.by_month[0] != ICAL_RECURRENCE_ARRAY_MAX) ) {
+ if (
+ (recur.by_day[0] != ICAL_RECURRENCE_ARRAY_MAX)
+ && (recur.by_day[0] != 0)
+ && (recur.by_month[0] != ICAL_RECURRENCE_ARRAY_MAX)
+ && (recur.by_month[0] != 0)
+ ) {
which_rryeartype_is_preselected = 1;
rrymweek = icalrecurrencetype_day_position(recur.by_day[0]);
rrymweekday = icalrecurrencetype_day_day_of_week(recur.by_day[0]) - 1;
" "
"<INPUT TYPE=\"submit\" NAME=\"delete_button\" VALUE=\"%s\">\n"
" "
- "<INPUT TYPE=\"submit\" NAME=\"check_button\" "
- "VALUE=\"%s\">\n"
+ "<INPUT TYPE=\"submit\" id=\"check_button\" NAME=\"check_button\" VALUE=\"%s\">\n"
" "
"<INPUT TYPE=\"submit\" NAME=\"cancel_button\" VALUE=\"%s\">\n"
"</CENTER>\n",
wprintf("</div>\n"); /* end 'fix_scrollbar_bug' div */
StrBufAppendPrintf(WC->trailing_javascript,
- "eventEditAllDay(); \n"
- "RecurrenceShowHide(); \n"
+ "eventEditAllDay(); \n"
+ "RecurrenceShowHide(); \n"
+ "EnableOrDisableCheckButton(); \n"
);
address_book_popup();
wDumpContent(1);
* msgnum: the index on the citserver
*/
void save_individual_event(icalcomponent *supplied_vevent, long msgnum, char *from,
- int unread, struct calview *calv) {
+ int unread, calview *calv) {
char buf[SIZ];
icalproperty *prop;
icalcomponent *vevent, *encaps;
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
icalproperty_free(prop);
}
+ /* Add NOW() to the calendar object... */
+ icalcomponent_set_dtstamp(vevent,
+ icaltime_from_timet(
+ time(NULL), 0));
+
if (havebstr("summary")) {
-
icalcomponent_add_property(vevent,
icalproperty_new_summary(bstr("summary")));
} else {
icalcomponent_add_property(vevent,
- icalproperty_new_summary("Untitled Event"));
+ icalproperty_new_summary(_("Untitled Event")));
}
while (prop = icalcomponent_get_first_property(vevent,
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));
}
icalproperty_free(prop);
}
- if (all_day_event == 0) {
+ if (all_day_event) {
+ icaltime_from_webform_dateonly(&t, "dtend");
+
+ /* with this field supposed to be non-inclusive we have to add one day */
+ icaltime_adjust(&t, 1, 0, 0, 0);
+ }
+ else {
icaltime_from_webform(&t, "dtend");
- icalcomponent_add_property(vevent,
- icalproperty_new_dtend(icaltime_normalize(t)
- )
- );
}
+ icalcomponent_add_property(vevent,
+ icalproperty_new_dtend(icaltime_normalize(t)
+ )
+ );
+
/* recurrence rules -- begin */
/* remove any existing rule */
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. */
/* First, strip out the parenthesized partstats. */
strcpy(form_attendees, bstr("attendees"));
- stripout(form_attendees, '(', ')');
+ while ( stripout(form_attendees, '(', ')') != 0);
/* Next, change any commas to newlines, because we want newline-separated attendees. */
j = strlen(form_attendees);
icalcomponent_free(vevent);
}
- /* If this was a save or delete, go back to the calendar view. */
+ /* If this was a save or delete, go back to the calendar or summary view. */
if (!havebstr("check_button")) {
- readloop("readfwd");
+ if (!strcasecmp(bstr("calview"), "summary")) {
+ summary();
+ }
+ else {
+ readloop(readfwd);
+ }
}
}