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"
34 bool frmContactEditor::LoadContact(wxString Filename){
36 // Load the contact into the contact editor.
39 wxString wxSContactString;
43 if (StartupEditMode == FALSE){
44 XVMData = MainPtr->GetViewMode();
47 wxSContactFilename = Filename;
49 // Check if we are using wxWidgets version 2.8 or less and
50 // execute the required command accordingly.
52 #if wxABI_VERSION < 20900
53 ContactFile.Open(Filename.c_str(), wxT("r"));
55 ContactFile.Open(Filename, wxT("r"));
58 if (ContactFile.IsOpened() == FALSE){
64 ContactFile.ReadAll(&wxSContactString, wxConvAuto());
68 std::map<int, wxString> ContactFileLines;
69 std::map<int, wxString>::iterator striter;
71 wxStringTokenizer wSTContactFileLines(wxSContactString, wxT("\r\n"));
73 int ContactLineSeek = 0;
75 while (wSTContactFileLines.HasMoreTokens() == TRUE){
77 ContactLine = wSTContactFileLines.GetNextToken();
78 ContactFileLines.insert(std::make_pair(ContactLineSeek, ContactLine));
85 bool QuoteMode = FALSE;
86 bool PropertyFind = TRUE;
87 bool HasExtraNicknames = FALSE;
88 bool IgnoreGender = FALSE;
89 bool ExtraLineSeek = TRUE;
90 bool BirthdayProcessed = FALSE;
91 bool AnniversaryProcessed = FALSE;
92 bool FNProcessed = FALSE;
93 bool GenderProcessed = FALSE;
94 bool NameProcessed = FALSE;
95 bool UIDProcessed = FALSE;
96 bool KindProcessed = FALSE;
97 bool ETagFound = FALSE;
98 bool ETagOrigFound = FALSE;
99 bool VersionProcessed = FALSE;
100 int intExtraNickname = 0;
101 wxString wxSProperty;
102 wxString wxSPropertySeg1;
103 wxString wxSPropertySeg2;
104 wxString wxSPropertyNextLine;
105 size_t ContactLineLen = 0;
106 int QuoteBreakPoint = 0;
109 int NicknameCount = 0;
118 int RelatedCount = 0;
123 int CategoryCount = 0;
129 int CalReqAdrCount = 0;
130 int FreeBusyCount = 0;
134 //int intValueSeek = 1;
136 for (std::map<int,wxString>::iterator iter = ContactFileLines.begin();
137 iter != ContactFileLines.end(); ++iter){
139 // Find the colon which splits the start bit from the data part.
141 ContactLine = iter->second;
143 while (ExtraLineSeek == TRUE){
145 // Check if there is extra data on the next line
146 // (indicated by space or tab at the start) and add data.
150 if (iter == ContactFileLines.end()){
157 wxSPropertyNextLine = iter->second;
160 if (wxSPropertyNextLine.Mid(0, 1) == wxT(" ") || wxSPropertyNextLine.Mid(0, 1) == wxT("\t")){
162 wxSPropertyNextLine.Remove(0, 1);
163 //wxSPropertyNextLine.Trim(FALSE);
164 //ContactLine.Trim();
165 ContactLine.Append(wxSPropertyNextLine);
170 ExtraLineSeek = FALSE;
176 ContactLineLen = ContactLine.Len();
178 // Make sure we are not in quotation mode.
179 // Make sure colon does not have \ or \\ before it.
181 for (int i = 0; i <= ContactLineLen; i++){
183 if ((ContactLine.Mid(i, 1) == wxT(";") || ContactLine.Mid(i, 1) == wxT(":")) && PropertyFind == TRUE){
185 PropertyFind = FALSE;
187 } else if (PropertyFind == TRUE){
189 wxSProperty.Append(ContactLine.Mid(i, 1));
193 if (ContactLine.Mid(i, 1) == wxT("\"")){
195 if (QuoteMode == TRUE){
207 if (ContactLine.Mid(i, 1) == wxT(":") && ContactLine.Mid((i - 1), 1) != wxT("\\") && QuoteMode == FALSE){
216 // Split that line at the point into two variables (ignore the colon).
218 wxSPropertySeg1 = ContactLine.Mid(0, QuoteBreakPoint);
219 wxSPropertySeg2 = ContactLine.Mid((QuoteBreakPoint + 1));
221 // Add the data into the contact editor depending on what it is.
223 if (wxSProperty == wxT("VERSION") && VersionProcessed == FALSE){
225 // Check if version is 4.0, otherwise don't
228 if (wxSPropertySeg2 != wxT("4.0")){
229 wxMessageBox(_("This file is not a vCard 4.0 contact and is not supported under Xestia Address Book."),
230 _("Contact not supported"), wxICON_ERROR);
235 VersionProcessed = TRUE;
237 } if (wxSProperty == wxT("KIND") && KindProcessed == FALSE){
239 // See frmContactEditor-LoadGroup.cpp
241 LoadKind(wxSPropertySeg2);
243 } else if (wxSProperty == wxT("MEMBER")){
245 // See frmContactEditor-LoadGroup.cpp
247 LoadMember(wxSPropertySeg2, &GroupCount);
249 } else if (wxSProperty == wxT("FN")){
251 // See frmContactEditor-LoadName.cpp
253 LoadFN(wxSPropertySeg1, wxSPropertySeg2, &FNCount, &FNProcessed, &ContactData);
255 } else if (wxSProperty == wxT("N") && NameProcessed == FALSE){
257 // See frmContactEditor-LoadName.cpp
259 LoadN(wxSPropertySeg1, wxSPropertySeg2, &NameProcessed, &ContactData);
261 } else if (wxSProperty == wxT("NICKNAME")){
263 // See frmContactEditor-LoadNickname.cpp
265 LoadNickname(wxSPropertySeg1, wxSPropertySeg2, &NicknameCount, &ContactData);
267 } else if (wxSProperty == wxT("GENDER") && GenderProcessed == FALSE){
269 // See frmContactEditor-LoadGender.cpp
271 LoadGender(wxSPropertySeg1, wxSPropertySeg2, &GenderProcessed, &ContactData);
273 } else if (wxSProperty == wxT("BDAY") && BirthdayProcessed == FALSE){
275 // See frmContactEditor-LoadBADays.cpp
277 LoadBDay(wxSPropertySeg1, wxSPropertySeg2, &BirthdayProcessed);
279 } else if (wxSProperty == wxT("ANNIVERSARY") && AnniversaryProcessed == FALSE){
281 // See frmContactEditor-LoadBADays.cpp
283 LoadAnniversary(wxSPropertySeg1, wxSPropertySeg2, &AnniversaryProcessed);
285 } else if (wxSProperty == wxT("TZ")){
287 // See frmContactEditor-LoadTimeZone.cpp
289 LoadTimeZone(wxSPropertySeg1, wxSPropertySeg2, &TZCount);
291 } else if (wxSProperty == wxT("ADR")){
293 // See frmContactEditor-LoadAddress.cpp
295 LoadADR(wxSPropertySeg1, wxSPropertySeg2, &ADRCount);
297 } else if (wxSProperty == wxT("EMAIL")){
299 // See frmContactEditor-LoadEmail.cpp
301 LoadEmail(wxSPropertySeg1, wxSPropertySeg2, &EmailCount);
303 } else if (wxSProperty == wxT("IMPP")){
305 // See frmContactEditor-LoadIM.cpp
307 LoadIM(wxSPropertySeg1, wxSPropertySeg2, &IMPPCount);
309 } else if (wxSProperty == wxT("TEL")){
311 // See frmContactEditor-LoadTelephone.cpp
313 LoadTelephone(wxSPropertySeg1, wxSPropertySeg2, &TelCount);
315 } else if (wxSProperty == wxT("LANG")){
317 // See frmContactEditor-LoadLanguage.cpp
319 LoadLanguage(wxSPropertySeg1, wxSPropertySeg2, &LangCount);
321 } else if (wxSProperty == wxT("GEO")){
323 // See frmContactEditor-LoadGeo.cpp
325 LoadGeo(wxSPropertySeg1, wxSPropertySeg2, &GeoCount);
327 } else if (wxSProperty == wxT("RELATED")){
329 // See fromContactEditor-LoadRelated.cpp
331 LoadRelated(wxSPropertySeg1, wxSPropertySeg2, &RelatedCount);
333 } else if (wxSProperty == wxT("URL")){
335 // See frmContactEditor-LoadURL.cpp
337 LoadURL(wxSPropertySeg1, wxSPropertySeg2, &URLCount);
339 } else if (wxSProperty == wxT("TITLE")) {
341 // See frmContactEditor-LoadTitle.cpp
343 LoadTitle(wxSPropertySeg1, wxSPropertySeg2, &TitleCount);
345 } else if (wxSProperty == wxT("ROLE")) {
347 // See frmContactEditor-LoadRole.cpp
349 LoadRole(wxSPropertySeg1, wxSPropertySeg2, &RoleCount);
351 } else if (wxSProperty == wxT("ORG")) {
353 // See frmContactEditor-LoadOrg.cpp
355 LoadOrg(wxSPropertySeg1, wxSPropertySeg2, &OrgCount);
357 } else if (wxSProperty == wxT("NOTE")) {
359 // See frmContactEditor-LoadNote.cpp
361 LoadNote(wxSPropertySeg1, wxSPropertySeg2, &NoteCount);
363 } else if (wxSProperty == wxT("CATEGORIES")) {
365 // See frmContactEditor-LoadCategory.cpp
367 LoadCategory(wxSPropertySeg1, wxSPropertySeg2, &CategoryCount);
369 } else if (wxSProperty == wxT("PHOTO")) {
371 // See frmContactEditor-LoadPhoto.cpp
373 LoadPhoto(wxSPropertySeg1, wxSPropertySeg2, &PhotoCount);
375 } else if (wxSProperty == wxT("LOGO")) {
377 // See frmContactEditor-LoadLogo.cpp
379 LoadLogo(wxSPropertySeg1, wxSPropertySeg2, &LogoCount);
381 } else if (wxSProperty == wxT("SOUND")) {
383 // See frmContactEditor-LoadSound.cpp
385 LoadSound(wxSPropertySeg1, wxSPropertySeg2, &SoundCount);
387 } else if (wxSProperty == wxT("CALURI")){
389 // See frmContactEditor-LoadCalendar.cpp
391 LoadCalURI(wxSPropertySeg1, wxSPropertySeg2, &CalAdrCount);
393 } else if (wxSProperty == wxT("CALADRURI")){
395 // See frmContactEditor-LoadCalendar.cpp
397 LoadCalAdrURI(wxSPropertySeg1, wxSPropertySeg2, &CalReqAdrCount);
399 } else if (wxSProperty == wxT("FBURL")){
401 // See frmContactEditor-LoadCalendar.cpp
403 LoadCalFreeBusy(wxSPropertySeg1, wxSPropertySeg2, &FreeBusyCount);
405 } else if (wxSProperty == wxT("KEY")){
407 // See frmContactEditor-LoadKey.cpp
409 LoadKey(wxSPropertySeg1, wxSPropertySeg2, &KeyCount);
411 } else if (wxSProperty == wxT("UID") && UIDProcessed == FALSE){
413 UIDToken = wxSPropertySeg2;
416 } else if (wxSProperty.Mid(0, 3) == wxT("VND")){
418 // Split the Vendor three ways.
420 wxStringTokenizer wSTVendorDetails(wxSPropertySeg1, wxT("-"));
423 wxString wxSVNDPropName;
426 while (wSTVendorDetails.HasMoreTokens() == TRUE){
428 wSTVendorDetails.GetNextToken();
429 wxSVNDID = wSTVendorDetails.GetNextToken();
430 wxSVNDPropName = wSTVendorDetails.GetNextToken();
435 if (!wxSVNDID.IsEmpty() && !wxSVNDPropName.IsEmpty()){
437 // Setup the values for later processing.
439 VendorList.insert(std::make_pair(intValueSeek, wxSPropertySeg2));
440 VendorListPEN.insert(std::make_pair(intValueSeek, wxSVNDID));
441 VendorListElement.insert(std::make_pair(intValueSeek, wxSVNDPropName));
443 // Add the data to the vendor variables.
447 coldata.SetId(intValueSeek);
448 coldata.SetData(intValueSeek);
449 coldata.SetText(wxSVNDID + wxT("-") + wxSVNDPropName);
451 ListCtrlIndex = lboVendorNamespace->InsertItem(coldata);
453 VendorList.erase(intValueSeek);
454 VendorListPEN.erase(intValueSeek);
455 VendorListElement.erase(intValueSeek);
457 VendorList.insert(std::make_pair(intValueSeek, wxSPropertySeg2));
458 VendorListPEN.insert(std::make_pair(intValueSeek, wxSVNDID));
459 VendorListElement.insert(std::make_pair(intValueSeek, wxSVNDPropName));
466 } else if (wxSProperty.Mid(0, 2) == wxT("X-")){
470 XTokenList.insert(std::make_pair(intValueSeek, wxSPropertySeg2));
471 XTokenListTokens.insert(std::make_pair(intValueSeek, wxSPropertySeg1.Mid(2)));
477 coldata.SetId(intValueSeek);
478 coldata.SetData(intValueSeek);
479 coldata.SetText(wxSPropertySeg1.Mid(2));
481 ListCtrlIndex = lboXToken->InsertItem(coldata);
489 // Reset the variables.
493 ExtraLineSeek = TRUE;
501 FMTimer.SetFilename(Filename);
502 FMTimer.Start(10000, FALSE);
509 void frmContactEditor::SplitValues(wxString *PropertyLine,
510 std::map<int,int> *SplitPoints,
511 std::map<int,int> *SplitLength,
514 size_t intPropertyLen = PropertyLine->Len();
515 int intSplitsFound = 0;
516 int intSplitSize = 0;
517 int intSplitSeek = 0;
519 for (int i = intSize; i <= intPropertyLen; i++){
523 if (PropertyLine->Mid(i, 1) == wxT(";") &&
524 PropertyLine->Mid((i - 1), 1) != wxT("\\")){
526 if (intSplitsFound == 0){
528 SplitLength->insert(std::make_pair(intSplitsFound, (intSplitSize)));
532 SplitLength->insert(std::make_pair(intSplitsFound, (intSplitSize - 1)));
536 SplitPoints->insert(std::make_pair(intSplitsFound, (i + 1)));
546 if (intSplitsFound == 0){
548 SplitPoints->insert(std::make_pair(intSplitsFound, (8 + 1)));
549 SplitLength->insert(std::make_pair(intSplitsFound, intSplitSize));
553 SplitPoints->insert(std::make_pair(intSplitsFound, (intSplitSeek + 1)));
554 SplitLength->insert(std::make_pair(intSplitsFound, intSplitSize));