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);
298 * \brief display form for changing your preferences and settings
300 void display_preferences(void)
302 output_headers(1, 1, 1, 0, 0, 0);
305 long DayEnd, DayStart, WeekStart;
306 int UseSig, ShowEmptyFloors;
314 time_format = get_time_format_cached ();
316 wprintf("<div class=\"box\">\n");
317 wprintf("<div class=\"boxlabel\">");
318 wprintf(_("Preferences and settings"));
321 wprintf("<div class=\"boxcontent\">");
324 wprintf("<form name=\"prefform\" action=\"set_preferences\" "
325 "method=\"post\">\n");
326 wprintf("<input type=\"hidden\" name=\"nonce\" value=\"%d\">\n", WC->nonce);
329 wprintf("<table class=\"altern\">\n");
334 get_preference("roomlistview", &Buf);
335 wprintf("<tr class=\"even\"><td>");
336 wprintf(_("Room list view"));
337 wprintf("</td><td>");
339 wprintf("<input type=\"radio\" name=\"roomlistview\" VALUE=\"folders\"");
340 if (!strcasecmp(ChrPtr(Buf), "folders")) wprintf(" checked");
342 wprintf(_("Tree (folders) view"));
343 wprintf("</input> ");
345 wprintf("<input type=\"radio\" name=\"roomlistview\" VALUE=\"rooms\"");
346 if (IsEmptyStr(ChrPtr(Buf)) || !strcasecmp(ChrPtr(Buf), "rooms")) wprintf(" checked");
348 wprintf(_("Table (rooms) view"));
349 wprintf("</input>\n");
351 wprintf("</td></tr>\n");
357 wprintf("<tr class=\"odd\"><td>");
358 wprintf(_("Time format"));
359 wprintf("</td><td>");
361 wprintf("<input type=\"radio\" name=\"calhourformat\" VALUE=\"12\"");
362 if (time_format == WC_TIMEFORMAT_AMPM)
365 wprintf(_("12 hour (am/pm)"));
366 wprintf("</input> ");
368 wprintf("<input type=\"radio\" name=\"calhourformat\" VALUE=\"24\"");
369 if (time_format == WC_TIMEFORMAT_24)
372 wprintf(_("24 hour"));
373 wprintf("</input>\n");
375 wprintf("</td></tr>\n");
378 * Calendar day view -- day start time
380 get_pref_long("daystart", &DayStart, 8);
382 wprintf("<tr class=\"even\"><td>");
383 wprintf(_("Calendar day view begins at:"));
384 wprintf("</td><td>");
386 wprintf("<select name=\"daystart\" size=\"1\">\n");
387 for (i=0; i<=23; ++i) {
389 if (time_format == WC_TIMEFORMAT_24) {
390 wprintf("<option %s value=\"%d\">%d:00</option>\n",
391 ((DayStart == i) ? "selected" : ""),
396 wprintf("<option %s value=\"%d\">%s</option>\n",
397 ((DayStart == i) ? "selected" : ""),
403 wprintf("</select>\n");
404 wprintf("</td></tr>\n");
407 * Calendar day view -- day end time
409 get_pref_long("dayend", &DayEnd, 17);
411 wprintf("<tr class=\"odd\"><td>");
412 wprintf(_("Calendar day view ends at:"));
413 wprintf("</td><td>");
415 wprintf("<select name=\"dayend\" size=\"1\">\n");
416 for (i=0; i<=23; ++i) {
418 if (time_format == WC_TIMEFORMAT_24) {
419 wprintf("<option %s value=\"%d\">%d:00</option>\n",
420 ((DayEnd == i) ? "selected" : ""),
425 wprintf("<option %s value=\"%d\">%s</option>\n",
426 ((DayEnd == i) ? "selected" : ""),
432 wprintf("</select>\n");
433 wprintf("</td></tr>\n");
436 * Day of week to begin calendar month view
438 get_pref_long("weekstart", &WeekStart, 17);
439 wprintf("<tr class=\"even\"><td>");
440 wprintf(_("Week starts on:"));
441 wprintf("</td><td>");
443 wprintf("<select name=\"weekstart\" size=\"1\">\n");
445 for (i=0; i<=1; ++i) {
447 localtime_r(&tt, &tm);
449 wc_strftime(daylabel, sizeof daylabel, "%A", &tm);
451 wprintf("<option %s value=\"%d\">%s</option>\n",
452 ((WeekStart == i) ? "selected" : ""),
457 wprintf("</select>\n");
458 wprintf("</td></tr>\n");
463 get_pref_yesno("use_sig", &UseSig, 0);
464 wprintf("<tr class=\"odd\"><td>");
465 wprintf(_("Attach signature to email messages?"));
466 wprintf("</td><td>");
468 wprintf(" <script type=\"text/javascript\"> "
469 " function show_or_hide_sigbox() { "
470 " if ( $F('yes_sig') ) { "
471 " $('signature_box').style.display = 'inline'; "
474 " $('signature_box').style.display = 'none'; "
480 wprintf("<input type=\"radio\" id=\"no_sig\" name=\"use_sig\" VALUE=\"no\"");
481 if (!UseSig) wprintf(" checked");
482 wprintf(" onChange=\"show_or_hide_sigbox();\" >");
483 wprintf(_("No signature"));
484 wprintf("</input> , \n");
486 wprintf("<input type=\"radio\" id=\"yes_sig\" name=\"use_sig\" VALUE=\"yes\"");
487 if (UseSig) wprintf(" checked");
488 wprintf(" onChange=\"show_or_hide_sigbox();\" >");
489 wprintf(_("Use this signature:"));
490 wprintf("<div id=\"signature_box\">"
491 "<br><textarea name=\"signature\" cols=\"40\" rows=\"5\">"
494 get_preference("signature", &Signature);
496 StrBufEUid_unescapize(ebuf, Signature);
497 escputs((char*)ChrPtr(ebuf));///TODO
499 wprintf("</textarea>"
503 wprintf("</input>\n");
505 wprintf("</td></tr>\n");
507 wprintf(" <script type=\"text/javascript\"> "
508 " show_or_hide_sigbox(); "
512 /** Character set to assume is in use for improperly encoded headers */
513 if (!get_preference("default_header_charset", &Buf)) {
514 Buf = NewStrBuf();////TODO: freeme!
515 StrBufPrintf(Buf, "%s", "UTF-8");
517 wprintf("<tr class=\"even\"><td>");
518 wprintf(_("Default character set for email headers:"));
519 wprintf("</td><td>");
520 wprintf("<input type=\"text\" NAME=\"default_header_charset\" MAXLENGTH=\"32\" VALUE=\"");
521 escputs((char*)ChrPtr(Buf)); // here shouldn't be bad chars, so...
523 wprintf("</td></tr>");
529 get_pref_yesno("emptyfloors", &ShowEmptyFloors, 0);
530 wprintf("<tr class=\"odd\"><td>");
531 wprintf(_("Show empty floors"));
532 wprintf("</td><td>");
534 wprintf("<input type=\"radio\" name=\"emptyfloors\" VALUE=\"yes\"");
535 if (ShowEmptyFloors) wprintf(" checked");
538 wprintf("</input> ");
540 wprintf("<input type=\"radio\" name=\"emptyfloors\" VALUE=\"no\"");
541 if (!ShowEmptyFloors) wprintf(" checked");
544 wprintf("</input>\n");
546 wprintf("</td></tr>\n");
549 wprintf("</table>\n");
551 /** submit buttons */
552 wprintf("<div class=\"buttons\"> ");
553 wprintf("<input type=\"submit\" name=\"change_button\" value=\"%s\">"
555 "<INPUT type=\"submit\" name=\"cancel_button\" value=\"%s\">\n",
562 wprintf("</form>\n");
568 * \brief Commit new preferences and settings
570 void set_preferences(void)
573 StrBuf *buf, *encBuf;
574 int *time_format_cache;
576 time_format_cache = &(WC->time_format_cache);
578 if (!havebstr("change_button")) {
579 safestrncpy(WC->ImportantMessage,
580 _("Cancelled. No settings were changed."),
581 sizeof WC->ImportantMessage);
587 * Set the last argument to 1 only for the final setting, so
588 * we don't send the prefs file to the server repeatedly
590 set_preference("roomlistview", NewStrBufPlain(bstr("roomlistview"), -1), 0);
591 fmt = lbstr("calhourformat");
592 set_pref_long("calhourformat", fmt, 0);
594 *time_format_cache = WC_TIMEFORMAT_24;
596 *time_format_cache = WC_TIMEFORMAT_AMPM;
598 set_pref_long("weekstart", lbstr("weekstart"), 0);
599 set_pref_yesno("use_sig", yesbstr("use_sig"), 0);
600 set_pref_long("daystart", lbstr("daystart"), 0);
601 set_pref_long("dayend", lbstr("dayend"), 0);
602 set_preference("default_header_charset", NewStrBufPlain(bstr("default_header_charset"), -1), 0);
603 set_preference("emptyfloors", NewStrBufPlain(bstr("emptyfloors"), -1), 0);
605 buf = NewStrBufPlain(bstr("signature"), -1);
606 encBuf = NewStrBuf();
607 StrBufEUid_escapize(encBuf, buf);
608 set_preference("signature", encBuf, 1);
615 InitModule_PREFERENCES
618 WebcitAddUrlHandler(HKEY("display_preferences"), display_preferences, 0);
619 WebcitAddUrlHandler(HKEY("set_preferences"), set_preferences, 0);