Home | News | Projects | Releases
Bugs | RFE | Repositories | Help
frmContactEditor: Check for parent window before sending update event
[xestiaab/.git] / source / contacteditor / frmContactEditor-Save.cpp
1 // frmContactEditor-Save.cpp - frmContactEditor save contact subroutines.
2 //
3 // (c) 2012-2016 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 "frmContactEditor.h"
20 #include "../enums.h"
21 #include "../version.h"
22 #include "../vcard/vcard.h"
23 #include "../vcard/vcard34conv.h"
24 #include "../common/textprocessing.h"
25 #include "../common/preferences.h"
26 #include "../common/uuid.h"
27 #include "../common/dirs.h"
29 void frmContactEditor::SaveContact( wxCommandEvent& event )
30 {
31     
32         // Do not save if the account is an unsupported account.
33         
34         if (boolUnsupportedAccount == true){
35         
36                 wxMessageBox(_("Cannot make changes to a contact from an unsupported account type."), _("Unsupported account"), wxICON_ERROR);          
37                 return;
38                 
39         }
40         
41         // Check if Display As combo box has a value in it.
42         // Do not go any further if there is no value.
43     
44         wxString cmbDisplayAsValue = cmbDisplayAs->GetValue();
45     
46         if (cmbDisplayAsValue.IsEmpty()){
47         
48                 wxMessageBox(_("Display As value cannot be left blank."), _("Display As value empty"), wxICON_ERROR);
49                 return;
50         
51         }
52     
53         // Save the updated contact data.
54     
55         //vCard ContactData;
56         wxString FilenameFinal;
57         bool ReplaceContact = FALSE;
58     
59         if (StartupEditMode == TRUE){
60     
61                 if (cmbType->GetCurrentSelection() == 1 ||
62                     cmbType->GetCurrentSelection() == 3 ||
63                     cmbType->GetCurrentSelection() == 4){
64         
65                         if (IsGroup == TRUE){
66             
67                                 // Mark contact for replacing.
68             
69                                 ReplaceContact = TRUE;
70                                 IsGroup = FALSE;
71             
72                         }
73         
74                 } else if (cmbType->GetCurrentSelection() == 2){
75         
76                         if (IsGroup == FALSE){
77             
78                                 // Mark contact for replacing.
79             
80                                 ReplaceContact = TRUE;
81                                 IsGroup = TRUE;
82             
83                         }
84         
85                 }
86     
87                 if (ReplaceContact == TRUE){
88         
89                         wxString wxDelSplitFilename;
90                         wxString wxDelFinalFilename;
91                         wxString wxSDelDataURL;
92                         wxStringTokenizer wSTDelFilename(wxSContactFilename, wxT("/"));
93                         
94                         while(wSTDelFilename.HasMoreTokens()){
95             
96                                 wxDelSplitFilename = wSTDelFilename.GetNextToken();
97             
98                         }
99         
100                         wxSDelDataURL = wxDelSplitFilename;
101         
102                         // Delete the contact from the server as it will be useless in certain
103                         // address book clients.
104         
105                         ActMgrPtr->AddTask(2, cmbDisplayAs->GetValue(), wxSContactAccount, wxSDelDataURL, wxDelSplitFilename, wxSContactFilename, wxT(""));
106         
107                         // Clear the filename so the trigger to recreate the UID is done.
108         
109                         wxSContactFilename.Clear();
110                         EditMode = FALSE;
111         
112                 }
113     
114         }
115     
116         if (wxSContactFilename.IsEmpty()){
117         
118                 // Generate a random UUID.
119         
120                 ContactEditorData.UIDToken = GenerateUUID();
121                 ContactEditorData.UIDToken = ContactEditorData.UIDToken.MakeUpper();
122         
123                 // Setup the filename.
124         
125                 FilenameFinal = GetAccountDir(wxSContactAccount, FALSE);
126         
127 #if defined(__HAIKU__)
128                 
129 #elif defined(__WIN32__)
130         
131                 FilenameFinal = GetAccountDir(wxSContactAccount, FALSE);
132                 FilenameFinal.Append(ContactEditorData.UIDToken);
133                 FilenameFinal.Append(wxT(".vcf"));
134                 wxSContactFilename = FilenameFinal;
135         
136 #else
137         
138                 FilenameFinal = GetAccountDir(wxSContactAccount, FALSE);
139                 FilenameFinal.Append(ContactEditorData.UIDToken);
140                 FilenameFinal.Append(wxT(".vcf"));
141                 wxSContactFilename = FilenameFinal;
142         
143 #endif
144         
145         } else {
146         
147                 if (ContactEditorData.UIDToken.IsEmpty()){
148             
149                         // UID Token is empty. (Shouldn't be).
150                         // Generate a new UID Token.
151             
152                         ContactEditorData.UIDToken = GenerateUUID();
153                         ContactEditorData.UIDToken = ContactEditorData.UIDToken.MakeUpper();
154             
155                 }
156         
157                 FilenameFinal = wxSContactFilename;
158         
159         }
160     
161         // Setup the data and write it into the account folder.
162     
163         // Begin preperations to write the contact to a file.
164     
165         bool FNFirst = TRUE;
166         std::map<int,int>::iterator intiter;
167         std::map<int,wxString>::iterator striter;
168     
169         // Set some values for saving.
170         
171         ContactEditorData.NameForename = txtForename->GetValue();
172         ContactEditorData.NameSurname = txtSurname->GetValue();
173         ContactEditorData.NameOtherNames = txtOtherNames->GetValue();
174         ContactEditorData.NameTitle = txtTitle->GetValue();
175         ContactEditorData.NameSuffix = txtSuffix->GetValue();
176         
177         ContactEditorData.GenderDetails = txtGenderDescription->GetValue();
178         
179         // Process Birthday: Get Day, Month & Year.
180         
181         wxDateTime BirthdayDate;
182         wxDateTime::Month BirthdayMonth;
183         int BirthdayDay;
184         int BirthdayYear;
185         wxString DataBeforeT;
186         wxString DataAfterT;
187         wxString FinalBirthdayString;
188         bool ProcessDataAfterT = FALSE;
189         
190         BirthdayDate = dapBirthday->GetValue();
191         
192         if (!txtBirthday->IsEmpty()){
193         
194                 // Birthday value is text so use this.
195                 
196                 ContactEditorData.Birthday = txtBirthday->GetValue();
197                 
198         } else if (BirthdayDate.IsValid()){
199             
200                 BirthdayDay = BirthdayDate.GetDay();
201                 BirthdayMonth = BirthdayDate.GetMonth();
202                 BirthdayYear = BirthdayDate.GetYear();
203             
204                 // Look for T and replace data before this.
205             
206                 wxStringTokenizer wSTDate(ContactEditorData.Birthday, wxT("T"));
207             
208                 while (wSTDate.HasMoreTokens()){
209                 
210                         if (ProcessDataAfterT == FALSE){
211                     
212                                 DataBeforeT = wSTDate.GetNextToken();
213                                 ProcessDataAfterT = TRUE;
214                     
215                         } else {
216                     
217                                 DataAfterT = wSTDate.GetNextToken();
218                                 break;
219                     
220                         }
221                 
222                 }
223             
224                 // If there is not T then replace altogether.
225             
226                 wxString FinalBirthdayDay;
227                 wxString FinalBirthdayMonth;
228                 wxString FinalBirthdayYear;
229             
230                 if (BirthdayDay < 10){
231                 
232                         FinalBirthdayDay = wxT("0") + wxString::Format(wxT("%i"), BirthdayDay);
233                 
234                 } else {
235                 
236                         FinalBirthdayDay = wxString::Format(wxT("%i"), BirthdayDay);
237                 
238                 }
239             
240                 if (((int)BirthdayMonth + 1) < 10){
241                 
242                         FinalBirthdayMonth = wxT("0") + wxString::Format(wxT("%i"), ((int)BirthdayMonth + 1));
243                 
244                 } else {
245                 
246                         FinalBirthdayMonth = wxString::Format(wxT("%i"), ((int)BirthdayMonth + 1));
247                 
248                 }
249             
250                 if (BirthdayYear == 0){
251                 
252                         FinalBirthdayYear = wxT("--");
253                 
254                 } else {
255                 
256                         FinalBirthdayYear = wxString::Format(wxT("%i"), BirthdayYear);
257                 
258                 }
259             
260                 if (!DataAfterT.IsEmpty()){
261                 
262                         FinalBirthdayString = FinalBirthdayYear + FinalBirthdayMonth + FinalBirthdayDay + wxT("T") + DataAfterT;
263                 
264                 } else {
265                 
266                         FinalBirthdayString = FinalBirthdayYear + FinalBirthdayMonth + FinalBirthdayDay;
267                 
268                 }
269                 
270                 if(!FinalBirthdayString.IsEmpty()){
271                         
272                         ContactEditorData.Birthday = FinalBirthdayString;
273                         
274                 }
275                 
276         }
277         
278         // Process Anniversary: Get Day, Month & Year.
279         
280         wxDateTime AnniversaryDate;
281         wxDateTime::Month AnniversaryMonth;
282         int AnniversaryDay;
283         int AnniversaryYear;
284         DataBeforeT = "";
285         DataAfterT = "";
286         wxString FinalAnniversaryString;
287         ProcessDataAfterT = FALSE;
288         
289         AnniversaryDate = dapAnniversary->GetValue();
290         
291         if (!txtAnniversary->IsEmpty()){
292         
293                 // Birthday value is text so use this.
294                 
295                 ContactEditorData.Anniversary = txtAnniversary->GetValue();
296                 
297         } else if (AnniversaryDate.IsValid()){
298             
299                 AnniversaryDay = AnniversaryDate.GetDay();
300                 AnniversaryMonth = AnniversaryDate.GetMonth();
301                 AnniversaryYear = AnniversaryDate.GetYear();
302             
303                 // Look for T and replace data before this.
304             
305                 wxStringTokenizer wSTDate(ContactEditorData.Anniversary, wxT("T"));
306             
307                 while (wSTDate.HasMoreTokens()){
308                 
309                         if (ProcessDataAfterT == FALSE){
310                     
311                                 DataBeforeT = wSTDate.GetNextToken();
312                                 ProcessDataAfterT = TRUE;
313                     
314                         } else {
315                     
316                                 DataAfterT = wSTDate.GetNextToken();
317                                 break;
318                     
319                         }
320                 
321                 }
322             
323                 // If there is not T then replace altogether.
324             
325                 wxString FinalAnniversaryDay;
326                 wxString FinalAnniversaryMonth;
327                 wxString FinalAnniversaryYear;
328            
329                 if (AnniversaryDay < 10){
330                 
331                         FinalAnniversaryDay = wxT("0") + wxString::Format(wxT("%i"), AnniversaryDay);
332                 
333                 } else {
334                 
335                         FinalAnniversaryDay = wxString::Format(wxT("%i"), AnniversaryDay);
336                 
337                 }
338             
339                 if (((int)AnniversaryMonth + 1) < 10){
340                 
341                         FinalAnniversaryMonth = wxT("0") + wxString::Format(wxT("%i"), ((int)AnniversaryMonth + 1));
342                 
343                 } else {
344                 
345                         FinalAnniversaryMonth = wxString::Format(wxT("%i"), ((int)AnniversaryMonth + 1));
346                 
347                 }
348         
349                 if (AnniversaryYear == 0){
350                 
351                         FinalAnniversaryYear = wxT("--");
352                 
353                 } else {
354                 
355                         FinalAnniversaryYear = wxString::Format(wxT("%i"), AnniversaryYear);
356                 
357                 }
358             
359                 if (!DataAfterT.IsEmpty()){
360                 
361                         FinalAnniversaryString = FinalAnniversaryYear + FinalAnniversaryMonth + FinalAnniversaryDay + wxT("T") + DataAfterT;
362                 
363                 } else {
364                 
365                         FinalAnniversaryString = FinalAnniversaryYear + FinalAnniversaryMonth + FinalAnniversaryDay;
366                 
367                 }
368                 
369                 if(!FinalAnniversaryString.IsEmpty()){
370                         
371                         ContactEditorData.Birthday = FinalAnniversaryString;
372                         
373                 }
374         
375         }
376         
377         // Process full name.
378         
379         if (ContactEditorData.FullNamesList.size() > 0){
380                 
381                 ContactEditorData.FullNamesList[0] = cmbDisplayAs->GetValue();
382                 
383         } else {
384                 
385                 ContactEditorData.FullNamesList.insert(std::make_pair(0, cmbDisplayAs->GetValue()));
386                 ContactEditorData.FullNamesListAltID.insert(std::make_pair(0, wxT("")));
387                 ContactEditorData.FullNamesListPID.insert(std::make_pair(0, wxT("")));
388                 ContactEditorData.FullNamesListType.insert(std::make_pair(0, wxT("")));
389                 ContactEditorData.FullNamesListLanguage.insert(std::make_pair(0, wxT("")));
390                 ContactEditorData.FullNamesListPref.insert(std::make_pair(0, 0));
391                 ContactEditorData.FullNamesListTokens.insert(std::make_pair(0, wxT("")));
392                 
393         }
394     
395         FMTimer.Stop();
396         ContactEditorData.SaveFile(FilenameFinal);
397     
398         vCard34Conv ConvFileFun;
399     
400         wxString wxSData;
401     
402         ConvFileFun.ConvertToV3(FilenameFinal, &wxSData);
403     
404         wxString AccountDirPrefix;
405         wxString AccountDir;
406         wxString PrefDir;
407     
408 #if defined(__HAIKU__)
410 #elif defined(__APPLE__)
411     
412         PrefDir = GetUserPrefDir();
413     
414         wxStringTokenizer wSTFilename(wxSContactFilename, wxT("/"));
415     
416 #elif defined(__WIN32__)
417     
418         PrefDir = GetUserPrefDir();
419     
420         wxStringTokenizer wSTFilename(wxSContactFilename, wxT("\\"));
421     
422 #else
423     
424         PrefDir = GetUserPrefDir();
425     
426         wxStringTokenizer wSTFilename(wxSContactFilename, wxT("/"));
427     
428 #endif
430         XABPreferences PrefData(PrefDir);
431     
432         wxString AccountType;
433     
434         for (int i = 0; i < PrefData.accounts.GetCount(); i++){
435         
436                 AccountDir = PrefData.accounts.GetAccountDirectory(i) + wxT(".carddav");
437         
438                 if (AccountDir == wxSContactAccount){
439             
440                         AccountDirPrefix = PrefData.accounts.GetAccountDirPrefix(i);
441                         AccountDirPrefix.Trim();
442                         AccountType = PrefData.accounts.GetAccountType(i);
443                         break;
444             
445                 }
446         
447         }
448     
449         wxString wxSplitFilename;
450         wxString wxSDataURL;
451     
452         while(wSTFilename.HasMoreTokens()){
453         
454                 wxSplitFilename = wSTFilename.GetNextToken();
455         
456         }
457     
458         wxSDataURL = wxSplitFilename;
459     
460         // Find out if the filename exists in the table.
461     
462         if (AccountType == wxT("CardDAV") || AccountType == wxT("carddav")){
463         
464                 wxString ETagResult;
465                 wxString ETagOriginal;
466         
467                 ETagDB *ETagDBPtr = NULL;
468         
469                 ETagDBPtr = ETagTmrPtr->GetPointer(wxSContactAccount);
470         
471                 wxString wxSETag = ETagDBPtr->GetETag(wxSplitFilename);
472                 wxString wxSETagOrig = ETagDBPtr->GetETagOriginal(wxSplitFilename);
474                 if (wxSETagOrig.IsEmpty()){
475             
476                         // Generate the ETag.
477             
478                         wxSETagOrig = wxString::Format(wxT("%X%X%X%X"), rand() % 1024, rand() % 1024, rand() % 1024, rand() % 1024);
479             
480                 }
481         
482                 if (wxSETag.IsEmpty()){
483             
484                         // Update empty ETag.
485             
486                         wxSETag = wxSETagOrig;
487                         ETagDBPtr->AddETag(wxSplitFilename, wxSETag, "");
488             
489                 } else {
490             
491                         // Don't change original ETag.
492             
493                         wxSETag = wxString::Format(wxT("%X%X%X%X"), rand() % 1024, rand() % 1024, rand() % 1024, rand() % 1024);
494                         ETagDBPtr->UpdateETag(wxSplitFilename, wxSETag);
495             
496                 }
497         
498                 if (EditMode == FALSE){
500                         ActMgrPtr->AddTask(0, cmbDisplayAs->GetValue(), wxSContactAccount, wxSDataURL, wxSplitFilename, FilenameFinal, wxSData);
501                         EditMode = TRUE;
502                         FMTimer.SetFilename(FilenameFinal);
503                         FMTimer.UpdateTimestamp();
504                         FMTimer.Start(10000, FALSE);
505             
506                         wxCommandEvent reloadevent(RELOADCONTACTLIST);
507                         reloadevent.SetString(wxSContactAccount);
508                         wxPostEvent(this->GetParent(), reloadevent);
509             
510                 } else {
511             
512                         ActMgrPtr->AddTask(1, cmbDisplayAs->GetValue(), wxSContactAccount, wxSDataURL, wxSplitFilename, FilenameFinal, wxSData);
513                         FMTimer.UpdateTimestamp();
514                         FMTimer.Start(10000, FALSE);
515             
516                 }
517         
518         }
519     
520         // Send a notification to update the main window
521         // with the new details.
522     
523         UCNotif *ucd;
524         ucd = new UCNotif;
525     
526         // TODO: Workout nickname settings by priority and
527         // type.
528     
529         vCardName NameData;
530         
531         NameData.Forename = txtForename->GetValue();
532         NameData.Surname = txtSurname->GetValue();
533         NameData.OtherNames = txtOtherNames->GetValue();
534         NameData.Title = txtTitle->GetValue();
535         NameData.Suffix = txtSuffix->GetValue();
536         
537         if (this->GetParent() != nullptr)
538         {
539                 ucd->ContactAccount = wxSContactAccount;
540                 ucd->ContactFilename = FilenameFinal;
541                 ucd->ContactName = cmbDisplayAs->GetValue();
542                 ucd->ContactNameArray = NameData;
543     
544                 for (std::map<int,wxString>::iterator gniter = ContactEditorData.GeneralNicknamesList.begin();
545                         gniter != ContactEditorData.GeneralNicknamesList.end(); gniter++){
546         
547                         ucd->ContactNickname = gniter->second;
548                         break;
549         
550                 }
551         
552                 wxCommandEvent event2(CE_UPDATECONTACTLIST);
553                 event2.SetClientData(ucd);
554                 wxPostEvent(MainPtr, event2);
555         }
556     
559 void frmContactEditor::SaveCloseContact( wxCommandEvent& event )
561     
562         // Save the updated contact data and close the form.
563     
564         wxCommandEvent NullEvent;
565         this->SaveContact(NullEvent);
566         this->Close();
567     
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