X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=webcit%2Fpreferences.c;h=28aac7dfef72640d99d7a947c414e9d1de725504;hb=48b40c677af024cbf96a4e63a8deb68be484d785;hp=02cd7416c3ae1f2b5e1a5e42762f0090387bc5a5;hpb=ee8121a2817b5a36b314a6c55ecba5d83fef3bad;p=citadel.git diff --git a/webcit/preferences.c b/webcit/preferences.c index 02cd7416c..28aac7dfe 100644 --- a/webcit/preferences.c +++ b/webcit/preferences.c @@ -10,11 +10,49 @@ #include "groupdav.h" +HashList *PreferenceHooks; +typedef struct _Prefs { + long Type; + const char *Setting; + const char *PrefStr; +} Prefs; + +void RegisterPreference(const char *Setting, const char *PrefStr, long Type) +{ + Prefs *Newpref = (Prefs*) malloc(sizeof(Prefs)); + Newpref->Setting = Setting; + Newpref->PrefStr = PrefStr; + Newpref->Type = Type; + Put(PreferenceHooks, Setting, strlen(Setting), Newpref, NULL); +} + +const char *PrefGetLocalStr(const char *Setting, long len) +{ + void *hash_value; + if (GetHash(PreferenceHooks, Setting, len, &hash_value) != 0) { + Prefs *Newpref = (Prefs*) hash_value; + return _(Newpref->PrefStr); + + } + return ""; +} + +#ifdef DBG_PREFS_HASH +inline const char *PrintPref(void *Prefstr) +{ + return ChrPtr(Prefstr); +} +#endif + +/* + * display preferences dialog + */ void load_preferences(void) { char buf[SIZ]; long msgnum = 0L; - + StrBuf *ReadBuf; + serv_printf("GOTO %s", USERCONFIGROOM); serv_getln(buf, sizeof buf); if (buf[0] != '2') return; @@ -33,26 +71,45 @@ void load_preferences(void) { serv_printf("MSG0 %ld", msgnum); serv_getln(buf, sizeof buf); if (buf[0] == '1') { - while (serv_getln(buf, sizeof buf), - (strcmp(buf, "text") && strcmp(buf, "000"))) { + ReadBuf = NewStrBuf(); + while (StrBuf_ServGetln(ReadBuf), + (strcmp(ChrPtr(ReadBuf), "text") && + strcmp(ChrPtr(ReadBuf), "000"))) { } - if (!strcmp(buf, "text")) { - while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) { - if (WC->preferences == NULL) { - WC->preferences = malloc(SIZ); - strcpy(WC->preferences, ""); + if (!strcmp(ChrPtr(ReadBuf), "text")) { + StrBuf *Key; + StrBuf *Data = NULL; + StrBuf *LastData = NULL; + + Key = NewStrBuf(); + while (StrBuf_ServGetln(ReadBuf), + strcmp(ChrPtr(ReadBuf), "000")) + { + if ((ChrPtr(ReadBuf)[0] == ' ') && + (Data != NULL)) { + StrBufAppendBuf(Data, ReadBuf, 1); } else { - WC->preferences = realloc( - WC->preferences, - strlen(WC->preferences) - +SIZ - ); + LastData = Data = NewStrBuf(); + StrBufExtract_token(Key, ReadBuf, 0, '|'); + StrBufExtract_token(Data, ReadBuf, 1, '|'); + if (!IsEmptyStr(ChrPtr(Key))) + { + Put(WC->hash_prefs, + ChrPtr(Key), StrLength(Key), + Data, + HFreeStrBuf); + } + else + { + FreeStrBuf(&Data); + LastData = NULL; + } } - strcat(WC->preferences, buf); - strcat(WC->preferences, "\n"); } + FreeStrBuf(&Key); } + FreeStrBuf(&ReadBuf); } } @@ -61,9 +118,9 @@ void load_preferences(void) { serv_getln(buf, sizeof buf); } -/* - * Goto the user's configuration room, creating it if necessary. - * Returns 0 on success or nonzero upon failure. +/** + * \brief Goto the user's configuration room, creating it if necessary. + * \return 0 on success or nonzero upon failure. */ int goto_config_room(void) { char buf[SIZ]; @@ -80,11 +137,13 @@ int goto_config_room(void) { return(0); } - +/** + * \brief save the modifications + */ void save_preferences(void) { char buf[SIZ]; long msgnum = 0L; - + if (goto_config_room() != 0) return; /* oh well. */ serv_puts("MSGS ALL|0|1"); serv_getln(buf, sizeof buf); @@ -104,210 +163,355 @@ void save_preferences(void) { serv_printf("ENT0 1||0|1|__ WebCit Preferences __|"); serv_getln(buf, sizeof buf); if (buf[0] == '4') { - serv_puts(WC->preferences); + long len; + HashPos *HashPos; + HashList *Hash; + void *Value; + const char *Key; + StrBuf *Buf; + StrBuf *SubBuf = NULL; + + Hash = WC->hash_prefs; +#ifdef DBG_PREFS_HASH + dbg_PrintHash(Hash, PrintPref, NULL); +#endif + HashPos = GetNewHashPos(); + while (GetNextHashPos(Hash, HashPos, &len, &Key, &Value)!=0) + { + size_t nchars; + Buf = (StrBuf*) Value; + if (Buf == NULL) + continue; + nchars = StrLength(Buf); + if (nchars > 80){ + int n = 0; + size_t offset, nchars; + if (SubBuf == NULL) + SubBuf = NewStrBuf(); + nchars = 1; + offset = 0; + while (nchars > 0) { + if (n == 0) + nchars = 70; + else + nchars = 80; + + nchars = StrBufSub(SubBuf, Buf, offset, nchars); + + if (n == 0) + serv_printf("%s|%s", Key, ChrPtr(SubBuf)); + else + serv_printf(" %s", ChrPtr(SubBuf)); + + offset += nchars; + nchars = StrLength(Buf) - offset; + n++; + } + + } + else + serv_printf("%s|%s", Key, ChrPtr(Buf)); + + } + if (SubBuf != NULL) + FreeStrBuf(&SubBuf); serv_puts(""); serv_puts("000"); + DeleteHashPos(&HashPos); } - /* Go back to the room we're supposed to be in */ + /** Go back to the room we're supposed to be in */ serv_printf("GOTO %s", WC->wc_roomname); serv_getln(buf, sizeof buf); } -void get_preference(char *key, char *value, size_t value_len) { - int num_prefs; - int i; - char buf[SIZ]; - char thiskey[SIZ]; +/** + * \brief query the actual setting of key in the citadel database + * \param key config key to query + * \param keylen length of the key string + * \param value StrBuf-value to the key to get + * \returns found? + */ +int get_PREFERENCE(const char *key, size_t keylen, StrBuf **value) +{ + void *hash_value = NULL; +#ifdef DBG_PREFS_HASH + dbg_PrintHash(WC->hash_prefs, PrintPref, NULL); +#endif + if (GetHash(WC->hash_prefs, key, keylen, &hash_value) == 0) { + *value = NULL; + return 0; + } + else { + *value = NULL; + *value = (StrBuf*) hash_value; + return 1; + } +} - strcpy(value, ""); +/** + * \brief Write a key into the webcit preferences database for this user + * + * \params key key whichs value is to be modified + * \param keylen length of the key string + * \param value value to set + * \param save_to_server 1 = flush all data to the server, 0 = cache it for now + */ +void set_PREFERENCE(const char *key, size_t keylen, StrBuf *value, int save_to_server) { + + Put(WC->hash_prefs, key, keylen, value, HFreeStrBuf); + + if (save_to_server) save_preferences(); +} - num_prefs = num_tokens(WC->preferences, '\n'); - for (i=0; ipreferences, i, '\n', sizeof buf); - extract_token(thiskey, buf, 0, '|', sizeof thiskey); - if (!strcasecmp(thiskey, key)) { - extract_token(value, buf, 1, '|', value_len); - } +int get_PREF_LONG(const char *key, size_t keylen, long *value, long Default) +{ + int ret; + StrBuf *val; + ret = get_PREFERENCE(key, keylen, &val); + if (ret) { + *value = atol(ChrPtr(val)); } + else { + *value = Default; + } + + return ret; } -void set_preference(char *key, char *value, int save_to_server) { - int num_prefs; - int i; - char buf[SIZ]; - char thiskey[SIZ]; - char *newprefs = NULL; - - num_prefs = num_tokens(WC->preferences, '\n'); - for (i=0; ipreferences, i, '\n', sizeof buf); - if (num_tokens(buf, '|') == 2) { - extract_token(thiskey, buf, 0, '|', sizeof thiskey); - if (strcasecmp(thiskey, key)) { - if (newprefs == NULL) newprefs = strdup(""); - newprefs = realloc(newprefs, - strlen(newprefs) + SIZ ); - strcat(newprefs, buf); - strcat(newprefs, "\n"); - } - } + +void set_PREF_LONG(const char *key, size_t keylen, long value, int save_to_server) +{ + StrBuf *val; + if (get_PREFERENCE(key, keylen, &val)) { + StrBufPrintf(val, "%ld", value); } + else { + val = NewStrBuf(); + StrBufPrintf(val, "%ld", value); + set_PREFERENCE(key, keylen, val, save_to_server); + } +} - if (newprefs == NULL) newprefs = strdup(""); - newprefs = realloc(newprefs, strlen(newprefs) + SIZ); - sprintf(&newprefs[strlen(newprefs)], "%s|%s\n", key, value); - free(WC->preferences); - WC->preferences = newprefs; +int get_PREF_YESNO(const char *key, size_t keylen, int *value, int Default) +{ + int ret; + StrBuf *val; + ret = get_PREFERENCE(key, keylen, &val); + if (ret) { + *value = strcmp(ChrPtr(val), "yes") == 0; + } + else { + *value = Default; + } - if (save_to_server) save_preferences(); + return ret; } +void set_PREF_YESNO(const char *key, size_t keylen, int value, int save_to_server) +{ + StrBuf *val; + if (get_PREFERENCE(key, keylen, &val)) { + StrBufPrintf(val, "%s", (value)?"yes":"no"); + } + else { + val = NewStrBuf(); + StrBufPrintf(val, "%s", (value)?"yes":"no"); + set_PREFERENCE(key, keylen, val, save_to_server); + } +} +StrBuf *get_ROOM_PREFS(const char *key, size_t keylen) +{ + StrBuf *pref_name, *pref_value; + + pref_name = NewStrBuf (); + StrBufPrintf(pref_name, "%s %s", key, WC->wc_roomname); + get_pref(pref_name, &pref_value); + FreeStrBuf(&pref_name); + return pref_value; +} +void set_ROOM_PREFS(const char *key, size_t keylen, StrBuf *value, int save_to_server) +{ + StrBuf *pref_name; + + pref_name = NewStrBuf (); + StrBufPrintf(pref_name, "%s %s", key, WC->wc_roomname); + set_PREFERENCE(ChrPtr(pref_name), StrLength(pref_name), value, save_to_server); + FreeStrBuf(&pref_name); +} -/* - * display form for changing your preferences and settings +/** + * \brief display form for changing your preferences and settings */ void display_preferences(void) { - output_headers(1, 1, 2, 0, 0, 0); - char ebuf[300]; - char buf[256]; - char calhourformat[16]; + output_headers(1, 1, 1, 0, 0, 0); + StrBuf *ebuf = NULL; int i; + long DayEnd, DayStart, WeekStart; + int UseSig, ShowEmptyFloors; + int time_format; + time_t tt; + struct tm tm; + char daylabel[32]; + StrBuf *Buf; + StrBuf *Signature; - wprintf("
\n"); - wprintf("
"); - wprintf("\""); - wprintf(" "); - wprintf(_("Preferences and settings")); - wprintf(""); - offer_start_page(); - wprintf("
\n"); - wprintf("
\n" - "
\n"); - - wprintf("
" - "
\n"); - - /* begin form */ - wprintf("
\n" - "
\n" - "\n"); - - /* + time_format = get_time_format_cached (); + + wprintf("
\n"); + wprintf("
"); + wprintf(_("Preferences and settings")); + wprintf("
"); + + wprintf("
"); + + /** begin form */ + wprintf("\n"); + wprintf("\n", WC->nonce); + + /** begin table */ + wprintf("
\n"); + + /** * Room list view */ - get_preference("roomlistview", buf, sizeof buf); - wprintf("\n"); - /* - * Calendar hour format + /** + * Time hour format */ - get_preference("calhourformat", calhourformat, sizeof calhourformat); - if (calhourformat[0] == 0) strcpy(calhourformat, "12"); - wprintf("\n"); - /* + /** * Calendar day view -- day start time */ - get_preference("daystart", buf, sizeof buf); - if (buf[0] == 0) strcpy(buf, "8"); - wprintf("\n"); - /* + /** * Calendar day view -- day end time */ - get_preference("dayend", buf, sizeof buf); - if (buf[0] == 0) strcpy(buf, "17"); - wprintf("\n"); + + /** + * Day of week to begin calendar month view + */ + get_pref_long("weekstart", &WeekStart, 17); + wprintf("\n"); - /* + /** * Signature */ - get_preference("use_sig", buf, sizeof buf); - if (buf[0] == 0) strcpy(buf, "no"); - wprintf("\n"); @@ -352,32 +561,74 @@ void display_preferences(void) " " ); + /** Character set to assume is in use for improperly encoded headers */ + if (!get_preference("default_header_charset", &Buf)) { + Buf = NewStrBuf(); + StrBufPrintf(Buf, "%s", "UTF-8"); + set_preference("default_header_charset", Buf, 0); + } + wprintf(""); + + /** + * Show empty floors? + */ + + get_pref_yesno("emptyfloors", &ShowEmptyFloors, 0); + wprintf("\n"); + + /** end table */ + wprintf("
"); - wprintf(_("Room list view")); + get_preference("roomlistview", &Buf); + wprintf("
"); + wprintf(PrefGetLocalStr(HKEY("roomlistview"))); wprintf(""); wprintf(""); wprintf(_("Tree (folders) view")); - wprintf("
\n"); + wprintf("   "); wprintf(""); wprintf(_("Table (rooms) view")); - wprintf("
\n"); + wprintf("\n"); wprintf("
"); - wprintf(_("Calendar hour format")); + + wprintf("
"); + wprintf(PrefGetLocalStr(HKEY("calhourformat"))); wprintf(""); wprintf(""); wprintf(_("12 hour (am/pm)")); - wprintf("
\n"); + wprintf("   "); wprintf(""); wprintf(_("24 hour")); - wprintf("
\n"); + wprintf("\n"); wprintf("
"); - wprintf(_("Calendar day view begins at:")); + get_pref_long("daystart", &DayStart, 8); + + wprintf("
"); + wprintf(PrefGetLocalStr(HKEY("daystart"))); wprintf(""); - wprintf("\n"); for (i=0; i<=23; ++i) { - if (!strcasecmp(calhourformat, "24")) { - wprintf("\n", - ((atoi(buf) == i) ? "SELECTED" : ""), + if (time_format == WC_TIMEFORMAT_24) { + wprintf("\n", + ((DayStart == i) ? "selected" : ""), i, i ); } else { - wprintf("\n", - ((atoi(buf) == i) ? "SELECTED" : ""), + wprintf("\n", + ((DayStart == i) ? "selected" : ""), i, hourname[i] ); } } - wprintf("\n"); + wprintf("\n"); wprintf("
"); - wprintf(_("Calendar day view ends at:")); + get_pref_long("dayend", &DayEnd, 17); + + wprintf("
"); + wprintf(PrefGetLocalStr(HKEY("dayend"))); wprintf(""); - wprintf("\n"); for (i=0; i<=23; ++i) { - if (!strcasecmp(calhourformat, "24")) { - wprintf("\n", - ((atoi(buf) == i) ? "SELECTED" : ""), + if (time_format == WC_TIMEFORMAT_24) { + wprintf("\n", + ((DayEnd == i) ? "selected" : ""), i, i ); } else { - wprintf("\n", - ((atoi(buf) == i) ? "SELECTED" : ""), + wprintf("\n", + ((DayEnd == i) ? "selected" : ""), i, hourname[i] ); } } - wprintf("\n"); + wprintf("\n"); + wprintf("
"); + wprintf(PrefGetLocalStr(HKEY("weekstart"))); + wprintf(""); + + wprintf("\n"); wprintf("
"); + get_pref_yesno("use_sig", &UseSig, 0); + wprintf("
"); wprintf(_("Attach signature to email messages?")); wprintf(""); @@ -323,27 +527,32 @@ void display_preferences(void) " " ); + wprintf(PrefGetLocalStr(HKEY("use_sig"))); + wprintf(""); wprintf(_("No signature")); - wprintf("
\n"); + wprintf(" ,  \n"); wprintf(""); - wprintf(_("Use this signature:")); + wprintf(PrefGetLocalStr(HKEY("signature"))); wprintf("
" "
" "
" ); - wprintf("
\n"); + wprintf("\n"); wprintf("
"); + wprintf(PrefGetLocalStr(HKEY("default_header_charset"))); + wprintf(""); + wprintf(""); + wprintf("
"); + wprintf(PrefGetLocalStr(HKEY("emptyfloors"))); + wprintf(""); + + wprintf(""); + wprintf(_("Yes")); + wprintf("   "); + + wprintf(""); + wprintf(_("No")); + wprintf("\n"); + + wprintf("
\n"); - wprintf("
\n" - "" + /** submit buttons */ + wprintf("
"); + wprintf("" " " "\n", _("Change"), _("Cancel") ); + wprintf("
\n"); - wprintf("\n"); - - /* end form */ - - - wprintf("
\n"); + /** end form */ + wprintf("\n"); + wprintf("
\n"); wDumpContent(1); } -/* - * Commit new preferences and settings +/** + * \brief Commit new preferences and settings */ void set_preferences(void) { - char ebuf[300]; + long fmt; + StrBuf *buf, *encBuf; + int *time_format_cache; + + time_format_cache = &(WC->time_format_cache); - if (strlen(bstr("change_button")) == 0) { + if (!havebstr("change_button")) { safestrncpy(WC->ImportantMessage, _("Cancelled. No settings were changed."), sizeof WC->ImportantMessage); @@ -385,17 +636,109 @@ void set_preferences(void) return; } - /* Set the last argument to 1 only for the final setting, so + /** + * Set the last argument to 1 only for the final setting, so * we don't send the prefs file to the server repeatedly */ - set_preference("roomlistview", bstr("roomlistview"), 0); - set_preference("calhourformat", bstr("calhourformat"), 0); - set_preference("use_sig", bstr("use_sig"), 0); - set_preference("daystart", bstr("daystart"), 0); - set_preference("dayend", bstr("dayend"), 0); - - euid_escapize(ebuf, bstr("signature")); - set_preference("signature", ebuf, 1); + set_preference("roomlistview", NewStrBufPlain(bstr("roomlistview"), -1), 0); + fmt = lbstr("calhourformat"); + set_pref_long("calhourformat", fmt, 0); + if (fmt == 24) + *time_format_cache = WC_TIMEFORMAT_24; + else + *time_format_cache = WC_TIMEFORMAT_AMPM; + + set_pref_long("weekstart", lbstr("weekstart"), 0); + set_pref_yesno("use_sig", yesbstr("use_sig"), 0); + set_pref_long("daystart", lbstr("daystart"), 0); + set_pref_long("dayend", lbstr("dayend"), 0); + set_preference("default_header_charset", NewStrBufPlain(bstr("default_header_charset"), -1), 0); + set_preference("emptyfloors", NewStrBufPlain(bstr("emptyfloors"), -1), 0); + + buf = NewStrBufPlain(bstr("signature"), -1); + encBuf = NewStrBuf(); + StrBufEUid_escapize(encBuf, buf); + set_preference("signature", encBuf, 1); + FreeStrBuf(&buf); display_main_menu(); } + + +#define PRF_STRING 1 +#define PRF_INT 2 +#define PRF_QP_STRING 3 +#define PRF_YESNO 4 + + +void tmplput_CFG_Value(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context) +{ + StrBuf *Setting; + if (get_PREFERENCE(Token->Params[0]->Start, + Token->Params[0]->len, + &Setting)) + StrBufAppendBuf(Target, Setting, 0); +} + +void tmplput_CFG_Descr(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context) +{ + const char *SettingStr; + SettingStr = PrefGetLocalStr(Token->Params[0]->Start, + Token->Params[0]->len); + if (SettingStr != NULL) + StrBufAppendBufPlain(Target, SettingStr, -1, 0); +} + + +void CfgZoneTempl(StrBuf *TemplBuffer, void *vContext) +{ + StrBuf *Zone = (StrBuf*) vContext; + + SVPutBuf("ZONENAME", Zone, 1); +} + +int ConditionalPreference(WCTemplateToken *Token, void *Context) +{ + StrBuf *Pref; + + if (!get_PREFERENCE(Token->Params[2]->Start, + Token->Params[2]->len, + &Pref)) + return 0; + + if (Token->nParameters == 3) { + return 1; + } + else if (Token->Params[3]->Type == TYPE_STR) + return ((Token->Params[3]->len == StrLength(Pref)) && + (strcmp(Token->Params[3]->Start, ChrPtr(Pref)) == 0)); + else + return (StrTol(Pref) == Token->Params[3]->lvalue); +} + + +void +InitModule_PREFERENCES +(void) +{ + WebcitAddUrlHandler(HKEY("display_preferences"), display_preferences, 0); + WebcitAddUrlHandler(HKEY("set_preferences"), set_preferences, 0); + + RegisterPreference("roomlistview",_("Room list view"),PRF_STRING); + RegisterPreference("calhourformat",_("Time format"), PRF_INT); + RegisterPreference("daystart", _("Calendar day view begins at:"), PRF_INT); + RegisterPreference("dayend", _("Calendar day view ends at:"), PRF_INT); + RegisterPreference("weekstart",_("Week starts on:"), PRF_INT); + + RegisterPreference("use_sig",_("Attach signature to email messages?"), PRF_YESNO); + RegisterPreference("signature",_("Use this signature:"),PRF_QP_STRING); + RegisterPreference("default_header_charset", _("Default character set for email headers:") ,PRF_STRING); + RegisterPreference("emptyfloors", _("Show empty floors"), PRF_YESNO); + + RegisterNamespace("PREF:VALUE", 1, 1, tmplput_CFG_Value); + RegisterNamespace("PREF:DESCR", 1, 1, tmplput_CFG_Descr); + RegisterIterator("PREF:ZONE", ZoneHash, NULL, CfgZoneTempl, NULL); + + RegisterConditional(HKEY("COND:PREF"), 4, ConditionalPreference); +} +/*@}*/