4 * Handles the HTML display of calendar items.
10 #ifndef WEBCIT_WITH_CALENDAR_SERVICE
12 void do_calendar_view(void) { /* stub for non-libical builds */
13 wprintf("<CENTER><I>Calendar view not available</I></CENTER><br />\n");
16 void do_tasks_view(void) { /* stub for non-libical builds */
17 wprintf("<CENTER><I>Tasks view not available</I></CENTER><br />\n");
20 #else /* WEBCIT_WITH_CALENDAR_SERVICE */
22 /****************************************************************************/
25 void calendar_month_view_display_events(time_t thetime) {
31 struct icaltimetype t;
33 int all_day_event = 0;
35 if (WC->num_cal == 0) {
36 wprintf("<br /><br /><br />\n");
40 localtime_r(&thetime, &today_tm);
41 month = today_tm.tm_mon + 1;
42 day = today_tm.tm_mday;
43 year = today_tm.tm_year + 1900;
45 for (i=0; i<(WC->num_cal); ++i) {
46 p = icalcomponent_get_first_property(WC->disp_cal[i].cal,
47 ICAL_DTSTART_PROPERTY);
49 t = icalproperty_get_dtstart(p);
50 event_tt = icaltime_as_timet(t);
52 if (t.is_date) all_day_event = 1;
53 else all_day_event = 0;
56 gmtime_r(&event_tt, &event_tm);
59 localtime_r(&event_tt, &event_tm);
62 if ((event_tm.tm_year == today_tm.tm_year)
63 && (event_tm.tm_mon == today_tm.tm_mon)
64 && (event_tm.tm_mday == today_tm.tm_mday)) {
66 p = icalcomponent_get_first_property(
68 ICAL_SUMMARY_PROPERTY);
72 wprintf("<TABLE border=0 cellpadding=2><TR>"
73 "<TD BGCOLOR=\"#CCCCDD\">"
77 wprintf("<FONT SIZE=-1>"
78 "<A HREF=\"/display_edit_event?msgnum=%ld&calview=%s&year=%s&month=%s&day=%s\">",
79 WC->disp_cal[i].cal_msgnum,
86 icalproperty_get_comment(p));
87 wprintf("</A></FONT><br />\n");
90 wprintf("</TD></TR></TABLE>");
104 void calendar_month_view(int year, int month, int day) {
105 struct tm starting_tm;
109 time_t previous_month;
112 /* Determine what day to start.
113 * First, back up to the 1st of the month...
115 memset(&starting_tm, 0, sizeof(struct tm));
116 starting_tm.tm_year = year - 1900;
117 starting_tm.tm_mon = month - 1;
118 starting_tm.tm_mday = day;
119 thetime = mktime(&starting_tm);
121 memcpy(&tm, &starting_tm, sizeof(struct tm));
122 while (tm.tm_mday != 1) {
123 thetime = thetime - (time_t)86400; /* go back 24 hours */
124 localtime_r(&thetime, &tm);
127 /* Determine previous and next months ... for links */
128 previous_month = thetime - (time_t)864000L; /* back 10 days */
129 next_month = thetime + (time_t)(31L * 86400L); /* ahead 31 days */
131 /* Now back up until we're on a Sunday */
132 localtime_r(&thetime, &tm);
133 while (tm.tm_wday != 0) {
134 thetime = thetime - (time_t)86400; /* go back 24 hours */
135 localtime_r(&thetime, &tm);
138 /* Outer table (to get the background color) */
139 wprintf("<div id=\"fix_scrollbar_bug\">"
140 "<TABLE width=100%% border=0 cellpadding=0 cellspacing=0 "
141 "bgcolor=#204B78><TR><TD>\n");
143 wprintf("<TABLE width=100%% border=0 cellpadding=0 cellspacing=0><tr>\n");
145 wprintf("<TD ALIGN=CENTER>");
147 localtime_r(&previous_month, &tm);
148 wprintf("<A HREF=\"readfwd?calview=month&year=%d&month=%d&day=1\">",
149 (int)(tm.tm_year)+1900, tm.tm_mon + 1);
150 wprintf("<IMG ALIGN=MIDDLE SRC=\"/static/prevdate_32x.gif\" BORDER=0></A>\n");
152 wprintf(" "
153 "<FONT SIZE=+1 COLOR=\"#FFFFFF\">"
156 " ", months[month-1], year);
158 localtime_r(&next_month, &tm);
159 wprintf("<A HREF=\"readfwd?calview=month&year=%d&month=%d&day=1\">",
160 (int)(tm.tm_year)+1900, tm.tm_mon + 1);
161 wprintf("<IMG ALIGN=MIDDLE SRC=\"/static/nextdate_32x.gif\" BORDER=0></A>\n");
163 wprintf("</TD></TR></TABLE>\n");
165 /* Inner table (the real one) */
166 wprintf("<TABLE width=100%% border=0 cellpadding=1 cellspacing=1 "
167 "bgcolor=#204B78><TR>");
168 for (i=0; i<7; ++i) {
169 wprintf("<TD ALIGN=CENTER WIDTH=14%%>"
170 "<FONT COLOR=\"#FFFFFF\">%s</FONT></TH>", days[i]);
175 for (i = 0; i < 35; ++i) {
176 localtime_r(&thetime, &tm);
178 /* Before displaying Sunday, start a new row */
183 wprintf("<TD BGCOLOR=\"#%s\" WIDTH=14%% HEIGHT=60 align=left VALIGN=TOP><B>",
184 ((tm.tm_mon != month-1) ? "DDDDDD" :
185 ((tm.tm_wday==0 || tm.tm_wday==6) ? "EEEECC" :
188 if ((i==0) || (tm.tm_mday == 1)) {
189 wprintf("%s ", months[tm.tm_mon]);
191 wprintf("<A HREF=\"readfwd?calview=day&year=%d&month=%d&day=%d\">"
198 /* put the data here, stupid */
199 calendar_month_view_display_events(thetime);
203 /* After displaying Saturday, end the row */
208 thetime += (time_t)86400; /* ahead 24 hours */
211 wprintf("</TABLE>" /* end of inner table */
212 "</TD></TR></TABLE>" /* end of outer table */
217 void calendar_week_view(int year, int month, int day) {
218 wprintf("<CENTER><I>week view FIXME</I></CENTER><br />\n");
223 * Display events for a particular hour of a particular day.
224 * (Specify hour < 0 to show "all day" events)
226 void calendar_day_view_display_events(int year, int month,
230 struct icaltimetype t;
233 int all_day_event = 0;
235 if (WC->num_cal == 0) {
236 // FIXME wprintf("<br /><br /><br />\n");
240 for (i=0; i<(WC->num_cal); ++i) {
241 p = icalcomponent_get_first_property(WC->disp_cal[i].cal,
242 ICAL_DTSTART_PROPERTY);
244 t = icalproperty_get_dtstart(p);
245 event_tt = icaltime_as_timet(t);
246 if (t.is_date) all_day_event = 1;
249 event_tm = gmtime(&event_tt);
252 event_tm = localtime(&event_tt);
255 if ((event_tm->tm_year == (year-1900))
256 && (event_tm->tm_mon == (month-1))
257 && (event_tm->tm_mday == day)
258 && ( ((event_tm->tm_hour == hour)&&(!t.is_date)) || ((hour<0)&&(t.is_date)) )
262 p = icalcomponent_get_first_property(
264 ICAL_SUMMARY_PROPERTY);
268 wprintf("<TABLE border=1 cellpadding=2><TR>"
269 "<TD BGCOLOR=\"#CCCCCC\">"
273 wprintf("<FONT SIZE=-1>"
274 "<A HREF=\"/display_edit_event?msgnum=%ld&calview=day&year=%d&month=%d&day=%d\">",
275 WC->disp_cal[i].cal_msgnum,
279 icalproperty_get_comment(p));
280 wprintf("</A></FONT><br />\n");
283 wprintf("</TD></TR></TABLE>");
296 void calendar_day_view(int year, int month, int day) {
298 struct icaltimetype today, yesterday, tomorrow;
299 char calhourformat[16];
301 get_preference("calhourformat", calhourformat, sizeof calhourformat);
303 /* Figure out the dates for "yesterday" and "tomorrow" links */
305 memset(&today, 0, sizeof(struct icaltimetype));
311 memcpy(&yesterday, &today, sizeof(struct icaltimetype));
313 yesterday = icaltime_normalize(yesterday);
315 memcpy(&tomorrow, &today, sizeof(struct icaltimetype));
317 tomorrow = icaltime_normalize(tomorrow);
320 /* Outer table (to get the background color) */
321 wprintf("<div id=\"fix_scrollbar_bug\">"
322 "<TABLE width=100%% border=0 cellpadding=0 cellspacing=0 "
323 "bgcolor=#204B78><TR><TD>\n");
325 /* Inner table (the real one) */
326 wprintf("<TABLE width=100%% border=0 cellpadding=1 cellspacing=1 "
327 "bgcolor=#204B78><TR>\n");
329 /* Innermost table (contains hours etc.) */
330 wprintf("<TD WIDTH=80%%>"
331 "<TABLE width=100%% border=0 cellpadding=1 cellspacing=1 "
332 "bgcolor=#204B78>\n");
334 /* Display events before 8:00 (hour=-1 is all-day events) */
336 "<TD BGCOLOR=\"#CCCCDD\" VALIGN=MIDDLE WIDTH=10%%></TD>"
337 "<TD BGCOLOR=\"#FFFFFF\" VALIGN=TOP>");
338 for (hour = (-1); hour <= 7; ++hour) {
339 calendar_day_view_display_events(year, month, day, hour);
341 wprintf("</TD></TR>\n");
343 /* Now the middle of the day... */
344 for (hour = 8; hour <= 17; ++hour) { /* could do HEIGHT=xx */
345 wprintf("<TR HEIGHT=30><TD BGCOLOR=\"#CCCCDD\" ALIGN=MIDDLE "
346 "VALIGN=MIDDLE WIDTH=10%%>");
347 wprintf("<A HREF=\"/display_edit_event?msgnum=0"
348 "&year=%d&month=%d&day=%d&hour=%d&minute=0\">",
349 year, month, day, hour
352 if (!strcasecmp(calhourformat, "24")) {
353 wprintf("%2d:00</A> ", hour);
356 wprintf("%d:00%s</A> ",
357 (hour <= 12 ? hour : hour-12),
358 (hour < 12 ? "am" : "pm")
362 wprintf("</TD><TD BGCOLOR=\"#FFFFFF\" VALIGN=TOP>");
364 /* put the data here, stupid */
365 calendar_day_view_display_events(year, month, day, hour);
367 wprintf("</TD></TR>\n");
370 /* Display events after 5:00... */
372 "<TD BGCOLOR=\"#CCCCDD\" VALIGN=MIDDLE WIDTH=10%%></TD>"
373 "<TD BGCOLOR=\"#FFFFFF\" VALIGN=TOP>");
374 for (hour = 18; hour <= 23; ++hour) {
375 calendar_day_view_display_events(year, month, day, hour);
377 wprintf("</TD></TR>\n");
380 wprintf("</TABLE>" /* end of innermost table */
384 wprintf("<TD WIDTH=20%% VALIGN=top>"); /* begin stuff-on-the-right */
387 /* Begin todays-date-with-left-and-right-arrows */
388 wprintf("<TABLE BORDER=0 WIDTH=100%% "
389 "CELLSPACING=0 CELLPADDING=0 BGCOLOR=\"#FFFFFF\">\n");
393 wprintf("<TD ALIGN=CENTER>");
394 wprintf("<A HREF=\"readfwd?calview=day&year=%d&month=%d&day=%d\">",
395 yesterday.year, yesterday.month, yesterday.day);
396 wprintf("<IMG ALIGN=MIDDLE SRC=\"/static/prevdate_32x.gif\" BORDER=0></A>");
400 wprintf("<TD ALIGN=CENTER>");
401 wprintf("<FONT SIZE=+2>%s</FONT><br />"
402 "<FONT SIZE=+3>%d</FONT><br />"
403 "<FONT SIZE=+2>%d</FONT><br />",
404 months[month-1], day, year);
408 wprintf("<TD ALIGN=CENTER>");
409 wprintf("<A HREF=\"readfwd?calview=day&year=%d&month=%d&day=%d\">",
410 tomorrow.year, tomorrow.month, tomorrow.day);
411 wprintf("<IMG ALIGN=MIDDLE SRC=\"/static/nextdate_32x.gif\""
415 wprintf("</TR></TABLE>\n");
416 /* End todays-date-with-left-and-right-arrows */
418 /* In the future we might want to put a month-o-matic here */
420 wprintf("</FONT></CENTER>\n");
422 wprintf("</TD>"); /* end stuff-on-the-right */
426 wprintf("</TR></TABLE>" /* end of inner table */
427 "</TD></TR></TABLE></div>" /* end of outer table */
435 * Display today's events.
437 void calendar_summary_view(void) {
440 struct icaltimetype t;
445 int all_day_event = 0;
446 char timestring[SIZ];
448 if (WC->num_cal == 0) {
453 localtime_r(&now, &today_tm);
455 for (i=0; i<(WC->num_cal); ++i) {
456 p = icalcomponent_get_first_property(WC->disp_cal[i].cal,
457 ICAL_DTSTART_PROPERTY);
459 t = icalproperty_get_dtstart(p);
460 event_tt = icaltime_as_timet(t);
461 if (t.is_date) all_day_event = 1;
462 fmt_time(timestring, event_tt);
465 gmtime_r(&event_tt, &event_tm);
468 localtime_r(&event_tt, &event_tm);
471 if ( (event_tm.tm_year == today_tm.tm_year)
472 && (event_tm.tm_mon == today_tm.tm_mon)
473 && (event_tm.tm_mday == today_tm.tm_mday)
477 p = icalcomponent_get_first_property(
479 ICAL_SUMMARY_PROPERTY);
482 icalproperty_get_comment(p));
483 wprintf(" (%s)<br />\n", timestring);
488 free_calendar_buffer();
493 void free_calendar_buffer(void) {
495 if (WC->num_cal) for (i=0; i<(WC->num_cal); ++i) {
496 icalcomponent_free(WC->disp_cal[i].cal);
506 void do_calendar_view(void) {
509 int year, month, day;
512 /* In case no date was specified, go with today */
514 localtime_r(&now, &tm);
515 year = tm.tm_year + 1900;
516 month = tm.tm_mon + 1;
519 /* Now see if a date was specified */
520 if (strlen(bstr("year")) > 0) year = atoi(bstr("year"));
521 if (strlen(bstr("month")) > 0) month = atoi(bstr("month"));
522 if (strlen(bstr("day")) > 0) day = atoi(bstr("day"));
524 /* How would you like that cooked? */
525 if (strlen(bstr("calview")) > 0) {
526 strcpy(calview, bstr("calview"));
529 strcpy(calview, "month");
532 /* Display the selected view */
533 if (!strcasecmp(calview, "day")) {
534 calendar_day_view(year, month, day);
536 else if (!strcasecmp(calview, "week")) {
537 calendar_week_view(year, month, day);
540 calendar_month_view(year, month, day);
543 /* Free the calendar stuff */
544 free_calendar_buffer();
550 * Helper function for do_tasks_view(). Returns the date/time due.
552 time_t get_task_due_date(icalcomponent *vtodo) {
559 /* If we're looking at a fully encapsulated VCALENDAR
560 * rather than a VTODO component, recurse into the data
561 * structure until we get a VTODO.
563 if (icalcomponent_isa(vtodo) == ICAL_VCALENDAR_COMPONENT) {
564 return get_task_due_date(
565 icalcomponent_get_first_component(
566 vtodo, ICAL_VTODO_COMPONENT
571 p = icalcomponent_get_first_property(vtodo, ICAL_DUE_PROPERTY);
573 return(icaltime_as_timet(icalproperty_get_due(p)));
582 * Compare the due dates of two tasks (this is for sorting)
584 int task_due_cmp(const void *task1, const void *task2) {
588 t1 = get_task_due_date(((struct disp_cal *)task1)->cal);
589 t2 = get_task_due_date(((struct disp_cal *)task2)->cal);
591 if (t1 < t2) return(-1);
592 if (t1 > t2) return(1);
600 void do_tasks_view(void) {
607 wprintf("<div id=\"fix_scrollbar_bug\">"
608 "<table border=0 cellspacing=0 width=100%% bgcolor=\"#FFFFFF\">\n<tr>\n"
609 "<TH>Name of task</TH>\n"
610 "<TH>Date due</TH></TR>\n"
613 /* Sort them if necessary */
614 if (WC->num_cal > 1) {
617 sizeof(struct disp_cal),
622 if (WC->num_cal) for (i=0; i<(WC->num_cal); ++i) {
625 wprintf("<TR BGCOLOR=\"#%s\"><TD>",
626 (bg ? "DDDDDD" : "FFFFFF")
629 p = icalcomponent_get_first_property(WC->disp_cal[i].cal,
630 ICAL_SUMMARY_PROPERTY);
631 wprintf("<A HREF=\"/display_edit_task?msgnum=%ld&taskrm=",
632 WC->disp_cal[i].cal_msgnum );
633 urlescputs(WC->wc_roomname);
635 wprintf("<IMG ALIGN=MIDDLE "
636 "SRC=\"/static/taskmanag_16x.gif\" BORDER=0> ");
638 escputs((char *)icalproperty_get_comment(p));
643 due = get_task_due_date(WC->disp_cal[i].cal);
644 fmt_date(buf, due, 0);
645 wprintf("<TD><FONT");
646 if (due < time(NULL)) {
647 wprintf(" COLOR=\"#FF0000\"");
649 wprintf(">%s</FONT></TD></TR>\n", buf);
652 wprintf("</table></div>\n");
655 free_calendar_buffer();
659 #endif /* WEBCIT_WITH_CALENDAR_SERVICE */