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 ArrayvCardOutData FNList;
137 FNList = vCardObj->GetByPartial(wxT("FN"));
139 PageData.append(wxT("<table style=\"background: #cccccc; width: 100%\">"));
140 PageData.append(wxT("<tr>"));
141 PageData.append(wxT("<td style=\"width:100%\">"));
142 PageData.append(wxT("<h2>"));
144 if (FNList.PropCount > 0){
145 FNList.PropValues[0].Trim();
146 PageData.append(FNList.PropValues[0]);
149 PageData.append(wxT("</h2>"));
150 PageData.append(wxT("</td>"));
151 PageData.append(wxT("<td style=\"width: 200px;\">"));
153 // Define common variables for ADR.
155 std::map<int,int> SplitPoints;
156 std::map<int,int> SplitLength;
157 std::map<int,int>::iterator SLiter;
164 wxString AddressPOBox;
165 wxString AddressStreet;
166 wxString AddressLocality;
167 wxString AddressRegion;
168 wxString AddressPostalCode;
169 wxString AddressCountry;
170 wxString AddressExtended;
172 wxString FinalAddressLine;
173 bool AddressFirst = TRUE;
175 // Define common variables for PHOTO and LOGO.
177 std::string PhotoDataBin;
178 std::string PhotoDataIn;
179 wxString PhotoSplitData;
180 wxString PhotoMIMEType;
181 wxString PhotoEncType;
182 wxString PhotoEncData;
183 bool LoadPicture = FALSE;
184 bool DataDisplay = FALSE;
185 bool RectData = FALSE;
186 wxRect PhotoRectPoints;
187 wxString SIDFilename;
193 ArrayvCardOutData ContactData = vCardObj->GetByPartial(wxT("PHOTO"));
195 if (ContactData.PropCount > 0){
201 /*std::map<int,int> SplitPts;
202 std::map<int,int> SplitLen;
203 std::map<wxString,wxString> SplitData;
206 SplitPropertyData(&ContactData.PropData[0],
212 for (std::map<wxString, wxString>::iterator striter = SplitData.begin();
213 striter != SplitData.end(); striter++){
219 // Look for the X-ABCROP-RECTANGLE.
221 wxStringTokenizer PhotoSplit(ContactData.PropData[0], wxT(":"));
222 wxString PhotoPropertyDataString = PhotoSplit.GetNextToken();
223 wxStringTokenizer PhotoPropertyData(PhotoPropertyDataString, wxT(";"));
224 wxString PropertyLineData;
225 wxString PropertyName;
226 wxString PropertyValue;
228 wxStringTokenizer DataSplit(ContactData.PropValues[0], wxT(";"));
229 PhotoSplitData = DataSplit.GetNextToken();
230 wxStringTokenizer MIMESplit(PhotoSplitData, wxT(":"));
231 MIMESplit.GetNextToken();
232 PhotoMIMEType = MIMESplit.GetNextToken();
233 PhotoSplitData = DataSplit.GetNextToken();
234 wxStringTokenizer EncSplit(PhotoSplitData, wxT(","));
235 PhotoEncType = EncSplit.GetNextToken();
236 PhotoEncData = EncSplit.GetNextToken();
238 // Convert the picture data from base64 to binary.
240 PhotoDataIn = std::string(PhotoEncData.mb_str());
241 PhotoDataBin = base64_decode(PhotoDataIn);
242 wxMemoryInputStream istream(PhotoDataBin.c_str(), (size_t)PhotoDataBin.size());
245 if (!photo.LoadFile(istream, wxBITMAP_TYPE_ANY)){
247 // Photo failed to load so do nothing.
253 while (PhotoPropertyData.HasMoreTokens()){
255 PropertyLineData = PhotoPropertyData.GetNextToken();
257 wxStringTokenizer PhotoPropPair(PropertyLineData, wxT("="));
258 wxString PhotoPropName = PhotoPropPair.GetNextToken();
259 wxString PhotoPropValue = PhotoPropPair.GetNextToken();
261 if (PhotoPropName == wxT("X-ABCROP-RECTANGLE")){
263 wxStringTokenizer PhotoRectData(PhotoPropValue, wxT("&"));
265 PhotoRectData.GetNextToken();
267 //PhotoRectPoints.SetX(wxAtoi(PhotoRectData.GetNextToken()));
268 //PhotoRectPoints.SetY(wxAtoi(PhotoRectData.GetNextToken()) - 100);
270 int PointXBase = wxAtoi(PhotoRectData.GetNextToken());
271 int PointYBase = wxAtoi(PhotoRectData.GetNextToken());
272 int PointWBase = wxAtoi(PhotoRectData.GetNextToken());
273 int PointHBase = wxAtoi(PhotoRectData.GetNextToken());
275 int PointX = PointXBase;
276 int PointY = PointYBase;
277 int PointW = PointWBase;
278 int PointH = PointHBase;
282 if (PointYBase > PointHBase){
284 PointX = photo.GetWidth() - PointXBase - 140;
285 PointY = photo.GetHeight() - PointYBase - 140;
289 } else if (PointXBase > PointWBase){
291 PointX = photo.GetWidth() - PointXBase;
292 PointY = PointYBase - 50;
300 /*int PointX = PointXBase;
301 int PointY = PointYBase;
302 int PointW = PointWBase;
303 int PointH = PointHBase;*/
305 // Bottom Left Method
307 /*int PointX = wxAtoi(PhotoRectData.GetNextToken());
308 int PointY = photo.GetHeight() - wxAtoi(PhotoRectData.GetNextToken()) - 340;
309 int PointW = wxAtoi(PhotoRectData.GetNextToken());
310 int PointH = wxAtoi(PhotoRectData.GetNextToken());*/
312 // Bottom Right Method
314 /*int PointXRemain = photo.GetWidth() - PointX - 140;
315 int PointYRemain = photo.GetHeight() - PointY - 140;*/
317 PhotoRectPoints.SetX(PointX);
318 PhotoRectPoints.SetY(PointY);
319 PhotoRectPoints.SetWidth(PointW);
320 PhotoRectPoints.SetHeight(PointH);
329 // Resize the picture to 125x125.
331 // Add to the wxMemnoryFSHandler.
333 SIDFilename = SID + wxT("-photo");
335 if (RectData == TRUE){
337 wxImage rectphoto = photo.GetSubImage(PhotoRectPoints);
338 rectphoto = rectphoto.Scale(75, 75, wxIMAGE_QUALITY_HIGH);
339 wxMemoryFSHandler::AddFile(SIDFilename, rectphoto, wxBITMAP_TYPE_PNG);
343 photo = photo.Scale(50, 50, wxIMAGE_QUALITY_HIGH);
344 wxMemoryFSHandler::AddFile(SIDFilename, photo, wxBITMAP_TYPE_PNG);
348 // Add the filename to the MemoryFSList map.
350 MemoryFSList->insert(std::make_pair(SIDFilename, SID));
356 if (LoadPicture == TRUE){
358 PageData.append(wxT("<img src=\"memory:") + SIDFilename + wxT("\">"));
366 ContactData = vCardObj->GetByPartial(wxT("LOGO"));
368 if (ContactData.PropCount > 0){
372 wxStringTokenizer DataSplit(ContactData.PropValues[0], wxT(";"));
373 PhotoSplitData = DataSplit.GetNextToken();
374 wxStringTokenizer MIMESplit(PhotoSplitData, wxT(":"));
375 MIMESplit.GetNextToken();
376 PhotoMIMEType = MIMESplit.GetNextToken();
377 PhotoSplitData = DataSplit.GetNextToken();
378 wxStringTokenizer EncSplit(PhotoSplitData, wxT(","));
379 PhotoEncType = EncSplit.GetNextToken();
380 PhotoEncData = EncSplit.GetNextToken();
382 // Convert the picture data from base64 to binary.
384 PhotoDataIn = std::string(PhotoEncData.mb_str());
385 PhotoDataBin = base64_decode(PhotoDataIn);
386 wxMemoryInputStream istream(PhotoDataBin.c_str(), (size_t)PhotoDataBin.size());
389 if (!photo.LoadFile(istream, wxBITMAP_TYPE_ANY)){
391 // Photo failed to load so do nothing.
399 photo = photo.Scale(50, 50, wxIMAGE_QUALITY_HIGH);
401 // Resize the picture to 125x125.
403 // Add to the wxMemnoryFSHandler.
405 SIDFilename = SID + wxT("-logo");
407 wxMemoryFSHandler::AddFile(SIDFilename, photo, wxBITMAP_TYPE_PNG);
409 // Add the filename to the MemoryFSList map.
411 MemoryFSList->insert(std::make_pair(SIDFilename, SID));
417 if (LoadPicture == TRUE){
419 PageData.append(wxT("<img src=\"memory:") + SIDFilename + wxT("\">"));
423 PageData.append(wxT("</td>"));
424 PageData.append(wxT("</tr>"));
425 PageData.append(wxT("</table>"));
427 // Process LOGO, PHOTO, SOUND, KEY, VND-* and X-*
428 // lines and display icons for each accordingly.
430 ContactData = vCardObj->GetByPartial(wxT("PHOTO"));
432 bool AddBreak = FALSE;
433 wxString TypePageData;
435 if (ContactData.PropCount > 1){
437 TypePageData.append(wxT("<img src=\"memory:cipto.png\" alt=\""));
438 TypePageData.append(_("This contact has multiple photos."));
439 TypePageData.append(wxT("\">"));
444 ContactData = vCardObj->GetByPartial(wxT("LOGO"));
446 if (ContactData.PropCount > 1){
448 TypePageData.append(wxT("<img src=\"memory:cilog.png\" alt=\""));
449 TypePageData.append(_("This contact has multiple logos."));
450 TypePageData.append(wxT("\">"));
455 ContactData = vCardObj->GetByPartial(wxT("SOUND"));
457 if (ContactData.PropCount >= 1){
459 TypePageData.append(wxT("<img src=\"memory:cisnd.png\" alt=\""));
460 TypePageData.append(_("This contact has audio information."));
461 TypePageData.append(wxT("\">"));
466 ContactData = vCardObj->GetByPartial(wxT("KEY"));
468 if (ContactData.PropCount >= 1){
470 TypePageData.append(wxT("<img src=\"memory:cikey.png\" alt=\""));
471 TypePageData.append(_("This contact has crytographic keys."));
472 TypePageData.append(wxT("\">"));
477 ContactData = vCardObj->GetByPartial(wxT("VND-"));
479 if (ContactData.PropCount >= 1){
481 TypePageData.append(wxT("<img src=\"memory:civen.png\" alt=\""));
482 TypePageData.append(_("This contact has vendor-specific information."));
483 TypePageData.append(wxT("\">"));
488 ContactData = vCardObj->GetByPartial(wxT("X-"));
490 if (ContactData.PropCount >= 1){
492 TypePageData.append(wxT("<img src=\"memory:ciext.png\" alt=\""));
493 TypePageData.append(_("This contact has extended information."));
494 TypePageData.append(wxT("\">"));
499 if (!TypePageData.IsEmpty()){
501 PageData.append("<table style=\"{background: #dddddd; width:100%}\"><tr><td>");
502 PageData.append(TypePageData);
503 PageData.append("</tr></td></table>");
507 if (AddBreak == TRUE){
509 PageData.append(wxT("<br><br>"));
513 bool MultiLogoIcon = FALSE;
514 bool MultiPhotoIcon = FALSE;
515 bool SoundIcon = FALSE;
516 bool KeyIcon = FALSE;
517 bool VendorIcon = FALSE;
518 bool XTokenIcon = FALSE;
522 ContactData = vCardObj->GetByPartial(wxT("BDAY"));
527 if (ContactData.PropCount > 0){
531 for (int i = 0; i < ContactData.PropCount; i++){
533 // Grab the first birthday only.
535 BDayLine = ContactData.PropValues[i];
538 CaptureString(&BDayLine, FALSE);
539 ConvertToHTML(&BDayLine);
541 DataLines.append(BDayLine);
551 PageData.append("<table CELLPADDING=4 style=\"{width: 100%;}\"><tr><td>");
553 if (DataDisplay == TRUE){
556 PageData.append(wxT("<b>"));
557 PageData.append(_("Birthday:"));
558 PageData.append(wxT("</b> "));
559 PageData.append(DataLines);
560 PageData.append(wxT("<br>"));
564 // Process Anniversary
566 ContactData = vCardObj->GetByPartial(wxT("ANNIVERSARY"));
571 if (ContactData.PropCount > 0){
575 for (int i = 0; i < ContactData.PropCount; i++){
577 // Grab the first anniversary only.
579 AnniLine = ContactData.PropValues[i];
582 CaptureString(&AnniLine, FALSE);
583 ConvertToHTML(&AnniLine);
585 DataLines.append(AnniLine);
595 if (DataDisplay == TRUE){
598 PageData.append(wxT("<b>"));
599 PageData.append(_("Anniversary:"));
600 PageData.append(wxT("</b> "));
601 PageData.append(DataLines);
602 PageData.append(wxT("<br>"));
608 ContactData = vCardObj->GetByPartial(wxT("NICKNAME"));
613 if (ContactData.PropCount > 0){
615 wxString NicknameLine;
617 for (int i = 0; i < ContactData.PropCount; i++){
619 NicknameLine = ContactData.PropValues[i];
622 CaptureString(&NicknameLine, FALSE);
623 ConvertToHTML(&NicknameLine);
625 DataLines.append(wxT("<tr><td><b>"));
626 DataLines.append(_("Nickname:"));
627 DataLines.append(wxT(" </b></td><td>"));
628 DataLines.append(NicknameLine);
629 DataLines.append(wxT("</td></tr>"));
637 if (DataDisplay == TRUE){
640 PageData.append(wxT("<h4>"));
641 PageData.append(_("Nicknames"));
642 PageData.append(wxT("</h4>"));
643 PageData.append(wxT("<br>"));
644 PageData.append(wxT("<table>"));
645 PageData.append(DataLines);
646 PageData.append(wxT("</table>"));
652 ContactData = vCardObj->GetByPartial(wxT("ADR"));
657 if (ContactData.PropCount > 0){
659 wxString AddressLine;
661 for (int i = 0; i < ContactData.PropCount; i++){
663 AddressLine = ContactData.PropValues[i];
665 intPropertyLen = AddressLine.Len();
672 AddressPOBox.clear();
673 AddressStreet.clear();
674 AddressLocality.clear();
675 AddressRegion.clear();
676 AddressPostalCode.clear();
677 AddressCountry.clear();
678 AddressExtended.clear();
679 FinalAddressLine.clear();
682 for (int i = 0; i <= intPropertyLen; i++){
686 if (AddressLine.Mid(i, 1) == wxT(";") && AddressLine.Mid((i - 1), 1) != wxT("\\")){
689 SplitPoints.insert(std::make_pair(intSplitsFound, (i + 1)));
691 if (intSplitsFound == 6){
693 SplitLength.insert(std::make_pair(intSplitsFound, (intSplitSize - 1)));
698 SplitLength.insert(std::make_pair(intSplitsFound, (intSplitSize - 1)));
708 // Split the data into several parts.
710 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
711 intiter != SplitPoints.end(); ++intiter){
713 if (intiter->first == 1){
717 SLiter = SplitLength.find(1);
719 //txtSurname->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(0, SLiter->second), TRUE));
720 AddressPOBox = AddressLine.Mid(0, SLiter->second);
721 intPrevValue = intiter->second;
723 } else if (intiter->first == 2){
725 // Deal with extended address.
727 SLiter = SplitLength.find(2);
729 AddressExtended = AddressLine.Mid(intPrevValue, SLiter->second);
730 //txtForename->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue, SLiter->second), TRUE));
731 intPrevValue = intiter->second;
733 } else if (intiter->first == 3){
735 // Deal with street address.
737 SLiter = SplitLength.find(3);
739 AddressStreet = AddressLine.Mid(intPrevValue, SLiter->second);
740 //txtOtherNames->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue, SLiter->second), TRUE));
741 intPrevValue = intiter->second;
743 } else if (intiter->first == 4){
745 // Deal with locality
747 SLiter = SplitLength.find(4);
749 AddressLocality = AddressLine.Mid(intPrevValue, SLiter->second);
750 //txtTitle->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue, SLiter->second), TRUE));
751 intPrevValue = intiter->second;
753 //txtSuffix->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue, wxSTRING_MAXLEN), TRUE));
755 } else if (intiter->first == 5){
759 SLiter = SplitLength.find(5);
761 AddressRegion = AddressLine.Mid(intPrevValue, SLiter->second);
762 //txtTitle->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue, SLiter->second), TRUE));
763 intPrevValue = intiter->second;
765 //txtSuffix->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue, wxSTRING_MAXLEN), TRUE));
767 } else if (intiter->first == 6){
769 // Deal with post code.
771 SLiter = SplitLength.find(6);
773 AddressPostalCode = AddressLine.Mid(intPrevValue, SLiter->second);
774 //txtTitle->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue, SLiter->second), TRUE));
775 intPrevValue = intiter->second;
777 // Deal with country.
779 AddressCountry = AddressLine.Mid(intPrevValue);
780 //txtSuffix->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue, wxSTRING_MAXLEN), TRUE));
786 if (!AddressStreet.IsEmpty()){
788 AddressStreet.Trim();
789 ConvertToHTML(&AddressStreet);
791 FinalAddressLine.append(AddressStreet);
792 AddressFirst = FALSE;
796 if (!AddressLocality.IsEmpty()){
798 AddressLocality.Trim();
799 ConvertToHTML(&AddressLocality);
801 if (AddressFirst == FALSE){
803 FinalAddressLine.append(wxT(",<br>"));
804 FinalAddressLine.append(AddressLocality);
808 FinalAddressLine.append(AddressLocality);
809 AddressFirst = FALSE;
815 if (!AddressRegion.IsEmpty()){
817 AddressRegion.Trim();
818 ConvertToHTML(&AddressRegion);
820 if (AddressFirst == FALSE){
822 FinalAddressLine.append(wxT(",<br>"));
823 FinalAddressLine.append(AddressRegion);
827 FinalAddressLine.append(AddressRegion);
828 AddressFirst = FALSE;
834 if (!AddressPostalCode.IsEmpty()){
836 AddressPostalCode.Trim();
837 ConvertToHTML(&AddressPostalCode);
839 if (AddressFirst == FALSE){
841 FinalAddressLine.append(wxT(",<br>"));
842 FinalAddressLine.append(AddressPostalCode);
846 FinalAddressLine.append(AddressPostalCode);
847 AddressFirst = FALSE;
853 if (!AddressCountry.IsEmpty()){
855 AddressCountry.Trim();
856 ConvertToHTML(&AddressCountry);
858 if (AddressFirst == FALSE){
860 FinalAddressLine.append(wxT(",<br>"));
861 FinalAddressLine.append(AddressCountry);
865 FinalAddressLine.append(AddressCountry);
866 AddressFirst = FALSE;
872 CaptureString(&FinalAddressLine, FALSE);
874 DataLines.append(wxT("<tr><td><b>"));
875 DataLines.append(_("Address:"));
876 DataLines.append(wxT(" </b></td><td>"));
877 DataLines.append(FinalAddressLine);
878 DataLines.append(wxT("</td></tr>"));
886 if (DataDisplay == TRUE){
889 PageData.append(wxT("<h4>"));
890 PageData.append(_("Addresses"));
891 PageData.append(wxT("</h4>"));
892 PageData.append(wxT("<br>"));
893 PageData.append(wxT("<table>"));
894 PageData.append(DataLines);
895 PageData.append(wxT("</table>"));
901 ContactData = vCardObj->GetByPartial(wxT("EMAIL"));
906 if (ContactData.PropCount > 0){
910 for (int i = 0; i < ContactData.PropCount; i++){
912 EmailLine = ContactData.PropValues[i];
915 CaptureString(&EmailLine, FALSE);
916 ConvertToHTML(&EmailLine);
918 DataLines.append(wxT("<tr><td><b>"));
919 DataLines.append(_("E-mail Address:"));
920 DataLines.append(wxT(" </b></td><td>"));
921 DataLines.append(EmailLine);
922 DataLines.append(wxT("</td></tr>"));
930 if (DataDisplay == TRUE){
933 PageData.append(wxT("<h4>"));
934 PageData.append(_("Email Addresses"));
935 PageData.append(wxT("</h4>"));
936 PageData.append(wxT("<br>"));
937 PageData.append(wxT("<table>"));
938 PageData.append(DataLines);
939 PageData.append(wxT("</table>"));
945 ContactData = vCardObj->GetByPartial(wxT("TEL"));
950 if (ContactData.PropCount > 0){
954 for (int i = 0; i < ContactData.PropCount; i++){
956 TelLine = ContactData.PropValues[i];
958 wxStringTokenizer TelSplit(TelLine, wxT(":"));
960 TelLine = TelSplit.GetNextToken();
962 if (TelSplit.HasMoreTokens()){
964 TelLine = TelSplit.GetNextToken();
969 CaptureString(&TelLine, FALSE);
970 ConvertToHTML(&TelLine);
972 DataLines.append(wxT("<tr><td><b>"));
973 DataLines.append(_("Telephone:"));
974 DataLines.append(wxT(" </b></td><td>"));
975 DataLines.append(TelLine);
976 DataLines.append(wxT("</td></tr>"));
984 if (DataDisplay == TRUE){
987 PageData.append(wxT("<h4>"));
988 PageData.append(_("Telephones"));
989 PageData.append(wxT("</h4>"));
990 PageData.append(wxT("<br>"));
991 PageData.append(wxT("<table>"));
992 PageData.append(DataLines);
993 PageData.append(wxT("</table>"));
999 ContactData = vCardObj->GetByPartial(wxT("IMPP"));
1001 DataDisplay = FALSE;
1004 if (ContactData.PropCount > 0){
1007 wxString IMTypeFriendly;
1010 for (int i = 0; i < ContactData.PropCount; i++){
1012 IMLine = ContactData.PropValues[i];
1014 wxStringTokenizer IMSplit(IMLine, wxT(":"));
1016 IMType = IMSplit.GetNextToken();
1017 IMLine = IMSplit.GetNextToken();
1019 // Process skype, gg, icq, yahoo etc into
1020 // something meaningful.
1022 if (IMType == wxT("aim")){
1026 IMTypeFriendly = _("AIM");
1028 } else if (IMType == wxT("xmpp")){
1032 IMTypeFriendly = _("XMPP");
1034 } else if (IMType == wxT("icq")){
1038 IMTypeFriendly = _("ICQ");
1040 } else if (IMType == wxT("skype")){
1044 IMTypeFriendly = _("Skype");
1046 } else if (IMType == wxT("gg")){
1050 IMTypeFriendly = _("Gadu-Gadu");
1052 } else if (IMType == wxT("yahoo")){
1056 IMTypeFriendly = _("Yahoo");
1060 // Other. Use IM type that was split.
1062 IMTypeFriendly = IMType;
1067 CaptureString(&IMLine, FALSE);
1068 ConvertToHTML(&IMLine);
1070 DataLines.append(wxT("<tr><td><b>"));
1071 DataLines.append(_("IM Address"));
1072 DataLines.append(_(" ("));
1073 DataLines.append(IMTypeFriendly);
1074 DataLines.append(_("):"));
1075 DataLines.append(wxT(" </b></td><td>"));
1076 DataLines.append(IMLine);
1077 DataLines.append(wxT("</td></tr>"));
1079 IMTypeFriendly.clear();
1089 if (DataDisplay == TRUE){
1092 PageData.append(wxT("<h4>"));
1093 PageData.append(_("Instant Messaging Addresses"));
1094 PageData.append(wxT("</h4>"));
1095 PageData.append(wxT("<br>"));
1096 PageData.append(wxT("<table>"));
1097 PageData.append(DataLines);
1098 PageData.append(wxT("</table>"));
1104 ContactData = vCardObj->GetByPartial(wxT("URL"));
1106 DataDisplay = FALSE;
1109 if (ContactData.PropCount > 0){
1113 for (int i = 0; i < ContactData.PropCount; i++){
1115 URLLine = ContactData.PropValues[i];
1118 CaptureString(&URLLine, FALSE);
1119 ConvertToHTML(&URLLine);
1121 DataLines.append(wxT("<tr><td><b>"));
1122 DataLines.append(_("Website:"));
1123 DataLines.append(wxT(" </b></td><td>"));
1124 DataLines.append(URLLine);
1125 DataLines.append(wxT("</td></tr>"));
1133 if (DataDisplay == TRUE){
1136 PageData.append(wxT("<h4>"));
1137 PageData.append(_("Website Addresses"));
1138 PageData.append(wxT("</h4>"));
1139 PageData.append(wxT("<br>"));
1140 PageData.append(wxT("<table>"));
1141 PageData.append(DataLines);
1142 PageData.append(wxT("</table>"));
1148 ContactData = vCardObj->GetByPartial(wxT("LANG"));
1150 DataDisplay = FALSE;
1153 if (ContactData.PropCount > 0){
1155 wxString NicknameLine;
1157 for (int i = 0; i < ContactData.PropCount; i++){
1159 NicknameLine = ContactData.PropValues[i];
1161 NicknameLine.Trim();
1162 CaptureString(&NicknameLine, FALSE);
1163 ConvertToHTML(&NicknameLine);
1165 DataLines.append(wxT("<tr><td><b>"));
1166 DataLines.append(_("Language:"));
1167 DataLines.append(wxT(" </b></td><td>"));
1168 DataLines.append(NicknameLine);
1169 DataLines.append(wxT("</td></tr>"));
1177 if (DataDisplay == TRUE){
1180 PageData.append(wxT("<h4>"));
1181 PageData.append(_("Languages"));
1182 PageData.append(wxT("</h4>"));
1183 PageData.append(wxT("<br>"));
1184 PageData.append(wxT("<table>"));
1185 PageData.append(DataLines);
1186 PageData.append(wxT("</table>"));
1192 ContactData = vCardObj->GetByPartial(wxT("TZ"));
1194 DataDisplay = FALSE;
1197 if (ContactData.PropCount > 0){
1199 wxString NicknameLine;
1201 for (int i = 0; i < ContactData.PropCount; i++){
1203 NicknameLine = ContactData.PropValues[i];
1205 NicknameLine.Trim();
1206 CaptureString(&NicknameLine, FALSE);
1207 ConvertToHTML(&NicknameLine);
1209 DataLines.append(wxT("<tr><td><b>"));
1210 DataLines.append(_("Timezone:"));
1211 DataLines.append(wxT(" </b></td><td>"));
1212 DataLines.append(NicknameLine);
1213 DataLines.append(wxT("</td></tr>"));
1221 if (DataDisplay == TRUE){
1224 PageData.append(wxT("<h4>"));
1225 PageData.append(_("Timezones"));
1226 PageData.append(wxT("</h4>"));
1227 PageData.append(wxT("<br>"));
1228 PageData.append(wxT("<table>"));
1229 PageData.append(DataLines);
1230 PageData.append(wxT("</table>"));
1236 ContactData = vCardObj->GetByPartial(wxT("GEO"));
1238 DataDisplay = FALSE;
1241 if (ContactData.PropCount > 0){
1245 for (int i = 0; i < ContactData.PropCount; i++){
1247 GeoLine = ContactData.PropValues[i];
1249 wxStringTokenizer GeoSplit(GeoLine, wxT(":"));
1251 GeoLine = GeoSplit.GetNextToken();
1253 if (GeoSplit.HasMoreTokens()){
1255 GeoLine = GeoSplit.GetNextToken();
1260 CaptureString(&GeoLine, FALSE);
1261 ConvertToHTML(&GeoLine);
1263 DataLines.append(wxT("<tr><td><b>"));
1264 DataLines.append(_("Geoposition:"));
1265 DataLines.append(wxT(" </b></td><td>"));
1266 DataLines.append(GeoLine);
1267 DataLines.append(wxT("</td></tr>"));
1275 if (DataDisplay == TRUE){
1278 PageData.append(wxT("<h4>"));
1279 PageData.append(_("Geopositioning"));
1280 PageData.append(wxT("</h4>"));
1281 PageData.append(wxT("<br>"));
1282 PageData.append(wxT("<table>"));
1283 PageData.append(DataLines);
1284 PageData.append(wxT("</table>"));
1290 ContactData = vCardObj->GetByPartial(wxT("TITLE"));
1292 DataDisplay = FALSE;
1295 if (ContactData.PropCount > 0){
1299 for (int i = 0; i < ContactData.PropCount; i++){
1301 TitleLine = ContactData.PropValues[i];
1304 CaptureString(&TitleLine, FALSE);
1305 ConvertToHTML(&TitleLine);
1307 DataLines.append(wxT("<tr><td><b>"));
1308 DataLines.append(_("Title:"));
1309 DataLines.append(wxT(" </b></td><td>"));
1310 DataLines.append(TitleLine);
1311 DataLines.append(wxT("</td></tr>"));
1319 if (DataDisplay == TRUE){
1322 PageData.append(wxT("<h4>"));
1323 PageData.append(_("Titles"));
1324 PageData.append(wxT("</h4>"));
1325 PageData.append(wxT("<br>"));
1326 PageData.append(wxT("<table>"));
1327 PageData.append(DataLines);
1328 PageData.append(wxT("</table>"));
1334 ContactData = vCardObj->GetByPartial(wxT("ROLE"));
1336 DataDisplay = FALSE;
1339 if (ContactData.PropCount > 0){
1343 for (int i = 0; i < ContactData.PropCount; i++){
1345 RoleLine = ContactData.PropValues[i];
1348 CaptureString(&RoleLine, FALSE);
1349 ConvertToHTML(&RoleLine);
1351 DataLines.append(wxT("<tr><td><b>"));
1352 DataLines.append(_("Role:"));
1353 DataLines.append(wxT(" </b></td><td>"));
1354 DataLines.append(RoleLine);
1355 DataLines.append(wxT("</td></tr>"));
1363 if (DataDisplay == TRUE){
1366 PageData.append(wxT("<h4>"));
1367 PageData.append(_("Roles"));
1368 PageData.append(wxT("</h4>"));
1369 PageData.append(wxT("<br>"));
1370 PageData.append(wxT("<table>"));
1371 PageData.append(DataLines);
1372 PageData.append(wxT("</table>"));
1378 ContactData = vCardObj->GetByPartial(wxT("ORG"));
1380 DataDisplay = FALSE;
1383 if (ContactData.PropCount > 0){
1387 for (int i = 0; i < ContactData.PropCount; i++){
1389 OrgLine = ContactData.PropValues[i];
1392 CaptureString(&OrgLine, FALSE);
1393 ConvertToHTML(&OrgLine);
1395 DataLines.append(wxT("<tr><td><b>"));
1396 DataLines.append(_("Organisation:"));
1397 DataLines.append(wxT(" </b></td><td>"));
1398 DataLines.append(OrgLine);
1399 DataLines.append(wxT("</td></tr>"));
1407 if (DataDisplay == TRUE){
1410 PageData.append(wxT("<h4>"));
1411 PageData.append(_("Organisations"));
1412 PageData.append(wxT("</h4>"));
1413 PageData.append(wxT("<br>"));
1414 PageData.append(wxT("<table>"));
1415 PageData.append(DataLines);
1416 PageData.append(wxT("</table>"));
1422 ContactData = vCardObj->GetByPartial(wxT("CATEGORIES"));
1424 DataDisplay = FALSE;
1427 if (ContactData.PropCount > 0){
1431 for (int i = 0; i < ContactData.PropCount; i++){
1433 CatLine = ContactData.PropValues[i];
1436 CaptureString(&CatLine, FALSE);
1437 ConvertToHTML(&CatLine);
1439 DataLines.append(wxT("<tr><td><b>"));
1440 DataLines.append(_("Category:"));
1441 DataLines.append(wxT(" </b></td><td>"));
1442 DataLines.append(CatLine);
1443 DataLines.append(wxT("</td></tr>"));
1451 if (DataDisplay == TRUE){
1454 PageData.append(wxT("<h4>"));
1455 PageData.append(_("Categories"));
1456 PageData.append(wxT("</h4>"));
1457 PageData.append(wxT("<br>"));
1458 PageData.append(wxT("<table>"));
1459 PageData.append(DataLines);
1460 PageData.append(wxT("</table>"));
1468 // Calendar Addresses
1470 ContactData = vCardObj->GetByPartial(wxT("CALURI"));
1472 DataDisplay = FALSE;
1475 if (ContactData.PropCount > 0){
1477 wxString CalURILine;
1479 for (int i = 0; i < ContactData.PropCount; i++){
1481 CalURILine = ContactData.PropValues[i];
1484 CaptureString(&CalURILine, FALSE);
1485 ConvertToHTML(&CalURILine);
1487 DataLines.append(wxT("<tr><td><b>"));
1488 DataLines.append(_("Calendar Address:"));
1489 DataLines.append(wxT(" </b></td><td>"));
1490 DataLines.append(CalURILine);
1491 DataLines.append(wxT("</td></tr>"));
1499 if (DataDisplay == TRUE){
1502 PageData.append(wxT("<h4>"));
1503 PageData.append(_("Calendar Addresses"));
1504 PageData.append(wxT("</h4>"));
1505 PageData.append(wxT("<br>"));
1506 PageData.append(wxT("<table>"));
1507 PageData.append(DataLines);
1508 PageData.append(wxT("</table>"));
1512 // Calendar Request Addresses
1514 ContactData = vCardObj->GetByPartial(wxT("CALADRURI"));
1516 DataDisplay = FALSE;
1519 if (ContactData.PropCount > 0){
1521 wxString CalAdrURILine;
1523 for (int i = 0; i < ContactData.PropCount; i++){
1525 CalAdrURILine = ContactData.PropValues[i];
1527 CalAdrURILine.Trim();
1528 CaptureString(&CalAdrURILine, FALSE);
1529 ConvertToHTML(&CalAdrURILine);
1531 DataLines.append(wxT("<tr><td><b>"));
1532 DataLines.append(_("Calendar Request Address:"));
1533 DataLines.append(wxT(" </b></td><td>"));
1534 DataLines.append(CalAdrURILine);
1535 DataLines.append(wxT("</td></tr>"));
1543 if (DataDisplay == TRUE){
1546 PageData.append(wxT("<h4>"));
1547 PageData.append(_("Calendar Request Addresses"));
1548 PageData.append(wxT("</h4>"));
1549 PageData.append(wxT("<br>"));
1550 PageData.append(wxT("<table>"));
1551 PageData.append(DataLines);
1552 PageData.append(wxT("</table>"));
1556 // Free/Busy Addresses
1558 ContactData = vCardObj->GetByPartial(wxT("FBURL"));
1560 DataDisplay = FALSE;
1563 if (ContactData.PropCount > 0){
1567 for (int i = 0; i < ContactData.PropCount; i++){
1569 FBURLLine = ContactData.PropValues[i];
1572 CaptureString(&FBURLLine, FALSE);
1573 ConvertToHTML(&FBURLLine);
1575 DataLines.append(wxT("<tr><td><b>"));
1576 DataLines.append(_("Free/Busy Address:"));
1577 DataLines.append(wxT(" </b></td><td>"));
1578 DataLines.append(FBURLLine);
1579 DataLines.append(wxT("</td></tr>"));
1587 if (DataDisplay == TRUE){
1590 PageData.append(wxT("<h4>"));
1591 PageData.append(_("Free/Busy Addresses"));
1592 PageData.append(wxT("</h4>"));
1593 PageData.append(wxT("<br>"));
1594 PageData.append(wxT("<table>"));
1595 PageData.append(DataLines);
1596 PageData.append(wxT("</table>"));
1602 ContactData = vCardObj->GetByPartial(wxT("NOTE"));
1604 DataDisplay = FALSE;
1607 if (ContactData.PropCount > 0){
1611 for (int i = 0; i < ContactData.PropCount; i++){
1613 NoteLine = ContactData.PropValues[i];
1616 CaptureString(&NoteLine, FALSE);
1617 ConvertToHTML(&NoteLine);
1619 DataLines.append(wxT("<tr><td><b>"));
1620 DataLines.append(_("Note:"));
1621 DataLines.append(wxT(" </b></td><td>"));
1622 DataLines.append(NoteLine);
1623 DataLines.append(wxT("</td></tr>"));
1631 if (DataDisplay == TRUE){
1633 PageData.append(wxT("<h4>"));
1634 PageData.append(_("Notes"));
1635 PageData.append(wxT("</h4>"));
1636 PageData.append(wxT("<br>"));
1637 PageData.append(wxT("<table>"));
1638 PageData.append(DataLines);
1639 PageData.append(wxT("</table>"));
1643 // Display the HTML document on the screen.
1645 PageData.append("</td></tr></table>");
1647 PageData.append(wxT("</body>"));
1648 PageData.append(wxT("</html>"));
1650 HTMLObj->SetPage(PageData);
1654 void SplitPropertyData(wxString *PropertyLine,
1655 std::map<int,int> *SplitPoints,
1656 std::map<int,int> *SplitLength,
1658 std::map<wxString,wxString> *SplitData){
1661 wxStringTokenizer PropertyElement;
1662 wxString PropertyName;
1663 wxString PropertyValue;
1664 int intPropertyLen = PropertyLine->Len();
1665 int intSplitsFound = 0;
1666 int intSplitSize = 0;
1667 int intSplitSeek = (intSize - 1);
1669 for (int i = intSize; i <= intPropertyLen; i++){
1673 if (PropertyLine->Mid(i, 1) == wxT(";") &&
1674 PropertyLine->Mid((i - 1), 1) != wxT("\\")){
1676 if (intSplitsFound == 0){
1678 DataStr = PropertyLine->Mid(intSplitSeek, (intSplitSize));
1679 SplitLength->insert(std::make_pair(intSplitsFound, (intSplitSize)));
1683 DataStr = PropertyLine->Mid(intSplitSeek, (intSplitSize - 1));
1684 SplitLength->insert(std::make_pair(intSplitsFound, (intSplitSize - 1)));
1688 SplitPoints->insert(std::make_pair(intSplitsFound, (i + 1)));
1691 intSplitSeek = (i + 1);
1694 if (!DataStr.IsEmpty()){
1696 PropertyElement.SetString(DataStr, wxT("="));
1697 PropertyName = PropertyElement.GetNextToken();
1698 PropertyValue = PropertyElement.GetNextToken();
1699 SplitData->insert(std::make_pair(PropertyName, PropertyValue));
1704 PropertyName.clear();
1705 PropertyValue.clear();
1711 if (intSplitsFound == 0){
1713 DataStr = PropertyLine->Mid(intSplitSeek, (intSplitSize));
1715 SplitPoints->insert(std::make_pair(intSplitsFound, (8 + 1)));
1716 SplitLength->insert(std::make_pair(intSplitsFound, intSplitSize));
1720 DataStr = PropertyLine->Mid(intSplitSeek, (intSplitSize - 1));
1722 SplitPoints->insert(std::make_pair(intSplitsFound, (intSplitSeek + 1)));
1723 SplitLength->insert(std::make_pair(intSplitsFound, intSplitSize));
1727 if (!DataStr.IsEmpty()){
1729 PropertyElement.SetString(DataStr, wxT("="));
1730 PropertyName = PropertyElement.GetNextToken();
1731 PropertyValue = PropertyElement.GetNextToken();
1732 SplitData->insert(std::make_pair(PropertyName, PropertyValue));