X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=webcit%2Fcalendar_view.c;h=78325f835832789f462a724429edc39da2917f08;hb=9f145319b92b196662aa51cb2e3d7c392629965e;hp=93a7d4059091624fe83107507b50692a720a069f;hpb=486fe78f4d6aefd8e6b3935dc046f735056cc756;p=citadel.git diff --git a/webcit/calendar_view.c b/webcit/calendar_view.c index 93a7d4059..78325f835 100644 --- a/webcit/calendar_view.c +++ b/webcit/calendar_view.c @@ -4,57 +4,371 @@ * Handles the HTML display of calendar items. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include "webcit.h" #include "webserver.h" -#ifndef WEBCIT_WITH_CALENDAR_SERVICE -void do_calendar_view(void) { /* stub for non-libical builds */ - wprintf("
Calendar view not available

\n"); +void embeddable_mini_calendar(int year, int month, char *urlformat) +{ + struct tm starting_tm; + struct tm tm; + time_t thetime; + int i, len; + 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]; + 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); + + /* + * Now 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; + starting_tm.tm_mday = 1; + thetime = mktime(&starting_tm); + + memcpy(&tm, &starting_tm, sizeof(struct tm)); + while (tm.tm_mday != 1) { + 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 */ + + /** 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 */ + localtime_r(&thetime, &tm); + } + + wprintf("
\n", div_id); + + /* Previous month link */ + localtime_r(&previous_month, &tm); + wprintf("«", + (int)(tm.tm_year)+1900, tm.tm_mon + 1); + + wc_strftime(colheader_label, sizeof colheader_label, "%B", &starting_tm); + wprintf("  " + "" + "%s %d" + "" + "  ", colheader_label, year); + + /* Next month link */ + localtime_r(&next_month, &tm); + wprintf("»", + (int)(tm.tm_year)+1900, tm.tm_mon + 1); + + wprintf("" + ""); + 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]); + + } + wprintf("\n"); + + + /** 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 */ + if ((i % 7) == 0) { + wprintf(""); + } + + if (tm.tm_mon == month-1) { + snprintf(url, sizeof url, urlformat, + tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday); + wprintf("", url, tm.tm_mday); + } + else { + wprintf(""); + } + + /** After displaying one week, end the row */ + if ((i % 7) == 6) { + wprintf("\n"); + } + + } + + thetime += (time_t)86400; /** ahead 24 hours */ + } + + wprintf("
%c
%d
" /** 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 + ); + } -void do_tasks_view(void) { /* stub for non-libical builds */ - wprintf("
Tasks view not available

\n"); +/* 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"); + return; + } -void calendar_month_view_display_events(time_t thetime) { + /* 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; + starting_tm.tm_mday = 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; + ending_tm.tm_mon = month - 1; + ending_tm.tm_mday = 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]; + all_day_event = 0; + q = icalcomponent_get_first_property(Cal->cal, ICAL_DTSTART_PROPERTY); + if (q != NULL) { + t = icalproperty_get_dtstart(q); + } + else { + memset(&t, 0, sizeof t); + } + q = icalcomponent_get_first_property(Cal->cal, ICAL_DTEND_PROPERTY); + if (q != NULL) { + end_t = icalproperty_get_dtend(q); + } + else { + memset(&end_t, 0, sizeof end_t); + } + if (t.is_date) all_day_event = 1; + + if (all_day_event) + { + show_event = ((t.year == year) && (t.month == month) && (t.day == day)); + } + 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 (show_event) { + p = icalcomponent_get_first_property(Cal->cal, ICAL_SUMMARY_PROPERTY); + if (p != NULL) { + + if (all_day_event) { + wprintf("" + "
" + ); + } + + wprintf("" + "unread)?"_unread":"_read", + WC->disp_cal[i].cal_msgnum, + year, month, day + ); + + wprintf("%s: %s
", _("From"), Cal->from); + wprintf("%s ", _("Summary:")); + escputs((char *)icalproperty_get_comment(p)); + wprintf("
"); + + q = icalcomponent_get_first_property( + WC->disp_cal[i].cal, + ICAL_LOCATION_PROPERTY); + if (q) { + wprintf("%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 + */ + if (icalcomponent_isa(Cal->cal) == ICAL_VEVENT_COMPONENT) { + + q = icalcomponent_get_first_property(Cal->cal, ICAL_DTSTART_PROPERTY); + if (q != NULL) { + t = icalproperty_get_dtstart(q); + + if (t.is_date) { + struct tm d_tm; + char d_str[32]; + 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); + } + else { + tt = icaltime_as_timet(t); + webcit_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); + webcit_fmt_date(buf, tt, 1); + wprintf("%s %s
", _("Ending date/time:"), buf); + } + + } + } + + } + + q = icalcomponent_get_first_property(Cal->cal, ICAL_DESCRIPTION_PROPERTY); + if (q) { + wprintf("%s ", _("Notes:")); + escputs((char *)icalproperty_get_comment(q)); + wprintf("
"); + } + + wprintf("\">"); + escputs((char *) + icalproperty_get_comment(p)); + wprintf("

\n"); + + if (all_day_event) { + wprintf("
"); + } + + } + + } + + + } +} + + +/** + * \brief Display one day of a whole month view of a calendar + * \param thetime the month we want to see + */ +void calendar_month_view_brief_events(time_t thetime, const char *daycolor) { int i; time_t event_tt; - struct tm event_tm; + time_t event_tts; + time_t event_tte; + struct wcsession *WCC = WC; /* This is done to make it run faster; WC is a function */ + struct tm event_tms; + struct tm event_tme; struct tm today_tm; icalproperty *p; + icalproperty *e; struct icaltimetype t; + struct disp_cal *Cal; int month, day, year; int all_day_event = 0; + char *timeformat; + int time_format; + + time_format = get_time_format_cached (); - if (WC->num_cal == 0) { - wprintf("


\n"); - return; - } + 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; @@ -62,73 +376,266 @@ void calendar_month_view_display_events(time_t thetime) { year = today_tm.tm_year + 1900; for (i=0; i<(WC->num_cal); ++i) { - p = icalcomponent_get_first_property(WC->disp_cal[i].cal, + Cal = &WCC->disp_cal[i]; + p = icalcomponent_get_first_property(Cal->cal, ICAL_DTSTART_PROPERTY); if (p != NULL) { t = icalproperty_get_dtstart(p); event_tt = icaltime_as_timet(t); - + event_tts=event_tt; if (t.is_date) all_day_event = 1; else all_day_event = 0; if (all_day_event) { - gmtime_r(&event_tt, &event_tm); + gmtime_r(&event_tts, &event_tms); } else { - localtime_r(&event_tt, &event_tm); + localtime_r(&event_tts, &event_tms); } - - 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)) { + /** \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); - if (p != NULL) { - - if (all_day_event) { - wprintf("" - "" + "", + daycolor, + sbuf, + daycolor, + ebuf); + + } + + } + + + } + } +} - if (all_day_event) { - wprintf("
" - ); - } - - wprintf("" - "", + e = icalcomponent_get_first_property( + WC->disp_cal[i].cal, + ICAL_DTEND_PROPERTY); + if ((p != NULL) && (e != NULL)) { + time_t difftime; + int hours, minutes; + t = icalproperty_get_dtend(e); + event_tte = icaltime_as_timet(t); + localtime_r(&event_tte, &event_tme); + difftime=(event_tte-event_tts)/60; + hours=(int)(difftime / 60); + minutes=difftime % 60; + wprintf("
%i:%2i" + "" + "", + daycolor, + hours, minutes, + (Cal->unread)?"_unread":"_read", + daycolor, WC->disp_cal[i].cal_msgnum, - bstr("calview"), bstr("year"), bstr("month"), bstr("day") - ); + ); + escputs((char *) - icalproperty_get_comment(p)); - wprintf("
\n"); + icalproperty_get_comment(p)); + /** \todo: allso ammitime format */ + wc_strftime(&sbuf[0], sizeof(sbuf), timeformat, &event_tms); + wc_strftime(&ebuf[0], sizeof(sbuf), timeformat, &event_tme); + + wprintf("
%s%s
"); - } - } +/** + * \brief view one month. pretty view + * \param year the year + * \param month the month + * \param day the actual day we want to see + */ +void calendar_month_view(int year, int month, int day) { + struct tm starting_tm; + struct tm tm; + time_t thetime; + int i; + time_t previous_month; + time_t next_month; + time_t colheader_time; + 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... + */ + memset(&starting_tm, 0, sizeof(struct tm)); + + starting_tm.tm_year = year - 1900; + starting_tm.tm_mon = month - 1; + starting_tm.tm_mday = day; + thetime = mktime(&starting_tm); + + memcpy(&tm, &starting_tm, sizeof(struct tm)); + while (tm.tm_mday != 1) { + 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 */ + + /** 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 */ + localtime_r(&thetime, &tm); + } + + /** Outer table (to get the background color) */ + wprintf("
" + " \n
"); + + wprintf("\n"); + + wprintf("
"); + localtime_r(&previous_month, &tm); + wprintf("", + (int)(tm.tm_year)+1900, tm.tm_mon + 1); + wprintf("\n"); + + wc_strftime(colheader_label, sizeof colheader_label, "%B", &starting_tm); + wprintf("  " + "" + "%s %d" + "" + "  ", colheader_label, year); + + localtime_r(&next_month, &tm); + wprintf("", + (int)(tm.tm_year)+1900, tm.tm_mon + 1); + wprintf("\n"); + + wprintf("
\n"); + + /** Inner table (the real one) */ + wprintf(""); + 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"); + + + /** 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; + } + + /** Before displaying Sunday, start a new row */ + if ((i % 7) == 0) { + wprintf(""); } + wprintf(""); + + /** After displaying Saturday, end the row */ + if ((i % 7) == 6) { + wprintf("\n"); + } } - } -} + thetime += (time_t)86400; /** ahead 24 hours */ + } + wprintf("
" + "%s
", + ((tm.tm_mon != month-1) ? "out" : + ((tm.tm_wday==0 || tm.tm_wday==6) ? "weekend" : + "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 + ); + + wprintf("
" /** end of inner table */ + "
" /** end of outer table */ + "
\n"); + + /** + * 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" + ); +} -void calendar_month_view(int year, int month, int day) { +/** + * \brief view one month. brief view + * \param year the year + * \param month the month + * \param day the actual day we want to see + */ +void calendar_brief_month_view(int year, int month, int day) { struct tm starting_tm; struct tm tm; time_t thetime; int i; time_t previous_month; time_t next_month; + char month_label[32]; - /* Determine what day to start. + /** Determine what day to start. * First, back up to the 1st of the month... */ memset(&starting_tm, 0, sizeof(struct tm)); @@ -143,181 +650,424 @@ void calendar_month_view(int year, int month, int day) { localtime_r(&thetime, &tm); } - /* Determine previous and next months ... for links */ + /** 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 */ - /* 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 */ localtime_r(&thetime, &tm); } - /* Outer table (to get the background color) */ - wprintf("
" - "" + "
\n"); - wprintf("\n"); + wprintf("
\n"); - wprintf("
"); + wprintf(""); localtime_r(&previous_month, &tm); - wprintf("", + wprintf("", (int)(tm.tm_year)+1900, tm.tm_mon + 1); - wprintf("\n"); + wprintf("\n"); + wc_strftime(month_label, sizeof month_label, "%B", &tm); wprintf("  " - "" + "" "%s %d" - "" - "  ", months[month-1], year); + "" + "  ", month_label, year); localtime_r(&next_month, &tm); - wprintf("", + wprintf("", (int)(tm.tm_year)+1900, tm.tm_mon + 1); - wprintf("\n"); + wprintf("\n"); - wprintf("
\n"); + wprintf("
\n"); - /* Inner table (the real one) */ - wprintf(""); - for (i=0; i<7; ++i) { - wprintf("\n"); + /** Inner table (the real one) */ + wprintf("
" - "%s", days[i]); - } - wprintf("
"); + wprintf("\n"); + wprintf(""); - } - wprintf("
\n"); - /* Now do 35 days */ + /** Now do 35 days */ for (i = 0; i < 35; ++i) { + char weeknumber[255]; + char weekday_name[32]; + char *daycolor; localtime_r(&thetime, &tm); - /* Before displaying Sunday, start a new row */ - if ((i % 7) == 0) { - wprintf("
", - ((tm.tm_mon != month-1) ? "DDDDDD" : - ((tm.tm_wday==0 || tm.tm_wday==6) ? "EEEECC" : - "FFFFFF")) - ); - if ((i==0) || (tm.tm_mday == 1)) { - wprintf("%s ", months[tm.tm_mon]); + /** 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") + ); } - 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(thetime); - - wprintf(""); - - /* After displaying Saturday, end the row */ + + daycolor=((tm.tm_mon != month-1) ? "DDDDDD" : + ((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); + + /** put the data of one day here, stupid */ + calendar_month_view_brief_events(thetime, daycolor); + + + /** After displaying Saturday, end the row */ if ((i % 7) == 6) { - wprintf("\n"); + wprintf("
%s %s
%s%s%s%s
%s,%i." + "
\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"); + wprintf("" /** end of inner table */ + "" /** end of outer table */ + "\n"); } - +/** + * \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 + */ void calendar_week_view(int year, int month, int day) { - wprintf("
week view FIXME

\n"); + wprintf("
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(int year, int month, - int day, int hour) { +void calendar_day_view_display_events(time_t thetime, + int year, + int month, + int day, + int notime_events, + int dstart, + int dend) +{ int i; - icalproperty *p; - struct icaltimetype t; + icalproperty *p = NULL; + icalproperty *q = NULL; time_t event_tt; - struct tm *event_tm; + time_t event_tte; + struct tm event_te; + struct tm event_tm; + int show_event = 0; int all_day_event = 0; - - if (WC->num_cal == 0) { - wprintf("


\n"); + int ongoing_event = 0; + struct wcsession *WCC = WC; /* This is done to make it run faster; WC is a function */ + struct disp_cal *Cal; + struct icaltimetype t; + struct icaltimetype end_t; + struct icaltimetype today_start_t; + struct icaltimetype today_end_t; + struct tm starting_tm; + struct tm ending_tm; + int top = 0; + int bottom = 0; + int gap = 1; + int startmin = 0; + int diffmin = 0; + int endmin = 0; + + char buf[256]; + struct tm d_tm; + char d_str[32]; + + if (WCC->num_cal == 0) { + /* nothing to display */ return; } - for (i=0; i<(WC->num_cal); ++i) { - p = icalcomponent_get_first_property(WC->disp_cal[i].cal, - ICAL_DTSTART_PROPERTY); - if (p != NULL) { - t = icalproperty_get_dtstart(p); - event_tt = icaltime_as_timet(t); - if (t.is_date) all_day_event = 1; + /* 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 = 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 = 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]; - if (all_day_event) { - event_tm = gmtime(&event_tt); - } - else { - event_tm = localtime(&event_tt); - } + all_day_event = 0; + ongoing_event=0; - if ((event_tm->tm_year == (year-1900)) - && (event_tm->tm_mon == (month-1)) - && (event_tm->tm_mday == day) - && ( ((event_tm->tm_hour == hour)&&(!t.is_date)) || ((hour<0)&&(t.is_date)) ) - ) { + q = icalcomponent_get_first_property(Cal->cal, ICAL_DTSTART_PROPERTY); + if (q != NULL) { + t = icalproperty_get_dtstart(q); + event_tt = icaltime_as_timet(t); + localtime_r(&event_tt, &event_te); + } + else { + memset(&t, 0, sizeof t); + } + 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); + } + if (t.is_date) all_day_event = 1; + if (all_day_event) + { + show_event = ((t.year == year) && (t.month == month) && (t.day == day) && (notime_events)); + } + else + { + show_event = ical_ctdl_is_overlap(t, end_t, today_start_t, today_end_t); + } - p = icalcomponent_get_first_property( - WC->disp_cal[i].cal, - ICAL_SUMMARY_PROPERTY); - if (p != NULL) { + /* If we determined that this event occurs today, then display it. + */ + p = icalcomponent_get_first_property(Cal->cal,ICAL_SUMMARY_PROPERTY); + + if ((show_event) && (p != NULL)) { + + if ((event_te.tm_mday != day) || (event_tm.tm_mday != day)) ongoing_event = 1; + + if (all_day_event && notime_events) + { + wprintf("
  • " + "unread)?"_unread":"_read", + Cal->cal_msgnum, year, month, day); + wprintf("%s
    ", _("All day event")); + wprintf("%s: %s
    ", _("From"), Cal->from); + wprintf("%s ", _("Summary:")); + escputs((char *) icalproperty_get_comment(p)); + wprintf("
    "); + q = icalcomponent_get_first_property(Cal->cal,ICAL_LOCATION_PROPERTY); + if (q) { + wprintf("%s ", _("Location:")); + escputs((char *)icalproperty_get_comment(q)); + wprintf("
    "); + } + 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); + q = icalcomponent_get_first_property(Cal->cal,ICAL_DESCRIPTION_PROPERTY); + if (q) { + wprintf("%s ", _("Notes:")); + escputs((char *)icalproperty_get_comment(q)); + wprintf("
    "); + } + wprintf("\">"); + escputs((char *) icalproperty_get_comment(p)); + wprintf("
    ("); + wprintf(_("All day event")); + wprintf(")
  • \n"); + } + else if (ongoing_event && notime_events) + { + wprintf("
  • " + "unread)?"_unread":"_read", + Cal->cal_msgnum, year, month, day); + wprintf("%s
    ", _("Ongoing event")); + wprintf("%s: %s
    ", _("From"), Cal->from); + wprintf("%s ", _("Summary:")); + escputs((char *) icalproperty_get_comment(p)); + wprintf("
    "); + q = icalcomponent_get_first_property(Cal->cal,ICAL_LOCATION_PROPERTY); + if (q) { + wprintf("%s ", _("Location:")); + escputs((char *)icalproperty_get_comment(q)); + wprintf("
    "); + } + webcit_fmt_date(buf, event_tt, 1); + wprintf("%s %s
    ", _("Starting date/time:"), buf); + webcit_fmt_date(buf, event_tte, 1); + wprintf("%s %s
    ", _("Ending date/time:"), buf); + q = icalcomponent_get_first_property(Cal->cal,ICAL_DESCRIPTION_PROPERTY); + if (q) { + wprintf("%s ", _("Notes:")); + escputs((char *)icalproperty_get_comment(q)); + wprintf("
    "); + } + wprintf("\">"); + escputs((char *) icalproperty_get_comment(p)); + wprintf("
    ("); + wprintf(_("Ongoing event")); + wprintf(")
  • \n"); + } + else if (!all_day_event && !notime_events) + { + gap++; - if (all_day_event) { - wprintf("" - "
    " - ); - } + if (event_te.tm_mday != day) event_te.tm_hour = 0; + if (event_tm.tm_mday != day) event_tm.tm_hour = 24; - wprintf("" - "", - WC->disp_cal[i].cal_msgnum, - year, month, day - ); - escputs((char *) - icalproperty_get_comment(p)); - wprintf("
    \n"); + /* Calculate the location of the top of the box */ + if (event_te.tm_hour < dstart) { + startmin = diffmin = event_te.tm_min / 6; + top = (event_te.tm_hour * 10) + startmin; + } + else if ((event_te.tm_hour >= dstart) && (event_te.tm_hour <= dend)) { + startmin = diffmin = (event_te.tm_min / 2); + top = (dstart * 10) + ((event_te.tm_hour - dstart) * 30) + startmin; + } + else if (event_te.tm_hour >dend) { + startmin = diffmin = event_te.tm_min / 6; + top = (dstart * 10) + ((dend - dstart - 1) * 30) + ((event_tm.tm_hour - dend + 1) * 10) + startmin ; + } + else { + /* should never get here */ + } - if (all_day_event) { - wprintf("
    "); - } + /* 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 * 10) + endmin; + } + else if ((event_tm.tm_hour >= dstart) && (event_tm.tm_hour <= dend)) { + endmin = diffmin = (event_tm.tm_min / 2); + bottom = (dstart * 10) + ((event_tm.tm_hour - dstart) * 30) + endmin ; + } + else if (event_tm.tm_hour >dend) { + endmin = diffmin = event_tm.tm_min / 6; + bottom = (dstart * 10) + ((dend - dstart + 1) * 30) + ((event_tm.tm_hour - dend - 1) * 10) + endmin; + } + else { + /* should never get here */ } + wprintf("
    ", + (Cal->unread)?"_unread":"_read", + top, (gap * 40), (bottom-top) + ); + wprintf("cal_msgnum, year, month, day, t.hour); + wprintf("%s: %s
    ", _("From"), Cal->from); + wprintf("%s ", _("Summary:")); + escputs((char *) icalproperty_get_comment(p)); + wprintf("
    "); + q = icalcomponent_get_first_property(Cal->cal,ICAL_LOCATION_PROPERTY); + if (q) { + wprintf("%s ", _("Location:")); + escputs((char *)icalproperty_get_comment(q)); + wprintf("
    "); + } + webcit_fmt_date(buf, event_tt, 1); + wprintf("%s %s
    ", _("Starting date/time:"), buf); + webcit_fmt_date(buf, event_tte, 1); + wprintf("%s %s
    ", _("Ending date/time:"), buf); + q = icalcomponent_get_first_property(Cal->cal,ICAL_DESCRIPTION_PROPERTY); + if (q) { + wprintf("%s ", _("Notes:")); + escputs((char *)icalproperty_get_comment(q)); + wprintf("
    "); + } + wprintf("\">"); + + escputs((char *) icalproperty_get_comment(p)); + wprintf("
    \n"); } - - } } } - - +/** + * \brief view one day + * \param year the year + * \param month the month + * \param day the day we want to display + */ void calendar_day_view(int year, int month, int day) { int hour; struct icaltimetype today, yesterday, tomorrow; - - - /* Figure out the dates for "yesterday" and "tomorrow" links */ + int daystart = 8; + int dayend = 17; + char daystart_str[16], dayend_str[16]; + struct tm d_tm; + char d_str[128]; + int time_format; + time_t today_t; + int timeline = 30; + int extratimeline = 0; + int gap = 0; + + 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 */ + 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 */ memset(&today, 0, sizeof(struct icaltimetype)); today.year = year; @@ -333,125 +1083,174 @@ void calendar_day_view(int year, int month, int day) { ++tomorrow.day; tomorrow = icaltime_normalize(tomorrow); + wprintf("
    "); - /* Outer table (to get the background color) */ - wprintf("
    " - ""); /** end stuff-on-the-right */ + wprintf("
    \n"); - - /* Inner table (the real one) */ - wprintf("\n"); - - /* Innermost table (contains hours etc.) */ - wprintf("
    " - "\n"); - - /* Display events before 8:00 (hour=-1 is all-day events) */ - wprintf("" - "" - "\n"); - - /* Now the middle of the day... */ - for (hour = 8; hour <= 17; ++hour) { /* could do HEIGHT=xx */ - wprintf("" - ); - - wprintf("
    "); - for (hour = (-1); hour <= 7; ++hour) { - calendar_day_view_display_events(year, month, day, hour); - } - wprintf("
    "); - wprintf("", - year, month, day, hour - ); - wprintf("%d:00%s ", - (hour <= 12 ? hour : hour-12), - (hour < 12 ? "am" : "pm") - ); - wprintf(""); - - /* put the data here, stupid */ - calendar_day_view_display_events(year, month, day, hour); + /** Inner table (the real one) */ + wprintf(" \n"); - wprintf("\n"); - } + /** Innermost cell (contains hours etc.) */ + wprintf("" - "" - "\n"); + /** Now the middle of the day... */ + extratimeline = timeline / 3; - wprintf("
    "); + wprintf("
    "); - /* Display events after 5:00... */ - wprintf("
    "); - for (hour = 18; hour <= 23; ++hour) { - calendar_day_view_display_events(year, month, day, hour); - } - wprintf("
    " /* end of innermost table */ - "
    "); /* begin stuff-on-the-right */ + for (hour = 0; hour < daystart; ++hour) { /* could do HEIGHT=xx */ + wprintf("
    " + "", + (hour * extratimeline ), extratimeline, + year, month, day, hour + ); + if (time_format == WC_TIMEFORMAT_24) { + wprintf("%2d:00 ", hour); + } + else { + wprintf("%d:00%s ", + (hour <= 12 ? hour : hour-12), + (hour < 12 ? "am" : "pm") + ); + } - /* Begin todays-date-with-left-and-right-arrows */ - wprintf("\n"); - wprintf(""); + wprintf(""); + } - /* Left arrow */ - wprintf(""); /* end of innermost table */ + + /** Display extra events (start/end times not present or not today) in the middle column */ + wprintf(""); /** end extra on the middle */ + + wprintf(""); + + wc_strftime(d_str, sizeof d_str, + "", + &d_tm ); + wprintf("%s", d_str); - wprintf("" - "Back to month view\n", year, month); - - wprintf("\n"); - - wprintf(""); /* end stuff-on-the-right */ + /** Right arrow */ + wprintf(""); + wprintf("
    "); - wprintf("", + gap = daystart * extratimeline; + + for (hour = daystart; hour <= dayend; ++hour) { /* could do HEIGHT=xx */ + wprintf("
    " + "", + gap + ((hour - daystart) * timeline ), timeline, + year, month, day, hour + ); + + if (time_format == WC_TIMEFORMAT_24) { + wprintf("%2d:00 ", hour); + } + else { + wprintf("%d:00%s ", + (hour <= 12 ? hour : hour-12), + (hour < 12 ? "am" : "pm") + ); + } + + wprintf("
    "); + } + + gap = gap + ((dayend - daystart + 1) * timeline); + + for (hour = (dayend + 1); hour < 24; ++hour) { /* could do HEIGHT=xx */ + wprintf("
    " + "", + gap + ((hour - dayend - 1) * extratimeline ), extratimeline, + year, month, day, hour + ); + + if (time_format == WC_TIMEFORMAT_24) { + wprintf("%2d:00 ", hour); + } + else { + wprintf("%d:00%s ", + (hour <= 12 ? hour : hour-12), + (hour < 12 ? "am" : "pm") + ); + } + + wprintf("
    "); + } + + /* Display events with start and end times on this day */ + calendar_day_view_display_events(today_t, year, month, day, 0, daystart, dayend); + + wprintf(""); + wprintf("
    "); + + wprintf("
      "); + + /** Display all-day events */ + calendar_day_view_display_events(today_t, year, month, day, 1, daystart, dayend); + + wprintf("
    "); + + wprintf("
    "); /** begin stuff-on-the-right */ + + /** Begin todays-date-with-left-and-right-arrows */ + wprintf("\n"); + wprintf(""); + + /** Left arrow */ + wprintf(""); - - /* Today's date */ - wprintf(""); - - /* Right arrow */ - wprintf(""); - - wprintf("
    "); + wprintf("", yesterday.year, yesterday.month, yesterday.day); - wprintf(""); - wprintf(""); - wprintf("%s
    " - "%d
    " - "%d
    ", - months[month-1], day, year); - wprintf("
    "); - wprintf("", - tomorrow.year, tomorrow.month, tomorrow.day); - wprintf("\n"); - wprintf("
    \n"); - /* End todays-date-with-left-and-right-arrows */ - - wprintf("

    " - " " - "Add new calendar event" - "

    \n", - year, month, day + wprintf(""); + wprintf("
    " + "%B
    " + "%d
    " + "%Y
    " + "
    "); + wprintf("", + 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("
    " /* end of inner table */ - "
    " /* end of outer table */ - ); + wprintf("\n"); + wprintf("
    " /** end of inner table */ + "
    "); + wprintf("\n" + ); } -/* - * Display today's events. + +/** + * \brief Display today's events. */ void calendar_summary_view(void) { int i; @@ -477,7 +1276,12 @@ void calendar_summary_view(void) { if (p != NULL) { t = icalproperty_get_dtstart(p); event_tt = icaltime_as_timet(t); - if (t.is_date) all_day_event = 1; + if (t.is_date) { + all_day_event = 1; + } + else { + all_day_event = 0; + } fmt_time(timestring, event_tt); if (all_day_event) { @@ -508,7 +1312,10 @@ void calendar_summary_view(void) { } - +/** + * \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) { @@ -521,34 +1328,37 @@ void free_calendar_buffer(void) { - +/** + * \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]; - /* 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 (strlen(bstr("year")) > 0) year = atoi(bstr("year")); - if (strlen(bstr("month")) > 0) month = atoi(bstr("month")); - if (strlen(bstr("day")) > 0) day = atoi(bstr("day")); + /** Now see if a date was specified */ + if (havebstr("year")) year = ibstr("year"); + if (havebstr("month")) month = ibstr("month"); + if (havebstr("day")) day = ibstr("day"); - /* How would you like that cooked? */ - if (strlen(bstr("calview")) > 0) { + /** How would you like that cooked? */ + if (havebstr("calview")) { strcpy(calview, bstr("calview")); } else { strcpy(calview, "month"); } - /* Display the selected view */ + /** Display the selected view */ if (!strcasecmp(calview, "day")) { calendar_day_view(year, month, day); } @@ -556,17 +1366,25 @@ void do_calendar_view(void) { calendar_week_view(year, month, day); } else { - calendar_month_view(year, month, day); + if (WC->wc_view == VIEW_CALBRIEF) { + calendar_brief_month_view(year, month, day); + } + else { + calendar_month_view(year, month, day); + } } - /* Free the calendar stuff */ + /** Free the calendar stuff */ free_calendar_buffer(); } -/* - * Helper function for do_tasks_view(). Returns the date/time due. +/** + * \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; @@ -575,7 +1393,8 @@ time_t get_task_due_date(icalcomponent *vtodo) { return(0L); } - /* If we're looking at a fully encapsulated VCALENDAR + /** + * If we're looking at a fully encapsulated VCALENDAR * rather than a VTODO component, recurse into the data * structure until we get a VTODO. */ @@ -597,8 +1416,10 @@ time_t get_task_due_date(icalcomponent *vtodo) { } -/* - * Compare the due dates of two tasks (this is for sorting) +/** + * \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; @@ -615,7 +1436,9 @@ int task_due_cmp(const void *task1, const void *task2) { - +/** + * \brief do the whole task view stuff + */ void do_tasks_view(void) { int i; time_t due; @@ -623,12 +1446,16 @@ void do_tasks_view(void) { char buf[SIZ]; icalproperty *p; - wprintf("
    \n\n" - "\n" - "\n" + wprintf("
    " + "
    Name of taskDate due
    \n\n" + "\n" ); - /* Sort them if necessary */ + /** Sort them if necessary */ if (WC->num_cal > 1) { qsort(WC->disp_cal, WC->num_cal, @@ -640,36 +1467,37 @@ void do_tasks_view(void) { if (WC->num_cal) for (i=0; i<(WC->num_cal); ++i) { bg = 1 - bg; - wprintf("\n"); + wprintf("\n"); + wprintf("\n"); due = get_task_due_date(WC->disp_cal[i].cal); - fmt_date(buf, due); - wprintf("\n", buf); + wprintf(">%s\n", buf); } - wprintf("
    "); + wprintf(_("Name of task")); + wprintf(""); + wprintf(_("Date due")); + wprintf("
    ", + 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)); } - wprintf("\n"); - wprintf("%s
    \n"); + wprintf("\n"); - /* Free the list */ + /** Free the list */ free_calendar_buffer(); } -#endif /* WEBCIT_WITH_CALENDAR_SERVICE */