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 void frmContactEditor::CloseContact( wxCommandEvent& event )
115 void frmContactEditor::CloseWindow( wxCloseEvent& event )
118 // TODO: Check if any changes have been made,
119 // ask if the changes should be made, process
120 // action based on question and then close.
122 WindowData *WData = new WindowData;
124 if (StartupEditMode == FALSE){
127 WData->WindowPointer = this;
128 WData->WindowID = ContactEditorUID;
130 wxCommandEvent delevent(WINDOW_CLOSE);
131 delevent.SetClientData(WData);
132 wxPostEvent(GetParent(), delevent);
140 void frmContactEditor::CutText( wxCommandEvent& event )
142 // This function left empty for future implementation.
145 void frmContactEditor::CopyText( wxCommandEvent& event )
147 // This function left empty for future implementation.
150 void frmContactEditor::PasteText( wxCommandEvent& event )
152 // This function left empty for future implementation.
155 void frmContactEditor::SetupContact( wxString AccountName )
158 wxSContactAccount = AccountName;
162 void frmContactEditor::SetupAccountData(bool UnsupportedAccount){
164 boolUnsupportedAccount = UnsupportedAccount;
168 int frmContactEditor::GetLastInt(std::map<int, wxString> *MapData){
173 std::map<int,wxString>::iterator iwxsit;
175 for( iwxsit=(*MapData).begin(); iwxsit != (*MapData).end(); iwxsit++){
176 intResult = (*iwxsit).first;
187 int frmContactEditor::GetLastInt(std::map<int, std::string> *MapData){
189 /* int intResult = 0;
191 std::map<int,std::string>::iterator iwxsit;
193 for( iwxsit=(*MapData).begin(); iwxsit != (*MapData).end(); iwxsit++){
194 intResult = (*iwxsit).first;
202 bool frmContactEditor::GetSelectedItem(wxListCtrl *ListCtrlPtr,
204 int *intSelectedData){
207 *intSelectedData = 0;
209 *longSelected = ListCtrlPtr->GetNextItem(*longSelected,
211 wxLIST_STATE_SELECTED);
213 *intSelectedData = (int)ListCtrlPtr->GetItemData(*longSelected);
215 if (*longSelected == -1){
223 void frmContactEditor::DeleteMapDataProcess(int IndexNum, std::map<int, std::string>* MapData){
224 MapData->erase(IndexNum);
227 void frmContactEditor::DeleteMapDataProcess(int IndexNum, std::map<int, wxString>* MapData){
228 MapData->erase(IndexNum);
231 void frmContactEditor::DeleteMapDataProcess(int IndexNum, std::map<int, int>* MapData){
232 MapData->erase(IndexNum);
235 void frmContactEditor::DeleteMapDataProcess(int IndexNum, std::map<int, bool>* MapData){
236 MapData->erase(IndexNum);
239 void frmContactEditor::ProcessSaveDataProc( wxString PropName,
240 std::map<int,int>* MapData){
242 int intIterVal = (*iterDataPtr)->first;
244 std::map<int,int>::iterator intIter;
246 intIter = MapData->find(intIterVal);
250 if (intIter->first == intIterVal){
252 intPropValue = intIter->second;
256 if (*boolAdditionalPtr == TRUE){
258 strPropertyPtr->Append(wxT(";"));
262 *boolAdditionalPtr = TRUE;
266 strPropertyPtr->Append(PropName + wxT("=") + wxString::Format(wxT("%i"), intPropValue));
268 *boolExtraPtr = TRUE;
276 void frmContactEditor::ProcessSaveDataProc( wxString PropName,
277 std::map<int,wxString>* MapData){
281 intIterVal = (*iterDataPtr)->first;
283 std::map<int,wxString>::iterator strIter;
285 strIter = MapData->find(intIterVal);
287 if (strIter == MapData->end()){
293 wxString strPropValue;
295 if (strIter->first == intIterVal){
297 strPropValue = strIter->second;
299 if (!strPropValue.IsEmpty() && PropName.IsEmpty()){
304 if (*boolAdditionalPtr == TRUE){
306 strPropertyPtr->Append(wxT(";"));
310 *boolAdditionalPtr = TRUE;
314 strPropertyPtr->Append(strPropValue);
316 *boolExtraPtr = TRUE;
322 if (!strPropValue.IsEmpty()){
327 if (*boolAdditionalPtr == TRUE){
329 strPropertyPtr->Append(wxT(";"));
333 *boolAdditionalPtr = TRUE;
337 // Look for semi-colon in property name and if there is then
340 if (PropName != wxT("TYPE")){
342 EscapeString(&strPropValue, FALSE);
346 if (strPropValue.find(wxT(";")) == wxNOT_FOUND && strPropValue.find(wxT(":")) == wxNOT_FOUND &&
347 strPropValue.find(wxT(",")) == wxNOT_FOUND){
349 strPropertyPtr->Append(PropName + wxT("=") + strPropValue);
353 strPropertyPtr->Append(PropName + wxT("=\"") + strPropValue + wxT("\""));
357 *boolExtraPtr = TRUE;
365 void frmContactEditor::ProcessSaveDataStrProc( wxString PropName,
366 std::map<int,std::string>* MapData){
368 int intIterVal = (*iterDataStringPtr)->first;
370 //std::map<int,wxString>::iterator strIter;
372 std::map<int,std::string>::iterator stdstrIter;
374 stdstrIter = MapData->find(intIterVal);
376 if (stdstrIter->first == intIterVal){
378 wxString strPropValue(stdstrIter->second.c_str(), wxConvUTF8);
380 if (!strPropValue.IsEmpty() && PropName.IsEmpty()){
385 if (*boolAdditionalPtr == TRUE){
387 strPropertyPtr->Append(wxT(";"));
391 *boolAdditionalPtr = TRUE;
395 strPropertyPtr->Append(strPropValue);
397 *boolExtraPtr = TRUE;
403 if (!strPropValue.IsEmpty()){
408 if (*boolAdditionalPtr == TRUE){
410 strPropertyPtr->Append(wxT(";"));
414 *boolAdditionalPtr = TRUE;
418 // Look for semi-colon in property name and if there is then
421 if (PropName != wxT("TYPE")){
423 EscapeString(&strPropValue, FALSE);
427 if (strPropValue.find(wxT(";")) == wxNOT_FOUND && strPropValue.find(wxT(":")) == wxNOT_FOUND &&
428 strPropValue.find(wxT(",")) == wxNOT_FOUND){
430 strPropertyPtr->Append(PropName + wxT("=") + strPropValue);
434 strPropertyPtr->Append(PropName + wxT("=\"") + strPropValue + wxT("\""));
438 *boolExtraPtr = TRUE;
447 void frmContactEditor::ProcessSaveDataStrProc( wxString PropName,
448 std::map<int,int>* MapData){
450 int intIterVal = (*iterDataStringPtr)->first;
452 std::map<int,int>::iterator intIter;
454 intIter = MapData->find(intIterVal);
458 if (intIter->first == intIterVal){
460 intPropValue = intIter->second;
464 if (*boolAdditionalPtr == TRUE){
466 strPropertyPtr->Append(wxT(";"));
470 *boolAdditionalPtr = TRUE;
474 strPropertyPtr->Append(PropName + wxT("=") + wxString::Format(wxT("%i"), intPropValue));
476 *boolExtraPtr = TRUE;
484 void frmContactEditor::ProcessSaveDataStrProc( wxString PropName,
485 std::map<int,wxString>* MapData){
489 intIterVal = (*iterDataStringPtr)->first;
491 std::map<int,wxString>::iterator strIter;
493 strIter = MapData->find(intIterVal);
495 if (strIter == MapData->end()){
497 // Ignore this section and return.
503 wxString strPropValue;
505 if (strIter->first == intIterVal){
507 strPropValue = strIter->second;
509 if (!strPropValue.IsEmpty() && PropName.IsEmpty()){
514 if (*boolAdditionalPtr == TRUE){
516 strPropertyPtr->Append(wxT(";"));
520 *boolAdditionalPtr = TRUE;
524 strPropertyPtr->Append(strPropValue);
526 *boolExtraPtr = TRUE;
532 if (!strPropValue.IsEmpty()){
537 if (*boolAdditionalPtr == TRUE){
539 strPropertyPtr->Append(wxT(";"));
543 *boolAdditionalPtr = TRUE;
547 // Look for semi-colon in property name and if there is then
550 if (PropName != wxT("TYPE")){
552 EscapeString(&strPropValue, FALSE);
556 if (strPropValue.find(wxT(";")) == wxNOT_FOUND && strPropValue.find(wxT(":")) == wxNOT_FOUND &&
557 strPropValue.find(wxT(",")) == wxNOT_FOUND){
559 strPropertyPtr->Append(PropName + wxT("=") + strPropValue);
563 strPropertyPtr->Append(PropName + wxT("=\"") + strPropValue + wxT("\""));
567 *boolExtraPtr = TRUE;
575 void frmContactEditor::ProcessCaptureStringsProc(wxString *strCapture){
577 CaptureString(strCapture, FALSE);
581 void frmContactEditor::ResetSaveProcessData(){
594 void frmContactEditor::SetupPointers(frmActivityMgr *ActMgr, wxETagProcessTimer *ETagProc,
595 frmMain *MainPtrInc){
598 ETagTmrPtr = ETagProc;
599 MainPtr = MainPtrInc;
603 void frmContactEditor::ContactFileChanged( wxCommandEvent &event ){
609 // Check if a dialog is already open.
611 if (DialogOpen == TRUE){
613 FMTimer.Start(1000, FALSE);
618 // Bring up a Yes/No modal dialog asking if the changed file should be reloaded.
620 int QuestionResponse;
622 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);
624 if (QuestionResponse == wxYES){
626 // Reload the contact.
627 wxString wxSReloadContactName = wxSContactFilename;
629 LoadContact(wxSReloadContactName);
633 // Do nothing other than update the timestamp so this message
634 // doesn't appear until the next time it changes.
636 FMTimer.UpdateTimestamp();
646 void frmContactEditor::UpdateMembersTab( wxCommandEvent &event ){
648 if (cmbType->GetCurrentSelection() == 2){
660 void frmContactEditor::SetUID(int UID){
662 ContactEditorUID = UID;
666 void frmContactEditor::SetMode(bool StartupEditModeIn){
668 StartupEditMode = StartupEditModeIn;