+ abEntry = (addrbookent*) malloc(sizeof(addrbookent));
+ memset(abEntry, 0, sizeof(addrbookent));
+ abEntry->name = NewStrBuf();
+ abEntry->VC = NewHash(0, lFlathash);
+ abEntry->ab_msgnum = Msg->msgnum;
+ parse_vcard(WC->WBuf, v, abEntry->VC, VCMime);
+
+ display_one_vcard(abEntry->name, abEntry, HKEY("vcard_list_name"));
+
+ if (StrLength(abEntry->name) == 0) {
+ StrBufPlain(abEntry->name, _("(no name)"), -1);
+ }
+
+ vcard_free(v);
+
+ Put(VS->addrbook, SKEY(abEntry->name), abEntry, deleteAbEnt);
+ return 0;
+}
+
+
+/*
+ * Render the address book using info we gathered during the scan
+ *
+ * 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 num_pages = 0;
+ int tabfirst = 0;
+ int tablast = 0;
+ StrBuf **tablabels;
+ int num_ab = GetCount(VS->addrbook);
+ HashList *headlines;
+ wcsession *WCC = WC;
+
+ WCTemplputParams *TP = NULL;
+ WCTemplputParams SubTP;
+
+ memset(&SubTP, 0, sizeof(WCTemplputParams));
+
+ if (num_ab == 0) {
+ do_template("vcard_list_empty");
+ return;
+ }
+
+ if (num_ab > 1) {
+ ///SortByHashKey(VS->addrbook, 0);
+ }
+
+ num_pages = (GetCount(VS->addrbook) / NAMESPERPAGE) + 1;
+
+ tablabels = malloc(num_pages * sizeof (StrBuf *));
+ if (tablabels == NULL) {
+ return;
+ }
+
+ headlines = NewHash(0, lFlathash);
+ for (i=0; i<num_pages; ++i) {
+ void *v1 = NULL;
+ void *v2 = NULL;
+ long hklen1, hklen2;
+ const char *c1, *c2;
+ StrBuf *headline;
+ addrbookent *a1, *a2;
+
+ tabfirst = i * NAMESPERPAGE;
+ tablast = tabfirst + NAMESPERPAGE - 1;
+ if (tablast > (num_ab - 1)) tablast = (num_ab - 1);
+
+ headline = NewStrBufPlain(NULL, StrLength(v1) + StrLength(v2) + 10);
+ if (GetHashAt(VS->addrbook, tabfirst, &hklen1, &c1, &v1)) {
+ a1 = (addrbookent*) v1;
+ StrBufAppendBuf(headline, a1->name, 0);
+
+ if (GetHashAt(VS->addrbook, tablast, &hklen2, &c2, &v2)) {
+
+ a2 = (addrbookent*) v2;
+ StrBufAppendBufPlain(headline, HKEY(" - "), 0);
+ StrBufAppendBuf(headline, a2->name, 0);
+ }
+ }
+ 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);
+
+ DoTemplate(HKEY("vcard_list"), WCC->WBuf, &SubTP);
+ UnStackContext(&SubTP);
+ DeleteHash(&headlines);
+ free(tablabels);
+ StrBufAppendBufPlain(WCC->WBuf, HKEY("</div>"), 0);/* closes: id=global */
+ wDumpContent(1);
+}
+
+
+
+int vcard_RenderView_or_Tail(SharedMessageStatus *Stat, void **ViewSpecific, long oper)
+{
+ const StrBuf *Mime;
+ vcardview_struct *VS;
+
+ VS = (vcardview_struct*) *ViewSpecific;
+ if (VS->is_singlecard)
+ read_message(WC->WBuf, HKEY("view_message"), lbstr("startmsg"), NULL, &Mime);
+ else
+ do_addrbook_view(VS); /* Render the address book */
+ return 0;
+}
+
+int vcard_Cleanup(void **ViewSpecific)
+{
+ vcardview_struct *VS;
+
+ VS = (vcardview_struct*) *ViewSpecific;
+ wDumpContent(1);
+ if ((VS != NULL) &&
+ (VS->addrbook != NULL))
+ DeleteHash(&VS->addrbook);
+ if (VS != NULL)
+ free(VS);
+
+ return 0;
+}
+
+void render_MIME_VCard(StrBuf *Target, WCTemplputParams *TP, StrBuf *FoundCharset)
+{
+ wc_mime_attachment *Mime = (wc_mime_attachment *) CTX(CTX_MIME_ATACH);
+ wcsession *WCC = WC;
+ if (StrLength(Mime->Data) == 0)
+ MimeLoadData(Mime);
+ if (StrLength(Mime->Data) > 0) {
+ struct vCard *v;
+ StrBuf *Buf;
+
+ Buf = NewStrBuf();
+ /** If it's my vCard I can edit it */
+ if ( (!strcasecmp(ChrPtr(WCC->CurRoom.name), USERCONFIGROOM))
+ || ((StrLength(WCC->CurRoom.name) > 11) &&
+ (!strcasecmp(&(ChrPtr(WCC->CurRoom.name)[11]), USERCONFIGROOM)))
+ || (WCC->CurRoom.view == VIEW_ADDRESSBOOK)
+ ) {
+ StrBufAppendPrintf(Buf, "<a href=\"edit_vcard?msgnum=%ld?partnum=%s\">",
+ Mime->msgnum, ChrPtr(Mime->PartNum));
+ StrBufAppendPrintf(Buf, "[%s]</a>", _("edit"));
+ }
+
+ /* In all cases, display the full card */
+
+ v = VCardLoad(Mime->Data);
+
+ if (v != NULL) {
+ 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 {
+ StrBufPlain(Buf, _("failed to load vcard"), -1);
+ }
+ FreeStrBuf(&Mime->Data);
+ Mime->Data = Buf;
+ }
+
+}
+
+void
+ServerStartModule_VCARD
+(void)
+{
+}
+
+void
+ServerShutdownModule_VCARD
+(void)
+{
+ DeleteHash(&DefineToToken);
+ DeleteHash(&vcNames);
+ DeleteHash(&VCTokenToDefine);
+}
+
+void
+InitModule_VCARD
+(void)
+{
+ StrBuf *Prefix = NewStrBufPlain(HKEY("VC:"));
+ DefineToToken = NewHash(1, lFlathash);
+ vcNames = NewHash(1, lFlathash);
+ 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,
+ NULL,
+ NULL,
+ NULL,
+ 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);
+
+ 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);
+ REGISTERTokenParamDefine(PhoneNumber);
+ REGISTERTokenParamDefine(EmailAddr);
+ REGISTERTokenParamDefine(Street);
+ REGISTERTokenParamDefine(Number);
+ REGISTERTokenParamDefine(AliasFor);
+ REGISTERTokenParamDefine(Base64BinaryAttachment);
+ REGISTERTokenParamDefine(TerminateList);
+ REGISTERTokenParamDefine(Address);
+
+ RegisterConditional("VC:HAVE:TYPE", 1, conditional_VC_Havetype, CTX_VCARD);
+ RegisterFilteredIterator("VC:TYPE", 1, DefineToToken, NULL, NULL, NULL, filter_VC_ByType, CTX_VCARD_TYPE, CTX_VCARD, IT_NOFLAG);
+ RegisterFilteredIterator("VC:TYPE:ITEMS", 0, NULL, getContextVcard, NULL, NULL, filter_VC_ByContextType, CTX_STRBUF, CTX_VCARD_TYPE, IT_NOFLAG);
+
+ RegisterMimeRenderer(HKEY("text/x-vcard"), render_MIME_VCard, 1, 201);
+ RegisterMimeRenderer(HKEY("text/vcard"), render_MIME_VCard, 1, 200);
+}