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>");
14 wprintf(_("The calendar view is not available."));
15 wprintf("</I></CENTER><br />\n");
18 void do_tasks_view(void) { /* stub for non-libical builds */
19 wprintf("<CENTER><I>");
20 wprintf(_("The tasks view is not available."));
21 wprintf("</I></CENTER><br />\n");
24 #else /* WEBCIT_WITH_CALENDAR_SERVICE */
26 /****************************************************************************/
29 void calendar_month_view_display_events(time_t thetime) {
35 struct icaltimetype t;
37 int all_day_event = 0;
39 if (WC->num_cal == 0) {
40 wprintf("<br /><br /><br />\n");
44 localtime_r(&thetime, &today_tm);
45 month = today_tm.tm_mon + 1;
46 day = today_tm.tm_mday;
47 year = today_tm.tm_year + 1900;
49 for (i=0; i<(WC->num_cal); ++i) {
50 p = icalcomponent_get_first_property(WC->disp_cal[i].cal,
51 ICAL_DTSTART_PROPERTY);
53 t = icalproperty_get_dtstart(p);
54 event_tt = icaltime_as_timet(t);
56 if (t.is_date) all_day_event = 1;
57 else all_day_event = 0;
60 gmtime_r(&event_tt, &event_tm);
63 localtime_r(&event_tt, &event_tm);
66 if ((event_tm.tm_year == today_tm.tm_year)
67 && (event_tm.tm_mon == today_tm.tm_mon)
68 && (event_tm.tm_mday == today_tm.tm_mday)) {
70 p = icalcomponent_get_first_property(
72 ICAL_SUMMARY_PROPERTY);
76 wprintf("<TABLE border=0 cellpadding=2><TR>"
77 "<TD BGCOLOR=\"#CCCCDD\">"
81 wprintf("<FONT SIZE=-1>"
82 "<A HREF=\"/display_edit_event?msgnum=%ld&calview=%s&year=%s&month=%s&day=%s\">",
83 WC->disp_cal[i].cal_msgnum,
90 icalproperty_get_comment(p));
91 wprintf("</A></FONT><br />\n");
94 wprintf("</TD></TR></TABLE>");
108 void calendar_month_view(int year, int month, int day) {
109 struct tm starting_tm;
113 time_t previous_month;
116 /* Determine what day to start.
117 * First, back up to the 1st of the month...
119 memset(&starting_tm, 0, sizeof(struct tm));
120 starting_tm.tm_year = year - 1900;
121 starting_tm.tm_mon = month - 1;
122 starting_tm.tm_mday = day;
123 thetime = mktime(&starting_tm);
125 memcpy(&tm, &starting_tm, sizeof(struct tm));
126 while (tm.tm_mday != 1) {
127 thetime = thetime - (time_t)86400; /* go back 24 hours */
128 localtime_r(&thetime, &tm);
131 /* Determine previous and next months ... for links */
132 previous_month = thetime - (time_t)864000L; /* back 10 days */
133 next_month = thetime + (time_t)(31L * 86400L); /* ahead 31 days */
135 /* Now back up until we're on a Sunday */
136 localtime_r(&thetime, &tm);
137 while (tm.tm_wday != 0) {
138 thetime = thetime - (time_t)86400; /* go back 24 hours */
139 localtime_r(&thetime, &tm);
142 /* Outer table (to get the background color) */
143 wprintf("<div id=\"fix_scrollbar_bug\">"
144 "<TABLE width=100%% border=0 cellpadding=0 cellspacing=0 "
145 "bgcolor=#204B78><TR><TD>\n");
147 wprintf("<TABLE width=100%% border=0 cellpadding=0 cellspacing=0><tr>\n");
149 wprintf("<TD ALIGN=CENTER>");
151 localtime_r(&previous_month, &tm);
152 wprintf("<A HREF=\"readfwd?calview=month&year=%d&month=%d&day=1\">",
153 (int)(tm.tm_year)+1900, tm.tm_mon + 1);
154 wprintf("<IMG ALIGN=MIDDLE SRC=\"/static/prevdate_32x.gif\" BORDER=0></A>\n");
156 wprintf(" "
157 "<FONT SIZE=+1 COLOR=\"#FFFFFF\">"
160 " ", months[month-1], year);
162 localtime_r(&next_month, &tm);
163 wprintf("<A HREF=\"readfwd?calview=month&year=%d&month=%d&day=1\">",
164 (int)(tm.tm_year)+1900, tm.tm_mon + 1);
165 wprintf("<IMG ALIGN=MIDDLE SRC=\"/static/nextdate_32x.gif\" BORDER=0></A>\n");
167 wprintf("</TD></TR></TABLE>\n");
169 /* Inner table (the real one) */
170 wprintf("<TABLE width=100%% border=0 cellpadding=1 cellspacing=1 "
171 "bgcolor=#204B78><TR>");
172 for (i=0; i<7; ++i) {
173 wprintf("<TD ALIGN=CENTER WIDTH=14%%>"
174 "<FONT COLOR=\"#FFFFFF\">%s</FONT></TH>", days[i]);
179 for (i = 0; i < 35; ++i) {
180 localtime_r(&thetime, &tm);
182 /* Before displaying Sunday, start a new row */
187 wprintf("<TD BGCOLOR=\"#%s\" WIDTH=14%% HEIGHT=60 align=left VALIGN=TOP><B>",
188 ((tm.tm_mon != month-1) ? "DDDDDD" :
189 ((tm.tm_wday==0 || tm.tm_wday==6) ? "EEEECC" :
192 if ((i==0) || (tm.tm_mday == 1)) {
193 wprintf("%s ", months[tm.tm_mon]);
195 wprintf("<A HREF=\"readfwd?calview=day&year=%d&month=%d&day=%d\">"
202 /* put the data here, stupid */
203 calendar_month_view_display_events(thetime);
207 /* After displaying Saturday, end the row */
212 thetime += (time_t)86400; /* ahead 24 hours */
215 wprintf("</TABLE>" /* end of inner table */
216 "</TD></TR></TABLE>" /* end of outer table */
221 void calendar_week_view(int year, int month, int day) {
222 wprintf("<CENTER><I>week view FIXME</I></CENTER><br />\n");
227 * Display events for a particular hour of a particular day.
228 * (Specify hour < 0 to show "all day" events)
230 void calendar_day_view_display_events(int year, int month,
234 struct icaltimetype t;
237 int all_day_event = 0;
239 if (WC->num_cal == 0) {
240 // FIXME wprintf("<br /><br /><br />\n");
244 for (i=0; i<(WC->num_cal); ++i) {
245 p = icalcomponent_get_first_property(WC->disp_cal[i].cal,
246 ICAL_DTSTART_PROPERTY);
248 t = icalproperty_get_dtstart(p);
249 event_tt = icaltime_as_timet(t);
250 if (t.is_date) all_day_event = 1;
253 event_tm = gmtime(&event_tt);
256 event_tm = localtime(&event_tt);
259 if ((event_tm->tm_year == (year-1900))
260 && (event_tm->tm_mon == (month-1))
261 && (event_tm->tm_mday == day)
262 && ( ((event_tm->tm_hour == hour)&&(!t.is_date)) || ((hour<0)&&(t.is_date)) )
266 p = icalcomponent_get_first_property(
268 ICAL_SUMMARY_PROPERTY);
272 wprintf("<TABLE border=1 cellpadding=2><TR>"
273 "<TD BGCOLOR=\"#CCCCCC\">"
277 wprintf("<FONT SIZE=-1>"
278 "<A HREF=\"/display_edit_event?msgnum=%ld&calview=day&year=%d&month=%d&day=%d\">",
279 WC->disp_cal[i].cal_msgnum,
283 icalproperty_get_comment(p));
284 wprintf("</A></FONT><br />\n");
287 wprintf("</TD></TR></TABLE>");
300 void calendar_day_view(int year, int month, int day) {
302 struct icaltimetype today, yesterday, tomorrow;
303 char calhourformat[16];
305 get_preference("calhourformat", calhourformat, sizeof calhourformat);
307 /* Figure out the dates for "yesterday" and "tomorrow" links */
309 memset(&today, 0, sizeof(struct icaltimetype));
315 memcpy(&yesterday, &today, sizeof(struct icaltimetype));
317 yesterday = icaltime_normalize(yesterday);
319 memcpy(&tomorrow, &today, sizeof(struct icaltimetype));
321 tomorrow = icaltime_normalize(tomorrow);
324 /* Outer table (to get the background color) */
325 wprintf("<div id=\"fix_scrollbar_bug\">"
326 "<TABLE width=100%% border=0 cellpadding=0 cellspacing=0 "
327 "bgcolor=#204B78><TR><TD>\n");
329 /* Inner table (the real one) */
330 wprintf("<TABLE width=100%% border=0 cellpadding=1 cellspacing=1 "
331 "bgcolor=#204B78><TR>\n");
333 /* Innermost table (contains hours etc.) */
334 wprintf("<TD WIDTH=80%%>"
335 "<TABLE width=100%% border=0 cellpadding=1 cellspacing=1 "
336 "bgcolor=#204B78>\n");
338 /* Display events before 8:00 (hour=-1 is all-day events) */
340 "<TD BGCOLOR=\"#CCCCDD\" VALIGN=MIDDLE WIDTH=10%%></TD>"
341 "<TD BGCOLOR=\"#FFFFFF\" VALIGN=TOP>");
342 for (hour = (-1); hour <= 7; ++hour) {
343 calendar_day_view_display_events(year, month, day, hour);
345 wprintf("</TD></TR>\n");
347 /* Now the middle of the day... */
348 for (hour = 8; hour <= 17; ++hour) { /* could do HEIGHT=xx */
349 wprintf("<TR HEIGHT=30><TD BGCOLOR=\"#CCCCDD\" ALIGN=MIDDLE "
350 "VALIGN=MIDDLE WIDTH=10%%>");
351 wprintf("<A HREF=\"/display_edit_event?msgnum=0"
352 "&year=%d&month=%d&day=%d&hour=%d&minute=0\">",
353 year, month, day, hour
356 if (!strcasecmp(calhourformat, "24")) {
357 wprintf("%2d:00</A> ", hour);
360 wprintf("%d:00%s</A> ",
361 (hour <= 12 ? hour : hour-12),
362 (hour < 12 ? "am" : "pm")
366 wprintf("</TD><TD BGCOLOR=\"#FFFFFF\" VALIGN=TOP>");
368 /* put the data here, stupid */
369 calendar_day_view_display_events(year, month, day, hour);
371 wprintf("</TD></TR>\n");
374 /* Display events after 5:00... */
376 "<TD BGCOLOR=\"#CCCCDD\" VALIGN=MIDDLE WIDTH=10%%></TD>"
377 "<TD BGCOLOR=\"#FFFFFF\" VALIGN=TOP>");
378 for (hour = 18; hour <= 23; ++hour) {
379 calendar_day_view_display_events(year, month, day, hour);
381 wprintf("</TD></TR>\n");
384 wprintf("</TABLE>" /* end of innermost table */
388 wprintf("<TD WIDTH=20%% VALIGN=top>"); /* begin stuff-on-the-right */
391 /* Begin todays-date-with-left-and-right-arrows */
392 wprintf("<TABLE BORDER=0 WIDTH=100%% "
393 "CELLSPACING=0 CELLPADDING=0 BGCOLOR=\"#FFFFFF\">\n");
397 wprintf("<TD ALIGN=CENTER>");
398 wprintf("<A HREF=\"readfwd?calview=day&year=%d&month=%d&day=%d\">",
399 yesterday.year, yesterday.month, yesterday.day);
400 wprintf("<IMG ALIGN=MIDDLE SRC=\"/static/prevdate_32x.gif\" BORDER=0></A>");
404 wprintf("<TD ALIGN=CENTER>");
405 wprintf("<FONT SIZE=+2>%s</FONT><br />"
406 "<FONT SIZE=+3>%d</FONT><br />"
407 "<FONT SIZE=+2>%d</FONT><br />",
408 months[month-1], day, year);
412 wprintf("<TD ALIGN=CENTER>");
413 wprintf("<A HREF=\"readfwd?calview=day&year=%d&month=%d&day=%d\">",
414 tomorrow.year, tomorrow.month, tomorrow.day);
415 wprintf("<IMG ALIGN=MIDDLE SRC=\"/static/nextdate_32x.gif\""
419 wprintf("</TR></TABLE>\n");
420 /* End todays-date-with-left-and-right-arrows */
422 /* In the future we might want to put a month-o-matic here */
424 wprintf("</FONT></CENTER>\n");
426 wprintf("</TD>"); /* end stuff-on-the-right */
430 wprintf("</TR></TABLE>" /* end of inner table */
431 "</TD></TR></TABLE></div>" /* end of outer table */
439 * Display today's events.
441 void calendar_summary_view(void) {
444 struct icaltimetype t;
449 int all_day_event = 0;
450 char timestring[SIZ];
452 if (WC->num_cal == 0) {
457 localtime_r(&now, &today_tm);
459 for (i=0; i<(WC->num_cal); ++i) {
460 p = icalcomponent_get_first_property(WC->disp_cal[i].cal,
461 ICAL_DTSTART_PROPERTY);
463 t = icalproperty_get_dtstart(p);
464 event_tt = icaltime_as_timet(t);
465 if (t.is_date) all_day_event = 1;
466 fmt_time(timestring, event_tt);
469 gmtime_r(&event_tt, &event_tm);
472 localtime_r(&event_tt, &event_tm);
475 if ( (event_tm.tm_year == today_tm.tm_year)
476 && (event_tm.tm_mon == today_tm.tm_mon)
477 && (event_tm.tm_mday == today_tm.tm_mday)
481 p = icalcomponent_get_first_property(
483 ICAL_SUMMARY_PROPERTY);
486 icalproperty_get_comment(p));
487 wprintf(" (%s)<br />\n", timestring);
492 free_calendar_buffer();
497 void free_calendar_buffer(void) {
499 if (WC->num_cal) for (i=0; i<(WC->num_cal); ++i) {
500 icalcomponent_free(WC->disp_cal[i].cal);
510 void do_calendar_view(void) {
513 int year, month, day;
516 /* In case no date was specified, go with today */
518 localtime_r(&now, &tm);
519 year = tm.tm_year + 1900;
520 month = tm.tm_mon + 1;
523 /* Now see if a date was specified */
524 if (strlen(bstr("year")) > 0) year = atoi(bstr("year"));
525 if (strlen(bstr("month")) > 0) month = atoi(bstr("month"));
526 if (strlen(bstr("day")) > 0) day = atoi(bstr("day"));
528 /* How would you like that cooked? */
529 if (strlen(bstr("calview")) > 0) {
530 strcpy(calview, bstr("calview"));
533 strcpy(calview, "month");
536 /* Display the selected view */
537 if (!strcasecmp(calview, "day")) {
538 calendar_day_view(year, month, day);
540 else if (!strcasecmp(calview, "week")) {
541 calendar_week_view(year, month, day);
544 calendar_month_view(year, month, day);
547 /* Free the calendar stuff */
548 free_calendar_buffer();
554 * Helper function for do_tasks_view(). Returns the date/time due.
556 time_t get_task_due_date(icalcomponent *vtodo) {
563 /* If we're looking at a fully encapsulated VCALENDAR
564 * rather than a VTODO component, recurse into the data
565 * structure until we get a VTODO.
567 if (icalcomponent_isa(vtodo) == ICAL_VCALENDAR_COMPONENT) {
568 return get_task_due_date(
569 icalcomponent_get_first_component(
570 vtodo, ICAL_VTODO_COMPONENT
575 p = icalcomponent_get_first_property(vtodo, ICAL_DUE_PROPERTY);
577 return(icaltime_as_timet(icalproperty_get_due(p)));
586 * Compare the due dates of two tasks (this is for sorting)
588 int task_due_cmp(const void *task1, const void *task2) {
592 t1 = get_task_due_date(((struct disp_cal *)task1)->cal);
593 t2 = get_task_due_date(((struct disp_cal *)task2)->cal);
595 if (t1 < t2) return(-1);
596 if (t1 > t2) return(1);
604 void do_tasks_view(void) {
611 wprintf("<div id=\"fix_scrollbar_bug\">"
612 "<table border=0 cellspacing=0 width=100%% bgcolor=\"#FFFFFF\">\n<tr>\n"
614 wprintf(_("Name of task"));
615 wprintf("</TH><TH>");
616 wprintf(_("Date due"));
617 wprintf("</TH></TR>\n"
620 /* Sort them if necessary */
621 if (WC->num_cal > 1) {
624 sizeof(struct disp_cal),
629 if (WC->num_cal) for (i=0; i<(WC->num_cal); ++i) {
632 wprintf("<TR BGCOLOR=\"#%s\"><TD>",
633 (bg ? "DDDDDD" : "FFFFFF")
636 p = icalcomponent_get_first_property(WC->disp_cal[i].cal,
637 ICAL_SUMMARY_PROPERTY);
638 wprintf("<A HREF=\"/display_edit_task?msgnum=%ld&taskrm=",
639 WC->disp_cal[i].cal_msgnum );
640 urlescputs(WC->wc_roomname);
642 wprintf("<IMG ALIGN=MIDDLE "
643 "SRC=\"/static/taskmanag_16x.gif\" BORDER=0> ");
645 escputs((char *)icalproperty_get_comment(p));
650 due = get_task_due_date(WC->disp_cal[i].cal);
651 fmt_date(buf, due, 0);
652 wprintf("<TD><FONT");
653 if (due < time(NULL)) {
654 wprintf(" COLOR=\"#FF0000\"");
656 wprintf(">%s</FONT></TD></TR>\n", buf);
659 wprintf("</table></div>\n");
662 free_calendar_buffer();
666 #endif /* WEBCIT_WITH_CALENDAR_SERVICE */