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 )
81 boolContactModified = FALSE;
83 dapAnniversary->SetValue(NoDate);
84 dapBirthday->SetValue(NoDate);
89 wxMemoryInputStream istream(buttons_play_png, sizeof(buttons_play_png));
90 wxImage button_play_pngi(istream, wxBITMAP_TYPE_PNG);
91 wxBitmap playiconbmp(button_play_pngi, -1);
92 btnPlay->SetBitmapLabel(playiconbmp);
94 wxMemoryInputStream istream2(buttons_stop_png, sizeof(buttons_stop_png));
95 wxImage button_stop_pngi(istream2, wxBITMAP_TYPE_PNG);
96 wxBitmap stopiconbmp(button_stop_pngi, -1);
97 btnStop->SetBitmapLabel(stopiconbmp);
99 FMTimer.SetupPointers(this);
100 //wxIcon contacticon;
101 //contacticon.CopyFromBitmap(contacticonbmp);
103 nbkContact->SetSelection(0);
107 void frmContactEditor::CloseContact( wxCommandEvent& event )
114 void frmContactEditor::CloseWindow( wxCloseEvent& event )
117 // TODO: Check if any changes have been made,
118 // ask if the changes should be made, process
119 // action based on question and then close.
121 WindowData *WData = new WindowData;
123 if (StartupEditMode == FALSE){
126 WData->WindowPointer = this;
127 WData->WindowID = ContactEditorUID;
129 wxCommandEvent delevent(WINDOW_CLOSE);
130 delevent.SetClientData(WData);
131 wxPostEvent(GetParent(), delevent);
139 void frmContactEditor::CutText( wxCommandEvent& event )
141 // This function left empty for future implementation.
144 void frmContactEditor::CopyText( wxCommandEvent& event )
146 // This function left empty for future implementation.
149 void frmContactEditor::PasteText( wxCommandEvent& event )
151 // This function left empty for future implementation.
154 void frmContactEditor::SetupContact( wxString AccountName )
157 wxSContactAccount = AccountName;
161 int frmContactEditor::GetLastInt(std::map<int, wxString> *MapData){
166 std::map<int,wxString>::iterator iwxsit;
168 for( iwxsit=(*MapData).begin(); iwxsit != (*MapData).end(); iwxsit++){
169 intResult = (*iwxsit).first;
180 int frmContactEditor::GetLastInt(std::map<int, std::string> *MapData){
182 /* int intResult = 0;
184 std::map<int,std::string>::iterator iwxsit;
186 for( iwxsit=(*MapData).begin(); iwxsit != (*MapData).end(); iwxsit++){
187 intResult = (*iwxsit).first;
195 bool frmContactEditor::GetSelectedItem(wxListCtrl *ListCtrlPtr,
197 int *intSelectedData){
200 *intSelectedData = 0;
202 *longSelected = ListCtrlPtr->GetNextItem(*longSelected,
204 wxLIST_STATE_SELECTED);
206 *intSelectedData = (int)ListCtrlPtr->GetItemData(*longSelected);
208 if (*longSelected == -1){
217 void frmContactEditor::DeleteMapDataProcess(int IndexNum, std::map<int, std::string>* MapData){
218 MapData->erase(IndexNum);
221 void frmContactEditor::DeleteMapDataProcess(int IndexNum, std::map<int, wxString>* MapData){
222 MapData->erase(IndexNum);
225 void frmContactEditor::DeleteMapDataProcess(int IndexNum, std::map<int, int>* MapData){
226 MapData->erase(IndexNum);
229 void frmContactEditor::DeleteMapDataProcess(int IndexNum, std::map<int, bool>* MapData){
230 MapData->erase(IndexNum);
233 void frmContactEditor::ProcessSaveDataProc( wxString PropName,
234 std::map<int,int>* MapData){
236 int intIterVal = (*iterDataPtr)->first;
238 std::map<int,int>::iterator intIter;
240 intIter = MapData->find(intIterVal);
244 if (intIter->first == intIterVal){
246 intPropValue = intIter->second;
250 if (*boolAdditionalPtr == TRUE){
252 strPropertyPtr->Append(wxT(";"));
256 *boolAdditionalPtr = TRUE;
260 strPropertyPtr->Append(PropName + wxT("=") + wxString::Format(wxT("%i"), intPropValue));
262 *boolExtraPtr = TRUE;
270 void frmContactEditor::ProcessSaveDataProc( wxString PropName,
271 std::map<int,wxString>* MapData){
275 intIterVal = (*iterDataPtr)->first;
277 std::map<int,wxString>::iterator strIter;
279 strIter = MapData->find(intIterVal);
281 if (strIter == MapData->end()){
287 wxString strPropValue;
289 if (strIter->first == intIterVal){
291 strPropValue = strIter->second;
293 if (!strPropValue.IsEmpty() && PropName.IsEmpty()){
298 if (*boolAdditionalPtr == TRUE){
300 strPropertyPtr->Append(wxT(";"));
304 *boolAdditionalPtr = TRUE;
308 strPropertyPtr->Append(strPropValue);
310 *boolExtraPtr = TRUE;
316 if (!strPropValue.IsEmpty()){
321 if (*boolAdditionalPtr == TRUE){
323 strPropertyPtr->Append(wxT(";"));
327 *boolAdditionalPtr = TRUE;
331 // Look for semi-colon in property name and if there is then
334 if (PropName != wxT("TYPE")){
336 EscapeString(&strPropValue, FALSE);
340 if (strPropValue.find(wxT(";")) == wxNOT_FOUND && strPropValue.find(wxT(":")) == wxNOT_FOUND &&
341 strPropValue.find(wxT(",")) == wxNOT_FOUND){
343 strPropertyPtr->Append(PropName + wxT("=") + strPropValue);
347 strPropertyPtr->Append(PropName + wxT("=\"") + strPropValue + wxT("\""));
351 *boolExtraPtr = TRUE;
359 void frmContactEditor::ProcessSaveDataStrProc( wxString PropName,
360 std::map<int,std::string>* MapData){
362 int intIterVal = (*iterDataStringPtr)->first;
364 //std::map<int,wxString>::iterator strIter;
366 std::map<int,std::string>::iterator stdstrIter;
368 stdstrIter = MapData->find(intIterVal);
370 if (stdstrIter->first == intIterVal){
372 wxString strPropValue(stdstrIter->second.c_str(), wxConvUTF8);
374 if (!strPropValue.IsEmpty() && PropName.IsEmpty()){
379 if (*boolAdditionalPtr == TRUE){
381 strPropertyPtr->Append(wxT(";"));
385 *boolAdditionalPtr = TRUE;
389 strPropertyPtr->Append(strPropValue);
391 *boolExtraPtr = TRUE;
397 if (!strPropValue.IsEmpty()){
402 if (*boolAdditionalPtr == TRUE){
404 strPropertyPtr->Append(wxT(";"));
408 *boolAdditionalPtr = TRUE;
412 // Look for semi-colon in property name and if there is then
415 if (PropName != wxT("TYPE")){
417 EscapeString(&strPropValue, FALSE);
421 if (strPropValue.find(wxT(";")) == wxNOT_FOUND && strPropValue.find(wxT(":")) == wxNOT_FOUND &&
422 strPropValue.find(wxT(",")) == wxNOT_FOUND){
424 strPropertyPtr->Append(PropName + wxT("=") + strPropValue);
428 strPropertyPtr->Append(PropName + wxT("=\"") + strPropValue + wxT("\""));
432 *boolExtraPtr = TRUE;
441 void frmContactEditor::ProcessSaveDataStrProc( wxString PropName,
442 std::map<int,int>* MapData){
444 int intIterVal = (*iterDataStringPtr)->first;
446 std::map<int,int>::iterator intIter;
448 intIter = MapData->find(intIterVal);
452 if (intIter->first == intIterVal){
454 intPropValue = intIter->second;
458 if (*boolAdditionalPtr == TRUE){
460 strPropertyPtr->Append(wxT(";"));
464 *boolAdditionalPtr = TRUE;
468 strPropertyPtr->Append(PropName + wxT("=") + wxString::Format(wxT("%i"), intPropValue));
470 *boolExtraPtr = TRUE;
478 void frmContactEditor::ProcessSaveDataStrProc( wxString PropName,
479 std::map<int,wxString>* MapData){
483 intIterVal = (*iterDataStringPtr)->first;
485 std::map<int,wxString>::iterator strIter;
487 strIter = MapData->find(intIterVal);
489 wxString strPropValue;
491 if (strIter->first == intIterVal){
493 strPropValue = strIter->second;
495 if (!strPropValue.IsEmpty() && PropName.IsEmpty()){
500 if (*boolAdditionalPtr == TRUE){
502 strPropertyPtr->Append(wxT(";"));
506 *boolAdditionalPtr = TRUE;
510 strPropertyPtr->Append(strPropValue);
512 *boolExtraPtr = TRUE;
518 if (!strPropValue.IsEmpty()){
523 if (*boolAdditionalPtr == TRUE){
525 strPropertyPtr->Append(wxT(";"));
529 *boolAdditionalPtr = TRUE;
533 // Look for semi-colon in property name and if there is then
536 if (PropName != wxT("TYPE")){
538 EscapeString(&strPropValue, FALSE);
542 if (strPropValue.find(wxT(";")) == wxNOT_FOUND && strPropValue.find(wxT(":")) == wxNOT_FOUND &&
543 strPropValue.find(wxT(",")) == wxNOT_FOUND){
545 strPropertyPtr->Append(PropName + wxT("=") + strPropValue);
549 strPropertyPtr->Append(PropName + wxT("=\"") + strPropValue + wxT("\""));
553 *boolExtraPtr = TRUE;
561 void frmContactEditor::ProcessCaptureStringsProc(wxString *strCapture){
563 CaptureString(strCapture, FALSE);
567 void frmContactEditor::ResetSaveProcessData(){
580 void frmContactEditor::SetupPointers(frmActivityMgr *ActMgr, wxETagProcessTimer *ETagProc,
581 frmMain *MainPtrInc){
584 ETagTmrPtr = ETagProc;
585 MainPtr = MainPtrInc;
589 void frmContactEditor::ContactFileChanged( wxCommandEvent &event ){
595 // Check if a dialog is already open.
597 if (DialogOpen == TRUE){
599 FMTimer.Start(1000, FALSE);
604 // Bring up a Yes/No modal dialog asking if the changed file should be reloaded.
606 int QuestionResponse;
608 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);
610 if (QuestionResponse == wxYES){
612 // Reload the contact.
613 wxString wxSReloadContactName = wxSContactFilename;
615 LoadContact(wxSReloadContactName);
619 // Do nothing other than update the timestamp so this message
620 // doesn't appear until the next time it changes.
622 FMTimer.UpdateTimestamp();
632 void frmContactEditor::UpdateMembersTab( wxCommandEvent &event ){
634 if (cmbType->GetCurrentSelection() == 2){
646 void frmContactEditor::SetUID(int UID){
648 ContactEditorUID = UID;
652 void frmContactEditor::SetMode(bool StartupEditModeIn){
654 StartupEditMode = StartupEditModeIn;