1 // frmContactEditor-Load.cpp - frmContactEditor load contact subroutines.
3 // (c) 2012-2015 Xestia Software Development.
5 // This file is part of Xestia Address Book.
7 // Xestia Address Book is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by the
9 // Free Software Foundation, version 3 of the license.
11 // Xestia Address Book is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License along
17 // with Xestia Address Book. If not, see <http://www.gnu.org/licenses/>
22 #include <wx/tokenzr.h>
23 #include <wx/datetime.h>
26 #include "frmContactEditor.h"
29 #include "../version.h"
30 #include "../vcard/vcard.h"
31 #include "../common/textprocessing.h"
32 #include "../common/dirs.h"
33 #include "cdo/ContactDataObject.h"
35 bool frmContactEditor::LoadContact(wxString Filename){
37 // Load the contact into the contact editor.
40 wxString wxSContactString;
44 if (StartupEditMode == FALSE){
45 XVMData = MainPtr->GetViewMode();
48 wxSContactFilename = Filename;
50 ContactLoadStatus LoadResult = ContactEditorData.LoadFile(Filename);
56 case CONTACTLOAD_FILEMISSING:
57 wxMessageBox(_("The file with the filename given does not exist."),
58 _("Contact not found"), wxICON_ERROR);
62 case CONTACTLOAD_FILEERROR:
63 wxMessageBox(_("The file with the filename given cannot be opened due to an error while trying open it."),
64 _("Error loading contact"), wxICON_ERROR);
68 case CONTACTLOAD_FILEINVALIDFORMAT:
69 wxMessageBox(_("This file is not a vCard 4.0 contact and is not supported under Xestia Address Book."),
70 _("Contact not supported"), wxICON_ERROR);
74 case CONTACTLOAD_FILEBASESPECFAIL:
75 wxMessageBox(_("This file is not a vCard 4.0 contact and is not supported under Xestia Address Book."),
76 _("Contact not supported"), wxICON_ERROR);
85 bool QuoteMode = FALSE;
86 bool PropertyFind = TRUE;
87 bool HasExtraNicknames = FALSE;
88 bool IgnoreGender = FALSE;
89 bool ExtraLineSeek = TRUE;
90 bool FNProcessed = FALSE;
91 bool GenderProcessed = FALSE;
92 bool NameProcessed = FALSE;
93 bool ETagFound = FALSE;
94 bool ETagOrigFound = FALSE;
95 bool VersionProcessed = FALSE;
96 int intExtraNickname = 0;
98 wxString wxSPropertySeg1;
99 wxString wxSPropertySeg2;
100 wxString wxSPropertyNextLine;
101 size_t ContactLineLen = 0;
102 int QuoteBreakPoint = 0;
105 int NicknameCount = 0;
114 int RelatedCount = 0;
119 int CategoryCount = 0;
125 int CalReqAdrCount = 0;
126 int FreeBusyCount = 0;
131 // Process the unique ID (UID)
133 // Do nothing at the moment.
135 // Process the contact type (KIND) (frmContactEditor-LoadGroup.cpp)
137 LoadKind(&ContactEditorData.ContactKind);
139 // Process the Birthday (BDAY) (frmContactEditor-LoadBADays.cpp)
141 LoadBirthday(&ContactEditorData.Birthday, &ContactEditorData.BirthdayText);
143 // Process the Anniversary (ANNIVERSARY) (frmContactEditor-LoadBADays.cpp)
145 LoadAnniversary(&ContactEditorData.Anniversary, &ContactEditorData.AnniversaryText);
147 // Process the Gender (GENDER) (frmContactEditor-LoadGender.cpp)
149 LoadGender(&ContactEditorData.Gender, &ContactEditorData.GenderDetails);
151 // Process the Name (N) (frmContactEditor-LoadName.cpp)
153 LoadName(&ContactEditorData.NameTitle, &ContactEditorData.NameForename,
154 &ContactEditorData.NameSurname, &ContactEditorData.NameOtherNames,
155 &ContactEditorData.NameSuffix);
157 // Process the group members (MEMBER) (frmContactEditor-LoadGroup.cpp)
159 LoadMember(&ContactEditorData.GroupsList);
161 // Process the addresses (ADR) (frmContactEditor-LoadAddress.cpp)
163 LoadAddress(&ContactEditorData.GeneralAddressList,
164 &ContactEditorData.GeneralAddressListTown,
165 &ContactEditorData.GeneralAddressListCounty,
166 &ContactEditorData.GeneralAddressListPostCode,
167 &ContactEditorData.GeneralAddressListPref,
168 &ContactEditorData.HomeAddressList,
169 &ContactEditorData.HomeAddressListTown,
170 &ContactEditorData.HomeAddressListCounty,
171 &ContactEditorData.HomeAddressListPostCode,
172 &ContactEditorData.HomeAddressListPref,
173 &ContactEditorData.BusinessAddressList,
174 &ContactEditorData.BusinessAddressListTown,
175 &ContactEditorData.BusinessAddressListCounty,
176 &ContactEditorData.BusinessAddressListPostCode,
177 &ContactEditorData.BusinessAddressListPref,
180 // Process the timezones (TZ).
182 LoadData(&ContactEditorData.GeneralTZList,
183 &ContactEditorData.GeneralTZListPref,
185 &ContactEditorData.HomeTZList,
186 &ContactEditorData.HomeTZListPref,
188 &ContactEditorData.BusinessTZList,
189 &ContactEditorData.BusinessTZListPref,
190 lboBusinessTimezones,
193 // Process the emails (EMAIL).
195 LoadData(&ContactEditorData.GeneralEmailList,
196 &ContactEditorData.GeneralEmailListPref,
198 &ContactEditorData.HomeEmailList,
199 &ContactEditorData.HomeEmailListPref,
201 &ContactEditorData.BusinessEmailList,
202 &ContactEditorData.BusinessEmailListPref,
206 // Process the nicknames (NICKNAME).
208 LoadData(&ContactEditorData.GeneralNicknamesList,
209 &ContactEditorData.GeneralNicknamesListPref,
211 &ContactEditorData.HomeNicknamesList,
212 &ContactEditorData.HomeNicknamesListPref,
214 &ContactEditorData.BusinessNicknamesList,
215 &ContactEditorData.BusinessNicknamesListPref,
216 lboBusinessNicknames,
219 // Process the languages (LANG).
221 LoadData(&ContactEditorData.GeneralLanguageList,
222 &ContactEditorData.GeneralLanguageListPref,
224 &ContactEditorData.HomeLanguageList,
225 &ContactEditorData.HomeLanguageListPref,
227 &ContactEditorData.BusinessLanguageList,
228 &ContactEditorData.BusinessLanguageListPref,
229 lboBusinessLanguages,
232 // Process the geopositiosn (GEO).
234 LoadData(&ContactEditorData.GeneralGeographyList,
235 &ContactEditorData.GeneralGeographyListPref,
237 &ContactEditorData.HomeGeographyList,
238 &ContactEditorData.HomeGeographyListPref,
240 &ContactEditorData.BusinessGeographyList,
241 &ContactEditorData.BusinessGeographyListPref,
242 lboBusinessGeoposition,
245 // Process the websites (URL).
247 LoadData(&ContactEditorData.GeneralWebsiteList,
248 &ContactEditorData.GeneralWebsiteListPref,
250 &ContactEditorData.HomeWebsiteList,
251 &ContactEditorData.HomeWebsiteListPref,
253 &ContactEditorData.BusinessWebsiteList,
254 &ContactEditorData.BusinessWebsiteListPref,
258 // Process the titles (TITLE).
260 LoadData(&ContactEditorData.GeneralTitleList,
261 &ContactEditorData.GeneralTitleListPref,
263 &ContactEditorData.HomeTitleList,
264 &ContactEditorData.HomeTitleListPref,
266 &ContactEditorData.BusinessTitleList,
267 &ContactEditorData.BusinessTitleListPref,
271 // Process the roles (ROLE).
273 LoadData(&ContactEditorData.GeneralRoleList,
274 &ContactEditorData.GeneralRoleListPref,
276 &ContactEditorData.HomeRoleList,
277 &ContactEditorData.HomeRoleListPref,
279 &ContactEditorData.BusinessRoleList,
280 &ContactEditorData.BusinessRoleListPref,
284 // Process the roles (ORG).
286 LoadData(&ContactEditorData.GeneralOrganisationsList,
287 &ContactEditorData.GeneralOrganisationsListPref,
289 &ContactEditorData.HomeOrganisationsList,
290 &ContactEditorData.HomeOrganisationsListPref,
291 lboHomeOrganisations,
292 &ContactEditorData.BusinessOrganisationsList,
293 &ContactEditorData.BusinessOrganisationsListPref,
294 lboBusinessOrganisations,
297 // Process the notes (NOTE).
299 LoadData(&ContactEditorData.GeneralNoteList,
300 &ContactEditorData.GeneralNoteListPref,
302 &ContactEditorData.HomeNoteList,
303 &ContactEditorData.HomeNoteListPref,
305 &ContactEditorData.BusinessNoteList,
306 &ContactEditorData.BusinessNoteListPref,
310 // Process the categories (CATEGORIES).
312 LoadData(&ContactEditorData.CategoriesList,
313 &ContactEditorData.CategoriesListPref,
317 // Process the telephone numbers (TEL).
319 LoadData(&ContactEditorData.GeneralTelephoneList,
320 &ContactEditorData.GeneralTelephoneListPref,
321 &ContactEditorData.GeneralTelephoneListTypeInfo,
323 &ContactEditorData.HomeTelephoneList,
324 &ContactEditorData.HomeTelephoneListPref,
325 &ContactEditorData.HomeTelephoneListTypeInfo,
327 &ContactEditorData.BusinessTelephoneList,
328 &ContactEditorData.BusinessTelephoneListPref,
329 &ContactEditorData.BusinessTelephoneListTypeInfo,
330 lboBusinessTelephone,
333 // Process the instant messaging (IMPP).
335 LoadData(&ContactEditorData.GeneralIMListTypeInfo,
336 &ContactEditorData.GeneralIMListPref,
337 &ContactEditorData.GeneralIMList,
339 &ContactEditorData.HomeIMListTypeInfo,
340 &ContactEditorData.HomeIMListPref,
341 &ContactEditorData.HomeIMList,
343 &ContactEditorData.BusinessIMListTypeInfo,
344 &ContactEditorData.BusinessIMListPref,
345 &ContactEditorData.BusinessIMList,
349 // Process the photos (PHOTO).
351 LoadPictureData("PHOTO",
352 &ContactEditorData.PicturesList,
353 &ContactEditorData.PicturesListPref,
354 &ContactEditorData.PicturesListType,
358 // Process the logos (LOGO).
360 LoadPictureData("LOGO",
361 &ContactEditorData.LogosList,
362 &ContactEditorData.LogosListPref,
363 &ContactEditorData.LogosListType,
367 // Process the sounds (SOUND).
369 LoadPictureData("SOUND",
370 &ContactEditorData.SoundsList,
371 &ContactEditorData.SoundsListPref,
372 &ContactEditorData.SoundsListType,
376 // Process the calendar addresses (CALURI).
379 &ContactEditorData.CalendarList,
380 &ContactEditorData.CalendarListPref,
381 &ContactEditorData.CalendarListType,
383 lboCalendarAddresses,
386 // Process the calendar request addresses (CALADRURI).
388 LoadData("CALADRURI",
389 &ContactEditorData.CalendarRequestList,
390 &ContactEditorData.CalendarRequestListPref,
391 &ContactEditorData.CalendarRequestListType,
393 lboCalendarRequestAddress,
396 // Process the free busy addresses (FBURL).
399 &ContactEditorData.FreeBusyList,
400 &ContactEditorData.FreeBusyListPref,
401 &ContactEditorData.FreeBusyListType,
403 lboFreeBusyAddresses,
406 // Process the keys. (KEY)
409 &ContactEditorData.KeyList,
410 &ContactEditorData.KeyListPref,
411 &ContactEditorData.KeyListType,
412 &ContactEditorData.KeyListDataType,
416 // Process the vendor specific information (VND-*).
418 LoadVendorData(&ContactEditorData.VendorListPEN,
419 &ContactEditorData.VendorListElement,
423 // Process the X-Tokens (X-*).
425 LoadXTokenData(&ContactEditorData.XTokenListTokens,
429 // Process the related people (RELATED).
431 LoadRelatedData(&ContactEditorData.GeneralRelatedList,
432 &ContactEditorData.GeneralRelatedListPref,
433 &ContactEditorData.GeneralRelatedListType,
437 // Process the full name (FN).
439 LoadData(&ContactEditorData.FullNamesList,
442 FMTimer.SetFilename(Filename);
443 FMTimer.Start(10000, FALSE);
450 void frmContactEditor::SplitValues(wxString *PropertyLine,
451 std::map<int,int> *SplitPoints,
452 std::map<int,int> *SplitLength,
457 size_t intPropertyLen = PropertyLine->Len();
458 int intSplitsFound = 0;
459 int intSplitSize = 0;
460 int intSplitSeek = 0;
462 for (int i = intSize; i <= intPropertyLen; i++){
466 if (PropertyLine->Mid(i, 1) == wxT(";") &&
467 PropertyLine->Mid((i - 1), 1) != wxT("\\")){
469 if (intSplitsFound == 0){
471 SplitLength->insert(std::make_pair(intSplitsFound, (intSplitSize)));
475 SplitLength->insert(std::make_pair(intSplitsFound, (intSplitSize - 1)));
479 SplitPoints->insert(std::make_pair(intSplitsFound, (i + 1)));
489 if (intSplitsFound == 0){
491 SplitPoints->insert(std::make_pair(intSplitsFound, (8 + 1)));
492 SplitLength->insert(std::make_pair(intSplitsFound, intSplitSize));
496 SplitPoints->insert(std::make_pair(intSplitsFound, (intSplitSeek + 1)));
497 SplitLength->insert(std::make_pair(intSplitsFound, intSplitSize));
503 void frmContactEditor::LoadData(std::map<int, wxString> *GeneralList,
504 std::map<int, int> *GeneralListPref,
505 wxListCtrl *GeneralListCtrl,
506 std::map<int, wxString> *HomeList,
507 std::map<int, int> *HomeListPref,
508 wxListCtrl *HomeListCtrl,
509 std::map<int, wxString> *BusinessList,
510 std::map<int, int> *BusinessListPref,
511 wxListCtrl *BusinessListCtrl,
514 // Load data into the controls (first section of data and preference
517 long ListCtrlIndex = -1;
519 // Deal with the general items.
521 for (std::map<int,wxString>::iterator Iter = GeneralList->begin();
522 Iter != GeneralList->end();
527 coldata.SetId(*DataCount);
528 coldata.SetData(*DataCount);
529 coldata.SetText(Iter->second);
531 ListCtrlIndex = GeneralListCtrl->InsertItem(coldata);
533 if (MapDataExists(DataCount, GeneralListPref)){
535 GeneralListCtrl->SetItem(ListCtrlIndex, 1, wxString::Format("%i", GeneralListPref->find(*DataCount)->second));
543 // Deal with the home items.
545 for (std::map<int,wxString>::iterator Iter = HomeList->begin();
546 Iter != HomeList->end();
551 coldata.SetId(*DataCount);
552 coldata.SetData(*DataCount);
553 coldata.SetText(Iter->second);
555 ListCtrlIndex = HomeListCtrl->InsertItem(coldata);
557 if (MapDataExists(DataCount, HomeListPref)){
559 HomeListCtrl->SetItem(ListCtrlIndex, 1, wxString::Format("%i", HomeListPref->find(*DataCount)->second));
567 // Deal with the work items.
569 for (std::map<int,wxString>::iterator Iter = BusinessList->begin();
570 Iter != BusinessList->end();
575 coldata.SetId(*DataCount);
576 coldata.SetData(*DataCount);
577 coldata.SetText(Iter->second);
579 ListCtrlIndex = BusinessListCtrl->InsertItem(coldata);
581 if (MapDataExists(DataCount, BusinessListPref)){
583 BusinessListCtrl->SetItem(ListCtrlIndex, 1, wxString::Format("%i", BusinessListPref->find(*DataCount)->second));
593 void frmContactEditor::LoadData(std::map<int, wxString> *GeneralList,
594 std::map<int, int> *GeneralListPref,
595 std::map<int, wxString> *GeneralListType,
596 wxListCtrl *GeneralListCtrl,
597 std::map<int, wxString> *HomeList,
598 std::map<int, int> *HomeListPref,
599 std::map<int, wxString> *HomeListType,
600 wxListCtrl *HomeListCtrl,
601 std::map<int, wxString> *BusinessList,
602 std::map<int, int> *BusinessListPref,
603 std::map<int, wxString> *BusinessListType,
604 wxListCtrl *BusinessListCtrl,
607 // Load data into the controls (first section of data,
608 // type and preference).
610 long ListCtrlIndex = -1;
612 // Deal with the general items.
614 for (std::map<int,wxString>::iterator Iter = GeneralList->begin();
615 Iter != GeneralList->end();
620 coldata.SetId(*DataCount);
621 coldata.SetData(*DataCount);
622 coldata.SetText(Iter->second);
624 ListCtrlIndex = GeneralListCtrl->InsertItem(coldata);
626 if (MapDataExists(DataCount, GeneralListPref)){
628 GeneralListCtrl->SetItem(ListCtrlIndex, 2, wxString::Format("%i", GeneralListPref->find(*DataCount)->second));
632 if (MapDataExists(DataCount, GeneralListType)){
634 GeneralListCtrl->SetItem(ListCtrlIndex, 1, GeneralListType->find(*DataCount)->second);
642 // Deal with the home items.
644 for (std::map<int,wxString>::iterator Iter = HomeList->begin();
645 Iter != HomeList->end();
650 coldata.SetId(*DataCount);
651 coldata.SetData(*DataCount);
652 coldata.SetText(Iter->second);
654 ListCtrlIndex = HomeListCtrl->InsertItem(coldata);
656 if (MapDataExists(DataCount, HomeListPref)){
658 HomeListCtrl->SetItem(ListCtrlIndex, 2, wxString::Format("%i", HomeListPref->find(*DataCount)->second));
662 if (MapDataExists(DataCount, HomeListType)){
664 HomeListCtrl->SetItem(ListCtrlIndex, 1, HomeListType->find(*DataCount)->second);
672 // Deal with the work items.
674 for (std::map<int,wxString>::iterator Iter = BusinessList->begin();
675 Iter != BusinessList->end();
680 coldata.SetId(*DataCount);
681 coldata.SetData(*DataCount);
682 coldata.SetText(Iter->second);
684 ListCtrlIndex = BusinessListCtrl->InsertItem(coldata);
686 if (MapDataExists(DataCount, BusinessListPref)){
688 BusinessListCtrl->SetItem(ListCtrlIndex, 2, wxString::Format("%i", BusinessListPref->find(*DataCount)->second));
692 if (MapDataExists(DataCount, BusinessListType)){
694 BusinessListCtrl->SetItem(ListCtrlIndex, 1, BusinessListType->find(*DataCount)->second);
705 void frmContactEditor::LoadData(std::map<int,wxString> *ItemList,
706 std::map<int,int> *ItemListPref,
707 wxListCtrl *ItemCtrl,
710 // Load the data (name and preference only).
712 long ListCtrlIndex = -1;
714 for (std::map<int,wxString>::iterator Iter = ItemList->begin();
715 Iter != ItemList->end();
720 coldata.SetId(*DataCount);
721 coldata.SetData(*DataCount);
722 coldata.SetText(Iter->second);
724 ListCtrlIndex = ItemCtrl->InsertItem(coldata);
726 if (MapDataExists(DataCount, ItemListPref)){
728 ItemCtrl->SetItem(ListCtrlIndex, 1, wxString::Format("%i", ItemListPref->find(*DataCount)->second));
738 void frmContactEditor::LoadData(std::map<int,wxString> *ItemList,
739 std::map<int,int> *ItemListPref,
740 std::map<int,wxString> *ItemListType,
741 wxListCtrl *ItemCtrl,
744 // Load the data (name, preference and type).
746 long ListCtrlIndex = -1;
748 for (std::map<int,wxString>::iterator Iter = ItemList->begin();
749 Iter != ItemList->end();
754 coldata.SetId(*DataCount);
755 coldata.SetData(*DataCount);
756 coldata.SetText(Iter->second);
758 ListCtrlIndex = ItemCtrl->InsertItem(coldata);
760 if (MapDataExists(DataCount, ItemListType)){
762 ItemCtrl->SetItem(ListCtrlIndex, 1, ItemListType->find(*DataCount)->second);
766 if (MapDataExists(DataCount, ItemListPref)){
768 ItemCtrl->SetItem(ListCtrlIndex, 2, wxString::Format("%i", ItemListPref->find(*DataCount)->second));
778 void frmContactEditor::LoadData(wxString ItemName,
779 std::map<int,wxString> *ItemList,
780 std::map<int,int> *ItemListPref,
781 std::map<int,wxString> *ItemListType,
782 std::map<int,wxString> *ItemListDataType,
783 wxListCtrl *ItemCtrl,
786 // Load data (name, preference, type and data type).
788 long ListCtrlIndex = -1;
790 for (std::map<int,wxString>::iterator Iter = ItemList->begin();
791 Iter != ItemList->end();
796 coldata.SetId(*DataCount);
797 coldata.SetData(*DataCount);
798 coldata.SetText(Iter->second);
800 if (ItemName == "KEY"){
802 // Get the key type, if any.
804 if (MapDataExists(DataCount, ItemListDataType)){
806 if (ItemListDataType->find(*DataCount)->second == "application/pgp-keys"){
808 coldata.SetText(_("PGP Key"));
814 coldata.SetText(_("Key"));
821 ListCtrlIndex = ItemCtrl->InsertItem(coldata);
823 if (MapDataExists(DataCount, ItemListType)){
825 if (ItemListType->find(*DataCount)->second == "home"){
827 ItemCtrl->SetItem(ListCtrlIndex, 1, _("Home"));
829 } else if (ItemListType->find(*DataCount)->second == "work"){
831 ItemCtrl->SetItem(ListCtrlIndex, 1, _("Work"));
837 if (MapDataExists(DataCount, ItemListPref)){
839 ItemCtrl->SetItem(ListCtrlIndex, 2, wxString::Format("%i", ItemListPref->find(*DataCount)->second));
849 void frmContactEditor::LoadPictureData(wxString ItemName,
850 std::map<int,std::string> *ItemList,
851 std::map<int,int> *ItemListPref,
852 std::map<int,wxString> *ItemListType,
853 wxListCtrl *ItemCtrl,
856 // Load the picture data.
858 long ListCtrlIndex = -1;
860 for (std::map<int,std::string>::iterator Iter = ItemList->begin();
861 Iter != ItemList->end();
866 coldata.SetId(*DataCount);
867 coldata.SetData(*DataCount);
869 if (ItemName == "PHOTO"){
871 coldata.SetText("Picture");
873 } else if (ItemName == "LOGO"){
875 coldata.SetText("Logo");
877 } else if (ItemName == "SOUND"){
879 coldata.SetText("Sound");
883 coldata.SetText("Object");
887 ListCtrlIndex = ItemCtrl->InsertItem(coldata);
889 if (MapDataExists(DataCount, ItemListType)){
891 if (ItemListType->find(*DataCount)->second == "home"){
893 ItemCtrl->SetItem(ListCtrlIndex, 1, _("Home"));
895 } else if (ItemListType->find(*DataCount)->second == "work"){
897 ItemCtrl->SetItem(ListCtrlIndex, 1, _("Work"));
903 if (MapDataExists(DataCount, ItemListPref)){
905 ItemCtrl->SetItem(ListCtrlIndex, 2, wxString::Format("%i", ItemListPref->find(*DataCount)->second));
915 void frmContactEditor::LoadVendorData(std::map<int,wxString> *ItemListPEN,
916 std::map<int,wxString> *ItemListElement,
917 wxListCtrl *ItemCtrl,
920 // Load the vendor data.
922 long ListCtrlIndex = -1;
925 for (std::map<int,wxString>::iterator Iter = ItemListPEN->begin();
926 Iter != ItemListPEN->end();
933 coldata.SetId(*DataCount);
934 coldata.SetData(*DataCount);
936 ItemValue.Append(ItemListPEN->find(*DataCount)->second);
937 ItemValue.Append("-");
938 ItemValue.Append(ItemListElement->find(*DataCount)->second);
940 coldata.SetText(ItemValue);
942 ListCtrlIndex = ItemCtrl->InsertItem(coldata);
950 void frmContactEditor::LoadXTokenData(std::map<int,wxString> *ItemListTokens,
951 wxListCtrl *ItemCtrl,
954 // Load the X-Token data.
956 long ListCtrlIndex = -1;
959 for (std::map<int,wxString>::iterator Iter = ItemListTokens->begin();
960 Iter != ItemListTokens->end();
967 coldata.SetId(*DataCount);
968 coldata.SetData(*DataCount);
970 ItemValue.Append(ItemListTokens->find(*DataCount)->second);
972 coldata.SetText(ItemValue);
974 ListCtrlIndex = ItemCtrl->InsertItem(coldata);
982 void frmContactEditor::LoadData(std::map<int,wxString> *ItemList,
983 wxComboBox *ItemCtrl){
985 // Load data into a wxComboBox.
989 if (MapDataExists(&ItemIndex, ItemList)){
991 cmbDisplayAs->SetValue(ItemList->find(0)->second);
997 void frmContactEditor::LoadRelatedData(std::map<int,wxString> *ItemList,
998 std::map<int,int> *ItemListPref,
999 std::map<int,wxString> *ItemListType,
1000 wxListCtrl *ItemCtrl,
1003 // Load related data (name, preference and type).
1005 long ListCtrlIndex = -1;
1006 wxString RelatedType;
1008 for (std::map<int,wxString>::iterator Iter = ItemList->begin();
1009 Iter != ItemList->end();
1012 RelatedType.clear();
1016 coldata.SetId(*DataCount);
1017 coldata.SetData(*DataCount);
1019 if (MapDataExists(DataCount, ItemListType)){
1021 std::map<int,wxString>::iterator TypeIter = ItemListType->find(*DataCount);
1023 if (TypeIter->second == wxT("contact")){
1025 RelatedType = _("Contact");
1027 } else if (TypeIter->second == wxT("acquaintance")){
1029 RelatedType = _("Acquaintance");
1031 } else if (TypeIter->second == wxT("friend")){
1033 RelatedType = _("Friend");
1035 } else if (TypeIter->second == wxT("met")){
1037 RelatedType = _("Met");
1039 } else if (TypeIter->second == wxT("co-worker")){
1041 RelatedType = _("Co-worker");
1043 } else if (TypeIter->second == wxT("colleague")){
1045 RelatedType = _("Colleague");
1047 } else if (TypeIter->second == wxT("co-resident")){
1049 RelatedType = _("Co-resident");
1051 } else if (TypeIter->second == wxT("neighbor")){
1053 RelatedType = _("Neighbour");
1055 } else if (TypeIter->second == wxT("child")){
1057 RelatedType = _("Child");
1059 } else if (TypeIter->second == wxT("parent")){
1061 RelatedType = _("Parent");
1063 } else if (TypeIter->second == wxT("sibling")){
1065 RelatedType = _("Sibling");
1067 } else if (TypeIter->second == wxT("spouse")){
1069 RelatedType = _("Spouse");
1071 } else if (TypeIter->second == wxT("kin")){
1073 RelatedType = _("Kin");
1075 } else if (TypeIter->second == wxT("muse")){
1077 RelatedType = _("Muse");
1079 } else if (TypeIter->second == wxT("crush")){
1081 RelatedType = _("Crush");
1083 } else if (TypeIter->second == wxT("date")){
1085 RelatedType = _("Date");
1087 } else if (TypeIter->second == wxT("sweetheart")){
1089 RelatedType = _("Sweetheart");
1091 } else if (TypeIter->second == wxT("me")){
1093 RelatedType = _("Me");
1095 } else if (TypeIter->second == wxT("agent")){
1097 RelatedType = _("Agent");
1099 } else if (TypeIter->second == wxT("emergency")){
1101 RelatedType = _("Emergency");
1105 RelatedType = TypeIter->second;
1111 coldata.SetText(RelatedType);
1113 ListCtrlIndex = ItemCtrl->InsertItem(coldata);
1115 if (MapDataExists(DataCount, ItemList)){
1117 ItemCtrl->SetItem(ListCtrlIndex, 1, ItemList->find(*DataCount)->second);
1121 if (MapDataExists(DataCount, ItemListPref)){
1123 ItemCtrl->SetItem(ListCtrlIndex, 2, wxString::Format("%i", ItemListPref->find(*DataCount)->second));
1133 void frmContactEditor::LoadKind(ContactKindType *KindType){
1135 // Load contact kind.
1138 case CONTACTKIND_INDIVIDUAL:
1139 cmbType->SetSelection(1);
1141 case CONTACTKIND_GROUP:
1142 cmbType->SetSelection(2);
1144 case CONTACTKIND_ORGANISATION:
1145 cmbType->SetSelection(3);
1147 case CONTACTKIND_LOCATION:
1148 cmbType->SetSelection(4);
1150 case CONTACTKIND_NONE:
1151 cmbType->SetSelection(0);
1155 wxCommandEvent nullevent;
1157 UpdateMembersTab(nullevent);
1161 void frmContactEditor::LoadBirthday(wxString *BirthdayData, bool *BirthdayText){
1165 if (BirthdayData->IsEmpty()){
1169 if (*BirthdayText == FALSE){
1172 wxDateTime::Month DateMonth;
1173 unsigned int DateDay;
1177 if (BirthdayData->Mid(0, 2) == wxT("--")){
1183 DateYear = wxAtoi(BirthdayData->Mid(0,4));
1187 DateMonth = (wxDateTime::Month)(wxAtoi(BirthdayData->Mid(4,2)) - 1);
1188 DateDay = wxAtoi(BirthdayData->Mid(6,2));
1190 wxDateTime BDayDate(DateDay,DateMonth,DateYear);
1192 dapBirthday->SetValue(BDayDate);
1196 txtBirthday->SetValue(*BirthdayData);
1202 void frmContactEditor::LoadAnniversary(wxString *AnniversaryData, bool *AnniversaryText){
1204 // Load Anniversary.
1206 if (AnniversaryData->IsEmpty()){
1210 if (*AnniversaryText == FALSE){
1213 wxDateTime::Month DateMonth;
1218 if (AnniversaryData->Mid(0, 2) == wxT("--")){
1224 DateYear = wxAtoi(AnniversaryData->Mid(0,4));
1228 DateMonth = (wxDateTime::Month)(wxAtoi(AnniversaryData->Mid(4,2)) - 1);
1229 DateDay = wxAtoi(AnniversaryData->Mid(6,2));
1231 wxDateTime ADayDate(DateDay,DateMonth,DateYear);
1233 dapAnniversary->SetValue(ADayDate);
1237 txtAnniversary->SetValue(*AnniversaryData);
1243 void frmContactEditor::LoadGender(wxString *GenderComponent, wxString *GenderIdentity){
1247 // Deal with the Gender Component.
1249 if (*GenderComponent == wxT("M")){
1253 cmbGender->SetSelection(1);
1255 } else if (*GenderComponent == wxT("F")){
1257 // Gender is Female.
1259 cmbGender->SetSelection(2);
1261 } else if (*GenderComponent == wxT("O")){
1265 cmbGender->SetSelection(3);
1267 } else if (*GenderComponent == wxT("N")){
1269 // Gender is None/Not Applicable.
1271 cmbGender->SetSelection(4);
1273 } else if (*GenderComponent == wxT("U")){
1275 // Gender is Unknown.
1277 cmbGender->SetSelection(5);
1281 // Deal with the Gender Identity.
1283 txtGenderDescription->SetValue(*GenderIdentity);
1287 void frmContactEditor::LoadName(wxString *NameTitle, wxString *NameForename,
1288 wxString *NameSurname, wxString *NameOtherNames,
1289 wxString *NameSuffix){
1293 txtTitle->SetValue(*NameTitle);
1294 txtForename->SetValue(*NameForename);
1295 txtSurname->SetValue(*NameSurname);
1296 txtOtherNames->SetValue(*NameOtherNames);
1297 txtSuffix->SetValue(*NameSuffix);
1301 void frmContactEditor::LoadMember(std::map<int,wxString> *GroupList){
1305 // Go through the list of contacts for the account and find the matching UID.
1306 // If contact with UID doesn't match then say (unknown contact).
1308 XABViewMode XVMData;
1309 if (StartupEditMode == FALSE){
1310 XVMData = MainPtr->GetViewMode();
1313 wxString AccountDirFinal = GetAccountDir(wxSContactAccount, FALSE);
1315 wxString vCardFilename;
1316 wxString vCardFilenameFull;
1317 wxString vCardDataString;
1319 wxString setname, setvalue;
1320 wxString MemberData;
1321 bool FoundContact = FALSE;
1322 std::multimap<wxString, wxString, std::greater<wxString>> vCardNamesAsc;
1323 std::multimap<wxString, wxString, std::less<wxString>> vCardNamesDsc;
1325 wxDir vcardaccdir(AccountDirFinal);
1327 for (std::map<int,wxString>::iterator MemberIter = GroupList->begin();
1328 MemberIter != GroupList->end();
1331 MemberData = MemberIter->second;
1333 bool ProcFiles = vcardaccdir.GetFirst(&vCardFilename, wxEmptyString, wxDIR_FILES);
1336 if (vCardFilename.Right(4) == wxT(".vcf") ||
1337 vCardFilename.Right(4) == wxT(".VCF") ||
1338 vCardFilename.Right(5) == wxT(".vcard") ||
1339 vCardFilename.Right(5) == wxT(".VCARD")){
1343 vCardFilenameFull.Append(AccountDirFinal);
1344 vCardFilenameFull.Append(wxT("/"));
1345 vCardFilenameFull.Append(vCardFilename);
1347 Person.LoadFile(vCardFilenameFull);
1349 if (MemberData.Left(9) == wxT("urn:uuid:")){
1351 wxString NewPropValue;
1352 NewPropValue = MemberData.Mid(9, wxString::npos);
1353 MemberData = NewPropValue;
1357 if (Person.MeetBaseSpecification()){
1359 wxString KindStatus = Person.Get(wxT("KIND"));
1361 if (KindStatus == wxT("group")){
1363 vCardFilename.Clear();
1364 vCardFilenameFull.Clear();
1365 vCardDataString.Clear();
1366 ProcFiles = vcardaccdir.GetNext(&vCardFilename);
1371 wxString PersonName = Person.Get(wxT("N"));
1372 wxString PersonUID = Person.Get(wxT("UID"));
1373 wxString PersonFilename = vCardFilenameFull;
1375 if (PersonUID != MemberData){
1377 vCardFilename.Clear();
1378 vCardFilenameFull.Clear();
1379 vCardDataString.Clear();
1380 ProcFiles = vcardaccdir.GetNext(&vCardFilename);
1385 FoundContact = TRUE;
1389 //ContactsNames.insert(std::make_pair(PersonName, ContactIndex));
1390 //ContactsUIDs.insert(std::make_pair(ContactIndex, PersonUID));
1392 if (XVMData.SortMode == 1){
1394 // Split the name into sections.
1396 vCardDataString = Person.Get(wxT("N"));
1398 vCardName NameData = Person.GetName();
1400 vCardDataString = NameData.Forename + wxT(" ") + NameData.Surname;
1402 } else if (XVMData.SortMode == 2){
1404 // Split the name into sections.
1406 vCardName NameData = Person.GetName();
1408 vCardDataString = NameData.Surname + wxT(", ") + NameData.Forename;
1410 } else if (XVMData.SortMode == 3){
1412 // Check and make sure that the top most nickname is used.
1414 vCardDataString = Person.Get(wxT("NICKNAME"));
1416 if (vCardDataString.IsEmpty()){
1418 vCardDataString = wxT("(no nickname)");
1422 } else if (XVMData.SortMode == 4){
1424 vCardDataString = Person.Get(wxT("FN"));
1428 if (XVMData.AscendingMode == TRUE){
1430 vCardNamesAsc.insert(std::make_pair(vCardDataString, PersonUID));
1434 vCardNamesDsc.insert(std::make_pair(vCardDataString, PersonUID));
1444 vCardFilename.Clear();
1445 vCardFilenameFull.Clear();
1446 vCardDataString.Clear();
1447 ProcFiles = vcardaccdir.GetNext(&vCardFilename);
1451 if (FoundContact == FALSE){
1453 if (XVMData.AscendingMode == TRUE){
1455 vCardNamesAsc.insert(std::make_pair(MemberIter->second, MemberIter->second));
1459 vCardNamesDsc.insert(std::make_pair(MemberIter->second, MemberIter->second));
1465 if (XVMData.AscendingMode == TRUE){
1467 for (std::map<wxString,wxString>::iterator iter = vCardNamesAsc.begin();
1468 iter != vCardNamesAsc.end(); ++iter){
1470 wxListItem ItemData;
1473 ItemData.SetText(iter->first);
1474 lboGroups->InsertItem(ItemData);
1480 for (std::map<wxString,wxString>::iterator iter = vCardNamesDsc.begin();
1481 iter != vCardNamesDsc.end(); ++iter){
1483 wxListItem ItemData;
1486 ItemData.SetText(iter->first);
1488 lboGroups->InsertItem(ItemData);
1498 void frmContactEditor::LoadAddress(std::map<int, wxString> *GeneralAddressList,
1499 std::map<int, wxString> *GeneralAddressListTown,
1500 std::map<int, wxString> *GeneralAddressListCounty,
1501 std::map<int, wxString> *GeneralAddressListPostCode,
1502 std::map<int, int> *GeneralAddressListPref,
1503 std::map<int, wxString> *HomeAddressList,
1504 std::map<int, wxString> *HomeAddressListTown,
1505 std::map<int, wxString> *HomeAddressListCounty,
1506 std::map<int, wxString> *HomeAddressListPostCode,
1507 std::map<int, int> *HomeAddressListPref,
1508 std::map<int, wxString> *BusinessAddressList,
1509 std::map<int, wxString> *BusinessAddressListTown,
1510 std::map<int, wxString> *BusinessAddressListCounty,
1511 std::map<int, wxString> *BusinessAddressListPostCode,
1512 std::map<int, int> *BusinessAddressListPref,
1517 long ListCtrlIndex = -1;
1519 // Deal with the general addresses.
1521 for (std::map<int,wxString>::iterator Iter = GeneralAddressList->begin();
1522 Iter != GeneralAddressList->end();
1527 coldata.SetId(*AddressCount);
1528 coldata.SetData(*AddressCount);
1529 coldata.SetText(Iter->second);
1531 ListCtrlIndex = lboAddresses->InsertItem(coldata);
1533 if (MapDataExists(AddressCount, GeneralAddressListTown)){
1535 lboAddresses->SetItem(ListCtrlIndex, 1, GeneralAddressListTown->find(*AddressCount)->second);
1539 if (MapDataExists(AddressCount, GeneralAddressListCounty)){
1541 lboAddresses->SetItem(ListCtrlIndex, 2, GeneralAddressListCounty->find(*AddressCount)->second);
1545 if (MapDataExists(AddressCount, GeneralAddressListPostCode)){
1547 lboAddresses->SetItem(ListCtrlIndex, 3, GeneralAddressListPostCode->find(*AddressCount)->second);
1551 if (MapDataExists(AddressCount, GeneralAddressListPref)){
1553 lboAddresses->SetItem(ListCtrlIndex, 4, wxString::Format("%i", GeneralAddressListPref->find(*AddressCount)->second));
1561 // Deal with the home addresses.
1563 for (std::map<int,wxString>::iterator Iter = HomeAddressList->begin();
1564 Iter != HomeAddressList->end();
1569 coldata.SetId(*AddressCount);
1570 coldata.SetData(*AddressCount);
1571 coldata.SetText(Iter->second);
1573 ListCtrlIndex = lboHomeAddresses->InsertItem(coldata);
1575 if (MapDataExists(AddressCount, HomeAddressListTown)){
1577 lboHomeAddresses->SetItem(ListCtrlIndex, 1, HomeAddressListTown->find(*AddressCount)->second);
1581 if (MapDataExists(AddressCount, HomeAddressListCounty)){
1583 lboHomeAddresses->SetItem(ListCtrlIndex, 2, HomeAddressListCounty->find(*AddressCount)->second);
1587 if (MapDataExists(AddressCount, HomeAddressListPostCode)){
1589 lboHomeAddresses->SetItem(ListCtrlIndex, 3, HomeAddressListPostCode->find(*AddressCount)->second);
1593 if (MapDataExists(AddressCount, HomeAddressListPref)){
1595 lboHomeAddresses->SetItem(ListCtrlIndex, 4, wxString::Format("%i", HomeAddressListPref->find(*AddressCount)->second));
1603 // Deal with the work addresses.
1605 for (std::map<int,wxString>::iterator Iter = BusinessAddressList->begin();
1606 Iter != BusinessAddressList->end();
1611 coldata.SetId(*AddressCount);
1612 coldata.SetData(*AddressCount);
1613 coldata.SetText(Iter->second);
1615 ListCtrlIndex = lboBusinessAddresses->InsertItem(coldata);
1617 if (MapDataExists(AddressCount, BusinessAddressListTown)){
1619 lboBusinessAddresses->SetItem(ListCtrlIndex, 1, BusinessAddressListTown->find(*AddressCount)->second);
1623 if (MapDataExists(AddressCount, BusinessAddressListCounty)){
1625 lboBusinessAddresses->SetItem(ListCtrlIndex, 2, BusinessAddressListCounty->find(*AddressCount)->second);
1629 if (MapDataExists(AddressCount, BusinessAddressListPostCode)){
1631 lboBusinessAddresses->SetItem(ListCtrlIndex, 3, BusinessAddressListPostCode->find(*AddressCount)->second);
1635 if (MapDataExists(AddressCount, BusinessAddressListPref)){
1637 lboBusinessAddresses->SetItem(ListCtrlIndex, 4, wxString::Format("%i", BusinessAddressListPref->find(*AddressCount)->second));