1 // getcontactinfo.cpp - Contact Information subroutines.
3 // (c) 2012-2015 Xestia Software Development.
5 // This file is part of Xestia Address Book.
7 // Xestia Address Book is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by the
9 // Free Software Foundation, version 3 of the license.
11 // Xestia Address Book is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License along
17 // with Xestia Address Book. If not, see <http://www.gnu.org/licenses/>
23 #include <wx/tokenzr.h>
24 #include <wx/fs_mem.h>
25 #include <wx/mstream.h>
26 #include <wx/filesys.h>
27 #include <wx/datetime.h>
28 //#include <b64/decode.h>
31 #include "getcontactinfo.h"
33 #include "textprocessing.h"
34 #include "../vcard/vcard34conv.h"
36 void LoadContactData(vCard *vCardObj, wxHtmlWindow *HTMLObj, wxString SID,
37 wxString OldSID, std::map<wxString, wxString> *MemoryFSList){
39 // Load the vCard contact data into the wxHTMLWindow given.
41 // Show message to user that the contact information is loading.
43 HTMLObj->SetBorders(0);
47 wxFileSystem::AddHandler(new wxMemoryFSHandler);
49 PageData.append(wxT("<html>"));
50 PageData.append(wxT("<head>"));
51 PageData.append(wxT("<title>Page Loading</title>"));
52 PageData.append(wxT("</head>"));
53 PageData.append(wxT("<body>"));
54 PageData.append(wxT("<h2>"));
55 PageData.append(_("Loading contact information..."));
56 PageData.append(wxT("</h2>"));
57 PageData.append(wxT("</body>"));
58 PageData.append(wxT("</html>"));
60 HTMLObj->SetPage(PageData);
64 // Delete the information from the old session.
66 if (!OldSID.IsEmpty()){
68 if (MemoryFSList->find(OldSID) == MemoryFSList->end()){
73 std::map<wxString, wxString>::iterator striter;
75 for (striter = MemoryFSList->begin(); striter != MemoryFSList->end(); striter++){
77 if (OldSID == striter->second){
79 // Delete the references from the wxMemoryFSHandler
80 // and the entry from the map.
82 wxMemoryFSHandler::RemoveFile(striter->first);
89 MemoryFSList->erase(striter);
95 // MAke sure new session ID doesn't conflict with existing
96 // data. If there is a match, generate a new one and check again.
98 bool SIDMatch = FALSE;
101 for (std::map<wxString, wxString>::iterator striter = MemoryFSList->begin();
102 striter != MemoryFSList->end(); striter++){
104 SIDTemp = striter->second;
108 // Generate a new random number.
110 SID = wxString::Format(wxT("%i"), rand() % 32768);
112 // Rewind the seek process back to the start.
114 striter = MemoryFSList->begin();
122 // Setup the HTML document.
124 PageData.append(wxT("<html>"));
125 PageData.append(wxT("<head>"));
126 PageData.append(wxT("<title>Contact Information</title>"));
127 PageData.append(wxT("</head>"));
129 // Process the CSS section.
131 PageData.append(wxT("<body>"));
133 // Process the data in the vCard object.
137 ArrayvCardOutData FNList;
138 FNList = vCardObj->GetByPartial(wxT("FN"));
140 PageData.append(wxT("<table style=\"background: #cccccc; width: 100%\">"));
141 PageData.append(wxT("<tr>"));
142 PageData.append(wxT("<td style=\"width:100%\">"));
143 PageData.append(wxT("<h2>"));
145 if (FNList.PropCount > 0){
146 FNList.PropValues[0].Trim();
147 PageData.append(FNList.PropValues[0]);
150 PageData.append(wxT("</h2>"));
151 PageData.append(wxT("</td>"));
152 PageData.append(wxT("<td style=\"width: 200px;\">"));
154 // Define common variables for ADR.
156 std::map<int,int> SplitPoints;
157 std::map<int,int> SplitLength;
158 std::map<int,int>::iterator SLiter;
165 wxString AddressPOBox;
166 wxString AddressStreet;
167 wxString AddressLocality;
168 wxString AddressRegion;
169 wxString AddressPostalCode;
170 wxString AddressCountry;
171 wxString AddressExtended;
173 wxString FinalAddressLine;
174 bool AddressFirst = TRUE;
176 // Define common variables for PHOTO and LOGO.
178 std::string PhotoDataBin;
179 std::string PhotoDataIn;
180 wxString PhotoSplitData;
181 wxString PhotoMIMEType;
182 wxString PhotoEncType;
183 wxString PhotoEncData;
184 bool LoadPicture = FALSE;
185 bool DataDisplay = FALSE;
186 bool RectData = FALSE;
187 wxRect PhotoRectPoints;
188 wxString SIDFilename;
194 ArrayvCardOutData ContactData = vCardObj->GetByPartial(wxT("PHOTO"));
196 if (ContactData.PropCount > 0){
202 /*std::map<int,int> SplitPts;
203 std::map<int,int> SplitLen;
204 std::map<wxString,wxString> SplitData;
207 SplitPropertyData(&ContactData.PropData[0],
213 for (std::map<wxString, wxString>::iterator striter = SplitData.begin();
214 striter != SplitData.end(); striter++){
220 // Look for the X-ABCROP-RECTANGLE.
222 wxStringTokenizer PhotoSplit(ContactData.PropData[0], wxT(":"));
223 wxString PhotoPropertyDataString = PhotoSplit.GetNextToken();
224 wxStringTokenizer PhotoPropertyData(PhotoPropertyDataString, wxT(";"));
225 wxString PropertyLineData;
226 wxString PropertyName;
227 wxString PropertyValue;
229 wxStringTokenizer DataSplit(ContactData.PropValues[0], wxT(";"));
230 PhotoSplitData = DataSplit.GetNextToken();
231 wxStringTokenizer MIMESplit(PhotoSplitData, wxT(":"));
232 MIMESplit.GetNextToken();
233 PhotoMIMEType = MIMESplit.GetNextToken();
234 PhotoSplitData = DataSplit.GetNextToken();
235 wxStringTokenizer EncSplit(PhotoSplitData, wxT(","));
236 PhotoEncType = EncSplit.GetNextToken();
237 PhotoEncData = EncSplit.GetNextToken();
239 // Convert the picture data from base64 to binary.
241 PhotoDataIn = std::string(PhotoEncData.mb_str());
242 PhotoDataBin = base64_decode(PhotoDataIn);
243 wxMemoryInputStream istream(PhotoDataBin.c_str(), (size_t)PhotoDataBin.size());
246 if (!photo.LoadFile(istream, wxBITMAP_TYPE_ANY)){
248 // Photo failed to load so do nothing.
254 while (PhotoPropertyData.HasMoreTokens()){
256 PropertyLineData = PhotoPropertyData.GetNextToken();
258 wxStringTokenizer PhotoPropPair(PropertyLineData, wxT("="));
259 wxString PhotoPropName = PhotoPropPair.GetNextToken();
260 wxString PhotoPropValue = PhotoPropPair.GetNextToken();
262 if (PhotoPropName == wxT("X-ABCROP-RECTANGLE")){
264 wxStringTokenizer PhotoRectData(PhotoPropValue, wxT("&"));
266 PhotoRectData.GetNextToken();
268 //PhotoRectPoints.SetX(wxAtoi(PhotoRectData.GetNextToken()));
269 //PhotoRectPoints.SetY(wxAtoi(PhotoRectData.GetNextToken()) - 100);
271 int PointXBase = wxAtoi(PhotoRectData.GetNextToken());
272 int PointYBase = wxAtoi(PhotoRectData.GetNextToken());
273 int PointWBase = wxAtoi(PhotoRectData.GetNextToken());
274 int PointHBase = wxAtoi(PhotoRectData.GetNextToken());
276 int PointX = PointXBase;
277 int PointY = PointYBase;
278 int PointW = PointWBase;
279 int PointH = PointHBase;
283 if (PointYBase > PointHBase){
285 PointX = photo.GetWidth() - PointXBase - 140;
286 PointY = photo.GetHeight() - PointYBase - 140;
290 } else if (PointXBase > PointWBase){
292 PointX = photo.GetWidth() - PointXBase;
293 PointY = PointYBase - 50;
301 PhotoRectPoints.SetX(PointX);
302 PhotoRectPoints.SetY(PointY);
303 PhotoRectPoints.SetWidth(PointW);
304 PhotoRectPoints.SetHeight(PointH);
313 // Resize the picture to 125x125.
315 // Add to the wxMemnoryFSHandler.
317 SIDFilename = SID + wxT("-photo");
319 if (RectData == TRUE){
321 wxImage rectphoto = photo.GetSubImage(PhotoRectPoints);
322 rectphoto = rectphoto.Scale(75, 75, wxIMAGE_QUALITY_HIGH);
323 wxMemoryFSHandler::AddFile(SIDFilename, rectphoto, wxBITMAP_TYPE_PNG);
327 photo = photo.Scale(50, 50, wxIMAGE_QUALITY_HIGH);
328 wxMemoryFSHandler::AddFile(SIDFilename, photo, wxBITMAP_TYPE_PNG);
332 // Add the filename to the MemoryFSList map.
334 MemoryFSList->insert(std::make_pair(SIDFilename, SID));
340 if (LoadPicture == TRUE){
342 PageData.append(wxT("<img src=\"memory:") + SIDFilename + wxT("\">"));
350 ContactData = vCardObj->GetByPartial(wxT("LOGO"));
352 if (ContactData.PropCount > 0){
356 wxStringTokenizer DataSplit(ContactData.PropValues[0], wxT(";"));
357 PhotoSplitData = DataSplit.GetNextToken();
358 wxStringTokenizer MIMESplit(PhotoSplitData, wxT(":"));
359 MIMESplit.GetNextToken();
360 PhotoMIMEType = MIMESplit.GetNextToken();
361 PhotoSplitData = DataSplit.GetNextToken();
362 wxStringTokenizer EncSplit(PhotoSplitData, wxT(","));
363 PhotoEncType = EncSplit.GetNextToken();
364 PhotoEncData = EncSplit.GetNextToken();
366 // Convert the picture data from base64 to binary.
368 PhotoDataIn = std::string(PhotoEncData.mb_str());
369 PhotoDataBin = base64_decode(PhotoDataIn);
370 wxMemoryInputStream istream(PhotoDataBin.c_str(), (size_t)PhotoDataBin.size());
373 if (!photo.LoadFile(istream, wxBITMAP_TYPE_ANY)){
375 // Photo failed to load so do nothing.
383 photo = photo.Scale(50, 50, wxIMAGE_QUALITY_HIGH);
385 // Resize the picture to 125x125.
387 // Add to the wxMemnoryFSHandler.
389 SIDFilename = SID + wxT("-logo");
391 wxMemoryFSHandler::AddFile(SIDFilename, photo, wxBITMAP_TYPE_PNG);
393 // Add the filename to the MemoryFSList map.
395 MemoryFSList->insert(std::make_pair(SIDFilename, SID));
401 if (LoadPicture == TRUE){
403 PageData.append(wxT("<img src=\"memory:") + SIDFilename + wxT("\">"));
407 PageData.append(wxT("</td>"));
408 PageData.append(wxT("</tr>"));
409 PageData.append(wxT("</table>"));
411 // Process LOGO, PHOTO, SOUND, KEY, VND-* and X-*
412 // lines and display icons for each accordingly.
414 ContactData = vCardObj->GetByPartial(wxT("PHOTO"));
416 bool AddBreak = FALSE;
417 wxString TypePageData;
419 if (ContactData.PropCount > 1){
421 TypePageData.append(wxT("<img src=\"memory:cipto.png\" alt=\""));
422 TypePageData.append(_("This contact has multiple photos."));
423 TypePageData.append(wxT("\">"));
428 ContactData = vCardObj->GetByPartial(wxT("LOGO"));
430 if (ContactData.PropCount > 1){
432 TypePageData.append(wxT("<img src=\"memory:cilog.png\" alt=\""));
433 TypePageData.append(_("This contact has multiple logos."));
434 TypePageData.append(wxT("\">"));
439 ContactData = vCardObj->GetByPartial(wxT("SOUND"));
441 if (ContactData.PropCount >= 1){
443 TypePageData.append(wxT("<img src=\"memory:cisnd.png\" alt=\""));
444 TypePageData.append(_("This contact has audio information."));
445 TypePageData.append(wxT("\">"));
450 ContactData = vCardObj->GetByPartial(wxT("KEY"));
452 if (ContactData.PropCount >= 1){
454 TypePageData.append(wxT("<img src=\"memory:cikey.png\" alt=\""));
455 TypePageData.append(_("This contact has crytographic keys."));
456 TypePageData.append(wxT("\">"));
461 ContactData = vCardObj->GetByPartial(wxT("VND-"));
463 if (ContactData.PropCount >= 1){
465 TypePageData.append(wxT("<img src=\"memory:civen.png\" alt=\""));
466 TypePageData.append(_("This contact has vendor-specific information."));
467 TypePageData.append(wxT("\">"));
472 ContactData = vCardObj->GetByPartial(wxT("X-"));
474 if (ContactData.PropCount >= 1){
476 TypePageData.append(wxT("<img src=\"memory:ciext.png\" alt=\""));
477 TypePageData.append(_("This contact has extended information."));
478 TypePageData.append(wxT("\">"));
483 if (!TypePageData.IsEmpty()){
485 PageData.append("<table style=\"{background: #dddddd; width:100%}\"><tr><td>");
486 PageData.append(TypePageData);
487 PageData.append("</tr></td></table>");
491 if (AddBreak == TRUE){
493 PageData.append(wxT("<br><br>"));
497 bool MultiLogoIcon = FALSE;
498 bool MultiPhotoIcon = FALSE;
499 bool SoundIcon = FALSE;
500 bool KeyIcon = FALSE;
501 bool VendorIcon = FALSE;
502 bool XTokenIcon = FALSE;
506 ContactData = vCardObj->GetByPartial(wxT("BDAY"));
511 if (ContactData.PropCount > 0){
515 for (int i = 0; i < ContactData.PropCount; i++){
517 // Grab the first birthday only.
519 BDayLine = ContactData.PropValues[i];
522 CaptureString(&BDayLine, FALSE);
523 ConvertToHTML(&BDayLine);
525 DataLines.append(BDayLine);
535 PageData.append("<table CELLPADDING=4 style=\"{width: 100%;}\"><tr><td>");
537 if (DataDisplay == TRUE){
540 PageData.append(wxT("<b>"));
541 PageData.append(_("Birthday:"));
542 PageData.append(wxT("</b> "));
543 PageData.append(DataLines);
544 PageData.append(wxT("<br>"));
548 // Process Anniversary
550 ContactData = vCardObj->GetByPartial(wxT("ANNIVERSARY"));
555 if (ContactData.PropCount > 0){
559 for (int i = 0; i < ContactData.PropCount; i++){
561 // Grab the first anniversary only.
563 AnniLine = ContactData.PropValues[i];
566 CaptureString(&AnniLine, FALSE);
567 ConvertToHTML(&AnniLine);
569 DataLines.append(AnniLine);
579 if (DataDisplay == TRUE){
582 PageData.append(wxT("<b>"));
583 PageData.append(_("Anniversary:"));
584 PageData.append(wxT("</b> "));
585 PageData.append(DataLines);
586 PageData.append(wxT("<br>"));
592 ContactData = vCardObj->GetByPartial(wxT("NICKNAME"));
597 if (ContactData.PropCount > 0){
599 wxString NicknameLine;
601 for (int i = 0; i < ContactData.PropCount; i++){
603 NicknameLine = ContactData.PropValues[i];
606 CaptureString(&NicknameLine, FALSE);
607 ConvertToHTML(&NicknameLine);
609 DataLines.append(wxT("<tr><td><b>"));
610 DataLines.append(_("Nickname:"));
611 DataLines.append(wxT(" </b></td><td>"));
612 DataLines.append(NicknameLine);
613 DataLines.append(wxT("</td></tr>"));
621 if (DataDisplay == TRUE){
624 PageData.append(wxT("<h4>"));
625 PageData.append(_("Nicknames"));
626 PageData.append(wxT("</h4>"));
627 PageData.append(wxT("<br>"));
628 PageData.append(wxT("<table>"));
629 PageData.append(DataLines);
630 PageData.append(wxT("</table>"));
636 ContactData = vCardObj->GetByPartial(wxT("ADR"));
641 if (ContactData.PropCount > 0){
643 wxString AddressLine;
645 for (int i = 0; i < ContactData.PropCount; i++){
647 AddressLine = ContactData.PropValues[i];
649 intPropertyLen = AddressLine.Len();
656 AddressPOBox.clear();
657 AddressStreet.clear();
658 AddressLocality.clear();
659 AddressRegion.clear();
660 AddressPostalCode.clear();
661 AddressCountry.clear();
662 AddressExtended.clear();
663 FinalAddressLine.clear();
666 for (int i = 0; i <= intPropertyLen; i++){
670 if (AddressLine.Mid(i, 1) == wxT(";") && AddressLine.Mid((i - 1), 1) != wxT("\\")){
673 SplitPoints.insert(std::make_pair(intSplitsFound, (i + 1)));
675 if (intSplitsFound == 6){
677 SplitLength.insert(std::make_pair(intSplitsFound, (intSplitSize - 1)));
682 SplitLength.insert(std::make_pair(intSplitsFound, (intSplitSize - 1)));
692 // Split the data into several parts.
694 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
695 intiter != SplitPoints.end(); ++intiter){
697 if (intiter->first == 1){
701 SLiter = SplitLength.find(1);
703 //txtSurname->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(0, SLiter->second), TRUE));
704 AddressPOBox = AddressLine.Mid(0, SLiter->second);
705 intPrevValue = intiter->second;
707 } else if (intiter->first == 2){
709 // Deal with extended address.
711 SLiter = SplitLength.find(2);
713 AddressExtended = AddressLine.Mid(intPrevValue, SLiter->second);
714 //txtForename->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue, SLiter->second), TRUE));
715 intPrevValue = intiter->second;
717 } else if (intiter->first == 3){
719 // Deal with street address.
721 SLiter = SplitLength.find(3);
723 AddressStreet = AddressLine.Mid(intPrevValue, SLiter->second);
724 //txtOtherNames->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue, SLiter->second), TRUE));
725 intPrevValue = intiter->second;
727 } else if (intiter->first == 4){
729 // Deal with locality
731 SLiter = SplitLength.find(4);
733 AddressLocality = AddressLine.Mid(intPrevValue, SLiter->second);
734 //txtTitle->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue, SLiter->second), TRUE));
735 intPrevValue = intiter->second;
737 //txtSuffix->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue, wxSTRING_MAXLEN), TRUE));
739 } else if (intiter->first == 5){
743 SLiter = SplitLength.find(5);
745 AddressRegion = AddressLine.Mid(intPrevValue, SLiter->second);
746 //txtTitle->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue, SLiter->second), TRUE));
747 intPrevValue = intiter->second;
749 //txtSuffix->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue, wxSTRING_MAXLEN), TRUE));
751 } else if (intiter->first == 6){
753 // Deal with post code.
755 SLiter = SplitLength.find(6);
757 AddressPostalCode = AddressLine.Mid(intPrevValue, SLiter->second);
758 //txtTitle->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue, SLiter->second), TRUE));
759 intPrevValue = intiter->second;
761 // Deal with country.
763 AddressCountry = AddressLine.Mid(intPrevValue);
764 //txtSuffix->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue, wxSTRING_MAXLEN), TRUE));
770 if (!AddressStreet.IsEmpty()){
772 AddressStreet.Trim();
773 ConvertToHTML(&AddressStreet);
775 FinalAddressLine.append(AddressStreet);
776 AddressFirst = FALSE;
780 if (!AddressLocality.IsEmpty()){
782 AddressLocality.Trim();
783 ConvertToHTML(&AddressLocality);
785 if (AddressFirst == FALSE){
787 FinalAddressLine.append(wxT(",<br>"));
788 FinalAddressLine.append(AddressLocality);
792 FinalAddressLine.append(AddressLocality);
793 AddressFirst = FALSE;
799 if (!AddressRegion.IsEmpty()){
801 AddressRegion.Trim();
802 ConvertToHTML(&AddressRegion);
804 if (AddressFirst == FALSE){
806 FinalAddressLine.append(wxT(",<br>"));
807 FinalAddressLine.append(AddressRegion);
811 FinalAddressLine.append(AddressRegion);
812 AddressFirst = FALSE;
818 if (!AddressPostalCode.IsEmpty()){
820 AddressPostalCode.Trim();
821 ConvertToHTML(&AddressPostalCode);
823 if (AddressFirst == FALSE){
825 FinalAddressLine.append(wxT(",<br>"));
826 FinalAddressLine.append(AddressPostalCode);
830 FinalAddressLine.append(AddressPostalCode);
831 AddressFirst = FALSE;
837 if (!AddressCountry.IsEmpty()){
839 AddressCountry.Trim();
840 ConvertToHTML(&AddressCountry);
842 if (AddressFirst == FALSE){
844 FinalAddressLine.append(wxT(",<br>"));
845 FinalAddressLine.append(AddressCountry);
849 FinalAddressLine.append(AddressCountry);
850 AddressFirst = FALSE;
856 CaptureString(&FinalAddressLine, FALSE);
858 DataLines.append(wxT("<tr><td><b>"));
859 DataLines.append(_("Address:"));
860 DataLines.append(wxT(" </b></td><td>"));
861 DataLines.append(FinalAddressLine);
862 DataLines.append(wxT("</td></tr>"));
870 if (DataDisplay == TRUE){
873 PageData.append(wxT("<h4>"));
874 PageData.append(_("Addresses"));
875 PageData.append(wxT("</h4>"));
876 PageData.append(wxT("<br>"));
877 PageData.append(wxT("<table>"));
878 PageData.append(DataLines);
879 PageData.append(wxT("</table>"));
885 ContactData = vCardObj->GetByPartial(wxT("EMAIL"));
890 if (ContactData.PropCount > 0){
894 for (int i = 0; i < ContactData.PropCount; i++){
896 EmailLine = ContactData.PropValues[i];
899 CaptureString(&EmailLine, FALSE);
900 ConvertToHTML(&EmailLine);
902 DataLines.append(wxT("<tr><td><b>"));
903 DataLines.append(_("E-mail Address:"));
904 DataLines.append(wxT(" </b></td><td>"));
905 DataLines.append(EmailLine);
906 DataLines.append(wxT("</td></tr>"));
914 if (DataDisplay == TRUE){
917 PageData.append(wxT("<h4>"));
918 PageData.append(_("Email Addresses"));
919 PageData.append(wxT("</h4>"));
920 PageData.append(wxT("<br>"));
921 PageData.append(wxT("<table>"));
922 PageData.append(DataLines);
923 PageData.append(wxT("</table>"));
929 ContactData = vCardObj->GetByPartial(wxT("TEL"));
934 if (ContactData.PropCount > 0){
938 for (int i = 0; i < ContactData.PropCount; i++){
940 TelLine = ContactData.PropValues[i];
942 wxStringTokenizer TelSplit(TelLine, wxT(":"));
944 TelLine = TelSplit.GetNextToken();
946 if (TelSplit.HasMoreTokens()){
948 TelLine = TelSplit.GetNextToken();
953 CaptureString(&TelLine, FALSE);
954 ConvertToHTML(&TelLine);
956 DataLines.append(wxT("<tr><td><b>"));
957 DataLines.append(_("Telephone:"));
958 DataLines.append(wxT(" </b></td><td>"));
959 DataLines.append(TelLine);
960 DataLines.append(wxT("</td></tr>"));
968 if (DataDisplay == TRUE){
971 PageData.append(wxT("<h4>"));
972 PageData.append(_("Telephones"));
973 PageData.append(wxT("</h4>"));
974 PageData.append(wxT("<br>"));
975 PageData.append(wxT("<table>"));
976 PageData.append(DataLines);
977 PageData.append(wxT("</table>"));
983 ContactData = vCardObj->GetByPartial(wxT("IMPP"));
988 if (ContactData.PropCount > 0){
991 wxString IMTypeFriendly;
994 for (int i = 0; i < ContactData.PropCount; i++){
996 IMLine = ContactData.PropValues[i];
998 wxStringTokenizer IMSplit(IMLine, wxT(":"));
1000 IMType = IMSplit.GetNextToken();
1001 IMLine = IMSplit.GetNextToken();
1003 // Process skype, gg, icq, yahoo etc into
1004 // something meaningful.
1006 if (IMType == wxT("aim")){
1010 IMTypeFriendly = _("AIM");
1012 } else if (IMType == wxT("xmpp")){
1016 IMTypeFriendly = _("XMPP");
1018 } else if (IMType == wxT("icq")){
1022 IMTypeFriendly = _("ICQ");
1024 } else if (IMType == wxT("skype")){
1028 IMTypeFriendly = _("Skype");
1030 } else if (IMType == wxT("gg")){
1034 IMTypeFriendly = _("Gadu-Gadu");
1036 } else if (IMType == wxT("yahoo")){
1040 IMTypeFriendly = _("Yahoo");
1044 // Other. Use IM type that was split.
1046 IMTypeFriendly = IMType;
1051 CaptureString(&IMLine, FALSE);
1052 ConvertToHTML(&IMLine);
1054 DataLines.append(wxT("<tr><td><b>"));
1055 DataLines.append(_("IM Address"));
1056 DataLines.append(_(" ("));
1057 DataLines.append(IMTypeFriendly);
1058 DataLines.append(_("):"));
1059 DataLines.append(wxT(" </b></td><td>"));
1060 DataLines.append(IMLine);
1061 DataLines.append(wxT("</td></tr>"));
1063 IMTypeFriendly.clear();
1073 if (DataDisplay == TRUE){
1076 PageData.append(wxT("<h4>"));
1077 PageData.append(_("Instant Messaging Addresses"));
1078 PageData.append(wxT("</h4>"));
1079 PageData.append(wxT("<br>"));
1080 PageData.append(wxT("<table>"));
1081 PageData.append(DataLines);
1082 PageData.append(wxT("</table>"));
1088 ContactData = vCardObj->GetByPartial(wxT("URL"));
1090 DataDisplay = FALSE;
1093 if (ContactData.PropCount > 0){
1097 for (int i = 0; i < ContactData.PropCount; i++){
1099 URLLine = ContactData.PropValues[i];
1102 CaptureString(&URLLine, FALSE);
1103 ConvertToHTML(&URLLine);
1105 DataLines.append(wxT("<tr><td><b>"));
1106 DataLines.append(_("Website:"));
1107 DataLines.append(wxT(" </b></td><td>"));
1108 DataLines.append(URLLine);
1109 DataLines.append(wxT("</td></tr>"));
1117 if (DataDisplay == TRUE){
1120 PageData.append(wxT("<h4>"));
1121 PageData.append(_("Website Addresses"));
1122 PageData.append(wxT("</h4>"));
1123 PageData.append(wxT("<br>"));
1124 PageData.append(wxT("<table>"));
1125 PageData.append(DataLines);
1126 PageData.append(wxT("</table>"));
1132 ContactData = vCardObj->GetByPartial(wxT("LANG"));
1134 DataDisplay = FALSE;
1137 if (ContactData.PropCount > 0){
1139 wxString NicknameLine;
1141 for (int i = 0; i < ContactData.PropCount; i++){
1143 NicknameLine = ContactData.PropValues[i];
1145 NicknameLine.Trim();
1146 CaptureString(&NicknameLine, FALSE);
1147 ConvertToHTML(&NicknameLine);
1149 DataLines.append(wxT("<tr><td><b>"));
1150 DataLines.append(_("Language:"));
1151 DataLines.append(wxT(" </b></td><td>"));
1152 DataLines.append(NicknameLine);
1153 DataLines.append(wxT("</td></tr>"));
1161 if (DataDisplay == TRUE){
1164 PageData.append(wxT("<h4>"));
1165 PageData.append(_("Languages"));
1166 PageData.append(wxT("</h4>"));
1167 PageData.append(wxT("<br>"));
1168 PageData.append(wxT("<table>"));
1169 PageData.append(DataLines);
1170 PageData.append(wxT("</table>"));
1176 ContactData = vCardObj->GetByPartial(wxT("TZ"));
1178 DataDisplay = FALSE;
1181 if (ContactData.PropCount > 0){
1183 wxString NicknameLine;
1185 for (int i = 0; i < ContactData.PropCount; i++){
1187 NicknameLine = ContactData.PropValues[i];
1189 NicknameLine.Trim();
1190 CaptureString(&NicknameLine, FALSE);
1191 ConvertToHTML(&NicknameLine);
1193 DataLines.append(wxT("<tr><td><b>"));
1194 DataLines.append(_("Timezone:"));
1195 DataLines.append(wxT(" </b></td><td>"));
1196 DataLines.append(NicknameLine);
1197 DataLines.append(wxT("</td></tr>"));
1205 if (DataDisplay == TRUE){
1208 PageData.append(wxT("<h4>"));
1209 PageData.append(_("Timezones"));
1210 PageData.append(wxT("</h4>"));
1211 PageData.append(wxT("<br>"));
1212 PageData.append(wxT("<table>"));
1213 PageData.append(DataLines);
1214 PageData.append(wxT("</table>"));
1220 ContactData = vCardObj->GetByPartial(wxT("GEO"));
1222 DataDisplay = FALSE;
1225 if (ContactData.PropCount > 0){
1229 for (int i = 0; i < ContactData.PropCount; i++){
1231 GeoLine = ContactData.PropValues[i];
1233 wxStringTokenizer GeoSplit(GeoLine, wxT(":"));
1235 GeoLine = GeoSplit.GetNextToken();
1237 if (GeoSplit.HasMoreTokens()){
1239 GeoLine = GeoSplit.GetNextToken();
1244 CaptureString(&GeoLine, FALSE);
1245 ConvertToHTML(&GeoLine);
1247 DataLines.append(wxT("<tr><td><b>"));
1248 DataLines.append(_("Geoposition:"));
1249 DataLines.append(wxT(" </b></td><td>"));
1250 DataLines.append(GeoLine);
1251 DataLines.append(wxT("</td></tr>"));
1259 if (DataDisplay == TRUE){
1262 PageData.append(wxT("<h4>"));
1263 PageData.append(_("Geopositioning"));
1264 PageData.append(wxT("</h4>"));
1265 PageData.append(wxT("<br>"));
1266 PageData.append(wxT("<table>"));
1267 PageData.append(DataLines);
1268 PageData.append(wxT("</table>"));
1274 ContactData = vCardObj->GetByPartial(wxT("TITLE"));
1276 DataDisplay = FALSE;
1279 if (ContactData.PropCount > 0){
1283 for (int i = 0; i < ContactData.PropCount; i++){
1285 TitleLine = ContactData.PropValues[i];
1288 CaptureString(&TitleLine, FALSE);
1289 ConvertToHTML(&TitleLine);
1291 DataLines.append(wxT("<tr><td><b>"));
1292 DataLines.append(_("Title:"));
1293 DataLines.append(wxT(" </b></td><td>"));
1294 DataLines.append(TitleLine);
1295 DataLines.append(wxT("</td></tr>"));
1303 if (DataDisplay == TRUE){
1306 PageData.append(wxT("<h4>"));
1307 PageData.append(_("Titles"));
1308 PageData.append(wxT("</h4>"));
1309 PageData.append(wxT("<br>"));
1310 PageData.append(wxT("<table>"));
1311 PageData.append(DataLines);
1312 PageData.append(wxT("</table>"));
1318 ContactData = vCardObj->GetByPartial(wxT("ROLE"));
1320 DataDisplay = FALSE;
1323 if (ContactData.PropCount > 0){
1327 for (int i = 0; i < ContactData.PropCount; i++){
1329 RoleLine = ContactData.PropValues[i];
1332 CaptureString(&RoleLine, FALSE);
1333 ConvertToHTML(&RoleLine);
1335 DataLines.append(wxT("<tr><td><b>"));
1336 DataLines.append(_("Role:"));
1337 DataLines.append(wxT(" </b></td><td>"));
1338 DataLines.append(RoleLine);
1339 DataLines.append(wxT("</td></tr>"));
1347 if (DataDisplay == TRUE){
1350 PageData.append(wxT("<h4>"));
1351 PageData.append(_("Roles"));
1352 PageData.append(wxT("</h4>"));
1353 PageData.append(wxT("<br>"));
1354 PageData.append(wxT("<table>"));
1355 PageData.append(DataLines);
1356 PageData.append(wxT("</table>"));
1362 ContactData = vCardObj->GetByPartial(wxT("ORG"));
1364 DataDisplay = FALSE;
1367 if (ContactData.PropCount > 0){
1371 for (int i = 0; i < ContactData.PropCount; i++){
1373 OrgLine = ContactData.PropValues[i];
1376 CaptureString(&OrgLine, FALSE);
1377 ConvertToHTML(&OrgLine);
1379 DataLines.append(wxT("<tr><td><b>"));
1380 DataLines.append(_("Organisation:"));
1381 DataLines.append(wxT(" </b></td><td>"));
1382 DataLines.append(OrgLine);
1383 DataLines.append(wxT("</td></tr>"));
1391 if (DataDisplay == TRUE){
1394 PageData.append(wxT("<h4>"));
1395 PageData.append(_("Organisations"));
1396 PageData.append(wxT("</h4>"));
1397 PageData.append(wxT("<br>"));
1398 PageData.append(wxT("<table>"));
1399 PageData.append(DataLines);
1400 PageData.append(wxT("</table>"));
1406 ContactData = vCardObj->GetByPartial(wxT("CATEGORIES"));
1408 DataDisplay = FALSE;
1411 if (ContactData.PropCount > 0){
1415 for (int i = 0; i < ContactData.PropCount; i++){
1417 CatLine = ContactData.PropValues[i];
1420 CaptureString(&CatLine, FALSE);
1421 ConvertToHTML(&CatLine);
1423 DataLines.append(wxT("<tr><td><b>"));
1424 DataLines.append(_("Category:"));
1425 DataLines.append(wxT(" </b></td><td>"));
1426 DataLines.append(CatLine);
1427 DataLines.append(wxT("</td></tr>"));
1435 if (DataDisplay == TRUE){
1438 PageData.append(wxT("<h4>"));
1439 PageData.append(_("Categories"));
1440 PageData.append(wxT("</h4>"));
1441 PageData.append(wxT("<br>"));
1442 PageData.append(wxT("<table>"));
1443 PageData.append(DataLines);
1444 PageData.append(wxT("</table>"));
1452 // Calendar Addresses
1454 ContactData = vCardObj->GetByPartial(wxT("CALURI"));
1456 DataDisplay = FALSE;
1459 if (ContactData.PropCount > 0){
1461 wxString CalURILine;
1463 for (int i = 0; i < ContactData.PropCount; i++){
1465 CalURILine = ContactData.PropValues[i];
1468 CaptureString(&CalURILine, FALSE);
1469 ConvertToHTML(&CalURILine);
1471 DataLines.append(wxT("<tr><td><b>"));
1472 DataLines.append(_("Calendar Address:"));
1473 DataLines.append(wxT(" </b></td><td>"));
1474 DataLines.append(CalURILine);
1475 DataLines.append(wxT("</td></tr>"));
1483 if (DataDisplay == TRUE){
1486 PageData.append(wxT("<h4>"));
1487 PageData.append(_("Calendar Addresses"));
1488 PageData.append(wxT("</h4>"));
1489 PageData.append(wxT("<br>"));
1490 PageData.append(wxT("<table>"));
1491 PageData.append(DataLines);
1492 PageData.append(wxT("</table>"));
1496 // Calendar Request Addresses
1498 ContactData = vCardObj->GetByPartial(wxT("CALADRURI"));
1500 DataDisplay = FALSE;
1503 if (ContactData.PropCount > 0){
1505 wxString CalAdrURILine;
1507 for (int i = 0; i < ContactData.PropCount; i++){
1509 CalAdrURILine = ContactData.PropValues[i];
1511 CalAdrURILine.Trim();
1512 CaptureString(&CalAdrURILine, FALSE);
1513 ConvertToHTML(&CalAdrURILine);
1515 DataLines.append(wxT("<tr><td><b>"));
1516 DataLines.append(_("Calendar Request Address:"));
1517 DataLines.append(wxT(" </b></td><td>"));
1518 DataLines.append(CalAdrURILine);
1519 DataLines.append(wxT("</td></tr>"));
1527 if (DataDisplay == TRUE){
1530 PageData.append(wxT("<h4>"));
1531 PageData.append(_("Calendar Request Addresses"));
1532 PageData.append(wxT("</h4>"));
1533 PageData.append(wxT("<br>"));
1534 PageData.append(wxT("<table>"));
1535 PageData.append(DataLines);
1536 PageData.append(wxT("</table>"));
1540 // Free/Busy Addresses
1542 ContactData = vCardObj->GetByPartial(wxT("FBURL"));
1544 DataDisplay = FALSE;
1547 if (ContactData.PropCount > 0){
1551 for (int i = 0; i < ContactData.PropCount; i++){
1553 FBURLLine = ContactData.PropValues[i];
1556 CaptureString(&FBURLLine, FALSE);
1557 ConvertToHTML(&FBURLLine);
1559 DataLines.append(wxT("<tr><td><b>"));
1560 DataLines.append(_("Free/Busy Address:"));
1561 DataLines.append(wxT(" </b></td><td>"));
1562 DataLines.append(FBURLLine);
1563 DataLines.append(wxT("</td></tr>"));
1571 if (DataDisplay == TRUE){
1574 PageData.append(wxT("<h4>"));
1575 PageData.append(_("Free/Busy Addresses"));
1576 PageData.append(wxT("</h4>"));
1577 PageData.append(wxT("<br>"));
1578 PageData.append(wxT("<table>"));
1579 PageData.append(DataLines);
1580 PageData.append(wxT("</table>"));
1586 ContactData = vCardObj->GetByPartial(wxT("NOTE"));
1588 DataDisplay = FALSE;
1591 if (ContactData.PropCount > 0){
1595 for (int i = 0; i < ContactData.PropCount; i++){
1597 NoteLine = ContactData.PropValues[i];
1600 CaptureString(&NoteLine, FALSE);
1601 ConvertToHTML(&NoteLine);
1603 DataLines.append(wxT("<tr><td><b>"));
1604 DataLines.append(_("Note:"));
1605 DataLines.append(wxT(" </b></td><td>"));
1606 DataLines.append(NoteLine);
1607 DataLines.append(wxT("</td></tr>"));
1615 if (DataDisplay == TRUE){
1617 PageData.append(wxT("<h4>"));
1618 PageData.append(_("Notes"));
1619 PageData.append(wxT("</h4>"));
1620 PageData.append(wxT("<br>"));
1621 PageData.append(wxT("<table>"));
1622 PageData.append(DataLines);
1623 PageData.append(wxT("</table>"));
1627 // Display the HTML document on the screen.
1629 PageData.append("</td></tr></table>");
1631 PageData.append(wxT("</body>"));
1632 PageData.append(wxT("</html>"));
1634 HTMLObj->SetPage(PageData);
1638 void SplitPropertyData(wxString *PropertyLine,
1639 std::map<int,int> *SplitPoints,
1640 std::map<int,int> *SplitLength,
1642 std::map<wxString,wxString> *SplitData){
1644 // Split the property data into SplitData.
1647 wxStringTokenizer PropertyElement;
1648 wxString PropertyName;
1649 wxString PropertyValue;
1650 int intPropertyLen = PropertyLine->Len();
1651 int intSplitsFound = 0;
1652 int intSplitSize = 0;
1653 int intSplitSeek = (intSize - 1);
1655 for (int i = intSize; i <= intPropertyLen; i++){
1659 if (PropertyLine->Mid(i, 1) == wxT(";") &&
1660 PropertyLine->Mid((i - 1), 1) != wxT("\\")){
1662 if (intSplitsFound == 0){
1664 DataStr = PropertyLine->Mid(intSplitSeek, (intSplitSize));
1665 SplitLength->insert(std::make_pair(intSplitsFound, (intSplitSize)));
1669 DataStr = PropertyLine->Mid(intSplitSeek, (intSplitSize - 1));
1670 SplitLength->insert(std::make_pair(intSplitsFound, (intSplitSize - 1)));
1674 SplitPoints->insert(std::make_pair(intSplitsFound, (i + 1)));
1677 intSplitSeek = (i + 1);
1680 if (!DataStr.IsEmpty()){
1682 PropertyElement.SetString(DataStr, wxT("="));
1683 PropertyName = PropertyElement.GetNextToken();
1684 PropertyValue = PropertyElement.GetNextToken();
1685 SplitData->insert(std::make_pair(PropertyName, PropertyValue));
1690 PropertyName.clear();
1691 PropertyValue.clear();
1697 if (intSplitsFound == 0){
1699 DataStr = PropertyLine->Mid(intSplitSeek, (intSplitSize));
1701 SplitPoints->insert(std::make_pair(intSplitsFound, (8 + 1)));
1702 SplitLength->insert(std::make_pair(intSplitsFound, intSplitSize));
1706 DataStr = PropertyLine->Mid(intSplitSeek, (intSplitSize - 1));
1708 SplitPoints->insert(std::make_pair(intSplitsFound, (intSplitSeek + 1)));
1709 SplitLength->insert(std::make_pair(intSplitsFound, intSplitSize));
1713 if (!DataStr.IsEmpty()){
1715 PropertyElement.SetString(DataStr, wxT("="));
1716 PropertyName = PropertyElement.GetNextToken();
1717 PropertyValue = PropertyElement.GetNextToken();
1718 SplitData->insert(std::make_pair(PropertyName, PropertyValue));