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