1 // frmContactEditor.cpp - Main frmContactEditor form section.
3 // (c) 2012-2016 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/>
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"
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
71 // Replace intResult with intValueSeek.
73 BEGIN_EVENT_TABLE(frmContactEditor, wxFrame)
74 EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, frmContactEditor::ContactFileChanged)
77 frmContactEditor::frmContactEditor( wxWindow* parent )
79 frmContactEditorADT( parent )
82 boolContactModified = FALSE;
84 dapAnniversary->SetValue(NoDate);
85 dapBirthday->SetValue(NoDate);
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);
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);
100 FMTimer.SetupPointers(this);
101 //wxIcon contacticon;
102 //contacticon.CopyFromBitmap(contacticonbmp);
104 nbkContact->SetSelection(0);
108 frmContactEditor::~frmContactEditor()
111 if (AudioStreamPlaybackPointer != nullptr)
114 delete AudioStreamPlaybackPointer;
115 AudioStreamPlaybackPointer = nullptr;
121 void frmContactEditor::CloseContact( wxCommandEvent& event )
128 void frmContactEditor::CloseWindow( wxCloseEvent& event )
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.
135 WindowData *WData = new WindowData;
137 if (StartupEditMode == FALSE){
140 WData->WindowPointer = this;
141 WData->WindowID = ContactEditorUID;
143 wxCommandEvent delevent(WINDOW_CLOSE);
144 delevent.SetClientData(WData);
145 wxPostEvent(GetParent(), delevent);
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 )
171 wxSContactAccount = AccountName;
175 void frmContactEditor::SetupAccountData(bool UnsupportedAccount){
177 boolUnsupportedAccount = UnsupportedAccount;
181 int frmContactEditor::GetLastInt(std::map<int, wxString> *MapData){
186 std::map<int,wxString>::iterator iwxsit;
188 for( iwxsit=(*MapData).begin(); iwxsit != (*MapData).end(); iwxsit++){
189 intResult = (*iwxsit).first;
200 int frmContactEditor::GetLastInt(std::map<int, std::string> *MapData){
202 /* int intResult = 0;
204 std::map<int,std::string>::iterator iwxsit;
206 for( iwxsit=(*MapData).begin(); iwxsit != (*MapData).end(); iwxsit++){
207 intResult = (*iwxsit).first;
215 bool frmContactEditor::GetSelectedItem(wxListCtrl *ListCtrlPtr,
217 int *intSelectedData){
220 *intSelectedData = 0;
222 *longSelected = ListCtrlPtr->GetNextItem(*longSelected,
224 wxLIST_STATE_SELECTED);
226 *intSelectedData = (int)ListCtrlPtr->GetItemData(*longSelected);
228 if (*longSelected == -1){
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){
255 int intIterVal = (*iterDataPtr)->first;
257 std::map<int,int>::iterator intIter;
259 intIter = MapData->find(intIterVal);
263 if (intIter->first == intIterVal){
265 intPropValue = intIter->second;
269 if (*boolAdditionalPtr == TRUE){
271 strPropertyPtr->Append(wxT(";"));
275 *boolAdditionalPtr = TRUE;
279 strPropertyPtr->Append(PropName + wxT("=") + wxString::Format(wxT("%i"), intPropValue));
281 *boolExtraPtr = TRUE;
289 void frmContactEditor::ProcessSaveDataProc( wxString PropName,
290 std::map<int,wxString>* MapData){
294 intIterVal = (*iterDataPtr)->first;
296 std::map<int,wxString>::iterator strIter;
298 strIter = MapData->find(intIterVal);
300 if (strIter == MapData->end()){
306 wxString strPropValue;
308 if (strIter->first == intIterVal){
310 strPropValue = strIter->second;
312 if (!strPropValue.IsEmpty() && PropName.IsEmpty()){
317 if (*boolAdditionalPtr == TRUE){
319 strPropertyPtr->Append(wxT(";"));
323 *boolAdditionalPtr = TRUE;
327 strPropertyPtr->Append(strPropValue);
329 *boolExtraPtr = TRUE;
335 if (!strPropValue.IsEmpty()){
340 if (*boolAdditionalPtr == TRUE){
342 strPropertyPtr->Append(wxT(";"));
346 *boolAdditionalPtr = TRUE;
350 // Look for semi-colon in property name and if there is then
353 if (PropName != wxT("TYPE")){
355 EscapeString(&strPropValue, FALSE);
359 if (strPropValue.find(wxT(";")) == wxNOT_FOUND && strPropValue.find(wxT(":")) == wxNOT_FOUND &&
360 strPropValue.find(wxT(",")) == wxNOT_FOUND){
362 strPropertyPtr->Append(PropName + wxT("=") + strPropValue);
366 strPropertyPtr->Append(PropName + wxT("=\"") + strPropValue + wxT("\""));
370 *boolExtraPtr = TRUE;
378 void frmContactEditor::ProcessSaveDataStrProc( wxString PropName,
379 std::map<int,std::string>* MapData){
381 int intIterVal = (*iterDataStringPtr)->first;
383 //std::map<int,wxString>::iterator strIter;
385 std::map<int,std::string>::iterator stdstrIter;
387 stdstrIter = MapData->find(intIterVal);
389 if (stdstrIter->first == intIterVal){
391 wxString strPropValue(stdstrIter->second.c_str(), wxConvUTF8);
393 if (!strPropValue.IsEmpty() && PropName.IsEmpty()){
398 if (*boolAdditionalPtr == TRUE){
400 strPropertyPtr->Append(wxT(";"));
404 *boolAdditionalPtr = TRUE;
408 strPropertyPtr->Append(strPropValue);
410 *boolExtraPtr = TRUE;
416 if (!strPropValue.IsEmpty()){
421 if (*boolAdditionalPtr == TRUE){
423 strPropertyPtr->Append(wxT(";"));
427 *boolAdditionalPtr = TRUE;
431 // Look for semi-colon in property name and if there is then
434 if (PropName != wxT("TYPE")){
436 EscapeString(&strPropValue, FALSE);
440 if (strPropValue.find(wxT(";")) == wxNOT_FOUND && strPropValue.find(wxT(":")) == wxNOT_FOUND &&
441 strPropValue.find(wxT(",")) == wxNOT_FOUND){
443 strPropertyPtr->Append(PropName + wxT("=") + strPropValue);
447 strPropertyPtr->Append(PropName + wxT("=\"") + strPropValue + wxT("\""));
451 *boolExtraPtr = TRUE;
460 void frmContactEditor::ProcessSaveDataStrProc( wxString PropName,
461 std::map<int,int>* MapData){
463 int intIterVal = (*iterDataStringPtr)->first;
465 std::map<int,int>::iterator intIter;
467 intIter = MapData->find(intIterVal);
471 if (intIter->first == intIterVal){
473 intPropValue = intIter->second;
477 if (*boolAdditionalPtr == TRUE){
479 strPropertyPtr->Append(wxT(";"));
483 *boolAdditionalPtr = TRUE;
487 strPropertyPtr->Append(PropName + wxT("=") + wxString::Format(wxT("%i"), intPropValue));
489 *boolExtraPtr = TRUE;
497 void frmContactEditor::ProcessSaveDataStrProc( wxString PropName,
498 std::map<int,wxString>* MapData){
502 intIterVal = (*iterDataStringPtr)->first;
504 std::map<int,wxString>::iterator strIter;
506 strIter = MapData->find(intIterVal);
508 if (strIter == MapData->end()){
510 // Ignore this section and return.
516 wxString strPropValue;
518 if (strIter->first == intIterVal){
520 strPropValue = strIter->second;
522 if (!strPropValue.IsEmpty() && PropName.IsEmpty()){
527 if (*boolAdditionalPtr == TRUE){
529 strPropertyPtr->Append(wxT(";"));
533 *boolAdditionalPtr = TRUE;
537 strPropertyPtr->Append(strPropValue);
539 *boolExtraPtr = TRUE;
545 if (!strPropValue.IsEmpty()){
550 if (*boolAdditionalPtr == TRUE){
552 strPropertyPtr->Append(wxT(";"));
556 *boolAdditionalPtr = TRUE;
560 // Look for semi-colon in property name and if there is then
563 if (PropName != wxT("TYPE")){
565 EscapeString(&strPropValue, FALSE);
569 if (strPropValue.find(wxT(";")) == wxNOT_FOUND && strPropValue.find(wxT(":")) == wxNOT_FOUND &&
570 strPropValue.find(wxT(",")) == wxNOT_FOUND){
572 strPropertyPtr->Append(PropName + wxT("=") + strPropValue);
576 strPropertyPtr->Append(PropName + wxT("=\"") + strPropValue + wxT("\""));
580 *boolExtraPtr = TRUE;
588 void frmContactEditor::ProcessCaptureStringsProc(wxString *strCapture){
590 CaptureString(strCapture, FALSE);
594 void frmContactEditor::ResetSaveProcessData(){
607 void frmContactEditor::SetupPointers(frmActivityMgr *ActMgr, wxETagProcessTimer *ETagProc,
608 frmMain *MainPtrInc){
611 ETagTmrPtr = ETagProc;
612 MainPtr = MainPtrInc;
616 void frmContactEditor::ContactFileChanged( wxCommandEvent &event ){
622 // Check if a dialog is already open.
624 if (DialogOpen == TRUE){
626 FMTimer.Start(1000, FALSE);
631 // Bring up a Yes/No modal dialog asking if the changed file should be reloaded.
633 int QuestionResponse;
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);
637 if (QuestionResponse == wxYES){
639 // Reload the contact.
640 wxString wxSReloadContactName = wxSContactFilename;
642 LoadContact(wxSReloadContactName);
646 // Do nothing other than update the timestamp so this message
647 // doesn't appear until the next time it changes.
649 FMTimer.UpdateTimestamp();
659 void frmContactEditor::UpdateMembersTab( wxCommandEvent &event ){
661 if (cmbType->GetCurrentSelection() == 2){
673 void frmContactEditor::SetUID(int UID){
675 ContactEditorUID = UID;
679 void frmContactEditor::SetMode(bool StartupEditModeIn){
681 StartupEditMode = StartupEditModeIn;