]> code.citadel.org Git - citadel.git/blob - webcit/event.c
* Added even more nifty JavaScript to cause the hour/minute and end date
[citadel.git] / webcit / event.c
1 /*
2  * $Id$
3  *
4  * Editing calendar events.
5  *
6  */
7
8 #include <ctype.h>
9 #include <stdlib.h>
10 #include <unistd.h>
11 #include <stdio.h>
12 #include <fcntl.h>
13 #include <signal.h>
14 #include <sys/types.h>
15 #include <sys/wait.h>
16 #include <sys/socket.h>
17 #include <limits.h>
18 #include <netinet/in.h>
19 #include <netdb.h>
20 #include <string.h>
21 #include <pwd.h>
22 #include <errno.h>
23 #include <stdarg.h>
24 #include <pthread.h>
25 #include <signal.h>
26 #include <time.h>
27 #include "webcit.h"
28 #include "webserver.h"
29
30
31 #ifdef HAVE_ICAL_H
32
33
34 /*
35  * Display an event by itself (for editing)
36  */
37 void display_edit_individual_event(icalcomponent *supplied_vevent, long msgnum) {
38         icalcomponent *vevent;
39         icalproperty *p;
40         struct icaltimetype t_start, t_end;
41         time_t now;
42         int created_new_vevent = 0;
43
44         now = time(NULL);
45
46         if (supplied_vevent != NULL) {
47                 vevent = supplied_vevent;
48         }
49         else {
50                 vevent = icalcomponent_new(ICAL_VEVENT_COMPONENT);
51                 created_new_vevent = 1;
52         }
53
54         output_headers(3);
55         wprintf("<TABLE WIDTH=100%% BORDER=0 BGCOLOR=007700><TR><TD>"
56                 "<IMG ALIGN=CENTER SRC=\"/static/vcalendar.gif\">"
57                 "<FONT SIZE=+1 COLOR=\"FFFFFF\""
58                 "<B>Edit event</B>"
59                 "</FONT></TD></TR></TABLE><BR>\n"
60         );
61
62         /************************************************************
63          * Uncomment this to see the UID in calendar events for debugging
64         wprintf("UID == ");
65         p = icalcomponent_get_first_property(vevent, ICAL_UID_PROPERTY);
66         if (p != NULL) {
67                 escputs((char *)icalproperty_get_comment(p));
68         }
69         *************************************************************/
70
71         wprintf("<FORM NAME=\"EventForm\" METHOD=\"POST\" ACTION=\"/save_event\">\n");
72
73         wprintf("<INPUT TYPE=\"hidden\" NAME=\"msgnum\" VALUE=\"%ld\">\n",
74                 msgnum);
75         wprintf("<INPUT TYPE=\"hidden\" NAME=\"calview\" VALUE=\"%s\">\n",
76                 bstr("calview"));
77         wprintf("<INPUT TYPE=\"hidden\" NAME=\"year\" VALUE=\"%s\">\n",
78                 bstr("year"));
79         wprintf("<INPUT TYPE=\"hidden\" NAME=\"month\" VALUE=\"%s\">\n",
80                 bstr("month"));
81         wprintf("<INPUT TYPE=\"hidden\" NAME=\"day\" VALUE=\"%s\">\n",
82                 bstr("day"));
83
84         /* Put it in a borderless table so it lines up nicely */
85         wprintf("<TABLE border=0 width=100%%>\n");
86
87         wprintf("<TR><TD><B>Summary</B></TD><TD>\n"
88                 "<INPUT TYPE=\"text\" NAME=\"summary\" "
89                 "MAXLENGTH=\"64\" SIZE=\"64\" VALUE=\"");
90         p = icalcomponent_get_first_property(vevent, ICAL_SUMMARY_PROPERTY);
91         if (p != NULL) {
92                 escputs((char *)icalproperty_get_comment(p));
93         }
94         wprintf("\"></TD></TR>\n");
95
96         wprintf("<TR><TD><B>Location</B></TD><TD>\n"
97                 "<INPUT TYPE=\"text\" NAME=\"location\" "
98                 "MAXLENGTH=\"64\" SIZE=\"64\" VALUE=\"");
99         p = icalcomponent_get_first_property(vevent, ICAL_LOCATION_PROPERTY);
100         if (p != NULL) {
101                 escputs((char *)icalproperty_get_comment(p));
102         }
103         wprintf("\"></TD></TR>\n");
104
105         wprintf("<TR><TD><B>Start</B></TD><TD>\n");
106         p = icalcomponent_get_first_property(vevent, ICAL_DTSTART_PROPERTY);
107         if (p != NULL) {
108                 t_start = icalproperty_get_dtstart(p);
109                 if (t_start.is_date) {
110                         t_start.hour = 0;
111                         t_start.minute = 0;
112                         t_start.second = 0;
113                 }
114         }
115         else {
116                 t_start = icaltime_from_timet(now, 0);
117         }
118         display_icaltimetype_as_webform(&t_start, "dtstart");
119
120         wprintf("<INPUT TYPE=\"checkbox\" NAME=\"alldayevent\" "
121                 "VALUE=\"yes\" onClick=\"
122
123                         if (this.checked) {
124                                 this.form.dtstart_hour.value='0';
125                                 this.form.dtstart_hour.disabled = true;
126                                 this.form.dtstart_minute.value='0';
127                                 this.form.dtstart_minute.disabled = true;
128                                 this.form.dtend_hour.value='0';
129                                 this.form.dtend_hour.disabled = true;
130                                 this.form.dtend_minute.value='0';
131                                 this.form.dtend_minute.disabled = true;
132                                 this.form.dtend_month.disabled = true;
133                                 this.form.dtend_day.disabled = true;
134                                 this.form.dtend_year.disabled = true;
135                         }
136                         else {
137                                 this.form.dtstart_hour.disabled = false;
138                                 this.form.dtstart_minute.disabled = false;
139                                 this.form.dtend_hour.disabled = false;
140                                 this.form.dtend_minute.disabled = false;
141                                 this.form.dtend_month.disabled = false;
142                                 this.form.dtend_day.disabled = false;
143                                 this.form.dtend_year.disabled = false;
144                         }
145
146
147                 \" %s >All day event",
148                 (t_start.is_date ? "CHECKED" : "" )
149         );
150
151         wprintf("</TD></TR>\n");
152
153         /* If this is an all-day-event, set the end time to be identical to
154          * the start time (the hour/minute/second will be set to midnight).
155          * Otherwise extract or create it.
156          */
157         wprintf("<TR><TD><B>End</B></TD><TD>\n");
158         if (t_start.is_date) {
159                 t_end = t_start;
160         }
161         else {
162                 p = icalcomponent_get_first_property(vevent,
163                                                         ICAL_DTEND_PROPERTY);
164                 if (p != NULL) {
165                         t_end = icalproperty_get_dtend(p);
166                 }
167                 else {
168                         t_end = icaltime_from_timet(now, 0);
169                 }
170         }
171         display_icaltimetype_as_webform(&t_end, "dtend");
172         wprintf("</TD></TR>\n");
173
174         wprintf("<TR><TD><B>Notes</B></TD><TD>\n"
175                 "<TEXTAREA NAME=\"description\" wrap=soft "
176                 "ROWS=10 COLS=80 WIDTH=80>\n"
177         );
178         p = icalcomponent_get_first_property(vevent, ICAL_DESCRIPTION_PROPERTY);
179         if (p != NULL) {
180                 escputs((char *)icalproperty_get_comment(p));
181         }
182         wprintf("</TEXTAREA></TD></TR></TABLE>\n");
183
184         wprintf("<CENTER>"
185                 "<INPUT TYPE=\"submit\" NAME=\"sc\" VALUE=\"Save\">"
186                 "&nbsp;&nbsp;"
187                 "<INPUT TYPE=\"submit\" NAME=\"sc\" VALUE=\"Delete\">\n"
188                 "&nbsp;&nbsp;"
189                 "<INPUT TYPE=\"submit\" NAME=\"sc\" VALUE=\"Cancel\">\n"
190                 "</CENTER>\n"
191         );
192
193         wprintf("</FORM>\n");
194         
195         wprintf("<SCRIPT language=\"javascript\">
196                 <!--
197
198                         if (document.EventForm.alldayevent.checked) {
199                                 document.EventForm.dtstart_hour.value='0';
200                                 document.EventForm.dtstart_hour.disabled = true;
201                                 document.EventForm.dtstart_minute.value='0';
202                                 document.EventForm.dtstart_minute.disabled = true;
203                                 document.EventForm.dtend_hour.value='0';
204                                 document.EventForm.dtend_hour.disabled = true;
205                                 document.EventForm.dtend_minute.value='0';
206                                 document.EventForm.dtend_minute.disabled = true;
207                                 document.EventForm.dtend_month.disabled = true;
208                                 document.EventForm.dtend_day.disabled = true;
209                                 document.EventForm.dtend_year.disabled = true;
210                         }
211                         else {
212                                 document.EventForm.dtstart_hour.disabled = false;
213                                 document.EventForm.dtstart_minute.disabled = false;
214                                 document.EventForm.dtend_hour.disabled = false;
215                                 document.EventForm.dtend_minute.disabled = false;
216                                 document.EventForm.dtend_month.disabled = false;
217                                 document.EventForm.dtend_day.disabled = false;
218                                 document.EventForm.dtend_year.disabled = false;
219                         }
220                 //-->
221                 </SCRIPT>
222         ");
223
224         wDumpContent(1);
225
226         if (created_new_vevent) {
227                 icalcomponent_free(vevent);
228         }
229 }
230
231 /*
232  * Save an edited event
233  */
234 void save_individual_event(icalcomponent *supplied_vevent, long msgnum) {
235         char buf[SIZ];
236         int delete_existing = 0;
237         icalproperty *prop;
238         icalcomponent *vevent;
239         int created_new_vevent = 0;
240         int all_day_event = 0;
241         struct icaltimetype event_start;
242
243         if (supplied_vevent != NULL) {
244                 vevent = supplied_vevent;
245         }
246         else {
247                 vevent = icalcomponent_new(ICAL_VEVENT_COMPONENT);
248                 created_new_vevent = 1;
249         }
250
251         if (!strcasecmp(bstr("sc"), "Save")) {
252
253                 /* Replace values in the component with ones from the form */
254
255                 while (prop = icalcomponent_get_first_property(vevent,
256                       ICAL_SUMMARY_PROPERTY), prop != NULL) {
257                         icalcomponent_remove_property(vevent, prop);
258                 }
259                 icalcomponent_add_property(vevent,
260                         icalproperty_new_summary(bstr("summary")));
261                 
262                 while (prop = icalcomponent_get_first_property(vevent,
263                       ICAL_LOCATION_PROPERTY), prop != NULL) {
264                         icalcomponent_remove_property(vevent, prop);
265                 }
266                 icalcomponent_add_property(vevent,
267                         icalproperty_new_location(bstr("location")));
268                 
269                 while (prop = icalcomponent_get_first_property(vevent,
270                       ICAL_DESCRIPTION_PROPERTY), prop != NULL) {
271                         icalcomponent_remove_property(vevent, prop);
272                 }
273                 icalcomponent_add_property(vevent,
274                         icalproperty_new_description(bstr("description")));
275         
276                 while (prop = icalcomponent_get_first_property(vevent,
277                       ICAL_DTSTART_PROPERTY), prop != NULL) {
278                         icalcomponent_remove_property(vevent, prop);
279                 }
280
281                 if (!strcmp(bstr("alldayevent"), "yes")) {
282                         all_day_event = 1;
283                         lprintf(9, "*** all day event ***\n");
284                 }
285                 else {
286                         all_day_event = 0;
287                 }
288
289                 event_start = icaltime_from_webform("dtstart");
290                 if (all_day_event) {
291                         event_start.is_date = 1;
292                         event_start.hour = 0;
293                         event_start.minute = 0;
294                         event_start.second = 0;
295                 }
296
297
298                 /* The following odd-looking snippet of code looks like it
299                  * takes some unnecessary steps.  It is done this way because
300                  * libical incorrectly turns an "all day event" into a normal
301                  * event starting at midnight (i.e. it serializes as date/time
302                  * instead of just date) unless icalvalue_new_date() is used.
303                  * So we force it, if this is an all day event.
304                  */
305                 prop = icalproperty_new_dtstart(event_start);
306                 if (all_day_event) {
307                         icalproperty_set_value(prop,
308                                 icalvalue_new_date(event_start)
309                         );
310                 }
311
312                 if (prop) icalcomponent_add_property(vevent, prop);
313                 else icalproperty_free(prop);
314
315
316
317                 while (prop = icalcomponent_get_first_property(vevent,
318                       ICAL_DTEND_PROPERTY), prop != NULL) {
319                         icalcomponent_remove_property(vevent, prop);
320                 }
321                 while (prop = icalcomponent_get_first_property(vevent,
322                       ICAL_DURATION_PROPERTY), prop != NULL) {
323                         icalcomponent_remove_property(vevent, prop);
324                 }
325
326                 if (all_day_event == 0) {
327                         icalcomponent_add_property(vevent,
328                                 icalproperty_new_dtend(icaltime_normalize(
329                                         icaltime_from_webform("dtend"))
330                                 )
331                         );
332                 }
333
334                 /* Give this event a UID if it doesn't have one. */
335                 if (icalcomponent_get_first_property(vevent,
336                    ICAL_UID_PROPERTY) == NULL) {
337                         generate_new_uid(buf);
338                         icalcomponent_add_property(vevent,
339                                 icalproperty_new_uid(buf)
340                         );
341                 }
342
343                 /* Serialize it and save it to the message base */
344                 serv_puts("ENT0 1|||4");
345                 serv_gets(buf);
346                 if (buf[0] == '4') {
347                         serv_puts("Content-type: text/calendar");
348                         serv_puts("");
349                         serv_puts(icalcomponent_as_ical_string(vevent));
350                         serv_puts("000");
351                         delete_existing = 1;
352                 }
353         }
354
355         /*
356          * If the user clicked 'Delete' then delete it, period.
357          */
358         if (!strcasecmp(bstr("sc"), "Delete")) {
359                 delete_existing = 1;
360         }
361
362         if ( (delete_existing) && (msgnum > 0L) ) {
363                 serv_printf("DELE %ld", atol(bstr("msgnum")));
364                 serv_gets(buf);
365         }
366
367         if (created_new_vevent) {
368                 icalcomponent_free(vevent);
369         }
370
371         /* Go back to the event list */
372         readloop("readfwd");
373 }
374
375
376 #endif /* HAVE_ICAL_H */