Began making changes to do better handling of character sets.
[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         char calhourformat[16];
56
57         get_preference("calhourformat", calhourformat, sizeof calhourformat);
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 (!strcasecmp(calhourformat, "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         time_t tt;
157         struct tm tm;
158         struct icaltimetype t2;
159
160         tt = time(NULL);
161         localtime_r(&tt, &tm);
162
163         sprintf(vname, "%s_month", prefix);     tm.tm_mon = atoi(bstr(vname)) - 1;
164         sprintf(vname, "%s_day", prefix);       tm.tm_mday = atoi(bstr(vname));
165         sprintf(vname, "%s_year", prefix);      tm.tm_year = atoi(bstr(vname)) - 1900;
166         sprintf(vname, "%s_hour", prefix);      tm.tm_hour = atoi(bstr(vname));
167         sprintf(vname, "%s_minute", prefix);    tm.tm_min = atoi(bstr(vname));
168
169         tt = mktime(&tm);
170         t2 = icaltime_from_timet(tt, 0);
171         memcpy(t, &t2, sizeof(struct icaltimetype));
172 }
173
174 /**
175  *\brief Get time from form
176  * get the time back from the user and convert it into internal structs.
177  * \param t our time element
178  * \param prefix whats that\todo ????
179  */
180
181 void icaltime_from_webform_dateonly(struct icaltimetype *t, char *prefix) {
182         char vname[32];
183
184         memset(t, 0, sizeof(struct icaltimetype));
185
186         sprintf(vname, "%s_month", prefix);     t->month = atoi(bstr(vname));
187         sprintf(vname, "%s_day", prefix);       t->day = atoi(bstr(vname));
188         sprintf(vname, "%s_year", prefix);      t->year = atoi(bstr(vname));
189         t->is_utc = 1;
190         t->is_date = 1;
191 }
192
193
194 /**
195  * \brief Render PAPSTAT
196  * Render a PARTSTAT parameter as a string (and put it in parentheses)
197  * \param buf the string to put it to
198  * \param attendee the attendee to textify
199  */
200 void partstat_as_string(char *buf, icalproperty *attendee) {
201         icalparameter *partstat_param;
202         icalparameter_partstat partstat;
203
204         strcpy(buf, _("(status unknown)"));
205
206         partstat_param = icalproperty_get_first_parameter(
207                                 attendee,
208                                 ICAL_PARTSTAT_PARAMETER
209         );
210         if (partstat_param == NULL) {
211                 return;
212         }
213
214         partstat = icalparameter_get_partstat(partstat_param);
215         switch(partstat) {
216                 case ICAL_PARTSTAT_X:
217                         strcpy(buf, "(x)");
218                         break;
219                 case ICAL_PARTSTAT_NEEDSACTION:
220                         strcpy(buf, _("(needs action)"));
221                         break;
222                 case ICAL_PARTSTAT_ACCEPTED:
223                         strcpy(buf, _("(accepted)"));
224                         break;
225                 case ICAL_PARTSTAT_DECLINED:
226                         strcpy(buf, _("(declined)"));
227                         break;
228                 case ICAL_PARTSTAT_TENTATIVE:
229                         strcpy(buf, _("(tenative)"));
230                         break;
231                 case ICAL_PARTSTAT_DELEGATED:
232                         strcpy(buf, _("(delegated)"));
233                         break;
234                 case ICAL_PARTSTAT_COMPLETED:
235                         strcpy(buf, _("(completed)"));
236                         break;
237                 case ICAL_PARTSTAT_INPROCESS:
238                         strcpy(buf, _("(in process)"));
239                         break;
240                 case ICAL_PARTSTAT_NONE:
241                         strcpy(buf, _("(none)"));
242                         break;
243         }
244 }
245
246
247 /**
248  * \brief embedd
249  * Utility function to encapsulate a subcomponent into a full VCALENDAR
250  * \param subcomp the component to encapsulate
251  * \returns the meta object ???
252  */
253 icalcomponent *ical_encapsulate_subcomponent(icalcomponent *subcomp) {
254         icalcomponent *encaps;
255
256         /* lprintf(9, "ical_encapsulate_subcomponent() called\n"); */
257
258         if (subcomp == NULL) {
259                 lprintf(3, "ERROR: called with NULL argument!\n");
260                 return NULL;
261         }
262
263         /**
264          * If we're already looking at a full VCALENDAR component,
265          * don't bother ... just return itself.
266          */
267         if (icalcomponent_isa(subcomp) == ICAL_VCALENDAR_COMPONENT) {
268                 return subcomp;
269         }
270
271         /** Encapsulate the VEVENT component into a complete VCALENDAR */
272         encaps = icalcomponent_new(ICAL_VCALENDAR_COMPONENT);
273         if (encaps == NULL) {
274                 lprintf(3, "%s:%d: Error - could not allocate component!\n",
275                         __FILE__, __LINE__);
276                 return NULL;
277         }
278
279         /** Set the Product ID */
280         icalcomponent_add_property(encaps, icalproperty_new_prodid(PRODID));
281
282         /** Set the Version Number */
283         icalcomponent_add_property(encaps, icalproperty_new_version("2.0"));
284
285         /** Encapsulate the subcomponent inside */
286         /* lprintf(9, "Doing the encapsulation\n"); */
287         icalcomponent_add_component(encaps, subcomp);
288
289         /** Convert all timestamps to UTC so we don't have to deal with
290          * stupid VTIMEZONE crap.
291          */
292         ical_dezonify(encaps);
293
294         /** Return the object we just created. */
295         return(encaps);
296 }
297
298
299
300
301 #endif
302 /*@}*/