Home | News | Projects | Releases
Bugs | RFE | Repositories | Help
frmContactEditor: Stop XAB crashing when pressing Modify/Delete
[xestiaab/.git] / source / contacteditor / frmContactEditor.cpp
1 // frmContactEditor.cpp - Main frmContactEditor form section.
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 <map>
20 #include <string>
21 #include <thread>
22 #include <vector>
23 #include <stdlib.h>
25 #include <wx/wx.h>
26 #include <wx/ffile.h>
27 #include <wx/tokenzr.h>
28 #include <wx/mstream.h>
29 #include <wx/fs_mem.h>
30 #include <wx/datetime.h>
32 #include "frmContactEditor.h"
33 #include "frmContactEditorNickname.h"
34 #include "frmContactEditorAddress.h"
35 #include "frmContactEditorEmail.h"
36 #include "frmContactEditorIM.h"
37 #include "frmContactEditorTelephone.h"
38 #include "frmContactEditorLanguages.h"
39 #include "frmContactEditorTimezones.h"
40 #include "frmContactEditorRelated.h"
41 #include "frmContactEditorWebsites.h"
42 #include "frmContactEditorTitles.h"
43 #include "frmContactEditorRoles.h"
44 #include "frmContactEditorGeoposition.h"
45 #include "frmContactEditorGroups.h"
46 #include "frmContactEditorOrganisations.h"
47 #include "frmContactEditorNotes.h"
48 #include "frmContactEditorCategory.h"
49 #include "frmContactEditorSound.h"
50 #include "frmContactEditorPicture.h"
51 #include "frmContactEditorCalAdr.h"
52 #include "frmContactEditorKey.h"
53 #include "frmContactEditorVendor.h"
54 #include "frmContactEditorXToken.h"
55 #include "../frmMain.h"
57 #include "../enums.h"
58 #include "../version.h"
59 #include "../vcard/vcard.h"
60 #include "../vcard/vcard34conv.h"
61 #include "../bitmaps.h"
62 #include "../common/base64.h"
63 #include "../common/textprocessing.h"
64 #include "../common/preferences.h"
65 #include "../common/uuid.h"
66 #include "../common/dirs.h"
68 // TODO: Investigate problems with SFML & PulseAudio - CPU usage problems when
69 // not being used.
71 // Replace intResult with intValueSeek.
73 BEGIN_EVENT_TABLE(frmContactEditor, wxFrame)
74 EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, frmContactEditor::ContactFileChanged)
75 END_EVENT_TABLE()
77 frmContactEditor::frmContactEditor( wxWindow* parent )
78 :
79 frmContactEditorADT( parent )
80 {
81         
82         boolContactModified = FALSE;
83         wxDateTime NoDate;
84         dapAnniversary->SetValue(NoDate);
85         dapBirthday->SetValue(NoDate);
86         tabMembers->Hide();
87     
88         // Setup the buttons.
89     
90         wxMemoryInputStream istream(buttons_play_png, sizeof(buttons_play_png));
91         wxImage button_play_pngi(istream, wxBITMAP_TYPE_PNG);
92         wxBitmap playiconbmp(button_play_pngi, -1);
93         btnPlay->SetBitmapLabel(playiconbmp);
94     
95         wxMemoryInputStream istream2(buttons_stop_png, sizeof(buttons_stop_png));
96         wxImage button_stop_pngi(istream2, wxBITMAP_TYPE_PNG);
97         wxBitmap stopiconbmp(button_stop_pngi, -1);
98         btnStop->SetBitmapLabel(stopiconbmp);
99         btnStop->Disable();
100         FMTimer.SetupPointers(this);
101         //wxIcon contacticon;
102         //contacticon.CopyFromBitmap(contacticonbmp);
103     
104         nbkContact->SetSelection(0);
105     
108 frmContactEditor::~frmContactEditor()
110         
111         if (AudioStreamPlaybackPointer != nullptr)
112         {
113                 
114                 delete AudioStreamPlaybackPointer;
115                 AudioStreamPlaybackPointer = nullptr;
116                 
117         }
118         
121 void frmContactEditor::CloseContact( wxCommandEvent& event )
123     
124         Close();
125     
128 void frmContactEditor::CloseWindow( wxCloseEvent& event )
130     
131         // TODO: Check if any changes have been made,
132         // ask if the changes should be made, process
133         // action based on question and then close.
134     
135         WindowData *WData = new WindowData;
136     
137         if (StartupEditMode == FALSE){
138     
139                 WData->DataType = 1;
140                 WData->WindowPointer = this;
141                 WData->WindowID = ContactEditorUID;
142     
143                 wxCommandEvent delevent(WINDOW_CLOSE);
144                 delevent.SetClientData(WData);
145                 wxPostEvent(GetParent(), delevent);
146     
147         }
148     
149         Destroy();
150     
153 void frmContactEditor::CutText( wxCommandEvent& event )
155         // This function left empty for future implementation.
158 void frmContactEditor::CopyText( wxCommandEvent& event )
160         // This function left empty for future implementation.
163 void frmContactEditor::PasteText( wxCommandEvent& event )
165         // This function left empty for future implementation.
168 void frmContactEditor::SetupContact( wxString AccountName )
170     
171         wxSContactAccount = AccountName;
172     
175 void frmContactEditor::SetupAccountData(bool UnsupportedAccount){
176         
177         boolUnsupportedAccount = UnsupportedAccount;
178         
181 int frmContactEditor::GetLastInt(std::map<int, wxString> *MapData){
182     
183         /*
184         int intResult = 0;
185      
186         std::map<int,wxString>::iterator iwxsit;
187      
188         for( iwxsit=(*MapData).begin(); iwxsit != (*MapData).end(); iwxsit++){
189         intResult = (*iwxsit).first;
190         }
191      
192         return intResult;
193         */
194     
195         intValueSeek++;
196         return intValueSeek;
197     
200 int frmContactEditor::GetLastInt(std::map<int, std::string> *MapData){
201     
202         /* int intResult = 0;
203      
204         std::map<int,std::string>::iterator iwxsit;
205      
206         for( iwxsit=(*MapData).begin(); iwxsit != (*MapData).end(); iwxsit++){
207         intResult = (*iwxsit).first;
208         }*/
209     
210         intValueSeek++;
211         return intValueSeek;
212     
215 bool frmContactEditor::GetSelectedItem(wxListCtrl *ListCtrlPtr, 
216                                        long *longSelected,
217                                        int *intSelectedData){
218     
219         *longSelected = -1;
220         *intSelectedData = 0;
221     
222         *longSelected = ListCtrlPtr->GetNextItem(*longSelected, 
223                 wxLIST_NEXT_ALL,
224                 wxLIST_STATE_SELECTED);
225     
226         if (*longSelected == -1){
227                 return FALSE;
228         }
229     
230         *intSelectedData = (int)ListCtrlPtr->GetItemData(*longSelected);
232         return TRUE;    
233         
236 void frmContactEditor::DeleteMapDataProcess(int IndexNum, std::map<int, std::string>* MapData){
237         MapData->erase(IndexNum);
240 void frmContactEditor::DeleteMapDataProcess(int IndexNum, std::map<int, wxString>* MapData){
241         MapData->erase(IndexNum);
244 void frmContactEditor::DeleteMapDataProcess(int IndexNum, std::map<int, int>* MapData){
245         MapData->erase(IndexNum);
248 void frmContactEditor::DeleteMapDataProcess(int IndexNum, std::map<int, bool>* MapData){
249         MapData->erase(IndexNum);
252 void frmContactEditor::ProcessSaveDataProc( wxString PropName,
253                                            std::map<int,int>* MapData){
254     
255         int intIterVal = (*iterDataPtr)->first;
256     
257         std::map<int,int>::iterator intIter;
258     
259         intIter = MapData->find(intIterVal);
260     
261         int intPropValue; 
262     
263         if (intIter->first == intIterVal){
264         
265                 intPropValue = intIter->second;
266         
267                 if (intPropValue){
268             
269                         if (*boolAdditionalPtr == TRUE){
270                 
271                                 strPropertyPtr->Append(wxT(";"));
272                 
273                         } else {
274                 
275                                 *boolAdditionalPtr = TRUE;
276                 
277                         }
278             
279                 strPropertyPtr->Append(PropName + wxT("=") + wxString::Format(wxT("%i"), intPropValue));
280             
281                 *boolExtraPtr = TRUE;
282             
283                 }
284         
285         }
286     
289 void frmContactEditor::ProcessSaveDataProc( wxString PropName,
290                                            std::map<int,wxString>* MapData){
291     
292         int intIterVal;
293     
294         intIterVal = (*iterDataPtr)->first;
295     
296         std::map<int,wxString>::iterator strIter;
297     
298         strIter = MapData->find(intIterVal);
299     
300         if (strIter == MapData->end()){
301         
302                 return;
303         
304         }
305     
306         wxString strPropValue;
307     
308         if (strIter->first == intIterVal){
309         
310                 strPropValue = strIter->second;
311         
312                 if (!strPropValue.IsEmpty() && PropName.IsEmpty()){
313             
314                 strPropValue.Trim();
315                 strPropValue.Trim();
316             
317                         if (*boolAdditionalPtr == TRUE){
318                 
319                                 strPropertyPtr->Append(wxT(";"));
320                 
321                         } else {
322                 
323                                 *boolAdditionalPtr = TRUE;
324                 
325                         }
326             
327                 strPropertyPtr->Append(strPropValue);   
328             
329                 *boolExtraPtr = TRUE;
330             
331                 return;
332             
333                 }
334         
335                 if (!strPropValue.IsEmpty()){
336             
337                         strPropValue.Trim();
338                         strPropValue.Trim();
339             
340                         if (*boolAdditionalPtr == TRUE){
341                 
342                                 strPropertyPtr->Append(wxT(";"));
343                 
344                         } else {
345                 
346                                 *boolAdditionalPtr = TRUE;
347                 
348                         }
349             
350                         // Look for semi-colon in property name and if there is then
351                         // quote the value.
352             
353                         if (PropName != wxT("TYPE")){
354                 
355                                 EscapeString(&strPropValue, FALSE);     
356                 
357                         }
358             
359                         if (strPropValue.find(wxT(";")) == wxNOT_FOUND && strPropValue.find(wxT(":")) == wxNOT_FOUND &&
360                                 strPropValue.find(wxT(",")) == wxNOT_FOUND){
361                 
362                                 strPropertyPtr->Append(PropName + wxT("=") + strPropValue);
363                 
364                         } else {
365                 
366                                 strPropertyPtr->Append(PropName + wxT("=\"") + strPropValue + wxT("\""));
367                 
368                         }
369             
370                         *boolExtraPtr = TRUE;
371             
372                 }
373         
374         }
375     
378 void frmContactEditor::ProcessSaveDataStrProc( wxString PropName,
379                                               std::map<int,std::string>* MapData){
380     
381         int intIterVal = (*iterDataStringPtr)->first;
382     
383         //std::map<int,wxString>::iterator strIter;
384     
385         std::map<int,std::string>::iterator stdstrIter;
386     
387         stdstrIter = MapData->find(intIterVal); 
388                                                 
389         if (stdstrIter->first == intIterVal){
390         
391                 wxString strPropValue(stdstrIter->second.c_str(), wxConvUTF8);
392         
393                 if (!strPropValue.IsEmpty() && PropName.IsEmpty()){
394             
395                         strPropValue.Trim();
396                         strPropValue.Trim();
397             
398                         if (*boolAdditionalPtr == TRUE){
399                 
400                                 strPropertyPtr->Append(wxT(";"));
401                 
402                         } else {
403                 
404                                 *boolAdditionalPtr = TRUE;
405                 
406                         }
407             
408                         strPropertyPtr->Append(strPropValue);
409             
410                         *boolExtraPtr = TRUE;
411             
412                         return;
413             
414                 }
415         
416                 if (!strPropValue.IsEmpty()){
417             
418                         strPropValue.Trim();
419                         strPropValue.Trim();
420             
421                         if (*boolAdditionalPtr == TRUE){
422                 
423                                 strPropertyPtr->Append(wxT(";"));
424                 
425                         } else {
426                 
427                                 *boolAdditionalPtr = TRUE;
428                 
429                         }
430             
431                         // Look for semi-colon in property name and if there is then
432                         // quote the value.
433             
434                         if (PropName != wxT("TYPE")){
435                 
436                                 EscapeString(&strPropValue, FALSE);
437                 
438                         }
439             
440                         if (strPropValue.find(wxT(";")) == wxNOT_FOUND && strPropValue.find(wxT(":")) == wxNOT_FOUND &&
441                                 strPropValue.find(wxT(",")) == wxNOT_FOUND){
442                 
443                                 strPropertyPtr->Append(PropName + wxT("=") + strPropValue);
444                 
445                         } else {
446                 
447                                 strPropertyPtr->Append(PropName + wxT("=\"") + strPropValue + wxT("\""));
448                 
449                         }
450             
451                         *boolExtraPtr = TRUE;
452             
453                 }
454         
455         }
456     
460 void frmContactEditor::ProcessSaveDataStrProc( wxString PropName,
461                                               std::map<int,int>* MapData){
462     
463         int intIterVal = (*iterDataStringPtr)->first;
464     
465         std::map<int,int>::iterator intIter;
466     
467         intIter = MapData->find(intIterVal);
468     
469         int intPropValue; 
470     
471         if (intIter->first == intIterVal){
472         
473                 intPropValue = intIter->second;
474         
475                 if (intPropValue){
476             
477                         if (*boolAdditionalPtr == TRUE){
478                 
479                                 strPropertyPtr->Append(wxT(";"));
480                 
481                         } else {
482                 
483                                 *boolAdditionalPtr = TRUE;
484                 
485                         }
486             
487                         strPropertyPtr->Append(PropName + wxT("=") + wxString::Format(wxT("%i"), intPropValue));
488             
489                         *boolExtraPtr = TRUE;
490             
491                 }
492         
493         }
494     
497 void frmContactEditor::ProcessSaveDataStrProc( wxString PropName,
498                                               std::map<int,wxString>* MapData){
499     
500         int intIterVal;
501     
502         intIterVal = (*iterDataStringPtr)->first;
503     
504         std::map<int,wxString>::iterator strIter;
505     
506         strIter = MapData->find(intIterVal);
507     
508         if (strIter == MapData->end()){
509                 
510                 // Ignore this section and return.
511                 
512                 return;
513                 
514         }
515                                                       
516         wxString strPropValue;
518         if (strIter->first == intIterVal){
519         
520                 strPropValue = strIter->second;
521         
522                 if (!strPropValue.IsEmpty() && PropName.IsEmpty()){
523             
524                         strPropValue.Trim();
525                         strPropValue.Trim();
526             
527                         if (*boolAdditionalPtr == TRUE){
528                 
529                                 strPropertyPtr->Append(wxT(";"));
530                 
531                         } else {
532                 
533                                 *boolAdditionalPtr = TRUE;
534                 
535                         }
536             
537                         strPropertyPtr->Append(strPropValue);   
538             
539                         *boolExtraPtr = TRUE;
540         
541                         return;
542             
543                 }
544         
545                 if (!strPropValue.IsEmpty()){
546             
547                         strPropValue.Trim();
548                         strPropValue.Trim();
549             
550                         if (*boolAdditionalPtr == TRUE){
551                 
552                                 strPropertyPtr->Append(wxT(";"));
553                 
554                         } else {
555                 
556                                 *boolAdditionalPtr = TRUE;
557                 
558                         }       
559             
560                         // Look for semi-colon in property name and if there is then
561                         // quote the value.
562             
563                         if (PropName != wxT("TYPE")){
564                 
565                                 EscapeString(&strPropValue, FALSE);
566                 
567                         }
568             
569                         if (strPropValue.find(wxT(";")) == wxNOT_FOUND && strPropValue.find(wxT(":")) == wxNOT_FOUND &&
570                                 strPropValue.find(wxT(",")) == wxNOT_FOUND){
571                 
572                                 strPropertyPtr->Append(PropName + wxT("=") + strPropValue);
573                 
574                         } else {
575                 
576                                 strPropertyPtr->Append(PropName + wxT("=\"") + strPropValue + wxT("\""));
577                 
578                         }
579             
580                         *boolExtraPtr = TRUE;
581             
582                 }
583         
584         }
585     
588 void frmContactEditor::ProcessCaptureStringsProc(wxString *strCapture){
589     
590         CaptureString(strCapture, FALSE);
591     
594 void frmContactEditor::ResetSaveProcessData(){
595     
596         strValue.Clear();
597         strValue2.Clear();
598         strValue3.Clear();    
599     
600         boolValue = FALSE;
601         boolValue2 = FALSE;    
602         intValue2 = 0;
603         intValue  = 0;
604     
607 void frmContactEditor::SetupPointers(frmActivityMgr *ActMgr, wxETagProcessTimer *ETagProc,
608                                      frmMain *MainPtrInc){
609     
610         ActMgrPtr = ActMgr;
611         ETagTmrPtr = ETagProc;
612         MainPtr = MainPtrInc;
613     
616 void frmContactEditor::ContactFileChanged( wxCommandEvent &event ){
617     
618         // Stop the timer.
619     
620         FMTimer.Stop();
621     
622         // Check if a dialog is already open.
623     
624         if (DialogOpen == TRUE){
625         
626                 FMTimer.Start(1000, FALSE);
627                 return;
628         
629         }
630     
631         // Bring up a Yes/No modal dialog asking if the changed file should be reloaded.
632     
633         int QuestionResponse;
634     
635         QuestionResponse = wxMessageBox(_("This contact has changed. Saving the contact may overwrite or lose any changes done by that change. Do you want to reload the contact with the changes made?"), _("Contact information has changed"), wxYES_NO, this);
636     
637         if (QuestionResponse == wxYES){
638         
639                 // Reload the contact.
640                 wxString wxSReloadContactName = wxSContactFilename;
641                 ClearContact();
642                 LoadContact(wxSReloadContactName);
643         
644         } else {
645         
646                 // Do nothing other than update the timestamp so this message
647                 // doesn't appear until the next time it changes.
648         
649                 FMTimer.UpdateTimestamp();
650         
651         }  
652     
653         // Start the timer.
654     
655         FMTimer.Start();
656     
659 void frmContactEditor::UpdateMembersTab( wxCommandEvent &event ){
660     
661         if (cmbType->GetCurrentSelection() == 2){
662         
663                 tabMembers->Show();
664         
665         } else {
666         
667                 tabMembers->Hide();
668         
669         }
670     
673 void frmContactEditor::SetUID(int UID){
674     
675         ContactEditorUID = UID;
676     
679 void frmContactEditor::SetMode(bool StartupEditModeIn){
681         StartupEditMode = StartupEditModeIn;
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