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>
29 #include "getcontactinfo.h"
31 #include "textprocessing.h"
32 #include "../vcard/vcard34conv.h"
34 void LoadContactData(vCard *vCardObj, wxHtmlWindow *HTMLObj, wxString SID,
35 wxString OldSID, std::map<wxString, wxString> *MemoryFSList, wxColour backgroundColour){
37 // Load the vCard contact data into the wxHTMLWindow given.
39 // Show message to user that the contact information is loading.
41 HTMLObj->SetBorders(0);
42 HTMLObj->SetBackgroundColour(wxColour(160,160,160,0));
46 wxFileSystem::AddHandler(new wxMemoryFSHandler);
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.
99 for (std::map<wxString, wxString>::iterator striter = MemoryFSList->begin();
100 striter != MemoryFSList->end(); striter++){
102 SIDTemp = striter->second;
106 // Generate a new random number.
108 SID = wxString::Format(wxT("%i"), rand() % 32768);
110 // Rewind the seek process back to the start.
112 striter = MemoryFSList->begin();
120 // Setup the HTML document.
122 PageData.append(wxT("<html>"));
123 PageData.append(wxT("<head>"));
124 PageData.append(wxT("<title>Contact Information</title>"));
125 PageData.append(wxT("</head>"));
127 // Process the CSS section.
129 PageData.append(wxT("<body>"));
131 // Process the data in the vCard object.
135 ArrayvCardOutData FNList;
136 FNList = vCardObj->GetByPartial(wxT("FN"));
138 PageData.append(wxT("<table style=\"background: #cccccc; width: 100%\">"));
139 PageData.append(wxT("<tr>"));
140 PageData.append(wxT("<td style=\"width:100%\">"));
141 PageData.append(wxT("<h2>"));
143 if (FNList.PropCount > 0){
144 FNList.PropValues[0].Trim();
145 CaptureString(&FNList.PropValues[0], false);
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){
197 // Look for the X-ABCROP-RECTANGLE.
199 wxStringTokenizer PhotoSplit(ContactData.PropData[0], wxT(":"));
200 wxString PhotoPropertyDataString = PhotoSplit.GetNextToken();
201 wxStringTokenizer PhotoPropertyData(PhotoPropertyDataString, wxT(";"));
202 wxString PropertyLineData;
203 wxString PropertyName;
204 wxString PropertyValue;
206 wxStringTokenizer DataSplit(ContactData.PropValues[0], wxT(";"));
207 PhotoSplitData = DataSplit.GetNextToken();
208 wxStringTokenizer MIMESplit(PhotoSplitData, wxT(":"));
209 MIMESplit.GetNextToken();
210 PhotoMIMEType = MIMESplit.GetNextToken();
211 PhotoSplitData = DataSplit.GetNextToken();
212 wxStringTokenizer EncSplit(PhotoSplitData, wxT(","));
213 PhotoEncType = EncSplit.GetNextToken();
214 PhotoEncData = EncSplit.GetNextToken();
216 // Convert the picture data from base64 to binary.
218 PhotoDataIn = std::string(PhotoEncData.mb_str());
219 PhotoDataBin = base64_decode(PhotoDataIn);
220 wxMemoryInputStream istream(PhotoDataBin.c_str(), (size_t)PhotoDataBin.size());
223 if (!photo.LoadFile(istream, wxBITMAP_TYPE_ANY)){
225 // Photo failed to load so do nothing.
231 while (PhotoPropertyData.HasMoreTokens()){
233 PropertyLineData = PhotoPropertyData.GetNextToken();
235 wxStringTokenizer PhotoPropPair(PropertyLineData, wxT("="));
236 wxString PhotoPropName = PhotoPropPair.GetNextToken();
237 wxString PhotoPropValue = PhotoPropPair.GetNextToken();
239 if (PhotoPropName == wxT("X-ABCROP-RECTANGLE")){
241 wxStringTokenizer PhotoRectData(PhotoPropValue, wxT("&"));
243 PhotoRectData.GetNextToken();
245 int PointXBase = wxAtoi(PhotoRectData.GetNextToken());
246 int PointYBase = wxAtoi(PhotoRectData.GetNextToken());
247 int PointWBase = wxAtoi(PhotoRectData.GetNextToken());
248 int PointHBase = wxAtoi(PhotoRectData.GetNextToken());
250 int PointX = PointXBase;
251 int PointY = PointYBase;
252 int PointW = PointWBase;
253 int PointH = PointHBase;
257 if (PointYBase > PointHBase){
259 PointX = photo.GetWidth() - PointXBase - 140;
260 PointY = photo.GetHeight() - PointYBase - 140;
264 } else if (PointXBase > PointWBase){
266 PointX = photo.GetWidth() - PointXBase;
267 PointY = PointYBase - 50;
275 PhotoRectPoints.SetX(PointX);
276 PhotoRectPoints.SetY(PointY);
277 PhotoRectPoints.SetWidth(PointW);
278 PhotoRectPoints.SetHeight(PointH);
287 // Resize the picture to 125x125.
289 // Add to the wxMemnoryFSHandler.
291 SIDFilename = SID + wxT("-photo");
293 if (RectData == TRUE){
295 wxImage rectphoto = photo.GetSubImage(PhotoRectPoints);
296 rectphoto = rectphoto.Scale(75, 75, wxIMAGE_QUALITY_HIGH);
297 wxMemoryFSHandler::AddFile(SIDFilename, rectphoto, wxBITMAP_TYPE_PNG);
301 photo = photo.Scale(50, 50, wxIMAGE_QUALITY_HIGH);
302 wxMemoryFSHandler::AddFile(SIDFilename, photo, wxBITMAP_TYPE_PNG);
306 // Add the filename to the MemoryFSList map.
308 MemoryFSList->insert(std::make_pair(SIDFilename, SID));
314 if (LoadPicture == TRUE){
316 PageData.append(wxT("<img src=\"memory:") + SIDFilename + wxT("\">"));
324 ContactData = vCardObj->GetByPartial(wxT("LOGO"));
326 if (ContactData.PropCount > 0){
330 wxStringTokenizer DataSplit(ContactData.PropValues[0], wxT(";"));
331 PhotoSplitData = DataSplit.GetNextToken();
332 wxStringTokenizer MIMESplit(PhotoSplitData, wxT(":"));
333 MIMESplit.GetNextToken();
334 PhotoMIMEType = MIMESplit.GetNextToken();
335 PhotoSplitData = DataSplit.GetNextToken();
336 wxStringTokenizer EncSplit(PhotoSplitData, wxT(","));
337 PhotoEncType = EncSplit.GetNextToken();
338 PhotoEncData = EncSplit.GetNextToken();
340 // Convert the picture data from base64 to binary.
342 PhotoDataIn = std::string(PhotoEncData.mb_str());
343 PhotoDataBin = base64_decode(PhotoDataIn);
344 wxMemoryInputStream istream(PhotoDataBin.c_str(), (size_t)PhotoDataBin.size());
347 if (!photo.LoadFile(istream, wxBITMAP_TYPE_ANY)){
349 // Photo failed to load so do nothing.
357 photo = photo.Scale(50, 50, wxIMAGE_QUALITY_HIGH);
359 // Resize the picture to 125x125.
361 // Add to the wxMemnoryFSHandler.
363 SIDFilename = SID + wxT("-logo");
365 wxMemoryFSHandler::AddFile(SIDFilename, photo, wxBITMAP_TYPE_PNG);
367 // Add the filename to the MemoryFSList map.
369 MemoryFSList->insert(std::make_pair(SIDFilename, SID));
375 if (LoadPicture == TRUE){
377 PageData.append(wxT("<img src=\"memory:") + SIDFilename + wxT("\">"));
381 PageData.append(wxT("</td>"));
382 PageData.append(wxT("</tr>"));
383 PageData.append(wxT("</table>"));
385 // Process LOGO, PHOTO, SOUND, KEY, VND-* and X-*
386 // lines and display icons for each accordingly.
388 ContactData = vCardObj->GetByPartial(wxT("PHOTO"));
390 bool AddBreak = FALSE;
391 wxString TypePageData;
393 if (ContactData.PropCount > 1){
395 TypePageData.append(wxT("<img src=\"memory:cipto.png\" alt=\""));
396 TypePageData.append(_("This contact has multiple photos."));
397 TypePageData.append(wxT("\">"));
402 ContactData = vCardObj->GetByPartial(wxT("LOGO"));
404 if (ContactData.PropCount > 1){
406 TypePageData.append(wxT("<img src=\"memory:cilog.png\" alt=\""));
407 TypePageData.append(_("This contact has multiple logos."));
408 TypePageData.append(wxT("\">"));
413 ContactData = vCardObj->GetByPartial(wxT("SOUND"));
415 if (ContactData.PropCount >= 1){
417 TypePageData.append(wxT("<img src=\"memory:cisnd.png\" alt=\""));
418 TypePageData.append(_("This contact has audio information."));
419 TypePageData.append(wxT("\">"));
424 ContactData = vCardObj->GetByPartial(wxT("KEY"));
426 if (ContactData.PropCount >= 1){
428 TypePageData.append(wxT("<img src=\"memory:cikey.png\" alt=\""));
429 TypePageData.append(_("This contact has crytographic keys."));
430 TypePageData.append(wxT("\">"));
435 ContactData = vCardObj->GetByPartial(wxT("VND-"));
437 if (ContactData.PropCount >= 1){
439 TypePageData.append(wxT("<img src=\"memory:civen.png\" alt=\""));
440 TypePageData.append(_("This contact has vendor-specific information."));
441 TypePageData.append(wxT("\">"));
446 ContactData = vCardObj->GetByPartial(wxT("X-"));
448 if (ContactData.PropCount >= 1){
450 TypePageData.append(wxT("<img src=\"memory:ciext.png\" alt=\""));
451 TypePageData.append(_("This contact has extended information."));
452 TypePageData.append(wxT("\">"));
457 if (!TypePageData.IsEmpty()){
459 PageData.append("<table style=\"{background: #dddddd; width:100%}\"><tr><td>");
460 PageData.append(TypePageData);
461 PageData.append("</tr></td></table>");
465 if (AddBreak == TRUE){
467 PageData.append(wxT("<br><br>"));
471 // TODO: Setup the second table.
475 ContactData = vCardObj->GetByPartial(wxT("BDAY"));
479 wxDateTime DateFormat;
484 if (ContactData.PropCount > 0){
488 for (int i = 0; i < ContactData.PropCount; i++){
490 // Grab the first birthday only.
492 BDayLine = ContactData.PropValues[i];
496 if (BDayLine.Mid(0,4) == wxT("1604")){
498 BDayLine = BDayLine.Mid(4,4);
500 BDayLine.Mid(0,2).ToLong(&MonthValue);
501 BDayLine.Mid(2,2).ToLong(&DayValue);
505 DateFormat.Set((wxDateTime::wxDateTime_t)(int)DayValue, (wxDateTime::Month)(MonthValue), 0, 0, 0, 0, 0);
507 } else if (BDayLine.Mid(0,2) == wxT("--")){
509 BDayLine = BDayLine.Mid(2,4);
511 BDayLine.Mid(0,2).ToLong(&MonthValue);
512 BDayLine.Mid(2,2).ToLong(&DayValue);
516 DateFormat.Set((wxDateTime::wxDateTime_t)(int)DayValue, (wxDateTime::Month)(MonthValue), 0, 0, 0, 0, 0);
521 BDayLine.Mid(0,4).ToLong(&YearValue);
522 BDayLine.Mid(4,2).ToLong(&MonthValue);
523 BDayLine.Mid(6,2).ToLong(&DayValue);
527 DateFormat.Set((wxDateTime::wxDateTime_t)(int)DayValue, (wxDateTime::Month)(MonthValue), YearValue, 0, 0, 0, 0);
533 BDayOutput.append(wxString::Format(wxT("%02i"), (int)DayValue));
534 BDayOutput.append(wxT("/"));
535 BDayOutput.append(wxString::Format(wxT("%02i"), (int)(MonthValue + 1)));
537 if (DateFormat.GetYear() != 0){
539 BDayOutput.append(wxT("/"));
540 BDayOutput.append(wxString::Format(wxT("%04i"), (int)YearValue));
544 CaptureString(&BDayOutput, FALSE);
545 ConvertToHTML(&BDayOutput);
547 DataLines.append(BDayOutput);
557 if (backgroundColour != wxTransparentColour){
558 PageData.append("<table CELLPADDING=4 style=\"{background-color: ");
559 PageData.append(backgroundColour.GetAsString(wxC2S_CSS_SYNTAX));
560 PageData.append("; width: 100%;}\"><tr><td>");
562 PageData.append("<table CELLPADDING=4 style=\"{width: 100%;}\"><tr><td>");
565 if (DataDisplay == TRUE){
568 PageData.append(wxT("<b>"));
569 PageData.append(_("Birthday:"));
570 PageData.append(wxT("</b> "));
571 PageData.append(DataLines);
572 PageData.append(wxT("<br>"));
576 // Process Anniversary
578 ContactData = vCardObj->GetByPartial(wxT("ANNIVERSARY"));
583 if (ContactData.PropCount > 0){
587 for (int i = 0; i < ContactData.PropCount; i++){
589 // Grab the first anniversary only.
591 AnniLine = ContactData.PropValues[i];
594 if (AnniLine.Mid(0,4) == wxT("1604")){
596 AnniLine = AnniLine.Mid(4,4);
598 AnniLine.Mid(0,2).ToLong(&MonthValue);
599 AnniLine.Mid(2,2).ToLong(&DayValue);
603 DateFormat.Set((wxDateTime::wxDateTime_t)(int)DayValue, (wxDateTime::Month)(MonthValue), 0, 0, 0, 0, 0);
605 } else if (AnniLine.Mid(0,2) == wxT("--")){
607 AnniLine = AnniLine.Mid(2,4);
609 AnniLine.Mid(0,2).ToLong(&MonthValue);
610 AnniLine.Mid(2,2).ToLong(&DayValue);
614 DateFormat.Set((wxDateTime::wxDateTime_t)(int)DayValue, (wxDateTime::Month)(MonthValue), 0, 0, 0, 0, 0);
619 AnniLine.Mid(0,4).ToLong(&YearValue);
620 AnniLine.Mid(4,2).ToLong(&MonthValue);
621 AnniLine.Mid(6,2).ToLong(&DayValue);
625 DateFormat.Set((wxDateTime::wxDateTime_t)(int)DayValue, (wxDateTime::Month)(MonthValue), YearValue, 0, 0, 0, 0);
629 wxString AnniDayOutput;
631 AnniDayOutput.append(wxString::Format(wxT("%02i"), (int)DayValue));
632 AnniDayOutput.append(wxT("/"));
633 AnniDayOutput.append(wxString::Format(wxT("%02i"), (int)(MonthValue + 1)));
635 if (DateFormat.GetYear() != 0){
637 AnniDayOutput.append(wxT("/"));
638 AnniDayOutput.append(wxString::Format(wxT("%04i"), (int)YearValue));
642 CaptureString(&AnniDayOutput, FALSE);
643 ConvertToHTML(&AnniDayOutput);
645 DataLines.append(AnniDayOutput);
655 if (DataDisplay == TRUE){
658 PageData.append(wxT("<b>"));
659 PageData.append(_("Anniversary:"));
660 PageData.append(wxT("</b> "));
661 PageData.append(DataLines);
662 PageData.append(wxT("<br>"));
668 ContactData = vCardObj->GetByPartial(wxT("NICKNAME"));
673 if (ContactData.PropCount > 0){
675 wxString NicknameLine;
677 for (int i = 0; i < ContactData.PropCount; i++){
679 NicknameLine = ContactData.PropValues[i];
682 CaptureString(&NicknameLine, FALSE);
683 ConvertToHTML(&NicknameLine);
685 DataLines.append(wxT("<tr><td><b>"));
686 DataLines.append(_("Nickname:"));
687 DataLines.append(wxT(" </b></td><td>"));
688 DataLines.append(NicknameLine);
689 DataLines.append(wxT("</td></tr>"));
697 if (DataDisplay == TRUE){
700 PageData.append(wxT("<h4>"));
701 PageData.append(_("Nicknames"));
702 PageData.append(wxT("</h4>"));
703 PageData.append(wxT("<br>"));
704 PageData.append(wxT("<table>"));
705 PageData.append(DataLines);
706 PageData.append(wxT("</table>"));
712 ContactData = vCardObj->GetByPartial(wxT("ADR"));
717 if (ContactData.PropCount > 0){
719 wxString AddressLine;
721 for (int i = 0; i < ContactData.PropCount; i++){
723 AddressLine = ContactData.PropValues[i];
725 intPropertyLen = AddressLine.Len();
732 AddressPOBox.clear();
733 AddressStreet.clear();
734 AddressLocality.clear();
735 AddressRegion.clear();
736 AddressPostalCode.clear();
737 AddressCountry.clear();
738 AddressExtended.clear();
739 FinalAddressLine.clear();
742 for (int i = 0; i <= intPropertyLen; i++){
746 if (AddressLine.Mid(i, 1) == wxT(";") && AddressLine.Mid((i - 1), 1) != wxT("\\")){
749 SplitPoints.insert(std::make_pair(intSplitsFound, (i + 1)));
751 if (intSplitsFound == 6){
753 SplitLength.insert(std::make_pair(intSplitsFound, (intSplitSize - 1)));
758 SplitLength.insert(std::make_pair(intSplitsFound, (intSplitSize - 1)));
768 // Split the data into several parts.
770 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
771 intiter != SplitPoints.end(); ++intiter){
773 if (intiter->first == 1){
777 SLiter = SplitLength.find(1);
779 AddressPOBox = AddressLine.Mid(0, SLiter->second);
780 intPrevValue = intiter->second;
782 } else if (intiter->first == 2){
784 // Deal with extended address.
786 SLiter = SplitLength.find(2);
788 AddressExtended = AddressLine.Mid(intPrevValue, SLiter->second);
789 intPrevValue = intiter->second;
791 } else if (intiter->first == 3){
793 // Deal with street address.
795 SLiter = SplitLength.find(3);
797 AddressStreet = AddressLine.Mid(intPrevValue, SLiter->second);
798 intPrevValue = intiter->second;
800 } else if (intiter->first == 4){
802 // Deal with locality
804 SLiter = SplitLength.find(4);
806 AddressLocality = AddressLine.Mid(intPrevValue, SLiter->second);
807 intPrevValue = intiter->second;
809 } else if (intiter->first == 5){
813 SLiter = SplitLength.find(5);
815 AddressRegion = AddressLine.Mid(intPrevValue, SLiter->second);
816 intPrevValue = intiter->second;
818 } else if (intiter->first == 6){
820 // Deal with post code.
822 SLiter = SplitLength.find(6);
824 AddressPostalCode = AddressLine.Mid(intPrevValue, SLiter->second);
825 intPrevValue = intiter->second;
827 // Deal with country.
829 AddressCountry = AddressLine.Mid(intPrevValue);
835 if (!AddressStreet.IsEmpty()){
837 AddressStreet.Trim();
838 ConvertToHTML(&AddressStreet);
840 FinalAddressLine.append(AddressStreet);
841 AddressFirst = FALSE;
845 if (!AddressLocality.IsEmpty()){
847 AddressLocality.Trim();
848 ConvertToHTML(&AddressLocality);
850 if (AddressFirst == FALSE){
852 FinalAddressLine.append(wxT(",<br>"));
853 FinalAddressLine.append(AddressLocality);
857 FinalAddressLine.append(AddressLocality);
858 AddressFirst = FALSE;
864 if (!AddressRegion.IsEmpty()){
866 AddressRegion.Trim();
867 ConvertToHTML(&AddressRegion);
869 if (AddressFirst == FALSE){
871 FinalAddressLine.append(wxT(",<br>"));
872 FinalAddressLine.append(AddressRegion);
876 FinalAddressLine.append(AddressRegion);
877 AddressFirst = FALSE;
883 if (!AddressPostalCode.IsEmpty()){
885 AddressPostalCode.Trim();
886 ConvertToHTML(&AddressPostalCode);
888 if (AddressFirst == FALSE){
890 FinalAddressLine.append(wxT(",<br>"));
891 FinalAddressLine.append(AddressPostalCode);
895 FinalAddressLine.append(AddressPostalCode);
896 AddressFirst = FALSE;
902 if (!AddressCountry.IsEmpty()){
904 AddressCountry.Trim();
905 ConvertToHTML(&AddressCountry);
907 if (AddressFirst == FALSE){
909 FinalAddressLine.append(wxT(",<br>"));
910 FinalAddressLine.append(AddressCountry);
914 FinalAddressLine.append(AddressCountry);
915 AddressFirst = FALSE;
921 CaptureString(&FinalAddressLine, FALSE);
923 DataLines.append(wxT("<tr><td><b>"));
924 DataLines.append(_("Address:"));
925 DataLines.append(wxT(" </b></td><td>"));
926 DataLines.append(FinalAddressLine);
927 DataLines.append(wxT("</td></tr>"));
935 if (DataDisplay == TRUE){
938 PageData.append(wxT("<h4>"));
939 PageData.append(_("Addresses"));
940 PageData.append(wxT("</h4>"));
941 PageData.append(wxT("<br>"));
942 PageData.append(wxT("<table>"));
943 PageData.append(DataLines);
944 PageData.append(wxT("</table>"));
950 ContactData = vCardObj->GetByPartial(wxT("EMAIL"));
955 if (ContactData.PropCount > 0){
959 for (int i = 0; i < ContactData.PropCount; i++){
961 EmailLine = ContactData.PropValues[i];
964 CaptureString(&EmailLine, FALSE);
965 ConvertToHTML(&EmailLine);
967 DataLines.append(wxT("<tr><td><b>"));
968 DataLines.append(_("E-mail Address:"));
969 DataLines.append(wxT(" </b></td><td>"));
970 DataLines.append(EmailLine);
971 DataLines.append(wxT("</td></tr>"));
979 if (DataDisplay == TRUE){
982 PageData.append(wxT("<h4>"));
983 PageData.append(_("Email Addresses"));
984 PageData.append(wxT("</h4>"));
985 PageData.append(wxT("<br>"));
986 PageData.append(wxT("<table>"));
987 PageData.append(DataLines);
988 PageData.append(wxT("</table>"));
994 ContactData = vCardObj->GetByPartial(wxT("TEL"));
999 if (ContactData.PropCount > 0){
1003 for (int i = 0; i < ContactData.PropCount; i++){
1005 TelLine = ContactData.PropValues[i];
1007 wxStringTokenizer TelSplit(TelLine, wxT(":"));
1009 TelLine = TelSplit.GetNextToken();
1011 if (TelSplit.HasMoreTokens()){
1013 TelLine = TelSplit.GetNextToken();
1018 CaptureString(&TelLine, FALSE);
1019 ConvertToHTML(&TelLine);
1021 DataLines.append(wxT("<tr><td><b>"));
1022 DataLines.append(_("Telephone:"));
1023 DataLines.append(wxT(" </b></td><td>"));
1024 DataLines.append(TelLine);
1025 DataLines.append(wxT("</td></tr>"));
1033 if (DataDisplay == TRUE){
1036 PageData.append(wxT("<h4>"));
1037 PageData.append(_("Telephones"));
1038 PageData.append(wxT("</h4>"));
1039 PageData.append(wxT("<br>"));
1040 PageData.append(wxT("<table>"));
1041 PageData.append(DataLines);
1042 PageData.append(wxT("</table>"));
1046 // Instant Messaging
1048 ContactData = vCardObj->GetByPartial(wxT("IMPP"));
1050 DataDisplay = FALSE;
1053 if (ContactData.PropCount > 0){
1056 wxString IMTypeFriendly;
1059 for (int i = 0; i < ContactData.PropCount; i++){
1061 IMLine = ContactData.PropValues[i];
1063 wxStringTokenizer IMSplit(IMLine, wxT(":"));
1065 IMType = IMSplit.GetNextToken();
1066 IMLine = IMSplit.GetNextToken();
1068 // Process skype, gg, icq, yahoo etc into
1069 // something meaningful.
1071 if (IMType == wxT("aim")){
1075 IMTypeFriendly = _("AIM");
1077 } else if (IMType == wxT("xmpp")){
1081 IMTypeFriendly = _("XMPP");
1083 } else if (IMType == wxT("icq")){
1087 IMTypeFriendly = _("ICQ");
1089 } else if (IMType == wxT("skype")){
1093 IMTypeFriendly = _("Skype");
1095 } else if (IMType == wxT("gg")){
1099 IMTypeFriendly = _("Gadu-Gadu");
1101 } else if (IMType == wxT("yahoo")){
1105 IMTypeFriendly = _("Yahoo");
1109 // Other. Use IM type that was split.
1111 IMTypeFriendly = IMType;
1116 CaptureString(&IMLine, FALSE);
1117 ConvertToHTML(&IMLine);
1119 DataLines.append(wxT("<tr><td><b>"));
1120 DataLines.append(_("IM Address"));
1121 DataLines.append(_(" ("));
1122 DataLines.append(IMTypeFriendly);
1123 DataLines.append(_("):"));
1124 DataLines.append(wxT(" </b></td><td>"));
1125 DataLines.append(IMLine);
1126 DataLines.append(wxT("</td></tr>"));
1128 IMTypeFriendly.clear();
1138 if (DataDisplay == TRUE){
1141 PageData.append(wxT("<h4>"));
1142 PageData.append(_("Instant Messaging Addresses"));
1143 PageData.append(wxT("</h4>"));
1144 PageData.append(wxT("<br>"));
1145 PageData.append(wxT("<table>"));
1146 PageData.append(DataLines);
1147 PageData.append(wxT("</table>"));
1153 ContactData = vCardObj->GetByPartial(wxT("URL"));
1155 DataDisplay = FALSE;
1158 if (ContactData.PropCount > 0){
1162 for (int i = 0; i < ContactData.PropCount; i++){
1164 URLLine = ContactData.PropValues[i];
1167 CaptureString(&URLLine, FALSE);
1168 ConvertToHTML(&URLLine);
1170 DataLines.append(wxT("<tr><td><b>"));
1171 DataLines.append(_("Website:"));
1172 DataLines.append(wxT(" </b></td><td>"));
1173 DataLines.append(URLLine);
1174 DataLines.append(wxT("</td></tr>"));
1182 if (DataDisplay == TRUE){
1185 PageData.append(wxT("<h4>"));
1186 PageData.append(_("Website Addresses"));
1187 PageData.append(wxT("</h4>"));
1188 PageData.append(wxT("<br>"));
1189 PageData.append(wxT("<table>"));
1190 PageData.append(DataLines);
1191 PageData.append(wxT("</table>"));
1197 ContactData = vCardObj->GetByPartial(wxT("LANG"));
1199 DataDisplay = FALSE;
1202 if (ContactData.PropCount > 0){
1204 wxString NicknameLine;
1206 for (int i = 0; i < ContactData.PropCount; i++){
1208 NicknameLine = ContactData.PropValues[i];
1210 NicknameLine.Trim();
1211 CaptureString(&NicknameLine, FALSE);
1212 ConvertToHTML(&NicknameLine);
1214 DataLines.append(wxT("<tr><td><b>"));
1215 DataLines.append(_("Language:"));
1216 DataLines.append(wxT(" </b></td><td>"));
1217 DataLines.append(NicknameLine);
1218 DataLines.append(wxT("</td></tr>"));
1226 if (DataDisplay == TRUE){
1229 PageData.append(wxT("<h4>"));
1230 PageData.append(_("Languages"));
1231 PageData.append(wxT("</h4>"));
1232 PageData.append(wxT("<br>"));
1233 PageData.append(wxT("<table>"));
1234 PageData.append(DataLines);
1235 PageData.append(wxT("</table>"));
1241 ContactData = vCardObj->GetByPartial(wxT("TZ"));
1243 DataDisplay = FALSE;
1246 if (ContactData.PropCount > 0){
1248 wxString NicknameLine;
1250 for (int i = 0; i < ContactData.PropCount; i++){
1252 NicknameLine = ContactData.PropValues[i];
1254 NicknameLine.Trim();
1255 CaptureString(&NicknameLine, FALSE);
1256 ConvertToHTML(&NicknameLine);
1258 DataLines.append(wxT("<tr><td><b>"));
1259 DataLines.append(_("Timezone:"));
1260 DataLines.append(wxT(" </b></td><td>"));
1261 DataLines.append(NicknameLine);
1262 DataLines.append(wxT("</td></tr>"));
1270 if (DataDisplay == TRUE){
1273 PageData.append(wxT("<h4>"));
1274 PageData.append(_("Timezones"));
1275 PageData.append(wxT("</h4>"));
1276 PageData.append(wxT("<br>"));
1277 PageData.append(wxT("<table>"));
1278 PageData.append(DataLines);
1279 PageData.append(wxT("</table>"));
1285 ContactData = vCardObj->GetByPartial(wxT("GEO"));
1287 DataDisplay = FALSE;
1290 if (ContactData.PropCount > 0){
1294 for (int i = 0; i < ContactData.PropCount; i++){
1296 GeoLine = ContactData.PropValues[i];
1298 wxStringTokenizer GeoSplit(GeoLine, wxT(":"));
1300 GeoLine = GeoSplit.GetNextToken();
1302 if (GeoSplit.HasMoreTokens()){
1304 GeoLine = GeoSplit.GetNextToken();
1309 CaptureString(&GeoLine, FALSE);
1310 ConvertToHTML(&GeoLine);
1312 DataLines.append(wxT("<tr><td><b>"));
1313 DataLines.append(_("Geoposition:"));
1314 DataLines.append(wxT(" </b></td><td>"));
1315 DataLines.append(GeoLine);
1316 DataLines.append(wxT("</td></tr>"));
1324 if (DataDisplay == TRUE){
1327 PageData.append(wxT("<h4>"));
1328 PageData.append(_("Geopositioning"));
1329 PageData.append(wxT("</h4>"));
1330 PageData.append(wxT("<br>"));
1331 PageData.append(wxT("<table>"));
1332 PageData.append(DataLines);
1333 PageData.append(wxT("</table>"));
1339 ContactData = vCardObj->GetByPartial(wxT("TITLE"));
1341 DataDisplay = FALSE;
1344 if (ContactData.PropCount > 0){
1348 for (int i = 0; i < ContactData.PropCount; i++){
1350 TitleLine = ContactData.PropValues[i];
1353 CaptureString(&TitleLine, FALSE);
1354 ConvertToHTML(&TitleLine);
1356 DataLines.append(wxT("<tr><td><b>"));
1357 DataLines.append(_("Title:"));
1358 DataLines.append(wxT(" </b></td><td>"));
1359 DataLines.append(TitleLine);
1360 DataLines.append(wxT("</td></tr>"));
1368 if (DataDisplay == TRUE){
1371 PageData.append(wxT("<h4>"));
1372 PageData.append(_("Titles"));
1373 PageData.append(wxT("</h4>"));
1374 PageData.append(wxT("<br>"));
1375 PageData.append(wxT("<table>"));
1376 PageData.append(DataLines);
1377 PageData.append(wxT("</table>"));
1383 ContactData = vCardObj->GetByPartial(wxT("ROLE"));
1385 DataDisplay = FALSE;
1388 if (ContactData.PropCount > 0){
1392 for (int i = 0; i < ContactData.PropCount; i++){
1394 RoleLine = ContactData.PropValues[i];
1397 CaptureString(&RoleLine, FALSE);
1398 ConvertToHTML(&RoleLine);
1400 DataLines.append(wxT("<tr><td><b>"));
1401 DataLines.append(_("Role:"));
1402 DataLines.append(wxT(" </b></td><td>"));
1403 DataLines.append(RoleLine);
1404 DataLines.append(wxT("</td></tr>"));
1412 if (DataDisplay == TRUE){
1415 PageData.append(wxT("<h4>"));
1416 PageData.append(_("Roles"));
1417 PageData.append(wxT("</h4>"));
1418 PageData.append(wxT("<br>"));
1419 PageData.append(wxT("<table>"));
1420 PageData.append(DataLines);
1421 PageData.append(wxT("</table>"));
1427 ContactData = vCardObj->GetByPartial(wxT("ORG"));
1429 DataDisplay = FALSE;
1432 if (ContactData.PropCount > 0){
1436 for (int i = 0; i < ContactData.PropCount; i++){
1438 OrgLine = ContactData.PropValues[i];
1441 CaptureString(&OrgLine, FALSE);
1442 ConvertToHTML(&OrgLine);
1444 DataLines.append(wxT("<tr><td><b>"));
1445 DataLines.append(_("Organisation:"));
1446 DataLines.append(wxT(" </b></td><td>"));
1447 DataLines.append(OrgLine);
1448 DataLines.append(wxT("</td></tr>"));
1456 if (DataDisplay == TRUE){
1459 PageData.append(wxT("<h4>"));
1460 PageData.append(_("Organisations"));
1461 PageData.append(wxT("</h4>"));
1462 PageData.append(wxT("<br>"));
1463 PageData.append(wxT("<table>"));
1464 PageData.append(DataLines);
1465 PageData.append(wxT("</table>"));
1471 ContactData = vCardObj->GetByPartial(wxT("CATEGORIES"));
1473 DataDisplay = FALSE;
1476 if (ContactData.PropCount > 0){
1480 for (int i = 0; i < ContactData.PropCount; i++){
1482 CatLine = ContactData.PropValues[i];
1485 CaptureString(&CatLine, FALSE);
1486 ConvertToHTML(&CatLine);
1488 DataLines.append(wxT("<tr><td><b>"));
1489 DataLines.append(_("Category:"));
1490 DataLines.append(wxT(" </b></td><td>"));
1491 DataLines.append(CatLine);
1492 DataLines.append(wxT("</td></tr>"));
1500 if (DataDisplay == TRUE){
1503 PageData.append(wxT("<h4>"));
1504 PageData.append(_("Categories"));
1505 PageData.append(wxT("</h4>"));
1506 PageData.append(wxT("<br>"));
1507 PageData.append(wxT("<table>"));
1508 PageData.append(DataLines);
1509 PageData.append(wxT("</table>"));
1517 // Calendar Addresses
1519 ContactData = vCardObj->GetByPartial(wxT("CALURI"));
1521 DataDisplay = FALSE;
1524 if (ContactData.PropCount > 0){
1526 wxString CalURILine;
1528 for (int i = 0; i < ContactData.PropCount; i++){
1530 CalURILine = ContactData.PropValues[i];
1533 CaptureString(&CalURILine, FALSE);
1534 ConvertToHTML(&CalURILine);
1536 DataLines.append(wxT("<tr><td><b>"));
1537 DataLines.append(_("Calendar Address:"));
1538 DataLines.append(wxT(" </b></td><td>"));
1539 DataLines.append(CalURILine);
1540 DataLines.append(wxT("</td></tr>"));
1548 if (DataDisplay == TRUE){
1551 PageData.append(wxT("<h4>"));
1552 PageData.append(_("Calendar Addresses"));
1553 PageData.append(wxT("</h4>"));
1554 PageData.append(wxT("<br>"));
1555 PageData.append(wxT("<table>"));
1556 PageData.append(DataLines);
1557 PageData.append(wxT("</table>"));
1561 // Calendar Request Addresses
1563 ContactData = vCardObj->GetByPartial(wxT("CALADRURI"));
1565 DataDisplay = FALSE;
1568 if (ContactData.PropCount > 0){
1570 wxString CalAdrURILine;
1572 for (int i = 0; i < ContactData.PropCount; i++){
1574 CalAdrURILine = ContactData.PropValues[i];
1576 CalAdrURILine.Trim();
1577 CaptureString(&CalAdrURILine, FALSE);
1578 ConvertToHTML(&CalAdrURILine);
1580 DataLines.append(wxT("<tr><td><b>"));
1581 DataLines.append(_("Calendar Request Address:"));
1582 DataLines.append(wxT(" </b></td><td>"));
1583 DataLines.append(CalAdrURILine);
1584 DataLines.append(wxT("</td></tr>"));
1592 if (DataDisplay == TRUE){
1595 PageData.append(wxT("<h4>"));
1596 PageData.append(_("Calendar Request Addresses"));
1597 PageData.append(wxT("</h4>"));
1598 PageData.append(wxT("<br>"));
1599 PageData.append(wxT("<table>"));
1600 PageData.append(DataLines);
1601 PageData.append(wxT("</table>"));
1605 // Free/Busy Addresses
1607 ContactData = vCardObj->GetByPartial(wxT("FBURL"));
1609 DataDisplay = FALSE;
1612 if (ContactData.PropCount > 0){
1616 for (int i = 0; i < ContactData.PropCount; i++){
1618 FBURLLine = ContactData.PropValues[i];
1621 CaptureString(&FBURLLine, FALSE);
1622 ConvertToHTML(&FBURLLine);
1624 DataLines.append(wxT("<tr><td><b>"));
1625 DataLines.append(_("Free/Busy Address:"));
1626 DataLines.append(wxT(" </b></td><td>"));
1627 DataLines.append(FBURLLine);
1628 DataLines.append(wxT("</td></tr>"));
1636 if (DataDisplay == TRUE){
1639 PageData.append(wxT("<h4>"));
1640 PageData.append(_("Free/Busy Addresses"));
1641 PageData.append(wxT("</h4>"));
1642 PageData.append(wxT("<br>"));
1643 PageData.append(wxT("<table>"));
1644 PageData.append(DataLines);
1645 PageData.append(wxT("</table>"));
1651 ContactData = vCardObj->GetByPartial(wxT("NOTE"));
1653 DataDisplay = FALSE;
1656 if (ContactData.PropCount > 0){
1660 for (int i = 0; i < ContactData.PropCount; i++){
1662 NoteLine = ContactData.PropValues[i];
1665 CaptureString(&NoteLine, FALSE);
1666 ConvertToHTML(&NoteLine);
1668 DataLines.append(wxT("<tr><td><b>"));
1669 DataLines.append(_("Note:"));
1670 DataLines.append(wxT(" </b></td><td>"));
1671 DataLines.append(NoteLine);
1672 DataLines.append(wxT("</td></tr>"));
1680 if (DataDisplay == TRUE){
1682 PageData.append(wxT("<h4>"));
1683 PageData.append(_("Notes"));
1684 PageData.append(wxT("</h4>"));
1685 PageData.append(wxT("<br>"));
1686 PageData.append(wxT("<table>"));
1687 PageData.append(DataLines);
1688 PageData.append(wxT("</table>"));
1692 // Display the HTML document on the screen.
1694 PageData.append("</td></tr></table>");
1696 PageData.append(wxT("</body>"));
1697 PageData.append(wxT("</html>"));
1699 HTMLObj->SetPage(PageData);
1703 void SplitPropertyData(wxString *PropertyLine,
1704 std::map<int,int> *SplitPoints,
1705 std::map<int,int> *SplitLength,
1707 std::map<wxString,wxString> *SplitData){
1709 // Split the property data into SplitData.
1712 wxStringTokenizer PropertyElement;
1713 wxString PropertyName;
1714 wxString PropertyValue;
1715 int intPropertyLen = PropertyLine->Len();
1716 int intSplitsFound = 0;
1717 int intSplitSize = 0;
1718 int intSplitSeek = (intSize - 1);
1720 for (int i = intSize; i <= intPropertyLen; i++){
1724 if (PropertyLine->Mid(i, 1) == wxT(";") &&
1725 PropertyLine->Mid((i - 1), 1) != wxT("\\")){
1727 if (intSplitsFound == 0){
1729 DataStr = PropertyLine->Mid(intSplitSeek, (intSplitSize));
1730 SplitLength->insert(std::make_pair(intSplitsFound, (intSplitSize)));
1734 DataStr = PropertyLine->Mid(intSplitSeek, (intSplitSize - 1));
1735 SplitLength->insert(std::make_pair(intSplitsFound, (intSplitSize - 1)));
1739 SplitPoints->insert(std::make_pair(intSplitsFound, (i + 1)));
1742 intSplitSeek = (i + 1);
1745 if (!DataStr.IsEmpty()){
1747 PropertyElement.SetString(DataStr, wxT("="));
1748 PropertyName = PropertyElement.GetNextToken();
1749 PropertyValue = PropertyElement.GetNextToken();
1750 SplitData->insert(std::make_pair(PropertyName, PropertyValue));
1755 PropertyName.clear();
1756 PropertyValue.clear();
1762 if (intSplitsFound == 0){
1764 DataStr = PropertyLine->Mid(intSplitSeek, (intSplitSize));
1766 SplitPoints->insert(std::make_pair(intSplitsFound, (8 + 1)));
1767 SplitLength->insert(std::make_pair(intSplitsFound, intSplitSize));
1771 DataStr = PropertyLine->Mid(intSplitSeek, (intSplitSize - 1));
1773 SplitPoints->insert(std::make_pair(intSplitsFound, (intSplitSeek + 1)));
1774 SplitLength->insert(std::make_pair(intSplitsFound, intSplitSize));
1778 if (!DataStr.IsEmpty()){
1780 PropertyElement.SetString(DataStr, wxT("="));
1781 PropertyName = PropertyElement.GetNextToken();
1782 PropertyValue = PropertyElement.GetNextToken();
1783 SplitData->insert(std::make_pair(PropertyName, PropertyValue));