X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=webcit%2Fcalendar_view.c;h=1b6e8681ebe2f9f3f2deeeb3ef7b5cf666f403c7;hb=HEAD;hp=c26241c017fefef1de07b67f1e4c221bc0078954;hpb=9a85a9f3c8905d5676603ed7d50c237e2545e2d9;p=citadel.git diff --git a/webcit/calendar_view.c b/webcit/calendar_view.c index c26241c01..c6b4a9ff3 100644 --- a/webcit/calendar_view.c +++ b/webcit/calendar_view.c @@ -1,46 +1,39 @@ - /* - * $Id$ - */ -/** - * \defgroup CalHtmlHandles Handles the HTML display of calendar items. - * \ingroup Calendaring - */ -/*@{*/ -#include "webcit.h" -#include "webserver.h" +// Handles the HTML display of calendar items. +// +// Copyright (c) 1996-2023 by the citadel.org team +// +// This program is open source software. Use, duplication, or disclosure +// is subject to the terms of the GNU General Public License, version 3. -#ifdef WEBCIT_WITH_CALENDAR_SERVICE +#include "webcit.h" -/****************************************************************************/ +#include "calendar.h" +// These define how high the hour rows are in the day view +#define TIMELINE 22 +#define EXTRATIMELINE 22 -void embeddable_mini_calendar(int year, int month, char *urlformat) -{ +void embeddable_mini_calendar(int year, int month) { struct tm starting_tm; struct tm tm; time_t thetime; - int i, len; + int i; time_t previous_month; time_t next_month; time_t colheader_time; struct tm colheader_tm; char colheader_label[32]; - int weekstart = 0; - char weekstart_buf[16]; + long weekstart = 0; char url[256]; char div_id[256]; - char escaped_urlformat[256]; snprintf(div_id, sizeof div_id, "mini_calendar_%d", rand() ); - /* Determine what day to start. - */ - get_preference("weekstart", weekstart_buf, sizeof weekstart_buf); - weekstart = atoi(weekstart_buf); + // Determine what day to start. If an impossible value is found, start on Sunday. + get_pref_long("weekstart", &weekstart, 17); + if (weekstart > 6) weekstart = 0; - /* - * Now back up to the 1st of the month... - */ + // Now back up to the 1st of the month... memset(&starting_tm, 0, sizeof(struct tm)); starting_tm.tm_year = year - 1900; @@ -50,154 +43,131 @@ void embeddable_mini_calendar(int year, int month, char *urlformat) memcpy(&tm, &starting_tm, sizeof(struct tm)); while (tm.tm_mday != 1) { - thetime = thetime - (time_t)86400; /* go back 24 hours */ + thetime = thetime - (time_t)86400; // go back 24 hours localtime_r(&thetime, &tm); } - /** Determine previous and next months ... for links */ - previous_month = thetime - (time_t)864000L; /* back 10 days */ - next_month = thetime + (time_t)(31L * 86400L); /* ahead 31 days */ + // Determine previous and next months ... for links + previous_month = thetime - (time_t)864000; // back 10 days + next_month = thetime + (time_t)(31L * 86400); // ahead 31 days - /** Now back up until we're on the user's preferred start day */ + // Now back up until we're on the user's preferred start day localtime_r(&thetime, &tm); while (tm.tm_wday != weekstart) { - thetime = thetime - (time_t)86400; /* go back 24 hours */ + thetime = thetime - (time_t)86400; // go back 24 hours localtime_r(&thetime, &tm); } - wprintf("
\n", div_id); + wc_printf("
\n", div_id); - /* Previous month link */ + // Previous month link localtime_r(&previous_month, &tm); - wprintf("«", - (int)(tm.tm_year)+1900, tm.tm_mon + 1); + wc_printf("«", (int)(tm.tm_year)+1900, tm.tm_mon + 1); wc_strftime(colheader_label, sizeof colheader_label, "%B", &starting_tm); - wprintf("  " + wc_printf("  " "" "%s %d" "" "  ", colheader_label, year); - /* Next month link */ + // Next month link localtime_r(&next_month, &tm); - wprintf("»", - (int)(tm.tm_year)+1900, tm.tm_mon + 1); + wc_printf("»", (int)(tm.tm_year)+1900, tm.tm_mon + 1); - wprintf("" - ""); + wc_printf("
"); colheader_time = thetime; for (i=0; i<7; ++i) { colheader_time = thetime + (i * 86400) ; localtime_r(&colheader_time, &colheader_tm); wc_strftime(colheader_label, sizeof colheader_label, "%A", &colheader_tm); - wprintf("", colheader_label[0]); + wc_printf("", colheader_label[0]); } - wprintf("\n"); - + wc_printf("\n"); - /** Now do 35 or 42 days */ + // Now do 35 or 42 days for (i = 0; i < 42; ++i) { localtime_r(&thetime, &tm); if (i < 35) { - /** Before displaying Sunday, start a new row */ + // Before displaying Sunday, start a new row if ((i % 7) == 0) { - wprintf(""); + wc_printf(""); } if (tm.tm_mon == month-1) { - snprintf(url, sizeof url, urlformat, + snprintf(url, sizeof url, "readfwd?calview=day?year=%d?month=%d?day=%d", tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday); - wprintf("", url, tm.tm_mday); + wc_printf("", url, tm.tm_mday); } else { - wprintf(""); + wc_printf(""); } - /** After displaying one week, end the row */ + // After displaying one week, end the row if ((i % 7) == 6) { - wprintf("\n"); + wc_printf("\n"); } } - thetime += (time_t)86400; /** ahead 24 hours */ + thetime += (time_t)86400; // ahead 24 hours } - wprintf("
%c%c
%d%d
" /** end of inner table */ + wc_printf("" // end of inner table "
\n"); - /* javascript for previous and next month */ - len = strlen(urlformat); - for (i=0; i " - " function minical_change_month(year, month) { " - " p = 'year=' + year + '&month=' + month " - " + '&urlformat=%s&r=' + CtdlRandomString(); " - " new Ajax.Updater('%s', 'mini_calendar', " - " { method: 'get', parameters: p, evalScripts: true } ); " - " } " - "\n" - , - escaped_urlformat, div_id + StrBufAppendPrintf(WC->trailing_javascript, + " function minical_change_month(year, month) { \n" + " p = 'year=' + year + '&month=' + month \n" + " + '&r=' + ctdlRandomString(); \n" + " new Ajax.Updater('%s', 'mini_calendar', \n" + " { method: 'get', parameters: p, evalScripts: true } ); \n" + " } \n" + "", + div_id ); } -/* ajax embedder for the above mini calendar */ -void ajax_mini_calendar(void) { - char urlformat[256]; - int i, len; - char *escaped_urlformat; - - escaped_urlformat = bstr("urlformat"); - len = strlen(escaped_urlformat) * 2 ; - for (i=0; inum_cal == 0) { - wprintf("


\n"); + if (GetCount(WC->disp_cal_items) == 0) { + wc_printf("
\n"); return; } - /* Create an imaginary event which spans the 24 hours of today. Any events which - * overlap with this one take place at least partially in this day. We have to - * convert it from a struct tm in order to make it UTC. - */ + // Create an imaginary event which spans the 24 hours of today. Any events which + // overlap with this one take place at least partially in this day. We have to + // convert it from a struct tm in order to make it UTC. memset(&starting_tm, 0, sizeof(struct tm)); starting_tm.tm_year = year - 1900; starting_tm.tm_mon = month - 1; @@ -205,7 +175,6 @@ void calendar_month_view_display_events(int year, int month, int day) starting_tm.tm_hour = 0; starting_tm.tm_min = 0; today_start_t = icaltime_from_timet_with_zone(mktime(&starting_tm), 0, icaltimezone_get_utc_timezone()); - today_start_t.is_utc = 1; memset(&ending_tm, 0, sizeof(struct tm)); ending_tm.tm_year = year - 1900; @@ -214,12 +183,17 @@ void calendar_month_view_display_events(int year, int month, int day) ending_tm.tm_hour = 23; ending_tm.tm_min = 59; today_end_t = icaltime_from_timet_with_zone(mktime(&ending_tm), 0, icaltimezone_get_utc_timezone()); - today_end_t.is_utc = 1; - /* Now loop through our list of events to see which ones occur today. - */ - for (i=0; i<(WCC->num_cal); ++i) { - Cal = &WCC->disp_cal[i]; + // Create another one without caring about the timezone for all day events. + today_t = icaltime_null_date(); + today_t.year = year; + today_t.month = month; + today_t.day = day; + + // Now loop through our list of events to see which ones occur today. + Pos = GetNewHashPos(WC->disp_cal_items, 0); + while (GetNextHashPos(WC->disp_cal_items, Pos, &hklen, &HashKey, &vCal)) { + Cal = (disp_cal*)vCal; all_day_event = 0; q = icalcomponent_get_first_property(Cal->cal, ICAL_DTSTART_PROPERTY); if (q != NULL) { @@ -235,127 +209,155 @@ void calendar_month_view_display_events(int year, int month, int day) else { memset(&end_t, 0, sizeof end_t); } - if (t.is_date) all_day_event = 1; + if (t.is_date) { + all_day_event = 1; + } - if (all_day_event) - { - show_event = ((t.year == year) && (t.month == month) && (t.day == day)); + if (all_day_event) { + show_event = ical_ctdl_is_overlap(t, end_t, today_t, icaltime_null_time()); } - else - { + else { show_event = ical_ctdl_is_overlap(t, end_t, today_start_t, today_end_t); } - /* If we determined that this event occurs today, then display it. - */ + // If we determined that this event occurs today, then display it. if (show_event) { + + //time_t logtt = icaltime_as_timet(t); + //syslog(LOG_DEBUG, "Match on %04d-%02d-%02d for event %x%s on %s", + //year, month, day, + //(int)Cal, ((all_day_event) ? " (all day)" : ""), + //ctime(&logtt) + //); + p = icalcomponent_get_first_property(Cal->cal, ICAL_SUMMARY_PROPERTY); + if (p == NULL) { + p = icalproperty_new_summary(_("Untitled Event")); + icalcomponent_add_property(Cal->cal, p); + } if (p != NULL) { if (all_day_event) { - wprintf("" + wc_printf("
" "
" ); } - wprintf("" - "disp_cal[i].cal_msgnum, - bstr("calview"), - bstr("year"), - bstr("month"), - bstr("day") - ); + wc_printf("" + "" + , + (Cal->unread)?"_unread":"_read", + Cal->cal_msgnum, + year, month, day + ); + + escputs((char *) icalproperty_get_comment(p)); - wprintf("%s ", _("Summary:")); + wc_printf(""); + + wc_printf("%s: %s
", _("From"), Cal->from); + wc_printf("%s ", _("Summary:")); escputs((char *)icalproperty_get_comment(p)); - wprintf("
"); - + wc_printf("
"); + q = icalcomponent_get_first_property( - WC->disp_cal[i].cal, + Cal->cal, ICAL_LOCATION_PROPERTY); if (q) { - wprintf("%s ", _("Location:")); + wc_printf("%s ", _("Location:")); escputs((char *)icalproperty_get_comment(q)); - wprintf("
"); - } - - /** - * Only show start/end times if we're actually looking at the VEVENT - * component. Otherwise it shows bogus dates for e.g. timezones - */ + wc_printf("
"); + } + + // Only show start/end times if we're actually looking at the VEVENT + // component. Otherwise it shows bogus dates for e.g. timezones if (icalcomponent_isa(Cal->cal) == ICAL_VEVENT_COMPONENT) { - + q = icalcomponent_get_first_property(Cal->cal, ICAL_DTSTART_PROPERTY); if (q != NULL) { + int no_end = 0; + t = icalproperty_get_dtstart(q); - + q = icalcomponent_get_first_property(Cal->cal, ICAL_DTEND_PROPERTY); + if (q != NULL) { + end_t = icalproperty_get_dtend(q); + } + else { + // events with starting date/time equal + // ending date/time might get only + // DTSTART but no DTEND + no_end = 1; + } + if (t.is_date) { + // all day event struct tm d_tm; - char d_str[32]; + + if (!no_end) { + // end given, have to adjust it + icaltime_adjust(&end_t, -1, 0, 0, 0); + } memset(&d_tm, 0, sizeof d_tm); d_tm.tm_year = t.year - 1900; d_tm.tm_mon = t.month - 1; d_tm.tm_mday = t.day; - wc_strftime(d_str, sizeof d_str, "%x", &d_tm); - wprintf("%s %s
", - _("Date:"), d_str); + wc_strftime(buf, sizeof buf, "%x", &d_tm); + + if (no_end || !icaltime_compare(t, end_t)) { + wc_printf("%s %s
", _("Date:"), buf); + } + else { + wc_printf("%s %s
", _("Starting date:"), buf); + d_tm.tm_year = end_t.year - 1900; + d_tm.tm_mon = end_t.month - 1; + d_tm.tm_mday = end_t.day; + wc_strftime(buf, sizeof buf, "%x", &d_tm); + wc_printf("%s %s
", _("Ending date:"), buf); + } } else { tt = icaltime_as_timet(t); - fmt_date(buf, tt, 1); - wprintf("%s %s
", - _("Starting date/time:"), buf); - - /* Embed the 'show end date/time' loop inside here so it - * only executes if this is NOT an all day event. - */ - q = icalcomponent_get_first_property(Cal->cal, ICAL_DTEND_PROPERTY); - if (q != NULL) { - t = icalproperty_get_dtend(q); - tt = icaltime_as_timet(t); - fmt_date(buf, tt, 1); - wprintf("%s %s
", _("Ending date/time:"), buf); + webcit_fmt_date(buf, 256, tt, DATEFMT_BRIEF); + if (no_end || !icaltime_compare(t, end_t)) { + wc_printf("%s %s
", _("Date/time:"), buf); + } + else { + wc_printf("%s %s
", _("Starting date/time:"), buf); + tt = icaltime_as_timet(end_t); + webcit_fmt_date(buf, 256, tt, DATEFMT_BRIEF); + wc_printf("%s %s
", _("Ending date/time:"), buf); } - } } - } - + q = icalcomponent_get_first_property(Cal->cal, ICAL_DESCRIPTION_PROPERTY); if (q) { - wprintf("%s ", _("Notes:")); + wc_printf("%s ", _("Notes:")); escputs((char *)icalproperty_get_comment(q)); - wprintf("
"); + wc_printf("
"); } - - wprintf("\">"); - escputs((char *) - icalproperty_get_comment(p)); - wprintf("

\n"); - + + wc_printf(""); + wc_printf("

\n"); + if (all_day_event) { - wprintf("
"); + wc_printf(""); } - } - } - - } + DeleteHashPos(&Pos); } -/** - * \brief Display one day of a whole month view of a calendar - * \param thetime the month we want to see - */ +// Display one day of a whole month view of a calendar void calendar_month_view_brief_events(time_t thetime, const char *daycolor) { - int i; + long hklen; + const char *HashKey; + void *vCal; + HashPos *Pos; time_t event_tt; time_t event_tts; time_t event_tte; @@ -365,24 +367,22 @@ void calendar_month_view_brief_events(time_t thetime, const char *daycolor) { icalproperty *p; icalproperty *e; struct icaltimetype t; - int month, day, year; + disp_cal *Cal; int all_day_event = 0; char *timeformat; int time_format; - + time_format = get_time_format_cached (); if (time_format == WC_TIMEFORMAT_24) timeformat="%k:%M"; else timeformat="%I:%M %p"; localtime_r(&thetime, &today_tm); - month = today_tm.tm_mon + 1; - day = today_tm.tm_mday; - year = today_tm.tm_year + 1900; - for (i=0; i<(WC->num_cal); ++i) { - p = icalcomponent_get_first_property(WC->disp_cal[i].cal, - ICAL_DTSTART_PROPERTY); + Pos = GetNewHashPos(WC->disp_cal_items, 0); + while (GetNextHashPos(WC->disp_cal_items, Pos, &hklen, &HashKey, &vCal)) { + Cal = (disp_cal*)vCal; + p = icalcomponent_get_first_property(Cal->cal, ICAL_DTSTART_PROPERTY); if (p != NULL) { t = icalproperty_get_dtstart(p); event_tt = icaltime_as_timet(t); @@ -396,21 +396,21 @@ void calendar_month_view_brief_events(time_t thetime, const char *daycolor) { else { localtime_r(&event_tts, &event_tms); } - /** \todo epoch &! daymask */ - if ((event_tms.tm_year == today_tm.tm_year) - && (event_tms.tm_mon == today_tm.tm_mon) - && (event_tms.tm_mday == today_tm.tm_mday)) { - - + // todo: epoch &! daymask + if ( (event_tms.tm_year == today_tm.tm_year) + && (event_tms.tm_mon == today_tm.tm_mon) + && (event_tms.tm_mday == today_tm.tm_mday)) + { + char sbuf[255]; char ebuf[255]; - - p = icalcomponent_get_first_property( - WC->disp_cal[i].cal, - ICAL_SUMMARY_PROPERTY); - e = icalcomponent_get_first_property( - WC->disp_cal[i].cal, - ICAL_DTEND_PROPERTY); + + p = icalcomponent_get_first_property(Cal->cal, ICAL_SUMMARY_PROPERTY); + if (p == NULL) { + p = icalproperty_new_summary(_("Untitled Event")); + icalcomponent_add_property(Cal->cal, p); + } + e = icalcomponent_get_first_property( Cal->cal, ICAL_DTEND_PROPERTY); if ((p != NULL) && (e != NULL)) { time_t difftime; int hours, minutes; @@ -420,70 +420,63 @@ void calendar_month_view_brief_events(time_t thetime, const char *daycolor) { difftime=(event_tte-event_tts)/60; hours=(int)(difftime / 60); minutes=difftime % 60; - wprintf("%i:%2i" - "" - "", - daycolor, - hours, minutes, - daycolor, - WC->disp_cal[i].cal_msgnum, - bstr("calview"), - bstr("year"), - bstr("month"), - bstr("day") - ); - - escputs((char *) - icalproperty_get_comment(p)); - /** \todo: allso ammitime format */ + wc_printf("%i:%2i" + "" + "", + daycolor, + hours, minutes, + (Cal->unread)?"_unread":"_read", + daycolor, + Cal->cal_msgnum, + bstr("year"), + bstr("month"), + bstr("day") + ); + + escputs((char *) icalproperty_get_comment(p)); + // todo: also ammitime format wc_strftime(&sbuf[0], sizeof(sbuf), timeformat, &event_tms); wc_strftime(&ebuf[0], sizeof(sbuf), timeformat, &event_tme); - - wprintf("" - "%s%s", - daycolor, - sbuf, - daycolor, - ebuf); - + + wc_printf("" + "%s%s", + daycolor, + sbuf, + daycolor, + ebuf + ); } - } - - } } + DeleteHashPos(&Pos); } -/** - * \brief view one month. pretty view - * \param year the year - * \param month the month - * \param day the actual day we want to see - */ +// view one month. pretty view void calendar_month_view(int year, int month, int day) { struct tm starting_tm; struct tm tm; + struct tm today_tm; time_t thetime; int i; time_t previous_month; time_t next_month; time_t colheader_time; + time_t today_timet; struct tm colheader_tm; char colheader_label[32]; - int chg_month = 0; - int weekstart = 0; - char weekstart_buf[16]; - - /* Determine what day to start. - */ - get_preference("weekstart", weekstart_buf, sizeof weekstart_buf); - weekstart = atoi(weekstart_buf); - - /* - * Now back up to the 1st of the month... - */ + long weekstart = 0; + + // Make sure we know which day is today. + today_timet = time(NULL); + localtime_r(&today_timet, &today_tm); + + // Determine what day to start. If an impossible value is found, start on Sunday. + get_pref_long("weekstart", &weekstart, 17); + if (weekstart > 6) weekstart = 0; + + // Now back up to the 1st of the month... memset(&starting_tm, 0, sizeof(struct tm)); starting_tm.tm_year = year - 1900; @@ -493,143 +486,119 @@ void calendar_month_view(int year, int month, int day) { memcpy(&tm, &starting_tm, sizeof(struct tm)); while (tm.tm_mday != 1) { - thetime = thetime - (time_t)86400; /* go back 24 hours */ + thetime = thetime - (time_t)86400; // go back 24 hours localtime_r(&thetime, &tm); } - /** Determine previous and next months ... for links */ - previous_month = thetime - (time_t)864000L; /* back 10 days */ - next_month = thetime + (time_t)(31L * 86400L); /* ahead 31 days */ + // Determine previous and next months ... for links + previous_month = thetime - (time_t)864000; // back 10 days + next_month = thetime + (time_t)(31L * 86400); // ahead 31 days - /** Now back up until we're on the user's preferred start day */ + // Now back up until we're on the user's preferred start day localtime_r(&thetime, &tm); while (tm.tm_wday != weekstart) { - thetime = thetime - (time_t)86400; /* go back 24 hours */ + thetime = thetime - (time_t)86400; // go back 24 hours localtime_r(&thetime, &tm); } - /** Outer table (to get the background color) */ - wprintf("
" - " \n
"); + // Outer table (to get the background color) + wc_printf(" \n
"); - wprintf("\n"); + wc_printf("
\n"); - wprintf("
"); + wc_printf(""); localtime_r(&previous_month, &tm); - wprintf("", + wc_printf("", (int)(tm.tm_year)+1900, tm.tm_mon + 1); - wprintf("\n"); + wc_printf("\"%s\"\n", _("previous")); wc_strftime(colheader_label, sizeof colheader_label, "%B", &starting_tm); - wprintf("  " - "" + wc_printf("  " + "" "%s %d" "" "  ", colheader_label, year); localtime_r(&next_month, &tm); - wprintf("", + wc_printf("", (int)(tm.tm_year)+1900, tm.tm_mon + 1); - wprintf("\n"); + wc_printf("\"%s\"\n", _("next")); - wprintf("
\n"); + wc_printf("
\n"); - /** Inner table (the real one) */ - wprintf(""); + // Inner table (the real one) + wc_printf("
"); + wc_printf(""); colheader_time = thetime; for (i=0; i<7; ++i) { colheader_time = thetime + (i * 86400) ; localtime_r(&colheader_time, &colheader_tm); wc_strftime(colheader_label, sizeof colheader_label, "%A", &colheader_tm); - wprintf("", colheader_label); } - wprintf("\n"); - + wc_printf("\n"); - /** Now do 35 or 42 days */ - for (i = 0; i < 42; ++i) { - localtime_r(&thetime, &tm); - - if ((i < 35) || (chg_month == 0)) { - - if ((i > 27) && ((tm.tm_mday == 1) || (tm.tm_mday == 31))) { - chg_month = 1; - } - if (i > 35) { - chg_month = 0; - } + // Now do 35 or 42 days + localtime_r(&thetime, &tm); + for (i = 0; i<42; ++i) { - /** Before displaying Sunday, start a new row */ - if ((i % 7) == 0) { - wprintf(""); - } + // Before displaying the first day of the week, start a new row + if ((i % 7) == 0) { + wc_printf(""); - - /** After displaying Saturday, end the row */ - if ((i % 7) == 6) { - wprintf("\n"); - } + wc_printf(""); + // After displaying the last day of the week, end the row + if ((i % 7) == 6) { + wc_printf("\n"); } - thetime += (time_t)86400; /** ahead 24 hours */ - } + thetime += (time_t)86400; // ahead 24 hours + localtime_r(&thetime, &tm); - wprintf("
" + wc_printf("" "%s
"); + wc_strftime(colheader_label, sizeof colheader_label, "%V", &tm); + wc_printf("%s ", colheader_label); + } - wprintf("
", - ((tm.tm_mon != month-1) ? "out" : + wc_printf("
", + ((tm.tm_mon != month-1) ? "out" : + (((tm.tm_year == today_tm.tm_year) && (tm.tm_mon == today_tm.tm_mon) && (tm.tm_mday == today_tm.tm_mday)) ? "today" : ((tm.tm_wday==0 || tm.tm_wday==6) ? "weekend" : - "day")) + "day"))) ); - if ((i==0) || (tm.tm_mday == 1)) { - wc_strftime(colheader_label, sizeof colheader_label, "%B", &tm); - wprintf("%s ", colheader_label); - } - wprintf("" - "%d
", - tm.tm_year + 1900, - tm.tm_mon + 1, - tm.tm_mday, - tm.tm_mday); - - /** put the data here, stupid */ - calendar_month_view_display_events( - tm.tm_year + 1900, - tm.tm_mon + 1, - tm.tm_mday + if ((i==0) || (tm.tm_mday == 1)) { + wc_strftime(colheader_label, sizeof colheader_label, "%B", &tm); + wc_printf("%s ", colheader_label); + } + wc_printf("" + "%d", + tm.tm_year + 1900, + tm.tm_mon + 1, + tm.tm_mday, + tm.tm_mday); + + // put the data here, stupid + calendar_month_view_display_events( + tm.tm_year + 1900, + tm.tm_mon + 1, + tm.tm_mday ); - wprintf("
" /** end of inner table */ - "
" /** end of outer table */ - "
\n"); + if ( ((i % 7) == 6) && (tm.tm_mon != month-1) && (tm.tm_mday < 15) ) { + i = 100; // break out of the loop + } + } - /** - * Initialize the bubble tooltips. - * - * Yes, this is as stupid as it looks. Instead of just making the call - * to btt_enableTooltips() straight away, we have to create a timer event - * and let it initialize as an event after 1 millisecond. This is to - * work around a bug in Internet Explorer that causes it to crash if we - * manipulate the innerHTML of various DOM nodes while the page is still - * being rendered. See http://www.shaftek.org/blog/archives/000212.html - * for more information. - */ - wprintf("\n" + wc_printf("" // end of inner table + "\n" // end of outer table ); } -/** - * \brief view one month. brief view - * \param year the year - * \param month the month - * \param day the actual day we want to see - */ + +// view one month. brief view void calendar_brief_month_view(int year, int month, int day) { struct tm starting_tm; struct tm tm; @@ -639,9 +608,8 @@ void calendar_brief_month_view(int year, int month, int day) { time_t next_month; char month_label[32]; - /** Determine what day to start. - * First, back up to the 1st of the month... - */ + // Determine what day to start. + // First, back up to the 1st of the month... memset(&starting_tm, 0, sizeof(struct tm)); starting_tm.tm_year = year - 1900; starting_tm.tm_mon = month - 1; @@ -650,56 +618,55 @@ void calendar_brief_month_view(int year, int month, int day) { memcpy(&tm, &starting_tm, sizeof(struct tm)); while (tm.tm_mday != 1) { - thetime = thetime - (time_t)86400; /* go back 24 hours */ + thetime = thetime - (time_t)86400; // go back 24 hours localtime_r(&thetime, &tm); } - /** Determine previous and next months ... for links */ - previous_month = thetime - (time_t)864000L; /* back 10 days */ - next_month = thetime + (time_t)(31L * 86400L); /* ahead 31 days */ + // Determine previous and next months ... for links + previous_month = thetime - (time_t)864000; // back 10 days + next_month = thetime + (time_t)(31L * 86400); // ahead 31 days - /** Now back up until we're on a Sunday */ + // Now back up until we're on a Sunday localtime_r(&thetime, &tm); while (tm.tm_wday != 0) { - thetime = thetime - (time_t)86400; /* go back 24 hours */ + thetime = thetime - (time_t)86400; // go back 24 hours localtime_r(&thetime, &tm); } - /** Outer table (to get the background color) */ - wprintf("
" - "
\n"); + // Outer table (to get the background color) + wc_printf("
\n"); - wprintf("\n"); + wc_printf("
\n"); - wprintf("
"); + wc_printf(""); localtime_r(&previous_month, &tm); - wprintf("", + wc_printf("", (int)(tm.tm_year)+1900, tm.tm_mon + 1); - wprintf("\n"); + wc_printf("\"%s\"\n", _("previous")); wc_strftime(month_label, sizeof month_label, "%B", &tm); - wprintf("  " - "" + wc_printf("  " + "" "%s %d" "" "  ", month_label, year); localtime_r(&next_month, &tm); - wprintf("", + wc_printf("", (int)(tm.tm_year)+1900, tm.tm_mon + 1); - wprintf("\n"); + wc_printf("\"%s\"\n", _("next")); - wprintf("
\n"); + wc_printf("
\n"); - /** Inner table (the real one) */ - wprintf(""); - wprintf("\n"); - wprintf("\n"); + wc_printf("
\n"); + wc_printf("
\n"); - /** Now do 35 days */ + // Now do 35 days for (i = 0; i < 35; ++i) { char weeknumber[255]; char weekday_name[32]; @@ -707,81 +674,68 @@ void calendar_brief_month_view(int year, int month, int day) { localtime_r(&thetime, &tm); - /** Before displaying Sunday, start a new CELL */ + // Before displaying Sunday, start a new CELL if ((i % 7) == 0) { wc_strftime(&weeknumber[0], sizeof(weeknumber), "%U", &tm); - wprintf("" - " \n", - _("Week"), - weeknumber, - _("Hours"), - _("Subject"), - _("Start"), - _("End") - ); + wc_printf("
%s %s
%s%s%s%s
" + " \n", + _("Week"), + weeknumber, + _("Hours"), + _("Subject"), + _("Start"), + _("End") + ); } - + daycolor=((tm.tm_mon != month-1) ? "DDDDDD" : - ((tm.tm_wday==0 || tm.tm_wday==6) ? "EEEECC" : - "FFFFFF")); - - /** Day Header */ + ((tm.tm_wday==0 || tm.tm_wday==6) ? "EEEECC" : + "FFFFFF")); + + // Day Header wc_strftime(weekday_name, sizeof weekday_name, "%A", &tm); - wprintf("\n", - daycolor, - weekday_name,tm.tm_mday, - daycolor); + wc_printf("\n", + daycolor, + weekday_name,tm.tm_mday, + daycolor); - /** put the data of one day here, stupid */ + // put the data of one day here, stupid calendar_month_view_brief_events(thetime, daycolor); - - /** After displaying Saturday, end the row */ + // After displaying Saturday, end the row if ((i % 7) == 6) { - wprintf("
%s %s
%s%s%s%s
%s,%i." - "
%s,%i." + "
\n"); + wc_printf("
\n"); } - thetime += (time_t)86400; /** ahead 24 hours */ + thetime += (time_t)86400; // ahead 24 hours } - wprintf("
" /** end of inner table */ - "" /** end of outer table */ - "
\n"); + wc_printf("" // end of inner table + "\n" // end of outer table + ); } -/** - * \brief view one week - * this should view just one week, but it's not here yet. - * \todo ny implemented - * \param year the year - * \param month the month - * \param day the day which we want to see the week around - */ + +// Calendar week view -- not implemented yet, this is a stub function void calendar_week_view(int year, int month, int day) { - wprintf("
week view FIXME

\n"); + wc_printf("
week view FIXME

\n"); } -/** - * \brief display one day - * Display events for a particular hour of a particular day. - * (Specify hour < 0 to show "all day" events) - * \param year the year - * \param month the month - * \param day the day - * \param hour the hour we want to start displaying - * \param dstart daystart - * \param dend dayend - */ -void calendar_day_view_display_events(time_t thetime, int year, int month, - int day, int hour, - int dstart, int dend) { - int i; +// display one day +// Display events for a particular hour of a particular day. +// (Specify hour < 0 to show "all day" events) +// +// dstart and dend indicate which hours our "daytime" begins and end +void calendar_day_view_display_events(time_t thetime, int year, int month, int day, int notime_events, int dstart, int dend) { + + long hklen; + const char *HashKey; + void *vCal; + HashPos *Pos; icalproperty *p = NULL; icalproperty *q = NULL; - time_t event_start; - time_t event_end; time_t event_tt; time_t event_tte; struct tm event_te; @@ -789,52 +743,56 @@ void calendar_day_view_display_events(time_t thetime, int year, int month, int show_event = 0; int all_day_event = 0; int ongoing_event = 0; - struct wcsession *WCC = WC; /* This is done to make it run faster; WC is a function */ - struct disp_cal *Cal; + disp_cal *Cal; struct icaltimetype t; struct icaltimetype end_t; struct icaltimetype today_start_t; struct icaltimetype today_end_t; + struct icaltimetype today_t; struct tm starting_tm; struct tm ending_tm; int top = 0; - int height = 0; - int gap = 0; + int bottom = 0; + int gap = 1; + int startmin = 0; + int diffmin = 0; + int endmin = 0; + + char buf[256]; - if (WCC->num_cal == 0) { - // \todo FIXME wprintf("


\n"); + if (GetCount(WC->disp_cal_items) == 0) { + // nothing to display return; } - event_start = thetime + 60 * 60 * hour; - event_end = thetime + 60 * 60 * (hour + 1); - - - /* Create an imaginary event which spans the current hour. Any events which - * overlap with this one take place at least partially in this day. - */ + // Create an imaginary event which spans the current day. Any events which + // overlap with this one take place at least partially in this day. memset(&starting_tm, 0, sizeof(struct tm)); starting_tm.tm_year = year - 1900; starting_tm.tm_mon = month - 1; starting_tm.tm_mday = day; - starting_tm.tm_hour = hour; + starting_tm.tm_hour = 0; starting_tm.tm_min = 0; today_start_t = icaltime_from_timet_with_zone(mktime(&starting_tm), 0, icaltimezone_get_utc_timezone()); - today_start_t.is_utc = 1; memset(&ending_tm, 0, sizeof(struct tm)); ending_tm.tm_year = year - 1900; ending_tm.tm_mon = month - 1; ending_tm.tm_mday = day; - ending_tm.tm_hour = hour; + ending_tm.tm_hour = 23; ending_tm.tm_min = 59; today_end_t = icaltime_from_timet_with_zone(mktime(&ending_tm), 0, icaltimezone_get_utc_timezone()); - today_end_t.is_utc = 1; - /* Now loop through our list of events to see which ones occur today. - */ - for (i=0; i<(WCC->num_cal); ++i) { - Cal = &WCC->disp_cal[i]; + // Create another one without caring about the timezone for all day events. + today_t = icaltime_null_date(); + today_t.year = year; + today_t.month = month; + today_t.day = day; + + // Now loop through our list of events to see which ones occur today. + Pos = GetNewHashPos(WC->disp_cal_items, 0); + while (GetNextHashPos(WC->disp_cal_items, Pos, &hklen, &HashKey, &vCal)) { + Cal = (disp_cal*)vCal; all_day_event = 0; ongoing_event=0; @@ -848,132 +806,251 @@ void calendar_day_view_display_events(time_t thetime, int year, int month, else { memset(&t, 0, sizeof t); } + + if (t.is_date) all_day_event = 1; + q = icalcomponent_get_first_property(Cal->cal, ICAL_DTEND_PROPERTY); if (q != NULL) { end_t = icalproperty_get_dtend(q); - event_tte = icaltime_as_timet(end_t); - localtime_r(&event_tte, &event_tm); } else { - memset(&end_t, 0, sizeof end_t); + // no end given means end = start + memcpy(&end_t, &t, sizeof(struct icaltimetype)); } - if (t.is_date) all_day_event = 1; - if (all_day_event) - { - show_event = ((t.year == year) && (t.month == month) && (t.day == day) && (hour == -1)); + if (all_day_event) { + show_event = ical_ctdl_is_overlap(t, end_t, today_t, icaltime_null_time()); + if (icaltime_compare(t, end_t)) { + // the end date is non-inclusive so adjust it by one day because our test is inclusive, + // note that a day is not too much because we are talking about all day events + icaltime_adjust(&end_t, -1, 0, 0, 0); + } } - else - { + else { show_event = ical_ctdl_is_overlap(t, end_t, today_start_t, today_end_t); } - - /* If we determined that this event occurs today, then display it. - */ + event_tte = icaltime_as_timet(end_t); + localtime_r(&event_tte, &event_tm); + + // If we determined that this event occurs today, then display it. p = icalcomponent_get_first_property(Cal->cal,ICAL_SUMMARY_PROPERTY); + if (p == NULL) { + p = icalproperty_new_summary(_("Untitled Event")); + icalcomponent_add_property(Cal->cal, p); + } + if ((show_event) && (p != NULL)) { - if ((event_te.tm_mday != today_start_t.day) && (event_tm.tm_mday != today_start_t.day)) ongoing_event = 1; + if ((event_te.tm_mday != day) || (event_tm.tm_mday != day)) ongoing_event = 1; - if (all_day_event) - { - wprintf("
  • ", - Cal->cal_msgnum, year, month, day, hour); - escputs((char *) icalproperty_get_comment(p)); - wprintf(" ("); - wprintf(_("All day event")); - wprintf(")
  • \n"); + if (all_day_event && notime_events) { + wc_printf("
  • " + "" + , + (Cal->unread)?"_unread":"_read", + Cal->cal_msgnum, year, month, day + ); + escputs((char *) icalproperty_get_comment(p)); + wc_printf(""); + wc_printf("%s
    ", _("All day event")); + wc_printf("%s: %s
    ", _("From"), Cal->from); + wc_printf("%s ", _("Summary:")); + escputs((char *) icalproperty_get_comment(p)); + wc_printf("
    "); + q = icalcomponent_get_first_property(Cal->cal,ICAL_LOCATION_PROPERTY); + if (q) { + wc_printf("%s ", _("Location:")); + escputs((char *)icalproperty_get_comment(q)); + wc_printf("
    "); + } + if (!icaltime_compare(t, end_t)) { // one day only + webcit_fmt_date(buf, 256, event_tt, DATEFMT_LOCALEDATE); + wc_printf("%s %s
    ", _("Date:"), buf); + } + else { + webcit_fmt_date(buf, 256, event_tt, DATEFMT_LOCALEDATE); + wc_printf("%s %s
    ", _("Starting date:"), buf); + webcit_fmt_date(buf, 256, event_tte, DATEFMT_LOCALEDATE); + wc_printf("%s %s
    ", _("Ending date:"), buf); + } + q = icalcomponent_get_first_property(Cal->cal,ICAL_DESCRIPTION_PROPERTY); + if (q) { + wc_printf("%s ", _("Notes:")); + escputs((char *)icalproperty_get_comment(q)); + wc_printf("
    "); + } + wc_printf("
    "); + wc_printf("
    ("); + wc_printf(_("All day event")); + wc_printf(")
  • \n"); } - else if (ongoing_event && (hour == -1)) - { - wprintf("
  • ", - Cal->cal_msgnum, year, month, day, hour); + + else if (ongoing_event && notime_events) { + + wc_printf("
  • " + "" + , + (Cal->unread)?"_unread":"_read", + Cal->cal_msgnum, year, month, day + ); escputs((char *) icalproperty_get_comment(p)); - wprintf(" ("); - wprintf(_("Ongoing event")); - wprintf(")
  • \n"); + wc_printf(""); + wc_printf("%s
    ", _("Ongoing event")); + wc_printf("%s: %s
    ", _("From"), Cal->from); + wc_printf("%s ", _("Summary:")); + escputs((char *) icalproperty_get_comment(p)); + wc_printf("
    "); + q = icalcomponent_get_first_property(Cal->cal,ICAL_LOCATION_PROPERTY); + if (q) { + wc_printf("%s ", _("Location:")); + escputs((char *)icalproperty_get_comment(q)); + wc_printf("
    "); + } + webcit_fmt_date(buf, 256, event_tt, DATEFMT_BRIEF); + wc_printf("%s %s
    ", _("Starting date/time:"), buf); + webcit_fmt_date(buf, 256, event_tte, DATEFMT_BRIEF); + wc_printf("%s %s
    ", _("Ending date/time:"), buf); + q = icalcomponent_get_first_property(Cal->cal,ICAL_DESCRIPTION_PROPERTY); + if (q) { + wc_printf("%s ", _("Notes:")); + escputs((char *)icalproperty_get_comment(q)); + wc_printf("
    "); + } + wc_printf("
    "); + wc_printf(" ("); + wc_printf(_("Ongoing event")); + wc_printf(")\n"); } - else - { - if ((hour == event_te.tm_hour) && ! ongoing_event ) { - if (event_te.tm_mday != today_start_t.day) event_te.tm_hour = 0; - if (event_tm.tm_mday != today_start_t.day) event_tm.tm_hour = 24; + else if (!all_day_event && !notime_events) { + gap++; - if ((event_te.tm_hour < dstart) && (event_tm.tm_hour <= dstart)) { - top = (event_te.tm_hour * 11) -1; - height= (event_tm.tm_hour - event_te.tm_hour) * 11; - } - if ((event_te.tm_hour < dstart) && (event_tm.tm_hour >= dstart)) { - top = (event_te.tm_hour * 11) - 1; - height = ((dstart - event_te.tm_hour) * 11) + ((event_tm.tm_hour - dstart) * 31); - } - if ((event_te.tm_hour <= dstart) && (event_tm.tm_hour > dend)) { - top = (event_te.tm_hour * 11) - 1; - height = ((dstart - event_te.tm_hour) * 11) + ((dend - dstart + 1) * 31) + ((event_tm.tm_hour - dend - 1) * 10); - } - if ((event_te.tm_hour >= dstart) && (event_tm.tm_hour <= dend)) { - top = (dstart * 11) + ((event_te.tm_hour - dstart) * 31) - 1; - height = ((event_tm.tm_hour - event_te.tm_hour) * 31); - } - if ((event_te.tm_hour >= dstart) && (event_te.tm_hour <= dend) && (event_tm.tm_hour > dend)) { - top = (dstart * 11) + ((event_te.tm_hour - dstart) * 31) - 1; - height = (((dend - event_te.tm_hour + 1) * 31) + ((event_tm.tm_hour - dend - 1) * 11)); - } - if ((event_te.tm_hour > dend) && (event_tm.tm_hour > dend)) { - top = (dstart * 11) + ((dend - dstart + 1) * 31) + ((event_tm.tm_hour - event_te.tm_hour) * 11) - 1; - height = ((event_tm.tm_hour - event_te.tm_hour) * 11); - } - wprintf("
    = dstart) && (event_te.tm_hour <= dend)) { + startmin = diffmin = (event_te.tm_min / 2); + top = (dstart * EXTRATIMELINE) + ((event_te.tm_hour - dstart) * TIMELINE) + startmin; + } + else if (event_te.tm_hour >dend) { + startmin = diffmin = event_te.tm_min / 6; + top = (dstart * EXTRATIMELINE) + ((dend - dstart - 1) * TIMELINE) + ((event_tm.tm_hour - dend + 1) * EXTRATIMELINE) + startmin ; + } + else { + // should never get here + } + + // Calculate the location of the bottom of the box + if (event_tm.tm_hour < dstart) { + endmin = diffmin = event_tm.tm_min / 6; + bottom = (event_tm.tm_hour * EXTRATIMELINE) + endmin; + } + else if ((event_tm.tm_hour >= dstart) && (event_tm.tm_hour <= dend)) { + endmin = diffmin = (event_tm.tm_min / 2); + bottom = (dstart * EXTRATIMELINE) + ((event_tm.tm_hour - dstart) * TIMELINE) + endmin ; + } + else if (event_tm.tm_hour >dend) { + endmin = diffmin = event_tm.tm_min / 6; + bottom = (dstart * EXTRATIMELINE) + ((dend - dstart + 1) * TIMELINE) + ((event_tm.tm_hour - dend - 1) * EXTRATIMELINE) + endmin; + } + else { + // should never get here + } + + wc_printf("
    ", - top, (50 + (gap * 50)), height + (Cal->unread)?"_unread":"_read", + top, (gap * 40), (bottom-top) ); - wprintf("", - Cal->cal_msgnum, year, month, day, t.hour, hour); + wc_printf("" + , + Cal->cal_msgnum, year, month, day, t.hour + ); escputs((char *) icalproperty_get_comment(p)); - wprintf("
    \n"); - gap++; + wc_printf(""); + wc_printf("%s: %s
    ", _("From"), Cal->from); + wc_printf("%s ", _("Summary:")); + escputs((char *) icalproperty_get_comment(p)); + wc_printf("
    "); + q = icalcomponent_get_first_property(Cal->cal,ICAL_LOCATION_PROPERTY); + if (q) { + wc_printf("%s ", _("Location:")); + escputs((char *)icalproperty_get_comment(q)); + wc_printf("
    "); + } + if (!icaltime_compare(t, end_t)) { // one day only + webcit_fmt_date(buf, 256, event_tt, DATEFMT_BRIEF); + wc_printf("%s %s
    ", _("Date/time:"), buf); + } + else { + webcit_fmt_date(buf, 256, event_tt, DATEFMT_BRIEF); + wc_printf("%s %s
    ", _("Starting date/time:"), buf); + webcit_fmt_date(buf, 256, event_tte, DATEFMT_BRIEF); + wc_printf("%s %s
    ", _("Ending date/time:"), buf); } - + q = icalcomponent_get_first_property(Cal->cal,ICAL_DESCRIPTION_PROPERTY); + if (q) { + wc_printf("%s ", _("Notes:")); + escputs((char *)icalproperty_get_comment(q)); + wc_printf("
    "); + } + wc_printf("
    "); + wc_printf("\n"); } } } + DeleteHashPos(&Pos); } -/** - * \brief view one day - * \param year the year - * \param month the month - * \param day the day we want to display - */ + +// view one day void calendar_day_view(int year, int month, int day) { int hour; struct icaltimetype today, yesterday, tomorrow; - int daystart = 8; - int dayend = 17; - char daystart_str[16], dayend_str[16]; + long daystart; + long dayend; struct tm d_tm; - char d_str[128]; + char d_str[160]; int time_format; time_t today_t; + int timeline = TIMELINE; + int extratimeline = EXTRATIMELINE; + int gap = 0; + int hourlabel; + int extrahourlabel; time_format = get_time_format_cached (); - get_preference("daystart", daystart_str, sizeof daystart_str); - if (!IsEmptyStr(daystart_str)) daystart = atoi(daystart_str); - get_preference("dayend", dayend_str, sizeof dayend_str); - if (!IsEmptyStr(dayend_str)) dayend = atoi(dayend_str); - - /** Today's date */ + get_pref_long("daystart", &daystart, 8); + get_pref_long("dayend", &dayend, 17); + + // when loading daystart/dayend, replace missing, corrupt, or impossible values with defaults + if ((daystart < 0) || (dayend < 2) || (daystart >= 23) || (dayend > 23) || (dayend <= daystart)) { + daystart = 9; + dayend = 17; + } + + // Today's date memset(&d_tm, 0, sizeof d_tm); d_tm.tm_year = year - 1900; d_tm.tm_mon = month - 1; d_tm.tm_mday = day; today_t = mktime(&d_tm); - /** Figure out the dates for "yesterday" and "tomorrow" links */ + // Figure out the dates for "yesterday" and "tomorrow" links memset(&today, 0, sizeof(struct icaltimetype)); today.year = year; @@ -989,113 +1066,152 @@ void calendar_day_view(int year, int month, int day) { ++tomorrow.day; tomorrow = icaltime_normalize(tomorrow); - wprintf("
    "); + // Inner table (the real one) + wc_printf(" \n"); + + // Innermost cell (contains hours etc.) + wc_printf(""); - wprintf(""); /** end stuff-on-the-right */ + wc_printf("
    "); + wc_printf("
    "); - /** Inner table (the real one) */ - wprintf(" \n"); + // Now the middle of the day... - /** Innermost cell (contains hours etc.) */ - wprintf(""); /* end of innermost table */ + if (time_format == WC_TIMEFORMAT_24) { + wc_printf("%2d:00 ", hour); + } + else { + wc_printf("%d:00%s ", + (hour <= 12 ? hour : hour-12), + (hour < 12 ? "am" : "pm") + ); + } + + wc_printf(""); + } + + gap = gap + ((dayend - daystart + 1) * timeline); + + for (hour = (dayend + 1); hour < 24; ++hour) { // could do HEIGHT=xx + wc_printf("
    " + "", + year, month, day, hour + ); + + if (time_format == WC_TIMEFORMAT_24) { + wc_printf("%2d:00 ", hour); + } + else { + wc_printf("%d:00%s ", + (hour <= 12 ? hour : hour-12), + (hour < 12 ? "am" : "pm") + ); + } + + wc_printf("
    "); + } + + // Display events with start and end times on this day + calendar_day_view_display_events(today_t, year, month, day, 0, daystart, dayend); - /** Extra events on the middle */ - wprintf(""); // end of innermost table - wprintf("
      "); + // Display extra events (start/end times not present or not today) in the middle column + wc_printf("
    "); /** end extra on the middle */ + wc_printf(""); - wprintf(""); // end extra on the middle - /** Begin todays-date-with-left-and-right-arrows */ - wprintf("
    "); - wprintf("
    "); - /** Now the middle of the day... */ - for (hour = 0; hour < 24; ++hour) { /* could do HEIGHT=xx */ - wprintf("
    ", - (hour < daystart ? "before" : (hour > dayend ? "after" : "")), + extrahourlabel = extratimeline - 2; + hourlabel = extrahourlabel * 150 / 100; + if (hourlabel > (timeline - 2)) hourlabel = timeline - 2; + + for (hour = 0; hour < daystart; ++hour) { // could do HEIGHT=xx + wc_printf("
    " + "", year, month, day, hour ); if (time_format == WC_TIMEFORMAT_24) { - wprintf("%2d:00 ", hour); + wc_printf("%2d:00 ", hour); } else { - wprintf("%d:00%s ", - (hour <= 12 ? hour : hour-12), + wc_printf("%d:00%s ", + ((hour == 0) ? 12 : (hour <= 12 ? hour : hour-12)), (hour < 12 ? "am" : "pm") ); } - wprintf("
    "); - + wc_printf(""); + } - /* put the data here, stupid */ - calendar_day_view_display_events(today_t, year, month, day, hour, daystart, dayend); + gap = daystart * extratimeline; - } + for (hour = daystart; hour <= dayend; ++hour) { // could do HEIGHT=xx + wc_printf("
    " + "", + year, month, day, hour + ); - wprintf("
    "); - wprintf("
    "); + wc_printf(""); + wc_printf(""); - /** Display all-day events) */ - calendar_day_view_display_events(today_t, year, month, day, -1, daystart, dayend); + wc_printf("
      "); - wprintf("
    "); + // Display all-day events + calendar_day_view_display_events(today_t, year, month, day, 1, daystart, dayend); - wprintf("
    "); /** begin stuff-on-the-right */ + wc_printf("
    \n"); - wprintf(""); + wc_printf(""); + // Begin todays-date-with-left-and-right-arrows + wc_printf("
    "); // begin stuff-on-the-right - /** Left arrow */ - wprintf(""); - wprintf("", - yesterday.year, yesterday.month, yesterday.day); - wprintf(""); - wprintf("
    \n"); + wc_printf(""); + + // Left arrow + wc_printf(""); wc_strftime(d_str, sizeof d_str, - "", &d_tm ); - wprintf("%s", d_str); + wc_printf("%s", d_str); - /** Right arrow */ - wprintf(""); - - wprintf("
    "); + wc_printf("", yesterday.year, yesterday.month, yesterday.day); + wc_printf("\"previous\""); + wc_printf("" - "%B
    " - "%d
    " - "%Y
    " + "
    " + "%A
    " + "%B
    " + "%d
    " + "%Y
    " "
    "); - wprintf("", + // Right arrow + wc_printf(""); + wc_printf("", tomorrow.year, tomorrow.month, tomorrow.day); - wprintf("\n"); - wprintf("
    \n"); - /** End todays-date-with-left-and-right-arrows */ - - /** Embed a mini month calendar in this space */ - wprintf("
    \n"); - embeddable_mini_calendar(year, month, "readfwd?calview=day&year=%d&month=%d&day=%d"); - - wprintf("\n"); + wc_printf("\"%s\"\n", _("next")); + wc_printf("
    \n"); + // End todays-date-with-left-and-right-arrows - wprintf("" /** end of inner table */ - "
    "); + // Embed a mini month calendar in this space + wc_printf("
    \n"); + embeddable_mini_calendar(year, month); - wprintf("\n" - ); + wc_printf(""); // end stuff-on-the-right + wc_printf("\n"); // end of inner table } -/** - * \brief Display today's events. - */ -void calendar_summary_view(void) { - int i; +// Display today's events. Returns the number of items displayed. +int calendar_summary_view(void) { + long hklen; + const char *HashKey; + void *vCal; + HashPos *Pos; + disp_cal *Cal; icalproperty *p; struct icaltimetype t; time_t event_tt; @@ -1104,17 +1220,19 @@ void calendar_summary_view(void) { time_t now; int all_day_event = 0; char timestring[SIZ]; + int num_displayed = 0; - if (WC->num_cal == 0) { - return; + if (GetCount(WC->disp_cal_items) == 0) { + return(0); } now = time(NULL); localtime_r(&now, &today_tm); - for (i=0; i<(WC->num_cal); ++i) { - p = icalcomponent_get_first_property(WC->disp_cal[i].cal, - ICAL_DTSTART_PROPERTY); + Pos = GetNewHashPos(WC->disp_cal_items, 0); + while (GetNextHashPos(WC->disp_cal_items, Pos, &hklen, &HashKey, &vCal)) { + Cal = (disp_cal*)vCal; + p = icalcomponent_get_first_property(Cal->cal, ICAL_DTSTART_PROPERTY); if (p != NULL) { t = icalproperty_get_dtstart(p); event_tt = icaltime_as_timet(t); @@ -1124,7 +1242,7 @@ void calendar_summary_view(void) { else { all_day_event = 0; } - fmt_time(timestring, event_tt); + fmt_time(timestring, SIZ, event_tt); if (all_day_event) { gmtime_r(&event_tt, &event_tm); @@ -1134,235 +1252,167 @@ void calendar_summary_view(void) { } if ( (event_tm.tm_year == today_tm.tm_year) - && (event_tm.tm_mon == today_tm.tm_mon) - && (event_tm.tm_mday == today_tm.tm_mday) - ) { - - - p = icalcomponent_get_first_property( - WC->disp_cal[i].cal, - ICAL_SUMMARY_PROPERTY); + && (event_tm.tm_mon == today_tm.tm_mon) + && (event_tm.tm_mday == today_tm.tm_mday) + ) { + p = icalcomponent_get_first_property(Cal->cal, ICAL_SUMMARY_PROPERTY); + if (p == NULL) { + p = icalproperty_new_summary(_("Untitled Task")); + icalcomponent_add_property(Cal->cal, p); + } if (p != NULL) { - escputs((char *) - icalproperty_get_comment(p)); - wprintf(" (%s)
    \n", timestring); + if (WC->CurRoom.view == VIEW_TASKS) { + wc_printf(""); + } + else { + wc_printf(""); + } + escputs((char *) icalproperty_get_comment(p)); + if (!all_day_event) { + wc_printf(" (%s)", timestring); + } + wc_printf("
    \n"); + ++num_displayed; } } } } - free_calendar_buffer(); + DeleteHashPos(&Pos); + DeleteHash(&WC->disp_cal_items); + return(num_displayed); } -/** - * \brief clean up ical memory - * \todo this could get troubel with future ical versions - */ -void free_calendar_buffer(void) { - int i; - if (WC->num_cal) for (i=0; i<(WC->num_cal); ++i) { - icalcomponent_free(WC->disp_cal[i].cal); - } - WC->num_cal = 0; - free(WC->disp_cal); - WC->disp_cal = NULL; -} +// Parse the URL variables in order to determine the scope and display of a calendar view +int calendar_GetParamsGetServerCall(SharedMessageStatus *Stat, + void **ViewSpecific, + long oper, + char *cmd, + long len, + char *filter, + long flen) +{ + calview *c; + time_t now; + struct tm tm; + char cv[32]; + int span = 3888000; + c = (calview*) malloc(sizeof(calview)); + memset(c, 0, sizeof(calview)); + *ViewSpecific = (void*)c; -/** - * \brief do the whole calendar page - * view any part of the calender. decide which way, etc. - */ -void do_calendar_view(void) { - time_t now; - struct tm tm; - int year, month, day; - char calview[SIZ]; + Stat->load_seen = 1; + strcpy(cmd, "MSGS ALL"); + Stat->maxmsgs = 32767; - /** In case no date was specified, go with today */ + // In case no date was specified, go with today now = time(NULL); localtime_r(&now, &tm); - year = tm.tm_year + 1900; - month = tm.tm_mon + 1; - day = tm.tm_mday; - - /** Now see if a date was specified */ - if (!IsEmptyStr(bstr("year"))) year = atoi(bstr("year")); - if (!IsEmptyStr(bstr("month"))) month = atoi(bstr("month")); - if (!IsEmptyStr(bstr("day"))) day = atoi(bstr("day")); - - /** How would you like that cooked? */ - if (!IsEmptyStr(bstr("calview"))) { - strcpy(calview, bstr("calview")); + c->year = tm.tm_year + 1900; + c->month = tm.tm_mon + 1; + c->day = tm.tm_mday; + + // Now see if a date was specified + if (havebstr("year")) c->year = ibstr("year"); + if (havebstr("month")) c->month = ibstr("month"); + if (havebstr("day")) c->day = ibstr("day"); + + // How would you like that cooked? + if (havebstr("calview")) { + strcpy(cv, bstr("calview")); } else { - strcpy(calview, "month"); + strcpy(cv, "month"); } - /** Display the selected view */ - if (!strcasecmp(calview, "day")) { - calendar_day_view(year, month, day); + // Display the selected view + if (!strcasecmp(cv, "day")) { + c->view = calview_day; + } + else if (!strcasecmp(cv, "week")) { + c->view = calview_week; } - else if (!strcasecmp(calview, "week")) { - calendar_week_view(year, month, day); + else if (!strcasecmp(cv, "summary")) { // shouldn't ever happen, but just in case + c->view = calview_day; } else { - if (WC->wc_view == VIEW_CALBRIEF) { - calendar_brief_month_view(year, month, day); + if (WC->CurRoom.view == VIEW_CALBRIEF) { + c->view = calview_brief; } else { - calendar_month_view(year, month, day); + c->view = calview_month; } } - /** Free the calendar stuff */ - free_calendar_buffer(); - + // Now try and set the lower and upper bounds so that we don't + // burn too many cpu cycles parsing data way in the past or future + tm.tm_year = c->year - 1900; + tm.tm_mon = c->month - 1; + tm.tm_mday = c->day; + now = mktime(&tm); + + if (c->view == calview_month) span = 3888000; + if (c->view == calview_brief) span = 3888000; + if (c->view == calview_week) span = 604800; + if (c->view == calview_day) span = 86400; + if (c->view == calview_summary) span = 86400; + + c->lower_bound = now - span; + c->upper_bound = now + span; + return 200; } -/** - * \brief get task due date - * Helper function for do_tasks_view(). - * \param vtodo a task to get the due date - * \return the date/time due. - */ -time_t get_task_due_date(icalcomponent *vtodo) { - icalproperty *p; +// Render a calendar view from data previously loaded into memory +int calendar_RenderView_or_Tail(SharedMessageStatus *Stat, void **ViewSpecific, long oper) { - if (vtodo == NULL) { - return(0L); - } + calview *c = (calview*) *ViewSpecific; - /** - * If we're looking at a fully encapsulated VCALENDAR - * rather than a VTODO component, recurse into the data - * structure until we get a VTODO. - */ - if (icalcomponent_isa(vtodo) == ICAL_VCALENDAR_COMPONENT) { - return get_task_due_date( - icalcomponent_get_first_component( - vtodo, ICAL_VTODO_COMPONENT - ) - ); + if (c->view == calview_day) { + calendar_day_view(c->year, c->month, c->day); } - - p = icalcomponent_get_first_property(vtodo, ICAL_DUE_PROPERTY); - if (p != NULL) { - return(icaltime_as_timet(icalproperty_get_due(p))); + else if (c->view == calview_week) { + calendar_week_view(c->year, c->month, c->day); } else { - return(0L); - } -} - - -/** - * \brief Compare the due dates of two tasks (this is for sorting) - * \param task1 first task to compare - * \param task2 second task to compare - */ -int task_due_cmp(const void *task1, const void *task2) { - time_t t1; - time_t t2; - - t1 = get_task_due_date(((struct disp_cal *)task1)->cal); - t2 = get_task_due_date(((struct disp_cal *)task2)->cal); - - if (t1 < t2) return(-1); - if (t1 > t2) return(1); - return(0); -} - - - - -/** - * \brief do the whole task view stuff - */ -void do_tasks_view(void) { - int i; - time_t due; - int bg = 0; - char buf[SIZ]; - icalproperty *p; - - wprintf("
    " - "\n\n" - "\n" - ); - - /** Sort them if necessary */ - if (WC->num_cal > 1) { - qsort(WC->disp_cal, - WC->num_cal, - sizeof(struct disp_cal), - task_due_cmp - ); - } - - if (WC->num_cal) for (i=0; i<(WC->num_cal); ++i) { - - bg = 1 - bg; - wprintf("\n"); - - due = get_task_due_date(WC->disp_cal[i].cal); - fmt_date(buf, due, 0); - wprintf("\n", buf); } - wprintf("
    "); - wprintf(_("Name of task")); - wprintf(""); - wprintf(_("Date due")); - wprintf("
    ", - (bg ? "DDDDDD" : "FFFFFF") - ); - - p = icalcomponent_get_first_property(WC->disp_cal[i].cal, - ICAL_SUMMARY_PROPERTY); - wprintf("disp_cal[i].cal_msgnum ); - urlescputs(WC->wc_roomname); - wprintf("\">"); - wprintf(" "); - if (p != NULL) { - escputs((char *)icalproperty_get_comment(p)); + if (WC->CurRoom.view == VIEW_CALBRIEF) { + calendar_brief_month_view(c->year, c->month, c->day); } - wprintf("\n"); - wprintf("year, c->month, c->day); } - wprintf(">%s
    \n"); - - /** Free the list */ - free_calendar_buffer(); - -} - -#else /* WEBCIT_WITH_CALENDAR_SERVICE */ - -/**\brief stub for non-libical builds */ -void do_calendar_view(void) { - wprintf("
    "); - wprintf(_("The calendar view is not available.")); - wprintf("

    \n"); -} - -/**\brief stub for non-libical builds */ -void do_tasks_view(void) { - wprintf("
    "); - wprintf(_("The tasks view is not available.")); - wprintf("

    \n"); + // Free the in-memory list of calendar items + DeleteHash(&WC->disp_cal_items); + return 0; } -/**\brief stub for non-libical builds */ -void ajax_mini_calendar(void) { +void +InitModule_CALENDAR_VIEW +(void) +{ + WebcitAddUrlHandler(HKEY("mini_calendar"), "", 0, ajax_mini_calendar, AJAX); } - -#endif /* WEBCIT_WITH_CALENDAR_SERVICE */ - -/** @} */