HUGE PATCH. This moves all of mime_parser.c and all
[citadel.git] / webcit / calendar.c
index 5353dfa67d8f11f7cc9502ff53b0239de196cdb5..3ced19b1d177605966ae6a6630a3836d18bcb918 100644 (file)
@@ -65,7 +65,7 @@ void display_task(long msgnum) {
 /**
  * \brief Process a calendar object
  * ...at this point it's already been deserialized by cal_process_attachment()
- * \param cal teh calendar object
+ * \param cal the calendar object
  * \param recursion_level call stack depth ??????
  * \param msgnum number of the mesage in our db
  * \param cal_partnum of the calendar object ???? 
@@ -85,10 +85,14 @@ void cal_process_object(icalcomponent *cal,
        char conflict_name[256];
        char conflict_message[256];
        int is_update = 0;
+       char divname[32];
+       static int divcount = 0;
+
+       sprintf(divname, "rsvp%04x", ++divcount);
 
        /** Leading HTML for the display of this object */
        if (recursion_level == 0) {
-               wprintf("<CENTER><TABLE border=0>\n");
+               wprintf("<div class=\"mimepart\">\n");
        }
 
        /** Look for a method */
@@ -97,58 +101,48 @@ void cal_process_object(icalcomponent *cal,
        /** See what we need to do with this */
        if (method != NULL) {
                the_method = icalproperty_get_method(method);
+               char *title;
+
+               wprintf("<div id=\"%s_title\">", divname);
+               wprintf("<img src=\"static/calarea_48x.gif\">");
+               wprintf("<span>");
                switch(the_method) {
                    case ICAL_METHOD_REQUEST:
-                       wprintf("<tr><td colspan=\"2\">\n"
-                               "<img align=\"center\" "
-                               "src=\"static/calarea_48x.gif\">"
-                               "&nbsp;&nbsp;"  
-                               "<B>");
-                       wprintf(_("Meeting invitation"));
-                       wprintf("</B></TD></TR>\n");
+                       title = _("Meeting invitation");
                        break;
                    case ICAL_METHOD_REPLY:
-                       wprintf("<TR><TD COLSPAN=2>\n"
-                               "<IMG ALIGN=CENTER "
-                               "src=\"static/calarea_48x.gif\">"
-                               "&nbsp;&nbsp;"  
-                               "<B>");
-                       wprintf(_("Attendee's reply to your invitation"));
-                       wprintf("</B></TD></TR>\n");
+                       title = _("Attendee's reply to your invitation");
                        break;
                    case ICAL_METHOD_PUBLISH:
-                       wprintf("<TR><TD COLSPAN=2>\n"
-                               "<IMG ALIGN=CENTER "
-                               "src=\"static/calarea_48x.gif\">"
-                               "&nbsp;&nbsp;"  
-                               "<B>");
-                       wprintf(_("Published event"));
-                       wprintf("</B></TD></TR>\n");
+                       title = _("Published event");
                        break;
                    default:
-                       wprintf("<TR><TD COLSPAN=2>");
-                       wprintf(_("This is an unknown type of calendar item."));
-                       wprintf("</TD></TR>\n");
+                       title = _("This is an unknown type of calendar item.");
                        break;
                }
+               wprintf("</span>");
+
+               wprintf("&nbsp;&nbsp;%s",title);
+               wprintf("</div>");
        }
 
+       wprintf("<dl>");
        p = icalcomponent_get_first_property(cal, ICAL_SUMMARY_PROPERTY);
        if (p != NULL) {
-               wprintf("<TR><TD><B>");
+               wprintf("<dt>");
                wprintf(_("Summary:"));
-               wprintf("</B></TD><TD>");
+               wprintf("</dt><dd>");
                escputs((char *)icalproperty_get_comment(p));
-               wprintf("</TD></TR>\n");
+               wprintf("</dd>\n");
        }
 
        p = icalcomponent_get_first_property(cal, ICAL_LOCATION_PROPERTY);
        if (p != NULL) {
-               wprintf("<TR><TD><B>");
+               wprintf("<dt>");
                wprintf(_("Location:"));
-               wprintf("</B></TD><TD>");
+               wprintf("</dt><dd>");
                escputs((char *)icalproperty_get_comment(p));
-               wprintf("</TD></TR>\n");
+               wprintf("</dd>\n");
        }
 
        /**
@@ -170,16 +164,16 @@ void cal_process_object(icalcomponent *cal,
                                d_tm.tm_mon = t.month - 1;
                                d_tm.tm_mday = t.day;
                                wc_strftime(d_str, sizeof d_str, "%x", &d_tm);
-                               wprintf("<TR><TD><B>");
+                               wprintf("<dt>");
                                wprintf(_("Date:"));
-                               wprintf("</B></TD><TD>%s</TD></TR>", d_str);
+                               wprintf("</dt><dd>%s</dd>", d_str);
                        }
                        else {
                                tt = icaltime_as_timet(t);
-                               fmt_date(buf, tt, 0);
-                               wprintf("<TR><TD><B>");
+                               webcit_fmt_date(buf, tt, 0);
+                               wprintf("<dt>");
                                wprintf(_("Starting date/time:"));
-                               wprintf("</B></TD><TD>%s</TD></TR>", buf);
+                               wprintf("</dt><dd>%s</dd>", buf);
                        }
                }
        
@@ -187,28 +181,28 @@ void cal_process_object(icalcomponent *cal,
                if (p != NULL) {
                        t = icalproperty_get_dtend(p);
                        tt = icaltime_as_timet(t);
-                       fmt_date(buf, tt, 0);
-                       wprintf("<TR><TD><B>");
+                       webcit_fmt_date(buf, tt, 0);
+                       wprintf("<dt>");
                        wprintf(_("Ending date/time:"));
-                       wprintf("</B></TD><TD>%s</TD></TR>", buf);
+                       wprintf("</dt><dd>%s</dd>", buf);
                }
 
        }
 
        p = icalcomponent_get_first_property(cal, ICAL_DESCRIPTION_PROPERTY);
        if (p != NULL) {
-               wprintf("<TR><TD><B>");
+               wprintf("<dt>");
                wprintf(_("Description:"));
-               wprintf("</B></TD><TD>");
+               wprintf("</dt><dd>");
                escputs((char *)icalproperty_get_comment(p));
-               wprintf("</TD></TR>\n");
+               wprintf("</dd>\n");
        }
 
        /** If the component has attendees, iterate through them. */
        for (p = icalcomponent_get_first_property(cal, ICAL_ATTENDEE_PROPERTY); (p != NULL); p = icalcomponent_get_next_property(cal, ICAL_ATTENDEE_PROPERTY)) {
-               wprintf("<TR><TD><B>");
+               wprintf("<dt>");
                wprintf(_("Attendee:"));
-               wprintf("</B></TD><TD>");
+               wprintf("</dt><dd>");
                safestrncpy(buf, icalproperty_get_attendee(p), sizeof buf);
                if (!strncasecmp(buf, "MAILTO:", 7)) {
 
@@ -222,7 +216,7 @@ void cal_process_object(icalcomponent *cal,
                        partstat_as_string(buf, p);
                        escputs(buf);
                }
-               wprintf("</TD></TR>\n");
+               wprintf("</dd>\n");
        }
 
        /** If the component has subcomponents, recurse through them. */
@@ -254,31 +248,36 @@ void cal_process_object(icalcomponent *cal,
                                                _("This event would conflict with '%s' which is already in your calendar."), conflict_name);
                                }
 
-                               wprintf("<TR><TD><B><I>%s</I></B></TD><td>",
+                               wprintf("<dt>%s",
                                        (is_update ?
                                                _("Update:") :
                                                _("CONFLICT:")
                                        )
                                );
+                               wprintf("</dt><dd>");
                                escputs(conflict_message);
-                               wprintf("</TD></TR>\n");
+                               wprintf("</dd>\n");
                        }
                }
                lprintf(9, "...done.\n");
 
+               wprintf("</dl>");
+
                /** Display the Accept/Decline buttons */
-               wprintf("<tr><td>%s</td>"
-                       "<td><font size=+1>"
-                       "<a href=\"respond_to_request?msgnum=%ld&cal_partnum=%s&sc=Accept\">%s</a>"
-                       " | "
-                       "<a href=\"respond_to_request?msgnum=%ld&cal_partnum=%s&sc=Tentative\">%s</a>"
-                       " | "
-                       "<a href=\"respond_to_request?msgnum=%ld&cal_partnum=%s&sc=Decline\">%s</a>"
-                       "</FONT></TD></TR>\n",
+               wprintf("<p id=\"%s_question\">"
+                       "%s "
+                       "&nbsp;&nbsp;&nbsp;<span class=\"button_link\"> "
+                       "<a href=\"javascript:RespondToInvitation('%s_question','%s_title','%ld','%s','Accept');\">%s</a>"
+                       "</span>&nbsp;&nbsp;&nbsp;<span class=\"button_link\">"
+                       "<a href=\"javascript:RespondToInvitation('%s_question','%s_title','%ld','%s','Tentative');\">%s</a>"
+                       "</span>&nbsp;&nbsp;&nbsp;<span class=\"button_link\">"
+                       "<a href=\"javascript:RespondToInvitation('%s_question','%s_title','%ld','%s','Decline');\">%s</a>"
+                       "</span></p>\n",
+                       divname,
                        _("How would you like to respond to this invitation?"),
-                       msgnum, cal_partnum, _("Accept"),
-                       msgnum, cal_partnum, _("Tentative"),
-                       msgnum, cal_partnum, _("Decline")
+                       divname, divname, msgnum, cal_partnum, _("Accept"),
+                       divname, divname, msgnum, cal_partnum, _("Tentative"),
+                       divname, divname, msgnum, cal_partnum, _("Decline")
                );
 
        }
@@ -294,25 +293,24 @@ void cal_process_object(icalcomponent *cal,
                 ***********/
 
                /** Display the update buttons */
-               wprintf("<TR><TD>"
-                       "%s"
-                       "</td><td><font size=+1>"
-                       "<a href=\"handle_rsvp?msgnum=%ld&cal_partnum=%s&sc=Update\">%s</a>"
-                       " | "
-                       "<a href=\"handle_rsvp?msgnum=%ld&cal_partnum=%s&sc=Ignore\">%s</a>"
-                       "</font>"
-                       "</TD></TR>\n",
+               wprintf("<p id=\"%s_question\" >"
+                       "%s "
+                       "&nbsp;&nbsp;&nbsp;<span class=\"button_link\"> "
+                       "<a href=\"javascript:HandleRSVP('%s_question','%s_title','%ld','%s','Update');\">%s</a>"
+                       "</span>&nbsp;&nbsp;&nbsp;<span class=\"button_link\">"
+                       "<a href=\"javascript:HandleRSVP('%s_question','%s_title','%ld','%s','Ignore');\">%s</a>"
+                       "</span></p>\n",
+                       divname,
                        _("Click <i>Update</i> to accept this reply and update your calendar."),
-                       msgnum, cal_partnum, _("Update"),
-                       msgnum, cal_partnum, _("Ignore")
+                       divname, divname, msgnum, cal_partnum, _("Update"),
+                       divname, divname, msgnum, cal_partnum, _("Ignore")
                );
 
        }
 
        /** Trailing HTML for the display of this object */
        if (recursion_level == 0) {
-
-               wprintf("</TR></TABLE></CENTER>\n");
+               wprintf("<p>&nbsp;</p></div>\n");
        }
 }
 
@@ -351,18 +349,9 @@ void cal_process_attachment(char *part_source, long msgnum, char *cal_partnum) {
  * Respond to a meeting request
  */
 void respond_to_request(void) {
-       char buf[SIZ];
+       char buf[1024];
 
-       output_headers(1, 1, 2, 0, 0, 0);
-
-       wprintf("<div id=\"banner\">\n");
-       wprintf("<TABLE WIDTH=100%% BORDER=0 BGCOLOR=\"#444455\"><TR><TD>"
-               "<SPAN CLASS=\"titlebar\">");
-       wprintf(_("Respond to meeting request"));
-       wprintf("</SPAN>"
-               "</TD></TR></TABLE>\n"
-       );
-       wprintf("</div>\n<div id=\"content\">\n");
+       begin_ajax_response();
 
        serv_printf("ICAL respond|%s|%s|%s|",
                bstr("msgnum"),
@@ -372,10 +361,7 @@ void respond_to_request(void) {
        serv_getln(buf, sizeof buf);
 
        if (buf[0] == '2') {
-               wprintf("<TABLE BORDER=0><TR><TD>"
-                       "<img src=\"static/calarea_48x.gif\" ALIGN=CENTER>"
-                       "</TD><TD>"
-               );
+               wprintf("<img src=\"static/calarea_48x.gif\"><span>");
                if (!strcasecmp(bstr("sc"), "accept")) {
                        wprintf(_("You have accepted this meeting invitation.  "
                                "It has been entered into your calendar.")
@@ -391,19 +377,14 @@ void respond_to_request(void) {
                }
                wprintf(" ");
                wprintf(_("A reply has been sent to the meeting organizer."));
-               wprintf("</TD></TR></TABLE>\n");
+               wprintf("</span>");
        } else {
-               wprintf("<img src=\"static/error.gif\" ALIGN=CENTER>"
-                       "%s\n", &buf[4]);
+               wprintf("<img align=\"center\" src=\"static/error.gif\"><span>");
+               wprintf("%s\n", &buf[4]);
+               wprintf("</span>");
        }
 
-       wprintf("<a href=\"dotskip?room=");
-       urlescputs(WC->wc_roomname);
-       wprintf("\"><br />");
-       wprintf(_("Return to messages"));
-       wprintf("</A><br />\n");
-
-       wDumpContent(1);
+       end_ajax_response();
 }
 
 
@@ -412,18 +393,9 @@ void respond_to_request(void) {
  * \brief Handle an incoming RSVP
  */
 void handle_rsvp(void) {
-       char buf[SIZ];
-
-       output_headers(1, 1, 2, 0, 0, 0);
+       char buf[1024];
 
-       wprintf("<div id=\"banner\">\n");
-       wprintf("<TABLE WIDTH=100%% BORDER=0 BGCOLOR=\"#444455\"><TR><TD>"
-               "<SPAN CLASS=\"titlebar\">");
-       wprintf(_("Update your calendar with this RSVP"));
-       wprintf("</SPAN>"
-               "</TD></TR></TABLE>\n"
-               "</div>\n<div id=\"content\">\n"
-       );
+       begin_ajax_response();
 
        serv_printf("ICAL handle_rsvp|%s|%s|%s|",
                bstr("msgnum"),
@@ -433,10 +405,7 @@ void handle_rsvp(void) {
        serv_getln(buf, sizeof buf);
 
        if (buf[0] == '2') {
-               wprintf("<TABLE BORDER=0><TR><TD>"
-                       "<img src=\"static/calarea_48x.gif\" ALIGN=CENTER>"
-                       "</TD><TD>"
-               );
+               wprintf("<img src=\"static/calarea_48x.gif\"><span>");
                if (!strcasecmp(bstr("sc"), "update")) {
                        wprintf(_("Your calendar has been updated to reflect this RSVP."));
                } else if (!strcasecmp(bstr("sc"), "ignore")) {
@@ -444,20 +413,14 @@ void handle_rsvp(void) {
                                "Your calendar has <b>not</b> been updated.")
                        );
                }
-               wprintf("</TD></TR></TABLE>\n"
-               );
+               wprintf("</span>");
        } else {
-               wprintf("<img src=\"static/error.gif\" ALIGN=CENTER>"
-                       "%s\n", &buf[4]);
+               wprintf("<img src=\"static/error.gif\"><span> %s\n", &buf[4]);
+               wprintf("</span>");
        }
 
-       wprintf("<a href=\"dotskip?room=");
-       urlescputs(WC->wc_roomname);
-       wprintf("\"><br />");
-       wprintf(_("Return to messages"));
-       wprintf("</A><br />\n");
+       end_ajax_response();
 
-       wDumpContent(1);
 }
 
 
@@ -483,15 +446,15 @@ void handle_rsvp(void) {
  * \param cal Our calendar to process
  * \param msgnum number of the mesage in our db
  */
-void display_individual_cal(icalcomponent *cal, long msgnum) {
-
-       WC->num_cal += 1;
-
-       WC->disp_cal = realloc(WC->disp_cal,
-                       (sizeof(struct disp_cal) * WC->num_cal) );
-       WC->disp_cal[WC->num_cal - 1].cal = icalcomponent_new_clone(cal);
-
-       WC->disp_cal[WC->num_cal - 1].cal_msgnum = msgnum;
+void display_individual_cal(icalcomponent *cal, long msgnum)
+{
+       struct wcsession *WCC = WC;     /* stack this for faster access (WC is a function) */
+
+       WCC->num_cal += 1;
+       WCC->disp_cal = realloc(WC->disp_cal, (sizeof(struct disp_cal) * WCC->num_cal) );
+       WCC->disp_cal[WCC->num_cal - 1].cal = icalcomponent_new_clone(cal);
+       ical_dezonify(WCC->disp_cal[WCC->num_cal - 1].cal);
+       WCC->disp_cal[WCC->num_cal - 1].cal_msgnum = msgnum;
 }
 
 
@@ -537,20 +500,20 @@ void display_edit_individual_task(icalcomponent *supplied_vtodo, long msgnum) {
        }
 
        output_headers(1, 1, 2, 0, 0, 0);
-       wprintf("<div id=\"banner\">\n"
-               "<TABLE WIDTH=100%% BORDER=0 BGCOLOR=\"#444455\"><TR>"
-               "<TD><img src=\"static/taskmanag_48x.gif\"></TD>"
-               "<td><SPAN CLASS=\"titlebar\">");
+       wprintf("<div id=\"banner\">\n");
+       wprintf("<img src=\"static/taskmanag_48x.gif\">");
+       wprintf("<h1>");
        wprintf(_("Edit task"));
-       wprintf("</SPAN>"
-               "</TD></TR></TABLE>\n"
-               "</div>\n<div id=\"content\">\n"
-       );
+       wprintf("</h1>");
+       wprintf("</div>\n");
+
+       wprintf("<div id=\"content\" class=\"service\">\n");
 
        wprintf("<div class=\"fix_scrollbar_bug\">"
-               "<table border=0 width=100%% bgcolor=\"#ffffff\"><tr><td>");
+               "<table class=\"calendar_background\"><tr><td>");
        
        wprintf("<FORM METHOD=\"POST\" action=\"save_task\">\n");
+       wprintf("<input type=\"hidden\" name=\"nonce\" value=\"%ld\">\n", WC->nonce);
        wprintf("<INPUT TYPE=\"hidden\" NAME=\"msgnum\" VALUE=\"%ld\">\n",
                msgnum);
 
@@ -665,7 +628,7 @@ void save_individual_task(icalcomponent *supplied_vtodo, long msgnum) {
                created_new_vtodo = 1;
        }
 
-       if (strlen(bstr("save_button")) > 0) {
+       if (!IsEmptyStr(bstr("save_button"))) {
 
                /** Replace values in the component with ones from the form */
 
@@ -674,9 +637,15 @@ void save_individual_task(icalcomponent *supplied_vtodo, long msgnum) {
                        icalcomponent_remove_property(vtodo, prop);
                        icalproperty_free(prop);
                }
-               icalcomponent_add_property(vtodo,
-                       icalproperty_new_summary(bstr("summary")));
-               
+               if (!IsEmptyStr(bstr("summary"))) {
+       
+                       icalcomponent_add_property(vtodo,
+                                       icalproperty_new_summary(bstr("summary")));
+               } else {
+                       icalcomponent_add_property(vtodo,
+                                       icalproperty_new_summary("Untitled Task"));
+               }
+       
                while (prop = icalcomponent_get_first_property(vtodo,
                      ICAL_DESCRIPTION_PROPERTY), prop != NULL) {
                        icalcomponent_remove_property(vtodo, prop);
@@ -738,7 +707,7 @@ void save_individual_task(icalcomponent *supplied_vtodo, long msgnum) {
                 * can't encapsulate something that may already be encapsulated
                 * somewhere else.
                 */
-               lprintf(9, "Encapsulating into full VCALENDAR component\n");
+               lprintf(9, "Encapsulating into full VCALENDAR component\n");
                encaps = ical_encapsulate_subcomponent(icalcomponent_new_clone(vtodo));
 
                /* Serialize it and save it to the message base */
@@ -763,7 +732,7 @@ void save_individual_task(icalcomponent *supplied_vtodo, long msgnum) {
        /**
         * If the user clicked 'Delete' then explicitly delete the message.
         */
-       if (strlen(bstr("delete_button")) > 0) {
+       if (!IsEmptyStr(bstr("delete_button"))) {
                delete_existing = 1;
        }
 
@@ -799,17 +768,18 @@ void display_using_handler(long msgnum,
                        icalcomponent_kind which_kind,
                        void (*callback)(icalcomponent *, long)
        ) {
-       char buf[SIZ];
-       char mime_partnum[SIZ];
-       char mime_filename[SIZ];
-       char mime_content_type[SIZ];
-       char mime_disposition[SIZ];
+       char buf[1024];
+       char mime_partnum[256];
+       char mime_filename[256];
+       char mime_content_type[256];
+       char mime_disposition[256];
        int mime_length;
-       char relevant_partnum[SIZ];
+       char relevant_partnum[256];
        char *relevant_source = NULL;
        icalcomponent *cal, *c;
 
-       sprintf(buf, "MSG0 %ld|1", msgnum);     /* ask for headers only */
+       relevant_partnum[0] = '\0';
+       sprintf(buf, "MSG4 %ld", msgnum);       /* we need the mime headers */
        serv_puts(buf);
        serv_getln(buf, sizeof buf);
        if (buf[0] != '1') return;
@@ -825,11 +795,14 @@ void display_using_handler(long msgnum,
                        if (!strcasecmp(mime_content_type, "text/calendar")) {
                                strcpy(relevant_partnum, mime_partnum);
                        }
+                       else if (!strcasecmp(mime_content_type, "text/vtodo")) {
+                               strcpy(relevant_partnum, mime_partnum);
+                       }
 
                }
        }
 
-       if (strlen(relevant_partnum) > 0) {
+       if (!IsEmptyStr(relevant_partnum)) {
                relevant_source = load_mimepart(msgnum, relevant_partnum);
                if (relevant_source != NULL) {
 
@@ -886,7 +859,7 @@ void display_edit_task(void) {
        long msgnum = 0L;
 
        /** Force change the room if we have to */
-       if (strlen(bstr("taskrm")) > 0) {
+       if (!IsEmptyStr(bstr("taskrm"))) {
                gotoroom(bstr("taskrm"));
        }
 
@@ -969,6 +942,7 @@ void do_freebusy(char *req) {
        char who[SIZ];
        char buf[SIZ];
        char *fb;
+       int len;
 
        extract_token(who, req, 1, ' ', sizeof who);
        if (!strncasecmp(who, "/freebusy/", 10)) {
@@ -976,10 +950,11 @@ void do_freebusy(char *req) {
        }
        unescape_input(who);
 
-       if ( (!strcasecmp(&who[strlen(who)-4], ".vcf"))
-          || (!strcasecmp(&who[strlen(who)-4], ".ifb"))
-          || (!strcasecmp(&who[strlen(who)-4], ".vfb")) ) {
-               who[strlen(who)-4] = 0;
+       len = strlen(who);
+       if ( (!strcasecmp(&who[len-4], ".vcf"))
+          || (!strcasecmp(&who[len-4], ".ifb"))
+          || (!strcasecmp(&who[len-4], ".vfb")) ) {
+               who[len-4] = 0;
        }
 
        lprintf(9, "freebusy requested for <%s>\n", who);