1 // frmContactEditor.cpp - Main frmContactEditor form section.
3 // (c) 2012-2015 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;
124 WData->WindowPointer = this;
125 WData->WindowID = ContactEditorUID;
127 wxCommandEvent delevent(WINDOW_CLOSE);
128 delevent.SetClientData(WData);
129 wxPostEvent(GetParent(), delevent);
135 void frmContactEditor::CutText( wxCommandEvent& event )
137 // This function left empty for future implementation.
140 void frmContactEditor::CopyText( wxCommandEvent& event )
142 // This function left empty for future implementation.
145 void frmContactEditor::PasteText( wxCommandEvent& event )
147 // This function left empty for future implementation.
150 void frmContactEditor::SetupContact( wxString AccountName )
153 wxSContactAccount = AccountName;
157 int frmContactEditor::GetLastInt(std::map<int, wxString> *MapData){
162 std::map<int,wxString>::iterator iwxsit;
164 for( iwxsit=(*MapData).begin(); iwxsit != (*MapData).end(); iwxsit++){
165 intResult = (*iwxsit).first;
176 int frmContactEditor::GetLastInt(std::map<int, std::string> *MapData){
178 /* int intResult = 0;
180 std::map<int,std::string>::iterator iwxsit;
182 for( iwxsit=(*MapData).begin(); iwxsit != (*MapData).end(); iwxsit++){
183 intResult = (*iwxsit).first;
191 bool frmContactEditor::GetSelectedItem(wxListCtrl *ListCtrlPtr,
193 int *intSelectedData){
196 *intSelectedData = 0;
198 *longSelected = ListCtrlPtr->GetNextItem(*longSelected,
200 wxLIST_STATE_SELECTED);
202 *intSelectedData = (int)ListCtrlPtr->GetItemData(*longSelected);
204 if (*longSelected == -1){
213 void frmContactEditor::DeleteMapDataProcess(int IndexNum, std::map<int, std::string>* MapData){
214 MapData->erase(IndexNum);
217 void frmContactEditor::DeleteMapDataProcess(int IndexNum, std::map<int, wxString>* MapData){
218 MapData->erase(IndexNum);
221 void frmContactEditor::DeleteMapDataProcess(int IndexNum, std::map<int, int>* MapData){
222 MapData->erase(IndexNum);
225 void frmContactEditor::DeleteMapDataProcess(int IndexNum, std::map<int, bool>* MapData){
226 MapData->erase(IndexNum);
229 void frmContactEditor::ProcessSaveDataProc( wxString PropName,
230 std::map<int,int>* MapData){
232 int intIterVal = (*iterDataPtr)->first;
234 std::map<int,int>::iterator intIter;
236 intIter = MapData->find(intIterVal);
240 if (intIter->first == intIterVal){
242 intPropValue = intIter->second;
246 if (*boolAdditionalPtr == TRUE){
248 strPropertyPtr->Append(wxT(";"));
252 *boolAdditionalPtr = TRUE;
256 strPropertyPtr->Append(PropName + wxT("=") + wxString::Format(wxT("%i"), intPropValue));
258 *boolExtraPtr = TRUE;
266 void frmContactEditor::ProcessSaveDataProc( wxString PropName,
267 std::map<int,wxString>* MapData){
271 intIterVal = (*iterDataPtr)->first;
273 std::map<int,wxString>::iterator strIter;
275 strIter = MapData->find(intIterVal);
277 if (strIter == MapData->end()){
283 wxString strPropValue;
285 if (strIter->first == intIterVal){
287 strPropValue = strIter->second;
289 if (!strPropValue.IsEmpty() && PropName.IsEmpty()){
294 if (*boolAdditionalPtr == TRUE){
296 strPropertyPtr->Append(wxT(";"));
300 *boolAdditionalPtr = TRUE;
304 strPropertyPtr->Append(strPropValue);
306 *boolExtraPtr = TRUE;
312 if (!strPropValue.IsEmpty()){
317 if (*boolAdditionalPtr == TRUE){
319 strPropertyPtr->Append(wxT(";"));
323 *boolAdditionalPtr = TRUE;
327 // Look for semi-colon in property name and if there is then
330 if (PropName != wxT("TYPE")){
332 EscapeString(&strPropValue, FALSE);
336 if (strPropValue.find(wxT(";")) == wxNOT_FOUND && strPropValue.find(wxT(":")) == wxNOT_FOUND &&
337 strPropValue.find(wxT(",")) == wxNOT_FOUND){
339 strPropertyPtr->Append(PropName + wxT("=") + strPropValue);
343 strPropertyPtr->Append(PropName + wxT("=\"") + strPropValue + wxT("\""));
347 *boolExtraPtr = TRUE;
355 void frmContactEditor::ProcessSaveDataStrProc( wxString PropName,
356 std::map<int,std::string>* MapData){
358 int intIterVal = (*iterDataStringPtr)->first;
360 //std::map<int,wxString>::iterator strIter;
362 std::map<int,std::string>::iterator stdstrIter;
364 stdstrIter = MapData->find(intIterVal);
366 if (stdstrIter->first == intIterVal){
368 wxString strPropValue(stdstrIter->second.c_str(), wxConvUTF8);
370 if (!strPropValue.IsEmpty() && PropName.IsEmpty()){
375 if (*boolAdditionalPtr == TRUE){
377 strPropertyPtr->Append(wxT(";"));
381 *boolAdditionalPtr = TRUE;
385 strPropertyPtr->Append(strPropValue);
387 *boolExtraPtr = TRUE;
393 if (!strPropValue.IsEmpty()){
398 if (*boolAdditionalPtr == TRUE){
400 strPropertyPtr->Append(wxT(";"));
404 *boolAdditionalPtr = TRUE;
408 // Look for semi-colon in property name and if there is then
411 if (PropName != wxT("TYPE")){
413 EscapeString(&strPropValue, FALSE);
417 if (strPropValue.find(wxT(";")) == wxNOT_FOUND && strPropValue.find(wxT(":")) == wxNOT_FOUND &&
418 strPropValue.find(wxT(",")) == wxNOT_FOUND){
420 strPropertyPtr->Append(PropName + wxT("=") + strPropValue);
424 strPropertyPtr->Append(PropName + wxT("=\"") + strPropValue + wxT("\""));
428 *boolExtraPtr = TRUE;
437 void frmContactEditor::ProcessSaveDataStrProc( wxString PropName,
438 std::map<int,int>* MapData){
440 int intIterVal = (*iterDataStringPtr)->first;
442 std::map<int,int>::iterator intIter;
444 intIter = MapData->find(intIterVal);
448 if (intIter->first == intIterVal){
450 intPropValue = intIter->second;
454 if (*boolAdditionalPtr == TRUE){
456 strPropertyPtr->Append(wxT(";"));
460 *boolAdditionalPtr = TRUE;
464 strPropertyPtr->Append(PropName + wxT("=") + wxString::Format(wxT("%i"), intPropValue));
466 *boolExtraPtr = TRUE;
474 void frmContactEditor::ProcessSaveDataStrProc( wxString PropName,
475 std::map<int,wxString>* MapData){
479 intIterVal = (*iterDataStringPtr)->first;
481 std::map<int,wxString>::iterator strIter;
483 strIter = MapData->find(intIterVal);
485 wxString strPropValue;
487 if (strIter->first == intIterVal){
489 strPropValue = strIter->second;
491 if (!strPropValue.IsEmpty() && PropName.IsEmpty()){
496 if (*boolAdditionalPtr == TRUE){
498 strPropertyPtr->Append(wxT(";"));
502 *boolAdditionalPtr = TRUE;
506 strPropertyPtr->Append(strPropValue);
508 *boolExtraPtr = TRUE;
514 if (!strPropValue.IsEmpty()){
519 if (*boolAdditionalPtr == TRUE){
521 strPropertyPtr->Append(wxT(";"));
525 *boolAdditionalPtr = TRUE;
529 // Look for semi-colon in property name and if there is then
532 if (PropName != wxT("TYPE")){
534 EscapeString(&strPropValue, FALSE);
538 if (strPropValue.find(wxT(";")) == wxNOT_FOUND && strPropValue.find(wxT(":")) == wxNOT_FOUND &&
539 strPropValue.find(wxT(",")) == wxNOT_FOUND){
541 strPropertyPtr->Append(PropName + wxT("=") + strPropValue);
545 strPropertyPtr->Append(PropName + wxT("=\"") + strPropValue + wxT("\""));
549 *boolExtraPtr = TRUE;
557 void frmContactEditor::ProcessCaptureStringsProc(wxString *strCapture){
559 CaptureString(strCapture, FALSE);
563 void frmContactEditor::ResetSaveProcessData(){
576 void frmContactEditor::SetupPointers(frmActivityMgr *ActMgr, wxETagProcessTimer *ETagProc,
577 frmMain *MainPtrInc){
580 ETagTmrPtr = ETagProc;
581 MainPtr = MainPtrInc;
585 void frmContactEditor::ContactFileChanged( wxCommandEvent &event ){
591 // Check if a dialog is already open.
593 if (DialogOpen == TRUE){
595 FMTimer.Start(1000, FALSE);
600 // Bring up a Yes/No modal dialog asking if the changed file should be reloaded.
602 int QuestionResponse;
604 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);
606 if (QuestionResponse == wxYES){
608 // Reload the contact.
609 wxString wxSReloadContactName = wxSContactFilename;
611 LoadContact(wxSReloadContactName);
615 // Do nothing other than update the timestamp so this message
616 // doesn't appear until the next time it changes.
618 FMTimer.UpdateTimestamp();
628 void frmContactEditor::UpdateMembersTab( wxCommandEvent &event ){
630 if (cmbType->GetCurrentSelection() == 2){
642 void frmContactEditor::SetUID(int UID){
644 ContactEditorUID = UID;
648 void frmContactEditor::SetMode(bool StartupEditModeIn){
650 StartupEditMode = StartupEditModeIn;