X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=webcit%2Fpreferences.c;h=116b5431670111dfdb97fde292013904ac128a9b;hb=3c8aa1790772c4f64f75a9c3ae3260154abd0120;hp=c8ec33116afa8f0cb1714486a114912d8c81f8cf;hpb=502a3baa576469141cf6f72fd805f1317d35fa12;p=citadel.git diff --git a/webcit/preferences.c b/webcit/preferences.c index c8ec33116..116b54316 100644 --- a/webcit/preferences.c +++ b/webcit/preferences.c @@ -9,10 +9,41 @@ #include "webserver.h" #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 Prefstr; + return ChrPtr(Prefstr); } +#endif /* * display preferences dialog @@ -20,7 +51,7 @@ inline const char *PrintPref(void *Prefstr) void load_preferences(void) { char buf[SIZ]; long msgnum = 0L; - char key[SIZ], value[SIZ]; + StrBuf *ReadBuf; serv_printf("GOTO %s", USERCONFIGROOM); serv_getln(buf, sizeof buf); @@ -40,17 +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")) { - extract_token(key, buf, 0, '|', sizeof key); - extract_token(value, buf, 1, '|', sizeof value); - if (!IsEmptyStr(key)) - Put(WC->hash_prefs, key, strlen(key), strdup(value), free); + 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 { + 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; + } + } } + FreeStrBuf(&Key); } + FreeStrBuf(&ReadBuf); } } @@ -108,15 +167,54 @@ void save_preferences(void) { HashPos *HashPos; HashList *Hash; void *Value; - char *Key; + const char *Key; + StrBuf *Buf; + StrBuf *SubBuf = NULL; Hash = WC->hash_prefs; - PrintHash(Hash, PrintPref, NULL); +#ifdef DBG_PREFS_HASH + dbg_PrintHash(Hash, PrintPref, NULL); +#endif HashPos = GetNewHashPos(); while (GetNextHashPos(Hash, HashPos, &len, &Key, &Value)!=0) { - serv_printf("%s|%s", Key, (char*)Value); + 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); @@ -130,52 +228,139 @@ void save_preferences(void) { /** * \brief query the actual setting of key in the citadel database * \param key config key to query - * \param value value to the key to get - * \param value_len length of the value string + * \param keylen length of the key string + * \param value StrBuf-value to the key to get + * \returns found? */ -void get_preference(char *key, char *value, size_t value_len) { +int get_PREFERENCE(const char *key, size_t keylen, StrBuf **value) +{ void *hash_value = NULL; - - strcpy(value, ""); - PrintHash(WC->hash_prefs, PrintPref, NULL); - if (GetHash(WC->hash_prefs, key, strlen(key), &hash_value) == 0) - return; - - if(hash_value) - safestrncpy(value, hash_value, value_len); +#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; + } } /** * \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(char *key, char *value, int save_to_server) { +void set_PREFERENCE(const char *key, size_t keylen, StrBuf *value, int save_to_server) { - Put(WC->hash_prefs, key, strlen(key), strdup(value), free); + Put(WC->hash_prefs, key, keylen, value, HFreeStrBuf); if (save_to_server) save_preferences(); } +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_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); + } +} +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; + } + + 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); +} + /** * \brief display form for changing your preferences and settings */ void display_preferences(void) { output_headers(1, 1, 1, 0, 0, 0); - char ebuf[300]; - char buf[256]; + 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; + time_format = get_time_format_cached (); wprintf("
\n"); @@ -188,7 +373,7 @@ void display_preferences(void) /** begin form */ wprintf("
\n"); - wprintf("\n", WC->nonce); + wprintf("\n", WC->nonce); /** begin table */ wprintf("\n"); @@ -196,19 +381,19 @@ void display_preferences(void) /** * Room list view */ - get_preference("roomlistview", buf, sizeof buf); + get_preference("roomlistview", &Buf); wprintf(""); @@ -388,20 +578,19 @@ void display_preferences(void) * Show empty floors? */ - get_preference("emptyfloors", buf, sizeof buf); - if (buf[0] == 0) strcpy(buf, "no"); + get_pref_yesno("emptyfloors", &ShowEmptyFloors, 0); wprintf("
"); - wprintf(_("Room list view")); + wprintf(PrefGetLocalStr(HKEY("roomlistview"))); wprintf(""); wprintf(""); wprintf(_("Tree (folders) view")); wprintf("   "); wprintf(""); wprintf(_("Table (rooms) view")); wprintf("\n"); @@ -220,7 +405,7 @@ void display_preferences(void) */ wprintf("
"); - wprintf(_("Time format")); + wprintf(PrefGetLocalStr(HKEY("calhourformat"))); wprintf(""); wprintf(""); - wprintf(_("Calendar day view begins at:")); + wprintf(PrefGetLocalStr(HKEY("daystart"))); wprintf(""); wprintf("
"); - wprintf(_("Calendar day view ends at:")); + wprintf(PrefGetLocalStr(HKEY("dayend"))); wprintf(""); wprintf("
"); - wprintf(_("Week starts on:")); + wprintf(PrefGetLocalStr(HKEY("weekstart"))); wprintf(""); wprintf("
"); wprintf(_("Attach signature to email messages?")); wprintf(""); @@ -344,22 +527,27 @@ void display_preferences(void) " " ); + wprintf(PrefGetLocalStr(HKEY("use_sig"))); + wprintf(""); wprintf(_("No signature")); wprintf(" ,  \n"); wprintf(""); - wprintf(_("Use this signature:")); + wprintf(PrefGetLocalStr(HKEY("signature"))); wprintf("
" "
" "
" ); @@ -374,13 +562,15 @@ void display_preferences(void) ); /** Character set to assume is in use for improperly encoded headers */ - get_preference("default_header_charset", buf, sizeof buf); - if (buf[0] == 0) strcpy(buf, "UTF-8"); + if (!get_preference("default_header_charset", &Buf)) { + Buf = NewStrBuf();////TODO: freeme! + StrBufPrintf(Buf, "%s", "UTF-8"); + } wprintf("
"); - wprintf(_("Default character set for email headers:")); + wprintf(PrefGetLocalStr(HKEY("default_header_charset"))); wprintf(""); wprintf(""); wprintf("
"); - wprintf(_("Show empty floors")); + wprintf(PrefGetLocalStr(HKEY("emptyfloors"))); wprintf(""); wprintf(""); wprintf(_("Yes")); wprintf("   "); wprintf(""); wprintf(_("No")); wprintf("\n"); @@ -432,13 +621,13 @@ void display_preferences(void) */ void set_preferences(void) { - char *fmt; - char ebuf[300]; + long fmt; + StrBuf *buf, *encBuf; int *time_format_cache; time_format_cache = &(WC->time_format_cache); - if (IsEmptyStr(bstr("change_button"))) { + if (!havebstr("change_button")) { safestrncpy(WC->ImportantMessage, _("Cancelled. No settings were changed."), sizeof WC->ImportantMessage); @@ -450,26 +639,81 @@ void set_preferences(void) * 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); - fmt = bstr("calhourformat"); - set_preference("calhourformat", fmt, 0); - if (!strcasecmp(fmt, "24")) + 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_preference("weekstart", bstr("weekstart"), 0); - set_preference("use_sig", bstr("use_sig"), 0); - set_preference("daystart", bstr("daystart"), 0); - set_preference("dayend", bstr("dayend"), 0); - set_preference("default_header_charset", bstr("default_header_charset"), 0); - set_preference("emptyfloors", bstr("emptyfloors"), 0); + 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); - euid_escapize(ebuf, bstr("signature")); - set_preference("signature", ebuf, 1); + buf = NewStrBufPlain(bstr("signature"), -1); + encBuf = NewStrBuf(); + StrBufEUid_escapize(encBuf, buf); + set_preference("signature", encBuf, 1); 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 *Context) +{ + +} + + +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); +} /*@}*/