1 // ContactDataObject.cpp - Client Data Object.
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/>
19 #include "ContactDataObject.h"
21 ContactLoadStatus ContactDataObject::LoadFile(wxString Filename){
23 if (!wxFileExists(Filename)){
25 return CONTACTLOAD_FILEMISSING;
31 if (!ContactFile.Open(Filename, wxFile::read, wxS_DEFAULT)){
33 return CONTACTLOAD_FILEERROR;
37 // Check that the vCard is a valid vCard 4.0 file.
39 vCard vCard4FormatCheck;
41 vCard4FormatCheck.LoadFile(Filename);
43 if (vCard4FormatCheck.Get("VERSION") != wxT("4.0")){
45 return CONTACTLOAD_FILEINVALIDFORMAT;
49 // Check that the vCard meets the base specification.
51 if (!vCard4FormatCheck.MeetBaseSpecification()){
53 return CONTACTLOAD_FILEBASESPECFAIL;
57 wxStringTokenizer wSTContactFileLines(vCard4FormatCheck.WriteString(), wxT("\r\n"));
59 std::map<int, wxString> ContactFileLines;
61 int ContactLineSeek = 0;
63 while (wSTContactFileLines.HasMoreTokens() == TRUE){
65 wxString ContactLine = wSTContactFileLines.GetNextToken();
66 ContactFileLines.insert(std::make_pair(ContactLineSeek, ContactLine));
71 wxString wxSPropertyNextLine;
73 bool ExtraLineSeek = TRUE;
74 bool QuoteMode = FALSE;
75 bool PropertyFind = TRUE;
76 bool KindProcessed = FALSE;
77 bool NameProcessed = FALSE;
78 bool GenderProcessed = FALSE;
79 bool BirthdayProcessed = FALSE;
80 bool AnniversaryProcessed = FALSE;
81 int ContactLineLen = 0;
82 int QuoteBreakPoint = 0;
85 int NicknameCount = 0;
86 int TimeZoneCount = 0;
90 int TelephoneCount = 0;
92 wxString PropertyLine;
93 wxString PropertySeg1;
94 wxString PropertySeg2;
95 wxString PropertyNextLine;
98 for (std::map<int,wxString>::iterator iter = ContactFileLines.begin();
99 iter != ContactFileLines.end(); ++iter){
101 ExtraLineSeek = TRUE;
107 PropertyLine.Clear();
108 PropertySeg1.Clear();
109 PropertySeg2.Clear();
112 ContactLine = iter->second;
114 while (ExtraLineSeek == TRUE){
116 // Check if there is extra data on the next line
117 // (indicated by space or tab at the start) and add data.
121 if (iter == ContactFileLines.end()){
128 PropertyNextLine = iter->second;
130 if (PropertyNextLine.Mid(0, 1) == wxT(" ") || PropertyNextLine.Mid(0, 1) == wxT("\t")){
132 PropertyNextLine.Remove(0, 1);
133 ContactLine.Append(PropertyNextLine);
138 ExtraLineSeek = FALSE;
144 ContactLineLen = ContactLine.Len();
146 // Make sure we are not in quotation mode.
147 // Make sure colon does not have \ or \\ before it.
149 for (int i = 0; i <= ContactLineLen; i++){
151 if ((ContactLine.Mid(i, 1) == wxT(";") || ContactLine.Mid(i, 1) == wxT(":")) && PropertyFind == TRUE){
153 PropertyFind = FALSE;
155 } else if (PropertyFind == TRUE){
157 Property.Append(ContactLine.Mid(i, 1));
161 if (ContactLine.Mid(i, 1) == wxT("\"")){
163 if (QuoteMode == TRUE){
175 if (ContactLine.Mid(i, 1) == wxT(":") && ContactLine.Mid((i - 1), 1) != wxT("\\") && QuoteMode == FALSE){
184 // Split that line at the point into two variables (ignore the colon).
186 PropertySeg1 = ContactLine.Mid(0, QuoteBreakPoint);
187 PropertySeg2 = ContactLine.Mid((QuoteBreakPoint + 1));
189 if (Property == wxT("KIND") && KindProcessed == FALSE){
191 ProcessKind(PropertySeg2);
193 } else if (Property == wxT("MEMBER")){
195 ProcessMember(PropertySeg1, PropertySeg2, &GroupCount);
198 } else if (Property == wxT("FN")){
200 ProcessFN(PropertySeg1, PropertySeg2, &FNCount);
203 } else if (Property == wxT("N") && NameProcessed == FALSE){
205 ProcessN(PropertySeg1, PropertySeg2);
206 NameProcessed = TRUE;
208 } else if (Property == wxT("NICKNAME")){
210 ProcessNickname(PropertySeg1, PropertySeg2, &NicknameCount);
213 } else if (Property == wxT("GENDER") && GenderProcessed == FALSE){
215 ProcessGender(PropertySeg1, PropertySeg2);
216 GenderProcessed = TRUE;
218 } else if (Property == wxT("BDAY") && BirthdayProcessed == FALSE){
220 ProcessBirthday(PropertySeg1, PropertySeg2);
221 BirthdayProcessed = TRUE;
223 } else if (Property == wxT("ANNIVERSARY") && AnniversaryProcessed == FALSE){
225 ProcessAnniversary(PropertySeg1, PropertySeg2);
226 AnniversaryProcessed = TRUE;
228 } else if (Property == wxT("TZ")){
230 ProcessTimeZone(PropertySeg1, PropertySeg2, &TimeZoneCount);
233 } else if (Property == wxT("ADR")){
235 ProcessAddress(PropertySeg1, PropertySeg2, &AddressCount);
238 } else if (Property == wxT("EMAIL")){
240 ProcessEmail(PropertySeg1, PropertySeg2, &EmailCount);
243 } else if (Property == wxT("IMPP")){
245 ProcessIM(PropertySeg1, PropertySeg2, &IMCount);
248 } else if (Property == wxT("TEL")){
250 ProcessTelephone(PropertySeg1, PropertySeg2, &TelephoneCount);
257 return CONTACTLOAD_OK;
261 void ContactDataObject::ProcessKind(wxString KindType){
263 if (KindType == wxT("individual")){
265 ContactKind = CONTACTKIND_INDIVIDUAL;
267 } else if (KindType == wxT("group")){
269 ContactKind = CONTACTKIND_GROUP;
271 } else if (KindType == wxT("org")){
273 ContactKind = CONTACTKIND_ORGANISATION;
275 } else if (KindType == wxT("location")){
277 ContactKind = CONTACTKIND_LOCATION;
281 ContactKind = CONTACTKIND_NONE;
286 void ContactDataObject::ProcessMember(wxString PropertySeg1, wxString PropertySeg2, int *GroupCount){
288 std::map<int, int> SplitPoints;
289 std::map<int, int> SplitLength;
291 int intPrevValue = 8;
295 SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue);
299 wxString PropertyName;
300 wxString PropertyValue;
301 wxString PropertyData;
302 wxString PropertyTokens;
303 std::map<int,int>::iterator SLiter;
304 bool FirstToken = TRUE;
306 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
307 intiter != SplitPoints.end(); ++intiter){
309 SLiter = SplitLength.find(intiter->first);
311 PropertyData = PropertySeg1.Mid(intPrevValue, (SLiter->second));
313 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
314 PropertyName = PropertyElement.GetNextToken();
315 PropertyValue = PropertyElement.GetNextToken();
317 intPrevValue = intiter->second;
319 CaptureString(&PropertyValue, FALSE);
321 if (PropertyName == wxT("ALTID")){
323 GroupsListAltID.erase(*GroupCount);
324 GroupsListAltID.insert(std::make_pair(*GroupCount, PropertyValue));
326 } else if (PropertyName == wxT("PID")){
328 GroupsListPID.erase(*GroupCount);
329 GroupsListPID.insert(std::make_pair(*GroupCount, PropertyValue));
331 } else if (PropertyName == wxT("PREF")){
333 int PriorityNumber = 0;
334 bool ValidNumber = TRUE;
337 PriorityNumber = std::stoi(PropertyValue.ToStdString());
340 catch(std::invalid_argument &e){
344 if (ValidNumber == TRUE){
346 GroupsListPref.erase(*GroupCount);
347 GroupsListPref.insert(std::make_pair(*GroupCount, PriorityNumber));
351 } else if (PropertyName == wxT("MEDIATYPE")){
353 GroupsListMediaType.erase(*GroupCount);
354 GroupsListMediaType.insert(std::make_pair(*GroupCount, PropertyValue));
356 } else if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty()){
358 if (FirstToken == TRUE){
360 PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue);
365 PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue);
373 GroupsList.insert(std::make_pair(*GroupCount, PropertySeg2));
375 if (!PropertyTokens.IsEmpty()){
377 GroupsListTokens.insert(std::make_pair(*GroupCount, PropertyTokens));
384 void ContactDataObject::ProcessFN(wxString PropertySeg1, wxString PropertySeg2, int *FNCount){
386 std::map<int, int> SplitPoints;
387 std::map<int, int> SplitLength;
389 int intPrevValue = 4;
393 SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue);
397 wxString PropertyName;
398 wxString PropertyValue;
399 wxString PropertyData;
400 wxString PropertyTokens;
401 std::map<int,int>::iterator SLiter;
402 bool FirstToken = TRUE;
404 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
405 intiter != SplitPoints.end(); ++intiter){
407 SLiter = SplitLength.find(intiter->first);
409 PropertyData = PropertySeg1.Mid(intPrevValue, (SLiter->second));
411 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
412 PropertyName = PropertyElement.GetNextToken();
413 PropertyValue = PropertyElement.GetNextToken();
415 intPrevValue = intiter->second;
417 CaptureString(&PropertyValue, FALSE);
419 if (PropertyName == wxT("TYPE")){
421 if (!PropertyValue.IsEmpty() || PropertyValue == wxT("home") ||
422 PropertyValue == wxT("work") ){
424 FullNamesListType.erase(*FNCount);
425 FullNamesListType.insert(std::make_pair(*FNCount, PropertyValue));
429 } else if (PropertyName == wxT("LANGUAGE")){
431 FullNamesListLanguage.erase(*FNCount);
432 FullNamesListLanguage.insert(std::make_pair(*FNCount, PropertyValue));
434 } else if (PropertyName == wxT("ALTID")){
436 FullNamesListAltID.erase(*FNCount);
437 FullNamesListAltID.insert(std::make_pair(*FNCount, PropertyValue));
439 } else if (PropertyName == wxT("PID")){
441 FullNamesListPID.erase(*FNCount);
442 FullNamesListPID.insert(std::make_pair(*FNCount, PropertyValue));
444 } else if (PropertyName == wxT("PREF")){
446 int PriorityNumber = 0;
447 bool ValidNumber = TRUE;
450 PriorityNumber = std::stoi(PropertyValue.ToStdString());
453 catch(std::invalid_argument &e){
457 if (ValidNumber == TRUE){
459 FullNamesListPref.erase(*FNCount);
460 FullNamesListPref.insert(std::make_pair(*FNCount, PriorityNumber));
464 } else if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty()){
466 if (FirstToken == TRUE){
468 PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue);
473 PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue);
481 FullNamesList.insert(std::make_pair(*FNCount, PropertySeg2));
483 if (!PropertyTokens.IsEmpty()){
485 FullNamesListTokens.insert(std::make_pair(*FNCount, PropertyTokens));
491 void ContactDataObject::ProcessN(wxString PropertySeg1, wxString PropertySeg2){
493 std::map<int, int> SplitPoints;
494 std::map<int, int> SplitLength;
496 int intPrevValue = 3;
500 SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue);
504 wxString PropertyName;
505 wxString PropertyValue;
506 wxString PropertyData;
507 wxString PropertyTokens;
508 std::map<int,int>::iterator SLiter;
509 bool FirstToken = TRUE;
511 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
512 intiter != SplitPoints.end(); ++intiter){
514 SLiter = SplitLength.find(intiter->first);
516 PropertyData = PropertySeg1.Mid(intPrevValue, (SLiter->second));
518 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
519 PropertyName = PropertyElement.GetNextToken();
520 PropertyValue = PropertyElement.GetNextToken();
522 intPrevValue = intiter->second;
524 CaptureString(&PropertyValue, FALSE);
526 if (PropertyName == wxT("ALTID")){
528 NameAltID = PropertyValue;
530 } else if (PropertyName == wxT("LANGUAGE")){
532 NameLanguage = PropertyValue;
534 } else if (PropertyName == wxT("SORT-AS")){
536 if (PropertyValue.Left(1) == wxT("\"") && PropertyValue.Right(1) == wxT("\"") &&
537 PropertyValue.Len() >= 3){
538 NameDisplayAs = PropertyValue.Mid(1, (PropertyValue.Len() - 2));
541 } else if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty()){
543 if (FirstToken == TRUE){
545 PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue);
550 PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue);
558 // Split the name data.
560 int intSplitSeek = 0;
561 int intSplitsFound = 0;
562 int intSplitSize = 0;
563 int intPropertyLen = PropertySeg2.Len();
565 std::map<int,wxString> NameValues;
568 for (int i = 0; i <= intPropertyLen; i++){
570 if (PropertySeg2.Mid(i, 1) == wxT(";") && PropertySeg2.Mid((i - 1), 1) != wxT("\\")){
572 NameValues.insert(std::make_pair(++intSplitsFound, PropertySeg2.Mid(intSplitSeek, intSplitSize)));
577 if (intSplitsFound == 4){
579 NameValues.insert(std::make_pair(++intSplitsFound, PropertySeg2.Mid(intSplitSeek, wxString::npos)));
593 // Split the data into several parts.
595 for (std::map<int, wxString>::iterator iter = NameValues.begin();
596 iter != NameValues.end(); ++iter){
598 if (iter->first == 1){
600 // Deal with family name.
602 NameSurname = iter->second;
604 } else if (iter->first == 2){
606 // Deal with given names.
608 NameForename = iter->second;
610 } else if (iter->first == 3){
612 // Deal with additional names.
614 NameOtherNames = iter->second;
616 } else if (iter->first == 4){
618 // Deal with honorifix prefixes and suffixes.
620 NameTitle = iter->second;
624 if (iter == NameValues.end()){
630 NameSuffix = iter->second;
636 // Add the name token data.
638 if (!PropertyTokens.IsEmpty()){
640 NameTokens = PropertyTokens;
646 void ContactDataObject::ProcessNickname(wxString PropertySeg1, wxString PropertySeg2, int *NicknameCount){
648 std::map<int, int> SplitPoints;
649 std::map<int, int> SplitLength;
651 int intPrevValue = 10;
654 SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue);
658 PropertyType PropType = PROPERTY_NONE;
660 // Look for type before continuing.
662 CheckType(&PropertySeg1, &SplitPoints, &SplitLength, &intPrevValue, &PropType);
666 std::map<int, wxString> *NicknamesList = NULL;
667 std::map<int, wxString> *NicknamesListType = NULL;
668 std::map<int, wxString> *NicknamesListLanguage = NULL;
669 std::map<int, wxString> *NicknamesListAltID = NULL;
670 std::map<int, wxString> *NicknamesListPID = NULL;
671 std::map<int, wxString> *NicknamesListTokens = NULL;
672 std::map<int, int> *NicknamesListPref = NULL;
676 NicknamesList = &GeneralNicknamesList;
677 NicknamesListType = &GeneralNicknamesListType;
678 NicknamesListLanguage = &GeneralNicknamesListLanguage;
679 NicknamesListAltID = &GeneralNicknamesListAltID;
680 NicknamesListPID = &GeneralNicknamesListPID;
681 NicknamesListTokens = &GeneralNicknamesListTokens;
682 NicknamesListPref = &GeneralNicknamesListPref;
685 NicknamesList = &HomeNicknamesList;
686 NicknamesListType = &HomeNicknamesListType;
687 NicknamesListLanguage = &HomeNicknamesListLanguage;
688 NicknamesListAltID = &HomeNicknamesListAltID;
689 NicknamesListPID = &HomeNicknamesListPID;
690 NicknamesListTokens = &HomeNicknamesListTokens;
691 NicknamesListPref = &HomeNicknamesListPref;
694 NicknamesList = &BusinessNicknamesList;
695 NicknamesListType = &BusinessNicknamesListType;
696 NicknamesListLanguage = &BusinessNicknamesListLanguage;
697 NicknamesListAltID = &BusinessNicknamesListAltID;
698 NicknamesListPID = &BusinessNicknamesListPID;
699 NicknamesListTokens = &BusinessNicknamesListTokens;
700 NicknamesListPref = &BusinessNicknamesListPref;
704 std::map<int, int>::iterator SLiter;
705 wxString PropertyData;
706 wxString PropertyName;
707 wxString PropertyValue;
708 wxString PropertyTokens;
709 bool FirstToken = TRUE;
711 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
712 intiter != SplitPoints.end(); ++intiter){
714 SLiter = SplitLength.find(intiter->first);
716 PropertyData = PropertySeg1.Mid(intPrevValue, (SLiter->second));
718 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
719 PropertyName = PropertyElement.GetNextToken();
720 PropertyValue = PropertyElement.GetNextToken();
722 intPrevValue = intiter->second;
724 CaptureString(&PropertyValue, FALSE);
726 if (PropertyName == wxT("ALTID")){
728 NicknamesListAltID->erase(*NicknameCount);
729 NicknamesListAltID->insert(std::make_pair(*NicknameCount, PropertyValue));
731 } else if (PropertyName == wxT("PID")){
733 NicknamesListPID->erase(*NicknameCount);
734 NicknamesListPID->insert(std::make_pair(*NicknameCount, PropertyValue));
736 } else if (PropertyName == wxT("PREF")){
738 int PriorityNumber = 0;
739 bool ValidNumber = TRUE;
742 PriorityNumber = std::stoi(PropertyValue.ToStdString());
745 catch(std::invalid_argument &e){
749 if (ValidNumber == TRUE){
751 NicknamesListPref->erase(*NicknameCount);
752 NicknamesListPref->insert(std::make_pair(*NicknameCount, PriorityNumber));
756 } else if (PropertyName == wxT("LANGUAGE")){
758 NicknamesListLanguage->erase(*NicknameCount);
759 NicknamesListLanguage->insert(std::make_pair(*NicknameCount, PropertyValue));
763 // Something else we don't know about so append
764 // to the tokens variable.
766 if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty() && PropertyName != wxT("TYPE")){
768 if (FirstToken == TRUE){
770 PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue);
775 PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue);
785 NicknamesList->insert(std::make_pair(*NicknameCount, PropertySeg2));
787 // Add the name token data.
789 if (!PropertyTokens.IsEmpty()){
791 NicknamesListTokens->insert(std::make_pair(*NicknameCount, PropertyTokens));
797 void ContactDataObject::ProcessGender(wxString PropertySeg1, wxString PropertySeg2){
799 std::map<int, int> SplitPoints;
800 std::map<int, int> SplitLength;
801 std::map<int, int>::iterator SLiter;
802 wxString PropertyData;
803 wxString PropertyName;
804 wxString PropertyValue;
805 wxString PropertyTokens;
806 bool FirstToken = TRUE;
807 int intPrevValue = 8;
809 SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue);
813 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
814 intiter != SplitPoints.end(); ++intiter){
816 SLiter = SplitLength.find(intiter->first);
818 PropertyData = PropertySeg1.Mid(intPrevValue, (SLiter->second));
820 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
821 PropertyName = PropertyElement.GetNextToken();
822 PropertyValue = PropertyElement.GetNextToken();
824 intPrevValue = intiter->second;
826 // Process properties.
828 size_t intPropertyValueLen = PropertyValue.Len();
830 if (PropertyValue.Mid((intPropertyValueLen - 1), 1) == wxT("\"")){
832 PropertyValue.Trim();
833 PropertyValue.RemoveLast();
837 if (PropertyValue.Mid(0, 1) == wxT("\"")){
839 PropertyValue.Remove(0, 1);
843 if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty()){
845 if (FirstToken == TRUE){
847 PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue);
852 PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue);
860 wxStringTokenizer GenderData (PropertySeg2, wxT(";"));
862 wxString GenderComponent;
864 if (GenderData.CountTokens() >= 2){
866 Gender = GenderData.GetNextToken();
867 GenderDetails = GenderData.GetString();
869 CaptureString(&GenderDetails, FALSE);
873 Gender = GenderData.GetNextToken();
877 if (!PropertyTokens.IsEmpty()){
879 GenderTokens = PropertyTokens;
885 void ContactDataObject::ProcessBirthday(wxString PropertySeg1, wxString PropertySeg2){
887 // Process date. Preserve the remainder in the string.
889 std::map<int, int> SplitPoints;
890 std::map<int, int> SplitLength;
891 std::map<int, int>::iterator SLiter;
892 wxString PropertyData;
893 wxString PropertyName;
894 wxString PropertyValue;
895 wxString PropertyTokens;
896 bool BirthdayText = FALSE;
897 int intPrevValue = 6;
899 SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue);
903 // Look for type before continuing.
905 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
906 intiter != SplitPoints.end(); ++intiter){
908 SLiter = SplitLength.find(intiter->first);
910 PropertyData = PropertySeg1.Mid(intPrevValue, SLiter->second);
912 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
913 PropertyName = PropertyElement.GetNextToken();
914 PropertyValue = PropertyElement.GetNextToken();
916 intPrevValue = intiter->second;
918 if (PropertyName == wxT("VALUE") && PropertyValue == wxT("text") && BirthdayText == FALSE){
920 CaptureString(&PropertySeg2, FALSE);
921 Birthday = PropertySeg2;
928 // Setup blank lines for later on.
931 bool FirstToken = TRUE;
933 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
934 intiter != SplitPoints.end(); ++intiter){
936 SLiter = SplitLength.find(intiter->first);
938 PropertyData = PropertySeg1.Mid(intPrevValue, SLiter->second);
940 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
941 PropertyName = PropertyElement.GetNextToken();
942 PropertyValue = PropertyElement.GetNextToken();
944 intPrevValue = intiter->second;
946 // Process properties.
948 CaptureString(&PropertyValue, FALSE);
950 if (PropertyValue.Mid((PropertyValue.Len() - 1), 1) == wxT("\"")){
952 PropertyValue.Trim();
953 PropertyValue.RemoveLast();
957 if (PropertyValue.Mid(0, 1) == wxT("\"")){
959 PropertyValue.Remove(0, 1);
963 if (PropertyName == wxT("ALTID")){
965 BirthdayAltID = PropertyValue;
967 } else if (PropertyName == wxT("CALSCALE")){
969 BirthdayCalScale = PropertyValue;
971 } else if (PropertyName != wxT("VALUE")) {
973 // Something else we don't know about so append
974 // to the tokens variable.
976 if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty()){
978 if (FirstToken == TRUE){
980 PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue);
985 PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue);
995 // Add the data to the variables and form.
997 if (BirthdayText == FALSE){
999 Birthday = PropertySeg2;
1003 if (!PropertyTokens.IsEmpty()){
1005 BirthdayTokens = PropertyTokens;
1011 void ContactDataObject::ProcessAnniversary(wxString PropertySeg1, wxString PropertySeg2){
1013 // Process date. Preserve the remainder in the string.
1015 std::map<int, int> SplitPoints;
1016 std::map<int, int> SplitLength;
1017 std::map<int, int>::iterator SLiter;
1018 wxString PropertyData;
1019 wxString PropertyName;
1020 wxString PropertyValue;
1021 wxString PropertyTokens;
1022 bool AnniversaryText = FALSE;
1023 int intPrevValue = 13;
1025 SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue);
1029 // Look for type before continuing.
1031 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
1032 intiter != SplitPoints.end(); ++intiter){
1034 SLiter = SplitLength.find(intiter->first);
1036 PropertyData = PropertySeg1.Mid(intPrevValue, SLiter->second);
1038 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
1039 PropertyName = PropertyElement.GetNextToken();
1040 PropertyValue = PropertyElement.GetNextToken();
1042 intPrevValue = intiter->second;
1044 if (PropertyName == wxT("VALUE") && PropertyValue == wxT("text") && AnniversaryText == FALSE){
1046 CaptureString(&PropertySeg2, FALSE);
1047 Anniversary = PropertySeg2;
1048 AnniversaryText = TRUE;
1054 // Setup blank lines for later on.
1057 bool FirstToken = TRUE;
1059 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
1060 intiter != SplitPoints.end(); ++intiter){
1062 SLiter = SplitLength.find(intiter->first);
1064 PropertyData = PropertySeg1.Mid(intPrevValue, SLiter->second);
1066 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
1067 PropertyName = PropertyElement.GetNextToken();
1068 PropertyValue = PropertyElement.GetNextToken();
1070 intPrevValue = intiter->second;
1072 // Process properties.
1074 CaptureString(&PropertyValue, FALSE);
1076 if (PropertyValue.Mid((PropertyValue.Len() - 1), 1) == wxT("\"")){
1078 PropertyValue.Trim();
1079 PropertyValue.RemoveLast();
1083 if (PropertyValue.Mid(0, 1) == wxT("\"")){
1085 PropertyValue.Remove(0, 1);
1089 if (PropertyName == wxT("ALTID")){
1091 AnniversaryAltID = PropertyValue;
1093 } else if (PropertyName == wxT("CALSCALE")){
1095 AnniversaryCalScale = PropertyValue;
1097 } else if (PropertyName != wxT("VALUE")) {
1099 // Something else we don't know about so append
1100 // to the tokens variable.
1102 if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty()){
1104 if (FirstToken == TRUE){
1106 PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue);
1111 PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue);
1121 // Add the data to the variables and form.
1123 if (AnniversaryText == FALSE){
1125 Anniversary = PropertySeg2;
1129 if (!PropertyTokens.IsEmpty()){
1131 AnniversaryTokens = PropertyTokens;
1137 void ContactDataObject::ProcessTimeZone(wxString PropertySeg1, wxString PropertySeg2, int *TimeZoneCount){
1139 std::map<int, int> SplitPoints;
1140 std::map<int, int> SplitLength;
1142 int intPrevValue = 4;
1145 SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue);
1149 PropertyType PropType = PROPERTY_NONE;
1151 // Look for type before continuing.
1153 CheckType(&PropertySeg1, &SplitPoints, &SplitLength, &intPrevValue, &PropType);
1157 std::map<int, wxString> *TZList = NULL;
1158 std::map<int, wxString> *TZListType = NULL;
1159 std::map<int, wxString> *TZListMediatype = NULL;
1160 std::map<int, wxString> *TZListAltID = NULL;
1161 std::map<int, wxString> *TZListPID = NULL;
1162 std::map<int, wxString> *TZListTokens = NULL;
1163 std::map<int, int> *TZListPref = NULL;
1167 TZList = &GeneralTZList;
1168 TZListType = &GeneralTZListType;
1169 TZListMediatype = &GeneralTZListMediatype;
1170 TZListAltID = &GeneralTZListAltID;
1171 TZListPID = &GeneralTZListPID;
1172 TZListTokens = &GeneralTZListTokens;
1173 TZListPref = &GeneralTZListPref;
1176 TZList = &HomeTZList;
1177 TZListType = &HomeTZListType;
1178 TZListMediatype = &HomeTZListMediatype;
1179 TZListAltID = &HomeTZListAltID;
1180 TZListPID = &HomeTZListPID;
1181 TZListTokens = &HomeTZListTokens;
1182 TZListPref = &HomeTZListPref;
1185 TZList = &BusinessTZList;
1186 TZListType = &BusinessTZListType;
1187 TZListMediatype = &BusinessTZListMediatype;
1188 TZListAltID = &BusinessTZListAltID;
1189 TZListPID = &BusinessTZListPID;
1190 TZListTokens = &BusinessTZListTokens;
1191 TZListPref = &BusinessTZListPref;
1195 std::map<int, int>::iterator SLiter;
1196 wxString PropertyData;
1197 wxString PropertyName;
1198 wxString PropertyValue;
1199 wxString PropertyTokens;
1200 bool FirstToken = TRUE;
1202 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
1203 intiter != SplitPoints.end(); ++intiter){
1205 SLiter = SplitLength.find(intiter->first);
1207 PropertyData = PropertySeg1.Mid(intPrevValue, (SLiter->second));
1209 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
1210 PropertyName = PropertyElement.GetNextToken();
1211 PropertyValue = PropertyElement.GetNextToken();
1213 intPrevValue = intiter->second;
1215 CaptureString(&PropertyValue, FALSE);
1217 if (PropertyName == wxT("ALTID")){
1219 TZListAltID->erase(*TimeZoneCount);
1220 TZListAltID->insert(std::make_pair(*TimeZoneCount, PropertyValue));
1222 } else if (PropertyName == wxT("PID")){
1224 TZListPID->erase(*TimeZoneCount);
1225 TZListPID->insert(std::make_pair(*TimeZoneCount, PropertyValue));
1227 } else if (PropertyName == wxT("PREF")){
1229 int PriorityNumber = 0;
1230 bool ValidNumber = TRUE;
1233 PriorityNumber = std::stoi(PropertyValue.ToStdString());
1236 catch(std::invalid_argument &e){
1237 ValidNumber = FALSE;
1240 if (ValidNumber == TRUE){
1242 TZListPref->erase(*TimeZoneCount);
1243 TZListPref->insert(std::make_pair(*TimeZoneCount, PriorityNumber));
1247 } else if (PropertyName == wxT("MEDIATYPE")){
1249 TZListMediatype->erase(*TimeZoneCount);
1250 TZListMediatype->insert(std::make_pair(*TimeZoneCount, PropertyValue));
1254 // Something else we don't know about so append
1255 // to the tokens variable.
1257 if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty() && PropertyName != wxT("TYPE")){
1259 if (FirstToken == TRUE){
1261 PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue);
1266 PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue);
1276 TZList->insert(std::make_pair(*TimeZoneCount, PropertySeg2));
1278 // Add the name token data.
1280 if (!PropertyTokens.IsEmpty()){
1282 TZListTokens->insert(std::make_pair(*TimeZoneCount, PropertyTokens));
1289 void ContactDataObject::ProcessAddress(wxString PropertySeg1, wxString PropertySeg2, int *AddressCount){
1291 size_t intPropertyLen = PropertySeg1.Len();
1292 std::map<int, int> SplitPoints;
1293 std::map<int, int> SplitLength;
1294 std::map<int, int>::iterator SLiter;
1295 wxString PropertyData;
1296 wxString PropertyName;
1297 wxString PropertyValue;
1298 wxString PropertyTokens;
1299 wxString AddressLabel;
1300 wxString AddressLang;
1301 wxString AddressAltID;
1302 wxString AddressPID;
1303 wxString AddressTokens;
1304 wxString AddressGeo;
1305 wxString AddressTimezone;
1306 wxString AddressType;
1307 wxString AddressMediatype;
1308 wxString AddressPOBox;
1309 wxString AddressExtended;
1310 wxString AddressStreet;
1311 wxString AddressLocality;
1312 wxString AddressCity;
1313 wxString AddressRegion;
1314 wxString AddressPostalCode;
1315 wxString AddressCountry;
1316 bool FirstToken = TRUE;
1317 int intSplitsFound = 0;
1318 int intSplitSize = 0;
1319 int intPrevValue = 5;
1324 SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue);
1328 PropertyType PropType = PROPERTY_NONE;
1330 // Look for type before continuing.
1332 CheckType(&PropertySeg1, &SplitPoints, &SplitLength, &intPrevValue, &PropType);
1336 std::map<int, wxString> *AddressList = NULL;
1337 std::map<int, wxString> *AddressListTown = NULL;
1338 std::map<int, wxString> *AddressListCounty = NULL;
1339 std::map<int, wxString> *AddressListPostCode = NULL;
1340 std::map<int, wxString> *AddressListCountry = NULL;
1341 std::map<int, wxString> *AddressListLabel = NULL;
1342 std::map<int, wxString> *AddressListLang = NULL;
1343 std::map<int, wxString> *AddressListAltID = NULL;
1344 std::map<int, wxString> *AddressListPID = NULL;
1345 std::map<int, wxString> *AddressListTokens = NULL;
1346 std::map<int, wxString> *AddressListGeo = NULL;
1347 std::map<int, wxString> *AddressListTimezone = NULL;
1348 std::map<int, wxString> *AddressListType = NULL;
1349 std::map<int, wxString> *AddressListMediatype = NULL;
1350 std::map<int, int> *AddressListPref = NULL;
1354 AddressList = &GeneralAddressList;
1355 AddressListTown = &GeneralAddressListTown;
1356 AddressListCounty = &GeneralAddressListCounty;
1357 AddressListPostCode = &GeneralAddressListPostCode;
1358 AddressListCountry = &GeneralAddressListCountry;
1359 AddressListLabel = &GeneralAddressListLabel;
1360 AddressListLang = &GeneralAddressListLang;
1361 AddressListAltID = &GeneralAddressListAltID;
1362 AddressListPID = &GeneralAddressListPID;
1363 AddressListTokens = &GeneralAddressListTokens;
1364 AddressListGeo = &GeneralAddressListGeo;
1365 AddressListTimezone = &GeneralAddressListTimezone;
1366 AddressListType = &GeneralAddressListType;
1367 AddressListMediatype = &GeneralAddressListMediatype;
1368 AddressListPref = &GeneralAddressListPref;
1371 AddressList = &HomeAddressList;
1372 AddressListTown = &HomeAddressListTown;
1373 AddressListCounty = &HomeAddressListCounty;
1374 AddressListPostCode = &HomeAddressListPostCode;
1375 AddressListCountry = &HomeAddressListCountry;
1376 AddressListLabel = &HomeAddressListLabel;
1377 AddressListLang = &HomeAddressListLang;
1378 AddressListAltID = &HomeAddressListAltID;
1379 AddressListPID = &HomeAddressListPID;
1380 AddressListTokens = &HomeAddressListTokens;
1381 AddressListGeo = &HomeAddressListGeo;
1382 AddressListTimezone = &HomeAddressListTimezone;
1383 AddressListType = &HomeAddressListType;
1384 AddressListMediatype = &HomeAddressListMediatype;
1385 AddressListPref = &HomeAddressListPref;
1388 AddressList = &BusinessAddressList;
1389 AddressListTown = &BusinessAddressListTown;
1390 AddressListCounty = &BusinessAddressListCounty;
1391 AddressListPostCode = &BusinessAddressListPostCode;
1392 AddressListCountry = &BusinessAddressListCountry;
1393 AddressListLabel = &BusinessAddressListLabel;
1394 AddressListLang = &BusinessAddressListLang;
1395 AddressListAltID = &BusinessAddressListAltID;
1396 AddressListPID = &BusinessAddressListPID;
1397 AddressListTokens = &BusinessAddressListTokens;
1398 AddressListGeo = &BusinessAddressListGeo;
1399 AddressListTimezone = &BusinessAddressListTimezone;
1400 AddressListType = &BusinessAddressListType;
1401 AddressListMediatype = &BusinessAddressListMediatype;
1402 AddressListPref = &BusinessAddressListPref;
1408 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
1409 intiter != SplitPoints.end(); ++intiter){
1411 SLiter = SplitLength.find(intiter->first);
1413 PropertyData = PropertySeg1.Mid(intPrevValue, (SLiter->second));
1415 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
1416 PropertyName = PropertyElement.GetNextToken();
1417 PropertyValue = PropertyElement.GetNextToken();
1419 intPrevValue = intiter->second;
1421 CaptureString(&PropertyValue, FALSE);
1423 // Process properties.
1425 if (PropertyName == wxT("LABEL")){
1427 AddressListLabel->erase(*AddressCount);
1428 AddressListLabel->insert(std::make_pair(*AddressCount, PropertyValue));
1430 } else if (PropertyName == wxT("LANGUAGE")){
1432 AddressListLang->erase(*AddressCount);
1433 AddressListLang->insert(std::make_pair(*AddressCount, PropertyValue));
1435 } else if (PropertyName == wxT("ALTID")){
1437 AddressListAltID->erase(*AddressCount);
1438 AddressListAltID->insert(std::make_pair(*AddressCount, PropertyValue));
1440 } else if (PropertyName == wxT("PID")){
1442 AddressListPID->erase(*AddressCount);
1443 AddressListPID->insert(std::make_pair(*AddressCount, PropertyValue));
1445 } else if (PropertyName == wxT("GEO")){
1447 AddressListGeo->erase(*AddressCount);
1448 AddressListGeo->insert(std::make_pair(*AddressCount, PropertyValue));
1450 } else if (PropertyName == wxT("TZ")){
1452 AddressListTimezone->erase(*AddressCount);
1453 AddressListTimezone->insert(std::make_pair(*AddressCount, PropertyValue));
1455 } else if (PropertyName == wxT("MEDIATYPE")){
1457 AddressListMediatype->erase(*AddressCount);
1458 AddressListMediatype->insert(std::make_pair(*AddressCount, PropertyValue));
1460 } else if (PropertyName == wxT("PREF")){
1462 int PriorityNumber = 0;
1463 bool ValidNumber = TRUE;
1466 PriorityNumber = std::stoi(PropertyValue.ToStdString());
1469 catch(std::invalid_argument &e){
1470 ValidNumber = FALSE;
1473 if (ValidNumber == TRUE){
1475 AddressListPref->erase(*AddressCount);
1476 AddressListPref->insert(std::make_pair(*AddressCount, PriorityNumber));
1482 if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty() && PropertyName != wxT("TYPE")){
1484 if (FirstToken == TRUE){
1486 PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue);
1491 PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue);
1501 // Split the address.
1503 //std::map<int, int>::iterator SLiter;
1504 intPropertyLen = PropertySeg2.Len();
1505 SplitPoints.clear();
1506 SplitLength.clear();
1511 for (int i = 0; i <= intPropertyLen; i++){
1515 if (PropertySeg2.Mid(i, 1) == wxT(";") && PropertySeg2.Mid((i - 1), 1) != wxT("\\")){
1518 SplitPoints.insert(std::make_pair(intSplitsFound, (i + 1)));
1520 if (intSplitsFound == 6){
1522 SplitLength.insert(std::make_pair(intSplitsFound, (intSplitSize - 1)));
1527 SplitLength.insert(std::make_pair(intSplitsFound, (intSplitSize - 1)));
1537 // Split the data into several parts.
1539 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
1540 intiter != SplitPoints.end(); ++intiter){
1542 if (intiter->first == 1){
1544 // Deal with PO Box.
1546 SLiter = SplitLength.find(1);
1548 //txtSurname->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(0, SLiter->second), TRUE));
1549 AddressPOBox = PropertySeg2.Mid(0, SLiter->second);
1550 intPrevValue = intiter->second;
1552 } else if (intiter->first == 2){
1554 // Deal with extended address.
1556 SLiter = SplitLength.find(2);
1558 AddressExtended = PropertySeg2.Mid(intPrevValue, SLiter->second);
1559 //txtForename->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue, SLiter->second), TRUE));
1560 intPrevValue = intiter->second;
1562 } else if (intiter->first == 3){
1564 // Deal with street address.
1566 SLiter = SplitLength.find(3);
1568 AddressStreet = PropertySeg2.Mid(intPrevValue, SLiter->second);
1569 //txtOtherNames->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue, SLiter->second), TRUE));
1570 intPrevValue = intiter->second;
1572 } else if (intiter->first == 4){
1574 // Deal with locality
1576 SLiter = SplitLength.find(4);
1578 AddressLocality = PropertySeg2.Mid(intPrevValue, SLiter->second);
1579 //txtTitle->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue, SLiter->second), TRUE));
1580 intPrevValue = intiter->second;
1582 //txtSuffix->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue), TRUE));
1584 } else if (intiter->first == 5){
1586 // Deal with region.
1588 SLiter = SplitLength.find(5);
1590 AddressRegion = PropertySeg2.Mid(intPrevValue, SLiter->second);
1591 //txtTitle->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue, SLiter->second), TRUE));
1592 intPrevValue = intiter->second;
1594 //txtSuffix->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue), TRUE));
1596 } else if (intiter->first == 6){
1598 // Deal with post code.
1600 SLiter = SplitLength.find(6);
1602 AddressPostalCode = PropertySeg2.Mid(intPrevValue, SLiter->second);
1603 //txtTitle->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue, SLiter->second), TRUE));
1604 intPrevValue = intiter->second;
1606 // Deal with country.
1608 AddressCountry = PropertySeg2.Mid(intPrevValue, wxString::npos);
1609 //txtSuffix->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue), TRUE));
1617 // Add the data to the General/Home/Work address variables.
1619 CaptureString(&AddressStreet, FALSE);
1620 CaptureString(&AddressLocality, FALSE);
1621 CaptureString(&AddressRegion, FALSE);
1622 CaptureString(&AddressPostalCode, FALSE);
1623 CaptureString(&AddressCountry, FALSE);
1625 if (!PropertyTokens.IsEmpty()){
1627 AddressListTokens->insert(std::make_pair(*AddressCount, PropertyTokens));
1631 AddressListCountry->insert(std::make_pair(*AddressCount, AddressCountry));
1632 AddressList->insert(std::make_pair(*AddressCount, AddressStreet));
1633 AddressListTown->insert(std::make_pair(*AddressCount, AddressLocality));
1634 AddressListCounty->insert(std::make_pair(*AddressCount, AddressRegion));
1635 AddressListPostCode->insert(std::make_pair(*AddressCount, AddressPostalCode));
1639 AddressListType->insert(std::make_pair(*AddressCount, wxT("")));
1642 AddressListType->insert(std::make_pair(*AddressCount, wxT("home")));
1645 AddressListType->insert(std::make_pair(*AddressCount, wxT("work")));
1649 AddressListTokens->insert(std::make_pair(*AddressCount, PropertyTokens));
1653 void ContactDataObject::ProcessEmail(wxString PropertySeg1, wxString PropertySeg2, int *EmailCount){
1655 std::map<int, int> SplitPoints;
1656 std::map<int, int> SplitLength;
1658 int intPrevValue = 7;
1661 SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue);
1665 PropertyType PropType = PROPERTY_NONE;
1667 // Look for type before continuing.
1669 CheckType(&PropertySeg1, &SplitPoints, &SplitLength, &intPrevValue, &PropType);
1671 std::map<int, wxString> *EmailList = NULL;
1672 std::map<int, wxString> *EmailListType = NULL;
1673 std::map<int, wxString> *EmailListAltID = NULL;
1674 std::map<int, wxString> *EmailListPID = NULL;
1675 std::map<int, wxString> *EmailListTokens = NULL;
1676 std::map<int, int> *EmailListPref = NULL;
1680 EmailList = &GeneralEmailList;
1681 EmailListType = &GeneralEmailListType;
1682 EmailListAltID = &GeneralEmailListAltID;
1683 EmailListPID = &GeneralEmailListPID;
1684 EmailListTokens = &GeneralEmailListTokens;
1685 EmailListPref = &GeneralEmailListPref;
1688 EmailList = &HomeEmailList;
1689 EmailListType = &HomeEmailListType;
1690 EmailListAltID = &HomeEmailListAltID;
1691 EmailListPID = &HomeEmailListPID;
1692 EmailListTokens = &HomeEmailListTokens;
1693 EmailListPref = &HomeEmailListPref;
1696 EmailList = &BusinessEmailList;
1697 EmailListType = &BusinessEmailListType;
1698 EmailListAltID = &BusinessEmailListAltID;
1699 EmailListPID = &BusinessEmailListPID;
1700 EmailListTokens = &BusinessEmailListTokens;
1701 EmailListPref = &BusinessEmailListPref;
1707 std::map<int,int>::iterator SLiter;
1708 wxString PropertyData;
1709 wxString PropertyName;
1710 wxString PropertyValue;
1711 wxString PropertyTokens;
1712 bool FirstToken = TRUE;
1714 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
1715 intiter != SplitPoints.end(); ++intiter){
1717 SLiter = SplitLength.find(intiter->first);
1719 PropertyData = PropertySeg1.Mid(intPrevValue, (SLiter->second));
1721 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
1722 PropertyName = PropertyElement.GetNextToken();
1723 PropertyValue = PropertyElement.GetNextToken();
1725 intPrevValue = intiter->second;
1727 CaptureString(&PropertyValue, FALSE);
1729 // Process properties.
1731 if (PropertyName == wxT("ALTID")){
1733 EmailListAltID->erase(*EmailCount);
1734 EmailListAltID->insert(std::make_pair(*EmailCount, PropertyValue));
1736 } else if (PropertyName == wxT("PID")){
1738 EmailListPID->erase(*EmailCount);
1739 EmailListPID->insert(std::make_pair(*EmailCount, PropertyValue));
1741 } else if (PropertyName == wxT("PREF")){
1743 int PriorityNumber = 0;
1744 bool ValidNumber = TRUE;
1747 PriorityNumber = std::stoi(PropertyValue.ToStdString());
1750 catch(std::invalid_argument &e){
1751 ValidNumber = FALSE;
1754 if (ValidNumber == TRUE){
1756 EmailListPref->erase(*EmailCount);
1757 EmailListPref->insert(std::make_pair(*EmailCount, PriorityNumber));
1763 if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty() && PropertyName != wxT("TYPE")){
1765 if (FirstToken == TRUE){
1767 PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue);
1772 PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue);
1782 EmailList->insert(std::make_pair(*EmailCount, PropertySeg2));
1784 // Add the name token data.
1786 if (!PropertyTokens.IsEmpty()){
1788 EmailListTokens->insert(std::make_pair(*EmailCount, PropertyTokens));
1795 void ContactDataObject::ProcessIM(wxString PropertySeg1, wxString PropertySeg2, int *IMCount){
1797 std::map<int, int> SplitPoints;
1798 std::map<int, int> SplitLength;
1800 int intPrevValue = 6;
1803 SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue);
1807 PropertyType PropType = PROPERTY_NONE;
1809 // Look for type before continuing.
1811 CheckType(&PropertySeg1, &SplitPoints, &SplitLength, &intPrevValue, &PropType);
1813 std::map<int, wxString> *IMList = NULL;
1814 std::map<int, wxString> *IMListType = NULL;
1815 std::map<int, wxString> *IMListAltID = NULL;
1816 std::map<int, wxString> *IMListPID = NULL;
1817 std::map<int, wxString> *IMListTokens = NULL;
1818 std::map<int, wxString> *IMListMediatype = NULL;
1819 std::map<int, int> *IMListPref = NULL;
1823 IMList = &GeneralIMList;
1824 IMListType = &GeneralIMListType;
1825 IMListAltID = &GeneralIMListAltID;
1826 IMListPID = &GeneralIMListPID;
1827 IMListTokens = &GeneralIMListTokens;
1828 IMListMediatype = &GeneralIMListMediatype;
1829 IMListPref = &GeneralIMListPref;
1832 IMList = &HomeIMList;
1833 IMListType = &HomeIMListType;
1834 IMListAltID = &HomeIMListAltID;
1835 IMListPID = &HomeIMListPID;
1836 IMListTokens = &HomeIMListTokens;
1837 IMListMediatype = &HomeIMListMediatype;
1838 IMListPref = &HomeIMListPref;
1841 IMList = &BusinessIMList;
1842 IMListType = &BusinessIMListType;
1843 IMListAltID = &BusinessIMListAltID;
1844 IMListPID = &BusinessIMListPID;
1845 IMListTokens = &BusinessIMListTokens;
1846 IMListMediatype = &BusinessIMListMediatype;
1847 IMListPref = &BusinessIMListPref;
1853 std::map<int,int>::iterator SLiter;
1854 wxString PropertyData;
1855 wxString PropertyName;
1856 wxString PropertyValue;
1857 wxString PropertyTokens;
1858 bool FirstToken = TRUE;
1860 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
1861 intiter != SplitPoints.end(); ++intiter){
1863 SLiter = SplitLength.find(intiter->first);
1865 PropertyData = PropertySeg1.Mid(intPrevValue, (SLiter->second));
1867 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
1868 PropertyName = PropertyElement.GetNextToken();
1869 PropertyValue = PropertyElement.GetNextToken();
1871 intPrevValue = intiter->second;
1873 CaptureString(&PropertyValue, FALSE);
1875 // Process properties.
1877 if (PropertyName == wxT("ALTID")){
1879 IMListAltID->erase(*IMCount);
1880 IMListAltID->insert(std::make_pair(*IMCount, PropertyValue));
1882 } else if (PropertyName == wxT("PID")){
1884 IMListPID->erase(*IMCount);
1885 IMListPID->insert(std::make_pair(*IMCount, PropertyValue));
1887 } else if (PropertyName == wxT("MEDIATYPE")){
1889 IMListMediatype->erase(*IMCount);
1890 IMListMediatype->insert(std::make_pair(*IMCount, PropertyValue));
1892 } else if (PropertyName == wxT("PREF")){
1894 int PriorityNumber = 0;
1895 bool ValidNumber = TRUE;
1898 PriorityNumber = std::stoi(PropertyValue.ToStdString());
1901 catch(std::invalid_argument &e){
1902 ValidNumber = FALSE;
1905 if (ValidNumber == TRUE){
1907 IMListPref->erase(*IMCount);
1908 IMListPref->insert(std::make_pair(*IMCount, PriorityNumber));
1914 if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty() && PropertyName != wxT("TYPE")){
1916 if (FirstToken == TRUE){
1918 PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue);
1923 PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue);
1933 IMList->insert(std::make_pair(*IMCount, PropertySeg2));
1935 // Add the name token data.
1937 if (!PropertyTokens.IsEmpty()){
1939 IMListTokens->insert(std::make_pair(*IMCount, PropertyTokens));
1945 void ContactDataObject::ProcessTelephone(wxString PropertySeg1, wxString PropertySeg2, int *TelephoneCount){
1947 std::map<int, int> SplitPoints;
1948 std::map<int, int> SplitLength;
1949 std::map<int, int>::iterator SLiter;
1953 PropertyType PropType = PROPERTY_NONE;
1955 // Look for type before continuing.
1958 wxString TelTypeDetail;
1959 wxString PropertyData;
1960 wxString PropertyName;
1961 wxString PropertyValue;
1962 wxString PropertyTokens;
1964 std::map<int,int> TypeSplitPoints;
1965 std::map<int,int> TypeSplitLength;
1966 std::map<int,int>::iterator TSLiter;
1968 int intSplitSize = 0;
1969 int intSplitsFound = 0;
1970 int intSplitPoint = 0;
1972 int intPrevValue = 5;
1974 SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue);
1978 // Look for type before continuing.
1980 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
1981 intiter != SplitPoints.end(); ++intiter){
1983 SLiter = SplitLength.find(intiter->first);
1985 PropertyData = PropertySeg1.Mid(intPrevValue, (SLiter->second));
1987 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
1988 PropertyName = PropertyElement.GetNextToken();
1989 PropertyValue = PropertyElement.GetNextToken();
1991 intPrevValue = intiter->second;
1993 if (PropertyName == wxT("TYPE")){
1995 // Process each value in type and translate each
1998 // Strip out the quotes if they are there.
2000 size_t intPropertyValueLen = PropertyValue.Len();
2002 if (PropertyValue.Mid((intPropertyValueLen - 1), 1) == wxT("\"")){
2004 PropertyValue.Trim();
2005 PropertyValue.RemoveLast();
2009 if (PropertyValue.Mid(0, 1) == wxT("\"")){
2011 PropertyValue.Remove(0, 1);
2015 TelTypeDetail = PropertyValue;
2021 for (int i = 0; i <= intPropertyValueLen; i++){
2025 if (PropertyValue.Mid(i, 1) == wxT(",") && PropertyValue.Mid((i - 1), 1) != wxT("\\")){
2027 if (intSplitsFound == 0){
2029 TypeSplitPoints.insert(std::make_pair(intSplitsFound, intSplitPoint));
2030 TypeSplitLength.insert(std::make_pair(intSplitsFound, (intSplitSize - 1)));
2034 TypeSplitPoints.insert(std::make_pair(intSplitsFound, intSplitPoint));
2035 TypeSplitLength.insert(std::make_pair(intSplitsFound, intSplitSize));
2048 TypeSplitPoints.insert(std::make_pair(intSplitsFound, intSplitPoint));
2049 TypeSplitLength.insert(std::make_pair(intSplitsFound, intSplitSize));
2051 int intTypeSeek = 0;
2053 for (std::map<int, int>::iterator typeiter = TypeSplitPoints.begin();
2054 typeiter != TypeSplitPoints.end(); ++typeiter){
2056 wxString TypePropertyName;
2058 TSLiter = TypeSplitLength.find(typeiter->first);
2060 TypePropertyName = PropertyValue.Mid(typeiter->second, TSLiter->second);
2062 if (intTypeSeek == 0){
2067 TelTypeUI.Append(wxT(","));
2071 if (TypePropertyName == wxT("home")){
2073 PropType = PROPERTY_HOME;
2075 } else if (TypePropertyName == wxT("work")){
2077 PropType = PROPERTY_WORK;
2082 if (TypePropertyName == wxT("text")){
2084 TelTypeUI.Append(_("text"));
2087 } else if (TypePropertyName == wxT("voice")){
2089 TelTypeUI.Append(_("voice"));
2092 } else if (TypePropertyName == wxT("fax")){
2094 TelTypeUI.Append(_("fax"));
2097 } else if (TypePropertyName == wxT("cell")){
2099 TelTypeUI.Append(_("mobile"));
2102 } else if (TypePropertyName == wxT("video")){
2104 TelTypeUI.Append(_("video"));
2107 } else if (TypePropertyName == wxT("pager")){
2109 TelTypeUI.Append(_("pager"));
2112 } else if (TypePropertyName == wxT("textphone")){
2114 TelTypeUI.Append(_("textphone"));
2125 std::map<int, wxString> *TelephoneList = NULL;
2126 std::map<int, wxString> *TelephoneListType = NULL;
2127 std::map<int, wxString> *TelephoneListAltID = NULL;
2128 std::map<int, wxString> *TelephoneListPID = NULL;
2129 std::map<int, wxString> *TelephoneListTokens = NULL;
2130 std::map<int, wxString> *TelephoneListTypeInfo = NULL;
2131 std::map<int, int> *TelephoneListPref = NULL;
2135 TelephoneList = &GeneralTelephoneList;
2136 TelephoneListType = &GeneralTelephoneListType;
2137 TelephoneListAltID = &GeneralTelephoneListAltID;
2138 TelephoneListPID = &GeneralTelephoneListPID;
2139 TelephoneListTokens = &GeneralTelephoneListTokens;
2140 TelephoneListTypeInfo = &GeneralTelephoneListTypeInfo;
2141 TelephoneListPref = &GeneralTelephoneListPref;
2144 TelephoneList = &HomeTelephoneList;
2145 TelephoneListType = &HomeTelephoneListType;
2146 TelephoneListAltID = &HomeTelephoneListAltID;
2147 TelephoneListPID = &HomeTelephoneListPID;
2148 TelephoneListTokens = &HomeTelephoneListTokens;
2149 TelephoneListTypeInfo = &HomeTelephoneListTypeInfo;
2150 TelephoneListPref = &HomeTelephoneListPref;
2153 TelephoneList = &BusinessTelephoneList;
2154 TelephoneListType = &BusinessTelephoneListType;
2155 TelephoneListAltID = &BusinessTelephoneListAltID;
2156 TelephoneListPID = &BusinessTelephoneListPID;
2157 TelephoneListTokens = &BusinessTelephoneListTokens;
2158 TelephoneListTypeInfo = &BusinessTelephoneListTypeInfo;
2159 TelephoneListPref = &BusinessTelephoneListPref;
2163 // Process the properties.
2165 bool FirstToken = TRUE;
2168 SplitPoints.clear();
2169 SplitLength.clear();
2171 SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue);
2175 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
2176 intiter != SplitPoints.end(); ++intiter){
2178 SLiter = SplitLength.find(intiter->first);
2180 PropertyData = PropertySeg1.Mid(intPrevValue, (SLiter->second));
2182 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
2183 PropertyName = PropertyElement.GetNextToken();
2184 PropertyValue = PropertyElement.GetNextToken();
2186 intPrevValue = intiter->second;
2188 CaptureString(&PropertyValue, FALSE);
2190 // Process properties.
2192 if (PropertyName == wxT("ALTID")){
2194 TelephoneListAltID->erase(*TelephoneCount);
2195 TelephoneListAltID->insert(std::make_pair(*TelephoneCount, PropertyValue));
2197 } else if (PropertyName == wxT("PID")){
2199 TelephoneListPID->erase(*TelephoneCount);
2200 TelephoneListPID->insert(std::make_pair(*TelephoneCount, PropertyValue));
2202 } else if (PropertyName == wxT("PREF")){
2204 int PriorityNumber = 0;
2205 bool ValidNumber = TRUE;
2208 PriorityNumber = std::stoi(PropertyValue.ToStdString());
2211 catch(std::invalid_argument &e){
2212 ValidNumber = FALSE;
2215 if (ValidNumber == TRUE){
2217 TelephoneListPref->erase(*TelephoneCount);
2218 TelephoneListPref->insert(std::make_pair(*TelephoneCount, PriorityNumber));
2224 if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty() && PropertyName != wxT("TYPE")){
2226 if (FirstToken == TRUE){
2228 PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue);
2233 PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue);
2243 TelephoneList->insert(std::make_pair(*TelephoneCount, PropertySeg2));
2244 TelephoneListTypeInfo->insert(std::make_pair(*TelephoneCount, TelTypeUI));
2246 // Add the name token data.
2248 if (!PropertyTokens.IsEmpty()){
2250 TelephoneListTokens->insert(std::make_pair(*TelephoneCount, PropertyTokens));
2256 void SplitValues(wxString *PropertyLine,
2257 std::map<int,int> *SplitPoints,
2258 std::map<int,int> *SplitLength,
2261 size_t intPropertyLen = PropertyLine->Len();
2262 int intSplitsFound = 0;
2263 int intSplitSize = 0;
2264 int intSplitSeek = 0;
2266 for (int i = intSize; i <= intPropertyLen; i++){
2270 if (PropertyLine->Mid(i, 1) == wxT(";") &&
2271 PropertyLine->Mid((i - 1), 1) != wxT("\\")){
2273 if (intSplitsFound == 0){
2275 SplitLength->insert(std::make_pair(intSplitsFound, (intSplitSize)));
2279 SplitLength->insert(std::make_pair(intSplitsFound, (intSplitSize - 1)));
2283 SplitPoints->insert(std::make_pair(intSplitsFound, (i + 1)));
2293 if (intSplitsFound == 0){
2295 SplitPoints->insert(std::make_pair(intSplitsFound, (8 + 1)));
2296 SplitLength->insert(std::make_pair(intSplitsFound, intSplitSize));
2300 SplitPoints->insert(std::make_pair(intSplitsFound, (intSplitSeek + 1)));
2301 SplitLength->insert(std::make_pair(intSplitsFound, intSplitSize));
2307 void CheckType(wxString *PropertySeg1,
2308 std::map<int,int> *SplitPoints,
2309 std::map<int,int> *SplitLength,
2311 PropertyType *PropType){
2313 wxString PropertyData;
2314 wxString PropertyName;
2315 wxString PropertyValue;
2316 std::map<int,int>::iterator SLiter;
2318 for (std::map<int, int>::iterator intiter = SplitPoints->begin();
2319 intiter != SplitPoints->end(); ++intiter){
2321 SLiter = SplitLength->find(intiter->first);
2323 PropertyData = PropertySeg1->Mid(*intPrevValue, (SLiter->second));
2325 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
2326 PropertyName = PropertyElement.GetNextToken();
2327 PropertyValue = PropertyElement.GetNextToken();
2329 *intPrevValue = intiter->second;
2331 if (PropertyName == wxT("TYPE")){
2333 if (PropertyValue == wxT("work")){
2335 *PropType = PROPERTY_WORK;
2337 } else if (PropertyValue == wxT("home")){
2339 *PropType = PROPERTY_HOME;
2343 *PropType = PROPERTY_NONE;