1 // frmMain.cpp - Main window form.
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/>
25 #include <wx/tokenzr.h>
27 #include <wx/mstream.h>
28 #include <wx/fs_mem.h>
30 #include <wx/filesys.h>
32 #include <wx/stdpaths.h>
33 #include <wx/fileconf.h>
34 #include <wx/gdicmn.h>
40 #include "frmPreferences.h"
41 #include "frmNewAccount.h"
42 #include "actmgr/frmActivityMgr.h"
43 #include "frmContact.h"
44 #include "frmConflictResolution.h"
45 #include "frmInvalidSSLCertificate.h"
46 #include "search/frmSearch.h"
47 #include "frmSSLCertificate.h"
48 #include "frmUpdate.h"
49 #include "import/frmImportResults.h"
52 #include "common/preferences.h"
53 #include "common/getcontactinfo.h"
54 #include "common/events.h"
55 #include "common/dirs.h"
56 #include "vcard/vcard.h"
57 #include "carddav/carddav.h"
58 #include "contacteditor/frmContactEditor.h"
59 #include "import/import.h"
60 #include "export/export.h"
61 #include "widgets/XABContactMenu.h"
62 #include "widgets/XABAccountView.h"
66 // Define the event types.
68 DEFINE_EVENT_TYPE(CE_UPDATECONTACTLIST);
69 DEFINE_EVENT_TYPE(CE_UPDATEACCOUNTLIST);
70 DEFINE_EVENT_TYPE(SE_UPDATECONTACTNOTIF);
71 DEFINE_EVENT_TYPE(CE_OPENCONTACT);
72 DEFINE_EVENT_TYPE(CE_OPENCONTACTLIST);
73 DEFINE_EVENT_TYPE(CE_NEWCONTACT);
74 DEFINE_EVENT_TYPE(CE_EDITCONTACT);
75 DEFINE_EVENT_TYPE(CE_DELETECONTACT);
76 DEFINE_EVENT_TYPE(CE_REVEALCONTACT);
77 DEFINE_EVENT_TYPE(CE_REMOVECONTACT);
78 DEFINE_EVENT_TYPE(CE_REMOVESEARCH);
79 DEFINE_EVENT_TYPE(SYNC_EMPTYSERVER);
80 DEFINE_EVENT_TYPE(ACTMGR_START);
81 DEFINE_EVENT_TYPE(ACTMGR_SHUFFLE);
82 DEFINE_EVENT_TYPE(ACTMGR_STOP);
83 DEFINE_EVENT_TYPE(WINDOW_ADD);
84 DEFINE_EVENT_TYPE(WINDOW_EDIT);
85 DEFINE_EVENT_TYPE(WINDOW_CLOSE);
86 DEFINE_EVENT_TYPE(CONNSTAT_UPDATE);
87 DEFINE_EVENT_TYPE(INVALIDSSLCERT);
88 DEFINE_EVENT_TYPE(INVALIDSSLCERTSTRING);
89 DEFINE_EVENT_TYPE(GETSELECTEDLIST);
90 DEFINE_EVENT_TYPE(SYNCACCOUNT);
91 DEFINE_EVENT_TYPE(IMPORT_RESULTSSHOW);
92 DEFINE_EVENT_TYPE(RELOADCONTACTLIST);
93 DEFINE_EVENT_TYPE(REFRESHADDRESSBOOK);
94 #if defined(__APPLE__)
95 DEFINE_EVENT_TYPE(INVALIDSSLTRUST);
98 // Setup the event table using the event types.
100 BEGIN_EVENT_TABLE(frmMain, wxFrame)
101 EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, frmMain::ConflictResolution)
102 EVT_COMMAND(wxID_ANY, CE_UPDATECONTACTLIST, frmMain::UpdateContactList)
103 EVT_COMMAND(wxID_ANY, CE_UPDATEACCOUNTLIST, frmMain::UpdateAccountList)
104 EVT_COMMAND(wxID_ANY, SE_UPDATECONTACTNOTIF, frmMain::UpdateSearchContactLists)
105 EVT_COMMAND(wxID_ANY, CE_OPENCONTACT, frmMain::OpenContactInfo)
106 EVT_COMMAND(wxID_ANY, CE_OPENCONTACTLIST, frmMain::OpenContactInfoList)
107 EVT_COMMAND(wxID_ANY, CE_NEWCONTACT, frmMain::ShowContactEditorNew)
108 EVT_COMMAND(wxID_ANY, CE_EDITCONTACT, frmMain::ShowContactEditorEdit)
109 EVT_COMMAND(wxID_ANY, CE_DELETECONTACT, frmMain::DeleteContact)
110 EVT_COMMAND(wxID_ANY, CE_REVEALCONTACT, frmMain::RevealContact)
111 EVT_COMMAND(wxID_ANY, CE_REMOVESEARCH, frmMain::RemoveContactsWindowPointer)
112 EVT_COMMAND(wxID_ANY, SYNC_EMPTYSERVER, frmMain::EmptyServerDialog)
113 EVT_COMMAND(wxID_ANY, ACTMGR_START, frmMain::ActivityIconStart)
114 EVT_COMMAND(wxID_ANY, ACTMGR_SHUFFLE, frmMain::ActivityIconShuffle)
115 EVT_COMMAND(wxID_ANY, ACTMGR_STOP, frmMain::ActivityIconStop)
116 EVT_COMMAND(wxID_ANY, WINDOW_ADD, frmMain::WindowAdd)
117 EVT_COMMAND(wxID_ANY, WINDOW_EDIT, frmMain::WindowEdit)
118 EVT_COMMAND(wxID_ANY, WINDOW_CLOSE, frmMain::WindowDelete)
119 EVT_COMMAND(wxID_ANY, CONNSTAT_UPDATE, frmMain::UpdateConnectionStatus)
120 EVT_COMMAND(wxID_ANY, INVALIDSSLCERT, frmMain::InvalidSSLCertificate)
121 EVT_COMMAND(wxID_ANY, INVALIDSSLCERTSTRING, frmMain::InvalidSSLCertificateString)
122 EVT_COMMAND(wxID_ANY, GETSELECTEDLIST, frmMain::GetSelectedList)
123 EVT_COMMAND(wxID_ANY, SYNCACCOUNT, frmMain::SyncAccount)
124 EVT_COMMAND(wxID_ANY, IMPORT_RESULTSSHOW, frmMain::ShowImportResults)
125 EVT_COMMAND(wxID_ANY, RELOADCONTACTLIST, frmMain::ReloadContactList)
126 EVT_COMMAND(wxID_ANY, REFRESHADDRESSBOOK, frmMain::RefreshAddressBook)
127 #if defined(__APPLE__)
128 EVT_COMMAND(wxID_ANY, INVALIDSSLTRUST, frmMain::DisplayTrustPanel)
132 frmMain::frmMain( wxWindow* parent )
137 // Setup the account icons.
139 wxMemoryInputStream astream(icons_accinet_png, sizeof(icons_accinet_png));
140 wxMemoryInputStream bstream(icons_acclocal_png, sizeof(icons_acclocal_png));
141 wxMemoryInputStream cstream(icons_accgroup_png, sizeof(icons_accgroup_png));
142 wxMemoryInputStream dstream(icons_accnone_png, sizeof(icons_accnone_png));
143 wxMemoryInputStream estream(icons_accunsupported_png, sizeof(icons_accunsupported_png));
145 wxImage icons_accinet_png(astream, wxBITMAP_TYPE_PNG);
146 wxBitmap AccInet(icons_accinet_png, -1);
148 wxIAccInet.CopyFromBitmap(AccInet);
150 wxImage icons_acclocal_png(bstream, wxBITMAP_TYPE_PNG);
151 wxBitmap AccNIcon(icons_acclocal_png, -1);
153 wxIAccNIcon.CopyFromBitmap(AccNIcon);
155 wxImage icons_accgroup_png(cstream, wxBITMAP_TYPE_PNG);
156 wxBitmap AccGrp(icons_accgroup_png, -1);
158 wxIAccGrp.CopyFromBitmap(AccGrp);
160 wxImage icons_accnone_png(dstream, wxBITMAP_TYPE_PNG);
161 wxBitmap AccNone(icons_accnone_png, -1);
163 wxIAccNone.CopyFromBitmap(AccNone);
165 wxImage icons_accunsupported_png(estream, wxBITMAP_TYPE_PNG);
166 wxBitmap AccUnsupported(icons_accunsupported_png, -1);
167 wxIcon wxIAccUnsupported;
168 wxIAccUnsupported.CopyFromBitmap(AccUnsupported);
170 AccountID = AccImgList->Add(wxIAccNIcon);
171 AccountNetID = AccImgList->Add(wxIAccInet);
172 AccountGrpID = AccImgList->Add(wxIAccGrp);
173 AccountNoneID = AccImgList->Add(wxIAccNone);
174 AccountUnsupportedID = AccImgList->Add(wxIAccUnsupported);
176 bmpIcon->SetIcon(AccImgList->GetIcon(AccountNoneID));
178 // Setup the status bar icons.
182 wxMemoryInputStream sslstream(icons_ssl_png, sizeof(icons_ssl_png));
183 wxMemoryInputStream sslwarningstream(icons_sslwarning_png, sizeof(icons_sslwarning_png));
184 wxMemoryInputStream nosslstream(icons_nossl_png, sizeof(icons_nossl_png));
186 wxImage icons_ssl_png(sslstream, wxBITMAP_TYPE_PNG);
187 imgSSL = new wxBitmap(icons_ssl_png, -1);
189 wxImage icons_sslwarning_png(sslwarningstream, wxBITMAP_TYPE_PNG);
190 imgSSLWarning = new wxBitmap(icons_sslwarning_png, -1);
192 wxImage icons_nossl_png(nosslstream, wxBITMAP_TYPE_PNG);
193 imgNoSSL = new wxBitmap(icons_nossl_png, -1);
197 wxMemoryInputStream act1(icons_act1_png, sizeof(icons_act1_png));
198 wxMemoryInputStream act2(icons_act2_png, sizeof(icons_act2_png));
199 wxMemoryInputStream act3(icons_act3_png, sizeof(icons_act3_png));
200 wxMemoryInputStream act4(icons_act4_png, sizeof(icons_act4_png));
201 wxMemoryInputStream actsleep(icons_actsleep_png, sizeof(icons_actsleep_png));
203 wxImage icons_actsleep_png(actsleep, wxBITMAP_TYPE_PNG);
204 imgActIconSleep = new wxBitmap (icons_actsleep_png, -1);
206 wxImage icons_act1_png(act1, wxBITMAP_TYPE_PNG);
207 imgActIcon1 = new wxBitmap (icons_act1_png, -1);
209 wxIAct1icon.CopyFromBitmap(*imgActIcon1);
211 wxImage icons_act2_png(act2, wxBITMAP_TYPE_PNG);
212 imgActIcon2 = new wxBitmap (icons_act2_png, -1);
214 wxIAct2icon.CopyFromBitmap(*imgActIcon2);
216 wxImage icons_act3_png(act3, wxBITMAP_TYPE_PNG);
217 imgActIcon3 = new wxBitmap (icons_act3_png, -1);
219 wxIAct3icon.CopyFromBitmap(*imgActIcon3);
221 wxImage icons_act4_png(act4, wxBITMAP_TYPE_PNG);
222 imgActIcon4 = new wxBitmap (icons_act4_png, -1);
224 wxIAct4icon.CopyFromBitmap(*imgActIcon4);
226 // Online/Offline icons.
228 wxMemoryInputStream onlinestream(icons_online_png, sizeof(icons_online_png));
229 wxMemoryInputStream offlinestream(icons_offline_png, sizeof(icons_offline_png));
231 wxImage icons_online_png(onlinestream, wxBITMAP_TYPE_PNG);
232 imgOnline = new wxBitmap(icons_online_png, -1);
234 wxImage icons_offline_png(offlinestream, wxBITMAP_TYPE_PNG);
235 imgOffline = new wxBitmap(icons_offline_png, -1);
237 // Setup the account view.
239 AccCtrl->SetPopupControl(treAccounts);
240 AccCtrl->SetPopupMaxHeight(175);
241 AccCtrl->SetPopupMinWidth(250);
242 treAccounts->AssignImageList(AccImgList);
244 wxListItem ColumnData;
246 ColumnData.SetText(wxT("Name0"));
247 ColumnData.SetWidth(320);
248 lstContacts->InsertColumn(0, ColumnData);
250 treAccounts->Connect(wxEVT_LEFT_DCLICK, wxTreeEventHandler(frmMain::LoadContactList), NULL, this);
251 treAccounts->Connect(wxEVT_TREE_SEL_CHANGED, wxTreeEventHandler(frmMain::LoadContactList), NULL, this);
253 #if defined(__HAIKU__)
255 #elif defined(__WIN32__)
257 int stbBottomData [4] = { -1, 8, 8, 8 };
261 int stbBottomData [4] = { -1, 20, 20, 20 };
265 stbBottom->SetFieldsCount(4, stbBottomData);
266 stbBottom->SetMinHeight(16);
271 stbBottom->GetFieldRect(1, rectOnline);
272 stbBottom->GetFieldRect(2, rectSSL);
273 stbBottom->GetFieldRect(3, rectActivity);
275 SSLToolTip = new wxToolTip(wxT(""));
277 imgConnStatus = new wxStaticBitmap(stbBottom, wxID_ANY, wxNullBitmap, wxPoint((rectOnline.GetX()),(rectOnline.GetY())), wxDefaultSize, 0 );
278 imgConnStatus->SetBitmap(*imgOnline);
279 imgConnStatus->Connect( wxEVT_LEFT_DCLICK, wxCommandEventHandler( frmMain::ToggleConnectionStatus ), NULL, this );
281 imgSSLStatus = new wxStaticBitmap(stbBottom, wxID_ANY, wxNullBitmap, wxPoint((rectSSL.GetX()),(rectSSL.GetY())), wxDefaultSize, 0 );
282 imgSSLStatus->SetBitmap(*imgNoSSL);
283 imgSSLStatus->SetToolTip(SSLToolTip);
284 imgSSLStatus->Connect( wxEVT_LEFT_DCLICK, wxCommandEventHandler( frmMain::ShowSSLCertificates ), NULL, this );
286 imgActivityStatus = new wxStaticBitmap(stbBottom, wxID_ANY, wxNullBitmap, wxPoint((rectActivity.GetX()),(rectActivity.GetY())), wxDefaultSize, 0);
287 imgActivityStatus->SetBitmap(*imgActIconSleep);
288 imgActivityStatus->Connect( wxEVT_LEFT_DCLICK, wxCommandEventHandler( frmMain::ShowActivityWindow ), NULL, this );
290 // Setup the window menu.
292 // By default should be:
297 // Contact editor windows:
303 mnuContactWindows = new wxMenuItem( mnuManage, wxID_ANY, wxString( _("Contact windows:") ), wxEmptyString, wxITEM_NORMAL );
304 mnuWindow->Append( mnuContactWindows );
306 mnuWindow->AppendSeparator();
308 mnuContactEditorWindows = new wxMenuItem( mnuManage, wxID_ANY, wxString( _("Contact editor windows:") ), wxEmptyString, wxITEM_NORMAL );
309 mnuWindow->Append( mnuContactEditorWindows );
311 mnuWindow->AppendSeparator();
313 mnuSearchWindows = new wxMenuItem( mnuManage, wxID_ANY, wxString( wxT("Search windows:") ), wxEmptyString, wxITEM_NORMAL );
314 mnuWindow->Append( mnuSearchWindows );
316 #if defined(__WIN32__)
321 mnuContactWindows->SetFont(fontstyle);
322 mnuContactEditorWindows->SetFont(fontstyle);
323 mnuSearchWindows->SetFont(fontstyle);
327 mnuContactWindows->Enable(FALSE);
328 mnuContactEditorWindows->Enable(FALSE);
329 mnuSearchWindows->Enable(FALSE);
333 // Hide unimplemented functions.
339 void frmMain::QuitApp( wxCloseEvent& event )
342 // Run the QuitApp function.
348 void frmMain::QuitApp( wxCommandEvent& event )
351 // Run the QuitApp function.
357 void frmMain::QuitApp()
360 // Function to run when quitting.
362 //Go through the windows and close each one (be it search
363 //or contact editor). Abort if user wants to cancel.
365 // Close the contact editor windows.
367 // Close the contact windows.
369 // Close the search windows.
371 // Write out the ETag databases.
373 // Save Preferences: Save the window position if that option is enabled.
375 wxString SetFilename = GetUserPrefDir();
377 #if defined(__HAIKU__)
381 #elif defined(__WIN32__)
383 SetFilename.Append(wxT("settings"));
389 SetFilename.Append(wxT("settings"));
393 wxFileConfig *cfgfile = new wxFileConfig("", "", SetFilename);
395 bool SaveWindowPos = FALSE;
396 wxString SaveWindowInc;
397 cfgfile->Read(wxT("SaveWindowPosition"), &SaveWindowInc);
399 if (SaveWindowInc == wxT("true")){
401 SaveWindowPos = TRUE;
405 if (SaveWindowPos == TRUE){
407 wxRect frmMainPos = this->GetRect();
409 cfgfile->Write(wxT("WindowPositionX"), frmMainPos.GetX());
410 cfgfile->Write(wxT("WindowPositionY"), frmMainPos.GetY());
411 cfgfile->Write(wxT("WindowPositionHeight"), frmMainPos.GetHeight());
412 cfgfile->Write(wxT("WindowPositionWidth"), frmMainPos.GetWidth());
419 //Everything closed... exit.
427 void frmMain::ShowActivityWindow( wxCommandEvent& event )
430 // Open the activity manager window.
432 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
433 frameActMgr->OpenWindow();
438 void frmMain::ShowAboutWindow( wxCommandEvent& event )
441 // Show the about window.
443 frmAbout *frameAbout = new frmAbout ( this );
444 frameAbout->SetupAboutWindow();
445 frameAbout->ShowModal();
451 void frmMain::OpenPreferences( wxCommandEvent& event)
454 // Open the preferences window.
456 ReloadAccounts = FALSE;
458 frmPreferences *framePreferences = new frmPreferences ( this );
459 framePreferences->SetupPointers(&ReloadAccounts);
460 framePreferences->ShowModal();
461 delete framePreferences;
462 framePreferences = NULL;
464 if (ReloadAccounts == TRUE){
466 // Reload the accounts as a change has been made within
467 // the application and clear the current contact information.
469 this->LoadPreferences();
470 this->ResetContactInfo();
476 void frmMain::OpenNewABDialog( wxCommandEvent& event)
479 // Open the new account dialog.
481 ReloadAccounts = FALSE;
483 frmNewAccount *frameNewAccount = new frmNewAccount ( this );
484 frameNewAccount->SetupPointers(&ReloadAccounts);
485 frameNewAccount->ShowModal();
486 delete frameNewAccount;
487 frameNewAccount = NULL;
489 if (ReloadAccounts == TRUE){
491 // Reload the accounts as a change has been made within
494 this->LoadPreferences();
500 void frmMain::LoadContactList( wxTreeEvent& event )
503 // Load the contact list.
505 // Clear all existing variables.
507 lstContacts->DeleteAllItems();
509 treAccounts->SetAccount();
511 wxTreeItemIdValue cookie;
512 wxTreeItemId next = treAccounts->GetRootItem();
513 wxString AccountName;
514 wxString AccountDir, AccountType, AccountDirFinal, AccountTypeFinal;
515 wxString AccountDirCmb;
516 long selectedaccount = 0;
518 wxTreeItemId selectedChild = treAccounts->GetSelection();
519 wxTreeItemId nextChild;
521 wxTreeItemId ActiveItemId = treAccounts->GetFocusedItem();
522 int ActiveItemIcon = treAccounts->GetItemImage(ActiveItemId, wxTreeItemIcon_Normal);
524 int SCImg = treAccounts->GetItemImage(selectedChild);
525 int AccountIndex = 0;
527 bmpIcon->SetIcon(AccImgList->GetIcon(SCImg));
529 // Process each account.
531 for (int i = 0; i < prefaccounts.GetCount(); i++){
533 if (ActiveItemIcon == 2){
535 std::multimap<wxTreeItemId, int>::iterator AGTiter = AccountGroupTreeId.find(ActiveItemId);
536 std::multimap<int, int>::iterator AGLiter = AccountGroupList.find(AGTiter->second);
537 int ActiveAccountG = AGLiter->second;
539 if (i == ActiveAccountG){
541 AccountDir.Append(prefaccounts.GetAccountDirectory(i));
542 AccountType.Append(prefaccounts.GetAccountType(i));
547 if (AccountType == wxT("CardDAV")){
548 AccountTypeFinal.Append(wxT("carddav"));
549 } else if (AccountType == wxT("Local")){
550 imgSSLStatus->SetBitmap(*imgOffline);
551 SSLToolTip->SetTip(wxT("SSL status is not applicable for this account"));
552 AccountTypeFinal.Append(wxT("local"));
554 imgSSLStatus->SetBitmap(*imgOffline);
555 SSLToolTip->SetTip(wxT("SSL status is not applicable for this account"));
556 AccountTypeFinal.Append(AccountType.Lower());
567 nextChild = treAccounts->GetFirstChild(next, cookie);
569 nextChild = treAccounts->GetNextSibling(nextChild);
572 AccountName = treAccounts->GetItemText(nextChild);
574 if (nextChild == selectedChild){
576 AccountDir.Append(prefaccounts.GetAccountDirectory(i));
577 AccountType.Append(prefaccounts.GetAccountType(i));
582 if (AccountType == wxT("CardDAV")){
583 AccountTypeFinal.Append(wxT("carddav"));
584 } else if (AccountType == wxT("Local")){
585 SSLToolTip->SetTip(wxT("SSL status is not applicable for this account"));
586 AccountTypeFinal.Append(wxT("local"));
588 AccountTypeFinal.Append(AccountType.Lower());
597 if (selectedaccount >= prefaccounts.GetCount()){
599 // The account selected isn't there so return.
607 // Open the directory and get the list of .vcf files
608 // in that directory.
610 ActiveAccount = AccountDir + wxT(".") + AccountTypeFinal;
611 ActiveAccountType = AccountType;
613 SetupSSLStatus(AccountIndex);
615 AccountDirFinal.Clear();
616 AccountDirFinal = GetAccountDir(AccountDir + wxT(".") + AccountTypeFinal, FALSE);
618 ContactsFileIndex.Clear();
620 wxString vCardFilename;
621 wxString vCardFilenameFull;
622 wxString vCardDataString;
623 wxStringTokenizer vcardfileline;
625 wxString setname, setvalue;
626 std::multimap<wxString, wxString, std::greater<wxString>> vCardNamesAsc;
627 std::multimap<wxString, wxString, std::less<wxString>> vCardNamesDsc;
628 long ContactIndex = 1;
629 long ContactSeekPoint = 0;
631 wxDir vcardaccdir(AccountDirFinal);
633 // Get the wxTreeItemId and image icon and compare it to the list.
635 if (ActiveItemIcon == AccountGrpID){
637 // It's a group so load the file containing the group and
638 // get the members of the group.
643 std::multimap<wxTreeItemId, int>::iterator AGTiter = AccountGroupTreeId.find(ActiveItemId);
644 std::multimap<int, wxString>::iterator AGFiter = AccountGroupFilename.find(AGTiter->second);
646 Group.LoadFile(AGFiter->second);
648 ArrayvCardOutData vCardMember = Group.GetByPartial(wxT("MEMBER"));
650 for (int i = 0; i < vCardMember.PropCount; i++){
652 vCardMember.PropValues[i].Trim();
653 if (vCardMember.PropValues[i].Left(9) == wxT("urn:uuid:")){
655 wxString NewPropValue;
656 NewPropValue = vCardMember.PropValues[i].Mid(9, wxString::npos);
657 vCardMember.PropValues[i] = NewPropValue;
663 bool ProcFiles = vcardaccdir.GetFirst(&vCardFilename, wxEmptyString, wxDIR_FILES);
667 if (vCardFilename.Right(4) == wxT(".vcf") ||
668 vCardFilename.Right(4) == wxT(".VCF") ||
669 vCardFilename.Right(5) == wxT(".vcard") ||
670 vCardFilename.Right(5) == wxT(".VCARD")){
673 bool FoundMember = FALSE;
675 vCardFilenameFull.Append(AccountDirFinal);
676 vCardFilenameFull.Append(wxT("/"));
677 vCardFilenameFull.Append(vCardFilename);
679 Person.LoadFile(vCardFilenameFull);
681 UIDCode = Person.Get(wxT("UID"));
683 for (int i = 0; i < vCardMember.PropCount; i++){
685 if (vCardMember.PropValues[i] == UIDCode){
693 if (FoundMember == FALSE){
695 vCardFilename.Clear();
696 vCardFilenameFull.Clear();
697 vCardDataString.Clear();
698 ProcFiles = vcardaccdir.GetNext(&vCardFilename);
703 if (Person.MeetBaseSpecification()){
707 // Split the name into sections.
709 vCardDataString = Person.Get(wxT("N"));
711 vCardName NameData = Person.GetName();
713 vCardDataString = NameData.Forename + wxT(" ") + NameData.Surname;
715 } else if (SortMode == 2){
717 // Split the name into sections.
719 vCardName NameData = Person.GetName();
721 vCardDataString = NameData.Surname + wxT(", ") + NameData.Forename;
723 } else if (SortMode == 3){
725 // Check and make sure that the top most nickname is used.
727 vCardDataString = Person.Get(wxT("NICKNAME"));
729 if (vCardDataString.IsEmpty()){
731 vCardDataString = wxT("(no nickname)");
735 } else if (SortMode == 4){
737 vCardDataString = Person.Get(wxT("FN"));
741 if (AscendingMode == TRUE){
742 vCardNamesAsc.insert(std::make_pair(vCardDataString, vCardFilenameFull));
744 vCardNamesDsc.insert(std::make_pair(vCardDataString, vCardFilenameFull));
751 vCardFilename.Clear();
752 vCardFilenameFull.Clear();
753 vCardDataString.Clear();
754 ProcFiles = vcardaccdir.GetNext(&vCardFilename);
760 bool ProcFiles = vcardaccdir.GetFirst(&vCardFilename, wxEmptyString, wxDIR_FILES);
763 if (vCardFilename.Right(4) == wxT(".vcf") ||
764 vCardFilename.Right(4) == wxT(".VCF") ||
765 vCardFilename.Right(5) == wxT(".vcard") ||
766 vCardFilename.Right(5) == wxT(".VCARD")){
770 vCardFilenameFull.Append(AccountDirFinal);
771 vCardFilenameFull.Append(vCardFilename);
773 Person.LoadFile(vCardFilenameFull);
775 if (Person.MeetBaseSpecification()){
779 // Split the name into sections.
781 vCardDataString = Person.Get(wxT("N"));
783 vCardName NameData = Person.GetName();
785 vCardDataString = NameData.Forename + wxT(" ") + NameData.Surname;
787 } else if (SortMode == 2){
789 // Split the name into sections.
791 vCardName NameData = Person.GetName();
793 vCardDataString = NameData.Surname + wxT(", ") + NameData.Forename;
795 } else if (SortMode == 3){
797 // Check and make sure that the top most nickname is used.
799 vCardDataString = Person.Get(wxT("NICKNAME"));
801 if (vCardDataString.IsEmpty()){
803 vCardDataString = wxT("(no nickname)");
807 } else if (SortMode == 4){
809 vCardDataString = Person.Get(wxT("FN"));
813 if (AscendingMode == TRUE){
815 vCardNamesAsc.insert(std::make_pair(vCardDataString, vCardFilenameFull));
819 vCardNamesDsc.insert(std::make_pair(vCardDataString, vCardFilenameFull));
827 vCardFilename.Clear();
828 vCardFilenameFull.Clear();
829 vCardDataString.Clear();
830 ProcFiles = vcardaccdir.GetNext(&vCardFilename);
837 // Insert the data into the control.
839 if (AscendingMode == TRUE){
840 for (std::map<wxString, wxString>::iterator iter = vCardNamesAsc.begin();
841 iter != vCardNamesAsc.end(); ++iter){
843 wxListItem ContactInfo;
845 ContactInfo.SetId(0);
846 ContactInfo.SetText(_("Mooo"));
847 ContactInfo.SetData(ContactSeekPoint);
848 ContactIndex = lstContacts->InsertItem(ContactInfo);
850 lstContacts->SetItem(ContactIndex, 0, iter->first);
852 ContactsFileIndex.Insert(iter->second, ContactSeekPoint);
859 for (std::map<wxString, wxString>::iterator iter = vCardNamesDsc.begin();
860 iter != vCardNamesDsc.end(); ++iter){
862 wxListItem ContactInfo;
864 ContactInfo.SetId(0);
865 ContactInfo.SetText(_("Mooo"));
866 ContactInfo.SetData(ContactSeekPoint);
867 ContactIndex = lstContacts->InsertItem(ContactInfo);
869 lstContacts->SetItem(ContactIndex, 0, iter->first);
870 ContactsFileIndex.Insert(iter->second, ContactSeekPoint);
879 void frmMain::ShowContactInfo( wxListEvent& event )
882 // Display the contact information.
884 long intSelected = -1;
885 long ContactSeekNum = -1;
887 // Check if several contacts have been selected.
889 int ContactTotal = 0;
893 intSelected = lstContacts->GetNextItem(intSelected,
895 wxLIST_STATE_SELECTED);
897 if (intSelected == -1){
907 if (ContactTotal == 0){
908 htmContactData->SetPage(wxT(""));
912 if (ContactTotal > 1){
914 htmContactData->SetPage(wxString::Format(wxT("%i contacts selected."), ContactTotal));
915 ActiveFilename.Clear();
920 intSelected = lstContacts->GetNextItem(intSelected,
922 wxLIST_STATE_SELECTED);
924 ContactSeekNum = lstContacts->GetItemData(intSelected);
927 wxString wxSContactString;
928 wxString ContactLine;
931 size_t ContactLineLen;
932 bool ExtraLineSeek = FALSE;
933 int QuoteBreakPoint = 0;
935 bool PropertyFind = FALSE;
936 bool QuoteMode = FALSE;
938 wxString wxSPropertyNextLine;
939 wxString wxSProperty;
940 wxString wxSPropertySeg1;
941 wxString wxSPropertySeg2;
943 // Check if we are using wxWidgets version 2.8 or less and
944 // execute the required command accordingly.
946 #if wxABI_VERSION < 20900
947 ContactFile.Open(ContactsFileIndex[ContactSeekNum].c_str(), wxT("r"));
949 ContactFile.Open(ContactsFileIndex[ContactSeekNum], wxT("r"));
952 if (ContactFile.IsOpened() == FALSE){
958 ContactFile.ReadAll(&wxSContactString, wxConvAuto());
962 std::map<int, wxString> ContactFileLines;
963 std::map<int, wxString>::iterator striter;
965 wxStringTokenizer wSTContactFileLines(wxSContactString, wxT("\r\n"));
967 int ContactLineSeek = 0;
969 while (wSTContactFileLines.HasMoreTokens() == TRUE){
971 ContactLine = wSTContactFileLines.GetNextToken();
972 ContactFileLines.insert(std::make_pair(ContactLineSeek, ContactLine));
977 if (ContactSeekNum < 0){
981 for (std::map<int, wxString>::iterator iter = ContactFileLines.begin();
982 iter != ContactFileLines.end(); ++iter){
984 // Find the colon which splits the start bit from the data part.
986 ContactLine = iter->second;
988 while (ExtraLineSeek == TRUE){
990 // Check if there is extra data on the next line
991 // (indicated by space or tab at the start) and add data.
995 if (iter == ContactFileLines.end()){
1002 wxSPropertyNextLine = iter->second;
1005 if (wxSPropertyNextLine.Mid(0, 1) == wxT(" ") || wxSPropertyNextLine.Mid(0, 1) == wxT("\t")){
1007 wxSPropertyNextLine.Remove(0, 1);
1008 ContactLine.Append(wxSPropertyNextLine);
1013 ExtraLineSeek = FALSE;
1019 ContactLineLen = ContactLine.Len();
1021 // Make sure we are not in quotation mode.
1022 // Make sure colon does not have \ or \\ before it.
1024 for (int i = 0; i <= ContactLineLen; i++){
1026 if ((ContactLine.Mid(i, 1) == wxT(";") || ContactLine.Mid(i, 1) == wxT(":")) && PropertyFind == TRUE){
1028 PropertyFind = FALSE;
1030 } else if (PropertyFind == TRUE){
1032 wxSProperty.Append(ContactLine.Mid(i, 1));
1036 if (ContactLine.Mid(i, 1) == wxT("\"")){
1038 if (QuoteMode == TRUE){
1050 if (ContactLine.Mid(i, 1) == wxT(":") && ContactLine.Mid((i - 1), 1) != wxT("\\") && QuoteMode == FALSE){
1052 QuoteBreakPoint = i;
1059 // Split that line at the point into two variables (ignore the colon).
1061 wxSPropertySeg1 = ContactLine.Mid(0, QuoteBreakPoint);
1062 wxSPropertySeg2 = ContactLine.Mid((QuoteBreakPoint + 1));
1064 // Insert both into the vCard data file.
1066 Person.AddRaw(wxSPropertySeg1, wxSPropertySeg2);
1069 PropertyFind = TRUE;
1070 ExtraLineSeek = TRUE;
1072 QuoteBreakPoint = 0;
1073 ContactLine.Clear();
1074 wxSProperty.Clear();
1078 OldSessionID = SessionID;
1079 SessionID = wxString::Format(wxT("%i"), rand() % 32768);
1080 LoadContactData(&Person, htmContactData, SessionID, OldSessionID, &MemoryFileList);
1081 ActiveFilename = ContactsFileIndex[ContactSeekNum];
1085 void frmMain::ShowContactEditorNew( wxCommandEvent& event )
1088 // Open a contact editor window to write a new contact with.
1090 // Check if there is an account selected and if not
1091 // return immediately.
1093 if (ActiveAccount.IsEmpty()){
1099 // Check if the account type is a valid account type, otherwise
1100 // display an error message.
1102 if (ActiveAccountType != "CardDAV" && ActiveAccountType != "carddav" &&
1103 ActiveAccountType != "Local" && ActiveAccountType != "local"){
1105 wxMessageBox(_("Cannot add a new contact as the account type is unsupported."), _("Unsupported account type"), wxICON_ERROR);
1110 // Add Pointer to SetupPointers for the ETagDB.
1112 wxMemoryInputStream istream(bigimgs_contactpersonicon48_png, sizeof(bigimgs_contactpersonicon48_png));
1113 wxImage bigimgs_contactpersonicon48i(istream, wxBITMAP_TYPE_PNG);
1114 wxBitmap contacticonbmp(bigimgs_contactpersonicon48i, -1);
1116 contacticon.CopyFromBitmap(contacticonbmp);
1118 frmContactEditor *ContactEditor = new frmContactEditor( this );
1122 ContactEditor->SetUID(WindowMenuItemID);
1124 WindowData *WData = new WindowData;
1126 WData->DataType = 1;
1127 WData->WindowPointer = (void*)ContactEditor;
1128 WData->WindowID = WindowMenuItemID;
1130 wxCommandEvent addevent(WINDOW_ADD);
1131 addevent.SetClientData(WData);
1132 wxPostEvent(this, addevent);
1134 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1135 ContactEditor->SetupHeaders();
1136 ContactEditor->SetupContact(ActiveAccount);
1137 ContactEditor->SetIcon(contacticon);
1138 ContactEditor->SetupPointers(frameActMgr, &ETagProcTimer, this);
1139 ContactEditor->Show(true);
1143 void frmMain::ShowContactEditorEdit( wxCommandEvent& event )
1146 // Open a contact editor window for editing an existing contact
1149 // Check if there is an account selected and if not
1150 // return immediately.
1152 int DataCheck = event.GetInt();
1154 if (ActiveAccount.IsEmpty() && DataCheck == 0){
1160 wxMemoryInputStream istream(bigimgs_contactpersonicon48_png, sizeof(bigimgs_contactpersonicon48_png));
1161 wxImage bigimgs_contactpersonicon48i(istream, wxBITMAP_TYPE_PNG);
1162 wxBitmap contacticonbmp(bigimgs_contactpersonicon48i, -1);
1164 contacticon.CopyFromBitmap(contacticonbmp);
1166 // Check if a contact has been selected.
1168 long intSelected = -1;
1169 long intContactSeekNum = -1;
1171 intSelected = lstContacts->GetNextItem(intSelected,
1173 wxLIST_STATE_SELECTED);
1175 if (intSelected == -1){
1181 intContactSeekNum = lstContacts->GetItemData(intSelected);
1183 // Get the filename of the selected contact.
1185 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1186 frmContactEditor *ContactEditor = new frmContactEditor( this );
1190 ContactEditor->SetUID(WindowMenuItemID);
1192 WindowData *WData = new WindowData;
1194 WData->DataType = 1;
1195 WData->WindowPointer = (void*)ContactEditor;
1196 WData->WindowID = WindowMenuItemID;
1198 wxCommandEvent addevent(WINDOW_ADD);
1199 addevent.SetClientData(WData);
1200 wxPostEvent(this, addevent);
1202 ContactEditor->SetupPointers(frameActMgr, &ETagProcTimer, this);
1203 ContactEditor->SetupHeaders();
1205 if (ActiveAccountType != "CardDAV" && ActiveAccountType != "carddav" &&
1206 ActiveAccountType != "Local" && ActiveAccountType != "local"){
1208 ContactEditor->SetupAccountData(true);
1212 // Check if pointer is NULL (not from the search forms) or not.
1214 if (DataCheck == 0){
1216 ContactEditor->LoadContact(ContactsFileIndex[intContactSeekNum]);
1217 ContactEditor->SetupContact(ActiveAccount);
1221 UCNotif *uc = (UCNotif*)event.GetClientData();
1225 ContactEditor->SetupContact(ActiveAccount);
1226 ContactEditor->LoadContact(ContactsFileIndex[intContactSeekNum]);
1230 ContactEditor->SetupContact(uc->ContactAccount);
1231 ContactEditor->LoadContact(uc->ContactFilename);
1240 ContactEditor->SetIcon(contacticon);
1241 ContactEditor->Show(true);
1245 void frmMain::RefreshAddressBook( wxCommandEvent& event ){
1247 // Refresh the address book data.
1249 // Check if ActiveAccount is empty. If not then check if
1250 // account type is not local otherwise continue.
1252 if (!ActiveAccount.IsEmpty()){
1254 if (ActiveAccountType == wxT("CardDAV") || ActiveAccountType == wxT("carddav")){
1256 // Account type is not local.
1258 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1259 frameActMgr->AddTask(3, wxT(""), ActiveAccount,
1260 wxT(""), wxT(""), wxT(""), wxT(""));
1264 wxMessageBox(_("The refresh address book command is not supported with this type of account."), wxT("Not supported"), wxICON_ERROR);
1272 void frmMain::OpenContactInfoList( wxListEvent& event )
1275 // Open the contact information window.
1277 wxStringTokenizer vcardfileline;
1280 wxString setname, setvalue;
1284 long intSelected = -1;
1285 long intContactSeekNum = -1;
1287 intSelected = lstContacts->GetNextItem(intSelected,
1289 wxLIST_STATE_SELECTED);
1291 intContactSeekNum = lstContacts->GetItemData(intSelected);
1293 if (intContactSeekNum == -1){
1299 Person.LoadFile(ContactsFileIndex[intContactSeekNum]);
1301 wxMemoryInputStream istream(bigimgs_contactpersonicon48_png, sizeof(bigimgs_contactpersonicon48_png));
1302 wxImage bigimgs_contactpersonicon48i(istream, wxBITMAP_TYPE_PNG);
1303 wxBitmap contacticonbmp(bigimgs_contactpersonicon48i, -1);
1305 contacticon.CopyFromBitmap(contacticonbmp);
1307 frmContact *Contact = new frmContact( this );
1309 // Add to window list.
1313 Contact->SetUID(WindowMenuItemID);
1315 WindowData *WData = new WindowData;
1317 WData->DataType = 0;
1318 WData->WindowPointer = (void*)Contact;
1319 WData->WindowID = WindowMenuItemID;
1321 wxCommandEvent addevent(WINDOW_ADD);
1322 addevent.SetClientData(WData);
1323 wxPostEvent(this, addevent);
1325 Contact->SetupPointers(&MemoryFileList);
1326 Contact->SetupContactData(&Person);
1328 Contact->SetIcon(contacticon);
1329 Contact->Show(true);
1333 void frmMain::OpenContactInfoList( wxCommandEvent& event ){
1335 // Open a list of contact information windows.
1338 OpenContactInfoList(pevent);
1342 void frmMain::OpenContactInfo( wxCommandEvent& event )
1345 // Open the contact information window.
1347 UCNotif *uc = (UCNotif*)event.GetClientData();
1349 wxStringTokenizer vcardfileline;
1352 wxString setname, setvalue;
1356 Person.LoadFile(uc->ContactFilename);
1358 wxMemoryInputStream istream(bigimgs_contactpersonicon48_png, sizeof(bigimgs_contactpersonicon48_png));
1359 wxImage bigimgs_contactpersonicon48i(istream, wxBITMAP_TYPE_PNG);
1360 wxBitmap contacticonbmp(bigimgs_contactpersonicon48i, -1);
1362 contacticon.CopyFromBitmap(contacticonbmp);
1364 frmContact *Contact = new frmContact( this );
1366 // Add to window list.
1370 Contact->SetUID(WindowMenuItemID);
1372 WindowData *WData = new WindowData;
1374 WData->DataType = 0;
1375 WData->WindowPointer = (void*)Contact;
1376 WData->WindowID = WindowMenuItemID;
1378 wxCommandEvent addevent(WINDOW_ADD);
1379 addevent.SetClientData(WData);
1380 wxPostEvent(this, addevent);
1382 Contact->SetupPointers(&MemoryFileList);
1383 Contact->SetupContactData(&Person);
1385 Contact->SetIcon(contacticon);
1386 Contact->Show(true);
1391 void frmMain::LoadPreferences( wxActivateEvent& event)
1394 // Load the preferences.
1396 this->LoadPreferences();
1400 void frmMain::LoadPreferences(){
1402 // Load the preferences.
1404 wxString preffilename = GetUserPrefDir();
1406 XABPreferences preferences(preffilename);
1408 // Setup the main window position (if needed).
1410 bool SaveWindowPos = preferences.GetBoolData(wxT("SaveWindowPosition"));
1411 bool HideLocalABs = preferences.GetBoolData(wxT("HideLocalAddressBooks"));
1413 if (SaveWindowPos == TRUE){
1415 this->SetSize(preferences.GetMainWindowData());
1419 treAccounts->DeleteAllItems();
1421 wxTreeItemId RootNode = treAccounts->AddRoot(wxT("Root Item"), AccountNoneID);
1423 // Stop all account timers and remove the accounts.
1425 for (std::map<wxString, wxAccountSyncTimer*>::iterator iter = AccountSyncTimers.begin();
1426 iter != AccountSyncTimers.end(); iter++){
1428 wxAccountSyncTimer *AccTmrPtr = iter->second;
1436 #if defined(__WIN32__)
1438 for (std::map<int, PCCERT_CONTEXT>::iterator CertificateIter = AccountCertificateData.begin();
1439 CertificateIter != AccountCertificateData.end(); CertificateIter++){
1441 CertFreeCertificateContext(CertificateIter->second);
1445 AccountCertificateData.clear();
1449 AccountSyncTimers.clear();
1452 wxString AccDirFull;
1453 wxString AccDirFullSfx;
1455 wxString AccDirFinal;
1456 AccountAccDirList.clear();
1457 AccountGroupList.clear();
1458 AccountGroupFilename.clear();
1459 AccountGroupTreeId.clear();
1460 wxTreeItemId AccountTreeId;
1461 wxTreeItemId GroupTreeId;
1464 // Relaod the accounts for the ETagProcTimer.
1466 ETagProcTimer.ReloadAccounts();
1468 for (int i = 0; i < preferences.accounts.GetCount(); i++){
1470 if ((preferences.accounts.GetAccountType(i) == wxT("Local") ||
1471 preferences.accounts.GetAccountType(i) == wxT("local")) && HideLocalABs == TRUE){
1477 if (preferences.accounts.GetAccountDirectory(i).IsEmpty()){
1483 AccDir = preferences.accounts.GetAccountDirectory(i);
1484 AccDirFull = preferences.accounts.GetAccountDirectory(i);
1486 AccDirFull.Append(wxT("."));
1487 AccDirFullSfx.Append(preferences.accounts.GetAccountType(i));
1488 AccDirFullSfx.LowerCase();
1489 AccDirFullSfx.Trim();
1490 AccDirFull.Append(AccDirFullSfx);
1491 AccName = preferences.accounts.GetAccountName(i);
1493 AccountAccDirList.insert(std::make_pair(i, AccDirFull));
1495 if (preferences.accounts.GetAccountType(i) == wxT("CardDAV") ||
1496 preferences.accounts.GetAccountType(i) == wxT("carddav")){
1498 // TODO: Check if the directory exists before doing anything.
1502 // Add a new timer using the existing account details.
1504 wxAccountSyncTimer *ActTmrPtr = new wxAccountSyncTimer;
1506 ActTmrPtr->SetupData(AccDirFull, AccName);
1507 ActTmrPtr->SetupPointers(this, ActMgrPtr, ETagProcTimer.GetPointer(AccDirFull));
1508 ActTmrPtr->Start((int)(preferences.accounts.GetAccountRefresh(i) * 1000));
1509 ActTmrPtr->SetOwner(this);
1510 ActTmrPtr->Notify();
1512 // Add the timer to the list of timers.
1514 AccountSyncTimers.insert(std::make_pair(AccDirFull, ActTmrPtr));
1516 AccountTreeId = treAccounts->AppendItem(RootNode, preferences.accounts.GetAccountName(i), AccountNetID, -1);
1518 } else if (preferences.accounts.GetAccountType(i) == wxT("Local") ||
1519 preferences.accounts.GetAccountType(i) == wxT("local")) {
1521 AccountTreeId = treAccounts->AppendItem(RootNode, preferences.accounts.GetAccountName(i), AccountID, -1);
1525 AccountTreeId = treAccounts->AppendItem(RootNode, preferences.accounts.GetAccountName(i), AccountUnsupportedID, -1);
1529 // Go through the account directory and find contact files with
1530 // 'KIND:group' set and add them to the list of groups for the account.
1532 AccDirFinal = GetAccountDir(AccDirFull, FALSE);
1534 wxDir vcardaccdir(AccDirFinal);
1536 wxString vCardFilename;
1537 wxString vCardDataString;
1538 wxString vCardFilenameFull;
1540 bool ProcFiles = vcardaccdir.GetFirst(&vCardFilename, wxEmptyString, wxDIR_FILES);
1544 if (vCardFilename.Right(4) == wxT(".vcf") ||
1545 vCardFilename.Right(4) == wxT(".VCF") ||
1546 vCardFilename.Right(5) == wxT(".vcard") ||
1547 vCardFilename.Right(5) == wxT(".VCARD")){
1551 vCardFilenameFull.Append(AccDirFinal);
1552 vCardFilenameFull.Append(wxT("/"));
1553 vCardFilenameFull.Append(vCardFilename);
1555 Person.LoadFile(vCardFilenameFull);
1557 if (Person.MeetBaseSpecification()){
1559 vCardDataString = Person.Get(wxT("KIND"));
1561 if (vCardDataString == wxT("group")){
1563 // The vCard kind is a group. Add to the account's group list.
1565 GroupTreeId = treAccounts->AppendItem(AccountTreeId, Person.Get(wxT("FN")), AccountGrpID, -1);
1566 treAccounts->SetItemHasChildren(AccountTreeId, TRUE);
1567 AccountGroupList.insert(std::make_pair(intGroupID, i));
1568 AccountGroupFilename.insert(std::make_pair(intGroupID, vCardFilenameFull));
1569 AccountGroupTreeId.insert(std::make_pair(GroupTreeId, intGroupID));
1579 vCardFilename.Clear();
1580 vCardFilenameFull.Clear();
1581 vCardDataString.Clear();
1582 ProcFiles = vcardaccdir.GetNext(&vCardFilename);
1586 // Clearup for next account.
1590 AccDirFullSfx.clear();
1591 AccDirFinal.clear();
1596 // Load the account settings as they are needed for connecting
1599 prefaccounts = preferences.accounts;
1603 void frmMain::ConflictResolution(wxCommandEvent& event){
1605 // Display the conflict resolution window.
1607 frmConflictResolution *frameCR = new frmConflictResolution ( this );
1608 vCardConflictObj *vCardConfObj = (vCardConflictObj*)event.GetClientData();
1609 vCard *ClientDataPtr = vCardConfObj->vCardLocalData;
1610 vCard *ServerDataPtr = vCardConfObj->vCardServerData;
1611 frameCR->LoadData(ClientDataPtr, ServerDataPtr, &MemoryFileList);
1612 frameCR->ShowModal();
1614 int FinalConflictResult = frameCR->GetResult();
1616 wxCommandEvent event2(ACTMGR_RESUMEPROC);
1617 event2.SetClientData(vCardConfObj->QRNotifData);
1618 event2.SetInt(FinalConflictResult);
1623 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1624 wxPostEvent(frameActMgr, event2);
1628 void frmMain::UpdateContactList(wxCommandEvent& event){
1630 // Update the contact list in the main window.
1632 UCNotif *ucd = (UCNotif*)event.GetClientData();
1634 // Check if the active account is being displayed in the
1635 // main window. If not, skip and delete the data.
1637 long longSelected = -1;
1638 int intSelectedData = 0;
1640 if (ActiveAccount == ucd->ContactAccount){
1642 // Look at the list of contacts and if it matches the
1643 // filename then update the name.
1647 longSelected = lstContacts->GetNextItem(longSelected,
1649 wxLIST_STATE_DONTCARE);
1651 if (longSelected == -1){
1657 intSelectedData = (int)lstContacts->GetItemData(longSelected);
1659 if (ucd->ContactFilename == ContactsFileIndex[intSelectedData]){
1661 // Work out which sorting mode we are in.
1665 // First Name, Last Name.
1667 lstContacts->SetItem(longSelected, 0, ucd->ContactNameArray.Forename + wxT(" ") + ucd->ContactNameArray.Surname);
1669 } else if (SortMode == 2){
1671 // Last Name, First Name.
1673 lstContacts->SetItem(longSelected, 0, ucd->ContactNameArray.Surname + wxT(", ") + ucd->ContactNameArray.Forename);
1675 } else if (SortMode == 3){
1679 lstContacts->SetItem(longSelected, 0, ucd->ContactNickname);
1681 } else if (SortMode == 4){
1685 lstContacts->SetItem(longSelected, 0, ucd->ContactName);
1692 // If the filename is the one loaded into the
1693 // browser control, then update this too.
1695 if (ActiveFilename == ContactsFileIndex[intSelectedData]){
1697 wxListEvent nullevent;
1698 ShowContactInfo(nullevent);
1706 for (std::map<int, void*>::iterator WindowIter = WindowListPointers.begin();
1707 WindowIter != WindowListPointers.end(); WindowIter++){
1709 if (WindowListType[WindowIter->first] != 0){
1715 frmContact *frmContactPtr = static_cast<frmContact*>(WindowIter->second);
1717 if (frmContactPtr->GetFilename() == ucd->ContactFilename){
1719 vCard UpdatedPerson;
1720 UpdatedPerson.LoadFile(ucd->ContactFilename);
1721 frmContactPtr->SetupContactData(&UpdatedPerson);
1727 // Send message to search window controller subroutine and
1728 // pass that notification onto the search windows.
1730 // Setup the new pointer to use the existing UCNotif without
1733 UCNotif *ucd2 = ucd;
1735 wxCommandEvent sup(SE_UPDATECONTACTNOTIF);
1736 sup.SetClientData(ucd2);
1737 wxPostEvent(this, sup);
1739 // Clear up the unused pointer.
1745 void frmMain::UpdateAccountList(wxCommandEvent& event){
1747 // Update the account list (currently unimplemented).
1751 void frmMain::SetupPointers(void *ActMgrPtrInc){
1753 // Setup the pointers for the main window.
1755 ActMgrPtr = ActMgrPtrInc;
1759 void frmMain::SetupForm(){
1761 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1762 frameActMgr->SetupPointers(&ETagProcTimer, this);
1764 // Setup the contact information icons for later.
1766 wxFileSystem::AddHandler(new wxMemoryFSHandler);
1770 wxMemoryInputStream ciptostream(icons_cipto_png, sizeof(icons_cipto_png));
1771 ciicon_png.LoadFile(ciptostream, wxBITMAP_TYPE_PNG);
1772 wxMemoryFSHandler::AddFile(wxT("cipto.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1774 wxMemoryInputStream cilogstream(icons_cilog_png, sizeof(icons_cilog_png));
1775 ciicon_png.LoadFile(cilogstream, wxBITMAP_TYPE_PNG);
1776 wxMemoryFSHandler::AddFile(wxT("cilog.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1778 wxMemoryInputStream cisndstream(icons_cisnd_png, sizeof(icons_cisnd_png));
1779 ciicon_png.LoadFile(cisndstream, wxBITMAP_TYPE_PNG);
1780 wxMemoryFSHandler::AddFile(wxT("cisnd.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1782 wxMemoryInputStream cikeystream(icons_cikey_png, sizeof(icons_cikey_png));
1783 ciicon_png.LoadFile(cikeystream, wxBITMAP_TYPE_PNG);
1784 wxMemoryFSHandler::AddFile(wxT("cikey.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1786 wxMemoryInputStream civenstream(icons_civen_png, sizeof(icons_civen_png));
1787 ciicon_png.LoadFile(civenstream, wxBITMAP_TYPE_PNG);
1788 wxMemoryFSHandler::AddFile(wxT("civen.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1790 wxMemoryInputStream ciextstream(icons_ciext_png, sizeof(icons_ciext_png));
1791 ciicon_png.LoadFile(ciextstream, wxBITMAP_TYPE_PNG);
1792 wxMemoryFSHandler::AddFile(wxT("ciext.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1798 void frmMain::UpdateSearchContactLists(wxCommandEvent& event){
1800 // Update the contact lists in the search windows.
1802 // Go through each of the search windows and
1803 // send the required notification to update the
1804 // contact information.
1806 // Get the event notification data.
1808 UCNotif *ucd = (UCNotif*)event.GetClientData();
1810 // Process each search window giving the new details.
1812 for (std::map<void*,wxString>::iterator switer = SearchWindowList.begin();
1813 switer != SearchWindowList.end(); switer++){
1815 // Duplicate the event notification data.
1817 UCNotif *ucd2 = new UCNotif;
1819 ucd2->ContactAccount = ucd->ContactAccount;
1820 ucd2->ContactFilename = ucd->ContactFilename;
1821 ucd2->ContactName = ucd->ContactName;
1822 ucd2->ContactNickname = ucd->ContactNickname;
1823 ucd2->ContactNameArray = ucd->ContactNameArray;
1825 // Pass the data to the search window for processing.
1827 frmSearch *frameSCH = static_cast<frmSearch*>(switer->first);
1828 wxCommandEvent schupdate(SE_UPDATERESULT);
1829 schupdate.SetClientData(ucd2);
1830 wxPostEvent(frameSCH, schupdate);
1832 // Clear up the pointer prior to variable deletion.
1843 void frmMain::OpenFindContactsWindow(wxCommandEvent& event){
1845 // Open a new search window.
1849 frmSearch *frameSCH = new frmSearch ( this );
1850 frameSCH->SetUID(WindowMenuItemID);
1851 frameSCH->Show(true);
1853 WindowData *WData = new WindowData;
1855 WData->DataType = 2;
1856 WData->WindowPointer = (void*)frameSCH;
1857 WData->WindowID = WindowMenuItemID;
1859 wxCommandEvent addevent(WINDOW_ADD);
1860 addevent.SetClientData(WData);
1861 wxPostEvent(this, addevent);
1863 // Add pointer to the list of open search windows.
1865 SearchWindowList.insert(std::make_pair(frameSCH, wxT("Search")));
1871 void frmMain::RemoveContactsWindowPointer(wxCommandEvent& event){
1873 // Remove the pointer for a contact window from the
1876 void *frameSCH = (void*)event.GetClientData();
1878 SearchWindowList.erase(frameSCH);
1884 void frmMain::RemoveContactEditorWindowPointer(wxCommandEvent& event){
1886 // Remove the pointer for a contact editor window from
1889 void *frameSCH = (void*)event.GetClientData();
1891 SearchWindowList.erase(frameSCH);
1897 void frmMain::RevealContact(wxCommandEvent& event){
1899 // Reveal a contact in the main window.
1901 UCNotif *uc = (UCNotif*)event.GetClientData();
1903 // Switch the account to the one passed.
1905 wxTreeItemIdValue cookie;
1906 wxTreeItemId next = treAccounts->GetRootItem();
1907 wxTreeItemId nextChild;
1909 for (int i = 0; i < prefaccounts.GetCount(); i++){
1912 nextChild = treAccounts->GetFirstChild(next, cookie);
1914 nextChild = treAccounts->GetNextSibling(nextChild);
1917 if (uc->ContactAccount == AccountAccDirList[i]){
1919 treAccounts->SelectItem(nextChild, TRUE);
1920 AccCtrl->SetText(treAccounts->GetItemText(nextChild));
1926 // Switch the contact to the one passed.
1928 long longSelected = -1;
1929 int intSelectedData = 0;
1933 longSelected = lstContacts->GetNextItem(longSelected,
1935 wxLIST_STATE_DONTCARE);
1937 if (longSelected == -1){
1943 intSelectedData = (int)lstContacts->GetItemData(longSelected);
1945 // Compare the filename with the one received.
1946 // If they match then select it.
1948 if (ContactsFileIndex[intSelectedData] == uc->ContactFilename){
1952 lstContacts->SetItemState(longSelected, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
1953 lstContacts->EnsureVisible(longSelected);
1957 lstContacts->SetItemState(longSelected, 0, wxLIST_STATE_SELECTED);
1965 void frmMain::DeleteContact(wxCommandEvent& event){
1967 // Delete a contact from the main window.
1969 // Check if a contact is selected.
1971 long intSelected = -1;
1972 long intContactSeekNum = -1;
1973 wxString wxSContactName;
1975 intSelected = lstContacts->GetNextItem(intSelected,
1977 wxLIST_STATE_SELECTED);
1979 if (intSelected == -1){
1983 // Check if the account type is a valid account type, otherwise
1984 // display an error message.
1986 if (ActiveAccountType != "CardDAV" && ActiveAccountType != "carddav" &&
1987 ActiveAccountType != "Local" && ActiveAccountType != "local"){
1989 wxMessageBox(_("Cannot delete contact as the account type is unsupported."), _("Unsupported account type"), wxICON_ERROR);
1994 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1996 // Get the item data of the contact.
1998 intContactSeekNum = lstContacts->GetItemData(intSelected);
2000 // Get the name of the contact.
2002 wxSContactName = lstContacts->GetItemText(intSelected);
2004 // Display a message confirming if the contact should
2007 int QuestionResponse;
2009 QuestionResponse = wxMessageBox(_("Are you sure you want to delete this contact?"), _("Delete contact"), wxYES_NO, this);
2011 if (QuestionResponse == wxNO){
2013 // Exit the subroutine
2019 // Delete the contact.
2021 if (!wxRemoveFile(ContactsFileIndex[intContactSeekNum])){
2023 wxMessageBox(_("Unable to delete the contact."), _("Cannot delete contact"), wxOK, this);
2028 // Remove the contact from the list.
2030 lstContacts->DeleteItem(intSelected);
2032 // Update the search windows, removing the deleted
2035 UCNotif *ucd = new UCNotif;
2037 ucd->ContactAccount = ActiveAccount;
2038 ucd->ContactFilename = ContactsFileIndex[intContactSeekNum];
2040 for (std::map<void*,wxString>::iterator switer = SearchWindowList.begin();
2041 switer != SearchWindowList.end(); switer++){
2043 // Duplicate the event notification data.
2045 UCNotif *ucd2 = new UCNotif;
2047 ucd2->ContactAccount = ucd->ContactAccount;
2048 ucd2->ContactFilename = ucd->ContactFilename;
2050 // Pass the data to the search window for processing.
2052 frmSearch *frameSCH = static_cast<frmSearch*>(switer->first);
2053 wxCommandEvent schdelete(SE_DELETERESULT);
2054 schdelete.SetClientData(ucd2);
2055 wxPostEvent(frameSCH, schdelete);
2057 // Clear up the pointer prior to variable deletion.
2064 // Clear the wxHTMLWindow.
2066 wxString EmptyPage = wxT("");
2068 htmContactData->SetPage(EmptyPage);
2070 wxStringTokenizer wSTFilename(ContactsFileIndex[intContactSeekNum], wxT("/"));
2072 wxString wxSplitFilename;
2073 wxString wxSDataURL;
2075 while(wSTFilename.HasMoreTokens()){
2077 wxSplitFilename = wSTFilename.GetNextToken();
2081 if (ActiveAccountType == wxT("CardDAV") || ActiveAccountType == wxT("carddav")){
2083 // Update the ETagDB and mark it as deleted.
2085 ETagDB *ETagDBPtr = ETagProcTimer.GetPointer(ActiveAccount);
2087 ETagDBPtr->UpdateETag(wxSplitFilename, wxT("DELETED"));
2089 // Get the Data URL.
2091 wxTreeItemIdValue cookie;
2092 wxTreeItemId next = treAccounts->GetRootItem();
2094 wxTreeItemId selectedChild = treAccounts->GetSelection();
2095 wxTreeItemId nextChild;
2097 for (int i = 0; i < prefaccounts.GetCount(); i++){
2100 nextChild = treAccounts->GetFirstChild(next, cookie);
2102 nextChild = treAccounts->GetNextSibling(nextChild);
2105 if (nextChild == selectedChild){
2107 wxSDataURL = prefaccounts.GetAccountDirPrefix(i) + wxT("/") + wxSplitFilename;
2114 // Add task to the activity monitor to delete the contact.
2116 frameActMgr->AddTask(2, wxSContactName, ActiveAccount, wxSDataURL, wxSplitFilename, ContactsFileIndex[intContactSeekNum], wxT(""));
2120 // Clear the variable. Don't delete as it will mess things up.
2122 ContactsFileIndex[intContactSeekNum] = wxT("");
2129 void frmMain::EmptyServerDialog(wxCommandEvent& event){
2131 // Display this message when the server information has changed
2134 QRNotif *qrn = (QRNotif *)event.GetClientData();
2136 int QResponse = wxMessageBox(_("The list of contacts on the server is empty. Upload all locally stored contacts for this account now?"), _("No contacts on server"), wxYES_NO, this);
2138 if (QResponse == wxNO){
2144 wxCommandEvent event2(ACTMGR_RESUMEPROC);
2145 event2.SetInt(*qrn->QResponse);
2146 event2.SetClientData(qrn->PausePtr);
2148 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
2150 wxPostEvent(frameActMgr, event2);
2154 void frmMain::DeleteContactSync(wxString &Account, wxString &Filename){
2156 // Remove the contact from the window after syncronising.
2158 // Check which account is currently active in the window.
2159 // If it is different from the one passed to this subroutine then
2160 // exit from the subroutine.
2162 if (Account != ActiveAccount){
2166 long longSelected = -1;
2167 int intSelectedData = 0;
2171 longSelected = lstContacts->GetNextItem(longSelected,
2173 wxLIST_STATE_DONTCARE);
2175 if (longSelected == -1){
2181 intSelectedData = (int)lstContacts->GetItemData(longSelected);
2183 // Compare the filename with the one received.
2184 // If they match then select it.
2186 if (ContactsFileIndex[intSelectedData] == Filename){
2188 // Remove the contact from the window.
2190 lstContacts->DeleteItem(intSelectedData);
2192 // Check if contact is the selected contact in the HTML window and
2193 // if it is then clear the window.
2195 if (ActiveFilename == Filename){
2197 wxString EmptyPage = wxT("");
2198 htmContactData->SetPage(EmptyPage);
2212 void frmMain::SortFNLN( wxCommandEvent& event ) {
2214 // Sort first name then last name.
2216 wxTreeEvent NullEvent;
2218 LoadContactList(NullEvent);
2222 void frmMain::SortLNFN( wxCommandEvent& event ) {
2224 // Sort last name then first name.
2226 wxTreeEvent NullEvent;
2228 LoadContactList(NullEvent);
2232 void frmMain::SortNickname( wxCommandEvent& event ) {
2234 // Sort by nickname.
2236 wxTreeEvent NullEvent;
2238 LoadContactList(NullEvent);
2242 void frmMain::SortDisplayAs( wxCommandEvent& event ) {
2244 // Sort by Display As name.
2246 wxTreeEvent NullEvent;
2248 LoadContactList(NullEvent);
2252 void frmMain::SortAscending( wxCommandEvent& event ) {
2256 wxTreeEvent NullEvent;
2257 AscendingMode = TRUE;
2258 LoadContactList(NullEvent);
2262 void frmMain::SortDescending( wxCommandEvent& event ) {
2266 wxTreeEvent NullEvent;
2267 AscendingMode = FALSE;
2268 LoadContactList(NullEvent);
2272 void frmMain::ToggleStatusBar( wxCommandEvent& event ) {
2274 // Toggle the appearance of the status bar.
2276 if (stbBottom->IsShown() == TRUE){
2290 void frmMain::ActivityIconStart( wxCommandEvent& event ){
2292 // Display the activity icon.
2294 imgActivityStatus->SetBitmap(*imgActIcon1);
2295 ActivityIconStatus = 0;
2299 void frmMain::ActivityIconShuffle( wxCommandEvent& event ){
2301 // Shuffle through the activity icons.
2303 switch (ActivityIconStatus){
2306 imgActivityStatus->SetBitmap(*imgActIcon1);
2307 ActivityIconStatus = 1;
2310 imgActivityStatus->SetBitmap(*imgActIcon2);
2311 ActivityIconStatus = 2;
2314 imgActivityStatus->SetBitmap(*imgActIcon3);
2315 ActivityIconStatus = 3;
2318 imgActivityStatus->SetBitmap(*imgActIcon4);
2319 ActivityIconStatus = 0;
2322 ActivityIconStatus = 0;
2328 void frmMain::ActivityIconStop( wxCommandEvent& event ){
2330 // Display the sleep icon.
2332 imgActivityStatus->SetBitmap(*imgActIconSleep);
2336 void frmMain::UpdateSBIconPlacement( wxSizeEvent& event ){
2338 // Set the placement of the status bar icons.
2340 if (imgConnStatus == 0 || imgSSLStatus == 0 || imgActivityStatus == 0){
2348 wxRect rectActivity;
2349 stbBottom->GetFieldRect(1, rectOnline);
2350 stbBottom->GetFieldRect(2, rectSSL);
2351 stbBottom->GetFieldRect(3, rectActivity);
2353 imgConnStatus->Move(rectOnline.GetX(),rectOnline.GetY());
2354 imgSSLStatus->Move(rectSSL.GetX(),rectSSL.GetY());
2355 imgActivityStatus->Move(rectActivity.GetX(),rectActivity.GetY());
2359 XABViewMode frmMain::GetViewMode(){
2361 // Set the view mode of the contact list.
2365 xvm.SortMode = SortMode;
2366 xvm.AscendingMode = AscendingMode;
2372 void frmMain::WindowAdd( wxCommandEvent &event ){
2374 // Add a window to the window list.
2376 WindowData *WData = (WindowData*)event.GetClientData();
2380 if (WData->DataType == 0){
2384 int intID = mnuContactWindows->GetId();
2386 mnuWindow->FindChildItem(intID, &pos);
2387 wxMenuItem *mnuNewItem = new wxMenuItem(NULL, WData->WindowID, wxT("Contact Window #") + wxString::Format(wxT("%i"), WData->WindowID), wxEmptyString, wxITEM_NORMAL, NULL);
2388 mnuNewItem->SetId(WData->WindowID);
2389 WindowListPointersMenu.insert(std::make_pair(WData->WindowID, mnuNewItem));
2390 WindowListPointers.insert(std::make_pair(WData->WindowID, WData->WindowPointer));
2391 WindowListType.insert(std::make_pair(WData->WindowID, 0));
2392 mnuWindow->Insert((pos + 1), mnuNewItem);
2393 this->Connect(mnuNewItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(frmMain::ShowContactWindow));
2395 } else if (WData->DataType == 1){
2397 // Contact Editor Window
2399 int intID = mnuContactEditorWindows->GetId();
2401 mnuWindow->FindChildItem(intID, &pos);
2402 wxMenuItem *mnuNewItem = new wxMenuItem(NULL, WData->WindowID, wxT("Contact Editor Window #") + wxString::Format(wxT("%i"), WData->WindowID), wxEmptyString, wxITEM_NORMAL, NULL);
2403 mnuNewItem->SetId(WData->WindowID);
2404 WindowListPointersMenu.insert(std::make_pair(WData->WindowID, mnuNewItem));
2405 WindowListPointers.insert(std::make_pair(WData->WindowID, WData->WindowPointer));
2406 WindowListType.insert(std::make_pair(WData->WindowID, 1));
2407 mnuWindow->Insert((pos + 1), mnuNewItem);
2408 this->Connect(mnuNewItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(frmMain::ShowContactEditorWindow));
2410 } else if (WData->DataType == 2){
2414 int intID = mnuSearchWindows->GetId();
2416 mnuWindow->FindChildItem(intID, &pos);
2417 wxMenuItem *mnuNewItem = new wxMenuItem(NULL, WData->WindowID, wxT("Search Window #") + wxString::Format(wxT("%i"), WData->WindowID), wxEmptyString, wxITEM_NORMAL, NULL);
2418 mnuNewItem->SetId(WData->WindowID);
2419 WindowListPointersMenu.insert(std::make_pair(WData->WindowID, mnuNewItem));
2420 WindowListPointers.insert(std::make_pair(WData->WindowID, WData->WindowPointer));
2421 WindowListType.insert(std::make_pair(WData->WindowID, 2));
2422 mnuWindow->Insert((pos + 1), mnuNewItem);
2423 this->Connect(mnuNewItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(frmMain::ShowSearchWindow));
2432 void frmMain::WindowEdit( wxCommandEvent &event ){
2434 // Edit a window in the window list.
2436 WindowData *WData = (WindowData*)event.GetClientData();
2438 if (WData->DataType == 0){
2440 // Get the window title and use that.
2442 frmContact *frmContactPtr = static_cast<frmContact*>(WData->WindowPointer);
2444 wxString WindowTitle = frmContactPtr->GetTitle();
2446 std::map<int, wxMenuItem*>::iterator MenuIter = WindowListPointersMenu.find(WData->WindowID);
2448 MenuIter->second->SetItemLabel(WindowTitle);
2450 } else if (WData->DataType == 1){
2452 // Get the window title and use that.
2454 frmContactEditor *frmCEPtr = static_cast<frmContactEditor*>(WData->WindowPointer);
2456 wxString WindowTitle = frmCEPtr->GetTitle();
2458 std::map<int, wxMenuItem*>::iterator MenuIter = WindowListPointersMenu.find(WData->WindowID);
2460 if (WindowTitle.IsEmpty()){
2462 MenuIter->second->SetItemLabel(_("Unnamed Contact"));
2466 MenuIter->second->SetItemLabel(WindowTitle);
2477 void frmMain::WindowDelete( wxCommandEvent &event ){
2479 // Delete a window from the window list.
2481 WindowData *WData = (WindowData*)event.GetClientData();
2483 std::map<int, wxMenuItem*>::iterator MenuIter = WindowListPointersMenu.find(WData->WindowID);
2485 mnuWindow->Remove(MenuIter->second);
2487 delete MenuIter->second;
2488 MenuIter->second = NULL;
2490 WindowListPointersMenu.erase(WData->WindowID);
2491 WindowListPointers.erase(WData->WindowID);
2492 WindowListType.erase(WData->WindowID);
2499 void frmMain::ShowContactWindow( wxCommandEvent &event ){
2501 // Show a contact window from the window list.
2503 std::map<int, void*>::iterator WindowIter = WindowListPointers.find(event.GetId());
2505 frmContact *frmContactPtr = static_cast<frmContact*>(WindowIter->second);
2507 frmContactPtr->Show();
2508 frmContactPtr->Raise();
2512 void frmMain::ShowContactEditorWindow( wxCommandEvent &event ){
2514 // Show a contact editor window from the window list.
2516 std::map<int, void*>::iterator WindowIter = WindowListPointers.find(event.GetId());
2518 frmContactEditor *frmCEPtr = static_cast<frmContactEditor*>(WindowIter->second);
2525 void frmMain::ShowSearchWindow( wxCommandEvent &event ){
2527 // Show a search window from the window list.
2529 std::map<int, void*>::iterator WindowIter = WindowListPointers.find(event.GetId());
2531 frmSearch *frmSearchPtr = static_cast<frmSearch*>(WindowIter->second);
2533 frmSearchPtr->Show();
2534 frmSearchPtr->Raise();
2538 void frmMain::ToggleConnectionStatus( wxCommandEvent &event ){
2540 // Toggle the online/offline connection status.
2542 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
2543 wxCommandEvent toggconn(ACTMGR_TOGGLECONN);
2544 wxPostEvent(frameActMgr, toggconn);
2548 void frmMain::ShowSSLCertificates( wxCommandEvent &event ){
2550 // Check the account type before continuing.
2552 wxString SeekAccount;
2553 wxString AccTypeLower;
2557 #if defined(__APPLE__)
2559 std::map<int, SecTrustRef>::iterator SSLTrustIter;
2561 for (int i = 0; i < prefaccounts.GetCount(); i++){
2563 SeekAccount.Append(prefaccounts.GetAccountDirectory(i));
2564 AccType.Append(prefaccounts.GetAccountType(i));
2565 AccountSSL = prefaccounts.GetAccountSSL(i);
2566 AccTypeLower = AccType.MakeLower();
2567 SeekAccount.Append(wxT("."));
2568 SeekAccount.Append(AccTypeLower);
2570 if (SeekAccount == ActiveAccount){
2572 if (AccTypeLower == wxT("local")){
2578 if (AccountSSL == false){
2584 SSLTrustIter = AccountTrustData.find(i);
2586 // Setup and display the form.
2588 DisplayCertificate(SSLTrustIter->second);
2592 SeekAccount.Clear();
2593 AccTypeLower.Clear();
2598 #elif defined(__WIN32__)
2600 std::map<int, PCCERT_CONTEXT>::iterator SSLCertificateIter;
2602 for (int i = 0; i < prefaccounts.GetCount(); i++){
2604 SeekAccount.Append(prefaccounts.GetAccountDirectory(i));
2605 AccType.Append(prefaccounts.GetAccountType(i));
2606 AccountSSL = prefaccounts.GetAccountSSL(i);
2607 AccTypeLower = AccType.MakeLower();
2608 SeekAccount.Append(wxT("."));
2609 SeekAccount.Append(AccTypeLower);
2611 if (SeekAccount == ActiveAccount){
2613 if (AccTypeLower == wxT("local")){
2619 if (AccountSSL == false){
2625 SSLCertificateIter = AccountCertificateData.find(i);
2627 // Setup and display the form.
2629 if (SSLCertificateIter->second->pCertInfo == NULL){
2631 wxMessageBox("No certificate information is available due to invalid connection details, connection being in progress or invalid certificate data received.");
2635 BOOL ModifiedCertificateData;
2636 CRYPTUI_VIEWCERTIFICATE_STRUCTW CertificateData = BuildCertificateData(SSLCertificateIter->second, (HWND)this->GetHandle());
2638 if (!CryptUIDlgViewCertificate(&CertificateData, &ModifiedCertificateData)){
2639 wxMessageBox(_("An error occured while trying to open the certificate dialog."), _("Error opening Certificate Information dialog"));
2644 //DisplayCertificate(SSLTrustIter->second);
2648 SeekAccount.Clear();
2649 AccTypeLower.Clear();
2656 std::map<int, SSLCertCollection>::iterator SSLColIter;
2658 for (int i = 0; i < prefaccounts.GetCount(); i++){
2660 SeekAccount.Append(prefaccounts.GetAccountDirectory(i));
2661 AccType.Append(prefaccounts.GetAccountType(i));
2662 AccountSSL = prefaccounts.GetAccountSSL(i);
2663 AccTypeLower = AccType.MakeLower();
2664 SeekAccount.Append(wxT("."));
2665 SeekAccount.Append(AccTypeLower);
2667 if (SeekAccount == ActiveAccount){
2669 if (AccTypeLower == wxT("local")){
2675 if (AccountSSL == false){
2681 SSLColIter = AccountSSLData.find(i);
2683 SSLCertCollection SSLCertInfo = SSLColIter->second;
2685 frmSSLCertificate *frameSSLCert = new frmSSLCertificate ( this );
2686 frameSSLCert->StartCertFrom(0);
2687 frameSSLCert->SetupCerts(SSLCertInfo);
2688 frameSSLCert->ShowModal();
2690 delete frameSSLCert;
2691 frameSSLCert = NULL;
2695 SeekAccount.Clear();
2696 AccTypeLower.Clear();
2705 void frmMain::ShowSSLInfo( wxCommandEvent &event ){
2707 // Check the account type before continuing.
2711 void frmMain::HideSSLInfo( wxCommandEvent &event ){
2713 // Check the account type before continuing.
2717 void frmMain::UpdateConnectionStatus( wxCommandEvent &event ){
2719 if (event.GetInt() == 0){
2721 imgConnStatus->SetBitmap(*imgOnline);
2725 imgConnStatus->SetBitmap(*imgOffline);
2731 void frmMain::InvalidSSLCertificate( wxCommandEvent &event ){
2733 // Display the form for showing an invalid SSL certificate.
2735 frmInvalidSSLCertificate *frameISC = new frmInvalidSSLCertificate ( this );
2736 SSLInvalidCertNotifObj *SSLICNObj = (SSLInvalidCertNotifObj*)event.GetClientData();
2737 SSLCertCollection SSLCCData = SSLICNObj->CertCollection;
2738 wxString AccountName = SSLICNObj->AccountName;
2739 frameISC->LoadData(SSLCCData, AccountName);
2740 frameISC->ShowModal();
2742 int FinalConflictResult = frameISC->GetResult();
2744 wxCommandEvent event2(ACTMGR_RESUMEPROC);
2745 event2.SetClientData(SSLICNObj->QRNotifData);
2746 event2.SetInt(FinalConflictResult);
2751 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
2752 wxPostEvent(frameActMgr, event2);
2756 void frmMain::InvalidSSLCertificateString( wxCommandEvent &event ){
2758 // Display the form for showing an invalid SSL certificate.
2760 frmInvalidSSLCertificate *frameISC = new frmInvalidSSLCertificate ( this );
2761 SSLInvalidCertNotifObjString *SSLICNObj = (SSLInvalidCertNotifObjString*)event.GetClientData();
2762 SSLCertCollectionString SSLCCData = SSLICNObj->CertCollection;
2763 wxString AccountName = SSLICNObj->AccountName;
2764 frameISC->LoadData(SSLCCData, AccountName);
2765 frameISC->ShowModal();
2767 int FinalConflictResult = frameISC->GetResult();
2769 wxCommandEvent event2(ACTMGR_RESUMEPROC);
2770 event2.SetClientData(SSLICNObj->QRNotifData);
2771 event2.SetInt(FinalConflictResult);
2776 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
2777 wxPostEvent(frameActMgr, event2);
2781 void frmMain::PauseAllTimers(){
2783 // Pause all the account timers.
2785 for (std::map<wxString, wxAccountSyncTimer*>::iterator ASTiter = AccountSyncTimers.begin();
2786 ASTiter != AccountSyncTimers.end(); ASTiter++){
2788 ASTiter->second->Stop();
2794 void frmMain::ResumeAllTimers(){
2796 // Resume all the account timers.
2798 for (std::map<wxString, wxAccountSyncTimer*>::iterator ASTiter = AccountSyncTimers.begin();
2799 ASTiter != AccountSyncTimers.end(); ASTiter++){
2801 ASTiter->second->Start();
2807 #if defined(__APPLE__)
2809 #elif defined(__WIN32__)
2811 void frmMain::UpdateSSLAccountStatus(int AccountID, int SSLStatus, PCCERT_CONTEXT CertificateContext){
2813 // Delete existing data.
2815 std::map<int, PCCERT_CONTEXT>::iterator CertificateIter = AccountCertificateData.find(AccountID);
2817 if (CertificateIter != AccountCertificateData.end()){
2818 CertFreeCertificateContext(CertificateIter->second);
2821 AccountCertificateData.erase(AccountID);
2822 AccountSSLResult.erase(AccountID);
2826 AccountCertificateData.insert(std::make_pair(AccountID, CertificateContext));
2827 AccountSSLResult.insert(std::make_pair(AccountID, SSLStatus));
2833 void frmMain::UpdateSSLAccountStatus(int AccountID, int SSLStatus, SSLCertCollection SSLCertInc){
2835 // Delete existing data.
2837 AccountSSLData.erase(AccountID);
2838 AccountSSLResult.erase(AccountID);
2842 AccountSSLData.insert(std::make_pair(AccountID, SSLCertInc));
2843 AccountSSLResult.insert(std::make_pair(AccountID, SSLStatus));
2849 void frmMain::SetupSSLStatus( int AccountID ){
2851 // Check if account ID given is
2852 // the active account and if not, do nothing.
2855 wxString AccTypeLower;
2857 AccType = prefaccounts.GetAccountType(AccountID);
2858 AccTypeLower = AccType.MakeLower();
2860 wxString AccountIDName = prefaccounts.GetAccountDirectory(AccountID) + wxT(".") +
2863 if (AccountIDName != ActiveAccount){
2869 // Check the account type is a supported account type.
2871 if (AccType != "CardDAV" && AccType != "carddav" &&
2872 AccType != "Local" && AccType != "local"){
2874 SSLToolTip->SetTip(wxT("SSL is not enabled for this account"));
2875 imgSSLStatus->SetBitmap(*imgNoSSL);
2880 // Check if the account has SSL enabled.
2882 bool SSLInUse = prefaccounts.GetAccountSSL(AccountID);
2884 if (SSLInUse == FALSE){
2886 SSLToolTip->SetTip(wxT("SSL is not enabled for this account"));
2887 imgSSLStatus->SetBitmap(*imgNoSSL);
2891 // Get the SSL Collection Data.
2893 std::map<int,int>::iterator SSLResultIter = AccountSSLResult.find(AccountID);
2895 // Check if a result value has been set.
2897 if (SSLResultIter == AccountSSLResult.end()){
2899 imgSSLStatus->SetBitmap(*imgSSLWarning);
2900 SSLToolTip->SetTip(wxT("Unable to determine SSL information for the '") + prefaccounts.GetAccountName(AccountID) + wxT("' account."));
2905 if (SSLResultIter->second == 1){
2907 imgSSLStatus->SetBitmap(*imgSSLWarning);
2908 SSLToolTip->SetTip(wxT("Invalid certificate(s) received for '") +
2909 prefaccounts.GetAccountName(AccountID) +
2910 wxT("' (Connection denied by user)\n\nDouble click for more information."));
2912 } else if (SSLResultIter->second == 0){
2914 imgSSLStatus->SetBitmap(*imgSSL);
2915 SSLToolTip->SetTip(wxT("Account '") +
2916 prefaccounts.GetAccountName(AccountID) +
2917 wxT("' secured using SSL\n\nDouble click for more information."));
2925 void frmMain::CheckUpdates( wxCommandEvent& event ){
2927 // Check for updates to Xestia Address Book.
2929 frmUpdate *frameUpdate = new frmUpdate ( this );
2930 frameUpdate->FetchData();
2931 frameUpdate->ShowModal();
2935 void frmMain::OpenImportDialog( wxCommandEvent& event ){
2937 // Run the import contacts function.
2943 void frmMain::OpenExportDialog( wxCommandEvent& event ){
2945 // Check if an account and at least one contact is selected
2946 // before continuing.
2948 wxArrayString ArrData;
2950 if (ActiveAccount.IsEmpty()){
2956 int ContactSelected = 0;
2957 int ContactsCollected = 0;
2958 long longSelected = -1;
2962 longSelected = lstContacts->GetNextItem(longSelected,
2964 wxLIST_STATE_SELECTED);
2966 if (longSelected == -1){
2972 int FileID = (int)lstContacts->GetItemData(longSelected);
2974 ArrData.Insert(ContactsFileIndex[FileID],
2975 ContactsCollected, 1);
2981 if (ContactSelected == 0){
2987 // Run the export contacts system.
2989 ExportRun(this, &ArrData);
2993 void frmMain::GetListControl(wxListCtrl *lstContactsPtr,
2994 wxArrayString *ContactsFileIndexPtr){
2996 // Set the list control pointers.
2998 lstContactsPtr = lstContacts;
2999 ContactsFileIndexPtr = &ContactsFileIndex;
3003 void frmMain::GetSelectedList( wxCommandEvent& event ){
3005 // Get the array of contact filenames.
3007 wxArrayString *ArrData = (wxArrayString*)event.GetClientData();
3009 // Process them into an array of files.
3011 long longSelected = -1;
3012 int ContactsCollected = 0;
3013 wxString ContactFilename;
3017 longSelected = lstContacts->GetNextItem(longSelected,
3019 wxLIST_STATE_SELECTED);
3021 if (longSelected == -1){
3027 // Get the file information and add to the list.
3029 int FileID = (int)lstContacts->GetItemData(longSelected);
3031 ArrData->Insert(ContactsFileIndex[FileID],
3032 ContactsCollected, 1);
3034 ContactsCollected++;
3035 ContactFilename.Clear();
3043 void frmMain::SyncAccount( wxCommandEvent& event ){
3045 // Syncronise the selected account.
3047 wxString AccNameInc = event.GetString();
3049 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
3050 frameActMgr->AddTask(3, wxT(""), AccNameInc,
3051 wxT(""), wxT(""), wxT(""), wxT(""));
3055 void frmMain::ShowHelp( wxCommandEvent& event ){
3057 // Based on the operating system, work out where
3058 // the documentation should be.
3062 #if defined(__HAIKU__)
3064 #elif defined(__WIN32__)
3070 if (wxFileExists("/usr/share/doc/xestiaab/index.html")){
3072 wxLaunchDefaultBrowser(wxT("file:///usr/share/doc/xestiaab/index.html"));
3075 #if XSDAB_RELEASE == 0
3077 } else if (wxFileExists("/usr/local/share/doc/xestiaab/index.html")){
3079 wxLaunchDefaultBrowser(wxT("file:///usr/local/share/doc/xestiaab/index.html"));
3088 #if XSDAB_RELEASE == 0
3090 wxMessageBox(_("The help documentation is not available.\n\nYou can view the documentation that came with your source package."), _("Help documentation missing!"));
3094 wxMessageBox(_("The help documentation is not available in the usual locations on the system. Please visit http://documentation.xestia.co.uk/xestiaab/ for documentation"), _("Help documentation missing!"));
3100 void frmMain::ShowImportResults( wxCommandEvent &event ){
3102 // Show the results of importing contacts.
3104 std::map<int,wxString> *ResultData = (std::map<int,wxString>*)event.GetClientData();
3106 frmImportResults *frmIR = new frmImportResults(this);
3107 frmIR->LoadData(ResultData, event.GetInt(), (int)event.GetExtraLong());
3118 void frmMain::ReloadContactList( wxCommandEvent &event ){
3120 // Check if the account name given is the current
3121 // account selected.
3123 if (ActiveAccount == event.GetString()){
3125 wxTreeEvent NullEvent;
3126 LoadContactList(NullEvent);
3132 void frmMain::ShowContactMenu( wxMouseEvent& event ){
3134 // Show the contact menu when a right click occurs
3135 // in the contacts list.
3137 bool EnableRefresh = FALSE;
3139 if (!ActiveAccount.IsEmpty() && (ActiveAccountType == "CardDAV" || ActiveAccountType == "carddav")){
3141 EnableRefresh = TRUE;
3145 ContactMenu->SetupPointers(this, lstContacts, EnableRefresh);
3147 this->PopupMenu(ContactMenu->MenuPointer(), wxDefaultPosition);
3151 void frmMain::ResetContactInfo(){
3153 // Reset the contact information to an empty page.
3155 wxString EmptyPage = wxT("");
3156 htmContactData->SetPage(EmptyPage);
3157 AccCtrl->SetValue("");