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;
149 nchars = StrLength(Buf);
152 size_t offset, nchars;
154 SubBuf = NewStrBuf();
163 nchars = StrBufSub(SubBuf, Buf, offset, nchars);
166 serv_printf("%s|%s", Key, ChrPtr(SubBuf));
168 serv_printf(" %s", Key, ChrPtr(SubBuf));
176 serv_printf("%s|%s", Key, ChrPtr(Buf));
183 DeleteHashPos(&HashPos);
186 /** Go back to the room we're supposed to be in */
187 serv_printf("GOTO %s", WC->wc_roomname);
188 serv_getln(buf, sizeof buf);
192 * \brief query the actual setting of key in the citadel database
193 * \param key config key to query
194 * \param keylen length of the key string
195 * \param value StrBuf-value to the key to get
198 int get_PREFERENCE(const char *key, size_t keylen, StrBuf **value)
200 void *hash_value = NULL;
202 dbg_PrintHash(WC->hash_prefs, PrintPref, NULL);
203 if (GetHash(WC->hash_prefs, key, keylen, &hash_value) == 0) {
209 *value = (StrBuf*) hash_value;
215 * \brief Write a key into the webcit preferences database for this user
217 * \params key key whichs value is to be modified
218 * \param keylen length of the key string
219 * \param value value to set
220 * \param save_to_server 1 = flush all data to the server, 0 = cache it for now
222 void set_PREFERENCE(const char *key, size_t keylen, StrBuf *value, int save_to_server) {
224 Put(WC->hash_prefs, key, keylen, value, HFreeStrBuf);
226 if (save_to_server) save_preferences();
229 int get_PREF_LONG(const char *key, size_t keylen, long *value, long Default)
233 ret = get_PREFERENCE(key, keylen, &val);
235 *value = atol(ChrPtr(val));
245 void set_PREF_LONG(const char *key, size_t keylen, long value, int save_to_server)
248 if (get_PREFERENCE(key, keylen, &val)) {
249 StrBufPrintf(val, "%ld", value);
253 StrBufPrintf(val, "%ld", value);
254 set_PREFERENCE(key, keylen, val, save_to_server);
260 int get_PREF_YESNO(const char *key, size_t keylen, int *value, int Default)
264 ret = get_PREFERENCE(key, keylen, &val);
266 *value = strcmp(ChrPtr(val), "yes") == 0;
275 void set_PREF_YESNO(const char *key, size_t keylen, int value, int save_to_server)
278 if (get_PREFERENCE(key, keylen, &val)) {
279 StrBufPrintf(val, "%s", (value)?"yes":"no");
283 StrBufPrintf(val, "%s", (value)?"yes":"no");
284 set_PREFERENCE(key, keylen, val, save_to_server);
289 * \brief display form for changing your preferences and settings
291 void display_preferences(void)
293 output_headers(1, 1, 1, 0, 0, 0);
296 long DayEnd, DayStart, WeekStart;
297 int UseSig, ShowEmptyFloors;
305 time_format = get_time_format_cached ();
307 wprintf("<div class=\"box\">\n");
308 wprintf("<div class=\"boxlabel\">");
309 wprintf(_("Preferences and settings"));
312 wprintf("<div class=\"boxcontent\">");
315 wprintf("<form name=\"prefform\" action=\"set_preferences\" "
316 "method=\"post\">\n");
317 wprintf("<input type=\"hidden\" name=\"nonce\" value=\"%d\">\n", WC->nonce);
320 wprintf("<table class=\"altern\">\n");
325 get_preference("roomlistview", &Buf);
326 wprintf("<tr class=\"even\"><td>");
327 wprintf(_("Room list view"));
328 wprintf("</td><td>");
330 wprintf("<input type=\"radio\" name=\"roomlistview\" VALUE=\"folders\"");
331 if (!strcasecmp(ChrPtr(Buf), "folders")) wprintf(" checked");
333 wprintf(_("Tree (folders) view"));
334 wprintf("</input> ");
336 wprintf("<input type=\"radio\" name=\"roomlistview\" VALUE=\"rooms\"");
337 if (IsEmptyStr(ChrPtr(Buf)) || !strcasecmp(ChrPtr(Buf), "rooms")) wprintf(" checked");
339 wprintf(_("Table (rooms) view"));
340 wprintf("</input>\n");
342 wprintf("</td></tr>\n");
348 wprintf("<tr class=\"odd\"><td>");
349 wprintf(_("Time format"));
350 wprintf("</td><td>");
352 wprintf("<input type=\"radio\" name=\"calhourformat\" VALUE=\"12\"");
353 if (time_format == WC_TIMEFORMAT_AMPM)
356 wprintf(_("12 hour (am/pm)"));
357 wprintf("</input> ");
359 wprintf("<input type=\"radio\" name=\"calhourformat\" VALUE=\"24\"");
360 if (time_format == WC_TIMEFORMAT_24)
363 wprintf(_("24 hour"));
364 wprintf("</input>\n");
366 wprintf("</td></tr>\n");
369 * Calendar day view -- day start time
371 get_pref_long("daystart", &DayStart, 8);
373 wprintf("<tr class=\"even\"><td>");
374 wprintf(_("Calendar day view begins at:"));
375 wprintf("</td><td>");
377 wprintf("<select name=\"daystart\" size=\"1\">\n");
378 for (i=0; i<=23; ++i) {
380 if (time_format == WC_TIMEFORMAT_24) {
381 wprintf("<option %s value=\"%d\">%d:00</option>\n",
382 ((DayStart == i) ? "selected" : ""),
387 wprintf("<option %s value=\"%d\">%s</option>\n",
388 ((DayStart == i) ? "selected" : ""),
394 wprintf("</select>\n");
395 wprintf("</td></tr>\n");
398 * Calendar day view -- day end time
400 get_pref_long("dayend", &DayEnd, 17);
402 wprintf("<tr class=\"odd\"><td>");
403 wprintf(_("Calendar day view ends at:"));
404 wprintf("</td><td>");
406 wprintf("<select name=\"dayend\" size=\"1\">\n");
407 for (i=0; i<=23; ++i) {
409 if (time_format == WC_TIMEFORMAT_24) {
410 wprintf("<option %s value=\"%d\">%d:00</option>\n",
411 ((DayEnd == i) ? "selected" : ""),
416 wprintf("<option %s value=\"%d\">%s</option>\n",
417 ((DayEnd == i) ? "selected" : ""),
423 wprintf("</select>\n");
424 wprintf("</td></tr>\n");
427 * Day of week to begin calendar month view
429 get_pref_long("weekstart", &WeekStart, 17);
430 wprintf("<tr class=\"even\"><td>");
431 wprintf(_("Week starts on:"));
432 wprintf("</td><td>");
434 wprintf("<select name=\"weekstart\" size=\"1\">\n");
436 for (i=0; i<=1; ++i) {
438 localtime_r(&tt, &tm);
440 wc_strftime(daylabel, sizeof daylabel, "%A", &tm);
442 wprintf("<option %s value=\"%d\">%s</option>\n",
443 ((WeekStart == i) ? "selected" : ""),
448 wprintf("</select>\n");
449 wprintf("</td></tr>\n");
454 get_pref_yesno("use_sig", &UseSig, 0);
455 wprintf("<tr class=\"odd\"><td>");
456 wprintf(_("Attach signature to email messages?"));
457 wprintf("</td><td>");
459 wprintf(" <script type=\"text/javascript\"> "
460 " function show_or_hide_sigbox() { "
461 " if ( $F('yes_sig') ) { "
462 " $('signature_box').style.display = 'inline'; "
465 " $('signature_box').style.display = 'none'; "
471 wprintf("<input type=\"radio\" id=\"no_sig\" name=\"use_sig\" VALUE=\"no\"");
472 if (!UseSig) wprintf(" checked");
473 wprintf(" onChange=\"show_or_hide_sigbox();\" >");
474 wprintf(_("No signature"));
475 wprintf("</input> , \n");
477 wprintf("<input type=\"radio\" id=\"yes_sig\" name=\"use_sig\" VALUE=\"yes\"");
478 if (UseSig) wprintf(" checked");
479 wprintf(" onChange=\"show_or_hide_sigbox();\" >");
480 wprintf(_("Use this signature:"));
481 wprintf("<div id=\"signature_box\">"
482 "<br><textarea name=\"signature\" cols=\"40\" rows=\"5\">"
485 get_preference("signature", &Signature);
487 StrBufEUid_unescapize(ebuf, Signature);
488 escputs(ChrPtr(ebuf));
490 wprintf("</textarea>"
494 wprintf("</input>\n");
496 wprintf("</td></tr>\n");
498 wprintf(" <script type=\"text/javascript\"> "
499 " show_or_hide_sigbox(); "
503 /** Character set to assume is in use for improperly encoded headers */
504 if (!get_preference("default_header_charset", &Buf)) {
505 Buf = NewStrBuf();////TODO: freeme!
506 StrBufPrintf(Buf, "%s", "UTF-8");
508 wprintf("<tr class=\"even\"><td>");
509 wprintf(_("Default character set for email headers:"));
510 wprintf("</td><td>");
511 wprintf("<input type=\"text\" NAME=\"default_header_charset\" MAXLENGTH=\"32\" VALUE=\"");
512 escputs(ChrPtr(Buf));
514 wprintf("</td></tr>");
520 get_pref_yesno("emptyfloors", &ShowEmptyFloors, 0);
521 wprintf("<tr class=\"odd\"><td>");
522 wprintf(_("Show empty floors"));
523 wprintf("</td><td>");
525 wprintf("<input type=\"radio\" name=\"emptyfloors\" VALUE=\"yes\"");
526 if (ShowEmptyFloors) wprintf(" checked");
529 wprintf("</input> ");
531 wprintf("<input type=\"radio\" name=\"emptyfloors\" VALUE=\"no\"");
532 if (!ShowEmptyFloors) wprintf(" checked");
535 wprintf("</input>\n");
537 wprintf("</td></tr>\n");
540 wprintf("</table>\n");
542 /** submit buttons */
543 wprintf("<div class=\"buttons\"> ");
544 wprintf("<input type=\"submit\" name=\"change_button\" value=\"%s\">"
546 "<INPUT type=\"submit\" name=\"cancel_button\" value=\"%s\">\n",
553 wprintf("</form>\n");
559 * \brief Commit new preferences and settings
561 void set_preferences(void)
565 int *time_format_cache;
567 time_format_cache = &(WC->time_format_cache);
569 if (!havebstr("change_button")) {
570 safestrncpy(WC->ImportantMessage,
571 _("Cancelled. No settings were changed."),
572 sizeof WC->ImportantMessage);
578 * Set the last argument to 1 only for the final setting, so
579 * we don't send the prefs file to the server repeatedly
581 set_preference("roomlistview", NewStrBufPlain(bstr("roomlistview"), -1), 0);
582 fmt = lbstr("calhourformat");
583 set_pref_long("calhourformat", fmt, 0);
585 *time_format_cache = WC_TIMEFORMAT_24;
587 *time_format_cache = WC_TIMEFORMAT_AMPM;
589 set_pref_long("weekstart", lbstr("weekstart"), 0);
590 set_pref_yesno("use_sig", yesbstr("use_sig"), 0);
591 set_pref_long("daystart", lbstr("daystart"), 0);
592 set_pref_long("dayend", lbstr("dayend"), 0);
593 set_preference("default_header_charset", NewStrBufPlain(bstr("default_header_charset"), -1), 0);
594 set_preference("emptyfloors", NewStrBufPlain(bstr("emptyfloors"), -1), 0);
596 ebuf = NewStrBufPlain(bstr("signature"), -1);
597 /////TODOeuid_escapize(ebuf);
598 set_preference("signature", ebuf, 1);