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;
91 wxString PropertyLine;
92 wxString PropertySeg1;
93 wxString PropertySeg2;
94 wxString PropertyNextLine;
97 for (std::map<int,wxString>::iterator iter = ContactFileLines.begin();
98 iter != ContactFileLines.end(); ++iter){
100 ExtraLineSeek = TRUE;
106 PropertyLine.Clear();
107 PropertySeg1.Clear();
108 PropertySeg2.Clear();
111 ContactLine = iter->second;
113 while (ExtraLineSeek == TRUE){
115 // Check if there is extra data on the next line
116 // (indicated by space or tab at the start) and add data.
120 if (iter == ContactFileLines.end()){
127 PropertyNextLine = iter->second;
129 if (PropertyNextLine.Mid(0, 1) == wxT(" ") || PropertyNextLine.Mid(0, 1) == wxT("\t")){
131 PropertyNextLine.Remove(0, 1);
132 ContactLine.Append(PropertyNextLine);
137 ExtraLineSeek = FALSE;
143 ContactLineLen = ContactLine.Len();
145 // Make sure we are not in quotation mode.
146 // Make sure colon does not have \ or \\ before it.
148 for (int i = 0; i <= ContactLineLen; i++){
150 if ((ContactLine.Mid(i, 1) == wxT(";") || ContactLine.Mid(i, 1) == wxT(":")) && PropertyFind == TRUE){
152 PropertyFind = FALSE;
154 } else if (PropertyFind == TRUE){
156 Property.Append(ContactLine.Mid(i, 1));
160 if (ContactLine.Mid(i, 1) == wxT("\"")){
162 if (QuoteMode == TRUE){
174 if (ContactLine.Mid(i, 1) == wxT(":") && ContactLine.Mid((i - 1), 1) != wxT("\\") && QuoteMode == FALSE){
183 // Split that line at the point into two variables (ignore the colon).
185 PropertySeg1 = ContactLine.Mid(0, QuoteBreakPoint);
186 PropertySeg2 = ContactLine.Mid((QuoteBreakPoint + 1));
188 if (Property == wxT("KIND") && KindProcessed == FALSE){
190 ProcessKind(PropertySeg2);
192 } else if (Property == wxT("MEMBER")){
194 ProcessMember(PropertySeg1, PropertySeg2, &GroupCount);
197 } else if (Property == wxT("FN")){
199 ProcessFN(PropertySeg1, PropertySeg2, &FNCount);
202 } else if (Property == wxT("N") && NameProcessed == FALSE){
204 ProcessN(PropertySeg1, PropertySeg2);
205 NameProcessed = TRUE;
207 } else if (Property == wxT("NICKNAME")){
209 ProcessNickname(PropertySeg1, PropertySeg2, &NicknameCount);
212 } else if (Property == wxT("GENDER") && GenderProcessed == FALSE){
214 ProcessGender(PropertySeg1, PropertySeg2);
215 GenderProcessed = TRUE;
217 } else if (Property == wxT("BDAY") && BirthdayProcessed == FALSE){
219 ProcessBirthday(PropertySeg1, PropertySeg2);
220 BirthdayProcessed = TRUE;
222 } else if (Property == wxT("ANNIVERSARY") && AnniversaryProcessed == FALSE){
224 ProcessAnniversary(PropertySeg1, PropertySeg2);
225 AnniversaryProcessed = TRUE;
227 } else if (Property == wxT("TZ")){
229 ProcessTimeZone(PropertySeg1, PropertySeg2, &TimeZoneCount);
232 } else if (Property == wxT("ADR")){
234 ProcessAddress(PropertySeg1, PropertySeg2, &AddressCount);
237 } else if (Property == wxT("EMAIL")){
239 // See frmContactEditor-LoadEmail.cpp
241 ProcessEmail(PropertySeg1, PropertySeg2, &EmailCount);
244 } else if (Property == wxT("IMPP")){
246 // See frmContactEditor-LoadIM.cpp
248 ProcessIM(PropertySeg1, PropertySeg2, &IMCount);
255 return CONTACTLOAD_OK;
259 void ContactDataObject::ProcessKind(wxString KindType){
261 if (KindType == wxT("individual")){
263 ContactKind = CONTACTKIND_INDIVIDUAL;
265 } else if (KindType == wxT("group")){
267 ContactKind = CONTACTKIND_GROUP;
269 } else if (KindType == wxT("org")){
271 ContactKind = CONTACTKIND_ORGANISATION;
273 } else if (KindType == wxT("location")){
275 ContactKind = CONTACTKIND_LOCATION;
279 ContactKind = CONTACTKIND_NONE;
284 void ContactDataObject::ProcessMember(wxString PropertySeg1, wxString PropertySeg2, int *GroupCount){
286 std::map<int, int> SplitPoints;
287 std::map<int, int> SplitLength;
289 int intPrevValue = 8;
293 SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue);
297 wxString PropertyName;
298 wxString PropertyValue;
299 wxString PropertyData;
300 wxString PropertyTokens;
301 std::map<int,int>::iterator SLiter;
302 bool FirstToken = TRUE;
304 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
305 intiter != SplitPoints.end(); ++intiter){
307 SLiter = SplitLength.find(intiter->first);
309 PropertyData = PropertySeg1.Mid(intPrevValue, (SLiter->second));
311 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
312 PropertyName = PropertyElement.GetNextToken();
313 PropertyValue = PropertyElement.GetNextToken();
315 intPrevValue = intiter->second;
317 CaptureString(&PropertyValue, FALSE);
319 if (PropertyName == wxT("ALTID")){
321 GroupsListAltID.erase(*GroupCount);
322 GroupsListAltID.insert(std::make_pair(*GroupCount, PropertyValue));
324 } else if (PropertyName == wxT("PID")){
326 GroupsListPID.erase(*GroupCount);
327 GroupsListPID.insert(std::make_pair(*GroupCount, PropertyValue));
329 } else if (PropertyName == wxT("PREF")){
331 int PriorityNumber = 0;
332 bool ValidNumber = TRUE;
335 PriorityNumber = std::stoi(PropertyValue.ToStdString());
338 catch(std::invalid_argument &e){
342 if (ValidNumber == TRUE){
344 GroupsListPref.erase(*GroupCount);
345 GroupsListPref.insert(std::make_pair(*GroupCount, PriorityNumber));
349 } else if (PropertyName == wxT("MEDIATYPE")){
351 GroupsListMediaType.erase(*GroupCount);
352 GroupsListMediaType.insert(std::make_pair(*GroupCount, PropertyValue));
354 } else if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty()){
356 if (FirstToken == TRUE){
358 PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue);
363 PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue);
371 GroupsList.insert(std::make_pair(*GroupCount, PropertySeg2));
373 if (!PropertyTokens.IsEmpty()){
375 GroupsListTokens.insert(std::make_pair(*GroupCount, PropertyTokens));
382 void ContactDataObject::ProcessFN(wxString PropertySeg1, wxString PropertySeg2, int *FNCount){
384 std::map<int, int> SplitPoints;
385 std::map<int, int> SplitLength;
387 int intPrevValue = 4;
391 SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue);
395 wxString PropertyName;
396 wxString PropertyValue;
397 wxString PropertyData;
398 wxString PropertyTokens;
399 std::map<int,int>::iterator SLiter;
400 bool FirstToken = TRUE;
402 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
403 intiter != SplitPoints.end(); ++intiter){
405 SLiter = SplitLength.find(intiter->first);
407 PropertyData = PropertySeg1.Mid(intPrevValue, (SLiter->second));
409 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
410 PropertyName = PropertyElement.GetNextToken();
411 PropertyValue = PropertyElement.GetNextToken();
413 intPrevValue = intiter->second;
415 CaptureString(&PropertyValue, FALSE);
417 if (PropertyName == wxT("TYPE")){
419 if (!PropertyValue.IsEmpty() || PropertyValue == wxT("home") ||
420 PropertyValue == wxT("work") ){
422 FullNamesListType.erase(*FNCount);
423 FullNamesListType.insert(std::make_pair(*FNCount, PropertyValue));
427 } else if (PropertyName == wxT("LANGUAGE")){
429 FullNamesListLanguage.erase(*FNCount);
430 FullNamesListLanguage.insert(std::make_pair(*FNCount, PropertyValue));
432 } else if (PropertyName == wxT("ALTID")){
434 FullNamesListAltID.erase(*FNCount);
435 FullNamesListAltID.insert(std::make_pair(*FNCount, PropertyValue));
437 } else if (PropertyName == wxT("PID")){
439 FullNamesListPID.erase(*FNCount);
440 FullNamesListPID.insert(std::make_pair(*FNCount, PropertyValue));
442 } else if (PropertyName == wxT("PREF")){
444 int PriorityNumber = 0;
445 bool ValidNumber = TRUE;
448 PriorityNumber = std::stoi(PropertyValue.ToStdString());
451 catch(std::invalid_argument &e){
455 if (ValidNumber == TRUE){
457 FullNamesListPref.erase(*FNCount);
458 FullNamesListPref.insert(std::make_pair(*FNCount, PriorityNumber));
462 } else if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty()){
464 if (FirstToken == TRUE){
466 PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue);
471 PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue);
479 FullNamesList.insert(std::make_pair(*FNCount, PropertySeg2));
481 if (!PropertyTokens.IsEmpty()){
483 FullNamesListTokens.insert(std::make_pair(*FNCount, PropertyTokens));
489 void ContactDataObject::ProcessN(wxString PropertySeg1, wxString PropertySeg2){
491 std::map<int, int> SplitPoints;
492 std::map<int, int> SplitLength;
494 int intPrevValue = 3;
498 SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue);
502 wxString PropertyName;
503 wxString PropertyValue;
504 wxString PropertyData;
505 wxString PropertyTokens;
506 std::map<int,int>::iterator SLiter;
507 bool FirstToken = TRUE;
509 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
510 intiter != SplitPoints.end(); ++intiter){
512 SLiter = SplitLength.find(intiter->first);
514 PropertyData = PropertySeg1.Mid(intPrevValue, (SLiter->second));
516 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
517 PropertyName = PropertyElement.GetNextToken();
518 PropertyValue = PropertyElement.GetNextToken();
520 intPrevValue = intiter->second;
522 CaptureString(&PropertyValue, FALSE);
524 if (PropertyName == wxT("ALTID")){
526 NameAltID = PropertyValue;
528 } else if (PropertyName == wxT("LANGUAGE")){
530 NameLanguage = PropertyValue;
532 } else if (PropertyName == wxT("SORT-AS")){
534 if (PropertyValue.Left(1) == wxT("\"") && PropertyValue.Right(1) == wxT("\"") &&
535 PropertyValue.Len() >= 3){
536 NameDisplayAs = PropertyValue.Mid(1, (PropertyValue.Len() - 2));
539 } else if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty()){
541 if (FirstToken == TRUE){
543 PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue);
548 PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue);
556 // Split the name data.
558 int intSplitSeek = 0;
559 int intSplitsFound = 0;
560 int intSplitSize = 0;
561 int intPropertyLen = PropertySeg2.Len();
563 std::map<int,wxString> NameValues;
566 for (int i = 0; i <= intPropertyLen; i++){
568 if (PropertySeg2.Mid(i, 1) == wxT(";") && PropertySeg2.Mid((i - 1), 1) != wxT("\\")){
570 NameValues.insert(std::make_pair(++intSplitsFound, PropertySeg2.Mid(intSplitSeek, intSplitSize)));
575 if (intSplitsFound == 4){
577 NameValues.insert(std::make_pair(++intSplitsFound, PropertySeg2.Mid(intSplitSeek, wxString::npos)));
591 // Split the data into several parts.
593 for (std::map<int, wxString>::iterator iter = NameValues.begin();
594 iter != NameValues.end(); ++iter){
596 if (iter->first == 1){
598 // Deal with family name.
600 NameSurname = iter->second;
602 } else if (iter->first == 2){
604 // Deal with given names.
606 NameForename = iter->second;
608 } else if (iter->first == 3){
610 // Deal with additional names.
612 NameOtherNames = iter->second;
614 } else if (iter->first == 4){
616 // Deal with honorifix prefixes and suffixes.
618 NameTitle = iter->second;
622 if (iter == NameValues.end()){
628 NameSuffix = iter->second;
634 // Add the name token data.
636 if (!PropertyTokens.IsEmpty()){
638 NameTokens = PropertyTokens;
644 void ContactDataObject::ProcessNickname(wxString PropertySeg1, wxString PropertySeg2, int *NicknameCount){
646 std::map<int, int> SplitPoints;
647 std::map<int, int> SplitLength;
649 int intPrevValue = 10;
652 SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue);
656 PropertyType PropType = PROPERTY_NONE;
658 // Look for type before continuing.
660 CheckType(&PropertySeg1, &SplitPoints, &SplitLength, &intPrevValue, &PropType);
664 std::map<int, wxString> *NicknamesList = NULL;
665 std::map<int, wxString> *NicknamesListType = NULL;
666 std::map<int, wxString> *NicknamesListLanguage = NULL;
667 std::map<int, wxString> *NicknamesListAltID = NULL;
668 std::map<int, wxString> *NicknamesListPID = NULL;
669 std::map<int, wxString> *NicknamesListTokens = NULL;
670 std::map<int, int> *NicknamesListPref = NULL;
674 NicknamesList = &GeneralNicknamesList;
675 NicknamesListType = &GeneralNicknamesListType;
676 NicknamesListLanguage = &GeneralNicknamesListLanguage;
677 NicknamesListAltID = &GeneralNicknamesListAltID;
678 NicknamesListPID = &GeneralNicknamesListPID;
679 NicknamesListTokens = &GeneralNicknamesListTokens;
680 NicknamesListPref = &GeneralNicknamesListPref;
683 NicknamesList = &HomeNicknamesList;
684 NicknamesListType = &HomeNicknamesListType;
685 NicknamesListLanguage = &HomeNicknamesListLanguage;
686 NicknamesListAltID = &HomeNicknamesListAltID;
687 NicknamesListPID = &HomeNicknamesListPID;
688 NicknamesListTokens = &HomeNicknamesListTokens;
689 NicknamesListPref = &HomeNicknamesListPref;
692 NicknamesList = &BusinessNicknamesList;
693 NicknamesListType = &BusinessNicknamesListType;
694 NicknamesListLanguage = &BusinessNicknamesListLanguage;
695 NicknamesListAltID = &BusinessNicknamesListAltID;
696 NicknamesListPID = &BusinessNicknamesListPID;
697 NicknamesListTokens = &BusinessNicknamesListTokens;
698 NicknamesListPref = &BusinessNicknamesListPref;
702 std::map<int, int>::iterator SLiter;
703 wxString PropertyData;
704 wxString PropertyName;
705 wxString PropertyValue;
706 wxString PropertyTokens;
707 bool FirstToken = TRUE;
709 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
710 intiter != SplitPoints.end(); ++intiter){
712 SLiter = SplitLength.find(intiter->first);
714 PropertyData = PropertySeg1.Mid(intPrevValue, (SLiter->second));
716 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
717 PropertyName = PropertyElement.GetNextToken();
718 PropertyValue = PropertyElement.GetNextToken();
720 intPrevValue = intiter->second;
722 CaptureString(&PropertyValue, FALSE);
724 if (PropertyName == wxT("ALTID")){
726 NicknamesListAltID->erase(*NicknameCount);
727 NicknamesListAltID->insert(std::make_pair(*NicknameCount, PropertyValue));
729 } else if (PropertyName == wxT("PID")){
731 NicknamesListPID->erase(*NicknameCount);
732 NicknamesListPID->insert(std::make_pair(*NicknameCount, PropertyValue));
734 } else if (PropertyName == wxT("PREF")){
736 int PriorityNumber = 0;
737 bool ValidNumber = TRUE;
740 PriorityNumber = std::stoi(PropertyValue.ToStdString());
743 catch(std::invalid_argument &e){
747 if (ValidNumber == TRUE){
749 NicknamesListPref->erase(*NicknameCount);
750 NicknamesListPref->insert(std::make_pair(*NicknameCount, PriorityNumber));
754 } else if (PropertyName == wxT("LANGUAGE")){
756 NicknamesListLanguage->erase(*NicknameCount);
757 NicknamesListLanguage->insert(std::make_pair(*NicknameCount, PropertyValue));
761 // Something else we don't know about so append
762 // to the tokens variable.
764 if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty() && PropertyName != wxT("TYPE")){
766 if (FirstToken == TRUE){
768 PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue);
773 PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue);
783 NicknamesList->insert(std::make_pair(*NicknameCount, PropertySeg2));
785 // Add the name token data.
787 if (!PropertyTokens.IsEmpty()){
789 NicknamesListTokens->insert(std::make_pair(*NicknameCount, PropertyTokens));
795 void ContactDataObject::ProcessGender(wxString PropertySeg1, wxString PropertySeg2){
797 std::map<int, int> SplitPoints;
798 std::map<int, int> SplitLength;
799 std::map<int, int>::iterator SLiter;
800 wxString PropertyData;
801 wxString PropertyName;
802 wxString PropertyValue;
803 wxString PropertyTokens;
804 bool FirstToken = TRUE;
805 int intPrevValue = 8;
807 SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue);
811 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
812 intiter != SplitPoints.end(); ++intiter){
814 SLiter = SplitLength.find(intiter->first);
816 PropertyData = PropertySeg1.Mid(intPrevValue, (SLiter->second));
818 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
819 PropertyName = PropertyElement.GetNextToken();
820 PropertyValue = PropertyElement.GetNextToken();
822 intPrevValue = intiter->second;
824 // Process properties.
826 size_t intPropertyValueLen = PropertyValue.Len();
828 if (PropertyValue.Mid((intPropertyValueLen - 1), 1) == wxT("\"")){
830 PropertyValue.Trim();
831 PropertyValue.RemoveLast();
835 if (PropertyValue.Mid(0, 1) == wxT("\"")){
837 PropertyValue.Remove(0, 1);
841 if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty()){
843 if (FirstToken == TRUE){
845 PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue);
850 PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue);
858 wxStringTokenizer GenderData (PropertySeg2, wxT(";"));
860 wxString GenderComponent;
862 if (GenderData.CountTokens() >= 2){
864 Gender = GenderData.GetNextToken();
865 GenderDetails = GenderData.GetString();
867 CaptureString(&GenderDetails, FALSE);
871 Gender = GenderData.GetNextToken();
875 if (!PropertyTokens.IsEmpty()){
877 GenderTokens = PropertyTokens;
883 void ContactDataObject::ProcessBirthday(wxString PropertySeg1, wxString PropertySeg2){
885 // Process date. Preserve the remainder in the string.
887 std::map<int, int> SplitPoints;
888 std::map<int, int> SplitLength;
889 std::map<int, int>::iterator SLiter;
890 wxString PropertyData;
891 wxString PropertyName;
892 wxString PropertyValue;
893 wxString PropertyTokens;
894 bool BirthdayText = FALSE;
895 int intPrevValue = 6;
897 SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue);
901 // Look for type before continuing.
903 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
904 intiter != SplitPoints.end(); ++intiter){
906 SLiter = SplitLength.find(intiter->first);
908 PropertyData = PropertySeg1.Mid(intPrevValue, SLiter->second);
910 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
911 PropertyName = PropertyElement.GetNextToken();
912 PropertyValue = PropertyElement.GetNextToken();
914 intPrevValue = intiter->second;
916 if (PropertyName == wxT("VALUE") && PropertyValue == wxT("text") && BirthdayText == FALSE){
918 CaptureString(&PropertySeg2, FALSE);
919 Birthday = PropertySeg2;
926 // Setup blank lines for later on.
929 bool FirstToken = TRUE;
931 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
932 intiter != SplitPoints.end(); ++intiter){
934 SLiter = SplitLength.find(intiter->first);
936 PropertyData = PropertySeg1.Mid(intPrevValue, SLiter->second);
938 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
939 PropertyName = PropertyElement.GetNextToken();
940 PropertyValue = PropertyElement.GetNextToken();
942 intPrevValue = intiter->second;
944 // Process properties.
946 CaptureString(&PropertyValue, FALSE);
948 if (PropertyValue.Mid((PropertyValue.Len() - 1), 1) == wxT("\"")){
950 PropertyValue.Trim();
951 PropertyValue.RemoveLast();
955 if (PropertyValue.Mid(0, 1) == wxT("\"")){
957 PropertyValue.Remove(0, 1);
961 if (PropertyName == wxT("ALTID")){
963 BirthdayAltID = PropertyValue;
965 } else if (PropertyName == wxT("CALSCALE")){
967 BirthdayCalScale = PropertyValue;
969 } else if (PropertyName != wxT("VALUE")) {
971 // Something else we don't know about so append
972 // to the tokens variable.
974 if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty()){
976 if (FirstToken == TRUE){
978 PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue);
983 PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue);
993 // Add the data to the variables and form.
995 if (BirthdayText == FALSE){
997 Birthday = PropertySeg2;
1001 if (!PropertyTokens.IsEmpty()){
1003 BirthdayTokens = PropertyTokens;
1009 void ContactDataObject::ProcessAnniversary(wxString PropertySeg1, wxString PropertySeg2){
1011 // Process date. Preserve the remainder in the string.
1013 std::map<int, int> SplitPoints;
1014 std::map<int, int> SplitLength;
1015 std::map<int, int>::iterator SLiter;
1016 wxString PropertyData;
1017 wxString PropertyName;
1018 wxString PropertyValue;
1019 wxString PropertyTokens;
1020 bool AnniversaryText = FALSE;
1021 int intPrevValue = 13;
1023 SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue);
1027 // Look for type before continuing.
1029 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
1030 intiter != SplitPoints.end(); ++intiter){
1032 SLiter = SplitLength.find(intiter->first);
1034 PropertyData = PropertySeg1.Mid(intPrevValue, SLiter->second);
1036 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
1037 PropertyName = PropertyElement.GetNextToken();
1038 PropertyValue = PropertyElement.GetNextToken();
1040 intPrevValue = intiter->second;
1042 if (PropertyName == wxT("VALUE") && PropertyValue == wxT("text") && AnniversaryText == FALSE){
1044 CaptureString(&PropertySeg2, FALSE);
1045 Anniversary = PropertySeg2;
1046 AnniversaryText = TRUE;
1052 // Setup blank lines for later on.
1055 bool FirstToken = TRUE;
1057 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
1058 intiter != SplitPoints.end(); ++intiter){
1060 SLiter = SplitLength.find(intiter->first);
1062 PropertyData = PropertySeg1.Mid(intPrevValue, SLiter->second);
1064 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
1065 PropertyName = PropertyElement.GetNextToken();
1066 PropertyValue = PropertyElement.GetNextToken();
1068 intPrevValue = intiter->second;
1070 // Process properties.
1072 CaptureString(&PropertyValue, FALSE);
1074 if (PropertyValue.Mid((PropertyValue.Len() - 1), 1) == wxT("\"")){
1076 PropertyValue.Trim();
1077 PropertyValue.RemoveLast();
1081 if (PropertyValue.Mid(0, 1) == wxT("\"")){
1083 PropertyValue.Remove(0, 1);
1087 if (PropertyName == wxT("ALTID")){
1089 AnniversaryAltID = PropertyValue;
1091 } else if (PropertyName == wxT("CALSCALE")){
1093 AnniversaryCalScale = PropertyValue;
1095 } else if (PropertyName != wxT("VALUE")) {
1097 // Something else we don't know about so append
1098 // to the tokens variable.
1100 if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty()){
1102 if (FirstToken == TRUE){
1104 PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue);
1109 PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue);
1119 // Add the data to the variables and form.
1121 if (AnniversaryText == FALSE){
1123 Anniversary = PropertySeg2;
1127 if (!PropertyTokens.IsEmpty()){
1129 AnniversaryTokens = PropertyTokens;
1135 void ContactDataObject::ProcessTimeZone(wxString PropertySeg1, wxString PropertySeg2, int *TimeZoneCount){
1137 std::map<int, int> SplitPoints;
1138 std::map<int, int> SplitLength;
1140 int intPrevValue = 4;
1143 SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue);
1147 PropertyType PropType = PROPERTY_NONE;
1149 // Look for type before continuing.
1151 CheckType(&PropertySeg1, &SplitPoints, &SplitLength, &intPrevValue, &PropType);
1155 std::map<int, wxString> *TZList = NULL;
1156 std::map<int, wxString> *TZListType = NULL;
1157 std::map<int, wxString> *TZListMediatype = NULL;
1158 std::map<int, wxString> *TZListAltID = NULL;
1159 std::map<int, wxString> *TZListPID = NULL;
1160 std::map<int, wxString> *TZListTokens = NULL;
1161 std::map<int, int> *TZListPref = NULL;
1165 TZList = &GeneralTZList;
1166 TZListType = &GeneralTZListType;
1167 TZListMediatype = &GeneralTZListMediatype;
1168 TZListAltID = &GeneralTZListAltID;
1169 TZListPID = &GeneralTZListPID;
1170 TZListTokens = &GeneralTZListTokens;
1171 TZListPref = &GeneralTZListPref;
1174 TZList = &HomeTZList;
1175 TZListType = &HomeTZListType;
1176 TZListMediatype = &HomeTZListMediatype;
1177 TZListAltID = &HomeTZListAltID;
1178 TZListPID = &HomeTZListPID;
1179 TZListTokens = &HomeTZListTokens;
1180 TZListPref = &HomeTZListPref;
1183 TZList = &BusinessTZList;
1184 TZListType = &BusinessTZListType;
1185 TZListMediatype = &BusinessTZListMediatype;
1186 TZListAltID = &BusinessTZListAltID;
1187 TZListPID = &BusinessTZListPID;
1188 TZListTokens = &BusinessTZListTokens;
1189 TZListPref = &BusinessTZListPref;
1193 std::map<int, int>::iterator SLiter;
1194 wxString PropertyData;
1195 wxString PropertyName;
1196 wxString PropertyValue;
1197 wxString PropertyTokens;
1198 bool FirstToken = TRUE;
1200 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
1201 intiter != SplitPoints.end(); ++intiter){
1203 SLiter = SplitLength.find(intiter->first);
1205 PropertyData = PropertySeg1.Mid(intPrevValue, (SLiter->second));
1207 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
1208 PropertyName = PropertyElement.GetNextToken();
1209 PropertyValue = PropertyElement.GetNextToken();
1211 intPrevValue = intiter->second;
1213 CaptureString(&PropertyValue, FALSE);
1215 if (PropertyName == wxT("ALTID")){
1217 TZListAltID->erase(*TimeZoneCount);
1218 TZListAltID->insert(std::make_pair(*TimeZoneCount, PropertyValue));
1220 } else if (PropertyName == wxT("PID")){
1222 TZListPID->erase(*TimeZoneCount);
1223 TZListPID->insert(std::make_pair(*TimeZoneCount, PropertyValue));
1225 } else if (PropertyName == wxT("PREF")){
1227 int PriorityNumber = 0;
1228 bool ValidNumber = TRUE;
1231 PriorityNumber = std::stoi(PropertyValue.ToStdString());
1234 catch(std::invalid_argument &e){
1235 ValidNumber = FALSE;
1238 if (ValidNumber == TRUE){
1240 TZListPref->erase(*TimeZoneCount);
1241 TZListPref->insert(std::make_pair(*TimeZoneCount, PriorityNumber));
1245 } else if (PropertyName == wxT("MEDIATYPE")){
1247 TZListMediatype->erase(*TimeZoneCount);
1248 TZListMediatype->insert(std::make_pair(*TimeZoneCount, PropertyValue));
1252 // Something else we don't know about so append
1253 // to the tokens variable.
1255 if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty() && PropertyName != wxT("TYPE")){
1257 if (FirstToken == TRUE){
1259 PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue);
1264 PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue);
1274 TZList->insert(std::make_pair(*TimeZoneCount, PropertySeg2));
1276 // Add the name token data.
1278 if (!PropertyTokens.IsEmpty()){
1280 TZListTokens->insert(std::make_pair(*TimeZoneCount, PropertyTokens));
1287 void ContactDataObject::ProcessAddress(wxString PropertySeg1, wxString PropertySeg2, int *AddressCount){
1289 size_t intPropertyLen = PropertySeg1.Len();
1290 std::map<int, int> SplitPoints;
1291 std::map<int, int> SplitLength;
1292 std::map<int, int>::iterator SLiter;
1293 wxString PropertyData;
1294 wxString PropertyName;
1295 wxString PropertyValue;
1296 wxString PropertyTokens;
1297 wxString AddressLabel;
1298 wxString AddressLang;
1299 wxString AddressAltID;
1300 wxString AddressPID;
1301 wxString AddressTokens;
1302 wxString AddressGeo;
1303 wxString AddressTimezone;
1304 wxString AddressType;
1305 wxString AddressMediatype;
1306 wxString AddressPOBox;
1307 wxString AddressExtended;
1308 wxString AddressStreet;
1309 wxString AddressLocality;
1310 wxString AddressCity;
1311 wxString AddressRegion;
1312 wxString AddressPostalCode;
1313 wxString AddressCountry;
1314 bool FirstToken = TRUE;
1315 int intSplitsFound = 0;
1316 int intSplitSize = 0;
1317 int intPrevValue = 5;
1322 SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue);
1326 PropertyType PropType = PROPERTY_NONE;
1328 // Look for type before continuing.
1330 CheckType(&PropertySeg1, &SplitPoints, &SplitLength, &intPrevValue, &PropType);
1334 std::map<int, wxString> *AddressList = NULL;
1335 std::map<int, wxString> *AddressListTown = NULL;
1336 std::map<int, wxString> *AddressListCounty = NULL;
1337 std::map<int, wxString> *AddressListPostCode = NULL;
1338 std::map<int, wxString> *AddressListCountry = NULL;
1339 std::map<int, wxString> *AddressListLabel = NULL;
1340 std::map<int, wxString> *AddressListLang = NULL;
1341 std::map<int, wxString> *AddressListAltID = NULL;
1342 std::map<int, wxString> *AddressListPID = NULL;
1343 std::map<int, wxString> *AddressListTokens = NULL;
1344 std::map<int, wxString> *AddressListGeo = NULL;
1345 std::map<int, wxString> *AddressListTimezone = NULL;
1346 std::map<int, wxString> *AddressListType = NULL;
1347 std::map<int, wxString> *AddressListMediatype = NULL;
1348 std::map<int, int> *AddressListPref = NULL;
1352 AddressList = &GeneralAddressList;
1353 AddressListTown = &GeneralAddressListTown;
1354 AddressListCounty = &GeneralAddressListCounty;
1355 AddressListPostCode = &GeneralAddressListPostCode;
1356 AddressListCountry = &GeneralAddressListCountry;
1357 AddressListLabel = &GeneralAddressListLabel;
1358 AddressListLang = &GeneralAddressListLang;
1359 AddressListAltID = &GeneralAddressListAltID;
1360 AddressListPID = &GeneralAddressListPID;
1361 AddressListTokens = &GeneralAddressListTokens;
1362 AddressListGeo = &GeneralAddressListGeo;
1363 AddressListTimezone = &GeneralAddressListTimezone;
1364 AddressListType = &GeneralAddressListType;
1365 AddressListMediatype = &GeneralAddressListMediatype;
1366 AddressListPref = &GeneralAddressListPref;
1369 AddressList = &HomeAddressList;
1370 AddressListTown = &HomeAddressListTown;
1371 AddressListCounty = &HomeAddressListCounty;
1372 AddressListPostCode = &HomeAddressListPostCode;
1373 AddressListCountry = &HomeAddressListCountry;
1374 AddressListLabel = &HomeAddressListLabel;
1375 AddressListLang = &HomeAddressListLang;
1376 AddressListAltID = &HomeAddressListAltID;
1377 AddressListPID = &HomeAddressListPID;
1378 AddressListTokens = &HomeAddressListTokens;
1379 AddressListGeo = &HomeAddressListGeo;
1380 AddressListTimezone = &HomeAddressListTimezone;
1381 AddressListType = &HomeAddressListType;
1382 AddressListMediatype = &HomeAddressListMediatype;
1383 AddressListPref = &HomeAddressListPref;
1386 AddressList = &BusinessAddressList;
1387 AddressListTown = &BusinessAddressListTown;
1388 AddressListCounty = &BusinessAddressListCounty;
1389 AddressListPostCode = &BusinessAddressListPostCode;
1390 AddressListCountry = &BusinessAddressListCountry;
1391 AddressListLabel = &BusinessAddressListLabel;
1392 AddressListLang = &BusinessAddressListLang;
1393 AddressListAltID = &BusinessAddressListAltID;
1394 AddressListPID = &BusinessAddressListPID;
1395 AddressListTokens = &BusinessAddressListTokens;
1396 AddressListGeo = &BusinessAddressListGeo;
1397 AddressListTimezone = &BusinessAddressListTimezone;
1398 AddressListType = &BusinessAddressListType;
1399 AddressListMediatype = &BusinessAddressListMediatype;
1400 AddressListPref = &BusinessAddressListPref;
1406 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
1407 intiter != SplitPoints.end(); ++intiter){
1409 SLiter = SplitLength.find(intiter->first);
1411 PropertyData = PropertySeg1.Mid(intPrevValue, (SLiter->second));
1413 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
1414 PropertyName = PropertyElement.GetNextToken();
1415 PropertyValue = PropertyElement.GetNextToken();
1417 intPrevValue = intiter->second;
1419 CaptureString(&PropertyValue, FALSE);
1421 // Process properties.
1423 if (PropertyName == wxT("LABEL")){
1425 AddressListLabel->erase(*AddressCount);
1426 AddressListLabel->insert(std::make_pair(*AddressCount, PropertyValue));
1428 } else if (PropertyName == wxT("LANGUAGE")){
1430 AddressListLang->erase(*AddressCount);
1431 AddressListLang->insert(std::make_pair(*AddressCount, PropertyValue));
1433 } else if (PropertyName == wxT("ALTID")){
1435 AddressListAltID->erase(*AddressCount);
1436 AddressListAltID->insert(std::make_pair(*AddressCount, PropertyValue));
1438 } else if (PropertyName == wxT("PID")){
1440 AddressListPID->erase(*AddressCount);
1441 AddressListPID->insert(std::make_pair(*AddressCount, PropertyValue));
1443 } else if (PropertyName == wxT("GEO")){
1445 AddressListGeo->erase(*AddressCount);
1446 AddressListGeo->insert(std::make_pair(*AddressCount, PropertyValue));
1448 } else if (PropertyName == wxT("TZ")){
1450 AddressListTimezone->erase(*AddressCount);
1451 AddressListTimezone->insert(std::make_pair(*AddressCount, PropertyValue));
1453 } else if (PropertyName == wxT("MEDIATYPE")){
1455 AddressListMediatype->erase(*AddressCount);
1456 AddressListMediatype->insert(std::make_pair(*AddressCount, PropertyValue));
1458 } else if (PropertyName == wxT("PREF")){
1460 int PriorityNumber = 0;
1461 bool ValidNumber = TRUE;
1464 PriorityNumber = std::stoi(PropertyValue.ToStdString());
1467 catch(std::invalid_argument &e){
1468 ValidNumber = FALSE;
1471 if (ValidNumber == TRUE){
1473 AddressListPref->erase(*AddressCount);
1474 AddressListPref->insert(std::make_pair(*AddressCount, PriorityNumber));
1480 if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty() && PropertyName != wxT("TYPE")){
1482 if (FirstToken == TRUE){
1484 PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue);
1489 PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue);
1499 // Split the address.
1501 //std::map<int, int>::iterator SLiter;
1502 intPropertyLen = PropertySeg2.Len();
1503 SplitPoints.clear();
1504 SplitLength.clear();
1509 for (int i = 0; i <= intPropertyLen; i++){
1513 if (PropertySeg2.Mid(i, 1) == wxT(";") && PropertySeg2.Mid((i - 1), 1) != wxT("\\")){
1516 SplitPoints.insert(std::make_pair(intSplitsFound, (i + 1)));
1518 if (intSplitsFound == 6){
1520 SplitLength.insert(std::make_pair(intSplitsFound, (intSplitSize - 1)));
1525 SplitLength.insert(std::make_pair(intSplitsFound, (intSplitSize - 1)));
1535 // Split the data into several parts.
1537 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
1538 intiter != SplitPoints.end(); ++intiter){
1540 if (intiter->first == 1){
1542 // Deal with PO Box.
1544 SLiter = SplitLength.find(1);
1546 //txtSurname->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(0, SLiter->second), TRUE));
1547 AddressPOBox = PropertySeg2.Mid(0, SLiter->second);
1548 intPrevValue = intiter->second;
1550 } else if (intiter->first == 2){
1552 // Deal with extended address.
1554 SLiter = SplitLength.find(2);
1556 AddressExtended = PropertySeg2.Mid(intPrevValue, SLiter->second);
1557 //txtForename->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue, SLiter->second), TRUE));
1558 intPrevValue = intiter->second;
1560 } else if (intiter->first == 3){
1562 // Deal with street address.
1564 SLiter = SplitLength.find(3);
1566 AddressStreet = PropertySeg2.Mid(intPrevValue, SLiter->second);
1567 //txtOtherNames->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue, SLiter->second), TRUE));
1568 intPrevValue = intiter->second;
1570 } else if (intiter->first == 4){
1572 // Deal with locality
1574 SLiter = SplitLength.find(4);
1576 AddressLocality = PropertySeg2.Mid(intPrevValue, SLiter->second);
1577 //txtTitle->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue, SLiter->second), TRUE));
1578 intPrevValue = intiter->second;
1580 //txtSuffix->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue), TRUE));
1582 } else if (intiter->first == 5){
1584 // Deal with region.
1586 SLiter = SplitLength.find(5);
1588 AddressRegion = PropertySeg2.Mid(intPrevValue, SLiter->second);
1589 //txtTitle->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue, SLiter->second), TRUE));
1590 intPrevValue = intiter->second;
1592 //txtSuffix->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue), TRUE));
1594 } else if (intiter->first == 6){
1596 // Deal with post code.
1598 SLiter = SplitLength.find(6);
1600 AddressPostalCode = PropertySeg2.Mid(intPrevValue, SLiter->second);
1601 //txtTitle->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue, SLiter->second), TRUE));
1602 intPrevValue = intiter->second;
1604 // Deal with country.
1606 AddressCountry = PropertySeg2.Mid(intPrevValue, wxString::npos);
1607 //txtSuffix->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue), TRUE));
1615 // Add the data to the General/Home/Work address variables.
1617 CaptureString(&AddressStreet, FALSE);
1618 CaptureString(&AddressLocality, FALSE);
1619 CaptureString(&AddressRegion, FALSE);
1620 CaptureString(&AddressPostalCode, FALSE);
1621 CaptureString(&AddressCountry, FALSE);
1623 if (!PropertyTokens.IsEmpty()){
1625 AddressListTokens->insert(std::make_pair(*AddressCount, PropertyTokens));
1629 AddressListCountry->insert(std::make_pair(*AddressCount, AddressCountry));
1630 AddressList->insert(std::make_pair(*AddressCount, AddressStreet));
1631 AddressListTown->insert(std::make_pair(*AddressCount, AddressLocality));
1632 AddressListCounty->insert(std::make_pair(*AddressCount, AddressRegion));
1633 AddressListPostCode->insert(std::make_pair(*AddressCount, AddressPostalCode));
1637 AddressListType->insert(std::make_pair(*AddressCount, wxT("")));
1640 AddressListType->insert(std::make_pair(*AddressCount, wxT("home")));
1643 AddressListType->insert(std::make_pair(*AddressCount, wxT("work")));
1647 AddressListTokens->insert(std::make_pair(*AddressCount, PropertyTokens));
1651 void ContactDataObject::ProcessEmail(wxString PropertySeg1, wxString PropertySeg2, int *EmailCount){
1653 std::map<int, int> SplitPoints;
1654 std::map<int, int> SplitLength;
1656 int intPrevValue = 7;
1659 SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue);
1663 PropertyType PropType = PROPERTY_NONE;
1665 // Look for type before continuing.
1667 CheckType(&PropertySeg1, &SplitPoints, &SplitLength, &intPrevValue, &PropType);
1669 std::map<int, wxString> *EmailList = NULL;
1670 std::map<int, wxString> *EmailListType = NULL;
1671 std::map<int, wxString> *EmailListAltID = NULL;
1672 std::map<int, wxString> *EmailListPID = NULL;
1673 std::map<int, wxString> *EmailListTokens = NULL;
1674 std::map<int, int> *EmailListPref = NULL;
1678 EmailList = &GeneralEmailList;
1679 EmailListType = &GeneralEmailListType;
1680 EmailListAltID = &GeneralEmailListAltID;
1681 EmailListPID = &GeneralEmailListPID;
1682 EmailListTokens = &GeneralEmailListTokens;
1683 EmailListPref = &GeneralEmailListPref;
1686 EmailList = &HomeEmailList;
1687 EmailListType = &HomeEmailListType;
1688 EmailListAltID = &HomeEmailListAltID;
1689 EmailListPID = &HomeEmailListPID;
1690 EmailListTokens = &HomeEmailListTokens;
1691 EmailListPref = &HomeEmailListPref;
1694 EmailList = &BusinessEmailList;
1695 EmailListType = &BusinessEmailListType;
1696 EmailListAltID = &BusinessEmailListAltID;
1697 EmailListPID = &BusinessEmailListPID;
1698 EmailListTokens = &BusinessEmailListTokens;
1699 EmailListPref = &BusinessEmailListPref;
1705 std::map<int,int>::iterator SLiter;
1706 wxString PropertyData;
1707 wxString PropertyName;
1708 wxString PropertyValue;
1709 wxString PropertyTokens;
1710 bool FirstToken = TRUE;
1712 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
1713 intiter != SplitPoints.end(); ++intiter){
1715 SLiter = SplitLength.find(intiter->first);
1717 PropertyData = PropertySeg1.Mid(intPrevValue, (SLiter->second));
1719 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
1720 PropertyName = PropertyElement.GetNextToken();
1721 PropertyValue = PropertyElement.GetNextToken();
1723 intPrevValue = intiter->second;
1725 CaptureString(&PropertyValue, FALSE);
1727 // Process properties.
1729 if (PropertyName == wxT("ALTID")){
1731 EmailListAltID->erase(*EmailCount);
1732 EmailListAltID->insert(std::make_pair(*EmailCount, PropertyValue));
1734 } else if (PropertyName == wxT("PID")){
1736 EmailListPID->erase(*EmailCount);
1737 EmailListPID->insert(std::make_pair(*EmailCount, PropertyValue));
1739 } else if (PropertyName == wxT("PREF")){
1741 int PriorityNumber = 0;
1742 bool ValidNumber = TRUE;
1745 PriorityNumber = std::stoi(PropertyValue.ToStdString());
1748 catch(std::invalid_argument &e){
1749 ValidNumber = FALSE;
1752 if (ValidNumber == TRUE){
1754 EmailListPref->erase(*EmailCount);
1755 EmailListPref->insert(std::make_pair(*EmailCount, PriorityNumber));
1761 if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty() && PropertyName != wxT("TYPE")){
1763 if (FirstToken == TRUE){
1765 PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue);
1770 PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue);
1780 EmailList->insert(std::make_pair(*EmailCount, PropertySeg2));
1782 // Add the name token data.
1784 if (!PropertyTokens.IsEmpty()){
1786 EmailListTokens->insert(std::make_pair(*EmailCount, PropertyTokens));
1793 void ContactDataObject::ProcessIM(wxString PropertySeg1, wxString PropertySeg2, int *IMCount){
1795 std::map<int, int> SplitPoints;
1796 std::map<int, int> SplitLength;
1798 int intPrevValue = 6;
1801 SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue);
1805 PropertyType PropType = PROPERTY_NONE;
1807 // Look for type before continuing.
1809 CheckType(&PropertySeg1, &SplitPoints, &SplitLength, &intPrevValue, &PropType);
1811 std::map<int, wxString> *IMList = NULL;
1812 std::map<int, wxString> *IMListType = NULL;
1813 std::map<int, wxString> *IMListAltID = NULL;
1814 std::map<int, wxString> *IMListPID = NULL;
1815 std::map<int, wxString> *IMListTokens = NULL;
1816 std::map<int, wxString> *IMListMediatype = NULL;
1817 std::map<int, int> *IMListPref = NULL;
1821 IMList = &GeneralIMList;
1822 IMListType = &GeneralIMListType;
1823 IMListAltID = &GeneralIMListAltID;
1824 IMListPID = &GeneralIMListPID;
1825 IMListTokens = &GeneralIMListTokens;
1826 IMListMediatype = &GeneralIMListMediatype;
1827 IMListPref = &GeneralIMListPref;
1830 IMList = &HomeIMList;
1831 IMListType = &HomeIMListType;
1832 IMListAltID = &HomeIMListAltID;
1833 IMListPID = &HomeIMListPID;
1834 IMListTokens = &HomeIMListTokens;
1835 IMListMediatype = &HomeIMListMediatype;
1836 IMListPref = &HomeIMListPref;
1839 IMList = &BusinessIMList;
1840 IMListType = &BusinessIMListType;
1841 IMListAltID = &BusinessIMListAltID;
1842 IMListPID = &BusinessIMListPID;
1843 IMListTokens = &BusinessIMListTokens;
1844 IMListMediatype = &BusinessIMListMediatype;
1845 IMListPref = &BusinessIMListPref;
1851 std::map<int,int>::iterator SLiter;
1852 wxString PropertyData;
1853 wxString PropertyName;
1854 wxString PropertyValue;
1855 wxString PropertyTokens;
1856 bool FirstToken = TRUE;
1858 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
1859 intiter != SplitPoints.end(); ++intiter){
1861 SLiter = SplitLength.find(intiter->first);
1863 PropertyData = PropertySeg1.Mid(intPrevValue, (SLiter->second));
1865 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
1866 PropertyName = PropertyElement.GetNextToken();
1867 PropertyValue = PropertyElement.GetNextToken();
1869 intPrevValue = intiter->second;
1871 CaptureString(&PropertyValue, FALSE);
1873 // Process properties.
1875 if (PropertyName == wxT("ALTID")){
1877 IMListAltID->erase(*IMCount);
1878 IMListAltID->insert(std::make_pair(*IMCount, PropertyValue));
1880 } else if (PropertyName == wxT("PID")){
1882 IMListPID->erase(*IMCount);
1883 IMListPID->insert(std::make_pair(*IMCount, PropertyValue));
1885 } else if (PropertyName == wxT("MEDIATYPE")){
1887 IMListMediatype->erase(*IMCount);
1888 IMListMediatype->insert(std::make_pair(*IMCount, PropertyValue));
1890 } else if (PropertyName == wxT("PREF")){
1892 int PriorityNumber = 0;
1893 bool ValidNumber = TRUE;
1896 PriorityNumber = std::stoi(PropertyValue.ToStdString());
1899 catch(std::invalid_argument &e){
1900 ValidNumber = FALSE;
1903 if (ValidNumber == TRUE){
1905 IMListPref->erase(*IMCount);
1906 IMListPref->insert(std::make_pair(*IMCount, PriorityNumber));
1912 if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty() && PropertyName != wxT("TYPE")){
1914 if (FirstToken == TRUE){
1916 PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue);
1921 PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue);
1931 IMList->insert(std::make_pair(*IMCount, PropertySeg2));
1933 // Add the name token data.
1935 if (!PropertyTokens.IsEmpty()){
1937 IMListTokens->insert(std::make_pair(*IMCount, PropertyTokens));
1943 void SplitValues(wxString *PropertyLine,
1944 std::map<int,int> *SplitPoints,
1945 std::map<int,int> *SplitLength,
1948 size_t intPropertyLen = PropertyLine->Len();
1949 int intSplitsFound = 0;
1950 int intSplitSize = 0;
1951 int intSplitSeek = 0;
1953 for (int i = intSize; i <= intPropertyLen; i++){
1957 if (PropertyLine->Mid(i, 1) == wxT(";") &&
1958 PropertyLine->Mid((i - 1), 1) != wxT("\\")){
1960 if (intSplitsFound == 0){
1962 SplitLength->insert(std::make_pair(intSplitsFound, (intSplitSize)));
1966 SplitLength->insert(std::make_pair(intSplitsFound, (intSplitSize - 1)));
1970 SplitPoints->insert(std::make_pair(intSplitsFound, (i + 1)));
1980 if (intSplitsFound == 0){
1982 SplitPoints->insert(std::make_pair(intSplitsFound, (8 + 1)));
1983 SplitLength->insert(std::make_pair(intSplitsFound, intSplitSize));
1987 SplitPoints->insert(std::make_pair(intSplitsFound, (intSplitSeek + 1)));
1988 SplitLength->insert(std::make_pair(intSplitsFound, intSplitSize));
1994 void CheckType(wxString *PropertySeg1,
1995 std::map<int,int> *SplitPoints,
1996 std::map<int,int> *SplitLength,
1998 PropertyType *PropType){
2000 wxString PropertyData;
2001 wxString PropertyName;
2002 wxString PropertyValue;
2003 std::map<int,int>::iterator SLiter;
2005 for (std::map<int, int>::iterator intiter = SplitPoints->begin();
2006 intiter != SplitPoints->end(); ++intiter){
2008 SLiter = SplitLength->find(intiter->first);
2010 PropertyData = PropertySeg1->Mid(*intPrevValue, (SLiter->second));
2012 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
2013 PropertyName = PropertyElement.GetNextToken();
2014 PropertyValue = PropertyElement.GetNextToken();
2016 *intPrevValue = intiter->second;
2018 if (PropertyName == wxT("TYPE")){
2020 if (PropertyValue == wxT("work")){
2022 *PropType = PROPERTY_WORK;
2024 } else if (PropertyValue == wxT("home")){
2026 *PropType = PROPERTY_HOME;
2030 *PropType = PROPERTY_NONE;