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));
178 serv_printf("%s|%s", Key, ChrPtr(Buf));
185 DeleteHashPos(&HashPos);
188 /** Go back to the room we're supposed to be in */
189 serv_printf("GOTO %s", WC->wc_roomname);
190 serv_getln(buf, sizeof buf);
194 * \brief query the actual setting of key in the citadel database
195 * \param key config key to query
196 * \param keylen length of the key string
197 * \param value StrBuf-value to the key to get
200 int get_PREFERENCE(const char *key, size_t keylen, StrBuf **value)
202 void *hash_value = NULL;
204 dbg_PrintHash(WC->hash_prefs, PrintPref, NULL);
205 if (GetHash(WC->hash_prefs, key, keylen, &hash_value) == 0) {
211 *value = (StrBuf*) hash_value;
217 * \brief Write a key into the webcit preferences database for this user
219 * \params key key whichs value is to be modified
220 * \param keylen length of the key string
221 * \param value value to set
222 * \param save_to_server 1 = flush all data to the server, 0 = cache it for now
224 void set_PREFERENCE(const char *key, size_t keylen, StrBuf *value, int save_to_server) {
226 Put(WC->hash_prefs, key, keylen, value, HFreeStrBuf);
228 if (save_to_server) save_preferences();
231 int get_PREF_LONG(const char *key, size_t keylen, long *value, long Default)
235 ret = get_PREFERENCE(key, keylen, &val);
237 *value = atol(ChrPtr(val));
247 void set_PREF_LONG(const char *key, size_t keylen, long value, int save_to_server)
250 if (get_PREFERENCE(key, keylen, &val)) {
251 StrBufPrintf(val, "%ld", value);
255 StrBufPrintf(val, "%ld", value);
256 set_PREFERENCE(key, keylen, val, save_to_server);
262 int get_PREF_YESNO(const char *key, size_t keylen, int *value, int Default)
266 ret = get_PREFERENCE(key, keylen, &val);
268 *value = strcmp(ChrPtr(val), "yes") == 0;
277 void set_PREF_YESNO(const char *key, size_t keylen, int value, int save_to_server)
280 if (get_PREFERENCE(key, keylen, &val)) {
281 StrBufPrintf(val, "%s", (value)?"yes":"no");
285 StrBufPrintf(val, "%s", (value)?"yes":"no");
286 set_PREFERENCE(key, keylen, val, save_to_server);
291 * \brief display form for changing your preferences and settings
293 void display_preferences(void)
295 output_headers(1, 1, 1, 0, 0, 0);
298 long DayEnd, DayStart, WeekStart;
299 int UseSig, ShowEmptyFloors;
307 time_format = get_time_format_cached ();
309 wprintf("<div class=\"box\">\n");
310 wprintf("<div class=\"boxlabel\">");
311 wprintf(_("Preferences and settings"));
314 wprintf("<div class=\"boxcontent\">");
317 wprintf("<form name=\"prefform\" action=\"set_preferences\" "
318 "method=\"post\">\n");
319 wprintf("<input type=\"hidden\" name=\"nonce\" value=\"%d\">\n", WC->nonce);
322 wprintf("<table class=\"altern\">\n");
327 get_preference("roomlistview", &Buf);
328 wprintf("<tr class=\"even\"><td>");
329 wprintf(_("Room list view"));
330 wprintf("</td><td>");
332 wprintf("<input type=\"radio\" name=\"roomlistview\" VALUE=\"folders\"");
333 if (!strcasecmp(ChrPtr(Buf), "folders")) wprintf(" checked");
335 wprintf(_("Tree (folders) view"));
336 wprintf("</input> ");
338 wprintf("<input type=\"radio\" name=\"roomlistview\" VALUE=\"rooms\"");
339 if (IsEmptyStr(ChrPtr(Buf)) || !strcasecmp(ChrPtr(Buf), "rooms")) wprintf(" checked");
341 wprintf(_("Table (rooms) view"));
342 wprintf("</input>\n");
344 wprintf("</td></tr>\n");
350 wprintf("<tr class=\"odd\"><td>");
351 wprintf(_("Time format"));
352 wprintf("</td><td>");
354 wprintf("<input type=\"radio\" name=\"calhourformat\" VALUE=\"12\"");
355 if (time_format == WC_TIMEFORMAT_AMPM)
358 wprintf(_("12 hour (am/pm)"));
359 wprintf("</input> ");
361 wprintf("<input type=\"radio\" name=\"calhourformat\" VALUE=\"24\"");
362 if (time_format == WC_TIMEFORMAT_24)
365 wprintf(_("24 hour"));
366 wprintf("</input>\n");
368 wprintf("</td></tr>\n");
371 * Calendar day view -- day start time
373 get_pref_long("daystart", &DayStart, 8);
375 wprintf("<tr class=\"even\"><td>");
376 wprintf(_("Calendar day view begins at:"));
377 wprintf("</td><td>");
379 wprintf("<select name=\"daystart\" size=\"1\">\n");
380 for (i=0; i<=23; ++i) {
382 if (time_format == WC_TIMEFORMAT_24) {
383 wprintf("<option %s value=\"%d\">%d:00</option>\n",
384 ((DayStart == i) ? "selected" : ""),
389 wprintf("<option %s value=\"%d\">%s</option>\n",
390 ((DayStart == i) ? "selected" : ""),
396 wprintf("</select>\n");
397 wprintf("</td></tr>\n");
400 * Calendar day view -- day end time
402 get_pref_long("dayend", &DayEnd, 17);
404 wprintf("<tr class=\"odd\"><td>");
405 wprintf(_("Calendar day view ends at:"));
406 wprintf("</td><td>");
408 wprintf("<select name=\"dayend\" size=\"1\">\n");
409 for (i=0; i<=23; ++i) {
411 if (time_format == WC_TIMEFORMAT_24) {
412 wprintf("<option %s value=\"%d\">%d:00</option>\n",
413 ((DayEnd == i) ? "selected" : ""),
418 wprintf("<option %s value=\"%d\">%s</option>\n",
419 ((DayEnd == i) ? "selected" : ""),
425 wprintf("</select>\n");
426 wprintf("</td></tr>\n");
429 * Day of week to begin calendar month view
431 get_pref_long("weekstart", &WeekStart, 17);
432 wprintf("<tr class=\"even\"><td>");
433 wprintf(_("Week starts on:"));
434 wprintf("</td><td>");
436 wprintf("<select name=\"weekstart\" size=\"1\">\n");
438 for (i=0; i<=1; ++i) {
440 localtime_r(&tt, &tm);
442 wc_strftime(daylabel, sizeof daylabel, "%A", &tm);
444 wprintf("<option %s value=\"%d\">%s</option>\n",
445 ((WeekStart == i) ? "selected" : ""),
450 wprintf("</select>\n");
451 wprintf("</td></tr>\n");
456 get_pref_yesno("use_sig", &UseSig, 0);
457 wprintf("<tr class=\"odd\"><td>");
458 wprintf(_("Attach signature to email messages?"));
459 wprintf("</td><td>");
461 wprintf(" <script type=\"text/javascript\"> "
462 " function show_or_hide_sigbox() { "
463 " if ( $F('yes_sig') ) { "
464 " $('signature_box').style.display = 'inline'; "
467 " $('signature_box').style.display = 'none'; "
473 wprintf("<input type=\"radio\" id=\"no_sig\" name=\"use_sig\" VALUE=\"no\"");
474 if (!UseSig) wprintf(" checked");
475 wprintf(" onChange=\"show_or_hide_sigbox();\" >");
476 wprintf(_("No signature"));
477 wprintf("</input> , \n");
479 wprintf("<input type=\"radio\" id=\"yes_sig\" name=\"use_sig\" VALUE=\"yes\"");
480 if (UseSig) wprintf(" checked");
481 wprintf(" onChange=\"show_or_hide_sigbox();\" >");
482 wprintf(_("Use this signature:"));
483 wprintf("<div id=\"signature_box\">"
484 "<br><textarea name=\"signature\" cols=\"40\" rows=\"5\">"
487 get_preference("signature", &Signature);
489 StrBufEUid_unescapize(ebuf, Signature);
490 escputs((char*)ChrPtr(ebuf));///TODO
492 wprintf("</textarea>"
496 wprintf("</input>\n");
498 wprintf("</td></tr>\n");
500 wprintf(" <script type=\"text/javascript\"> "
501 " show_or_hide_sigbox(); "
505 /** Character set to assume is in use for improperly encoded headers */
506 if (!get_preference("default_header_charset", &Buf)) {
507 Buf = NewStrBuf();////TODO: freeme!
508 StrBufPrintf(Buf, "%s", "UTF-8");
510 wprintf("<tr class=\"even\"><td>");
511 wprintf(_("Default character set for email headers:"));
512 wprintf("</td><td>");
513 wprintf("<input type=\"text\" NAME=\"default_header_charset\" MAXLENGTH=\"32\" VALUE=\"");
514 escputs((char*)ChrPtr(Buf)); // here shouldn't be bad chars, so...
516 wprintf("</td></tr>");
522 get_pref_yesno("emptyfloors", &ShowEmptyFloors, 0);
523 wprintf("<tr class=\"odd\"><td>");
524 wprintf(_("Show empty floors"));
525 wprintf("</td><td>");
527 wprintf("<input type=\"radio\" name=\"emptyfloors\" VALUE=\"yes\"");
528 if (ShowEmptyFloors) wprintf(" checked");
531 wprintf("</input> ");
533 wprintf("<input type=\"radio\" name=\"emptyfloors\" VALUE=\"no\"");
534 if (!ShowEmptyFloors) wprintf(" checked");
537 wprintf("</input>\n");
539 wprintf("</td></tr>\n");
542 wprintf("</table>\n");
544 /** submit buttons */
545 wprintf("<div class=\"buttons\"> ");
546 wprintf("<input type=\"submit\" name=\"change_button\" value=\"%s\">"
548 "<INPUT type=\"submit\" name=\"cancel_button\" value=\"%s\">\n",
555 wprintf("</form>\n");
561 * \brief Commit new preferences and settings
563 void set_preferences(void)
566 StrBuf *buf, *encBuf;
567 int *time_format_cache;
569 time_format_cache = &(WC->time_format_cache);
571 if (!havebstr("change_button")) {
572 safestrncpy(WC->ImportantMessage,
573 _("Cancelled. No settings were changed."),
574 sizeof WC->ImportantMessage);
580 * Set the last argument to 1 only for the final setting, so
581 * we don't send the prefs file to the server repeatedly
583 set_preference("roomlistview", NewStrBufPlain(bstr("roomlistview"), -1), 0);
584 fmt = lbstr("calhourformat");
585 set_pref_long("calhourformat", fmt, 0);
587 *time_format_cache = WC_TIMEFORMAT_24;
589 *time_format_cache = WC_TIMEFORMAT_AMPM;
591 set_pref_long("weekstart", lbstr("weekstart"), 0);
592 set_pref_yesno("use_sig", yesbstr("use_sig"), 0);
593 set_pref_long("daystart", lbstr("daystart"), 0);
594 set_pref_long("dayend", lbstr("dayend"), 0);
595 set_preference("default_header_charset", NewStrBufPlain(bstr("default_header_charset"), -1), 0);
596 set_preference("emptyfloors", NewStrBufPlain(bstr("emptyfloors"), -1), 0);
598 buf = NewStrBufPlain(bstr("signature"), -1);
599 encBuf = NewStrBuf();
600 StrBufEUid_escapize(encBuf, buf);
601 set_preference("signature", encBuf, 1);
608 InitModule_PREFERENCES
611 WebcitAddUrlHandler(HKEY("display_preferences"), display_preferences, 0);
612 WebcitAddUrlHandler(HKEY("set_preferences"), set_preferences, 0);