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;
91 int LanguageCount = 0;
93 wxString PropertyLine;
94 wxString PropertySeg1;
95 wxString PropertySeg2;
96 wxString PropertyNextLine;
99 for (std::map<int,wxString>::iterator iter = ContactFileLines.begin();
100 iter != ContactFileLines.end(); ++iter){
102 ExtraLineSeek = TRUE;
108 PropertyLine.Clear();
109 PropertySeg1.Clear();
110 PropertySeg2.Clear();
113 ContactLine = iter->second;
115 while (ExtraLineSeek == TRUE){
117 // Check if there is extra data on the next line
118 // (indicated by space or tab at the start) and add data.
122 if (iter == ContactFileLines.end()){
129 PropertyNextLine = iter->second;
131 if (PropertyNextLine.Mid(0, 1) == wxT(" ") || PropertyNextLine.Mid(0, 1) == wxT("\t")){
133 PropertyNextLine.Remove(0, 1);
134 ContactLine.Append(PropertyNextLine);
139 ExtraLineSeek = FALSE;
145 ContactLineLen = ContactLine.Len();
147 // Make sure we are not in quotation mode.
148 // Make sure colon does not have \ or \\ before it.
150 for (int i = 0; i <= ContactLineLen; i++){
152 if ((ContactLine.Mid(i, 1) == wxT(";") || ContactLine.Mid(i, 1) == wxT(":")) && PropertyFind == TRUE){
154 PropertyFind = FALSE;
156 } else if (PropertyFind == TRUE){
158 Property.Append(ContactLine.Mid(i, 1));
162 if (ContactLine.Mid(i, 1) == wxT("\"")){
164 if (QuoteMode == TRUE){
176 if (ContactLine.Mid(i, 1) == wxT(":") && ContactLine.Mid((i - 1), 1) != wxT("\\") && QuoteMode == FALSE){
185 // Split that line at the point into two variables (ignore the colon).
187 PropertySeg1 = ContactLine.Mid(0, QuoteBreakPoint);
188 PropertySeg2 = ContactLine.Mid((QuoteBreakPoint + 1));
190 if (Property == wxT("KIND") && KindProcessed == FALSE){
192 ProcessKind(PropertySeg2);
194 } else if (Property == wxT("MEMBER")){
196 ProcessMember(PropertySeg1, PropertySeg2, &GroupCount);
199 } else if (Property == wxT("FN")){
201 ProcessFN(PropertySeg1, PropertySeg2, &FNCount);
204 } else if (Property == wxT("N") && NameProcessed == FALSE){
206 ProcessN(PropertySeg1, PropertySeg2);
207 NameProcessed = TRUE;
209 } else if (Property == wxT("NICKNAME")){
211 ProcessNickname(PropertySeg1, PropertySeg2, &NicknameCount);
214 } else if (Property == wxT("GENDER") && GenderProcessed == FALSE){
216 ProcessGender(PropertySeg1, PropertySeg2);
217 GenderProcessed = TRUE;
219 } else if (Property == wxT("BDAY") && BirthdayProcessed == FALSE){
221 ProcessBirthday(PropertySeg1, PropertySeg2);
222 BirthdayProcessed = TRUE;
224 } else if (Property == wxT("ANNIVERSARY") && AnniversaryProcessed == FALSE){
226 ProcessAnniversary(PropertySeg1, PropertySeg2);
227 AnniversaryProcessed = TRUE;
229 } else if (Property == wxT("TZ")){
231 ProcessTimeZone(PropertySeg1, PropertySeg2, &TimeZoneCount);
234 } else if (Property == wxT("ADR")){
236 ProcessAddress(PropertySeg1, PropertySeg2, &AddressCount);
239 } else if (Property == wxT("EMAIL")){
241 ProcessEmail(PropertySeg1, PropertySeg2, &EmailCount);
244 } else if (Property == wxT("IMPP")){
246 ProcessIM(PropertySeg1, PropertySeg2, &IMCount);
249 } else if (Property == wxT("TEL")){
251 ProcessTelephone(PropertySeg1, PropertySeg2, &TelephoneCount);
254 } else if (Property == wxT("LANG")){
256 // See frmContactEditor-LoadLanguage.cpp
258 ProcessLanguage(PropertySeg1, PropertySeg2, &LanguageCount);
265 return CONTACTLOAD_OK;
269 void ContactDataObject::ProcessKind(wxString KindType){
271 if (KindType == wxT("individual")){
273 ContactKind = CONTACTKIND_INDIVIDUAL;
275 } else if (KindType == wxT("group")){
277 ContactKind = CONTACTKIND_GROUP;
279 } else if (KindType == wxT("org")){
281 ContactKind = CONTACTKIND_ORGANISATION;
283 } else if (KindType == wxT("location")){
285 ContactKind = CONTACTKIND_LOCATION;
289 ContactKind = CONTACTKIND_NONE;
294 void ContactDataObject::ProcessMember(wxString PropertySeg1, wxString PropertySeg2, int *GroupCount){
296 std::map<int, int> SplitPoints;
297 std::map<int, int> SplitLength;
299 int intPrevValue = 8;
303 SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue);
307 wxString PropertyName;
308 wxString PropertyValue;
309 wxString PropertyData;
310 wxString PropertyTokens;
311 std::map<int,int>::iterator SLiter;
312 bool FirstToken = TRUE;
314 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
315 intiter != SplitPoints.end(); ++intiter){
317 SLiter = SplitLength.find(intiter->first);
319 PropertyData = PropertySeg1.Mid(intPrevValue, (SLiter->second));
321 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
322 PropertyName = PropertyElement.GetNextToken();
323 PropertyValue = PropertyElement.GetNextToken();
325 intPrevValue = intiter->second;
327 CaptureString(&PropertyValue, FALSE);
329 if (PropertyName == wxT("ALTID")){
331 GroupsListAltID.erase(*GroupCount);
332 GroupsListAltID.insert(std::make_pair(*GroupCount, PropertyValue));
334 } else if (PropertyName == wxT("PID")){
336 GroupsListPID.erase(*GroupCount);
337 GroupsListPID.insert(std::make_pair(*GroupCount, PropertyValue));
339 } else if (PropertyName == wxT("PREF")){
341 int PriorityNumber = 0;
342 bool ValidNumber = TRUE;
345 PriorityNumber = std::stoi(PropertyValue.ToStdString());
348 catch(std::invalid_argument &e){
352 if (ValidNumber == TRUE){
354 GroupsListPref.erase(*GroupCount);
355 GroupsListPref.insert(std::make_pair(*GroupCount, PriorityNumber));
359 } else if (PropertyName == wxT("MEDIATYPE")){
361 GroupsListMediaType.erase(*GroupCount);
362 GroupsListMediaType.insert(std::make_pair(*GroupCount, PropertyValue));
364 } else if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty()){
366 if (FirstToken == TRUE){
368 PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue);
373 PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue);
381 GroupsList.insert(std::make_pair(*GroupCount, PropertySeg2));
383 if (!PropertyTokens.IsEmpty()){
385 GroupsListTokens.insert(std::make_pair(*GroupCount, PropertyTokens));
392 void ContactDataObject::ProcessFN(wxString PropertySeg1, wxString PropertySeg2, int *FNCount){
394 std::map<int, int> SplitPoints;
395 std::map<int, int> SplitLength;
397 int intPrevValue = 4;
401 SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue);
405 wxString PropertyName;
406 wxString PropertyValue;
407 wxString PropertyData;
408 wxString PropertyTokens;
409 std::map<int,int>::iterator SLiter;
410 bool FirstToken = TRUE;
412 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
413 intiter != SplitPoints.end(); ++intiter){
415 SLiter = SplitLength.find(intiter->first);
417 PropertyData = PropertySeg1.Mid(intPrevValue, (SLiter->second));
419 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
420 PropertyName = PropertyElement.GetNextToken();
421 PropertyValue = PropertyElement.GetNextToken();
423 intPrevValue = intiter->second;
425 CaptureString(&PropertyValue, FALSE);
427 if (PropertyName == wxT("TYPE")){
429 if (!PropertyValue.IsEmpty() || PropertyValue == wxT("home") ||
430 PropertyValue == wxT("work") ){
432 FullNamesListType.erase(*FNCount);
433 FullNamesListType.insert(std::make_pair(*FNCount, PropertyValue));
437 } else if (PropertyName == wxT("LANGUAGE")){
439 FullNamesListLanguage.erase(*FNCount);
440 FullNamesListLanguage.insert(std::make_pair(*FNCount, PropertyValue));
442 } else if (PropertyName == wxT("ALTID")){
444 FullNamesListAltID.erase(*FNCount);
445 FullNamesListAltID.insert(std::make_pair(*FNCount, PropertyValue));
447 } else if (PropertyName == wxT("PID")){
449 FullNamesListPID.erase(*FNCount);
450 FullNamesListPID.insert(std::make_pair(*FNCount, PropertyValue));
452 } else if (PropertyName == wxT("PREF")){
454 int PriorityNumber = 0;
455 bool ValidNumber = TRUE;
458 PriorityNumber = std::stoi(PropertyValue.ToStdString());
461 catch(std::invalid_argument &e){
465 if (ValidNumber == TRUE){
467 FullNamesListPref.erase(*FNCount);
468 FullNamesListPref.insert(std::make_pair(*FNCount, PriorityNumber));
472 } else if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty()){
474 if (FirstToken == TRUE){
476 PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue);
481 PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue);
489 FullNamesList.insert(std::make_pair(*FNCount, PropertySeg2));
491 if (!PropertyTokens.IsEmpty()){
493 FullNamesListTokens.insert(std::make_pair(*FNCount, PropertyTokens));
499 void ContactDataObject::ProcessN(wxString PropertySeg1, wxString PropertySeg2){
501 std::map<int, int> SplitPoints;
502 std::map<int, int> SplitLength;
504 int intPrevValue = 3;
508 SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue);
512 wxString PropertyName;
513 wxString PropertyValue;
514 wxString PropertyData;
515 wxString PropertyTokens;
516 std::map<int,int>::iterator SLiter;
517 bool FirstToken = TRUE;
519 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
520 intiter != SplitPoints.end(); ++intiter){
522 SLiter = SplitLength.find(intiter->first);
524 PropertyData = PropertySeg1.Mid(intPrevValue, (SLiter->second));
526 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
527 PropertyName = PropertyElement.GetNextToken();
528 PropertyValue = PropertyElement.GetNextToken();
530 intPrevValue = intiter->second;
532 CaptureString(&PropertyValue, FALSE);
534 if (PropertyName == wxT("ALTID")){
536 NameAltID = PropertyValue;
538 } else if (PropertyName == wxT("LANGUAGE")){
540 NameLanguage = PropertyValue;
542 } else if (PropertyName == wxT("SORT-AS")){
544 if (PropertyValue.Left(1) == wxT("\"") && PropertyValue.Right(1) == wxT("\"") &&
545 PropertyValue.Len() >= 3){
546 NameDisplayAs = PropertyValue.Mid(1, (PropertyValue.Len() - 2));
549 } else if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty()){
551 if (FirstToken == TRUE){
553 PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue);
558 PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue);
566 // Split the name data.
568 int intSplitSeek = 0;
569 int intSplitsFound = 0;
570 int intSplitSize = 0;
571 int intPropertyLen = PropertySeg2.Len();
573 std::map<int,wxString> NameValues;
576 for (int i = 0; i <= intPropertyLen; i++){
578 if (PropertySeg2.Mid(i, 1) == wxT(";") && PropertySeg2.Mid((i - 1), 1) != wxT("\\")){
580 NameValues.insert(std::make_pair(++intSplitsFound, PropertySeg2.Mid(intSplitSeek, intSplitSize)));
585 if (intSplitsFound == 4){
587 NameValues.insert(std::make_pair(++intSplitsFound, PropertySeg2.Mid(intSplitSeek, wxString::npos)));
601 // Split the data into several parts.
603 for (std::map<int, wxString>::iterator iter = NameValues.begin();
604 iter != NameValues.end(); ++iter){
606 if (iter->first == 1){
608 // Deal with family name.
610 NameSurname = iter->second;
612 } else if (iter->first == 2){
614 // Deal with given names.
616 NameForename = iter->second;
618 } else if (iter->first == 3){
620 // Deal with additional names.
622 NameOtherNames = iter->second;
624 } else if (iter->first == 4){
626 // Deal with honorifix prefixes and suffixes.
628 NameTitle = iter->second;
632 if (iter == NameValues.end()){
638 NameSuffix = iter->second;
644 // Add the name token data.
646 if (!PropertyTokens.IsEmpty()){
648 NameTokens = PropertyTokens;
654 void ContactDataObject::ProcessNickname(wxString PropertySeg1, wxString PropertySeg2, int *NicknameCount){
656 std::map<int, int> SplitPoints;
657 std::map<int, int> SplitLength;
659 int intPrevValue = 10;
662 SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue);
666 PropertyType PropType = PROPERTY_NONE;
668 // Look for type before continuing.
670 CheckType(&PropertySeg1, &SplitPoints, &SplitLength, &intPrevValue, &PropType);
674 std::map<int, wxString> *NicknamesList = NULL;
675 std::map<int, wxString> *NicknamesListType = NULL;
676 std::map<int, wxString> *NicknamesListLanguage = NULL;
677 std::map<int, wxString> *NicknamesListAltID = NULL;
678 std::map<int, wxString> *NicknamesListPID = NULL;
679 std::map<int, wxString> *NicknamesListTokens = NULL;
680 std::map<int, int> *NicknamesListPref = NULL;
684 NicknamesList = &GeneralNicknamesList;
685 NicknamesListType = &GeneralNicknamesListType;
686 NicknamesListLanguage = &GeneralNicknamesListLanguage;
687 NicknamesListAltID = &GeneralNicknamesListAltID;
688 NicknamesListPID = &GeneralNicknamesListPID;
689 NicknamesListTokens = &GeneralNicknamesListTokens;
690 NicknamesListPref = &GeneralNicknamesListPref;
693 NicknamesList = &HomeNicknamesList;
694 NicknamesListType = &HomeNicknamesListType;
695 NicknamesListLanguage = &HomeNicknamesListLanguage;
696 NicknamesListAltID = &HomeNicknamesListAltID;
697 NicknamesListPID = &HomeNicknamesListPID;
698 NicknamesListTokens = &HomeNicknamesListTokens;
699 NicknamesListPref = &HomeNicknamesListPref;
702 NicknamesList = &BusinessNicknamesList;
703 NicknamesListType = &BusinessNicknamesListType;
704 NicknamesListLanguage = &BusinessNicknamesListLanguage;
705 NicknamesListAltID = &BusinessNicknamesListAltID;
706 NicknamesListPID = &BusinessNicknamesListPID;
707 NicknamesListTokens = &BusinessNicknamesListTokens;
708 NicknamesListPref = &BusinessNicknamesListPref;
712 std::map<int, int>::iterator SLiter;
713 wxString PropertyData;
714 wxString PropertyName;
715 wxString PropertyValue;
716 wxString PropertyTokens;
717 bool FirstToken = TRUE;
719 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
720 intiter != SplitPoints.end(); ++intiter){
722 SLiter = SplitLength.find(intiter->first);
724 PropertyData = PropertySeg1.Mid(intPrevValue, (SLiter->second));
726 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
727 PropertyName = PropertyElement.GetNextToken();
728 PropertyValue = PropertyElement.GetNextToken();
730 intPrevValue = intiter->second;
732 CaptureString(&PropertyValue, FALSE);
734 if (PropertyName == wxT("ALTID")){
736 NicknamesListAltID->erase(*NicknameCount);
737 NicknamesListAltID->insert(std::make_pair(*NicknameCount, PropertyValue));
739 } else if (PropertyName == wxT("PID")){
741 NicknamesListPID->erase(*NicknameCount);
742 NicknamesListPID->insert(std::make_pair(*NicknameCount, PropertyValue));
744 } else if (PropertyName == wxT("PREF")){
746 int PriorityNumber = 0;
747 bool ValidNumber = TRUE;
750 PriorityNumber = std::stoi(PropertyValue.ToStdString());
753 catch(std::invalid_argument &e){
757 if (ValidNumber == TRUE){
759 NicknamesListPref->erase(*NicknameCount);
760 NicknamesListPref->insert(std::make_pair(*NicknameCount, PriorityNumber));
764 } else if (PropertyName == wxT("LANGUAGE")){
766 NicknamesListLanguage->erase(*NicknameCount);
767 NicknamesListLanguage->insert(std::make_pair(*NicknameCount, PropertyValue));
771 // Something else we don't know about so append
772 // to the tokens variable.
774 if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty() && PropertyName != wxT("TYPE")){
776 if (FirstToken == TRUE){
778 PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue);
783 PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue);
793 NicknamesList->insert(std::make_pair(*NicknameCount, PropertySeg2));
795 // Add the name token data.
797 if (!PropertyTokens.IsEmpty()){
799 NicknamesListTokens->insert(std::make_pair(*NicknameCount, PropertyTokens));
805 void ContactDataObject::ProcessGender(wxString PropertySeg1, wxString PropertySeg2){
807 std::map<int, int> SplitPoints;
808 std::map<int, int> SplitLength;
809 std::map<int, int>::iterator SLiter;
810 wxString PropertyData;
811 wxString PropertyName;
812 wxString PropertyValue;
813 wxString PropertyTokens;
814 bool FirstToken = TRUE;
815 int intPrevValue = 8;
817 SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue);
821 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
822 intiter != SplitPoints.end(); ++intiter){
824 SLiter = SplitLength.find(intiter->first);
826 PropertyData = PropertySeg1.Mid(intPrevValue, (SLiter->second));
828 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
829 PropertyName = PropertyElement.GetNextToken();
830 PropertyValue = PropertyElement.GetNextToken();
832 intPrevValue = intiter->second;
834 // Process properties.
836 size_t intPropertyValueLen = PropertyValue.Len();
838 if (PropertyValue.Mid((intPropertyValueLen - 1), 1) == wxT("\"")){
840 PropertyValue.Trim();
841 PropertyValue.RemoveLast();
845 if (PropertyValue.Mid(0, 1) == wxT("\"")){
847 PropertyValue.Remove(0, 1);
851 if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty()){
853 if (FirstToken == TRUE){
855 PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue);
860 PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue);
868 wxStringTokenizer GenderData (PropertySeg2, wxT(";"));
870 wxString GenderComponent;
872 if (GenderData.CountTokens() >= 2){
874 Gender = GenderData.GetNextToken();
875 GenderDetails = GenderData.GetString();
877 CaptureString(&GenderDetails, FALSE);
881 Gender = GenderData.GetNextToken();
885 if (!PropertyTokens.IsEmpty()){
887 GenderTokens = PropertyTokens;
893 void ContactDataObject::ProcessBirthday(wxString PropertySeg1, wxString PropertySeg2){
895 // Process date. Preserve the remainder in the string.
897 std::map<int, int> SplitPoints;
898 std::map<int, int> SplitLength;
899 std::map<int, int>::iterator SLiter;
900 wxString PropertyData;
901 wxString PropertyName;
902 wxString PropertyValue;
903 wxString PropertyTokens;
904 bool BirthdayText = FALSE;
905 int intPrevValue = 6;
907 SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue);
911 // Look for type before continuing.
913 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
914 intiter != SplitPoints.end(); ++intiter){
916 SLiter = SplitLength.find(intiter->first);
918 PropertyData = PropertySeg1.Mid(intPrevValue, SLiter->second);
920 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
921 PropertyName = PropertyElement.GetNextToken();
922 PropertyValue = PropertyElement.GetNextToken();
924 intPrevValue = intiter->second;
926 if (PropertyName == wxT("VALUE") && PropertyValue == wxT("text") && BirthdayText == FALSE){
928 CaptureString(&PropertySeg2, FALSE);
929 Birthday = PropertySeg2;
936 // Setup blank lines for later on.
939 bool FirstToken = TRUE;
941 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
942 intiter != SplitPoints.end(); ++intiter){
944 SLiter = SplitLength.find(intiter->first);
946 PropertyData = PropertySeg1.Mid(intPrevValue, SLiter->second);
948 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
949 PropertyName = PropertyElement.GetNextToken();
950 PropertyValue = PropertyElement.GetNextToken();
952 intPrevValue = intiter->second;
954 // Process properties.
956 CaptureString(&PropertyValue, FALSE);
958 if (PropertyValue.Mid((PropertyValue.Len() - 1), 1) == wxT("\"")){
960 PropertyValue.Trim();
961 PropertyValue.RemoveLast();
965 if (PropertyValue.Mid(0, 1) == wxT("\"")){
967 PropertyValue.Remove(0, 1);
971 if (PropertyName == wxT("ALTID")){
973 BirthdayAltID = PropertyValue;
975 } else if (PropertyName == wxT("CALSCALE")){
977 BirthdayCalScale = PropertyValue;
979 } else if (PropertyName != wxT("VALUE")) {
981 // Something else we don't know about so append
982 // to the tokens variable.
984 if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty()){
986 if (FirstToken == TRUE){
988 PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue);
993 PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue);
1003 // Add the data to the variables and form.
1005 if (BirthdayText == FALSE){
1007 Birthday = PropertySeg2;
1011 if (!PropertyTokens.IsEmpty()){
1013 BirthdayTokens = PropertyTokens;
1019 void ContactDataObject::ProcessAnniversary(wxString PropertySeg1, wxString PropertySeg2){
1021 // Process date. Preserve the remainder in the string.
1023 std::map<int, int> SplitPoints;
1024 std::map<int, int> SplitLength;
1025 std::map<int, int>::iterator SLiter;
1026 wxString PropertyData;
1027 wxString PropertyName;
1028 wxString PropertyValue;
1029 wxString PropertyTokens;
1030 bool AnniversaryText = FALSE;
1031 int intPrevValue = 13;
1033 SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue);
1037 // Look for type before continuing.
1039 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
1040 intiter != SplitPoints.end(); ++intiter){
1042 SLiter = SplitLength.find(intiter->first);
1044 PropertyData = PropertySeg1.Mid(intPrevValue, SLiter->second);
1046 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
1047 PropertyName = PropertyElement.GetNextToken();
1048 PropertyValue = PropertyElement.GetNextToken();
1050 intPrevValue = intiter->second;
1052 if (PropertyName == wxT("VALUE") && PropertyValue == wxT("text") && AnniversaryText == FALSE){
1054 CaptureString(&PropertySeg2, FALSE);
1055 Anniversary = PropertySeg2;
1056 AnniversaryText = TRUE;
1062 // Setup blank lines for later on.
1065 bool FirstToken = TRUE;
1067 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
1068 intiter != SplitPoints.end(); ++intiter){
1070 SLiter = SplitLength.find(intiter->first);
1072 PropertyData = PropertySeg1.Mid(intPrevValue, SLiter->second);
1074 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
1075 PropertyName = PropertyElement.GetNextToken();
1076 PropertyValue = PropertyElement.GetNextToken();
1078 intPrevValue = intiter->second;
1080 // Process properties.
1082 CaptureString(&PropertyValue, FALSE);
1084 if (PropertyValue.Mid((PropertyValue.Len() - 1), 1) == wxT("\"")){
1086 PropertyValue.Trim();
1087 PropertyValue.RemoveLast();
1091 if (PropertyValue.Mid(0, 1) == wxT("\"")){
1093 PropertyValue.Remove(0, 1);
1097 if (PropertyName == wxT("ALTID")){
1099 AnniversaryAltID = PropertyValue;
1101 } else if (PropertyName == wxT("CALSCALE")){
1103 AnniversaryCalScale = PropertyValue;
1105 } else if (PropertyName != wxT("VALUE")) {
1107 // Something else we don't know about so append
1108 // to the tokens variable.
1110 if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty()){
1112 if (FirstToken == TRUE){
1114 PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue);
1119 PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue);
1129 // Add the data to the variables and form.
1131 if (AnniversaryText == FALSE){
1133 Anniversary = PropertySeg2;
1137 if (!PropertyTokens.IsEmpty()){
1139 AnniversaryTokens = PropertyTokens;
1145 void ContactDataObject::ProcessTimeZone(wxString PropertySeg1, wxString PropertySeg2, int *TimeZoneCount){
1147 std::map<int, int> SplitPoints;
1148 std::map<int, int> SplitLength;
1150 int intPrevValue = 4;
1153 SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue);
1157 PropertyType PropType = PROPERTY_NONE;
1159 // Look for type before continuing.
1161 CheckType(&PropertySeg1, &SplitPoints, &SplitLength, &intPrevValue, &PropType);
1165 std::map<int, wxString> *TZList = NULL;
1166 std::map<int, wxString> *TZListType = NULL;
1167 std::map<int, wxString> *TZListMediatype = NULL;
1168 std::map<int, wxString> *TZListAltID = NULL;
1169 std::map<int, wxString> *TZListPID = NULL;
1170 std::map<int, wxString> *TZListTokens = NULL;
1171 std::map<int, int> *TZListPref = NULL;
1175 TZList = &GeneralTZList;
1176 TZListType = &GeneralTZListType;
1177 TZListMediatype = &GeneralTZListMediatype;
1178 TZListAltID = &GeneralTZListAltID;
1179 TZListPID = &GeneralTZListPID;
1180 TZListTokens = &GeneralTZListTokens;
1181 TZListPref = &GeneralTZListPref;
1184 TZList = &HomeTZList;
1185 TZListType = &HomeTZListType;
1186 TZListMediatype = &HomeTZListMediatype;
1187 TZListAltID = &HomeTZListAltID;
1188 TZListPID = &HomeTZListPID;
1189 TZListTokens = &HomeTZListTokens;
1190 TZListPref = &HomeTZListPref;
1193 TZList = &BusinessTZList;
1194 TZListType = &BusinessTZListType;
1195 TZListMediatype = &BusinessTZListMediatype;
1196 TZListAltID = &BusinessTZListAltID;
1197 TZListPID = &BusinessTZListPID;
1198 TZListTokens = &BusinessTZListTokens;
1199 TZListPref = &BusinessTZListPref;
1203 std::map<int, int>::iterator SLiter;
1204 wxString PropertyData;
1205 wxString PropertyName;
1206 wxString PropertyValue;
1207 wxString PropertyTokens;
1208 bool FirstToken = TRUE;
1210 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
1211 intiter != SplitPoints.end(); ++intiter){
1213 SLiter = SplitLength.find(intiter->first);
1215 PropertyData = PropertySeg1.Mid(intPrevValue, (SLiter->second));
1217 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
1218 PropertyName = PropertyElement.GetNextToken();
1219 PropertyValue = PropertyElement.GetNextToken();
1221 intPrevValue = intiter->second;
1223 CaptureString(&PropertyValue, FALSE);
1225 if (PropertyName == wxT("ALTID")){
1227 TZListAltID->erase(*TimeZoneCount);
1228 TZListAltID->insert(std::make_pair(*TimeZoneCount, PropertyValue));
1230 } else if (PropertyName == wxT("PID")){
1232 TZListPID->erase(*TimeZoneCount);
1233 TZListPID->insert(std::make_pair(*TimeZoneCount, PropertyValue));
1235 } else if (PropertyName == wxT("PREF")){
1237 int PriorityNumber = 0;
1238 bool ValidNumber = TRUE;
1241 PriorityNumber = std::stoi(PropertyValue.ToStdString());
1244 catch(std::invalid_argument &e){
1245 ValidNumber = FALSE;
1248 if (ValidNumber == TRUE){
1250 TZListPref->erase(*TimeZoneCount);
1251 TZListPref->insert(std::make_pair(*TimeZoneCount, PriorityNumber));
1255 } else if (PropertyName == wxT("MEDIATYPE")){
1257 TZListMediatype->erase(*TimeZoneCount);
1258 TZListMediatype->insert(std::make_pair(*TimeZoneCount, PropertyValue));
1262 // Something else we don't know about so append
1263 // to the tokens variable.
1265 if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty() && PropertyName != wxT("TYPE")){
1267 if (FirstToken == TRUE){
1269 PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue);
1274 PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue);
1284 TZList->insert(std::make_pair(*TimeZoneCount, PropertySeg2));
1286 // Add the name token data.
1288 if (!PropertyTokens.IsEmpty()){
1290 TZListTokens->insert(std::make_pair(*TimeZoneCount, PropertyTokens));
1297 void ContactDataObject::ProcessAddress(wxString PropertySeg1, wxString PropertySeg2, int *AddressCount){
1299 size_t intPropertyLen = PropertySeg1.Len();
1300 std::map<int, int> SplitPoints;
1301 std::map<int, int> SplitLength;
1302 std::map<int, int>::iterator SLiter;
1303 wxString PropertyData;
1304 wxString PropertyName;
1305 wxString PropertyValue;
1306 wxString PropertyTokens;
1307 wxString AddressLabel;
1308 wxString AddressLang;
1309 wxString AddressAltID;
1310 wxString AddressPID;
1311 wxString AddressTokens;
1312 wxString AddressGeo;
1313 wxString AddressTimezone;
1314 wxString AddressType;
1315 wxString AddressMediatype;
1316 wxString AddressPOBox;
1317 wxString AddressExtended;
1318 wxString AddressStreet;
1319 wxString AddressLocality;
1320 wxString AddressCity;
1321 wxString AddressRegion;
1322 wxString AddressPostalCode;
1323 wxString AddressCountry;
1324 bool FirstToken = TRUE;
1325 int intSplitsFound = 0;
1326 int intSplitSize = 0;
1327 int intPrevValue = 5;
1332 SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue);
1336 PropertyType PropType = PROPERTY_NONE;
1338 // Look for type before continuing.
1340 CheckType(&PropertySeg1, &SplitPoints, &SplitLength, &intPrevValue, &PropType);
1344 std::map<int, wxString> *AddressList = NULL;
1345 std::map<int, wxString> *AddressListTown = NULL;
1346 std::map<int, wxString> *AddressListCounty = NULL;
1347 std::map<int, wxString> *AddressListPostCode = NULL;
1348 std::map<int, wxString> *AddressListCountry = NULL;
1349 std::map<int, wxString> *AddressListLabel = NULL;
1350 std::map<int, wxString> *AddressListLang = NULL;
1351 std::map<int, wxString> *AddressListAltID = NULL;
1352 std::map<int, wxString> *AddressListPID = NULL;
1353 std::map<int, wxString> *AddressListTokens = NULL;
1354 std::map<int, wxString> *AddressListGeo = NULL;
1355 std::map<int, wxString> *AddressListTimezone = NULL;
1356 std::map<int, wxString> *AddressListType = NULL;
1357 std::map<int, wxString> *AddressListMediatype = NULL;
1358 std::map<int, int> *AddressListPref = NULL;
1362 AddressList = &GeneralAddressList;
1363 AddressListTown = &GeneralAddressListTown;
1364 AddressListCounty = &GeneralAddressListCounty;
1365 AddressListPostCode = &GeneralAddressListPostCode;
1366 AddressListCountry = &GeneralAddressListCountry;
1367 AddressListLabel = &GeneralAddressListLabel;
1368 AddressListLang = &GeneralAddressListLang;
1369 AddressListAltID = &GeneralAddressListAltID;
1370 AddressListPID = &GeneralAddressListPID;
1371 AddressListTokens = &GeneralAddressListTokens;
1372 AddressListGeo = &GeneralAddressListGeo;
1373 AddressListTimezone = &GeneralAddressListTimezone;
1374 AddressListType = &GeneralAddressListType;
1375 AddressListMediatype = &GeneralAddressListMediatype;
1376 AddressListPref = &GeneralAddressListPref;
1379 AddressList = &HomeAddressList;
1380 AddressListTown = &HomeAddressListTown;
1381 AddressListCounty = &HomeAddressListCounty;
1382 AddressListPostCode = &HomeAddressListPostCode;
1383 AddressListCountry = &HomeAddressListCountry;
1384 AddressListLabel = &HomeAddressListLabel;
1385 AddressListLang = &HomeAddressListLang;
1386 AddressListAltID = &HomeAddressListAltID;
1387 AddressListPID = &HomeAddressListPID;
1388 AddressListTokens = &HomeAddressListTokens;
1389 AddressListGeo = &HomeAddressListGeo;
1390 AddressListTimezone = &HomeAddressListTimezone;
1391 AddressListType = &HomeAddressListType;
1392 AddressListMediatype = &HomeAddressListMediatype;
1393 AddressListPref = &HomeAddressListPref;
1396 AddressList = &BusinessAddressList;
1397 AddressListTown = &BusinessAddressListTown;
1398 AddressListCounty = &BusinessAddressListCounty;
1399 AddressListPostCode = &BusinessAddressListPostCode;
1400 AddressListCountry = &BusinessAddressListCountry;
1401 AddressListLabel = &BusinessAddressListLabel;
1402 AddressListLang = &BusinessAddressListLang;
1403 AddressListAltID = &BusinessAddressListAltID;
1404 AddressListPID = &BusinessAddressListPID;
1405 AddressListTokens = &BusinessAddressListTokens;
1406 AddressListGeo = &BusinessAddressListGeo;
1407 AddressListTimezone = &BusinessAddressListTimezone;
1408 AddressListType = &BusinessAddressListType;
1409 AddressListMediatype = &BusinessAddressListMediatype;
1410 AddressListPref = &BusinessAddressListPref;
1416 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
1417 intiter != SplitPoints.end(); ++intiter){
1419 SLiter = SplitLength.find(intiter->first);
1421 PropertyData = PropertySeg1.Mid(intPrevValue, (SLiter->second));
1423 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
1424 PropertyName = PropertyElement.GetNextToken();
1425 PropertyValue = PropertyElement.GetNextToken();
1427 intPrevValue = intiter->second;
1429 CaptureString(&PropertyValue, FALSE);
1431 // Process properties.
1433 if (PropertyName == wxT("LABEL")){
1435 AddressListLabel->erase(*AddressCount);
1436 AddressListLabel->insert(std::make_pair(*AddressCount, PropertyValue));
1438 } else if (PropertyName == wxT("LANGUAGE")){
1440 AddressListLang->erase(*AddressCount);
1441 AddressListLang->insert(std::make_pair(*AddressCount, PropertyValue));
1443 } else if (PropertyName == wxT("ALTID")){
1445 AddressListAltID->erase(*AddressCount);
1446 AddressListAltID->insert(std::make_pair(*AddressCount, PropertyValue));
1448 } else if (PropertyName == wxT("PID")){
1450 AddressListPID->erase(*AddressCount);
1451 AddressListPID->insert(std::make_pair(*AddressCount, PropertyValue));
1453 } else if (PropertyName == wxT("GEO")){
1455 AddressListGeo->erase(*AddressCount);
1456 AddressListGeo->insert(std::make_pair(*AddressCount, PropertyValue));
1458 } else if (PropertyName == wxT("TZ")){
1460 AddressListTimezone->erase(*AddressCount);
1461 AddressListTimezone->insert(std::make_pair(*AddressCount, PropertyValue));
1463 } else if (PropertyName == wxT("MEDIATYPE")){
1465 AddressListMediatype->erase(*AddressCount);
1466 AddressListMediatype->insert(std::make_pair(*AddressCount, PropertyValue));
1468 } else if (PropertyName == wxT("PREF")){
1470 int PriorityNumber = 0;
1471 bool ValidNumber = TRUE;
1474 PriorityNumber = std::stoi(PropertyValue.ToStdString());
1477 catch(std::invalid_argument &e){
1478 ValidNumber = FALSE;
1481 if (ValidNumber == TRUE){
1483 AddressListPref->erase(*AddressCount);
1484 AddressListPref->insert(std::make_pair(*AddressCount, PriorityNumber));
1490 if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty() && PropertyName != wxT("TYPE")){
1492 if (FirstToken == TRUE){
1494 PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue);
1499 PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue);
1509 // Split the address.
1511 //std::map<int, int>::iterator SLiter;
1512 intPropertyLen = PropertySeg2.Len();
1513 SplitPoints.clear();
1514 SplitLength.clear();
1519 for (int i = 0; i <= intPropertyLen; i++){
1523 if (PropertySeg2.Mid(i, 1) == wxT(";") && PropertySeg2.Mid((i - 1), 1) != wxT("\\")){
1526 SplitPoints.insert(std::make_pair(intSplitsFound, (i + 1)));
1528 if (intSplitsFound == 6){
1530 SplitLength.insert(std::make_pair(intSplitsFound, (intSplitSize - 1)));
1535 SplitLength.insert(std::make_pair(intSplitsFound, (intSplitSize - 1)));
1545 // Split the data into several parts.
1547 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
1548 intiter != SplitPoints.end(); ++intiter){
1550 if (intiter->first == 1){
1552 // Deal with PO Box.
1554 SLiter = SplitLength.find(1);
1556 //txtSurname->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(0, SLiter->second), TRUE));
1557 AddressPOBox = PropertySeg2.Mid(0, SLiter->second);
1558 intPrevValue = intiter->second;
1560 } else if (intiter->first == 2){
1562 // Deal with extended address.
1564 SLiter = SplitLength.find(2);
1566 AddressExtended = PropertySeg2.Mid(intPrevValue, SLiter->second);
1567 //txtForename->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue, SLiter->second), TRUE));
1568 intPrevValue = intiter->second;
1570 } else if (intiter->first == 3){
1572 // Deal with street address.
1574 SLiter = SplitLength.find(3);
1576 AddressStreet = PropertySeg2.Mid(intPrevValue, SLiter->second);
1577 //txtOtherNames->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue, SLiter->second), TRUE));
1578 intPrevValue = intiter->second;
1580 } else if (intiter->first == 4){
1582 // Deal with locality
1584 SLiter = SplitLength.find(4);
1586 AddressLocality = PropertySeg2.Mid(intPrevValue, SLiter->second);
1587 //txtTitle->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue, SLiter->second), TRUE));
1588 intPrevValue = intiter->second;
1590 //txtSuffix->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue), TRUE));
1592 } else if (intiter->first == 5){
1594 // Deal with region.
1596 SLiter = SplitLength.find(5);
1598 AddressRegion = PropertySeg2.Mid(intPrevValue, SLiter->second);
1599 //txtTitle->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue, SLiter->second), TRUE));
1600 intPrevValue = intiter->second;
1602 //txtSuffix->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue), TRUE));
1604 } else if (intiter->first == 6){
1606 // Deal with post code.
1608 SLiter = SplitLength.find(6);
1610 AddressPostalCode = PropertySeg2.Mid(intPrevValue, SLiter->second);
1611 //txtTitle->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue, SLiter->second), TRUE));
1612 intPrevValue = intiter->second;
1614 // Deal with country.
1616 AddressCountry = PropertySeg2.Mid(intPrevValue, wxString::npos);
1617 //txtSuffix->SetValue(ContactData.Convert(wxSPropertySeg2.Mid(intPrevValue), TRUE));
1625 // Add the data to the General/Home/Work address variables.
1627 CaptureString(&AddressStreet, FALSE);
1628 CaptureString(&AddressLocality, FALSE);
1629 CaptureString(&AddressRegion, FALSE);
1630 CaptureString(&AddressPostalCode, FALSE);
1631 CaptureString(&AddressCountry, FALSE);
1633 if (!PropertyTokens.IsEmpty()){
1635 AddressListTokens->insert(std::make_pair(*AddressCount, PropertyTokens));
1639 AddressListCountry->insert(std::make_pair(*AddressCount, AddressCountry));
1640 AddressList->insert(std::make_pair(*AddressCount, AddressStreet));
1641 AddressListTown->insert(std::make_pair(*AddressCount, AddressLocality));
1642 AddressListCounty->insert(std::make_pair(*AddressCount, AddressRegion));
1643 AddressListPostCode->insert(std::make_pair(*AddressCount, AddressPostalCode));
1647 AddressListType->insert(std::make_pair(*AddressCount, wxT("")));
1650 AddressListType->insert(std::make_pair(*AddressCount, wxT("home")));
1653 AddressListType->insert(std::make_pair(*AddressCount, wxT("work")));
1657 AddressListTokens->insert(std::make_pair(*AddressCount, PropertyTokens));
1661 void ContactDataObject::ProcessEmail(wxString PropertySeg1, wxString PropertySeg2, int *EmailCount){
1663 std::map<int, int> SplitPoints;
1664 std::map<int, int> SplitLength;
1666 int intPrevValue = 7;
1669 SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue);
1673 PropertyType PropType = PROPERTY_NONE;
1675 // Look for type before continuing.
1677 CheckType(&PropertySeg1, &SplitPoints, &SplitLength, &intPrevValue, &PropType);
1679 std::map<int, wxString> *EmailList = NULL;
1680 std::map<int, wxString> *EmailListType = NULL;
1681 std::map<int, wxString> *EmailListAltID = NULL;
1682 std::map<int, wxString> *EmailListPID = NULL;
1683 std::map<int, wxString> *EmailListTokens = NULL;
1684 std::map<int, int> *EmailListPref = NULL;
1688 EmailList = &GeneralEmailList;
1689 EmailListType = &GeneralEmailListType;
1690 EmailListAltID = &GeneralEmailListAltID;
1691 EmailListPID = &GeneralEmailListPID;
1692 EmailListTokens = &GeneralEmailListTokens;
1693 EmailListPref = &GeneralEmailListPref;
1696 EmailList = &HomeEmailList;
1697 EmailListType = &HomeEmailListType;
1698 EmailListAltID = &HomeEmailListAltID;
1699 EmailListPID = &HomeEmailListPID;
1700 EmailListTokens = &HomeEmailListTokens;
1701 EmailListPref = &HomeEmailListPref;
1704 EmailList = &BusinessEmailList;
1705 EmailListType = &BusinessEmailListType;
1706 EmailListAltID = &BusinessEmailListAltID;
1707 EmailListPID = &BusinessEmailListPID;
1708 EmailListTokens = &BusinessEmailListTokens;
1709 EmailListPref = &BusinessEmailListPref;
1715 std::map<int,int>::iterator SLiter;
1716 wxString PropertyData;
1717 wxString PropertyName;
1718 wxString PropertyValue;
1719 wxString PropertyTokens;
1720 bool FirstToken = TRUE;
1722 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
1723 intiter != SplitPoints.end(); ++intiter){
1725 SLiter = SplitLength.find(intiter->first);
1727 PropertyData = PropertySeg1.Mid(intPrevValue, (SLiter->second));
1729 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
1730 PropertyName = PropertyElement.GetNextToken();
1731 PropertyValue = PropertyElement.GetNextToken();
1733 intPrevValue = intiter->second;
1735 CaptureString(&PropertyValue, FALSE);
1737 // Process properties.
1739 if (PropertyName == wxT("ALTID")){
1741 EmailListAltID->erase(*EmailCount);
1742 EmailListAltID->insert(std::make_pair(*EmailCount, PropertyValue));
1744 } else if (PropertyName == wxT("PID")){
1746 EmailListPID->erase(*EmailCount);
1747 EmailListPID->insert(std::make_pair(*EmailCount, PropertyValue));
1749 } else if (PropertyName == wxT("PREF")){
1751 int PriorityNumber = 0;
1752 bool ValidNumber = TRUE;
1755 PriorityNumber = std::stoi(PropertyValue.ToStdString());
1758 catch(std::invalid_argument &e){
1759 ValidNumber = FALSE;
1762 if (ValidNumber == TRUE){
1764 EmailListPref->erase(*EmailCount);
1765 EmailListPref->insert(std::make_pair(*EmailCount, PriorityNumber));
1771 if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty() && PropertyName != wxT("TYPE")){
1773 if (FirstToken == TRUE){
1775 PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue);
1780 PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue);
1790 EmailList->insert(std::make_pair(*EmailCount, PropertySeg2));
1792 // Add the name token data.
1794 if (!PropertyTokens.IsEmpty()){
1796 EmailListTokens->insert(std::make_pair(*EmailCount, PropertyTokens));
1803 void ContactDataObject::ProcessIM(wxString PropertySeg1, wxString PropertySeg2, int *IMCount){
1805 std::map<int, int> SplitPoints;
1806 std::map<int, int> SplitLength;
1808 int intPrevValue = 6;
1811 SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue);
1815 PropertyType PropType = PROPERTY_NONE;
1817 // Look for type before continuing.
1819 CheckType(&PropertySeg1, &SplitPoints, &SplitLength, &intPrevValue, &PropType);
1821 std::map<int, wxString> *IMList = NULL;
1822 std::map<int, wxString> *IMListType = NULL;
1823 std::map<int, wxString> *IMListAltID = NULL;
1824 std::map<int, wxString> *IMListPID = NULL;
1825 std::map<int, wxString> *IMListTokens = NULL;
1826 std::map<int, wxString> *IMListMediatype = NULL;
1827 std::map<int, int> *IMListPref = NULL;
1831 IMList = &GeneralIMList;
1832 IMListType = &GeneralIMListType;
1833 IMListAltID = &GeneralIMListAltID;
1834 IMListPID = &GeneralIMListPID;
1835 IMListTokens = &GeneralIMListTokens;
1836 IMListMediatype = &GeneralIMListMediatype;
1837 IMListPref = &GeneralIMListPref;
1840 IMList = &HomeIMList;
1841 IMListType = &HomeIMListType;
1842 IMListAltID = &HomeIMListAltID;
1843 IMListPID = &HomeIMListPID;
1844 IMListTokens = &HomeIMListTokens;
1845 IMListMediatype = &HomeIMListMediatype;
1846 IMListPref = &HomeIMListPref;
1849 IMList = &BusinessIMList;
1850 IMListType = &BusinessIMListType;
1851 IMListAltID = &BusinessIMListAltID;
1852 IMListPID = &BusinessIMListPID;
1853 IMListTokens = &BusinessIMListTokens;
1854 IMListMediatype = &BusinessIMListMediatype;
1855 IMListPref = &BusinessIMListPref;
1861 std::map<int,int>::iterator SLiter;
1862 wxString PropertyData;
1863 wxString PropertyName;
1864 wxString PropertyValue;
1865 wxString PropertyTokens;
1866 bool FirstToken = TRUE;
1868 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
1869 intiter != SplitPoints.end(); ++intiter){
1871 SLiter = SplitLength.find(intiter->first);
1873 PropertyData = PropertySeg1.Mid(intPrevValue, (SLiter->second));
1875 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
1876 PropertyName = PropertyElement.GetNextToken();
1877 PropertyValue = PropertyElement.GetNextToken();
1879 intPrevValue = intiter->second;
1881 CaptureString(&PropertyValue, FALSE);
1883 // Process properties.
1885 if (PropertyName == wxT("ALTID")){
1887 IMListAltID->erase(*IMCount);
1888 IMListAltID->insert(std::make_pair(*IMCount, PropertyValue));
1890 } else if (PropertyName == wxT("PID")){
1892 IMListPID->erase(*IMCount);
1893 IMListPID->insert(std::make_pair(*IMCount, PropertyValue));
1895 } else if (PropertyName == wxT("MEDIATYPE")){
1897 IMListMediatype->erase(*IMCount);
1898 IMListMediatype->insert(std::make_pair(*IMCount, PropertyValue));
1900 } else if (PropertyName == wxT("PREF")){
1902 int PriorityNumber = 0;
1903 bool ValidNumber = TRUE;
1906 PriorityNumber = std::stoi(PropertyValue.ToStdString());
1909 catch(std::invalid_argument &e){
1910 ValidNumber = FALSE;
1913 if (ValidNumber == TRUE){
1915 IMListPref->erase(*IMCount);
1916 IMListPref->insert(std::make_pair(*IMCount, PriorityNumber));
1922 if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty() && PropertyName != wxT("TYPE")){
1924 if (FirstToken == TRUE){
1926 PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue);
1931 PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue);
1941 IMList->insert(std::make_pair(*IMCount, PropertySeg2));
1943 // Add the name token data.
1945 if (!PropertyTokens.IsEmpty()){
1947 IMListTokens->insert(std::make_pair(*IMCount, PropertyTokens));
1953 void ContactDataObject::ProcessTelephone(wxString PropertySeg1, wxString PropertySeg2, int *TelephoneCount){
1955 std::map<int, int> SplitPoints;
1956 std::map<int, int> SplitLength;
1957 std::map<int, int>::iterator SLiter;
1961 PropertyType PropType = PROPERTY_NONE;
1963 // Look for type before continuing.
1966 wxString TelTypeDetail;
1967 wxString PropertyData;
1968 wxString PropertyName;
1969 wxString PropertyValue;
1970 wxString PropertyTokens;
1972 std::map<int,int> TypeSplitPoints;
1973 std::map<int,int> TypeSplitLength;
1974 std::map<int,int>::iterator TSLiter;
1976 int intSplitSize = 0;
1977 int intSplitsFound = 0;
1978 int intSplitPoint = 0;
1980 int intPrevValue = 5;
1982 SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue);
1986 // Look for type before continuing.
1988 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
1989 intiter != SplitPoints.end(); ++intiter){
1991 SLiter = SplitLength.find(intiter->first);
1993 PropertyData = PropertySeg1.Mid(intPrevValue, (SLiter->second));
1995 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
1996 PropertyName = PropertyElement.GetNextToken();
1997 PropertyValue = PropertyElement.GetNextToken();
1999 intPrevValue = intiter->second;
2001 if (PropertyName == wxT("TYPE")){
2003 // Process each value in type and translate each
2006 // Strip out the quotes if they are there.
2008 size_t intPropertyValueLen = PropertyValue.Len();
2010 if (PropertyValue.Mid((intPropertyValueLen - 1), 1) == wxT("\"")){
2012 PropertyValue.Trim();
2013 PropertyValue.RemoveLast();
2017 if (PropertyValue.Mid(0, 1) == wxT("\"")){
2019 PropertyValue.Remove(0, 1);
2023 TelTypeDetail = PropertyValue;
2029 for (int i = 0; i <= intPropertyValueLen; i++){
2033 if (PropertyValue.Mid(i, 1) == wxT(",") && PropertyValue.Mid((i - 1), 1) != wxT("\\")){
2035 if (intSplitsFound == 0){
2037 TypeSplitPoints.insert(std::make_pair(intSplitsFound, intSplitPoint));
2038 TypeSplitLength.insert(std::make_pair(intSplitsFound, (intSplitSize - 1)));
2042 TypeSplitPoints.insert(std::make_pair(intSplitsFound, intSplitPoint));
2043 TypeSplitLength.insert(std::make_pair(intSplitsFound, intSplitSize));
2056 TypeSplitPoints.insert(std::make_pair(intSplitsFound, intSplitPoint));
2057 TypeSplitLength.insert(std::make_pair(intSplitsFound, intSplitSize));
2059 int intTypeSeek = 0;
2061 for (std::map<int, int>::iterator typeiter = TypeSplitPoints.begin();
2062 typeiter != TypeSplitPoints.end(); ++typeiter){
2064 wxString TypePropertyName;
2066 TSLiter = TypeSplitLength.find(typeiter->first);
2068 TypePropertyName = PropertyValue.Mid(typeiter->second, TSLiter->second);
2070 if (intTypeSeek == 0){
2075 TelTypeUI.Append(wxT(","));
2079 if (TypePropertyName == wxT("home")){
2081 PropType = PROPERTY_HOME;
2083 } else if (TypePropertyName == wxT("work")){
2085 PropType = PROPERTY_WORK;
2090 if (TypePropertyName == wxT("text")){
2092 TelTypeUI.Append(_("text"));
2095 } else if (TypePropertyName == wxT("voice")){
2097 TelTypeUI.Append(_("voice"));
2100 } else if (TypePropertyName == wxT("fax")){
2102 TelTypeUI.Append(_("fax"));
2105 } else if (TypePropertyName == wxT("cell")){
2107 TelTypeUI.Append(_("mobile"));
2110 } else if (TypePropertyName == wxT("video")){
2112 TelTypeUI.Append(_("video"));
2115 } else if (TypePropertyName == wxT("pager")){
2117 TelTypeUI.Append(_("pager"));
2120 } else if (TypePropertyName == wxT("textphone")){
2122 TelTypeUI.Append(_("textphone"));
2133 std::map<int, wxString> *TelephoneList = NULL;
2134 std::map<int, wxString> *TelephoneListType = NULL;
2135 std::map<int, wxString> *TelephoneListAltID = NULL;
2136 std::map<int, wxString> *TelephoneListPID = NULL;
2137 std::map<int, wxString> *TelephoneListTokens = NULL;
2138 std::map<int, wxString> *TelephoneListTypeInfo = NULL;
2139 std::map<int, int> *TelephoneListPref = NULL;
2143 TelephoneList = &GeneralTelephoneList;
2144 TelephoneListType = &GeneralTelephoneListType;
2145 TelephoneListAltID = &GeneralTelephoneListAltID;
2146 TelephoneListPID = &GeneralTelephoneListPID;
2147 TelephoneListTokens = &GeneralTelephoneListTokens;
2148 TelephoneListTypeInfo = &GeneralTelephoneListTypeInfo;
2149 TelephoneListPref = &GeneralTelephoneListPref;
2152 TelephoneList = &HomeTelephoneList;
2153 TelephoneListType = &HomeTelephoneListType;
2154 TelephoneListAltID = &HomeTelephoneListAltID;
2155 TelephoneListPID = &HomeTelephoneListPID;
2156 TelephoneListTokens = &HomeTelephoneListTokens;
2157 TelephoneListTypeInfo = &HomeTelephoneListTypeInfo;
2158 TelephoneListPref = &HomeTelephoneListPref;
2161 TelephoneList = &BusinessTelephoneList;
2162 TelephoneListType = &BusinessTelephoneListType;
2163 TelephoneListAltID = &BusinessTelephoneListAltID;
2164 TelephoneListPID = &BusinessTelephoneListPID;
2165 TelephoneListTokens = &BusinessTelephoneListTokens;
2166 TelephoneListTypeInfo = &BusinessTelephoneListTypeInfo;
2167 TelephoneListPref = &BusinessTelephoneListPref;
2171 // Process the properties.
2173 bool FirstToken = TRUE;
2176 SplitPoints.clear();
2177 SplitLength.clear();
2179 SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue);
2183 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
2184 intiter != SplitPoints.end(); ++intiter){
2186 SLiter = SplitLength.find(intiter->first);
2188 PropertyData = PropertySeg1.Mid(intPrevValue, (SLiter->second));
2190 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
2191 PropertyName = PropertyElement.GetNextToken();
2192 PropertyValue = PropertyElement.GetNextToken();
2194 intPrevValue = intiter->second;
2196 CaptureString(&PropertyValue, FALSE);
2198 // Process properties.
2200 if (PropertyName == wxT("ALTID")){
2202 TelephoneListAltID->erase(*TelephoneCount);
2203 TelephoneListAltID->insert(std::make_pair(*TelephoneCount, PropertyValue));
2205 } else if (PropertyName == wxT("PID")){
2207 TelephoneListPID->erase(*TelephoneCount);
2208 TelephoneListPID->insert(std::make_pair(*TelephoneCount, PropertyValue));
2210 } else if (PropertyName == wxT("PREF")){
2212 int PriorityNumber = 0;
2213 bool ValidNumber = TRUE;
2216 PriorityNumber = std::stoi(PropertyValue.ToStdString());
2219 catch(std::invalid_argument &e){
2220 ValidNumber = FALSE;
2223 if (ValidNumber == TRUE){
2225 TelephoneListPref->erase(*TelephoneCount);
2226 TelephoneListPref->insert(std::make_pair(*TelephoneCount, PriorityNumber));
2232 if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty() && PropertyName != wxT("TYPE")){
2234 if (FirstToken == TRUE){
2236 PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue);
2241 PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue);
2251 TelephoneList->insert(std::make_pair(*TelephoneCount, PropertySeg2));
2252 TelephoneListTypeInfo->insert(std::make_pair(*TelephoneCount, TelTypeUI));
2254 // Add the name token data.
2256 if (!PropertyTokens.IsEmpty()){
2258 TelephoneListTokens->insert(std::make_pair(*TelephoneCount, PropertyTokens));
2264 void ContactDataObject::ProcessLanguage(wxString PropertySeg1, wxString PropertySeg2, int *LanguageCount){
2266 std::map<int, int> SplitPoints;
2267 std::map<int, int> SplitLength;
2269 int intPrevValue = 6;
2272 SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue);
2276 PropertyType PropType = PROPERTY_NONE;
2278 // Look for type before continuing.
2280 CheckType(&PropertySeg1, &SplitPoints, &SplitLength, &intPrevValue, &PropType);
2282 std::map<int, wxString> *LanguageList = NULL;
2283 std::map<int, wxString> *LanguageListType = NULL;
2284 std::map<int, wxString> *LanguageListAltID = NULL;
2285 std::map<int, wxString> *LanguageListPID = NULL;
2286 std::map<int, wxString> *LanguageListTokens = NULL;
2287 std::map<int, int> *LanguageListPref = NULL;
2291 LanguageList = &GeneralLanguageList;
2292 LanguageListType = &GeneralLanguageListType;
2293 LanguageListAltID = &GeneralLanguageListAltID;
2294 LanguageListPID = &GeneralLanguageListPID;
2295 LanguageListTokens = &GeneralLanguageListTokens;
2296 LanguageListPref = &GeneralLanguageListPref;
2299 LanguageList = &HomeLanguageList;
2300 LanguageListType = &HomeLanguageListType;
2301 LanguageListAltID = &HomeLanguageListAltID;
2302 LanguageListPID = &HomeLanguageListPID;
2303 LanguageListTokens = &HomeLanguageListTokens;
2304 LanguageListPref = &HomeLanguageListPref;
2307 LanguageList = &BusinessLanguageList;
2308 LanguageListType = &BusinessLanguageListType;
2309 LanguageListAltID = &BusinessLanguageListAltID;
2310 LanguageListPID = &BusinessLanguageListPID;
2311 LanguageListTokens = &BusinessLanguageListTokens;
2312 LanguageListPref = &BusinessLanguageListPref;
2318 std::map<int,int>::iterator SLiter;
2319 wxString PropertyData;
2320 wxString PropertyName;
2321 wxString PropertyValue;
2322 wxString PropertyTokens;
2323 bool FirstToken = TRUE;
2325 for (std::map<int, int>::iterator intiter = SplitPoints.begin();
2326 intiter != SplitPoints.end(); ++intiter){
2328 SLiter = SplitLength.find(intiter->first);
2330 PropertyData = PropertySeg1.Mid(intPrevValue, (SLiter->second));
2332 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
2333 PropertyName = PropertyElement.GetNextToken();
2334 PropertyValue = PropertyElement.GetNextToken();
2336 intPrevValue = intiter->second;
2338 CaptureString(&PropertyValue, FALSE);
2340 // Process properties.
2342 if (PropertyName == wxT("ALTID")){
2344 LanguageListAltID->erase(*LanguageCount);
2345 LanguageListAltID->insert(std::make_pair(*LanguageCount, PropertyValue));
2347 } else if (PropertyName == wxT("PID")){
2349 LanguageListPID->erase(*LanguageCount);
2350 LanguageListPID->insert(std::make_pair(*LanguageCount, PropertyValue));
2352 } else if (PropertyName == wxT("PREF")){
2354 int PriorityNumber = 0;
2355 bool ValidNumber = TRUE;
2358 PriorityNumber = std::stoi(PropertyValue.ToStdString());
2361 catch(std::invalid_argument &e){
2362 ValidNumber = FALSE;
2365 if (ValidNumber == TRUE){
2367 LanguageListPref->erase(*LanguageCount);
2368 LanguageListPref->insert(std::make_pair(*LanguageCount, PriorityNumber));
2374 if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty() && PropertyName != wxT("TYPE")){
2376 if (FirstToken == TRUE){
2378 PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue);
2383 PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue);
2393 LanguageList->insert(std::make_pair(*LanguageCount, PropertySeg2));
2395 // Add the name token data.
2397 if (!PropertyTokens.IsEmpty()){
2399 LanguageListTokens->insert(std::make_pair(*LanguageCount, PropertyTokens));
2405 void SplitValues(wxString *PropertyLine,
2406 std::map<int,int> *SplitPoints,
2407 std::map<int,int> *SplitLength,
2410 size_t intPropertyLen = PropertyLine->Len();
2411 int intSplitsFound = 0;
2412 int intSplitSize = 0;
2413 int intSplitSeek = 0;
2415 for (int i = intSize; i <= intPropertyLen; i++){
2419 if (PropertyLine->Mid(i, 1) == wxT(";") &&
2420 PropertyLine->Mid((i - 1), 1) != wxT("\\")){
2422 if (intSplitsFound == 0){
2424 SplitLength->insert(std::make_pair(intSplitsFound, (intSplitSize)));
2428 SplitLength->insert(std::make_pair(intSplitsFound, (intSplitSize - 1)));
2432 SplitPoints->insert(std::make_pair(intSplitsFound, (i + 1)));
2442 if (intSplitsFound == 0){
2444 SplitPoints->insert(std::make_pair(intSplitsFound, (8 + 1)));
2445 SplitLength->insert(std::make_pair(intSplitsFound, intSplitSize));
2449 SplitPoints->insert(std::make_pair(intSplitsFound, (intSplitSeek + 1)));
2450 SplitLength->insert(std::make_pair(intSplitsFound, intSplitSize));
2456 void CheckType(wxString *PropertySeg1,
2457 std::map<int,int> *SplitPoints,
2458 std::map<int,int> *SplitLength,
2460 PropertyType *PropType){
2462 wxString PropertyData;
2463 wxString PropertyName;
2464 wxString PropertyValue;
2465 std::map<int,int>::iterator SLiter;
2467 for (std::map<int, int>::iterator intiter = SplitPoints->begin();
2468 intiter != SplitPoints->end(); ++intiter){
2470 SLiter = SplitLength->find(intiter->first);
2472 PropertyData = PropertySeg1->Mid(*intPrevValue, (SLiter->second));
2474 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
2475 PropertyName = PropertyElement.GetNextToken();
2476 PropertyValue = PropertyElement.GetNextToken();
2478 *intPrevValue = intiter->second;
2480 if (PropertyName == wxT("TYPE")){
2482 if (PropertyValue == wxT("work")){
2484 *PropType = PROPERTY_WORK;
2486 } else if (PropertyValue == wxT("home")){
2488 *PropType = PROPERTY_HOME;
2492 *PropType = PROPERTY_NONE;