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),
84 /* Go back to the room we're supposed to be in */
85 serv_printf("GOTO %s", WC->wc_roomname);
86 serv_getln(buf, sizeof buf);
90 * \brief Goto the user's configuration room, creating it if necessary.
91 * \return 0 on success or nonzero upon failure.
93 int goto_config_room(void) {
96 serv_printf("GOTO %s", USERCONFIGROOM);
97 serv_getln(buf, sizeof buf);
98 if (buf[0] != '2') { /* try to create the config room if not there */
99 serv_printf("CRE8 1|%s|4|0", USERCONFIGROOM);
100 serv_getln(buf, sizeof buf);
101 serv_printf("GOTO %s", USERCONFIGROOM);
102 serv_getln(buf, sizeof buf);
103 if (buf[0] != '2') return(1);
109 * \brief save the modifications
111 void save_preferences(void) {
115 if (goto_config_room() != 0) return; /* oh well. */
116 serv_puts("MSGS ALL|0|1");
117 serv_getln(buf, sizeof buf);
119 serv_puts("subj|__ WebCit Preferences __");
122 while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
127 serv_printf("DELE %ld", msgnum);
128 serv_getln(buf, sizeof buf);
131 serv_printf("ENT0 1||0|1|__ WebCit Preferences __|");
132 serv_getln(buf, sizeof buf);
140 StrBuf *SubBuf = NULL;
142 Hash = WC->hash_prefs;
143 dbg_PrintHash(Hash, PrintPref, NULL);
144 HashPos = GetNewHashPos();
145 while (GetNextHashPos(Hash, HashPos, &len, &Key, &Value)!=0)
148 Buf = (StrBuf*) Value;
151 nchars = StrLength(Buf);
154 size_t offset, nchars;
156 SubBuf = NewStrBuf();
165 nchars = StrBufSub(SubBuf, Buf, offset, nchars);
168 serv_printf("%s|%s", Key, ChrPtr(SubBuf));
170 serv_printf(" %s", ChrPtr(SubBuf));
173 nchars = StrLength(Buf) - offset;
179 serv_printf("%s|%s", Key, ChrPtr(Buf));
186 DeleteHashPos(&HashPos);
189 /** Go back to the room we're supposed to be in */
190 serv_printf("GOTO %s", WC->wc_roomname);
191 serv_getln(buf, sizeof buf);
195 * \brief query the actual setting of key in the citadel database
196 * \param key config key to query
197 * \param keylen length of the key string
198 * \param value StrBuf-value to the key to get
201 int get_PREFERENCE(const char *key, size_t keylen, StrBuf **value)
203 void *hash_value = NULL;
205 dbg_PrintHash(WC->hash_prefs, PrintPref, NULL);
206 if (GetHash(WC->hash_prefs, key, keylen, &hash_value) == 0) {
212 *value = (StrBuf*) hash_value;
218 * \brief Write a key into the webcit preferences database for this user
220 * \params key key whichs value is to be modified
221 * \param keylen length of the key string
222 * \param value value to set
223 * \param save_to_server 1 = flush all data to the server, 0 = cache it for now
225 void set_PREFERENCE(const char *key, size_t keylen, StrBuf *value, int save_to_server) {
227 Put(WC->hash_prefs, key, keylen, value, HFreeStrBuf);
229 if (save_to_server) save_preferences();
232 int get_PREF_LONG(const char *key, size_t keylen, long *value, long Default)
236 ret = get_PREFERENCE(key, keylen, &val);
238 *value = atol(ChrPtr(val));
248 void set_PREF_LONG(const char *key, size_t keylen, long value, int save_to_server)
251 if (get_PREFERENCE(key, keylen, &val)) {
252 StrBufPrintf(val, "%ld", value);
256 StrBufPrintf(val, "%ld", value);
257 set_PREFERENCE(key, keylen, val, save_to_server);
263 int get_PREF_YESNO(const char *key, size_t keylen, int *value, int Default)
267 ret = get_PREFERENCE(key, keylen, &val);
269 *value = strcmp(ChrPtr(val), "yes") == 0;
278 void set_PREF_YESNO(const char *key, size_t keylen, int value, int save_to_server)
281 if (get_PREFERENCE(key, keylen, &val)) {
282 StrBufPrintf(val, "%s", (value)?"yes":"no");
286 StrBufPrintf(val, "%s", (value)?"yes":"no");
287 set_PREFERENCE(key, keylen, val, save_to_server);
292 * \brief display form for changing your preferences and settings
294 void display_preferences(void)
296 output_headers(1, 1, 1, 0, 0, 0);
299 long DayEnd, DayStart, WeekStart;
300 int UseSig, ShowEmptyFloors;
308 time_format = get_time_format_cached ();
310 wprintf("<div class=\"box\">\n");
311 wprintf("<div class=\"boxlabel\">");
312 wprintf(_("Preferences and settings"));
315 wprintf("<div class=\"boxcontent\">");
318 wprintf("<form name=\"prefform\" action=\"set_preferences\" "
319 "method=\"post\">\n");
320 wprintf("<input type=\"hidden\" name=\"nonce\" value=\"%d\">\n", WC->nonce);
323 wprintf("<table class=\"altern\">\n");
328 get_preference("roomlistview", &Buf);
329 wprintf("<tr class=\"even\"><td>");
330 wprintf(_("Room list view"));
331 wprintf("</td><td>");
333 wprintf("<input type=\"radio\" name=\"roomlistview\" VALUE=\"folders\"");
334 if (!strcasecmp(ChrPtr(Buf), "folders")) wprintf(" checked");
336 wprintf(_("Tree (folders) view"));
337 wprintf("</input> ");
339 wprintf("<input type=\"radio\" name=\"roomlistview\" VALUE=\"rooms\"");
340 if (IsEmptyStr(ChrPtr(Buf)) || !strcasecmp(ChrPtr(Buf), "rooms")) wprintf(" checked");
342 wprintf(_("Table (rooms) view"));
343 wprintf("</input>\n");
345 wprintf("</td></tr>\n");
351 wprintf("<tr class=\"odd\"><td>");
352 wprintf(_("Time format"));
353 wprintf("</td><td>");
355 wprintf("<input type=\"radio\" name=\"calhourformat\" VALUE=\"12\"");
356 if (time_format == WC_TIMEFORMAT_AMPM)
359 wprintf(_("12 hour (am/pm)"));
360 wprintf("</input> ");
362 wprintf("<input type=\"radio\" name=\"calhourformat\" VALUE=\"24\"");
363 if (time_format == WC_TIMEFORMAT_24)
366 wprintf(_("24 hour"));
367 wprintf("</input>\n");
369 wprintf("</td></tr>\n");
372 * Calendar day view -- day start time
374 get_pref_long("daystart", &DayStart, 8);
376 wprintf("<tr class=\"even\"><td>");
377 wprintf(_("Calendar day view begins at:"));
378 wprintf("</td><td>");
380 wprintf("<select name=\"daystart\" size=\"1\">\n");
381 for (i=0; i<=23; ++i) {
383 if (time_format == WC_TIMEFORMAT_24) {
384 wprintf("<option %s value=\"%d\">%d:00</option>\n",
385 ((DayStart == i) ? "selected" : ""),
390 wprintf("<option %s value=\"%d\">%s</option>\n",
391 ((DayStart == i) ? "selected" : ""),
397 wprintf("</select>\n");
398 wprintf("</td></tr>\n");
401 * Calendar day view -- day end time
403 get_pref_long("dayend", &DayEnd, 17);
405 wprintf("<tr class=\"odd\"><td>");
406 wprintf(_("Calendar day view ends at:"));
407 wprintf("</td><td>");
409 wprintf("<select name=\"dayend\" size=\"1\">\n");
410 for (i=0; i<=23; ++i) {
412 if (time_format == WC_TIMEFORMAT_24) {
413 wprintf("<option %s value=\"%d\">%d:00</option>\n",
414 ((DayEnd == i) ? "selected" : ""),
419 wprintf("<option %s value=\"%d\">%s</option>\n",
420 ((DayEnd == i) ? "selected" : ""),
426 wprintf("</select>\n");
427 wprintf("</td></tr>\n");
430 * Day of week to begin calendar month view
432 get_pref_long("weekstart", &WeekStart, 17);
433 wprintf("<tr class=\"even\"><td>");
434 wprintf(_("Week starts on:"));
435 wprintf("</td><td>");
437 wprintf("<select name=\"weekstart\" size=\"1\">\n");
439 for (i=0; i<=1; ++i) {
441 localtime_r(&tt, &tm);
443 wc_strftime(daylabel, sizeof daylabel, "%A", &tm);
445 wprintf("<option %s value=\"%d\">%s</option>\n",
446 ((WeekStart == i) ? "selected" : ""),
451 wprintf("</select>\n");
452 wprintf("</td></tr>\n");
457 get_pref_yesno("use_sig", &UseSig, 0);
458 wprintf("<tr class=\"odd\"><td>");
459 wprintf(_("Attach signature to email messages?"));
460 wprintf("</td><td>");
462 wprintf(" <script type=\"text/javascript\"> "
463 " function show_or_hide_sigbox() { "
464 " if ( $F('yes_sig') ) { "
465 " $('signature_box').style.display = 'inline'; "
468 " $('signature_box').style.display = 'none'; "
474 wprintf("<input type=\"radio\" id=\"no_sig\" name=\"use_sig\" VALUE=\"no\"");
475 if (!UseSig) wprintf(" checked");
476 wprintf(" onChange=\"show_or_hide_sigbox();\" >");
477 wprintf(_("No signature"));
478 wprintf("</input> , \n");
480 wprintf("<input type=\"radio\" id=\"yes_sig\" name=\"use_sig\" VALUE=\"yes\"");
481 if (UseSig) wprintf(" checked");
482 wprintf(" onChange=\"show_or_hide_sigbox();\" >");
483 wprintf(_("Use this signature:"));
484 wprintf("<div id=\"signature_box\">"
485 "<br><textarea name=\"signature\" cols=\"40\" rows=\"5\">"
488 get_preference("signature", &Signature);
490 StrBufEUid_unescapize(ebuf, Signature);
491 escputs((char*)ChrPtr(ebuf));///TODO
493 wprintf("</textarea>"
497 wprintf("</input>\n");
499 wprintf("</td></tr>\n");
501 wprintf(" <script type=\"text/javascript\"> "
502 " show_or_hide_sigbox(); "
506 /** Character set to assume is in use for improperly encoded headers */
507 if (!get_preference("default_header_charset", &Buf)) {
508 Buf = NewStrBuf();////TODO: freeme!
509 StrBufPrintf(Buf, "%s", "UTF-8");
511 wprintf("<tr class=\"even\"><td>");
512 wprintf(_("Default character set for email headers:"));
513 wprintf("</td><td>");
514 wprintf("<input type=\"text\" NAME=\"default_header_charset\" MAXLENGTH=\"32\" VALUE=\"");
515 escputs((char*)ChrPtr(Buf)); // here shouldn't be bad chars, so...
517 wprintf("</td></tr>");
523 get_pref_yesno("emptyfloors", &ShowEmptyFloors, 0);
524 wprintf("<tr class=\"odd\"><td>");
525 wprintf(_("Show empty floors"));
526 wprintf("</td><td>");
528 wprintf("<input type=\"radio\" name=\"emptyfloors\" VALUE=\"yes\"");
529 if (ShowEmptyFloors) wprintf(" checked");
532 wprintf("</input> ");
534 wprintf("<input type=\"radio\" name=\"emptyfloors\" VALUE=\"no\"");
535 if (!ShowEmptyFloors) wprintf(" checked");
538 wprintf("</input>\n");
540 wprintf("</td></tr>\n");
543 wprintf("</table>\n");
545 /** submit buttons */
546 wprintf("<div class=\"buttons\"> ");
547 wprintf("<input type=\"submit\" name=\"change_button\" value=\"%s\">"
549 "<INPUT type=\"submit\" name=\"cancel_button\" value=\"%s\">\n",
556 wprintf("</form>\n");
562 * \brief Commit new preferences and settings
564 void set_preferences(void)
567 StrBuf *buf, *encBuf;
568 int *time_format_cache;
570 time_format_cache = &(WC->time_format_cache);
572 if (!havebstr("change_button")) {
573 safestrncpy(WC->ImportantMessage,
574 _("Cancelled. No settings were changed."),
575 sizeof WC->ImportantMessage);
581 * Set the last argument to 1 only for the final setting, so
582 * we don't send the prefs file to the server repeatedly
584 set_preference("roomlistview", NewStrBufPlain(bstr("roomlistview"), -1), 0);
585 fmt = lbstr("calhourformat");
586 set_pref_long("calhourformat", fmt, 0);
588 *time_format_cache = WC_TIMEFORMAT_24;
590 *time_format_cache = WC_TIMEFORMAT_AMPM;
592 set_pref_long("weekstart", lbstr("weekstart"), 0);
593 set_pref_yesno("use_sig", yesbstr("use_sig"), 0);
594 set_pref_long("daystart", lbstr("daystart"), 0);
595 set_pref_long("dayend", lbstr("dayend"), 0);
596 set_preference("default_header_charset", NewStrBufPlain(bstr("default_header_charset"), -1), 0);
597 set_preference("emptyfloors", NewStrBufPlain(bstr("emptyfloors"), -1), 0);
599 buf = NewStrBufPlain(bstr("signature"), -1);
600 encBuf = NewStrBuf();
601 StrBufEUid_escapize(encBuf, buf);
602 set_preference("signature", encBuf, 1);
609 InitModule_PREFERENCES
612 WebcitAddUrlHandler(HKEY("display_preferences"), display_preferences, 0);
613 WebcitAddUrlHandler(HKEY("set_preferences"), set_preferences, 0);