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