Home | News | Projects | Releases
Bugs | RFE | Repositories | Help
Added source code, header and unit tests for the FN vCard property member and value...
[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                         // See frmContactEditor-LoadGroup.cpp
182                 
183                         ProcessKind(PropertySeg2);
184                 
185                 } else if (Property == wxT("MEMBER")){
187                         // See frmContactEditor-LoadGroup.cpp
189                         ProcessMember(PropertySeg1, PropertySeg2, &GroupCount);
190                         GroupCount++;   
191                 
192                 } else if (Property == wxT("FN")){
193                 
194                         ProcessFN(PropertySeg1, PropertySeg2, &FNCount);
195                         FNCount++;
196                 
197                 }
198                 
199         }
200         
201         return CONTACTLOAD_OK;
205 void ContactDataObject::ProcessKind(wxString KindType){
207         if (KindType == wxT("individual")){
208                         
209                 ContactKind = CONTACTKIND_INDIVIDUAL;
210                         
211         } else if (KindType == wxT("group")){
212                         
213                 ContactKind = CONTACTKIND_GROUP;
214                         
215         } else if (KindType == wxT("org")){
216                         
217                 ContactKind = CONTACTKIND_ORGANISATION;
218                         
219         } else if (KindType == wxT("location")){
220                         
221                 ContactKind = CONTACTKIND_LOCATION;
222                         
223         } else {
224                         
225                 ContactKind = CONTACTKIND_NONE;                 
226         }
230 void ContactDataObject::ProcessMember(wxString PropertySeg1, wxString PropertySeg2, int *GroupCount){
232         std::map<int, int> SplitPoints;
233         std::map<int, int> SplitLength;
235         int intPrevValue = 8;
236         int intPref = 0;                        
237         int intType = 0;
238         
239         SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue);
241         intPrevValue = 7;
242         
243         // Look for type before continuing.
244         
245         wxString PropertyName;
246         wxString PropertyValue;
247         wxString PropertyData;
248         wxString PropertyTokens;
249         std::map<int,int>::iterator SLiter;
250         bool FirstToken = TRUE;
251         
252         for (std::map<int, int>::iterator intiter = SplitPoints.begin(); 
253         intiter != SplitPoints.end(); ++intiter){
254         
255                 SLiter = SplitLength.find(intiter->first);
256         
257                 PropertyData = PropertySeg1.Mid(intPrevValue, (SLiter->second));
258                 
259                 wxStringTokenizer PropertyElement (PropertyData, wxT("="));
260                 PropertyName = PropertyElement.GetNextToken();                          
261                 PropertyValue = PropertyElement.GetNextToken();
262                 
263                 intPrevValue = intiter->second;
264                 
265                 CaptureString(&PropertyValue, FALSE);
266                 
267                 //ContactProcess::ContactProcessCaptureStrings(&PropertyValue);
268         
269                 if (PropertyName == wxT("ALTID")){
271                         GroupsListAltID.erase(*GroupCount);
272                         GroupsListAltID.insert(std::make_pair(*GroupCount, PropertyValue));
273                 
274                 } else if (PropertyName == wxT("PID")){
276                         GroupsListPID.erase(*GroupCount);
277                         GroupsListPID.insert(std::make_pair(*GroupCount, PropertyValue));
278                 
279                 } else if (PropertyName == wxT("PREF")){
281                         int PriorityNumber = 0;
282                         bool ValidNumber = TRUE;
283                         
284                         try{
285                                 PriorityNumber = std::stoi(PropertyValue.ToStdString());
286                         }
287                         
288                         catch(std::invalid_argument &e){
289                                 ValidNumber = FALSE;
290                         }
292                         if (ValidNumber == TRUE){
294                                 GroupsListPref.erase(*GroupCount);
295                                 GroupsListPref.insert(std::make_pair(*GroupCount, PriorityNumber));
296                 
297                         }
298                 
299                 } else if (PropertyName == wxT("MEDIATYPE")){
301                         GroupsListMediaType.erase(*GroupCount);
302                         GroupsListMediaType.insert(std::make_pair(*GroupCount, PropertyValue));
303                 
304                 } else if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty()){
305                         
306                         if (FirstToken == TRUE){
307                                 
308                                 PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue);
309                                 FirstToken = FALSE;
310                                 
311                         } else {
312                         
313                                 PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue);
314                                 
315                         }
316                         
317                 }
318                 
319         }
321         GroupsList.insert(std::make_pair(*GroupCount, PropertySeg2));
323         if (!PropertyTokens.IsEmpty()){
324         
325                 GroupsListTokens.insert(std::make_pair(*GroupCount, PropertyTokens));
326         
327         }
332 void ContactDataObject::ProcessFN(wxString PropertySeg1, wxString PropertySeg2, int *FNCount){
334         FullNamesList.insert(std::make_pair(*FNCount, PropertySeg2));
338 void SplitValues(wxString *PropertyLine, 
339         std::map<int,int> *SplitPoints, 
340         std::map<int,int> *SplitLength, 
341         int intSize){
342         
343         size_t intPropertyLen = PropertyLine->Len();
344         int intSplitsFound = 0;
345         int intSplitSize = 0;
346         int intSplitSeek = 0;
347         
348         for (int i = intSize; i <= intPropertyLen; i++){
350                 intSplitSize++;
351         
352                 if (PropertyLine->Mid(i, 1) == wxT(";") &&
353                     PropertyLine->Mid((i - 1), 1) != wxT("\\")){
354            
355                     if (intSplitsFound == 0){
356             
357                         SplitLength->insert(std::make_pair(intSplitsFound, (intSplitSize)));
358           
359                     } else {
360            
361                         SplitLength->insert(std::make_pair(intSplitsFound, (intSplitSize - 1)));
362             
363                     }
364             
365                     SplitPoints->insert(std::make_pair(intSplitsFound, (i + 1)));
366             
367                     intSplitsFound++;
368                     intSplitSeek = i;
369                     intSplitSize = 0;
370             
371                 }
373         }
375         if (intSplitsFound == 0){
377                 SplitPoints->insert(std::make_pair(intSplitsFound, (8 + 1)));
378                 SplitLength->insert(std::make_pair(intSplitsFound, intSplitSize));
380         } else {
382                 SplitPoints->insert(std::make_pair(intSplitsFound, (intSplitSeek + 1)));
383                 SplitLength->insert(std::make_pair(intSplitsFound, intSplitSize));
385         }
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