edb17de924caf8ce698331de81e47f5e36331894
[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         time_t monthselect_time;
53         struct tm monthselect_tm;
54         char monthselect_str[32];
55         int time_format;
56         
57         time_format = get_time_format_cached ();
58
59         now = time(NULL);
60         localtime_r(&now, &tm_now);
61         this_year = tm_now.tm_year + 1900;
62
63         if (t == NULL) return;
64         if (t->is_date) all_day_event = 1;
65         tt = icaltime_as_timet(*t);
66         if (all_day_event) {
67                 gmtime_r(&tt, &tm);
68         }
69         else {
70                 localtime_r(&tt, &tm);
71         }
72
73         wprintf(_("Month: "));
74         wprintf("<SELECT NAME=\"%s_month\" SIZE=\"1\">\n", prefix);
75         for (i=0; i<=11; ++i) {
76                 monthselect_time = 1137997451 + (i * 2592000);
77                 localtime_r(&monthselect_time, &monthselect_tm);
78                 wc_strftime(monthselect_str, sizeof monthselect_str, "%B", &monthselect_tm);
79                 wprintf("<OPTION %s VALUE=\"%d\">%s</OPTION>\n",
80                         ((tm.tm_mon == i) ? "SELECTED" : ""),
81                         i+1,
82                         monthselect_str
83                 );
84         }
85         wprintf("</SELECT>\n");
86
87         wprintf(_("Day: "));
88         wprintf("<SELECT NAME=\"%s_day\" SIZE=\"1\">\n", prefix);
89         for (i=1; i<=31; ++i) {
90                 wprintf("<OPTION %s VALUE=\"%d\">%d</OPTION>\n",
91                         ((tm.tm_mday == i) ? "SELECTED" : ""),
92                         i, i
93                 );
94         }
95         wprintf("</SELECT>\n");
96
97         wprintf(_("Year: "));
98         wprintf("<SELECT NAME=\"%s_year\" SIZE=\"1\">\n", prefix);
99         if ((this_year - t->year) > span) {
100                 wprintf("<OPTION SELECTED VALUE=\"%d\">%d</OPTION>\n",
101                         t->year, t->year);
102         }
103         for (i=(this_year-span); i<=(this_year+span); ++i) {
104                 wprintf("<OPTION %s VALUE=\"%d\">%d</OPTION>\n",
105                         ((t->year == i) ? "SELECTED" : ""),
106                         i, i
107                 );
108         }
109         if ((t->year - this_year) > span) {
110                 wprintf("<OPTION SELECTED VALUE=\"%d\">%d</OPTION>\n",
111                         t->year, t->year);
112         }
113         wprintf("</SELECT>\n");
114
115         wprintf(_("Hour: "));
116         wprintf("<SELECT NAME=\"%s_hour\" SIZE=\"1\">\n", prefix);
117         for (i=0; i<=23; ++i) {
118
119         if (time_format == WC_TIMEFORMAT_24) {
120                         wprintf("<OPTION %s VALUE=\"%d\">%d</OPTION>\n",
121                                 ((tm.tm_hour == i) ? "SELECTED" : ""),
122                                 i, i
123                         );
124                 }
125                 else {
126                         wprintf("<OPTION %s VALUE=\"%d\">%s</OPTION>\n",
127                                 ((tm.tm_hour == i) ? "SELECTED" : ""),
128                                 i, hourname[i]
129                         );
130                 }
131
132         }
133         wprintf("</SELECT>\n");
134
135         wprintf(_("Minute: "));
136         wprintf("<SELECT NAME=\"%s_minute\" SIZE=\"1\">\n", prefix);
137         for (i=0; i<=59; ++i) {
138                 if ( (i % 5 == 0) || (tm.tm_min == i) ) {
139                         wprintf("<OPTION %s VALUE=\"%d\">:%02d</OPTION>\n",
140                                 ((tm.tm_min == i) ? "SELECTED" : ""),
141                                 i, i
142                         );
143                 }
144         }
145         wprintf("</SELECT>\n");
146 }
147
148 /**
149  *\brief Get time from form
150  * get the time back from the user and convert it into internal structs.
151  * \param t our time element
152  * \param prefix whats that\todo ????
153  */
154 void icaltime_from_webform(struct icaltimetype *t, char *prefix) {
155         char vname[32];
156         struct icaltimetype t2;
157         char timestr[32];
158         int month, mday, year, hour, minute;
159
160         sprintf(vname, "%s_month", prefix);     month = atoi(bstr(vname));
161         sprintf(vname, "%s_day", prefix);       mday = atoi(bstr(vname));
162         sprintf(vname, "%s_year", prefix);      year = atoi(bstr(vname));
163         sprintf(vname, "%s_hour", prefix);      hour = atoi(bstr(vname));
164         sprintf(vname, "%s_minute", prefix);    minute = atoi(bstr(vname));
165
166         sprintf(timestr, "%04d%02d%02dT%02d%02d00", year, month, mday, hour, minute);
167         t2 = icaltime_from_string(timestr);
168         memcpy(t, &t2, sizeof(struct icaltimetype));
169 }
170
171
172 /**
173  *\brief Get time from form
174  * get the time back from the user and convert it into internal structs.
175  * \param t our time element
176  * \param prefix whats that\todo ????
177  */
178
179 void icaltime_from_webform_dateonly(struct icaltimetype *t, char *prefix) {
180         char vname[32];
181
182         memset(t, 0, sizeof(struct icaltimetype));
183
184         sprintf(vname, "%s_month", prefix);     t->month = atoi(bstr(vname));
185         sprintf(vname, "%s_day", prefix);       t->day = atoi(bstr(vname));
186         sprintf(vname, "%s_year", prefix);      t->year = atoi(bstr(vname));
187         t->is_utc = 1;
188         t->is_date = 1;
189 }
190
191
192 /**
193  * \brief Render PAPSTAT
194  * Render a PARTSTAT parameter as a string (and put it in parentheses)
195  * \param buf the string to put it to
196  * \param attendee the attendee to textify
197  */
198 void partstat_as_string(char *buf, icalproperty *attendee) {
199         icalparameter *partstat_param;
200         icalparameter_partstat partstat;
201
202         strcpy(buf, _("(status unknown)"));
203
204         partstat_param = icalproperty_get_first_parameter(
205                                 attendee,
206                                 ICAL_PARTSTAT_PARAMETER
207         );
208         if (partstat_param == NULL) {
209                 return;
210         }
211
212         partstat = icalparameter_get_partstat(partstat_param);
213         switch(partstat) {
214                 case ICAL_PARTSTAT_X:
215                         strcpy(buf, "(x)");
216                         break;
217                 case ICAL_PARTSTAT_NEEDSACTION:
218                         strcpy(buf, _("(needs action)"));
219                         break;
220                 case ICAL_PARTSTAT_ACCEPTED:
221                         strcpy(buf, _("(accepted)"));
222                         break;
223                 case ICAL_PARTSTAT_DECLINED:
224                         strcpy(buf, _("(declined)"));
225                         break;
226                 case ICAL_PARTSTAT_TENTATIVE:
227                         strcpy(buf, _("(tenative)"));
228                         break;
229                 case ICAL_PARTSTAT_DELEGATED:
230                         strcpy(buf, _("(delegated)"));
231                         break;
232                 case ICAL_PARTSTAT_COMPLETED:
233                         strcpy(buf, _("(completed)"));
234                         break;
235                 case ICAL_PARTSTAT_INPROCESS:
236                         strcpy(buf, _("(in process)"));
237                         break;
238                 case ICAL_PARTSTAT_NONE:
239                         strcpy(buf, _("(none)"));
240                         break;
241         }
242 }
243
244
245 /**
246  * \brief embedd
247  * Utility function to encapsulate a subcomponent into a full VCALENDAR
248  * \param subcomp the component to encapsulate
249  * \returns the meta object ???
250  */
251 icalcomponent *ical_encapsulate_subcomponent(icalcomponent *subcomp) {
252         icalcomponent *encaps;
253
254         /* lprintf(9, "ical_encapsulate_subcomponent() called\n"); */
255
256         if (subcomp == NULL) {
257                 lprintf(3, "ERROR: called with NULL argument!\n");
258                 return NULL;
259         }
260
261         /**
262          * If we're already looking at a full VCALENDAR component,
263          * don't bother ... just return itself.
264          */
265         if (icalcomponent_isa(subcomp) == ICAL_VCALENDAR_COMPONENT) {
266                 return subcomp;
267         }
268
269         /** Encapsulate the VEVENT component into a complete VCALENDAR */
270         encaps = icalcomponent_new(ICAL_VCALENDAR_COMPONENT);
271         if (encaps == NULL) {
272                 lprintf(3, "%s:%d: Error - could not allocate component!\n",
273                         __FILE__, __LINE__);
274                 return NULL;
275         }
276
277         /** Set the Product ID */
278         icalcomponent_add_property(encaps, icalproperty_new_prodid(PRODID));
279
280         /** Set the Version Number */
281         icalcomponent_add_property(encaps, icalproperty_new_version("2.0"));
282
283         /** Encapsulate the subcomponent inside */
284         /* lprintf(9, "Doing the encapsulation\n"); */
285         icalcomponent_add_component(encaps, subcomp);
286
287         /** Convert all timestamps to UTC so we don't have to deal with
288          * stupid VTIMEZONE crap.
289          */
290         ical_dezonify(encaps);
291
292         /** Return the object we just created. */
293         return(encaps);
294 }
295
296
297
298
299 #endif
300 /*@}*/