Home | News | Projects | Releases
Bugs | RFE | Repositories | Help
266a5e0eceda576864815d8774381b50d3e64821
[xestiaab/.git] / source / contacteditor / ContactDataObject.cpp
1 // ContactDataObject.cpp - Client Data Object.
2 //
3 // (c) 2012-2015 Xestia Software Development.
4 //
5 // This file is part of Xestia Address Book.
6 //
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.
10 //
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.
15 //
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){
22         
23         if (!wxFileExists(Filename)){
24         
25                 return CONTACTLOAD_FILEMISSING;
26         
27         }
28         
29         wxFile ContactFile;
30         
31         if (!ContactFile.Open(Filename, wxFile::read, wxS_DEFAULT)){
32         
33                 return CONTACTLOAD_FILEERROR;
34         
35         }
36         
37         // Check that the vCard is a valid vCard 4.0 file.
39         vCard vCard4FormatCheck;
40         
41         vCard4FormatCheck.LoadFile(Filename);
42         
43         if (vCard4FormatCheck.Get("VERSION") != wxT("4.0")){
44         
45                 return CONTACTLOAD_FILEINVALIDFORMAT;
46         
47         }
49         // Check that the vCard meets the base specification.
50         
51         if (!vCard4FormatCheck.MeetBaseSpecification()){
52         
53                 return CONTACTLOAD_FILEBASESPECFAIL;
54         
55         }
56         
57         wxStringTokenizer wSTContactFileLines(vCard4FormatCheck.WriteString(), wxT("\r\n"));
58         
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));
67                 ContactLineSeek++;              
68         
69         }
70         
71         wxString wxSPropertyNextLine;
72         
73         bool ExtraLineSeek = TRUE;
74         bool QuoteMode = FALSE;
75         bool PropertyFind = TRUE;
76         bool KindProcessed = FALSE;
77         int ContactLineLen = 0;
78         int QuoteBreakPoint = 0;
79         int GroupCount = 0;
80         int FNCount = 0;
81         wxString ContactLine;
82         wxString PropertyLine;
83         wxString PropertySeg1;
84         wxString PropertySeg2;
85         wxString PropertyNextLine;
86         wxString Property;
87         
88         for (std::map<int,wxString>::iterator iter = ContactFileLines.begin(); 
89          iter != ContactFileLines.end(); ++iter){
91                 ExtraLineSeek = TRUE;
92                 QuoteMode = FALSE;
93                 PropertyFind = TRUE;
94                 ContactLineLen = 0;
95                 QuoteBreakPoint = 0;
96                 ContactLine.Clear();
97                 PropertyLine.Clear();
98                 PropertySeg1.Clear();
99                 PropertySeg2.Clear();
100                 Property.Clear();
101          
102                 ContactLine = iter->second;
103                 
104                 while (ExtraLineSeek == TRUE){
105                 
106                         // Check if there is extra data on the next line 
107                         // (indicated by space or tab at the start) and add data.
108                 
109                         iter++;
110                         
111                         if (iter == ContactFileLines.end()){
112                         
113                                 iter--;
114                                 break;
115                         
116                         }                       
117                 
118                         PropertyNextLine = iter->second;
119                 
120                         if (PropertyNextLine.Mid(0, 1) == wxT(" ") || PropertyNextLine.Mid(0, 1) == wxT("\t")){
121                 
122                                 PropertyNextLine.Remove(0, 1);
123                                 ContactLine.Append(PropertyNextLine);
124                 
125                         } else {
126                         
127                                 iter--;
128                                 ExtraLineSeek = FALSE;
129                         
130                         }
131                 
132                 }
134                 ContactLineLen = ContactLine.Len();
135                 
136                 // Make sure we are not in quotation mode.
137                 // Make sure colon does not have \ or \\ before it.
138                 
139                 for (int i = 0; i <= ContactLineLen; i++){
140                 
141                         if ((ContactLine.Mid(i, 1) == wxT(";") || ContactLine.Mid(i, 1) == wxT(":")) && PropertyFind == TRUE){
142                         
143                                 PropertyFind = FALSE;
144                         
145                         } else if (PropertyFind == TRUE){
146                         
147                                 Property.Append(ContactLine.Mid(i, 1));
148                         
149                         }               
150                 
151                         if (ContactLine.Mid(i, 1) == wxT("\"")){
152                         
153                                 if (QuoteMode == TRUE){
154                                 
155                                         QuoteMode = FALSE;
156                                 
157                                 } else {
158                         
159                                         QuoteMode = TRUE;
160                                         
161                                 }
162                         
163                         }
164                         
165                         if (ContactLine.Mid(i, 1) == wxT(":") && ContactLine.Mid((i - 1), 1) != wxT("\\") && QuoteMode == FALSE){
166                         
167                                 QuoteBreakPoint = i;
168                                 break;
169                         
170                         }
171                 
172                 }
173                 
174                 // Split that line at the point into two variables (ignore the colon).
175                 
176                 PropertySeg1 = ContactLine.Mid(0, QuoteBreakPoint);
177                 PropertySeg2 = ContactLine.Mid((QuoteBreakPoint + 1));
178                 
179                  if (Property == wxT("KIND") && KindProcessed == FALSE){
180                                 
181                         ProcessKind(PropertySeg2);
182                 
183                 } else if (Property == wxT("MEMBER")){
185                         ProcessMember(PropertySeg1, PropertySeg2, &GroupCount);
186                         GroupCount++;   
187                 
188                 } else if (Property == wxT("FN")){
189                 
190                         ProcessFN(PropertySeg1, PropertySeg2, &FNCount);
191                         FNCount++;
192                 
193                 }
194                 
195         }
196         
197         return CONTACTLOAD_OK;
201 void ContactDataObject::ProcessKind(wxString KindType){
203         if (KindType == wxT("individual")){
204                         
205                 ContactKind = CONTACTKIND_INDIVIDUAL;
206                         
207         } else if (KindType == wxT("group")){
208                         
209                 ContactKind = CONTACTKIND_GROUP;
210                         
211         } else if (KindType == wxT("org")){
212                         
213                 ContactKind = CONTACTKIND_ORGANISATION;
214                         
215         } else if (KindType == wxT("location")){
216                         
217                 ContactKind = CONTACTKIND_LOCATION;
218                         
219         } else {
220                         
221                 ContactKind = CONTACTKIND_NONE;                 
222         }
226 void ContactDataObject::ProcessMember(wxString PropertySeg1, wxString PropertySeg2, int *GroupCount){
228         std::map<int, int> SplitPoints;
229         std::map<int, int> SplitLength;
231         int intPrevValue = 8;
232         int intPref = 0;                        
233         int intType = 0;
234         
235         SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue);
237         intPrevValue = 7;
238         
239         wxString PropertyName;
240         wxString PropertyValue;
241         wxString PropertyData;
242         wxString PropertyTokens;
243         std::map<int,int>::iterator SLiter;
244         bool FirstToken = TRUE;
245         
246         for (std::map<int, int>::iterator intiter = SplitPoints.begin(); 
247         intiter != SplitPoints.end(); ++intiter){
248         
249                 SLiter = SplitLength.find(intiter->first);
250         
251                 PropertyData = PropertySeg1.Mid(intPrevValue, (SLiter->second));
252                 
253                 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
254                 PropertyName = PropertyElement.GetNextToken();                          
255                 PropertyValue = PropertyElement.GetNextToken();
256                 
257                 intPrevValue = intiter->second;
258                 
259                 CaptureString(&PropertyValue, FALSE);
260         
261                 if (PropertyName == wxT("ALTID")){
263                         GroupsListAltID.erase(*GroupCount);
264                         GroupsListAltID.insert(std::make_pair(*GroupCount, PropertyValue));
265                 
266                 } else if (PropertyName == wxT("PID")){
268                         GroupsListPID.erase(*GroupCount);
269                         GroupsListPID.insert(std::make_pair(*GroupCount, PropertyValue));
270                 
271                 } else if (PropertyName == wxT("PREF")){
273                         int PriorityNumber = 0;
274                         bool ValidNumber = TRUE;
275                         
276                         try{
277                                 PriorityNumber = std::stoi(PropertyValue.ToStdString());
278                         }
279                         
280                         catch(std::invalid_argument &e){
281                                 ValidNumber = FALSE;
282                         }
284                         if (ValidNumber == TRUE){
286                                 GroupsListPref.erase(*GroupCount);
287                                 GroupsListPref.insert(std::make_pair(*GroupCount, PriorityNumber));
288                 
289                         }
290                 
291                 } else if (PropertyName == wxT("MEDIATYPE")){
293                         GroupsListMediaType.erase(*GroupCount);
294                         GroupsListMediaType.insert(std::make_pair(*GroupCount, PropertyValue));
295                 
296                 } else if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty()){
297                         
298                         if (FirstToken == TRUE){
299                                 
300                                 PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue);
301                                 FirstToken = FALSE;
302                                 
303                         } else {
304                         
305                                 PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue);
306                                 
307                         }
308                         
309                 }
310                 
311         }
313         GroupsList.insert(std::make_pair(*GroupCount, PropertySeg2));
315         if (!PropertyTokens.IsEmpty()){
316         
317                 GroupsListTokens.insert(std::make_pair(*GroupCount, PropertyTokens));
318         
319         }
324 void ContactDataObject::ProcessFN(wxString PropertySeg1, wxString PropertySeg2, int *FNCount){
326         std::map<int, int> SplitPoints;
327         std::map<int, int> SplitLength;
329         int intPrevValue = 4;
330         int intPref = 0;                        
331         int intType = 0;
332         
333         SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue);
335         intPrevValue = 3;
336         
337         wxString PropertyName;
338         wxString PropertyValue;
339         wxString PropertyData;
340         wxString PropertyTokens;
341         std::map<int,int>::iterator SLiter;
342         bool FirstToken = TRUE;
343         
344         for (std::map<int, int>::iterator intiter = SplitPoints.begin(); 
345         intiter != SplitPoints.end(); ++intiter){
346         
347                 SLiter = SplitLength.find(intiter->first);
348         
349                 PropertyData = PropertySeg1.Mid(intPrevValue, (SLiter->second));
350                 
351                 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
352                 PropertyName = PropertyElement.GetNextToken();                          
353                 PropertyValue = PropertyElement.GetNextToken();
354                 
355                 intPrevValue = intiter->second;
356                 
357                 CaptureString(&PropertyValue, FALSE);
358                 
359                 if (PropertyName == wxT("TYPE")){
361                         if (!PropertyValue.IsEmpty() || PropertyValue == wxT("home") ||
362                                 PropertyValue == wxT("work") ){
364                                 FullNamesListType.erase(*FNCount);
365                                 FullNamesListType.insert(std::make_pair(*FNCount, PropertyValue));
366                 
367                         }
368                 
369                 } else if (PropertyName == wxT("LANGUAGE")){
371                         FullNamesListLanguage.erase(*FNCount);
372                         FullNamesListLanguage.insert(std::make_pair(*FNCount, PropertyValue));
373                 
374                 } else if (PropertyName == wxT("ALTID")){
375                 
376                         FullNamesListAltID.erase(*FNCount);
377                         FullNamesListAltID.insert(std::make_pair(*FNCount, PropertyValue));
378                 
379                 } else if (PropertyName == wxT("PID")){
381                         FullNamesListPID.erase(*FNCount);
382                         FullNamesListPID.insert(std::make_pair(*FNCount, PropertyValue));
383                 
384                 } else if (PropertyName == wxT("PREF")){
386                         int PriorityNumber = 0;
387                         bool ValidNumber = TRUE;
388                         
389                         try{
390                                 PriorityNumber = std::stoi(PropertyValue.ToStdString());
391                         }
392                         
393                         catch(std::invalid_argument &e){
394                                 ValidNumber = FALSE;
395                         }
397                         if (ValidNumber == TRUE){
399                                 FullNamesListPref.erase(*FNCount);
400                                 FullNamesListPref.insert(std::make_pair(*FNCount, PriorityNumber));
402                         }
403                 
404                 } else if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty()){
405                         
406                         if (FirstToken == TRUE){
407                                 
408                                 PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue);
409                                 FirstToken = FALSE;
410                                 
411                         } else {
412                         
413                                 PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue);
414                                 
415                         }
416                         
417                 } 
418         
419         }
421         FullNamesList.insert(std::make_pair(*FNCount, PropertySeg2));
423         if (!PropertyTokens.IsEmpty()){
424         
425                 FullNamesListTokens.insert(std::make_pair(*FNCount, PropertyTokens));
426         
427         }
431 void SplitValues(wxString *PropertyLine, 
432         std::map<int,int> *SplitPoints, 
433         std::map<int,int> *SplitLength, 
434         int intSize){
435         
436         size_t intPropertyLen = PropertyLine->Len();
437         int intSplitsFound = 0;
438         int intSplitSize = 0;
439         int intSplitSeek = 0;
440         
441         for (int i = intSize; i <= intPropertyLen; i++){
443                 intSplitSize++;
444         
445                 if (PropertyLine->Mid(i, 1) == wxT(";") &&
446                     PropertyLine->Mid((i - 1), 1) != wxT("\\")){
447            
448                     if (intSplitsFound == 0){
449             
450                         SplitLength->insert(std::make_pair(intSplitsFound, (intSplitSize)));
451           
452                     } else {
453            
454                         SplitLength->insert(std::make_pair(intSplitsFound, (intSplitSize - 1)));
455             
456                     }
457             
458                     SplitPoints->insert(std::make_pair(intSplitsFound, (i + 1)));
459             
460                     intSplitsFound++;
461                     intSplitSeek = i;
462                     intSplitSize = 0;
463             
464                 }
466         }
468         if (intSplitsFound == 0){
470                 SplitPoints->insert(std::make_pair(intSplitsFound, (8 + 1)));
471                 SplitLength->insert(std::make_pair(intSplitsFound, intSplitSize));
473         } else {
475                 SplitPoints->insert(std::make_pair(intSplitsFound, (intSplitSeek + 1)));
476                 SplitLength->insert(std::make_pair(intSplitsFound, intSplitSize));
478         }
Xestia Software Development
Yn Maystri
© 2006 - 2019 Xestia Software Development
Software

Xestia Address Book
Xestia Calendar
Development

Xestia Gelforn
Everything else

About
News
Privacy Policy