X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=webcit%2Fpreferences.c;h=46e439f7f1984c70c72cae9dab6442cc521c4633;hb=808f3be91dd6b6677e380695e2f16e6473141a7e;hp=6c59ed24d1112f9bd3b7f4c86d36d5b5e677ad25;hpb=e98baf58a3e63a60f6d89cc007e7849f175912cf;p=citadel.git diff --git a/webcit/preferences.c b/webcit/preferences.c index 6c59ed24d..46e439f7f 100644 --- a/webcit/preferences.c +++ b/webcit/preferences.c @@ -9,18 +9,87 @@ #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 ChrPtr(Prefstr); } +#endif + + +void ParsePref(HashList **List, StrBuf *ReadBuf) +{ + 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(*List, + ChrPtr(Key), StrLength(Key), + Data, + HFreeStrBuf); + } + else + { + FreeStrBuf(&Data); + LastData = NULL; + } + } + } + FreeStrBuf(&Key); +} + /* * display preferences dialog */ -void load_preferences(void) { +void load_preferences(void) +{ + StrBuf *ReadBuf; char buf[SIZ]; long msgnum = 0L; - StrBuf *ReadBuf; serv_printf("GOTO %s", USERCONFIGROOM); serv_getln(buf, sizeof buf); @@ -46,43 +115,14 @@ void load_preferences(void) { strcmp(ChrPtr(ReadBuf), "000"))) { } 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); + ParsePref(&WC->hash_prefs, ReadBuf); } } + FreeStrBuf(&ReadBuf); } /* Go back to the room we're supposed to be in */ - serv_printf("GOTO %s", WC->wc_roomname); + serv_printf("GOTO %s", ChrPtr(WC->wc_roomname)); serv_getln(buf, sizeof buf); } @@ -105,6 +145,62 @@ int goto_config_room(void) { return(0); } +void WritePrefsToServer(HashList *Hash) +{ + long len; + HashPos *HashPos; + 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(Hash, 0); + 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); + DeleteHashPos(&HashPos); +} + /** * \brief save the modifications */ @@ -131,62 +227,14 @@ void save_preferences(void) { serv_printf("ENT0 1||0|1|__ WebCit Preferences __|"); serv_getln(buf, sizeof buf); if (buf[0] == '4') { - long len; - HashPos *HashPos; - HashList *Hash; - void *Value; - char *Key; - StrBuf *Buf; - StrBuf *SubBuf = NULL; - - Hash = WC->hash_prefs; - dbg_PrintHash(Hash, PrintPref, NULL); - 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", Key, ChrPtr(SubBuf)); - - offset += nchars; - n++; - } - - } - else - serv_printf("%s|%s", Key, ChrPtr(Buf)); - - } - if (SubBuf != NULL) - FreeStrBuf(&SubBuf); + + WritePrefsToServer(WC->hash_prefs); serv_puts(""); serv_puts("000"); - DeleteHashPos(&HashPos); } /** Go back to the room we're supposed to be in */ - serv_printf("GOTO %s", WC->wc_roomname); + serv_printf("GOTO %s", ChrPtr(WC->wc_roomname)); serv_getln(buf, sizeof buf); } @@ -200,8 +248,9 @@ void save_preferences(void) { 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; @@ -287,320 +336,285 @@ void set_PREF_YESNO(const char *key, size_t keylen, int value, int save_to_serve } } -/** - * \brief display form for changing your preferences and settings +StrBuf *get_ROOM_PREFS(const char *key, size_t keylen) +{ + StrBuf *pref_name, *pref_value; + + pref_name = NewStrBuf (); + StrBufPrintf(pref_name, "%s %s", key, ChrPtr(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, ChrPtr(WC->wc_roomname)); + set_PREFERENCE(ChrPtr(pref_name), StrLength(pref_name), value, save_to_server); + FreeStrBuf(&pref_name); +} + +/* + * Offer to make any page the user's "start page." */ -void display_preferences(void) +void offer_start_page(StrBuf *Target, WCTemplputParams *TP) { - 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; - - 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); - wprintf("\n"); - - /** - * Time hour format - */ - - wprintf("\n"); - - /** - * Calendar day view -- day start time - */ - get_pref_long("daystart", &DayStart, 8); - - wprintf("\n"); - - /** - * Calendar day view -- day end time - */ - get_pref_long("dayend", &DayEnd, 17); - - wprintf("\n"); - - /** - * Day of week to begin calendar month view - */ - get_pref_long("weekstart", &WeekStart, 17); - wprintf("\n"); - - /** - * Signature - */ - get_pref_yesno("use_sig", &UseSig, 0); - wprintf("\n"); - - wprintf(" " - ); - - /** Character set to assume is in use for improperly encoded headers */ - if (!get_preference("default_header_charset", &Buf)) { - Buf = NewStrBuf();////TODO: freeme! - StrBufPrintf(Buf, "%s", "UTF-8"); + if (bstr("startpage") == NULL) { + safestrncpy(WC->ImportantMessage, + _("You no longer have a start page selected."), + sizeof WC->ImportantMessage); + display_main_menu(); + return; } - wprintf(""); - - /** - * Show empty floors? - */ - - get_pref_yesno("emptyfloors", &ShowEmptyFloors, 0); - wprintf("\n"); - - /** end table */ - wprintf("
"); - wprintf(_("Room list view")); - wprintf(""); - - wprintf(""); - wprintf(_("Tree (folders) view")); - wprintf("   "); - - wprintf(""); - wprintf(_("Table (rooms) view")); - wprintf("\n"); - - wprintf("
"); - wprintf(_("Time format")); - wprintf(""); - - wprintf(""); - wprintf(_("12 hour (am/pm)")); - wprintf("   "); - - wprintf(""); - wprintf(_("24 hour")); - wprintf("\n"); - - wprintf("
"); - wprintf(_("Calendar day view begins at:")); - wprintf(""); - - wprintf("\n"); - wprintf("
"); - wprintf(_("Calendar day view ends at:")); - wprintf(""); - - wprintf("\n"); - wprintf("
"); - wprintf(_("Week starts on:")); - wprintf(""); - - wprintf("\n"); - wprintf("
"); - wprintf(_("Attach signature to email messages?")); - wprintf(""); - - wprintf(" " - ); - - wprintf(""); - wprintf(_("No signature")); - wprintf(" ,  \n"); - - wprintf(""); - wprintf(_("Use this signature:")); - wprintf("
" - "
" - "
" - ); - - wprintf("\n"); - - wprintf("
"); - wprintf(_("Default character set for email headers:")); - wprintf(""); - wprintf(""); - wprintf("
"); - wprintf(_("Show empty floors")); - wprintf(""); - - wprintf(""); - wprintf(_("Yes")); - wprintf("   "); - - wprintf(""); - wprintf(_("No")); - wprintf("\n"); - - wprintf("
\n"); - - /** submit buttons */ - wprintf("
"); - wprintf("" - " " - "\n", - _("Change"), - _("Cancel") - ); - wprintf("
\n"); - - /** end form */ - wprintf("
\n"); - wprintf("
\n"); + + set_preference("startpage", NewStrBufPlain(bstr("startpage"), -1), 1); + + output_headers(1, 1, 0, 0, 0, 0); + do_template("newstartpage", NULL); wDumpContent(1); } + + /** * \brief Commit new preferences and settings */ void set_preferences(void) { long fmt; - StrBuf *ebuf; + StrBuf *buf, *encBuf; int *time_format_cache; - time_format_cache = &(WC->time_format_cache); + time_format_cache = &(WC->time_format_cache); + + if (!havebstr("change_button")) { + safestrncpy(WC->ImportantMessage, + _("Cancelled. No settings were changed."), + sizeof WC->ImportantMessage); + display_main_menu(); + return; + } + + /** + * 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", 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); + set_preference("defaultfrom", NewStrBufDup(sbstr("defaultfrom")), 0); + set_preference("defaultname", NewStrBufDup(sbstr("defaultname")), 0); + set_preference("defaulthandle", NewStrBufDup(sbstr("defaulthandle")), 0); + + + buf = NewStrBufPlain(bstr("signature"), -1); + encBuf = NewStrBuf(); + StrBufEUid_escapize(encBuf, buf); + set_preference("signature", encBuf, 1); + FreeStrBuf(&buf); - if (!havebstr("change_button")) { - safestrncpy(WC->ImportantMessage, - _("Cancelled. No settings were changed."), - sizeof WC->ImportantMessage); - display_main_menu(); - return; + 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, WCTemplputParams *TP) +{ + StrBuf *Setting; + if (get_PREFERENCE(TKEY(0), &Setting)) + StrBufAppendTemplate(Target, TP, Setting, 1); +} + +void tmplput_CFG_Descr(StrBuf *Target, WCTemplputParams *TP) +{ + const char *SettingStr; + SettingStr = PrefGetLocalStr(TKEY(0)); + if (SettingStr != NULL) + StrBufAppendBufPlain(Target, SettingStr, -1, 0); +} + + +void CfgZoneTempl(StrBuf *TemplBuffer, WCTemplputParams *TP) +{ + StrBuf *Zone = (StrBuf*) CTX; + + SVPutBuf("ZONENAME", Zone, 1); +} + +int ConditionalPreference(StrBuf *Target, WCTemplputParams *TP) +{ + StrBuf *Pref; + + if (!get_PREFERENCE(TKEY(2), &Pref)) + return 0; + + if (TP->Tokens->nParameters == 3) { + return 1; } + else if (TP->Tokens->Params[3]->Type == TYPE_STR) + return ((TP->Tokens->Params[3]->len == StrLength(Pref)) && + (strcmp(TP->Tokens->Params[3]->Start, ChrPtr(Pref)) == 0)); + else + return (StrTol(Pref) == TP->Tokens->Params[3]->lvalue); +} - /** - * 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", 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); - - ebuf = NewStrBufPlain(bstr("signature"), -1); - /////TODOeuid_escapize(ebuf); - set_preference("signature", ebuf, 1); +int ConditionalHazePreference(StrBuf *Target, WCTemplputParams *TP) +{ + StrBuf *Pref; - display_main_menu(); + if (!get_PREFERENCE(TKEY(2), &Pref) || + (Pref == NULL)) + return 0; + else + return 1; +} + +HashList *GetGVEAHash(StrBuf *Target, WCTemplputParams *TP) +{ + StrBuf *Rcp; + HashList *List = NULL; + int Done = 0; + int i, n = 1; + char N[64]; + + Rcp = NewStrBuf(); + serv_puts("GVEA"); + StrBuf_ServGetln(Rcp); + if (GetServerStatus(Rcp, NULL) == 1) { + FlushStrBuf(Rcp); + List = NewHash(1, NULL); + while (!Done && (StrBuf_ServGetln(Rcp)>=0)) { + if ( (StrLength(Rcp)==3) && + !strcmp(ChrPtr(Rcp), "000")) + { + Done = 1; + } + else { + i = snprintf(N, sizeof(N), "%d", n); + StrBufTrim(Rcp); + Put(List, N, i, Rcp, HFreeStrBuf); + Rcp = NewStrBuf(); + } + n++; + } + } + FreeStrBuf(&Rcp); + return List; +} +void DeleteGVEAHash(HashList **KillMe) +{ + DeleteHash(KillMe); +} + +HashList *GetGVSNHash(StrBuf *Target, WCTemplputParams *TP) +{ + StrBuf *Rcp; + HashList *List = NULL; + int Done = 0; + int i, n = 1; + char N[64]; + + Rcp = NewStrBuf(); + serv_puts("GVSN"); + StrBuf_ServGetln(Rcp); + if (GetServerStatus(Rcp, NULL) == 1) { + FlushStrBuf(Rcp); + List = NewHash(1, NULL); + while (!Done && (StrBuf_ServGetln(Rcp)>=0)) { + if ( (StrLength(Rcp)==3) && + !strcmp(ChrPtr(Rcp), "000")) + { + Done = 1; + } + else { + i = snprintf(N, sizeof(N), "%d", n); + StrBufTrim(Rcp); + Put(List, N, i, Rcp, HFreeStrBuf); + Rcp = NewStrBuf(); + } + n++; + } + } + FreeStrBuf(&Rcp); + return List; +} +void DeleteGVSNHash(HashList **KillMe) +{ + DeleteHash(KillMe); } +void +InitModule_PREFERENCES +(void) +{ + WebcitAddUrlHandler(HKEY("set_preferences"), set_preferences, 0); + WebcitAddUrlHandler(HKEY("change_start_page"), change_start_page, 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); + RegisterPreference("defaultfrom", _("Preferred email address"), PRF_STRING); + RegisterPreference("defaultname", _("Preferred display name for email messages"), PRF_STRING); + RegisterPreference("defaulthandle", _("Preferred display name for bulletin board posts"), PRF_STRING); + RegisterNamespace("OFFERSTARTPAGE", 0, 0, offer_start_page, CTX_NONE); + RegisterNamespace("PREF:VALUE", 1, 2, tmplput_CFG_Value, CTX_NONE); + RegisterNamespace("PREF:DESCR", 1, 1, tmplput_CFG_Descr, CTX_NONE); + RegisterIterator("PREF:ZONE", 0, ZoneHash, NULL, CfgZoneTempl, NULL, CTX_PREF, CTX_NONE, IT_NOFLAG); + + RegisterConditional(HKEY("COND:PREF"), 4, ConditionalPreference, CTX_NONE); + RegisterConditional(HKEY("COND:PREF:SET"), 4, ConditionalHazePreference, CTX_NONE); + + RegisterIterator("PREF:VALID:EMAIL:ADDR", 0, NULL, + GetGVEAHash, NULL, DeleteGVEAHash, CTX_STRBUF, CTX_NONE, IT_NOFLAG); + RegisterIterator("PREF:VALID:EMAIL:NAME", 0, NULL, + GetGVSNHash, NULL, DeleteGVSNHash, CTX_STRBUF, CTX_NONE, IT_NOFLAG); + +} /*@}*/