From fa6a8a4169f7c99d97490f91e06b93c82fc29251 Mon Sep 17 00:00:00 2001 From: Steve Brokenshire Date: Sun, 20 Dec 2015 17:53:44 +0000 Subject: [PATCH] Added source code, headers and unit testing for the TITLE vCard Property for ContactDataObject. --- source/contacteditor/ContactDataObject.cpp | 202 ++++++++++++++++++++- source/contacteditor/ContactDataObject.h | 1 + source/tests/LoadCheck-Load4.vcf | 5 + source/tests/xestiaab_contactload.h | 121 ++++++++++++ 4 files changed, 323 insertions(+), 6 deletions(-) diff --git a/source/contacteditor/ContactDataObject.cpp b/source/contacteditor/ContactDataObject.cpp index 13c869f..a8c6e7d 100644 --- a/source/contacteditor/ContactDataObject.cpp +++ b/source/contacteditor/ContactDataObject.cpp @@ -92,6 +92,7 @@ ContactLoadStatus ContactDataObject::LoadFile(wxString Filename){ int GeographicCount = 0; int RelatedCount = 0; int URLCount = 0; + int TitleCount = 0; wxString ContactLine; wxString PropertyLine; wxString PropertySeg1; @@ -282,6 +283,13 @@ ContactLoadStatus ContactDataObject::LoadFile(wxString Filename){ ProcessURL(PropertySeg1, PropertySeg2, &URLCount); URLCount++; + } else if (Property == wxT("TITLE")) { + + // See frmContactEditor-LoadTitle.cpp + + ProcessTitle(PropertySeg1, PropertySeg2, &TitleCount); + TitleCount++; + } } @@ -2757,14 +2765,22 @@ void ContactDataObject::ProcessRelated(wxString PropertySeg1, wxString PropertyS } else if (PropertyName == wxT("PREF")){ - intPref = wxAtoi(PropertyValue); - - if (intPref > 0 && intPref < 101){ - + int PriorityNumber = 0; + bool ValidNumber = TRUE; + + try{ + PriorityNumber = std::stoi(PropertyValue.ToStdString()); + } + + catch(std::invalid_argument &e){ + ValidNumber = FALSE; + } + + if (ValidNumber == TRUE){ + GeneralRelatedListPref.erase(*RelatedCount); - GeneralRelatedListPref.insert(std::make_pair(*RelatedCount, intPref)); + GeneralRelatedListPref.insert(std::make_pair(*RelatedCount, PriorityNumber)); - } } else if (PropertyName == wxT("LANGUAGE")){ @@ -2983,6 +2999,180 @@ void ContactDataObject::ProcessURL(wxString PropertySeg1, wxString PropertySeg2, } +void ContactDataObject::ProcessTitle(wxString PropertySeg1, wxString PropertySeg2, int *TitleCount){ + + std::map SplitPoints; + std::map SplitLength; + std::map::iterator SLiter; + wxString PropertyData; + wxString PropertyName; + wxString PropertyValue; + wxString PropertyTokens; + bool FirstToken = TRUE; + int intPrevValue = 7; + int intPref = 0; + int intType = 0; + long ListCtrlIndex; + + SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue); + + intPrevValue = 6; + + PropertyType PropType = PROPERTY_NONE; + + // Look for type before continuing. + + CheckType(&PropertySeg1, &SplitPoints, &SplitLength, &intPrevValue, &PropType); + + // Setup the pointers. + + std::map *TitleList = NULL; + std::map *TitleListAltID = NULL; + std::map *TitleListPID = NULL; + std::map *TitleListType = NULL; + std::map *TitleListTokens = NULL; + std::map *TitleListLanguage = NULL; + std::map *TitleListPref = NULL; + + // Setup blank lines for later on. + + switch(PropType){ + case PROPERTY_NONE: + TitleList = &GeneralTitleList; + TitleListType = &GeneralTitleListType; + TitleListAltID = &GeneralTitleListAltID; + TitleListPID = &GeneralTitleListPID; + TitleListTokens = &GeneralTitleListTokens; + TitleListLanguage = &GeneralTitleListLanguage; + TitleListPref = &GeneralTitleListPref; + break; + case PROPERTY_HOME: + TitleList = &HomeTitleList; + TitleListType = &HomeTitleListType; + TitleListAltID = &HomeTitleListAltID; + TitleListPID = &HomeTitleListPID; + TitleListTokens = &HomeTitleListTokens; + TitleListLanguage = &HomeTitleListLanguage; + TitleListPref = &HomeTitleListPref; + break; + case PROPERTY_WORK: + TitleList = &BusinessTitleList; + TitleListType = &BusinessTitleListType; + TitleListAltID = &BusinessTitleListAltID; + TitleListPID = &BusinessTitleListPID; + TitleListTokens = &BusinessTitleListTokens; + TitleListLanguage = &BusinessTitleListLanguage; + TitleListPref = &BusinessTitleListPref; + break; + } + + intPrevValue = 6; + + for (std::map::iterator intiter = SplitPoints.begin(); + intiter != SplitPoints.end(); ++intiter){ + + SLiter = SplitLength.find(intiter->first); + + PropertyData = PropertySeg1.Mid(intPrevValue, (SLiter->second)); + + wxStringTokenizer PropertyElement (PropertyData, wxT("=")); + PropertyName = PropertyElement.GetNextToken(); + PropertyValue = PropertyElement.GetNextToken(); + + intPrevValue = intiter->second; + + // Process properties. + + size_t intPropertyValueLen = PropertyValue.Len(); + + if (PropertyValue.Mid((intPropertyValueLen - 1), 1) == wxT("\"")){ + + PropertyValue.Trim(); + PropertyValue.RemoveLast(); + + } + + if (PropertyValue.Mid(0, 1) == wxT("\"")){ + + PropertyValue.Remove(0, 1); + + } + + CaptureString(&PropertyValue, FALSE); + + if (PropertyName == wxT("ALTID")){ + + TitleListAltID->erase(*TitleCount); + TitleListAltID->insert(std::make_pair(*TitleCount, PropertyValue)); + + } else if (PropertyName == wxT("PID")){ + + TitleListPID->erase(*TitleCount); + TitleListPID->insert(std::make_pair(*TitleCount, PropertyValue)); + + } else if (PropertyName == wxT("PREF")){ + + int PriorityNumber = 0; + bool ValidNumber = TRUE; + + try{ + PriorityNumber = std::stoi(PropertyValue.ToStdString()); + } + + catch(std::invalid_argument &e){ + ValidNumber = FALSE; + } + + if (ValidNumber == TRUE){ + + TitleListPref->erase(*TitleCount); + TitleListPref->insert(std::make_pair(*TitleCount, PriorityNumber)); + + } + + } else if (PropertyName == wxT("LANGUAGE")){ + + TitleListLanguage->erase(*TitleCount); + TitleListLanguage->insert(std::make_pair(*TitleCount, PropertyValue)); + + } else { + + // Something else we don't know about so append + // to the tokens variable. + + if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty() && PropertyName != wxT("TYPE")){ + + if (FirstToken == TRUE){ + + PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue); + FirstToken = FALSE; + + } else { + + PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue); + + } + + } + + } + + } + + // Add the data to the General/Home/Work address variables. + + CaptureString(&PropertySeg2, FALSE); + + TitleList->insert(std::make_pair(*TitleCount, PropertySeg2)); + + if (!PropertyTokens.IsEmpty()){ + + TitleListTokens->insert(std::make_pair(*TitleCount, PropertyTokens)); + + } + +} + void SplitValues(wxString *PropertyLine, std::map *SplitPoints, std::map *SplitLength, diff --git a/source/contacteditor/ContactDataObject.h b/source/contacteditor/ContactDataObject.h index 02b6820..6ee0279 100644 --- a/source/contacteditor/ContactDataObject.h +++ b/source/contacteditor/ContactDataObject.h @@ -71,6 +71,7 @@ class ContactDataObject{ void ProcessGeographic(wxString PropertySeg1, wxString PropertySeg2, int *GeographicCount); void ProcessRelated(wxString PropertySeg1, wxString PropertySeg2, int *RelatedCount); void ProcessURL(wxString PropertySeg1, wxString PropertySeg2, int *URLCount); + void ProcessTitle(wxString PropertySeg1, wxString PropertySeg2, int *TitleCount); public: diff --git a/source/tests/LoadCheck-Load4.vcf b/source/tests/LoadCheck-Load4.vcf index 64651dc..34df7cf 100644 --- a/source/tests/LoadCheck-Load4.vcf +++ b/source/tests/LoadCheck-Load4.vcf @@ -60,4 +60,9 @@ URL;TYPE=home;ALTID=10;PID=11;PREF=12;MEDIATYPE=grass/soggy;BON=Bon:http://e xample.com/home/ URL;TYPE=work;ALTID=20;PID=21;PREF=22;MEDIATYPE=chocolate/yummy;YES=No:http: //example.com/business/ +TITLE;ALTID=20;PID=21;LANGUAGE=text/plain;PREF=22;EEP=LIGHT:Lord of Light +TITLE;TYPE=home;ALTID=30;PID=31;LANGUAGE=grass/dry;PREF=32;EEP=DARK:Lord of + Darkness +TITLE;TYPE=work;ALTID=40;PID=41;LANGUAGE=moths/eew;PREF=42;EEP=BOTH:Master o + f the Light & Darkness END:VCARD diff --git a/source/tests/xestiaab_contactload.h b/source/tests/xestiaab_contactload.h index fc7a48c..0f3f88a 100644 --- a/source/tests/xestiaab_contactload.h +++ b/source/tests/xestiaab_contactload.h @@ -1578,4 +1578,125 @@ TEST(ContactLoad, URLTests){ } +TEST(ContactLoad, TitleTests){ + + ContactDataObject TestFile; + + // Check that the vCard 4.0 file loads OK. + + ASSERT_EQ(CONTACTLOAD_OK, TestFile.LoadFile("LoadCheck-Load4.vcf")); + + std::map::iterator TestFileIter; + std::map::iterator TestFileIntIter; + + // Start with the general URL. + + TestFileIter = TestFile.GeneralTitleList.find(0); + ASSERT_NE(TestFile.GeneralTitleList.end(), TestFileIter); + ASSERT_EQ("Lord of Light", TestFileIter->second); + + // Check the ALTID section. + + TestFileIter = TestFile.GeneralTitleListAltID.find(0); + ASSERT_NE(TestFile.GeneralTitleListAltID.end(), TestFileIter); + ASSERT_EQ("20", TestFileIter->second); + + // Check the PID section. + + TestFileIter = TestFile.GeneralTitleListPID.find(0); + ASSERT_NE(TestFile.GeneralTitleListPID.end(), TestFileIter); + ASSERT_EQ("21", TestFileIter->second); + + // Check the LANGUAGE section. + + TestFileIter = TestFile.GeneralTitleListLanguage.find(0); + ASSERT_NE(TestFile.GeneralTitleListLanguage.end(), TestFileIter); + ASSERT_EQ("text/plain", TestFileIter->second); + + // Check the PREF section. + + TestFileIntIter = TestFile.GeneralTitleListPref.find(0); + ASSERT_NE(TestFile.GeneralTitleListPref.end(), TestFileIntIter); + ASSERT_EQ(22, TestFileIntIter->second); + + // Check the extra tokens. + + TestFileIter = TestFile.GeneralTitleListTokens.find(0); + ASSERT_NE(TestFile.GeneralTitleListTokens.end(), TestFileIter); + ASSERT_EQ("EEP=LIGHT", TestFileIter->second); + + // Start with the home URL. + + TestFileIter = TestFile.HomeTitleList.find(1); + ASSERT_NE(TestFile.HomeTitleList.end(), TestFileIter); + ASSERT_EQ("Lord of Darkness", TestFileIter->second); + + // Check the ALTID section. + + TestFileIter = TestFile.HomeTitleListAltID.find(1); + ASSERT_NE(TestFile.HomeTitleListAltID.end(), TestFileIter); + ASSERT_EQ("30", TestFileIter->second); + + // Check the PID section. + + TestFileIter = TestFile.HomeTitleListPID.find(1); + ASSERT_NE(TestFile.HomeTitleListPID.end(), TestFileIter); + ASSERT_EQ("31", TestFileIter->second); + + // Check the LANGUAGE section. + + TestFileIter = TestFile.HomeTitleListLanguage.find(1); + ASSERT_NE(TestFile.HomeTitleListLanguage.end(), TestFileIter); + ASSERT_EQ("grass/dry", TestFileIter->second); + + // Check the PREF section. + + TestFileIntIter = TestFile.HomeTitleListPref.find(1); + ASSERT_NE(TestFile.HomeTitleListPref.end(), TestFileIntIter); + ASSERT_EQ(32, TestFileIntIter->second); + + // Check the extra tokens. + + TestFileIter = TestFile.HomeTitleListTokens.find(1); + ASSERT_NE(TestFile.HomeTitleListTokens.end(), TestFileIter); + ASSERT_EQ("EEP=DARK", TestFileIter->second); + + // Start with the business URL. + + TestFileIter = TestFile.BusinessTitleList.find(2); + ASSERT_NE(TestFile.BusinessTitleList.end(), TestFileIter); + ASSERT_EQ("Master of the Light & Darkness", TestFileIter->second); + + // Check the ALTID section. + + TestFileIter = TestFile.BusinessTitleListAltID.find(2); + ASSERT_NE(TestFile.BusinessTitleListAltID.end(), TestFileIter); + ASSERT_EQ("40", TestFileIter->second); + + // Check the PID section. + + TestFileIter = TestFile.BusinessTitleListPID.find(2); + ASSERT_NE(TestFile.BusinessTitleListPID.end(), TestFileIter); + ASSERT_EQ("41", TestFileIter->second); + + // Check the LANGUAGE section. + + TestFileIter = TestFile.BusinessTitleListLanguage.find(2); + ASSERT_NE(TestFile.BusinessTitleListLanguage.end(), TestFileIter); + ASSERT_EQ("moths/eew", TestFileIter->second); + + // Check the PREF section. + + TestFileIntIter = TestFile.BusinessTitleListPref.find(2); + ASSERT_NE(TestFile.BusinessTitleListPref.end(), TestFileIntIter); + ASSERT_EQ(42, TestFileIntIter->second); + + // Check the extra tokens. + + TestFileIter = TestFile.BusinessTitleListTokens.find(2); + ASSERT_NE(TestFile.BusinessTitleListTokens.end(), TestFileIter); + ASSERT_EQ("EEP=BOTH", TestFileIter->second); + +} + // TODO: Add tests for the Contact Loading process. \ No newline at end of file -- 2.39.5