]> code.citadel.org Git - citadel.git/blobdiff - webcit/event.c
* split tasks view into its own file
[citadel.git] / webcit / event.c
index fb72422d0408ee9e0951a13e4051285d7c6833fa..d1c7bbc6be69b444398b3f5d1120dccf0cf3c9c8 100644 (file)
@@ -6,6 +6,7 @@
 
 #include "webcit.h"
 #include "webserver.h"
+#include "calendar.h"
 
 /*
  * Display an event by itself (for editing)
@@ -13,7 +14,7 @@
  * msgnum              reference on the citserver
  */
 void display_edit_individual_event(icalcomponent *supplied_vevent, long msgnum, char *from,
-       int unread, struct calview *calv)
+       int unread, calview *calv)
 {
        icalcomponent *vevent;
        icalproperty *p;
@@ -33,6 +34,13 @@ void display_edit_individual_event(icalcomponent *supplied_vevent, long msgnum,
        char weekday_labels[7][32];
        char month_labels[12][32];
        long weekstart = 0;
+       icalproperty *rrule = NULL;
+       struct icalrecurrencetype recur;
+
+       char *tabnames[3];
+       tabnames[0] = _("Event");
+       tabnames[1] = _("Attendees");
+       tabnames[2] = _("Recurrence");
 
        get_pref_long("weekstart", &weekstart, 17);
        if (weekstart > 6) weekstart = 0;
@@ -71,6 +79,10 @@ void display_edit_individual_event(icalcomponent *supplied_vevent, long msgnum,
 
        if (supplied_vevent != NULL) {
                vevent = supplied_vevent;
+
+               /* Convert all timestamps to UTC to make them easier to process. */
+               ical_dezonify(vevent);
+
                /*
                 * If we're looking at a fully encapsulated VCALENDAR
                 * rather than a VEVENT component, attempt to use the first
@@ -122,7 +134,7 @@ void display_edit_individual_event(icalcomponent *supplied_vevent, long msgnum,
        wprintf("SEQUENCE == %d<br />\n", sequence);
        *************************************************************/
 
-       wprintf("<FORM NAME=\"EventForm\" METHOD=\"POST\" action=\"save_event\">\n");
+       wprintf("<form name=\"EventForm\" method=\"POST\" action=\"save_event\">\n");
        wprintf("<input type=\"hidden\" name=\"nonce\" value=\"%d\">\n", WC->nonce);
 
        wprintf("<INPUT TYPE=\"hidden\" NAME=\"msgnum\" VALUE=\"%ld\">\n",
@@ -136,11 +148,6 @@ void display_edit_individual_event(icalcomponent *supplied_vevent, long msgnum,
        wprintf("<INPUT TYPE=\"hidden\" NAME=\"day\" VALUE=\"%s\">\n",
                bstr("day"));
 
-       char *tabnames[] = {
-               _("Event"),
-               _("Attendees"),
-               _("Recurrence")
-       };
 
        tabbed_dialog(3, tabnames);
        begin_tab(0, 3);
@@ -219,34 +226,51 @@ void display_edit_individual_event(icalcomponent *supplied_vevent, long msgnum,
 
        wprintf("</TD></TR>\n");
 
-       /*
-        * If this is an all-day-event, set the end time to be identical to
-        * the start time (the hour/minute/second will be set to midnight).
-        * Otherwise extract or create it.
-        */
        wprintf("<TR><TD><B>");
        wprintf(_("End"));
        wprintf("</B></TD><TD id=\"dtendcell\">\n");
-       if (t_start.is_date) {
-               t_end = t_start;
+       p = icalcomponent_get_first_property(vevent,
+                                               ICAL_DTEND_PROPERTY);
+       if (p != NULL) {
+               t_end = icalproperty_get_dtend(p);
+               
+               /*
+                * If this is an all-day-event, the end time is set to real end
+                * day + 1, so we have to adjust accordingly. 
+                */
+               if (t_start.is_date) {
+                       icaltime_adjust(&t_end, -1, 0, 0, 0);
+               }
        }
        else {
-               p = icalcomponent_get_first_property(vevent,
-                                                       ICAL_DTEND_PROPERTY);
-               if (p != NULL) {
-                       t_end = icalproperty_get_dtend(p);
+               if (created_new_vevent == 1) {
+                       /* set default duration */
+                       if (t_start.is_date) {
+                               /*
+                                * If this is an all-day-event, set the end time to be identical to
+                                * the start time (the hour/minute/second will be set to midnight).
+                                */
+                               t_end = t_start;
+                       }
+                       else {
+                               /*
+                                * If this is not an all-day event and there is no
+                                * end time specified, make the default one hour
+                                * from the start time.
+                                */
+                               t_end = t_start;
+                               t_end.hour += 1;
+                               t_end.second = 0;
+                               t_end = icaltime_normalize(t_end);
+                               /* t_end = icaltime_from_timet(now, 0); */
+                       }
                }
                else {
                        /*
-                        * If this is not an all-day event and there is no
-                        * end time specified, make the default one hour
-                        * from the start time.
+                        * If an existing event has no end date/time this is
+                        * supposed to mean end = start.
                         */
                        t_end = t_start;
-                       t_end.hour += 1;
-                       t_end.second = 0;
-                       t_end = icaltime_normalize(t_end);
-                       /* t_end = icaltime_from_timet(now, 0); */
                }
        }
        display_icaltimetype_as_webform(&t_end, "dtend", 0);
@@ -256,7 +280,7 @@ void display_edit_individual_event(icalcomponent *supplied_vevent, long msgnum,
        wprintf(_("Notes"));
        wprintf("</B></TD><TD>\n"
                "<TEXTAREA NAME=\"description\" wrap=soft "
-               "ROWS=5 COLS=80 WIDTH=80>\n"
+               "ROWS=5 COLS=72 WIDTH=72>\n"
        );
        p = icalcomponent_get_first_property(vevent, ICAL_DESCRIPTION_PROPERTY);
        if (p != NULL) {
@@ -270,7 +294,7 @@ void display_edit_individual_event(icalcomponent *supplied_vevent, long msgnum,
         */
        if (icalcomponent_get_first_property(vevent, ICAL_ORGANIZER_PROPERTY)
           == NULL) {
-               sprintf(organizer_string, "MAILTO:%s", WC->cs_inet_email);
+               sprintf(organizer_string, "MAILTO:%s", ChrPtr(WC->cs_inet_email));
                icalcomponent_add_property(vevent,
                        icalproperty_new_organizer(organizer_string)
                );
@@ -382,7 +406,9 @@ void display_edit_individual_event(icalcomponent *supplied_vevent, long msgnum,
 
        wprintf("</TD><TD>"
                "<TEXTAREA %s NAME=\"attendees\" id=\"attendees_box\" wrap=soft "
-               "ROWS=3 COLS=80 WIDTH=80>\n",
+               "onchange=\"EnableOrDisableCheckButton();\" "
+               "onKeyPress=\"EnableOrDisableCheckButton();\" "
+               "ROWS=10 COLS=72 WIDTH=72>\n",
                (organizer_is_me ? "" : "DISABLED ")
        );
        i = 0;
@@ -410,8 +436,6 @@ void display_edit_individual_event(icalcomponent *supplied_vevent, long msgnum,
 
        /* Recurrence tab */
        begin_tab(2, 3);
-       icalproperty *rrule = NULL;
-       struct icalrecurrencetype recur;
 
        rrule = icalcomponent_get_first_property(vevent, ICAL_RRULE_PROPERTY);
        if (rrule) {
@@ -582,13 +606,14 @@ void display_edit_individual_event(icalcomponent *supplied_vevent, long msgnum,
        int rrymweek = rrmweek;
        int rrymweekday = rrmweekday;
        int rrymonth = t_start.month;
-
-       lprintf(9, "FIXME: RRYMWEEK %d, RRYMWEEKDAY %d, RRYMONTH %d\n", rrymweek, rrymweekday, rrymonth);
-
        int which_rryeartype_is_preselected = 0;
 
-       if ( (recur.by_day[0] != ICAL_RECURRENCE_ARRAY_MAX) 
-          && (recur.by_month[0] != ICAL_RECURRENCE_ARRAY_MAX) ) {
+       if (
+               (recur.by_day[0] != ICAL_RECURRENCE_ARRAY_MAX) 
+               && (recur.by_day[0] != 0) 
+               && (recur.by_month[0] != ICAL_RECURRENCE_ARRAY_MAX)
+               && (recur.by_month[0] != 0)
+       ) {
                which_rryeartype_is_preselected = 1;
                rrymweek = icalrecurrencetype_day_position(recur.by_day[0]);
                rrymweekday = icalrecurrencetype_day_day_of_week(recur.by_day[0]) - 1;
@@ -707,8 +732,7 @@ void display_edit_individual_event(icalcomponent *supplied_vevent, long msgnum,
                "&nbsp;&nbsp;"
                "<INPUT TYPE=\"submit\" NAME=\"delete_button\" VALUE=\"%s\">\n"
                "&nbsp;&nbsp;"
-               "<INPUT TYPE=\"submit\" NAME=\"check_button\" "
-                               "VALUE=\"%s\">\n"
+               "<INPUT TYPE=\"submit\" id=\"check_button\" NAME=\"check_button\" VALUE=\"%s\">\n"
                "&nbsp;&nbsp;"
                "<INPUT TYPE=\"submit\" NAME=\"cancel_button\" VALUE=\"%s\">\n"
                "</CENTER>\n",
@@ -723,8 +747,9 @@ void display_edit_individual_event(icalcomponent *supplied_vevent, long msgnum,
        wprintf("</div>\n");                    /* end 'fix_scrollbar_bug' div */
 
        StrBufAppendPrintf(WC->trailing_javascript,
-               "eventEditAllDay();     \n"
-               "RecurrenceShowHide();  \n"
+               "eventEditAllDay();             \n"
+               "RecurrenceShowHide();          \n"
+               "EnableOrDisableCheckButton();  \n"
        );
        address_book_popup();
        wDumpContent(1);
@@ -741,7 +766,7 @@ void display_edit_individual_event(icalcomponent *supplied_vevent, long msgnum,
  * msgnum:             the index on the citserver
  */
 void save_individual_event(icalcomponent *supplied_vevent, long msgnum, char *from,
-                       int unread, struct calview *calv) {
+                       int unread, calview *calv) {
        char buf[SIZ];
        icalproperty *prop;
        icalcomponent *vevent, *encaps;
@@ -759,6 +784,10 @@ void save_individual_event(icalcomponent *supplied_vevent, long msgnum, char *fr
 
        if (supplied_vevent != NULL) {
                vevent = supplied_vevent;
+
+               /* Convert all timestamps to UTC to make them easier to process. */
+               ical_dezonify(vevent);
+
                /*
                 * If we're looking at a fully encapsulated VCALENDAR
                 * rather than a VEVENT component, attempt to use the first
@@ -792,13 +821,17 @@ void save_individual_event(icalcomponent *supplied_vevent, long msgnum, char *fr
                        icalproperty_free(prop);
                }
 
+               /* Add NOW() to the calendar object... */
+               icalcomponent_set_dtstamp(vevent, 
+                                         icaltime_from_timet(
+                                                 time(NULL), 0));
+
                if (havebstr("summary")) {
-       
                        icalcomponent_add_property(vevent,
                                        icalproperty_new_summary(bstr("summary")));
                } else {
                        icalcomponent_add_property(vevent,
-                                       icalproperty_new_summary("Untitled Event"));
+                                       icalproperty_new_summary(_("Untitled Event")));
                }
        
                while (prop = icalcomponent_get_first_property(vevent,
@@ -840,16 +873,10 @@ void save_individual_event(icalcomponent *supplied_vevent, long msgnum, char *fr
                        icaltime_from_webform(&event_start, "dtstart");
                }
 
-               /*
-                * The following odd-looking snippet of code looks like it
-                * takes some unnecessary steps.  It is done this way because
-                * libical incorrectly turns an "all day event" into a normal
-                * event starting at midnight (i.e. it serializes as date/time
-                * instead of just date) unless icalvalue_new_date() is used.
-                * So we force it, if this is an all day event.
-                */
                prop = icalproperty_new_dtstart(event_start);
+
                if (all_day_event) {
+                       /* Force it to serialize as a date-only rather than date/time */
                        icalproperty_set_value(prop, icalvalue_new_date(event_start));
                }
 
@@ -867,14 +894,21 @@ void save_individual_event(icalcomponent *supplied_vevent, long msgnum, char *fr
                        icalproperty_free(prop);
                }
 
-               if (all_day_event == 0) {
+               if (all_day_event) {
+                       icaltime_from_webform_dateonly(&t, "dtend");    
+
+                       /* with this field supposed to be non-inclusive we have to add one day */
+                       icaltime_adjust(&t, 1, 0, 0, 0);
+               }
+               else {
                        icaltime_from_webform(&t, "dtend");     
-                       icalcomponent_add_property(vevent,
-                               icalproperty_new_dtend(icaltime_normalize(t)
-                               )
-                       );
                }
 
+               icalcomponent_add_property(vevent,
+                       icalproperty_new_dtend(icaltime_normalize(t)
+                       )
+               );
+
                /* recurrence rules -- begin */
 
                /* remove any existing rule */
@@ -1019,7 +1053,7 @@ void save_individual_event(icalcomponent *supplied_vevent, long msgnum, char *fr
 
                /* First, strip out the parenthesized partstats.  */
                strcpy(form_attendees, bstr("attendees"));
-               stripout(form_attendees, '(', ')');
+               while ( stripout(form_attendees, '(', ')') != 0);
 
                /* Next, change any commas to newlines, because we want newline-separated attendees. */
                j = strlen(form_attendees);
@@ -1142,8 +1176,13 @@ STARTOVER:       for (attendee = icalcomponent_get_first_property(vevent, ICAL_ATTENDE
                icalcomponent_free(vevent);
        }
 
-       /* If this was a save or delete, go back to the calendar view. */
+       /* If this was a save or delete, go back to the calendar or summary view. */
        if (!havebstr("check_button")) {
-               readloop("readfwd");
+               if (!strcasecmp(bstr("calview"), "summary")) {
+                       summary();
+               }
+               else {
+                       readloop(readfwd);
+               }
        }
 }