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 // Check if we are using wxWidgets version 2.8 or less and
51 // execute the required command accordingly.
53 #if wxABI_VERSION < 20900
54 ContactFile.Open(Filename.c_str(), wxT("r"));
56 ContactFile.Open(Filename, wxT("r"));
59 if (ContactFile.IsOpened() == FALSE){
65 ContactEditorData.LoadFile(Filename);
67 ContactFile.ReadAll(&wxSContactString, wxConvAuto());
71 std::map<int, wxString> ContactFileLines;
72 std::map<int, wxString>::iterator striter;
74 wxStringTokenizer wSTContactFileLines(wxSContactString, wxT("\r\n"));
76 int ContactLineSeek = 0;
78 while (wSTContactFileLines.HasMoreTokens() == TRUE){
80 ContactLine = wSTContactFileLines.GetNextToken();
81 ContactFileLines.insert(std::make_pair(ContactLineSeek, ContactLine));
88 bool QuoteMode = FALSE;
89 bool PropertyFind = TRUE;
90 bool HasExtraNicknames = FALSE;
91 bool IgnoreGender = FALSE;
92 bool ExtraLineSeek = TRUE;
93 bool BirthdayProcessed = FALSE;
94 bool AnniversaryProcessed = FALSE;
95 bool FNProcessed = FALSE;
96 bool GenderProcessed = FALSE;
97 bool NameProcessed = FALSE;
98 bool UIDProcessed = FALSE;
99 bool KindProcessed = FALSE;
100 bool ETagFound = FALSE;
101 bool ETagOrigFound = FALSE;
102 bool VersionProcessed = FALSE;
103 int intExtraNickname = 0;
104 wxString wxSProperty;
105 wxString wxSPropertySeg1;
106 wxString wxSPropertySeg2;
107 wxString wxSPropertyNextLine;
108 size_t ContactLineLen = 0;
109 int QuoteBreakPoint = 0;
112 int NicknameCount = 0;
121 int RelatedCount = 0;
126 int CategoryCount = 0;
132 int CalReqAdrCount = 0;
133 int FreeBusyCount = 0;
137 //int intValueSeek = 1;
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 for (std::map<int,wxString>::iterator iter = ContactFileLines.begin();
152 iter != ContactFileLines.end(); ++iter){
154 // Find the colon which splits the start bit from the data part.
156 ContactLine = iter->second;
158 while (ExtraLineSeek == TRUE){
160 // Check if there is extra data on the next line
161 // (indicated by space or tab at the start) and add data.
165 if (iter == ContactFileLines.end()){
172 wxSPropertyNextLine = iter->second;
175 if (wxSPropertyNextLine.Mid(0, 1) == wxT(" ") || wxSPropertyNextLine.Mid(0, 1) == wxT("\t")){
177 wxSPropertyNextLine.Remove(0, 1);
178 //wxSPropertyNextLine.Trim(FALSE);
179 //ContactLine.Trim();
180 ContactLine.Append(wxSPropertyNextLine);
185 ExtraLineSeek = FALSE;
191 ContactLineLen = ContactLine.Len();
193 // Make sure we are not in quotation mode.
194 // Make sure colon does not have \ or \\ before it.
196 for (int i = 0; i <= ContactLineLen; i++){
198 if ((ContactLine.Mid(i, 1) == wxT(";") || ContactLine.Mid(i, 1) == wxT(":")) && PropertyFind == TRUE){
200 PropertyFind = FALSE;
202 } else if (PropertyFind == TRUE){
204 wxSProperty.Append(ContactLine.Mid(i, 1));
208 if (ContactLine.Mid(i, 1) == wxT("\"")){
210 if (QuoteMode == TRUE){
222 if (ContactLine.Mid(i, 1) == wxT(":") && ContactLine.Mid((i - 1), 1) != wxT("\\") && QuoteMode == FALSE){
231 // Split that line at the point into two variables (ignore the colon).
233 wxSPropertySeg1 = ContactLine.Mid(0, QuoteBreakPoint);
234 wxSPropertySeg2 = ContactLine.Mid((QuoteBreakPoint + 1));
236 // Add the data into the contact editor depending on what it is.
238 if (wxSProperty == wxT("VERSION") && VersionProcessed == FALSE){
240 // Check if version is 4.0, otherwise don't
243 if (wxSPropertySeg2 != wxT("4.0")){
244 wxMessageBox(_("This file is not a vCard 4.0 contact and is not supported under Xestia Address Book."),
245 _("Contact not supported"), wxICON_ERROR);
250 VersionProcessed = TRUE;
252 } if (wxSProperty == wxT("KIND") && KindProcessed == FALSE){
254 // See frmContactEditor-LoadGroup.cpp
256 LoadKind(wxSPropertySeg2);
258 } else if (wxSProperty == wxT("MEMBER")){
260 // See frmContactEditor-LoadGroup.cpp
262 LoadMember(wxSPropertySeg2, &GroupCount);
264 } else if (wxSProperty == wxT("FN")){
266 // See frmContactEditor-LoadName.cpp
268 LoadFN(wxSPropertySeg1, wxSPropertySeg2, &FNCount, &FNProcessed, &ContactData);
270 } else if (wxSProperty == wxT("N") && NameProcessed == FALSE){
272 // See frmContactEditor-LoadName.cpp
274 LoadN(wxSPropertySeg1, wxSPropertySeg2, &NameProcessed, &ContactData);
276 } else if (wxSProperty == wxT("NICKNAME")){
278 // See frmContactEditor-LoadNickname.cpp
280 LoadNickname(wxSPropertySeg1, wxSPropertySeg2, &NicknameCount, &ContactData);
282 }/* else if (wxSProperty == wxT("GENDER") && GenderProcessed == FALSE){
284 // See frmContactEditor-LoadGender.cpp
286 LoadGender(wxSPropertySeg1, wxSPropertySeg2, &GenderProcessed, &ContactData);
288 } else if (wxSProperty == wxT("BDAY") && BirthdayProcessed == FALSE){
290 // See frmContactEditor-LoadBADays.cpp
292 LoadBDay(wxSPropertySeg1, wxSPropertySeg2, &BirthdayProcessed);
294 } else if (wxSProperty == wxT("ANNIVERSARY") && AnniversaryProcessed == FALSE){
296 // See frmContactEditor-LoadBADays.cpp
298 LoadAnniversary(wxSPropertySeg1, wxSPropertySeg2, &AnniversaryProcessed);
300 }*/ else if (wxSProperty == wxT("TZ")){
302 // See frmContactEditor-LoadTimeZone.cpp
304 LoadTimeZone(wxSPropertySeg1, wxSPropertySeg2, &TZCount);
306 } else if (wxSProperty == wxT("ADR")){
308 // See frmContactEditor-LoadAddress.cpp
310 LoadADR(wxSPropertySeg1, wxSPropertySeg2, &ADRCount);
312 } else if (wxSProperty == wxT("EMAIL")){
314 // See frmContactEditor-LoadEmail.cpp
316 LoadEmail(wxSPropertySeg1, wxSPropertySeg2, &EmailCount);
318 } else if (wxSProperty == wxT("IMPP")){
320 // See frmContactEditor-LoadIM.cpp
322 LoadIM(wxSPropertySeg1, wxSPropertySeg2, &IMPPCount);
324 } else if (wxSProperty == wxT("TEL")){
326 // See frmContactEditor-LoadTelephone.cpp
328 LoadTelephone(wxSPropertySeg1, wxSPropertySeg2, &TelCount);
330 } else if (wxSProperty == wxT("LANG")){
332 // See frmContactEditor-LoadLanguage.cpp
334 LoadLanguage(wxSPropertySeg1, wxSPropertySeg2, &LangCount);
336 } else if (wxSProperty == wxT("GEO")){
338 // See frmContactEditor-LoadGeo.cpp
340 LoadGeo(wxSPropertySeg1, wxSPropertySeg2, &GeoCount);
342 } else if (wxSProperty == wxT("RELATED")){
344 // See fromContactEditor-LoadRelated.cpp
346 LoadRelated(wxSPropertySeg1, wxSPropertySeg2, &RelatedCount);
348 } else if (wxSProperty == wxT("URL")){
350 // See frmContactEditor-LoadURL.cpp
352 LoadURL(wxSPropertySeg1, wxSPropertySeg2, &URLCount);
354 } else if (wxSProperty == wxT("TITLE")) {
356 // See frmContactEditor-LoadTitle.cpp
358 LoadTitle(wxSPropertySeg1, wxSPropertySeg2, &TitleCount);
360 } else if (wxSProperty == wxT("ROLE")) {
362 // See frmContactEditor-LoadRole.cpp
364 LoadRole(wxSPropertySeg1, wxSPropertySeg2, &RoleCount);
366 } else if (wxSProperty == wxT("ORG")) {
368 // See frmContactEditor-LoadOrg.cpp
370 LoadOrg(wxSPropertySeg1, wxSPropertySeg2, &OrgCount);
372 } else if (wxSProperty == wxT("NOTE")) {
374 // See frmContactEditor-LoadNote.cpp
376 LoadNote(wxSPropertySeg1, wxSPropertySeg2, &NoteCount);
378 } else if (wxSProperty == wxT("CATEGORIES")) {
380 // See frmContactEditor-LoadCategory.cpp
382 LoadCategory(wxSPropertySeg1, wxSPropertySeg2, &CategoryCount);
384 } else if (wxSProperty == wxT("PHOTO")) {
386 // See frmContactEditor-LoadPhoto.cpp
388 LoadPhoto(wxSPropertySeg1, wxSPropertySeg2, &PhotoCount);
390 } else if (wxSProperty == wxT("LOGO")) {
392 // See frmContactEditor-LoadLogo.cpp
394 LoadLogo(wxSPropertySeg1, wxSPropertySeg2, &LogoCount);
396 } else if (wxSProperty == wxT("SOUND")) {
398 // See frmContactEditor-LoadSound.cpp
400 LoadSound(wxSPropertySeg1, wxSPropertySeg2, &SoundCount);
402 } else if (wxSProperty == wxT("CALURI")){
404 // See frmContactEditor-LoadCalendar.cpp
406 LoadCalURI(wxSPropertySeg1, wxSPropertySeg2, &CalAdrCount);
408 } else if (wxSProperty == wxT("CALADRURI")){
410 // See frmContactEditor-LoadCalendar.cpp
412 LoadCalAdrURI(wxSPropertySeg1, wxSPropertySeg2, &CalReqAdrCount);
414 } else if (wxSProperty == wxT("FBURL")){
416 // See frmContactEditor-LoadCalendar.cpp
418 LoadCalFreeBusy(wxSPropertySeg1, wxSPropertySeg2, &FreeBusyCount);
420 } else if (wxSProperty == wxT("KEY")){
422 // See frmContactEditor-LoadKey.cpp
424 LoadKey(wxSPropertySeg1, wxSPropertySeg2, &KeyCount);
426 } else if (wxSProperty == wxT("UID") && UIDProcessed == FALSE){
428 UIDToken = wxSPropertySeg2;
431 } else if (wxSProperty.Mid(0, 3) == wxT("VND")){
433 // Split the Vendor three ways.
435 wxStringTokenizer wSTVendorDetails(wxSPropertySeg1, wxT("-"));
438 wxString wxSVNDPropName;
441 while (wSTVendorDetails.HasMoreTokens() == TRUE){
443 wSTVendorDetails.GetNextToken();
444 wxSVNDID = wSTVendorDetails.GetNextToken();
445 wxSVNDPropName = wSTVendorDetails.GetNextToken();
450 if (!wxSVNDID.IsEmpty() && !wxSVNDPropName.IsEmpty()){
452 // Setup the values for later processing.
454 VendorList.insert(std::make_pair(intValueSeek, wxSPropertySeg2));
455 VendorListPEN.insert(std::make_pair(intValueSeek, wxSVNDID));
456 VendorListElement.insert(std::make_pair(intValueSeek, wxSVNDPropName));
458 // Add the data to the vendor variables.
462 coldata.SetId(intValueSeek);
463 coldata.SetData(intValueSeek);
464 coldata.SetText(wxSVNDID + wxT("-") + wxSVNDPropName);
466 ListCtrlIndex = lboVendorNamespace->InsertItem(coldata);
468 VendorList.erase(intValueSeek);
469 VendorListPEN.erase(intValueSeek);
470 VendorListElement.erase(intValueSeek);
472 VendorList.insert(std::make_pair(intValueSeek, wxSPropertySeg2));
473 VendorListPEN.insert(std::make_pair(intValueSeek, wxSVNDID));
474 VendorListElement.insert(std::make_pair(intValueSeek, wxSVNDPropName));
481 } else if (wxSProperty.Mid(0, 2) == wxT("X-")){
485 XTokenList.insert(std::make_pair(intValueSeek, wxSPropertySeg2));
486 XTokenListTokens.insert(std::make_pair(intValueSeek, wxSPropertySeg1.Mid(2)));
492 coldata.SetId(intValueSeek);
493 coldata.SetData(intValueSeek);
494 coldata.SetText(wxSPropertySeg1.Mid(2));
496 ListCtrlIndex = lboXToken->InsertItem(coldata);
504 // Reset the variables.
508 ExtraLineSeek = TRUE;
516 FMTimer.SetFilename(Filename);
517 FMTimer.Start(10000, FALSE);
524 void frmContactEditor::SplitValues(wxString *PropertyLine,
525 std::map<int,int> *SplitPoints,
526 std::map<int,int> *SplitLength,
529 size_t intPropertyLen = PropertyLine->Len();
530 int intSplitsFound = 0;
531 int intSplitSize = 0;
532 int intSplitSeek = 0;
534 for (int i = intSize; i <= intPropertyLen; i++){
538 if (PropertyLine->Mid(i, 1) == wxT(";") &&
539 PropertyLine->Mid((i - 1), 1) != wxT("\\")){
541 if (intSplitsFound == 0){
543 SplitLength->insert(std::make_pair(intSplitsFound, (intSplitSize)));
547 SplitLength->insert(std::make_pair(intSplitsFound, (intSplitSize - 1)));
551 SplitPoints->insert(std::make_pair(intSplitsFound, (i + 1)));
561 if (intSplitsFound == 0){
563 SplitPoints->insert(std::make_pair(intSplitsFound, (8 + 1)));
564 SplitLength->insert(std::make_pair(intSplitsFound, intSplitSize));
568 SplitPoints->insert(std::make_pair(intSplitsFound, (intSplitSeek + 1)));
569 SplitLength->insert(std::make_pair(intSplitsFound, intSplitSize));