4 * Manage user preferences with a little help from the Citadel server.
13 inline const char *PrintPref(void *Prefstr)
15 return ChrPtr(Prefstr);
20 * display preferences dialog
22 void load_preferences(void) {
27 serv_printf("GOTO %s", USERCONFIGROOM);
28 serv_getln(buf, sizeof buf);
29 if (buf[0] != '2') return;
31 serv_puts("MSGS ALL|0|1");
32 serv_getln(buf, sizeof buf);
34 serv_puts("subj|__ WebCit Preferences __");
37 while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
42 serv_printf("MSG0 %ld", msgnum);
43 serv_getln(buf, sizeof buf);
45 ReadBuf = NewStrBuf();
46 while (StrBuf_ServGetln(ReadBuf),
47 (strcmp(ChrPtr(ReadBuf), "text") &&
48 strcmp(ChrPtr(ReadBuf), "000"))) {
50 if (!strcmp(ChrPtr(ReadBuf), "text")) {
53 StrBuf *LastData = NULL;
56 while (StrBuf_ServGetln(ReadBuf),
57 strcmp(ChrPtr(ReadBuf), "000"))
59 if ((ChrPtr(ReadBuf)[0] == ' ') &&
61 StrBufAppendBuf(Data, ReadBuf, 1);
64 LastData = Data = NewStrBuf();
65 StrBufExtract_token(Key, ReadBuf, 0, '|');
66 StrBufExtract_token(Data, ReadBuf, 1, '|');
67 if (!IsEmptyStr(ChrPtr(Key)))
70 ChrPtr(Key), StrLength(Key),
87 /* Go back to the room we're supposed to be in */
88 serv_printf("GOTO %s", WC->wc_roomname);
89 serv_getln(buf, sizeof buf);
93 * \brief Goto the user's configuration room, creating it if necessary.
94 * \return 0 on success or nonzero upon failure.
96 int goto_config_room(void) {
99 serv_printf("GOTO %s", USERCONFIGROOM);
100 serv_getln(buf, sizeof buf);
101 if (buf[0] != '2') { /* try to create the config room if not there */
102 serv_printf("CRE8 1|%s|4|0", USERCONFIGROOM);
103 serv_getln(buf, sizeof buf);
104 serv_printf("GOTO %s", USERCONFIGROOM);
105 serv_getln(buf, sizeof buf);
106 if (buf[0] != '2') return(1);
112 * \brief save the modifications
114 void save_preferences(void) {
118 if (goto_config_room() != 0) return; /* oh well. */
119 serv_puts("MSGS ALL|0|1");
120 serv_getln(buf, sizeof buf);
122 serv_puts("subj|__ WebCit Preferences __");
125 while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
130 serv_printf("DELE %ld", msgnum);
131 serv_getln(buf, sizeof buf);
134 serv_printf("ENT0 1||0|1|__ WebCit Preferences __|");
135 serv_getln(buf, sizeof buf);
143 StrBuf *SubBuf = NULL;
145 Hash = WC->hash_prefs;
146 #ifdef DBG_PREFS_HASH
147 dbg_PrintHash(Hash, PrintPref, NULL);
149 HashPos = GetNewHashPos();
150 while (GetNextHashPos(Hash, HashPos, &len, &Key, &Value)!=0)
153 Buf = (StrBuf*) Value;
156 nchars = StrLength(Buf);
159 size_t offset, nchars;
161 SubBuf = NewStrBuf();
170 nchars = StrBufSub(SubBuf, Buf, offset, nchars);
173 serv_printf("%s|%s", Key, ChrPtr(SubBuf));
175 serv_printf(" %s", ChrPtr(SubBuf));
178 nchars = StrLength(Buf) - offset;
184 serv_printf("%s|%s", Key, ChrPtr(Buf));
191 DeleteHashPos(&HashPos);
194 /** Go back to the room we're supposed to be in */
195 serv_printf("GOTO %s", WC->wc_roomname);
196 serv_getln(buf, sizeof buf);
200 * \brief query the actual setting of key in the citadel database
201 * \param key config key to query
202 * \param keylen length of the key string
203 * \param value StrBuf-value to the key to get
206 int get_PREFERENCE(const char *key, size_t keylen, StrBuf **value)
208 void *hash_value = NULL;
209 #ifdef DBG_PREFS_HASH
210 dbg_PrintHash(WC->hash_prefs, PrintPref, NULL);
212 if (GetHash(WC->hash_prefs, key, keylen, &hash_value) == 0) {
218 *value = (StrBuf*) hash_value;
224 * \brief Write a key into the webcit preferences database for this user
226 * \params key key whichs value is to be modified
227 * \param keylen length of the key string
228 * \param value value to set
229 * \param save_to_server 1 = flush all data to the server, 0 = cache it for now
231 void set_PREFERENCE(const char *key, size_t keylen, StrBuf *value, int save_to_server) {
233 Put(WC->hash_prefs, key, keylen, value, HFreeStrBuf);
235 if (save_to_server) save_preferences();
238 int get_PREF_LONG(const char *key, size_t keylen, long *value, long Default)
242 ret = get_PREFERENCE(key, keylen, &val);
244 *value = atol(ChrPtr(val));
254 void set_PREF_LONG(const char *key, size_t keylen, long value, int save_to_server)
257 if (get_PREFERENCE(key, keylen, &val)) {
258 StrBufPrintf(val, "%ld", value);
262 StrBufPrintf(val, "%ld", value);
263 set_PREFERENCE(key, keylen, val, save_to_server);
269 int get_PREF_YESNO(const char *key, size_t keylen, int *value, int Default)
273 ret = get_PREFERENCE(key, keylen, &val);
275 *value = strcmp(ChrPtr(val), "yes") == 0;
284 void set_PREF_YESNO(const char *key, size_t keylen, int value, int save_to_server)
287 if (get_PREFERENCE(key, keylen, &val)) {
288 StrBufPrintf(val, "%s", (value)?"yes":"no");
292 StrBufPrintf(val, "%s", (value)?"yes":"no");
293 set_PREFERENCE(key, keylen, val, save_to_server);
297 StrBuf *get_ROOM_PREFS(const char *key, size_t keylen)
299 StrBuf *pref_name, *pref_value;
301 pref_name = NewStrBuf ();
302 StrBufPrintf(pref_name, "%s %s", key, WC->wc_roomname);
303 get_pref(pref_name, &pref_value);
304 FreeStrBuf(&pref_name);
308 void set_ROOM_PREFS(const char *key, size_t keylen, StrBuf *value, int save_to_server)
312 pref_name = NewStrBuf ();
313 StrBufPrintf(pref_name, "%s %s", key, WC->wc_roomname);
314 set_PREFERENCE(ChrPtr(pref_name), StrLength(pref_name), value, save_to_server);
315 FreeStrBuf(&pref_name);
319 * \brief display form for changing your preferences and settings
321 void display_preferences(void)
323 output_headers(1, 1, 1, 0, 0, 0);
326 long DayEnd, DayStart, WeekStart;
327 int UseSig, ShowEmptyFloors;
335 time_format = get_time_format_cached ();
337 wprintf("<div class=\"box\">\n");
338 wprintf("<div class=\"boxlabel\">");
339 wprintf(_("Preferences and settings"));
342 wprintf("<div class=\"boxcontent\">");
345 wprintf("<form name=\"prefform\" action=\"set_preferences\" "
346 "method=\"post\">\n");
347 wprintf("<input type=\"hidden\" name=\"nonce\" value=\"%d\">\n", WC->nonce);
350 wprintf("<table class=\"altern\">\n");
355 get_preference("roomlistview", &Buf);
356 wprintf("<tr class=\"even\"><td>");
357 wprintf(_("Room list view"));
358 wprintf("</td><td>");
360 wprintf("<input type=\"radio\" name=\"roomlistview\" VALUE=\"folders\"");
361 if (!strcasecmp(ChrPtr(Buf), "folders")) wprintf(" checked");
363 wprintf(_("Tree (folders) view"));
364 wprintf("</input> ");
366 wprintf("<input type=\"radio\" name=\"roomlistview\" VALUE=\"rooms\"");
367 if (IsEmptyStr(ChrPtr(Buf)) || !strcasecmp(ChrPtr(Buf), "rooms")) wprintf(" checked");
369 wprintf(_("Table (rooms) view"));
370 wprintf("</input>\n");
372 wprintf("</td></tr>\n");
378 wprintf("<tr class=\"odd\"><td>");
379 wprintf(_("Time format"));
380 wprintf("</td><td>");
382 wprintf("<input type=\"radio\" name=\"calhourformat\" VALUE=\"12\"");
383 if (time_format == WC_TIMEFORMAT_AMPM)
386 wprintf(_("12 hour (am/pm)"));
387 wprintf("</input> ");
389 wprintf("<input type=\"radio\" name=\"calhourformat\" VALUE=\"24\"");
390 if (time_format == WC_TIMEFORMAT_24)
393 wprintf(_("24 hour"));
394 wprintf("</input>\n");
396 wprintf("</td></tr>\n");
399 * Calendar day view -- day start time
401 get_pref_long("daystart", &DayStart, 8);
403 wprintf("<tr class=\"even\"><td>");
404 wprintf(_("Calendar day view begins at:"));
405 wprintf("</td><td>");
407 wprintf("<select name=\"daystart\" size=\"1\">\n");
408 for (i=0; i<=23; ++i) {
410 if (time_format == WC_TIMEFORMAT_24) {
411 wprintf("<option %s value=\"%d\">%d:00</option>\n",
412 ((DayStart == i) ? "selected" : ""),
417 wprintf("<option %s value=\"%d\">%s</option>\n",
418 ((DayStart == i) ? "selected" : ""),
424 wprintf("</select>\n");
425 wprintf("</td></tr>\n");
428 * Calendar day view -- day end time
430 get_pref_long("dayend", &DayEnd, 17);
432 wprintf("<tr class=\"odd\"><td>");
433 wprintf(_("Calendar day view ends at:"));
434 wprintf("</td><td>");
436 wprintf("<select name=\"dayend\" size=\"1\">\n");
437 for (i=0; i<=23; ++i) {
439 if (time_format == WC_TIMEFORMAT_24) {
440 wprintf("<option %s value=\"%d\">%d:00</option>\n",
441 ((DayEnd == i) ? "selected" : ""),
446 wprintf("<option %s value=\"%d\">%s</option>\n",
447 ((DayEnd == i) ? "selected" : ""),
453 wprintf("</select>\n");
454 wprintf("</td></tr>\n");
457 * Day of week to begin calendar month view
459 get_pref_long("weekstart", &WeekStart, 17);
460 wprintf("<tr class=\"even\"><td>");
461 wprintf(_("Week starts on:"));
462 wprintf("</td><td>");
464 wprintf("<select name=\"weekstart\" size=\"1\">\n");
466 for (i=0; i<=1; ++i) {
468 localtime_r(&tt, &tm);
470 wc_strftime(daylabel, sizeof daylabel, "%A", &tm);
472 wprintf("<option %s value=\"%d\">%s</option>\n",
473 ((WeekStart == i) ? "selected" : ""),
478 wprintf("</select>\n");
479 wprintf("</td></tr>\n");
484 get_pref_yesno("use_sig", &UseSig, 0);
485 wprintf("<tr class=\"odd\"><td>");
486 wprintf(_("Attach signature to email messages?"));
487 wprintf("</td><td>");
489 wprintf(" <script type=\"text/javascript\"> "
490 " function show_or_hide_sigbox() { "
491 " if ( $F('yes_sig') ) { "
492 " $('signature_box').style.display = 'inline'; "
495 " $('signature_box').style.display = 'none'; "
501 wprintf("<input type=\"radio\" id=\"no_sig\" name=\"use_sig\" VALUE=\"no\"");
502 if (!UseSig) wprintf(" checked");
503 wprintf(" onChange=\"show_or_hide_sigbox();\" >");
504 wprintf(_("No signature"));
505 wprintf("</input> , \n");
507 wprintf("<input type=\"radio\" id=\"yes_sig\" name=\"use_sig\" VALUE=\"yes\"");
508 if (UseSig) wprintf(" checked");
509 wprintf(" onChange=\"show_or_hide_sigbox();\" >");
510 wprintf(_("Use this signature:"));
511 wprintf("<div id=\"signature_box\">"
512 "<br><textarea name=\"signature\" cols=\"40\" rows=\"5\">"
515 get_preference("signature", &Signature);
517 StrBufEUid_unescapize(ebuf, Signature);
518 escputs((char*)ChrPtr(ebuf));///TODO
520 wprintf("</textarea>"
524 wprintf("</input>\n");
526 wprintf("</td></tr>\n");
528 wprintf(" <script type=\"text/javascript\"> "
529 " show_or_hide_sigbox(); "
533 /** Character set to assume is in use for improperly encoded headers */
534 if (!get_preference("default_header_charset", &Buf)) {
535 Buf = NewStrBuf();////TODO: freeme!
536 StrBufPrintf(Buf, "%s", "UTF-8");
538 wprintf("<tr class=\"even\"><td>");
539 wprintf(_("Default character set for email headers:"));
540 wprintf("</td><td>");
541 wprintf("<input type=\"text\" NAME=\"default_header_charset\" MAXLENGTH=\"32\" VALUE=\"");
542 escputs((char*)ChrPtr(Buf)); // here shouldn't be bad chars, so...
544 wprintf("</td></tr>");
550 get_pref_yesno("emptyfloors", &ShowEmptyFloors, 0);
551 wprintf("<tr class=\"odd\"><td>");
552 wprintf(_("Show empty floors"));
553 wprintf("</td><td>");
555 wprintf("<input type=\"radio\" name=\"emptyfloors\" VALUE=\"yes\"");
556 if (ShowEmptyFloors) wprintf(" checked");
559 wprintf("</input> ");
561 wprintf("<input type=\"radio\" name=\"emptyfloors\" VALUE=\"no\"");
562 if (!ShowEmptyFloors) wprintf(" checked");
565 wprintf("</input>\n");
567 wprintf("</td></tr>\n");
570 wprintf("</table>\n");
572 /** submit buttons */
573 wprintf("<div class=\"buttons\"> ");
574 wprintf("<input type=\"submit\" name=\"change_button\" value=\"%s\">"
576 "<INPUT type=\"submit\" name=\"cancel_button\" value=\"%s\">\n",
583 wprintf("</form>\n");
589 * \brief Commit new preferences and settings
591 void set_preferences(void)
594 StrBuf *buf, *encBuf;
595 int *time_format_cache;
597 time_format_cache = &(WC->time_format_cache);
599 if (!havebstr("change_button")) {
600 safestrncpy(WC->ImportantMessage,
601 _("Cancelled. No settings were changed."),
602 sizeof WC->ImportantMessage);
608 * Set the last argument to 1 only for the final setting, so
609 * we don't send the prefs file to the server repeatedly
611 set_preference("roomlistview", NewStrBufPlain(bstr("roomlistview"), -1), 0);
612 fmt = lbstr("calhourformat");
613 set_pref_long("calhourformat", fmt, 0);
615 *time_format_cache = WC_TIMEFORMAT_24;
617 *time_format_cache = WC_TIMEFORMAT_AMPM;
619 set_pref_long("weekstart", lbstr("weekstart"), 0);
620 set_pref_yesno("use_sig", yesbstr("use_sig"), 0);
621 set_pref_long("daystart", lbstr("daystart"), 0);
622 set_pref_long("dayend", lbstr("dayend"), 0);
623 set_preference("default_header_charset", NewStrBufPlain(bstr("default_header_charset"), -1), 0);
624 set_preference("emptyfloors", NewStrBufPlain(bstr("emptyfloors"), -1), 0);
626 buf = NewStrBufPlain(bstr("signature"), -1);
627 encBuf = NewStrBuf();
628 StrBufEUid_escapize(encBuf, buf);
629 set_preference("signature", encBuf, 1);
636 InitModule_PREFERENCES
639 WebcitAddUrlHandler(HKEY("display_preferences"), display_preferences, 0);
640 WebcitAddUrlHandler(HKEY("set_preferences"), set_preferences, 0);