X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=webcit%2Fvcard_edit.c;h=f94841f9ac7caf062ec408cf5d4f93f50a9101d9;hb=7c2e682ec435f9e2c08a0f49ec67e6aa4358f263;hp=b3f2cba847d5cc58eb261a9ab213b91e90977af2;hpb=cdcc9f45abe49abb1f696528bcdd790e264121e0;p=citadel.git diff --git a/webcit/vcard_edit.c b/webcit/vcard_edit.c index b3f2cba84..f94841f9a 100644 --- a/webcit/vcard_edit.c +++ b/webcit/vcard_edit.c @@ -15,6 +15,7 @@ #include "calendar.h" CtxType CTX_VCARD = CTX_NONE; +CtxType CTX_VCARD_LIST = CTX_NONE; CtxType CTX_VCARD_TYPE = CTX_NONE; long VCEnumCounter = 0; @@ -102,6 +103,24 @@ ConstStr VCStr [] = { {HKEY("uid")} }; +/* + * Address book entry (keep it short and sweet, it's just a quickie lookup + * which we can use to get to the real meat and bones later) + */ +typedef struct _addrbookent { + StrBuf *name; + HashList *VC; + long ab_msgnum; /* message number of address book entry */ + StrBuf *msgNoStr; +} addrbookent; + +void deleteAbEnt(void *v) { + addrbookent *vc = (addrbookent*)v; + DeleteHash(&vc->VC); + FreeStrBuf(&vc->name); + FreeStrBuf(&vc->msgNoStr); + free(vc); +} HashList *DefineToToken = NULL; HashList *VCTokenToDefine = NULL; @@ -196,8 +215,8 @@ void tmpl_vcard_item(StrBuf *Target, WCTemplputParams *TP) { void *vItem; long searchFieldNo = GetTemplateTokenNumber(Target, TP, 0, 0); - HashList *vc = (HashList*) CTX(CTX_VCARD); - if (GetHash(vc, LKEY(searchFieldNo), &vItem) && (vItem != NULL)) { + addrbookent *ab = (addrbookent*) CTX(CTX_VCARD); + if (GetHash(ab->VC, LKEY(searchFieldNo), &vItem) && (vItem != NULL)) { StrBufAppendTemplate(Target, TP, (StrBuf*) vItem, 1); } } @@ -206,7 +225,7 @@ void tmpl_vcard_context_item(StrBuf *Target, WCTemplputParams *TP) { void *vItem; vcField *t = (vcField*) CTX(CTX_VCARD_TYPE); - HashList *vc = (HashList*) CTX(CTX_VCARD); + addrbookent *ab = (addrbookent*) CTX(CTX_VCARD); if (t == NULL) { LogTemplateError(NULL, "VCard item", ERR_NAME, TP, @@ -214,7 +233,7 @@ void tmpl_vcard_context_item(StrBuf *Target, WCTemplputParams *TP) return; } - if (GetHash(vc, LKEY(t->cval), &vItem) && (vItem != NULL)) { + if (GetHash(ab->VC, LKEY(t->cval), &vItem) && (vItem != NULL)) { StrBufAppendTemplate(Target, TP, (StrBuf*) vItem, 0); } else { @@ -256,6 +275,15 @@ void tmpl_vcard_name_str(StrBuf *Target, WCTemplputParams *TP) } } +void tmpl_vcard_msgno(StrBuf *Target, WCTemplputParams *TP) +{ + addrbookent *ab = (addrbookent*) CTX(CTX_VCARD); + if (ab->msgNoStr == NULL) { + ab->msgNoStr = NewStrBufPlain(NULL, 64); + } + StrBufPrintf(ab->msgNoStr, "%ld", ab->ab_msgnum); + StrBufAppendTemplate(Target, TP, ab->msgNoStr, 0); +} void tmpl_vcard_context_name_str(StrBuf *Target, WCTemplputParams *TP) { void *vItem; @@ -289,8 +317,8 @@ int filter_VC_ByType(const char* key, long len, void *Context, StrBuf *Target, W searchType = GetTemplateTokenNumber(Target, TP, IT_ADDT_PARAM(0), 0); if (vf->Type == searchType) { - HashList *vc = (HashList*) CTX(CTX_VCARD); - if (GetHash(vc, LKEY(vf->cval), &v) && v != NULL) + addrbookent *ab = (addrbookent*) CTX(CTX_VCARD); + if (GetHash(ab->VC, LKEY(vf->cval), &v) && v != NULL) return 1; } return rc; @@ -302,15 +330,15 @@ int filter_VC_ByType(const char* key, long len, void *Context, StrBuf *Target, W HashList *getContextVcard(StrBuf *Target, WCTemplputParams *TP) { vcField *vf = (vcField*) CTX(CTX_VCARD_TYPE); - HashList *vc = (HashList*) CTX(CTX_VCARD); + addrbookent *ab = (addrbookent*) CTX(CTX_VCARD); - if ((vf == NULL) || (vc == NULL)) { + if ((vf == NULL) || (ab == NULL)) { LogTemplateError(NULL, "VCard item type", ERR_NAME, TP, "Need VCard and Vcard type in context"); return NULL; } - return vc; + return ab->VC; } int filter_VC_ByContextType(const char* key, long len, void *Context, StrBuf *Target, WCTemplputParams *TP) @@ -331,14 +359,14 @@ int filter_VC_ByContextType(const char* key, long len, void *Context, StrBuf *Ta int conditional_VC_Havetype(StrBuf *Target, WCTemplputParams *TP) { - HashList *vc = (HashList*) CTX(CTX_VCARD); + addrbookent *ab = (addrbookent*) CTX(CTX_VCARD); long HaveFieldType = GetTemplateTokenNumber(Target, TP, 2, 0); int rc = 0; void *vVCitem; const char *Key; long len; - HashPos *it = GetNewHashPos(vc, 0); - while (GetNextHashPos(vc, it, &len, &Key, &vVCitem) && + HashPos *it = GetNewHashPos(ab->VC, 0); + while (GetNextHashPos(ab->VC, it, &len, &Key, &vVCitem) && (vVCitem != NULL)) { void *vvcField; @@ -358,20 +386,6 @@ int conditional_VC_Havetype(StrBuf *Target, WCTemplputParams *TP) return rc; } - - -/* - * Helper function for do_addrbook_view() - * Converts a name into a three-letter tab label - */ -void nametab(char *tabbuf, long len, char *name) { - stresc(tabbuf, len, name, 0, 0); - tabbuf[0] = toupper(tabbuf[0]); - tabbuf[1] = tolower(tabbuf[1]); - tabbuf[2] = tolower(tabbuf[2]); - tabbuf[3] = 0; -} - wc_mime_attachment *load_vcard(message_summary *Msg) { HashPos *it; @@ -414,76 +428,20 @@ wc_mime_attachment *load_vcard(message_summary *Msg) return VCMime; } - - -/* - * Turn a vCard "n" (name) field into something displayable. - */ -void vcard_n_prettyize(char *name) -{ - char *original_name; - int i, j, len; - - original_name = strdup(name); - len = strlen(original_name); - for (i=0; i<5; ++i) { - if (len > 0) { - if (original_name[len-1] == ' ') { - original_name[--len] = 0; - } - if (original_name[len-1] == ';') { - original_name[--len] = 0; - } - } - } - strcpy(name, ""); - j=0; - for (i=0; icval), ThisFieldStr, HFreeStrBuf); } -/* - * html print a vcard - * display_vcard() calls this after parsing the textual vCard into - * our 'struct vCard' data object. - * - * Set 'full' to nonzero to display the full card, otherwise it will only - * show a summary line. - * - * This code is a bit ugly, so perhaps an explanation is due: we do this - * in two passes through the vCard fields. On the first pass, we process - * fields we understand, and then render them in a pretty fashion at the - * end. Then we make a second pass, outputting all the fields we don't - * understand in a simple two-column name/value format. - * v the vCard to parse - * msgnum Citadel message pointer - */ + void parse_vcard(StrBuf *Target, struct vCard *v, HashList *VC, wc_mime_attachment *Mime) { - StrBuf *Val = NULL; StrBuf *Swap = NULL; int i, j, k; char buf[SIZ]; @@ -509,34 +467,18 @@ void parse_vcard(StrBuf *Target, struct vCard *v, HashList *VC, wc_mime_attachme /*len = */extract_token(firsttoken, ChrPtr(thisname), 0, ';', sizeof firsttoken); ntokens = num_tokens(ChrPtr(thisname), ';'); for (j=0, k=0; j < ntokens && k < 10; ++j) { - /*int evc[10];*/ - len = extract_token(buf, ChrPtr(thisname), j, ';', sizeof buf); if (!strcasecmp(buf, "encoding=quoted-printable")) { is_qp = 1; -/* remove_token(thisname, j, ';');*/ } else if (!strcasecmp(buf, "encoding=base64")) { is_b64 = 1; -/* remove_token(thisname, j, ';');*/ } else{ if (StrLength(thisVCToken) > 0) { StrBufAppendBufPlain(thisVCToken, HKEY(";"), 0); } StrBufAppendBufPlain(thisVCToken, buf, len, 0); - /* - if (GetHash(VCToEnum, buf, len, &V)) - { - evc[k] = (int) V; - - Put(VC, IKEY(evc), Val, HFreeStrBuf); - - syslog(LOG_DEBUG, "[%ul] -> k: %d %s - %s", evc, k, buf, VCStr[evc[k]].Key); - k++; - } -*/ - } } @@ -577,6 +519,10 @@ void parse_vcard(StrBuf *Target, struct vCard *v, HashList *VC, wc_mime_attachme break; case Base64BinaryAttachment: + ThisFieldStr = NewStrBufPlain(v->prop[i].value, -1); + StrBufDecodeBase64(ThisFieldStr); + PutVcardItem(VC, thisField, ThisFieldStr, is_qp, Swap); + break; case TerminateList: case UnKnown: break; @@ -602,30 +548,6 @@ void parse_vcard(StrBuf *Target, struct vCard *v, HashList *VC, wc_mime_attachme StrBufAppendBufPlain(oldVal, v->prop[i].value, -1, 0); continue; } - - /* copy over the payload into a StrBuf */ - Val = NewStrBufPlain(v->prop[i].value, -1); - - /* if we have some untagged QP, detect it here. */ - if (is_qp || (strstr(v->prop[i].value, "=?")!=NULL)){ - StrBuf *b; - StrBuf_RFC822_to_Utf8(Swap, Val, NULL, NULL); /* default charset, current charset */ - b = Val; - Val = Swap; - Swap = b; - FlushStrBuf(Swap); - } - else if (is_b64) { - StrBufDecodeBase64(Val); - } -#if 0 - syslog(LOG_DEBUG, "-> firsttoken: %s thisname: %s Value: [%s][%s]", - firsttoken, - ChrPtr(thisname), - ChrPtr(Val), - v->prop[i].value); -#endif - FreeStrBuf(&Val); } FreeStrBuf(&thisname); FreeStrBuf(&Swap); @@ -634,14 +556,14 @@ void parse_vcard(StrBuf *Target, struct vCard *v, HashList *VC, wc_mime_attachme void tmplput_VCARD_ITEM(StrBuf *Target, WCTemplputParams *TP) { - HashList *VC = CTX(CTX_VCARD); + addrbookent *ab = CTX(CTX_VCARD); int evc; void *vStr; evc = GetTemplateTokenNumber(Target, TP, 0, -1); if (evc != -1) { - if (GetHash(VC, IKEY(evc), &vStr)) + if (GetHash(ab->VC, IKEY(evc), &vStr)) { StrBufAppendTemplate(Target, TP, (StrBuf*) vStr, @@ -651,13 +573,19 @@ void tmplput_VCARD_ITEM(StrBuf *Target, WCTemplputParams *TP) } -void display_one_vcard (StrBuf *Target, HashList *VC, const char *tp_name, size_t tp_name_len) +HashList *CtxGetVcardList(StrBuf *Target, WCTemplputParams *TP) +{ + HashList *pb = CTX(CTX_VCARD_LIST); + return pb; +} + +void display_one_vcard (StrBuf *Target, addrbookent *ab, const char *tp_name, size_t tp_name_len) { WCTemplputParams *TP = NULL; WCTemplputParams SubTP; memset(&SubTP, 0, sizeof(WCTemplputParams)); - StackContext(TP, &SubTP, VC, CTX_VCARD, 0, NULL); + StackContext(TP, &SubTP, ab, CTX_VCARD, 0, NULL); DoTemplate(tp_name, tp_name_len, Target, &SubTP); UnStackContext(&SubTP); @@ -711,14 +639,16 @@ void do_edit_vcard(long msgnum, char *partnum, wc_mime_attachment *VCAtt, const char *return_to, const char *force_room) { - HashList *VC; WCTemplputParams SubTP; + WCTemplputParams SubTP; wcsession *WCC = WC; message_summary *Msg = NULL; wc_mime_attachment *VCMime = NULL; struct vCard *v; char whatuser[256]; - VC = NewHash(0, lFlathash); + addrbookent ab; + memset(&ab, 0, sizeof(addrbookent)); + ab.VC = NewHash(0, lFlathash); /* Display the form */ output_headers(1, 1, 1, 0, 0, 0); @@ -737,6 +667,7 @@ void do_edit_vcard(long msgnum, char *partnum, convenience_page("770000", _("Error"), "");/*TODO: important message*/ DestroyMessageSummary(Msg); return; + DeleteHash(&ab.VC); } v = VCardLoad(VCMime->Data); @@ -745,23 +676,23 @@ void do_edit_vcard(long msgnum, char *partnum, v = VCardLoad(VCAtt->Data); } - parse_vcard(WCC->WBuf, v, VC, NULL); + parse_vcard(WCC->WBuf, v, ab.VC, NULL); vcard_free(v); } memset(&SubTP, 0, sizeof(WCTemplputParams)); - { WCTemplputParams *TP = NULL; WCTemplputParams SubTP; - StackContext(TP, &SubTP, VC, CTX_VCARD, 0, NULL); + + StackContext(TP, &SubTP, &ab, CTX_VCARD, 0, NULL); DoTemplate(HKEY("vcard_edit"), WCC->WBuf, &SubTP); UnStackContext(&SubTP); } - DeleteHash(&VC); + DeleteHash(&ab.VC); wDumpContent(1); @@ -783,8 +714,6 @@ void edit_vcard(void) { do_edit_vcard(msgnum, partnum, NULL, NULL, "", NULL); } - - /* * parse edited vcard from the browser */ @@ -953,22 +882,6 @@ void submit_vcard(void) { -/* - * Address book entry (keep it short and sweet, it's just a quickie lookup - * which we can use to get to the real meat and bones later) - */ -typedef struct _addrbookent { - StrBuf *name; - HashList *VC; - long ab_msgnum; /* message number of address book entry */ -} addrbookent; - -void deleteAbEnt(void *v) { - addrbookent *vc = (addrbookent*)v; - DeleteHash(&vc->VC); - FreeStrBuf(&vc->name); -} - typedef struct _vcardview_struct { long is_singlecard; HashList *addrbook; @@ -1031,7 +944,7 @@ int vcard_LoadMsgFromServer(SharedMessageStatus *Stat, abEntry->ab_msgnum = Msg->msgnum; parse_vcard(WC->WBuf, v, abEntry->VC, VCMime); - display_one_vcard(abEntry->name, abEntry->VC, HKEY("vcard_list_name")); + display_one_vcard(abEntry->name, abEntry, HKEY("vcard_list_name")); if (StrLength(abEntry->name) == 0) { StrBufPlain(abEntry->name, _("(no name)"), -1); @@ -1050,19 +963,15 @@ int vcard_LoadMsgFromServer(SharedMessageStatus *Stat, * addrbook the addressbook to render * num_ab the number of the addressbook */ +static int NAMESPERPAGE = 60; void do_addrbook_view(vcardview_struct* VS) { long i = 0; - int displayed = 0; - int bg = 0; - static int NAMESPERPAGE = 60; int num_pages = 0; int tabfirst = 0; int tablast = 0; - int page = 0; - char **tablabels; + StrBuf **tablabels; int num_ab = GetCount(VS->addrbook); HashList *headlines; - HashPos *it; wcsession *WCC = WC; WCTemplputParams *TP = NULL; @@ -1076,12 +985,12 @@ void do_addrbook_view(vcardview_struct* VS) { } if (num_ab > 1) { - ///SortByHashKey(VS->addrbook, 0); + SortByHashKey(VS->addrbook, 1); } num_pages = (GetCount(VS->addrbook) / NAMESPERPAGE) + 1; - tablabels = malloc(num_pages * sizeof (char *)); + tablabels = malloc(num_pages * sizeof (StrBuf *)); if (tablabels == NULL) { return; } @@ -1103,75 +1012,26 @@ void do_addrbook_view(vcardview_struct* VS) { if (GetHashAt(VS->addrbook, tabfirst, &hklen1, &c1, &v1)) { a1 = (addrbookent*) v1; StrBufAppendBuf(headline, a1->name, 0); - + StrBuf_Utf8StrCut(headline, 3); if (GetHashAt(VS->addrbook, tablast, &hklen2, &c2, &v2)) { a2 = (addrbookent*) v2; StrBufAppendBufPlain(headline, HKEY(" - "), 0); StrBufAppendBuf(headline, a2->name, 0); + StrBuf_Utf8StrCut(headline, 9); } } + tablabels[i] = headline; Put(headlines, LKEY(i), headline, HFreeStrBuf); } + StrTabbedDialog(WC->WBuf, num_pages, tablabels); + StackContext(TP, &SubTP, VS->addrbook, CTX_VCARD_LIST, 0, NULL); - tabbed_dialog(num_pages, tablabels); - page = (-1); - - it = GetNewHashPos(VS->addrbook, 0); - for (i=0; iaddrbook, it, &hklen, &key, &v); - if (v == NULL) - continue; - abEnt = (addrbookent *) v; - if ((i / NAMESPERPAGE) != page) { /* New tab */ - page = (i / NAMESPERPAGE); - if (page > 0) { - do_template("vcard_list_section_end"); - end_tab(page-1, num_pages); - } - begin_tab(page, num_pages); - do_template("vcard_list_section_start"); - displayed = 0; - } - - if ((displayed % 4) == 0) { - if (displayed > 0) { - do_template("vcard_list_row_end"); - } - do_template("vcard_list_row_start"); - bg = 1 - bg; - } - - - StackContext(TP, &SubTP, abEnt->VC, CTX_VCARD, 0, NULL); - - DoTemplate(HKEY("vcard_list_entry"), WCC->WBuf, &SubTP); - UnStackContext(&SubTP); - - ++displayed; - } - DeleteHashPos(&it); - - /* Placeholders for empty columns at end */ - if ((num_ab % 4) != 0) { - for (i=0; i<(4-(num_ab % 4)); ++i) { - do_template("vcard_list_cell_end"); - } - } - - do_template("vcard_list_section_end"); - end_tab((num_pages-1), num_pages); - - begin_tab(num_pages, num_pages); - /* FIXME there ought to be something here */ - end_tab(num_pages, num_pages); - + DoTemplate(HKEY("vcard_list"), WCC->WBuf, &SubTP); + UnStackContext(&SubTP); DeleteHash(&headlines); - wDumpContent(1); + free(tablabels); + StrBufAppendBufPlain(WCC->WBuf, HKEY(""), 0);/* closes: id=global */ } @@ -1231,12 +1091,16 @@ void render_MIME_VCard(StrBuf *Target, WCTemplputParams *TP, StrBuf *FoundCharse v = VCardLoad(Mime->Data); if (v != NULL) { - HashList *VC; - - VC = NewHash(0, lFlathash); - parse_vcard(Target, v, VC, Mime); - display_one_vcard (Target, VC, HKEY("vcard_msg_display")); - DeleteHash(&VC); + addrbookent ab; + memset(&ab, 0, sizeof(addrbookent)); + + ab.VC = NewHash(0, lFlathash); + ab.ab_msgnum = Mime->msgnum; + + parse_vcard(Target, v, ab.VC, Mime); + display_one_vcard (Target, &ab, HKEY("vcard_msg_display")); + DeleteHash(&ab.VC); + vcard_free(v); } else { @@ -1252,8 +1116,6 @@ void ServerStartModule_VCARD (void) { - ///VCToEnum = NewHash(0, NULL); - } void @@ -1263,7 +1125,6 @@ ServerShutdownModule_VCARD DeleteHash(&DefineToToken); DeleteHash(&vcNames); DeleteHash(&VCTokenToDefine); - /// DeleteHash(&VCToEnum); } void @@ -1276,8 +1137,14 @@ InitModule_VCARD VCTokenToDefine = NewHash(1, NULL); autoRegisterTokens(&VCEnumCounter, VCStrE, Prefix, 0, 0); FreeStrBuf(&Prefix); + + REGISTERTokenParamDefine(NAMESPERPAGE); + + RegisterCTX(CTX_VCARD); + RegisterCTX(CTX_VCARD_LIST); RegisterCTX(CTX_VCARD_TYPE); + RegisterReadLoopHandlerset( VIEW_ADDRESSBOOK, vcard_GetParamsGetServerCall, @@ -1287,6 +1154,10 @@ InitModule_VCARD vcard_LoadMsgFromServer, vcard_RenderView_or_Tail, vcard_Cleanup); + + RegisterIterator("MAIL:VCARDS", 0, NULL, CtxGetVcardList, NULL, NULL, CTX_VCARD, CTX_VCARD_LIST, IT_NOFLAG); + + WebcitAddUrlHandler(HKEY("edit_vcard"), "", 0, edit_vcard, 0); WebcitAddUrlHandler(HKEY("submit_vcard"), "", 0, submit_vcard, 0); WebcitAddUrlHandler(HKEY("vcardphoto"), "", 0, display_vcard_photo_img, NEED_URL); @@ -1294,6 +1165,7 @@ InitModule_VCARD RegisterNamespace("VC:ITEM", 2, 2, tmpl_vcard_item, preeval_vcard_item, CTX_VCARD); RegisterNamespace("VC:CTXITEM", 1, 1, tmpl_vcard_context_item, NULL, CTX_VCARD_TYPE); RegisterNamespace("VC:NAME", 1, 1, tmpl_vcard_name_str, preeval_vcard_name_str, CTX_VCARD); + RegisterNamespace("VC:MSGNO", 0, 1, tmpl_vcard_msgno, NULL, CTX_VCARD); RegisterNamespace("VC:CTXNAME", 1, 1, tmpl_vcard_context_name_str, NULL, CTX_VCARD_TYPE); REGISTERTokenParamDefine(FlatString); REGISTERTokenParamDefine(StringCluster);