converted comments to get caught by doxygen
[citadel.git] / webcit / calendar_tools.c
1 /*
2  * $Id$
3  */
4 /**
5  * \defgroup MiscCal Miscellaneous functions which handle calendar components.
6  */
7 /*@{*/
8 #include "webcit.h"
9 #include "webserver.h"
10
11 /* \todo FIXME ... this needs to be internationalized */
12 /** Month Strings. */
13 char *months[] = { 
14         "January",
15         "February",
16         "March",
17         "April",
18         "May",
19         "June",
20         "July",
21         "August",
22         "September",
23         "October",
24         "November",
25         "December"
26 };
27
28 /** Day Strings */
29 char *days[] = { 
30         "Sunday",
31         "Monday",
32         "Tuesday",
33         "Wednesday",
34         "Thursday",
35         "Friday",
36         "Saturday"
37 };
38
39 /** Hour strings */
40 char *hourname[] = {
41         "12am", "1am", "2am", "3am", "4am", "5am", "6am",
42         "7am", "8am", "9am", "10am", "11am", "12pm",
43         "1pm", "2pm", "3pm", "4pm", "5pm", "6pm",
44         "7pm", "8pm", "9pm", "10pm", "11pm"
45 };
46
47 #ifdef WEBCIT_WITH_CALENDAR_SERVICE
48
49 /**
50  * \brief display and edit date/time
51  * The display_icaltimetype_as_webform() and icaltime_from_webform() functions
52  * handle the display and editing of date/time properties in web pages.  The
53  * first one converts an icaltimetype into valid HTML markup -- a series of form
54  * fields for editing the date and time.  When the user submits the form, the
55  * results can be fed back into the second function, which turns it back into
56  * an icaltimetype.  The "prefix" string required by both functions is prepended
57  * to all field names.  This allows a form to contain more than one date/time
58  * property (for example, a start and end time) by ensuring the field names are
59  * unique within the form.
60  *
61  * \todo NOTE: These functions assume that the icaltimetype being edited is in UTC, and
62  * will convert to/from local time for editing.  "local" in this case is assumed
63  * to be the time zone in which the WebCit server is running.  A future improvement
64  * might be to allow the user to specify his/her timezone.
65  * \param t the time we want to parse
66  * \param prefix ???? \todo
67  */
68
69
70 void display_icaltimetype_as_webform(struct icaltimetype *t, char *prefix) {
71         int i;
72         time_t now;
73         struct tm tm_now;
74         int this_year;
75         time_t tt;
76         struct tm tm;
77         const int span = 10;
78         int all_day_event = 0;
79         char calhourformat[16];
80
81         get_preference("calhourformat", calhourformat, sizeof calhourformat);
82
83         now = time(NULL);
84         localtime_r(&now, &tm_now);
85         this_year = tm_now.tm_year + 1900;
86
87         if (t == NULL) return;
88         if (t->is_date) all_day_event = 1;
89         tt = icaltime_as_timet(*t);
90         if (all_day_event) {
91                 gmtime_r(&tt, &tm);
92         }
93         else {
94                 localtime_r(&tt, &tm);
95         }
96
97         wprintf(_("Month: "));
98         wprintf("<SELECT NAME=\"%s_month\" SIZE=\"1\">\n", prefix);
99         for (i=0; i<=11; ++i) {
100                 wprintf("<OPTION %s VALUE=\"%d\">%s</OPTION>\n",
101                         ((tm.tm_mon == i) ? "SELECTED" : ""),
102                         i+1,
103                         months[i]
104                 );
105         }
106         wprintf("</SELECT>\n");
107
108         wprintf(_("Day: "));
109         wprintf("<SELECT NAME=\"%s_day\" SIZE=\"1\">\n", prefix);
110         for (i=1; i<=31; ++i) {
111                 wprintf("<OPTION %s VALUE=\"%d\">%d</OPTION>\n",
112                         ((tm.tm_mday == i) ? "SELECTED" : ""),
113                         i, i
114                 );
115         }
116         wprintf("</SELECT>\n");
117
118         wprintf(_("Year: "));
119         wprintf("<SELECT NAME=\"%s_year\" SIZE=\"1\">\n", prefix);
120         if ((this_year - t->year) > span) {
121                 wprintf("<OPTION SELECTED VALUE=\"%d\">%d</OPTION>\n",
122                         t->year, t->year);
123         }
124         for (i=(this_year-span); i<=(this_year+span); ++i) {
125                 wprintf("<OPTION %s VALUE=\"%d\">%d</OPTION>\n",
126                         ((t->year == i) ? "SELECTED" : ""),
127                         i, i
128                 );
129         }
130         if ((t->year - this_year) > span) {
131                 wprintf("<OPTION SELECTED VALUE=\"%d\">%d</OPTION>\n",
132                         t->year, t->year);
133         }
134         wprintf("</SELECT>\n");
135
136         wprintf(_("Hour: "));
137         wprintf("<SELECT NAME=\"%s_hour\" SIZE=\"1\">\n", prefix);
138         for (i=0; i<=23; ++i) {
139
140                 if (!strcasecmp(calhourformat, "24")) {
141                         wprintf("<OPTION %s VALUE=\"%d\">%d</OPTION>\n",
142                                 ((tm.tm_hour == i) ? "SELECTED" : ""),
143                                 i, i
144                         );
145                 }
146                 else {
147                         wprintf("<OPTION %s VALUE=\"%d\">%s</OPTION>\n",
148                                 ((tm.tm_hour == i) ? "SELECTED" : ""),
149                                 i, hourname[i]
150                         );
151                 }
152
153         }
154         wprintf("</SELECT>\n");
155
156         wprintf(_("Minute: "));
157         wprintf("<SELECT NAME=\"%s_minute\" SIZE=\"1\">\n", prefix);
158         for (i=0; i<=59; ++i) {
159                 if ( (i % 5 == 0) || (tm.tm_min == i) ) {
160                         wprintf("<OPTION %s VALUE=\"%d\">:%02d</OPTION>\n",
161                                 ((tm.tm_min == i) ? "SELECTED" : ""),
162                                 i, i
163                         );
164                 }
165         }
166         wprintf("</SELECT>\n");
167 }
168
169 /**
170  *\brief Get time from form
171  * get the time back from the user and convert it into internal structs.
172  * \param t our time element
173  * \param prefix whats that\todo ????
174  */
175 void icaltime_from_webform(struct icaltimetype *t, char *prefix) {
176         char vname[32];
177         time_t tt;
178         struct tm tm;
179         struct icaltimetype t2;
180
181         tt = time(NULL);
182         localtime_r(&tt, &tm);
183
184         sprintf(vname, "%s_month", prefix);     tm.tm_mon = atoi(bstr(vname)) - 1;
185         sprintf(vname, "%s_day", prefix);       tm.tm_mday = atoi(bstr(vname));
186         sprintf(vname, "%s_year", prefix);      tm.tm_year = atoi(bstr(vname)) - 1900;
187         sprintf(vname, "%s_hour", prefix);      tm.tm_hour = atoi(bstr(vname));
188         sprintf(vname, "%s_minute", prefix);    tm.tm_min = atoi(bstr(vname));
189
190         tt = mktime(&tm);
191         t2 = icaltime_from_timet(tt, 0);
192         memcpy(t, &t2, sizeof(struct icaltimetype));
193 }
194
195 /**
196  *\brief Get time from form
197  * get the time back from the user and convert it into internal structs.
198  * \param t our time element
199  * \param prefix whats that\todo ????
200  */
201
202 void icaltime_from_webform_dateonly(struct icaltimetype *t, char *prefix) {
203         char vname[32];
204
205         memset(t, 0, sizeof(struct icaltimetype));
206
207         sprintf(vname, "%s_month", prefix);     t->month = atoi(bstr(vname));
208         sprintf(vname, "%s_day", prefix);       t->day = atoi(bstr(vname));
209         sprintf(vname, "%s_year", prefix);      t->year = atoi(bstr(vname));
210         t->is_utc = 1;
211         t->is_date = 1;
212 }
213
214
215 /**
216  * \brief Render PAPSTAT
217  * Render a PARTSTAT parameter as a string (and put it in parentheses)
218  * \param buf the string to put it to
219  * \param attendee the attendee to textify
220  */
221 void partstat_as_string(char *buf, icalproperty *attendee) {
222         icalparameter *partstat_param;
223         icalparameter_partstat partstat;
224
225         strcpy(buf, _("(status unknown)"));
226
227         partstat_param = icalproperty_get_first_parameter(
228                                 attendee,
229                                 ICAL_PARTSTAT_PARAMETER
230         );
231         if (partstat_param == NULL) {
232                 return;
233         }
234
235         partstat = icalparameter_get_partstat(partstat_param);
236         switch(partstat) {
237                 case ICAL_PARTSTAT_X:
238                         strcpy(buf, "(x)");
239                         break;
240                 case ICAL_PARTSTAT_NEEDSACTION:
241                         strcpy(buf, _("(needs action)"));
242                         break;
243                 case ICAL_PARTSTAT_ACCEPTED:
244                         strcpy(buf, _("(accepted)"));
245                         break;
246                 case ICAL_PARTSTAT_DECLINED:
247                         strcpy(buf, _("(declined)"));
248                         break;
249                 case ICAL_PARTSTAT_TENTATIVE:
250                         strcpy(buf, _("(tenative)"));
251                         break;
252                 case ICAL_PARTSTAT_DELEGATED:
253                         strcpy(buf, _("(delegated)"));
254                         break;
255                 case ICAL_PARTSTAT_COMPLETED:
256                         strcpy(buf, _("(completed)"));
257                         break;
258                 case ICAL_PARTSTAT_INPROCESS:
259                         strcpy(buf, _("(in process)"));
260                         break;
261                 case ICAL_PARTSTAT_NONE:
262                         strcpy(buf, _("(none)"));
263                         break;
264         }
265 }
266
267
268 /**
269  * \brief embedd
270  * Utility function to encapsulate a subcomponent into a full VCALENDAR
271  * \param subcomp the component to encapsulate
272  * \returns the meta object ???
273  */
274 icalcomponent *ical_encapsulate_subcomponent(icalcomponent *subcomp) {
275         icalcomponent *encaps;
276
277         /* lprintf(9, "ical_encapsulate_subcomponent() called\n"); */
278
279         if (subcomp == NULL) {
280                 lprintf(3, "ERROR: called with NULL argument!\n");
281                 return NULL;
282         }
283
284         /**
285          * If we're already looking at a full VCALENDAR component,
286          * don't bother ... just return itself.
287          */
288         if (icalcomponent_isa(subcomp) == ICAL_VCALENDAR_COMPONENT) {
289                 return subcomp;
290         }
291
292         /** Encapsulate the VEVENT component into a complete VCALENDAR */
293         encaps = icalcomponent_new(ICAL_VCALENDAR_COMPONENT);
294         if (encaps == NULL) {
295                 lprintf(3, "%s:%d: Error - could not allocate component!\n",
296                         __FILE__, __LINE__);
297                 return NULL;
298         }
299
300         /** Set the Product ID */
301         icalcomponent_add_property(encaps, icalproperty_new_prodid(PRODID));
302
303         /** Set the Version Number */
304         icalcomponent_add_property(encaps, icalproperty_new_version("2.0"));
305
306         /** Encapsulate the subcomponent inside */
307         /* lprintf(9, "Doing the encapsulation\n"); */
308         icalcomponent_add_component(encaps, subcomp);
309
310         /** Convert all timestamps to UTC so we don't have to deal with
311          * stupid VTIMEZONE crap.
312          */
313         ical_dezonify(encaps);
314
315         /** Return the object we just created. */
316         return(encaps);
317 }
318
319
320
321
322 #endif
323 /*@}*/