4 * Manage user preferences with a little help from the Citadel server.
12 inline const char *PrintPref(void *Prefstr)
14 return ChrPtr(Prefstr);
18 * display preferences dialog
20 void load_preferences(void) {
25 serv_printf("GOTO %s", USERCONFIGROOM);
26 serv_getln(buf, sizeof buf);
27 if (buf[0] != '2') return;
29 serv_puts("MSGS ALL|0|1");
30 serv_getln(buf, sizeof buf);
32 serv_puts("subj|__ WebCit Preferences __");
35 while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
40 serv_printf("MSG0 %ld", msgnum);
41 serv_getln(buf, sizeof buf);
43 ReadBuf = NewStrBuf();
44 while (StrBuf_ServGetln(ReadBuf),
45 (strcmp(ChrPtr(ReadBuf), "text") &&
46 strcmp(ChrPtr(ReadBuf), "000"))) {
48 if (!strcmp(ChrPtr(ReadBuf), "text")) {
51 StrBuf *LastData = NULL;
54 while (StrBuf_ServGetln(ReadBuf),
55 strcmp(ChrPtr(ReadBuf), "000"))
57 if ((ChrPtr(ReadBuf)[0] == ' ') &&
59 StrBufAppendBuf(Data, ReadBuf, 1);
62 LastData = Data = NewStrBuf();
63 StrBufExtract_token(Key, ReadBuf, 0, '|');
64 StrBufExtract_token(Data, ReadBuf, 1, '|');
65 if (!IsEmptyStr(ChrPtr(Key)))
68 ChrPtr(Key), StrLength(Key),
85 /* Go back to the room we're supposed to be in */
86 serv_printf("GOTO %s", WC->wc_roomname);
87 serv_getln(buf, sizeof buf);
91 * \brief Goto the user's configuration room, creating it if necessary.
92 * \return 0 on success or nonzero upon failure.
94 int goto_config_room(void) {
97 serv_printf("GOTO %s", USERCONFIGROOM);
98 serv_getln(buf, sizeof buf);
99 if (buf[0] != '2') { /* try to create the config room if not there */
100 serv_printf("CRE8 1|%s|4|0", USERCONFIGROOM);
101 serv_getln(buf, sizeof buf);
102 serv_printf("GOTO %s", USERCONFIGROOM);
103 serv_getln(buf, sizeof buf);
104 if (buf[0] != '2') return(1);
110 * \brief save the modifications
112 void save_preferences(void) {
116 if (goto_config_room() != 0) return; /* oh well. */
117 serv_puts("MSGS ALL|0|1");
118 serv_getln(buf, sizeof buf);
120 serv_puts("subj|__ WebCit Preferences __");
123 while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
128 serv_printf("DELE %ld", msgnum);
129 serv_getln(buf, sizeof buf);
132 serv_printf("ENT0 1||0|1|__ WebCit Preferences __|");
133 serv_getln(buf, sizeof buf);
141 StrBuf *SubBuf = NULL;
143 Hash = WC->hash_prefs;
144 dbg_PrintHash(Hash, PrintPref, NULL);
145 HashPos = GetNewHashPos();
146 while (GetNextHashPos(Hash, HashPos, &len, &Key, &Value)!=0)
149 Buf = (StrBuf*) Value;
152 nchars = StrLength(Buf);
155 size_t offset, nchars;
157 SubBuf = NewStrBuf();
166 nchars = StrBufSub(SubBuf, Buf, offset, nchars);
169 serv_printf("%s|%s", Key, ChrPtr(SubBuf));
171 serv_printf(" %s", ChrPtr(SubBuf));
174 nchars = StrLength(Buf) - offset;
180 serv_printf("%s|%s", Key, ChrPtr(Buf));
187 DeleteHashPos(&HashPos);
190 /** Go back to the room we're supposed to be in */
191 serv_printf("GOTO %s", WC->wc_roomname);
192 serv_getln(buf, sizeof buf);
196 * \brief query the actual setting of key in the citadel database
197 * \param key config key to query
198 * \param keylen length of the key string
199 * \param value StrBuf-value to the key to get
202 int get_PREFERENCE(const char *key, size_t keylen, StrBuf **value)
204 void *hash_value = NULL;
206 dbg_PrintHash(WC->hash_prefs, PrintPref, NULL);
207 if (GetHash(WC->hash_prefs, key, keylen, &hash_value) == 0) {
213 *value = (StrBuf*) hash_value;
219 * \brief Write a key into the webcit preferences database for this user
221 * \params key key whichs value is to be modified
222 * \param keylen length of the key string
223 * \param value value to set
224 * \param save_to_server 1 = flush all data to the server, 0 = cache it for now
226 void set_PREFERENCE(const char *key, size_t keylen, StrBuf *value, int save_to_server) {
228 Put(WC->hash_prefs, key, keylen, value, HFreeStrBuf);
230 if (save_to_server) save_preferences();
233 int get_PREF_LONG(const char *key, size_t keylen, long *value, long Default)
237 ret = get_PREFERENCE(key, keylen, &val);
239 *value = atol(ChrPtr(val));
249 void set_PREF_LONG(const char *key, size_t keylen, long value, int save_to_server)
252 if (get_PREFERENCE(key, keylen, &val)) {
253 StrBufPrintf(val, "%ld", value);
257 StrBufPrintf(val, "%ld", value);
258 set_PREFERENCE(key, keylen, val, save_to_server);
264 int get_PREF_YESNO(const char *key, size_t keylen, int *value, int Default)
268 ret = get_PREFERENCE(key, keylen, &val);
270 *value = strcmp(ChrPtr(val), "yes") == 0;
279 void set_PREF_YESNO(const char *key, size_t keylen, int value, int save_to_server)
282 if (get_PREFERENCE(key, keylen, &val)) {
283 StrBufPrintf(val, "%s", (value)?"yes":"no");
287 StrBufPrintf(val, "%s", (value)?"yes":"no");
288 set_PREFERENCE(key, keylen, val, save_to_server);
293 * \brief display form for changing your preferences and settings
295 void display_preferences(void)
297 output_headers(1, 1, 1, 0, 0, 0);
300 long DayEnd, DayStart, WeekStart;
301 int UseSig, ShowEmptyFloors;
309 time_format = get_time_format_cached ();
311 wprintf("<div class=\"box\">\n");
312 wprintf("<div class=\"boxlabel\">");
313 wprintf(_("Preferences and settings"));
316 wprintf("<div class=\"boxcontent\">");
319 wprintf("<form name=\"prefform\" action=\"set_preferences\" "
320 "method=\"post\">\n");
321 wprintf("<input type=\"hidden\" name=\"nonce\" value=\"%d\">\n", WC->nonce);
324 wprintf("<table class=\"altern\">\n");
329 get_preference("roomlistview", &Buf);
330 wprintf("<tr class=\"even\"><td>");
331 wprintf(_("Room list view"));
332 wprintf("</td><td>");
334 wprintf("<input type=\"radio\" name=\"roomlistview\" VALUE=\"folders\"");
335 if (!strcasecmp(ChrPtr(Buf), "folders")) wprintf(" checked");
337 wprintf(_("Tree (folders) view"));
338 wprintf("</input> ");
340 wprintf("<input type=\"radio\" name=\"roomlistview\" VALUE=\"rooms\"");
341 if (IsEmptyStr(ChrPtr(Buf)) || !strcasecmp(ChrPtr(Buf), "rooms")) wprintf(" checked");
343 wprintf(_("Table (rooms) view"));
344 wprintf("</input>\n");
346 wprintf("</td></tr>\n");
352 wprintf("<tr class=\"odd\"><td>");
353 wprintf(_("Time format"));
354 wprintf("</td><td>");
356 wprintf("<input type=\"radio\" name=\"calhourformat\" VALUE=\"12\"");
357 if (time_format == WC_TIMEFORMAT_AMPM)
360 wprintf(_("12 hour (am/pm)"));
361 wprintf("</input> ");
363 wprintf("<input type=\"radio\" name=\"calhourformat\" VALUE=\"24\"");
364 if (time_format == WC_TIMEFORMAT_24)
367 wprintf(_("24 hour"));
368 wprintf("</input>\n");
370 wprintf("</td></tr>\n");
373 * Calendar day view -- day start time
375 get_pref_long("daystart", &DayStart, 8);
377 wprintf("<tr class=\"even\"><td>");
378 wprintf(_("Calendar day view begins at:"));
379 wprintf("</td><td>");
381 wprintf("<select name=\"daystart\" size=\"1\">\n");
382 for (i=0; i<=23; ++i) {
384 if (time_format == WC_TIMEFORMAT_24) {
385 wprintf("<option %s value=\"%d\">%d:00</option>\n",
386 ((DayStart == i) ? "selected" : ""),
391 wprintf("<option %s value=\"%d\">%s</option>\n",
392 ((DayStart == i) ? "selected" : ""),
398 wprintf("</select>\n");
399 wprintf("</td></tr>\n");
402 * Calendar day view -- day end time
404 get_pref_long("dayend", &DayEnd, 17);
406 wprintf("<tr class=\"odd\"><td>");
407 wprintf(_("Calendar day view ends at:"));
408 wprintf("</td><td>");
410 wprintf("<select name=\"dayend\" size=\"1\">\n");
411 for (i=0; i<=23; ++i) {
413 if (time_format == WC_TIMEFORMAT_24) {
414 wprintf("<option %s value=\"%d\">%d:00</option>\n",
415 ((DayEnd == i) ? "selected" : ""),
420 wprintf("<option %s value=\"%d\">%s</option>\n",
421 ((DayEnd == i) ? "selected" : ""),
427 wprintf("</select>\n");
428 wprintf("</td></tr>\n");
431 * Day of week to begin calendar month view
433 get_pref_long("weekstart", &WeekStart, 17);
434 wprintf("<tr class=\"even\"><td>");
435 wprintf(_("Week starts on:"));
436 wprintf("</td><td>");
438 wprintf("<select name=\"weekstart\" size=\"1\">\n");
440 for (i=0; i<=1; ++i) {
442 localtime_r(&tt, &tm);
444 wc_strftime(daylabel, sizeof daylabel, "%A", &tm);
446 wprintf("<option %s value=\"%d\">%s</option>\n",
447 ((WeekStart == i) ? "selected" : ""),
452 wprintf("</select>\n");
453 wprintf("</td></tr>\n");
458 get_pref_yesno("use_sig", &UseSig, 0);
459 wprintf("<tr class=\"odd\"><td>");
460 wprintf(_("Attach signature to email messages?"));
461 wprintf("</td><td>");
463 wprintf(" <script type=\"text/javascript\"> "
464 " function show_or_hide_sigbox() { "
465 " if ( $F('yes_sig') ) { "
466 " $('signature_box').style.display = 'inline'; "
469 " $('signature_box').style.display = 'none'; "
475 wprintf("<input type=\"radio\" id=\"no_sig\" name=\"use_sig\" VALUE=\"no\"");
476 if (!UseSig) wprintf(" checked");
477 wprintf(" onChange=\"show_or_hide_sigbox();\" >");
478 wprintf(_("No signature"));
479 wprintf("</input> , \n");
481 wprintf("<input type=\"radio\" id=\"yes_sig\" name=\"use_sig\" VALUE=\"yes\"");
482 if (UseSig) wprintf(" checked");
483 wprintf(" onChange=\"show_or_hide_sigbox();\" >");
484 wprintf(_("Use this signature:"));
485 wprintf("<div id=\"signature_box\">"
486 "<br><textarea name=\"signature\" cols=\"40\" rows=\"5\">"
489 get_preference("signature", &Signature);
491 StrBufEUid_unescapize(ebuf, Signature);
492 escputs((char*)ChrPtr(ebuf));///TODO
494 wprintf("</textarea>"
498 wprintf("</input>\n");
500 wprintf("</td></tr>\n");
502 wprintf(" <script type=\"text/javascript\"> "
503 " show_or_hide_sigbox(); "
507 /** Character set to assume is in use for improperly encoded headers */
508 if (!get_preference("default_header_charset", &Buf)) {
509 Buf = NewStrBuf();////TODO: freeme!
510 StrBufPrintf(Buf, "%s", "UTF-8");
512 wprintf("<tr class=\"even\"><td>");
513 wprintf(_("Default character set for email headers:"));
514 wprintf("</td><td>");
515 wprintf("<input type=\"text\" NAME=\"default_header_charset\" MAXLENGTH=\"32\" VALUE=\"");
516 escputs((char*)ChrPtr(Buf)); // here shouldn't be bad chars, so...
518 wprintf("</td></tr>");
524 get_pref_yesno("emptyfloors", &ShowEmptyFloors, 0);
525 wprintf("<tr class=\"odd\"><td>");
526 wprintf(_("Show empty floors"));
527 wprintf("</td><td>");
529 wprintf("<input type=\"radio\" name=\"emptyfloors\" VALUE=\"yes\"");
530 if (ShowEmptyFloors) wprintf(" checked");
533 wprintf("</input> ");
535 wprintf("<input type=\"radio\" name=\"emptyfloors\" VALUE=\"no\"");
536 if (!ShowEmptyFloors) wprintf(" checked");
539 wprintf("</input>\n");
541 wprintf("</td></tr>\n");
544 wprintf("</table>\n");
546 /** submit buttons */
547 wprintf("<div class=\"buttons\"> ");
548 wprintf("<input type=\"submit\" name=\"change_button\" value=\"%s\">"
550 "<INPUT type=\"submit\" name=\"cancel_button\" value=\"%s\">\n",
557 wprintf("</form>\n");
563 * \brief Commit new preferences and settings
565 void set_preferences(void)
568 StrBuf *buf, *encBuf;
569 int *time_format_cache;
571 time_format_cache = &(WC->time_format_cache);
573 if (!havebstr("change_button")) {
574 safestrncpy(WC->ImportantMessage,
575 _("Cancelled. No settings were changed."),
576 sizeof WC->ImportantMessage);
582 * Set the last argument to 1 only for the final setting, so
583 * we don't send the prefs file to the server repeatedly
585 set_preference("roomlistview", NewStrBufPlain(bstr("roomlistview"), -1), 0);
586 fmt = lbstr("calhourformat");
587 set_pref_long("calhourformat", fmt, 0);
589 *time_format_cache = WC_TIMEFORMAT_24;
591 *time_format_cache = WC_TIMEFORMAT_AMPM;
593 set_pref_long("weekstart", lbstr("weekstart"), 0);
594 set_pref_yesno("use_sig", yesbstr("use_sig"), 0);
595 set_pref_long("daystart", lbstr("daystart"), 0);
596 set_pref_long("dayend", lbstr("dayend"), 0);
597 set_preference("default_header_charset", NewStrBufPlain(bstr("default_header_charset"), -1), 0);
598 set_preference("emptyfloors", NewStrBufPlain(bstr("emptyfloors"), -1), 0);
600 buf = NewStrBufPlain(bstr("signature"), -1);
601 encBuf = NewStrBuf();
602 StrBufEUid_escapize(encBuf, buf);
603 set_preference("signature", encBuf, 1);
610 InitModule_PREFERENCES
613 WebcitAddUrlHandler(HKEY("display_preferences"), display_preferences, 0);
614 WebcitAddUrlHandler(HKEY("set_preferences"), set_preferences, 0);