Back to index

webcit  8.12-dfsg
event.c
Go to the documentation of this file.
00001 /*
00002  * Editing calendar events.
00003  *
00004  * Copyright (c) 1996-2012 by the citadel.org team
00005  *
00006  * This program is open source software.  You can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License, version 3.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  */
00014 
00015 #include "webcit.h"
00016 #include "webserver.h"
00017 #include "calendar.h"
00018 
00019 /*
00020  * Display an event by itself (for editing)
00021  * supplied_vevent   the event to edit
00022  * msgnum            reference on the citserver
00023  */
00024 void display_edit_individual_event(icalcomponent *supplied_vevent, long msgnum, char *from,
00025        int unread, calview *calv)
00026 {
00027        icalcomponent *vevent;
00028        icalproperty *p;
00029        icalvalue *v;
00030        struct icaltimetype t_start, t_end;
00031        time_t now;
00032        struct tm tm_now;
00033        int created_new_vevent = 0;
00034        icalproperty *organizer = NULL;
00035        char organizer_string[SIZ];
00036        icalproperty *attendee = NULL;
00037        char attendee_string[SIZ];
00038        char buf[SIZ];
00039        int organizer_is_me = 0;
00040        int i, j = 0;
00041        /************************************************************
00042         * Uncomment this to see the UID in calendar events for debugging
00043        int sequence = 0;
00044        */
00045        char weekday_labels[7][32];
00046        char month_labels[12][32];
00047        long weekstart = 0;
00048        icalproperty *rrule = NULL;
00049        struct icalrecurrencetype recur;
00050        char weekday_is_selected[7];
00051        int which_rrmonthtype_is_preselected = 0;
00052 
00053        int rrmday;
00054        int rrmweekday;
00055 
00056        icaltimetype day1;
00057        int weekbase;
00058        int rrmweek;
00059        int rrymweek;
00060        int rrymweekday;
00061        int rrymonth;
00062        int which_rrend_is_preselected;
00063        int which_rryeartype_is_preselected;
00064 
00065        const char *ch;
00066        char *tabnames[3];
00067        const char *frequency_units[8];
00068        const char *ordinals[6];
00069 
00070        frequency_units[0] = _("seconds");
00071        frequency_units[1] = _("minutes");
00072        frequency_units[2] = _("hours");
00073        frequency_units[3] = _("days");
00074        frequency_units[4] = _("weeks");
00075        frequency_units[5] = _("months");
00076        frequency_units[6] = _("years");
00077        frequency_units[7] = _("never");
00078 
00079 
00080        ordinals[0] = "0";
00081        ordinals[1] = _("first");
00082        ordinals[2] = _("second");
00083        ordinals[3] = _("third");
00084        ordinals[4] = _("fourth");
00085        ordinals[5] = _("fifth");
00086 
00087 
00088        tabnames[0] = _("Event");
00089        tabnames[1] = _("Attendees");
00090        tabnames[2] = _("Recurrence");
00091 
00092        get_pref_long("weekstart", &weekstart, 17);
00093        if (weekstart > 6) weekstart = 0;
00094 
00095        syslog(9, "display_edit_individual_event(%ld) calview=%s year=%s month=%s day=%s\n",
00096               msgnum, bstr("calview"), bstr("year"), bstr("month"), bstr("day")
00097        );
00098 
00099        /* populate the weekday names - begin */
00100        now = time(NULL);
00101        localtime_r(&now, &tm_now);
00102        while (tm_now.tm_wday != 0) {
00103               now -= 86400L;
00104               localtime_r(&now, &tm_now);
00105        }
00106        for (i=0; i<7; ++i) {
00107               localtime_r(&now, &tm_now);
00108               wc_strftime(weekday_labels[i], 32, "%A", &tm_now);
00109               now += 86400L;
00110        }
00111        /* populate the weekday names - end */
00112 
00113        /* populate the month names - begin */
00114        now = 259200L;       /* 1970-jan-04 is the first Sunday ever */
00115        localtime_r(&now, &tm_now);
00116        for (i=0; i<12; ++i) {
00117               localtime_r(&now, &tm_now);
00118               wc_strftime(month_labels[i], 32, "%B", &tm_now);
00119               now += 2678400L;
00120        }
00121        /* populate the month names - end */
00122 
00123        now = time(NULL);
00124        strcpy(organizer_string, "");
00125        strcpy(attendee_string, "");
00126 
00127        if (supplied_vevent != NULL) {
00128               vevent = supplied_vevent;
00129 
00130               /* Convert all timestamps to UTC to make them easier to process. */
00131               ical_dezonify(vevent);
00132 
00133               /*
00134                * If we're looking at a fully encapsulated VCALENDAR
00135                * rather than a VEVENT component, attempt to use the first
00136                * relevant VEVENT subcomponent.  If there is none, the
00137                * NULL returned by icalcomponent_get_first_component() will
00138                * tell the next iteration of this function to create a
00139                * new one.
00140                */
00141               if (icalcomponent_isa(vevent) == ICAL_VCALENDAR_COMPONENT) {
00142                      display_edit_individual_event(
00143                             icalcomponent_get_first_component(
00144                                    vevent, ICAL_VEVENT_COMPONENT), 
00145                             msgnum, from, unread, NULL
00146                      );
00147                      return;
00148               }
00149        }
00150        else {
00151               vevent = icalcomponent_new(ICAL_VEVENT_COMPONENT);
00152               created_new_vevent = 1;
00153        }
00154 
00155        /* Learn the sequence */
00156        p = icalcomponent_get_first_property(vevent, ICAL_SEQUENCE_PROPERTY);
00157        /************************************************************
00158         * Uncomment this to see the UID in calendar events for debugging
00159        if (p != NULL) {
00160               sequence = icalproperty_get_sequence(p);
00161        }
00162        */
00163        /* Begin output */
00164        output_headers(1, 1, 1, 0, 0, 0);
00165        wc_printf("<div id=\"room_banner_override\">\n");
00166        wc_printf("<h1>");
00167        wc_printf(_("Add or edit an event"));
00168        wc_printf("</h1>");
00169        wc_printf("</div>\n");
00170 
00171        wc_printf("<div id=\"content\" class=\"service\">\n");
00172 
00173        /************************************************************
00174         * Uncomment this to see the UID in calendar events for debugging
00175        wc_printf("UID == ");
00176        p = icalcomponent_get_first_property(vevent, ICAL_UID_PROPERTY);
00177        if (p != NULL) {
00178               escputs((char *)icalproperty_get_comment(p));
00179        }
00180        wc_printf("<br>\n");
00181        wc_printf("SEQUENCE == %d<br>\n", sequence);
00182        *************************************************************/
00183 
00184        wc_printf("<form name=\"EventForm\" method=\"POST\" action=\"save_event\">\n");
00185        wc_printf("<input type=\"hidden\" name=\"nonce\" value=\"%d\">\n", WC->nonce);
00186 
00187        wc_printf("<input type=\"hidden\" name=\"msgnum\" value=\"%ld\">\n",
00188               msgnum);
00189        wc_printf("<input type=\"hidden\" name=\"calview\" value=\"%s\">\n",
00190               bstr("calview"));
00191        wc_printf("<input type=\"hidden\" name=\"year\" value=\"%s\">\n",
00192               bstr("year"));
00193        wc_printf("<input type=\"hidden\" name=\"month\" value=\"%s\">\n",
00194               bstr("month"));
00195        wc_printf("<input type=\"hidden\" name=\"day\" value=\"%s\">\n",
00196               bstr("day"));
00197 
00198 
00199        tabbed_dialog(3, tabnames);
00200        begin_tab(0, 3);
00201 
00202        /* Put it in a borderless table so it lines up nicely */
00203        wc_printf("<table border='0' width='100%%'>\n");
00204 
00205        wc_printf("<tr><td><b>");
00206        wc_printf(_("Summary"));
00207        wc_printf("</b></td><td>\n"
00208               "<input type=\"text\" name=\"summary\" "
00209               "maxlength=\"64\" size=\"64\" value=\"");
00210        p = icalcomponent_get_first_property(vevent, ICAL_SUMMARY_PROPERTY);
00211        if (p != NULL) {
00212               escputs((char *)icalproperty_get_comment(p));
00213        }
00214        wc_printf("\"></td></tr>\n");
00215 
00216        wc_printf("<tr><td><b>");
00217        wc_printf(_("Location"));
00218        wc_printf("</b></td><td>\n"
00219               "<input type=\"text\" name=\"location\" "
00220               "maxlength=\"64\" size=\"64\" value=\"");
00221        p = icalcomponent_get_first_property(vevent, ICAL_LOCATION_PROPERTY);
00222        if (p != NULL) {
00223               escputs((char *)icalproperty_get_comment(p));
00224        }
00225        wc_printf("\"></td></tr>\n");
00226 
00227        wc_printf("<tr><td><b>");
00228        wc_printf(_("Start"));
00229        wc_printf("</b></td><td>\n");
00230        p = icalcomponent_get_first_property(vevent, ICAL_DTSTART_PROPERTY);
00231        if (p != NULL) {
00232               t_start = icalproperty_get_dtstart(p);
00233               if (t_start.is_date) {
00234                      t_start.hour = 0;
00235                      t_start.minute = 0;
00236                      t_start.second = 0;
00237               }
00238        }
00239        else {
00240               localtime_r(&now, &tm_now);
00241               if (havebstr("year")) {
00242                      tm_now.tm_year = ibstr("year") - 1900;
00243                      tm_now.tm_mon = ibstr("month") - 1;
00244                      tm_now.tm_mday = ibstr("day");
00245               }
00246               if (havebstr("hour")) {
00247                      tm_now.tm_hour = ibstr("hour");
00248                      tm_now.tm_min = ibstr("minute");
00249                      tm_now.tm_sec = 0;
00250               }
00251               else {
00252                      tm_now.tm_hour = 0;
00253                      tm_now.tm_min = 0;
00254                      tm_now.tm_sec = 0;
00255               }
00256 
00257               t_start = icaltime_from_timet_with_zone(
00258                      mktime(&tm_now),
00259                      ((yesbstr("alldayevent")) ? 1 : 0),
00260                      icaltimezone_get_utc_timezone()
00261               );
00262               t_start.is_utc = 1;
00263 
00264        }
00265        display_icaltimetype_as_webform(&t_start, "dtstart", 0);
00266 
00267        wc_printf("<input type=\"checkbox\" id=\"alldayevent\" name=\"alldayevent\" "
00268               "value=\"yes\" onclick=\"eventEditAllDay();\""
00269               " %s >%s",
00270               (t_start.is_date ? "checked=\"checked\"" : "" ),
00271               _("All day event")
00272        );
00273 
00274        wc_printf("</td></tr>\n");
00275 
00276        wc_printf("<tr><td><b>");
00277        wc_printf(_("End"));
00278        wc_printf("</b></td><td id=\"dtendcell\">\n");
00279        p = icalcomponent_get_first_property(vevent,
00280                                           ICAL_DTEND_PROPERTY);
00281        if (p != NULL) {
00282               t_end = icalproperty_get_dtend(p);
00283 
00284               /*
00285                * If this is an all-day-event, the end time is set to real end
00286                * day + 1, so we have to adjust accordingly.
00287                */
00288               if (t_start.is_date) {
00289                      icaltime_adjust(&t_end, -1, 0, 0, 0);
00290               }
00291        }
00292        else {
00293               if (created_new_vevent == 1) {
00294                      /* set default duration */
00295                      if (t_start.is_date) {
00296                             /*
00297                              * If this is an all-day-event, set the end time to be identical to
00298                              * the start time (the hour/minute/second will be set to midnight).
00299                              */
00300                             t_end = t_start;
00301                      }
00302                      else {
00303                             /*
00304                              * If this is not an all-day event and there is no
00305                              * end time specified, make the default one hour
00306                              * from the start time.
00307                              */
00308                             t_end = t_start;
00309                             t_end.hour += 1;
00310                             t_end.second = 0;
00311                             t_end = icaltime_normalize(t_end);
00312                             /* t_end = icaltime_from_timet(now, 0); */
00313                      }
00314               }
00315               else {
00316                      /*
00317                       * If an existing event has no end date/time this is
00318                       * supposed to mean end = start.
00319                       */
00320                      t_end = t_start;
00321               }
00322        }
00323        display_icaltimetype_as_webform(&t_end, "dtend", 0);
00324        wc_printf("</td></tr>\n");
00325 
00326        wc_printf("<tr><td><b>");
00327        wc_printf(_("Notes"));
00328        wc_printf("</b></td><td>\n"
00329               "<textarea name=\"description\" "
00330               "rows='5' cols='72' style='width:72'>\n"
00331        );
00332        p = icalcomponent_get_first_property(vevent, ICAL_DESCRIPTION_PROPERTY);
00333        if (p != NULL) {
00334               escputs((char *)icalproperty_get_comment(p));
00335        }
00336        wc_printf("</textarea></td></tr>");
00337 
00338        /*
00339         * For a new event, the user creating the event should be the
00340         * organizer.  Set this field accordingly.
00341         */
00342        if (icalcomponent_get_first_property(vevent, ICAL_ORGANIZER_PROPERTY)
00343           == NULL) {
00344               sprintf(organizer_string, "mailto:%s", ChrPtr(WC->cs_inet_email));
00345               icalcomponent_add_property(vevent,
00346                      icalproperty_new_organizer(organizer_string)
00347               );
00348        }
00349 
00350        /*
00351         * Determine who is the organizer of this event.
00352         * We need to determine "me" or "not me."
00353         */
00354        organizer = icalcomponent_get_first_property(vevent, ICAL_ORGANIZER_PROPERTY);
00355        if (organizer != NULL) {
00356               strcpy(organizer_string, icalproperty_get_organizer(organizer));
00357               if (!strncasecmp(organizer_string, "mailto:", 7)) {
00358                      strcpy(organizer_string, &organizer_string[7]);
00359                      striplt(organizer_string);
00360                      serv_printf("ISME %s", organizer_string);
00361                      serv_getln(buf, sizeof buf);
00362                      if (buf[0] == '2') {
00363                             organizer_is_me = 1;
00364                      }
00365               }
00366        }
00367 
00368        wc_printf("<tr><td><b>");
00369        wc_printf(_("Organizer"));
00370        wc_printf("</b></td><td>");
00371        escputs(organizer_string);
00372        if (organizer_is_me) {
00373               wc_printf(" <font size='-1'><i>");
00374               wc_printf(_("(you are the organizer)"));
00375               wc_printf("</i></font>\n");
00376        }
00377 
00378        /*
00379         * Transmit the organizer as a hidden field.   We don't want the user
00380         * to be able to change it, but we do want it fed back to the server,
00381         * especially if this is a new event and there is no organizer already
00382         * in the calendar object.
00383         */
00384        wc_printf("<input type=\"hidden\" name=\"organizer\" value=\"");
00385        escputs(organizer_string);
00386        wc_printf("\">");
00387 
00388        wc_printf("</td></tr>\n");
00389 
00390        /* Transparency */
00391        wc_printf("<tr><td><b>");
00392        wc_printf(_("Show time as:"));
00393        wc_printf("</b></td><td>");
00394 
00395        p = icalcomponent_get_first_property(vevent, ICAL_TRANSP_PROPERTY);
00396        if (p == NULL) {
00397               /* No transparency found.  Default to opaque (busy). */
00398               p = icalproperty_new_transp(ICAL_TRANSP_OPAQUE);
00399               if (p != NULL) {
00400                      icalcomponent_add_property(vevent, p);
00401               }
00402        }
00403        if (p != NULL) {
00404               v = icalproperty_get_value(p);
00405        }
00406        else {
00407               v = NULL;
00408        }
00409 
00410        wc_printf("<input type=\"radio\" name=\"transp\" value=\"transparent\"");
00411        if ((v != NULL) && (icalvalue_get_transp(v) == ICAL_TRANSP_TRANSPARENT)) {
00412               wc_printf(" CHECKED");
00413        }
00414        wc_printf(">");
00415        wc_printf(_("Free"));
00416        wc_printf("&nbsp;&nbsp;");
00417 
00418        wc_printf("<input type=\"radio\" name=\"transp\" value=\"opaque\"");
00419        if ((v != NULL) && (icalvalue_get_transp(v) == ICAL_TRANSP_OPAQUE)) {
00420               wc_printf(" CHECKED");
00421        }
00422        wc_printf(">");
00423        wc_printf(_("Busy"));
00424 
00425        wc_printf("</td></tr>\n");
00426 
00427 
00428        /* Done with properties. */
00429        wc_printf("</TABLE>\n");
00430 
00431        end_tab(0, 3);
00432 
00433        /* Attendees tab (need to move things here) */
00434        begin_tab(1, 3);
00435        wc_printf("<table border='0' width='100%%'>\n"); /* same table style as the event tab */
00436        wc_printf("<tr><td><b>");
00437        wc_printf(_("Attendees"));
00438        wc_printf("</b><br>"
00439               "<font size='-2'>");
00440        wc_printf(_("(One per line)"));
00441        wc_printf("</font>\n");
00442 
00443        /* Pop open an address book -- begin */
00444        wc_printf(
00445               "&nbsp;<a href=\"javascript:PopOpenAddressBook('attendees_box|%s');\" "
00446               "title=\"%s\">"
00447               "<img alt='' align='middle' border='0' width='16' height='16' src=\"static/webcit_icons/essen/16x16/contact.png\">"
00448               "</a>",
00449               _("Attendees"),
00450               _("Contacts")
00451        );
00452        /* Pop open an address book -- end */
00453 
00454        wc_printf("</td><td>"
00455               "<textarea %s name=\"attendees\" id=\"attendees_box\" "
00456               "onchange=\"EnableOrDisableCheckButton();\" "
00457               "onKeyPress=\"EnableOrDisableCheckButton();\" "
00458               "rows='10' cols='72' style='width:72'>\n",
00459               (organizer_is_me ? "" : "disabled='disabled' ")
00460        );
00461        i = 0;
00462        for (attendee = icalcomponent_get_first_property(vevent, ICAL_ATTENDEE_PROPERTY);
00463            attendee != NULL;
00464            attendee = icalcomponent_get_next_property(vevent, ICAL_ATTENDEE_PROPERTY)) {
00465               ch = icalproperty_get_attendee(attendee);
00466               if ((ch != NULL) && !strncasecmp(ch, "mailto:", 7)) {
00467 
00468                      /* screen name or email address */
00469                      safestrncpy(attendee_string, ch + 7, sizeof(attendee_string));
00470                      striplt(attendee_string);
00471                      if (i++) wc_printf("\n");
00472                      escputs(attendee_string);
00473                      wc_printf(" ");
00474 
00475                      /* participant status */
00476                      partstat_as_string(buf, attendee);
00477                      escputs(buf);
00478               }
00479        }
00480        wc_printf("</textarea></td></tr>\n");
00481        wc_printf("</table>\n");
00482        end_tab(1, 3);
00483 
00484        /* Recurrence tab */
00485        begin_tab(2, 3);
00486 
00487        rrule = icalcomponent_get_first_property(vevent, ICAL_RRULE_PROPERTY);
00488        if (rrule) {
00489               recur = icalproperty_get_rrule(rrule);
00490        }
00491        else {
00492               /* blank recurrence with some sensible defaults */
00493               memset(&recur, 0, sizeof(struct icalrecurrencetype));
00494               recur.count = 3;
00495               recur.until = icaltime_null_time();
00496               recur.interval = 1;
00497               recur.freq = ICAL_WEEKLY_RECURRENCE;
00498        }
00499 
00500        wc_printf("<input type=\"checkbox\" id=\"is_recur\" name=\"is_recur\" "
00501               "value=\"yes\" "
00502               "onclick=\"RecurrenceShowHide();\""
00503               " %s >%s",
00504               (rrule ? "checked=\"checked\"" : "" ),
00505               _("This is a recurring event")
00506        );
00507 
00508        wc_printf("<div id=\"rrule_div\">\n");           /* begin 'rrule_div' div */
00509 
00510        wc_printf("<table border='0' cellspacing='10' width='100%%'>\n");
00511 
00512        wc_printf("<tr><td><b>");
00513        wc_printf(_("Recurrence rule"));
00514        wc_printf("</b></td><td>");
00515 
00516        if ((recur.freq < 0) || (recur.freq > 6)) recur.freq = 4;
00517        wc_printf("%s ", _("Repeats every"));
00518 
00519        wc_printf("<input type=\"text\" name=\"interval\" maxlength=\"3\" size=\"3\" ");
00520        wc_printf("value=\"%d\">&nbsp;", recur.interval);
00521 
00522        wc_printf("<select name=\"freq\" id=\"freq_selector\" size=\"1\" "
00523               "onChange=\"RecurrenceShowHide();\">\n");
00524        for (i=0; i<(sizeof frequency_units / sizeof(char *)); ++i) {
00525               wc_printf("<option %s%svalue=\"%d\">%s</option>\n",
00526                      ((i == recur.freq) ? "selected='selected' " : ""),
00527                      (((i == recur.freq) || ((i>=3)&&(i<=6))) ? "" : "disabled='disabled' "),
00528                      i,
00529                      frequency_units[i]
00530               );
00531        }
00532        wc_printf("</select>\n");
00533 
00534        wc_printf("<div id=\"weekday_selector\">");      /* begin 'weekday_selector' div */
00535        wc_printf("%s<br>", _("on these weekdays:"));
00536 
00537        memset(weekday_is_selected, 0, 7);
00538 
00539        for (i=0; i<ICAL_BY_DAY_SIZE; ++i) {
00540               if (recur.by_day[i] == ICAL_RECURRENCE_ARRAY_MAX) {
00541                      i = ICAL_RECURRENCE_ARRAY_MAX;                   /* all done */
00542               }
00543               else {
00544                      for (j=0; j<7; ++j) {
00545                             if (icalrecurrencetype_day_day_of_week(recur.by_day[i]) == j+1) {
00546                                    weekday_is_selected[j] = 1;
00547                             }
00548                      }
00549               }
00550        }
00551 
00552        for (j=0; j<7; ++j) {
00553               i = ((j + (int)weekstart) % 7);
00554               wc_printf("<input type=\"checkbox\" name=\"weekday%d\" value=\"yes\"", i);
00555               if (weekday_is_selected[i]) wc_printf(" checked='checked'");
00556               wc_printf(">%s\n", weekday_labels[i]);
00557        }
00558        wc_printf("</div>\n");                           /* end 'weekday_selector' div */
00559 
00560 
00561 
00562 
00563 
00564        wc_printf("<div id=\"monthday_selector\">");     /* begin 'monthday_selector' div */
00565 
00566        wc_printf("<input type=\"radio\" name=\"rrmonthtype\" id=\"rrmonthtype_mday\" "
00567               "value=\"rrmonthtype_mday\" "
00568               "%s onChange=\"RecurrenceShowHide();\">",
00569               ((which_rrmonthtype_is_preselected == 0) ? "checked='checked'" : "")
00570        );
00571 
00572        rrmday = t_start.day;
00573        rrmweekday = icaltime_day_of_week(t_start) - 1;
00574 
00575        /* Figure out what week of the month we're in */
00576        day1 = t_start;
00577        day1.day = 1;
00578        weekbase = icaltime_week_number(day1);
00579        rrmweek = icaltime_week_number(t_start) - weekbase + 1;
00580 
00581        /* Are we going by day of the month or week/day? */
00582 
00583        if (recur.by_month_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
00584               which_rrmonthtype_is_preselected = 0;
00585               rrmday = recur.by_month_day[0];
00586        }
00587        else if (recur.by_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
00588               which_rrmonthtype_is_preselected = 1;
00589               rrmweek = icalrecurrencetype_day_position(recur.by_day[0]);
00590               rrmweekday = icalrecurrencetype_day_day_of_week(recur.by_day[0]) - 1;
00591        }
00592 
00593        wc_printf(_("on day %s%d%s of the month"), "<span id=\"rrmday\">", rrmday, "</span>");
00594        wc_printf("<br>\n");
00595 
00596        wc_printf("<input type=\"radio\" name=\"rrmonthtype\" id=\"rrmonthtype_wday\" "
00597               "value=\"rrmonthtype_wday\" "
00598               "%s onChange=\"RecurrenceShowHide();\">",
00599               ((which_rrmonthtype_is_preselected == 1) ? "checked='checked'" : "")
00600        );
00601 
00602        wc_printf(_("on the "));
00603        wc_printf("<select name=\"rrmweek\" id=\"rrmweek\" size=\"1\" "
00604               "onChange=\"RecurrenceShowHide();\">\n");
00605        for (i=1; i<=5; ++i) {
00606               wc_printf("<option %svalue=\"%d\">%s</option>\n",
00607                      ((i==rrmweek) ? "selected='selected' " : ""),
00608                      i,
00609                      ordinals[i]
00610               );
00611        }
00612        wc_printf("</select> \n");
00613 
00614        wc_printf("<select name=\"rrmweekday\" id=\"rrmweekday\" size=\"1\" "
00615               "onChange=\"RecurrenceShowHide();\">\n");
00616        for (j=0; j<7; ++j) {
00617               i = ((j + (int)weekstart) % 7);
00618               wc_printf("<option %svalue=\"%d\">%s</option>\n",
00619                      ((i==rrmweekday) ? "selected='selected' " : ""),
00620                      i,
00621                      weekday_labels[i]
00622               );
00623        }
00624        wc_printf("</select>");
00625 
00626        wc_printf(" %s<br>\n", _("of the month"));
00627 
00628        wc_printf("</div>\n");                           /* end 'monthday_selector' div */
00629 
00630 
00631        rrymweek = rrmweek;
00632        rrymweekday = rrmweekday;
00633        rrymonth = t_start.month;
00634        which_rryeartype_is_preselected = 0;
00635 
00636        if (
00637               (recur.by_day[0] != ICAL_RECURRENCE_ARRAY_MAX)
00638               && (recur.by_day[0] != 0)
00639               && (recur.by_month[0] != ICAL_RECURRENCE_ARRAY_MAX)
00640               && (recur.by_month[0] != 0)
00641        ) {
00642               which_rryeartype_is_preselected = 1;
00643               rrymweek = icalrecurrencetype_day_position(recur.by_day[0]);
00644               rrymweekday = icalrecurrencetype_day_day_of_week(recur.by_day[0]) - 1;
00645               rrymonth = recur.by_month[0];
00646        }
00647 
00648        wc_printf("<div id=\"yearday_selector\">");      /* begin 'yearday_selector' div */
00649 
00650        wc_printf("<input type=\"radio\" name=\"rryeartype\" id=\"rryeartype_ymday\" "
00651               "value=\"rryeartype_ymday\" "
00652               "%s onChange=\"RecurrenceShowHide();\">",
00653               ((which_rryeartype_is_preselected == 0) ? "checked='checked'" : "")
00654        );
00655        wc_printf(_("every "));
00656        wc_printf("<span id=\"ymday\">%s</span><br>", _("year on this date"));
00657 
00658        wc_printf("<input type=\"radio\" name=\"rryeartype\" id=\"rryeartype_ywday\" "
00659               "value=\"rryeartype_ywday\" "
00660               "%s onChange=\"RecurrenceShowHide();\">",
00661               ((which_rryeartype_is_preselected == 1) ? "checked='checked'" : "")
00662        );
00663 
00664        wc_printf(_("on the "));
00665        wc_printf("<select name=\"rrymweek\" id=\"rrymweek\" size=\"1\" "
00666               "onChange=\"RecurrenceShowHide();\">\n");
00667        for (i=1; i<=5; ++i) {
00668               wc_printf("<option %svalue=\"%d\">%s</option>\n",
00669                      ((i==rrymweek) ? "selected='selected' " : ""),
00670                      i,
00671                      ordinals[i]
00672               );
00673        }
00674        wc_printf("</select> \n");
00675 
00676        wc_printf("<select name=\"rrymweekday\" id=\"rrymweekday\" size=\"1\" "
00677               "onChange=\"RecurrenceShowHide();\">\n");
00678        for (j=0; j<7; ++j) {
00679               i = ((j + (int)weekstart) % 7);
00680               wc_printf("<option %svalue=\"%d\">%s</option>\n",
00681                      ((i==rrymweekday) ? "selected='selected' " : ""),
00682                      i,
00683                      weekday_labels[i]
00684               );
00685        }
00686        wc_printf("</select>");
00687 
00688        wc_printf(" %s ", _("of"));
00689 
00690        wc_printf("<select name=\"rrymonth\" id=\"rrymonth\" size=\"1\" "
00691               "onChange=\"RecurrenceShowHide();\">\n");
00692        for (i=1; i<=12; ++i) {
00693               wc_printf("<option %svalue=\"%d\">%s</option>\n",
00694                      ((i==rrymonth) ? "selected='selected' " : ""),
00695                      i,
00696                      month_labels[i-1]
00697               );
00698        }
00699        wc_printf("</select>");
00700        wc_printf("<br>\n");
00701 
00702        wc_printf("</div>\n");                           /* end 'yearday_selector' div */
00703 
00704        wc_printf("</td></tr>\n");
00705 
00706 
00707        which_rrend_is_preselected = 0;
00708        if (!icaltime_is_null_time(recur.until)) which_rrend_is_preselected = 2;
00709        if (recur.count > 0) which_rrend_is_preselected = 1;
00710 
00711        wc_printf("<tr><td><b>");
00712        wc_printf(_("Recurrence range"));
00713        wc_printf("</b></td><td>\n");
00714 
00715        wc_printf("<input type=\"radio\" name=\"rrend\" id=\"rrend_none\" "
00716               "value=\"rrend_none\" "
00717               "%s onChange=\"RecurrenceShowHide();\">",
00718               ((which_rrend_is_preselected == 0) ? "checked='checked'" : "")
00719        );
00720        wc_printf("%s<br>\n", _("No ending date"));
00721 
00722        wc_printf("<input type=\"radio\" name=\"rrend\" id=\"rrend_count\" "
00723               "value=\"rrend_count\" "
00724               "%s onChange=\"RecurrenceShowHide();\">",
00725               ((which_rrend_is_preselected == 1) ? "checked='checked'" : "")
00726        );
00727        wc_printf(_("Repeat this event"));
00728        wc_printf(" <input type=\"text\" name=\"rrcount\" id=\"rrcount\" maxlength=\"3\" size=\"3\" ");
00729        wc_printf("value=\"%d\"> ", recur.count);
00730        wc_printf(_("times"));
00731        wc_printf("<br>\n");
00732 
00733        wc_printf("<input type=\"radio\" name=\"rrend\" id=\"rrend_until\" "
00734               "value=\"rrend_until\" "
00735               "%s onChange=\"RecurrenceShowHide();\">",
00736               ((which_rrend_is_preselected == 2) ? "checked='checked'" : "")
00737        );
00738        wc_printf(_("Repeat this event until "));
00739 
00740        if (icaltime_is_null_time(recur.until)) {
00741               recur.until = icaltime_add(t_start, icaldurationtype_from_int(604800));
00742        }
00743        display_icaltimetype_as_webform(&recur.until, "rruntil", 1);
00744        wc_printf("<br>\n");
00745 
00746        wc_printf("</td></tr>\n");
00747 
00748        wc_printf("</table>\n");
00749        wc_printf("</div>\n");                           /* end 'rrule' div */
00750 
00751        end_tab(2, 3);
00752 
00753        /* submit buttons (common area beneath the tabs) */
00754        begin_tab(3, 3);
00755        wc_printf("<center>"
00756               "<input type=\"submit\" name=\"save_button\" value=\"%s\">"
00757               "&nbsp;&nbsp;"
00758               "<input type=\"submit\" name=\"delete_button\" value=\"%s\">\n"
00759               "&nbsp;&nbsp;"
00760               "<input type=\"submit\" id=\"check_button\" name=\"check_button\" value=\"%s\">\n"
00761               "&nbsp;&nbsp;"
00762               "<input type=\"submit\" name=\"cancel_button\" value=\"%s\">\n"
00763               "</center>\n",
00764               _("Save"),
00765               _("Delete"),
00766               _("Check attendee availability"),
00767               _("Cancel")
00768        );
00769        end_tab(3, 3);
00770        wc_printf("</form>\n");
00771 
00772        StrBufAppendPrintf(WC->trailing_javascript,
00773               "eventEditAllDay();         \n"
00774               "RecurrenceShowHide();             \n"
00775               "EnableOrDisableCheckButton();     \n"
00776        );
00777        address_book_popup();
00778        wDumpContent(1);
00779 
00780        if (created_new_vevent) {
00781               icalcomponent_free(vevent);
00782        }
00783 }
00784 
00785 /*
00786  * Save an edited event
00787  *
00788  * supplied_vevent:  the event to save
00789  * msgnum:           the index on the citserver
00790  */
00791 void save_individual_event(icalcomponent *supplied_vevent, long msgnum, char *from,
00792                      int unread, calview *calv) {
00793        char buf[SIZ];
00794        icalproperty *prop;
00795        icalcomponent *vevent, *encaps;
00796        int created_new_vevent = 0;
00797        int all_day_event = 0;
00798        struct icaltimetype event_start, t;
00799        icalproperty *attendee = NULL;
00800        char attendee_string[SIZ];
00801        int i, j;
00802        int foundit;
00803        char form_attendees[SIZ];
00804        char organizer_string[SIZ];
00805        int sequence = 0;
00806        enum icalproperty_transp formtransp = ICAL_TRANSP_NONE;
00807        const char *ch;
00808 
00809        if (supplied_vevent != NULL) {
00810               vevent = supplied_vevent;
00811 
00812               /* Convert all timestamps to UTC to make them easier to process. */
00813               ical_dezonify(vevent);
00814 
00815               /*
00816                * If we're looking at a fully encapsulated VCALENDAR
00817                * rather than a VEVENT component, attempt to use the first
00818                * relevant VEVENT subcomponent.  If there is none, the
00819                * NULL returned by icalcomponent_get_first_component() will
00820                * tell the next iteration of this function to create a
00821                * new one.
00822                */
00823               if (icalcomponent_isa(vevent) == ICAL_VCALENDAR_COMPONENT) {
00824                      save_individual_event(
00825                             icalcomponent_get_first_component(
00826                                    vevent, ICAL_VEVENT_COMPONENT),
00827                             msgnum, from, unread, NULL
00828                      );
00829                      return;
00830               }
00831        }
00832        else {
00833               vevent = icalcomponent_new(ICAL_VEVENT_COMPONENT);
00834               created_new_vevent = 1;
00835        }
00836 
00837        if ( (havebstr("save_button"))
00838           || (havebstr("check_button")) ) {
00839 
00840               /* Replace values in the component with ones from the form */
00841 
00842               while (prop = icalcomponent_get_first_property(vevent,
00843                     ICAL_SUMMARY_PROPERTY), prop != NULL) {
00844                      icalcomponent_remove_property(vevent, prop);
00845                      icalproperty_free(prop);
00846               }
00847 
00848               /* Add NOW() to the calendar object... */
00849               icalcomponent_set_dtstamp(vevent,
00850                                      icaltime_from_timet(
00851                                             time(NULL), 0));
00852 
00853               if (havebstr("summary")) {
00854                      icalcomponent_add_property(vevent,
00855                                    icalproperty_new_summary(bstr("summary")));
00856               } else {
00857                      icalcomponent_add_property(vevent,
00858                                    icalproperty_new_summary(_("Untitled Event")));
00859               }
00860 
00861               while (prop = icalcomponent_get_first_property(vevent,
00862                                    ICAL_LOCATION_PROPERTY), prop != NULL) {
00863                      icalcomponent_remove_property(vevent, prop);
00864                      icalproperty_free(prop);
00865               }
00866               if (havebstr("location")) {
00867                      icalcomponent_add_property(vevent,
00868                                    icalproperty_new_location(bstr("location")));
00869               }
00870               while (prop = icalcomponent_get_first_property(vevent,
00871                               ICAL_DESCRIPTION_PROPERTY), prop != NULL) {
00872                      icalcomponent_remove_property(vevent, prop);
00873                      icalproperty_free(prop);
00874               }
00875               if (havebstr("description")) {
00876                      icalcomponent_add_property(vevent,
00877                             icalproperty_new_description(bstr("description")));
00878               }
00879 
00880               while (prop = icalcomponent_get_first_property(vevent,
00881                     ICAL_DTSTART_PROPERTY), prop != NULL) {
00882                      icalcomponent_remove_property(vevent, prop);
00883                      icalproperty_free(prop);
00884               }
00885 
00886               if (yesbstr("alldayevent")) {
00887                      all_day_event = 1;
00888               }
00889               else {
00890                      all_day_event = 0;
00891               }
00892 
00893               if (all_day_event) {
00894                      icaltime_from_webform_dateonly(&event_start, "dtstart");
00895               }
00896               else {
00897                      icaltime_from_webform(&event_start, "dtstart");
00898               }
00899 
00900               prop = icalproperty_new_dtstart(event_start);
00901 
00902               if (all_day_event) {
00903                      /* Force it to serialize as a date-only rather than date/time */
00904                      icalproperty_set_value(prop, icalvalue_new_date(event_start));
00905               }
00906 
00907               if (prop) icalcomponent_add_property(vevent, prop);
00908               else icalproperty_free(prop);
00909 
00910               while (prop = icalcomponent_get_first_property(vevent,
00911                     ICAL_DTEND_PROPERTY), prop != NULL) {
00912                      icalcomponent_remove_property(vevent, prop);
00913                      icalproperty_free(prop);
00914               }
00915               while (prop = icalcomponent_get_first_property(vevent,
00916                     ICAL_DURATION_PROPERTY), prop != NULL) {
00917                      icalcomponent_remove_property(vevent, prop);
00918                      icalproperty_free(prop);
00919               }
00920 
00921               if (all_day_event) {
00922                      icaltime_from_webform_dateonly(&t, "dtend");
00923 
00924                      /* with this field supposed to be non-inclusive we have to add one day */
00925                      icaltime_adjust(&t, 1, 0, 0, 0);
00926               }
00927               else {
00928                      icaltime_from_webform(&t, "dtend");
00929               }
00930 
00931               icalcomponent_add_property(vevent,
00932                      icalproperty_new_dtend(icaltime_normalize(t)
00933                      )
00934               );
00935 
00936               /* recurrence rules -- begin */
00937 
00938               /* remove any existing rule */
00939               while (prop = icalcomponent_get_first_property(vevent, ICAL_RRULE_PROPERTY), prop != NULL) {
00940                      icalcomponent_remove_property(vevent, prop);
00941                      icalproperty_free(prop);
00942               }
00943 
00944               if (yesbstr("is_recur")) {
00945                      struct icalrecurrencetype recur;
00946                      icalrecurrencetype_clear(&recur);
00947 
00948                      recur.interval = atoi(bstr("interval"));
00949                      recur.freq = atoi(bstr("freq"));
00950 
00951                      switch(recur.freq) {
00952 
00953                             /* These can't happen; they're disabled. */
00954                             case ICAL_SECONDLY_RECURRENCE:
00955                                    break;
00956                             case ICAL_MINUTELY_RECURRENCE:
00957                                    break;
00958                             case ICAL_HOURLY_RECURRENCE:
00959                                    break;
00960 
00961                             /* Daily is valid but there are no further inputs. */
00962                             case ICAL_DAILY_RECURRENCE:
00963                                    break;
00964 
00965                             /* These are the real options. */
00966 
00967                             case ICAL_WEEKLY_RECURRENCE:
00968                                    j=0;
00969                                    for (i=0; i<7; ++i) {
00970                                           snprintf(buf, sizeof buf, "weekday%d", i);
00971                                           if (YESBSTR(buf)) recur.by_day[j++] =
00972                                                  icalrecurrencetype_day_day_of_week(i+1);
00973                                    }
00974                                    recur.by_day[j++] = ICAL_RECURRENCE_ARRAY_MAX;
00975                                    break;
00976 
00977                             case ICAL_MONTHLY_RECURRENCE:
00978                                    if (!strcasecmp(bstr("rrmonthtype"), "rrmonthtype_mday")) {
00979                                           recur.by_month_day[0] = event_start.day;
00980                                           recur.by_month_day[1] = ICAL_RECURRENCE_ARRAY_MAX;
00981                                    }
00982                                    else if (!strcasecmp(bstr("rrmonthtype"), "rrmonthtype_wday")) {
00983                                           recur.by_day[0] = (atoi(bstr("rrmweek")) * 8)
00984                                                         + atoi(bstr("rrmweekday")) + 1;
00985                                           recur.by_day[1] = ICAL_RECURRENCE_ARRAY_MAX;
00986                                    }
00987                                    break;
00988 
00989                             case ICAL_YEARLY_RECURRENCE:
00990                                    if (!strcasecmp(bstr("rryeartype"), "rryeartype_ymday")) {
00991                                           /* no further action is needed here */
00992                                    }
00993                                    else if (!strcasecmp(bstr("rryeartype"), "rryeartype_ywday")) {
00994                                           recur.by_month[0] = atoi(bstr("rrymonth"));
00995                                           recur.by_month[1] = ICAL_RECURRENCE_ARRAY_MAX;
00996                                           recur.by_day[0] = (atoi(bstr("rrymweek")) * 8)
00997                                                         + atoi(bstr("rrymweekday")) + 1;
00998                                           recur.by_day[1] = ICAL_RECURRENCE_ARRAY_MAX;
00999                                    }
01000                                    break;
01001 
01002                             /* This one can't happen either. */
01003                             case ICAL_NO_RECURRENCE:
01004                                    break;
01005                      }
01006 
01007                      if (!strcasecmp(bstr("rrend"), "rrend_count")) {
01008                             recur.count = atoi(bstr("rrcount"));
01009                      }
01010                      else if (!strcasecmp(bstr("rrend"), "rrend_until")) {
01011                             icaltime_from_webform_dateonly(&recur.until, "rruntil");
01012                      }
01013 
01014                      icalcomponent_add_property(vevent, icalproperty_new_rrule(recur));
01015               }
01016 
01017               /* recurrence rules -- end */
01018 
01019               /* See if transparency is indicated */
01020               if (havebstr("transp")) {
01021                      if (!strcasecmp(bstr("transp"), "opaque")) {
01022                             formtransp = ICAL_TRANSP_OPAQUE;
01023                      }
01024                      else if (!strcasecmp(bstr("transp"), "transparent")) {
01025                             formtransp = ICAL_TRANSP_TRANSPARENT;
01026                      }
01027 
01028                      while (prop = icalcomponent_get_first_property(vevent, ICAL_TRANSP_PROPERTY),
01029                            (prop != NULL)) {
01030                             icalcomponent_remove_property(vevent, prop);
01031                             icalproperty_free(prop);
01032                      }
01033 
01034                      icalcomponent_add_property(vevent, icalproperty_new_transp(formtransp));
01035               }
01036 
01037               /* Give this event a UID if it doesn't have one. */
01038               if (icalcomponent_get_first_property(vevent,
01039                  ICAL_UID_PROPERTY) == NULL) {
01040                      generate_uuid(buf);
01041                      icalcomponent_add_property(vevent, icalproperty_new_uid(buf));
01042               }
01043 
01044               /* Increment the sequence ID */
01045               while (prop = icalcomponent_get_first_property(vevent,
01046                     ICAL_SEQUENCE_PROPERTY), (prop != NULL) ) {
01047                      i = icalproperty_get_sequence(prop);
01048                      if (i > sequence) sequence = i;
01049                      icalcomponent_remove_property(vevent, prop);
01050                      icalproperty_free(prop);
01051               }
01052               ++sequence;
01053               icalcomponent_add_property(vevent,
01054                      icalproperty_new_sequence(sequence)
01055               );
01056 
01057               /*
01058                * Set the organizer, only if one does not already exist *and*
01059                * the form is supplying one
01060                */
01061               strcpy(buf, bstr("organizer"));
01062               if ( (icalcomponent_get_first_property(vevent,
01063                  ICAL_ORGANIZER_PROPERTY) == NULL)
01064                  && (!IsEmptyStr(buf)) ) {
01065 
01066                      /* set new organizer */
01067                      sprintf(organizer_string, "MAILTO:%s", buf);
01068                      icalcomponent_add_property(vevent,
01069                             icalproperty_new_organizer(organizer_string)
01070                      );
01071 
01072               }
01073 
01074               /*
01075                * Add any new attendees listed in the web form
01076                */
01077 
01078               /* First, strip out the parenthesized partstats.  */
01079               strcpy(form_attendees, bstr("attendees"));
01080               while (       stripout(form_attendees, '(', ')') != 0);
01081 
01082               /* Next, change any commas to newlines, because we want newline-separated attendees. */
01083               j = strlen(form_attendees);
01084               for (i=0; i<j; ++i) {
01085                      if (form_attendees[i] == ',') {
01086                             form_attendees[i] = '\n';
01087                             while (isspace(form_attendees[i+1])) {
01088                                    strcpy(&form_attendees[i+1], &form_attendees[i+2]);
01089                             }
01090                      }
01091               }
01092 
01093               /* Now iterate! */
01094               for (i=0; i<num_tokens(form_attendees, '\n'); ++i) {
01095                      extract_token(buf, form_attendees, i, '\n', sizeof buf);
01096                      striplt(buf);
01097                      if (!IsEmptyStr(buf)) {
01098                             sprintf(attendee_string, "MAILTO:%s", buf);
01099                             foundit = 0;
01100 
01101                             for (attendee = icalcomponent_get_first_property(vevent, ICAL_ATTENDEE_PROPERTY); attendee != NULL; attendee = icalcomponent_get_next_property(vevent, ICAL_ATTENDEE_PROPERTY)) {
01102                                    ch = icalproperty_get_attendee(attendee);
01103                                    if ((ch != NULL) && !strcasecmp(attendee_string, ch))
01104                                           ++foundit;
01105                             }
01106 
01107 
01108                             if (foundit == 0) {
01109                                    icalcomponent_add_property(vevent,
01110                                                            icalproperty_new_attendee(attendee_string)
01111                                    );
01112                             }
01113                      }
01114               }
01115 
01116               /*
01117                * Remove any attendees *not* listed in the web form
01118                */
01119 STARTOVER:    for (attendee = icalcomponent_get_first_property(vevent, ICAL_ATTENDEE_PROPERTY); attendee != NULL; attendee = icalcomponent_get_next_property(vevent, ICAL_ATTENDEE_PROPERTY)) {
01120                      ch = icalproperty_get_attendee(attendee);
01121                      if ((ch != NULL) && !strncasecmp(ch, "MAILTO:", 7)) {
01122                             safestrncpy(attendee_string, ch + 7, sizeof(attendee_string));
01123                             striplt(attendee_string);
01124                             foundit = 0;
01125                             for (i=0; i<num_tokens(form_attendees, '\n'); ++i) {
01126                                    extract_token(buf, form_attendees, i, '\n', sizeof buf);
01127                                    striplt(buf);
01128                                    if (!strcasecmp(buf, attendee_string)) ++foundit;
01129                             }
01130                             if (foundit == 0) {
01131                                    icalcomponent_remove_property(vevent, attendee);
01132                                    icalproperty_free(attendee);
01133                                    goto STARTOVER;
01134                             }
01135                      }
01136               }
01137 
01138               /*
01139                * Encapsulate event into full VCALENDAR component.  Clone it first,
01140                * for two reasons: one, it's easier to just free the whole thing
01141                * when we're done instead of unbundling, but more importantly, we
01142                * can't encapsulate something that may already be encapsulated
01143                * somewhere else.
01144                */
01145               encaps = ical_encapsulate_subcomponent(icalcomponent_new_clone(vevent));
01146 
01147               /* Set the method to PUBLISH */
01148               icalcomponent_set_method(encaps, ICAL_METHOD_PUBLISH);
01149 
01150               /* If the user clicked 'Save' then save it to the server. */
01151               if ( (encaps != NULL) && (havebstr("save_button")) ) {
01152                      serv_puts("ENT0 1|||4|||1|");
01153                      serv_getln(buf, sizeof buf);
01154                      switch (buf[0]) {
01155                      case '8':
01156                             serv_puts("Content-type: text/calendar");
01157                             serv_puts("Content-Transfer-Encoding: quoted-printable");
01158                             serv_puts("");
01159                             text_to_server_qp(icalcomponent_as_ical_string(encaps));
01160 //                          serv_puts(icalcomponent_as_ical_string(encaps));
01161                             serv_puts("000");
01162                      case '4':
01163                             while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {}
01164                             break;
01165                      case '2':
01166                             AppendImportantMessage(buf + 4, - 1);
01167                             break;
01168                      default:
01169                             break;
01170                      }
01171                      icalmemory_free_ring ();
01172                      icalcomponent_free(encaps);
01173                      encaps = NULL;
01174               }
01175 
01176               /* Or, check attendee availability if the user asked for that. */
01177               if ( (encaps != NULL) && (havebstr("check_button")) ) {
01178 
01179                      /* Call this function, which does the real work */
01180                      check_attendee_availability(encaps);
01181 
01182                      /* This displays the form again, with our annotations */
01183                      display_edit_individual_event(encaps, msgnum, from, unread, NULL);
01184 
01185                      icalcomponent_free(encaps);
01186                      encaps = NULL;
01187               }
01188               if (encaps != NULL) {
01189                      icalcomponent_free(encaps);
01190                      encaps = NULL;
01191               }
01192 
01193        }
01194 
01195        /*
01196         * If the user clicked 'Delete' then delete it.
01197         */
01198        if ( (havebstr("delete_button")) && (msgnum > 0L) ) {
01199               serv_printf("DELE %ld", lbstr("msgnum"));
01200               serv_getln(buf, sizeof buf);
01201        }
01202 
01203        if (created_new_vevent) {
01204               icalcomponent_free(vevent);
01205        }
01206 
01207        /* If this was a save or delete, go back to the calendar or summary view. */
01208        if (!havebstr("check_button")) {
01209               if (!strcasecmp(bstr("calview"), "summary")) {
01210                      display_summary_page();
01211               }
01212               else {
01213                      readloop(readfwd, eUseDefault);
01214               }
01215        }
01216 }