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){
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);
45 wxFileSystem::AddHandler(new wxMemoryFSHandler);
47 PageData.append(wxT("<html>"));
48 PageData.append(wxT("<head>"));
49 PageData.append(wxT("<title>Page Loading</title>"));
50 PageData.append(wxT("</head>"));
51 PageData.append(wxT("<body>"));
52 PageData.append(wxT("<h2>"));
53 PageData.append(_("Loading contact information..."));
54 PageData.append(wxT("</h2>"));
55 PageData.append(wxT("</body>"));
56 PageData.append(wxT("</html>"));
58 HTMLObj->SetPage(PageData);
62 // Delete the information from the old session.
64 if (!OldSID.IsEmpty()){
66 if (MemoryFSList->find(OldSID) == MemoryFSList->end()){
71 std::map<wxString, wxString>::iterator striter;
73 for (striter = MemoryFSList->begin(); striter != MemoryFSList->end(); striter++){
75 if (OldSID == striter->second){
77 // Delete the references from the wxMemoryFSHandler
78 // and the entry from the map.
80 wxMemoryFSHandler::RemoveFile(striter->first);
87 MemoryFSList->erase(striter);
93 // MAke sure new session ID doesn't conflict with existing
94 // data. If there is a match, generate a new one and check again.
98 for (std::map<wxString, wxString>::iterator striter = MemoryFSList->begin();
99 striter != MemoryFSList->end(); striter++){
101 SIDTemp = striter->second;
105 // Generate a new random number.
107 SID = wxString::Format(wxT("%i"), rand() % 32768);
109 // Rewind the seek process back to the start.
111 striter = MemoryFSList->begin();
119 // Setup the HTML document.
121 PageData.append(wxT("<html>"));
122 PageData.append(wxT("<head>"));
123 PageData.append(wxT("<title>Contact Information</title>"));
124 PageData.append(wxT("</head>"));
126 // Process the CSS section.
128 PageData.append(wxT("<body>"));
130 // Process the data in the vCard object.
134 ArrayvCardOutData FNList;
135 FNList = vCardObj->GetByPartial(wxT("FN"));
137 PageData.append(wxT("<table style=\"background: #cccccc; width: 100%\">"));
138 PageData.append(wxT("<tr>"));
139 PageData.append(wxT("<td style=\"width:100%\">"));
140 PageData.append(wxT("<h2>"));
142 if (FNList.PropCount > 0){
143 FNList.PropValues[0].Trim();
144 CaptureString(&FNList.PropValues[0], false);
145 PageData.append(FNList.PropValues[0]);
148 PageData.append(wxT("</h2>"));
149 PageData.append(wxT("</td>"));
150 PageData.append(wxT("<td style=\"width: 200px;\">"));
152 // Define common variables for ADR.
154 std::map<int,int> SplitPoints;
155 std::map<int,int> SplitLength;
156 std::map<int,int>::iterator SLiter;
163 wxString AddressPOBox;
164 wxString AddressStreet;
165 wxString AddressLocality;
166 wxString AddressRegion;
167 wxString AddressPostalCode;
168 wxString AddressCountry;
169 wxString AddressExtended;
171 wxString FinalAddressLine;
172 bool AddressFirst = TRUE;
174 // Define common variables for PHOTO and LOGO.
176 std::string PhotoDataBin;
177 std::string PhotoDataIn;
178 wxString PhotoSplitData;
179 wxString PhotoMIMEType;
180 wxString PhotoEncType;
181 wxString PhotoEncData;
182 bool LoadPicture = FALSE;
183 bool DataDisplay = FALSE;
184 bool RectData = FALSE;
185 wxRect PhotoRectPoints;
186 wxString SIDFilename;
192 ArrayvCardOutData ContactData = vCardObj->GetByPartial(wxT("PHOTO"));
194 if (ContactData.PropCount > 0){
196 // Look for the X-ABCROP-RECTANGLE.
198 wxStringTokenizer PhotoSplit(ContactData.PropData[0], wxT(":"));
199 wxString PhotoPropertyDataString = PhotoSplit.GetNextToken();
200 wxStringTokenizer PhotoPropertyData(PhotoPropertyDataString, wxT(";"));
201 wxString PropertyLineData;
202 wxString PropertyName;
203 wxString PropertyValue;
205 wxStringTokenizer DataSplit(ContactData.PropValues[0], wxT(";"));
206 PhotoSplitData = DataSplit.GetNextToken();
207 wxStringTokenizer MIMESplit(PhotoSplitData, wxT(":"));
208 MIMESplit.GetNextToken();
209 PhotoMIMEType = MIMESplit.GetNextToken();
210 PhotoSplitData = DataSplit.GetNextToken();
211 wxStringTokenizer EncSplit(PhotoSplitData, wxT(","));
212 PhotoEncType = EncSplit.GetNextToken();
213 PhotoEncData = EncSplit.GetNextToken();
215 // Convert the picture data from base64 to binary.
217 PhotoDataIn = std::string(PhotoEncData.mb_str());
218 PhotoDataBin = base64_decode(PhotoDataIn);
219 wxMemoryInputStream istream(PhotoDataBin.c_str(), (size_t)PhotoDataBin.size());
222 if (!photo.LoadFile(istream, wxBITMAP_TYPE_ANY)){
224 // Photo failed to load so do nothing.
230 while (PhotoPropertyData.HasMoreTokens()){
232 PropertyLineData = PhotoPropertyData.GetNextToken();
234 wxStringTokenizer PhotoPropPair(PropertyLineData, wxT("="));
235 wxString PhotoPropName = PhotoPropPair.GetNextToken();
236 wxString PhotoPropValue = PhotoPropPair.GetNextToken();
238 if (PhotoPropName == wxT("X-ABCROP-RECTANGLE")){
240 wxStringTokenizer PhotoRectData(PhotoPropValue, wxT("&"));
242 PhotoRectData.GetNextToken();
244 int PointXBase = wxAtoi(PhotoRectData.GetNextToken());
245 int PointYBase = wxAtoi(PhotoRectData.GetNextToken());
246 int PointWBase = wxAtoi(PhotoRectData.GetNextToken());
247 int PointHBase = wxAtoi(PhotoRectData.GetNextToken());
249 int PointX = PointXBase;
250 int PointY = PointYBase;
251 int PointW = PointWBase;
252 int PointH = PointHBase;
256 if (PointYBase > PointHBase){
258 PointX = photo.GetWidth() - PointXBase - 140;
259 PointY = photo.GetHeight() - PointYBase - 140;
263 } else if (PointXBase > PointWBase){
265 PointX = photo.GetWidth() - PointXBase;
266 PointY = PointYBase - 50;
274 PhotoRectPoints.SetX(PointX);
275 PhotoRectPoints.SetY(PointY);
276 PhotoRectPoints.SetWidth(PointW);
277 PhotoRectPoints.SetHeight(PointH);
286 // Resize the picture to 125x125.
288 // Add to the wxMemnoryFSHandler.
290 SIDFilename = SID + wxT("-photo");
292 if (RectData == TRUE){
294 wxImage rectphoto = photo.GetSubImage(PhotoRectPoints);
295 rectphoto = rectphoto.Scale(75, 75, wxIMAGE_QUALITY_HIGH);
296 wxMemoryFSHandler::AddFile(SIDFilename, rectphoto, wxBITMAP_TYPE_PNG);
300 photo = photo.Scale(50, 50, wxIMAGE_QUALITY_HIGH);
301 wxMemoryFSHandler::AddFile(SIDFilename, photo, wxBITMAP_TYPE_PNG);
305 // Add the filename to the MemoryFSList map.
307 MemoryFSList->insert(std::make_pair(SIDFilename, SID));
313 if (LoadPicture == TRUE){
315 PageData.append(wxT("<img src=\"memory:") + SIDFilename + wxT("\">"));
323 ContactData = vCardObj->GetByPartial(wxT("LOGO"));
325 if (ContactData.PropCount > 0){
329 wxStringTokenizer DataSplit(ContactData.PropValues[0], wxT(";"));
330 PhotoSplitData = DataSplit.GetNextToken();
331 wxStringTokenizer MIMESplit(PhotoSplitData, wxT(":"));
332 MIMESplit.GetNextToken();
333 PhotoMIMEType = MIMESplit.GetNextToken();
334 PhotoSplitData = DataSplit.GetNextToken();
335 wxStringTokenizer EncSplit(PhotoSplitData, wxT(","));
336 PhotoEncType = EncSplit.GetNextToken();
337 PhotoEncData = EncSplit.GetNextToken();
339 // Convert the picture data from base64 to binary.
341 PhotoDataIn = std::string(PhotoEncData.mb_str());
342 PhotoDataBin = base64_decode(PhotoDataIn);
343 wxMemoryInputStream istream(PhotoDataBin.c_str(), (size_t)PhotoDataBin.size());
346 if (!photo.LoadFile(istream, wxBITMAP_TYPE_ANY)){
348 // Photo failed to load so do nothing.
356 photo = photo.Scale(50, 50, wxIMAGE_QUALITY_HIGH);
358 // Resize the picture to 125x125.
360 // Add to the wxMemnoryFSHandler.
362 SIDFilename = SID + wxT("-logo");
364 wxMemoryFSHandler::AddFile(SIDFilename, photo, wxBITMAP_TYPE_PNG);
366 // Add the filename to the MemoryFSList map.
368 MemoryFSList->insert(std::make_pair(SIDFilename, SID));
374 if (LoadPicture == TRUE){
376 PageData.append(wxT("<img src=\"memory:") + SIDFilename + wxT("\">"));
380 PageData.append(wxT("</td>"));
381 PageData.append(wxT("</tr>"));
382 PageData.append(wxT("</table>"));
384 // Process LOGO, PHOTO, SOUND, KEY, VND-* and X-*
385 // lines and display icons for each accordingly.
387 ContactData = vCardObj->GetByPartial(wxT("PHOTO"));
389 bool AddBreak = FALSE;
390 wxString TypePageData;
392 if (ContactData.PropCount > 1){
394 TypePageData.append(wxT("<img src=\"memory:cipto.png\" alt=\""));
395 TypePageData.append(_("This contact has multiple photos."));
396 TypePageData.append(wxT("\">"));
401 ContactData = vCardObj->GetByPartial(wxT("LOGO"));
403 if (ContactData.PropCount > 1){
405 TypePageData.append(wxT("<img src=\"memory:cilog.png\" alt=\""));
406 TypePageData.append(_("This contact has multiple logos."));
407 TypePageData.append(wxT("\">"));
412 ContactData = vCardObj->GetByPartial(wxT("SOUND"));
414 if (ContactData.PropCount >= 1){
416 TypePageData.append(wxT("<img src=\"memory:cisnd.png\" alt=\""));
417 TypePageData.append(_("This contact has audio information."));
418 TypePageData.append(wxT("\">"));
423 ContactData = vCardObj->GetByPartial(wxT("KEY"));
425 if (ContactData.PropCount >= 1){
427 TypePageData.append(wxT("<img src=\"memory:cikey.png\" alt=\""));
428 TypePageData.append(_("This contact has crytographic keys."));
429 TypePageData.append(wxT("\">"));
434 ContactData = vCardObj->GetByPartial(wxT("VND-"));
436 if (ContactData.PropCount >= 1){
438 TypePageData.append(wxT("<img src=\"memory:civen.png\" alt=\""));
439 TypePageData.append(_("This contact has vendor-specific information."));
440 TypePageData.append(wxT("\">"));
445 ContactData = vCardObj->GetByPartial(wxT("X-"));
447 if (ContactData.PropCount >= 1){
449 TypePageData.append(wxT("<img src=\"memory:ciext.png\" alt=\""));
450 TypePageData.append(_("This contact has extended information."));
451 TypePageData.append(wxT("\">"));
456 if (!TypePageData.IsEmpty()){
458 PageData.append("<table style=\"{background: #dddddd; width:100%}\"><tr><td>");
459 PageData.append(TypePageData);
460 PageData.append("</tr></td></table>");
464 if (AddBreak == TRUE){
466 PageData.append(wxT("<br><br>"));
472 ContactData = vCardObj->GetByPartial(wxT("BDAY"));
476 wxDateTime DateFormat;
481 if (ContactData.PropCount > 0){
485 for (int i = 0; i < ContactData.PropCount; i++){
487 // Grab the first birthday only.
489 BDayLine = ContactData.PropValues[i];
493 if (BDayLine.Mid(0,4) == wxT("1604")){
495 BDayLine = BDayLine.Mid(4,4);
497 BDayLine.Mid(0,2).ToLong(&MonthValue);
498 BDayLine.Mid(2,2).ToLong(&DayValue);
502 DateFormat.Set((wxDateTime::wxDateTime_t)(int)DayValue, (wxDateTime::Month)(MonthValue), 0, 0, 0, 0, 0);
504 } else if (BDayLine.Mid(0,2) == wxT("--")){
506 BDayLine = BDayLine.Mid(2,4);
508 BDayLine.Mid(0,2).ToLong(&MonthValue);
509 BDayLine.Mid(2,2).ToLong(&DayValue);
513 DateFormat.Set((wxDateTime::wxDateTime_t)(int)DayValue, (wxDateTime::Month)(MonthValue), 0, 0, 0, 0, 0);
518 BDayLine.Mid(0,4).ToLong(&YearValue);
519 BDayLine.Mid(4,2).ToLong(&MonthValue);
520 BDayLine.Mid(6,2).ToLong(&DayValue);
524 DateFormat.Set((wxDateTime::wxDateTime_t)(int)DayValue, (wxDateTime::Month)(MonthValue), YearValue, 0, 0, 0, 0);
530 BDayOutput.append(wxString::Format(wxT("%02i"), (int)DayValue));
531 BDayOutput.append(wxT("/"));
532 BDayOutput.append(wxString::Format(wxT("%02i"), (int)(MonthValue + 1)));
534 if (DateFormat.GetYear() != 0){
536 BDayOutput.append(wxT("/"));
537 BDayOutput.append(wxString::Format(wxT("%04i"), (int)YearValue));
541 CaptureString(&BDayOutput, FALSE);
542 ConvertToHTML(&BDayOutput);
544 DataLines.append(BDayOutput);
554 PageData.append("<table CELLPADDING=4 style=\"{width: 100%;}\"><tr><td>");
556 if (DataDisplay == TRUE){
559 PageData.append(wxT("<b>"));
560 PageData.append(_("Birthday:"));
561 PageData.append(wxT("</b> "));
562 PageData.append(DataLines);
563 PageData.append(wxT("<br>"));
567 // Process Anniversary
569 ContactData = vCardObj->GetByPartial(wxT("ANNIVERSARY"));
574 if (ContactData.PropCount > 0){
578 for (int i = 0; i < ContactData.PropCount; i++){
580 // Grab the first anniversary only.
582 AnniLine = ContactData.PropValues[i];
585 if (AnniLine.Mid(0,4) == wxT("1604")){
587 AnniLine = AnniLine.Mid(4,4);
589 AnniLine.Mid(0,2).ToLong(&MonthValue);
590 AnniLine.Mid(2,2).ToLong(&DayValue);
594 DateFormat.Set((wxDateTime::wxDateTime_t)(int)DayValue, (wxDateTime::Month)(MonthValue), 0, 0, 0, 0, 0);
596 } else if (AnniLine.Mid(0,2) == wxT("--")){
598 AnniLine = AnniLine.Mid(2,4);
600 AnniLine.Mid(0,2).ToLong(&MonthValue);
601 AnniLine.Mid(2,2).ToLong(&DayValue);
605 DateFormat.Set((wxDateTime::wxDateTime_t)(int)DayValue, (wxDateTime::Month)(MonthValue), 0, 0, 0, 0, 0);
610 AnniLine.Mid(0,4).ToLong(&YearValue);
611 AnniLine.Mid(4,2).ToLong(&MonthValue);
612 AnniLine.Mid(6,2).ToLong(&DayValue);
616 DateFormat.Set((wxDateTime::wxDateTime_t)(int)DayValue, (wxDateTime::Month)(MonthValue), YearValue, 0, 0, 0, 0);
620 wxString AnniDayOutput;
622 AnniDayOutput.append(wxString::Format(wxT("%02i"), (int)DayValue));
623 AnniDayOutput.append(wxT("/"));
624 AnniDayOutput.append(wxString::Format(wxT("%02i"), (int)(MonthValue + 1)));
626 if (DateFormat.GetYear() != 0){
628 AnniDayOutput.append(wxT("/"));
629 AnniDayOutput.append(wxString::Format(wxT("%04i"), (int)YearValue));
633 CaptureString(&AnniDayOutput, FALSE);
634 ConvertToHTML(&AnniDayOutput);
636 DataLines.append(AnniDayOutput);
646 if (DataDisplay == TRUE){
649 PageData.append(wxT("<b>"));
650 PageData.append(_("Anniversary:"));
651 PageData.append(wxT("</b> "));
652 PageData.append(DataLines);
653 PageData.append(wxT("<br>"));
659 ContactData = vCardObj->GetByPartial(wxT("NICKNAME"));
664 if (ContactData.PropCount > 0){
666 wxString NicknameLine;
668 for (int i = 0; i < ContactData.PropCount; i++){
670 NicknameLine = ContactData.PropValues[i];
673 CaptureString(&NicknameLine, FALSE);
674 ConvertToHTML(&NicknameLine);
676 DataLines.append(wxT("<tr><td><b>"));
677 DataLines.append(_("Nickname:"));
678 DataLines.append(wxT(" </b></td><td>"));
679 DataLines.append(NicknameLine);
680 DataLines.append(wxT("</td></tr>"));
688 if (DataDisplay == TRUE){
691 PageData.append(wxT("<h4>"));
692 PageData.append(_("Nicknames"));
693 PageData.append(wxT("</h4>"));
694 PageData.append(wxT("<br>"));
695 PageData.append(wxT("<table>"));
696 PageData.append(DataLines);
697 PageData.append(wxT("</table>"));
703 ContactData = vCardObj->GetByPartial(wxT("ADR"));
708 if (ContactData.PropCount > 0){
710 wxString AddressLine;
712 for (int i = 0; i < ContactData.PropCount; i++){
714 AddressLine = ContactData.PropValues[i];
716 intPropertyLen = AddressLine.Len();
723 AddressPOBox.clear();
724 AddressStreet.clear();
725 AddressLocality.clear();
726 AddressRegion.clear();
727 AddressPostalCode.clear();
728 AddressCountry.clear();
729 AddressExtended.clear();
730 FinalAddressLine.clear();
733 for (int i = 0; i <= intPropertyLen; i++){
737 if (AddressLine.Mid(i, 1) == wxT(";") && AddressLine.Mid((i - 1), 1) != wxT("\\")){
740 SplitPoints.insert(std::make_pair(intSplitsFound, (i + 1)));
742 if (intSplitsFound == 6){
744 SplitLength.insert(std::make_pair(intSplitsFound, (intSplitSize - 1)));
749 SplitLength.insert(std::make_pair(intSplitsFound, (intSplitSize - 1)));
759 // Split the data into several parts.
761 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
762 intiter != SplitPoints.end(); ++intiter){
764 if (intiter->first == 1){
768 SLiter = SplitLength.find(1);
770 AddressPOBox = AddressLine.Mid(0, SLiter->second);
771 intPrevValue = intiter->second;
773 } else if (intiter->first == 2){
775 // Deal with extended address.
777 SLiter = SplitLength.find(2);
779 AddressExtended = AddressLine.Mid(intPrevValue, SLiter->second);
780 intPrevValue = intiter->second;
782 } else if (intiter->first == 3){
784 // Deal with street address.
786 SLiter = SplitLength.find(3);
788 AddressStreet = AddressLine.Mid(intPrevValue, SLiter->second);
789 intPrevValue = intiter->second;
791 } else if (intiter->first == 4){
793 // Deal with locality
795 SLiter = SplitLength.find(4);
797 AddressLocality = AddressLine.Mid(intPrevValue, SLiter->second);
798 intPrevValue = intiter->second;
800 } else if (intiter->first == 5){
804 SLiter = SplitLength.find(5);
806 AddressRegion = AddressLine.Mid(intPrevValue, SLiter->second);
807 intPrevValue = intiter->second;
809 } else if (intiter->first == 6){
811 // Deal with post code.
813 SLiter = SplitLength.find(6);
815 AddressPostalCode = AddressLine.Mid(intPrevValue, SLiter->second);
816 intPrevValue = intiter->second;
818 // Deal with country.
820 AddressCountry = AddressLine.Mid(intPrevValue);
826 if (!AddressStreet.IsEmpty()){
828 AddressStreet.Trim();
829 ConvertToHTML(&AddressStreet);
831 FinalAddressLine.append(AddressStreet);
832 AddressFirst = FALSE;
836 if (!AddressLocality.IsEmpty()){
838 AddressLocality.Trim();
839 ConvertToHTML(&AddressLocality);
841 if (AddressFirst == FALSE){
843 FinalAddressLine.append(wxT(",<br>"));
844 FinalAddressLine.append(AddressLocality);
848 FinalAddressLine.append(AddressLocality);
849 AddressFirst = FALSE;
855 if (!AddressRegion.IsEmpty()){
857 AddressRegion.Trim();
858 ConvertToHTML(&AddressRegion);
860 if (AddressFirst == FALSE){
862 FinalAddressLine.append(wxT(",<br>"));
863 FinalAddressLine.append(AddressRegion);
867 FinalAddressLine.append(AddressRegion);
868 AddressFirst = FALSE;
874 if (!AddressPostalCode.IsEmpty()){
876 AddressPostalCode.Trim();
877 ConvertToHTML(&AddressPostalCode);
879 if (AddressFirst == FALSE){
881 FinalAddressLine.append(wxT(",<br>"));
882 FinalAddressLine.append(AddressPostalCode);
886 FinalAddressLine.append(AddressPostalCode);
887 AddressFirst = FALSE;
893 if (!AddressCountry.IsEmpty()){
895 AddressCountry.Trim();
896 ConvertToHTML(&AddressCountry);
898 if (AddressFirst == FALSE){
900 FinalAddressLine.append(wxT(",<br>"));
901 FinalAddressLine.append(AddressCountry);
905 FinalAddressLine.append(AddressCountry);
906 AddressFirst = FALSE;
912 CaptureString(&FinalAddressLine, FALSE);
914 DataLines.append(wxT("<tr><td><b>"));
915 DataLines.append(_("Address:"));
916 DataLines.append(wxT(" </b></td><td>"));
917 DataLines.append(FinalAddressLine);
918 DataLines.append(wxT("</td></tr>"));
926 if (DataDisplay == TRUE){
929 PageData.append(wxT("<h4>"));
930 PageData.append(_("Addresses"));
931 PageData.append(wxT("</h4>"));
932 PageData.append(wxT("<br>"));
933 PageData.append(wxT("<table>"));
934 PageData.append(DataLines);
935 PageData.append(wxT("</table>"));
941 ContactData = vCardObj->GetByPartial(wxT("EMAIL"));
946 if (ContactData.PropCount > 0){
950 for (int i = 0; i < ContactData.PropCount; i++){
952 EmailLine = ContactData.PropValues[i];
955 CaptureString(&EmailLine, FALSE);
956 ConvertToHTML(&EmailLine);
958 DataLines.append(wxT("<tr><td><b>"));
959 DataLines.append(_("E-mail Address:"));
960 DataLines.append(wxT(" </b></td><td>"));
961 DataLines.append(EmailLine);
962 DataLines.append(wxT("</td></tr>"));
970 if (DataDisplay == TRUE){
973 PageData.append(wxT("<h4>"));
974 PageData.append(_("Email Addresses"));
975 PageData.append(wxT("</h4>"));
976 PageData.append(wxT("<br>"));
977 PageData.append(wxT("<table>"));
978 PageData.append(DataLines);
979 PageData.append(wxT("</table>"));
985 ContactData = vCardObj->GetByPartial(wxT("TEL"));
990 if (ContactData.PropCount > 0){
994 for (int i = 0; i < ContactData.PropCount; i++){
996 TelLine = ContactData.PropValues[i];
998 wxStringTokenizer TelSplit(TelLine, wxT(":"));
1000 TelLine = TelSplit.GetNextToken();
1002 if (TelSplit.HasMoreTokens()){
1004 TelLine = TelSplit.GetNextToken();
1009 CaptureString(&TelLine, FALSE);
1010 ConvertToHTML(&TelLine);
1012 DataLines.append(wxT("<tr><td><b>"));
1013 DataLines.append(_("Telephone:"));
1014 DataLines.append(wxT(" </b></td><td>"));
1015 DataLines.append(TelLine);
1016 DataLines.append(wxT("</td></tr>"));
1024 if (DataDisplay == TRUE){
1027 PageData.append(wxT("<h4>"));
1028 PageData.append(_("Telephones"));
1029 PageData.append(wxT("</h4>"));
1030 PageData.append(wxT("<br>"));
1031 PageData.append(wxT("<table>"));
1032 PageData.append(DataLines);
1033 PageData.append(wxT("</table>"));
1037 // Instant Messaging
1039 ContactData = vCardObj->GetByPartial(wxT("IMPP"));
1041 DataDisplay = FALSE;
1044 if (ContactData.PropCount > 0){
1047 wxString IMTypeFriendly;
1050 for (int i = 0; i < ContactData.PropCount; i++){
1052 IMLine = ContactData.PropValues[i];
1054 wxStringTokenizer IMSplit(IMLine, wxT(":"));
1056 IMType = IMSplit.GetNextToken();
1057 IMLine = IMSplit.GetNextToken();
1059 // Process skype, gg, icq, yahoo etc into
1060 // something meaningful.
1062 if (IMType == wxT("aim")){
1066 IMTypeFriendly = _("AIM");
1068 } else if (IMType == wxT("xmpp")){
1072 IMTypeFriendly = _("XMPP");
1074 } else if (IMType == wxT("icq")){
1078 IMTypeFriendly = _("ICQ");
1080 } else if (IMType == wxT("skype")){
1084 IMTypeFriendly = _("Skype");
1086 } else if (IMType == wxT("gg")){
1090 IMTypeFriendly = _("Gadu-Gadu");
1092 } else if (IMType == wxT("yahoo")){
1096 IMTypeFriendly = _("Yahoo");
1100 // Other. Use IM type that was split.
1102 IMTypeFriendly = IMType;
1107 CaptureString(&IMLine, FALSE);
1108 ConvertToHTML(&IMLine);
1110 DataLines.append(wxT("<tr><td><b>"));
1111 DataLines.append(_("IM Address"));
1112 DataLines.append(_(" ("));
1113 DataLines.append(IMTypeFriendly);
1114 DataLines.append(_("):"));
1115 DataLines.append(wxT(" </b></td><td>"));
1116 DataLines.append(IMLine);
1117 DataLines.append(wxT("</td></tr>"));
1119 IMTypeFriendly.clear();
1129 if (DataDisplay == TRUE){
1132 PageData.append(wxT("<h4>"));
1133 PageData.append(_("Instant Messaging Addresses"));
1134 PageData.append(wxT("</h4>"));
1135 PageData.append(wxT("<br>"));
1136 PageData.append(wxT("<table>"));
1137 PageData.append(DataLines);
1138 PageData.append(wxT("</table>"));
1144 ContactData = vCardObj->GetByPartial(wxT("URL"));
1146 DataDisplay = FALSE;
1149 if (ContactData.PropCount > 0){
1153 for (int i = 0; i < ContactData.PropCount; i++){
1155 URLLine = ContactData.PropValues[i];
1158 CaptureString(&URLLine, FALSE);
1159 ConvertToHTML(&URLLine);
1161 DataLines.append(wxT("<tr><td><b>"));
1162 DataLines.append(_("Website:"));
1163 DataLines.append(wxT(" </b></td><td>"));
1164 DataLines.append(URLLine);
1165 DataLines.append(wxT("</td></tr>"));
1173 if (DataDisplay == TRUE){
1176 PageData.append(wxT("<h4>"));
1177 PageData.append(_("Website Addresses"));
1178 PageData.append(wxT("</h4>"));
1179 PageData.append(wxT("<br>"));
1180 PageData.append(wxT("<table>"));
1181 PageData.append(DataLines);
1182 PageData.append(wxT("</table>"));
1188 ContactData = vCardObj->GetByPartial(wxT("LANG"));
1190 DataDisplay = FALSE;
1193 if (ContactData.PropCount > 0){
1195 wxString NicknameLine;
1197 for (int i = 0; i < ContactData.PropCount; i++){
1199 NicknameLine = ContactData.PropValues[i];
1201 NicknameLine.Trim();
1202 CaptureString(&NicknameLine, FALSE);
1203 ConvertToHTML(&NicknameLine);
1205 DataLines.append(wxT("<tr><td><b>"));
1206 DataLines.append(_("Language:"));
1207 DataLines.append(wxT(" </b></td><td>"));
1208 DataLines.append(NicknameLine);
1209 DataLines.append(wxT("</td></tr>"));
1217 if (DataDisplay == TRUE){
1220 PageData.append(wxT("<h4>"));
1221 PageData.append(_("Languages"));
1222 PageData.append(wxT("</h4>"));
1223 PageData.append(wxT("<br>"));
1224 PageData.append(wxT("<table>"));
1225 PageData.append(DataLines);
1226 PageData.append(wxT("</table>"));
1232 ContactData = vCardObj->GetByPartial(wxT("TZ"));
1234 DataDisplay = FALSE;
1237 if (ContactData.PropCount > 0){
1239 wxString NicknameLine;
1241 for (int i = 0; i < ContactData.PropCount; i++){
1243 NicknameLine = ContactData.PropValues[i];
1245 NicknameLine.Trim();
1246 CaptureString(&NicknameLine, FALSE);
1247 ConvertToHTML(&NicknameLine);
1249 DataLines.append(wxT("<tr><td><b>"));
1250 DataLines.append(_("Timezone:"));
1251 DataLines.append(wxT(" </b></td><td>"));
1252 DataLines.append(NicknameLine);
1253 DataLines.append(wxT("</td></tr>"));
1261 if (DataDisplay == TRUE){
1264 PageData.append(wxT("<h4>"));
1265 PageData.append(_("Timezones"));
1266 PageData.append(wxT("</h4>"));
1267 PageData.append(wxT("<br>"));
1268 PageData.append(wxT("<table>"));
1269 PageData.append(DataLines);
1270 PageData.append(wxT("</table>"));
1276 ContactData = vCardObj->GetByPartial(wxT("GEO"));
1278 DataDisplay = FALSE;
1281 if (ContactData.PropCount > 0){
1285 for (int i = 0; i < ContactData.PropCount; i++){
1287 GeoLine = ContactData.PropValues[i];
1289 wxStringTokenizer GeoSplit(GeoLine, wxT(":"));
1291 GeoLine = GeoSplit.GetNextToken();
1293 if (GeoSplit.HasMoreTokens()){
1295 GeoLine = GeoSplit.GetNextToken();
1300 CaptureString(&GeoLine, FALSE);
1301 ConvertToHTML(&GeoLine);
1303 DataLines.append(wxT("<tr><td><b>"));
1304 DataLines.append(_("Geoposition:"));
1305 DataLines.append(wxT(" </b></td><td>"));
1306 DataLines.append(GeoLine);
1307 DataLines.append(wxT("</td></tr>"));
1315 if (DataDisplay == TRUE){
1318 PageData.append(wxT("<h4>"));
1319 PageData.append(_("Geopositioning"));
1320 PageData.append(wxT("</h4>"));
1321 PageData.append(wxT("<br>"));
1322 PageData.append(wxT("<table>"));
1323 PageData.append(DataLines);
1324 PageData.append(wxT("</table>"));
1330 ContactData = vCardObj->GetByPartial(wxT("TITLE"));
1332 DataDisplay = FALSE;
1335 if (ContactData.PropCount > 0){
1339 for (int i = 0; i < ContactData.PropCount; i++){
1341 TitleLine = ContactData.PropValues[i];
1344 CaptureString(&TitleLine, FALSE);
1345 ConvertToHTML(&TitleLine);
1347 DataLines.append(wxT("<tr><td><b>"));
1348 DataLines.append(_("Title:"));
1349 DataLines.append(wxT(" </b></td><td>"));
1350 DataLines.append(TitleLine);
1351 DataLines.append(wxT("</td></tr>"));
1359 if (DataDisplay == TRUE){
1362 PageData.append(wxT("<h4>"));
1363 PageData.append(_("Titles"));
1364 PageData.append(wxT("</h4>"));
1365 PageData.append(wxT("<br>"));
1366 PageData.append(wxT("<table>"));
1367 PageData.append(DataLines);
1368 PageData.append(wxT("</table>"));
1374 ContactData = vCardObj->GetByPartial(wxT("ROLE"));
1376 DataDisplay = FALSE;
1379 if (ContactData.PropCount > 0){
1383 for (int i = 0; i < ContactData.PropCount; i++){
1385 RoleLine = ContactData.PropValues[i];
1388 CaptureString(&RoleLine, FALSE);
1389 ConvertToHTML(&RoleLine);
1391 DataLines.append(wxT("<tr><td><b>"));
1392 DataLines.append(_("Role:"));
1393 DataLines.append(wxT(" </b></td><td>"));
1394 DataLines.append(RoleLine);
1395 DataLines.append(wxT("</td></tr>"));
1403 if (DataDisplay == TRUE){
1406 PageData.append(wxT("<h4>"));
1407 PageData.append(_("Roles"));
1408 PageData.append(wxT("</h4>"));
1409 PageData.append(wxT("<br>"));
1410 PageData.append(wxT("<table>"));
1411 PageData.append(DataLines);
1412 PageData.append(wxT("</table>"));
1418 ContactData = vCardObj->GetByPartial(wxT("ORG"));
1420 DataDisplay = FALSE;
1423 if (ContactData.PropCount > 0){
1427 for (int i = 0; i < ContactData.PropCount; i++){
1429 OrgLine = ContactData.PropValues[i];
1432 CaptureString(&OrgLine, FALSE);
1433 ConvertToHTML(&OrgLine);
1435 DataLines.append(wxT("<tr><td><b>"));
1436 DataLines.append(_("Organisation:"));
1437 DataLines.append(wxT(" </b></td><td>"));
1438 DataLines.append(OrgLine);
1439 DataLines.append(wxT("</td></tr>"));
1447 if (DataDisplay == TRUE){
1450 PageData.append(wxT("<h4>"));
1451 PageData.append(_("Organisations"));
1452 PageData.append(wxT("</h4>"));
1453 PageData.append(wxT("<br>"));
1454 PageData.append(wxT("<table>"));
1455 PageData.append(DataLines);
1456 PageData.append(wxT("</table>"));
1462 ContactData = vCardObj->GetByPartial(wxT("CATEGORIES"));
1464 DataDisplay = FALSE;
1467 if (ContactData.PropCount > 0){
1471 for (int i = 0; i < ContactData.PropCount; i++){
1473 CatLine = ContactData.PropValues[i];
1476 CaptureString(&CatLine, FALSE);
1477 ConvertToHTML(&CatLine);
1479 DataLines.append(wxT("<tr><td><b>"));
1480 DataLines.append(_("Category:"));
1481 DataLines.append(wxT(" </b></td><td>"));
1482 DataLines.append(CatLine);
1483 DataLines.append(wxT("</td></tr>"));
1491 if (DataDisplay == TRUE){
1494 PageData.append(wxT("<h4>"));
1495 PageData.append(_("Categories"));
1496 PageData.append(wxT("</h4>"));
1497 PageData.append(wxT("<br>"));
1498 PageData.append(wxT("<table>"));
1499 PageData.append(DataLines);
1500 PageData.append(wxT("</table>"));
1508 // Calendar Addresses
1510 ContactData = vCardObj->GetByPartial(wxT("CALURI"));
1512 DataDisplay = FALSE;
1515 if (ContactData.PropCount > 0){
1517 wxString CalURILine;
1519 for (int i = 0; i < ContactData.PropCount; i++){
1521 CalURILine = ContactData.PropValues[i];
1524 CaptureString(&CalURILine, FALSE);
1525 ConvertToHTML(&CalURILine);
1527 DataLines.append(wxT("<tr><td><b>"));
1528 DataLines.append(_("Calendar Address:"));
1529 DataLines.append(wxT(" </b></td><td>"));
1530 DataLines.append(CalURILine);
1531 DataLines.append(wxT("</td></tr>"));
1539 if (DataDisplay == TRUE){
1542 PageData.append(wxT("<h4>"));
1543 PageData.append(_("Calendar Addresses"));
1544 PageData.append(wxT("</h4>"));
1545 PageData.append(wxT("<br>"));
1546 PageData.append(wxT("<table>"));
1547 PageData.append(DataLines);
1548 PageData.append(wxT("</table>"));
1552 // Calendar Request Addresses
1554 ContactData = vCardObj->GetByPartial(wxT("CALADRURI"));
1556 DataDisplay = FALSE;
1559 if (ContactData.PropCount > 0){
1561 wxString CalAdrURILine;
1563 for (int i = 0; i < ContactData.PropCount; i++){
1565 CalAdrURILine = ContactData.PropValues[i];
1567 CalAdrURILine.Trim();
1568 CaptureString(&CalAdrURILine, FALSE);
1569 ConvertToHTML(&CalAdrURILine);
1571 DataLines.append(wxT("<tr><td><b>"));
1572 DataLines.append(_("Calendar Request Address:"));
1573 DataLines.append(wxT(" </b></td><td>"));
1574 DataLines.append(CalAdrURILine);
1575 DataLines.append(wxT("</td></tr>"));
1583 if (DataDisplay == TRUE){
1586 PageData.append(wxT("<h4>"));
1587 PageData.append(_("Calendar Request Addresses"));
1588 PageData.append(wxT("</h4>"));
1589 PageData.append(wxT("<br>"));
1590 PageData.append(wxT("<table>"));
1591 PageData.append(DataLines);
1592 PageData.append(wxT("</table>"));
1596 // Free/Busy Addresses
1598 ContactData = vCardObj->GetByPartial(wxT("FBURL"));
1600 DataDisplay = FALSE;
1603 if (ContactData.PropCount > 0){
1607 for (int i = 0; i < ContactData.PropCount; i++){
1609 FBURLLine = ContactData.PropValues[i];
1612 CaptureString(&FBURLLine, FALSE);
1613 ConvertToHTML(&FBURLLine);
1615 DataLines.append(wxT("<tr><td><b>"));
1616 DataLines.append(_("Free/Busy Address:"));
1617 DataLines.append(wxT(" </b></td><td>"));
1618 DataLines.append(FBURLLine);
1619 DataLines.append(wxT("</td></tr>"));
1627 if (DataDisplay == TRUE){
1630 PageData.append(wxT("<h4>"));
1631 PageData.append(_("Free/Busy Addresses"));
1632 PageData.append(wxT("</h4>"));
1633 PageData.append(wxT("<br>"));
1634 PageData.append(wxT("<table>"));
1635 PageData.append(DataLines);
1636 PageData.append(wxT("</table>"));
1642 ContactData = vCardObj->GetByPartial(wxT("NOTE"));
1644 DataDisplay = FALSE;
1647 if (ContactData.PropCount > 0){
1651 for (int i = 0; i < ContactData.PropCount; i++){
1653 NoteLine = ContactData.PropValues[i];
1656 CaptureString(&NoteLine, FALSE);
1657 ConvertToHTML(&NoteLine);
1659 DataLines.append(wxT("<tr><td><b>"));
1660 DataLines.append(_("Note:"));
1661 DataLines.append(wxT(" </b></td><td>"));
1662 DataLines.append(NoteLine);
1663 DataLines.append(wxT("</td></tr>"));
1671 if (DataDisplay == TRUE){
1673 PageData.append(wxT("<h4>"));
1674 PageData.append(_("Notes"));
1675 PageData.append(wxT("</h4>"));
1676 PageData.append(wxT("<br>"));
1677 PageData.append(wxT("<table>"));
1678 PageData.append(DataLines);
1679 PageData.append(wxT("</table>"));
1683 // Display the HTML document on the screen.
1685 PageData.append("</td></tr></table>");
1687 PageData.append(wxT("</body>"));
1688 PageData.append(wxT("</html>"));
1690 HTMLObj->SetPage(PageData);
1694 void SplitPropertyData(wxString *PropertyLine,
1695 std::map<int,int> *SplitPoints,
1696 std::map<int,int> *SplitLength,
1698 std::map<wxString,wxString> *SplitData){
1700 // Split the property data into SplitData.
1703 wxStringTokenizer PropertyElement;
1704 wxString PropertyName;
1705 wxString PropertyValue;
1706 int intPropertyLen = PropertyLine->Len();
1707 int intSplitsFound = 0;
1708 int intSplitSize = 0;
1709 int intSplitSeek = (intSize - 1);
1711 for (int i = intSize; i <= intPropertyLen; i++){
1715 if (PropertyLine->Mid(i, 1) == wxT(";") &&
1716 PropertyLine->Mid((i - 1), 1) != wxT("\\")){
1718 if (intSplitsFound == 0){
1720 DataStr = PropertyLine->Mid(intSplitSeek, (intSplitSize));
1721 SplitLength->insert(std::make_pair(intSplitsFound, (intSplitSize)));
1725 DataStr = PropertyLine->Mid(intSplitSeek, (intSplitSize - 1));
1726 SplitLength->insert(std::make_pair(intSplitsFound, (intSplitSize - 1)));
1730 SplitPoints->insert(std::make_pair(intSplitsFound, (i + 1)));
1733 intSplitSeek = (i + 1);
1736 if (!DataStr.IsEmpty()){
1738 PropertyElement.SetString(DataStr, wxT("="));
1739 PropertyName = PropertyElement.GetNextToken();
1740 PropertyValue = PropertyElement.GetNextToken();
1741 SplitData->insert(std::make_pair(PropertyName, PropertyValue));
1746 PropertyName.clear();
1747 PropertyValue.clear();
1753 if (intSplitsFound == 0){
1755 DataStr = PropertyLine->Mid(intSplitSeek, (intSplitSize));
1757 SplitPoints->insert(std::make_pair(intSplitsFound, (8 + 1)));
1758 SplitLength->insert(std::make_pair(intSplitsFound, intSplitSize));
1762 DataStr = PropertyLine->Mid(intSplitSeek, (intSplitSize - 1));
1764 SplitPoints->insert(std::make_pair(intSplitsFound, (intSplitSeek + 1)));
1765 SplitLength->insert(std::make_pair(intSplitsFound, intSplitSize));
1769 if (!DataStr.IsEmpty()){
1771 PropertyElement.SetString(DataStr, wxT("="));
1772 PropertyName = PropertyElement.GetNextToken();
1773 PropertyValue = PropertyElement.GetNextToken();
1774 SplitData->insert(std::make_pair(PropertyName, PropertyValue));