5 * \defgroup CalHtmlHandles Handles the HTML display of calendar items.
11 #ifndef WEBCIT_WITH_CALENDAR_SERVICE
13 /**\brief stub for non-libical builds */
14 void do_calendar_view(void) {
15 wprintf("<CENTER><I>");
16 wprintf(_("The calendar view is not available."));
17 wprintf("</I></CENTER><br />\n");
20 /**\brief stub for non-libical builds */
21 void do_tasks_view(void) {
22 wprintf("<CENTER><I>");
23 wprintf(_("The tasks view is not available."));
24 wprintf("</I></CENTER><br />\n");
27 #else /* WEBCIT_WITH_CALENDAR_SERVICE */
29 /****************************************************************************/
32 * \brief Display a whole month view of a calendar
33 * \param thetime the month we want to see
35 void calendar_month_view_display_events(time_t thetime) {
41 struct icaltimetype t;
43 int all_day_event = 0;
45 if (WC->num_cal == 0) {
46 wprintf("<br /><br /><br />\n");
50 localtime_r(&thetime, &today_tm);
51 month = today_tm.tm_mon + 1;
52 day = today_tm.tm_mday;
53 year = today_tm.tm_year + 1900;
55 for (i=0; i<(WC->num_cal); ++i) {
56 p = icalcomponent_get_first_property(WC->disp_cal[i].cal,
57 ICAL_DTSTART_PROPERTY);
59 t = icalproperty_get_dtstart(p);
60 event_tt = icaltime_as_timet(t);
62 if (t.is_date) all_day_event = 1;
63 else all_day_event = 0;
66 gmtime_r(&event_tt, &event_tm);
69 localtime_r(&event_tt, &event_tm);
72 if ((event_tm.tm_year == today_tm.tm_year)
73 && (event_tm.tm_mon == today_tm.tm_mon)
74 && (event_tm.tm_mday == today_tm.tm_mday)) {
76 p = icalcomponent_get_first_property(
78 ICAL_SUMMARY_PROPERTY);
82 wprintf("<TABLE border=0 cellpadding=2><TR>"
83 "<TD BGCOLOR=\"#CCCCDD\">"
87 wprintf("<FONT SIZE=-1>"
88 "<a href=\"display_edit_event?msgnum=%ld&calview=%s&year=%s&month=%s&day=%s\">",
89 WC->disp_cal[i].cal_msgnum,
96 icalproperty_get_comment(p));
97 wprintf("</A></FONT><br />\n");
100 wprintf("</TD></TR></TABLE>");
114 * \brief view one day
115 * \param year the year
116 * \param month the month
117 * \param day the actual day we want to see
119 void calendar_month_view(int year, int month, int day) {
120 struct tm starting_tm;
124 time_t previous_month;
127 /** Determine what day to start.
128 * First, back up to the 1st of the month...
130 memset(&starting_tm, 0, sizeof(struct tm));
131 starting_tm.tm_year = year - 1900;
132 starting_tm.tm_mon = month - 1;
133 starting_tm.tm_mday = day;
134 thetime = mktime(&starting_tm);
136 memcpy(&tm, &starting_tm, sizeof(struct tm));
137 while (tm.tm_mday != 1) {
138 thetime = thetime - (time_t)86400; /* go back 24 hours */
139 localtime_r(&thetime, &tm);
142 /** Determine previous and next months ... for links */
143 previous_month = thetime - (time_t)864000L; /* back 10 days */
144 next_month = thetime + (time_t)(31L * 86400L); /* ahead 31 days */
146 /** Now back up until we're on a Sunday */
147 localtime_r(&thetime, &tm);
148 while (tm.tm_wday != 0) {
149 thetime = thetime - (time_t)86400; /* go back 24 hours */
150 localtime_r(&thetime, &tm);
153 /** Outer table (to get the background color) */
154 wprintf("<div class=\"fix_scrollbar_bug\">"
155 "<TABLE width=100%% border=0 cellpadding=0 cellspacing=0 "
156 "bgcolor=#204B78><TR><TD>\n");
158 wprintf("<TABLE width=100%% border=0 cellpadding=0 cellspacing=0><tr>\n");
160 wprintf("<TD ALIGN=CENTER>");
162 localtime_r(&previous_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/prevdate_32x.gif\" BORDER=0></A>\n");
167 wprintf(" "
168 "<FONT SIZE=+1 COLOR=\"#FFFFFF\">"
171 " ", months[month-1], year);
173 localtime_r(&next_month, &tm);
174 wprintf("<a href=\"readfwd?calview=month&year=%d&month=%d&day=1\">",
175 (int)(tm.tm_year)+1900, tm.tm_mon + 1);
176 wprintf("<IMG ALIGN=MIDDLE src=\"static/nextdate_32x.gif\" BORDER=0></A>\n");
178 wprintf("</TD></TR></TABLE>\n");
180 /** Inner table (the real one) */
181 wprintf("<TABLE width=100%% border=0 cellpadding=1 cellspacing=1 "
182 "bgcolor=#204B78><TR>");
183 for (i=0; i<7; ++i) {
184 wprintf("<TD ALIGN=CENTER WIDTH=14%%>"
185 "<FONT COLOR=\"#FFFFFF\">%s</FONT></TH>", wdays[i]);
189 /** Now do 35 days */
190 for (i = 0; i < 35; ++i) {
191 localtime_r(&thetime, &tm);
193 /* Before displaying Sunday, start a new row */
198 wprintf("<TD BGCOLOR=\"#%s\" WIDTH=14%% HEIGHT=60 align=left VALIGN=TOP><B>",
199 ((tm.tm_mon != month-1) ? "DDDDDD" :
200 ((tm.tm_wday==0 || tm.tm_wday==6) ? "EEEECC" :
203 if ((i==0) || (tm.tm_mday == 1)) {
204 wprintf("%s ", months[tm.tm_mon]);
206 wprintf("<a href=\"readfwd?calview=day&year=%d&month=%d&day=%d\">"
213 /** put the data here, stupid */
214 calendar_month_view_display_events(thetime);
218 /** After displaying Saturday, end the row */
223 thetime += (time_t)86400; /** ahead 24 hours */
226 wprintf("</TABLE>" /** end of inner table */
227 "</TD></TR></TABLE>" /** end of outer table */
232 * \brief view one week
233 * this should view just one week, but it's not here yet.
234 * \todo ny implemented
235 * \param year the year
236 * \param month the month
237 * \param day the day which we want to see the week around
239 void calendar_week_view(int year, int month, int day) {
240 wprintf("<CENTER><I>week view FIXME</I></CENTER><br />\n");
245 * \brief display one day
246 * Display events for a particular hour of a particular day.
247 * (Specify hour < 0 to show "all day" events)
248 * \param year the year
249 * \param month the month
251 * \param hour the hour we want to start displaying?????
253 void calendar_day_view_display_events(int year, int month,
257 struct icaltimetype t;
260 int all_day_event = 0;
262 if (WC->num_cal == 0) {
263 // \todo FIXME wprintf("<br /><br /><br />\n");
267 for (i=0; i<(WC->num_cal); ++i) {
268 p = icalcomponent_get_first_property(WC->disp_cal[i].cal,
269 ICAL_DTSTART_PROPERTY);
271 t = icalproperty_get_dtstart(p);
272 event_tt = icaltime_as_timet(t);
281 event_tm = gmtime(&event_tt);
284 event_tm = localtime(&event_tt);
287 if ((event_tm->tm_year == (year-1900))
288 && (event_tm->tm_mon == (month-1))
289 && (event_tm->tm_mday == day)
290 && ( ((event_tm->tm_hour == hour)&&(!t.is_date)) || ((hour<0)&&(t.is_date)) )
294 p = icalcomponent_get_first_property(
296 ICAL_SUMMARY_PROPERTY);
300 wprintf("<TABLE border=1 cellpadding=2><TR>"
301 "<TD BGCOLOR=\"#CCCCCC\">"
305 wprintf("<FONT SIZE=-1>"
306 "<a href=\"display_edit_event?msgnum=%ld&calview=day&year=%d&month=%d&day=%d\">",
307 WC->disp_cal[i].cal_msgnum,
311 icalproperty_get_comment(p));
312 wprintf("</A></FONT><br />\n");
315 wprintf("</TD></TR></TABLE>");
328 * \brief view one day
329 * \param year the year
330 * \param month the month
331 * \param day the day we want to display
333 void calendar_day_view(int year, int month, int day) {
335 struct icaltimetype today, yesterday, tomorrow;
336 char calhourformat[16];
339 char daystart_str[16], dayend_str[16];
341 get_preference("calhourformat", calhourformat, sizeof calhourformat);
342 get_preference("daystart", daystart_str, sizeof daystart_str);
343 if (strlen(daystart_str) > 0) daystart = atoi(daystart_str);
344 get_preference("dayend", dayend_str, sizeof dayend_str);
345 if (strlen(dayend_str) > 0) dayend = atoi(dayend_str);
348 /** Figure out the dates for "yesterday" and "tomorrow" links */
350 memset(&today, 0, sizeof(struct icaltimetype));
356 memcpy(&yesterday, &today, sizeof(struct icaltimetype));
358 yesterday = icaltime_normalize(yesterday);
360 memcpy(&tomorrow, &today, sizeof(struct icaltimetype));
362 tomorrow = icaltime_normalize(tomorrow);
365 /** Outer table (to get the background color) */
366 wprintf("<div class=\"fix_scrollbar_bug\">"
367 "<TABLE width=100%% border=0 cellpadding=0 cellspacing=0 "
368 "bgcolor=#204B78><TR><TD>\n");
370 /** Inner table (the real one) */
371 wprintf("<TABLE width=100%% border=0 cellpadding=1 cellspacing=1 "
372 "bgcolor=#204B78><TR>\n");
374 /** Innermost table (contains hours etc.) */
375 wprintf("<TD WIDTH=80%%>"
376 "<TABLE width=100%% border=0 cellpadding=1 cellspacing=1 "
377 "bgcolor=#204B78>\n");
379 /** Display events before 8:00 (hour=-1 is all-day events) */
381 "<TD BGCOLOR=\"#CCCCDD\" VALIGN=MIDDLE WIDTH=10%%></TD>"
382 "<TD BGCOLOR=\"#FFFFFF\" VALIGN=TOP>");
383 for (hour = (-1); hour <= (daystart-1); ++hour) {
384 calendar_day_view_display_events(year, month, day, hour);
386 wprintf("</TD></TR>\n");
388 /** Now the middle of the day... */
389 for (hour = daystart; hour <= dayend; ++hour) { /* could do HEIGHT=xx */
390 wprintf("<TR HEIGHT=30><TD BGCOLOR=\"#CCCCDD\" ALIGN=MIDDLE "
391 "VALIGN=MIDDLE WIDTH=10%%>");
392 wprintf("<a href=\"display_edit_event?msgnum=0"
393 "&year=%d&month=%d&day=%d&hour=%d&minute=0\">",
394 year, month, day, hour
397 if (!strcasecmp(calhourformat, "24")) {
398 wprintf("%2d:00</A> ", hour);
401 wprintf("%d:00%s</A> ",
402 (hour <= 12 ? hour : hour-12),
403 (hour < 12 ? "am" : "pm")
407 wprintf("</TD><TD BGCOLOR=\"#FFFFFF\" VALIGN=TOP>");
409 /* put the data here, stupid */
410 calendar_day_view_display_events(year, month, day, hour);
412 wprintf("</TD></TR>\n");
415 /** Display events after 5:00... */
417 "<TD BGCOLOR=\"#CCCCDD\" VALIGN=MIDDLE WIDTH=10%%></TD>"
418 "<TD BGCOLOR=\"#FFFFFF\" VALIGN=TOP>");
419 for (hour = (dayend+1); hour <= 23; ++hour) {
420 calendar_day_view_display_events(year, month, day, hour);
422 wprintf("</TD></TR>\n");
425 wprintf("</TABLE>" /* end of innermost table */
429 wprintf("<TD WIDTH=20%% VALIGN=top>"); /* begin stuff-on-the-right */
432 /** Begin todays-date-with-left-and-right-arrows */
433 wprintf("<TABLE BORDER=0 WIDTH=100%% "
434 "CELLSPACING=0 CELLPADDING=0 BGCOLOR=\"#FFFFFF\">\n");
438 wprintf("<TD ALIGN=CENTER>");
439 wprintf("<a href=\"readfwd?calview=day&year=%d&month=%d&day=%d\">",
440 yesterday.year, yesterday.month, yesterday.day);
441 wprintf("<IMG ALIGN=MIDDLE src=\"static/prevdate_32x.gif\" BORDER=0></A>");
445 wprintf("<TD ALIGN=CENTER>");
446 wprintf("<FONT SIZE=+2>%s</FONT><br />"
447 "<FONT SIZE=+3>%d</FONT><br />"
448 "<FONT SIZE=+2>%d</FONT><br />",
449 months[month-1], day, year);
453 wprintf("<TD ALIGN=CENTER>");
454 wprintf("<a href=\"readfwd?calview=day&year=%d&month=%d&day=%d\">",
455 tomorrow.year, tomorrow.month, tomorrow.day);
456 wprintf("<IMG ALIGN=MIDDLE src=\"static/nextdate_32x.gif\""
460 wprintf("</TR></TABLE>\n");
461 /** End todays-date-with-left-and-right-arrows */
463 /** \todo In the future we might want to put a month-o-matic here */
465 wprintf("</FONT></CENTER>\n");
467 wprintf("</TD>"); /** end stuff-on-the-right */
471 wprintf("</TR></TABLE>" /** end of inner table */
472 "</TD></TR></TABLE></div>" /** end of outer table */
480 * \brief Display today's events.
482 void calendar_summary_view(void) {
485 struct icaltimetype t;
490 int all_day_event = 0;
491 char timestring[SIZ];
493 if (WC->num_cal == 0) {
498 localtime_r(&now, &today_tm);
500 for (i=0; i<(WC->num_cal); ++i) {
501 p = icalcomponent_get_first_property(WC->disp_cal[i].cal,
502 ICAL_DTSTART_PROPERTY);
504 t = icalproperty_get_dtstart(p);
505 event_tt = icaltime_as_timet(t);
512 fmt_time(timestring, event_tt);
515 gmtime_r(&event_tt, &event_tm);
518 localtime_r(&event_tt, &event_tm);
521 if ( (event_tm.tm_year == today_tm.tm_year)
522 && (event_tm.tm_mon == today_tm.tm_mon)
523 && (event_tm.tm_mday == today_tm.tm_mday)
527 p = icalcomponent_get_first_property(
529 ICAL_SUMMARY_PROPERTY);
532 icalproperty_get_comment(p));
533 wprintf(" (%s)<br />\n", timestring);
538 free_calendar_buffer();
543 * \brief clean up ical memory
544 * \todo this could get troubel with future ical versions
546 void free_calendar_buffer(void) {
548 if (WC->num_cal) for (i=0; i<(WC->num_cal); ++i) {
549 icalcomponent_free(WC->disp_cal[i].cal);
559 * \brief do the whole calendar page
560 * view any part of the calender. decide which way, etc.
562 void do_calendar_view(void) {
565 int year, month, day;
568 /** In case no date was specified, go with today */
570 localtime_r(&now, &tm);
571 year = tm.tm_year + 1900;
572 month = tm.tm_mon + 1;
575 /** Now see if a date was specified */
576 if (strlen(bstr("year")) > 0) year = atoi(bstr("year"));
577 if (strlen(bstr("month")) > 0) month = atoi(bstr("month"));
578 if (strlen(bstr("day")) > 0) day = atoi(bstr("day"));
580 /** How would you like that cooked? */
581 if (strlen(bstr("calview")) > 0) {
582 strcpy(calview, bstr("calview"));
585 strcpy(calview, "month");
588 /** Display the selected view */
589 if (!strcasecmp(calview, "day")) {
590 calendar_day_view(year, month, day);
592 else if (!strcasecmp(calview, "week")) {
593 calendar_week_view(year, month, day);
596 calendar_month_view(year, month, day);
599 /** Free the calendar stuff */
600 free_calendar_buffer();
606 * \brief get task due date
607 * Helper function for do_tasks_view().
608 * \param vtodo a task to get the due date
609 * \return the date/time due.
611 time_t get_task_due_date(icalcomponent *vtodo) {
619 * If we're looking at a fully encapsulated VCALENDAR
620 * rather than a VTODO component, recurse into the data
621 * structure until we get a VTODO.
623 if (icalcomponent_isa(vtodo) == ICAL_VCALENDAR_COMPONENT) {
624 return get_task_due_date(
625 icalcomponent_get_first_component(
626 vtodo, ICAL_VTODO_COMPONENT
631 p = icalcomponent_get_first_property(vtodo, ICAL_DUE_PROPERTY);
633 return(icaltime_as_timet(icalproperty_get_due(p)));
642 * \brief Compare the due dates of two tasks (this is for sorting)
643 * \param task1 first task to compare
644 * \param task2 second task to compare
646 int task_due_cmp(const void *task1, const void *task2) {
650 t1 = get_task_due_date(((struct disp_cal *)task1)->cal);
651 t2 = get_task_due_date(((struct disp_cal *)task2)->cal);
653 if (t1 < t2) return(-1);
654 if (t1 > t2) return(1);
662 * \brief do the whole task view stuff
664 void do_tasks_view(void) {
671 wprintf("<div class=\"fix_scrollbar_bug\">"
672 "<table border=0 cellspacing=0 width=100%% bgcolor=\"#FFFFFF\">\n<tr>\n"
674 wprintf(_("Name of task"));
675 wprintf("</TH><TH>");
676 wprintf(_("Date due"));
677 wprintf("</TH></TR>\n"
680 /** Sort them if necessary */
681 if (WC->num_cal > 1) {
684 sizeof(struct disp_cal),
689 if (WC->num_cal) for (i=0; i<(WC->num_cal); ++i) {
692 wprintf("<TR BGCOLOR=\"#%s\"><TD>",
693 (bg ? "DDDDDD" : "FFFFFF")
696 p = icalcomponent_get_first_property(WC->disp_cal[i].cal,
697 ICAL_SUMMARY_PROPERTY);
698 wprintf("<a href=\"display_edit_task?msgnum=%ld&taskrm=",
699 WC->disp_cal[i].cal_msgnum );
700 urlescputs(WC->wc_roomname);
702 wprintf("<IMG ALIGN=MIDDLE "
703 "src=\"static/taskmanag_16x.gif\" BORDER=0> ");
705 escputs((char *)icalproperty_get_comment(p));
710 due = get_task_due_date(WC->disp_cal[i].cal);
711 fmt_date(buf, due, 0);
712 wprintf("<TD><FONT");
713 if (due < time(NULL)) {
714 wprintf(" COLOR=\"#FF0000\"");
716 wprintf(">%s</FONT></TD></TR>\n", buf);
719 wprintf("</table></div>\n");
722 free_calendar_buffer();
726 #endif /* WEBCIT_WITH_CALENDAR_SERVICE */