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 // Show message to user that the contact information is loading.
41 HTMLObj->SetBorders(0);
45 wxFileSystem::AddHandler(new wxMemoryFSHandler);
46 //wxMemoryFSHandler::AddFile();
48 PageData.append(wxT("<html>"));
49 PageData.append(wxT("<head>"));
50 PageData.append(wxT("<title>Page Loading</title>"));
51 PageData.append(wxT("</head>"));
52 PageData.append(wxT("<body>"));
53 PageData.append(wxT("<h2>"));
54 PageData.append(_("Loading contact information..."));
55 PageData.append(wxT("</h2>"));
56 PageData.append(wxT("</body>"));
57 PageData.append(wxT("</html>"));
59 HTMLObj->SetPage(PageData);
63 // Delete the information from the old session.
65 if (!OldSID.IsEmpty()){
67 if (MemoryFSList->find(OldSID) == MemoryFSList->end()){
72 std::map<wxString, wxString>::iterator striter;
74 for (striter = MemoryFSList->begin(); striter != MemoryFSList->end(); striter++){
76 if (OldSID == striter->second){
78 // Delete the references from the wxMemoryFSHandler
79 // and the entry from the map.
81 wxMemoryFSHandler::RemoveFile(striter->first);
88 MemoryFSList->erase(striter);
94 // MAke sure new session ID doesn't conflict with existing
95 // data. If there is a match, generate a new one and check again.
97 bool SIDMatch = FALSE;
100 for (std::map<wxString, wxString>::iterator striter = MemoryFSList->begin();
101 striter != MemoryFSList->end(); striter++){
103 SIDTemp = striter->second;
107 // Generate a new random number.
109 SID = wxString::Format(wxT("%i"), rand() % 32768);
111 // Rewind the seek process back to the start.
113 striter = MemoryFSList->begin();
121 // Setup the HTML document.
123 PageData.append(wxT("<html>"));
124 PageData.append(wxT("<head>"));
125 PageData.append(wxT("<title>Contact Information</title>"));
126 PageData.append(wxT("</head>"));
128 // Process the CSS section.
130 PageData.append(wxT("<body>"));
132 // Process the data in the vCard object.
136 PageData.append(wxT("<table style=\"background: #cccccc; width: 100%\">"));
137 PageData.append(wxT("<tr>"));
138 PageData.append(wxT("<td style=\"width:100%\">"));
139 PageData.append(wxT("<h2>"));
140 PageData.append(vCardObj->Get(wxT("FN")));
141 PageData.append(wxT("</h2>"));
142 PageData.append(wxT("</td>"));
143 PageData.append(wxT("<td style=\"width: 200px;\">"));
145 // Define common variables for ADR.
147 std::map<int,int> SplitPoints;
148 std::map<int,int> SplitLength;
149 std::map<int,int>::iterator SLiter;
156 wxString AddressPOBox;
157 wxString AddressStreet;
158 wxString AddressLocality;
159 wxString AddressRegion;
160 wxString AddressPostalCode;
161 wxString AddressCountry;
162 wxString AddressExtended;
164 wxString FinalAddressLine;
165 bool AddressFirst = TRUE;
167 // Define common variables for PHOTO and LOGO.
169 std::string PhotoDataBin;
170 std::string PhotoDataIn;
171 wxString PhotoSplitData;
172 wxString PhotoMIMEType;
173 wxString PhotoEncType;
174 wxString PhotoEncData;
175 bool LoadPicture = FALSE;
176 bool DataDisplay = FALSE;
177 bool RectData = FALSE;
178 wxRect PhotoRectPoints;
179 wxString SIDFilename;
185 ArrayvCardOutData ContactData = vCardObj->GetByPartial(wxT("PHOTO"));
187 if (ContactData.PropCount > 0){
193 /*std::map<int,int> SplitPts;
194 std::map<int,int> SplitLen;
195 std::map<wxString,wxString> SplitData;
198 SplitPropertyData(&ContactData.PropData[0],
204 for (std::map<wxString, wxString>::iterator striter = SplitData.begin();
205 striter != SplitData.end(); striter++){
211 // Look for the X-ABCROP-RECTANGLE.
213 wxStringTokenizer PhotoSplit(ContactData.PropData[0], wxT(":"));
214 wxString PhotoPropertyDataString = PhotoSplit.GetNextToken();
215 wxStringTokenizer PhotoPropertyData(PhotoPropertyDataString, wxT(";"));
216 wxString PropertyLineData;
217 wxString PropertyName;
218 wxString PropertyValue;
220 wxStringTokenizer DataSplit(ContactData.PropValues[0], wxT(";"));
221 PhotoSplitData = DataSplit.GetNextToken();
222 wxStringTokenizer MIMESplit(PhotoSplitData, wxT(":"));
223 MIMESplit.GetNextToken();
224 PhotoMIMEType = MIMESplit.GetNextToken();
225 PhotoSplitData = DataSplit.GetNextToken();
226 wxStringTokenizer EncSplit(PhotoSplitData, wxT(","));
227 PhotoEncType = EncSplit.GetNextToken();
228 PhotoEncData = EncSplit.GetNextToken();
230 // Convert the picture data from base64 to binary.
232 PhotoDataIn = std::string(PhotoEncData.mb_str());
233 PhotoDataBin = base64_decode(PhotoDataIn);
234 wxMemoryInputStream istream(PhotoDataBin.c_str(), (size_t)PhotoDataBin.size());
237 if (!photo.LoadFile(istream, wxBITMAP_TYPE_ANY)){
239 // Photo failed to load so do nothing.
245 while (PhotoPropertyData.HasMoreTokens()){
247 PropertyLineData = PhotoPropertyData.GetNextToken();
249 wxStringTokenizer PhotoPropPair(PropertyLineData, wxT("="));
250 wxString PhotoPropName = PhotoPropPair.GetNextToken();
251 wxString PhotoPropValue = PhotoPropPair.GetNextToken();
253 if (PhotoPropName == wxT("X-ABCROP-RECTANGLE")){
255 wxStringTokenizer PhotoRectData(PhotoPropValue, wxT("&"));
257 PhotoRectData.GetNextToken();
259 //PhotoRectPoints.SetX(wxAtoi(PhotoRectData.GetNextToken()));
260 //PhotoRectPoints.SetY(wxAtoi(PhotoRectData.GetNextToken()) - 100);
262 int PointXBase = wxAtoi(PhotoRectData.GetNextToken());
263 int PointYBase = wxAtoi(PhotoRectData.GetNextToken());
264 int PointWBase = wxAtoi(PhotoRectData.GetNextToken());
265 int PointHBase = wxAtoi(PhotoRectData.GetNextToken());
267 int PointX = PointXBase;
268 int PointY = PointYBase;
269 int PointW = PointWBase;
270 int PointH = PointHBase;
274 if (PointYBase > PointHBase){
276 PointX = photo.GetWidth() - PointXBase - 140;
277 PointY = photo.GetHeight() - PointYBase - 140;
281 } else if (PointXBase > PointWBase){
283 PointX = photo.GetWidth() - PointXBase;
284 PointY = PointYBase - 50;
292 /*int PointX = PointXBase;
293 int PointY = PointYBase;
294 int PointW = PointWBase;
295 int PointH = PointHBase;*/
297 // Bottom Left Method
299 /*int PointX = wxAtoi(PhotoRectData.GetNextToken());
300 int PointY = photo.GetHeight() - wxAtoi(PhotoRectData.GetNextToken()) - 340;
301 int PointW = wxAtoi(PhotoRectData.GetNextToken());
302 int PointH = wxAtoi(PhotoRectData.GetNextToken());*/
304 // Bottom Right Method
306 /*int PointXRemain = photo.GetWidth() - PointX - 140;
307 int PointYRemain = photo.GetHeight() - PointY - 140;*/
309 PhotoRectPoints.SetX(PointX);
310 PhotoRectPoints.SetY(PointY);
311 PhotoRectPoints.SetWidth(PointW);
312 PhotoRectPoints.SetHeight(PointH);
321 // Resize the picture to 125x125.
323 // Add to the wxMemnoryFSHandler.
325 SIDFilename = SID + wxT("-photo");
327 if (RectData == TRUE){
329 wxImage rectphoto = photo.GetSubImage(PhotoRectPoints);
330 rectphoto = rectphoto.Scale(75, 75, wxIMAGE_QUALITY_HIGH);
331 wxMemoryFSHandler::AddFile(SIDFilename, rectphoto, wxBITMAP_TYPE_PNG);
335 photo = photo.Scale(50, 50, wxIMAGE_QUALITY_HIGH);
336 wxMemoryFSHandler::AddFile(SIDFilename, photo, wxBITMAP_TYPE_PNG);
340 // Add the filename to the MemoryFSList map.
342 MemoryFSList->insert(std::make_pair(SIDFilename, SID));
348 if (LoadPicture == TRUE){
350 PageData.append(wxT("<img src=\"memory:") + SIDFilename + wxT("\">"));
358 ContactData = vCardObj->GetByPartial(wxT("LOGO"));
360 if (ContactData.PropCount > 0){
364 wxStringTokenizer DataSplit(ContactData.PropValues[0], wxT(";"));
365 PhotoSplitData = DataSplit.GetNextToken();
366 wxStringTokenizer MIMESplit(PhotoSplitData, wxT(":"));
367 MIMESplit.GetNextToken();
368 PhotoMIMEType = MIMESplit.GetNextToken();
369 PhotoSplitData = DataSplit.GetNextToken();
370 wxStringTokenizer EncSplit(PhotoSplitData, wxT(","));
371 PhotoEncType = EncSplit.GetNextToken();
372 PhotoEncData = EncSplit.GetNextToken();
374 // Convert the picture data from base64 to binary.
376 PhotoDataIn = std::string(PhotoEncData.mb_str());
377 PhotoDataBin = base64_decode(PhotoDataIn);
378 wxMemoryInputStream istream(PhotoDataBin.c_str(), (size_t)PhotoDataBin.size());
381 if (!photo.LoadFile(istream, wxBITMAP_TYPE_ANY)){
383 // Photo failed to load so do nothing.
391 photo = photo.Scale(50, 50, wxIMAGE_QUALITY_HIGH);
393 // Resize the picture to 125x125.
395 // Add to the wxMemnoryFSHandler.
397 SIDFilename = SID + wxT("-logo");
399 wxMemoryFSHandler::AddFile(SIDFilename, photo, wxBITMAP_TYPE_PNG);
401 // Add the filename to the MemoryFSList map.
403 MemoryFSList->insert(std::make_pair(SIDFilename, SID));
409 if (LoadPicture == TRUE){
411 PageData.append(wxT("<img src=\"memory:") + SIDFilename + wxT("\">"));
415 PageData.append(wxT("</td>"));
416 PageData.append(wxT("</tr>"));
417 PageData.append(wxT("</table>"));
419 // Process LOGO, PHOTO, SOUND, KEY, VND-* and X-*
420 // lines and display icons for each accordingly.
422 ContactData = vCardObj->GetByPartial(wxT("PHOTO"));
424 bool AddBreak = FALSE;
425 wxString TypePageData;
427 if (ContactData.PropCount > 1){
429 TypePageData.append(wxT("<img src=\"memory:cipto.png\" alt=\""));
430 TypePageData.append(_("This contact has multiple photos."));
431 TypePageData.append(wxT("\">"));
436 ContactData = vCardObj->GetByPartial(wxT("LOGO"));
438 if (ContactData.PropCount > 1){
440 TypePageData.append(wxT("<img src=\"memory:cilog.png\" alt=\""));
441 TypePageData.append(_("This contact has multiple logos."));
442 TypePageData.append(wxT("\">"));
447 ContactData = vCardObj->GetByPartial(wxT("SOUND"));
449 if (ContactData.PropCount >= 1){
451 TypePageData.append(wxT("<img src=\"memory:cisnd.png\" alt=\""));
452 TypePageData.append(_("This contact has audio information."));
453 TypePageData.append(wxT("\">"));
458 ContactData = vCardObj->GetByPartial(wxT("KEY"));
460 if (ContactData.PropCount >= 1){
462 TypePageData.append(wxT("<img src=\"memory:cikey.png\" alt=\""));
463 TypePageData.append(_("This contact has crytographic keys."));
464 TypePageData.append(wxT("\">"));
469 ContactData = vCardObj->GetByPartial(wxT("VND-"));
471 if (ContactData.PropCount >= 1){
473 TypePageData.append(wxT("<img src=\"memory:civen.png\" alt=\""));
474 TypePageData.append(_("This contact has vendor-specific information."));
475 TypePageData.append(wxT("\">"));
480 ContactData = vCardObj->GetByPartial(wxT("X-"));
482 if (ContactData.PropCount >= 1){
484 TypePageData.append(wxT("<img src=\"memory:ciext.png\" alt=\""));
485 TypePageData.append(_("This contact has extended information."));
486 TypePageData.append(wxT("\">"));
491 if (!TypePageData.IsEmpty()){
493 PageData.append("<table style=\"{background: #dddddd; width:100%}\"><tr><td>");
494 PageData.append(TypePageData);
495 PageData.append("</tr></td></table>");
499 if (AddBreak == TRUE){
501 PageData.append(wxT("<br><br>"));
505 bool MultiLogoIcon = FALSE;
506 bool MultiPhotoIcon = FALSE;
507 bool SoundIcon = FALSE;
508 bool KeyIcon = FALSE;
509 bool VendorIcon = FALSE;
510 bool XTokenIcon = FALSE;
514 ContactData = vCardObj->GetByPartial(wxT("BDAY"));
519 if (ContactData.PropCount > 0){
523 for (int i = 0; i < ContactData.PropCount; i++){
525 // Grab the first birthday only.
527 BDayLine = ContactData.PropValues[i];
530 CaptureString(&BDayLine, FALSE);
531 ConvertToHTML(&BDayLine);
533 DataLines.append(BDayLine);
543 PageData.append("<table CELLPADDING=4 style=\"{width: 100%;}\"><tr><td>");
545 if (DataDisplay == TRUE){
548 PageData.append(wxT("<b>"));
549 PageData.append(_("Birthday:"));
550 PageData.append(wxT("</b> "));
551 PageData.append(DataLines);
552 PageData.append(wxT("<br>"));
556 // Process Anniversary
558 ContactData = vCardObj->GetByPartial(wxT("ANNIVERSARY"));
563 if (ContactData.PropCount > 0){
567 for (int i = 0; i < ContactData.PropCount; i++){
569 // Grab the first anniversary only.
571 AnniLine = ContactData.PropValues[i];
574 CaptureString(&AnniLine, FALSE);
575 ConvertToHTML(&AnniLine);
577 DataLines.append(AnniLine);
587 if (DataDisplay == TRUE){
590 PageData.append(wxT("<b>"));
591 PageData.append(_("Anniversary:"));
592 PageData.append(wxT("</b> "));
593 PageData.append(DataLines);
594 PageData.append(wxT("<br>"));
600 ContactData = vCardObj->GetByPartial(wxT("NICKNAME"));
605 if (ContactData.PropCount > 0){
607 wxString NicknameLine;
609 for (int i = 0; i < ContactData.PropCount; i++){
611 NicknameLine = ContactData.PropValues[i];
614 CaptureString(&NicknameLine, FALSE);
615 ConvertToHTML(&NicknameLine);
617 DataLines.append(wxT("<tr><td><b>"));
618 DataLines.append(_("Nickname:"));
619 DataLines.append(wxT(" </b></td><td>"));
620 DataLines.append(NicknameLine);
621 DataLines.append(wxT("</td></tr>"));
629 if (DataDisplay == TRUE){
632 PageData.append(wxT("<h4>"));
633 PageData.append(_("Nicknames"));
634 PageData.append(wxT("</h4>"));
635 PageData.append(wxT("<br>"));
636 PageData.append(wxT("<table>"));
637 PageData.append(DataLines);
638 PageData.append(wxT("</table>"));
644 ContactData = vCardObj->GetByPartial(wxT("ADR"));
649 if (ContactData.PropCount > 0){
651 wxString AddressLine;
653 for (int i = 0; i < ContactData.PropCount; i++){
655 AddressLine = ContactData.PropValues[i];
657 intPropertyLen = AddressLine.Len();
664 AddressPOBox.clear();
665 AddressStreet.clear();
666 AddressLocality.clear();
667 AddressRegion.clear();
668 AddressPostalCode.clear();
669 AddressCountry.clear();
670 AddressExtended.clear();
671 FinalAddressLine.clear();
674 for (int i = 0; i <= intPropertyLen; i++){
678 if (AddressLine.Mid(i, 1) == wxT(";") && AddressLine.Mid((i - 1), 1) != wxT("\\")){
681 SplitPoints.insert(std::make_pair(intSplitsFound, (i + 1)));
683 if (intSplitsFound == 6){
685 SplitLength.insert(std::make_pair(intSplitsFound, (intSplitSize - 1)));
690 SplitLength.insert(std::make_pair(intSplitsFound, (intSplitSize - 1)));
700 // Split the data into several parts.
702 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
703 intiter != SplitPoints.end(); ++intiter){
705 if (intiter->first == 1){
709 SLiter = SplitLength.find(1);
711 //txtSurname->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(0, SLiter->second), TRUE));
712 AddressPOBox = AddressLine.Mid(0, SLiter->second);
713 intPrevValue = intiter->second;
715 } else if (intiter->first == 2){
717 // Deal with extended address.
719 SLiter = SplitLength.find(2);
721 AddressExtended = AddressLine.Mid(intPrevValue, SLiter->second);
722 //txtForename->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue, SLiter->second), TRUE));
723 intPrevValue = intiter->second;
725 } else if (intiter->first == 3){
727 // Deal with street address.
729 SLiter = SplitLength.find(3);
731 AddressStreet = AddressLine.Mid(intPrevValue, SLiter->second);
732 //txtOtherNames->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue, SLiter->second), TRUE));
733 intPrevValue = intiter->second;
735 } else if (intiter->first == 4){
737 // Deal with locality
739 SLiter = SplitLength.find(4);
741 AddressLocality = AddressLine.Mid(intPrevValue, SLiter->second);
742 //txtTitle->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue, SLiter->second), TRUE));
743 intPrevValue = intiter->second;
745 //txtSuffix->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue, wxSTRING_MAXLEN), TRUE));
747 } else if (intiter->first == 5){
751 SLiter = SplitLength.find(5);
753 AddressRegion = AddressLine.Mid(intPrevValue, SLiter->second);
754 //txtTitle->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue, SLiter->second), TRUE));
755 intPrevValue = intiter->second;
757 //txtSuffix->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue, wxSTRING_MAXLEN), TRUE));
759 } else if (intiter->first == 6){
761 // Deal with post code.
763 SLiter = SplitLength.find(6);
765 AddressPostalCode = AddressLine.Mid(intPrevValue, SLiter->second);
766 //txtTitle->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue, SLiter->second), TRUE));
767 intPrevValue = intiter->second;
769 // Deal with country.
771 AddressCountry = AddressLine.Mid(intPrevValue);
772 //txtSuffix->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue, wxSTRING_MAXLEN), TRUE));
778 if (!AddressStreet.IsEmpty()){
780 AddressStreet.Trim();
781 ConvertToHTML(&AddressStreet);
783 FinalAddressLine.append(AddressStreet);
784 AddressFirst = FALSE;
788 if (!AddressLocality.IsEmpty()){
790 AddressLocality.Trim();
791 ConvertToHTML(&AddressLocality);
793 if (AddressFirst == FALSE){
795 FinalAddressLine.append(wxT(",<br>"));
796 FinalAddressLine.append(AddressLocality);
800 FinalAddressLine.append(AddressLocality);
801 AddressFirst = FALSE;
807 if (!AddressRegion.IsEmpty()){
809 AddressRegion.Trim();
810 ConvertToHTML(&AddressRegion);
812 if (AddressFirst == FALSE){
814 FinalAddressLine.append(wxT(",<br>"));
815 FinalAddressLine.append(AddressRegion);
819 FinalAddressLine.append(AddressRegion);
820 AddressFirst = FALSE;
826 if (!AddressPostalCode.IsEmpty()){
828 AddressPostalCode.Trim();
829 ConvertToHTML(&AddressPostalCode);
831 if (AddressFirst == FALSE){
833 FinalAddressLine.append(wxT(",<br>"));
834 FinalAddressLine.append(AddressPostalCode);
838 FinalAddressLine.append(AddressPostalCode);
839 AddressFirst = FALSE;
845 if (!AddressCountry.IsEmpty()){
847 AddressCountry.Trim();
848 ConvertToHTML(&AddressCountry);
850 if (AddressFirst == FALSE){
852 FinalAddressLine.append(wxT(",<br>"));
853 FinalAddressLine.append(AddressCountry);
857 FinalAddressLine.append(AddressCountry);
858 AddressFirst = FALSE;
864 CaptureString(&FinalAddressLine, FALSE);
866 DataLines.append(wxT("<tr><td><b>"));
867 DataLines.append(_("Address:"));
868 DataLines.append(wxT(" </b></td><td>"));
869 DataLines.append(FinalAddressLine);
870 DataLines.append(wxT("</td></tr>"));
878 if (DataDisplay == TRUE){
881 PageData.append(wxT("<h4>"));
882 PageData.append(_("Addresses"));
883 PageData.append(wxT("</h4>"));
884 PageData.append(wxT("<br>"));
885 PageData.append(wxT("<table>"));
886 PageData.append(DataLines);
887 PageData.append(wxT("</table>"));
893 ContactData = vCardObj->GetByPartial(wxT("EMAIL"));
898 if (ContactData.PropCount > 0){
902 for (int i = 0; i < ContactData.PropCount; i++){
904 EmailLine = ContactData.PropValues[i];
907 CaptureString(&EmailLine, FALSE);
908 ConvertToHTML(&EmailLine);
910 DataLines.append(wxT("<tr><td><b>"));
911 DataLines.append(_("E-mail Address:"));
912 DataLines.append(wxT(" </b></td><td>"));
913 DataLines.append(EmailLine);
914 DataLines.append(wxT("</td></tr>"));
922 if (DataDisplay == TRUE){
925 PageData.append(wxT("<h4>"));
926 PageData.append(_("Email Addresses"));
927 PageData.append(wxT("</h4>"));
928 PageData.append(wxT("<br>"));
929 PageData.append(wxT("<table>"));
930 PageData.append(DataLines);
931 PageData.append(wxT("</table>"));
937 ContactData = vCardObj->GetByPartial(wxT("TEL"));
942 if (ContactData.PropCount > 0){
946 for (int i = 0; i < ContactData.PropCount; i++){
948 TelLine = ContactData.PropValues[i];
950 wxStringTokenizer TelSplit(TelLine, wxT(":"));
952 TelLine = TelSplit.GetNextToken();
954 if (TelSplit.HasMoreTokens()){
956 TelLine = TelSplit.GetNextToken();
961 CaptureString(&TelLine, FALSE);
962 ConvertToHTML(&TelLine);
964 DataLines.append(wxT("<tr><td><b>"));
965 DataLines.append(_("Telephone:"));
966 DataLines.append(wxT(" </b></td><td>"));
967 DataLines.append(TelLine);
968 DataLines.append(wxT("</td></tr>"));
976 if (DataDisplay == TRUE){
979 PageData.append(wxT("<h4>"));
980 PageData.append(_("Telephones"));
981 PageData.append(wxT("</h4>"));
982 PageData.append(wxT("<br>"));
983 PageData.append(wxT("<table>"));
984 PageData.append(DataLines);
985 PageData.append(wxT("</table>"));
991 ContactData = vCardObj->GetByPartial(wxT("IMPP"));
996 if (ContactData.PropCount > 0){
999 wxString IMTypeFriendly;
1002 for (int i = 0; i < ContactData.PropCount; i++){
1004 IMLine = ContactData.PropValues[i];
1006 wxStringTokenizer IMSplit(IMLine, wxT(":"));
1008 IMType = IMSplit.GetNextToken();
1009 IMLine = IMSplit.GetNextToken();
1011 // Process skype, gg, icq, yahoo etc into
1012 // something meaningful.
1014 if (IMType == wxT("aim")){
1018 IMTypeFriendly = _("AIM");
1020 } else if (IMType == wxT("xmpp")){
1024 IMTypeFriendly = _("XMPP");
1026 } else if (IMType == wxT("icq")){
1030 IMTypeFriendly = _("ICQ");
1032 } else if (IMType == wxT("skype")){
1036 IMTypeFriendly = _("Skype");
1038 } else if (IMType == wxT("gg")){
1042 IMTypeFriendly = _("Gadu-Gadu");
1044 } else if (IMType == wxT("yahoo")){
1048 IMTypeFriendly = _("Yahoo");
1052 // Other. Use IM type that was split.
1054 IMTypeFriendly = IMType;
1059 CaptureString(&IMLine, FALSE);
1060 ConvertToHTML(&IMLine);
1062 DataLines.append(wxT("<tr><td><b>"));
1063 DataLines.append(_("IM Address"));
1064 DataLines.append(_(" ("));
1065 DataLines.append(IMTypeFriendly);
1066 DataLines.append(_("):"));
1067 DataLines.append(wxT(" </b></td><td>"));
1068 DataLines.append(IMLine);
1069 DataLines.append(wxT("</td></tr>"));
1071 IMTypeFriendly.clear();
1081 if (DataDisplay == TRUE){
1084 PageData.append(wxT("<h4>"));
1085 PageData.append(_("Instant Messaging Addresses"));
1086 PageData.append(wxT("</h4>"));
1087 PageData.append(wxT("<br>"));
1088 PageData.append(wxT("<table>"));
1089 PageData.append(DataLines);
1090 PageData.append(wxT("</table>"));
1096 ContactData = vCardObj->GetByPartial(wxT("URL"));
1098 DataDisplay = FALSE;
1101 if (ContactData.PropCount > 0){
1105 for (int i = 0; i < ContactData.PropCount; i++){
1107 URLLine = ContactData.PropValues[i];
1110 CaptureString(&URLLine, FALSE);
1111 ConvertToHTML(&URLLine);
1113 DataLines.append(wxT("<tr><td><b>"));
1114 DataLines.append(_("Website:"));
1115 DataLines.append(wxT(" </b></td><td>"));
1116 DataLines.append(URLLine);
1117 DataLines.append(wxT("</td></tr>"));
1125 if (DataDisplay == TRUE){
1128 PageData.append(wxT("<h4>"));
1129 PageData.append(_("Website Addresses"));
1130 PageData.append(wxT("</h4>"));
1131 PageData.append(wxT("<br>"));
1132 PageData.append(wxT("<table>"));
1133 PageData.append(DataLines);
1134 PageData.append(wxT("</table>"));
1140 ContactData = vCardObj->GetByPartial(wxT("LANG"));
1142 DataDisplay = FALSE;
1145 if (ContactData.PropCount > 0){
1147 wxString NicknameLine;
1149 for (int i = 0; i < ContactData.PropCount; i++){
1151 NicknameLine = ContactData.PropValues[i];
1153 NicknameLine.Trim();
1154 CaptureString(&NicknameLine, FALSE);
1155 ConvertToHTML(&NicknameLine);
1157 DataLines.append(wxT("<tr><td><b>"));
1158 DataLines.append(_("Language:"));
1159 DataLines.append(wxT(" </b></td><td>"));
1160 DataLines.append(NicknameLine);
1161 DataLines.append(wxT("</td></tr>"));
1169 if (DataDisplay == TRUE){
1172 PageData.append(wxT("<h4>"));
1173 PageData.append(_("Languages"));
1174 PageData.append(wxT("</h4>"));
1175 PageData.append(wxT("<br>"));
1176 PageData.append(wxT("<table>"));
1177 PageData.append(DataLines);
1178 PageData.append(wxT("</table>"));
1184 ContactData = vCardObj->GetByPartial(wxT("TZ"));
1186 DataDisplay = FALSE;
1189 if (ContactData.PropCount > 0){
1191 wxString NicknameLine;
1193 for (int i = 0; i < ContactData.PropCount; i++){
1195 NicknameLine = ContactData.PropValues[i];
1197 NicknameLine.Trim();
1198 CaptureString(&NicknameLine, FALSE);
1199 ConvertToHTML(&NicknameLine);
1201 DataLines.append(wxT("<tr><td><b>"));
1202 DataLines.append(_("Timezone:"));
1203 DataLines.append(wxT(" </b></td><td>"));
1204 DataLines.append(NicknameLine);
1205 DataLines.append(wxT("</td></tr>"));
1213 if (DataDisplay == TRUE){
1216 PageData.append(wxT("<h4>"));
1217 PageData.append(_("Timezones"));
1218 PageData.append(wxT("</h4>"));
1219 PageData.append(wxT("<br>"));
1220 PageData.append(wxT("<table>"));
1221 PageData.append(DataLines);
1222 PageData.append(wxT("</table>"));
1228 ContactData = vCardObj->GetByPartial(wxT("GEO"));
1230 DataDisplay = FALSE;
1233 if (ContactData.PropCount > 0){
1237 for (int i = 0; i < ContactData.PropCount; i++){
1239 GeoLine = ContactData.PropValues[i];
1241 wxStringTokenizer GeoSplit(GeoLine, wxT(":"));
1243 GeoLine = GeoSplit.GetNextToken();
1245 if (GeoSplit.HasMoreTokens()){
1247 GeoLine = GeoSplit.GetNextToken();
1252 CaptureString(&GeoLine, FALSE);
1253 ConvertToHTML(&GeoLine);
1255 DataLines.append(wxT("<tr><td><b>"));
1256 DataLines.append(_("Geoposition:"));
1257 DataLines.append(wxT(" </b></td><td>"));
1258 DataLines.append(GeoLine);
1259 DataLines.append(wxT("</td></tr>"));
1267 if (DataDisplay == TRUE){
1270 PageData.append(wxT("<h4>"));
1271 PageData.append(_("Geopositioning"));
1272 PageData.append(wxT("</h4>"));
1273 PageData.append(wxT("<br>"));
1274 PageData.append(wxT("<table>"));
1275 PageData.append(DataLines);
1276 PageData.append(wxT("</table>"));
1282 ContactData = vCardObj->GetByPartial(wxT("TITLE"));
1284 DataDisplay = FALSE;
1287 if (ContactData.PropCount > 0){
1291 for (int i = 0; i < ContactData.PropCount; i++){
1293 TitleLine = ContactData.PropValues[i];
1296 CaptureString(&TitleLine, FALSE);
1297 ConvertToHTML(&TitleLine);
1299 DataLines.append(wxT("<tr><td><b>"));
1300 DataLines.append(_("Title:"));
1301 DataLines.append(wxT(" </b></td><td>"));
1302 DataLines.append(TitleLine);
1303 DataLines.append(wxT("</td></tr>"));
1311 if (DataDisplay == TRUE){
1314 PageData.append(wxT("<h4>"));
1315 PageData.append(_("Titles"));
1316 PageData.append(wxT("</h4>"));
1317 PageData.append(wxT("<br>"));
1318 PageData.append(wxT("<table>"));
1319 PageData.append(DataLines);
1320 PageData.append(wxT("</table>"));
1326 ContactData = vCardObj->GetByPartial(wxT("ROLE"));
1328 DataDisplay = FALSE;
1331 if (ContactData.PropCount > 0){
1335 for (int i = 0; i < ContactData.PropCount; i++){
1337 RoleLine = ContactData.PropValues[i];
1340 CaptureString(&RoleLine, FALSE);
1341 ConvertToHTML(&RoleLine);
1343 DataLines.append(wxT("<tr><td><b>"));
1344 DataLines.append(_("Role:"));
1345 DataLines.append(wxT(" </b></td><td>"));
1346 DataLines.append(RoleLine);
1347 DataLines.append(wxT("</td></tr>"));
1355 if (DataDisplay == TRUE){
1358 PageData.append(wxT("<h4>"));
1359 PageData.append(_("Roles"));
1360 PageData.append(wxT("</h4>"));
1361 PageData.append(wxT("<br>"));
1362 PageData.append(wxT("<table>"));
1363 PageData.append(DataLines);
1364 PageData.append(wxT("</table>"));
1370 ContactData = vCardObj->GetByPartial(wxT("ORG"));
1372 DataDisplay = FALSE;
1375 if (ContactData.PropCount > 0){
1379 for (int i = 0; i < ContactData.PropCount; i++){
1381 OrgLine = ContactData.PropValues[i];
1384 CaptureString(&OrgLine, FALSE);
1385 ConvertToHTML(&OrgLine);
1387 DataLines.append(wxT("<tr><td><b>"));
1388 DataLines.append(_("Organisation:"));
1389 DataLines.append(wxT(" </b></td><td>"));
1390 DataLines.append(OrgLine);
1391 DataLines.append(wxT("</td></tr>"));
1399 if (DataDisplay == TRUE){
1402 PageData.append(wxT("<h4>"));
1403 PageData.append(_("Organisations"));
1404 PageData.append(wxT("</h4>"));
1405 PageData.append(wxT("<br>"));
1406 PageData.append(wxT("<table>"));
1407 PageData.append(DataLines);
1408 PageData.append(wxT("</table>"));
1414 ContactData = vCardObj->GetByPartial(wxT("CATEGORIES"));
1416 DataDisplay = FALSE;
1419 if (ContactData.PropCount > 0){
1423 for (int i = 0; i < ContactData.PropCount; i++){
1425 CatLine = ContactData.PropValues[i];
1428 CaptureString(&CatLine, FALSE);
1429 ConvertToHTML(&CatLine);
1431 DataLines.append(wxT("<tr><td><b>"));
1432 DataLines.append(_("Category:"));
1433 DataLines.append(wxT(" </b></td><td>"));
1434 DataLines.append(CatLine);
1435 DataLines.append(wxT("</td></tr>"));
1443 if (DataDisplay == TRUE){
1446 PageData.append(wxT("<h4>"));
1447 PageData.append(_("Categories"));
1448 PageData.append(wxT("</h4>"));
1449 PageData.append(wxT("<br>"));
1450 PageData.append(wxT("<table>"));
1451 PageData.append(DataLines);
1452 PageData.append(wxT("</table>"));
1460 // Calendar Addresses
1462 ContactData = vCardObj->GetByPartial(wxT("CALURI"));
1464 DataDisplay = FALSE;
1467 if (ContactData.PropCount > 0){
1469 wxString CalURILine;
1471 for (int i = 0; i < ContactData.PropCount; i++){
1473 CalURILine = ContactData.PropValues[i];
1476 CaptureString(&CalURILine, FALSE);
1477 ConvertToHTML(&CalURILine);
1479 DataLines.append(wxT("<tr><td><b>"));
1480 DataLines.append(_("Calendar Address:"));
1481 DataLines.append(wxT(" </b></td><td>"));
1482 DataLines.append(CalURILine);
1483 DataLines.append(wxT("</td></tr>"));
1491 if (DataDisplay == TRUE){
1494 PageData.append(wxT("<h4>"));
1495 PageData.append(_("Calendar Addresses"));
1496 PageData.append(wxT("</h4>"));
1497 PageData.append(wxT("<br>"));
1498 PageData.append(wxT("<table>"));
1499 PageData.append(DataLines);
1500 PageData.append(wxT("</table>"));
1504 // Calendar Request Addresses
1506 ContactData = vCardObj->GetByPartial(wxT("CALADRURI"));
1508 DataDisplay = FALSE;
1511 if (ContactData.PropCount > 0){
1513 wxString CalAdrURILine;
1515 for (int i = 0; i < ContactData.PropCount; i++){
1517 CalAdrURILine = ContactData.PropValues[i];
1519 CalAdrURILine.Trim();
1520 CaptureString(&CalAdrURILine, FALSE);
1521 ConvertToHTML(&CalAdrURILine);
1523 DataLines.append(wxT("<tr><td><b>"));
1524 DataLines.append(_("Calendar Request Address:"));
1525 DataLines.append(wxT(" </b></td><td>"));
1526 DataLines.append(CalAdrURILine);
1527 DataLines.append(wxT("</td></tr>"));
1535 if (DataDisplay == TRUE){
1538 PageData.append(wxT("<h4>"));
1539 PageData.append(_("Calendar Request Addresses"));
1540 PageData.append(wxT("</h4>"));
1541 PageData.append(wxT("<br>"));
1542 PageData.append(wxT("<table>"));
1543 PageData.append(DataLines);
1544 PageData.append(wxT("</table>"));
1548 // Free/Busy Addresses
1550 ContactData = vCardObj->GetByPartial(wxT("FBURL"));
1552 DataDisplay = FALSE;
1555 if (ContactData.PropCount > 0){
1559 for (int i = 0; i < ContactData.PropCount; i++){
1561 FBURLLine = ContactData.PropValues[i];
1564 CaptureString(&FBURLLine, FALSE);
1565 ConvertToHTML(&FBURLLine);
1567 DataLines.append(wxT("<tr><td><b>"));
1568 DataLines.append(_("Free/Busy Address:"));
1569 DataLines.append(wxT(" </b></td><td>"));
1570 DataLines.append(FBURLLine);
1571 DataLines.append(wxT("</td></tr>"));
1579 if (DataDisplay == TRUE){
1582 PageData.append(wxT("<h4>"));
1583 PageData.append(_("Free/Busy Addresses"));
1584 PageData.append(wxT("</h4>"));
1585 PageData.append(wxT("<br>"));
1586 PageData.append(wxT("<table>"));
1587 PageData.append(DataLines);
1588 PageData.append(wxT("</table>"));
1594 ContactData = vCardObj->GetByPartial(wxT("NOTE"));
1596 DataDisplay = FALSE;
1599 if (ContactData.PropCount > 0){
1603 for (int i = 0; i < ContactData.PropCount; i++){
1605 NoteLine = ContactData.PropValues[i];
1608 CaptureString(&NoteLine, FALSE);
1609 ConvertToHTML(&NoteLine);
1611 DataLines.append(wxT("<tr><td><b>"));
1612 DataLines.append(_("Note:"));
1613 DataLines.append(wxT(" </b></td><td>"));
1614 DataLines.append(NoteLine);
1615 DataLines.append(wxT("</td></tr>"));
1623 if (DataDisplay == TRUE){
1625 PageData.append(wxT("<h4>"));
1626 PageData.append(_("Notes"));
1627 PageData.append(wxT("</h4>"));
1628 PageData.append(wxT("<br>"));
1629 PageData.append(wxT("<table>"));
1630 PageData.append(DataLines);
1631 PageData.append(wxT("</table>"));
1635 // Display the HTML document on the screen.
1637 PageData.append("</td></tr></table>");
1639 PageData.append(wxT("</body>"));
1640 PageData.append(wxT("</html>"));
1642 HTMLObj->SetPage(PageData);
1646 void SplitPropertyData(wxString *PropertyLine,
1647 std::map<int,int> *SplitPoints,
1648 std::map<int,int> *SplitLength,
1650 std::map<wxString,wxString> *SplitData){
1653 wxStringTokenizer PropertyElement;
1654 wxString PropertyName;
1655 wxString PropertyValue;
1656 int intPropertyLen = PropertyLine->Len();
1657 int intSplitsFound = 0;
1658 int intSplitSize = 0;
1659 int intSplitSeek = (intSize - 1);
1661 for (int i = intSize; i <= intPropertyLen; i++){
1665 if (PropertyLine->Mid(i, 1) == wxT(";") &&
1666 PropertyLine->Mid((i - 1), 1) != wxT("\\")){
1668 if (intSplitsFound == 0){
1670 DataStr = PropertyLine->Mid(intSplitSeek, (intSplitSize));
1671 SplitLength->insert(std::make_pair(intSplitsFound, (intSplitSize)));
1675 DataStr = PropertyLine->Mid(intSplitSeek, (intSplitSize - 1));
1676 SplitLength->insert(std::make_pair(intSplitsFound, (intSplitSize - 1)));
1680 SplitPoints->insert(std::make_pair(intSplitsFound, (i + 1)));
1683 intSplitSeek = (i + 1);
1686 if (!DataStr.IsEmpty()){
1688 PropertyElement.SetString(DataStr, wxT("="));
1689 PropertyName = PropertyElement.GetNextToken();
1690 PropertyValue = PropertyElement.GetNextToken();
1691 SplitData->insert(std::make_pair(PropertyName, PropertyValue));
1696 PropertyName.clear();
1697 PropertyValue.clear();
1703 if (intSplitsFound == 0){
1705 DataStr = PropertyLine->Mid(intSplitSeek, (intSplitSize));
1707 SplitPoints->insert(std::make_pair(intSplitsFound, (8 + 1)));
1708 SplitLength->insert(std::make_pair(intSplitsFound, intSplitSize));
1712 DataStr = PropertyLine->Mid(intSplitSeek, (intSplitSize - 1));
1714 SplitPoints->insert(std::make_pair(intSplitsFound, (intSplitSeek + 1)));
1715 SplitLength->insert(std::make_pair(intSplitsFound, intSplitSize));
1719 if (!DataStr.IsEmpty()){
1721 PropertyElement.SetString(DataStr, wxT("="));
1722 PropertyName = PropertyElement.GetNextToken();
1723 PropertyValue = PropertyElement.GetNextToken();
1724 SplitData->insert(std::make_pair(PropertyName, PropertyValue));